数字系统设计:测试基准m_第1页
数字系统设计:测试基准m_第2页
数字系统设计:测试基准m_第3页
数字系统设计:测试基准m_第4页
数字系统设计:测试基准m_第5页
已阅读5页,还剩114页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

Testbench设计主讲人:姜小波本章目录Testbench设计Testbench简介Testbench基本结构激励信号的产生

时钟信号复位信号复杂周期性信号两相关性信号一般激励信号典型错误

Testbench综合应用实例高级Testbench设计高级Testbench概述文件的读写VCD数据库文件断言语句(Assert)高级Testbench实例34每个人都知道调试的难度是编程的一倍。5一个例子著名的Pentium处理器浮点运算BugIntel的主流处理器330万个晶体管早期版本都存在浮点除法的硬件错误增加5个晶体管、修改一层掩模版即可修正在互连网上被首次发现Intel最终为所有用户提供更换耗资4.75亿美元61996年6月4日:欧洲阿里安5大型运载火箭在法属圭亚那库鲁进行首次发射时,于起飞后40秒发生爆炸。7一些启示集成电路设计中错误是无处不在的!错误并不会十分“巨大”;因此也就非常隐蔽;一但错误被漏过,“后果很严重”!Intel为什么没有发现这个错误?8Why?设计验证的标准步骤:在高抽象层次软件模型上进行大量的仿真验证对逻辑设计进行了软件和硬件仿真硬件仿真器价值上百万美元运行速度比真实芯片低6个数量级样品验证运行几十亿次测试与错误擦身而过需要约1trillion的测试矢量对于复杂系统来说,很难全面验证它的所有方面!9对Intel的影响短期影响出现错误的尴尬经济上的损失长期影响所有人都将更加认真仔细地对待验证为验证方法的研究提供了一个好的契机和研究范例Intel甚至从这件事的影响力上得到了很多意外的好处10结论数字系统的验证工作非常关键责任重大!数字系统的验证非常具有挑战性工程上:具有严格的技术和管理上的要求!理论和方法:亟待技术上的进步甚至是突破!掀起一场功能验证相关研究的热潮!11结论原则一:项目一定DELAY!原则二:预算一定超支!原则三:怀疑可能有问题的地方一定有问题!12概念明晰(verificationvs.test)设计(design)加工(manufacture)验证(verification)测试(test)检验设计过程是否引入了错误检验加工完成的芯片是否有缺陷“软件测试”Softwaretest“回归测试”Regressiontest“测试用例”Testsuite……“测试平台”Testbench13概念明晰(verificationvs.validation)Verification在于检验设计过程中是否引入了错误,关注功能实现的各个环节Validation在于检验设计的成果(产出)是否符合要求,可以解释为验收测试14概念明晰(verificationvs.simulation)VerificationFunctionalVerificationSimulationTimingAnalysisPowerAnalysisSignalIntegrationFormalverificationStaticAnalysis15验证vs.功能验证以功能为验证目标的验证早期功能验证=集成电路验证(功能+时序+测试)目前功能验证不再等同与验证,但仍然是集成电路验证的最重要组成部分功能、时序、功耗、信号完整性、可测性、可制造性16功能验证的意义和重要性(尽可能)确保设计正确性的必然要求提高设计信心的必要手段加快设计进度的关键环节集成电路功能验证应受到更多的重视17功能验证面临越来越多的难题设计规模越来越大,复杂度指数级提高模块类型的多样性(ALU、FIFO、Cache、FSM……控制结构的复杂性(交互状态机、异常处理、复杂的存储空间管理……)设计错误的隐蔽性越来越高发现晚的设计错误,修正成本非常高技术方法上的力不从心严重影响产品面世时间(TTM)18功能验证的瓶颈效应验证过程占整个设计周期的2/3,甚至高达90%;验证工程师是设计工程师的2倍;验证编码占整个设计编码的80%19芯片设计的一次通过率低于50%!其中有超过70%的有功能错误!20错误起源分析设计规范的理解错误设计人员之间对技术问题的误解遗漏的功能协议的不一致资源冲突时序节拍问题(cyclelevel)……21验证对设计周期的影响超过70%的设计的性能比预期低10%以上!通常设计会由于进度原因而在没有进行足够的功能和性能验证的情况下勉强流片!22设计重用的负担转嫁基于IP重用的设计方法强调使用预先设计好的功能模块,集成和重用成为SoC设计的基本方法,这使得更多的工作量被转移到功能验证上。Testbench简介Testbench基本结构激励信号的产生Testbench实例Testbench设计初步数字系统设计方法基于中小规模集成电路的设计方法电路运行速度快,实时性好。然而过程过于繁琐复杂,不适用于大型的数子系统设计;基于MCU的设计方法较为直观人性化,然而MCU的性能难以满足某些特定场合(如高速情况下)的应用需求;基于PLD的EDA设计则是一种全新的设计思想与设计理念。兼具了中小规模集成电路设计与MCU设计方式的优点;在顶层设计上采用多种输入描述方法,具有MCU方式设计的灵活性、直观性;底层硬件逻辑设计由EDA工具自动完成保证了设计效率;功能开发上是软件实现的,物理机制为纯硬件电路;纯硬件的物理机制使其具有更强的抗干扰能力、更快的运行速度。真实世界VHDLSIMULATOR数字系统设计TestBench..?!VHDLtestbenchTestbench简介编写Testbench目的

对使用硬件描述语言(HDL)设计的电路进行仿真验证,测试设计电路的功能、部分性能是否与预期的目标相符。编写Testbench进行测试的过程1)实例化需要测试的设计(DUT,DesignUnderTest);

