verilog系统函数.doc_第1页
verilog系统函数.doc_第2页
verilog系统函数.doc_第3页
verilog系统函数.doc_第4页
verilog系统函数.doc_第5页
已阅读5页,还剩19页未读 继续免费阅读

下载本文档

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

文档简介

Verilog中常用的系统函数(2011-12-06 14:54:39) 转载标签: 杂谈分类: FPGA的研究 Verilog HDL常用的系统任务1.$display(,);/显示变量的值或变量的范围,自动加换行如:$display(“dout=%d dout”,dout);2.$write();/和上面的用法相同,但是不会自动加换行3.$monitor(,);/在多模块调试的情况下,许多模块中都调用了$monitor,因为任何时刻只能有一个$monitor起作用,因此需配合$monitoron与$monitoroff使用,把需要监视的模块用$monitoron打开,在监视完毕后及时用$monitoroff关闭,以便把$monitor 让给其他模块使用。$monitor与$display的不同处还在于$monitor往往在initial块中调用,只要不调用$monitoroff,$monitor便不间断地对所设定的信号进行监视。4.$time系统函数:返回64位的整数来表示当前的仿真时刻; $realtime系统函数:返回一个实型数表示当前仿真时刻。都以模块的仿真时间尺度为基准。5.$monitor($realtime,set=%b,set);/其中一个用法5.系统任务$finish:退出仿真器,返回操作系统6.系统任务$stop:暂停仿真器7.系统任务$random:$random%b或者$random%b8.系统任务$readmemb和$readmemh:用于从文件中读取数据到寄存器中,任何时候都可以被执行(数据方向:文件寄存器);有以下用法:1) $readmemb(,);2) $readmemb(,);3) $readmemb(,);4) $readmemh(,);5) $readmemh(,);6) $readmemh(,);其中文件中的地址表示方式hhhh-hh,但是寄存器中的地址可直接用数表示。这里说的地址均是寄存器的地址。9.显示层次任务:$display(Dispalying in %m);/可以显示正在仿真的位置10.选通显示:$strobe(,);/可以保证当所有的赋值语句完成之后才进行显示,同步机制。11.值变转储任务:将调试过程中感兴趣的信号转存到VCD文件中的任务。$dumpfile();/ 选择转储的VCD文件$dumpvars();/ 选择需要存储的VCD变量范围$dumpall;/建立一个监测点,转储当前所有VCD变量的现行值$dumpon;和$dumpoff;/控制转储的开始和结束,可用时间延时控制转储过程。1激励的设置相应于被测试模块的输入激励设置为reg型,输出相应设置为wire类型,双向端口inout在测试中需要进行处理。方法1:为双向端口设置中间变量inout_reg作为该inout的输出寄存,inout口在testbench中要定义为wire型变量,然后用输出使能控制传输方向。eg:inout 0:0 bi_dir_port;wire 0:0 bi_dir_port;reg 0:0 bi_dir_port_reg;reg bi_dir_port_oe;assign bi_dir_port=bi_dir_port_oe?bi_dir_port_reg:1bz;用bi_dir_port_oe控制端口数据方向,并利用中间变量寄存器改变其值。等于两个模块之间用inout双向口互连。往端口写(就是往模块里面输入)方法2:使用force和release语句,这种方法不能准确反映双向端口的信号变化,但这种方法可以反映块内信号的变化。具体如示:module test();wire data_inout;reg data_reg;reg link;#xx; /延时force data_inout=1bx; /强制作为输入端口.#xx;release data_inout; /释放输入端口endmodule从文本文件中读取和写入向量1)读取文本文件:用 $readmemb系统任务从文本文件中读取二进制向量(可以包含输入激励和输出期望值)。$readmemh 用于读取十六进制文件。例如:reg 7:0 mem1:256 / a 8-bit, 256-word 定义存储器meminitial $readmemh ( mem.data, mem ) / 将.dat文件读入寄存器mem中initial $readmemh ( mem.data, mem, 128, 1 ) / 参数为寄存器加载数据的地址始终2)输出文本文件:打开输出文件用?$fopen 例如:integer out_file; / out_file 是一个文件描述,需要定义为 integer类型out_file = $fopen ( cpu.data ); / cpu.data 是需要打开的文件,也就是最终的输出文本设计中的信号值可以通过$fmonitor, $fdisplay,2. Verilog和Ncverilog命令使用库文件或库目录ex). ncverilog -f run.f -v lib/lib.v -y lib2 +libext+.v /一般编译文件在run.f中, 库文件在lib.v中,lib2目录中的.v文件系统自动搜索使用库文件或库目录,只编译需要的模块而不必全部编译3Verilog Testbench信号记录的系统任务:1). SHM数据库可以记录在设计仿真过程中信号的变化. 它只在probes有效的时间内记录你set probe on的信号的变化.ex). $shm_open(waves.shm); /打开波形数据库$shm_probe(top, AS); / set probe on top,第二个参数: A - signals of the specific scrope S - Ports of the specified scope and below, excluding library cellsC - Ports of the specified scope and below, including library cellsAS - Signals of the specified scope and below, excluding library cellsAC - Signals of the specified scope and below, including library cells还有一个 M ,表示当前scope的memories, 可以跟上面的结合使用, AM AMS AMC什么都不加表示当前scope的ports;$shm_close /关闭数据库2). VCD数据库也可以记录在设计仿真过程中信号的变化. 它只记录你选择的信号的变化.ex). $dumpfile(filename); /打开数据库$dumpvars(1, top.u1); /scope = top.u1, depth = 1第一个参数表示深度, 为0时记录所有深度; 第二个参数表示scope,省略时表当前的scope.$dumpvars; /depth = all scope = all$dumpvars(0); /depth = all scope = current$dumpvars(1, top.u1); /depth = 1 scope = top.u1$dumpoff /暂停记录数据改变,信号变化不写入库文件中$dumpon /重新恢复记录3). Debussy fsdb数据库也可以记录信号的变化,它的优势是可以跟debussy结合,方便调试.如果要在ncverilog仿真时,记录信号, 首先要设置debussy:a. setenv LD_LIBRARY_PATH :$LD_LIBRARY_PATH(path for debpli.so file (/share/PLI/nc_xl/nc_loadpli1)b. while invoking ncverilog use the +ncloadpli1 option.ncverilog -f run.f +debug +ncloadpli1=debpli:deb_PLIPtrfsdb数据库文件的记录方法,是使用$fsdbDumpfile和$fsdbDumpvars系统函数,使用方法参见VCD注意: 在用ncverilog的时候,为了正确地记录波形,要使用参数: +access+rw, 否则没有读写权限在记录信号或者波形时需要指出被记录信号的路径,如:tb.module.u1.clk.关于信号记录的系统任务的说明:在testbench中使用信号记录的系统任务,就可以将自己需要的部分的结果以及波形文件记录下来(可采用sigalscan工具查看),适用于对较大的系统进行仿真,速度快,优于全局仿真。使用简单,在testbench中添加:initial begin$shm_open(waves.shm);$shm_probe(要记录信号的路径“,”AS“);10000$shm_close; 即可。 4. ncverilog编译的顺序: ncverilog file1 file2 .有时候这些文件存在依存关系,如在file2中要用到在file1中定义的变量,这时候就要注意其编译的顺序是从后到前,就先编译file2然后才是file2.5. 信号的强制赋值force首先, force语句只能在过程语句中出现,即要在initial 或者 always 中间. 去除force 用 release 语句.initial begin force sig1 = 1b1; . ; release sig1; endforce可以对wire赋值,这时整个net都被赋值; 也可以对reg赋值.6加载测试向量时,避免在时钟的上下沿变化为了模拟真实器件的行为,加载测试向量时,避免在时钟的上下沿变化,而是在时钟的上升沿延时一个时间单位后,加载的测试向量发生变化。如:assign #5 c=ab(posedge clk) #(0.1*cycle) A=1;*/testbench的波形输出module top;.initialbegin$dumpfile(./top.vcd); /存储波形的文件名和路径,一般是.vcd格式.$dumpvars(1,top); /存储top这一层的所有信号数据$dumpvars(2,top.u1); /存储top.u1之下两层的所有数据信号(包含top.u1这一层)$dumpvars(3,top.u2); /存储top.u2之下三层的所有数据信号(包含top.u2这一层)$dumpvars(0,top.u3); /存储top.u3之下所有层的所有数据信号endendmodule/产生随机数,seed是种子$random(seed);ex: din Y) = 0.2;(B*-Y) = 0.3;(C*-Y) = 0.1;endspecifyendmodule/时间刻度timescale 单位时间/时间精确度/文件I/O1.打开文件integer file_id;file_id = fopen(file_path/file_name);2.写入文件/$fmonitor只要有变化就一直记录$fmonitor(file_id, %format_char, parameter);eg:$fmonitor(file_id, %m: %t in1=%d o1=%h, $time, in1, o1);/$fwrite需要触发条件才记录$fwrite(file_id, %format_char, parameter);/$fdisplay需要触发条件才记录$fdisplay(file_id, %format_char, parameter);$fstrobe();3.读取文件integer file_id;file_id = $fread(file_path/file_name, r);4.关闭文件$fclose(fjile_id);5.由文件设定存储器初值$readmemh(file_name, memory_name); /初始化数据为十六进制$readmemb(file_name, memory_name); /初始化数据为二进制/仿真控制$finish(parameter); /parameter = 0,1,2$stop(parameter);/读入SDF文件$sdf_annotate(sdf_file_name, module_instance, scale_factors);/module_instance: sdf文件所对应的instance名./scale_factors:针对timming delay中的最小延时min,典型延迟typ,最大延时max调整延迟参数/generate语句,在Verilog-2001中定义.用于表达重复性动作/必须事先声明genvar类型变量作为generate循环的指标eg:genvar i;generate for(i = 0; i 4; i = i + 1)beginassign = dini = i % 2;endendgenerate/资源共享always (A or B or C or D)sum = sel ? (A+B):(C+D);/上面例子使用两个加法器和一个MUX,面积大/下面例子使用一个加法器和两个MUX,面积小always (A or B or C or D)begintmp1 = sel ? A:C;tmp2 = sel ? B:D;endalways (tmp1 or tmp2)sum = tmp1 + tmp2;*模板:module testbench; /定义一个没有输入输出的modulereg /将DUT的输入定义为reg类型wire /将DUT的输出定义为wire类型/在这里例化DUTinitialbegin /在这里添加激励(可以有多个这样的结构)endalways /通常在这里定义时钟信号initial/在这里添加比较语句(可选)endinitial/在这里添加输出语句(在屏幕上显示仿真结果)endendmodule一下介绍一些书写Testbench的技巧:1.如果激励中有一些重复的项目,可以考虑将这些语句编写成一个task,这样会给书写和仿真带来很大方便。例如,一个存储器的testbench的激励可以包含write,read等task。2.如果DUT中包含双向信号(inout),在编写testbench时要注意。需要一个reg变量来表示其输入,还需要一个wire变量表示其输出。3.如果initial块语句过于复杂,可以考虑将其分为互补相干的几个部分,用数个initial块来描述。在仿真时,这些initial块会并发运行。这样方便阅读和修改。4.每个testbench都最好包含$stop语句,用以指明仿真何时结束。最后提供一个简单的示例(转自Xilinx文档):DUT:module shift_reg (clock, reset, load, sel, data, shiftreg);input clock;input reset;input load;input 1:0 sel;input 4:0 data;output 4:0 shiftreg;reg 4:0 shiftreg;always (posedge clock)beginif (reset)shiftreg = 0;else if (load)shiftreg = data;elsecase (sel)2b00 : shiftreg = shiftreg;2b01 : shiftreg = shiftreg 1;default : shiftreg = shiftreg;endcaseendendmoduleTestbench:module testbench; / declare testbench namereg clock;reg load;reg reset; / declaration of signalswire 4:0 shiftreg;reg 4:0 data;reg 1:0 sel;/ instantiation of the shift_reg design belowshift_reg dut(.clock (clock),.load (load),.reset (reset),.shiftreg (shiftreg),.data (data),.sel (sel);/this process block sets up the free running clockinitial beginclock = 0;forever #50 clock = clock;endinitial begin/ this process block specifies the stimulus.reset = 1;data = 5b00000;load = 0;sel = 2b00;#200reset = 0;load = 1;#200data = 5b00001;#100sel = 2b01;load = 0;#200sel = 2b10;#1000 $stop;endinitial begin/ this process block pipes the ASCII results to the/terminal or text editor$timeformat(-9,1,ns,12);$display( Time Clk Rst Ld SftRg Data Sel);$monitor(%t %b %b %b %b %b %b, $realtime,clock, reset, load, shiftreg, data, sel);endendmoduleposted 2009-10-28 11:24 神一样驴子 阅读(508) 评论(1) 编辑 (转)verilog 中文件输入输出任务全文地址:/blog/static/111127004200982725032948/系统函数fopen用于打开一个文件,并还回一个整数指针然后,fdisplay就可以使用这个文件指针在文件中写入信息,写完后,则可以使用fclose系统关闭这个文件例如:integer write_out_file;定义一个文件指针integer write_out_file=$fopen(write_out_file.txt);$fdisplay(write_out_file,%hnh,addr,data);fclose(write_out_file);以上语法是将addr,data分别显示在%hnh中的个h的位置,并写入write_out_file文件指针所指向的write_out_file.txt中从文件中读取数据,可以用 $readmemb $readmemh从文件中读入数据,该文件格式是一定的reg:data:;$readmemh(file_nametxt,data );就是将file_nametxt中的数据读入到data数组中,然后就可以使用这些数据了 还有一种方式可以把指定的数据放入指定的存储器地址单元内,就是在存放数据的文本文件内,给相应的数据规定其内存地址,形式如下:address_in_hexadecimal data2f20两个系统任务可以在仿真的任何时刻被执行使用,其使用格式共有以下六种: 1) $readmemb(,); 2) $readmemb(,); 3) $readmemb(,); 4) $readmemh(,); 5) $readmemh(,); 6) $readmemh(,);在这两个系统任务中,被读取的数据文件的内容只能包含:空白位置(空格,换行,制表格(tab)和form-feeds),注释行(/形式的和/*.*/形式的都允许),二进制或十六进制的数字。数字中不能包含位宽说明和格式说明,对于$readmemb系统任务,每个数字必须是二进制数字,对于$readmemh系统任务,每个数字必须是十六进制数字。数字中不定值x或X,高阻值z或Z,和下划线(_)的使用方法及代表的意义与一般Verilog HDL程序中的用法及意义是一样的。另外数字必须用空白位置或注释行来分隔开。在下面的讨论中,地址一词指对存贮器(memory)建模的数组的寻址指针。当数据文件被读取时,每一个被读取的数字都被存放到地址连续的存贮器单元中去。存贮器单元的存放地址范围由系统任务声明语句中的起始地址和结束地址来说明,每个数据的存放地址在数据文件中进行说明。当地址出现在数据文件中,其格式为字符“”后跟上十六进制数。如:hh.h对于这个十六进制的地址数中,允许大写和小写的数字。在字符“”和数字之间不允许存在空白位置。可以在数据文件里出现多个地址。当系统任务遇到一个地址说明时,系统任务将该地址后的数据存放到存贮器中相应的地址单元中去。对于上面六种系统任务格式,需补充说明以下五点:1) 如果系统任务声明语句中和数据文件里都没有进行地址说明,则缺省的存放起始地址为该存贮器定义语句中的起始地址。数据文件里的数据被连续存放到该存贮器中,直到该存贮器单元存满为止或数据文件里的数据存完。2) 如果系统任务中说明了存放的起始地址,没有说明存放的结束地址,则数据从起始地址开始存放,存放到该存贮器定义语句中的结束地址为止。3) 如果在系统任务声明语句中,起始地址和结束地址都进行了说明,则数据文件里的数据按该起始地址开始存放到存贮器单元中,直到该结束地址,而不考虑该存贮器的定义语句中的起始地址和结束地址。4) 如果地址信息在系统任务和数据文件里都进行了说明,那么数据文件里的地址必须在系统任务中地址参数声明的范围之内。否则将提示错误信息,并且装载数据到存贮器中的操作被中断。5) 如果数据文件里的数据个数和系统任务中起始地址及结束地址暗示的数据个数不同的话,也要提示错误信息。下面举例说明:先定义一个有256个地址的字节存贮器 mem:reg7:0 mem1:256;下面给出的系统任务以各自不同的方式装载数据到存贮器mem中。initial $readmemh(mem.data,mem);initial $readmemh(mem.data,mem,16);initial $readmemh(mem.data,mem,128,1);第一条语句在仿真时刻为0时,将装载数据到以地址是1的存贮器单元为起始存放单元的存贮器中去。第二条语句将装载数据到以单元地址是16的存贮器单元为起始存放单元的存贮器中去,一直到地址是256的单元为止。第三条语句将从地址是128的单元开始装载数据,一直到地址为1的单元。在第三种情况中,当装载完毕,系统要检查在数据文件里是否有128个数据,如果没有,系统将提示错误信息。 引用参考1.打开文件integer file_id;file_id = fopen(file_path/file_name);2.写入文件/$fmonitor只要有变化就一直记录$fmonitor(file_id, %format_char, parameter);eg:$fmonitor(file_id, %m: %t in1=%d o1=%h, $time, in1, o1);/$fwrite需要触发条件才记录$fwrite(file_id, %format_char, parameter);/$fdisplay需要触发条件才记录$fdisplay(file_id, %format_char, parameter);$fstrobe();3.读取文件integer file_id;file_id = $fread(file_path/file_name, r);4.关闭文件$fclose(fjile_id);5.由文件设定存储器初值$readmemh(file_name, memory_name); /初始化数据为十六进制$readmemb(file_name, memory_name); /初始化数据为二进制转:/logs/19569780.htmlVerilog 提供了丰富的系统函数,这为Testbench的编写提供了方便。尤其是IEEE1364-2005,其系统级建模的能力更强。 以前我一般常用到的系统函数只有几个:$readmemb,$readmemh,$display,$fmonitor,$fwrite,$fopen,$fclose等。通常需要对文件作预处理,才能用于Testbench读取。今天又尝试了几个其他的文件输入输出函数,不需要对文件进行预处理,直接使用需要的文件,只对需要的部分进行读取。 $fseek,文件定位,可以从任意点对文件进行操作; $fscanf,对文件一行进行读写。 下面是一些常见的应用: 1、读写文件timescale 1 ns/1 nsmodule FileIO_tb;integer fp_r, fp_w, cnt;reg 7:0 reg1, reg2, reg3;initial begin fp_r = $fopen(data_in.txt, r); fp_w = $fopen(data_out.txt, w); while(!$feof(fp_r) begin cnt = $fscanf(fp_r, %d %d %d, reg1, reg2, reg3); $display(%d %d %d, reg1, reg2, reg3); $fwrite(fp_w, %d %d %dn, reg3, reg2, reg1); end $fclose(fp_r); $fclose(fp_w);endendmodule 2、integer file, char;reg eof; initial begin file = $fopenr(myfile.txt); eof = 0; while (eof = 0) begin char = $fgetc(file); eof = $feof (file); $display (%s, char);endend 3、文件处理定位define SEEK_SET 0define SEEK_CUR 1define SEEK_END 2integer file, offset, position, r;r = $fseek(file, 0, SEEK_SET); /* Beginning */r = $fseek(file, 0, SEEK_CUR); /* No effect */r = $fseek(file, 0, SEEK_END); /* End of file */r = $fseek(file, position, SEEK_SET); /* Previous loc */ 4、integer r, file, start, count;reg 15:0 mem0:10, r16;r = $fread(file, mem0, start, count);r = $fread(file, r16); 5、integer file, position;position = $ftell(file); 6、integer file, r, a, b;reg 80*8:1 string;file = $fopenw(output.log);r = $sformat(string, Formatted %d %x, a, b);r = $sprintf(string, Formatted %d %x, a, b);r = $fprintf(file, Formatted %d %x, a, b); 7、integer file, r;file = $fopenw(output.log);r = $fflush(file); 8、/ This is a pattern file - read_pattern.pat / time bin dec hex10: 001 1 120.0: 010 20 02050.02: 111 5 FFF62.345: 100 4 DEADBEEF75.789: XXX 2 ZzZzZzZztimescale 1ns / 10 psdefine EOF 32hFFFF_FFFFdefine NULL 0define MAX_LINE_LENGTH 1000module read_pattern;integer file, c, r;reg 3:0 bin;reg 31:0 dec, hex;real real_time;reg 8*MAX_LINE_LENGTH:0 line; /* Line of text read from file */initial begin : file_block $timeformat(-9, 3, ns, 6); $display(time bin decimal hex); file = $fopenr(read_pattern.pat); if (file = NULL) / If error opening file disable file_block; / Just quit c = $fgetc(file); while (c != EOF) begin /* Check the first character for comment */ if (c = /) r = $fgets(line, MAX_LINE_LENGTH, file); else begin / Push the character back to the file then read the next time r = $ungetc(c, file); r = $fscanf(file, %f:n, real_time); / Wait until the absolute time in the file, then read stimulus if ($realtime real_time) $display(Error - absolute time in file is out of order - %t, real_time); else #(real_time - $realtime) r = $fscanf(file, %b %d %hn,bin,dec,

温馨提示

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

评论

0/150

提交评论