Vivado ROM IP的生成和调用

1 需求

1、如何将MATLAB生成的数据导入到FPGA中;
2、vivado如何对数据进行分析;
3、如何验证vivado数据的可靠性;
4、如何将vivado的数据导出到MATLAB进行分析

2 具体实现

2.1 MATLAB生成的数据导入到FPGA

2.1.1 生成coe文件

   .coe 是 FPGA 设计中常用的存储文件,用于 ROM、RAM 等存储器数据的加,所以我们将MATLAB的数据导出为.coe。如何导出呢?MATLAB程序如下:

close all;
clear all;
clc;
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%           参数定义
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
fc=3e6;         % 信号频率
fs=65e6;        % 采样频率
L=1024;          % 采样点数
ADC_bit=16;     % 采样位数

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%              产生信号
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
t=0:1/fs:(L-1)/fs;
noise=randn(1,length(t));
noise=0;
st=sin(2*pi*fc*t)+noise;
y=st/max(abs(st));                 % 归一化
yt=round(y*(2^(ADC_bit-1)-1));     % 12bit量化
figure(1);
plot(st);hold on;
figure(2);
plot(y);hold on;
figure(3);
plot(yt);hold on;


%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%            MATLAB生成coe文件
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%.coe文件中
% 第一行为定义数据格式, 2代表 ROM 的数据格式为二进制。
% 从第 3 行开始到第最后一行,是这个  L(数据长度为1024* ADC_bit(16bit) 大小 ROM 的初始化数据。
% 第一行到倒数第二行的数字后面用逗号,最后一行数字结束用分号。
fid=fopen('data0.coe','w');
fprintf(fid,'Memory_Initialization_Radix = 2;\r\n'); % 二进制
fprintf(fid,'Memory_Initialization_Vector = \r\n');
for p=1:L
    B_s=dec2bin(yt(p)+(yt(p)<0)*2^ADC_bit,ADC_bit);
    for q=1:ADC_bit  % 16位,依次判断这16位的数值
        if B_s(q)=='1'
            data=1;
        else
            data=0;
        end
        fprintf(fid,'%d',data);
    end
    
    %  下面if语句的目的
    %  每行数字后面用逗号(,),最后一行数字结束用分号(;)
    if (p<L)
        fprintf(fid,',\r\n'); 
    else
        fprintf(fid,';\r\n');    % 分号(;)  结束标志位
    end
   
end
fclose(fid);


导出的coe文件为
在这里插入图片描述
在.coe文件中, 第一行为定义数据格式, 2代表 ROM 的数据格式为二进制。
从第 3 行开始到第最后一行,是这个L(数据长度为1024)* ADC_bit(16bit)大小 ROM 的初始化数据。 第一行到倒数第二行的数字后面用逗号,最后一行数字结束用分号。

2.1.2 将coe文件导入到FPGA,并分析

1、打开vivado软件,新建一个工程;
2、添加 ROM IP核
(1)打开IP catalog,搜索ROM。找到 Block Memory Generator,双击打开。
在这里插入图片描述
(2)ROM IP核配置
a、 将 Component Name 改为 rom_ip,在 Basic 栏目下,将 Memory Type 改为 Single Prot ROM。
在这里插入图片描述
b、切换到 Port A Options 栏目下。
将 ROM 位宽 Port A Width 改为 16;
将 ROM 深度 Port A Depth 改为1024;
使能管脚 Enable Port Type 改为 Always Enabled;
取消 勾选Primitives Output Register。
在这里插入图片描述
depth :表示有多少个数据。
width :表示一个数据有多少位。对于AD9238而言,ADC数据有12位
c、切换到 Other Options 栏目下,勾选 Load Init File,点击 Browse,选中之前制作好的.coe 文件。
在这里插入图片描述
d、点击 ok,点击 Generate 生成 ip 核。
3、添加 ILA IP核
目的在于对coe数据进行观察
4、添加源文件、编写源文件

`timescale 1ns / 1ps


module v_rom(
    input sys_clk,  //50MHz时钟
    input rst_n     //复位,低电平有效
    );
    
wire [15:0] rom_data; //ROM读出数据  每个数据有16bit
reg  [9:0]  rom_addr; //ROM输入地址  1024个数据,需要2^10个地址
   
//产生ROM地址读取数据
always @ (posedge sys_clk or negedge rst_n)
begin
    if(!rst_n)
        rom_addr <= 10'd0;
    else
        rom_addr <= rom_addr+1'b1;
end

//实例化ROM
rom_ip rom_ip_inst
(
    .clka (sys_clk ),   //inoput clka
    .addra (rom_addr ), //input [9:0] addra  1024个数据,需要2^10个地址
    .douta (rom_data )  //output [15:0] douta    
);
//实例化逻辑分析仪
ila_0 ila_m0
(
    .clk    (sys_clk),
    .probe0 (rom_addr), // input wire [9:0]  probe0  
    .probe1 (rom_data) // input wire [15:0]  probe1
);    
endmodule

5、添加约束文件

############## clock and reset define##################
create_clock -period 20 [get_ports sys_clk]
set_property IOSTANDARD LVCMOS33 [get_ports {sys_clk}]
set_property PACKAGE_PIN U18 [get_ports {sys_clk}]
set_property IOSTANDARD LVCMOS33 [get_ports {rst_n}]
set_property PACKAGE_PIN N15 [get_ports {rst_n}]

6、保存并生成比特流文件
7、ila波形分析
a、添加触发信号
在这里插入图片描述
b、点击第二个三角形进行触发,设置waveform style为analog;设置radix为signed Decimal。其结果如下

在这里插入图片描述
从上图可以看出,rom_data的数据为一个正弦波,和MATLAB产生的信号是一样的。rom_addr从0增加到511,再从-512变到-1。为什么不是0~2^10-1呢?因为我们radix设置的是有符号十进制,而不是无符号十进制。

2.2 将ila的数据导入到MATLAB分析

1、设置radix为二进制。
2、导出ILa数据
在这里插入图片描述
3、用excel打开iladata.csv
只保留数据栏,第一行删除----------全选中数据,右键点击设置单元格格式-----自定义-----选中0----点击确定----保存退出。

在这里插入图片描述
4、MATLAB分析数据
主函数:

close all;
clear all;
clc;
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% bin2dec函数:将二进制转换为十进制。
% uint16(A)  把A转换为16位非负整型
% Y = typecast(X, DATATYPE) 函数的作用是在不更改基础数据的情况下转换数据类型。
% 大矩阵计算,如果用single类型的数据能节省一半的内存空间
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
filenameCSV = 'iladata.csv';
data = importfile(filenameCSV); 
SIZEdata = size( data );
L = SIZEdata(1);
lie = SIZEdata(2);
y = zeros( L,lie );
for i = 1 : L
    for j = 1 : lie
       x1 = data( i, j );
       x2 = typecast( uint16(bin2dec( x1 )),'int16');
       x3 = single( x2 );
       y( i,j ) = x3;
    end
end


Y=fftshift(fft(y'));
P=abs(Y)/L;

fs = 65e6;  % 采样频率  AD9238的采样频率为65M
f = (0:L-1)*fs/L-fs/2;
t=0:1/fs:(L-1)/fs ; 

figure(1)
plot(t,real(y));grid on;
xlabel('时间(s)');ylabel('幅度');

figure(2)
plot(f/1000,P);grid on;
xlabel('频率/KHz');ylabel('幅度');

子函数:

function data = importfile(filename, startRow, endRow)
% IMPORTFILE1 将文本文件中的数值数据作为列矢量导入。

%  初始化变量。
delimiter = ',';
if nargin<=2
    startRow = 1;
    endRow = inf;
end

%  每个文本行的格式字符串:
%1: 文本 (%q)
%  有关详细信息,请参阅 TEXTSCAN 文档。
formatSpec = '%q%[^\n\r]';

% 打开文本文件。
fileID = fopen(filename,'r');

% 根据格式字符串读取数据列。
% 该调用基于生成此代码所用的文件的结构。如果其他文件出现错误,请尝试通过导入工具重新生成代码。
dataArray = textscan(fileID, formatSpec, endRow(1)-startRow(1)+1, 'Delimiter', delimiter, ...
                     'EmptyValue' ,NaN,'HeaderLines', startRow(1)-1, 'ReturnOnError', false);
for block=2:length(startRow)
    frewind(fileID);
    dataArrayBlock = textscan(fileID, formatSpec, endRow(block)-startRow(block)+1, 'Delimiter', delimiter, ...
                   'EmptyValue' ,NaN,'HeaderLines', startRow(block)-1, 'ReturnOnError', false);
    dataArray{1} = [dataArray{1};dataArrayBlock{1}];
end

% 关闭文本文件。
fclose(fileID);


% 将导入的数组分配给列变量名称
data = dataArray{:, 1};



仿真结果:
在这里插入图片描述
在这里插入图片描述
时域波形为正弦波,信号频率为2983KHz,和最初所设的3MHz接近。说明
MATLAB和FPGA联合仿真成功。

3 注意事项

当我们rom的数据发生变化时,重新在ROM导入数据后,如下图所示
在这里插入图片描述
可能会出现如下问题
在这里插入图片描述
解决方法:

右键?红色文件------点击replace file----找到对应文件即可在这里插入图片描述
效果图:
在这里插入图片描述

  • 13
    点赞
  • 79
    收藏
    觉得还不错? 一键收藏
  • 4
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值