2)产生模拟激励(波形);3)将产生的激励加入到被测试模块并观察其输出响应;4)将输出响应与期望进行比较,从而判断设计的正确性。输出响应可以以波形方式显示或存储测试结果到文件中Testbench简介Testbench基本结构激励信号的产生Testbench实例Testbench设计初步激励信号待测试实例波形、数据输入输出Testbench是VHDL程序之一,它遵循VHDL基本程序的框架,也具有自身的独特性Testbench的基本结构结构体描述库的调用程序包的调用空实体被测试元件的声明Testbench的基本结构LIBRARYIEEE;USEIEEE.std_logic_1164.all;ENTITYTBISENDENTITY;ARCHITECTUREbehavOFTBISCOMPONENTEntity_Under_Test

PORT(……)

--端口列表ENDCOMPONENTBEGIN……--局部信号的声明DUT:

Entity_Under_Testportmap(……)

Gen1:PROCESS()

……ENDPROCESS;

Gen2:PROCESS()

……ENDPROCESS;ENDbehav;局部信号声明例化被测试元件产生激励信号Testbench简介Testbench基本结构激励信号的产生Testbench实例Testbench设计初步时钟信号的产生复位信号的产生复杂周期性信号的产生使用DELAYED属性产生两相关性信号一般激励信号的产生典型错误激励信号的产生激励信号的产生时钟信号的产生

时钟信号是同步设计中最重要的信号之一。是属于周期性出现的信号。时钟信号分类:(1)对称时钟信号(占空比为50%)(2)非对称时钟信号(占空比不是50%

)Testbench中产生时钟信号方式:(1)并行的信号赋值语句(2)单独process进程clk1、clk2和clk3有何区别?试用并行赋值语句产生上述时钟信号激励信号的产生时钟信号的产生

使用并行的信号赋值语句产生时钟信号激励信号的产生时钟信号的产生

使用并行的信号赋值语句产生时钟信号……signalclk1:std_logic:='0';signalclk2:std_logic;signalclk3:std_logic;constantclk_period:time:=40ns;……clk1<=notclk1afterclk_period/2;clk2<='0'afterclk_period/4whenclk2='1'else'1'after3*clk_period/4whenclk2='0'else‘1’;--此值实际上是定义clk2的起始值clk3<='0'afterclk_period/4whenclk3='1'else'1'after3*clk_period/4whenclk3='0'else'0';……clk1为对称时钟信号,其初始值在信号定义时赋值;clk2和clk3为非对称时钟信号,其初值在并行赋值语句中给予激励信号的产生时钟信号的产生

使用process进程产生时钟信号clk1和clk2有何区别?试用process进程产生上述时钟信号激励信号的产生时钟信号的产生

使用process进程产生时钟信号……signalclk1:std_logic;signalclk2:std_logic;……clk1_gen:processconstantclk_period:time:=40ns;beginclk1<='1';waitforclk_period/2;clk1<='0';waitforclk_period/2;endprocess;clk2_gen:processconstantclk_period:time:=20ns;beginclk2<='0';waitforclk_period/4;clk2<='1';waitfor3*clk_period/4;endprocess;……常量只在该进程中起作用常量只在该进程中起作用激励信号的产生数字系统往往需要复位信号对系统进行复位,以便初始化系统。Testbench中产生复位信号方式:(1)并行赋值语句(2)在进程中设定复位信号的产生

激励信号的产生复位信号的产生

试分别用并行赋值语句、process进程产生上图中的reset1和reset2信号激励信号的产生复位信号的产生

……signalreset1:std_logic;signalreset2:std_logic;……reset1<='0','1'after20ns,'0'after40ns;reset2_gen:processbeginreset2<='0';waitfor20ns;reset2<='1';waitfor40ns;reset2<='0';wait;endprocess;……激励信号的产生复杂周期性信号的产生

观察period1和period2信号的周期是多少?试用进程的方法产生该信号激励信号的产生复杂周期性信号的产生

……signalperiod1,period2:std_logic:='0';……TB:processbeginperiod1<='1'after5ns,'0'after10ns,'1'after20ns,'0'after25ns;period2<='1'after10ns,'0'after20ns,'1'after25ns,'0'after30ns;waitfor35ns;endprocess;……方法一激励信号的产生复杂周期性信号的产生

