Menu Close

Verilog testbench编写进阶(1)–$display

在仿真程序中我们可以利用modelsim或Vivado 自带的仿真程序设置和观察波形,但有时候利用数据列表、报告文件等会得到更好的效果。本文介绍的$display函数是激励文件中经常使用的系统函数,它可以很好的帮助我们观察运行结果,定位运行中出现的问题。需要注意的是$display函数只能用在仿真程序中,是不可综合的函数,因此不能在实体程序中使用。

 

1.$display 函数

$display函数系统任务的作用是用来在控制台输出信息。注意在控制台直接输出字符时,在没有其它控制字符的控制显示格式的情况下,字符串原封不动的显示在屏幕上。 如:

$display("the code is running...");

在终端屏幕上显示如下:

the code is running...
  • 格式字符输出,如输出以10进制显示还是16进制显示等。这些格式是由%引导,后面紧跟表示进制的字符标识,如2进制为%b,8进制为%o,16进制为%h,10进制为%d等。其格式如下:

$display(“字符区” ,表达式1,表达式2,…);

表达式可是各种运算符组成的表达式,也可以是变量或常数,见例1:

例:

$display("data0= %b;data1= %o ; data2= %d; data3= %h",4, 6 ,12,13);

显示如下:

data0= 100;data1= 6 ; data2= 12; data3= d

 

  • 换行

上例中所有的数据在终端上都显示在一行中,为了清晰需要每笔数占用一行,需要换行控制。换行是由\n实现的,如上例可以改写如下:

$display(" data0= %b; \ndata1= %o; \ndata2= %d; \ndata3= %h; \n", 4, 6 ,12,13);

显示如下:

data0= 100;
data1= 6;
data2= 12;
data3= d;
  • 显示系统时间,系统是时间是由$time标识,系统时间是指系统开始运行到目前为止消耗(或累积)的时间,例:
initial begin
$display("simulation time= %t ; \n", $time);
#10

$display("simulation time= %t ; \n", $time);
#20

$display("simulation time = %t ; \n", $time);

end

显示结果为:

simulation time=0;
simulation time=10000;
simulation time=30000;

 

例1:列表显示0到100的累加值

`timescale 1 ns / 1 ps
 
 
module tb_dis (); 
 
integer i;
 
reg  [12:0] acc; 
 
initial 
begin
    acc = 0;
    $display(" running time =%t ; acc value= %d " ,$time, acc);
 
    for(i = 0; i < 101; i = i + 1)
    begin
        #10
        acc = acc + i;
 
        $display(" running time =%t ; i= %d ;  acc value= %d " ,$time, i, acc);
    end
    #10; 
    $stop;
end
 
endmodule

 

在modelsim transcript 窗口列表显示如下:

%title插图%num

.

.

.

%title插图%num

Modelsim的仿真波形如下:

%title插图%num

图1:

在对例化的模块输出显示时,一定要对$display函数适当的延时才能输出正确结果。观察例2的结果,就会知道,$display显示有一个Δ延时,如果没有一个适当的延迟,不会把上次的结果显示出来。

例2:$display 函数延时显示

module addab
(
    input  [3:0] a, b,
    output [4:0] y
);
 
assign y = a + b;
 
endmodule

 

仿真程序:

module tb_dis ();
 
reg [3:0] a,b;
wire [4:0] y;
 
initial begin
    a = 3;
    b = 5;
    $display("time =%t, a= %d, b=%d, y= %d ",$time ,a, b, y);
    #10
 
    a = 4;
    b = 5;
    $display("time =%t, a= %d, b=%d, y= %d ",$time ,a, b, y);
    #10
 
    a = 3;
    b = 7;
    $display("time =%t, a= %d, b=%d, y= %d ",$time ,a, b, y);
    #10
 
    a = 2;
    b = 6;
    $display("time =%t, a= %d, b=%d, y= %d ",$time ,a, b, y);
 
end
 
addab  addab_inst
(
    .a (a),
    .b (b),
    .y (y)
);
 
endmodule

 

%title插图%num

从上面的结果看,对于例化的模块提供输入,紧接着调用$display,会显示上次结果。修改仿真程序如下:

module tb_dis ();
 
reg [3:0] a,b; 
wire [4:0] y;
 
initial begin
    a = 3;
    b = 5;
    #10
    $display("time =%t, a= %d, b=%d, y= %d ",$time ,a, b, y);
 
    a = 4;
    b = 5;
    #10
    $display("time =%t, a= %d, b=%d, y= %d ",$time ,a, b, y);
 
    a = 3;
    b = 7;
    #10
    $display("time =%t, a= %d, b=%d, y= %d ",$time ,a, b, y);
 
    a = 2;
    b = 6;
    #10
    $display("time =%t, a= %d, b=%d, y= %d ",$time ,a, b, y);
end
 
addab addab_inst
(
    .a (a),
    .b (b),
    .y (y)
);
 
endmodule

 

%title插图%num

修改后,显示结果就正常了。

 

 

Posted in Quartus II, Verilog, Verilog, 教材与教案, 文章

发表评论

相关链接