加入星计划,您可以享受以下权益:

  • 创作内容快速变现
  • 行业影响力扩散
  • 作品版权保护
  • 300W+ 专业用户
  • 1.5W+ 优质创作者
  • 5000+ 长期合作伙伴
立即加入
  • 正文
  • 推荐器件
  • 相关推荐
  • 电子产业图谱
申请入驻 产业图谱

FPGA入门基础之Testbench仿真文件编写示例

04/29 11:50
702
阅读需 19 分钟
加入交流群
扫码加入
获取工程师必备礼包
参与热点资讯讨论

引言:在编写完HDL代码后,往往需要通过仿真软件Modelsim或者Vivadao自带的仿真功能对HDL代码功能进行验证,此时我们需要编写Testbench文件对HDL功能进行测试验证。本文我们介绍写Testbench编写的一些要点。

1.Testbench文件结构模板

编写Testbench的目的是为了测试设计电路的功能、性能与设计的预期是否相符。验证软件功能通过包括以下步骤:

• 产生合适的模拟激励(波形):该激励通常要覆盖被测HDL模块(黑盒或者称作DUT模块)所有可能得输入状态;
• 将产生的激励加入到被测试模块中并观察其响应:即将DUT模块例化到Testbench文件中,运行仿真软测测试;
• 将输出响应与期望值相比较:该步骤是验证DUT功能较耗时的部分,需要仔细分析代码功能是否达到预期设计,所有代码段功能是否正常。

Testbench结构一般模板如下:

module Test_bench_name();//通常无输入无输出//01:信号或变量声明定义//--逻辑设计中输入对应 reg 型//--逻辑设计中输出对应 wire 型//02:使用 initial 或 always 语句产生激励//03:例化待测试DUT模块//04:监控和比较输出响应endmodule

2.时钟激励输入示例

常见的时钟有:50%占空比连续时钟、固定周期数时钟、非50%占空比时钟,示例如下。

/*----------------------------------------------------------------时钟激励产生方法一:50%占空比时钟----------------------------------------------------------------*/parameter ClockPeriod=10; //参数化时钟周期initial  begin    clk_i=0;    forever#(ClockPeriod/2) clk_i = ~clk_i; end
/*---------------------------------------------------------------- 时钟激励产生方法二:50%占空比时钟----------------------------------------------------------------*/initialbegin  clk_i=0; endalways #(ClockPeriod/2) clk_i=~clk_i;
/*---------------------------------------------------------------- 时钟激励产生方法三:产生固定数量的时钟脉冲----------------------------------------------------------------*/parameter ClockPeriod=10; //参数化时钟周期initialbegin  clk_i=0;   repeat(6)  #(ClockPeriod/2) clk_i=~clk_i; end
/*---------------------------------------------------------------- 时钟激励产生方法四:产生非占空比为 50%的时钟----------------------------------------------------------------*/parameter ClockPeriod=10; //参数化时钟周期initialbeginclk_i=0;forever  begin    #((ClockPeriod/2)-2) clk_i=0;    #((ClockPeriod/2)+2) clk_i=1;     endend

3.复位激励输入示例

复位输入主要包括异步复位、同步复位,代码示例如下。

/*---------------------------------------------------------------- 复位信号产生方法一:异步复位----------------------------------------------------------------*/initialbegin  rst_n_i=1;  #100; rst_n_i=0;  #100; rst_n_i=1; end/*---------------------------------------------------------------- 复位信号产生方法二:同步复位----------------------------------------------------------------*/initialbegin  rst_n_i=1; clk_i = 0;  @(negedge clk_i)  rst_n_i=0;  #100; //固定时间复位  repeat(10) @(negedge clk_i); //固定周期数复位  @(negedge clk_i)  rst_n_i=1; endalways #5 clk_i=~clk_i;

/*---------------------------------------------------------------- 复位信号产生方法三:复位任务封装----------------------------------------------------------------*/task reset;input [31:0] reset_time; //复位时间可调,输入复位时间  RST_ING=0; //复位方式可调,低电平高电平  begin    rst_n=RST_ING; //复位中    #reset_time; //复位时间    rst_n_i=~RST_ING; //撤销复位,复位结束  endendtask

4.双向口inout示例

/*---------------------------------------------------------------- 双向信号inout 在 testbench 中定义为 wire 型变量----------------------------------------------------------------*/reg  sck;wire sda;   //inout信号sda定义为wire型reg  sda_r; //inout 输出定义为reg型reg  sda_en;assign sda_r = (sda_en) ? mosi : 1'bz;assign sda =sda_r;

5.特殊信号设计

