Verilog 系统函数介绍

1      $display

    这个函数系统任务的作用是用来在控制台输出信息。

    1)  直接显示字符串

$display("!!! Start  Simulation !!!"); 
  
  

    2) 显示data_display 的16进制 ,10进制

$display("data_display = %h hex %d decimal", 100, 100);
  
  

    3)  显示data_display 的8进制   2进制

$display("data_display = %o otal %b binary",100, 100);
  
  

    4) 主要展示换行操作

$display("data_display = %d otal next line \n %b binary", 100, 100);
  
  

    5)  显示系统仿真时间

$display("simulation time is %t",$time);
  
  

    具体代码如下:


  
  
  1. reg flag;
  2. //--------------------------------------------------------------------------------
  3. //****************************** 系统显示 $display *******************************
  4. reg [ 31: 0] data_display;
  5. initial
  6. begin
  7. data_display = 32'd100;
  8. flag = 0;
  9. $display( "!!! Start Simulation !!!");
  10. # 10;
  11. //显示16进制 10进制
  12. $display( "data_display = %h hex %d decimal", 100, 100);
  13. # 10;
  14. //显示8进制 2进制
  15. $display( "data_display = %o otal %b binary", 100, 100);
  16. # 10;
  17. //ASCII码
  18. $display( "data_display has %c ascii character value", 64);
  19. # 10;
  20. //显示10进制 换行 2进制
  21. $display( "data_display = %d otal next line \n %b binary", 100, 100);
  22. # 10
  23. //显示系统仿真时间
  24. $display( "simulation time is %t",$time);
  25. flag = 1;
  26. end

        结果显示:

        在第五行展示了换行功能;为了验证系统仿真时间,笔者这边用flag参数拉高来测试时间,时间结果如下图显示,和显示时间一致;

2      $fopen

        用法:<文件句柄>=$fopen("<文件名>");

       句柄就是任务$fopen返回的多通道描述符,默认为32位,最低位(第0位)默认被设置1,默认开放标准输出通道,即transcript窗口。

        每一次使用$fopen函数后都打开了一个新的通道,并且返回了一个设置为1的位相对应。默认应该是0001,以上每调用分别设置为0010 ,0100,1000(只考虑最低四位)。

3     $fscanf

函数功能,读取txt(.dat)文件数据,具体代码如下:


  
  
  1. //****************************** 读文件 $fscanf *******************************
  2. //宏定义,定义数据长度
  3. `define DATA_LENGTH 8
  4. //定义RAM大小
  5. reg signed [ 15: 0] Sig0 [`DATA_LENGTH -1: 0];
  6. reg [ 15: 0] Sig1 [`DATA_LENGTH -1: 0];
  7. //定义句柄
  8. integer data_file0;
  9. integer data_file1;
  10. integer i;
  11. //读取函数
  12. initial
  13. begin
  14. # 200;
  15. //打开句柄
  16. data_file0 = $fopen( "file/rd_data0_fpga.txt", "r");
  17. data_file1 = $fopen( "file/rd_data1_fpga.txt", "r");
  18. for(i = 0;i < `DATA_LENGTH; i = i + 1)
  19. begin
  20. $ fscanf(data_file0, "%d",Sig0[i]); //读取十进制
  21. $ fscanf(data_file1, "%h",Sig1[i]); //读取十六进制
  22. end
  23. $fclose(data_file0); ////关闭这个句柄
  24. $fclose(data_file1); ////关闭这个句柄
  25. end

        结果显示如下:

        红色(蓝色)箭头右边modesim中是读取的数据,txt中是原始数据;

4      $fwrite ($fdisplay)

        函数功能,将数据写入到txt文件中(与fscanf正好相反)   。

        $fwrite和$fdisplay的区别,$fwrite写下一个数不会自动转行,可以加\n来转行,$fdisplay则会自动转行。这里只介绍$fwrite了,$fdisplay和$fwrite基本一样的写法。

        代码如下:


  
  
  1. //****** $fwrite 写下一个数不会自动转行,所以要加\n
  2. //将读取的Sig0,Sig1重新写进两个新的txt中
  3. //定义句柄
  4. integer data_wr0;
  5. integer data_wr1;
  6. integer m;
  7. //读取函数
  8. initial
  9. begin
  10. # 400;
  11. //打开句柄
  12. data_wr0 = $fopen( "file/wr_data1_fpga.txt", "w");
  13. data_wr1 = $fopen( "file/wr_data2_fpga.txt", "w");
  14. for(m = 0;m < `DATA_LENGTH; m = m + 1)
  15. begin
  16. @(clk);
  17. $fwrite(data_wr0, "%d\n",Sig0[m]); //向txt写十进制 写下一个数不会自动转行,所以要加\n
  18. $fwrite(data_wr1, "%h\n",Sig1[m]); //向txt写十六进制 写下一个数不会自动转行,所以要加\n
  19. end
  20. //关闭这个句柄
  21. $fclose(data_wr0);
  22. $fclose(data_wr1);
  23. end

            结果展示:
 

        左边箭头所指的数据是待写入txt的数据,右边竖线部分是实际写入到txt的数据。

        注意!!! 笔者刚发现一个规律,就是定义(reg  signed [15:0]    Sig;)这个信号的时候

    如果写成:    $fclose(data_wr0,"%d\n",Sig[15:0]); 则在txt中输出的是无符号数;
  
  
    反之,写成:  $fclose(data_wr0,"%d\n",Sig); 则在txt中输出的是有符号数;

  
  

 

 

5      $fclose

        fclose(<FileHandle>);关闭文件,<File Handle>为所获得的句柄。

6      $fread

读取文件:$fread

integer file_id;

file_id = $fread(“file_path/file_name”, “r”);

7      $random

       $rabdom 这个系统函数提供了一个产生随机数的手段。当函数被调用时返回一个32bit的随机数。它是一个带符号的整形数。$random一般的用法是:$ramdom% b ,其中 b>0.它给出了一个范围在(-b+1):(b-1)中的随机数。

        代码如下:


  
  
  1. //***************************** 随机数 $random *******************************
  2. //宏定义,定义数据长度
  3. `define RANDOM_LENGTH 68
  4. reg signed [ 15: 0] rand1;
  5. reg signed [ 15: 0] rand2;
  6. reg signed [ 15: 0] rand3;
  7. reg [ 15: 0] cnt_correct1;
  8. reg [ 15: 0] cnt_correct2;
  9. reg [ 15: 0] cnt_correct3;
  10. reg signed [ 15: 0] min;
  11. reg signed [ 15: 0] max;
  12. integer k;
  13. initial
  14. begin
  15. k = 0;
  16. min = 10; //只能是正的
  17. max = 20;
  18. rand1 = 0;rand2 = 0;rand3 = 0;
  19. cnt_correct1 = 0;cnt_correct2 = 0;cnt_correct3 = 0;
  20. # 800;
  21. for(k = 0;k < `RANDOM_LENGTH; k = k + 1)
  22. begin
  23. @(clk);
  24. //给出了一个范围在-59到59之间的随机数
  25. rand1 = $random % 60;
  26. //通过位并接操作产生一个值在0到59之间的数
  27. rand2 = {$random} % 60;
  28. //产生一个在min, max之间随机数的例子:
  29. rand3 = min+{$random}%(max-min+ 1);
  30. // 测试程序
  31. if((rand1 < 60)&&(rand1 > -60))
  32. cnt_correct1 = cnt_correct1 + 1;
  33. if((rand2 < 60)&&(rand2 >= 0))
  34. cnt_correct2 = cnt_correct2 + 1;
  35. if((rand3 <= max)&&(rand3 >= min))
  36. cnt_correct3 = cnt_correct3 + 1;
  37. end
  38. end

        结果展示:

    

7      $stop

                暂停仿真。


8      示例

 1 下面是一些常见的应用:
  2         1、读写文件
  3 `timescale 1 ns/1 ns
  4 module FileIO_tb;
  5 integer fp_r, fp_w, cnt;
  6 reg [7:0] reg1, reg2, reg3;
  7 initial begin
  8   fp_r = $fopen("data_in.txt", "r");
  9   fp_w = $fopen("data_out.txt", "w");
 10  
 11   while(!$feof(fp_r)) begin
 12     cnt = $fscanf(fp_r, "%d %d %d", reg1, reg2, reg3);
 13     $display("%d %d %d", reg1, reg2, reg3);
 14     $fwrite(fp_w, "%d %d %d\n", reg3, reg2, reg1);
 15   end
 16  
 17   $fclose(fp_r);
 18   $fclose(fp_w);
 19 end
 20 endmodule
 21            2、
 22 integer file, char;
 23 reg eof;
 24 initial begin
 25    file = $fopenr("myfile.txt");
 26    eof = 0;
 27    while (eof == 0) begin
 28        char = $fgetc(file);
 29        eof = $feof (file);
 30        $display ("%s", char); 
 31    end
 32 end
 33         3、文件处理定位
 34 `define SEEK_SET 0
 35 `define SEEK_CUR 1
 36 `define SEEK_END 2
 37 integer file, offset, position, r;
 38 r = $fseek(file, 0, `SEEK_SET);
 39 r = $fseek(file, 0, `SEEK_CUR);
 40 r = $fseek(file, 0, `SEEK_END);
 41 r = $fseek(file, position, `SEEK_SET);
 42       4、
 43 integer r, file, start, count;
 44 reg [15:0] mem[0:10], r16;
 45 r = $fread(file, mem[0], start, count);
 46 r = $fread(file, r16);
 47          5、
 48 integer file, position;
 49 position = $ftell(file);
 50            6、
 51 integer file, r, a, b;
 52 reg [80*8:1] string;
 53 file = $fopenw("output.log");
 54 r = $sformat(string, "Formatted %d %x", a, b);
 55 r = $sprintf(string, "Formatted %d %x", a, b);
 56 r = $fprintf(file, "Formatted %d %x", a, b);
 57        7、
 58 integer file, r;
 59 file = $fopenw("output.log");
 60 r = $fflush(file);
 61         8、
 62 // This is a pattern file - read_pattern.pat
 63 // time bin dec hex
 64 10: 001 1 1
 65 20.0: 010 20 020
 66 50.02: 111 5 FFF
 67 62.345: 100 4 DEADBEEF
 68 75.789: XXX 2 ZzZzZzZz
 69 `timescale 1ns / 10 ps
 70 `define EOF 32'hFFFF_FFFF
 71 `define NULL 0
 72 `define MAX_LINE_LENGTH 1000
 73 
 74 module read_pattern;
 75 integer file, c, r;
 76 reg [3:0] bin;
 77 reg [31:0] dec, hex;
 78 real real_time;
 79 reg [8*`MAX_LINE_LENGTH:0] line;
 80 
 81 initial
 82     begin : file_block
 83     $timeformat(-9, 3, "ns", 6);
 84     $display("time bin decimal hex");
 85     file = $fopenr("read_pattern.pat");
 86     if (file == `NULL) // If error opening file
 87         disable file_block; // Just quit
 88 
 89     c = $fgetc(file);
 90     while (c != `EOF)
 91         begin
 92        
 93         if (c == "/")
 94             r = $fgets(line, `MAX_LINE_LENGTH, file);
 95         else
 96             begin
 97             // Push the character back to the file then read the next time
 98             r = $ungetc(c, file);
 99             r = $fscanf(file," %f:\n", real_time);
100 
101             // Wait until the absolute time in the file, then read stimulus
102             if ($realtime > real_time)
103                 $display("Error - absolute time in file is out of order - %t",
104                         real_time);
105                 else
106                     #(real_time - $realtime)
107                         r = $fscanf(file," %b %d %h\n",bin,dec,hex);
108                 end // if c else
109             c = $fgetc(file);
110         end // while not EOF
111 
112     r = $fcloser(file);
113     end // initial
114 
115 // Display changes to the signals
116 always @(bin or dec or hex)
117     $display("%t %b %d %h", $realtime, bin, dec, hex);
118 
119 endmodule // read_pattern
120         9、自动比较输出结果
121 `define EOF 32'hFFFF_FFFF
122 `define NULL 0
123 `define MAX_LINE_LENGTH 1000
124 module compare;
125 integer file, r;
126 reg a, b, expect, clock;
127 wire out;
128 reg [`MAX_LINE_LENGTH*8:1];
129 parameter cycle = 20;
130 
131 initial
132     begin : file_block
133     $display("Time Stim Expect Output");
134     clock = 0;
135 
136     file = $fopenr("compare.pat");
137     if (file == `NULL)
138         disable file_block;
139 
140     r = $fgets(line, MAX_LINE_LENGTH, file); // Skip comments
141     r = $fgets(line, MAX_LINE_LENGTH, file);
142 
143     while (!$feof(file))
144         begin
145         // Wait until rising clock, read stimulus
146         @(posedge clock)
147         r = $fscanf(file, " %b %b %b\n", a, b, expect);
148 
149         // Wait just before the end of cycle to do compare
150         #(cycle - 1)
151         $display("%d %b %b %b %b", $stime, a, b, expect, out);
152         $strobe_compare(expect, out);
153         end // while not EOF
154 
155     r = $fcloser(file);
156     $stop;
157     end // initial
158 
159 always #(cycle / 2) clock = !clock; // Clock generator
160 
161 and #4 (out, a, b); // Circuit under test
162 endmodule // compare
163         10、从文件中读数据到mem(这个好像一般人用的最多了)
164 `define EOF 32'HFFFF_FFFF
165 `define MEM_SIZE 200_000
166 module load_mem;
167 integer file, i;
168 reg [7:0] mem[0:`MEM_SIZE];
169 reg [80*8:1] file_name;
170 initial    
171 begin    
172 file_name = "data.bin";    
173 file = $fopenr(file_name);    
174 i = $fread(file, mem[0]);    
175 $display("Loaded %0d entries \n", i);    
176 i = $fcloser(file);    
177 $stop;    
178 end endmodule // load_mem

    

猜你喜欢

转载自blog.csdn.net/alangaixiaoxiao/article/details/83070226