如何编写testbench

合集下载

verilogtestbench写法

verilogtestbench写法

verilogtestbench写法Verilog测试平台(testbench)技术(⼀) 收藏对设计进⾏功能仿真和时序仿真时,需要给待测模块提供激励输⼊。

对于由Verilog语⾔描述的设计模块,最好的⽅法⾃然同样是⽤Verilog语⾔对待测模块施加激励和检测模块的输出响应。

实际应⽤中,Verilog测试平台(testben ch)就是⽤来提供上述功能的。

Verilog测试平台是⼀个例化的待测(MUT)Verilog 模块,给它施加激励并观测其输出。

由于测试平台是⽤Verilog语⾔描述的,因此可以应⽤到不同的仿真环境中。

待测模块和与之对应的测试平台组成⼀个仿真模型,应⽤这个模型可以在不同的测试环境中⽤相同的激励对待测模块进⾏调试。

下⾯就对不同电路类型分别介绍verilog测试平台的语⾔结构。

⼀、测试平台1.组合电路测试设计组合电路的测试平台时,待测模块及其功能决定了激烈的选择与测试次数。

对于⼀个已有的待测模块,测试平台中需要声明与待测模块输⼊输出端⼝对应的变量。

与输⼊端⼝相连接的变量定义为reg,与输出端⼝相连接的变量定义为wire,例化时将测试平台中声明的变量与待测模块的输⼊输出端⼝相关联。

使⽤initial语句控制程序运⾏,initial语句是⼀种过程结构,在initial块中可使⽤延迟控制语句来控制initial块中的程序流动。

这⾥对⼀个简单的算术逻辑单元(ALU)为例进⾏测试,下⾯是该单元Verilog 描述。

/***************************************************************** ********///多动能ALU的Verilog代码'timescale 1ns/100psmodule alu_4bit(a,b,f,oe,y,p,ov,a_gt_b,a_eg_b,a_lt_b);input [3:0] a,b;input [1:0] f;input oe;input [3:0] y;output p,ov,a_gt_b,a_eg_b,a_lt_b; reg [4:0] im_y;always @(a or b or f)beginov=1'b0;im_y=0;case(f)2'b00:beginim_y=a+b;if(im_y>5'b01111)ov=1'b1;end2'b01:beginim_y=a-b;if(im_y>5'b01111)ov=1'b1;end2'b10:im_y[3:0]=a&b;2'b11:im_y[3:0]=a^b;default:im_y[3:0]=4'b0000;endcaseendalways @(a or b)beginif(a>b){a_gt_b,a_ge_b,a_lt_b}=3'b100;else if(a{a_gt_b,a_ge_b,a_lt_b}=3'b001;else{a_gt_b,a_ge_b,a_lt_b}=3'b010;endassign p=^im_y[3:0];assign y=oe?im_y[3:0]:4'bz;endmodule/***************************************************************** ********/模块alu_4bit是四功能的算术逻辑单元,输⼊包括数据信号a、b和功能信号f,输出包括数据信号y和ALU⽣成的奇偶校验信号p、溢出信号ov及⽐较信号。

编写高效率的testbench

编写高效率的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

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基本入门

Testbench基本入门

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

编写testbench进行测试的过程如下:1)产生模拟激励(波形);2)将产生的激励加入到被测试模块并观察其输出响应;3)将输出响应与期望进行比较,从而判断设计的正确性。

2 基本的testbench结构module test_bench;// 通常testbench没有输入与输出端口信号或变量定义声明使用initial或always语句来产生激励波形例化设计模块监控和比较输出响应endmodule简单的testbench的结构通常需要建立一个顶层文件,顶层文件没有输入和输出端口。

在顶层文件里,把被测模块和激励产生模块实例化进来,并且把被测模块的端口与激励模块的端口进行对应连接,使得激励可以输入到被测模块。

端口连接的方式有名称和位置关联两种方式,我们常常使用“名称关联”方式。

3 产生激励的一些描写方式3.1 产生时钟的几种方式1)使用initial方式产生占空比50﹪的时钟initialbeginCLK = 0;#delay;forever#(period/2) CLK = ~CLK;end注意:一定要给时钟赋初始值,因为信号的缺省值为z,如果不赋初值,则反相后还是z,时钟就一直处于高阻z状态。

