FPGA学习笔记:面向验证和仿真的行为描述语句(3)

来源:互联网 发布:表白楼宇生成器软件 编辑:程序博客网 时间:2024/06/07 02:08

仿真激励的产生
1、变量初始化
基本原则:可综合代码中完成内部变量的初始化,Testbench中完成可综合代码所需要的各类接口信号的初始化。初始化的方法有两种:
(1)initial初始化:
initial语句只执行一次,即在设计被开始模拟执行时开始,专门用于对输入信号进行初始化和产生特定的信号波形。一个Testbench可以包含多个initial语块,且同时执行,initial语块中的所有变量必须是reg型。
(2)定义变量时初始化:
直接用“=”在变量右端赋初值。例如:

 reg [7:0] cnt=8'00000000;//将8比特的寄存器变量cnt初始化为全0比特   

或者:

reg [3:0] temp=0;

2、时钟信号的产生
(1)普通时钟信号
指的是占空比为50%的时钟信号,可通过initial或者always语句产生,其方法如下:
基于initial语句:

parameter clk_period=10;reg clk;initial   begin      clk=0;      forever #(clk_preiod/2) clk=~clk;   end

基于always语句:

parameter clk_period=10;reg clk;initial   clk=0;   always #(clk_period/2) clk=~clk;

注:initial语句用于带clk初始化。
(2)自定义占空比的时钟信号
可通过Always模块快速实现,例如:

parameter High_time=5,Low_time=20;reg clk;always   begin      clk=1;      #High_time;      clk=0;      #Low_time;   end

由于对clk直接赋值,所以不需要用initial语句初始化clk信号。
(3)相位偏移的时钟信号
相位偏移是两个时钟信号之间的相对概念。其代码为:

parameter High_time=5,Low_time=5,pshift_time=2;reg clk_a;wire clk_b;always   begin      clk_a=1;      #High_time;      clk_b=0;      #Low_time;   endassign #pshife_time clk_b=clk_a;

(4)固定数目的时钟信号
repeat语句来产生固定数目的时钟脉冲,其代码如下:

parameter clk_cnt=5,clk_period=2;reg clk;initial   begin      clk=1;      repeat (clk_cnt) #clk_period/2 clk=~clk;   end

3、复位信号的产生
复位信号不是周期信号,通常通过initial语句产生的值序列来描述。
(1)异步复位信号

paramter rst_repiod=100;reg rst_n;initial   begin      rst_n=0;      #rst_period;      rst_n=1;   end

上述代码将产生低有效的复位信号rst_n,其复位时间为100个仿真代码。
(2)同步复位信号

parameter rst_repiod=100;reg rst_n;initial   begin      rst_n=1;      @(posedge clk);      rst_n=0;      #rst_repiod;      @(posedge clk)      rst_n=1;   end

上述代码首先将复位信号rst_n初始化为1,然后等待时钟信号clk的上升沿,将复位信号拉低,进入有效复位状态,然后进过100个仿真周期,等待下一个时钟信号上升沿的到来,将复位信号置1。
当需要复位时间为时钟周期的整数倍时,可以将rst_repiod修改为时钟周期的整数倍俩实现,也可以通过下面代码:

parameter rst_num=100;initial   begin      rst_n;      @(posedge clk);      rst_n=0;      repeat(rst_num) @(posedge clk);      rst_n=1;   end

上述代码在clk的第一个上升沿开始复位,然后经过5个时钟上升沿后,在第五个时钟上升沿撤销复位信号,进入有效工作状态。
4、数据信号的产生
数据信号的产生主要有两种形式:一种是初始化和产生都在单个initial中完成;另一种是初始化在initial中完成,而产生却在always语句块中完成。前者适合不规则数据数列,并且长度较短;后者适合具有一定规律的数据数列,长度不限。
例一:产生位宽为4的质数序列{1,2,3,5,7,11,13},并且重复两次,其中样值采样间隔为4个仿真时间单位:

'timescale 1ns/ 1psmodule tb_shuju1;reg [3:0] q_out;parameter sample_period=4;parameter queue_num=2;initial   begin      q_out=0;      repeat(queue_num)         begin            # sample_period q_out=1;            # sample_period q_out=2;            # sample_period q_out=3;            # sample_period q_out=5;            # sample_period q_out=7;            # sample_period q_out=11;            # sample_period q_out=13;         end   endendmodule

例二:产生位宽为4的偶数序列,并重复多次。由于该序列规律明显,利用always语句最为方便:

module tb_shuju2;reg [3:0] q_out;parameter sample_period=4;initial   q_out=0;   always #sample_period q_out=q_out+2;endmodule

6、测试向量的产生
如果有方法产生期望的结果,可以用Verilog或其他工具自动地比较期望值和实际值。如果没有简易的方法产生期望的结果,那么测试向量时可以简化仿真结果的。例如16位复数乘法器的代码仿真验证。

阅读全文
0 0
原创粉丝点击