方法二……signalperiod1,period2:std_logic;……period1_gen:processbeginperiod1<='0';waitfor5ns;period1<='1';waitfor5ns;period1<='0';waitfor10ns;period1<='1';waitfor5ns;period1<='0';waitfor10ns;endprocess;period2_gen:processbeginperiod2<='0';waitfor10ns;period2<='1';waitfor10ns;period2<='0';waitfor5ns;period2<='1';waitfor5ns;period2<='0';waitfor5ns;endprocess;激励信号的产生使用DELAYED属性产生两相关性信号

period1和period2信号具有怎样的相关性?试用delayed属性产生上述信号delayed是VHDL的预定义属性,使用它可以产生两个相关性的信号激励信号的产生使用DELAYED属性产生两相关性信号

delayed是VHDL的预定义属性,使用它可以产生两个相关性的信号……signalperiod1,period2:std_logic;……period1<='1'after30nswhenperiod1='0'else'0'after20nswhenperiod1='1'else'0';period2<=period1'delayed(10ns);……激励信号的产生一般的激励信号

一般的激励信号通常在process进程中定义,而在process进程中一般需要使用wait语句比较test_vector1和test_vector2的异同,并用process进程实现之激励信号的产生一般的激励信号

一般的激励信号通常在process进程中定义,而在process进程中一般需要使用wait语句……signaltest_vector1:std_logic_vector(1downto0);signaltest_vector2:std_logic_vector(1downto0);……TB1:processbegintest_vector1<="01";waitfor10ns;test_vector1<="10";

waitfor20ns;endprocess;TB2:processbegintest_vector2<="01";waitfor10ns;test_vector2<="10";

wait;endprocess;激励信号的产生一般的激励信号

产生test_vector中所有可能的输入情况signaltest_vector3:std_logic_vector(3downto0):="0000";signaltest_vector4:std_logic_vector(3downto0):="0000";signaltest_vector5:std_logic_vector(3downto0);signaltest_vector6:std_logic_vector(3downto0);TB3:processbeginwaitfor10ns;test_vector3<=test_vector3+1;endprocess;TB4:processbeginwaitfor10ns;test_vector4<=test_vector4+1;waitfor10ns;endprocess;TB5:processbegintest_vector5<="0000";waitfor10ns;test_vector5<=test_vector5+1;endprocess;TB6:processbegintest_vector6<="0000";waitfor10ns;test_vector6<=test_vector6+1;waitfor10ns;endprocess;比较四个process的异同,试画出各个test_vector波形激励信号的产生一般的激励信号

产生test_vector中所有可能的输入情况TB3:processbeginwaitfor10ns;test_vector3<=test_vector3+1;endprocess;TB4:processbeginwaitfor10ns;test_vector4<=test_vector4+1;waitfor10ns;endprocess;激励信号的产生一般的激励信号

产生test_vector中所有可能的输入情况TB5:processbegintest_vector5<="0000";waitfor10ns;test_vector5<=test_vector5+1;endprocess;TB6:processbegintest_vector6<="0000";waitfor10ns;test_vector6<=test_vector6+1;waitfor10ns;endprocess;激励信号的产生一般的激励信号

产生两个test_vector中所有可能的输入情况如上图所示,2bit的test_ab和test_sel是否覆盖了所有的输入情况?试用VHDL产生上述信号激励信号的产生一般的激励信号

产生两个test_vector中所有可能的输入情况double_loop:processbegintest_ab<="00";test_sel<="00";forIin0to3loopforJin0to3loopwaitfor10ns;test_ab<=test_ab+1;endloop;test_sel<=test_sel+1;endloop;endprocess;signaltest_ab:std_logic_vector(1downto0);signaltest_sel:std_logic_vector(1downto0);在testbench中可以用for循环(因为testbench不需综合),但在设计中不推荐使用for循环激励信号的产生典型错误

signaltest_vector:STD_LOGIC_VECTOR(2downto0);signalreset:STD_LOGIC;gen1:processbeginreset<='1';waitfor100ns;reset<='0';test_vector<="000";wait;endprocess;gen2:processbeginwaitfor200ns;test_vector<="001";waitfor200ns;test_vector<="011";endprocess;该程序是否有错?假如没错,请分析test_vector和reset的时序激励信号的产生典型错误

signaltest_vector:STD_LOGIC_VECTOR(2downto0);signalreset:STD_LOGIC;gen1:processbeginreset<='1';waitfor100ns;reset<='0';

test_vector<="000";

wait;endprocess;gen2:processbeginwaitfor200ns;

test_vector<="001";waitfor200ns;

