抓取Vivado仿真数据导入Matlab分析

其实题目应该叫Verilog仿真后如何导入Matlab分析,但是我搜索的时候用的关键词就是上面的,所以怎么也搜索不出来,最后还是大佬搭救了我一把。

思路就是写一个时序逻辑,每个周期将要保存的数据写入文本文件,之后再用Matlab读取文本文件分析。

首先是Verilog的代码,假设有8个信号需要保存,名字是data1-8,时钟为clk,数据有效指示为data_en,即当data1-8有数据时,data_en为1,而data1-8无数据时,data_en为0。

之后我们根据data_en为1来保存数据,data_en的下降沿来停止保存数据,代码如下:

reg data_en_neg_edge = 1'b0;
reg data_en_r1 = 1'b0;
reg data_en_r2 = 1'b0;

always @ (posedge clk_timer) begin
    data_en_r1 <= data_en;
    data_en_r2 <= data_en_r1;
end    

always @ (posedge clk_timer) begin
    if ((data_en_r2 == 1'b1) && (data_en_r1 == 1'b0))
        data_en_neg_edge <= 1'b1;
end    

integer fid1;
integer fid2;
integer fid3;
integer fid4;
integer fid5;
integer fid6;
integer fid7;
integer fid8;

initial begin
    fid1  = $fopen("1.txt","w");
    fid2  = $fopen("2.txt","w");
    fid3  = $fopen("3.txt","w");
    fid4  = $fopen("4.txt","w");
    fid5  = $fopen("5.txt","w");
    fid6  = $fopen("6.txt","w");
    fid7  = $fopen("7.txt","w");
    fid8  = $fopen("8.txt","w");
end  

always @ (posedge clk) begin
    if(data_en == 1) begin
        $fwrite(fid1,"%h\n",data1);
        $fwrite(fid2,"%h\n",data2);
        $fwrite(fid3,"%h\n",data3);
        $fwrite(fid4,"%h\n",data4);
        $fwrite(fid5,"%h\n",data5);
        $fwrite(fid6,"%h\n",data6);
        $fwrite(fid7,"%h\n",data7);
        $fwrite(fid8,"%h\n",data8);
    end
    else if(data_en_neg_edge ==1) begin
        $fclose(fid1);        
        $fclose(fid2);        
        $fclose(fid3);        
        $fclose(fid4);        
        $fclose(fid5);        
        $fclose(fid6);        
        $fclose(fid7);        
        $fclose(fid8);          
    end 
end    

把这段代码加入仿真文件,仿真之后就会在项目文件夹中找到8个txt文件,内容便是保存下来的信号。

得到txt之后,便可以导入到matlab中分析,我这里由于数据宽度不统一,因此不能使用load函数,而由于数据以16进制存储,因此需要以字符串形式导入,在导入之后再进行转换。

在我这里,导入之后8路数据需要拼接一下,之后才能进行傅里叶变换,用了reshape函数。

顺带一提,由于matlab早期版本中,函数只能在单独的一个.m文件中定义,因此下面的代码会报错。我运行下面代码的版本是2018b,仅供参考。

file_list = dir('*.txt');
data = [];
for i=1:1:length(file_list)
    data = [data;get_content(file_list(i).name)];
    disp(file_list(i).name)
end
data_in_one_line = reshape(data,1,numel(data));
simple_fft_analyzer(data_in_one_line);


function simple_fft_analyzer(data_in_one_line)
    figure;
    plot(1:1:length(data_in_one_line),data_in_one_line);
    figure;
    y = fft(data_in_one_line);
    plot(1:1:length(y(2:end)),abs(y(2:end)));
end

function content = get_content(file_path)
    file_id     = fopen(file_path);
    raw_content = textscan(file_id,'%s');
    fclose(file_id);

    raw_content = raw_content{1};
    line_number = length(raw_content);
    content     = zeros(1,line_number);

    for i=1:1:line_number
        content(i)=hex2dec(raw_content{i});
    end 
end