$display、$write;$fopen、$fdisplay、$fclose;$strobe
$display和$write任务
- 格式: $display(p1,p2,...pn); $write(p1,p2,...pn);
- p1通常称为"格式控制”;p2~pn称为“输出列表”;
- 这两个任务的作用基本相同。$display在结束后自动换行,$write不会自动换行。所以,当想让消息在一行显示时,用$write
- 在$display和$write中,输出格式控制要用双引号括起来。
- 下表给出几种常用的输出格式:
输出格式 | 说明 |
%h或%H | 16进制 |
%d或%D | 10进制 |
%o或%O | 8进制 |
%b或%B | 2进制 |
%c或%C | ASCII码 |
%v或%V | 输出网络型数据信号强度 |
%m或%M | 输出等级层次的名字 |
%s或%S | 字符串 |
%t或%T | 以当前的时间格式 |
%e或%E | 指数形式 |
%f或%F | 以10进制形式输出实型数 |
%g或%G | 以指数或10进制的形式输出实型数 |
其中:%v %m %t的具体情况可见:http://blog.51cto.com/lihaichuan/981060。
换码序列及功能
换码序列 | 功能 |
\n | 换行 |
\t | 右移一个制表符 |
\\ | 字符\ |
\" | 双引号字符" |
\o | 1~3位八进制数代表的字符 |
%% | 百分号% |
在$display()中可以通过在%和表示进制的字符之间插入一个0来自动调整显示输出数据宽度的方式。eg:
$display("d=%0h a=%0h",data,addr);
如果输出列表中表达式的值包含有不确定的值或高阻值,其结果输出遵循以下规则:
(1).在输出格式为十进制的情况下:
• 如果表达式值的所有位均为不定值,则输出结果为小写的x。
• 如果表达式值的所有位均为高阻值,则输出结果为小写的z。
• 如果表达式值的部分位为不定值,则输出结果为大写的X。
• 如果表达式值的部分位为高阻值,则输出结果为大写的Z。
(2).在输出格式为十六进制和八进制的情况下:
• 每4位二进制数为一组代表一位十六进制数,每3位二进制数为一组代表一位八进制数。
• 如果表达式值相对应的某进制数的所有位均为不定值,则该位进制数的输出的结果为小写的
x。
• 如果表达式值相对应的某进制数的所有位均为高阻值,则该位进制数的输出结果为小写的z。
• 如果表达式值相对应的某进制数的部分位为不定值,则该位进制数输出结果为大写的X。
• 如果表达式值相对应的某进制数的部分位为高阻值,则该位进制数输出结果为大写的Z。
对于二进制输出格式,表达式值的每一位的输出结果为0、1、x、z。下面举例说明:
语句输出结果:
1 $display("%d",1'bx); // 输出结果为:x 2 3 $display("%h",14'bx0_1010); //输出结果为:xxXa 4 5 $display("%h %o",12'b001x_xx10_1x01,12'b001_xxx_101_x01); //结果为:XXX1x5X
$display("%h %o",12'b001x_xx10_1x01,12'b001_xxx_101_x01); 输出结果为:XXX 1x5X
注意:因为$write在输出时不换行,要注意它的使用。可以在$write中加入换行符\n,以确保明确的
输出显示格式。
文件输出
-
文件可以用系统任务$fopen打开;
- 用法:$fopen("<文件名>"); 用法:<文件句柄>=$fopen("<文件名>");
- 任务$fopen返回一个被称为多通道描述符的32位值。多通道描述符中只有一位被设置为1。标准输出有一个多通道描述符,其最低位(第0位)被设置为1。标准输出也被称为通道0.标准通道一直开放。
- 由于标准输出将描述符的最低位占用,同时描述符的第31位是保留位。所以,使用多通道2描述符最多可以同时开30个文件。
- 注意:用$fopen打开文件会将原来的文件清空,若要读数据就用$readmemb,$readmemh就可以了,这个语句不会清空原来文件中的数据。
用$fopen的情况是为了取得句柄,即文件地址,也就是写文件时用$fdisplay(desc,"display1");时才用。$readmemb和$readmemh会在Verilog的一些系统任务(二)。
-
系统任务$fdisplay、$fmonitor、$fwrite和$fstrobe都用于写文件。
- $fdisplay和$fmonitor任务的用法: $fdisplay/$fmonitor(<文件描述符>,p1,p2,...,pn);
下面是一个对文件打开和写文件的例子:
1 module files; 2 integer handle1,handle2,handle3; 3 // 标准输出一直是打开的:descriptor=32'h0000_0001;(bit0 set 1) 4 initial 5 begin 6 handle1=$fopen("file1.out"); // handle1=32'h0000_0002(bit1 set 1) 7 handle2=$fopen("file2.out"); // handle2=32'h0000_0004(bit2 set 1) 8 handle3=$fopen("file3.out"); // handle3=32'h0000_0008(bit3 set 1) 9 end 10 integer desc1,desc2,desc3; 11 initial 12 begin 13 #10 desc1=handle1|1; // 按位或;desc1=32'h0000_0003 14 $fdisplay(desc1,"Display 1"); // 写到文件file1.out和标准输出stdout 15 16 desc2=handle2|handle1; // desc2=32'h0000_0006 17 $fdisplay(desc2,"Display 2"); // 写道文件file1.out和file2.out 18 19 desc3=handle3; // desc3=32'h0000_0008 20 $fdisplay(desc3,"Display 2"); // 只写到文件file3.out 21 22 #10 $fclose(handle1); 23 $fclose(handle2); 24 $fclose(handle3); 25 end 26 endmodule
-
显示层次
- 通过任何显示任务,例如$display、$write、$monitor或者$strobe任务中的%m选项的方式可以显示任何级别的层次。
-
选通显示
- 选通显示由关键字为$strobe的系统任务完成。这个任务与$display任务大体上相同。但是如果使用strobe语句,那么$strobe语句总是在其他同时刻的其他赋值语句执行完成以后才执行。
- 用处:$strobe提供了一种同步机制,他可以确保所有在同一时钟沿赋值的其他语句在执行完毕以后才显示数据。
- 例子如下:
always @(posedge clock) begin a=b; c=d; end always @(posedge clock) $ strobe ("Displaying a=%b,c=%b",a,c);
如果使用的是display,那么忧郁两个always块同时运行,会出现无法找到display是在前一个always赋值语句之前还是之后执行。而顺序不同会产生不同的结果。但是当使用了strobe后,则strobe语句是在同时刻的所有语句的最后执行。那么,就可以确保是在赋值完毕后才进行输出操作。