test_vector<="011";endprocess;同一个信号在两个进程中进行赋值,在某些时间段内发生了冲突,所以会出现不定状态同一信号不推荐在不同的进程中赋值Testbench简介Testbench基本结构激励信号的产生Testbench实例Testbench设计初步Testbench实例组合逻辑电路:2位全加器的设计与验证时序逻辑电路:六进制计数器的设计与验证Testbench实例2位全加器的设计libraryieee;useieee.std_logic_1164.all;useieee.std_logic_unsigned.all;entityadder_2is port(cin:instd_logic;a,b:instd_logic_vector(1downto0);s:outstd_logic_vector(1downto0); cout:outstd_logic);endadder_2;architecturebehofadder_2issignalsint:std_logic_vector(2downto0); signalaa,bb:std_logic_vector(2downto0);begin aa<='0'&a(1downto0); bb<='0'&b(1downto0); sint<=aa+bb+cin; s(1downto0)<=sint(1downto0); cout<=sint(2);endbeh;如何写Testbench对此加法器覆盖全面的测试验证?Testbench实例2位全加器的验证为了对此加法器覆盖全面的验证,cin、a、b三个信号应该具有上图所示的波形,如何产生该波形呢?Testbench实例2位全加器的验证libraryieee;useieee.std_logic_1164.all;useieee.std_logic_unsigned.all;entityadder_2_tbisendadder_2_tb;architecturetbofadder_2_tbisCOMPONENTadder_2PORT(cin:instd_logic; a,b:instd_logic_vector(1downto0); s:outstd_logic_vector(1downto0); cout:outstd_logic);ENDCOMPONENT;signala_t,b_t,s_t:std_logic_vector(1downto0);signalcin_t,cout_t:std_logic;beginDUT:adder_2PORTMAP(cin=>cin_t,a=>a_t,b=>b_t,s=>s_t,cout=>cout_t);库、程序包的调用Testbench实体(空实体)定义Testbench是VHDL程序之一,它遵循VHDL基本程序的框架,也具有自身的独特性被测元件的声明注意:此处并非adder_2_tb被测元件的例化Testbench实例2位全加器的验证(续)TB:processbegina_t<="01";b_t<="00";waitfor10ns;b_t<="01";waitfor10ns;b_t<="10";waitfor10ns;b_t<="11";waitfor10ns;a_t<="10";b_t<="00";waitfor10ns;b_t<="01";waitfor10ns;b_t<="10";waitfor10ns;b_t<="11";waitfor10ns;a_t<="11";b_t<="00";waitfor10ns;b_t<="01";waitfor10ns;b_t<="10";waitfor10ns;b_t<="11";waitfor10ns;a_t<="00";b_t<="00";cin_t<=‘1';waitfor10ns;b_t<="01";waitfor10ns;b_t<="10";waitfor10ns;b_t<="11";waitfor10ns;①②④③对此加法器进行全面的测试验证的方法一方法一当加法器位数增加时,要覆盖所有可能的输入,此方法需要罗列的情况倍数增加,代码书写将会非常麻烦Testbench实例2位全加器的验证(续)a_t<="01";b_t<="00";waitfor10ns;b_t<="01";waitfor10ns;b_t<="10";waitfor10ns;b_t<="11";waitfor10ns;a_t<="10";b_t<="00";waitfor10ns;b_t<="01";waitfor10ns;b_t<="10";waitfor10ns;b_t<="11";waitfor10ns;a_t<="11";b_t<="00";waitfor10ns;b_t<="01";waitfor10ns;b_t<="10";waitfor10ns;b_t<="11";waitfor10ns;a_t<="00";b_t<="00";cin_t<='0';waitfor10ns;b_t<="01";waitfor10ns;b_t<="10";waitfor10ns;b_t<="11";waitfor10ns;⑤⑥⑧⑦endprocess;endtb;对此加法器进行全面的测试验证的方法一方法一Testbench实例2位全加器的验证(续)TB:processbegin a_t<="00";b_t<="00";cin_t<='0';forKin0to1loopforIin0to3loopforJin0to3loopwaitfor10ns;a_t<=a_t+1;endloop;b_t<=b_t+1;endloop;cin_t<=notcin_t;endloop;endprocess;endtb;对此加法器进行全面的测试验证的方法二方法二Testbench实例2位全加器的验证(续)仿真结果通过对波形进行分析可知,本设计功能正确Testbench实例六进制计数器的设计libraryieee;useieee.std_logic_1164.all;useieee.std_logic_unsigned.all;entitycnt6isport(clr,en,clk:instd_logic;q:outstd_logic_vector(2downto0));endentity;architecturertlofcnt6issignaltmp:std_logic_vector(2downto0);beginprocess(clk)beginif(clk'eventandclk='1')thenif(clr='0')thentmp<="000";elsif(en='1')thenif(tmp="101")thentmp<="000";elsetmp<=unsigned(tmp)+'1';endif;endif;endif;q<=tmp;endprocess;endrtl;①②③Testbench实例六进制计数器的验证libraryieee;useieee.std_logic_1164.all;useieee.std_logic_unsigned.all;entitycnt6_tbisendcnt6_tb;architecturertlofcnt6_tbiscomponentcnt6port(clr,en,clk:instd_logic;q:outstd_logic_vector(2downto0));endcomponent;signalclr:std_logic:='0';signalen:std_logic:='0';signalclk:std_logic:='0';signalq:std_logic_vector(2downto0);constantclk_period:time:=10ns;beginDUT:cnt6portmap(clk=>clk,en=>en,clr=>clr,q=>q);

