版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领
文档简介
编写Testbench激励与响应吴宗军2003.092--WriteTestbench--可编程器件及IC验证措施小规模设计的电路适用的验证方法1、仿真2、PCB板上的物理测试;因规模小,时序和功能验证不复杂,基本不需其它验证措施。大规模设计的电路适用的验证方法1、仿真2、物理测试3、一致性验证4、静态时序分析5、(IC用)DFT和ATPG3--WriteTestbench--一、编写测试向量的目的RTL功能仿真;FPGA功能及时序仿真;ASIC后端流程的前/后仿真;ASIC样片在测试机台上的测试。*在所有阶段,都要用到RTL设计者设计的测试向量,随着ASIC流程的进行,该测试向量格式会发生变化。*在ASIC阶段,还要用到DFT、MEMBIST生成的测试向量,由EDA工具生动生成。4--WriteTestbench--二、测试向量的简要流程5--WriteTestbench--用HDL编写测试向量和直接画时序图仿真方法的比较画图仿真方法优点:直观、简单、方便。缺点:适用于信号数量不多、测试深度不长、简单协议的仿真,波形的调整不方便,如想改变时钟频率,输入信号的setup/holdtime都不方便;同时观察仿真的结果正确与否需人工进行。HDL编写的测试向量缺点:不够简单和方便,波形也不直观。依据设计者的熟练程度而异。优点:信号数量可以很多,测试深度任意,尤其适用于有复杂协议(如PCI、以太网、无线协议等)的仿真,仿真状态的调整方便,甚至于仿真结果的分析都可由测试向量自动进行,可在整个设计流程中使用同一测试向量,自动检测分析本流程的设计结果。一个优秀的测试向量需要有一个同样优秀的设计相配合,它们之间是相互监督的关系。6--WriteTestbench--三、ASIC前/后仿真及芯片测试机台的测试向量通用格式要求有输出检测;测试向量中只能有一个主控时钟;以主控时钟的CYCLE宽度为测试周期,一个周期内输入信号只能改变一次;输入信号(包括双向口处于非输出模式时)必须确定,即不能为0或1以外的值;输出信号尽量控制使其不要处在除0和1以外的其它状态;一般的测试机台不能检测输出信号的高阻态输出;7--WriteTestbench--四、推荐测试向量格式Inputdelay和outputstrobetime的值均可调节8--WriteTestbench--五、测试向量时钟设计1、要求:因测试向量中只能有一个主控时钟,所以要求RTL代码中时钟数(树)尽可能少,不同时钟之间最好要有同相,同频,倍频的关系,以免X状态的传递导致整个仿真的崩溃。时钟以高电平开始第一个CYCLE,这样形成的第一个CYCLE是一个完整的CYCLE。2、实例:parameterPCY=40,PHC=20,SCY=20,SHC=10;initialbeginRX_ZT_PCLK<=1;forever#PHCRX_ZT_PCLK<=~RX_ZT_PCLK;end9--WriteTestbench--六、输入信号处理要求:基于时钟CYCLE,每个CYCLE仅可变化一次,按INPUTDELAY来调节输入延迟,以达到在不同测试要求测试TSU,THD的需要,尽量不要用动态的数值来控制输入延迟。原因:ASIC测试向量每一个输入的INPUTDELAY在整个测试向量过程中不会改变。例:parameterPCY=40,PHC=20,indelay=2;#indelay;//initialinputdelay;RTX_ZT_PFRAME_tb<=0;RTX_ZT_PIRDY_tb<=0;RX_ZT_PIDSEL<=1;#PCY;RTX_ZT_PFRAME_tb<=1;RX_ZT_PIDSEL<=0;RTX_ZT_PCBE_tb<=4'b0000;//ALLBYTEENABLED;if(i==0)RTX_ZT_PAD_tb<=32'h55555555;//write;elseif(i==2)RTX_ZT_PAD_tb<=32'haaaaaaaa;//write;elseRTX_ZT_PAD_tb<=32'hZZZZZZZZ;//read;#(PCY*3-indelay);//rightattherisingedgeofclk;andwaitfortargetack;while(!PCI_DATA_TRANSFER)#PCY;#indelay;//2nsaftertherisisngedgeofclk;RTX_ZT_PIRDY_tb<=1;#(PCY*10);10--WriteTestbench--七、复位信号处理要求:复位信号按普通信号处理;复位信号能迅速控制整个芯片和所有输出的状态,这是对RTL代码设计者的要求,这主要是良好的电路结构的需要,附带也会节省测试向量的工作;测试设备有可能将数个不足长的测试向量合并成一个测试向量,通过复位来分隔它们,如果复位不能清掉上次测试在芯片内部留下的状态和输出,则会影响到下一段测试向量。11--WriteTestbench--八、双向信号处理要求:RTL代码设计过程中,要分离出In,Out,Out_en三部分,一方面,ASIC芯片的双向IO设计时需要这分离的三部分信号;另一方面,ASIC测试机台无法自动决定双向管脚何时该输入,何时该输出,它需要Out_en信号来控制输入/输出转换;输入端按输入信号处理,在双向口Out_en有效时输入高阻电平“Z”,输出端用Out_en来控制;例:assignRTX_ZT_EDOUT=RTX_ZT_EDOUT_tb;initialbeginRX_ZT_EDEVICE_DIN<=1'b1;RTX_ZT_EDOUT_tb<=1;#(SCY+indelay);foreverif(TX_ZT_EDOUT_OEN_N)RTX_ZT_EDOUT_tb<=1;elseRTX_ZT_EDOUT_tb<=1'bz;#(SCY);endend12--WriteTestbench--九、仿真结果保留(二进制格式)测试向量稳定后,可以将输入向量、输出结果保留,以进行对比测试,ASIC流程各阶段的仿真,并监测仿真结果。因为输入和输出信号在一个CYCLE内只变化一次,所以可在一个CYCLE的未期采样输入、输出、三态使能信号存入文件中。时钟信号无需保留,方便后续仿真自由决定时钟频率。例:#definestrobe=1;initialbegindesc=$fopen("zx2701_ptarget.dat");#(SCY-strobe);//1nsbeforeclkrisingedge,foreverbegin$fwrite(desc,"%d",din);$fwrite(desc,"%d",dout);$fwrite(desc,"%d",dinout);$fwrite(desc,"%d",U_ENTITY.dinout_oen);$fwrite(desc,"\n");#(SCY);endend13--WriteTestbench--记得在仿真结束之前关闭文件
.
.
.
#(PCY*20)
$fclose(desc);
$stop;
$finish;
end
14--WriteTestbench--十、测试结果保留(VCD格式)initialbegin$dumpfile("testbench.vcd");$dumpvars(0,U_ZT.RX_ZT_PRST_N,U_ZT.RX_ZT_PCLK,
U_ZT.TX_ZT_PREQ_N,U_ZT.RX_ZT_PGNT_N,U_ZT.TX_ZT_EDOUT_OEN_N);end...$dumpfinish:VCD文件不是基于CYCLE的,信号值一变动就会存入到文件中,它比前述二进制方式更精确,但对我们而言不实用。15--WriteTestbench--十一、对照仿真及ASIC流程各阶段仿真测试数据从文件中读取输入信号按文件中读出值在INPUT_DELAY的控制下加入文件中读出的输出信号用于和仿真出的输出结果对照比较从文件中读出的双向信号值,在Out_en无效时作为输入信号值加入,反之作为输出对照值和仿真出的双向口的输出结果对照比较。16--WriteTestbench--例:输入部分initial//txttestbenchreader;begin$readmemb("zx2701_gports_fc.dat",mem_a);for(i=0;i<filelength;i++)beginone_line=mem_a[0];#indelay;RX_ZT_PRST_N<=one_line[0];TX_ZT_PREQ_N_tb<=one_line[1];RTX_ZT_PFRAME_tb<=one_line[2];TX_ZT_FRAME_OEN_N_tb<=one_line[3];#(SCY-indelay);//righttoclkrising_edge;end$stop;$finish;endassignRTX_ZT_PFRAME=(TX_ZT_FRAME_OEN_N_tb)?RTX_ZT_PFRAME_tb:1'bz;17--WriteTestbench--例:输出检测initialbeginresult=1;#(SCY-tstrobe);//2NSBEFORECLKRISINGEDGE;foreverbeginresult=(TX_ZT_PREQ_N_tb==TX_ZT_PREQ_N)&&(TX_ZT_FRAME_OEN_N_tb||(RTX_ZT_PFRAME_N==RTX_ZT_PFRAME_tb))#SCY;if(!result)$write("resulterror,yoursimulationmaymeetsomeerror,atcycle:%d\n",i);endend双向口由于还有输入部他分,易和输出部分产成碰撞,处理更要留意,建议单独用一个INITIAL,并重新安排一个INPUT_DELAY来处理。经过这样输入输出处理的对照仿真就和真实的芯片测试机台仿真基本同了。18--WriteTestbench--initial$sdf_annotate("ZX2701B_PAD.sdf",U_ZT);十二、SDF文件读取19--WriteTestbench--十三、跨越时钟域的测试问题在跨越两个时钟边界时易导致测试结果出错,在测试机台上判断为废片,但实际上芯片功能并没有错。20--WriteTestbench--原因原因:即使是从芯片外部同频同相的两个时钟输入,由于各自负载量不同,时钟树分布不同,测试机台打入信号时的误差,最终到达各自的DFF时已经完全没有同相关系了。影响:即使功能上是能够容忍,但可能无法满足测试向量要求每个CYCLE精确的输出值的要求,导致将功能正确的芯片判断为废片。21--WriteTestbench--解决方法一、尽量减少时钟数always@(posedgealeornegedgerst)if(!rst)dout<=0;elsedout<=din;always@(posedgeclkornegedgerst)if(!rst)…….Elseif(dout=xxxx)…….在CLK和ALE之间存在跨越两个时钟边界的数据传输,这两个时钟之间无相位关系,仿真时可能出错,但功能或许已经通过其它手段得到保证不会出错。always@(posedgeclkornegedgerst)if(!rst)begindout<=0;din_reg<=0;endelsebegindin_reg<=din;ale_reg<=ale;if(ale&&!ale_reg)//alerisingdout<=din_reg;elsedout<=dout;end22--WriteTestbench--解决方法二、在RTL设计过程中,只用管脚提供的时钟,不要派生出新的时钟来,用到DLL的情况例外。always@(posedgeclkornegedgerst)if(!rst)count<=0;elsecount<=count+1;always@(posedgecount[4]ornegedgerst)if(!rst)dout<=0;elsedout<=dina+dinb;always@(posedgeclkornegedgerst)if(!rst)…..elseif(dout==xxxx)…..count[4]被派生出作为一个新的时钟,一个跨越两个时钟边界的数据传输线出现了。always@(posedgeclkornegedgerst)if(!rst)begincount<=0;dout<=0;endelsebegincount<=count+1;if(count[4:0]==5'b11111)dout<=dina+dinb;elsedout<=dout;end23--WriteTestbench--解决方法三、在跨越两个时钟边界的数据线上加上延时用BUFFER,来弥补HOLD时间。注、此种方法可能导致和FPGA的后仿真结果不一致,但通常应该和RTL代码的纯行为仿真是一致的,在测试向量中两个时钟相位一致的前提下。24--WriteTestbench--小结:测试向量和RTL的分别RTL:平面化的电路结构描述测试向量:时序化的过程描述RTL:主要由状态机来描述,测试向量:软件化的时序过程,可用流程图的方式描述。谢谢!吴宗军2003.10.1526--WriteTestbench--抽象波形的生成(2)tasksync_resetbeginrst<=1’b1;d0<=1’b1;d1<=1’b0;sel<=$random;@(posedgeclk);#(Thodl);{rst,d0,d1,sel}<=4’bxxxx;#(cycle–Thold–Tsetup);endendtasktaskload_d0Inputdatabeginrst<=1’b0;d0<=data;d1<=~data;sel<=1’b0;@(posedgeclk);#(Thodl);{rst,d0,d1,sel}<=4’bxxxx;#(cycle–Thold–Tsetup);endendtaskInitialbeginsync_reset;load_d0(1’b1);sync_reset;load_d0(1’b1);load_d0(1’b1);load_d0(1’b1);end27--WriteTestbench--输出验证输出验证的手段响应的可视检查产生仿真结果减小采样观察波形产生激励只完成了一半的工作,实际上,只有差不多30%的工作,另外一部分工作就是验证输出是否期待的结果,而后者是更加耗时的和容易产生错误的。28--WriteTestbench--响应的可视检查可视检查的手段parameterINTERVAL=10alwaysbegin#(INTERVAL);$write(...);end按照一定的时间间隔打印信息29--WriteTestbench--响应的可视检查always@(posedgeclk)$write(...);可视检查的手段按照一定的时间间隔打印信息基于参考信号打印信息30--WriteTestbench--响应的可视检查initialbegin$monitor("...",rst,d0,d1);end基于信号的变换打印信息可视检查的手段按照一定的时间间隔打印信息基于参考信号打印信息31--WriteTestbench--响应的可视检查initialbegin$monitor("...",rst,d0,d1);$monitoroff;sync_reset;load_do(1’b1);sync_reset;$monitoron;$load_d1(1’b1);$load_d0(1’b0);$sync_reset;$monitoroff;end减小采样,加速仿真基于信号的变换打印信息可视检查的手段按照一定的时间间隔打印信息基于参考信号打印信息32--WriteTestbench--响应的可视检查观察波形减小采样,加速仿真基于信号的变换打印信息可视检查的手段按照一定的时间间隔打印信息基于参考信号打印信息33--WriteTestbench--当模型错误出现错误的时候,花多少时间可以诊断出错误,时间是否我们可以接受的?对于一个简单的设计,一个较短的仿真周期,较少的信号变量,可视化的检查非常有效!对于一个复杂点的设计,成百上千的时钟周期,数百的输入输出信号变量,可视化的检查方法是否还是适用?34--WriteTestbench--输入输出向量initialbegin//In:rst,d0,d1,sel//Out:q,qbapply_vector(4’b1110,2’b00);apply_vector(4’b0100,2’b10);apply_vector(4’b1111,2’b00);apply_vector(4’b0011,2’b10);apply_vector(4’b0010,2’b01);apply_vector(4’b0011,2’b10);apply_vector(4’b1111,2’b00);endTaskapply_vector;input[…]in_data;output[…]out_data;begininputs<=in_data;@(posedgeclk)forkbegin#(Thold);inputs<=…’bx;endbegin#(Td);if(outputs!=out_data)…endjoinend输出结果与期待值比较,只对不满足条件的结果检查优点?35--WriteTestbench--完美向量(GoldenVector)(1)它是一套正确的参考仿真结果它不跟随内部时序的改变而改变它具有很高的可维护性参考模型DUV输出比较激励的生成什么是完美向量?36--WriteTestbench--完美向量(GoldenVector)(2)直接将Testbench产生的文件和目标文件比较利用工具比较波形文件采用人工的方式监视结果参考模型DUV输出比较激励的生成结果的比较?37--WriteTestbench--复杂的激励激励和设计之间的反馈从死锁中恢复异步接口CPU操作可配置的操作38--WriteTestbench--激励和设计之间的反馈taskbus_request;integercycle_count=0;beginreq<=1;@(posedgeclk);while(grt==1'b0)begin@(posedgeclk);count=count+1;endif((count<6)|(count>0)$display("cycle_count=%h",cycle_count);endendtask在输入和输出向量中我们谈到可以采用输出结果与期待比较的验证方式,但是如果这个结果是一个范围,那我们该采取什么方式?监视信号是否与协议符合39--WriteTestbench--从死锁中恢复(1)反馈天生的风险:激励依赖设计的完成情况。如果设计不能够提供期待的反馈,激励的成生将会被挂起,等待的情况将永远不会发生。如果grt信号不为1,那么整个任务将会粘在while语句,不会结束taskbus_request;integercount=0;beginreq<=1;@(posedgeclk);while(grt==1'b0)begin@(posedgeclk);count=count+1;endif((count<6)||(count>0)$display(“requestmeettheprotocol”);endendtask40--WriteTestbench--从死锁中恢复(2)taskbus_request;integercount=0;integerloop=1;beginreq<=1;@(posedgeclk);while((grt==1'b0)&&(loop==1’b1))begin@(posedgeclk);count=count+1;if(count>50)beginloop=0;$display(“nogrant”);endendif((count<6)||(count>0)$display(“requestmeettheprotocol”);endendtask当遇到grt信号不在期待的时间响应的时候,如何避免死锁?如何预测死锁的发生?只要遇到反馈的情况,就必然有死锁存在。如何解决死锁的发生?信号在期待的周期内没有发生,那么强行退出任务,报告错误,继续完成其他的测试用例41--WriteTestbench--从死锁中恢复(3)在测试用例中处理死锁问题使得整个流程更有弹性taskbus_request;outputstatus;integercount=0;Integerloop=1;beginstatus=1’b1;req<=1;@(posedgeclk);while((grt==1'b0)&&(loop==1’b1))begin@(posedgeclk);count=count+1;if(count>50)beginloop=1’b0;status=1’b0;endendif((count<6)||(count>0)$display(“requestmeettheprotocol”);endendtasktasktestcase;reggranted;integerattempts;integerloop;beginattempts=0;loop=1;while(loop)beginbus_request(granted);if(granted!=1)beginattempts=attempts+1;if(attempts<5)$display(“nogrant”);loop=0;endloop=0;endendendtask42--WriteTestbench--异步接口(1)taskbus_request;outputgood;beginreq=1'b1;fork:wait_for_grt#60disablewait_for_grt;@(posedgegrt)disablewait_for_grt;jiongood=(grt==1'b1);endendtask在期待的时间点等待信号事件43--WriteTestbench--异步接口(2)taskbus_request;outputgood;begin:bus_request_taskif(grt==1’b1)begingood=1’b0;disablebus_request_taskendreq=1'b1;fork:wait_for_grt#60disablewait_for_grt;@(posedgegrt)disablewait_for_grt;jiongood=(grt==1'b1);endendtask当仲裁器工作不正常的时候grt信号将不会按照协议正常的产生,此时不会在期待的时间点有grt的上升沿。因此必须首先验证grt信号,然后才验证req信号44--WriteTestbench--复杂的响应什么是复杂响应?处理未知的或者变化的延迟抽象输出操作一般输出监视监视多种可能的操作监视双向接口45--WriteTestbench--什么是复杂响应?我们已经确信:即使是一个简单的响应,可视监视的验证方式也不是一个可行的方法。而复杂的响应更加不能采用波形的监视的方式来验证。验证输出响应的处理应该是自动的。复杂响应=延迟+输出协议46--WriteTestbench--一个简单的说明-单个写CPUI/FRS-232TxTxFIFOCPUWriteIntdelaySerialTxGapininputsequenceTimeCPU写周期内部延迟事务结束47--WriteTestbench--一个简单的说明-连续写CPUI/FRS-232TxTxFIFOCPUWriteIntdelaySerialTxTimeCPU写周期内部延迟事务结束48--WriteTestbench--抽象输出操作taskrev;inputrx;input[7:0]expected;integerperiod;reg[7:0]data;beginperiod=100;wait(rx==1'b1);#(period/2);data[7]=0;for(i=0;i<8;i=i+1)begin#(100)ldata[i]=rx;end#periodrx=0;
if(expected!=data)$display(…);endendtask将任务封装起来,同时输入期待的值与实际值比较Self-checking49--WriteTestbench--处理未知的或者变化的延迟ConfigWriteConfigWriteIsIdle?DataOk?IsIdle?DataOk?InitStimulusResponseEnd上图描述了UART发送路径。指示了从配置,Idle检查到激活数据发送的过程。50--WriteTestbench--initialbegin...//initsimulationfork:config_phasebegin...//configdisableconfig_phaseendbegin...//checkoutputremainsidleendjoin
fork:data_phasebegin...//writedatatosendviaCPIi/fendbegin...//checkdatasentseriallyendjoin...//terminatesimulationendUART配置状态是否Idle检查发送数据串行数据协议检查51--WriteTestbench--通用输出监视taskrev;inputrx;output[7:0]actual;integerperiod;reg[7:0]data;beginperiod=100;wait(rx==1'b1);#(period/2);data[7]=0;for(i=0;i<8;i=i+1)begin#(100)ldata[i]=rx;end#periodrx=0;actual=data;endendtask将任务封装起来,同返回输出值,能够让testbench灵活的使用!52--WriteTestbench--监视多种可能的操作(1)loadA,R0loadB,R1addR0,R1,R2stor2,XloadC,R3addR0,R3,R4stoR4,YLocationAisreadbeforelocationXandYarewrittenLocationBisreadbeforelocationXiswrittenLocationCisreadbeforelocationYiswrittenLocationXmustbewrittenwiththevalueA+BLocationYmustbewrittenwiththevalueA+C或许存在这样的情形,在输出接口上不止发生一种类型的操作。你不能预测下一步是哪种指定的操作。例如:在处理器乱序执行指令时,你不能预测(如果你没有足够的处理器结构知识)读或者写周期将会出现在数据存储器接口上。这一功能的正确性决定于相关数据位置的访问顺序。53--WriteTestbench--监视多种可能的操作(2)当不知道下一个操作是什么的时候,你如何写一个封装形式的输出Monitor?你的Monitor必须在下一个周期开始时能够识别出该周期类型。验证所有操作前导(preamble),反馈识别信息给testbench,然后testbench调用适当的任务完成操作的验证。54--WriteTestbench--监视多种可能的操作(3)parameterREAD_CYCLE=0;WRITE_CYCLE=1;timelast_addr;tasknext_cycle_is;outputcycle_kind;output[23:0]address;begin@(negedgeale);address=addr;cycle_kind=(rw==1'b1)?READ_CYCLE:WRITE_CYCLE;#(Tahold);if($time-last_addr<Tahold-Tasetup)$write("Setup/Holdtimeviol.onaddr\n");endendtaskinitialbegin:test_procedureregcycle_kind;reg[23:0]addr;
next_cycle_is(cycle_kind,addr);case(cycle_kind)READ_CYCLE:read_cycle(addr);WRITE_CYCLE:write_cycle(addr);endcase...end类型判断不同类型不同处理55--WriteTestbench--监视双向接口(1)如果一个任务或者过程发起操作,那么它就是激励生成器,如果一个任务或者过程等待设计发起操作,那么它就是输出监视器。BridgeOn-ChipMasterPCISlaveon-chipbusPCIbus桥转换一个私有on-chip总线和PCI总线协议。On-chip总线发起操作。如果地址属于桥地址空间,桥转换协议到PCI总线。桥允许on-chip总线到PCI总线上的从器件透明访问。56--WriteTestbench--监视双向接口(2)BridgeOn-ChipMasterPCISlaveon-chipbusPCIbusBridgeOn-ChipGeneratorPCIMonitor为了验证桥,你需要一个on-chip总线的产生器和PCI总线的监视器,如上图。例如可以采用一个存储器模型来代替PCI监视器,写
温馨提示
- 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
- 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
- 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
- 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
- 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
- 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
- 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
评论
0/150
提交评论