Verilog關於文字資料的讀寫操作
Testbench編寫指南是博主新開的一個系列,主要介紹在編寫testbench時使用到的技巧,讓編寫者的水平不再僅僅停留在時鐘訊號、復位訊號等簡單訊號的設定上,更好的完成對設計的模擬工作。
第2篇的題材是檔案的讀寫控制,模擬時經常需要從檔案中讀取測試激勵,還要將模擬結果存取在檔案中供其它程式讀取呼叫。
讀取txt檔案資料
示例程式碼如下:
integer i; //陣列座標 reg [9:0] stimulus[1:data_num]; //陣列形式儲存讀出的資料 initial begin $readmemb("SinIn.txt", stimulus); //將txt檔案中的資料儲存在陣列中 i = 0; repeat(data_num) begin //重複讀取陣列中的資料 i = i + 1; din = stimulus[i]; #clk_period; //每個時鐘讀取一次 end end
用“陣列”來表述Verilog HDL中的定義並不準確,但對大多數人來說應該更好理解。可以將stimulus視作一個儲存器,[9:0]定義了資料的位寬,[1:data_num]定義了儲存器的深度。stimulus的定義應該與txt檔案中的資料相匹配。txt檔案中每行儲存一個數據,則上述定義對應的是txt中儲存了data_num個數據,每個資料的最大位寬為10bit。
讀取二進位制格式的檔案是用系統任務readmemb;讀取十六進位制格式檔案使用readmemb;讀取十六進位制格式檔案使用readmemh。其命令為$readmemb(“filename”, mem_name),將filename中的內容讀取到mem_name中。
注意filename檔案路徑中應該用反斜槓“/”,與windows系統中的檔案路徑使用的“\”不同。如果不指定路徑,向上面程式一樣直接寫檔名字,那麼該檔案必須和testbench檔案在同一路徑下。
repeat(n) begin … end中的內容應該根據設計的需要編寫。
將資料寫入txt檔案
示例程式碼如下:
integer file_out; initial begin file_out = $fopen("mixer_out.txt"); if (!file_out) begin $display("can't open file"); $finish; end end wire signed [19:0] dout_s = dout; wire rst_write = clk & rst_n; //復位期間不應寫入資料 always @ (posedge rst_write) $fdisplay(file_out, "%d", dout_s);
寫入檔案需要先用$fopen系統任務開啟檔案,這個系統任務在開啟檔案的同時會清空檔案,並返回一個控制代碼,如果控制代碼為0則表示開啟檔案失敗。
如果原來不存在該檔案,則會自動建立該檔案。
開啟檔案之後便可以用得到的控制代碼和$fdisplay系統任務向檔案中寫入資料。這個系統任務和我們在C++中常用的fprintf函式的用法很像。
上面的程式中是將資料轉換為帶符號數signed後再寫入,必須說明轉換與否是有差別的,如果按預設的unsigned的格式寫入txt的是無符號數。
另外,每使用一次$fdisplay,都會在資料後插入一個換行符。