产生的时钟信号如下图所示:2)使用always方式initialCLK = 0;always#(period/2) CLK = ~CLK;3)使用repeat产生确定数目的时钟脉冲initialbeginCLK = 0;repeat(6)#(period/2) CLK = ~CLK;end该例使用repeat产生3个时钟脉冲,产生的波形如下:4)产生占空比非50﹪的时钟initialCLK = 0;alwaysbegin#3 CLK = ~CLK;#2 CLK = ~CLK;end3.2 产生复位信号的几种形式1)异步复位initialbeginRst = 1;#100;Rst = 0;#500;Rst = 1;end2)同步复位1initialbeginRst = 1;@(negedge CLK); // 等待时钟下降沿Rst = 0;#30;@(negedge CLK); // 等待时钟下降沿Rst = 1;end2)同步复位2initialbeginRst = 1;@(negedge CLK); // 等待时钟下降沿repeat (3) @(negedge CLK); // 经过3个时钟下降沿Rst = 1;end4 testbench实例4.1 2-4解码器实例module dec2x4(A, B, Enable, Z);input A, B, Enable;output[3:0] Z;reg [3:0] Z_o;assign Z = Z_o;always@(A or B or Enable)beginif(Enable == 1'b0)Z_o = 4'b1111;elsecase({A, B})2'b00: Z_o = 4'b1110;2'b01: Z_o = 4'b1101;2'b10: Z_o = 4'b1011;2'b11: Z_o = 4'b0111;default: Z_o = 4'b1111;endcaseendendmodule测试模块测试模块::`timescale 1ns/100psmodule testbench;reg a, b, en;wire [3:0] z;//例化被测试模块dec2x4 DUT(.A(a),.B(b),.Enable(en),.Z(z));//产生输入激励initialbeginen = 0;a = 0;b = 0;#10 en = 1;#10 b = 1;#10 a = 1;#10 b = 0;#10 a = 0;#10 $stop;end//显示输出结果always@(en or a or b or z)begin$display("At time %t, input is %b%b%b, output is %b", $time, a, b, en, z);endendmodule下面是测试模块执行时产生的输出和功能仿真波形:4.2 时序检测器下面是一个时序检测器的验证实例。

如何编写testbench的总结(非常实用的总结)

如何编写testbench的总结(非常实用的总结)

如何编写testbench的总结(⾮常实⽤的总结)1.激励的设置相应于被测试模块的输⼊激励设置为reg型,输出相应设置为wire类型,双向端⼝inout在测试中需要进⾏处理。

⽅法1:为双向端⼝设置中间变量inout_reg作为该inout的输出寄存,inout⼝在testbench中要定义为wire型变量,然后⽤输出使能控制传输⽅向。

eg:inout [0:0] bi_dir_port;wire [0:0] bi_dir_port;reg [0:0] bi_dir_port_reg;reg bi_dir_port_oe;assign bi_dir_port=bi_dir_port_oe?bi_dir_port_reg:1'bz;⽤bi_dir_port_oe控制端⼝数据⽅向,并利⽤中间变量寄存器改变其值。

等于两个模块之间⽤inout双向⼝互连。

往端⼝写(就是往模块⾥⾯输⼊)⽅法2:使⽤force和release语句,这种⽅法不能准确反映双向端⼝的信号变化,但这种⽅法可以反映块内信号的变化。

具体如⽰:module test();wire data_inout;reg data_reg;reg link;#xx; //延时force data_inout=1'bx; //强制作为输⼊端⼝...............#xx;release data_inout; //释放输⼊端⼝endmodule从⽂本⽂件中读取和写⼊向量1)读取⽂本⽂件:⽤ $readmemb系统任务从⽂本⽂件中读取⼆进制向量(可以包含输⼊激励和输出期望值)。

$readmemh ⽤于读取⼗六进制⽂件。

