当前位置:   article > 正文

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

testbench 中多个initial

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

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

或者:

reg [3:0] temp=0;
  • 1

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

parameter clk_period=10;
reg clk;
initial
   begin
      clk=0;
      forever #(clk_preiod/2) clk=~clk;
   end
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7

基于always语句:

parameter clk_period=10;
reg clk;
initial
   clk=0;
   always #(clk_period/2) clk=~clk;
  • 1
  • 2
  • 3
  • 4
  • 5

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

parameter High_time=5,Low_time=20;
reg clk;
always
   begin
      clk=1;
      #High_time;
      clk=0;
      #Low_time;
   end
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9

由于对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;
   end
assign #pshife_time clk_b=clk_a;
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11

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

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

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

paramter rst_repiod=100;
reg rst_n;
initial
   begin
      rst_n=0;
      #rst_period;
      rst_n=1;
   end
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8

上述代码将产生低有效的复位信号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
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11

上述代码首先将复位信号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
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9

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

'timescale 1ns/ 1ps
module 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
   end
endmodule
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20

例二:产生位宽为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
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7

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

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/很楠不爱3/article/detail/661362
推荐阅读
相关标签
  

闽ICP备14008679号