这里写目录标题
- Testbench文件
- 时间单位/精度
- 测试模块
- 输入信号初始化
- always 语句实现信号变化
- 实例化
- 系统函数
Testbench文件
编写Testbench的目的是在Modsim中进行仿真验证,查看仿真波形和打印信息验证代码逻辑。
例如下面代码:
`timescale 1ns/1ns
module tb_led_dynamic();//parameter define
parameter T =20 ;//reg define
reg sys_clk;
reg sys_rst_n;//wire define
wire [7:0]seg_led;
wire [5:0]sel;
reg key;
wire led;
//*****************************************************
//** main code
//*****************************************************initial beginsys_clk <=1'b0;sys_rst_n <=1'b0;key <=1'b1;#50 sys_rst_n <=1'b1; #1200_000_000 key <=1'b0;#50_000_000 key <=1'b1; #950_000_000 key <=1'b0;#50_000_000 key <=1'b1;
endalways # (T/2) sys_clk <= ~sys_clk;top_seg_led u0(.sys_clk (sys_clk),.sys_rst_n (sys_rst_n),.seg_sel (sel),.seg_led (seg_led),.key (key),.led (led) );endmodule
时间单位/精度
定义时间单位: `timescale 1ns/1ns 表示时间单位为1ns,时间精度为1ns。
通常由值 1、10、和 100 以及单位 s、ms、us、ns、ps 和 fs 组成。
定义的是仿真过程所有与时间相关量的单位(即1单位的时间)。
例如常用的延时函数:#50,代表着延时50个单位时间。
测试模块
module tb_led_dynamic();
......
.....
...
endmodule
这里是定义了测试模块的名字为tb_led_dynamic,编写的.v文件中的模块叫功能模块,那里也有名字的定义。
在测试模块中,输入信号一般定义为 reg 型信号,因为后面需要在always/initial语句块中被赋值,输出信号一般为 wire型即可。
输入信号初始化
用initial 语句进行初始化,该语句中的代码块只执行一次
always 语句实现信号变化
这里的意思是每隔10个时间单位,sys_clk时钟信号反转一次。实现了50Mhz的时钟。
还有例如:
always #10 in <= {$random} % 8
表示每隔10个时间单位in的电平变化一次
{$random}%8 表示随机选取[0,7]之间的数。
in <= {$random} % 8; 在赋值时会自动进行数据类型转换
实例化
如何把自定义的信号以及模拟的信号和实际功能模块挂钩呢,所以采用的是实例化,即把模拟的输入信号传入到功能模块中。
系统函数
例如:
$timeformat(-9, 0, "ns", 6);$monitor("time:%t in:%b out:%b",$time,in,out);
$timeformat 设置显示时间的格式
常见的有:
(1)$time
作用:返回所在模块的仿真时间,可以查看信号的出现的时间,用来把握信号的时序。
如:display(′′thetimeisdisplay(''the time is %t'',display(′′thetimeistime) ;//显示当时的时间
(2)$display
作用: 将需要显示的内容在命令栏显示出来
如: $display(“the signal is %d”,ad); //将ad信号以十进制的方式显示出来
(3)$monitor
作用:监视变量的变化,一旦变量变化,则将变量显示出
如:$ monitor (“at time is %t and the signal is %b\n”,$time , signal) ;
(3) 文件操作类
$fopen
作用:打开一个文件面,对文件的操作
$fdisplay
作用:在打开的文件里,写入显示的内容
$fmonitor
作用:在打开的文件里,写入监视的变量变化时的内容
$fclose
作用:关闭当前的内容