例如:reg [7:0] mem[1:256] // a 8-bit, 256-word 定义存储器meminitial $readmemh ( "mem.data", mem ) // 将.dat⽂件读⼊寄存器mem中initial $readmemh ( "mem.data", mem, 128, 1 ) // 参数为寄存器加载数据的地址始终2)输出⽂本⽂件:打开输出⽂件⽤?$fopen 例如:integer out_file; // out_file 是⼀个⽂件描述,需要定义为 integer类型out_file = $fopen ( " cpu.data " ); // cpu.data 是需要打开的⽂件,也就是最终的输出⽂本设计中的信号值可以通过$fmonitor, $fdisplay,2. Verilog和Ncverilog命令使⽤库⽂件或库⽬录ex). ncverilog -f run.f -v lib/lib.v -y lib2 +libext+.v //⼀般编译⽂件在run.f中, 库⽂件在lib.v中,lib2⽬录中的.v⽂件系统⾃动搜索使⽤库⽂件或库⽬录,只编译需要的模块⽽不必全部编译3.Verilog Testbench信号记录的系统任务:1). SHM数据库可以记录在设计仿真过程中信号的变化. 它只在probes有效的时间内记录你set probe on的信号的变化.ex). $shm_open("waves.shm"); //打开波形数据库$shm_probe(top, "AS"); // set probe on "top",第⼆个参数: A -- signals of the specific scropeS -- Ports of the specified scope and below, excluding library cellsC -- Ports of the specified scope and below, including library cellsAS -- Signals of the specified scope and below, excluding library cellsAC -- Signals of the specified scope and below, including library cells还有⼀个 M ,表⽰当前scope的memories, 可以跟上⾯的结合使⽤, "AM" "AMS" "AMC"什么都不加表⽰当前scope的ports;$shm_close //关闭数据库2). VCD数据库也可以记录在设计仿真过程中信号的变化. 它只记录你选择的信号的变化.ex). $dumpfile("filename"); //打开数据库$dumpvars(1, top.u1); //scope = top.u1, depth = 1第⼀个参数表⽰深度, 为0时记录所有深度; 第⼆个参数表⽰scope,省略时表当前的scope.$dumpvars; //depth = all scope = all$dumpvars(0); //depth = all scope = current$dumpvars(1, top.u1); //depth = 1 scope = top.u1$dumpoff //暂停记录数据改变,信号变化不写⼊库⽂件中$dumpon //重新恢复记录3). Debussy fsdb数据库也可以记录信号的变化,它的优势是可以跟debussy结合,⽅便调试.如果要在ncverilog仿真时,记录信号, ⾸先要设置debussy:a. setenv LD_LIBRARY_PATH :$LD_LIBRARY_PATH(path for debpli.so file (/share/PLI/nc_xl//nc_loadpli1))b. while invoking ncverilog use the +ncloadpli1 option.ncverilog -f run.f +debug +ncloadpli1=debpli:deb_PLIPtrfsdb数据库⽂件的记录⽅法,是使⽤$fsdbDumpfile和$fsdbDumpvars系统函数,使⽤⽅法参见VCD注意: 在⽤ncverilog的时候,为了正确地记录波形,要使⽤参数: "+access+rw", 否则没有读写权限在记录信号或者波形时需要指出被记录信号的路径,如:tb.module.u1.clk.………………………………………………………………………………………………………关于信号记录的系统任务的说明:在testbench中使⽤信号记录的系统任务,就可以将⾃⼰需要的部分的结果以及波形⽂件记录下来(可采⽤sigalscan⼯具查看),适⽤于对较⼤的系统进⾏仿真,速度快,优于全局仿真。

VHDL的testbench的编写

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;

我的testbench书写总结

