仿真验证与TESTBENCH编写

上传人:1666****666 文档编号:46992480 上传时间:2021-12-16 格式:PPT 页数:132 大小:1.69MB
收藏 版权申诉 举报 下载
仿真验证与TESTBENCH编写_第1页
第1页 / 共132页
仿真验证与TESTBENCH编写_第2页
第2页 / 共132页
仿真验证与TESTBENCH编写_第3页
第3页 / 共132页
资源描述:

《仿真验证与TESTBENCH编写》由会员分享,可在线阅读,更多相关《仿真验证与TESTBENCH编写(132页珍藏版)》请在装配图网上搜索。

1、第五章第五章 仿真验证与仿真验证与Testbench编写编写12/3/20211Microelectronics School Xidian University 5.1 Verilog HDL电路仿真和验证概述电路仿真和验证概述 仿真,也叫模拟,是通过使用EDA仿真工具,通过输入测试信号,比对输出信号(波形、文本或者VCD文件)和期望值,来确认是否得到与期望所一致的正确的设计结果,验证设计的正确性。验证是一个证明设计思路如何实现,保证设计在功能上正确的一个过程。验证在Verilog HDL设计的整个流程中分为4个阶段:p阶段1: 功能验证;p阶段2: 综合后验证;p阶段3: 时序验证;p阶段

2、4: 板级验证。12/3/20212Microelectronics School Xidian University 5.2 Verilog HDL测试程序设计基础测试程序设计基础 5.2.1 Testbench及其结构在仿真的时候Testbench用来产生测试激励给待验证设计(Design Under Verification,DUV),或者称为待测设计(Design Under Test,DUT)。 Testbench平台结构 测试程序的一般结构 由于Testbench是一个测试平台,信号集成在模块内部,没有输入输出。 在Testbench模块内,例化待测设计的顶层模块,并把测试行为的代

3、码封装在内,直接对待测系统提供测试激励。 例5.2-1 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($t

4、ime, T= %b, clk= %b, rst_n= %b, data_out= %b, T, clk, rst_n, data_out); endendmoduleT触发器的仿真波形和部分文本输出结果 :部分文本输出结果: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= 1, clk= 0, rst_n= 1, data_out= 1从图中可以清

5、晰地看出Testbench的主要功能:(1)为DUT提供激励信号。(2)正确实例化DUT。(3)将仿真数据显示在终端或者存为文件,也可以显示在波形窗口中以供分析检查。(4)复杂设计可以使用EDA工具,或者通过用户接口自动比较仿真结果与理想值,实现结果的自动检查。在编写Testbench时需要注意的问题 :(1)testbench代码不需要可综合Testbench代码只是硬件行为描述不是硬件设计 。(2)行为级描述效率高Verilog HDL语言具备5个描述层次,分别为开关级、门级、RTL级、算法级和系统级。 (3)掌握结构化、程式化的描述方式 结构化的描述有利于设计维护,可通过initial、

