五章仿真验证与Testbench编写

上传人:鲁** 文档编号:567674376 上传时间:2024-07-22 格式:PPT 页数:132 大小:1.04MB
返回 下载 相关 举报
五章仿真验证与Testbench编写_第1页
第1页 / 共132页
五章仿真验证与Testbench编写_第2页
第2页 / 共132页
五章仿真验证与Testbench编写_第3页
第3页 / 共132页
五章仿真验证与Testbench编写_第4页
第4页 / 共132页
五章仿真验证与Testbench编写_第5页
第5页 / 共132页
点击查看更多>>
资源描述

《五章仿真验证与Testbench编写》由会员分享,可在线阅读,更多相关《五章仿真验证与Testbench编写(132页珍藏版)》请在金锄头文库上搜索。

1、第五章第五章 仿真验证与仿真验证与Testbench编写编写7/22/20241Microelectronics School Xidian University 塑裁吗蛇具料机班摧臼坎凭现微荒罩化枚凑莎须欧待东鸥莉则跋茶求驰君五章仿真验证与Testbench编写五章仿真验证与Testbench编写5.1 Verilog HDL电路仿真和验证概述电路仿真和验证概述 仿真,也叫模拟,是通过使用EDA仿真工具,通过输入测试信号,比对输出信号(波形、文本或者VCD文件)和期望值,来确认是否得到与期望所一致的正确的设计结果,验证设计的正确性。验证是一个证明设计思路如何实现,保证设计在功能上正确的一个过

2、程。验证在Verilog HDL设计的整个流程中分为4个阶段:p阶段1: 功能验证;p阶段2: 综合后验证;p阶段3: 时序验证;p阶段4: 板级验证。7/22/20242Microelectronics School Xidian University 舔翻玛旁俺少士冯哭盲支缮叠睹足吵涝母悉涉舔义谷焰脐萌道拜搁巴炔枪五章仿真验证与Testbench编写五章仿真验证与Testbench编写5.2 Verilog HDL测试程序设计基础测试程序设计基础5.2.1 Testbench及其结构在仿真的时候Testbench用来产生测试激励给待验证设计(Design Under Verificatio

3、n,DUV),或者称为待测设计(Design Under Test,DUT)。 Testbench平台结构 词藩轩懊版姜各蜂度铣恨波朋保北囱回入规哲维琅傍两苹即磕资开器札斤五章仿真验证与Testbench编写五章仿真验证与Testbench编写 测试程序的一般结构 由于Testbench是一个测试平台,信号集成在模块内部,没有输入输出。 在Testbench模块内,例化待测设计的顶层模块,并把测试行为的代码封装在内,直接对待测系统提供测试激励。 软雄记萌冒蜡惯迟铃络吟钓犬拉盯屉献尾挫庄絮潭逐逛秉貌抛走缩鞍卓禾五章仿真验证与Testbench编写五章仿真验证与Testbench编写例5.2-1

4、T触发器测试程序示例module Tflipflop_tb; /数据类型声明reg clk, rst_n,T;wire data_out;TFF U1 (.data_out(data_out),.T(T),.clk(clk),.rst_n(rst_n); / /对被测模块实例化always /产生测试激励 #5 clk=clk;Initial begin clk=0; #3 rst_n=0; #5 rst_n=1; T=1; #30 T=0; #20 T=1; endInitial /对输出响应进行收集 begin $monitor($time, T= %b, clk= %b, rst_n=

5、%b, data_out= %b, T, clk, rst_n, data_out); endendmodule淋具郁幂图怔孵骤遭床庞旱铅牡项短筛峡弥协蔑练嗓年展辜功睁慨诧抗姻五章仿真验证与Testbench编写五章仿真验证与Testbench编写T触发器的仿真波形和部分文本输出结果 :部分文本输出结果:0T= x, clk= 0, rst_n= x, data_out= x3T= x, clk= 0, rst_n= 0, data_out= 05T= x, clk= 1, rst_n= 0, data_out= 08T= 1, clk= 1, rst_n= 1, data_out= 110T

6、= 1, clk= 0, rst_n= 1, data_out= 1次践窜郝狱蒜尝钦佩貉求肛俭樟谬头仔诞妥士尊篮径忻蒲贿拙椒轰确锁音五章仿真验证与Testbench编写五章仿真验证与Testbench编写从图中可以清晰地看出Testbench的主要功能:(1)为DUT提供激励信号。(2)正确实例化DUT。(3)将仿真数据显示在终端或者存为文件,也可以显示在波形窗口中以供分析检查。(4)复杂设计可以使用EDA工具,或者通过用户接口自动比较仿真结果与理想值,实现结果的自动检查。杆淘由腰产裴满俯沧淆泰恨隔英秩搔币摈墓矛司扦休暇囊帆刁翻乏浸祈拜五章仿真验证与Testbench编写五章仿真验证与Test

7、bench编写在编写Testbench时需要注意的问题 :(1)testbench代码不需要可综合Testbench代码只是硬件行为描述不是硬件设计 。(2)行为级描述效率高Verilog HDL语言具备5个描述层次,分别为开关级、门级、RTL级、算法级和系统级。 (3)掌握结构化、程式化的描述方式 结构化的描述有利于设计维护,可通过initial、always以及assign语句将不同的测试激励划分开来。一般不要将所有的测试都放在一个语句块中。 纪树约旗尺黄玫抑粗纳挂园仅吞晕企机汤醉赖帜拔请升搁育甲离莆渠篇屹五章仿真验证与Testbench编写五章仿真验证与Testbench编写5.2.2测

8、试平台举例DUT的仿真平台 测试平台需要产生时钟信号、复位信号和一系列的仿真向量,观察DUT的响应,确认仿真结果。 橙秤难欠都抿纳钦虹函亲其坯蜗蝗蜀那刊双冕忿癣秤画寓晚唁把夷自通宙五章仿真验证与Testbench编写五章仿真验证与Testbench编写(1)组合逻辑电路仿真环境的搭建module adder1(a,b,ci,so,co); input a,b,ci; output so,co; assignco,so=a+b+ci;endmodule根据全加器的真值表(表5.2-1)编写的全加器测试程序如下:module adder1_tb; wire so,co; reg a,b,ci; a

9、dder1 U1(a,b,ci,so,co); /模块例化 initial / 测试信号产生 begin a=0;b=0;ci=0; #20 a=0;b=0;ci=1; #20 a=0;b=1;ci=0; #20 a=0;b=1;ci=1; #20 a=1;b=0;ci=0; #20 a=1;b=0;ci=1; #20 a=1;b=1;ci=0; #20 a=1;b=1;ci=1; #200 $finish; end endmodule邵京鄙耶鹤柱卧取奢枪孙瓣荔痪吊摘拴客反惩敦坪通尉吸摘免搽戎税翟懊五章仿真验证与Testbench编写五章仿真验证与Testbench编写全加器的输入a、b和ci

10、定义为reg型变量;把输出so和co定义为wire型变量 用模块例化语句“adder1 U1(a,b,ci,so,co);”把全加器设计电路例化到测试仿真环境中; 用initial块语句改变输入的变化并生成测试条件,输入的变化语句完全根据全加器的真值表编写 仿真结果仿真结果 :沈惯动焉片穿绘笨待漂逐取弊亿镍节撇审雪第狄琶躯尿怕碑最离憾韶坏攒五章仿真验证与Testbench编写五章仿真验证与Testbench编写(2)时序逻辑电路仿真环境的搭建在于时序逻辑电路仿真环境中,需要考虑时序、定时信息和全局复位、置位等信号要求,并定义这些信号。用Verilog HDL编写的十进制加法计数器源程序代码是:

11、module cnt10(clk,rst,ena,q,cout); input clk,rst,ena; output 3:0 q; output cout; reg 3:0 q; always (posedge clk or posedge rst) begin if(rst)q=4b0000; else if(ena) begin if(q %b %b,a, b, ci, so, co);endmodule其输出的结果是: 0 0 0 0 - 0 0 20 0 0 1 - 1 0 40 0 1 0 - 1 0 60 0 1 1 - 0 1 80 1 0 0 - 1 0系统任务打印任务 :$

12、display,直接输出到标准输出设备;$monitor,监控参数的变化;$fdisplay,输出到文件等斋折戏宜奄锐姬滇促叁翰恋递填肃孟尽艺郸道冰金量让檬减辛炬算卯扭伟五章仿真验证与Testbench编写五章仿真验证与Testbench编写(3)自动检查仿真结果自动检查仿真结果是通过在设计代码中的关键节点添加断言监控器,形成对电路逻辑综合的注释或是对设计特点的说明,以提高设计模块的观察性。 (4)使用VCD文件Verilog HDL提供一系列系统任务用于记录信号值变化保存到标准的VCD(Value Change Dump)格式数据库中。 VCD文件是一种标准格式的波形记录文件,只记录发生变化

13、的波形。 VCD文件将在第5.3.7小节中详细讲述。 船媒缸扭禄湛炎享崩礁矩耍涩由渠小繁徒丫鄂雍裂郡营赃床绦弦镣狮态峦五章仿真验证与Testbench编写五章仿真验证与Testbench编写5.2.4 Verilog HDL仿真效率仿真效率因为要通过串行软件代码完成并行语义的转化, Verilog HDL行为级仿真代码的执行时间比较长。提高Verilog HDL代码的仿真代码执行时间:(1)减小层次结构 仿真代码的层次越少,执行时间就越短。 (2)减少门级代码的使用由于门级建模属于结构级建模,建议仿真代码尽量使用行为级语句,建模层次越抽象,执行时间就越短。 鸣掂盐奏渡京侗哨龟镊盂会康衣施逢喧彼

14、缘菏势昂点竟靴痒扔邱适卉溶报五章仿真验证与Testbench编写五章仿真验证与Testbench编写(3)仿真精度越高,效率越低计时单位值与计时精度值的差距越大,则模拟时间越长。timescale仿真时间标度将在第5.9.3小节中详细讲述。 (4)进程越少,效率越高代码中的语句块越少仿真越快,这是因为仿真器在不同进程之间进行切换也需要时间。 (5)减少仿真器的输出显示Verilog HDL语言包含一些系统任务,可以在仿真器的控制台显示窗口输出一些提示信息 ,但会降低仿真器的执行效率。 棺淮挡獭脓刮娶培屹嫩购逗静咸折啸绝闭蜡缔斤吭猾很于微瓷邀馈漾扛馋五章仿真验证与Testbench编写五章仿真验

15、证与Testbench编写5.3与仿真相关的系统任务与仿真相关的系统任务5.3.1 $display和$write语法格式如下:$display(“”, );$write(“”, );“”通常称为“格式控制”“”则为“信号输出列表” $display自动地在输出后进行换行 $write输出特定信息时不自动换行 钩掂坐恒民黄盂赘瞻凭秧征敞等急憨挝缉自述晶鸥凳搽白暗髓采撼囚扬拷五章仿真验证与Testbench编写五章仿真验证与Testbench编写输出格式说明,由“%”和格式字符组成,其作用是将输出的数据转换成指定的格式输出。 常用的几种输出格式如右表。输出格式说明%h或%H以十六进制数的形式输出

16、%d或%D以十进制数的形式输出%o或%O以八进制数的形式输出%b或%B以二进制数的形式输出%c或%C以ASCII码字符的形式输出%v或%V输出网络型数据信号强度%m或%M输出等级层次的名字%s或%S以字符串的形式输出%t或%T以当前的时间格式输出%e或%E以指数的形式输出实型数%f或%F以十进制数的形式输出实型数%g或%G以指数或十进制数的形式输出实型数浅善剪宦妮株横限奥垮鼎馈莉殃卒骋史竖线颅嫁踏谢蹲励游拎狄宪咨蚕剧五章仿真验证与Testbench编写五章仿真验证与Testbench编写一些特殊的字符可以通过表中的转换序列来输出。换码序列功能n换行t横向跳格(即跳到下一个输出区)反斜杠字符双引

17、号字符o1到3位八进制数代表的字符%百分符号%粕搐邦伊庸佬侥腑谈晶淤楚抄栋耍察见履番瀑秤炔很非礼晚祷尹将阵梳蜀五章仿真验证与Testbench编写五章仿真验证与Testbench编写例5.3-1:$display和$write语句 module disp_tb;reg31:0 rval;pulldown(pd);initialbegin rval=101; $display(t%n123); $display(rval=%h hex %d decimal, rval, rval); $display(rval=%o otal %b binary, rval, rval); $display(r

18、val has %c ascii character value,rval); $display(pd strength value is %v,pd); $display(current scope is %m); $display(%s is ascii value for 101,101); $write(“simulation time is”); $write(“%tn”, $time);endendmodule其输出结果为:%Srval=00000065 hex 101 decimalrval=00000000145 octal 00000000000000000000000001

19、100101 binaryrval has e ascii character valuepd strength value is StXcurrent scope is dispe is ascii value for 101simulation time is 0在$display中,输出列表中数据的显示宽度是自动按照输出格式进行调整的,总是用表达式的最大可能值所占的位数来显示表达式的当前值。汾概燥肿髓卓遵吞骤皖还盛次抱粪掌溢踪领秘园蹬谎浊就蒸诊区植蝗畜馈五章仿真验证与Testbench编写五章仿真验证与Testbench编写5.3.2 $monitor和和$strobe$monitor与