/*---------------------------------------------------------------- 特殊激励信号产生描述一:输入信号任务封装----------------------------------------------------------------*/task i_data;  input [7:0] dut_data;  begin@(posedge data_en); send_data=0;    @(posedge data_en); send_data=dut_data[0];    @(posedge data_en); send_data=dut_data[1];    @(posedge data_en); send_data=dut_data[2];    @(posedge data_en); send_data=dut_data[3];    @(posedge data_en); send_data=dut_data[4];    @(posedge data_en); send_data=dut_data[5];    @(posedge data_en); send_data=dut_data[6];    @(posedge data_en); send_data=dut_data[7];    @(posedge data_en); send_data=1;    #100;   endendtask//调用方法:i_data(8'hXX);
/*---------------------------------------------------------------- 特殊激励信号产生描述二:多输入信号任务封装----------------------------------------------------------------*/task more_input;  input [7:0] a;  input [7:0] b;  input [31:0] times;   output [8:0] c;  begin    repeat(times) //等待 times 个时钟上升沿    @(posedge clk_i) c=a+b; //时钟上升沿 a,b 相加  endendtask//调用方法:more_input(x,y,t,z); //按声明顺序
/*---------------------------------------------------------------- 特殊激励信号产生描述三:输入信号产生,一次 SRAM 写信号产生----------------------------------------------------------------*/initialbegin  cs_n=1; //片选无效  wr_n=1; //写使能无效  rd_n=1; //读使能无效  addr=8'hxx; //地址无效  data=8'hzz; //数据无效  #100; cs_n=0; //片选有效  wr_n=0; //写使能有效  addr=8'hF1; //写入地址  data=8'h2C; //写入数据  #100; cs_n=1; wr_n=1;  #10; addr=8'hxx;  data=8'hzz; end
/*----------------------------------------------------------------特殊激励信号产生描述四:@与 wait----------------------------------------------------------------*///@使用沿触发//wait 语句都是使用电平触发initialbegin  start=1'b1;   wait(en=1'b1);  #10; start=1'b0; end

6.仿真控制语句及系统任务描述

/*---------------------------------------------------------------- 仿真控制语句及系统任务描述----------------------------------------------------------------*/$stop  // 停止运行仿真,modelsim 中可继续仿真$stop(n) //带参数系统任务,根据参数 0,1或2不同,输出仿真信息$finish //结束运行仿真,不可继续仿真$finish(n) //带参数系统任务,根据参数 0,1或2不同,输出仿真信息//0:不输出任何信息//1:输出当前仿真时刻和位置//2:输出当前仿真时刻、位置和仿真过程中用到的 memory 以及 CPU 时间的统计$random //产生随机数$random % n //产生范围-n 到 n 之间的随机数{$random} % n //产生范围 0 到 n 之间的随机数/*----------------------------------------------------------------

7. 仿真终端显示描述

/*---------------------------------------------------------------- 仿真终端显示描述----------------------------------------------------------------*/$monitor //仿真打印输出, 打印出仿真过程中的变量,使其终端显示/*$monitor($time,,,"clk=%d reset=%d out=%d",clk,reset,out);*/ $display //终端打印字符串,显示仿真结果等/*$display(” Simulation start ! ");$display(” At time %t,input is %b%b%b,output is %b",$time,a,b,en,z); */$time //返回 64 位整型时间$stime //返回 32 位整型时间$realtime //实行实型模拟时间

8. 文本输入方式

/*---------------------------------------------------------------- 文本输入方式:$readmemb/$readmemh----------------------------------------------------------------*///verilog 提供了读入文本的系统函数$readmemb/$readmemh("<数据文件名>",<存储器名>);$readmemb/$readmemh("<数据文件名>",<存储器名>,<起始地址>);$readmemb/$readmemh("<数据文件名>",<存储器名>,<起始地址>,<结束地址>);$readmemb:/*读取二进制数据,读取文件内容只能包含:空白位置,注释行,二进制数数据中不能包含位宽说明和格式说明,每个数字必须是二进制数字。*/$readmemh:/*读取十六进制数据,读取文件内容只能包含:空白位置,注释行,十六进制数数据中不能包含位宽说明和格式说明,每个数字必须是十六进制数字。*/

 

推荐器件

更多器件
器件型号 数量 器件厂商 器件描述 数据手册 ECAD模型 风险等级 参考价格 更多信息
A3P250-FGG144 1 Microsemi Corporation Field Programmable Gate Array, 6144 CLBs, 250000 Gates, 350MHz, CMOS, PBGA144, 13X 13 MM, 1.45 MM HEIGHT, 1 MM PITCH, GREEN, FBGA-144

ECAD模型

下载ECAD模型
$21.87 查看
XC7A15T-2CPG236I 1 AMD Xilinx Field Programmable Gate Array, 1300 CLBs, PBGA236, BGA-236

ECAD模型

下载ECAD模型
$47.36 查看
EP2C8F256C8N 1 Altera Corporation Field Programmable Gate Array, 516 CLBs, 402.5MHz, 8256-Cell, CMOS, PBGA256, LEAD FREE, FBGA-256
暂无数据 查看

相关推荐

电子产业图谱

专注FPGA技术开发,涉及Intel FPGA、Xilinx FPGA技术开发,开发环境使用,代码风格、时序收敛、器件架构以及软硬件项目实战开发,个人公众号:FPGA技术实战。