【发布时间】:2016-01-28 19:13:13
【问题描述】:
所以,我试图合成我的 verilog 代码以从 ps2 键盘->fpga->vga 发送数据。只是为了代码的背景,我想按下按钮“1”,它会出现在屏幕的中心(称为 display_area)
我意识到有些事情没有按预期工作。 经过仔细调试,我意识到问题在于将并行数据总线从 rom 转换为串行输出的模块,以在每个像素中分配一个值。
代码本身很简单,我只是提供尽可能多的信息。
我们需要时钟的上升沿进入始终区域(或复位)。如果 display_area_enable 的值为 1,我们将激活一个从 7 到 0(8 个周期)的计数器来索引来自 rom 的数据。
但是,在第一个时钟上,如果显示区域在 vga_clk 脉冲变为 1 的确切时刻变为 1,则计数器会得到应有的值,但 one_bit_output(模块的输出)不会。 One_bit_output 在第二次访问 always 块时获得其第一个正确值。因此,我们需要 9 个周期来访问 8 位总线。
我会提供代码和modelsim测试台
module shifter(reset,char_rom_data_out,vga_clk,display_area_enable,one_bit_output,counter);
input [7:0]char_rom_data_out;
input vga_clk,display_area_enable,reset;
output reg one_bit_output;
output reg [2:0]counter;
always @(posedge vga_clk or posedge reset)
begin
if (reset)
begin
counter=3'd7;
one_bit_output=0;
end
else if (display_area_enable==1)
begin
one_bit_output<=(char_rom_data_out[counter]==1);
counter<=counter-1;
end
else if (display_area_enable==0)
begin
counter<=3'd7;
one_bit_output<=0;
end
end
endmodule
module testbz();
reg reset,vga_clk,display_area_enable;
reg [7:0]char_rom_data_out;
wire [2:0] counter;
wire one_bit_output;
shifter dignitas(reset,char_rom_data_out,vga_clk,display_area_enable,one_bit_output,counter);
initial
begin
reset<=1; char_rom_data_out<=8'b11110001; vga_clk<=0;display_area_enable=0; //sto 10 skaei o prwtos kyklos, kai meta ana 20
#5 reset<=0; display_area_enable<=0;
#5 display_area_enable<=1;
#160 display_area_enable<=0;
end
always
begin
#10 vga_clk=~vga_clk;
end
endmodule
模拟是:
有人可以向我解释为什么在 vga_clk 的第一个脉冲上,输出不是预期的吗?
【问题讨论】:
-
@toolic 你是对的,当然,只是不断编写/删除代码并尝试不同的东西的一个错字。谢谢!在第一个 posedge clk 上,one_bit_output 应该等于 char_rom 数据的 MSB,将计数器设置为 6。所以你是对的,计数器没有正确启动。问题是我已经尝试创建一个具有多重播放方式的计数器,但有些无法在我的 fpga 上正确合成。
-
@toolic 你认为这是来自柜台的问题吗?
-
@toolic 我不同意。我们需要与其他模块同步,为此我们需要一个 clk。同步基于时钟。
-
代码的目的,正如我所说的,是在 vga 屏幕上显示在键盘上按下的数字。因此,当 hsync 和 vsync 信号被发送到 vga 时(从左上角,到右上角,然后回溯到起点)。
-
在特定的时间,或者准确的说,在特定的时钟脉冲上,我们会进入一个显示区域,即400x200(h_pixel_counter为200,v_line_counter为400)。该信号将保持活动状态,直到我们离开该区域,比如说直到 600x400。因为我们需要在特定时间(25Mhz)向VGA屏幕发送数据,所以我们需要一个时钟来实现这一点。所以每 1/(25Mhz) 秒我们就会有一个信号表明我们是否在显示区域中。结果,我们无法提前知道显示区域的值。
标签: verilog