VIVADO中的IP核在MATLAB中仿真

項目簡述

我們都會用MATLAB進行算法驗證,但是經常會發現如果VIVADO中調用了IP核,那麼最終會發現VIVADO與MATLAB之間的數據不可以統一的對應起來。那麼,MATLAB驗證的效果就會大大下降,那麼可不可以想辦法將VIVADO中的IP核封裝成一個函數在MATLAB中調用呢?答案是可以的。這篇博客主要以FFT的IP核爲例講解封裝成一個函數並且成功在MATLAB中調用。

本次實驗所使用的軟硬件工具如下:
1、VIVADO 2019.1
2、MATLAB 2015b
3、VS2015

VIVADO建立FFT IP核

首先建立VIVADO工程,然後選擇FFT IP核開始定製
在這裏插入圖片描述
這裏定製一下IP的信息,這裏需要注意定製IP的信息與MATLAB中調用的文件的設置需要一樣,這樣纔可以將MATLAB中的數據與VIVADO相對應。
在這裏插入圖片描述
在這裏插入圖片描述
在這裏插入圖片描述
上面每步定製的意思我們在前面講解FFT IP的時候已經進行了相應的講解,需要學習的同學可以查閱前面的文章,這裏我們不再贅述。最後點擊生成FFT 的IP核。這裏特別要注意,數據的輸入輸出是AXI-Stream格式的數據,也就是說是以字節對齊的,比如所輸入數據實部12位、虛部11位,那麼在輸入數據線上的表示就是實部16位、虛部16位。這也是很多初學者不明白數據位寬與自己設置不一樣的原因。

MATLAB調用FFT IP核

上面我們已經生成了FFT IP,然後再生成目錄的cmodel文件中有相應的文件,但是需要我們提前編譯一下,這裏選擇的編譯環境是VS2015。cmodel中的文件有兩個,如下:
在這裏插入圖片描述
上面的是linux系統,下面的是windos系統。我們將下面的文件進行解壓放到MATLAB的文件夾中。然後打開MATLAB切換到相應的文件夾下:
在這裏插入圖片描述
然後再MATLAB的命令行輸入 run make_xfft_v9_1_mex,然後出現如下結果:
在這裏插入圖片描述
在生成文件中多出了.mexw64後綴的文件證明我們生成相應的MATLAB函數成功。然後查閱技術手冊,會發現函數的調用主要有以下幾個端口:
在這裏插入圖片描述

函數調用的輸出如下:

上面的參數在使用的時候要與VIVADO的IP定製的時候相一致,那麼在MATLAB中調用該函數的時候纔可以與VIVADO中仿真出來的結果相一致。而且前面我們定製IP的時候選擇的是可以實施配置,那麼只需要我們MATLAB與VIVADO實時配置的參數相一致,MATLAB與VIVADO兩個輸出的結果完全一致,最終實現了VIVADO中的IP核在MATLAB中調用的現象。
在這裏插入圖片描述
下面以FFT爲例給出相應的代碼:

clc;
clear all;
addpath(genpath(pwd));
sim_options = struct(...
    'MODE',        '2k'   ...         %fft模式  1k 2k 4k 8k
    );
tx_nFrame=1;
%------------------------------------------------------------------------------
% Parameters Definition
%------------------------------------------------------------------------------
switch sim_options.MODE
    case '1k'
        NFFT   = 1024;       % FFT number of points
    case '2k'
        NFFT   = 2048;       % FFT number of points
    case '4k'
        NFFT   = 4096;       % FFT number of points
    case '8k'
        NFFT   = 8192;       % FFT number of points
    otherwise, error('sim_options UNKNOWN MODE');
end
%------------------------------------------------------------------------------
% Input arguments checking
%------------------------------------------------------------------------------
q_in =  quantizer( 'mode','fixed','roundmod', 'floor','overflowmode','wrap','format',[12 11]);
q_out = quantizer( 'mode','fixed','roundmod', 'floor','overflowmode','wrap','format',[12 11]);
%gen data 


