前言
在FPGA開發過程中幾乎都要用到仿真的功能,對於一些簡單的外部激勵(如時鍾、復位、簡單數據或者信號等)直接在testbench中編寫產生就行了,但對於復雜的外部激勵數據,很難在testbench中產生,這時就要通過讀取外部文件里的數據來實現。通過和matlab的配合使用,基本上可以模擬各種外部激勵。
舉例來說:輸入信號是三個不同頻率的正弦波的相加,經過FIR低通濾波器濾除高頻分量,輸出頻率最低的那個正弦信號。這種情況下測試用的輸入信號不能通過testbench編寫產生。
簡單來說有以下兩種方法可以模擬輸入信號:
- 在FPGA內部通過DDS產生三個正弦波,然后將三個波形相加作為輸入信號。
- 利用matlab產生輸入信號,將數據導出為.txt文件,在仿真時讀取文件內的數據作為外部激勵。
顯然第二種方法更加靈活和便捷。下面,具體介紹一下這種方法的使用。
平台:
- Vivado 16.4
- Matlab R2017b
Matlab程序編寫:
- 代碼如下:
%=============設置系統參數==============%
f1=1e6; %設置波形頻率
f2=500e3;
f3=800e3;
Fs=20e6; %設置采樣頻率
L=1024; %數據長度
N=14; %數據位寬
%=============產生輸入信號==============%
t=0:1/Fs:(1/Fs)*(L-1);
y1=sin(2*pi*f1*t);
y2=sin(2*pi*f2*t);
y3=sin(2*pi*f3*t);
y4=y1+y2+y3;
y_n=round(y4*(2^(N-3)-1)); %N比特量化;如果有n個信號相加,則設置(N-n)
%=================畫圖==================%
a=10; %改變系數可以調整顯示周期
stem(t,y_n);
axis([0 L/Fs/a -2^N 2^N]); %顯示
%=============寫入外部文件==============%
fid=fopen('E:\Workspace\Vivado_16.4\TEST\TestBench\sin_data.txt','w'); %把數據寫入sin_data.txt文件中,如果沒有就創建該文件
for k=1:length(y_n)
B_s=dec2bin(y_n(k)+((y_n(k))<0)*2^N,N);
for j=1:N
if B_s(j)=='1'
tb=1;
else
tb=0;
end
fprintf(fid,'%d',tb);
end
fprintf(fid,'\r\n');
end
fprintf(fid,';');
fclose(fid);
此程序中設置了三個頻率分別為1M、500k和800k的正弦波,然后將三個波形相加並且量化后作為輸出。最后將路徑設置為相應文件所在路徑即可,需要注意的是如果對應路徑下沒有相應文件,則會自動新建文件並寫入數據。
-
運行程序:

-
打開對應的文件目錄

可以看到二進制數據文件已經生成。
接下來就可以進行在testbench中讀取外部數據的操作了。
Testbench的編寫:
- 代碼如下:
`timescale 1ns/1ps module TB_readfile(); reg SCLK; reg [13:0] data_out; //--------------時鍾部分----------------// initial SCLK = 0; always #10 SCLK = ~SCLK; //-------------------------------------// parameter data_num = 32'd1024; integer i = 0; reg [13:0] data_men[1:data_num]; reg [13:0] data_reg = 0; initial begin $readmemb("E:/Workspace/Vivado_16.4/2017_8_28_TEST/TestBench/sin_data.txt",data_men); //注意斜杠的方向,不能反<<<<<<< end always @(posedge SCLK) begin data_out <= data_men[i]; i <= i + 8'd1; end //------------------------------------// endmodule
里只需要讀取外部數據,所以Vivado工程里只需要添加仿真文件就行了。
- 運行仿真:

可以看到,仿真的波形和matlab中顯示的波形一致,說明結果正確。