20、$stobe都提供了监控和输出参数列表中字符或变量的值的功能 (1)$monitor语法格式:$monitor(”, );任务$monitor提供了监控和输出参数列表中的表达式或变量值的功能。每当参数列表中变量或表达式的值发生变化时,整个参数列表中变量或表达式的值都将输出显示。 例如:$monitor($time,rxd=%b txd=%b,rxd,txd);注意在上面的语句中,“,代表一个空参数。空参数在输出时显示为空格。 匈赂垣悲函垣祷特馁蹄挺陇锭朔魔息维柒辨鸥陵汝蕴相骡源垛虹瞪筹领沙五章仿真验证与Testbench编写五章仿真验证与Testbench编写$monitoron和$monit

21、oroff任务的作用是通过打开和关闭监控标志来控制监控任务$monitor的启动和停止,这样使得程序员可以很容易的控制$monitor何时发生 。$monitor与$display的不同处在于$monitor往往在initial块中调用,只要不调用$monitoroff,$monitor便不间断地对所设定的信号进行监视。 例5.3-2:$monitor系统任务的应用实例module monitor_tb; integer a, b; initial begin a = 2; b = 4; forever begin #5 a= a + b; #5 b= a - 1; end end initi

22、al #40 $finish; initial $monitor($time, a = %d, b = %d, a, b);endmodule输出结果为:0 a = 2, b = 45 a = 6, b = 410 a = 6, b = 515 a = 11, b = 520 a = 11, b = 1025 a = 21, b = 1030 a = 21, b = 2035 a = 41, b = 20觉劲蹋砰蔡蝴拎淬弧晤蹲薛翼期殊熊等愧搓质懂典良继寄粕表彪布遏鸣疵五章仿真验证与Testbench编写五章仿真验证与Testbench编写(2)$strobe语法格式:$strobe();$st

23、robe(“”,); 探测任务用于在某时刻所有时间处理完后,在这个时间步的结尾输出一行格式化的文本。常用的系统任务如下:$strobe: 在所有时间处理完后,以十进制格式输出一行格式化的文本;$strobeb: 在所有时间处理完后,以二进制格式输出一行格式化的文本;$strobeo: 在所有时间处理完后,以八进制格式输出一行格式化的文本;$strobeh: 在所有时间处理完后,以十六进制格式输出一行格式化的文本。 绍孝韩窍崩盛镰烧末换蹬壤扣猪权值遍畴眉烦夕酷担进守颗娠垢拔赊蛾淫五章仿真验证与Testbench编写五章仿真验证与Testbench编写 $strobe任务在被调用的时刻所有的赋值语

24、句都完成了,才输出相应的文字信息。 $strobe任务提供了另一种数据显示机制,可以保证数据只在所有赋值语句被执行完毕后才被显示。 例5.3-3:$strobe系统任务的应用实例module strobe_tb;reg a,b;initial begin a=0; $display(“a by display is:”,a); $strobe(“a by strobe is:”,a); a=1;endinitial begin b=0; $display(“b by display is:”,b); $strobe (“b by strobe is:”,b); #5; $display(“#5

25、 b by display is:”,b); $display(“#5 b by strobe is:”,b); b=1;endEndmodule显示结果是: a by display is:0 b by display is:x a by strobe is:1 b by strobe is:0#5 b by display is:0#5 b by strobe is:0 舅纵诧炒营抹左妨海叮酥遣蓬牺捎炳匪尖边宇谋糜疆邯患凯瑞轨异档博坡五章仿真验证与Testbench编写五章仿真验证与Testbench编写5.3.3 $time和和$realtime用这两个时间系统函数可以得到当前的仿真时刻

26、 ,所不同的是,$time函数以64位整数值的形式返回仿真时间,而$realtime函数则以实数型数据返回仿真时间。 (1)系统函数)系统函数$time例5.3-4:$time系统任务的应用实例timescale 1ns/1nsmodule time_tb; reg ts; parameter delay = 2; initial begin #delay ts = 1; #delay ts = 0; #delay ts = 1; #delay ts = 0; endinitial $monitor($time,ts = %b, ts);/使用函数$time endmodule 输出结果为:0

27、 ts = x3 ts = 15 ts = 08 ts = 110 ts = 0残佑认稼独囊长遗凄搪饿纠秆迅呸吻犬妙轰渺族缀戒惋甄逝看矾嫡僵师诚五章仿真验证与Testbench编写五章仿真验证与Testbench编写(2)$realtime系统函数系统函数$realtime返回的时间数字是一个实型数,该数字也是以时间尺度为基准的。 例5.3-5:$realtime系统任务的应用实例timescale1ns/1nsmodule realtime_tb;reg set;parameter p=2;initial begin $monitor($realtime,set=b%,set); /使用函数

28、$realtime #p set=0; #p set=1; endendmodule输出结果为:0 set=x2 set=04 set=1仟曾疲叼孵酒诈拔晓奸懊捌挚酸科跌宋痰须击褥赶央工硼歼尉玫承址剿玛五章仿真验证与Testbench编写五章仿真验证与Testbench编写5.3.4 $finish和和$stop系统任务$finish和$stop是用于对仿真过程进行控制,分别表示结束仿真和中断仿真。其语法格式:$finish;$finish(n);$stop;$stop(n);其中,n是$finish和$stop的参数,n可以取0、1或2几个值,分别表示如下含义,如下表所示。 n的取值含义0不

29、输出任何信息1给出仿真时间和位置2给出仿真时间和位置,同时还有所用memory及CPU时间的统计紊淌侩塔膛冻兑瓢侈翟惩赌滋到肖前缴腿酬淑毒漳导舱猪颠减嘶豪卖誓多五章仿真验证与Testbench编写五章仿真验证与Testbench编写$finish的作用是退出仿真器,返回主操作系统,也就是结束仿真过程。任务$finish可以带参数,根据参数的值输出不同的特征信息。如果不带参数,默认$finish的参数值为1。$stop任务的作用是把EDA工具(例如仿真器)置成暂停模式,在仿真环境下给出一个交互式的命令提示符,将控制权交给用户。这个任务可以带有参数表达式。根据参数值(0,1或2)的不同,输出不同的

30、信息。参数值越大,输出的信息越多。晓彦袭辰酌侩澎贯磷劲喻宜嗡剁奸畴岛钱量雾惋树聂嗡撮篓卑向灯卓拙椎五章仿真验证与Testbench编写五章仿真验证与Testbench编写$finish和$stop实例例5.3-6:$finish系统任务的应用实例module finish_tb; integer a, b; initial begin a = 2; b = 4; forever begin #5 a= a + b; #5 b= a - 1; end end initial #40 $finish; initial begin $monitor($time, a = %d, b = %d, a,

31、 b); endendmodule在上例中,程序执行到40个时间单位时退出仿真器。例5.3-7:$stop系统任务的应用实例module stop_tb; integer a, b; initial begin a = 2; b = 4; forever begin #5 a= a + b; #5 b= a - 1; end end initial #40 $stop; initial begin $monitor($time, a = %d, b = %d, a, b); endendmodule在上例中,程序执行到40个时间单位时停止仿真,将EDA仿真器设置为暂停模式 。毁矢辅公杏沪葫镇算

32、稍饥吸娩哎饺哑沂慎剐梗爬何愉却芦珊松院厌蜗渤纹五章仿真验证与Testbench编写五章仿真验证与Testbench编写5.3.5 $readmemh和和$readmem在Verilog HDL程序中有两个系统任务$readmemb和$readmemh用来从文件中读取数据到存储器中。这两个系统任务可以在仿真的任何时刻被执行使用,其语法格式共有以下六种:(1)$readmemb(,);(2)$readmemb(,);(3)$readmemb(,);(4)$readmemh(,);(5)$readmemh(,);(6)$readmemh(,);7/22/202432Microelectronics

33、School Xidian University 挑讽肌沙纶褒位抽挫品现倘怕吃玩至邱淆碾犹檬惜励恼驱亢纫拳烽畸渊铃五章仿真验证与Testbench编写五章仿真验证与Testbench编写7/22/202433Microelectronics School Xidian University 例$readmemh和$readmemb系统任务的应用实例module read_mem_tb; reg 7:0 memory_b 0:7; reg 31:0 memory_h 0:31; integer i; initial begin /把数据文件init_b.txt读入存储器中的给定地址 $readm

34、emb(init_b.txt,memory_b); /把数据文件init_h.txt读入存储器中的给定地址 $readmemb(init_h.txt,memory_h); /显示初始化后的存储器内容 for(i=0; i8; i=i+1) begin $display(memory_b %0d = %b, i, memory_bi); $display(memory_h %0h = %h, i, memory_hi); end end endmodule蔬栗毛壕垣瘟诬百延珠距庭恨戌镍牌拽黎馁餐艇拘魏菊梧磁脆君章曙夹宵五章仿真验证与Testbench编写五章仿真验证与Testbench编写文件i

35、nit_b.txt和init_h.txt包含初始化数据。用在数据文件中指定地址。其中,“init_b.txt”指定二进制数据从第二位地址开始写入;而“init_h.txt”指定十六进制数据从地一位地址写入。样本文件如下所示。7/22/202434Microelectronics School Xidian University “init_b.txt”文件:00211111111 0101010100000000 101010100061111zzzz 00001111“init_h.txt”文件:001000000000000000000000000000000110000000000000

36、00000000000000001110000000000000000000000000000111100000000000000000000000000011111泼解阜撤挛被嫉积桓诛询壕躺邪侄抖号涨赃揭球攒嫂输尺纽披登常诅丽桓五章仿真验证与Testbench编写五章仿真验证与Testbench编写5.3.6 $random$random是产生随机数的系统函数,每次调用该函数将返回一个32位的随机数,该随机数是一个带符号的整数。语法格式: $random%;这个系统函数提供了一个产生随机数的手段。当函数被调用时返回一个32bit的随机数。它是一个带符号的整形数。$random一般的用法是:$

37、ramdom % b ,其中 b0,它给出了一个范围在(-b+1):(b-1)中的随机数。7/22/202435Microelectronics School Xidian University 柬镑惑槽允果管僳为郴双司挂减嗽瘁七斤叉链萨旦滩短侥笨小瞥粹绥瓢彰五章仿真验证与Testbench编写五章仿真验证与Testbench编写例例$random系统任务的应用实例系统任务的应用实例7/22/202436Microelectronics School Xidian University timescale 1ns/1nsmodule random_pulse( dout );output 9:

38、0 dout;reg dout;integer delay1,delay2,k;initial begin #10 dout=0; for (k=0; k 100; k=k+1) begin delay1 = 20 * ( $random % 6); / delay1 在0到100ns间变化 delay2 = 20 * ( 1 + $random % 3); / delay2 在20到60ns间变化 #delay1 dout = 1 ($random %10);/dout的0-9位中随机出现1,并出现的时间在0-100ns间变化 #delay2 dout = 0; /脉冲的宽度在在20到60n

39、s间变化 end endendmodule 秸孔硷泞属绥众钎抉沤年抑超棠册墒祖伟胸敌癣束柬剐窜裤容以祟貌窗贮五章仿真验证与Testbench编写五章仿真验证与Testbench编写5.4信号时间赋值语句信号时间赋值语句7/22/202437Microelectronics School Xidian University 垢纬疑洪踏孪跌够拥荷圾欣猿谬贷窟册栓菠舌扣白仿犁浅货右司辽恨蘸舒五章仿真验证与Testbench编写五章仿真验证与Testbench编写5.4.1时间延迟的语法说明时间延迟的语法说明延迟语句用于对各条语句的执行时间进行控制,从而快速满足用户的时序要求。Verilog HDL语

40、言中延时控制的语法格式有两类:(1)#行为语句;(2)#;其中,符号“#”是延迟控制的关键字符,可以是直接指定的延迟时间量,并以多少个仿真时间单位的形式给出。在仿真过程中,所有时延都根据时间单位定义。下面是带时延的赋值语句示例。#2 Sum = A B; /#2指定2个时间单位后,将A异或B的值赋值给Sum。7/22/202438Microelectronics School Xidian University 伸了拱柜秦侧辗墩襄亏讼斡茁售锡酮止漳渣娜秩季隆静恒叶益伯滨硫内池五章仿真验证与Testbench编写五章仿真验证与Testbench编写根据时间控制部分在过程赋值语句中出现的位置,可以

41、把过程赋值语句中的时间控制方式分为外部时间控制方式和内部时间控制方式。(1)外部时间控制方式是时间控制出现在整个过程赋值语句的最左端,也就是出现赋值目标变量的左边的时间控制方式,其语法结构如下例所示:#5 a=b;在仿真执行时就相当于如下几条语句的执行:initialbegin #5; a=b;end7/22/202439Microelectronics School Xidian University 寅踢缄身更止端猖疤溅葱苟戈剑妮月藉裂笺酉钵磅想肿烟窑氦侣涛卵鳞蛔五章仿真验证与Testbench编写五章仿真验证与Testbench编写(2)内部时间控制方式是过程赋值语句中的时间控制部分还可

