通過文件讀寫方式實現Matlab和Modelsim的聯合仿真


雖然Modelsim的功能非常強大,仿真的波形可以以多種形式進行顯示,但是當涉及到數字信號處理的算法的仿真驗證的時候,則顯得有點不足。而進行數字信號處理是Matlab的強項,不但有大量的關於數字信號處理的函數,而且圖形顯示功能也很強大,所以在做數字信號處理算法的FPGA驗證的時候借助Matlab會大大加快算法驗證的速度。

 

    關於Matlab和Modelsim聯合仿真,我從網上看到兩種方法,一種是通過Link for Modelsim建立Matlab和Modelsim的聯合仿真接口;另一種就是通過文件讀寫的方式實現Matlab和Modelsim的聯合仿真。我沒有仔細研究過第一種方法,我大概看了一下,感覺過程比較復雜,不過功能肯定也很強大,網上有一篇關於Link for Modelsim的文章http://space.ednchina.com/Upload/2009/11/16/9e8d0364-20ed-4583-a85e-4d1fc50783a7.rar" target=_blank>,有興趣的朋友可以去看一看。關於第二種方法,只是通過幾個文件讀寫函數就可以實現了,而且基本可以滿足當前仿真的要求,所以這里主要討論一下我所使用的這種方法,希望能夠拋磚引玉吧,因為我也只能算個初學者而已。

 

    1. Matlab產生數據用作Modelsim仿真

 

    在FPGA進行算法驗證的時候,經常需要輸入仿真數據,這些數據可以用FPGA產生,但是如果數據產生過程很復雜的話,需要耗費很大的精力,並且產生的數據的准確性也不能保證。例如,如果要驗證一個通信接收機的相關算法,那么我們就需要先產生發送數據,也就是說得先做一個發射機,如果這個過程也由FPGA實現的話,也是一個很復雜的過程。這時候我們就可以借助Matlab,利用Matlab內部自帶的各種函數,產生需要的信號,再經過定點化,就作為FPGA接收模塊的輸入信號了。這樣做無疑會節約很多時間和精力。

 

    下面用一個簡單的例子說明如何用Matlab產生的數據用作Modelsim仿真。

 

    首先利用matlab產生一個周期256點8bit的正弦波數據,然后以16進制形式寫入sin.txt文件

 

          N = 256;

 

          n = 1:256;

 

          x = fix(128 + (2^7 - 1) * sin(2*pi*n/N));

 

          fid = fopen('sin.txt','wt');

 

          fprintf(fid,'%x\n',x);

 

         fclose(fid);

 

    下圖是截取的產生的數據文件的內容

 

 

    然后將產生的sin.txt文件復制到Modelsim的工程下,在Verilog文件中先定義一個8bit X 256數組,然后通過$readmemh命令,將文件中的數據讀入,相關的Verilog代碼如下:

 

reg [7:0] data_mem[0:255]; //定義一個8bit X 256的數組

 

initial

 

    begin

 

    $readmemh("sin.txt",data_mem); //將sin.txt中的數據讀入存儲器data_mem

 

    end

 

    關於$readmemh的用法可以參見Verilog的參考書,這里就不詳細說了。

 

后面就可以用data_mem作為你的測試數據了。例如可以通過以下代碼,將data_mem的數據送給data_out:

 

always @(posedge clk)

 

begin

 

    if(rst)

 

        begin

 

        data_out <= 8'd0;

 

        i <= 8'd0;

 

        end

 

    else

 

        begin

 

        data_out <= data_mem[i]; //將存儲器中的數據輸出

 

        i <= i + 8'd1;

 

        end

 

end

 

    這樣利用data_out就可以輸出一個正弦波波形,下圖是Molesim仿真產生的正弦波波形:

 

    2. Matlab對Modelsim仿真生成的數據進行分析

 

        Matlab對Modelsim仿真生成數據的處理也是通過文件讀寫實現的。即通過Verilog語句,將仿真過程中的某個信號寫入文件,然后在Matlab中在把這個文件的數據讀出來,就可以在Matlab中進行分析了。

 

    下圖也通過一個簡單的例子,說明一下整個過程。

 

    以下的Verilog語句實現將信號data_out的數據寫入data_out.txt文件

 

    integer w_file;

 

    initial w_file = $fopen("data_out.txt");

 

    always @(i)

 

    begin

 

        $fdisplay(w_file,"%h",data_out);

 

        if(i == 8'd255)    //共寫入256個數據

 

            $stop;

 

    end

 

    下圖是截取的data_out.txt的部分內容:

 

 

 

    然后就可以編一小段Matlab的程序將data_out.txt中的數據讀取進行分析了。下面一段Matlab的程序是將數據讀取,並通過圖形顯示出數據的波形。

 

    fid = fopen('data_out.txt','r');

 

    for i = 1 : 256;

 

        num(i) = fscanf(fid, '%x', 1);    %這句話的意思是從fid所指的文件以16進制方式讀出一個數據。

 

    end

 

    fclose(fid);

 

    plot(num);

 

    當利用fscanf函數時要注意兩點,

 

    第一:保證讀取的數據格式和文件中保存的數據格式是相同的,例如這里文件中保存的格式是十六進制,所以讀取的時候也應該以十六進制的形式讀出。

 

    第二:要保證文件中數據的個數和設定的讀取的數目(這里是256)保持一致。例如,要將生成文件data_out.txt中多余的換行符去掉(一般最后會多出一行),否則Matlab會將空的行也當做一個數據,從而兩個數目不一致,導致Matlab報錯。

 

    下圖是Matlab將data_out.txt中的數據讀出,並顯示出的波形:

 

 

 

    當然,有了Matlab這個強大的工具,也就可以很方便的看信號的頻譜等信息了。

 

    另外在說一點,就是關於通過Verilog將數據寫入文件有多種方法,上面用的是$fdisplay這個系統函數,當然還有$fmonitor和$fwrite等幾個命令,下面簡單說一下這幾個命令的不同。




  • $fdisplay

    這個命令需要有觸發條件,才會把數據寫入文件,例如,上例的觸發條件就是always(i),當i變化的時候才寫入。每寫入一次數據會自動增加一個換行符。


  • $fmonitor

    這個命令不需要觸發條件,只要有變化就可以將數據寫入文件。例如可以通過以下語句:


    initial $fmonitor(w_file,"%h",data_out);


    這樣可以將整個仿真過程產生的data_out數據都寫入文件中。


  • $fwrite

    這個命令和$fdisplay基本相同,也是需要觸發條件才會寫入,不同的是每寫入一個數據不會自動添加換行符。例如可以通過以下語句:


    always @(posedge clk)


    begin


        $fwrite(w_file,"%h\n",data_out);


    end

 

    關於這幾個命令的詳細介紹,大家可以參考Verilog的相關數據。

 

        簡單總結一下上面用到的幾個函數:



  • 關於Matlab的函數有:fopen, fscanf,fclose。 
  • 關於Modelsim的函數有:$fopen,$fclose,$readmemh,$readmemb,$fmonitor,$fdisplay,$fwrite。

 

    上面就是我關於Matlab和Modesim進行聯合仿真的一些心得,如果大家還有其他更好的方法,希望不吝賜教啊!

 

    下面是相關的代碼,包括Matlab的代碼和Verilog的代碼。

 轉自:http://bbs.ednchina.com/BLOG_ARTICLE_285466.HTM


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM