Verilog语法:与仿真相关的系统任务

1.$display和 $write

语法格式:
$display("<format_specifiers>", <signal1 , signal2, ..., signaln>);
$write("<format_specifiers>", <signal1, signa12, ..., signaln>);

"<format_specifiers>"通常称为“格式控制”
"<signal1, signa12, …, signaln>"为”信号输出列表“
$display自动地在输出后进行换行
$write输出特定信息是不换行

输出格式说明,由“%"和格式字符组成,其作用是将输出的数据转换成指定的格式输出。
常用的几种输出格式如下表:
 


一些特殊的字符可以通过表中的转换序列来输出:
 


例:$display和 $write语句

module disp_tb; 
  reg[31 :0] rval; 
  pulldown(pd);
  initial
    begin
      rval=101;
      $display("\\\t%%\n\"\123”);
      $display("rval=%h hex %d decimal" rval, rval);
      $display("rval=%o otal %b binary", rval, rval);
      $display("rval 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("%t\n", $time); 
    end
endmodule


在$display中,输出列表中数据的显示宽度是自动按照输出格式进行调整的,总是用表达式的最大值所占的位数来显示表达式的当前值。

2.$monitor与 $stobe

$monitor与$stobe都提供了监控和输出参数列表中字符或变量的值的功能
(1)$monitor语法格式:
$monitor("<format_specifiers>", <signal1, signal2, ..., signaln>);
任务$monitor提供了监控和输出参数列表中的表达式或变量值的功能。每当参数列表中变量或表达式的值发生变化时,整个参数列表中变量或表达式的值都将输出显示。
例如:$monitor($time, , “rxd=%b txd=%b”,rxd txd);
注意在上面的语句中,", ,"代表一个空参数。空参数在输出时显示为空格。

$monitoron和$monitoroff任务的作用是通过打开和关闭监控标志来控制监控任务$monitor的启动和停止,这样使得程序员可以很容易的控制$monitor何时发生。
$monitor与$display的不同处在于$monitor往往在initial块中调用,只要不调用$monitoroff,$monitor便不间断地对所设定的信号进行监视。

例:$monitor系统任务的应用

module monitor_tb;
  integer a,b;
  initial 
    begin
      a = 2;
      b = 2;
      forever 
        begin
          #5 a = a + b;
          #5 b = a - 1;
        end
    end
  initial $monitor($time,"a = %d,b = %d",a, b);
endmodule


(2)$strobe语法格式:
$strobe(<functions_or_signals>);
$strobe("<string_and/or_variables>",<functions_or_signals>);
探测任务用于在某时刻所有时间处理完后,在这个时间步的结尾输出一行格式化的文本。常用的系统任务如下:
$stobe:在所有时间处理完后,以十进制格式输出一行格式化的文本;
$strobeb:在所有时间处理完后,以二进制格式输出一行格式化的文本;
$strobeo:在所有时间处理完后,以八进制格式输出一行格式化的文本;
$strobeh:在所有时间处理完后,以十六进制格式输出一行格式化的文本。

$strobe任务在被调用的时刻所有的赋值语句都完成了,才输出相应的文字信息。$strobe任务提供了另一种数据显示机制,可以保证数据只在所有赋值语句被执行完毕后才被显示。

3.$time和 $reltime

  • 用这两个时间系统函数可以得到当前的仿真时刻,不同的是,$time函数以64位整数值的形式返回仿真时间,而 $realtime函数则以实数型数据返回仿真时间。
    (1)系统函数 $time
    例:$time系统任务的应用实例
`timescale 1ns/1ns
module time_tb;
  reg ts;
  parameter dalay = 2;
  initial 
    begin
      #delay ts = 1;
      #delay ts = 0;
      #delay ts = 1;
      #delay ts = 0;
    end
  initial
    $monitor($time,,"ts = %b",ts);
  $time
endmodule

输出结果:

0 ts = x
3 ts = 1
5 ts = 0
8 ts = 1
10 ts = 0

(2) $realtime系统函数

$realtime返回的时间数字是一个实型数,该数字也是以时间尺度为基准的。
例:$realtime 系统任务的应用实例:

`timescalel 1ns/1ns 
module realtime_tb; 
  reg set; 
  parameter p=2; 
  initial
    begin
      $monitor($realtime, ,"set=b%" ,set); 
      #p set=0;
      #p set=1;
    end
endmodule

输出结果:

0 set=x
2 set=0
4 set=1

4.$finish和 $stop

系统任务$finish和$stop是用于对仿真过程进行控制,分别表示结束仿真和中断仿真。其语法格式:
$finish;
$fimsh(n);
$stop;
$stop(n);
其中,n是$finish和$stop的参数,n可以取0、1或2几个值,分别表示如下含义,如下表所示。


$finish的作用是退出仿真器,返回主操作系统,也就是结束仿真过程。任务$finish可以带参数,根据参数的值输出不同的特征信息。如果不带参数,默认$finish的参数值为1。
$stop任务的作用是把EDA工具(例如仿真器)置成暂停模式,在仿真环境下给出一个交互式的命令提示符,将控制权交给用户。这个任务可以带有参数表达式。根据参数值(0,1或2)的不同,输出不同的信息。参数值越大,输出的信息越多。

$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; //程序执行到40个时间单位时退出仿真器
  initial 
    begin
      $monitor($time,"a = %d,b = %d",a,b);
    end
endmodule

$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; //程序执行到40个时间单位时停止仿真
  initial 
    begin
      $monitor($time,"a = %d,b = %d",a,b);
    end
endmodule

5.$readmemh和 $readmem

在Verilog程序中有两个系统任务$readmemh和$readmem用来从文件读取数据到存储器中。在两个系统任务可以在仿真的任何时刻被执行使用,其语法格式共有一下:
(1) $readmemb(“<file_name>”,<memory_name>);
(2) $readmemb(“<file_name>”,<memory_name>,<start_addr>);
(3) $readmemb(“<file_name>”,<memory_name>,<start_addr>,<finish_addr>);
(4) $readmemh(“<file_name>” ,<memory_name>);
(5) $readmemh(“<file_name>”,<memory_name>,<start_addr>);
(6) $readmemh(“<file_name>”,<memory_name>,<start_addr>,<finish_addr>);

例:$readmemh和$readmem系统任务实例

module read_mem_tb;
  reg [7:0] memory_b [0:7];
  reg [7:0] memory_h [0:31];
  integer i;
  initial
    begin
      $readmemb("init_b.txt",memory_b); //把数据文件init_b.txt读入存储器中的指定地址
      $readmemh("init_h.txt",memory_h);
      for(i = 0;i < 8; i=i+1)
        begin
          $display("memory_b[%0d] = %b",i.memory_b[i]);
          $display("memory_h[%0h] = %h",i.memory_h[i]);
        end
    end
endmodule

文件init_b.txt和init_h.txt包含初始化数据。用@<address>在数据文件中指定地址。其中,"init_b.txt"指定二进制数据从第二位地址开始写入;而"init_h.txt"指定十六进制数据从地一位地址写入。样本文件如下:

init_b.txt:

@002 
11111111 01010101
00000000 10101010
@001
1111zzzz 00001111

init_h.txt:

@001
00000000000000000000000000000011
00000000000000000000000000000111
00000000000000000000000000001111
00000000000000000000000000011111

6.$random

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

实例:

`timescale 1ns/1ns 
module random_pulse(dout); 
  output [9: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);
          delay2 = 20 * (1 +{$random} % 3); 
          #delay1 dout= 1 << ({$random}%10);
          $delay2 dout = 0;
        end
    end
endmodule

7. $fopen,$fwrite,$fclose,$fread

$fopen

系统任务$fopen可以用来打开指定的文件(以便后续对其进行写入操作),其返回值为integer变量,表示当前文件的句柄值,获取句柄值后,后续就可以根据句柄值对不同的文件进行写入操作。即

integer handle1; //定义句柄1

handle1 = $fopen("file_name",type) //以指定类型(type)的方式来打开文件,并将其返回值赋给handle1

type指定了打开文件的类型,可以是以下种类:

通常情况下,我们使用 w 来作为类型值,即以对一个ASCII文本文件进行写操作的方式来打开该文件 (txt)。

比如,我们在如下路径新建一个TXT文件file_test1.txt:

然后就可以用下述的方法将其打开:

integer handle1; //定义句柄1

handle1 = $fopen("D:/file_test/file_test1.txt","w"); //以w类型(写)的方式来打开文件,并将其返回值赋给handle1

$fwrite

$fwrite用来向文件中写入数据。与文件读取不同,文件写入需要打开文件,写入,最后关闭文件。操作流程如下:

handle = $fopen("D:/file.txt","w");//按照写操作打开文件,得到对应的句柄,作为文件操作标识;其中,文件路径间隔为“/”而不是“\”

$fwrite(handle,"%d\n",data);//按照十进制格式写入数据到handle对应文件中,只能逐个写入(即data不能是数组)

$fclose(handle);//关闭文件,至此文件操作结束

$fread
integer <integer>;
<integer> = $fread(<store>,<file_desc>); 
<integer> = $fread(<store>,<file_desc>, <start> ); 
<integer> = $fread(<store>,<file_desc>, <start>, <count> ); 
<integer> = $fread(<store>,<file_desc>, , <count> ); 
integer:整型数值,返回本次$fread 读取的真实字节数量,当返回值为0 ,表示错误读取或者文件结束。
store:将二进制文件中的数据读取到寄存器或者二维数组中。
file_desc:为打开的文件句柄
start: 为二维数组的起始地址
count: 从起始地址开始, 写入二维数组的数量。
  • 23
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值