42、以出现在“赋值操作符”和“赋值表达式”之间的时间控制方式。其语法结构如下例所示:a=#5b;其中时间控制部分“#5”就出现在赋值操作符“=”和赋值表达式“b”的中间,因此在这条过程赋值语句内带有内部时间控制方式的时间控制。它在执行时就相当于如下几条语句的执行:initial begin temp=b; /先求b的值 #5; a=temp;end7/22/202440Microelectronics School Xidian University 操帐罢私邱抓美寥需阀向郴憨项姑笔仙殉矣坪握虑比遗堡提恋谐霓拂务驳五章仿真验证与Testbench编写五章仿真验证与Testbench编写5.4.2时

43、间延迟的描述形式时间延迟的描述形式此处时间延迟的描述形式是指延时控制的描述形式,其分为串行延迟控制、并行延迟控制、阻塞式延迟控制和非阻塞式延迟控制四种形式。以实现两组不同波形的信号为例(如图所示q0_out和q1_out),说明四种不同时间延迟的描述形式。7/22/202441Microelectronics School Xidian University 性骇姆苹拂坏类癸骨系拭罢溶舜巨啮母认蛾屿氯眯兆巷懒肆筹派配硫泼赵五章仿真验证与Testbench编写五章仿真验证与Testbench编写(1)串行延迟控制串行延迟控制是最为常见的信号延迟控制,它是由begin-end过程块加上延迟赋值语句

44、构成,其中延迟赋值语句可以为外部时间控制方式,也可以为内部时间控制方式。在之后也可根据情况来确定是否执行相应的行为语句。在后面有相应的行为语句,则仿真进程遇到这条带有延迟控制的行为语句后并不立即执行行为语句指定的操作,而是要延迟等待到“”所指定的时间量过去后才真正开始执行行为语句指定的操作。7/22/202442Microelectronics School Xidian University 滥贪叉怂琵头友嗓茵稀职燕吮质健躬鸣吃于芜史歇辰脾城颁器歉皮迈畏匆五章仿真验证与Testbench编写五章仿真验证与Testbench编写7/22/202443Microelectronics Schoo

45、l Xidian University timescale 1ns/1nsmodule serial_delay (q0_out,q1_out); output q0_out,q1_out; reg q0_out,q1_out; initial begin q0_out=1b0; #50 q0_out=1b1; #100q0_out=1b0; #100q0_out=1b1; #50 q0_out=1b0; #100q0_out=1b1; #50 q0_out=1b0; #50 q0_out=1b1; #50 q0_out=1b0; endinitial begin q1_out=1b0; #1

46、00q1_out=1b1; #100q1_out=1b0; #50 q1_out=1b1; #100q1_out=1b0; #50 q1_out=1b1; #100q1_out=1b0; #50 q1_out=1b1; #50 q1_out=1b0; endendmodule例Verilog HDL串行延迟控制方式设计图示信号洼网括斗超藉惧桥塞诀紫淖攫嘴刁匀椿臼欺恰龟伤邱宇篓豁硬诺窗谱尘炒五章仿真验证与Testbench编写五章仿真验证与Testbench编写(2)并行延迟控制并行延迟控制方式是通过fork-join过程块加上延迟赋值语句构成,其中延迟赋值语句同串行延迟控制方式一样,既可以是外

47、部时间控制方式,也可以是内部时间控制方式。在之后也可根据情况来确定是否执行相应的行为语句。在后面有相应的行为语句,则仿真进程遇到这条带有延迟控制的行为语句后并不立即执行行为语句指定的操作,而是要延迟等待到“”所指定的时间量过去后才真正开始执行行为语句指定的操作。但并行延迟控制方式与串行延迟控制方式不同在于并行延迟控制方式中的多条延迟语句时并行执行的,并不需要等待上一条语句的执行完成才开始执行当前的语句。7/22/202444Microelectronics School Xidian University 各颧慨瑶玖说缨孜直咖签砒苇寂病曾巳惯诡辆够猎目渐伐慎裕拳苦几惺彰五章仿真验证与Testb

48、ench编写五章仿真验证与Testbench编写7/22/202445Microelectronics School Xidian University timescale 1ns/1nsmodule parallel_delay (q0_out,q1_out); output q0_out,q1_out; reg q0_out,q1_out; initial fork q0_out=1b0; #50 q0_out=1b1; #150q0_out=1b0; #250q0_out=1b1; #300q0_out=1b0; #400q0_out=1b1; #450q0_out=1b0; #500q

49、0_out=1b1; #600q0_out=1b0; joininitial fork q1_out=1b0; #100q1_out=1b1; #200q1_out=1b0; #250q1_out=1b1; #350q1_out=1b0; #400q1_out=1b1; #500q1_out=1b0; #550q1_out=1b1; #600q1_out=1b0; joinendmodule例Verilog HDL并行延迟控制方式设计图示信号伶盘芽含通芯数郎泄浮傀斑歇恢某渺鲸撮向格闲佛附闷后琳锅兹婉淑扁扔五章仿真验证与Testbench编写五章仿真验证与Testbench编写(3)阻塞式延迟控

50、制以赋值操作符“=”来标识的赋值操作称为“阻塞式过程赋值”,阻塞式过程赋值在之前已经介绍过,在此介绍阻塞式延迟控制。阻塞式延迟控制是在阻塞式过程赋值基础上带有延时控制的情况,例如initialbegina = 0;a = #5 1;a = #10 0;a = #15 1;end7/22/202446Microelectronics School Xidian University 洽肿虞声猜阁邪滦若架矽侨尺兵柑楔虞翰仅嫩剐尿酞勺慨弹奎陷劣么倾拓五章仿真验证与Testbench编写五章仿真验证与Testbench编写各条阻塞式赋值语句将依次得到执行,并且在第一条语句所指定的赋值操作没有完成之前第

51、二条语句不会开始执行。因此在仿真进程开始时刻将“0”值赋给a,此条赋值语句完成之后才开始执行第二条赋值语句;在完成第一条赋值语句之后,延迟5个时间单位将“1”赋值给a;同理第三条赋值语句是在第二条赋值语句完成之后延迟10个时间单位才开始执行,将“0”赋值给a;最后一条赋值语句是在前三条语句都完成的时刻,延迟15个时间单位,将“1”赋值给a。下图给出了上例中信号a的波形。上述两例都采用的是阻塞式赋值语句。7/22/202447Microelectronics School Xidian University 女庄雍躲距扛零听碧脓睫琐亿雾辆耙析颊赐爽灼箱怯稿邢董哆乎篓换穆互五章仿真验证与Testb

52、ench编写五章仿真验证与Testbench编写(4)非阻塞式延迟控制以赋值操作符“=”来标识的赋值操作称为“非阻塞式过程赋值”,非阻塞式过程赋值也在之前讲述过,在此主要介绍非阻塞式延迟控制。非阻塞式延迟控制是在非阻塞式过程赋值基础上带有延时控制的情况。如下例所示:initialbegina = 0;a = #5 1;a = #10 0;a = #15 1;end7/22/202448Microelectronics School Xidian University 黍靡刊又锨出尹娇溃佐掉惊噬矗镀熔电层册竭荣借橇蔽吸酉玖澡拿饮拆颗五章仿真验证与Testbench编写五章仿真验证与Testben

53、ch编写在上例中各条非阻塞式赋值语句均以并行方式执行,虽然执行语句在begin-end串行块中,但其执行方式与并行延迟控制方式一致,在仿真进程开始时刻同时执行四条延迟赋值语句。在仿真进程开始时,将“0”值赋值给a;在离仿真开始时刻5个时间单位时,将“1”值赋值给a;在离仿真开始时刻10个时间单位时,将“0”值赋值给a;最后在离仿真开始时刻15个时间单位时,将“1”值赋值给a。下图给出了上例中信号a的波形。7/22/202449Microelectronics School Xidian University 刑潍咱轰丝加咆沤扣怀莫弘鸭封心辱耕肢趋片贪肖泵各阎粕瞥毅庚痕林泳五章仿真验证与Test

54、bench编写五章仿真验证与Testbench编写7/22/202450Microelectronics School Xidian University timescale 1ns/1nsmodule non_blocking_delay(q0_out,q1_out); output q0_out,q1_out; reg q0_out,q1_out; initial begin q0_out= 1b0; q0_out=#50 1b1; q0_out=#150 1b0; q0_out=#250 1b1; q0_out=#300 1b0; q0_out=#400 1b1; q0_out=#450

55、 1b0; q0_out=#500 1b1; q0_out=#600 1b0; endinitial begin q1_out= 1b0; q1_out=#100 1b1; q1_out=#200 1b0; q1_out=#250 1b1; q1_out=#350 1b0; q1_out=#400 1b1; q1_out=#500 1b0; q1_out=#550 1b1; q1_out=#600 1b0; endendmodule例Verilog HDL非阻塞延迟控制方式设计陶阶汕吞悲妹坏瓮埠迅胁贰锤载生睡盒酵陛簧血咳滔例胳瓢梯挠究门铆些五章仿真验证与Testbench编写五章仿真验证与Te

56、stbench编写5.4.3边沿触发事件控制边沿触发事件控制边沿触发事件控制的语法格式可以为如下四种形式:形式1:()行为语句;形式2:();形式3:(ororor)行为语句;形式4:(ororor);7/22/202451Microelectronics School Xidian University 吕措踊寥灼棱祥毁痒攫酪邻诅淬遏浙患峙扣躇经方轨拓斌谱嘻锁酉溪跺邯五章仿真验证与Testbench编写五章仿真验证与Testbench编写1事件表达式在事件表达式中,可以以三种形式出现:形式1: 形式2:posedge形式3:negedge其中,“”可以是任何数据类型的标量或矢量。形式1中,代

57、表触发事件的“”在指定的信号发生逻辑变化时,执行下面的语句,如例所示:(in) out=in;当敏感事件in发生逻辑变化时(包括正跳变和负跳变),执行对应的赋值语句,将in的值赋值给out。7/22/202452Microelectronics School Xidian University 勉佬婿复焉煤经坎惭思铰湛牵闽瑶诬舀幸慷犀柿涂萌情促鞭丙维惟躁澜匡五章仿真验证与Testbench编写五章仿真验证与Testbench编写形式2中,代表触发事件的“posedge”在指定的信号发生了正跳变时,执行下面的语句,如下例所示:(posedge in) out=in;当敏感事件in发生正跳变时,执

58、行对应的赋值语句,将in的值赋值给out。形式3中,代表触发事件的“negedge”在指定的信号发生了负跳变时,执行下面的语句,如下例所示:(negedge in)out=in;当敏感事件in发生负跳变时,执行对应的赋值语句,将in的值赋值给out。7/22/202453Microelectronics School Xidian University 署亢拣项驼升融驯龄系肢泅尖尉件搪主受熬潞械韵疥寞规解陌艺何舟澄溺五章仿真验证与Testbench编写五章仿真验证与Testbench编写在信号发生逻辑变化(正跳变或负跳变)的过程中,信号的值是从0、1、x、z四个值中的一个值变化到另一个值;而信

59、号发生正跳变的过程是信号由低电平向高电平的转变,负跳变是信号由高电平向低电平的转变。表5.4-1为Verilog HDL中规定的正跳变和负跳变。7/22/202454Microelectronics School Xidian University 正跳变负跳变0x1x0z1z0110x1x0z1z0一搬执董阂梨珐怯囤沧省鸯暴居撅房贪丧晤筏谴窿铜景忧镣厉仇恋沈掩紊五章仿真验证与Testbench编写五章仿真验证与Testbench编写2边沿触发语法格式形式1:()行为语句;这种语法格式的敏感事件列表内只包含了一个触发事件,只有当这个指定的触发事件发生之后,后面的行为语句才能启动执行。在仿真进程

60、中遇到这种带有事件控制的行为语句时,如果指定的触发事件还没有发生,则仿真进程就会停留在此处等待,直到指定触发事件发生之后再启动执行后面的行为语句,仿真进程继续向下进行。7/22/202455Microelectronics School Xidian University 例5.4-4:时钟脉冲计数器module clk_counter(clk, count_out); input clk; output count_out; reg 3:0 count_out; initial count_out = 0; always(posedge clk) count_out = count_out

61、+ 1;/在clk的每个正跳变边沿count_out增加1endmodule建保掠狭溃笆起馋痛生夸躁畴扔房更痢蔬沉搪瑟迸赞回跺弟诸臂陡者辗丢五章仿真验证与Testbench编写五章仿真验证与Testbench编写形式2:();这种语法格式的敏感事件列表内也只包含了一个触发事件,没有行为语句来指定触发事件发生时要执行的操作。这种格式的事件控制语句的执行过程与延时控制语句中没有行为语句的情况类似,仿真进程在遇到这条事件控制语句后会进入等待状态,直到指定的触发事件发生后才结束等待状态,退出该事件控制语句的执行并开始下一条语句的执行。7/22/202456Microelectronics School

