【FPGA-DSP】第二期:DSP开发流程【全过程】

目录

1. System Generator安装

1.1 system generator的安装

1.1.1 vivado安装System Generator

1.1.2  System Generator配置

1.3 启动

2. FPGA-DSP开发流程

2.1 FPGA-DSP 开发流程介绍

2.2 FPGA-DSP 实际开发流程

1. 软件启动

 2. matlab编写

3. Simulink仿真 

Simulink输入信号

乘法器 

 时延器

累加器

输出示波器设置

完整的Simulink设计 

仿真

4. Vivado

4.1 Simulink设计导出为Vivado工程

4.2 Vivado仿真测试

4.2.1 导入vicado工程文件

​编辑

4.2.2 综合

4.2.3 仿真

5. 基于ROM的Simulink输入方式(便于下载)

5.1 Simulink设计

5.2 Vivado仿真

5.2.1 导入vivado工程

5.2.2 添加ILA ip核

5.2.3 ip核例化

5.2.4 RTL分析

5.2.5 管脚约束

5.3 下载

5.3.1 开发板连接 

5.3.2 ILA 验证

6. FPGA数据分析


本章节首先介绍FPGA进行DSP开发所需要的软件环境,及其安装方式,接着介绍完整的FPGA数字信号处理开发流程

DSP学习教程参考B站视频 

1. System Generator安装

System Generator是Xilinx公司进行数字信号处理开发的一种设计工具,它通过将Xilinx开发的一些模块嵌入到Simulink的库中,可以在Simulink中进行定点仿真,可以设置定点信号的类型,这样就可以比较定点仿真与浮点仿真的区别。并且可以生成HDL文件,或者网表,可以在ISE中进行调用。或者直接生成比特流下载文件。能够加快DSP系统的开发进度。

参考:

(112条消息) System Generator从入门到放弃(一)-安装与使用_system gengerator_碎碎思的博客-CSDN博客https://blog.csdn.net/Pieces_thinking/article/details/83656686

(一)初识System Generator(安装+使用) - 知乎 (zhihu.com)https://zhuanlan.zhihu.com/p/330926863

1.1 system generator的安装

注意:System Generator版本必须与vivado版本保持一致,同时你使用的matlab版本需要兼容安装的System Generator版本。

版本兼容信息需要在安装MATLAB或者Vivado时进行相关的查询,具体可以在ug973(13/81页,每个版本不同)官方文档中查询

我所处的开发环境:

  • Win10
  • matlabR2021b
  • vivado2018.3

因此我需要首先查阅vivado18.03的用户手册

进入用户手册后,查阅该版本对于第三方软件兼容性的说明

从上方的图可以看到MATLAB版本可以兼容R2017a,R2017b和R2018a,不过更高版本的当然也可以了,我用的就是R2021b,旧版本的不太清楚在使用的时候会不会出什么问题,可以自己尝试.当然要兼容ug973这个文件里没有的版本还需要对一个文件做下修改,不然System Generator会不支持自己版本的MATLAB,具体修改方式见1.1.2章节

1.1.1 vivado安装System Generator

System Generator是在安装VIVADO时就可选的,如果安装VIVADO的时候没安,就自己再补安下,可以看以下的操作步骤,安装过程参考

(一)初识System Generator(安装+使用) - 知乎 (zhihu.com)https://zhuanlan.zhihu.com/p/330926863

我的vivado2018.3之前是没有安装该套件的,因此我需要安装System Generator for DSP。 

安装好之后程序会自动寻找本机中的matlab

由于matlab的版本与vivado不一致,因此无法找到对应版本的matlab,接下来我将会修改配置文件来使得System Generator添加2021b版本的matlab 

1.1.2  System Generator配置

首先查看matlab的版本信息

matlab软件版本为2021b ,在matlab命令行输入下面的命令即可获得安装路径:

 接着打开vivado的安装路径,找到ml_supported.xml文件,然后编辑,往里面添加你自己MATLAB版本的信息

