(转自:真OO无双)http://www.cnblogs.com/oomusou/archive/2008/02/11/1066839.html
Abstract
Verilog雖然為硬體描述語言,亦提供讀取/寫入文字檔的功能。
Introduction
為什麼需要用Verilog讀取/寫入文字檔呢?主要用在寫Testbench,並且有兩個優點:
1.資料處理的個數不需寫死在Testbench內。
2.文字檔可以用其他更強大的語言產生,如C/C++、Python。
3.將資料輸出到文字檔後,可用其他語言分析,如C/C++、Python、Excel。
Verilog
1/* 2 (C) OOMusou 2008 http://oomusou.cnblogs.com 3 4 Filename : FileIO_tb.v 5 Compiler : ModelSim SE 6.1f 6 Description : Demo how to access text file 7 Release : 02/11/2008 1.0 8 */ 9 10 `timescale 1 ns/1 ns 11 12 module FileIO_tb; 13 14 integer fp_r, fp_w, cnt; 15 reg [7:0] reg1, reg2, reg3; 16 17 initial begin 18 fp_r = $fopen("data_in.txt", "r"); 19 fp_w = $fopen("data_out.txt", "w"); 20 21 while(!$feof(fp_r)) begin 22 cnt = $fscanf(fp_r, "%d %d %d", reg1, reg2, reg3); 23 $display("%d %d %d", reg1, reg2, reg3); 24 $fwrite(fp_w, "%d %d %d\n", reg3, reg2, reg1); 25 end 26 27 $fclose(fp_r); 28 $fclose(fp_w); 29 end 30 31 endmodule
data_in.txt
1 2 3 4 5 6
data_out.txt
3 2 1 6 5 4
18行
fp_r = $fopen("data_in.txt", "r"); fp_w = $fopen("data_out.txt", "w");
$fopen()類似C語言的fopen(),連參數都一樣,主要用來開啟檔案,並取得file handle。
21行
while(!$feof(fp_r)) begin end
使用while迴圈,若不是最後一行,則一直讀取,類似c語言的while(!foef(fp_r)) {}。
22行
cnt = $fscanf(fp_r, "%d %d %d", reg1, reg2, reg3);
$fscanf()類似C語言的fscanf(),連參數都一樣,可將資料從文字檔讀入變數;與C語言不同的是,$fscanf()傳回讀入的變數個數, 一定得用一個變數去接,但C語言的fscanf()則可忽略。
23行
$display("%d %d %d", reg1, reg2, reg3);
$display()類似C語言的printf(),可將變數顯示在commanr window,並且自動換行。
24行
$fwrite(fp_w, "%d %d %d\n", reg3, reg2, reg1);
$fwrite()類似C語言的fprintf(),可將變數寫入文字檔。
27行
$fclose(fp_r); $fclose(fp_w);
$fclose()類似C語言的fclose(),可關閉檔案。
所對應的C語言
1 /* 2 (C) OOMusou 2008 http://oomusou.cnblogs.com 3 4 Filename : FileIO.c 5 Compiler : Visual C++ 8.0 6 Description : Demo how to access text file 7 Release : 02/11/2008 1.0 8 */ 9 10 #include <stdio.h> 11 12 int main() { 13 FILE *fp_r = fopen("data_in.txt", "r"); 14 FILE *fp_w = fopen("data_out.txt", "w"); 15 16 int reg1, reg2, reg3; 17 while(!feof(fp_r)) { 18 fscanf(fp_r, "%d %d %d", ®1, ®2, ®3); 19 printf("%d %d %d\n", reg1, reg2, reg3); 20 fprintf(fp_w, "%d %d %d\n", reg3, reg2, reg1); 21 } 22 23 fclose(fp_r); 24 fclose(fp_w); 25 }
Conclusion
在COM、.NET之前,不同語言之間要合作,唯一的管道就是文字檔。Verilog是硬體語言,若要和軟體語言合作,又得使用文字檔這種古老的方法了。
Verilog是一個C-Like的語言,連system function也特意地跟C語言靠攏,本例又再度得到證明,Verilog程式碼幾乎與C語言一行一行的對應。若你原本熟悉軟體的C語言,又想切入硬體描述語言,Verilog會讓你備感親切。
See Also:(原創) 如何讀取/寫入文字檔? (C)
Abstract
雖然C++提供了較簡單的方式如寫文字檔,不過在嵌入式系統,C語言仍較受歡迎,本文討論如何用C語言讀寫文字檔。
Introduction
之前大都使用C++讀取文字檔,所以對傳統C語言的方式反而不熟悉,由於在(原創) 如何讀取文/寫入字檔? (IC Design) (Verilog)使用了Verilog讀取文字檔,發現Verilog的寫法竟然與C語言非常相似,再加上C語言在嵌入式系統較受歡迎,所以也一併學習了C語言的方式。
C語言
1 /* 2 (C) OOMusou 2008 http://oomusou.cnblogs.com 3 4 Filename : FileIO.c 5 Compiler : Visual C++ 8.0 6 Description : Demo how to access text file 7 Release : 02/11/2008 1.0 8 */ 9 10 #include <stdio.h> 11 12 int main() { 13 int reg1, reg2, reg3; 14 15 FILE *fp_r = fopen("data_in.txt", "r"); 16 FILE *fp_w = fopen("data_out.txt", "w"); 17 18 if (fp_r == NULL) 19 return -1; 20 21 if (fp_w == NULL) 22 return -1; 23 24 while(!feof(fp_r)) { 25 fscanf(fp_r, "%d %d %d", ®1, ®2, ®3); 26 printf("%d %d %d\n", reg1, reg2, reg3); 27 fprintf(fp_w, "%d %d %d\n", reg3, reg2, reg1); 28 } 29 30 fclose(fp_r); 31 fclose(fp_w); 32 }
執行結果
5 6 4
data_in.txt
1 2 3
4 5 6
data_out.txt
6 5 4
15行
FILE *fp_w = fopen("data_out.txt", "w");
fopen()執行開檔的動作,第一個參數是檔案名稱,第二個參數r代表read,w代表write。值得注意的是,file handle是一個FILE *,根據stdio.h的定義,FILE是一個struct的typedef,定義如下:
struct _iobuf { char *_ptr; int _cnt; char *_base; int _flag; int _file; int _charbuf; int _bufsiz; char *_tmpfname; }; typedef struct _iobuf FILE;
所以fp_r是一個pointer to struct。
24行
使用while迴圈,若不是最後一行,則一直讀取。
25行
fscanf()類似scanf(),將資料從文字檔讀入變數,和scanf()一樣,要傳入的是變數的位址,而非變數而已。
27行
fprintf()類似printf(),將資料從變數寫入文字檔。
30行
fclose(fp_w);
對文字檔進行關檔的動作。
Conclusion
C語言讀寫文字檔的方式和Verilog非常類似,其實是Verilog刻意去學習C語言。