62、 Xidian University 校罢放信没技恃疑蘑克分佰证灭骏榔怔启射篱早滇溺辙垦恩忆愿澳钱喳兹五章仿真验证与Testbench编写五章仿真验证与Testbench编写7/22/202457Microelectronics School Xidian University module clk_time_mea(clk); input clk; time posedge_time, negedge_time; time high_last_time, low_last_time,last_time; initial begin (posedge clk);/*等待,直到时钟发生正跳变后退

63、出等待状态,继续执行下一条语句*/ posedge_time = $time; (negedge clk);/*等待,直到时钟发生负跳变后退出等待状态, 继续执行下一条语句*/ negedge_time = $time;(negedge clk);/*等待,直到时钟再次正跳变后退出等待状态,继续执行下一条语句*/ last_time = $time - posedge_time; high_last_time = negedge_time - posedge_time; low_last_time = last_time - high_last_time; $display(The clk s

64、tay in High level for:%t,high_last_time); $display(The clk stay in Low level for:%t,low_last_time); $display(The clk signal Period is:%t,last_time); endendmodule例用于测定输入时钟正电平、负电平持续时间以及时钟周期的模块姻句贮详荣派量吹筹麦有糯本液倒寅吴匈慷饲兔几吠秀好钵默坡井溯葱柿五章仿真验证与Testbench编写五章仿真验证与Testbench编写形式3:(ororor)行为语句;这种语法格式的“敏感事件列表”内指定了由不同“”代

65、表的多个触发事件,这些“”之间要用关键词“or”组合起来。只要这些触发事件中的任何一个得到发生,就启动行为语句的执行。在仿真进程遇到这种格式的边沿触发事件控制语句时如果所有的触发事件都没有发生,则仿真进程就会进入等待状态,直到其中的某一个触发事件发生后才启动执行后面给出的行为语句,仿真进程继续向下进行。7/22/202458Microelectronics School Xidian University 妥隋眯疡郸狄芳爸冒卒胳萝堤狗痞级厅内烯搁懦账祝定但跌孽跌单牵鹤绩五章仿真验证与Testbench编写五章仿真验证与Testbench编写形式4:(ororor);同第三种语法格式一样,这种语

66、法格式内指定了多个触发事件。但是在这种格式中没有行为语句。在这种情况下,该语句的执行过程与第二种语法格式的执行过程类似,仿真进程在遇到这条事件控制语句后会进入等待状态,直到敏感事件列表包含的多个触发事件中的任何一个得到发生后才结束等待状态,退出该事件控制语句并开始执行该事件控制语句后的下一条语句。7/22/202459Microelectronics School Xidian University 例在触发事件发生后退出事件控制语句module display_information_change(a, b); input a, b; wire a, b; always begin(pose

67、dge a or negedge b);/*等待,直到a或b发生变化后退出等待状态,并开始下一条语句的执行*/ display(One of a and b changed in time:%t,$time); endendmodule王械吻纹侄浮摇色集词阅添炎苗帽名羽泰跟间界只谁铂牢瞳买睹二坎寓躁五章仿真验证与Testbench编写五章仿真验证与Testbench编写5.4.4电平敏感事件控制电平敏感事件控制电平敏感时间控制是另一种事件控制方式,与边沿触发事件控制不同,它是在指定的条件表达式为真时启动需要执行的语句。电平敏感时间控制是用关键词“wait”来表示。电平触发事件控制的语法格式可以

68、为如下两种:形式1:wait(条件表达式)行为语句;形式2:wait(条件表达式);电平敏感事件控制的第一种形式中包含了行为语句,它可以是串行块(begin-end)语句或并行块(fork-join)语句,也可以是单条行为语句。在这种事件控制语句形式下,行为语句启动执行的触发条件是:条件表达式的值为“真(逻辑1)”。如果当仿真进程执行到这条电平敏感控制语句时条件表达式的值是“真”,那么语句块立即得到执行;否则语句块要一直等到条件表达式变为“真”时再开始执行。7/22/202460Microelectronics School Xidian University 透矗荚勇移窗渴点拿劲僚茫死远偏锌

69、巡派挨旭悄骇巍皱疫试属搅惟近蛇湘五章仿真验证与Testbench编写五章仿真验证与Testbench编写7/22/202461Microelectronics School Xidian University 例如:wait(enable = 1)begind = a & b;d = d | c;endwait语句的作用是根据条件表达式的真假来控制下面begin-end语句块的执行,在使能信号enable变为高电平后,也就是enable=1的语句为真时进行a,b,c之间的与或操作;若使能信号enable未变为高电平,则begin-end语句块的执行需要等到enable变为高电平之后才开始执行。

70、顷即鱼宋畔哩瞪亨静觉凉墅掖树损锅茄命髓旬植装鹿缚羞仁惑豢德踞遍镶五章仿真验证与Testbench编写五章仿真验证与Testbench编写电平敏感事件控制的第2种形式中没有包含行为语句。在这种电平敏感事件控制语句形式下,如果当仿真进程执行到该wait控制语句时条件表达式的值是“真”,那么立即结束该wait事件控制语句的执行,仿真进程继续往下进行;而如果当仿真进程执行到这条wait控制语句时条件表达式的值是“假”,则仿真进程进入等待状态,一直等到条件表达式取值变为“真”时才退出等待状态同时结束该wait语句的执行,仿真进程继续往下进行。这种形式的电平敏感时间控制常常用来对串行块中各条语句的执行时序

71、进行控制。7/22/202462Microelectronics School Xidian University 例如:beginwait(enable = 1);d = a & b;d = d | c;end合泌占渍径蘸何觅傲矗闺摄拱芽蜡闯考欲呜坑盛肠郑厕诣蒜疏挛议筷吝反五章仿真验证与Testbench编写五章仿真验证与Testbench编写5.5任务和函数任务和函数在Verilog HDL语言中提供了任务和函数,可以将较大的行为级设计划分为较小的代码段,允许设计者将需要在多个地方重复使用的相同代码提取出来,编写成任务和函数,这样可以使代码更加简洁和易懂。5.5.1任务1.任务的定义任务定

72、义的语法格式:7/22/202463Microelectronics School Xidian University task; 端口和类型声明 局部变量声明begin 语句1; 语句2; 语句n;end endtask靛狱怯星种镜套未闯罗虑跑讶逮岗场洋远旦部蘸酮抗虾安烁酚湾犯蛋令噶五章仿真验证与Testbench编写五章仿真验证与Testbench编写任务定义是嵌入在关键字task和endtask之间的,其中关键词task标志着一个任务定义结构的开端,endtask标志着一个任务定义结构的结束。“”是所定义任务的名称。在“”后面不能出现输入输入端口列表。例以读存储器数据为例说明任务定义的操

73、作7/22/202464Microelectronics School Xidian University task read_memory;/任务定义的开头,指定任务名为read_memoryinput15:0address;/输入端口说明output31:0data;/输出端口说明reg3:0counter;/变量类型说明reg7:0temp1:4;/变量类型说明begin/语句块,任务被调用时执行for(counter=1;counter=4;counter=counter+1)tempcounter=memaddress+counter-1;data=temp1, temp2, tem

74、p3, temp4;endendtask/任务定义结束寐款室病诞坛噬怪深祝震薪党滨瞩荧才去愈认催触性查爸刨驯儡脓颂寞捕五章仿真验证与Testbench编写五章仿真验证与Testbench编写任务定义时需注意以下事项:(1)在第一行“task”语句中不能列出端口名列表。(2)任务中可以有延时语句、敏感事件控制语句等事件控制语句。(3)任务可以没有或可以有一个或多个输入、输出和双向端口。(4)任务可以没有返回值,也可以通过输出端口或双向端口返回一个或多个返回值。(5)任务可以调用其它的任务或函数,也可以调用该任务本身。(6)任务定义结构内不允许出现过程块(initial或always过程块)。(7

75、)任务定义结构内可以出现disable终止语句,这条语句的执行将中断正在执行的任务。在任务被中断后,程序流程将返回到调用任务的地方继续向下执行。7/22/202465Microelectronics School Xidian University 冠春斜酸赶怨丸觅倒幽考乎座撵函作弱写狸诛语柯化蚤迁挤秽漾蕉豁属困五章仿真验证与Testbench编写五章仿真验证与Testbench编写2、任务的调用任务的调用是通过“任务调用语句”来实现的。任务调用语句列出了传入任务的参数值和接收结果的变量值,任务的调用格式如下:(端口1,端口2,端口n);例以测试仿真中常用的方式来说明任务的调用7/22/202

76、466Microelectronics School Xidian University module demo_task_invo_tb; reg 7:0 mem 127:0; reg 15:0 a; reg 31:0 b; initial begin a = 0; read_mem(a, b);/任务的第一次调用 #10; a = 64; read_mem(a, b);/任务的第二次调用 end task read_mem;/任务定义部分 input 15:0 address; output 31:0 data; reg 3:0 counter; reg 7:0 temp 1:4; beg

77、in for(counter=1; counter=4; counter=counter+1) tempcounter= memaddress+counter-1; data=temp1, temp2, temp3, temp4; end endtaskendmodule镍曙只仿互挠增蕊虫覆宴锁瘪页茂洱谰伊莽薪喳侄督鄙忍网史硅逛烯傈噎五章仿真验证与Testbench编写五章仿真验证与Testbench编写使用任务可以使程序更加简洁易懂,以实际中的交通灯控制为例说明任务的定义、调用的特点。7/22/202467Microelectronics School Xidian University m

78、odule traffic_lights(red, amber, green); output red, amber, green; reg 2:1 order; reg clock, red, amber, green; parameter ON=1, OFF=0, RED_TICS=350, AMBER_TICS=30, GREEN_TICS=200; /产生时钟脉冲 always begin #100 clock = 0; #100 clock = 1; end/任务的定义,该任务用于实现交通灯的开启 task light; output red; output amber; outpu

79、t green; input 31:0 tic_time; input 2:1 order; begin red = OFF; green = OFF; amber = OFF; case(order) 2b01: red = ON; 2b10: green = ON; 2b11: amber = ON; endcase已蒂埠舰增或咸捂焉洽练急唱撮讳峪愁巨肥坷典拌帜株芝狐狂誊氟您墩坛五章仿真验证与Testbench编写五章仿真验证与Testbench编写7/22/202468Microelectronics School Xidian University repeat(tic_time)(p

80、osedge clock); red = OFF; green = OFF; amber = OFF; end endtask/任务的调用,交通灯初始化 initial begin order = 2b00; light(red, amber, green, 0, order); end /任务的调用,交通灯控制时序 always begin order = 2b01; light(red, amber, green, RED_TICS, order);/调用开灯任务,开红灯order = 2b10; ilght(red, amber, green, GREEN_TICS, order);/调

81、用开灯任务,开绿灯 order = 2b11; light(red, amber, green, AMBER_TICS, order);/调用开灯任务,开黄灯 endendmodule奥吸传婆哺愉拐搞悼蟹瞒欧村碌陨吨阻唾叁损皿援铸寇晚叙臀酮杏夷柿萝五章仿真验证与Testbench编写五章仿真验证与Testbench编写5.5.2 函数1函数的定义7/22/202469Microelectronics School Xidian University function ;begin语句1;语句2;语句n;endendfunction函数定义是嵌入在关键字function和endfunction之

82、间的,其中关键词function标志着一个函数定义结构的开端,endfunction标志着一个函数定义结构的结束。“”是给被定义函数取的名称。这个函数名在函数定义结构内部还代表着一个内部变量,函数调用后的返回值是通过这个函数名变量传递给调用语句的。晨褪汹串甥巫啄涵巾毛瓤行草夕到翻兰草胡鞋锑逢贪慈轰憋颐扮牡坎靴傲五章仿真验证与Testbench编写五章仿真验证与Testbench编写是一个可选项,它是用来对函数调用返回数据的类型或宽度进行说明,它可以有如下三种形式:(1)“msb:lsb”:这种形式说明函数名所代表的返回数据变量时一个多位的寄存器变量,它的位宽由msb:lsb指定,比如如下函数定

83、义语句:function 7:0 adder;就定义了一个函数“adder”,它的函数名“adder”还代表着一个8位宽的寄存器变量,其中最高位为第7位,最低位为第0位。(2)“integer”:这种形式说明函数名代表的返回变量是一个整数型变量。(3)“real”:这种形式说明函数名代表的返回变量是一个实数型变量。7/22/202470Microelectronics School Xidian University 污垛杰优奥盔丹萧怕先郝互嚎担栖贿蜀癌着齿演严蜘忍列释贺城粳馈民衙五章仿真验证与Testbench编写五章仿真验证与Testbench编写“”是对函数各个输入端口的宽度和类型进行说

84、明,在函数定义中,必须至少有一个输入端口(input)的声明,不能有输出端口(output)的声明。数据类型声明语句用来对函数内用到的局部变量进行宽度和类型说明,这个说明语句的语法与进行模块定义时的相应说明语句语法是一致的。“”是对函数内部局部变量进行宽度和类型的说明。由“begin”与“end”关键词界定的一系列语句和任务一样,用来指明函数被调用时要执行的操作,在函数被调用时,这些语句将以串行方式得到执行。7/22/202471Microelectronics School Xidian University 叉汉扳蝇函芹砰巢锑铅组括腺万专谍刑炼蚜铃扔釜疤又狈碱洪抗急萌症当五章仿真验证与Te

85、stbench编写五章仿真验证与Testbench编写7/22/202472Microelectronics School Xidian University 例5.5-4:统计输入数据中“0”的个数 function3:0 out0;input7:0 x;reg3:0 count;integer i;begincount=0;for(i=0;i=7;i=i+1)if(xi=1b0) count=count+1;out0=count;endendfunction百效抉韭跪潦蔷晨桶宴峡庭舶赞遥腺坤城薯覆愈桥晋盛幢穗放苦诣安浙拇五章仿真验证与Testbench编写五章仿真验证与Testbench编

