目录
一、简介二、在Simulink中生成Verilog语言1、在Simulink中建立Kalman滤波器仿真2、将Kalman滤波器部分打包3、生成Verilog程序3.1、参数配置3.2、HDL Code代码生成 三、Vivado中实现Kalman滤波仿真1、在Vivado中创建工程并将Kalman.v与Kalman_tb.v文件添加到工程中2、在Matlab中生成波形文件,代码如下3、重写tb仿真文件4、Vivado中仿真编译 四、小结一、简介
此内容基于博文:基于Matlab Hdl Coder实现FPGA程序开发(卡尔曼滤波算法实现)实现,Simulink仿真构建参考于上链接中。
本博文解决了上博文中无法生成Verilog语言的问题,并对于自动生成的Verilog——testbench文件进行了优化——通过matlab产生信号及白噪声,并将信号数据载入到Vivado-tb文件中,最终通过vivado软件自带仿真器进行观察。
二、在Simulink中生成Verilog语言
1、在Simulink中建立Kalman滤波器仿真
此处进行简单演示,建立好的Kalman滤波器模型如下图所示。
2、将Kalman滤波器部分打包
将创建好的滤波器模型打包为一个模块,便于之后将此模块转换为Verilog语言——全选后点击“create subsystem”;
生成模块后可添加信号及示波器观察Kalman功能是否正常。
3、生成Verilog程序
3.1、参数配置
1、点击simulation进行Model Configuration Parameters配置;
2、点击Solver,将Solver selection_Type改为Fixed-step,其余默认,点击apply应用;
3、点击Hardware Implementation,将Device vendor设置为ASIC/FPGA,其余默认,点击apply应用;
4、设置芯片型号及时钟频率,其余默认,点击apply应用;
5、将复位电平设置为低电平有效,其余默认,点击OK完成参数配置。
6、关联Vivado软件,进行联合编译:在matlab命令窗口输入命令,hdlsetuptoolpath (‘ToolName’,‘…’,‘ToolPath’,‘…’),具体用法可右键参照帮助。
3.2、HDL Code代码生成
1、Code–HDL Code–HDL W… A… 打开工作区,进行相关配置,并检查错误;
2、选择Kalman模块,生成相应程序;
3、在工作区1.1中将综合工具选为相应编译器,之前的相关配置会自动填充,之后点Apply应用;在1.2中将时钟频率设为相应频率,Apply即可;
4、右击Set Target ,Run All完成此部分设定;
5、在3.1.1中,将语言选择为Verilog;在3.1.5中,将Generate RTL code和Generate test bench勾选;在3.2中,勾选Generate RTL Code与Generate Testbench,点击Apply;在3.3中勾选Skip This Task;其余默认即可,记得完成每一步配置后点击Apply;然后Run all第3部分;
6、此时3.2部分会报错,这里点击下图所示,将实数检查设为none/warning(因为Verilog语言在综合时不允许有浮点数存在,所以会报错,我们这里仅进行仿真,所以忽略此错误);
7、再次Run All第三部分,完成Verilog程序生成;(因为我们这里仅进行了仿真所以不需要进行Run第4部分综合编译,且生成的程序中存在real类型变量,不能进行综合)。
三、Vivado中实现Kalman滤波仿真
1、在Vivado中创建工程并将Kalman.v与Kalman_tb.v文件添加到工程中
2、在Matlab中生成波形文件,代码如下
其中cosy_dig为叠加了白噪声的混合信号。
fc= 0.25e6 ;% 中心频率Fs= 50e6 ; % 采样频率T = 1/fc ; % 信号周期Num = Fs * T ;% 周期内信号采样点数t = (0:Num-1)/Fs ;% 离散时间cosn = cos(2*pi*fc*t) ; % 信号snr=10;px_dBW=10;pn_W=10^((px_dBW-snr)/10);n=sqrt(pn_W)*randn(1,length(cosn));%噪声y1=mapminmax(cosn+n);cosy_dig = floor((2^11-1) * y1 + 2^11) ; %幅值扩展到 0~4095cosy_dig1 = floor((2^11-1) * n + 2^11) ; %幅值扩展到 0~4095cosy_dig2 = floor((2^11-1) * cosn + 2^11) ;%幅值扩展到 0~4095fid = fopen('E:\JXR\FPGA\matlab\Kalman1\whitenosie.dat', 'wt') ; %写数据文件fprintf(fid, '%x\n',cosy_dig1) ;fclose(fid) ;fid1 = fopen('E:\JXR\FPGA\matlab\Kalman1\sin.dat', 'wt') ; %写数据文件fprintf(fid1, '%x\n', cosy_dig2) ;fclose(fid1) ;fid2 = fopen('E:\JXR\FPGA\matlab\Kalman1\cosy_dig.dat', 'wt') ; %写数据文件fprintf(fid2, '%x\n', cosy_dig) ;fclose(fid2) ;figure('name','混合信号时域波形');subplot(221);plot(cosy_dig1);hold on ;subplot(222);plot(t,cosy_dig2) ;hold on ;subplot(223);plot(t,y1) ;hold on ;subplot(224);plot(t,cosy_dig) ;
3、重写tb仿真文件
生成的tb文件很乱,我这里重新写了tb文件,并将matlab中生成的波形数据载入,具体代码如下:
`timescale 1ns / 1psmodule Kalman_tb;parameter NIN =12 ; //matlab中生成文件数据位宽为12reg clk; reg rstn;reg en; reg [63:0] In1; wire ce_out;wire [63:0] Out1;//============== 200MHz clk generating=======================localparam T200M_HALF = 2.5000;initial beginclk = 1'b0 ;forever begin# T200M_HALF clk = ~clk ;endend //========reset and finish=============initial beginrstn = 1'b0 ;# 30 ;rstn = 1'b1 ;# (T200M_HALF * 2 * 2000) ;$finish ;end //=====read cos data into register ======== parameter SIN_DATA_NUM = 200 ;reg[NIN-1:0] stimulus1 [0: SIN_DATA_NUM-1] ;integeri ;initial begin$readmemh("E:/JXR/FPGA/matlab/Kalman1/cosy_dig.dat", stimulus1) ; //提取加噪声后的波形数据i = 0 ;en = 0 ;In1 =0;# 200 ;forever begin@(negedge clk) beginen= 1 ;In1 = stimulus1[i] ;if (i == SIN_DATA_NUM-1) begini = 0 ;endelse begini = i + 1 ;endendendendKalman Kalman_u(.clk (clk),.reset(rstn),.clk_enable (en),.In1 (In1),.ce_out(ce_out),.Out1 (Out1));endmodule // kalman_tb
4、Vivado中仿真编译
仿真结果如下所示:
四、小结
比较初步的实现了simulink仿真转换为Verilog语言程序在vivado中的Kalman滤波仿真,不足之处是程序中变量均为real型,不能综合编译烧录于实际硬件中,还有待改进,望能共同交流协作。
如果觉得《基于Matlab中Simulink生成FPGA-Verilog语言及联合Vivado的仿真(以卡尔曼-Kalman滤波器为例)》对你有帮助,请点赞、收藏,并留下你的观点哦!