$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語句是在同時刻的所有語句的最后執行。那么,就可以確保是在賦值完畢后才進行輸出操作。