库、程序包的调用Testbench实体(空实体)定义被测元件的声明被测元件的例化Testbench实例六进制计数器的验证(续)clk_gen:processbeginwaitforclk_period/2;clk<='1';waitforclk_period/2;clk<='0';endprocess;clr_gen:processbeginclr<='0';waitfor15ns;clr<='1';wait;endprocess;en_gen:processbeginen<='0';waitfor25ns;en<='1';wait;endprocess;endrtl;①②③仿真结果Testbench设计进阶高级Testbench概述文件的读写VCD数据库文件断言语句(Assert)高级Testbench实例Testbench设计进阶高级Testbench概述文件的读写VCD数据库文件断言语句(Assert)高级Testbench实例高级Testbench概述简单Testbench高级Testbench简单Testbench概述在前一节内容中,我们所看到的验证方法都是比较简单的,这里称为简单Testbench,一般结构如下图所示。激励信号待测试实例波形、数据输入输出所输出的结果以波形或者数据显示,需要人工分析其结果的正确性,如果被测信号数量较多且时序负责,工作量会非常巨大。高级Testbench概述激励信号待测试实例输入输出高级Testbench是在简单Testbench基础上改进过来的,能够自动读入测试矢量文件、完成输出值和期望值的比较等功能。如下图所示输出值和期望值比较测试矢量文件测试结果(Yes/No)更智能化,减少人工分析的繁琐!载入期望值Testbench设计进阶高级Testbench概述文件的读写VCD数据库文件断言语句(Assert)高级Testbench实例文件的读写文件定义TEXTIO介绍TEXTIO数据类型及过程代码示例仿真时,VHDL允许设计人员从文件加载数据或将数据存储到文件中。比如用户定义的测试矢量可以保存在文件中,然后在仿真时从文件中读取这些测试矢量。另外,仿真的结果也可以保存在文件中。VHDL标准中的文件I/O主要是由TEXTIO程序包提供,用于仿真,综合工具不能综合如果想在仿真时候进行文件操作,必须引入标准库STD中的TEXTIO定义的程序库,该程序包中包含了文件输入输出所需的基本子程序。“USESTD.TEXTIO.ALL”文件的读写TEXTIO是VHDL标准库STD中的一个程序包(Package)。在该包中定义了三个类型:LINE类型、TEXT类型以及SIDE类型。另外,还有一个子类型(subtype)WIDTH。此外,在该程序包中还定义了一些访问文件所必须的过程(Procedure)。TEXTIO介绍TEXTIO数据类型LINETEXTSIDEWIDTH进程READLINEWRITELINEREADWRITE数据类型——LINETEXTIO—数据类型LINE为存取类型的变量,它表示该变量是指向字符串的指针,它是TEXTIO中所有操作的基本单元。读文件时,先按行(LINE)读出一行数据,再对LINE操作来读取各种数据类型的数据;写文件时,先将各种的数据类型组合成LINE,再将LINE写入文件。在用户使用时,必须注意只有变量才可以是存取类型,而信号则不能是存取类型。例如,我们可以定义

variableDLine:LINE;

但不能定义成

