仿真验证与Testbench编写
TestBench
模拟界面控制
库文 件
逻辑模拟结果一致性的确定
在TestBench中加入预期结果比较
利用波形比较工具检测逻辑模拟波形的 一致性
$display $time $fopen $finish
$fdisplay $write $fclose $stop
$monitor $strobe $dump
利用虚拟原型、估计综合及后设计的结果;
HDL代码调试
逻辑模拟验证
在TestBench中加入$strobe系统任务,记 录、探测所关心的信号波形; 在逻辑模拟验证前,利用模拟器提供的 功能,选择需要观察的信号并加以记录; 在TestBench中增加模拟结果与预期的正 确结果的比较,检测不正确的HDL代码
Verilog HDL提供的支持
Verilog HDL提供了几个系统任务支持从 文件中直接读取输入激励码向量 $readmemb(“File_Name”, Test_Vector); 从文件中读取二进制输入激励码向量
$readmemh(“File_Name”, Test_Vector); 从文件中读取二进制输入激励码向量
Reg Reg …… [7:0] A, B; Start;
二进制表示的 输入激励码及 其输出预期结 果表示
Reg [33:0]
…….
……
Vector, Test_Vector[0:Test_Length];
$readmemb(“Test_Fixed.v”, Test_Vector); For (I=0; I<Test_Length; I = I+1) 按一定时序将Test_Vector[I]送入Vector并送入A、B、 Start;
编写高效率的testbench
编写高效率的testbench简介:由于设计的规模越来越大也越来越复杂,数字设计的验证已经成为一个日益困难和繁琐的任务。
验证工程师们依靠一些验证工具和方法来应付这个挑战。
对于几百万门的大型设计,工程师们一般使用一套形式验证(formal verification)工具。
然而对于一些小型的设计,设计工程师常常发现用带有testbench的HDL仿真器就可以很好地进行验证。
Testbench已经成为一个验证高级语言(HLL --High-Level Language) 设计的标准方法。
通常testbench完成如下的任务:1.实例化需要测试的设计(DUT);2.通过对DUT模型加载测试向量来仿真设计;3.将输出结果到终端或波形窗口中加以视觉检视;4.另外,将实际结果和预期结果进行比较。
通常testbench用工业标准的VHDL或Verilog硬件描述语言来编写。
Testbench调用功能设计,然后进行仿真。
复杂的testbench完成一些附加的功能—例如它们包含一些逻辑来选择产生合适的设计激励或比较实际结果和预期结果。
后续的章节描述了一个仔细构建的testbench的结构,并且提供了一个自动比较实际结果与预期结果的进行自我检查的testbench例子。
图1给出了一个如上所描述步骤的标准HDL验证流程。
由于testbench使用VHDL或Verilog来描述,testbench的验证过程可以根据不同的平台或不同的软件工具实现。
由于VHDL或Verilog是公开的通用标准,使用VHDL或Verilog编写的testbench以后也可以毫无困难地重用(reuse)。
图1使用Testbench的HDL验证流程构建TestbenchTestbench用VHDL或Verilog来编写。
由于testbench只用来进行仿真,它们没有那些适用于综合的RTL语言子集的语法约束限制,而是所有的行为结构都可以使用。
因而testbench可以编写的更为通用,使得它们可以更容易维护。
VHDL——如何写简单的testbench
use ieee.std_logic_1164.all;use ieee.std_logic_arith.all;--use ieee.std_logic_unsigned.all;entity cnt6 isport(clr,en,clk :in std_logic;q :out std_logic_vector(2 downto 0) );end entity;architecture rtl of cnt6 issignal tmp :std_logic_vector(2 downto 0); beginprocess(clk)-- variable q6:integer;beginif(clk'event and clk='1') thenif(clr='0')thentmp<="000";elsif(en='1') thenif(tmp="101")thentmp<="000";elsetmp<=unsigned(tmp)+'1';end if;end if;end if;q<=tmp;-- qa<=q(0);-- qb<=q(1);-- qc<=q(2);end process;end rtl;二、六进制计数器testbench的代码signal en :std_logic:='0';signal clk :std_logic:='0';signal q :std_logic_vector(2 downto 0);constant clk_period :time :=20 ns;begininstant:cnt6 port map(clk=>clk,en=>en,clr=>clr,q=>q);clk_gen:processbeginwait for clk_period/2;clk<='1';wait for clk_period/2;clk<='0';end process;clr_gen:processbeginclr<='0';wait for 30 ns;clr<='1';wait;end process;en_gen:processbeginen<='0';wait for 50ns;en<='1';wait;end process;end rtl;--测试平台文件(testbench)的基本结构library ieee;use ieee.std_logic_1164.all;entity test_bench is --测试平台文件的空实体(不需要端口定义) end test_bench;architecture tb_behavior of test_bench iscomponent entity_under_test --被测试元件的声明port(list-of-ports-theri-types-and-modes);end component;begininstantiation:entity_under_test port map(port-associations);process() --产生时钟信号……end process;process() --产生激励源……end process;end tb_behavior;------------------------------------------------------------------- --简单计数程序源码library ieee;use ieee.std_logic_1164.all;use ieee.std_logic_unsigned.all;use ieee.std_logic_unsigned.all;entity sim_counter isport(clk :in std_logic;reset :in std_logic;count :out std_logic_vector(3 downto 0));end entity;architecture behavioral of sim_counter issignal temp :std_logic_vector(3 downto 0);beginprocess(clk,reset)beginif reset='1' thentemp<="0000";elsif clk'event and clk='1' thentemp<=temp+1;end if;end process;count<=temp;end behavioral;------------------------------------------------------------------- --简单计数程序,测试文件代码(testbench)library ieee;use ieee.std_logic_1164.all;use ieee.std_logic_unsigned.all;use ieee.numeric_std.all;entity counter_tb_vhd is --测试平台实体end counter_tb_vhd;architecture behavior of counter_tb_vhd is--被测试元件(DUT)的声明component sim_counterport(clk :in std_logic;reset :in std_logic;count :out std_logic_vector(3 downto 0));end component;--输入信号signal clk:std_logic:='0';signal reset :std_logic:='0';--输出信号signal count :std_logic_vector(3 downto 0);constant clk_period :time :=20 ns; --时钟周期的定义begindut:sim_counter port map(clk=>clk,reset=>reset,counter=>counter);clk_gen:processbeginclk='1';wait for clk_period/2;clk='0';wait for clk_period/2;end process;tb:process --激励信号beginwait for 20 ns;reset<='1';wait for 20 ns;reset<='0';wait for 200 ns;wait; --will wait forever;end process;end;--激励信号的产生方式--1.以一定的离散时间间隔产生激励信号的波形--2.基于实体的状态产生激励信号,也就是说基于实体的输出响应产生激励信号--两种常用的复位信号--1.周期性的激励信号,如时钟--2.时序变化的激励型号,如复位--eg.产生不对称时钟信号w_clk<='0' after period/4 when w_clk='1' else'1' after 3*period/4 when w_clk='0' else'0';--eg.产生堆成时钟信号,process语句clk_gen1:processconstan clk_period := 40 ns;beginclk='1';wait for clk_period/2;clk='0';wait for clk_period/2;end process;四、如果自己不想写这些testbench的这些固定格式,可以在quartus 里自动生成testbench文件的模板,然后往里面写信号就行了步骤:processing->start->start test bench template write这里需要注意的是要在仿真选项里选择一个仿真工具,然后才会生成testbench自动生成的testbench模板格式如下:-- Copyright (C) 1991-2008 Altera Corporation-- Your use of Altera Corporation's design tools, logic functions-- and other software and tools, and its AMPP partner logic-- functions, and any output files from any of the foregoing-- (including device programming or simulation files), and any-- associated documentation or information are expressly subject-- to the terms and conditions of the Altera Program License-- Subscription Agreement, Altera MegaCore Function License-- Agreement, or other applicable license agreement, including,-- without limitation, that your use is for the sole purpose of-- programming logic devices manufactured by Altera and sold by-- Altera or its authorized distributors. Please refer to the-- applicable agreement for further details.-- ***************************************************************************-- This file contains a Vhdl test bench template that is freely editable to-- suit user's needs .Comments are provided in each section to help the user -- fill out necessary details.-- ***************************************************************************-- Generated on "03/13/2011 20:05:04"-- Vhdl Test Bench template for design : cnt6---- Simulation tool : ModelSim (VHDL)--LIBRARY ieee;USE ieee.std_logic_1164.all;ENTITY cnt6_vhd_tst ISEND cnt6_vhd_tst;ARCHITECTURE cnt6_arch OF cnt6_vhd_tst IS-- constants-- signalsSIGNAL clk : STD_LOGIC;SIGNAL clr : STD_LOGIC;SIGNAL en : STD_LOGIC;SIGNAL q : STD_LOGIC_VECTOR(2 DOWNTO 0);COMPONENT cnt6PORT (clk : IN STD_LOGIC;clr : IN STD_LOGIC;en : IN STD_LOGIC;q : OUT STD_LOGIC_VECTOR(2 DOWNTO 0));END COMPONENT;BEGINi1 : cnt6PORT MAP (-- list connections between master ports and signalsclk => clk,clr => clr,en => en,q => q);init : PROCESS-- variable declarationsBEGIN-- code that executes only onceWAIT;END PROCESS init;always : PROCESS-- optional sensitivity list-- ( )-- variable declarationsBEGIN-- code executes for every event on sensitivity list WAIT;END PROCESS always;END cnt6_arch;。
如何编写Testbench
2 如何编写Testbench1)何时使用initial和alwaysinitial和always 是2个基本的过程结构语句,在仿真的一开始即开始相互并行执行。
通常被动的检测响应使用always语句,而主动的产生激励使用initial语句。
initial和always的区别是always 语句不断地重复执行,initial语句则只执行一次。
但是,如果希望在initial里的多次运行一个语句块,怎么办?这时可以在initial里嵌入循环语句(while,repeat,for,forever 等),如:initialbeginforever /* 无条件连续执行*/begin……endend其它循环语句请参考一些教材,这里不作赘述。
另外,如果希望在仿真的某一时刻同时启动多个任务,可以使用fork...。
join语句。
例如,在仿真开始的 100 ns 后,希望同时启动发送和接收任务,而不是发送完毕后再进行接收,如下所示:initialbegin#100 ;fork /*并行执行*/Send_task ;Receive_task ;joinEnd2)如何作多种工作模式的遍历测试如果设计的工作模式很多,免不了做各种模式的遍历测试,而遍历测试是需要非常大的工作量的。
我们经常遇到这样的情况:很多时候,各种模式之间仅仅是部分寄存器配置值的不同,而各模式间的测试都是雷同的。
有什么方法可以减轻这种遍历测试的工作量?不妨试试for循环语句,采用循环变量来传递各种模式的配置值,会帮助减少很多测试代码,而且不会漏掉每一种模式.initialbeginfor ( i = 0 ; i 〈 m ; i = i + 1 ) /*遍历模式1至模式m*/for ( j = 0 ; j < n ; j = j +1 ) /*遍历子模式1至子模式n */begincase ( j ) /* 设置每种模式所需的配置值 */0 : 配置值= a ;1 : 配置值= b ;2 : 配置值= c ;……endcase/*共同的测试向量*/endend3) 如何加速问题定位过程在这部分里,通过一些实际例子,介绍在出现问题时如何借助 testbench 加快问题的定位过程。
Verilog-testbench的写法
数字集成电路设计入门--从HDL到版图于敦山北大微电子学系第十五章Verilog Test Bench使用简介学习内容:•用一个复杂的test bench复习设计的组织与仿真•建立test bench通常使用的编码风格及方法设计组织虚线表示编译时检测输入文件是否存在及可读并允许生成输出文件。
test bench 组织stimulus要验证的设计简单的test bench•简单的test bench 向要验证的设计提供向量,人工验证输出。
•复杂的test bench 是自检测的,其结果自动验证。
复杂的test bench激励验证结果要验证的设计并行块•fork…join块在测试文件中很常用。
他们的并行特性使用户可以说明绝对时间,并且可以并行的执行复杂的过程结构,如循环或任务。
module inline_ tb;reg [7: 0] data_ bus;// instance of DUTinitial forkdata_bus = 8'b00;Time | data_ bus0 | 8’b0000_0000 10 | 8’b0100_0101 30 | 8’b0100_0110 40 | 8’b0100_0111 45 | 8’b1000_1110#10 data_bus = 8'h45;#20 repeat (10) #10 data_bus = data_bus + 1;#25 repeat (5) #20 data_bus = data_bus<< 1;#140 data_bus = 8'h0f;joinendmodule上面的两个repeat循环从不同时间开始,并行执行。
象这样的特殊的激励集在单个的begin…end块中将很难实现。
50 | 8’b1000_1111 60 | 8’b1001_0000 65 | 8’b0010_0000 70 | 8’b0010_0001 80 | 8’b0010_0010 85 | 8’b0100_0100 90 | 8’b0100_0101 100 | 8’b0100_0110 105 | 8’b1000_1100 110 | 8’b1000_1101 120 | 8’b1000_1110 125 | 8’b0001_1100 140 | 8’b0000_1111包含文件•包含文件用于读入代码的重复部分或公共数据。
verilog testbench语法
verilog testbench语法Verilog testbench 是用来对 Verilog 设计进行仿真验证的代码。
它提供了一系列的输入信号和时钟,以及对输出结果的预期值进行比较,以验证设计的正确性。
以下是 Verilog testbench 的基本语法:1. 模块定义:```module testbench_name;// 输入输出信号声明// 实例化需要测试的模块// 给输入信号赋值// 检查输出信号和预期结果是否相符endmodule```2. 时钟定义:```reg clk; // 定义时钟信号always #5 clk = ~clk; // 定义时钟周期```3. 输入信号声明和赋值:```reg input1;wire expected_output;reg [3:0] array_input [7:0];// 给输入信号赋值initial begininput1 = 1'b0;#10;input1 = 1'b1;#10;//...end```4. 实例化需要测试的模块:```// 通过实例化需要测试的模块// 给模块的输入端口连接输入信号// 给模块的输出端口连接输出信号// 在 testbench 中实例化被测试的模块//...```5. 检查输出信号和预期结果:```// 在仿真过程中,通过比较输出信号和预期结果来验证设计的正确性// 根据需要使用相应的比较语句,如 `==`, `!=`, `===`, `!==`, `>`, `<` 等// 在每个时钟周期末检查预期输出结果//...```这些是 Verilog testbench 的基本语法。
在具体的测试中,需要根据设计的功能和需求来给输入信号赋值,并检查输出信号和预期结果是否一致。
1 ModelSim的使用与Testbench的编写
重温了基本的Quartus操作和语法后,需要对手头的工作进行仿真验证,Quartus 9.x自带的Vector Waveform已经淘汰掉了,必须用 ModelSim进行仿真。
现在就开始一步步入手ModelSim,并通过与Quartus无缝衔接实现仿真。
本文使用了ModelSim10.0c + QuartusII 10.0,其他版本基本雷同,请自行研究。
源程序如下:module add(mclk,rst_n,a_in,b_in,c_out);input mclk, rst_n;input[7:0] a_in, b_in;output[8:0] c_out;reg[8:0] c_out;always@(posedge mclk, negedge rst_n)beginif(!rst_n)c_out <= 9'h0;elsec_out <= a_in + b_in;endendmodule请建立工程,将源程序编译通过.1.设置第三方EDA工具在Tools -> Options中设置ModelSim的安装路径,注意要设置到win32文件夹(64位软件对应的就是win64)。
建立一个工程(依然以加法器为例)。
在Assignments -> Settings中设置仿真工具为ModelSim。
这样Quartus就能无缝调用ModelSim了。
当然也可以在建立工程的时候就设置仿真工具。
2.编写Testbench说到Testbench,你可以叫它Testbench,或者Testbenches,但不是Test Bench。
说起来,就连Quartus也没注意这个问题,至于原因嘛参见Common Mistakes In Technical Texts一文。
文章中还列举了些别的错误用语,包括Flip-flop不能写成Flipflop,等等。
文章链接:/papers/Technical_Text_Mistakes.pdf我们可以通过Quartus自动生成一个Testbench的模板,选择Processing -> Start -> Start Test Bench Template Writer,等待完成后,在导航栏中打开刚才生成的Testbench,默认是保存在simulation\modelsim文件夹下的.vt格式文件。
Verilog仿真文件testbench编写样例
Verilog 仿真文件testbench编写样例`timescale 1ns/100psmodule testbench;localparam DATA_WIDTH = 32;localparam CLK_100_PERIOD = 5;localparam CLK_200_PERIOD = 2.5;localparam SIM_TIME = 150000;localparam ;localparam ;reg clk_100, clk_200;wire clk;assign clk = clk_100;alwaysbeginclk_100 = 0;forever #CLK_100_PERIOD clk_100 = ~clk_100;endalwaysbeginclk_200 = 0;forever #CLK_200_PERIOD clk_200 = ~clk_200;endreg rstn;integer fp_testin;integer fp_matlab_out;integer fp_sim_out;integer fp_outdiff;reg signed [DATA_WIDTH/2-1:0] matlab_in_re, matlab_in_im;reg signed [DATA_WIDTH/2-1:0] matlab_out_re, matlab_out_im;reg signed [DATA_WIDTH/2-1:0] matlab_diff_re, matlab_diff_im;reg signed [DATA_WIDTH/2-1:0] matlab_diff_re2, matlab_diff_im2;reg signed [DATA_WIDTH/2-1:0] max_diff_re, max_diff_im;initial beginmax_diff_re = 0;max_diff_im = 0;rstn = 0;#500rstn = 1;#SIM_TIMEsim_finish();$stop();endtask sim_finish;beginif(fp_testin!=0)$fclose(fp_testin);if(fp_matlab_out!=0)$fclose(fp_matlab_out);if(fp_sim_out)$fclose(fp_sim_out);if(fp_outdiff!=0)$fclose(fp_outdiff);endendtaskinitialbeginfp_testin = 0;fp_testin=$fopen("txt_file/input_data.txt"," r");if(fp_testin==0)begin$display("input_data.txt open failed!"); sim_finish();$stop();endelse begin$fscanf(fp_testin,"%d, %d\n",matlab_in_re,matlab_in_im); endfp_matlab_out = 0;fp_matlab_out =$fopen("txt_file/matlab_out.txt"," r");if(fp_matlab_out==0)begin$display("fp_matlab_out.txt openfailed!");sim_finish();$stop();endelse begin$fscanf(fp_matlab_out,"%d, %d\n",matlab _out_re,matlab_out_im);endfp_sim_out = 0;fp_sim_out =$fopen("txt_file/modelsim_out.txt",&quo t;w");if(fp_sim_out == 0)begin$display("modelsim_out_re.txt openfailed!");sim_finish();$stop();endfp_outdiff = 0;fp_outdiff =$fopen("text_file/outdiff.txt","w& quot;);if(fp_outdiff==0)begin$display("outdiff.txt open failed!"); sim_finish();$stop();endendalways @(posedge clk)beginif(stest_wvalid && stest_wready) //ready to changebeginif(~$feof(fp_testin))$fscanf(fp_testin,"%d, %d\n",matlab_in_re,matlab_in_im); endelsebeginmatlab_in_re <= matlab_in_re;matlab_in_im <= matlab_in_im;endendalways @(posedge clk_100)beginif(mfc_wready && mfc_wvalid)beginmatlab_diff_re <= mfc_wdata_re - matlab_out_re; matlab_diff_im <= mfc_wdata_im - matlab_out_im; matlab_diff_re2 <= matlab_out_re - mfc_wdata_re ; matlab_diff_im2 <= matlab_out_im - mfc_wdata_im ; if(max_diff_re < matlab_diff_re)beginmax_diff_re <= matlab_diff_re;$display("max_diff_re:%dmax_diff_im:%d\n",max_diff_re,max_diff_im); endelse if(max_diff_re < matlab_diff_re2)beginmax_diff_re <= matlab_diff_re2;$display("max_diff_re:%dmax_diff_im:%d\n",max_diff_re,max_diff_im); endif(max_diff_im < matlab_diff_im)beginmax_diff_im <= matlab_diff_im;$display("max_diff_re:%dmax_diff_im:%d\n",max_diff_re,max_diff_im); endelse if(max_diff_im < matlab_diff_im2)beginmax_diff_im <= matlab_diff_im2;$display("max_diff_re:%dmax_diff_im:%d\n",max_diff_re,max_diff_im); end$fscanf(fp_matlab_out,"%d, %d\n",matlab _out_re,matlab_out_im);$fwrite(fp_sim_out, "%d, %d\n",mfc_wdata_re,mfc_wdata_im);$fwrite(fp_outdiff,"%d, %d\n",matlab_diff_re,matlab_diff_i m);endendendmodule。
VHDL的testbench的编写
VHDL的testbench的编写大多数硬件设计人员对verilog的testbench比较熟悉,那是因为verilog被设计出来的目的就是为了用于测试使用,也正是因为这样verilog的语法规则才被设计得更像C语言,而verilog发展到后来却因为它更接近C语言的语法规则,设计起来更加方便,不像VHDL那也死板严密,所以verilog 又渐渐受到硬件设计者们的青睐。
但其实VHDL在最开始也是具有测试能力的,而且它的语法严密,但我们同样可以用它来编写我们的测试文件。
下面以一个8bit计数器为例子给出个简单的testbench模板及注释:通过编写testbench来仿真和通过拖波形来仿真,最大的好处就是,当测试数据无比庞大时,可以简易得通过testbench中的算法来实现,而另一个更为重要的方面就是,可以通过testbench对数据文件进行读写操作,从而简化我们的仿真工作。
首先介绍下时间控制语句——wait:(其实wait语句是通过控制仿真的两种状态——执行和挂起,来控制时间的)1.wait——无线等待;语法【wait;】,类似于Verilog中的¥Stop2.wait on——敏感信号量变化;语法【wait on 信号;】,表示当信号发生变化的时候,仿真开始继续执行,从而结束挂起状态3.wait until——条件满足;语法【waituntil 表达式】,表达式为一个布尔表达式,表示当表达式为“真”时,仿真继续执行,结束挂起状态4.wait for——时间控制;语法【waitfor 时间表达式】,例:【wait for 30ns;】VHDL也提供了文件I/O的操作,以下简单介绍在我们大部分情况下如何通过VHDL来进行文件操作。
file类型:文件句柄,用于定义文件。
语法1【file 文件变量名:text is 读取或者写入类型“文件名”;】text——文件类型为文本类型,读取类型为in,写入类型为out;语法2【file 文件变量名:text;】只是定义了文件变量名,并没有给赋予初值。
Testbench写法总结
outer_port_tb_wire,inner_port_tb_wire);
end
else
begin
$display("\n **** time=%t ****",$time);
$display("ERROR! out_en=%d",out_en_tb);
$display("ERROR! outer_port_tb_wire != inner_port_tb_wire" );
$display("ERROR! outer_port_tb_wire=%d, inner_port_tb_wire=%d",
outer_port_tb_wire,inner_port_tb_wire);
end
end
endmodule
验证该双向端口的testbench结构如图2所示。
这是一个self-checking testbench,可以自动检查仿真结果是否正确,并在Modelsim控制台上打印出提示信息。图中Monitor完成信号采样、结果自动比较的功能。
testbench的工作过程为
1)out_en=1时,双向端口处于输出状态,testbench给inner_port_tb_reg信号赋值,然后读取outer_port_tb_wire的值,如果两者一致,双向端口工作正常。
module tb();
reg[7:0] inner_port_tb_reg;
wire[7:0] inner_port_tb_wire;
reg[7:0] outer_port_tb_reg;
wire[7:0] outer_port_tb_wire;
vivado testbench 语法
在 Vivado中,编写 Testbench 是进行数字电路仿真和验证的重要步骤。
以下是 Vivado Testbench 的一些语法要点:1. 语言选择:Vivado支持使用 SystemVerilog 或 Verilog 作为 Testbench 的语言。
你可以根据需要选择其中之一进行编写。
2. 模块实例化:Testbench 通常包含一个顶层模块来实例化待测试的模块。
你需要创建一个模块,并使用待测试模块的端口信号进行实例化。
3. 时钟和复位:在 Testbench 中,你通常需要生成时钟信号和复位信号,并将其应用于待测试模块的输入端口。
你可以使用 `fork...join` 结构和 `repeat` 或 `forever` 循环来生成时钟信号。
4. 输入模拟:在 Testbench 中,你需要为待测试模块的输入端口提供合适的模拟数据。
你可以使用 `#` 操作符来延迟信号的更新,以模拟不同的输入情况。
5. 断言和检查:在 Testbench 中,你可以使用断言语句来验证待测试模块的行为是否符合预期。
Vivado 支持使用 `assert` 和 `assume` 等关键字来定义断言。
6. 输出比较:在仿真结束后,你可以比较待测试模块的输出信号与预期结果进行验证。
你可以使用 `$display` 或 `$monitor` 等系统任务来显示输出信号的值。
7. 仿真控制:你可以使用 `initial` 块或 `always` 块来控制 Testbench 的仿真行为。
你可以使用 `#` 操作符来延迟仿真时间或 `disable` 关键字来停止仿真。
8. 仿真时长:在 Vivado 中,你可以使用 `run` 或 `run XXns` 命令来指定仿真运行的时长。
默认情况下,仿真会一直运行直到遇到 `$finish` 或 `$stop` 系统任务。
以上是 Vivado Testbench 的一些语法要点。
vivadotestbench写法
主题:vivadotestbench编写方法内容:1. 什么是vivadotestbench?vivadotestbench是一个用于编写Verilog的测试台,用于对Verilog 模块进行仿真和验证。
它可以帮助工程师们在Verilog设计的早期阶段进行功能验证和性能评估,以确保设计的稳定性和正确性。
2. vivadotestbench的基本结构vivadotestbench通常包含以下基本结构:模块实例化、时钟和复位初始化、输入数据生成、仿真控制和输出检测。
这些基本结构构成了一个完整的测试台,可以用于对Verilog模块进行全面的验证和测试。
3. vivadotestbench的编写步骤编写vivadotestbench的步骤可以分为以下几个部分:3.1 模块实例化:首先需要实例化待测模块,并且连接时钟、复位信号和输入输出端口。
3.2 时钟和复位初始化:在测试台中需要为待测模块提供时钟信号,并对复位信号进行初始化。
3.3 输入数据生成:根据待测模块的输入端口,生成相应的测试数据,并将其输入到待测模块中。
3.4 仿真控制:控制仿真的开始、暂停和结束,以及执行仿真的时长和步长等。
3.5 输出检测:对待测模块的输出进行检测和比对,以验证其正确性和稳定性。
4. vivadotestbench的常见问题及解决方法在编写vivadotestbench的过程中,可能会遇到一些常见的问题,例如时序约束不准确、测试数据生成不完整、输出检测逻辑错误等。
针对这些问题,可以采取一些解决方法,如优化时序约束、增加测试数据生成的覆盖率、修正输出检测逻辑等。
5. vivadotestbench的优点和应用场景vivadotestbench具有易用性好、灵活性强、功能全面等优点,适用于对Verilog模块进行全面的仿真和验证。
它可以帮助工程师们提高设计的稳定性和正确性,加快设计的上线速度,降低设计的风险和成本。
结论:vivadotestbench是一个强大的Verilog测试台,可以帮助工程师们在Verilog设计的早期阶段进行全面的功能验证和性能评估。
(verilog和vhdl)Testbench编程指南
(verilog和vhdl)Testbench编程指南TestBench编程指南如今数字设计的规模变得越来越庞大,设计的复杂程度也越来越高,这就使得设计的验证变得越来越困难,而且费时费力。
为了应对这种挑战,验证工程师依靠各种验证工具和方法。
对于大型设计,如几百万门的设计,通常采用一整套正式的验证工具。
然而,对于小一些的设计,设计工程师发现往往采用带TestBench的HDL仿真工具是最好的途径。
TestBench已经变成验证高级语言设计的一种标准的方法。
通常,TestBench执行以下任务:z例化设计,使其可测试(DUT-design under test);z通过将测试向量应用到模型来仿真例化后的可测试的设计;z将结果输出到终端,或者输出波形窗口;z将真实的结果和期望的结果进行比较;一般,TestBench采用工业标准的VHDL或者Verilog硬件描述语言来编写。
TestBench调用功能设计,然后仿真。
复杂的测试文件执行附加功能――例如,他们包含逻辑以决定合适的设计激励或者比较真实的结果和期望的结果。
以下章节将讨论一个组织良好的测试文件的组成,以及例举了一个带有自检的测试文件(自动将真实的结果和预期的结果进行比较)。
下图是一个标准的HDL验证的流程。
自从测试文件可以用VHDL或者Verilog编写以来,测试验证流程就可以在平台和供应商的工具交叉进行。
同时,由于VHDL和Verilog都是标准的公用的语言,所以用VHDL或者是Verilog描述的验证可以很简单的被再使用。
图1. HDL验证流程测试文件构成:测试文件可以采用VHDL或者Verilog语言编写。
由于测试文件只是用来仿真的,他们就不被用于综合的RTL语言子集的语法所约束。
相反,所有行为结构都可以被使用。
这样,测试文件可以被写的更通用,更易于维护。
所有的测试文件都包含以下基本内容,如表1。
如上所属,测试文件经常同时包含附加功能,如结果的可视化显示和内建错误检测。
Testbench文件编写纪要(Verilog)
Testbench⽂件编写纪要(Verilog)之前在使⽤Verilog做FPGA项⽬中、以及其他⼀些不同的场合下,零散的写过⼀些练⼿性质的testbench⽂件,开始⼏次写的时候,每次都会因为⼀些基本的东西没记住、写的很不熟练,后⾯写的时候稍微熟练了⼀点、但是整体编写下来⽐较零碎不成体系,所以在这⾥简要记录⼀下⼀般情况下、针对⼩型的verilog模块进⾏测试时所需要使⽤到的testbench⽂件的编写要点。
本⽂主要参考了在⽹上找到的Lattice公司的“A Verilog HDL Test Bench Primer”⼿册中的有关内容。
谢谢!模块实例化、reg&wire声明、initial和always块的使⽤需要测试的模块(Verilog-module)被称为DUT(Design Under Test),在testbench中需要对⼀个或者多个DUT进⾏实例化。
Testbench中的顶层module不需要定义输⼊和输出。
Testbench中连接到DUT instance的输⼊的为reg类型、连接到DUT instance的输出的为wire类型。
对于DUT的inout类型变量,在testbench中需要分别使⽤reg、wire类型的变量进⾏调⽤。
例如,对于下⾯这样⼀个待测试module:module bidir_infer (DATA, READ_WRITE);input READ_WRITE ;inout [1:0] DATA ;reg [1:0] LATCH_OUT ;always @ (READ_WRITE or DATA) beginif (READ_WRITE == 1)LATCH_OUT <= DATA;endassign DATA = (READ_WRITE == 1) ? 2'bZ : LATCH_OUT;endmodule为其设计的testbench⽂件可以是:module test_bidir_ver;reg read_writet;reg [1:0] data_in;wire [1:0] datat, data_out;bidir_infer uut (datat, read_writet);assign datat = (read_writet == 1) ? data_in : 2'bZ;assign data_out = (read_writet == 0) ? datat : 2'bZ;initial beginread_writet = 1;data_in = 11;#50 read_writet = 0;endendmodule和普通的Verilog模块中⼀样、使⽤assign对wire类型的变量进⾏赋值。
verilog testbench语法
Verilog Testbench语法深度解析1. 什么是Verilog Testbench?Verilog Testbench是一种用于验证Verilog硬件描述语言(HDL)设计的测试环境。
它可以模拟设计的功能,并验证其正确性。
Testbench通常包括测试向量生成、时序控制、错误检测和报告等功能,用于对设计的每个功能进行全面的测试。
2. Verilog Testbench的基本结构Verilog Testbench通常包括模块实例化、时钟生成、信号驱动、仿真结束条件等基本结构。
下面我们分别来详细解析一下这些基本结构:2.1 模块实例化模块实例化是将被测试的Verilog设计模块实例化到Testbench中进行仿真。
在Testbench中,需要为被测设计的每个模块实例化一个对应的实例,并连接所需的输入和输出信号。
如果我们要测试一个简单的加法器模块,那么Testbench中就需要实例化这个加法器,并为其提供输入信号。
2.2 时钟生成时钟是数字电路中非常重要的一部分,它的稳定性和频率对设计的正确性有很大影响。
因此在Testbench中,通常需要生成一个时钟信号,并为被测设计提供时钟。
时钟的生成需要考虑到时钟周期、占空比、起始相位等因素。
2.3 信号驱动在Verilog Testbench中,需要为被测设计提供输入信号,并对其进行驱动。
这些输入信号可以是测试用的模拟信号,也可以是从文件读取的数据。
对于复杂的设计,输入信号的生成可能需要一定的算法和规则。
2.4 仿真结束条件仿真结束条件是指在Testbench中指定了仿真运行的结束条件。
通常情况下,仿真会在满足了所有测试用例,并且通过了所有检查点之后结束。
在Testbench中需要注意设置好仿真的结束条件,以避免不必要的浪费。
3. Verilog Testbench的个人观点对于Verilog Testbench,我个人认为它是Verilog设计中不可或缺的一部分。
verilog testbench例子
Verilog Testbench例子Verilog是一种硬件描述语言,用于描述数字系统。
在Verilog中,testbench是用于验证设计的一部分。
它是一个独立的模块,用于提供输入信号并验证设计的输出信号。
在本文中,我们将介绍一个Verilog testbench的例子,以帮助读者更好地理解Verilog设计和验证的流程。
1. 确定测试目标在编写Verilog testbench之前,首先需要确定测试的目标。
这包括对设计的功能和性能的需求,并确定测试中需要关注的重点。
测试目标的确定将有助于后续测试用例的编写和验证结果的分析。
2. 编写testbench框架testbench通常包括以下几个部分:- 时钟信号生成器:用于生成时钟信号,驱动设计的时序逻辑。
- 信号生成器:用于生成各种输入信号,模拟实际工作状态下的输入情况。
- 仿真模型:绑定被测设计的接口,将输入信号传递给设计,并验证设计的输出信号是否符合预期。
下面是一个简单的testbench框架的例子:```verilog`timescale 1ns / 1nsmodule tb_example;// Define signalsreg clk;reg rst;reg [7:0] data_in;wire [7:0] data_out;// Instantiate design under test (DUT) example_dut dut(.clk(clk),.rst(rst),.data_in(data_in),.data_out(data_out));// Clock generatoralways#5 clk = ~clk;// Stimulus generatorinitial beginrst = 1;#10 rst = 0;#20 data_in = 8'hFF;#20 data_in = 8'h00;// Add more stimulus hereend// Check outputsalways (posedge clk) begin// Add output check hereendendmodule```3. 编写测试用例编写测试用例是testbench编写的关键步骤之一。
testbench 的编写及使用方法思考与体会
【导言】1. 什么是 testbench?2. testbench 的作用和优势【testbench 编写】3. testbench 编写的基本步骤4. testbench 编写的注意事项5. testbench 编写过程中的实际问题与解决方法【testbench 使用方法】6. testbench 的使用流程7. testbench 的结果分析和验证8. testbench 使用过程中的常见错误及解决办法【结语】9. testbench 的编写与使用思考10. testbench 的未来发展预期【导言】1. 什么是 testbench?Testbench 是指在数字电路设计中对被测电路模块进行验证的仿真测试工具。
它是一种独立的模块化设计,用于测试另一个模块或芯片的功能和性能。
在数字电路设计中,testbench 是非常重要的工具,可以帮助设计人员验证电路的正确性和稳定性。
2. testbench 的作用和优势testbench 主要用于验证设计的功能和性能是否符合预期,并且检测是否有潜在的bug存在。
它可以模拟各种工作条件和异常情况,帮助设计人员有效地发现和解决问题。
testbench 的优势在于能够大大提高验证的效率和准确性,节省了大量的人力和时间成本。
【testbench 编写】3. testbench 编写的基本步骤要编写一个高质量的 testbench,需要遵循以下基本步骤:(1)分析被测电路的功能和接口,确定测试的重点和目标;(2)编写测试数据生成模块,包括设计测试用例和对输入信号进行生成;(3)编写时序控制模块,用于控制测试数据的输入和时序顺序;(4)编写仿真结果分析模块,用于对仿真结果进行验证和分析;(5)整合以上模块,编写完整的 testbench。
4. testbench 编写的注意事项在编写 testbench 的过程中,需要注意以下几点:(1)保证测试用例的全面性和充分性,覆盖各种工作条件和异常情况;(2)时序控制模块的设计要符合被测电路的时序要求,保证测试数据的输入顺序和时序正确;(3)仿真结果分析模块要设计完善,能够对仿真结果进行准确的验证和分析;(4)编写的 testbench 要符合规范,可读性强,方便他人理解和维护。
第四讲 逻辑验证与Testbench编写
制作人:梁瑞宇 单位:河海大学
第四讲 逻辑验证与Testbench编写 6/ 30
制作人:梁瑞宇 单位:河海大学
第四讲 逻辑验证与Testbench编写 7/ 30
测试平台实例 module testbench; wire [7:0]Mpi_Data; wire/reg [5:0]Mpi_Addr; wire/reg Mpi_cs_n; wire/reg Mpi_rw; wire/reg Clock; wire/reg Rst_n;
第四讲 逻辑验证与Testbench编写 26/ 30
制作人:梁瑞宇 单位:河海大学
第四讲 逻辑验证与Testbench编写 27/ 30
方法二
module wholedesignII(din,clk,qout); input din; input clk; output qout; reg o1,o2,o3; wire xorresult; always @(posedge clk) begin o1 <= din; o2 <= o1; o3 <= o2; end
endmodule
制作人:梁瑞宇 单位:河海大学
第四讲 逻辑验证与Testbench编写 30/ 30
制作人:梁瑞宇 单位:河海大学
第四讲 逻辑验证与Testbench编写 31/ 30
作业: 编写testbench验证第二讲的作业——全加器 要求:实现覆盖测试
制作人:梁瑞宇 单位ch编写 21/ 30
制作人:梁瑞宇 单位:河海大学
第四讲 逻辑验证与Testbench编写 22/ 30
注意事项 Testbench不是硬件 使用行为级描述方式描述Testbench 设计高效的Testbench • 避免使用无限循环 • 使用逻辑模块划分激励 • 避免不必要的输出显示 • 掌握程式化的仿真结构描述方法
verilog testbench语法
verilog testbench语法摘要:一、Verilog 简介二、Verilog Testbench 的作用三、Verilog Testbench 语法1.模块声明2.信号声明3.初始化语句4.循环语句5.断言和读取语句6.函数和任务声明7.子模块和测试序列四、Verilog Testbench 实例1.简单实例2.复杂实例五、Verilog Testbench 应用场景六、总结正文:一、Verilog 简介Verilog 是一种硬件描述语言,用于描述数字电路和模拟混合信号电路。
它被广泛应用于电子设计自动化(EDA)领域,可以用来设计、验证和仿真数字电路。
二、Verilog Testbench 的作用Verilog Testbench 是一个用于验证Verilog 代码的工具,它可以模拟真实环境中的测试信号,并检查电路的行为是否符合预期。
Testbench 可以帮助我们发现代码中的错误,提高设计质量。
三、Verilog Testbench 语法1.模块声明一个Testbench 模块使用`module`关键字声明,例如:```module tb_example();```2.信号声明在Testbench 中,需要声明待测试模块的输入输出信号。
例如:```reg [7:0] A, B;wire C;```3.初始化语句初始化语句用于设置信号的初始值。
例如:```initial beginA = 8"h00;B = 8"h01;end```4.循环语句Testbench 中可以使用`for`、`forever`和`while`等循环语句。
例如:```initial beginfor (A = 8"h00; A < 8"hFF; A = A + 8"h01) begin// 测试代码endend```5.断言和读取语句断言语句用于检查信号之间的关系是否满足预期。
Verilog-HDL-如何编写TESTBENCH
08:292主要内容Verilog 对验证的支持系统函数和系统任务如何编写模块的TESTBENCH08:293系统任务和系统函数是Verilog中预先定义好的,用于调试和编译预处理的任务或函数。
以$开头,用于控制和检测仿真模拟过程主要有:(1)用于获取仿真时间的系统函数(2)支持文本输出(检测信号、显示信号)的系统任务(3)用于文件输入、输出操作的系统任务(4)用于暂停和退出仿真的系统任务(5)用于产生随机数的系统任务08:294获取当前仿真时间的系统函数$time,$realtime,$stime:返回当前仿真时间。
$time返回一个64位的整数时间值,$realtime返回的结果是实数时间值,是更为精确的仿真时间 $stime返回一个32位整数时间值。
(对大于232的时间,返回模232的值。
使用它可以节省显示及打印空间。
)这些函数的返回值使用调用模块中`timescale 定义的模块仿真时间尺度为单位08:295例..\..\verilog_example\Dec2x4.v..\..\verilog_example\Dec_Test.v # At time 0, input is 0,0,0, output is,xxxx # At time 4, input is 0,0,0, output is,1111# At time 10, input is 0,0,1, output is,1111# At time 13, input is 0,0,1, output is,0111# At time 20, input is 1,0,1, output is,0111# At time 23, input is 1,0,1, output is,0101# At time 26, input is 1,0,1, output is,1101# At time 30, input is 1,1,1, output is,1101# At time 33, input is 1,1,1, output is,1100# At time 36, input is 1,1,1, output is,1110# At time 40, input is 0,1,1, output is,1110# At time 44, input is 0,1,1, output is,1011# At time 50, input is 0,0,1, output is,1011# At time 54, input is 0,0,1, output is,011108:296Verilog 支持的文本输出的系统任务显示任务:用于仿真模拟期间显示信息。
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
盒法。
11
5.2 Verilog HDL测试程序设 计基础
5.2.1 Testbench及其结构
在Verilog HDL中,通常采用测试平台(Testbench)方式 进行仿真和验证。在仿真时,Testbench用来产生测试激励 给待验证设计(Design Under Verification,DUV),或者称 12 为待测试设计(Design Under Test,DUT),同时检查 DUV/DUT的输出是否与预期的一致,从而达到验证设计 功能的目的,如图5.2-1所示。
RTL级代码中的每条路径是否都能按预定要求正确工作。
验证人员是在对内部的设计细节熟悉且能够对内部信 号完全控制和观察的情况下进行验证的。
白盒法的优点在于容易观察和控制验证的进展状况,
9 可以根据事先设置的观测点,在错误出现后很快定位问题 的根源。
其缺点则是需要耗费很长的时间去了解RTL级的实现细节,
在设计过程中,仿真是在综合之前完成的,这就是通
常所说的行为级仿真、RTL仿真或前仿真。在RTL设计阶
段只包含了时钟及其时序,并未包含门延迟和线延迟。因 此,RTL仿真对于时钟来说是正确的,并且不用考虑竞争
冒险、毛刺、建立和保持时间以及其它一些详细的时序问
题,这样RTL仿真就具有较快的速度。 验证是一系列测试平台的集合,是一个证明设计思路
第5章 仿真验证与Testbench编写
5.1 Verilog HDL电路仿真和验证概述 5.2 Verilog HDL测试程序设计基础 5.3 与仿真相关的系统任务 5.4 信号时间赋值语句 5.5 任务和函数
5.6 典型测试向量的设计
5.7 用户自定义元件模型 5.8 基本门级元件和模块的延迟建模 5.9 编译预处理语句 5.10 Verilog HDL测试方法简介 本章小结
试,因此本书所介绍的验证仅限于在PC平台上运行的前3
5 个阶段的验证。
在测试验证环节中,要求测试需具备高效、完备的特
性。高效是指以最短的时间发现错误,从而能以最短的时
间上市;完备是指发现全部的错误,要求测试需达到一定 的覆盖率,包括代码的覆盖率和功能的覆盖率。
目前常用的功能验证有三种:黑盒法、白盒法和灰盒
设计确认可以通过仿真和验证来完成。仿真和验证能确保
设计的完整性、可靠性、实效性以及先进性。 仿真,也可以称为模拟,是通过EDA仿真工具,对所
设计电路或系统输入测试信号,然后根据其输出信号(波形、
文本或者VCD文件)与期望值进行比较,来确认是否得到 与所期望一致的正确的设计结果,从而验证设计的正确性。 3
如何实现及保证设计在功能上正确的过程。验证在Verilog
4 HDL设计的整个流程中分为4个阶段:
阶段1—功能验证;
阶段2—综合后验证;
阶段3—时序验证; 阶段4—板级验证。
其中前3个阶段是在PC平台上依靠EDA工具来实现的,
最后一个阶段则需要在真正的硬件平台(FPGA、CPLD等) 上进行,需要借助一些调试工具或者专业性的分析仪来调
且难以实现设计与验证的分离,验证团队可能会受设计团
队思路的影响,出现沿着设计思路去验证的现象,结果是 无法证明设计的功能是否正确。
10
3) 灰盒法
灰盒法是介于黑盒法和白盒法之间的一种测试方法。
灰盒测试关注输出对于输入的正确性,同时也关注内部表 现,但这种关注没有白盒法那样详细、完整,只是通过一
些表征性的现象、事件、标志来判断内部的运行状况。在
16
//产生测试激励
always
#5 clk=~clk; initial
begin
clk=0; #3 பைடு நூலகம்st_n=0;
1
5.1 Verilog HDL电路仿真和 验证概述
在Verilog HDL集成电路设计过程中,设计者完成RTL 级描述后需要对设计进行设计确认。设计确认是设计者检
查设计中是否包含缺陷的过程。在设计中,表述不清的设
2 计规范、设计者的错误或者错误地调用了元件等都可能给 设计带来缺陷。
因此,设计确认对于集成电路设计来说具有重要的作用。
法。
6
1) 黑盒法
黑盒法就是把测试代码看做一个黑盒子,测试人员完
全不考虑代码内部的逻辑结构和内部特性,只依据程序的 需求规格说明书,检查程序的功能是否符合它的功能说明。
验证人员在RTL级输入端施加激励信号,然后将输出值与
期望值相比较,以验证设计的正确性。
7
黑盒法主要有两个优点:(1) 简单。验证者无需了解
部的实现细节不了解,无法插入内部测试点,因此很难对
8 错误进行迅速定位,在大规模设计中难以跟踪错误的根源。 黑盒法一般适用于中小规模电路的验证。
2) 白盒法
白盒法也称结构测试或逻辑驱动测试,它是按照RTL
级代码内部结构进行测试,通过测试来检测RTL级代码内 部实现是否按照设计规格说明书的规定正常执行,检验
13
图5.2-1 Testbench结构
应该指出的是,由于Testbench是一个测试平台,信号
集成在模块内部,因此没有输入、输出。在Testbench模块
内,例化待测设计的顶层模块,并把测试行为的代码封装 在内,直接对待测系统提供测试激励。图5.2-2给出了一个
典型的Testbench程序结构。
14
15
图5.2-2 典型的Testbench程序结构
下面举例介绍测试程序中各模块的分布。
例5.2-1 T触发器测试程序示例。
module Tflipflop_tb; //数据类型声明
reg clk, rst_n,T;
wire data_out; //对被测试模块实例化
TFF U1 (.data_out(data_out),.T(T),.clk(clk),.rst_n(rst_n));
RTL级设计的细节,只需根据规格说明书搭建Testbench(测
试平台)。(2) 易于实现验证和设计的独立性。由于验证者 不了解RTL级设计细节,在搭建Testbench时不会受设计者
思路的影响,因此能避免按RTL级设计者的实现思路来验
证RTL级设计的情况。 黑盒法的主要缺点是可观测性差。由于验证人员对内