Verilog-testbench的写法
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简介:由于设计的规模越来越大也越来越复杂,数字设计的验证已经成为一个日益困难和繁琐的任务。
验证工程师们依靠一些验证工具和方法来应付这个挑战。
对于几百万门的大型设计,工程师们一般使用一套形式验证(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可以编写的更为通用,使得它们可以更容易维护。
test bench 教程

最近项目上要用到FPGA,之前用的一直是verilog,后面换成了VHDL。
对ISE一窍不通啊,研究了一些testbench文件的编写,record一下。
借用一下博文/lovelink/item/ff34ce9b12f45988581461ac的话。
首先对TESTBENCH作一个形象一些的比喻吧,它就象是一个面包板(做过电路实验吧),他对外没有任何接口,但它要向要插在他上面的器件提供接口,这样才能正确的插入,还有它必须对插在它上面的器件提供正常的信号。
当然在它上面还必须要有这个器件。
这时就完成了一个TESTBENCH。
应该大概明白了其中的意思了吧。
好了,根据上面的比喻我们可以非常明确的知道一个TESTBENCH要写一些什么东西,首先它对外无接口,所以它的实体部分是空的。
在它上面要有相应的器件,所以在它的结构体中要申明我们要测试的器件,也就是component的申明。
还有就是它要对器件提供接口,所以它的结构体应该提供一些信号,并且要对这些信号进行正确的测试赋值。
当然还要进行一些插入工作,就是信号的对应工作。
这样一个TESTBENCH就完成了。
原理很简单的,应该很容易明白。
不过在真正的测试中可能不会用太多的这种方式吧,应该会选用测试向量吧,这个的准确性更高一些。
不过怎么样写测试向量,这到是一个有大学问的东西,因为当我们的管脚很多的时候,测试的向量数目是要心指数增长的,当然不可能把所有的情况都测试完成了,只有是测试其中的一部分,这儿怎么样写出有代表性的一组测试向量是很有学问的,应该说是研究的热点吧。
几个testbench要用到的重要语句:(1)wait:无限等待,表示永远挂起,对于汉语wait语句的进程来说,进程在一开始执行一次后面就不执行了;(2)wait on 信号表:敏感信号等待语句,等待敏感信号表中的信号发生变化才执行;(3)wait until 表达式:条件等待语句,当条件表达式中所含的信号发生了变化,并为true时,进程才脱离等待状态;(4)wait for 时间表达式:此语句中声明了一个时间段,从从执行到当前的wait语句开始,只要这个时间段内,进程处于等待状态,超过这段时间,进程自动恢复执行该等待语句的下一条语句。
组合-时序逻辑电路Verilog-Testbench代码_带仿真代码和波形_

1组合逻辑电路--基本门电路1.1基本门电路1.1.1结构化描述方式代码如下View Code1 module logics2 (3 input iA,4 input iB,5 output oAnd,6 output oOr,7 output oNot8 );910 and and_inst(oAnd,iA,iB);11 or or_inst(oOr,iA,iB);12 not not_inst(oNot,iA);1314 endmodule最底层的是门级原语and or not RTL级视图testbench如下View Code1 `timescale 1 ns/ 1 ns2 module logics_tb();34 reg ia;5 reg ib;67 wire oAnd;8 wire oOr;9 wire oNot;1011 initial12 begin13 ia=0;14 #40 ia=1;15 #40 ia=0;16 #40 ia=1;17 #40 ia=0;18 end1920 initial21 begin22 ib=0;23 #40 ib=0;24 #40 ib=1;25 #40 ib=1;26 #40 ib=0;27 end2829 logics logics_inst30 (31 .iA(ia),32 .iB(ib),33 .oAnd(oAnd),34 .oOr(oOr),35 .oNot(oNot)36 );3738 endmoduleRTL级仿真图形如下GATE级仿真图如下可见RTL级仿真是理想的,GATE级仿真考虑了延迟和信号开始的不确定。
1.1.2采用流描述方法代码如下View Code1 module logics2 (3 input iA,4 input iB,5 output oAnd,6 output oOr,7 output oNot8 );910 assign oAnd=iA&iB;11 assign oOr=iA|iB;12 assign oNot=~iA;1314 endmoduleRTL级视图,仿真图形同上。
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 的基本语法。
在具体的测试中,需要根据设计的功能和需求来给输入信号赋值,并检查输出信号和预期结果是否一致。
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包含文件•包含文件用于读入代码的重复部分或公共数据。
如何编写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⼯具查看),适⽤于对较⼤的系统进⾏仿真,速度快,优于全局仿真。
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’即高阻态。
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、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
• 一个更为复杂的 一个更为复杂的test bench可以: 可以: 可以 – 不但能报告错误 , 而能进行一些动作 , 如取消一个激励块并跳 不但能报告错误,而能进行一些动作, 转到下一个激励。 转到下一个激励。 – 在内部保持错误跟踪 , 并在每次测试结束时产生一个错误报告 。 在内部保持错误跟踪,并在每次测试结束时产生一个错误报告。
并行块
• fork…join块在测试文件中很常用。他们的并行特性使用户可以说明 块在测试文件中很常用。 块在测试文件中很常用 绝对时间,并且可以并行的执行复杂的过程结构,如循环或任务。 绝对时间,并且可以并行的执行复杂的过程结构,如循环或任务。
module inline_ tb; reg [7: 0] data_ bus; // instance of DUT initial fork data_bus = 8'b00; #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; join endmodule 上面的两个repeat循环从不同时间开始,并行执行。 象这样的特殊的激励集在单个的begin…end块中 将很难实现。
设计组织
虚线表示编译时检测输入文件是否存在及可读并允许生成输出文件。
bench组织 test bench组织
stimulus
要验证的设计
简单的test bench
激励 要验证的设计 验证结果 复杂的test bench
• 简单的 简单的test bench向要验证的设计提供向量,人工验证输出。 向要验证的设计提供向量, 向要验证的设计提供向量 人工验证输出。 • 复杂的test bench是自检测的,其结果自动验证。 是自检测的,其结果自动验证。 复杂的 是自检测的
包含文件
• 包含文件用于读入代码的重复部分或公共数据。 包含文件用于读入代码的重复部分或公共数据。
module clk_gen (clk); output clk; reg clk; `include "common.txt" initial begin while ($ time < sim_end) begin clk = initial_clock; #(period/2) clk = !initial_clock; #(period/2); end $finish; end endmodule // common. txt // clock and simulator constants parameter initial_clock = 1; parameter period = 15; parameter max_cyc = 100; parameter sim_end = period * max_cyc
线性激励
• 线性激励有以下特性: 线性激励有以下特性: 只有变量的值改变时才列出 易于定义复杂的时序关系 对一个复杂的测试,测试基准(test bench)可能非常大 对一个复杂的测试,测试基准 可能非常大
module inline_ tb; reg [7: 0] data_ bus, addr; wire [7: 0] results; DUT u1 (results, data_ bus, addr); initial fork data_bus = 8'h00; addr = 8'h3f; #10 data_ bus = 8'h45; #15 addr = 8'hf0; #40 data_ bus = 8'h0f; #60 $finish; join endmodule
矢量回放
• 保存在文件中的矢量反过来可以作为激励
module read_file_tb; parameter num_vecs = 256; reg [7:0] data_bus; reg [7:0] stim [num_vecs-1:0]; integer i; DUT u1 (results, data_bus) initial begin // Vectors are loaded $readmemb ("vec. txt", stim); for (i =0; i < num_vecs ; i = i + 1) #50 data_bus = stim[i]; end endmodule // 激励文件 激励文件vec.txt 00111000 00111001 00111010 00111100 00110000 00101000 00011000 01111000 10111000 . .
数字集成电路设计入门 --从HDL到版图
于敦山
北大微电子学系
Bench使用简介 第十五章 Verilog Test Bench使用简介
学习内容: 学习内容: • 用一个复杂的 用一个复杂的test bench复习设计的组织与仿真 复习设计的组织与仿真 • 建立 建立test bench通常使用的编码风格及方法 通常使用的编码风格及方法
• 使用矢量文件输入 输出的优点: 使用矢量文件输入/输出的优点: 输出的优点 – 激励修改简单 – 设计反复验证时直接使用工具比较矢量文件。 设计反复验证时直接使用工具比较矢量文件。
错误及警告报告
• 使用文本或文件输出类的系统任务报告错误及警告
always @( posedge par_err) $display (" error-bus parity errors detected"); always @( posedge cor_err) $display("warning-correctable error detected");
矢量采样
• 在仿真过程中可以对激励和响应矢量进行采样,作为其它仿真的激 在仿真过程中可以对激励和响应矢量进行采样, 励和期望结果。 励和期望结果。
module capture_tb; parameter period = 20 reg [7:0] in_vec, out_vec; integer RESULTS, STIMULUS; DUT u1 (out_ vec, in_ vec); initial begin STIMULUS = $fopen("stimulus. txt") ; RESULTS = $fopen("results. txt") ; fork if (STIMULUS != 0 ) forever #( period/2) $fstrobeb (STIMULUS, "%b", in_vec); if (RESULTS != 0 ) #( period/2) forever #( period/2) $fstrobeb (RESULTS, "%b", out_vec); join end endmodule
在上面的例子中,公共参数在一个独立的文件中定义。 在上面的例子中,公共参数在一个独立的文件中定义。此文件在不同 的仿真中可被不同的测试文件调用。 的仿真中可被不同的测试文件调用。
施加激励
种方法。一些常用的方法有: 产生激励并加到设计有很多 种方法。一些常用的方法有: • 从一个 从一个initial块中施加线激励 块中施加线激励 • 从一个循环或 从一个循环或always块施加激励 块施加激励 • 从一个向量或整数数组施加激励 • 记录一个仿真过程,然后在另一个仿真中回放施加激励 记录一个仿真过程,
•
•
强制激励
在上面两个例子中, 上所赋的常数值, 在上面两个例子中,在 net或register上所赋的常数值,覆盖所有在时刻 和时刻 或 上所赋的常数值 覆盖所有在时刻10和时刻 20之间可能发生在该信号上的其他任何赋值或驱动。如果所赋值是一个表达式, 之间可能发生在该信号上的其他任何赋值或驱动。 之间可能发生在该信号上的其他任何赋值或驱动 如果所赋值是一个表达式, 则该表达式将被持续计算。 则该表达式将被持续计算。 • • • • • • 可以强制(force)并释放一个信号的指定位、部分位或连接,但位的指定不能 并释放一个信号的指定位、部分位或连接, 可以强制 并释放一个信号的指定位 是一个变量(例如out_vec[i]) 是一个变量(例如 ) 不能对register的一位或部分位使用 的一位或部分位使用assign和deassign 不能对 的一位或部分位使用 和 对同一个信号, 覆盖assign。 对同一个信号,force覆盖 覆盖 。 后面的assign或force语句覆盖以前相同类型的语句。 语句覆盖以前相同类型的语句。 后面的 或 语句覆盖以前相同类型的语句 如果对一个信号先assign然后 如果对一个信号先 然后force,它将保持force值。在对其进行release后, ,它将保持 值 在对其进行 后 然后 信号为assign值。 信号为 值 如果在一个信号上force多个值,然后 多个值, 该信号, 如果在一个信号上 多个值 然后release该信号,则不出现任何 该信号 则不出现任何force值。 值
数组激励
• 从数组产生激励有以下特性: 从数组产生激励有以下特性: 在每次反复中, 在每次反复中,修改同一组激励变量 激励数组可以直接从文件中读取
module array_ tb; reg [7: 0] data_ bus, stim_ array[ 0: 15]; // 数 组 integer i; DUT u1 (results, stimulus); initial begin // 从数组读入数据 #20 stimulus = stim_array[0]; #30 stimulus = stim_array[15]; // 线激励 #20 stimulus = stim_array[1]; for (i = 14; i > 1; i = i - 1) // 循环 #50 stimulus = stim_array[i] ; #30 $finish; end endmodule