Testbench(激励)文件的编写:

论坛 期权论坛 脚本     
匿名技术用户   2020-12-29 02:37   1342   0

编写testbench文件的主要目的是为了对使用硬件描述语言( Verilog HDL或者VHDL)设计的电路进行仿真验证,测试设计电路的功能、部分性能是否与预期的目标相符。

本文使用的为简单的 Led流水灯的例子:

led_demo.v

//模块
module led_demo(
 input sys_clk , //系统时钟
 input sys_rst_n, //系统复位,低电平有效
 output reg [3:0] led //LED灯
 );

//reg define
reg [23:0] counter; //变量

//*****************************************************
//** main code
//*****************************************************

//计数器对系统时钟计数
//时钟的上升沿 或者 复位的下降沿
always @(posedge sys_clk or negedge sys_rst_n) begin
 if (!sys_rst_n)
  counter <= 24'd0;
 else if (counter < 24'd10_000_000)//计数到10_000_000,E1输入50MHz的时钟, 此处为200ms
  counter <= counter + 1'b1;
 else
  counter <= 24'd0;
end

//通过移位寄存器控制IO口的高低电平,从而改变LED的显示状态
always @(posedge sys_clk or negedge sys_rst_n) begin
 if (!sys_rst_n)
  led <= 4'b0001; //led初值为1
 else if(counter == 24'd10_000_000)
  led[3:0] <= {led[2:0],led[3]};//拼接 相当于左移一位
 else
  led <= led; //保持
end


endmodule

开发软件为Quartus II 13,平台芯片为Cyclone IV EP4CE10F;

参考正点原子的FPGA教程做学习笔记。

一. 声明仿真的单位和精度
`timescale 仿真单位/仿真精度
例如: `timescale 1ns/1ns

二. 定义模块名(开头结尾)

module led_demo_tb()

...

endmodule

三. 信号或变量定义

reg sys_clk;
reg sys_rst_n;

// wires                                               
wire [3:0]  led;

四. 使用always产生激励波形 CLK

always #10  sys_clk = ~sys_clk;

五. 初始化赋值

initial                                                
begin                                                  
// code that executes only once                        
// insert code here --> begin                          
  sys_clk = 1'b0;
  sys_rst_n = 1'b0; // 复位
  #100 sys_rst_n = 1'b1; // 在第100ns的时候复位信号拉高                                                 
// --> end                                             
  $display("Running testbench");                       
end 

六. 例化设计模块

例化被测模块的目的是把被测模块和激励模块实例化起来,并且把被测模块的端口与激励模块的端口进行相应的连接,使得激励可以输入到被测模块。如果被测模块是由多个模块组成的,激励模块中只需要例化多个模块的顶层模块。

// assign statements (if any)                          
led_demo  u0_led_demo(
// port map - connection between master ports and signals/registers   
 .led(led),
 .sys_clk(sys_clk),
 .sys_rst_n(sys_rst_n)
);

左侧带“ .” 的信号为flow_led模块定义的端口信号,右侧括号内的信号为激励模块中定义的信号,其信号名可以和被测模块中的信号名一致,也可以不一致,命名一致的好处是便于理解激励模块和被测模块信号之间的对应关系。在实例化被测模块后,以endmodule结束。

完整代码如下:

led_demo_tb.vt

`timescale 1 ns/ 1 ns
module  led_demo_tb();
// constants                                           
// general purpose registers
// test vector input registers
reg sys_clk;
reg sys_rst_n;

// wires                                               
wire [3:0]  led;

always #10  sys_clk = ~sys_clk;

initial                                                
begin                                                  
// code that executes only once                        
// insert code here --> begin                          
  sys_clk = 1'b0;
  sys_rst_n = 1'b0; // 复位
  #100 sys_rst_n = 1'b1; // 在第100ns的时候复位信号拉高                                                    
// --> end                                             
  $display("Running testbench");                       
end 


// assign statements (if any)                          
led_demo  u0_led_demo(
// port map - connection between master ports and signals/registers   
 .led(led),
 .sys_clk(sys_clk),
 .sys_rst_n(sys_rst_n)
);

                                         
endmodule

编写好就开始仿真

选择文件

运行RTL仿真(功能仿真)
【 Tools】→【 Run Simulation Tool】→【 RTL Simulation】按钮
可以看到sys_clk每10us跳变一次,这样相当于50MHz时钟

复位信号sys_rst_n在100ns的时候变高了

这里由于我Led流水之间的间隔时间长200ms,就先不看了。

想看的话需要把流水速度加快看

分享到 :
0 人收藏
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

积分:7942463
帖子:1588486
精华:0
期权论坛 期权论坛
发布
内容

下载期权论坛手机APP