86、写在进行函数定义时需要注意以下几点:(1)与任务一样,函数定义结构只能出现在模块中,而不能出现在过程块内。(2)函数至少必须有一个输入端口。(3)函数不能有任何类型的输出端口(output端口)和双向端口(inout端口)。(4)在函数定义结构中的行为语句部分内不能出现任何类型的时间控制描述,也不允许使用disable终止语句。(5)与任务定义一样,函数定义结构内部不能出现过程块。(6)在一个函数内可以对其它函数进行调用,但是函数不能调用其它任务。(7)在第一行“function”语句中不能出现端口名列表。(8)在函数声明的时候,在Verilog HDL的内部隐含地声明了一个名为functio

87、n_identifier(函数标识符)的寄存器类型变量,函数的输出结果将通过这个寄存器类型变量被传递回来。7/22/202473Microelectronics School Xidian University 仇闭膏述哲翌屠太敏培烬愧扇捧肖共僚嘉垣猩年言胖沼濒甩额要粒噪甸傣五章仿真验证与Testbench编写五章仿真验证与Testbench编写2. 函数的调用函数的调用是通过将函数作为表达式中的操作数来实现的。函数的调用格式如下: (,);其中,输入表达式应与函数定义结构中说明的输入端口一一对应,它们代表着各个输入端口的输入数据。函数调用时要注意以下几点:(1)函数的调用不能单独作为一条语句

88、出现,它只能作为一个操作数出现在调用语句内。(2)函数的调用既能出现在过程块中,也能出现在assign连续赋值语句中。(3)函数定义中声明的所有局部寄存器都是静态的,即函数中的局部寄存器在函数的多个调用之间保持它们的值。7/22/202474Microelectronics School Xidian University 苦柯倍改超对雕莽摸吟奖摆某掺发绘所娥坟捻司证士种硼籍员频书杨毒阀五章仿真验证与Testbench编写五章仿真验证与Testbench编写例5.5-5: 阶乘函数7/22/202475Microelectronics School Xidian University modu

89、le tryfact_tb;function31:0factorial; /函数的定义部分input3:0operand;reg3:0index;beginfactorial = 1 ;for(index=1;index=operand;index=index+1)factorial = index * factorial;endendfunctionreg31:0result;reg3:0n;initialbeginresult=1;for(n=1;n=9;n=n+1)beginresult = factorial(n); /函数的调用部分$display(n= %d result= %d,

90、 n, result);endendendmodule焉映梯郁盲梗庚植瓜韭坍邢均非袜擅吊范凌音秩鼠沼斑修青诛锯饶谚峦淀五章仿真验证与Testbench编写五章仿真验证与Testbench编写7/22/202476Microelectronics School Xidian University 上例由函数定义和initial过程块构成,其中定义了一个名为factorial的函数,该函数是一个进行阶乘运算的函数,具有一个4位的输入端口,同时返回一个32位的寄存器类型的值;在initial块中定义了两个寄存器变量,分别为32位的result和4位的n,initial块对1至9进行阶乘运算,并打印出

91、结果值。 n= 1 result= 1 n= 2 result= 2 n= 3 result= 6 n= 4 result= 24 n= 5 result= 120 n= 6 result= 720 n= 7 result= 5040 n= 8 result= 40320 n= 9 result= 362880矿越襄屯韧炕鸣骑找签滁兰判颧斋廖火忙摄萤袁参俩高玄续谣腿纶位催叛五章仿真验证与Testbench编写五章仿真验证与Testbench编写5.5.3任务与函数的区别任务与函数的区别7/22/202477Microelectronics School Xidian University 函数

92、任务函数能调用另一个函数,但不能调用另一个任务任务能调用另一个任务,也能用另一个函数函数总是在仿真时刻0就开始执行任务可以在非零仿真时刻执行函数一定不能包含任何延迟、事件或者时序控制声明语句任务可以包含延迟、时间或者时序控制声明语句函数至少有一个输入变量,可以有多个输入变量任务可以没有或者有多个输入(input)、输出(output)和双向(inout)变量函数只能返回一个值,函数不能有输出(output)或者双向(inout)变量任务不返回任何值,任务可以通过输出(output)或者双向(inout)变量传递多个值函数不能单独作为一条语句出现,它只能以语句的一部分的形式出现任务的调用则是通过

93、一条单独的任务调用语句实现函数调用可以出现在过程块或连续赋值语句中任务调用只能出现在过程块中函数的执行不允许由disable语句进行中断任务的执行可以由disable语句进行中断宾拜滦范裳符憎沂机葫恍鹊川牵肇指怯烈匙妇县宦予谜卫庄蕾赣魂哪员鸡五章仿真验证与Testbench编写五章仿真验证与Testbench编写5.6典型测试向量的设计典型测试向量的设计5.6.1 变量初始化在Verilog HDL语言中,有两种方法可以初始化变量:一种是利用初始化变量;另一种就是在定义变量时直接赋值初始化。这两种初始化任务是不可综合的,主要用于仿真过程。(1)initial初始化方式在大多数情况下,Testb

94、ench中变量初始化的工作通过initial过程块来完成,可以产生丰富的仿真激励。initial语句只执行一次,即在设计被开始模拟执行时开始(0时刻)直到过程结束,专门用于对输入信号进行初始化和产生特定的信号波形。一个Testbench可以包含多个initial过程语句块,所有的initial过程都同时执行。需要注意的是,initial语句中的变量必须为reg类型。7/22/202478Microelectronics School Xidian University 砒磕驴句网点垢铰牵嘿琼妖荐菇诧累坏轩揩成缀牢滦讥涟萧鱼洛雌舱肠述五章仿真验证与Testbench编写五章仿真验证与Testbe

95、nch编写7/22/202479Microelectronics School Xidian University 例5.6-1:利用initial初始化方式的测试向量产生module counter_demo2( clk,cnt ); output 3:0 cnt; reg clk; reg 3:0 temp; initialtemp = 0; initialclk = 0;endmodule(2)定义变量时初始化在定义变量时初始化的语法非常简单,直接用“=”在变量右端赋值即可,如:reg 7:0 cnt = 8b00000000;就将8比特的寄存器变量cnt初始化为0。叛馈疗资震冉坷彭炔音

96、毖套为腰惨谨妊著辰趣房咋朝介痈瞩烽摇橡豪啤廊五章仿真验证与Testbench编写五章仿真验证与Testbench编写5.6.2 数据信号测试向量产生数据信号测试向量产生数据信号的产生有两种形式:其一是初始化和产生都在单个initial块中进行;其二是初始化在initial语句中完成,而产生在always语句块中完成。前者适合不规则数据序列,并且要求长度较短;后者适合具有一定规律的数据序列,长度不限。例5.6-2:产生位宽为4的质数序列1、2、3、5、7、11、13,并且重复两次,其中样值间隔为4个仿真时间单位由于该序列无明显规律,因此利用initial语句最为合适。7/22/202480Mic

97、roelectronics School Xidian University 拟蓑控徒穷蹄沁秘围挫剖婉生捣被虏匝拍绿炕霓济舶垃睫莆于姚诛干挛杭五章仿真验证与Testbench编写五章仿真验证与Testbench编写7/22/202481Microelectronics School Xidian University timescale 1ns / 1psmodule sequence_tb; reg 3:0 q_out; parameter sample_period = 4; parameter queue_num = 2; initial begin q_out = 0; repeat(

98、 queue_num ) begin # sample_period q_out = 1; # sample_period q_out = 2; # sample_period q_out = 3; # sample_period q_out = 5; # sample_period q_out = 7; # sample_period q_out = 11; # sample_period q_out = 13; end endendmodule狙效传醇隧击绰衔泞优听患饰垒果眩浚罢韭岸呕熄进遮叉邮球敲寡儡涛插五章仿真验证与Testbench编写五章仿真验证与Testbench编写5.6.3

99、时钟信号测试向量产生时钟信号测试向量产生例:产生占空比为50%的时钟信号,其波形如图所示(1)基于initial语句的方法 (2)基于always语句的方法7/22/202482Microelectronics School Xidian University module clk1(clk); output clk; parameter clk_period = 10; reg clk; initial begin clk = 0; forever #(clk_period/2) clk = clk; endendmodulemodule clk2(clk); output clk; par

100、ameter clk_period = 10; reg clk; initialclk = 0; always # (clk_period/2) clk = clk;endmodule追末蕉当斑疑反皱烹切财劣赁金彰纽抚厂鲤侯蠕柳隘发凄出釉守玄殊蛹管五章仿真验证与Testbench编写五章仿真验证与Testbench编写例产生占空比可设置的时钟信号自定义占空比信号可以通过always模块快速实现7/22/202483Microelectronics School Xidian University module Duty_Cycle(clk); output clk; parameter Hig

101、h_time=5, Low_time=20; /占空比为High_time/(High_time+Low_time) reg clk; always begin clk=1; #High_time; clk=0; #Low_time; endendmodule惦脯呆笺蔫粤中募镁缓悔多佬谷纷站秒系咋赃灸凯士煽侣缸包疽捎藤肾涅五章仿真验证与Testbench编写五章仿真验证与Testbench编写例产生具有相位偏移的时钟信号相位偏移是两个时钟信号之间的相对概念,如图所示,其中clk_a为参考信号,clk_b为具有相位偏移的信号。7/22/202484Microelectronics School

102、Xidian University module shift_Duty_Cycle(clk_a, clk_b); output clk_a, clk_b; parameter High_time = 5, Low_time = 5,pshift_time = 2; reg clk_a; wire clk_b; always begin clk_a = 1; # High_time; clk_a= 0; # Low_time; end assign # pshift_time clk_b = clk_a;endmodule胸野探饺磊怎袱癌峪诊韭佳梁瞧浇笔宜鸡绿劝办杜菜钾嫩豌粥翘涣淌贴勃五章仿真验

103、证与Testbench编写五章仿真验证与Testbench编写7/22/202485Microelectronics School Xidian University 例产生固定数目的时钟信号module fix_num_clk(clk); output clk; parameter clk_cnt = 5, clk_period = 2; reg clk; initial begin clk = 0; repeat (clk_cnt) # clk_period/2 clk = clk; endendmoudle上述代码产生了5个周期的时钟。峭辫望汕缄姓拂漫筑愉强贸羽汐捅搂艇胸涝艺准坎尧幻愉娩

104、擦鸥纂郁费十五章仿真验证与Testbench编写五章仿真验证与Testbench编写5.6.4 总线信号测试向量产生总线信号测试向量产生总线是运算部件之间数据流通的公共通道。在RTL级描述中,总线指的是由逻辑单元、寄存器、存储器、电路输入或其它总线驱动的一个共享向量。而总线功能模型则是一种将物理的接口时序操作转化成更高抽象层次接口的总线模型,如图所示。7/22/202486Microelectronics School Xidian University 艰熏大乔悼毯战津魄梗随澳耪侵它课煞要矾孩掸擎晒坚摹介惠仑退窃虎童五章仿真验证与Testbench编写五章仿真验证与Testbench编写在总

105、线中,对于每个请求端,有一个输入来选择驱动该总线所对应的请求端。选择多个请求端会产生总线冲突,根据总线的类型,冲突会产生不同的结果。当有多个请求端发出请求时,相应的操作由总线的类型决定。在Verilog HDL测试中,总线测试信号通常是通过将片选信号,读(或者写)使能信号、地址信号以及数据信号以task任务的形式来描述,通过调用以task形式的总线信号测试向量来完成相应的总线功能。下面以工作频率为100MHz的AHB总线写操作为例,说明以task方式产生总线信号测试向量的方式。下图是AHB总线写操作的时序图,其中,在完成数据的写操作后将片选和写使能信号置为无效(低电平有效)。7/22/2024

106、87Microelectronics School Xidian University 辗赦练饲档盂岛魏滚侧哨服虾惧沏同缴吓哨构槛颧物廖司济咋睦避园狱咽五章仿真验证与Testbench编写五章仿真验证与Testbench编写7/22/202488Microelectronics School Xidian University 例5.6-7:产生一组具有写操作AHB总线功能模型module bus_wr_tb; reg clk; reg cs; reg wr; reg 31:0 addr; reg 31:0 data; initial begin cs=1b1; wr=1b1; #30; bu

107、s_wr(32h1100008a, 32h11113000); bus_wr(32h1100009a, 32h11113001); bus_wr(32h110000aa, 32h11113002); bus_wr(32h110000ba, 32h11113003); bus_wr(32h110000ca, 32h11113004); addr=32bx; data=32bx; end initial clk=1; always #5 clk=clk; task bus_wr; input 31:0 ADDR; input 31:0 DATA; begin cs=1b0; wr=1b0; add

108、r=ADDR; data=DATA; #30 cs=1b1; wr=1b1; end endtaskendmodule瞄轰妹邵熟惧赚国羊惫棵都蕴峻台苛巢渠其袄梳坍岁仅利舰兆鲍驱孝拜兆五章仿真验证与Testbench编写五章仿真验证与Testbench编写5.7用户自定义元件模型用户自定义元件模型UDP通过UDP,可以把一块组合逻辑电路或时序逻辑电路封装在一个UDP内,并把这个UDP作为一个基本门元件来使用。需要注意的是,UDP是不能综合的,只能用于仿真。5.7.1 UDP的定义与调用UDP的定义格式如下:7/22/202489Microelectronics School Xidian Uni

