编写高效的测试设计test benches.docx
- 文档编号:24622241
- 上传时间:2023-05-29
- 格式:DOCX
- 页数:23
- 大小:241.31KB
编写高效的测试设计test benches.docx
《编写高效的测试设计test benches.docx》由会员分享,可在线阅读,更多相关《编写高效的测试设计test benches.docx(23页珍藏版)》请在冰豆网上搜索。
编写高效的测试设计testbenches
编写高效的测试设计(testbenches)
编写高效的测试设计(testbenches)
原文作者:
MujtabaHamid
注:
一个设计的测试验证是非常重要的。
有效的测试可以助我们快速的完成或改善设计。
Testbenches建议编写有效的测试代码来通过软件实现可靠的验证。
无意中发现,顺手译为中文,以备将来方便。
也贴给没有找到更好中文版本的同道人。
Testbenches本意应该是测试平台更合理,但是在中文中阅读起来很不舒服。
所以本文中有时译为“测试设计”,“测试代码”,有时干脆是“测试”。
摘要:
应用笔记为HDL验证设计的新手,或者是没有丰富的测试设计经验的逻辑设计者而编写。
测试设计是验证HDL设计的主要手段。
本应用笔记为创建或准备和构建有效的测试设计提供准则。
它也提供一个为任何设计开发自较验测的测试设计的一个代数方法。
涉及的所有设计文件可以从以下的站点获得:
PC:
ftp:
//
UNIX:
ftp:
//
简介:
由于设计的规模越来越大和越来越复杂,数字设计的验证已经成为一个日益困难和繁琐的事。
面对挑战,验证工程师们依靠许多的验证工具和方法。
对于大的系统,如几百万门的设计,工程师们一般使用一套可靠的验证工具。
当然,对于一些小的设计,设计工程师常常发现带有测试的hdl仿真器就可以做得很好。
测试设计已经成为一个验证高级语言设计HLL(High-LevelLanguage)的标准方法。
典型的,测试设计完成以下任务:
实现测试设计;
仿真通过使用模块的测试向量来仿真测试设计;
输出结果到终端或波形窗口以检视;
可选择的将实际结果和预期结果进行比较。
一般测试设计使用工业标准的VHDL或verilog硬件描述语言来编写。
测试设计调用功能设计,然后仿真。
复杂的测试设计完成一些附加的功能----如它们包含逻辑来为设计决定适当的设计激励或比较实际结果和预期结果。
后续的章节说明了一个非常稳定的测试设计的结构,并且提供了一个自较验测例子----它将自动比较实际结果和测试设计的预期结果。
图1说明一个基于以上基本要求的标准的hdl验证流程。
由于测试设计使用VHDL或verilogHDL来描述,测试设计的验证过程可以在不同的平台或不同公司的软件工具环境完成。
另外,由于VHDL或verilogHDL是公开的通用标准语言,使用VHDL或verilogHDL来描述验证设计可以毫无困难的在将来重用。
图1使用测试设计的HDL测试验证流程
构建测试设计:
测试设计可以用VHDL或verilogHDL来描述.因为测试设计只用来进行仿真,它们没有那些适应综合中仅应用的rtl语言子集的语法约束的限制.而是所有的行为结构都可以使用。
从而测试设计可以编写的更为通用,使得它们可以更容易维护。
所有的测试设计包含了如表1的基本程序段块。
正如上面所提到的,测试设计一般包含更多的附加功能,如在终端上可视的结果和内建的错误检测。
表1测试设计的基本程序段
下面的例子说明经常使用的测试设计的结构。
产生时钟信号
使用系统时钟来的时序逻辑设计必须产生时钟。
重复的时钟信号可以很容易的在vhdl或verilog源码中实现。
以下是vhdl和verilog的时钟发生示例。
VHDL:
--Declareaclockperiodconstant.
ConstantClockPeriod:
TIME:
=10ns;
--ClockGenerationmethod1:
Clock<=notClockafterClockPeriod/2;
--ClockGenerationmethod2:
GENERATECLOCK:
process
begin
waitfor(ClockPeriod/2)
Clock<=’1’;
waitfor(ClockPeriod/2)
Clock<=’0’;
endprocess;
Verilog:
//Declareaclockperiodconstant.
ParameterClockPeriod=10;
//ClockGenerationmethod1:
initialbegin
foreverClock=#(ClockPeriod/2)~Clock;
end
//ClockGenerationmethod2:
initialbegin
always#(ClockPeriod/2)Clock=~Clock;
end
准备激励信号
为了获得测试设计的验证结果,激励必须在测试设计中提供。
在测试设计中使用的并行激励块提供必要的激励。
两个方法被考虑:
绝对时间激励和相对时间激励。
在第一个方法里,仿真变量被详细描述为相对于仿真时间零点。
通过比较,相对时间激励提供初始值,然后在重触发激励前等待一个事件。
根据设计者的需要,两种方法可以在测试设计中组合使用。
表2绝对时间激励
表2和表3分别以vhdl和verilog提供了一个绝对时间激励和相对时间激励的源代码。
表3相对时间激励
VHDL进程块和Verilog初始块与设计文件中的其他的进程块或初始块同时执行。
然而,在每一个进程块或初始块中,事件是按照书写的顺序有序的规划的。
这说明在仿真时间零点并发的每一个块激励的顺序。
多模块应该被用来将复杂的激励顺序分解为有更好的可读性和方便维护的代码。
显示结果
在verilog中推荐使用关键字$display和$monitor显示结果。
虽然vhdl没有等效的显示指令,它提供了std_textio标准文本输入输出程序包。
它允许文件的i/o重定向到显示终端窗口(作为这个技术的示例,参看下面的自较验查验证设计)
下面是verilog示例,它将在终端屏幕上显示一些值。
//pipestheASCIIresultstotheterminalortexteditor
initialbegin
$timeformat(-9,1,"ns",12);
$display("TimeClkRstLdSftRgDataSel");
$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说明显示为八进制。
(参见verilog准则了解完整的关键字及格式描述符)
图2说明格式显示结果
图2仿真结果返回结果
简单的测试设计
简单的测试设计实例化用户设计,然后提供相应的激励。
测试输出被图形化显示在仿真器的波形窗口里或者作为文本发送到用户的终端或者是管道输出文本。
以下是一个简单的用Verilog实现的设计,它实现了一个移位寄存器的功能。
moduleshift_reg(clock,reset,load,sel,data,shiftreg);
inputclock;
inputreset;
inputload;
input[1:
0]sel;
input[4:
0]data;
output[4:
0]shiftreg;
reg[4:
0]shiftreg;
always@(posedgeclock)
begin
if(reset)
shiftreg=0;
elseif(load)
shiftreg=data;
else
case(sel)
2’b00:
shiftreg=shiftreg;
2’b01:
shiftreg=shiftreg<<1;
2’b10:
shiftreg=shiftreg>>1;
default:
shiftreg=shiftreg;
endcase
end
endmodule
以下是简单的测试设计示例移位寄存器设计的例子,verilog描述。
moduletestbench;//declaretestbenchname
regclock;
regload;
regreset;//declarationofsignals
wire[4:
0]shiftreg;
reg[4:
0]data;
reg[1:
0]sel;
//instantiationoftheshift_regdesignbelow
shift_regdut(.clock(clock),
.load(load),
.reset(reset),
.shiftreg(shiftreg),
.data(data),
.sel(sel));
//thisprocessblocksetsupthefreerunningclock
initialbegin
clock=0;
forever#50clock=~clock;
end
initialbegin//thisprocessblockspecifiesthestimulus.
reset=1;
data=5’b00000;
load=0;
sel=2’b00;
#200
reset=0;
load=1;
#200
data=5’b00001;
#100
sel=2’b01;
load=0;
#200
sel=2’b10;
#1000$stop;
end
initialbegin//thisprocessblockpipestheASCIIresultstothe
//terminalortexteditor
$timeformat(-9,1,"ns",12);
$display("TimeClkRstLdSftRgDataSel");
$monitor("%t%b%b%b%b%b%b",$realtime,
clock,reset,load,shiftreg,data,sel);
end
endmodule
以上的测试设计实例化设计,设置时钟,提供激励信号。
所有的进程块在仿真时间零点开始。
英镑标记(#)说明下一个激励作用前的延迟。
$stop命令使仿真器停止测试仿真(所有测试设计中都应该包含一个停止命令)。
最后,$monitor语句返回ascII格式的结果到屏幕或者管道输出到一个文本编辑器。
接后的是一个vhdl描述的的测试设计,它实例化设计并提供激励到上述用verilog描述的移位寄存器.
VHDL测试设计示例:
libraryIEEE;
useIEEE.std_logic_1164.all;
entitytestbenchis
endentitytestbench;
architecturetest_regoftestbenchis
componentshift_regis
port(clock:
instd_logic;
reset:
instd_logic;
load:
instd_logic;
sel:
instd_logic_vector(1downto0);
data:
instd_logic_vector(4downto0);
shiftreg:
outstd_logic_vector(4downto0));
endcomponent;
signalclock,reset,load:
std_logic;
signalshiftreg,data:
std_logic_vector(4downto0);
signalsel:
std_logic_vector(1downto0);
constantClockPeriod:
TIME:
=50ns;
begin
UUT:
shift_regportmap(clock=>clock,reset=>reset,
load=>load,data=>data,
shiftreg=>shiftreg);
processbegin
clock<=notclockafter(ClockPeriod/2);
endprocess;
processbegin
reset<=’1’;
data<="00000";
load<=’0’;
set<="00";
waitfor200ns;
reset<=’0’;
load<=’1’;
waitfor200ns;
data<="00001";
waitfor100ns;
sel<="01";
load<=’0’;
waitfor200ns;
sel<="10";
waitfor1000ns;
endprocess;
endarchitecturetest_reg;
上述vhdl测试设计与之前提到的verilog测试设计的功能是相似的,如希望用一个命令来返回输出到终端。
在vhdl中,std_textio程序包被用于在终端上显示信息,它将被搁到下一节说明。
自动验证
推荐自动实现测试结果的验证,尤其是对于较大的设计来说。
自动化减少了检查设计是否正确所要求的时间,也使人可能的犯错最少。
一般有以下几种常用的自动测试验证的方法:
1、数据库比较。
首先,要创建一个包含预期输出(一个黄金向量文件)的数据库文件。
然后,仿真输出被捕获并与黄金向量文件中参考的向量比较(在unix中的diff工具可以用来比较ascii数据文件)。
然而,因为从输出到输入文件指针没有提供,是这种方法的一个缺点,使得跟踪一个导致错误输出的原因比较困难。
2、波形比较。
波形比较可以自动或是手动的运行。
自动的方法使用一个测试比较器来比较黄金波形与测试输出波形。
xilinx的hdlbencher工具可以用于执行一个自动波形比较(关于hdlbencher的相关信息,请参看
3、自较验测试。
一个自较验测试检查预期的结果与运行时间的实际结果,并不是在仿真结束以后。
因为有用的错误跟踪信息可以内建在一个测试设计中,用来说明哪些地方设计有误,调试时间可以非常明显地缩短。
更多的关于自较验测试的信息在下一节说明。
自较验测试
自较验测试通过在一个测试文档中放置一系列的预期向量表来实现。
运行时间时间间隔将这些向量与定义好的实际仿真结果进行比较。
如果实际结果与预期结果匹配,仿真成功。
如果结果不匹配,测试报告两者的差异。
为同步设计实现自较验测试更简单一些,因为与实现的结果相比较可以在一个时钟沿或任何一个整数倍的时钟周期后。
比较的方法基于设计本身的特性。
比如一个用于内存I/O的测试应该检查每一次更新数据时的结果或者从一个内存位置读取。
类似的,如果一个设计用了一个显而易见的组合块的数字,在预期结果描述时,组合时延就必须要考虑。
在自较验测试中,预期输出与实际输出在一个特定的运行时间间隔比较以便提供自动的错误检查。
这个技术在小到中型的设计中非常好。
但是,因为当设计复杂后,可能的输出组合成指数倍的增长,为一个大型设计编写一个自较验测试设计是非常困难和非常费时的。
以下是一个用verilog和vhdl描述的自较验测试的简单的例子:
Verilog例子
下述的设计实例中,预期的结果被详细说明。
后面的代码,两种结果被比较,比较的结果被返回终端。
如果没有错误,一个“endofgoodsimulation”消息会显示。
如果失配发生,根据期望与实际值的失配情况,错误会被相应报告。
‘timescale1ns/1ps
moduletest_sc;
regtbreset,tbstrtstop;
regtbclk;
wire[6:
0]onesout,tensout;
wire[9:
0]tbtenthsout;
parametercycles=25;
reg[9:
0]Data_in_t[0:
cycles];
///////////////////////////////
//InstantiationoftheDesign
///////////////////////////////
stopwatchUUT(.CLK(tbclk),.RESET(tbreset),.STRTSTOP(tbstrtstop),
.ONESOUT(onesout),.TENSOUT(tensout),.TENTHSOUT(tbtenthsout));
wire[4:
0]tbonesout,tbtensout;
assigntbtensout=led2hex(tensout);
assigntbonesout=led2hex(onesout);
///////////////////////////////////////////////////////////////
//EXPECTEDRESULTS
///////////////////////////////////////////////////////////////
initialbegin
Data_in_t[1]=10’b1111111110;
Data_in_t[2]=10’b1111111101;
Data_in_t[3]=10’b1111111011;
Data_in_t[4]=10’b1111110111;
Data_in_t[5]=10’b1111101111;
Data_in_t[6]=10’b1111011111;
Data_in_t[7]=10’b1110111111;
Data_in_t[8]=10’b1101111111;
Data_in_t[9]=10’b1011111111;
Data_in_t[10]=10’b0111111111;
Data_in_t[11]=10’b1111111110;
Data_in_t[12]=10’b1111111110;
Data_in_t[13]=10’b1111111101;
Data_in_t[14]=10’b1111111011;
Data_in_t[15]=10’b1111110111;
Data_in_t[16]=10’b1111101111;
Data_in_t[17]=10’b1111011111;
Data_in_t[18]=10’b1110111111;
Data_in_t[19]=10’b1101111111;
Data_in_t[20]=10’b1011111111;
Data_in_t[21]=10’b0111111111;
Data_in_t[22]=10’b1111111110;
Data_in_t[23]=10’b1111111110;
Data_in_t[24]=10’b1111111101;
Data_in_t[25]=10’b1111111011;
end
regGSR;
assignglbl.GSR=GSR;
initialbegin
GSR=1;
/////////////////////////////////
//WaittillGlobalResetFinished
/////////////////////////////////
#100GSR=0;
end
//////////////////
//Createtheclock
//////////////////
initialbegin
tbclk=0;
//WaittillGlobalResetFinished,thencycleclock
#100forever#60tbclk=~tbclk;
end
initialbegin
////////////////////////////
//InitializeAllInputPorts
////////////////////////////
tbreset=1;
tbstrtstop=1;
///////////////////////
//ApplyDesignStimulus
///////////////////////
#240tbreset=0;
tbstrtstop=0;
#5000tbstrtstop=1;
#8125tbstrtstop=0;
#500tbstrtstop=1;
#875tbreset=1;
#375tbreset=0;
#700tbstrtstop=0;
#550tbstrtstop=1;
///////////////////////////////////////////////////////
//simulationmustbehaltedinsideaninitialstatement
///////////////////////////////////////////////////////
//#100000$stop;
end
integeri,errors;
///////////////////////////////////////////////////////////////////
///////////////
//Blockbelowcomparestheexpectedvs.actualresults
//ateverynegativeclockedge.
///////////////////////////////////////////////////////////////////
///////////////
always@(posedgetbclk)
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- 编写高效的测试设计test benches 编写 高效 测试 设计 test