​ 

添加完后,保存,然后打开System Generator 2018.3 MATLAB Configurator,在开始菜单中的Xilinx Design Tools下可以找到。 添加matlab安装路径即可

点击apply即可成功安装~

1.3 启动

  • 首先在开始菜单选择System Generator,双击运行,该程序自动打开matlab

  • 在matlab中启动Sumulink

  • 选择blank model建立新模型

  • 选择Simulink库中的Xilinx Blockset 

注意:如果库中没找到这个Xilinx Blockset的话说明你的vivado与matlab不匹配,或者System Generator没有成功安装。 

2. FPGA-DSP开发流程

2.1 FPGA-DSP 开发流程介绍

第2期 - 开发流程 - 基于FPGA的数字信号处理系统开发笔记_哔哩哔哩_bilibilihttps://www.bilibili.com/video/BV1SK4y1s7nS/?spm_id_from=333.999.0.0&vd_source=71acea6682c8121539b919e1e8ca93ef基于Matlab的完整FPGA-DSP开发流程如下:

注意:ILA回传给matlab的数据,每次最大回传深度为2^17,超过这一最大值后,ILA无法一次性传回所有数据。同时ILA是使用的自身FPGA资源,因此当ILA消耗过多资源时可能会使得FPGA时序或运行速度无法满足要求。

上面的流程图可以理解为下面红色注释 

一般情况下,Simulink的设计与vivado仿真结果一致

2.2 FPGA-DSP 实际开发流程

目标:首先使用matlab进行预设计,设计出预期想要达到的结果,接着使用Simulink搭建,来实现我们的预设计。 

1. 软件启动

首先启动vivado软件,再通过system generator来启动matlab

正确启动后的matlab命令行内显示如下字样

在父文件夹(DSP_learn)中创建三个文件夹,分别保存我们的不同类型文件

  

 2. matlab编写

  • .m文件脚本编写 
%% DSP 开发过程学习
% 参考教程 https://www.bilibili.com/video/BV1SK4y1s7nS/?p=2&spm_id_from=pageDriver&vd_source=71acea6682c8121539b919e1e8ca93ef
%----------------------------------------------------------------------------------------------------------------------------
clc;clear all;close all;

%% system parameters
N = 1024;% samples
Fs = 10000; % sample rate kHz
Ts = 1/Fs;

%% Input 
A =1;
t = (0:1024-1)*Ts;
f = 50;
n = Fs/f;%一个周期内的样本点数

x = A*sin(2*pi*f*t);

% figure
figure(1)
plot(t,x);
hold on
%% Multiply,add,delay
C = 2;
D = n/2;%延迟半个时钟周期的样本点

y_mul = zeros(1,N);
y_delay = zeros(1,N);
y_add = zeros(1,N);
y_out = zeros(1,N);
% y_0 = C*x;这种方式在FPGA中不适用,FPGA不是矩阵运算,而是按照时钟信号进行循环运算的
for i = 1:N
    %乘法
    y_mul(i) = C*x(i);  %在FPGA中,一次CLK信号完成一次乘法操作,因此我们在matlab编写的时候也需要使用循环乘积的形式,即for循环
    %延迟,当i大于延迟条件D时,可以开始延迟
    if(i>D)
        y_delay(i) = y_mul(i-D);
    end
    y_add = y_delay + y_mul;
end
y_out = y_add;
figure(1)
plot(t,y_out);
legend('input signal','output signal')

输出预设计图像:

半个周期后的sin函数由于图像时延了半个周期并相互叠加,因此波峰波谷相互抵消。 

3. Simulink仿真 

参考视频教程17:00

注意:在接好连线后,我们需要显示端口数据类型(ports data types),参考mathwork官网教程(与视频中的修改方式不同,原因是matlab的版本不一致)

牢记:把仿真变量放在matlab中,Simulink的构建只是调用matlab工作区中的变量

  • Simulink输入信号