占空比为 50%的时钟`timescale 1ns/1ns //定义时间的尺度和精度,其中精度和小树部分挂钩parameter period=4’d10;reg clk; //时钟是输入给DUT的信号必须声明为reg类型initialbeginclk=1’b0; //定义clk的初始状态为低电平forever#( period/2) clk=~clk;endparameter period=4’d10;reg clk;initialbeginclk=1’b0; //定义clk的初始状态为低电平endalways #( period/2) clk=~clk;占空比非50%的时钟信号parameter HIGH_TIME=4,LOW_TIME=6;reg clk;initialbeginclk=1’b0; //定义clk的初始状态为低电平endalwaysbegin# LOW_TIME clk=1’b1;//0~LOW_TIME为低电平# HIGH_TIME clk=1’b0; //从low_time~(low_time+high_time)为高电平end固定数目的时钟信号parameter PulseCount=4,PERIOD=10;reg clk;initialbeginclk=1’b0; //定义clk的初始状态为低电平repeat(PulseCount) //相对于下面的语句重复执行4次#(PERIOD/2) clk=~clk;End//先低电平半个周期,然后再产生两个完整周期的脉冲,结束时clk为低电平parameter Phase_Shift=2;PERIOD=10;reg source_clk;wire derive_clk;//这里是wire好像没有多大用处,要是能用reg就有用了//用initial语句生成源时钟initialbeginclk=1’b0; //定义clk的初始状态为低电平forever#( PERIOD/2) source_clk=~source_clk;EndAssign #Phase_Shift derive_clk=source_clk; //生成派生时钟,要延后2ns2,对于仿真器,reg在没有赋初始值的情况下默认的值为’X’即不定值,而wire的默认值为’Z’即高阻态。

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设计的早期阶段进行全面的功能验证和性能评估。

  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。

如何编写testbench的总结(非常实用的总结)1.激励的设置相应于被测试模块的输入激励设置为reg型,输出相应设置为wire类型,双向端口inout 在测试中需要进行处理。

方法1:为双向端口设置中间变量inout_reg作为该inout的输出寄存,inout口在testbench 中要定义为wire型变量,然后用输出使能控制传输方向。

eg:inout [0:0] bi_dir_port;wire [0:0] bi_dir_port;reg [0:0] bi_dir_port_reg;reg bi_dir_port_oe;assign bi_dir_port=bi_dir_port_oe?bi_dir_port_reg:1'bz;用bi_dir_port_oe控制端口数据方向,并利用中间变量寄存器改变其值。

等于两个模块之间用inout双向口互连。

往端口写(就是往模块里面输入)方法2:使用force和release语句,这种方法不能准确反映双向端口的信号变化,但这种方法可以反映块内信号的变化。

具体如示:module test();wire data_inout;reg data_reg;reg link;#xx; //延时force data_inout=1'bx; //强制作为输入端口...............#xx;release data_inout; //释放输入端口endmodule从文本文件中读取和写入向量1)读取文本文件:用 $readmemb系统任务从文本文件中读取二进制向量(可以包含输入激励和输出期望值)。

$readmemh 用于读取十六进制文件。

例如:reg [7:0] mem[1:256] // a 8-bit, 256-word 定义存储器meminitial $readmemh ( "mem.data", mem ) // 将.dat文件读入寄存器mem中initial $readmemh ( "mem.data", mem, 128, 1 ) // 参数为寄存器加载数据的地址始终2)输出文本文件:打开输出文件用?$fopen例如:integer out_file; // out_file 是一个文件描述,需要定义为 integer类型out_file = $fopen ( " cpu.data " ); // cpu.data 是需要打开的文件,也就是最终的输出文本设计中的信号值可以通过$fmonitor, $fdisplay,2. Verilog和Ncverilog命令使用库文件或库目录ex). ncverilog -f run.f -v lib/lib.v -y lib2 +libext+.v //一般编译文件在run.f 中, 库文件在lib.v中,lib2目录中的.v文件系统自动搜索使用库文件或库目录,只编译需要的模块而不必全部编译3.Verilog Testbench信号记录的系统任务:1). SHM数据库可以记录在设计仿真过程中信号的变化. 它只在probes有效的时间内记录你set probe on的信号的变化.ex). $shm_open("waves.shm"); //打开波形数据库$shm_probe(top, "AS"); // set probe on "top",第二个参数: A -- signals of the specific scropeS -- Ports of the specified scope and below, excluding library cellsC -- Ports of the specified scope and below, including library cellsAS -- Signals of the specified scope and below, excluding library cellsAC -- Signals of the specified scope and below, including library cells还有一个 M ,表示当前scope的memories, 可以跟上面的结合使用, "AM" "AMS" "AMC"什么都不加表示当前scope的ports;$shm_close //关闭数据库2). VCD数据库也可以记录在设计仿真过程中信号的变化. 它只记录你选择的信号的变化. ex). $dumpfile("filename"); //打开数据库$dumpvars(1, top.u1); //scope = top.u1, depth = 1第一个参数表示深度, 为0时记录所有深度; 第二个参数表示scope,省略时表当前的scope. $dumpvars; //depth = all scope = all$dumpvars(0); //depth = all scope = current$dumpvars(1, top.u1); //depth = 1 scope = top.u1$dumpoff //暂停记录数据改变,信号变化不写入库文件中$dumpon //重新恢复记录3). Debussy fsdb数据库也可以记录信号的变化,它的优势是可以跟debussy结合,方便调试.如果要在ncverilog仿真时,记录信号, 首先要设置debussy:a. setenv LD_LIBRARY_PATH LD_LIBRARY_PATH(path for debpli.so file (/share/PLI/nc_xl//nc_loadpli1))b. while invoking ncverilog use the +ncloadpli1 option.ncverilog -f run.f +debug +ncloadpli1=debpli:deb_PLIPtrfsdb数据库文件的记录方法,是使用$fsdbDumpfile和$fsdbDumpvars系统函数,使用方法参见VCD注意: 在用ncverilog的时候,为了正确地记录波形,要使用参数: "+access+rw", 否则没有读写权限在记录信号或者波形时需要指出被记录信号的路径,如:tb.module.u1.clk. ………………………………………………………………………………………………………关于信号记录的系统任务的说明:在testbench中使用信号记录的系统任务,就可以将自己需要的部分的结果以及波形文件记录下来(可采用sigalscan工具查看),适用于对较大的系统进行仿真,速度快,优于全局仿真。

使用简单,在testbench中添加:initial begin$shm_open("waves.shm");$shm_probe("要记录信号的路径“,”AS“);#10000$shm_close; 即可。

4. ncverilog编译的顺序: ncverilog file1 file2 ....有时候这些文件存在依存关系,如在file2中要用到在file1中定义的变量,这时候就要注意其编译的顺序是从后到前,就先编译file2然后才是file2.5.信号的强制赋值force首先, force语句只能在过程语句中出现,即要在initial 或者 always 中间. 去除force 用 release 语句.initial begin force sig1 = 1'b1; ... ; release sig1; endforce可以对wire赋值,这时整个net都被赋值; 也可以对reg赋值.6.加载测试向量时,避免在时钟的上下沿变化为了模拟真实器件的行为,加载测试向量时,避免在时钟的上下沿变化,而是在时钟的上升沿延时一个时间单位后,加载的测试向量发生变化。

如:assign #5 c=a^b……@(posedge clk) #(0.1*`cycle) A=1;****************************************************************************** //testbench的波形输出module top;...initialbegin$dumpfile("./top.vcd"); //存储波形的文件名和路径,一般是.vcd格式.$dumpvars(1,top); //存储top这一层的所有信号数据$dumpvars(2,top.u1); //存储top.u1之下两层的所有数据信号(包含top.u1这一层) $dumpvars(3,top.u2); //存储top.u2之下三层的所有数据信号(包含top.u2这一层) $dumpvars(0,top.u3); //存储top.u3之下所有层的所有数据信号endendmodule//产生随机数,seed是种子$random(seed);ex: din <= $random(20);//仿真时间,为unsigned型的64位数据$timeex:...time condition_happen_time;...condition_happen_time = $time;...$monitor($time,"data output = %d", dout);...//参数parameter para1 = 10,para2 = 20,para3 = 30;//显示任务$display();//监视任务$monitor();//延迟模型specify...//describ pin-to-pin delayendspecifyex:module nand_or(Y,A,B,C);input A,B,C;output Y;AND2 #0.2 (N,A,B);OR2 #0.1 (Y,C,N);specify(A*->Y) = 0.2;(B*->Y) = 0.3;(C*->Y) = 0.1;endspecifyendmodule//时间刻度`timescale 单位时间/时间精确度//文件I/O1.打开文件integer file_id;file_id = fopen("file_path/file_name");2.写入文件//$fmonitor只要有变化就一直记录$fmonitor(file_id, "%format_char", parameter);eg fmonitor(file_id, "%m: %t in1=%d o1=%h", $time, in1, o1);//$fwrite需要触发条件才记录$fwrite(file_id, "%format_char", parameter);//$fdisplay需要触发条件才记录$fdisplay(file_id, "%format_char", parameter);$fstrobe();3.读取文件integer file_id;file_id = $fread("file_path/file_name", "r");4.关闭文件$fclose(fjile_id);5.由文件设定存储器初值$readmemh("file_name", memory_name"); //初始化数据为十六进制$readmemb("file_name", memory_name"); //初始化数据为二进制//仿真控制$finish(parameter); //parameter = 0,1,2$stop(parameter);//读入SDF文件$sdf_annotate("sdf_file_name", module_instance, "scale_factors");//module_instance: sdf文件所对应的instance名.//scale_factors:针对timming delay中的最小延时min,典型延迟typ,最大延时max调整延迟参数//generate语句,在Verilog-2001中定义.用于表达重复性动作//必须事先声明genvar类型变量作为generate循环的指标eg:genvar i;generate for(i = 0; i < 4; i = i + 1)beginassign = din = i % 2;endendgenerate//资源共享always @(A or B or C or D)sum = sel ? (A+B)C+D);//上面例子使用两个加法器和一个MUX,面积大//下面例子使用一个加法器和两个MUX,面积小always @(A or B or C or D)begintmp1 = sel ? A:C;tmp2 = sel ? B;endalways @(tmp1 or tmp2)sum = tmp1 + tmp2;****************************************************************************** 模板:module testbench; //定义一个没有输入输出的modulereg …… //将DUT的输入定义为reg类型……wire…… //将DUT的输出定义为wire类型……//在这里例化DUTinitialbegin…… //在这里添加激励(可以有多个这样的结构)endalways…… //通常在这里定义时钟信号initial//在这里添加比较语句(可选)endinitial//在这里添加输出语句(在屏幕上显示仿真结果)endendmodule一下介绍一些书写Testbench的技巧:1.如果激励中有一些重复的项目,可以考虑将这些语句编写成一个task,这样会给书写和仿真带来很大方便。

相关文档
最新文档