1. 程式人生 > >Verilog關於文字資料的讀寫操作

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,都會在資料後插入一個換行符。