《verilog语言学习14-16.ppt》由会员分享,可在线阅读,更多相关《verilog语言学习14-16.ppt(51页珍藏版)》请在taowenge.com淘文阁网|工程机械CAD图纸|机械工程制图|CAD装配图下载|SolidWorks_CaTia_CAD_UG_PROE_设计图分享下载上搜索。
1、验证系统中的任务验证系统中的任务(task)(task)及函数及函数(function)(function)Verilog读取当前仿真时间的系统函数读取当前仿真时间的系统函数 $time $stime $realtimeVerilog支持文本输出的系统任务:支持文本输出的系统任务: $display $strobe $write $monitor仿真时间仿真时间访问仿真时间访问仿真时间$time,$realtime,和和$stime函数返回当前仿真时间。函数返回当前仿真时间。这些函数的返回值使用调用模块中这些函数的返回值使用调用模块中timescale定义的时间单位定义的时间单位$time返回
2、一个返回一个64位整数时间值。位整数时间值。$stime返回一个返回一个32位整数时间值。位整数时间值。$realtime返回一个实数时间值。返回一个实数时间值。 $stime函数返回一个函数返回一个32位整数时间值。对大于位整数时间值。对大于232的时间,返回模的时间,返回模232的值。的值。使用它可以节省显示及打印空间。使用它可以节省显示及打印空间。 输出格式化时间信息输出格式化时间信息timescale 10ns / 100psmodule top; reg in1; not m1( o1, in1); initial begin $timeformat(-9, 2, ns, 10);
3、in1 = 0; #8 in1 = 1; #10 $display(%t %b %b, $realtime, in1, o1); #10 $finish; endendmodule在这个例子中,显示在这个例子中,显示的时间为:的时间为:180.00 nsunit:0(s)到到-15(fs)之间的之间的整数,表示时间度量整数,表示时间度量precision:要显示的十进:要显示的十进制小数位数。制小数位数。suffix:在时间值后显示的:在时间值后显示的字符串字符串min_width:显示前三项的:显示前三项的最小宽度最小宽度 若使用多个若使用多个timescale,以最小的时间精度显示时间值。
4、,以最小的时间精度显示时间值。可用系统任务可用系统任务$timeformat结合格式符结合格式符%t全局控制时间显示方式。全局控制时间显示方式。$timeformat系统任务的语法为:系统任务的语法为: $timeformat(,);输出格式化时间信息输出格式化时间信息timescale 1 ns / 10 psmodule top; reg in1; not #9.53 n1 (o1, in1); initial begin $display(time realtime stime t in1 t o1 ); $timeformat(-9, 2, ns, 10); $monitor(%d %
5、t %d t %b t %b, $time, $realtime, $stime, in1, o1); in1 = 0; #10 in1 = 1; #10 $finish; endendmoduletime realtime stime in1 o1 0 0.00ns 0 0 x10 9.53ns 10 0 110 10.00ns 10 1 120 19.53ns 20 1 0输出格式化时间信息输出格式化时间信息对#延迟,Verilog将延迟值舍入最近(四舍五入)时间精度值。例如,上面的例子修改为:timescale 1ns/ 100psnot #9.42 n1 (o1, in1);结果为:t
6、ime realtime stime in1 o1 0 0.00ns 0 0 x 9 9.40ns 9 0 110 10.00ns 10 1 119 19.40ns 19 1 0timescale 1ns/ 100psnot #9.49 n1 (o1, in1);结果为:time realtime stime in1 o1 0 0.00ns 0 0 x 9 9.50ns 9 0 110 10.00ns 10 1 119 19.50ns 19 1 0显示信号值显示信号值 $displaydisplay$display输出参数列表中信号的当前值。输出参数列表中信号的当前值。 语法:语法:$disp
7、lay(“ format_specifiers”, )$display输出时输出时自动换行自动换行。 $display ($ time, “%b t %h t %d t %o”, sig1, sig2, sig3, sig4); $display ($ time, “%b t”, sig1, “%h t”, sig2, “% d t”, sig3, “%o”, sig4);$display支持二进制、八进制、十进制和十六进制。缺省基数为十进制。支持二进制、八进制、十进制和十六进制。缺省基数为十进制。 $display (sig1, sig2, sig3, sig4); $displayb (s
8、ig1, sig2, sig3, sig4); $displayo (sig1, sig2, sig3, sig4); $displayh (sig1, sig2, sig3, sig4); %h %o %d %b %c %s %v %m %t hex octal decimal binary ASCII string strength module time t n %0d tab 换行 反斜杠 双引号 上述的ASCII表示 无前导0的十进制数格式符转义符显示信号值显示信号值$writewrite和和$strobestrobe$write与与$display相同,不同的是不会自动换行。相同,
9、不同的是不会自动换行。 $write($time, “%b t %h t %d t %o t”, sig1, sig2, sig3, sig4); $strobe与与$display相同,不同的是在仿真时间前进之前的信号值。相同,不同的是在仿真时间前进之前的信号值。而而$display和和$write立即显示信号值。也就是说立即显示信号值。也就是说$strobe显示稳定状态显示稳定状态信号值,而信号值,而$display和和$write可以显示信号的中间状态值。可以显示信号的中间状态值。 $strobe($time, “%b t %h t %d t %o t”, sig1, sig2, sig
10、3, sig4);$write和和$strobe都支持多种数基,缺省为十进制。都支持多种数基,缺省为十进制。$writeb$strobeb $writeo$strobeo $writeh$strobeh显示信号值显示信号值$writewrite和和$strobestrobe下面是模块下面是模块textio仿真的输出:仿真的输出:$writeb输出:输出: 0 xxxxxxxx x 注意注意data是是32位数据,由位数据,由8位十六位十六进制数表示。时间以没有前导零进制数表示。时间以没有前导零的十进制形式输出。的十进制形式输出。 缺省情况下,值以十进制显示,缺省情况下,值以十进制显示,忽略前导
11、零,与忽略前导零,与%0d格式符相同。格式符相同。可以在一个格式化符前插入一个可以在一个格式化符前插入一个0使使Verilog忽略开头的零。忽略开头的零。 $displayh: 00000000000000f 00000010 1 注意当前时间,一个注意当前时间,一个64位量,需位量,需要要16个十六进制的数。个十六进制的数。$display: 10 20$strobe: 10 30module textio; reg flag; reg 31: 0 data; initial begin $writeb(%d, $time, ,%h t, data, , flag, n); #15 flag
12、 = 1; data = 16; $displayh($time, ,data, , flag); end initial begin #10 data = 20; $strobe($time, , data); $display($time, , data); data = 30; endendmodule监视信号值监视信号值$monitormonitor$monitor持续监视参数列表中的变量。持续监视参数列表中的变量。在一个时间片中,参数表中任何信号发生变化,在一个时间片中,参数表中任何信号发生变化,$monitor将在仿真时将在仿真时间前进前显示参数表的信号值。间前进前显示参数表的信号
13、值。后面的后面的$monitor将覆盖前面的将覆盖前面的$monitor。可以用系统任务可以用系统任务$monitoron和和$monitoroff控制持续监视。控制持续监视。$monitor支持多种基数。缺省为十进制。支持多种基数。缺省为十进制。 $monitor ($ time, “%b t %h t %d t %o”, sig1, sig2, sig3, sig4);监示信号值监示信号值$monitormonitor$monitor是唯一的不断输出信号值的系统任务。其它系统任务在返回值之后是唯一的不断输出信号值的系统任务。其它系统任务在返回值之后就结束。就结束。$monitor和和$st
14、robe一样,显示参数列表中信号的稳定状态值,也就是在仿真一样,显示参数列表中信号的稳定状态值,也就是在仿真时间前进之前显示信号。在一个时间步中,参数列表中信号值的任何变化将时间前进之前显示信号。在一个时间步中,参数列表中信号值的任何变化将触发触发$monitor 。但。但$time,$stime,$realtime不能触发。不能触发。任何后续的任何后续的$monitor覆盖前面调用的覆盖前面调用的$monitor。只有新的。只有新的$monitor的参数列的参数列表中的信号被监视,而前面的表中的信号被监视,而前面的$monitor的参数则不被监视。的参数则不被监视。可以用可以用$monito
15、ron和和$monitoroff系统任务控制持续监视,使用户可以在仿真系统任务控制持续监视,使用户可以在仿真时只监视特定时间段的信号。时只监视特定时间段的信号。$monitor参数列表的形式与参数列表的形式与$display相同。相同。$monitor支持多种基数。缺省为十进制。支持多种基数。缺省为十进制。$monitorb$monitoro$monitorh文件输出文件输出$fopen打开一个文件并返回一个多通道描述符(打开一个文件并返回一个多通道描述符(MCD)。)。 MCD是与文件唯一对应的是与文件唯一对应的32位无符号整数。位无符号整数。 如果文件不能打开并进行写操作,如果文件不能打开
16、并进行写操作,MCD将等于将等于0。 如果文件成功打开,如果文件成功打开,MCD中的一位将被置位。中的一位将被置位。以以$f开始的显示系统任务将输出写入与开始的显示系统任务将输出写入与MCD相对应的文件中。相对应的文件中。 . . .integer MCD1; MCD1 = $fopen(); $fdisplay( MCD1, P1, P2, ., Pn); $fwrite( MCD1, P1, P2, ., Pn); $fstrobe( MCD1, P1, P2, ., Pn); $fmonitor( MCD1, P1, P2, ., Pn); $fclose( MCD1);. . .文件输
17、出文件输出$fopen打开参数中指定的文件并返回一个打开参数中指定的文件并返回一个32位无符号位无符号 整数整数MCD,MCD是与文件一一对应的多通道描述符。如果文件不能打开并进行是与文件一一对应的多通道描述符。如果文件不能打开并进行写操作,它返回写操作,它返回0。$fclose关闭关闭MCD指定的通道。指定的通道。输出信息到输出信息到log文件和标准输出的四个格式化显示任务文件和标准输出的四个格式化显示任务($display, $write, $monitor, $strobe)都有相对应的任务用于向指定文件输出。)都有相对应的任务用于向指定文件输出。这些对应的任务(这些对应的任务($fdi
18、splay,$fwrite,$fmonitor,$fstrobe)的参数形式)的参数形式与对应的任务相同,只有一个例外:第一个参数必须是一个指定向何与对应的任务相同,只有一个例外:第一个参数必须是一个指定向何哪个文件输出的哪个文件输出的MCD。MCD可以是一个表达式,但其值必须是一个可以是一个表达式,但其值必须是一个32位的无符号整数。这个值决定了该任务向哪个打开的文件写入位的无符号整数。这个值决定了该任务向哪个打开的文件写入。MCD可以看作由可以看作由32个标志构成的组,每个标志代表一个单一的输出个标志构成的组,每个标志代表一个单一的输出通道。通道。文件输出文件输出. . .integer
19、messages, broadcast, cpu_chann, alu_chann;initialbegin cpu_chann = $fopen( cpu.dat); if(! cpu_chann) $finish; alu_chann = $fopen( alu.dat); if(! alu_chann) $finish;/ channel to both cpu. dat and alu. dat messages = cpu_chann | alu_chann;/ channel to both files, standard out, and verilog. log broadca
20、st = 1 | messages;endalways ( posedge clock) / print the following to alu. dat $fdisplay( alu_chann, acc= %h f=%h a=%h b=%h, acc, f, a, b);/* at every reset print a message to alu. dat, cpu. dat, standard outputand the verilog. log file */always ( negedge reset) $fdisplay( broadcast, system reset at
21、 time %d, $time);. . .必须声明为integer通道0(编号为1)为标准输出及verilog.log文件输入文件输入Verilog中有两个系统任务可以将数据文件读入寄存器组。一个读取二进中有两个系统任务可以将数据文件读入寄存器组。一个读取二进制数据,另一个读取十六进制数据:制数据,另一个读取十六进制数据:$readmemb $readmemb (file_name, ); $readmemb (file_name, , ); $readmemb (file_name, , , );$readmemh $readmemh ( file_name, ); $readmemh (
22、 file_name, , ); $readmemh ( file_name, , , );文件输入文件输入系统任务系统任务$readmemb和和$readmemh从一个文本文件读取数据并写入存储器。从一个文本文件读取数据并写入存储器。如果数据为二进制,使用如果数据为二进制,使用$readmemb;如果数据为十六进制,使用;如果数据为十六进制,使用$readmemh。filename指定要调入的文件。指定要调入的文件。mem_name指定存储器名。指定存储器名。start和和finish决定存储器将被装载的地址。决定存储器将被装载的地址。Start为开始地址,为开始地址,finish为结束地为
23、结束地址。如果不指定开始和结束地址,址。如果不指定开始和结束地址,$readmem按从低端开始读入数据,与说按从低端开始读入数据,与说明顺序无关。明顺序无关。文件输入文件输入$readmemb和和$readmemh的文件格式的文件格式 : $readmemb(mem_file. txt, mema);0000_00000110_0001 0011_0010/ 地址地址3255没有定义没有定义100 / hex1111_1100/地址地址2571022没有定义没有定义3FF1110_0010文本文件:文本文件:mem_file.txt0000000000110000110011001031111
24、11002561110001010230 7声明的存储器组声明的存储器组reg 0:7 mema0:1023module readmem;reg 0:7 mema 0:1023initial$readmemb(“mem_file.txt”, mema);endmodule文件输入文件输入$readmemb和和$readmemh的文件格式的文件格式 : $readmemb(mem_file. txt, mema);可以指定二进制(可以指定二进制(b)或十六进制()或十六进制(h)数)数用下划线(用下划线(_)提高可读性。)提高可读性。可以包含单行或多行注释。可以包含单行或多行注释。可以用空格和换
25、行区分存储器字。可以用空格和换行区分存储器字。可以给后面的值设定一个特定的地址,格式为:可以给后面的值设定一个特定的地址,格式为: (hex_address) 十六进制地址的大小写不敏感。十六进制地址的大小写不敏感。 在在和数字之间不允许有空格。和数字之间不允许有空格。 复习复习问题:问题:哪个系统任务显示参数列表中信号的稳定状态值?哪个系统任务显示参数列表中信号的稳定状态值?每次能打开多少个输出文件?每次能打开多少个输出文件?解答:解答:系统任务系统任务$monitor和和$strobe显示参数列表中信号的稳定状态值。显示参数列表中信号的稳定状态值。这些任务在时间前进之前输出信号值。这些任务
26、在时间前进之前输出信号值。每次只能打开一个输出文件,包括已由仿真器打开的任何每次只能打开一个输出文件,包括已由仿真器打开的任何log文件。文件。第十五章第十五章 Verilog Test BenchVerilog Test Bench使用简介使用简介学习内容:学习内容:用一个复杂的用一个复杂的test bench复习设计的组织与仿真复习设计的组织与仿真建立建立test bench通常使用的编码风格及方法通常使用的编码风格及方法设计组织设计组织虚线表示编译时检测输入文件是否存在及可读并允许生成输出文件。 test benchtest bench组织组织简单的简单的test bench向要验证的设
27、计提供向量,人工验证输出。向要验证的设计提供向量,人工验证输出。复杂的复杂的test bench是自检测的,其结果自动验证。是自检测的,其结果自动验证。 stimulus要验证的设计简单的test bench复杂的test bench激励验证结果要验证的设计并行块并行块forkjoin块在测试文件中很常用。他们的并行特性使用户可以说明块在测试文件中很常用。他们的并行特性使用户可以说明绝对时间,并且可以并行的执行复杂的过程结构,如循环或任务。绝对时间,并且可以并行的执行复杂的过程结构,如循环或任务。module inline_ tb; reg 7: 0 data_ bus; / instance
28、 of DUT initial fork data_bus = 8b00; #10 data_bus = 8h45; #20 repeat (10) #10 data_bus = data_bus + 1; #25 repeat (5) #20 data_bus = data_bus 1; #140 data_bus = 8h0f; joinendmodule上面的两个repeat循环从不同时间开始,并行执行。象这样的特殊的激励集在单个的beginend块中将很难实现。 Time | data_ bus 0 | 8b0000_000010 | 8b0100_010130 | 8b0100_01
29、1040 | 8b0100_011145 | 8b1000_111050 | 8b1000_111160 | 8b1001_000065 | 8b0010_000070 | 8b0010_000180 | 8b0010_001085 | 8b0100_010090 | 8b0100_0101100 | 8b0100_0110105 | 8b1000_1100110 | 8b1000_1101120 | 8b1000_1110125 | 8b0001_1100140 | 8b0000_1111包含文件包含文件包含文件用于读入代码的重复部分或公共数据。包含文件用于读入代码的重复部分或公共数据。 m
30、odule clk_gen (clk);output clk; reg clk;include common.txtinitial begin while ($ time sim_end) begin clk = initial_clock; #(period/2) clk = !initial_clock; #(period/2); end $finish;endendmodule在上面的例子中,公共参数在一个独立的文件中定义。此文件在不同在上面的例子中,公共参数在一个独立的文件中定义。此文件在不同的仿真中可被不同的测试文件调用。的仿真中可被不同的测试文件调用。 / common. txt/
31、 clock and simulator constantsparameter initial_clock = 1;parameter period = 15;parameter max_cyc = 100;parameter sim_end = period * max_cyc施加激励施加激励产生激励并加到设计有很多产生激励并加到设计有很多 种方法。一些常用的方法有:种方法。一些常用的方法有:从一个从一个initial块中施加线激励块中施加线激励从一个循环或从一个循环或always块施加激励块施加激励从一个向量或整数数组施加激励从一个向量或整数数组施加激励记录一个仿真过程,然后在另一个仿真中
32、回放施加激励记录一个仿真过程,然后在另一个仿真中回放施加激励线性激励线性激励线性激励有以下特性:线性激励有以下特性: 只有变量的值改变时才列出只有变量的值改变时才列出 易于定义复杂的时序关系易于定义复杂的时序关系 对一个复杂的测试,测试基准对一个复杂的测试,测试基准(test bench)可能非常大可能非常大module inline_ tb; reg 7: 0 data_ bus, addr; wire 7: 0 results; DUT u1 (results, data_ bus, addr); initial fork data_bus = 8h00; addr = 8h3f; #10
33、 data_ bus = 8h45; #15 addr = 8hf0; #40 data_ bus = 8h0f; #60 $finish; joinendmodule循环激励循环激励从循环产生激励有以下特性:从循环产生激励有以下特性: 在每一次循环,修改同一组激励变量在每一次循环,修改同一组激励变量 时序关系规则时序关系规则 代码紧凑代码紧凑 module loop_tb; reg clk; reg 7:0 stimulus; wire 7:0 results; integer i; DUT u1 (results, stimulus); always begin / clock gener
34、ation clk = 1; #5 clk = 0; #5 end initial begin for (i = 0; i 1; i = i - 1) / 循环循环 #50 stimulus = stim_arrayi ; #30 $finish; endendmodule矢量采样矢量采样在仿真过程中可以对激励和响应矢量进行采样,作为其它仿真的激在仿真过程中可以对激励和响应矢量进行采样,作为其它仿真的激励和期望结果。励和期望结果。module capture_tb; parameter period = 20 reg 7:0 in_vec, out_vec; integer RESULTS,
35、STIMULUS; DUT u1 (out_ vec, in_ vec); initial begin STIMULUS = $fopen(stimulus. txt) ; RESULTS = $fopen(results. txt) ; fork if (STIMULUS != 0 ) forever #( period/2) $fstrobeb (STIMULUS, %b, in_vec); if (RESULTS != 0 ) #( period/2) forever #( period/2) $fstrobeb (RESULTS, %b, out_vec); join endendmo
36、dule矢量回放矢量回放保存在文件中的矢量反过来可以作为激励保存在文件中的矢量反过来可以作为激励module read_file_tb; parameter num_vecs = 256; reg 7:0 data_bus; reg 7:0 stim num_vecs-1:0; integer i; DUT u1 (results, data_bus) initial begin / Vectors are loaded $readmemb (vec. txt, stim); for (i =0; i num_vecs ; i = i + 1) #50 data_bus = stimi; en
37、dendmodule/ 激励文件激励文件vec.txt001110000011100100111010001111000011000000101000000110000111100010111000.使用矢量文件输入使用矢量文件输入/输出的优点:输出的优点: 激励修改简单激励修改简单 设计反复验证时直接使用工具比较矢量文件。设计反复验证时直接使用工具比较矢量文件。错误及警告报告错误及警告报告使用文本或文件输出类的系统任务报告错误及警告使用文本或文件输出类的系统任务报告错误及警告always ( posedge par_err) $display ( error-bus parity error
38、s detected);always ( posedge cor_err) $display(warning-correctable error detected);一个更为复杂的一个更为复杂的test bench可以:可以: 不但能报告错误,而能进行一些动作,如取消一个激励块并跳转不但能报告错误,而能进行一些动作,如取消一个激励块并跳转到下一个激励。到下一个激励。 在内部保持错误跟踪,并在每次测试结束时产生一个错误报告。在内部保持错误跟踪,并在每次测试结束时产生一个错误报告。强制激励强制激励在过程块中,可以用两种持续赋值语句驱动一个值或表达式到一个信号。在过程块中,可以用两种持续赋值语句驱动
39、一个值或表达式到一个信号。 过程持续赋值通常不可综合,所以它们通常用于测试基准描述。过程持续赋值通常不可综合,所以它们通常用于测试基准描述。 对每一种持续赋值,都有对应的命令停止信号赋值。对每一种持续赋值,都有对应的命令停止信号赋值。 不允许在赋值语句内部出现时序控制。不允许在赋值语句内部出现时序控制。对一个寄存器使用对一个寄存器使用assign和和deassign,将覆盖所有其他在该信号上的赋值。,将覆盖所有其他在该信号上的赋值。这个寄存器可以是这个寄存器可以是RTL设计中的一个节点或测试基准中在多个地方赋值的设计中的一个节点或测试基准中在多个地方赋值的信号等。信号等。 initial be
40、gin #10 assign top.dut.fsm1.state_reg = init_state ; #20 deassign top.dut.fsm1.state_reg ; end在在register和和net上(例如一个门级扫描寄存器的输出)使用上(例如一个门级扫描寄存器的输出)使用force和和release,将覆盖该信号上的所有其他驱动。将覆盖该信号上的所有其他驱动。 initial begin #10 force top. dut. counter. scan_ reg. q = 0 ; #20 release top. dut. counter. scan_ reg. q ;
41、 end强制激励强制激励可以强制可以强制(force)并释放一个信号的指定位、部分位或连接,但位的指定不能并释放一个信号的指定位、部分位或连接,但位的指定不能是一个变量(例如是一个变量(例如out_veci)不能对不能对register的一位或部分位使用的一位或部分位使用assign和和deassign对同一个信号,对同一个信号,force覆盖覆盖assign。后面的后面的assign或或force语句覆盖以前相同类型的语句。语句覆盖以前相同类型的语句。如果对一个信号先如果对一个信号先assign然后然后force,它将保持,它将保持force值。在对其进行值。在对其进行release后,后,
42、信号为信号为assign值。值。如果在一个信号上如果在一个信号上force多个值,然后多个值,然后release该信号,则不出现任何该信号,则不出现任何force值。值。 在上面两个例子中,在在上面两个例子中,在 net或或register上所赋的常数值,覆盖所有在时刻上所赋的常数值,覆盖所有在时刻10和时刻和时刻20之间可能发生在该信号上的其他任何赋值或驱动。如果所赋值是一个表达式,之间可能发生在该信号上的其他任何赋值或驱动。如果所赋值是一个表达式,则该表达式将被持续计算。则该表达式将被持续计算。建立时钟建立时钟例例1:虽然有时候在设计中给出时钟,但通常时钟是测试基准中建立。:虽然有时候在设
43、计中给出时钟,但通常时钟是测试基准中建立。下面介绍如何产生不同的时钟波形。同时给出用门级和行为级描述方法下面介绍如何产生不同的时钟波形。同时给出用门级和行为级描述方法下面是一个简单对称时钟的例子:下面是一个简单对称时钟的例子: reg ck;always begin #( period/2) ck = 0; #( period/2) ck = 1;endreg go; wire ck;nand #( period/2) u1 (ck, ck, go);initial begin go = 0; #( period/2) go = 1;end注意:注意:在一些仿真器中,时钟与设计使用相同的抽象级
44、描述时,仿真性能会好一些。 产生的波形(假定产生的波形(假定period为为20)建立时钟建立时钟例例2:有启动延时的对称时钟的例子:有启动延时的对称时钟的例子:reg ck;initial begin ck = 0; #( period) forever #( period/2) ck = !ck;endreg go; wire ck;nand #( period/2) u1 (ck, ck, go);initialbegin go = 0; #(period) go = 1;end注意:注意:在行为描述中,在时间0将CK初始化为0;而在结构描述中,直到period/2才影响CK值。当go信
45、号在时间0初始化时,CK值到period/2才变化。可以使用特殊命令force和release立即影响CK值。产生的波形(假定产生的波形(假定period为为20)建立时钟建立时钟例例3:有不规则启动延时的不对称时钟的例子:有不规则启动延时的不对称时钟的例子:注意:注意:在行为描述中,CK值立刻被影响;而在结构描述中,在传播延时后才输出正确波形。产生的波形(假定产生的波形(假定period为为20)reg ck;initial begin #(period + 1) ck = 1; #(period/2 1) forever begin #(period/4) ck = 0; #(3*peri
46、od/4) ck = 1; endendreg go; wire ck;nand #(3*period/4, period/4) u1(ck, ck, go);initial begin #(period/4 + 1) go = 0; #(5*period/4 1) go = 1;end使用使用tasktask在在test bench中使用中使用task可以压缩重复操作,提高代码效率。可以压缩重复操作,提高代码效率。module bus_ctrl_tb; reg 7: 0 data; reg data_valid, data_rd; cpu u1 (data_valid, data,data_
47、rd); initial begin cpu_driver (8b0000_0000); cpu_driver (8b1010_1010); cpu_driver (8b0101_0101); end task cpu_driver; input 7:0 data_in; begin #30 data_valid = 1; wait (data_rd = 1); #20 data = data_ in; wait (data_rd = 0); #20 data = 8hzz; #30 data_valid = 0; end endtaskendmodule 使用使用tasktask产生的波形产
48、生的波形复习复习问题:问题:什么操作可以容易的在什么操作可以容易的在forkjoin块做到,而不容易在块做到,而不容易在beginend块做到?块做到?通常怎样产生规则激励和不规则激励?通常怎样产生规则激励和不规则激励?从一个文件中读取激励时使用什么数据类型?从一个文件中读取激励时使用什么数据类型?在行为级时钟模型中能做哪些在门级时钟模型中很难或不能作到的事?在行为级时钟模型中能做哪些在门级时钟模型中很难或不能作到的事? 解答:解答:forkjoin块中不但能够赋值,还可以并行执行循环、条件语句、任务或函块中不但能够赋值,还可以并行执行循环、条件语句、任务或函数调用。数调用。循环或循环或alw
49、ays块能有效地产生规则激励,不规则激励适合用在块能有效地产生规则激励,不规则激励适合用在initial块产生。块产生。用寄存器组(存储器)并用用寄存器组(存储器)并用$readmem系统任务从一个文件以读取向量。系统任务从一个文件以读取向量。行为级代码可以很容易地产生一个启动时间不规则的时钟波形,并且可以行为级代码可以很容易地产生一个启动时间不规则的时钟波形,并且可以在时刻零初始化时钟。在时刻零初始化时钟。 第第1616章章 存储器建模存储器建模学习内容学习内容: 如何描述存储器如何描述存储器 如何描述双向端口如何描述双向端口存储器件建模存储器件建模描述存储器必须做两件事:描述存储器必须做两
50、件事: 说明一个适当容量的存储器。说明一个适当容量的存储器。 提供内容访问的级别,例如:提供内容访问的级别,例如: 只读只读 读和写读和写 写同时读写同时读 多个读操作,同时进行单个写操作多个读操作,同时进行单个写操作 同时有多个读和多个写操作,有保证一致性的方法同时有多个读和多个写操作,有保证一致性的方法简单简单ROMROM描述描述 下面的下面的ROM描述中使用二维寄存器组定义了一个存储器描述中使用二维寄存器组定义了一个存储器mem。ROM的数的数据单独保存在文件据单独保存在文件my_rom_data中,如右边所示。通常用这种方法使中,如右边所示。通常用这种方法使ROM数据独立于数据独立于R