VHDL中txt文件的讀寫

  在對VHDL代碼進行ModelSim仿真的時候,如果測試一個比較簡單的功能,比如簡單地測試一個IPCore,那麼我們只需要

signalName <= x"01"; wait for cam_period*5; 
signalName <= x"10"; wait for cam_period*5;

類似的代碼就可以滿足我們的要求。
  但是呢,假如你要測試一個大的COMPONENT,或者是測試一個數據序列,抑或是一個圖像,那麼這時候,通過文件讀取數據將會使工作簡單很多。與此同時,爲了保存試驗結果,也常常用到文件。尤其是對於FPGA的圖像處理,文件讀取必不可少。首先將一副正常圖像轉換爲一個txt文件,然後作爲FPGA的輸入,經過處理的圖像數據再保存成txt文件,再將這個txt文件轉換爲圖像,這樣就可以直觀地看到圖像處理的效果了。
  那麼今天筆者就來講一下VHDLtxt文件的讀取和寫入。

file_open(file_status,FILE_OUT,"data_record.txt",write_mode);

  上面那句代碼是整個文件讀取與寫入系統中最重要的,意思是以write Mode形式打開“data_record.txt”這個文檔。
  TXT文本的讀寫方式一共有三種,分別是READ_MODEWRITE_MODEAPPEND_MODE。按照字面意思就可以理解,分別是讀取模式、寫入模式與擴展模式。APPEND_MODEWRITE_MODE的區別在於,WRITE_MODE會清除掉文本中原來存在的內容,而APPEND_MODE不會。

file_open(file_status,FILE_OUT,"data_record.txt",read_mode);
file_open(file_status,FILE_OUT,"data_record.txt",append_mode);

這是另外兩種模式。

--讀取數據
stim_process : process(cam_clk)
variable i : integer:= 0;
file TEST_IN  : TEXT;
variable LINE_IN: line;
variable dat_in : std_logic_vector(31 downto 0);
begin
  if(rst_n = '0' and dataIn = '0') then
    file_open(TEST_IN, "image-binary-data.txt", READ_MODE);
    dataIn <= '1';
  elsif(rising_edge(cam_clk)) then
    if((i mod ((512*135) + 300)) < 300) then
      vs_i <= '0';
    else
      vs_i <= '1';
    end if;
    if (((i mod ((512*135) + 300)) < 300) or (((i mod (512*135+300))-300) mod 135) < 7) then
      hs_i <= '0';
      dv_i <= '0';
      da_i <= (others => '0');
    else
      hs_i <= '1';
      dv_i <= '1';
      readline(TEST_IN, LINE_IN);
      read(LINE_IN, dat_in); 
      da_i <= dat_in;
    end if;
    i := i + 1;
  end if;
end process;

  這是從 image-binary-data.txt 讀取數據的一個過程,當然其中還包含了一個判斷的過程,只在某些時刻纔會從文本中讀取數據。
  在這邊有一個小技巧,就是設置一個標誌signal,這裏我設置的是 dataIn , 設置其初始值爲'0',當文本打開之後,將該signal設置爲’1’,在 rst_n = '0'以及dataIn = '0' 這兩個條件都滿足的情況下才進行文本的打開,之後就開始進行文本按行地讀取,並輸入到下一個COMPONENT中。
  下面介紹一下文本的寫入。

--保存輸出數據
process(cam_clk)
FILE FILE_OUT : TEXT;
variable file_status:file_open_status;
variable buf:LINE;
begin
   if(rst_n = '0' and dataOut = '0') then
      file_open(file_status,FILE_OUT,"data_record.txt",write_mode);
      file_close(FILE_OUT);
      file_open(file_status,FILE_OUT,"data_record.txt",append_mode);
      dataOut <= '1';
   elsif(rising_edge(cam_clk))then
     if(dv_o='1') then
       write(buf,da_o);
       writeline(FILE_OUT,buf);
     end if;
     if(sim_end = '1') then
       file_close(FILE_OUT);
     end if;
   end if;
end process;

  和上面的代碼一樣,這裏也有一個dataOut的標誌signal,在rst_n = '0' and dataOut = '0' 這兩個要求同時滿足的時候纔打開文本。但是看到在 rst_n = '0' and dataOut = '0' 這個條件下面做了四件事情,打開文本,再關閉,再打開,然後將標誌signal‘1’,而且兩次打開的模式不同,一次是write_mode,一次是append_mode,爲什麼要這樣處理呢。下面給大家講一下這個緣由。
  文本打開了,肯定是要關閉的,那如果用write_mode這種模式打開的話,file_close(FILE_OUT)的時候,也就是文本關閉的時候,文本中只會留下一行數據。而換成append_mode這種模式的話,在file_close(FILE_OUT)的時候,之前寫入文本的數據都會留下來。那爲什麼先要用write_mode這種模式打開呢,我用這種模式打開了,然後再關閉,整個文檔裏的內容就清除了,就可以保證接下去操作的是空文本,這就是先用write_mode打開的原因。
  要注意的是,在寫入的狀態下,在沒有關閉文本的情況下,文本的大小一直是0K,但是呢,打開還是能看到文本中的數據信息的,裏面的數據也可以複製出來,但是這些數據並不真正存在於這個文本中,這個文本也被ModelSim佔用,不能複製,剪切等操作。
  這裏設置了一個結束仿真的標誌signal sim_end,這個默認值也是‘0’。有兩種用法,一個是在仿真代碼裏寫明什麼情況這個signal置一,比如延時多少之後,或者是某個標誌位變化了之類的。還有一種比較暴力,就是利用ModelSimsignalForce,覺得仿真了一段時間差不多了,就將該值強制Force‘1’,然後文本就關閉了,仿真就結束了。
  在write_modeappend_mode的時候,要寫入的文本是會自動生成的,不需要事先生成,這樣就比較方便,比如說仿真的時候,把輸出文檔命名成時間,或者是跟更改參數有關的文件名,多仿真幾次之後再去處理這些生成的文本。
  要提醒的是,輸入進來的數據和輸出的數據都是二進制數據,所以要先用Matlab或者是Visual Studio等工具先將數據轉換成二進制數據。同理,輸出的數據也要先轉換爲普通數據,才能很好地去觀察其特性。


如何你覺得這個文章對你有幫助,支持一下作者~

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章