此内容基于博文:基于Matlab Hdl Coder实现FPGA程序开发(卡尔曼滤波算法实现)实现,Simulink仿真构建参考于上链接中。
本博文解决了上博文中无法生成Verilog语言的问题,并对于自动生成的Verilog——testbench文件进行了优化——通过matlab产生信号及白噪声,并将信号数据载入到Vivado-tb文件中,最终通过vivado软件自带仿真器进行观察。
此处进行简单演示,建立好的Kalman滤波器模型如下图所示。
将创建好的滤波器模型打包为一个模块,便于之后将此模块转换为Verilog语言——全选后点击“create subsystem”;
生成模块后可添加信号及示波器观察Kalman功能是否正常。
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’,‘…’),具体用法可右键参照帮助。
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类型变量,不能进行综合)。
其中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~4095
cosy_dig1 = floor((2^11-1) * n + 2^11) ; %幅值扩展到 0~4095
cosy_dig2 = floor((2^11-1) * cosn + 2^11) ; %幅值扩展到 0~4095
fid = 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) ;
生成的tb文件很乱,我这里重新写了tb文件,并将matlab中生成的波形数据载入,具体代码如下:
`timescale 1ns / 1ps
module Kalman_tb;
parameter NIN =12 ; //matlab中生成文件数据位宽为12
reg 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 begin
clk = 1'b0 ;
forever begin
# T200M_HALF clk = ~clk ;
end
end
//========reset and finish=============
initial begin
rstn = 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] ;
integer i ;
initial begin
$readmemh("E:/JXR/FPGA/matlab/Kalman1/cosy_dig.dat", stimulus1) ; //提取加噪声后的波形数据
i = 0 ;
en = 0 ;
In1 =0;
# 200 ;
forever begin
@(negedge clk) begin
en = 1 ;
In1 = stimulus1[i] ;
if (i == SIN_DATA_NUM-1) begin
i = 0 ;
end
else begin
i = i + 1 ;
end
end
end
end
Kalman Kalman_u(
.clk (clk),
.reset (rstn),
.clk_enable (en),
.In1 (In1),
.ce_out (ce_out),
.Out1 (Out1)
);
endmodule // kalman_tb
仿真结果如下所示:
比较初步的实现了simulink仿真转换为Verilog语言程序在vivado中的Kalman滤波仿真,不足之处是程序中变量均为real型,不能综合编译烧录于实际硬件中,还有待改进,望能共同交流协作。