我们需要将matlab工作区的参数作为输入信号传递给simulink,因此我们需首先在.m文件中添加我们需要传递的输入信号参数,该参数应该包含了输入信号x及其离散的时间样本点,(第一列为时间,第二列为信号值)添加的代码如下:

%% Simulink 输入信号变量
x_in(:,1) = 1:N;%第一列为时间序列
x_in(:,2) = x;%第二列为输入信号

Simulink中设置如下:

我们给这个模块连接一个示波器,运行1024个样本点,检查是否和我们matlab仿真的输入信号x一致 

  • 乘法器 

matlab代码 Simulink实现
  •  时延器

matlab代码 Simulink实现
  • 累加器

matlab代码 Simulink实现 Simulink实现
  • 输出示波器设置

  • 完整的Simulink设计 

注意每一个连线之间的数据类型,matlab的双精度浮点输入给FPGA时,通过input gateway转换成定点数,FPGA输出给matlab同理。参考我的这篇文章(97条消息) 【FPGA-DSP】第一期:DSP基础_fpga中的dsp模块_༜黎明之光༜的博客-CSDN博客https://blog.csdn.net/weixin_44810982/article/details/129748023但是,值得注意的是输入input getway的数据类型是fix_16_14,然而输出output getway是fix_33_28,两者位宽并不一致,因此我们需要对输出进行截位操作来让位宽保持一致。添加了截位模块(Convert)后的设计如下

  • 仿真

仿真点数(停止时间)仍然为1024个点,仿真结果如下:

matlab仿真图像 截位前的Simulink图像 截位后的Simulink图像

4. Vivado

4.1 Simulink设计导出为Vivado工程

将第三章中的设计输出,并在vivado中查看结果

双击图标

注意:如果导出不成功的话可能是因为Vivado没有导入许可证,我在生成vivado文件的时候就遇到了这问题 。

参考解决方法:(98条消息) (一) vivado2018.3安装注册指南_vivado注册 2035_jacktwan的博客-CSDN博客https://blog.csdn.net/weixin_42668358/article/details/125512721

4.2 Vivado仿真测试

4.2.1 导入vicado工程文件

4.2.2 综合

4.2.3 仿真

注意:我们使用system generator时,在matlab simulink中已经根据我们的输入输出生成了testbench文件,因此我们直接运行就好

因此直接运行行为仿真即可,仿真结果如下:

易知,这与matlab的Simulink中的结果一致,但当我们将vivado生成的bit流文件下载到开发板的时候往往容易出现问题。下面就简要讲一下通过ROM实现vivado文件下载到FPGA开发板。

5. 基于ROM的Simulink输入方式(便于下载)

5.1 Simulink设计

我们需要将Simulink的输入(From Workspace)修改为通过ROM的方式输入,这样所有的数据都以.coe文件的形式存在ROM的IP核中。Simulink中修改方式如下:

注意:示波器(Scope)的输入信号必须通过input/output getway,不能直接与FPGA内部接线。因为这里设计数据的转换,不能直接连接。

新添加的模块解释如下: 

ROM Counter

ROM存储matlab工作区中输入信号x的1024个值,Counter从0~1023循环计数作为地址信号来访问ROM对应地址中变量x的值。因此当Counter从0计数到1023意味着ROM输出了一次完整的x信号,包含1024个数据点。

示波器的输出结果如下:

5.2 Vivado仿真

5.2.1 导入vivado工程

按照刚才的方式在Simulink中生成vivado工程文件,再通过vivado打开文件,同理。

5.2.2 添加ILA ip核

注意:我们使用ILA ip核只需要对输入输出数据进行分析,输入信号深度为1024,同时由于FPGA的输入输出均为fix_16_14(16bit)因此第二页probe0/1均为16bit位宽 

5.2.3 ip核例化

在顶层模块中添加我们的ip核

同时将输入信号修改为线网型变量(wire)

5.2.4 RTL分析

 更进一步的,System Generator生成的IP核如下图所示