6、always以及assign语句将不同的测试激励划分开来。一般不要将所有的测试都放在一个语句块中。 5.2.2测试平台举例DUT的仿真平台 测试平台需要产生时钟信号、复位信号和一系列的仿真向量,观察DUT的响应,确认仿真结果。 (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; adder1 U1(a,b

7、,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全加器的输入a、b和ci定义为reg型变量;把输出so和co定义为wire型变量 用模块例化语句“adder1 U1(a,b,ci,so,co);”把全加器设计电路例化到测试仿真环境中

8、; 用initial块语句改变输入的变化并生成测试条件,输入的变化语句完全根据全加器的真值表编写 仿真结果仿真结果 :(2)时序逻辑电路仿真环境的搭建在于时序逻辑电路仿真环境中,需要考虑时序、定时信息和全局复位、置位等信号要求,并定义这些信号。用Verilog HDL编写的十进制加法计数器源程序代码是: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

9、; 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系统任务打印任务 :$display,直接输出到标准输出设备;$monitor,监控参数的变化;$fdisplay,输出到文件等(3)自动检查仿真结果自动检查仿真结果是通过在设计代码中的关键节点添加断言监控器,形成对电路逻辑综合的注释或是对设计特点的说明,以提高设计模块的观察性。 (4)使用VCD文件Verilog

10、HDL提供一系列系统任务用于记录信号值变化保存到标准的VCD(Value Change Dump)格式数据库中。 VCD文件是一种标准格式的波形记录文件,只记录发生变化的波形。 VCD文件将在第5.3.7小节中详细讲述。 5.2.4 Verilog HDL仿真效率仿真效率因为要通过串行软件代码完成并行语义的转化, Verilog HDL行为级仿真代码的执行时间比较长。提高Verilog HDL代码的仿真代码执行时间:(1)减小层次结构 仿真代码的层次越少,执行时间就越短。 (2)减少门级代码的使用由于门级建模属于结构级建模,建议仿真代码尽量使用行为级语句,建模层次越抽象,执行时间就越短。 (3

11、)仿真精度越高,效率越低计时单位值与计时精度值的差距越大,则模拟时间越长。timescale仿真时间标度将在第5.9.3小节中详细讲述。 (4)进程越少,效率越高代码中的语句块越少仿真越快,这是因为仿真器在不同进程之间进行切换也需要时间。 (5)减少仿真器的输出显示Verilog HDL语言包含一些系统任务,可以在仿真器的控制台显示窗口输出一些提示信息 ,但会降低仿真器的执行效率。 5.3与仿真相关的系统任务与仿真相关的系统任务5.3.1 $display和$write语法格式如下:$display(“”, );$write(“”, );“”通常称为“格式控制”“”则为“信号输出列表” $di

12、splay自动地在输出后进行换行 $write输出特定信息时不自动换行 输出格式说明,由“%”和格式字符组成,其作用是将输出的数据转换成指定的格式输出。 常用的几种输出格式如右表。输出格式说明%h或%H以十六进制数的形式输出%d或%D以十进制数的形式输出%o或%O以八进制数的形式输出%b或%B以二进制数的形式输出%c或%C以ASCII码字符的形式输出%v或%V输出网络型数据信号强度%m或%M输出等级层次的名字%s或%S以字符串的形式输出%t或%T以当前的时间格式输出%e或%E以指数的形式输出实型数%f或%F以十进制数的形式输出实型数%g或%G以指数或十进制数的形式输出实型数一些特殊的字符可以通

13、过表中的转换序列来输出。换码序列功能n换行t横向跳格(即跳到下一个输出区)反斜杠字符双引号字符o1到3位八进制数代表的字符%百分符号%例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(rval has %c ascii charact

14、er 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 00000000000000000000000001100101 binaryrval has e

15、ascii character valuepd strength value is StXcurrent scope is dispe is ascii value for 101simulation time is 0在$display中,输出列表中数据的显示宽度是自动按照输出格式进行调整的,总是用表达式的最大可能值所占的位数来显示表达式的当前值。5.3.2 $monitor和和$strobe$monitor与$stobe都提供了监控和输出参数列表中字符或变量的值的功能 (1)$monitor语法格式:$monitor(”, );任务$monitor提供了监控和输出参数列表中的表达式或变量值

16、的功能。每当参数列表中变量或表达式的值发生变化时,整个参数列表中变量或表达式的值都将输出显示。 例如:$monitor($time,rxd=%b txd=%b,rxd,txd);注意在上面的语句中,“,代表一个空参数。空参数在输出时显示为空格。 $monitoron和$monitoroff任务的作用是通过打开和关闭监控标志来控制监控任务$monitor的启动和停止,这样使得程序员可以很容易的控制$monitor何时发生 。$monitor与$display的不同处在于$monitor往往在initial块中调用,只要不调用$monitoroff,$monitor便不间断地对所设定的信号进行监视

17、。 例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 initial #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 =

18、21, b = 1030 a = 21, b = 2035 a = 41, b = 20(2)$strobe语法格式:$strobe();$strobe(“”,); 探测任务用于在某时刻所有时间处理完后,在这个时间步的结尾输出一行格式化的文本。常用的系统任务如下:$strobe: 在所有时间处理完后,以十进制格式输出一行格式化的文本;$strobeb: 在所有时间处理完后,以二进制格式输出一行格式化的文本;$strobeo: 在所有时间处理完后,以八进制格式输出一行格式化的文本;$strobeh: 在所有时间处理完后,以十六进制格式输出一行格式化的文本。 $strobe任务在被调用的时刻所有的

19、赋值语句都完成了,才输出相应的文字信息。 $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(

20、“#5 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 5.3.3 $time和和$realtime用这两个时间系统函数可以得到当前的仿真时刻 ,所不同的是,$time函数以64位整数值的形式返回仿真时间,而$realtime函数则以实数型数据返回仿真时间。 (1)系统函

21、数)系统函数$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 ts = x3 ts = 15 ts = 08 ts = 110 ts = 0(2)$realtime系统函数系统函数$real

22、time返回的时间数字是一个实型数,该数字也是以时间尺度为基准的。 例5.3-5:$realtime系统任务的应用实例timescale1ns/1nsmodule realtime_tb;reg set;parameter p=2;initial begin $monitor($realtime,set=b%,set); /使用函数$realtime #p set=0; #p set=1; endendmodule输出结果为:0 set=x2 set=04 set=15.3.4 $finish和和$stop系统任务$finish和$stop是用于对仿真过程进行控制,分别表示结束仿真和中断仿真。

23、其语法格式:$finish;$finish(n);$stop;$stop(n);其中,n是$finish和$stop的参数,n可以取0、1或2几个值,分别表示如下含义,如下表所示。 n的取值含义0不输出任何信息1给出仿真时间和位置2给出仿真时间和位置,同时还有所用memory及CPU时间的统计$finish的作用是退出仿真器,返回主操作系统,也就是结束仿真过程。任务$finish可以带参数,根据参数的值输出不同的特征信息。如果不带参数,默认$finish的参数值为1。$stop任务的作用是把EDA工具(例如仿真器)置成暂停模式,在仿真环境下给出一个交互式的命令提示符,将控制权交给用户。这个任务

24、可以带有参数表达式。根据参数值(0,1或2)的不同,输出不同的信息。参数值越大,输出的信息越多。$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, b); endendmodule在上例中,程序执行到40个时间单位时退出

25、仿真器。例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仿真器设置为暂停模式 。5.3.5 $readmemh和和$readmem在Verilog HDL程序中有两个系统任

26、务$readmemb和$readmemh用来从文件中读取数据到存储器中。这两个系统任务可以在仿真的任何时刻被执行使用,其语法格式共有以下六种:(1)$readmemb(,);(2)$readmemb(,);(3)$readmemb(,);(4)$readmemh(,);(5)$readmemh(,);(6)$readmemh(,);12/3/202132Microelectronics School Xidian University 12/3/202133Microelectronics School Xidian University 例$readmemh和$readmemb系统任务的应用

27、实例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读入存储器中的给定地址 $readmemb(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); $dis

28、play(memory_h %0h = %h, i, memory_hi); end end endmodule文件init_b.txt和init_h.txt包含初始化数据。用在数据文件中指定地址。其中,“init_b.txt”指定二进制数据从第二位地址开始写入;而“init_h.txt”指定十六进制数据从地一位地址写入。样本文件如下所示。12/3/202134Microelectronics School Xidian University “init_b.txt”文件:00211111111 0101010100000000 101010100061111zzzz 00001111“ini

29、t_h.txt”文件:001000000000000000000000000000000110000000000000000000000000000011100000000000000000000000000001111000000000000000000000000000111115.3.6 $random$random是产生随机数的系统函数,每次调用该函数将返回一个32位的随机数,该随机数是一个带符号的整数。语法格式: $random%;这个系统函数提供了一个产生随机数的手段。当函数被调用时返回一个32bit的随机数。它是一个带符号的整形数。$random一般的用法是:$ramdom %

30、b ,其中 b0,它给出了一个范围在(-b+1):(b-1)中的随机数。12/3/202135Microelectronics School Xidian University 例例$random系统任务的应用实例系统任务的应用实例12/3/202136Microelectronics School Xidian University timescale 1ns/1nsmodule random_pulse( dout );output 9:0 dout;reg dout;integer delay1,delay2,k;initial begin #10 dout=0; for (k=0; k

31、 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到60ns间变化 end endendmodule 5.4信号时间赋值语句信号时间赋值语句12/3/202137Microelectronics School X

32、idian University 5.4.1时间延迟的语法说明时间延迟的语法说明延迟语句用于对各条语句的执行时间进行控制,从而快速满足用户的时序要求。Verilog HDL语言中延时控制的语法格式有两类:(1)#行为语句;(2)#;其中,符号“#”是延迟控制的关键字符,可以是直接指定的延迟时间量,并以多少个仿真时间单位的形式给出。在仿真过程中,所有时延都根据时间单位定义。下面是带时延的赋值语句示例。#2 Sum = A B; /#2指定2个时间单位后,将A异或B的值赋值给Sum。12/3/202138Microelectronics School Xidian University 根据时间控

33、制部分在过程赋值语句中出现的位置,可以把过程赋值语句中的时间控制方式分为外部时间控制方式和内部时间控制方式。(1)外部时间控制方式是时间控制出现在整个过程赋值语句的最左端,也就是出现赋值目标变量的左边的时间控制方式,其语法结构如下例所示:#5 a=b;在仿真执行时就相当于如下几条语句的执行:initialbegin #5; a=b;end12/3/202139Microelectronics School Xidian University (2)内部时间控制方式是过程赋值语句中的时间控制部分还可以出现在“赋值操作符”和“赋值表达式”之间的时间控制方式。其语法结构如下例所示:a=#5b;其中时

34、间控制部分“#5”就出现在赋值操作符“=”和赋值表达式“b”的中间,因此在这条过程赋值语句内带有内部时间控制方式的时间控制。它在执行时就相当于如下几条语句的执行:initial begin temp=b; /先求b的值 #5; a=temp;end12/3/202140Microelectronics School Xidian University 5.4.2时间延迟的描述形式时间延迟的描述形式此处时间延迟的描述形式是指延时控制的描述形式,其分为串行延迟控制、并行延迟控制、阻塞式延迟控制和非阻塞式延迟控制四种形式。以实现两组不同波形的信号为例(如图所示q0_out和q1_out),说明四种不

35、同时间延迟的描述形式。12/3/202141Microelectronics School Xidian University (1)串行延迟控制串行延迟控制是最为常见的信号延迟控制,它是由begin-end过程块加上延迟赋值语句构成,其中延迟赋值语句可以为外部时间控制方式,也可以为内部时间控制方式。在之后也可根据情况来确定是否执行相应的行为语句。在后面有相应的行为语句,则仿真进程遇到这条带有延迟控制的行为语句后并不立即执行行为语句指定的操作,而是要延迟等待到“”所指定的时间量过去后才真正开始执行行为语句指定的操作。12/3/202142Microelectronics School Xidi

36、an University 12/3/202143Microelectronics School 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;

37、#50 q0_out=1b0; endinitial begin q1_out=1b0; #100q1_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串行延迟控制方式设计图示信号(2)并行延迟控制并行延迟控制方式是通过fork-join过程块加上延迟赋值语句构成,其中延迟赋值语句同串行延迟控制方式一样,既可以是外部时间控制方式,也可以是内部时间控制方式。

38、在之后也可根据情况来确定是否执行相应的行为语句。在后面有相应的行为语句,则仿真进程遇到这条带有延迟控制的行为语句后并不立即执行行为语句指定的操作,而是要延迟等待到“”所指定的时间量过去后才真正开始执行行为语句指定的操作。但并行延迟控制方式与串行延迟控制方式不同在于并行延迟控制方式中的多条延迟语句时并行执行的,并不需要等待上一条语句的执行完成才开始执行当前的语句。12/3/202144Microelectronics School Xidian University 12/3/202145Microelectronics School Xidian University timescale 1n

39、s/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; #500q0_out=1b1; #600q0_out=1b0; joininitial fork q1_out=1b0; #100q1_out=1b1; #200q1_out=1b0; #

40、250q1_out=1b1; #350q1_out=1b0; #400q1_out=1b1; #500q1_out=1b0; #550q1_out=1b1; #600q1_out=1b0; joinendmodule例Verilog HDL并行延迟控制方式设计图示信号(3)阻塞式延迟控制以赋值操作符“=”来标识的赋值操作称为“阻塞式过程赋值”,阻塞式过程赋值在之前已经介绍过,在此介绍阻塞式延迟控制。阻塞式延迟控制是在阻塞式过程赋值基础上带有延时控制的情况,例如initialbegina = 0;a = #5 1;a = #10 0;a = #15 1;end12/3/202146Microel

41、ectronics School Xidian University 各条阻塞式赋值语句将依次得到执行,并且在第一条语句所指定的赋值操作没有完成之前第二条语句不会开始执行。因此在仿真进程开始时刻将“0”值赋给a,此条赋值语句完成之后才开始执行第二条赋值语句;在完成第一条赋值语句之后,延迟5个时间单位将“1”赋值给a;同理第三条赋值语句是在第二条赋值语句完成之后延迟10个时间单位才开始执行,将“0”赋值给a;最后一条赋值语句是在前三条语句都完成的时刻,延迟15个时间单位,将“1”赋值给a。下图给出了上例中信号a的波形。上述两例都采用的是阻塞式赋值语句。12/3/202147Microelectr

42、onics School Xidian University (4)非阻塞式延迟控制以赋值操作符“=”来标识的赋值操作称为“非阻塞式过程赋值”,非阻塞式过程赋值也在之前讲述过,在此主要介绍非阻塞式延迟控制。非阻塞式延迟控制是在非阻塞式过程赋值基础上带有延时控制的情况。如下例所示:initialbegina = 0;a = #5 1;a = #10 0;a = #15 1;end12/3/202148Microelectronics School Xidian University 在上例中各条非阻塞式赋值语句均以并行方式执行,虽然执行语句在begin-end串行块中,但其执行方式与并行延迟控制

43、方式一致,在仿真进程开始时刻同时执行四条延迟赋值语句。在仿真进程开始时,将“0”值赋值给a;在离仿真开始时刻5个时间单位时,将“1”值赋值给a;在离仿真开始时刻10个时间单位时,将“0”值赋值给a;最后在离仿真开始时刻15个时间单位时,将“1”值赋值给a。下图给出了上例中信号a的波形。12/3/202149Microelectronics School Xidian University 12/3/202150Microelectronics School Xidian University timescale 1ns/1nsmodule non_blocking_delay(q0_out,q

44、1_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 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=#

45、350 1b0; q1_out=#400 1b1; q1_out=#500 1b0; q1_out=#550 1b1; q1_out=#600 1b0; endendmodule例Verilog HDL非阻塞延迟控制方式设计5.4.3边沿触发事件控制边沿触发事件控制边沿触发事件控制的语法格式可以为如下四种形式:形式1:()行为语句;形式2:();形式3:(ororor)行为语句;形式4:(ororor);12/3/202151Microelectronics School Xidian University 1事件表达式在事件表达式中,可以以三种形式出现:形式1: 形式2:posedge形式3

46、:negedge其中,“”可以是任何数据类型的标量或矢量。形式1中,代表触发事件的“”在指定的信号发生逻辑变化时,执行下面的语句,如例所示:(in) out=in;当敏感事件in发生逻辑变化时(包括正跳变和负跳变),执行对应的赋值语句,将in的值赋值给out。12/3/202152Microelectronics School Xidian University 形式2中,代表触发事件的“posedge”在指定的信号发生了正跳变时,执行下面的语句,如下例所示:(posedge in) out=in;当敏感事件in发生正跳变时,执行对应的赋值语句,将in的值赋值给out。形式3中,代表触发事件的

47、“negedge”在指定的信号发生了负跳变时,执行下面的语句,如下例所示:(negedge in)out=in;当敏感事件in发生负跳变时,执行对应的赋值语句,将in的值赋值给out。12/3/202153Microelectronics School Xidian University 在信号发生逻辑变化(正跳变或负跳变)的过程中,信号的值是从0、1、x、z四个值中的一个值变化到另一个值;而信号发生正跳变的过程是信号由低电平向高电平的转变,负跳变是信号由高电平向低电平的转变。表5.4-1为Verilog HDL中规定的正跳变和负跳变。12/3/202154Microelectronics S

48、chool Xidian University 正跳变负跳变0 x1x0z1z0110 x1x0z1z02边沿触发语法格式形式1:()行为语句;这种语法格式的敏感事件列表内只包含了一个触发事件,只有当这个指定的触发事件发生之后,后面的行为语句才能启动执行。在仿真进程中遇到这种带有事件控制的行为语句时,如果指定的触发事件还没有发生,则仿真进程就会停留在此处等待,直到指定触发事件发生之后再启动执行后面的行为语句,仿真进程继续向下进行。12/3/202155Microelectronics School Xidian University 例5.4-4:时钟脉冲计数器module clk_count

49、er(clk, count_out); input clk; output count_out; reg 3:0 count_out; initial count_out = 0; always(posedge clk) count_out = count_out + 1;/在clk的每个正跳变边沿count_out增加1endmodule形式2:();这种语法格式的敏感事件列表内也只包含了一个触发事件,没有行为语句来指定触发事件发生时要执行的操作。这种格式的事件控制语句的执行过程与延时控制语句中没有行为语句的情况类似,仿真进程在遇到这条事件控制语句后会进入等待状态,直到指定的触发事件发生后才

50、结束等待状态,退出该事件控制语句的执行并开始下一条语句的执行。12/3/202156Microelectronics School Xidian University 12/3/202157Microelectronics 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);/*等待,直到时钟发生正跳变后退出等待

51、状态,继续执行下一条语句*/ 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 stay

52、 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例用于测定输入时钟正电平、负电平持续时间以及时钟周期的模块形式3:(ororor)行为语句;这种语法格式的“敏感事件列表”内指定了由不同“”代表的多个触发事件,这些“”之间要用关键词“or”组合起来。只要这些触发事件中的任何一个得到发生,就启动行为语句的执行。在仿真进程遇到这种格式的

53、边沿触发事件控制语句时如果所有的触发事件都没有发生,则仿真进程就会进入等待状态,直到其中的某一个触发事件发生后才启动执行后面给出的行为语句,仿真进程继续向下进行。12/3/202158Microelectronics School Xidian University 形式4:(ororor);同第三种语法格式一样,这种语法格式内指定了多个触发事件。但是在这种格式中没有行为语句。在这种情况下,该语句的执行过程与第二种语法格式的执行过程类似,仿真进程在遇到这条事件控制语句后会进入等待状态,直到敏感事件列表包含的多个触发事件中的任何一个得到发生后才结束等待状态,退出该事件控制语句并开始执行该事件控制

54、语句后的下一条语句。12/3/202159Microelectronics School Xidian University 例在触发事件发生后退出事件控制语句module display_information_change(a, b); input a, b; wire a, b; always begin(posedge a or negedge b);/*等待,直到a或b发生变化后退出等待状态,并开始下一条语句的执行*/ display(One of a and b changed in time:%t,$time); endendmodule5.4.4电平敏感事件控制电平敏感事件控制

55、电平敏感时间控制是另一种事件控制方式,与边沿触发事件控制不同,它是在指定的条件表达式为真时启动需要执行的语句。电平敏感时间控制是用关键词“wait”来表示。电平触发事件控制的语法格式可以为如下两种:形式1:wait(条件表达式)行为语句;形式2:wait(条件表达式);电平敏感事件控制的第一种形式中包含了行为语句,它可以是串行块(begin-end)语句或并行块(fork-join)语句,也可以是单条行为语句。在这种事件控制语句形式下,行为语句启动执行的触发条件是:条件表达式的值为“真(逻辑1)”。如果当仿真进程执行到这条电平敏感控制语句时条件表达式的值是“真”,那么语句块立即得到执行;否则语

56、句块要一直等到条件表达式变为“真”时再开始执行。12/3/202160Microelectronics School Xidian University 12/3/202161Microelectronics School Xidian University 例如:wait(enable = 1)begind = a & b;d = d | c;endwait语句的作用是根据条件表达式的真假来控制下面begin-end语句块的执行,在使能信号enable变为高电平后,也就是enable=1的语句为真时进行a,b,c之间的与或操作;若使能信号enable未变为高电平,则begin-end

57、语句块的执行需要等到enable变为高电平之后才开始执行。电平敏感事件控制的第2种形式中没有包含行为语句。在这种电平敏感事件控制语句形式下,如果当仿真进程执行到该wait控制语句时条件表达式的值是“真”,那么立即结束该wait事件控制语句的执行,仿真进程继续往下进行;而如果当仿真进程执行到这条wait控制语句时条件表达式的值是“假”,则仿真进程进入等待状态,一直等到条件表达式取值变为“真”时才退出等待状态同时结束该wait语句的执行,仿真进程继续往下进行。这种形式的电平敏感时间控制常常用来对串行块中各条语句的执行时序进行控制。12/3/202162Microelectronics School

58、 Xidian University 例如:beginwait(enable = 1);d = a & b;d = d | c;end5.5任务和函数任务和函数在Verilog HDL语言中提供了任务和函数,可以将较大的行为级设计划分为较小的代码段,允许设计者将需要在多个地方重复使用的相同代码提取出来,编写成任务和函数,这样可以使代码更加简洁和易懂。5.5.1任务1.任务的定义任务定义的语法格式:12/3/202163Microelectronics School Xidian University task; 端口和类型声明 局部变量声明begin 语句1; 语句2; 语句n;end

59、 endtask任务定义是嵌入在关键字task和endtask之间的,其中关键词task标志着一个任务定义结构的开端,endtask标志着一个任务定义结构的结束。“”是所定义任务的名称。在“”后面不能出现输入输入端口列表。例以读存储器数据为例说明任务定义的操作12/3/202164Microelectronics School Xidian University task read_memory;/任务定义的开头,指定任务名为read_memoryinput15:0address;/输入端口说明output31:0data;/输出端口说明reg3:0counter;/变量类型说明reg7:0t

60、emp1:4;/变量类型说明begin/语句块,任务被调用时执行for(counter=1;counter=4;counter=counter+1)tempcounter=memaddress+counter-1;data=temp1, temp2, temp3, temp4;endendtask/任务定义结束任务定义时需注意以下事项:(1)在第一行“task”语句中不能列出端口名列表。(2)任务中可以有延时语句、敏感事件控制语句等事件控制语句。(3)任务可以没有或可以有一个或多个输入、输出和双向端口。(4)任务可以没有返回值,也可以通过输出端口或双向端口返回一个或多个返回值。(5)任务可以调

61、用其它的任务或函数,也可以调用该任务本身。(6)任务定义结构内不允许出现过程块(initial或always过程块)。(7)任务定义结构内可以出现disable终止语句,这条语句的执行将中断正在执行的任务。在任务被中断后,程序流程将返回到调用任务的地方继续向下执行。12/3/202165Microelectronics School Xidian University 2、任务的调用任务的调用是通过“任务调用语句”来实现的。任务调用语句列出了传入任务的参数值和接收结果的变量值,任务的调用格式如下:(端口1,端口2,端口n);例以测试仿真中常用的方式来说明任务的调用12/3/202166Micr

62、oelectronics 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; begin for(

63、counter=1; counter=4; counter=counter+1) tempcounter= memaddress+counter-1; data=temp1, temp2, temp3, temp4; end endtaskendmodule使用任务可以使程序更加简洁易懂,以实际中的交通灯控制为例说明任务的定义、调用的特点。12/3/202167Microelectronics School Xidian University module traffic_lights(red, amber, green); output red, amber, green; reg 2:1

64、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; output green; input 31:0 tic_time; input 2:1 order; begin red = OFF; green = OFF

65、; amber = OFF; case(order) 2b01: red = ON; 2b10: green = ON; 2b11: amber = ON; endcase12/3/202168Microelectronics School Xidian University repeat(tic_time)(posedge clock); red = OFF; green = OFF; amber = OFF; end endtask/任务的调用,交通灯初始化 initial begin order = 2b00; light(red, amber, green, 0, order); en

66、d /任务的调用,交通灯控制时序 always begin order = 2b01; light(red, amber, green, RED_TICS, order);/调用开灯任务,开红灯order = 2b10; ilght(red, amber, green, GREEN_TICS, order);/调用开灯任务,开绿灯 order = 2b11; light(red, amber, green, AMBER_TICS, order);/调用开灯任务,开黄灯 endendmodule5.5.2 函数1函数的定义12/3/202169Microelectronics School Xidian University function ;begin语句1;语句2;语句n;endendfunction函数定义是嵌入在关键字function和endfunction之间的,其中关键词function标志着一个函数定义结构的开端,endfunction标志着一个函数定义结构的结束。“”是给被定义函数取的名称。这个函数名在函数定义结构内部还代表着一个内部变量,函数调用后的返回值是通过这个函数名变量传递给调

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

copyright@ 2023-2025  zhuangpeitu.com 装配图网版权所有   联系电话:18123376007

备案号:ICP2024067431-1 川公网安备51140202000466号


本站为文档C2C交易模式,即用户上传的文档直接被用户下载,本站只是中间服务平台,本站所有文档下载所得的收益归上传人(含作者)所有。装配图网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对上载内容本身不做任何修改或编辑。若文档所含内容侵犯了您的版权或隐私,请立即通知装配图网,我们立即给予删除!