系列文章目录
一、FPGA学习笔记(一)入门背景、软件及时钟约束
二、FPGA学习笔记(二)Verilog语法初步学习(语法篇1)
三、FPGA学习笔记(三) 流水灯入门FPGA设计流程
四、FPGA学习笔记(四)通过数码管学习顶层模块和例化的编写
五、FPGA学习笔记(五)Testbench(测试平台)文件编写进行Modelsim仿真
六、FPGA学习笔记(六)Modelsim单独仿真和Quartus联合仿真
七、FPGA学习笔记(七)verilog的深入学习之任务与函数(语法篇3)
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 begin
sys_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;
end
always # (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
变量声明
声明信号或变量的关键字为reg和wire,在initial语句或者always语句(过程赋值语句)中使用的变量定义成reg类型,在assign(连续赋值语句)语句或者用于连接被例化模块名的信号定义成wire类型。
关于为什么会出现reg和wire的区别:
链接: Verilog 中定义信号为什么要区分 wire 和 reg 两种类型?
经典解释:wire表示直通,即输入有变化,输出马上无条件地反映(如与、非门的简单连接)。reg表示一定要有触发,输出才会反映输入的状态。reg相当于存储单元,wire相当于物理连线。
寄存器型数据保持最后一次的赋值,而线型数据需要持续的驱动。wire使用在连续赋值语句中,而reg使用在过程赋值语句(initial ,always)中。wire若无驱动器连接,其值为z,reg默认初始值为不定值 x 。
时间单位/精度
timescale
定义时间单位: `timescale 1ns/1ns 表示时间单位为1ns,时间精度为1ns。
通常由值 1、10、和 100 以及单位 s、ms、us、ns、ps 和 fs 组成。
定义的是仿真过程所有与时间相关量的单位(即1单位的时间)。
例如常用的延时函数:#50,代表着延时50个单位时间。
define
`define clock_period 20
always #(`clock_period/2) clock = ~clock;
可以自己宏定义,后面调用的时候在名字前面加 `。
测试模块
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
作用:返回所在模块的仿真时间,可以查看信号的出现的时间,用来把握信号的时序。
如:
d
i
s
p
l
a
y
(
′
′
t
h
e
t
i
m
e
i
s
display(''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
作用:关闭当前的内容文章来源:https://www.toymoban.com/news/detail-469884.html
文章来源地址https://www.toymoban.com/news/detail-469884.html
到了这里,关于FPGA学习笔记(五)Testbench(测试平台)文件编写进行Modelsim仿真的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!