signalDLine:LINE;数据类型——TEXTTEXT为ASCII文件类型。定义成为TEXT类型的文件是长度可变的ASCII文件。需要注意的是VHDL'87和VHDL'93在使用文件方面有较大的差异,在编译时注意选中对应的标准。TEXTIO—数据类型数据类型——SIDESIDE只能有两种状态,即right和left,分别表示将数据从左边还是右边写入行变量。该类型主要是在TEXTIO程序包包含的过程中使用。数据类型——WIDTHWIDTH为自然数的子类型。所谓子类型表示其取值范围是父类型范围的子集。TEXTIO—数据类型TEXTIO—文件定义文件可以通过它所存储的内容来进行区分typetext是字符串文件;typeIntegerFileType是整数型文件;VHDL1987中的文件定义fileinfile:textisin“inputdata.txt”;fileoutfile:textisout“outputdata.txt”;VHDL1993中的文件定义fileinfile:textopenread_modeis“inputdata.txt”;fileoutfile:textopenwrite_modeis“outputdata.txt”;TEXTIO—文件定义二进制I/O文件(VHDL1993)支持read(f,value),write(f,value)和endfile(f)操作VHDL93支持FILE_OPEN()和FILE_CLOSE()操作直接和间接的文件打开操作;USESTD.TEXTIO.ALL;ENTITYio93ISENDENTITYio93;ARCHITECTUREbehavioralOFio93ISBEGINPROCESSISTYPEINTEGERFILETYPEISFILEOFINTEGER;FILEdataout:INTEGERFILETYPE;VARIABLEcount:INTEGER:=0;VARIABLEfstatus:FILE_OPEN_STATUS;BEGINFILE_OPEN(fstatus,dataout,"myfile.txt",WRITE_MODE);FORjIN1TO8LOOPWRITE(dataout,count);count:=count+2;ENDLOOP;WAIT;ENDPROCESS;ENDARCHITECTUREbehavioral;TEXTIO—文件定义二进制I/O文件(VHDL1987)支持read(f,value),write(f,value)和endfile(f)操作直接和间接的文件打开操作;USESTD.TEXTIO.ALL;ENTITYio87ISENDENTITYio87;ARCHITECTUREbehavioralOFio87ISBEGINPROCESSTYPEINTEGERFILETYPEISFILEOFINTEGER;FILEdataout:INTEGERFILETYPEISOUT"output.txt";VARIABLEcheck:INTEGER:=0;BEGINFORcountIN1TO10LOOPcheck:=check+1;WRITE(dataout,check);ENDLOOP;WAIT;ENDPROCESS;ENDbehavioral;TEXTIO提供了基本的用于访问文本文件的过程。类似于C++,VHDL提供了重载功能,即完成相近功能的不同过程可以有相同的过程名,但其参数列表不同,或参数类型不同或参数个数不同。TEXTIO提供的基本过程有:procedureREADLINE(文件变量;行变量);

---用于从指定文件读取一行数据到行变量中。procedureWRITELINE(文件变量;行变量);---用于向指定文件写入行变量所包含的数据。procedureREAD(…);

---可重载,用于从行变量中读取相应数据类型的数据。procedureWRITE(…);

---可重载,用于将数据写入行变量。TEXTIO—读写过程TEXTIO—使用例程在ModelSim的输出结果如下:打开文件写入信息USESTD.TEXTIO.ALL;ENTITYformatted_ioISENDformatted_io;ARCHITECTUREbehavioralOFformatted_ioISBEGINPROCESSISFILEoutfile:TEXT;VARIABLEfstatus:FILE_OPEN_STATUS;VARIABLEcount:INTEGER:=5;VARIABLEvalue:BIT_VECTOR(3DOWNTO0):=X"6";VARIABLEbuf:LINE;BEGINFILE_OPEN(fstatus,outfile,"myfile.txt",write_mode);WRITE(buf,STRING'("ThisisanexampleofformattedI/O"));WRITELINE(outfile,buf);WRITE(buf,STRING'("TheFirstParameteris="));WRITE(buf,count);WRITE(buf,'');WRITE(buf,STRING'("TheSecondParameteris="));WRITE(buf,value);WRITELINE(outfile,buf);WRITE(buf,STRING'("...andsoon"));WRITELINE(outfile,buf);FILE_CLOSE(outfile);WAIT;ENDPROCESS;ENDARCHITECTUREbehavioral;Testbench设计进阶高级Testbench概述文件的读写VCD数据库文件断言语句(Assert)高级Testbench实例VCD数据库文件VCD数据库用VCD文件记录仿真数据操作提示VCD文件样式利用ModelSim查看VCD文件VCD数据库

VCD数据库是仿真过程中数据信号变化的记录。它只记录用户指定的信号。其后缀名一般为(*.vcd)。VCD文件的作用如下:1、存储波形;2、波形数据交换;3、用于测试,很多测试工具都可以读入VCD文件,然后根据VCD文件产生激励,并且比对输出结果,实现对芯片的测试。用VCD文件记录仿真数据在VHDL中没有像VerilogHDL那样,直接提供一系列的函数来生成VCD文件,但我们可以借助ModelSim的vcd命令来实现用VCD文件记录仿真数据。ModelSim的vcd命令使用方式如下:(更详细的参数说明,请查看ModelSimSEReferenceManual)建立vcd文件:vcdfile[-dumpports][-direction][<filename>][-map<mappingpairs>][-no_strength_range][-nomap][-unique]例:vcdfilemylog.vcd(建立一个名为mylog.vcd的VCD文件)

