標籤:blog http io os 使用 ar for 檔案 資料
TEXTIO 在VHDL 模擬與磁碟檔案之間架起了橋樑,使用文字檔擴充VHDL 的模擬功能。本文介紹TEXTIO 程式包,以一個加法器執行個體說明TEXTIO 的使用方法,最後使用ModelSim 對設計進行模擬,並分析模擬結果。在對VHDL 來源程式進行模擬時, 由於有的輸入輸出關係僅僅靠輸入波形或編寫testbench 中的訊號輸入是難以驗證結果正確性的,例如, 設計8 位加法器,如果將所有的輸入都驗證一遍, 是非常麻煩的,因為要全面判斷輸出是否正確需要一個個的驗證。此外,若用VHDL 設計一個處理器,需要讀入指令,這時候採用文字檔非常必要。
TEXTIO 提供了VHDL 模擬時與磁碟檔案的互動。在驗證加法器時候, 可以將所有輸入儲存在一個文字檔中,將其它軟體計算出的結果儲存在另外的檔案中。在VHDL 模擬時,可以直接讀取輸入檔案作為設計的輸入參數,並自動將結果與事先儲存的檔案相比較,給出一定的資訊來確定結果的正確與否。在對VHDL 編寫的處理器調試時,可以將包括指令類型、源地址、目標地址在內的指令儲存成文字檔, 利用TEXTIO 來讀取這些指令。同時,將結果及中間變數儲存成文字檔,以事後判斷是否正確及便於尋找原因。由於TEXTIO 的文本輸入輸出功能非常有限,一些公司提供了擴充其功能的程式包,例如std_developerskit庫中的std_iopak 程式包。在本文中,僅僅對TEXTIO 程式包做簡單的介紹及其簡單的使用。
1 TEXTIO介紹
TEXTIO 是VHDL 標準庫STD 中的一個程式包(Package)。在該包中定義了三個類型:LINE 類型、TEXT類型以及SIDE 類型。另外,還有一個子類型(subtype)WIDTH。此外,在該程式包中還定義了一些訪問檔案所必須的過程(Procedure)。
1.1 類型定義
(1)type LINE is access string
定義了LINE 為存取類型的變數,它表示該變數是指向字串的指標,它是TEXTIO 中所有操作的基本單元。讀檔案時,先按行(LINE)讀出一行資料,再對LINE 操作來讀取各種資料類型的資料;寫檔案時,先將各種的資料類型組合成LINE,再將LINE 寫入檔案。在使用者使用時, 必須注意只有變數才可以是存取類型,而訊號則不能是存取類型。例如, 我們可以定義
variable DLine : LINE;
但不能定義成
signal DLine : LINE;
(2)type TEXT is file of string
定義了TEXT 為ASCII 檔案類型。 定義成為TEXT 類型的檔案是長度可變的ASCII 檔案。例如在TEXTIO 中定義了兩個標準的文字檔。
file input : TEXT open read_mode is STD_INPUT;
file output : TEXT open write_mode is STD_OUTPUT;
定義好以後,就可以通過檔案類型變數input 和output 來訪問其對應的檔案STD _ INPUT 和STD_OUTPUT。
(3)type SIDE is (right,left)
定義了SIDE 類型。表示定義了一個名為SIDE 的資料類型,其中只能有兩種狀態,即right 和left,分別表示將資料從左邊還是右邊寫入行變數。該類型主要是在TEXTIO 程式包包含的過程中使用。
(4)subtype WIDTH is natural
定義WIDTH 為自然數的子類型。所謂子類型表示其取值範圍是父類型範圍的子集。
1.2 流程定義
TEXTIO 提供了基本的用於訪問文字檔的過程。類似於C++,VHDL 提供了重載功能,即完成相近功能的不同過程可以有相同的過程名, 但其參數列表不同, 或參數類型不同或參數個數不同。
TEXTIO 提供的基本過程有:
procedure READLINE(檔案變數;行變數);用於從指定檔案讀取一行資料到行變數中。
procedure WRITELINE(檔案變數;行變數);用於向指定檔案寫入行變數所包含的資料。
procedure READ(行變數;資料類型);用於從行變數中讀取相應資料類型的資料。
根據參數資料類型及參數個數的不同,有多種重載方式,TEXTIO 提供了bit、bit_vector 、BOOLEAN 、character、 integer、real、string、time資料類型的重載。同時,提供了返回過程是否正確執行的BOOLEAN 資料類型的重載。例如, 讀取整數的過程為
procedure READ(L:inout LINE; VALUE: out integer; GOOD: out BOOLEAN);其中,GOOD 用於返回過程是否正確執行, 若正確執行, 則返回TRUE 。
procedure WRITE(行變數; 資料變數; 寫入方式; 位寬);
該過程將資料寫入行變數。其中寫入方式表示寫在行變數的左邊還是右邊,且其值只能為left 或right,位寬表示寫入資料時占的位寬。例如:
write(OutLine,OutData,left,2);
表示將變數OutData 寫入LINE 變數OutLine 的左邊佔2 個位元組。
2 TEXTIO應用執行個體
下面以一個簡單的8 位加法器來說明TEXTIO 的使用。輸入資料為兩個8 位的有符號數, 輸出為9 位的有符號數,以防止溢出。在編寫加法器的描述檔案時,首先要對兩個數進行位的擴充,再進行加法運算。在編寫測試檔案時,要注意讀入資料與得到結果之間相差一個刻度。因此,需要在讀出的結果與計算的結果之間插入一個刻度的等待。textio包如下
-- textio.vhdllibrary std; use std.standard.all; -- needed for bootstrap modepackage TEXTIO is -- Type Definitions for Text I/O type LINE is access STRING; -- a line is a pointer to a STRING value type TEXT is file of STRING; -- a file of variable-length ASCII records type SIDE is (RIGHT, LEFT); -- for justifying output data within fields subtype WIDTH is NATURAL; -- for specifying widths of output fields -- Standard Text Files file INPUT: TEXT open READ_MODE is "STD_INPUT"; file OUTPUT: TEXT open WRITE_MODE is "STD_OUTPUT"; -- Input Routines for Standard Types procedure READLINE (file F: TEXT; L: inout LINE); procedure READ (L: inout LINE; VALUE: out BIT; GOOD: out BOOLEAN); procedure READ (L: inout LINE; VALUE: out BIT); procedure READ (L: inout LINE; VALUE: out BIT_VECTOR; GOOD: out BOOLEAN); procedure READ (L: inout LINE; VALUE: out BIT_VECTOR); procedure READ (L: inout LINE; VALUE: out BOOLEAN; GOOD: out BOOLEAN); procedure READ (L: inout LINE; VALUE: out BOOLEAN); procedure READ (L: inout LINE; VALUE: out CHARACTER; GOOD: out BOOLEAN); procedure READ (L: inout LINE; VALUE: out CHARACTER); procedure READ (L: inout LINE; VALUE: out INTEGER; GOOD: out BOOLEAN); procedure READ (L: inout LINE; VALUE: out INTEGER); procedure READ (L: inout LINE; VALUE: out REAL; GOOD: out BOOLEAN); procedure READ (L: inout LINE; VALUE: out REAL); procedure READ (L: inout LINE; VALUE: out STRING; GOOD: out BOOLEAN); procedure READ (L: inout LINE; VALUE: out STRING); procedure READ (L: inout LINE; VALUE: out TIME; GOOD: out BOOLEAN); procedure READ (L: inout LINE; VALUE: out TIME); -- Output Routines for Standard Types procedure WRITELINE (file F: TEXT; L: inout LINE); procedure WRITE (L: inout LINE; VALUE: in BIT; JUSTIFIED: in SIDE := RIGHT; FIELD: in WIDTH := 0); procedure WRITE (L: inout LINE; VALUE: in BIT_VECTOR; JUSTIFIED: in SIDE := RIGHT; FIELD: in WIDTH := 0); procedure WRITE (L: inout LINE; VALUE: in BOOLEAN; JUSTIFIED: in SIDE := RIGHT; FIELD: in WIDTH := 0); procedure WRITE (L: inout LINE; VALUE: in CHARACTER; JUSTIFIED: in SIDE := RIGHT; FIELD: in WIDTH := 0); procedure WRITE (L: inout LINE; VALUE: in INTEGER; JUSTIFIED: in SIDE := RIGHT; FIELD: in WIDTH := 0); procedure WRITE (L: inout LINE; VALUE: in REAL; JUSTIFIED: in SIDE := RIGHT; FIELD: in WIDTH := 0; DIGITS: in NATURAL := 0); procedure WRITE (L: inout LINE; VALUE: in STRING; JUSTIFIED: in SIDE := RIGHT; FIELD: in WIDTH := 0); procedure WRITE (L: inout LINE; VALUE: in TIME; JUSTIFIED: in SIDE := RIGHT; FIELD: in WIDTH := 0; UNIT: in TIME := ns); -- File Position Predicates function ENDLINE (L: in LINE) return BOOLEAN;end TEXTIO;
8位全加器如下:
library ieee;use ieee.std_logic_1164.all;use ieee.std_logic_signed.all;entity Add2In is port( D1 : in std_logic_vector(7 downto 0); D2 : in std_logic_vector(7 downto 0); Q : out std_logic_vector(8 downto 0); Clk : in std_logic );end entity;architecture beha of Add2In isbegin process(Clk) begin if Clk‘event and Clk = ‘1‘ then Q <= (‘0‘ & D1) + D2; end if; end process;end beha;
編寫測試檔案。
在測試程式中, 首先讀出輸入檔案的一行內容,再從該行中提取出兩個值輸入加法器。從預定結果檔案中提取出一個值,將加法器計算結果與該值比較, 若兩者不同則輸出警告資訊。也可以將輸出寫入一個文字檔,再比較兩個文字檔的異同以獲知出錯的地方。這裡要注意的是要使用TEXTIO 程式包, 另外, 測試檔案實體內的連接埠為空白,相當於一塊獨立的電路板。使用Component 在其中包含了上面定義的加法器,該獨立的電路板所完成的功能是對設計的加法器進行測試。在程式中使用了assert Assert 陳述式,要注意該語句後的運算式或變數為真時不執行後續的輸出,為假時執行後續的輸出。在程式中,還使用了類型轉換函式CONV _ STD _LOGIC_VECTOR (),將整數轉換為8 位的標準類型。另外,在程式中定義了變數Dlatch ,該變數的作用是將計算結果與預定結果的比較延遲一個刻度, 周期地與預定結果比較。
LIBRARY ieee; USE ieee.std_logic_1164.all; USE ieee.std_logic_arith.all;USE ieee.std_logic_signed.all;USE std.textio.all;ENTITY Add2In_vhd_tst ISEND Add2In_vhd_tst;ARCHITECTURE Add2In_arch OF Add2In_vhd_tst IS SIGNAL Clk : STD_LOGIC := ‘0‘;SIGNAL D1 : STD_LOGIC_VECTOR(7 DOWNTO 0):=(others => ‘0‘);SIGNAL D2 : STD_LOGIC_VECTOR(7 DOWNTO 0):=(others => ‘0‘);SIGNAL Q : STD_LOGIC_VECTOR(8 DOWNTO 0);SIGNAL SResult : INTEGER;SIGNAL OutData : INTEGER;SIGNAL Dlatch : boolean := false;COMPONENT Add2In PORT ( Clk : IN STD_LOGIC; D1 : IN STD_LOGIC_VECTOR(7 DOWNTO 0); D2 : IN STD_LOGIC_VECTOR(7 DOWNTO 0); Q : OUT STD_LOGIC_VECTOR(8 DOWNTO 0) );END COMPONENT;BEGIN i1 : Add2In PORT MAP ( Clk => Clk, D1 => D1, D2 => D2, Q => Q ); init : PROCESS(Clk) BEGIN Clk <= not Clk after 10ns;END PROCESS init; always : PROCESS FILE InputD : text open read_mode is "TestData.dat"; FILE OutputD : text open write_mode is "OutData.txt"; VARIABLE Dline : LINE; VARIABLE Rline : LINE; VARIABLE Data1 : INTEGER; VARIABLE Data2 : INTEGER; VARIABLE OutData : INTEGER;BEGIN WAIT UNTIL Clk‘event and CLk = ‘1‘; readline(InputD, Dline); read(Dline, Data1); read(Dline, Data2); D1 <= conv_std_logic_vector(Data1, 8); D2 <= conv_std_logic_vector(Data2, 8); OutData <= conv_integer(Q); writeline(OutputD, Rline); write(Rline, OutData);END PROCESS always; PROCESSFILE InputR : text open read_mode is "Result.dat";VARIABLE Rline : LINE;VARIABLE Result : INTEGER;BEGIN WAIT UNTIL Clk‘event and Clk = ‘1‘; Dlatch <= true; if Dlatch then readline(InputR, Rline); read(Rline, Result); SResult <= Result; if(SResult /= Q) then assert false report "Two values are different" severity warning; end if; end if;END PROCESS;END Add2In_arch;
TEXTIO 使得VHDL 的模擬功能有了大的飛躍, 在使用VHDL 描述處理器等模型及判斷系統對不規則輸入的響應時,起到了非常大的作用。本文通過簡單的執行個體,說明了TEXTIO 庫及其簡單的應用流程。在當前嵌入式系統廣泛應用的背景下,將更為需要TEXTIO 的應用。
引用地址:http://www.eefocus.com/article/08-03/9143280903334AkJ.html
VHDL學習之TEXTIO在模擬中的應用