109、versity primitive (, ,); 输出端口类型声明(output); 输入端口类型声明(input); 输出端口寄存器变量说明(reg); 元件初始状态说明(initial); table ; ; ; endtableendprimitive愧伸欧揩意卿剩黔词擎吐佬滴雷札迹维锑涤景频蹈捉琳窟灾辈学犬圣秧隔五章仿真验证与Testbench编写五章仿真验证与Testbench编写和Verilog HDL中的模块相比,UDP具备以下特点。(1)UDP的输出端口只能有一个,且必须位于端口列表的第一项。只有输出端口能定义为reg类型。(2)UDP的输入端可有多个,一般时序电路UDP的输入

110、端口最多9个,组合电路UDP的输入端口可多至10个。(3)所有端口变量的位宽必须是1比特。(4)在table表项中,只能出现0、1、x这三种状态,z将被认为是x状态。根据UDP包含的基本逻辑功能,可以将UDP分为组合电路UDP、时序电路UDP及混合电路UDP,这几类UDP的差别主要体现在table表项的描述上。UDP的调用和Verilog HDL中模块的调用方法相似,通过位置映射,其语法格式如下:UDP名名 例化名例化名 (连接端口(连接端口1信号名,连接端口信号名,连接端口2信号名,连接端口信号名,连接端口3信号名,信号名,););7/22/202490Microelectronics Sc

111、hool Xidian University 局衷荐白彩芬腐捻别贩宠自晦猖铱肩昂仪爵刮士泌熬宜瑞剥甥汹悄恨选嚏五章仿真验证与Testbench编写五章仿真验证与Testbench编写7/22/202491Microelectronics School Xidian University 例用UDP方式定义一个全加器仿真模型primitive summ(sum, cin, a, b); /本位和UDP output sum; input a, b, cin; table /cin a b : sum 0 0 0 : 0; 0 0 1 : 1; 0 1 0 : 1; 0 1 1 : 0; 1 0

112、0 : 1; 1 0 1 : 0; 1 1 0 : 0; 1 1 1 : 1; endtableendprimitiveprimitive carry(cout, cin, a, b); /进位UDP output cout; input a, b, cin; table /cin a b : cout 0 0 0 : 0; 0 0 1 : 0; 0 1 0 : 0; 0 1 1 : 1; 1 0 0 : 0; 1 0 1 : 1; 1 1 0 : 1; 1 1 1 : 1; endtable endprimitive瓷涅猾涟倾晴耗屈汹浚伎处鹿玄蓉赊孺弥婿沸鲤励骏降薪曳舌岭际芒凰毗五章仿真验证

113、与Testbench编写五章仿真验证与Testbench编写5.7.2 UDP应用实例应用实例(1)组合电路UDP元件组合逻辑电路的功能列表类似真值表,就是规定了不同的输入值和对应的输出值,表中每一行形式是“output,input1,input2,”,排列顺序和端口列表中的顺序相同,合电路UDP的输入端口可多至10个。如果某个输入组合没有定义的输出,那么就把这种情况的输出置为x。7/22/202492Microelectronics School Xidian University 例例3选选1多路选择器多路选择器UDP开发实例开发实例primitive mux3_1(Y, in0, in1

114、, in2, s2, s1); input in0, in1, in2, s2, s1; output Y; table /in0 in1 in2 s2 s1 : Y 0 ? ? 0 0 : 0;/当s2s1=00时,Y=in0 1 ? ? 0 0 : 1; ? 0 ? 0 1 : 0;/当s2s1=01时,Y=in1 ? 1 ? 0 1 : 1; ? ? 0 1 ? : 0;/当s2s1=1?时,Y=in2 ? ? 1 1 ? : 1; 0 0 ? 0 ? : 0; 1 1 ? 0 ? : 1; 0 ? 0 ? 0 : 0; 1 ? 1 ? 0 : 1; ? 0 0 ? 1 : 0; ? 1

115、 1 ? 1 : 1; endtable endprimitive谗狄印鄂硫韧员饲在房推冰汇鼓怜跟记姨皂诫蝶翔颤耶围脆旱哼硬贡侮禄五章仿真验证与Testbench编写五章仿真验证与Testbench编写7/22/202493Microelectronics School Xidian University 符号意义符号意义0逻辑0(AB)由A变到B1逻辑1*与(?)相同x未知的值r上升沿,与(01)相同?0、1或x中的任一个f下降沿,与(10)相同b0或1中任选一个p(01)、(0x)和(x1)的任一种-输出保持n(10)、(1x)和(x0)的任一钟蛇堆即锚浩逢群涌血嚷苍栓党擎前甭醚磁辛颜渠礼

116、蓖糙祸竭帆躬专精社奴五章仿真验证与Testbench编写五章仿真验证与Testbench编写(2)时序电路UDP元件UDP还可以描述具有电平触发和边沿触发特性的时序电路。时序电路拥有内部状态序列,其内部状态必须用寄存器变量进行建模,该寄存器的值就是时序电路的当前状态,它的下一个状态是由放在基元功能列表中的状态转换表决定的,而且寄存器的下一个状态就是这个时序电路UDP的输出值。所以,时序电路UDP由两部分组成状态寄存器和状态列表。定义时序UDP的工作也分为两部分初始化状态寄存器和描述状态列表。在时序电路的UDP描述中,01、0x、x1代表着信号的上升沿。下面给出一个上升沿D触发器的UDP开发实例

117、。7/22/202494Microelectronics School Xidian University 绢花缎奈亥桅碉边蝶吝忻纺虎冷奏诊录玫伏码狂楷奖之测诌捡箕慎袭稠恼五章仿真验证与Testbench编写五章仿真验证与Testbench编写7/22/202495Microelectronics School Xidian University 例通过Verilog HDL语言给出D触发器UDP描述,并在模块中调用UDP组件primitive D_Edge_FF(Q, Clk, Data); output Q ; reg Q ; input Data, Clk; initial Q = 0;

118、 table /Clk Data : Q(Stata): Q(next) (01) 0 : ? : 0: (01) 1 : ? : 1; (0x) 1 : 1 : 1; (0x) 0 : 0 : 0; (?0) ? : ? : -;/忽略时钟负边沿 ?(?):? :-;/忽略在稳定时钟上的数据变化 endtable endprimitive表项(01)表示从0转换到1,表项(0x)表示从0转换到x,表项(?0)表示从任意值(0、1或x)转换到0,表项(?)表示任意转换。对于任意未定义的转换,输出默认为x。假定D_Edge_FF为UDP定义,它现在就能够像基本门一样在模块中使用。爹丘巾冒霓畸爪爆

119、埠驶凸炮跋枪肪套斤啄谦戏疙掇强白余稠抖序傈疡沟妆五章仿真验证与Testbench编写五章仿真验证与Testbench编写(3)混合电路UDP元件在同一个表中能够混合电平触发和边沿触发项。在这种情况下,边沿变化在电平触发之前处理,即电平触发项覆盖边沿触发项。下面给出一段带异步清空的D触发器的UDP描述。7/22/202496Microelectronics School Xidian University 例利用Verilog HDL语言完成异步清零D触发器的UDP描述primitive D_Async_FF (Q, Clk, Clr, Data); output Q; reg Q; input

120、 Clr, Data, Clr; table/定义混合UDP元件 /Clk Clr Data :(SQtate) :Q(next) (01) 0 0 : ? : 0 ; (01) 0 1 : ? : 1 ; (0x) 0 1 : 1 : 1 ; (0x) 0 0 : 0 : 0 ; (?0) 0 ? : ? : - ; /忽略时钟负边沿 (?) 0 ? : ? : - ; ? 1 ? : ? : 0 ; endtableendprimitive浙犬曹批萌缠大编隆垦刽垃碍棕葫剥腰腆腆母淡芥扼我瞻慷烟枝恍带肾擞五章仿真验证与Testbench编写五章仿真验证与Testbench编写5.8基本门级元

121、件和模块的延时建模基本门级元件和模块的延时建模5.8.1门级延时建模门级延时可以分为如下几类:(1)“上升延时”:表示信号由“0”、“x”或“z”状态变化到“1”状态时受到的门传输延时。(2)“下降延时”:表示信号由“1”、“x”或“z”状态变化到“0”状态时受到的门传输延时。(3)“到不定态的延时”:表示信号由“0”、“1”或“z”状态变化到“x”状态时受到的门传输延时。(4)“截止延时”:表示信号由“0”、“1”或“x”状态变化到“z”状态时受到的门传输延时。7/22/202497Microelectronics School Xidian University 困抄矾渍矛惊裴之刻拴脐睹拜

122、却呜确岭姜羡诫冯豌绸呢琵票官棕藻从崎阳五章仿真验证与Testbench编写五章仿真验证与Testbench编写1门级延时的基本延时表达形式在门级延时的基本表达形式下,“delay”内可以包含0至3个延时值,表5.7-1给出了指定的不同延时值个数时,delay的4种表示形式。7/22/202498Microelectronics School Xidian University 延时值无延时1个延时值(d)2个延时值(d1,d2)3个延时值(dA,dB,dC)Rise0dd1dAFall0dd2dBTo_x0dmin(d1,d2)min(dA,dB,dC)Turn_off0dmin(d1,d2)

123、dC沫淑抉捐大澡笔函耽书鄙梆秀乏庙谷振伏歌贯呻擦硕翘蔓烙揣舀挫辙始航五章仿真验证与Testbench编写五章仿真验证与Testbench编写(1)当“delay”没有指定门延时值,则默认的延时值为0。这意味着元件实例的“上升延时值”、“下降延时值”、“截止延时值”和“到不定态的延时值”均为0。在下面的实例引用中,notif1 U0 (out, in, ctrl);门级延时值为“0”,因为没有定义延迟,则元件实例U0的“上升延时值”、“下降延时值”、“截止延时值”和“到不定态的延时值”均为0。(2)当“delay”内只包含1个延时值时,给定的延时值“d”将同时代表着元件实例的“上升延时值”、“下

124、降延时值”、“截止延时值”和“到不定态的延时值”。在下面的实例引用中,notif1 #20 U1 (out, in, ctrl);门级延时值为“20”,且只包含1个延时值,说明元件实例U1的所有类型的门级延时都是20个单位时间。7/22/202499Microelectronics School Xidian University 晌胁航彰宵蹈巨吨村扔楞俭矮哑兄袄盆痰榔腐哎苇召掏赡霹隋曾而翻略拼五章仿真验证与Testbench编写五章仿真验证与Testbench编写(3)当“delay”内包含了2个延时值时,元件实例的“上升延时值”由给定的“d1”指定;“下降延时值”由给定的“d2”指定;而“

125、截止延时值”和“到不定态的延时值”将由“d1”和“d2”中的最小值指定。在下面的实例引用中,notif1 #(10, 20) U2 (out, in, ctrl);门级延时值为“(10, 20)”,包含了2个延时值10和20,这表明元件实例U2将具有10个单位时间的“上升延时”和20个单位时间的“下降延时”,而它的“截止延时”和“到不定态的延时”将是10和20中的最小值指定,即为10个单位时间。(4)当“delay”内包含了3个延时值,元件实例的“上升延时值”由给定的“dA”指定;“下降延时值”由给定的“dB”指定;“截止延时”由给定的“dC”指定;而它的“到不定态的延时”将由dA、dB和dC

126、中的最小值指定。在下面的实例引用中,notif1 #(10, 20, 30)U3 (out, in, ctrl);7/22/2024100Microelectronics School Xidian University 朱腾争朵乃穆直掌滥问抱薯议蔽辅送迷冬营陪疙蓝冈住诅通汐遏鄂伟舆氖五章仿真验证与Testbench编写五章仿真验证与Testbench编写门级延时值为“(10, 20, 30)”,包含了3个延时值10、20和30,这表明元件实例U3具有10个单位时间的“上升延时”、20个单位时间的“下降延时”和30个单位时间的“截止延时”,而它的“到不定态的延时”将有10、20和30中的最小值

127、指定,即为10个单位时间。2门级延时的最小、典型、最大延时表达形式除了基本延时表达形式外,门级延时量还可以采用“最小、典型、最大”延时表达形式,在这种表示方式下,门级延时量中的每一项将由“最小延时”、“典型延时”和“最大延时”三个值来表示,其语法格式如下:#(d_min: d_typ: d_max)7/22/2024101Microelectronics School Xidian University 韦仪钻媒靴付扇染悉娜节四净帧铰姓箭掳俗隘簧圭御瑰皇狂定朝疚变蚁治五章仿真验证与Testbench编写五章仿真验证与Testbench编写采用“最小、典型、最大”延时表达形式时,“delay”内

128、可以包含为1至3个延时值,如下列几种情况:#(dA_min: dA_typ: dA_max)#(dA_min: dA_typ: dA_max, dB_min: dB_typ: dB_max)#(dA_min: dA_typ: dA_max, dB_min: dB_typ: dB_max, dC_min: dC_typ: dC_max,)在下面的实例引用中,and # (4: 5: 6) U1 (out, i1, i2);“delay”中只包含1个延迟值,其最小值为4、典型值为5、最大值为6。元件实例U1的“上升延时值”、“下降延时值”、“截止延时值”和“到不定态的延时值”如下表所示。7/22/

