当前位置:懂科普 >

综合知识

> 怎么写testbench

怎么写testbench

1. 如何写TESTBENCH, 给个教程吧

一、基本概念和基础知识Testbench 不仅要产生激励也就是输入,还要验证响应也就是输出。

怎么写testbench

当然也可以只产生激励,然后通过波形窗口通过人工的方法去验证波形,这种方法只能适用于小规模的设计。在ISE 环境中,当前资源操作窗显示了资源管理窗口中选中的资源文件能进行的相关操作。

在资源管理窗口选中了testbench 文件后,在当前资源操作窗显示的ModelSimSimulator 中显示了4 种能进行的模拟操作,分别是:Simulator Behavioral Model(功能仿真)、Simulator Post-translate VHDL Model(翻译后仿真)、Simulator Post-Map VHDLModel(映射后仿真)、Simulator Post-Place & Route VHDL Model(布局布线后仿真)。如图1 所示:图1l Simulator Behavioral Model 也就是所说的功能仿真、行为仿真、前仿真。

验证功能是否正确,这是设计的第一步。功能仿真正确的程序不一定能被正确综合,也就是硬件实现。

有的在综合时报错误,有的虽然能综合但结果并不正确。当然,功能仿真如果都不能通过,以后的步骤也就无法进行。

这是必做的仿真。l Simulator Post-translate VHDL Model 也就是翻译后仿真。

对源程序进行编译后首先排除了语法错误,对一些像类属命令(Generic)、生成语句(Generate)等进行了展开。不是必做的仿真。

l Simulator Post-Map VHDL Model也就是映射后仿真。不同的器件内部结构也不尽相同,映射的作用就是将综合后产生的网表文件对应到实际的器件上去。

由于映射不包含布线,也就是要用什么类型的逻辑单元虽然已经确定但要用哪个位置的还没有确定,因此,映射后仿真不包含布线延时。不是必做的仿真。

l Simulator Post-Place & Route VHDL Model 也就是所说的布局布线后仿真、时序仿真、后仿真。这是最完整的仿真,既包含逻辑延时又包含布线延时。

在做布局布线后仿真时要用到一个叫SDF的文件。SDF文件包含设计中每个单元(Cell)的延时和时序约束数据。

通过加载这个文件就能得到完整的时序情况。它是必做的仿真。

一般必须进行功能仿真和布局布线后仿真。常见问题:为什么有的testbench在进行功能仿真时能正确进行,而在进行布局布线后仿真时就不能运行。

有两点要注意的地方:(1)、在做映射后仿真或布局布线后仿真时,都已经经过了综合工具的综合,源程序中的类属命令(Generic)、生成语句(Generate)等都已经进行展开。例如,如果用Generic 定义了一个参数width,综合工具进行综合时已经按照一个确定的width 值进行了综合。

它生成的电路已经具有一个确定的结构,不能再随意调整。所以在映射后仿真和布局布线后仿真的testbench中,往往不能出现Generic 语句。

(2)映射后仿真和布局布线后仿真都要用到SDF 文件,并且要将SDF文件关联到设计中的实例。所以在映射后仿真和布局布线后仿真的testbench中,第一,要将你的设计声明成一个元件。

第二,实例化你设计的元件并且实例名要取为UUT(默认的,当然也可以改)。关于断言语句在仿真中为了能得到更多信息,经常要用到断言语句(assert)。

其语法如下:Assert<条件>Report<消息>Severity<出错级别>;出错级别共有5 种:l Notel Warningl Errorl Failurel Fatal在VHDL 模型的模拟过程中,一旦断言语句的条件为假,则发送消息并将出错级别发送给模拟器。通常可以设置一个中止模拟器运行的出错级别,一般默认的中止运行的出错级别为Failure。

我们来看一个例子:assert falsereport "********* " & IMAGE(DWIDTH) & "BIT DIVIDER SEQUENCE FINISHEDAT " & IMAGE(now) & " !" & " *********"severity note;断言的条件不是一个条件表达式,而直接是false。这说明只要程序执行到这里断言就一定会成立,送出消息。