% DataIn_x = -1+2*rand(1,NFFT);
% DataIn_x = quantize(q_in,DataIn_x);
% 
% fid1 = fopen('RE_DATA.txt','w');
% fprintf(fid1,'%d\n',DataIn_x*2^11);
% 
% DataIn_y = -1+2*rand(1,NFFT);
% DataIn_y = quantize(q_in,DataIn_y);
% 
% fid1 = fopen('IM_DATA.txt','w');
% fprintf(fid1,'%d\n',DataIn_y*2^11);


fid1 = fopen('RE_DATA.txt','r');
DataIn_x = fscanf(fid1,'%d');

fid1 = fopen('IM_DATA.txt','r');
DataIn_y = fscanf(fid1,'%d');

DataIn = DataIn_x/2^11 + DataIn_y/2^11*1i;
DataIn = DataIn.';

% fid1 = fopen('com_data_in.txt','w');
% fprintf(fid1,'%d\n',imag(DataIn)*2^11);
%------------------------------------------------------------------------------
% Procedure
%------------------------------------------------------------------------------
fftDI = DataIn;

fftDO = zeros(size(DataIn,1), NFFT);
DataOut = zeros(size(DataIn,1), NFFT);

% IFFT
for numfft = 1:size(fftDI,1)
    fftDO(numfft,:) = fft_cmodel(fftDI(numfft,:),12,0);
    DataOut(numfft,:) = quantize(q_out,fftDO(numfft,:));
end
%==================================================================================
%                 t2_tx_removepadding
%==================================================================================
fft_data_com =DataOut(:)*2^11;

fft_cmodel代碼:

function [output,blkexp,overflow] = fft_cmodel(input,INPUT_WIDTH,direction)
 
% Generics for this smoke test
generics.C_NFFT_MAX=11;
generics.C_ARCH = 1;
generics.C_HAS_NFFT = 1;
generics.C_USE_FLT_PT = 0;
generics.C_INPUT_WIDTH = 12; % Must be 32 if C_USE_FLT_PT = 1
generics.C_TWIDDLE_WIDTH = 16; % Must be 24 or 25 if C_USE_FLT_PT = 1
generics.C_HAS_SCALING = 1; % Set to 0 if C_USE_FLT_PT = 1
generics.C_HAS_BFP = 0; % Set to 0 if C_USE_FLT_PT = 1
generics.C_HAS_ROUNDING = 1; % Set to 0 if C_USE_FLT_PT = 1

channels = 1;

q =  quantizer( 'mode','fixed','roundmod', 'convergent','overflowmode','saturate','format',[generics.C_INPUT_WIDTH, generics.C_INPUT_WIDTH-1]);

input = quantize(q,input);

nfft = log2(length(input));

if generics.C_ARCH == 1 || generics.C_ARCH == 3
scaling_sch = ones(1,floor(nfft/2)) * 2;
if mod(nfft,2) == 1
  scaling_sch = [scaling_sch 1];
end
else
scaling_sch = ones(1,nfft);
end

% Run the MEX function

 [output, blkexp, overflow] = xfft_v9_1_bitacc_mex(generics, nfft, input, scaling_sch, direction);


上面便是在MATLAB中調用VIVADO中的IP核的代碼,最主要的就是下面的模塊:
在這裏插入圖片描述
其餘的代碼都是構建這個函數的輸入變量。上面的代碼模塊大家不懂也沒有關係,這篇博客主要是爲了讓大家瞭解VIVADO中的IP如何在MATLAB中仿真。其中這種功能最主要的參考就是本IP的技術手冊中model部分,如下:
在這裏插入圖片描述

小結

要想驗證上面結果的正確性,我們需要將上面輸出的結果與VIVADO中的相互對比,但是這裏就涉及到了FFT的實時配置,這在我們之後的博客中進行講解。

總結

創作不易,認爲文章有幫助的同學們可以關注、點贊、轉發支持。爲行業貢獻及其微小的一部分。或者對文章有什麼看法或者需要更近一步交流的同學,可以加入下面的羣:
在這裏插入圖片描述

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