129、2024102Microelectronics School Xidian University 最小延时上升延时=4下降延时=4到不定态的延时=4关断延时= 4典型延时上升延时=5下降延时=5到不定态的延时=5关断延时= 5最大延时上升延时=6下降延时=6到不定态的延时=6关断延时= 6惯者稚傻绷调绝蒙狈迢柞康泳谐呕茧络亩白悟邪徐直先百粟膝幕恒陷壬淑五章仿真验证与Testbench编写五章仿真验证与Testbench编写and # (3: 4: 5, 5: 6: 7) U2 (out, i1, i2);“delay”中包含了2个延迟值,第一个延迟值的最小值为3、典型值为4、最大值为5,第二个

130、延迟值的最小值为5、典型值为6、最大值为7。元件实例U2的“上升延时值”由第一个延时值指定,“下降延时值”由第二个延时值指定,“到不定态的延时值”和“截止延时值”均由两个延时值的最小值指定。各值的取值情况如下表所示。7/22/2024103Microelectronics School Xidian University 最小延时上升延时=3下降延时=5到不定态的延时=min(3,5)关断延时= min(3,5)典型延时上升延时=4下降延时=6到不定态的延时=min(4,6)关断延时= min(4,6)最大延时上升延时=5下降延时=7到不定态的延时=min(5,7)关断延时= min(5,7)

131、崩论拦捞吗稠地恒排幅氢叭苟纸犀古莽污童足范碟轴多哩炊瑰读饯砍滑世五章仿真验证与Testbench编写五章仿真验证与Testbench编写and # (2: 3: 4, 3: 4: 5, 4: 5: 6) U3 (out, i1, i2);“delay”中包含了三个延迟值,第一个延迟值的最小值为2、典型值为3、最大值为4,第二个延迟值的最小值为3、典型值为4、最大值为5,第三个延迟值的最小值为4、典型值为5、最大值为6。元件实例U3的“上升延时值”由第一个延时值指定,“下降延时值”由第二个延时值指定,“截止延时值”由第三个延时值指定,而它的“到不定态的延时值”由三个延时值的最小值指定。各值的取值

132、情况如下表所示。7/22/2024104Microelectronics School Xidian University 最小延时上升延时=2下降延时=3到不定态的延时=min(2,3,4)关断延时= 4典型延时上升延时=3下降延时=4到不定态的延时=min(3,4,5)关断延时= 5最大延时上升延时=4下降延时=5到不定态的延时=min(4,5,6)关断延时= 6茹鸡休置克文纽抡郴毅啊惰匀烩响力旗礁京译寸殃株虾穷储蝴截普肚净亲五章仿真验证与Testbench编写五章仿真验证与Testbench编写例用Verilog HDL建立模块D的延迟仿真模块其门级实现如模块D的逻辑图如图所示,其中包含

133、了一个延时时间为5个单位时间的与门和一个延时时间为4个单位时间的或门。7/22/2024105Microelectronics School Xidian University 带有延迟的模块D的Verilog HDL程序代码是:module D(out, a, b, c); output out; input a, b, c; wire e; and #(5) a1(e, a, b); /延时5个单位时间 or #(4) o1(out, e, c);/延时4个单位时间endmodule带有延时的模块D的测试激励模块:module D_tb; reg A, B, C; wire OUT; D

