编写高效率的testbench
Vivado HLS工程testbench的三个要素

编写高效Vivado HLS工程testbench的三个要素在C程序的设计中,任何一个C程序的顶层都是main()函数。
而在vivado HLS的设计中,只要函数的层次在main()函数以下,都可以被综合。
但是每个vivado HLS工程只能指定一个top层函数作为输出RTL模块的顶层,其它和这个函数层次平行,不需要被综合的函数都可以作为testbench来使用。
这样就带来一个问题,如何编写vivado HLS工程的testbench更高效,或者说能更好的让HLS工具自动重用C testbench 验证产生的RTL代码就变得非常重要。
通常,在Vivado HLS中,好的C testbench设计原则是testbench设计和需要实现的算法函数分别保存在不同的文件中,并且充分利用头文件。
Testbench 常常包含了一些HLS综合不支持的操作,比如通过文件的读写取得仿真数据并保存结果,或者打印一些测试结果进行分析。
在头文件中,完成对testbench中所有的数据类型和函数的定义,以及包含共享的设计文件和函数库。
Vivado HLS中,只能指定一个top层函数用于综合,top层函数可以包含多个子函数。
当需要综合多个并行层次的函数时,可以编写一个wrapper函数作为top层函数,将需要综合的多个并行函数封装起来。
C testbench的目不仅是要验证需要综合的top函数功能正确(C编译器验证环境),同时重用C testbench作为综合产生RTL代码的仿真激励,HLS工具自动调用C testbench来验证RTL功能的一致性(C编译器和RTL仿真器的协同仿真环境)。
这样,编写一个好的风格testbench可以很好的提高设计的验证效率,如果在HLS综合前和综合过程中,需要修改综合函数的代码,可以用testbench 验证,确保需要综合的C算法功能正确。
Vivado HLS中推荐高效的testbench具有如下三个特征:1.Testbench代码和需要综合的C算法代码保存在不同的文件中(例子1-1)。
如何写testbench

