新建工程
打开Vivado软件,直接在欢迎界面点击Create New Project,或在开始菜单中选择File - New Project即可新建工程。
点击Next;
输入工程名称和路径。
选择RTL Project,勾选Do not specify sources at this time(这样可以跳过添加源文件的步骤,源文件可以后面再添加)。
直接选择Boards,然后选择Zedboard Zynq Evaluation and Development Kit 硬件开发包。
点击Next,再点击Finish,项目新建完成
添加Verilog设计文件(Design Source)
在Project Manager窗口中,右击选择Design Sources,在空白处或任意文件夹上右击,选择Add Sources。
选择Add or Create Design Sources,点击Next。
点击Create File按钮,弹出的小窗口中输入文件名,点击OK。
可以一次性新建或添加多个文件,最后点击Finish。
稍后会弹出定义模块的窗口,也就是刚刚添加的test文件。可以在这里设置test模块的输入输出端口;或者直接点击OK,稍后再自行编写。
点击OK后,如果弹出下面窗口直接点击Yes。
test文件和对应的模块即创建完成,如下图。
添加Verilog仿真文件(Simulation Source)
操作和上一步添加Verilog设计文件基本一致,唯一的区别是选择Add or Create Simulation Sources。新建一个名为simu的仿真文件。
设计文件新建完成后,在Design Sources和Simulation Sources中都有,而仿真文件只会出现在Simulation Sources文件夹中。设计文件可以用于仿真,也可以用于最终烧写进开发板,而仿真文件仅用于仿真。
编写代码
打开设计test模块,编写代码实现一个如下。
1 module Test(a,b,c,d,e);// 模块接口 2 input [5:0] a; // 输入信号a 3 input [5:0] b; // 输入信号b 4 input [5:0] c; // 输入信号c 5 input [5:0] d; // 输入信号d 6 output[7:0] e; // 求和输出信号 7 wire [6:0]outa1,outa2; // 定义输出网线型 8 assign e = outa2+outa1; // 把两部分输出结果合并 9 /* 10 通常,我们模块的调用写法如下: 11 被调用的模块名字- 自定义的名字- 括号内信号 12 这里比如括号内的信号,.ina(ina1) 13 这种写法最常用,信号的顺序可以调换 14 */ 15 adder myadder1 (.ina(a),.inb(b),.outa(outa1)); 16 // 调用adder 模块,自定义名字为myadder1 17 adder myadder2 (.ina(c),.inb(d),.outa(outa2)); 18 // 调用adder 模块,自定义名字为myadder2 19 endmodule 20 //adder 子模块 21 module adder(ina,inb,outa );// 模块接口 22 input [5:0] ina; // ina-输入信号 23 input [5:0] inb; // inb-输入信号 24 output [6:0] outa; // outa-输入信号 25 assign outa = ina + inb; // 求和 26 // 模块结束 27 endmodule
行为仿真(Behavioral Simulation)与Testbench
为了验证代码是否正确,可以对代码进行行为仿真。行为仿真时,输入信号可以使用Testbench编写。
如果直接修改test模块,在其中添加Testbench代码,再进行仿真,是一种不太正确的做法。因为test模块是设计文件,后面可能会直接烧写进板子。进行仿真时添加了Testbench代码,之后再烧写进板子又得删掉Testbench代码,这样容易出现错误,而且操作起来也比较麻烦。尤其是接口数量多,内部比较复杂的模块。
所以我们将Testbench代码全部写到仿真文件simu中,并在simu文件中调用test模块,从而进行仿真。
编写仿真代码
在simu模块中编写代码如下:
1 module simu(); 2 reg [5:0] a; 3 reg [5:0] b; 4 reg [5:0] c; 5 reg [5:0] d; 6 wire[7:0] e; 7 reg [5:0] i; //中间变量 8 // 调用被仿真模块模块 9 Test myTest (.a(a), .b(b),.c(c),.d(d),.e(e)); 10 initial begin // initial是仿真用的初始化关键词 11 a=0;b=0;c=0;d=0; // 必须初始化输入信号 12 for(i=1;i<31;i=i+1) begin 13 #10 ; 14 a = i; 15 b = i; 16 c = i; 17 d = i; 18 end // 给是输入信号a 赋值 19 end 20 initial begin 21 $monitor($time,,,"%d + %d + %d + %d ={%d}",a,b,c,d,e); // 信号打印输出 22 #500 $finish; 23 end 24 endmodule
代码说明:
Test myTest (.a(a), .b(b),.c(c),.d(d),.e(e))调用了前面写好的Test模块,其中myTest是模块名称, Test为类名,而myTest为对象名称。同样,Verilog中调用模块时,可以实例化多个Test对象。
行为仿真
右击simu模块,选择Set as Top,将simu模块设置为仿真时的顶层模块。顶层模块类似于C编程时的入口函数,即main函数。main`函数可以调用其他子函数;类似的,顶层模块可以调用其他模块。(或保持默认设置,即如果没有将仿真模块设置为顶层文件时,执行此操作)。
在Flow Navigator窗口中点击Run Simulation - Run Behavioral Simulation;或者在菜单中选择Flow - Run Simulation - Run Behavioral Simulation,即可启动行为仿真。
稍后Behavioral Simulation窗口打开,即可看到输出的仿真波形。
操作技巧
双击图中右侧的Untitled 2标签,可以最大化仿真波形窗口。在波形窗口按住Ctrl键并滚动鼠标滚轮,可以横向缩放波形;按住Shift并滚动鼠标滚轮,可以横向平移波形。
在Behavioral Simulation窗口中的Scopes子窗口,根据模块调用关系选中myTest,在右侧的Objects窗口即可看到test模块中所有的信号。右击信号,选择Add To Wave Window,可将波形添加到右侧的仿真波形窗口,保存仿真文件,再次仿真时就可以看到该信号的波形。
对于一些输出数字信号波形的情况,例如让reg [7:0] sine_out输出正弦波,仿真后右击信号,选择Waveform Style - Analog,即可以波形的形式查看信号。如图显示的就是正弦波信号(注意这里信号本身还是数字信号,并不是模拟信号,只是用软件显示出了其幅值随时间变化的波形)。
对于多位信号例如wire [7:0] p,默认使用二进制形式显示,可以根据需要修改。例如右击选择Radix - Unsigned Decimal即可设置为无符号十进制显示,如图。