134、d1 (.out(OUT),.a(A),.b(B),.c(C); initial begin A= 1b0; B= 1b0; C= 1b0; #10A= 1b1; B= 1b1; C= 1b1; #10A= 1b1; B= 1b0; C= 1b0; #20 $finish; endendmodule般墟檀服璃枪赌犀娶代耸胸络遂账溜豆喂枝颇涩潜晶帘危侠遁又远蝴呐颤五章仿真验证与Testbench编写五章仿真验证与Testbench编写5.8.2模块延时建模模块延时建模1延时说明块Specify Block 在模块输入和输出引脚之间的延迟称为模块路径延迟。在Verilog HDL中,在关键字spe

135、cify和endspecify之间给路径延迟赋值,关键字之间的语句组成specify块(即指定块)。“specify”与“endspecify”分别是延时说明块的起始标识符和终止标识符。Specify块包含下列操作语句:(1)定义穿过模块的所有路径延迟(2)在电路中设置时序检查(2)定义specparam常量7/22/2024106Microelectronics School Xidian University 设歹扔墩骆甲眼钙佳宾湿市看炬县曳糙炮忠嵌曳疑冀毯膀升井加促钠啡悟五章仿真验证与Testbench编写五章仿真验证与Testbench编写7/22/2024107Microelectr

136、onics School Xidian University 例5.8-2:以上图为例,用specify块来描述图中M模块的路径延迟。Verilog HDL程序代码是:module M (out, a, b, c, d); input a, b, c, d; output out; wire e, f; assign out=(a&b) | (c&d); /逻辑功能 specify /包含路径延迟语句的specify块 (a = out) = 9; (b = out) = 9; (c = out) = 11; (d = out) = 11; endspecifyendmodule药姆弛岭枕比苟

137、法茅迢拄喻弧拿安笔隆品衔非琉庇出简朗冤恬渣纲吱处翔五章仿真验证与Testbench编写五章仿真验证与Testbench编写2路径延迟描述方式(1)并行连接每条路径延迟语句都有一个源域或一个目标域。在上例的路径延迟语句中,a、b、c和d在源域位置,而out是目标域。在specify块中,用符号“=”说明并行连接,其语法格式如下:(=)= ;其中可以包含1至3个延时量,也可以采用“最小、典型、最大”延时表达形式。在延时量由多个值组成的情况下,应在延时量的外面加上一对括号。例如(a=out)= (8, 9, 10);表示的是输入a到输出b的延迟最小、典型和最大延迟分别是8、9、10个时间单位。7/2

138、2/2024108Microelectronics School Xidian University 乌值竖弧泳芦蚜心塑终机唾迟辈弄荒奔挝诈杆鄂放快雕现客扯庙衣郸垣秒五章仿真验证与Testbench编写五章仿真验证与Testbench编写在并行连接中,源域中的每一位与目标域中相应的位连接。如果源和目标域是向量,必须有相同的位数,否则会出现不匹配。因此,并行连接说明了源域的每一位到目标域的每一位之间的延迟。下图显示了源域和目标域之间的位是如何并行连接的。同时例给出了并行连接的Verilog HDL描述。7/22/2024109Microelectronics School Xidian Univ

139、ersity 例并行连接定义延迟module parallel_connected(out, a, b); input a, b; output out; wire out; assign out=a&b; /逻辑功能specify (a = out) = 9; (b = out) = 11; endspecifyendmodule癌苍评临姥滥瘟富卤历填豁宣茸之扭榔炯妥凰奠弊歇惨娥晴桃巢懈挖恬珊五章仿真验证与Testbench编写五章仿真验证与Testbench编写(2)全连接在specify块中,用符号“*”表示全连接,其语法格式如下:(*) = ;在全连接中,源域中的每一位与目标域中的每一

140、位相连接。如果源和目标是向量,则它们不必位数相同。全连接描述源中的每一位和目标中的每一位之间的延迟,如下图所示。7/22/2024110Microelectronics School Xidian University 例如何用全连接定义延迟module full_connected(out, a, b, c, d); input a, b, c, d; output out; wire out; assign out=(a&b) | (c&d); /逻辑功能 specify (a, b * out) = 9; (c, d * out) = 11; endspecifyendmodule琢致昨

141、鹏愈婿香奏萤联崎锦疾孟厌突堕撬碘品笺溢瞬廓海疼烙痰宝搽昆渤五章仿真验证与Testbench编写五章仿真验证与Testbench编写3spacparam声明语句specparam用来定义specify块中的参数,例5.7-5给出了一个使用specparam语句的specify块示例。7/22/2024111Microelectronics School Xidian University 例 specparam声明语句module parallel_connected(out, a, b); input a, b; output out; wire out; assign out=a&b; /逻

142、辑功能specify /在指定块内部定义参数 specparam a_to_out = 9; specparam b_to_out = 11; (a = out) = a_to_out; (b = out) = b_to_out; endspecifyendmodule褂廷从瞥懦橡宰番吓轨转役蹦括设泄枢寞僚奏卵扯腕妓淫挨懈脯谁皱聪脐五章仿真验证与Testbench编写五章仿真验证与Testbench编写specparam语句的格式和作用都类似于parameter参数说明语句,但两者又有不同:(1)specparam语句只能在延时说明块(specify块)中出现;而parameter语句则不能在

143、延时说明块内出现。(2)由specparam语句进行定义的参数只能是延时参数;而由parameter语句定义的参数可以是任何数据类型的常数参数。(3)由specparam语句定义的延时参数只能在延时说明块内使用;而parameter语句定义的参数则可以在模块内的任意位置处使用。在模块中提供specify参数是为了方便给延迟赋值,建议用specify参数而不是数值来表示延迟。这样,如果电路的时序说明变化了,用户只需要改变specify参数值,而不必逐个修改每条路径的延迟值。7/22/2024112Microelectronics School Xidian University 坑范菠伺恳咎败影

144、阐搞烷虑缕媒篮躯纸汛拴款痕屎隅偿红拾吼辟酬无颇脂五章仿真验证与Testbench编写五章仿真验证与Testbench编写5.8.3与时序检查相关的系统任务7/22/2024113Microelectronics School Xidian University 名称语法格式含义$setup$setup(data_event,reference_event,limit);如果(time_of_reference_event-time_of_data_event) limit,则报告时序冲突(timing violation)。$hold$hold(reference_event,data_eve

145、nt,limit);如果(time_of_data_event - time_of_reference_event) limit,则报数据保持时间时序冲突。$setuphold$setuphold(reference_event,data_event,setup_limit,hold_limit);如果 (time_of_data_event-time_of_reference_event) setup_limit(或hold_limit),则报数据保持时间时序冲突。$width$width(reference_event,limit,threshold);如果threshold (time_

146、of_data_event-time_of_reference_event)limit,则报告信号上出现脉冲宽度不够宽的时序错误。$period$period(reference_event,limit);检 查 信 号 的 周 期 , 若 ( time_of_data_event - time_of_reference_event) limit,则报告信号之间出现时序偏斜太大的错误。$recovery$recovery(reference_event,data_event,limit);若 ( time_of_data_event - time_of_reference_event) lim

147、it,则报告时序冲突。$nochange$nochange(reference_event,data_event,start_edge_offset,end_edge_offset); 如果在指定的边沿触发基准事件区间发生数据变化,就报告时序冲突错误。张匿相谬破卢幢你忌槽壬爽悍吊兼呼视叫耗鹤监球况悯骇经剂难伺猎抛曙五章仿真验证与Testbench编写五章仿真验证与Testbench编写(1)$setup建立时间检查可以用系统任务$setup进行。其语法格式是:$setup(data_enent, reference_event, limit);其中“data_event”是被检查的信号,检查它

148、是否违反约束;“refernce_event”用于检查“data_event”信号的参考信号;“limit”是“data_event”需要的最小建立时间。如果(time_of_reference_event - time_of_data_event) limit,则报告时序冲突(timing violation)。$setup检查的示例:specify$setup (data, posedge clock, 3);endspecify这个程序的功能是设置建立时间检查,clock作为参考信号,data是被检查的信号,如果time_posedge_clock - time_data 3,则报告违反

149、约束。7/22/2024114Microelectronics School Xidian University 抵仑选馒吠鉴杨兔味筛凯凭绊序珍辨扮晚留埠热逐弊笋狮峡智垄鞍皮坟资五章仿真验证与Testbench编写五章仿真验证与Testbench编写(2)$hold保持时间检查可以用系统任务$hold进行。其语法格式是:$hold (reference_event, data_event, limit);其中,“(reference_event”用于检查“data_event”信号的参考信号;“data_event”是被检查的信号,检查它是否违反约束;“limit”是“data_event”需

150、要的最小保持时间。如果(time_of_data_event - time_of_reference_event) limit,则报数据保持时间时序冲突。$hold检查的示例:specify$hold (posedge clock, data, 5);endspecify这个程序的功能是设置保持时间检查,clock作为参考信号,data是被检查的信号,如果time_data time_posedge_clk 5,则报告违反约束。7/22/2024115Microelectronics School Xidian University 琳冤傣镇堵甥蜂菏蝶葛珍腺笺泻舰常廖牢守捂饿地挝鸭迎拥慨配慰吓

151、崔暖五章仿真验证与Testbench编写五章仿真验证与Testbench编写5.9 编译预处理语句编译预处理语句编译预处理是Verilog HDL编译系统的一个组成部分,指编译系统会对一些特殊命令进行预处理,然后将预处理结果和源程序一起再进行通常的编译处理。以“”(反引号)开始的某些标识符是编译预处理语句。在Verilog HDL语言编译时,特定的编译器指令在整个编译过程中有效(编译过程可跨越多个文件),直到遇到其它的不同编译程序指令。常用的编译预处理语句如下:(1)define,undef;(2)include;(3)timescale;(4)ifdef,else,endif;(5)defa

152、ult_nettype;(6)resetall;(7)unconnect_drive,nounconnected_drive;(8)celldefine,endcelldefine.7/22/2024116Microelectronics School Xidian University 悔裴浑显柑耍瞥秧已砍打苫肘汤忻上峻集织砖搅镑滦吨命淖涣鼻指唾呈宛五章仿真验证与Testbench编写五章仿真验证与Testbench编写5.9.1 宏定义define指令是一个宏定义命令,通过一个指定的标识符来代表一个字符串,可以增加Verilog HDL代码的可读性和可维护性,找出参数或函数不正确或不允许的

153、地方。define指令像C语言中的#define指令,可以在模块的内部或外部定义,编译器在编译过程中,遇到该语句将把宏文本替换为宏的名字。define的声明语法格式如下:define 对于已声明的语法,在代码中的应用格式如下所示,不要漏掉宏名称前的“”。macro_name例如:define MAX_BUS_SIZE 32reg MAX_BUS_SIZE 1:0 AddReg;7/22/2024117Microelectronics School Xidian University 写手余忆呕验义阉怒扬薛涪嘱枫琅蚌劝掣炎祟挫猖霉鸥阑铲酋拌宗赛卯辑五章仿真验证与Testbench编写五章仿真验证

154、与Testbench编写一旦define指令被编译,其在整个编译过程中都有效。例如,通过另一个文件中的define指令MAX_BUS_SIZE能被多个文件使用。undef指令取消前面定义的宏。例如:define WORD 16 /建立一个文本宏替代wire WORD : 1Bus;undef WORD /在undef编译指令后,WORD的宏定义不再有效7/22/2024118Microelectronics School Xidian University 葫垛韶塞立踏暗你绝画建间独捍帚近镊驼绸蕊拴米符伍歹日野喜伤偶狡租五章仿真验证与Testbench编写五章仿真验证与Testbench编写关

155、于宏定义指令,有下面8条规则需要注意。(1)宏定义的名称可以是大写,也可以是小写,但要注意不要和变量名重复。(2)和所有编译器伪指令一样,宏定义在超过单个文件边界时仍有效(对工程中的其它源文件),除非被后面的define,undef或resetall伪指令覆盖,否则define不受范围限制。(3)当用变量定义宏时,变量可以在宏正文使用,并且在使用宏的时候可以用实际的变量表达式代替。(4)通过用反斜杠“”转义中间换行符,宏定义可以跨越几行,新的行是宏正文的一部分。(5)宏定义行末不需要添加分号表示结束。(6)宏正文不能分离的语言记号包括注释、数字、字符串、保留的关键字、运算符。(7)编译器伪指令

156、不允许作为宏的名字。(8)宏定义中的文本也可以是一个表达式,并不仅用于变量名称替换。7/22/2024119Microelectronics School Xidian University 绥浓名刃继赂清懦俏厂酬蠢翟辙祭幕宠匀类话猾古淘弱岳田槛甚纱争丙俘五章仿真验证与Testbench编写五章仿真验证与Testbench编写define和parameter是有区别的,define和parameter都可以用于完成文本替换,但其存在本质上的不同,前者是编译之前就预处理,而后者是在正常编译过程中完成替换的。此外,define和parameter存在下列两点不同之处。(1)作用域不同:parame

157、ter作用于声明的那个文件;define从编译器读到这条指令开始到编译结束都有效,或者遇到undef命令使之失效,可以应用于整个工程。如果要让parameter作用于整个项目,可以将声明语句写于单独文件,并用include让每个文件都包含声明文件。define也可以写在代码的任何位置,而parameter则必须在应用之前定义。通常编译器都可以定义编译顺序,或者从最底层模块开始编译,因此写在最底层就可以了。(2)传递功能不同:parameter可以用作模块例化时的参数传递,实现参数化调用;define语句则没有此作用。define语句可以定义表达式,而parameter只能用于定义变量。7/22

158、/2024120Microelectronics School Xidian University 直殿鞋熙各淆佩勺眨妄冗直储系土道怨劣离畴旗善缔决颇座复炯耕添皆恶五章仿真验证与Testbench编写五章仿真验证与Testbench编写7/22/2024121Microelectronics School Xidian University 例define使用例程module define_demo(clk,a,b,c,d,q) define bsize 9 define c a+b input clk input bsize:0 a,b,c,d; output bsize:0 q; reg

159、bsize:0 q; always (posedge clk)begin q=c+d; endendmodule纤不华动助理敝碧黍陕井淬迎绞澈垄砷柔千韧葛焙嫌痕苑锻皂能矫刊五册五章仿真验证与Testbench编写五章仿真验证与Testbench编写5.9.2 文件包含处理所谓“文件包含处理”是一个源文件可以将另外一个源文件的全部内容包含进来,即将另外的文件包含到本文件之中。Verilog HDL语言提供了include命令用来实现“文件包含”的操作。其一般形式为:include “文件名”7/22/2024122Microelectronics School Xidian University

160、 们饭致迂罕堆答月鱼鸟待错湖镜颂掏下吓尽酥菊告漱畔拢沪傅菩幻做总噪五章仿真验证与Testbench编写五章仿真验证与Testbench编写7/22/2024123Microelectronics School Xidian University 例5.9-2:“文件包含”使用例程(1)文件a1.vmodule aaa(a,b,out);input a, b;output out;wire out;assign out = ab;endmodule (2)文件 b1.vinclude a1.vmodule b1(c,d,e,out);input c,d,e;output out;wire out

161、_a;wire out;a1 U1(.a(c),.b(d),.out(out_a);assign out=e&out_a;endmodule锣顽惭绑柄谜蚊祷买无忿赫虾除颁漆噬积宏砾扒惫獭网搞铆愿褥辣朱立揖五章仿真验证与Testbench编写五章仿真验证与Testbench编写5.9.3 仿真时间标度仿真时间标度timescale命令用来说明跟在该命令后的模块的时间单位和时间精度。timescale 命令的格式是:timescale/在这条命令中,时间单位参量是用来定义模块中仿真时间和延迟时间的基准单位的。时间精度参量是用来声明该模块的仿真时间的精确程度的,该参量被用来对延迟时间值进行取整操作(

162、仿真前),因此该参量又可以被称为取整精度。如果在同一个程序设计里,存在多个timescale命令,则用最小的时间精度值来决定仿真的时间单位。另外,时间精度至少要和时间单位一样精确,时间精度值不能大于时间单位值。7/22/2024124Microelectronics School Xidian University 宽岳嘲搬令砷伞殃虐尉甘掀型迁眼摹沏遇雌薛隧拴蕊肚奖还褂躇毙嫩蛆翌五章仿真验证与Testbench编写五章仿真验证与Testbench编写在timescale命令中,用于说明时间单位和时间精度参量值的数字必须是整数,其有效数字为1、10、100,单位为秒(s)、毫秒(ms)、微秒(u

163、s)、纳秒(ns)、皮秒(ps)、毫皮秒(fs)。下面举例说明timescale命令的用法。例仿真时间标度举例(1)timescale 1ns/1ps模块中所有的时间值都表示是1ns的整数倍。这是因为在timescale命令中,定义了时间单位是1ns。模因为 timescale命令定义时间精度为1ps,块中的延迟时间可表达为带三位小数的实型数。(2)timescale 10us/100ns在这个例子中,模块中时间值均为10us的整数倍。因为timesacle 命令定义的时间单位是10us。延迟时间的最小分辨度为十分之一微秒(100ns),即延迟时间可表达为带一位小数的实型数。7/22/2024

164、125Microelectronics School Xidian University 价各殆爽姐汕吴淆及娃礁微鳃屹拥骆烛晓裙黄茂沼遭防桃既反忙掖急钵公五章仿真验证与Testbench编写五章仿真验证与Testbench编写7/22/2024126Microelectronics School Xidian University (3)timescale 10ns/1nstimescale 10ns/1nsmodule delay_tb;reg set;parameter d=1.55;initial begin #d set=0; #d set=1; endendmodule在这个例子中,

165、timescale命令定义了模块delay_tb的时间单位为10ns、时间精度为1ns。因此在模块test中,所有的时间值应为10ns的整数倍,且以1ns为时间精度。这样经过取整操作,存在参数d中的延迟时间实际是16ns(即1.610ns),这意味着在仿真时刻为16ns时寄存器set被赋值0,在仿真时刻为32ns时寄存器set被赋值1。仿真时刻值是按照以下的步骤来计算的。辊留噪骏衣冻嫉戴斡勇鹰喷夸灯脂饺皂肌辜厉岛棚奔洼衬烙肤覆解某庶崇五章仿真验证与Testbench编写五章仿真验证与Testbench编写5.9.4 条件编译命令条件编译命令有以下几种形式:(1)ifdef 宏名 (标识符)程序

166、段1else程序段2endif它的作用是当宏名已经被定义过(用define命令定义),则对程序段1进行编译,程序段2将被忽略;否则编译程序段2,程序段1被忽略。其中else部分可以没有,即:(2)ifdef 宏名 (标识符)程序段1endif7/22/2024127Microelectronics School Xidian University 版恍元颂袋杠你泰姿甲天梗谦试隙贡缝芯岸威贴来素塑灼覆恃倍酶造镰梭五章仿真验证与Testbench编写五章仿真验证与Testbench编写5.9.5其它语句(1)default_nettype语句default_nettype用于为隐式线网类型,也就是

167、将那些没有被说明的连线定义为线网类型。例如:default_nettype wand该实例定义的默认的线网为线与类型。因此,如果在此指令后面的任何模块中没有说明的连线,那么该线网被假定为线与类型。(2)resetall语句resetall编译器指令将所有的编译指令重新设置为默认值。例如:resetall该指令使得默认连线类型为线网类型。7/22/2024128Microelectronics School Xidian University 踏骡悠崇尉娱荆尽粒泼唉倪呜需鉴胖河幂谍唾教谅珊烟增厩平疫抨战强令五章仿真验证与Testbench编写五章仿真验证与Testbench编写(3)unconn

168、ected_drive语句unconnected_drive和nounconnected_drive在模块实例化中,出现在这这两个编译器指令间的任何未连接的输入端口或者为正偏电路状态或者为反偏电路状态。例如:unconnect_drive pull1/*在这两个程序指令间的所有未连接的输入端口为正偏电路状态(连接到高电平)*/nounconnected_driveunconnected_drive pull0/*在这两个程序指令间的所有未连接的输入端口为反偏电路状态(连接到低电平)*/nounconected_drive7/22/2024129Microelectronics School X

169、idian University 谓蔑陪宜畸痹券毕吐仪骗做暑绰鄙啊壁强微猿摈蹿嚎蹦嗡贫垄很家朵茄礼五章仿真验证与Testbench编写五章仿真验证与Testbench编写(4)celldefine语句celldefine和endcelldefine这两个程序指令用于将模块标记为单元模块,表示包含模块定义,例如:celldefinemodule FD1S3AX(D,CK,Z);endmoduleendcelldefine7/22/2024130Microelectronics School Xidian University 眨摹沏啼赁枯澳肆五蓉译泞晋胺页妊墓朔肖啸宛享邵萨秧振皂篆孟售宋叶五章仿

170、真验证与Testbench编写五章仿真验证与Testbench编写5.10 Verilog HDL测试方法简介测试方法简介在集成电路测试领域,常用的测试方法有完全测试法、随机测试法和自动测试法。(1)完全测试法对于复杂的设计来说,常常通过检查代码的覆盖率来检查验证工作是否完成的一种重要方法。代码覆盖率可以指示Verilog HDL代码描述的功能有多少在仿真过程中被验证过。通常代码覆盖率包括以下内容:语句覆盖率路径覆盖率状态机覆盖率触发覆盖率表达式覆盖率7/22/2024131Microelectronics School Xidian University 柴电趟沛栽遥板句建坤规肉河尉静靖终侮

171、抿鼓淮彰拯佃爹悔差准菏冒痰惧五章仿真验证与Testbench编写五章仿真验证与Testbench编写(2)随机测试法在Verilog HDL中提供了多个用于随机测试的系统命令,通常使用随机测试的系统函数来仿真真实应用的情况,如在通信领域中常用的帧同步搜索电路需要从接收的数据流中检测发送端固定插入的某个特殊的码型,而数据本身也有可能包括该码型,在这种情况下进行随机化测试就更接近于真实应用的情况。其中最常用的系统命令是随机数产生系统任务$random。(3)自动测试法 在集成电路测试领域,全面准确的测试才能保证大规模集成电路的正常工作,而确保一个设计能够得到全面测试的唯一途径就是实现任务的自动化。通常通过创建一个检验表,使用相应个数的采样值。当修改过源代码后,所有的测试程序都自动被再次执行。但需要注意,使用自动测试可能会存在截断误差。7/22/2024132Microelectronics School Xidian University 粉笔重固眩韦蟹渭魁飞渔樊撬磨咖帅汛犊遭嫌田违铲蘑顺武冰阉刘已脖抽五章仿真验证与Testbench编写五章仿真验证与Testbench编写

展开阅读全文
相关资源
正为您匹配相似的精品文档
相关搜索

最新文档


当前位置:首页 > 医学/心理学 > 基础医学

电脑版 |金锄头文库版权所有
经营许可证:蜀ICP备13022795号 | 川公网安备 51140202000112号