在仿真程序中我们可以利用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 窗口列表显示如下:
.
.
.
Modelsim的仿真波形如下:
图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
从上面的结果看,对于例化的模块提供输入,紧接着调用$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
修改后,显示结果就正常了。