出错级别为note,在模拟器的输出窗口将会显示:图2再看一个例子:assert (s_cyi((DWIDTH-1)/4) = '0')and (s_ovi = '0')and (s_qutnt = conv_std_logic_vector(v_quot,DWIDTH))and (s_rmndr = conv_std_logic_vector(v_remd,DWIDTH))report "ERROR in division!"severity failure;断言的条件有4 个并且是与的关系,只要其中一个条件不成立则整个表达式为假,断言成立。如果断言成立将输出“ERROR in division!“这个消息。

并且通知模拟器出错级别为failure,这一般会停止模拟。这个断言实际是在对结果进行验证。

二、实际testbench分析下面将详细分析一个实际的testbench,它是用来测试8051 的ALU单元的除法功能的。8 位的除法器,被除数和除数的组合共有256*256=65536 种。

我们采用的方法是穷举所有的输入组合,这样的代码覆盖率可以达到100%。它的验证必须通过程序自动完成,否则通过人工方法工作量太大。

把要测试的程序当作一个元件,例如想象成一个74 系列数字电路。Testbench 的作用是在被测试电路的输入端加上激励,然后比较被测试电路的输出和计算出来的期望值是否一致。

对我们这个例子来说,在要仿真的ALU 输入端产生65536 种输入组合,然后将ALU产生的对应输出值和testbench 算出的期望值相比较,如果有错误产生则停止模拟并输出信息。ALU 的除法单元的输入有4 个,分别是被除数、除。

2. 怎样写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 定义存储器mem initial $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 scrope S -- Ports of the specified scope and below, excluding library cells C -- Ports of the specified scope and below, including library cells AS -- Signals of the specified scope and below, excluding library cells AC -- 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_PLIPtr fsdb数据库文件的记录方法,是使用$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; end force可以对wire赋值,这时整个net都被赋值; 。

3. 如何编写testbench的总结

相应于被测试模块的输入激励设置为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 scrope S -- 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 //重新恢复记录。

4. Verilog键盘扫描程序的testbench怎么写

modulemul3_testbench;//定义一个没有输入输出端口的测试平台rega2,a1,a0,b2,b1,b0;//被测模块的input端口,改为对应的reg寄存器做输入信号wirep5,p4,p3,p2,p1,p0;//被测模块的output端口,改为对应的wire型initialbegin//初始化所有输入信号的寄存器值a2=0;a1=0;a0=0;b2=0;b1=0;b0=0;#50//一般延迟较长时间后,应该使复位信号不复位系统正常工作,但你没有复位信号end//初始化模块结束后一般时序电路仿真是产生时钟信号,//这是纯组合逻辑没有时钟信号就省略了//然后就可以根据你所需要验证的功能在此位置编写initial块或always块给reg型//的输入信号赋值的相关逻辑,观察wire型输入信号的值//---------------------------调用被测对象,格式如一般元件调用-------------------mul3DUT(.a2(a2),.a1(a2),.a0(a0),.b2(b2),.b1(b2),.b0(b0),.p5(p5),.p4(p4),.p3(p3),.p2(p2),.p1(p1),.p0(p0));endmodule//最后的提示,你的程序里定义了整数型变量,其实是不好的用法,甚至不能被正确综合,//可以用等值的reg型变量来替代,即使你定义成整数型,实际上也是被综合成reg型的,//另外,一般可综合代码中最好不要用for语句,个人认为你的代码会完全功能不正常的。

5. 如何编写testbench的总结

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

方法:为双向端口设置中间变量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; regbi_dir_port_oe; assignbi_dir_port=bi_dir_port_oe?bi_dir_port_reg:1'bz; 用bi_dir_port_oe控制端口数据方向,并利用中间变量寄存器改变其值。

等于两个模块之间用inout双向口互连。往端口写(就是往模块里面输入)。

6. 如何编写 test bench来仿真VHDL程序

本文介绍如何写testbench来仿真VHDL程序。