5.2.5 管脚约束

我们只有一个时钟信号作为输入, System Generator IP核中生成的波形不作为输出信号,仅作为FPGA内部ILA逻辑分析仪的输入信号,因此我们需要添加的管脚约束仅有CLK一个

添加管脚约束如下:

 CLK对印的管脚参考自己的FPGA开发板说明书

5.3 下载

生成bit流文件烧写进我们的FPGA开发板 

5.3.1 开发板连接 

5.3.2 ILA 验证

下载好bit流文件后,vivado会自动打开ILA窗口

注意:自从vivado2017.4以后都取消了ila波形仿真图的real setting,因此查看定点数时需要通过修改matlab代码或者使用modelsim联调。

到此为止,说明我们的理论设计全链路全部完成。但是如果我们想对FPGA进行进一步分析,如FPGA内部数据导出,详见下一章

6. FPGA数据分析

我们对ILA 的数据进行回传分析,导出数据方法如下:

  • 首先在ILA窗口中将波形的数据类型修改为有符号的十进制
  • 接着再导出数据

导出之后,该csv文件会出现在vivado的工程文件夹中

然后复制到matlab工作文件夹中

对csv文件进行读取,读取代码如下:

%% ILA csv文件matlab读取
% 参考教程 https://www.bilibili.com/video/BV1SK4y1s7nS/?p=2&spm_id_from=pageDriver&vd_source=71acea6682c8121539b919e1e8ca93ef
%----------------------------------------------------------------------------------------------------------------------------

%% 所需输入参数
N = 1024;%深度
m = 16;%位宽 fix_16_14

%% 导入数据(ILA 数据需设置为有符号十进制)
row = 1;
col_i = 3;%第四列
col_o = 4;%第五列
input_0 = csvread('iladata.csv',row,col_i,[row,col_i,row+N-1,col_i]);
output_0 = csvread('iladata.csv',row,col_o,[row,col_o,row+N-1,col_o]);
% 导出了16位的数据,其中第1位为符号位,整数1位,14个小数位

%% 数据处理
%提取符号位,并将其去掉
input_1 = abs(input_0);
output_1 = abs(output_0);
signed_i = input_0./input_1;
signed_i(find(isnan(signed_i)==1))=0;%去除掉符号位后,变成15位二进制数

signed_o = output_0./output_1;
signed_o(find(isnan(signed_o)==1))=0;%去除掉符号位后,变成15位二进制数

% 十进制转化为2进制
input_1_b = dec2bin(input_1); 
output_1_b = dec2bin(output_1);

input_int = input_1_b(:,1);
input_dec = input_1_b(:,2:15);%第一位为整数,后2~15位均为小数

output_int = output_1_b(:,1);
output_dec = output_1_b(:,2:15);

input_I = bin2dec(input_int);   %整数位
input_D = zeros(N,1);   %小数位
%将小数位2进制转换为十进制小数
for i =1:N
   for j = 1:14 
       input_D(i) = input_D(i) + 2^(-j)*str2num(input_dec(i,j));
   end 
end

% 输入信号plot
input = signed_i.*(input_I+input_D);
figure(1)
subplot (2,1,1)
plot(input );

%% 输出信号
output_I = bin2dec(output_int);   %整数位
output_D = zeros(N,1);   %小数位

%将小数位2进制转换为十进制小数
for i =1:N
   for j = 1:14 
       output_D(i) = output_D(i) + 2^(-j)*str2num(output_dec(i,j));
   end 
end
% 输出信号plot
output = signed_o.*(output_I+output_D);
figure(1)
subplot (2,1,2)
plot(output );

 输出结果如下:

可知,数据导出的图像与ILA图像保持一致,但与只使用matlab仿真存在相位差异,这是正常现象,因为FPGA存在时延等非理想因素,与matlab仿真会存在误差,但是波形一致即可。

猜你喜欢

转载自blog.csdn.net/weixin_44810982/article/details/129746580