用VCD文件记录仿真数据添加记录对象:vcdadd[-r][-in][-out][-inout][-internal][-ports][-file<filename>][-dumpports]<object_name>...例:vcdaddtestbench2/uut/*(把testbench2/uut/模块中的所有对象添加到vcd数据库中)暂停、开始记录:vcdoff[<filename>](暂停)vcdon[<filename>](开始)操作提示

1、在ModelSim中建立一个工程,并编译好模块文件和Testbench文件。2、载入Testbench的顶层模块进行仿真,这个时候ModelSim会载入需要调用的模块,但仿真还没有开始3、建立VCD文件:在命令框中输入“vcdfilemylog.vcd”(mylog.vcd可以是VCD文件的文件名,可以根据自己的意愿更改,但后缀名必须为*.vcd)4、添加要记录的对象:在命令框中输入“vcdaddtestbench2/uut/*”就可以把testbench2/uut里面的所有对象,都添加到记录的进程中。5、点击run–all按钮运行仿真,直至仿真结束。6、可以利用ModelSim的vcd2wlf命令把VCD文件转换为WLF格式的波形文件,这样可以利用ModelSim的波形查看器窗口查看数据。也可以利用其它工具打开或者调用。VCD文件样式利用ModelSim的vcd命令生成的VCD文件的样式如下(省略了部分数据)$date SatOct0811:16:562011$end$version

ModelSimVersion6.5b$end$timescale 1ns$end$scopemoduletestbench2$end$scopemoduleuut$end$varwire1%a[4]$end$varwire1&a[3]$end$varwire1'a[2]$end$varwire1(a[1]$end$varwire1-b[4]$end$varwire1.b[3]$end$varwire1/b[2]$end$varwire10b[1]$end$varwire11cin$end$varwire16sum[4]$end$varwire17sum[3]$end$varwire18sum[2]$end$varwire19sum[1]$end$varwire1:cout$end$upscope$end$upscope$end$enddefinitions$end#0$dumpvars1!1"1#1$1%1&1'1(0)0*0+0!0:09070503利用ModelSim查看VCD文件如上面的文件格式所示,VCD文件仅仅是文本文件,需要用波形查看器才可以直观地观察里面的数据波形。在ModelSim中需要把VCD文件转换为wlf格式的文件,才可以用波形查看器查看。以上一页完整的VCD文件mylog.vcd为例。在ModelSim的命令框中输入:vcd2wlfmylog.vcdmylog.wlf即可生成名为mylog.wlf的波形文件,直接用ModelSim打开即可Testbench设计进阶高级Testbench概述文件的读写VCD数据库文件断言语句(Assert)高级Testbench实例断言语句(Assert)断言语句的使用方法断言语句的应用实例ModelSim中的断言警告级别的设置断言语句(Assert)断言语句(Assert)语句可以在仿真的过程中,检查一个条件并报告信息。根据所选择的严重级别和仿真工具的设置,在ASSERT语句报告了信息后,继续执行(警告级别WARNING)或者停止(错误ERROR和致命错误FAILURE)。默认的严重级别为ERROR。断言语句的使用方法下面的例子是断言语句在仿真时的应用,它判断了仿真的时间,如果当前时间为1000ns,则仿真完成,使用ERROR严重级别终止仿真过程。PROCESSBEGINASSERT(NOW<=1000ns) REPORT“Simulationcompletedsuccessfully” SEVERITYERROR;ENDPROCESS;断言语句判断条件的判断结果为FALSE,则执行后面的报告及严重级语句,否则跳过这些错误报告语句并继续执行。当(NOW<=1000ns)不成立时,执行这两条语句断言语句的使用方法可以使用ASSERT语句设定一个判断条件,以便对仿真的某个结果或值做出响应,例如下面的实例程序。PROCESS(q)BEGINASSERT(q/=“1001”) REPORT“Theshiftergetstheresult!” SEVERITYERROR;ENDPROCESS;如果信号q等于“1001”,则终止仿真,并输出“Theshiftergetstheresult!”。断言语句的应用实例下面以一个简单的实例来讲述使用断言语句来响应一个仿真的过程。【例1-1】4位加减计数器的仿真计数器的位数为4位带有CLR清零端当DIR信号为高电平时,计数器为加1计数器;低电平时为减1计数器;LIBRARYIEEE;USEIEEE.STD_LOGIC_1164.ALL;USEIEEE.STD_LOGIC_UNSIGNED.ALL;ENTITYcounterISPORT(CLK,CLR,DIR:INSTD_LOGIC;CT_RESULT:OUTSTD_LOGIC_VECTOR(3DOWNTO0));ENDcounter;ARCHITECTUREBehavOFcounterISSIGNALTMP:STD_LOGIC_VECTOR(3DOWNTO0);BEGINPROCESS(CLK,CLR)BEGINIF(CLR=‘1’)THEN--清零TMP<="0000";ELSIF(CLK'EVENTANDCLK='1')THENIF(DIR='1')THEN--当DIR为高电平时,计数器为加1计数器TMP<=TMP+1;ELSETMP<=TMP-1;--当DIR为低电平时,计数器为减1计数器ENDIF;ENDIF;ENDPROCESS;CT_RESULT<=TMP;ENDBehav;4位加减计数器设计引用库声明定义实体定义实体的功能LIBRARYIEEE;USEIEEE.STD_LOGIC_1164.ALL;USEIEEE.STD_LOGIC_UNSIGNED.ALL;USEIEEE.NUMERIC_STD.ALL;ENTITYcounter_tbISENDcounter_tb;ARCHITECTUREBEHAVOFcounter_tbISCOMPONENTcounterPORT(CLK,CLR,DIR:INSTD_LOGIC;CT_RESULT:OUTSTD_LOGIC_VECTOR(3DOWNTO0));ENDCOMPONENT;

SIGNALCLK:STD_LOGIC:='0';SIGNALCLR:STD_LOGIC:='0';SIGNALDIR:STD_LOGIC:='0';

SIGNALCT_RESULT:STD_LOGIC_VECTOR(3DOWNTO0);

CONSTANTCLK_PERIOD:TIME:=40NS;

4位加减计数器Testbench声明使用的库定义一个没有端口的实体声明待测试的实体定义激励信号仿真时钟信号的周期BEGINUUT:counterPORTMAP(CLK=>CLK,CLR=>CLR,DIR=>DIR,CT_RESULT=>CT_RESULT);CLK_GEN:PROCESSBEGINCLK<='1';WAITFORCLK_PERIOD/2;CLK<='0';WAITFORCLK_PERIOD/2;ENDPROCESS;

TB:PROCESSBEGINCLR<='1';DIR<='1';WAITFOR20NS;CLR<='0';WAITFOR280NS;DIR<='0';WAITFOR320NS;WAIT;--WAITFOREVERENDPROCESS;4位加减计数器Testbench例化待测试的实体,并连接激励信号时钟产生进程激励信号产生进程PROCESS(CT_RESULT)BEGINASSERT(CT_RESULT/="1001")REPORT"Theconutergetstonine!"SEVERITYERROR;ENDPROCESS;ENDBEHAV;4位加减计数器TestbenchASSERT语句分析:这个例子的断言语句用于判断计数的结果是否等于“1001”,条件判断使用了“不等于(/=)”逻辑,如果判断条件为FALSE,即计数值等于“1001”时,报告错误。仿真测试结果#**Error:Theconutergetstonine!#Time:840nsIteration:3Instance:/counter_tb在ModelSim的输出窗口中输出以下信息:在ModelSim的输出波形如图:红色标记处就是断言语句输出错误信息的时刻ModelSim中的断言警告级别ModelSim中设定了以下断言警告级别(从高到低)Fatal、Failure、Error、Warning、Note/Info在ModelSim中,对于哪个级别及以上的警告会让仿真停止呢?

答案:ModelSim里面有相关的选项设置,默认情况下为“Failure”级别及以上(即Failure和Fatal)。因此,在默认设置下,我们的例程中Error级别的警告不会中断仿真的进程。ModelSim中的断言警告级别若需要更改ModelSim断言的设置,请执行以下步骤。①②根据需要设置Testbench设计进阶高级Testbench概述文件的读写VCD数据库文件断言语句(Assert)高级Testbench实例高级Testbench实例高级Testbench实例下面的仿真实例将综合运用前文所述的ASSERT断言语句和文件操作TEXTIO程序包。待验证的实体是一个8位加法器,仿真用的Testbench文件从文本文件中读取激励信号矢量,并将仿真的结果和文本文件中的期望值进行比较,自动完成验证过程。激励信号8位加法器输入输出输出值和期望值比较测试矢量文件测试结果(Yes/No)期望值8位加法器实体--------------------------------------------------------------------------Single-bitadder------------------------------------------------------------------------libraryIEEE;useIEEE.std_logic_1164.all;entityadderisport(a:instd_logic;b:instd_logic;cin:instd_logic;sum:outstd_logic;cout:outstd_logic);endadder;--descriptionofadderusingconcurrentsignalassignmentsarchitecturertlofadderisbeginsum<=(axorb)xorcin;cout<=(aandb)or(cinanda)or(cinandb);endrtl;①--------------------------------------------------------------------------N-bitadder--ThewidthoftheadderisdeterminedbygenericN------------------------------------------------------------------------libraryIEEE;useIEEE.std_logic_1164.all;entityadderNisgeneric(N:integer:=16);port(a:instd_logic_vector(Ndownto1);b:instd_logic_vector(Ndownto1);cin:instd_logic;sum:outstd_logic_vector(Ndownto1);cout:outstd_logic);endadderN;②8位加法器实体(续)--structuralimplementationoftheN-bitadderarchitecturestructuralofadderNiscomponentadderport(a:instd_logic;b:instd_logic;cin:instd_logic;sum:outstd_logic;cout:outstd_logic);endcomponent;signalcarry:std_logic_vector(0toN);begincarry(0)<=cin;cout<=carry(N);--instantiateasingle-bitadderNtimesgen:forIin1toNgenerate add:adderportmap( a=>a(I), b=>b(I), cin=>carry(I-1), sum=>sum(I), cout=>carry(I));endgenerate;endstructural;③--behavioralimplementationoftheN-bitadderarchitecturebehavioralofadderNisbeginp1:process(a,b,cin) variablevsum:std_logic_vector(Ndownto1); variablecarry:

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论