通常testbench完成如下的任务:1. 实例化需要测试的设计(DUT);2. 通过对DUT模型加载测试向量来仿真设计;3. 将输出结果到终端或波形窗口中加以视觉检视;4. 另外,将实际结果和预期结果进行比较。 一、构建Testbench 本文用VHDL来写,由于testbench只用来进行仿真,它们没有那些适用于综合的RTL语言子集的语法约束限制,而是所有的行为结构都可以使用。

所有testbench包含了以下的基本程序段:Entity and Architecture Declaration ;Signal Declaration ;Instantiation of Top-level Design ;Provide Stimulus. 在ISE工程中添加source:VHDL Test Bench到顶层文件,在source for 选项中选择Behavioral Simulation。你会发现Test Bench中有很多已经自动写好,可根据自己的设计需要改写程序。

其中Entity是空的,由于是仿真,不必有管脚的输入输出,只要写好激励信号就可以了。 二、双击Simulate Behavioral Model进行Modelsim仿真 我们在modelsim仿真的过程中,如果想改写激励程序,点击environment back(图中向左的箭头),回到激励程序的编写环境。

可以利用其提供的模板直接改写testbench,点source->show language template,需要将read only取消掉,否则无法改写。本人建议,在这个环境中可以看到模板,你可以根据需要将相应的语句拷到VHDL Testbench中去。

这里只是简单介绍如何用test bench来仿真VHDL程序,其中各种激励信号的编写、时序的安排要依靠设计的需要,这些只能靠平时不断的积累。 这里介绍的是从ISE中直接调用modelsim进行仿真,因此关于ISE和modelsim的关联也是大家经常遇到的问题。

这个下次再总结。

7. 如何编写testbench的总结

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

方法:为双向端口设置中间变量 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; regbi_dir_port_oe; assignbi_dir_port=bi_dir_port_oe?bi_dir_port_reg:1'bz; 用 bi_dir_port_oe 控制端口数据方向,并利用中间变量寄存器改变其值。

等于两个模块之间 用 inout 双向口互连。往端口写(就是往模块里面输入 )。

8. 如何编写 test bench来仿真VHDL程序

本文介绍如何写testbench来仿真VHDL程序。

通常testbench完成如下的任务:1. 实例化需要测试的设计(DUT);2. 通过对DUT模型加载测试向量来仿真设计;3. 将输出结果到终端或波形窗口中加以视觉检视;4. 另外,将实际结果和预期结果进行比较。 一、构建Testbench 本文用VHDL来写,由于testbench只用来进行仿真,它们没有那些适用于综合的RTL语言子集的语法约束限制,而是所有的行为结构都可以使用。

所有testbench包含了以下的基本程序段:Entity and Architecture Declaration ;Signal Declaration ;Instantiation of Top-level Design ;Provide Stimulus. 在ISE工程中添加source:VHDL Test Bench到顶层文件,在source for 选项中选择Behavioral Simulation。你会发现Test Bench中有很多已经自动写好,可根据自己的设计需要改写程序。

其中Entity是空的,由于是仿真,不必有管脚的输入输出,只要写好激励信号就可以了。 二、双击Simulate Behavioral Model进行Modelsim仿真 我们在modelsim仿真的过程中,如果想改写激励程序,点击environment back(图中向左的箭头),回到激励程序的编写环境。

可以利用其提供的模板直接改写testbench,点source->show language template,需要将read only取消掉,否则无法改写。本人建议,在这个环境中可以看到模板,你可以根据需要将相应的语句拷到VHDL Testbench中去。

这里只是简单介绍如何用test bench来仿真VHDL程序,其中各种激励信号的编写、时序的安排要依靠设计的需要,这些只能靠平时不断的积累。 这里介绍的是从ISE中直接调用modelsim进行仿真,因此关于ISE和modelsim的关联也是大家经常遇到的问题。

这个下次再总结。

标签: testbench
  • 文章版权属于文章作者所有,转载请注明 https://dongkepu.com/zonghezhishi/gwrzz4.html