📜  Verilog显示任务

📅  最后修改于: 2021-01-11 15:04:34             🧑  作者: Mango

Verilog显示任务

显示系统任务主要用于显示信息和调试消息,以跟踪日志文件中的模拟流。显示任务和格式可以使用不同的组来打印值。

通常,显示系统任务分为三类,例如:

  • 显示和编写任务
  • Verilog频闪
  • 持续监控任务

当调用这些任务之一时,它仅打印其参数。打印参数的顺序与x在参数列表中出现的顺序相同。如果未指定任何参数,则可以将其声明为空参数,并且在调用显示任务时,它仅打印单个空格字符。参数可以是返回值和带引号的字符串。

显示和编写任务

第一组显示任务与以ANSI C语言打印函数非常相似。 $ write和$ display任务以相同的方式工作,唯一的区别是$ display任务在输出的末尾添加了一个新行字符,而$ write任务则没有。

句法

$ display$ write都按照参数在参数列表中出现的顺序显示参数。

$display();
$write();

$写入不追加新行字符为它的字符串的末尾,而$显示可以从以下所示的实例中可以看出。

module tb;
  initial begin
    $display ("This ends with a new line ");
    $write ("This does not,");
    $write ("like this. To start new line, use newline char");
    $display ("This always starts on a new line!");
  end
endmodule

现在,执行上面的代码,我们将获得以下输出。

ncsim> run
This ends with a new line 
This does not, like this. To start a new line, use newline char
Hello!
ncsim: *W,RNQUIE: Simulation is complete.

Verilog频闪

$ strobe在当前增量时间步结束时打印变量的最终值,并且格式类似于$ display 。换行符会自动添加到文本中。

module tb;
  initial begin
    reg [7:0] a;
    reg [7:0] b;
    
    a = 8'h2D;
    b = 8'h2D;
    
    #10;                  // Wait till simulation reaches 10ns
    b <= a + 1;           // Assign a+1 value to b
    
    $display ("[$display] time=%0t a=0x%0h b=0x%0h", $time, a, b);
    $strobe  ("[$strobe]  time=%0t a=0x%0h b=0x%0h", $time, a, b);
    
    #1;
    $display ("[$display] time=%0t a=0x%0h b=0x%0h", $time, a, b);
    $strobe  ("[$strobe]  time=%0t a=0x%0h b=0x%0h", $time, a, b);
    
  end
endmodule

注意:$ strobe在时间10ns,0x2E时显示变量b的最终更新值,并且$ display仅在下一个模拟增量11ns时才选择该值。

输出看起来像:

ncsim> run
[$display] time=10 a=0x2d b=0x2d
[$strobe]  time=10 a=0x2d b=0x2e
[$display] time=11 a=0x2d b=0x2e
[$strobe]  time=11 a=0x2d b=0x2e
ncsim: *W,RNQUIE: Simulation is complete.
ncsim> exit

Verilog连续显示器

$ monitor可以在参数列表中的变量或表达式发生更改时自动打印出变量或表达式值。

每次更新任何参数后,它都会达到调用$ display的类似效果。换行符会自动添加到文本中。

module tb;  
initial begin
    reg [7:0] a;
    reg [7:0] b;
    
    a = 8'h2D;
    b = 8'h2D;
        
    #10;                  // Wait till simulation reaches 10ns
    b <= a + 1;           // Assign a+1 value to b
    
    $monitor ("[$monitor] time=%0t a=0x%0h b=0x%0h", $time, a, b);
    
    #1 b <= 8'hA4;
    #5 b <= a - 8'h33;
    #10 b <= 8'h1;
  
  end
endmodule

$ monitor就像一个在主线程的后台运行的任务,它监视并显示其自变量的值更改。在模拟过程中,可以多次发出新的$ monitor任务。

ncsim> run
[$monitor] time=10 a=0x2d b=0x2e
[$monitor] time=11 a=0x2d b=0xa4
[$monitor] time=16 a=0x2d b=0xfa
[$monitor] time=26 a=0x2d b=0x1
ncsim: *W,RNQUIE: Simulation is complete.

