在前几节的努力下,我们成功地实现了VGA显示系统的各个部分,这篇文章我们将把零散的模块进行组合,并仿真验证。
根据整体框架图,我们书写顶层模块VGA_Test:
Top
module vga_test(
input wire clk,
input wire sys_resetn,//低电平有效
output wire hsync,
output wire vsync,
output wire [15:0] rbg_out
);
wire vga_clk;
wire locked;
wire reset_n;
wire [9:0] pix_x,pix_y;
wire [15:0] pix_data;
assign reset_n = (sys_resetn & locked);
PLL_25M PLL_25M_inst (
.areset ( ~sys_resetn ),
.inclk0 ( clk ),
.c0 ( vga_clk ),
.locked ( locked )
);
vga_ctrl vga_ctrl_inst(
.clk(vga_clk),
.reset_n(reset_n),
.rgb(pix_data),
.H_sync(hsync),
.V_sync(vsync),
.pic_x(pix_x),
.pic_y(pix_y),
.rgb_out(rbg_out)
);
vga_pic vga_pic_inst(
.pix_x(pix_x),
.pix_y(pix_y),
.clk(vga_clk),
.reset_n(reset_n),
.pix_data(pix_data)
);
endmodule
这里相比前几节做了一点小修改,复位信号原本是高电平有效,现改为低电平有效。书写顶层模块的时候要注意,要充分理解 wire型变量的实际意义,每个模块之间相互的连线都是线网,且不可用reg变量进行连接。
TestBench
`timescale 1ns/1ns
module tb_vga_ctrl();
reg reset,clk;
initial begin
reset = 1'b0;
clk = 1'b0;
#200 reset = 1'b1;
end
always #10 clk = ~clk;
vga_test vga_test_inst(
.sys_resetn(reset),
.clk(clk)
);
endmodule
大家看,TestBench里的时钟信号和复位信号就一定要是reg型,因为它们都需要存储前一个值,并且没有其它信号驱动它们。
我们建立一个quartus II工程,将vga_ctrl、vga_pic、PLL_25M、tb_vga_ctrl、vga_test加入工程,并将vga_test设置为顶层模块。
接下来,我们进行编译,不断Debug,知道没有错误出现。这时我们打开RTL_View可以看到整体的一个电路图:
之后我们开始仿真:
值得注意的是,由于我们使用了Alter的IP核,因此我们的仿真最好是用Quartus联合Modelsim仿真,方法也很简单
首先进入Settings,找到仿真的EDA选项
仿真工具选择我们电脑上的Modelsim,并且新建一个TestBench并绑定上我们的tb_vga_test。
开始仿真即可。有的同学可能会遇到modelsim中仿真启动失败的情况,这个一般是由于库文件没有起作用导致,可以在仿真中添加库文件然后再仿真一次即可解决。
如果是有库的,那么直接在选项一里点开始仿真即可。
波形分析
分析后可以发现各个信号跳变符合预期,至此我们的工作基本完成,下一步的任务就是进行上板测试了!