如何编写testbench今天,我来带领大家写一个简单的testbench ,顺便讲解如何写好一个testbench 以及写testbench 时应该注意的地方。
在讲解testbench 之前,我们先看一下前面的那个AND_2程序的仿真图,如下:如上图中所标,在1处,B 已经为低电平了,但是输出C 仍然为高电平,这样求与运算就会出错。
在2处,A 和B 都是低电平了,C 仍然为高电平,直到下次出现时钟的上升沿为止,为什么会这样呢?编译的时候并没有报错,呵呵,出了怪事了啊!其实编译器只能检查处语法错误,无法检测到逻辑错误,这个图给出的结果和我们程序所表达的结果一样,但是这并不是我们所要的求与运算,我们想要的是A 和B 同时为高电平时,C 才输出高电平。
我们把程序的敏感列表改为:always@(posedge clk or negedge rst or A or B)就可以了,把A 的电平改变和B的电平改变都加进敏感列表,激励不变,所得到的仿真图:这才是我们所要的求与运算!好了,现在开始讲如何写testbench 。
Testbench 不像RTL 级代码,可以用高级行为语句,不用考虑其可综合性,这样就能写出高效的检测代码。
在语法上,testbench 和可综合代码一样,都是类C 结构。
好了,我们开始吧!1,建立工程等,与之前的一样,但是在创建文件的时候,我们一次创建两个。
取名分别为ParallelSerial_Mult 和ParallelSerial_Mult_test。
创建完成后,如下图:这两个代码分别如下:moduleParallelSerial_Mult(Clk,Rst,MultiplicandIn,MultiplierIn,Load,Product,Out_en);parameter N=8;parameter CYCLES=3;input Clk,Rst,Load;input[N-1:0]MultiplicandIn,MultiplierIn;output[2*N-1:0]Product;output Out_en;reg[2*N-1:0]Product;wire Out_en;reg[N-1:0]Multiplicand;reg[2*N-1:0]NextProduct;reg[CYCLES:0]Count;reg Busy;wire[N-1:0]Sum;wire Carry;assign{Carry,Sum}=Multiplicand+Product[2*N-1:N];assign Out_en=Count[CYCLES];always@(posedge Clk or negedge Rst)if(!Rst)beginMultiplicand<=0;Count<=0;Product<=0;Busy<=0;endelsebeginProduct<=NextProduct;if(Load)beginMultiplicand<=MultiplicandIn;Count<=0;Busy<=1'b1;endelsebeginif(Busy)Count<=Count+1'b1;if(Count[CYCLES])beginCount<=0;Busy<=1'b0;endendendalways@(Load or MultiplierIn or Product or Count[CYCLES]or Carry or Sum) casex({Product[0],Count[CYCLES],Load})3'bxx1:NextProduct={{N{1'b0}},MultiplierIn[N-1:0]};3'b100:NextProduct={Carry,Sum,Product[N-1:1]};3'b000:NextProduct={1'b0,Product[2*N-1:1]};default:NextProduct=Product;endcaseendmodule这个代码是书中第120页的8位乘法器。
testbench的写法

首先对TESTBENCH作一个形象一些的比喻吧,它就象是一个面包板(做过电路实验吧),他对外没有任何接口,但它要向要插在他上面的器件提供接口,这样才能正确的插入,还有它必须对插在它上面的器件提供正常的信号。
当然在它上面还必须要有这个器件。
这时就完成了一个TESTBENCH。
应该大概明白了其中的意思了吧。
好了,根据上面的比喻我们可以非常明确的知道一个TESTBENCH要写一些什么东西,首先它对外无接口,所以它的实体部分是空的。
在它上面要有相应的器件,所以在它的结构体中要申明我们要测试的器件,也就是component的申明。
还有就是它要对器件提供接口,所以它的结构体应该提供一些信号,并且要对这些信号进行正确的测试赋值。
当然还要进行一些插入工作,就是信号的对应工作。
这样一个TESTBENCH就完成了。
原理很简单的,应该很容易明白。
不过在真正的测试中可能不会用太多的这种方式吧,应该会选用测试向量吧,这个的准确性更高一些。
不过怎么样写测试向量,这到是一个有大学问的东西,因为当我们的管脚很多的时候,测试的向量数目是要心指数增长的,当然不可能把所有的情况都测试完成了,只有是测试其中的一部分,这儿怎么样写出有代表性的一组测试向量是很有学问的,应该说是研究的热点吧。
下面给一个测试向量的例子,这是在网上找的代码,可能对大家有帮助吧。
这是一个计数器的测试向量。
library ieee;use ieee.std_logic_1164.all;use ieee.std_logic_unsigned.all;entity counter isport(clk: in std_logic;reset: in std_logic;en: in std_logic;q: out std_logic_vector(3 downto 0));end counter;architecture behave of counter issignal q_n: std_logic_vector(3 downto 0);beginprocess(clk, reset, en, q_n)beginif (reset = '1') thenq_n <= (others => '0');--异步清零elsif rising_edge(clk) thenif en = '1' thenq_n <= q_n + 1;end if;end if;end process;q <= q_n;end behave;library ieee;use ieee.std_logic_1164.all;use ieee.std_logic_unsigned.all;entity testbench is //一个空的实体,没有输入和输出。
简单的Testbench设计

//被测设计的输入信号,对应测试脚本的输出信号(注意要定义成 reg) reg clk; reg rst_n; //被测设计的输出信号,对应测试脚本的输入信号(注意要定义成 wire) wire led; //例化待测模块 Led led_test
简单的 Testbench nch 是一种验证的手段。首先,任何设计都是会有输入输出的。 但是在软环境中没有激励输入,也不会对你设计的输出正确性进行评估。那 幺此时便有一种,模拟实际环境的输入激励和输出校验的一种“虚拟平台”的 产生。在这个平台上你可以对你的设计从软件层面上进行分析和校验,这个 就是 testbench 的含义。 简单的 Testbench 设计 //timescale 仿真时间单位/时间精度(时间精度不能比时间单位还要 大) timescale 1ns/1ps //定义一个无输入无输出的 Moudle module Led_clg_tst();
( .clk(clk), .rst_n(rst_n), .led(led) ); //使用 Initail 生成 rst_n 激励 initial begin //监控 Led 信号变化
monitor(monitor(time,”led value= %b\n”,led); end //使用 alwasys 模拟产生 25M 的时钟信号 always #20 clk = ~clk; endmodule
怎样写testbench

怎样写testbench本文的实际编程环境:ISE 6.2i.03ModelSim 5.8 SESynplify Pro 7.6编程语言 VHDL在ISE中调用ModelSim进行仿真一、基本概念和基础知识Testbench不仅要产生激励也就是输入,还要验证响应也就是输出。
当然也可以只产生激励,然后通过波形窗口通过人工的方法去验证波形,这种方法只能适用于小规模的设计。
在ISE环境中,当前资源操作窗显示了资源管理窗口中选中的资源文件能进行的相关操作。
在资源管理窗口选中了testbench文件后,在当前资源操作窗显示的ModelSim Simulator中显示了4种能进行的模拟操作,分别是:Simulator Behavioral Model(功能仿真)、Simulator Post-translate VHDL Model(翻译后仿真)、Simulator Post-Map VHDL Model(映射后仿真)、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也就是映射后仿真。
不同的器件内部结构也不尽相同,映射的作用就是将综合后产生的网表文件对应到实际的器件上去。
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。
如上所属,测试文件经常同时包含附加功能,如结果的可视化显示和内建错误检测。
Vivado HLS工程testbench的三个要素
编写高效Vivado HLS工程testbench的三个要素在C程序的设计中,任何一个C程序的顶层都是main()函数。
而在vivado HLS的设计中,只要函数的层次在main()函数以下,都可以被综合。
但是每个vivado HLS工程只能指定一个top层函数作为输出RTL模块的顶层,其它和这个函数层次平行,不需要被综合的函数都可以作为testbench来使用。
这样就带来一个问题,如何编写vivado HLS工程的testbench更高效,或者说能更好的让HLS工具自动重用C testbench 验证产生的RTL代码就变得非常重要。
通常,在Vivado HLS中,好的C testbench设计原则是testbench设计和需要实现的算法函数分别保存在不同的文件中,并且充分利用头文件。
Testbench常常包含了一些HLS综合不支持的操作,比如通过文件的读写取得仿真数据并保存结果,或者打印一些测试结果进行分析。
在头文件中,完成对testbench中所有的数据类型和函数的定义,以及包含共享的设计文件和函数库。
Vivado HLS中,只能指定一个top层函数用于综合,top层函数可以包含多个子函数。
当需要综合多个并行层次的函数时,可以编写一个wrapper函数作为top层函数,将需要综合的多个并行函数封装起来。
C testbench的目不仅是要验证需要综合的top函数功能正确(C编译器验证环境),同时重用C testbench作为综合产生RTL代码的仿真激励,HLS工具自动调用C testbench来验证RTL功能的一致性(C编译器和RTL 仿真器的协同仿真环境)。
这样,编写一个好的风格testbench可以很好的提高设计的验证效率,如果在HLS综合前和综合过程中,需要修改综合函数的代码,可以用testbench验证,确保需要综合的C算法功能正确。
Vivado HLS中推荐高效的testbench具有如下三个特征:1.Testbench代码和需要综合的C算法代码保存在不同的文件中(例子1-1)。
testbench万能模版
`timescale 1ns/1ps // 定义时间单位和精度//定义仿真时间initial begin#10000 finish;end//设计顶层模块testbenchmodule testbench;//定义内部的信号变量以及类型wire [7:0]count; //线型定义输出端,连接各模块的输出端口,用线连接没有记忆reg clk; //寄存器定义激励信号,连接各模块的输入端口,具有记忆功能reg reset; //两个最基本的激励信号//固定参数的赋值,状态的编码/***parameter tpd_reset_to_count = 3 ;parameter tpd_clk_to_count = 2 ; **///变量初始化/**initial begina=b;b=c;c=d;end **///时钟设置always #500 clk=~clk;initialbeginclk =1;reset=0; //一般是低电平复位#100clk =0;reset=1;end//调用函数用modelsim生成fsdb文件initialbegin$fsdbDumpfile("wave_test.fsdb");$fsdbDumpvars(0);end//调用模块与顶层模块的各个端口的连接(一一对应时自动连接)filename u1(.cp(clk),.clr(reset),.RSTSM(),.DQ_IN(),.MASTER_CNT(),.SLA VE_CNT());//调用输出图像的函数integer fid;initialbeginfid=$fopen("report.txt","w+");#1000000$fclose(fid);endalways @ (posedge clk negedge reset) $display(fid,"timerh=%d",timerh);endmodule //结束顶层模块。
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编写的关键步骤之一。
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
Writing Efficient Testbenches编写高效的测试设计(testbenches)原文作者:Mujtaba Hamid注:一个设计的测试验证是非常重要的。
有效的测试可以助我们快速的完成或改善设计。
Testbenches建议编写有效的测试代码来通过软件实现可靠的验证。
无意中发现,顺手译为中文,以备将来方便。
也贴给没有找到更好中文版本的同道人。
Testbenches本意应该是测试平台更合理,但是在中文中阅读起来很不舒服。
所以本文中有时译为“测试设计”,“测试代码”,有时干脆是“测试”。
摘要:应用笔记为HDL验证设计的新手,或者是没有丰富的测试设计经验的逻辑设计者而编写。
测试设计是验证HDL设计的主要手段。
本应用笔记为创建或准备和构建有效的测试设计提供准则。
它也提供一个为任何设计开发自较验测的测试设计的一个代数方法。
涉及的所有设计文件可以从以下的站点获得:PC: ftp:///pub/applications/xapp/xapp199.zipUNIX: ftp:///pub/applications/xapp/xapp199.tar.gz简介:由于设计的规模越来越大也越来越复杂,数字设计的验证已经成为一个日益困难和繁琐的任务。
验证工程师们依靠一些验证工具和方法来应付这个挑战。
对于几百万门的大型设计,工程师们一般使用一套形式验证(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 可以编写的更为通用,使得它们可以更容易维护。
所有testbench包含了如表1的基本程序段。
正如上面所提到的,testbench通常包含附加功能,如在终端上可视的结果和内建的错误检测。
表1 testbench的基本程序段下面的例子介绍testbench中经常使用的结构。
产生时钟信号使用系统时钟的时序逻辑设计必须产生时钟。
时钟信号在VHDL或Verilog中可以很容易地实现。
以下是VHDL和Verilog的时钟发生示例。
VHDL:-- Declare a clock period constant.Constant ClockPeriod : TIME := 10 ns;-- Clock Generation method 1:Clock <= not Clock after ClockPeriod / 2;-- Clock Generation method 2:GENERATE CLOCK: processbeginwait for (ClockPeriod / 2)Clock <= ’1’;wait for (ClockPeriod / 2)Clock <= ’0’;end process;Verilog:// Declare a clock period constant.Parameter ClockPeriod = 10;// Clock Generation method 1:initial beginClock = 0;forever Clock = #(ClockPeriod / 2) ~ Clock;end// Clock Generation method 2:always #(ClockPeriod / 2) Clock = ~Clock;提供激励信号为了获得testbench的验证结果,激励必须作用于DUT。
在testbench中使用的并行激励块提供必要的激励。
激励的产生可以采用两个方法:绝对时间激励和相对时间激励。
在第一个方法里,仿真变量相对于仿真时间零点进行详细描述。
相对而言,相对时间激励提供初始值,然后等待一个事件来重新触发激励。
根据设计者的需要,两种方法可以在testbench中同时使用。
下面的程序段是绝对时间激励的例子。
initial beginreset = 1;load = 0;cout_updn = 0;#100 reset = 0;#20 load = 1;#20 count_updn = 1;end下面的程序段是相对时间激励的例子。
always @(posedge clock)tb_count <= tb_count + 1;initial beginif(tb_count <= 5)beginreset = 1;load = 0;count_updn = 0;endelsebeginreset = 0;load = 1;count_updn = 1;endendinitial beginif(count = 1100) begincount_updn <= 0;$display(“Terminal count Reached,now counting down”);endendVerilog的initial块与文件中的其他initial块是同时执行。
然而,在每一个initial块中,事件是按照书写的顺序执行的。
这说明在每一个并行块中的激励序列从序仿真时间零点开始。
为了代码有更好的可读性和更方便的可维护性,应采用多个块来分割复杂的测试激励。
显示结果在Verilog中可以非常方便地使用系统函数$display()和$monitor()显示结果。
VHDL 没有等效的显示指令,它提供了std_textio标准文本输入输出程序包。
它允许文件的i/o重定向到显示终端窗口(作为这个技术的示例,参看下面的自较验查验证设计)下面是verilog示例,它将在终端屏幕上显示一些值。
// pipes the ASCII results to the terminal or text editorinitial begin$timeformat(-9,1,"ns",12);$display(" Time Clk Rst Ld SftRg Data Sel");$monitor("%t %b %b %b %b %b %b", $realtime,clock, reset, load, shiftreg, data, sel);end系统函数$display在终端屏幕上输出引用的附加说明文字(“。
”)。
系统函数$monitor操作不同。
因为它的输出是事件驱动的。
例中的变量$realtime(由用户赋值到当前的仿真时间)用于触发信号列表中值的显示。
信号表由变量$realtime开始,跟随其他将要显示的信号名(clock, reset, load等)。
以%开始的关键字包含一个格式描述的表,用来控制如何格式化显示信号列表中的每个信号的值。
格式列表是位置确定的。
每个格式说明有序地与信号列表中的信号顺序相关。
比如%t说明规定了$realtime的值是时间格式。
并且第一个%b说明符格式化clock的值是二进制形式。
Verilog提供附加的格式说明,比如%h用于说明十六进制,%d说明十进制,%c说明显示为八进制。
图2说明格式显示结果图2仿真结果简单的testbench实例化用户设计,然后提供相应的激励。
测试输出被图形化显示在仿真器的波形窗口里或者作为文本发送到用户的终端或者是管道输出文本。
以下是一个简单的用Verilog实现的设计,它实现了一个移位寄存器的功能。
module shift_reg (clock, reset, load, sel, data, shiftreg);input clock;input reset;input load;input [1:0] sel;input [4:0] data;output [4:0] shiftreg;reg [4:0] shiftreg;always @ (posedge clock)beginif (reset)shiftreg = 0;else if (load)shiftreg = data;elsecase (sel)2’b00 : shiftreg = shiftreg;2’b01 : shiftreg = shiftreg << 1;2’b10 : shiftreg = shiftreg >> 1;default : shiftreg = shiftreg;endcaseendendmodule以下是简单的testbench,示例移位寄存器设计的例子verilog描述。
module testbench; // declare testbench namereg clock;reg load;reg reset; // declaration of signalswire [4:0] shiftreg;reg [4:0] data;reg [1:0] sel;// instantiation of the shift_reg design belowshift_reg dut(.clock (clock),.load (load),.reset (reset),.shiftreg (shiftreg),.data (data),.sel (sel));//this process block sets up the free running clockclock = 0;forever #50 clock = ~clock;endinitial begin// this process block specifies the stimulus.reset = 1;data = 5’b00000;load = 0;sel = 2’b00;#200reset = 0;load = 1;#200data = 5’b00001;#100sel = 2’b01;load = 0;#200sel = 2’b10;#1000 $stop;endinitial begin// this process block pipes the ASCII results to the//terminal or text editor$timeformat(-9,1,"ns",12);$display(" Time Clk Rst Ld SftRg Data Sel");$monitor("%t %b %b %b %b %b %b", $realtime,clock, reset, load, shiftreg, data, sel);endendmodule以上的testbench实例化设计,设置时钟,提供激励信号。