Verilog格式说明符

要在显示函数中打印变量,必须为每个变量指定适当的格式说明符。

这些任务具有特殊字符(%),表示需要有关信号值的信息。使用字符串,编译器会识别%字符并知道下一个字符是格式规范。

如果使用格式规范符号,则应始终跟随相应的参数(%m参数除外)。

Argument Description
%h, %H Display in hexadecimal format
%d, %D Display in decimal format
%b, %B Display in binary format
%o or %O Display octal format
%m, %M Display hierarchical name
%s, %S Display as a string
%t, %T Display in time format
%f, %F Display ‘real’ in a decimal format
%e, %E Display ‘real’ in an exponential format

这些系统任务可以通过扩展名“ o”,“ h”和“ b”来调用。例如$ writeb,$ writeo$ displayh。调用它们时,它们会通知模拟器某些参数没有相应的格式规范,并且应更改默认显示格式。默认情况下,$ display和$ write系统任务使用十进制格式来更改显示格式。

显示数据的大小至关重要。通常,它取决于格式规范。如果我们使用十六进制格式,则数据将显示为四个字符,每个字符代表值的四位(单个十六进制值可以代表四位)。

同样,八进制值将显示为一组代表三个位的字符。表达式的结果将自动调整大小。但是,我们可以通过在%字符后添加0(零)来更改默认设置。

裁定另一个非常有用的显示任务功能适用于具有未知或高阻抗值的表达式的结果。如果我们使用十进制格式(%d),则遵循以下规则:

  • 当所有位均为未知值时,将显示单个小写的“ x”字符。
  • 当某些位的值未知时,将显示单个大写的“ X”字符。
  • 当所有位均为高阻抗值时,将显示单个小写的“ z”字符。
  • 当某些位具有高阻抗时,将显示单个大写字母“ Z”字符。

如果我们使用十六进制(%h)和八进制(%o)格式,则遵循以下规则:

  • 当组中的所有位均为未知值时,将显示单个小写的“ x”。
  • 当某些组位的值未知时,将显示单个大写字母“ X”。
  • 当组中的所有位均为高阻抗值时,将显示单个小写的“ z”。
  • 当组中的某些位具有高阻抗时,将显示单个大写字母“ Z”。

注意:在八进制格式中,组表示三个位,可以表示为0到7范围内的一位数字。在十六进制格式中,四位可以表示为在0到9范围内的一个字符以及范围内的字符从a到f。

module tb;
  initial begin
    reg [7:0]  a;
    reg [39:0] str = "Hello";
    time       cur_time;
    real       float_pt;

    a = 8'h0E;
    float_pt = 3.142;

    $display ("a = %h", a);
    $display ("a = %d", a);
    $display ("a = %b", a);
    $display ("str = %s", str);
    #200 cur_time = $time;
    $display ("time = %t", cur_time);
    $display ("float_pt = %f", float_pt);
    $display ("float_pt = %e", float_pt);
  end
endmodule

上面的代码执行后给出以下输出,例如:

ncsim> run
a = 0e
a =  14
a = 00001110
str = Hello
time =                  200
float_pt = 3.142000
float_pt = 3.142000e+00
ncsim: *W,RNQUIE: Simulation is complete.

Verilog转义序列

一些字符被认为是唯一的,因为它们代表其他显示目的,例如换行符,制表符和换页符。

要打印这些特殊字符,这些字符的每次出现来转义

Argument Description
\n Newline character
\t Tab character
\\ Backslash
\ddd Octal code
%% Percent sign

module tb;
  initial begin
    $write ("Newline character
");
    $display ("Tab character     stop");
    $display ("Escaping  " %%");

/*
    // Compilation errors
    $display ("Without escaping ");       // ERROR : Unterminated string
    $display ("Without escaping "");       // ERROR : Unterminated string
*/
  end
endmodule

输出看起来像:

ncsim> run
Newline character 
 
Tab character    stop
Escaping  " %
ncsim: *W,RNQUIE: Simulation is complete.