matlab联合vivada创建FIR滤波器
整体过程:利用matlab生成.coe 作为vivado的IP文件 接着利用matlab生成两个不同频率波s1 s2 并叠加生成s采样数据以16进制写入文本文件 作为仿真输入波形 查看滤波器效果
1、matlba部分
- 创建一个fir滤波器 参考如下公众号:FIR滤波器matlab部分
- 其中各部分想要补充的:
这是一些参数的描述 后面就是 file export–> target .coe file
2、vivado部分
同样参考上述链接 fir滤波器
其中想要补充对代码的一些理解:
`timescale 1ns / 1ps
//////////////////////////////////////////////////////////////////////////////////
// Company:
// Engineer:
//
// Create Date: 2023/10/06 16:21:48
// Design Name:
// Module Name: fir_ip_tb
// Project Name:
// Target Devices:
// Tool Versions:
// Description:
//
// Dependencies:
//
// Revision:
// Revision 0.01 - File Created
// Additional Comments:
//
//////////////////////////////////////////////////////////////////////////////////
module fir_ip_tb(
);
reg clk;
reg [15:0] data_in;
wire [31:0] data_out;
wire data_out_valid;
wire data_in_ready;
//Instantiate a Module
design_1_wrapper U1_design_1_wrapper
(
.M_AXIS_DATA_0_tdata (data_out),
.M_AXIS_DATA_0_tvalid(data_out_valid),
.S_AXIS_DATA_0_tdata(data_in),
.S_AXIS_DATA_0_tready(data_in_ready),
.S_AXIS_DATA_0_tvalid(1'b1),
.aclk_0(clk)
);
initial begin
clk = 0;
end
always #16 clk = ~clk;
//get the data from the file named s1_s2_bit.txt
parameter data_num = 64;
integer Pattern;
reg [15:0] stimulus[1:data_num];//upon the length of reg 16bit so each data is 16bit
initial
begin
$readmemh("D:/FPGA_MATLAB/s1_s2_bit.txt",stimulus);//Read Hexadecimal Data it is important that you have to save data in the way of hex and each data needs to be on a new line
Pattern=0;
repeat(30) begin
repeat(data_num) begin
Pattern = Pattern+1;
data_in = stimulus[Pattern];
#32;
end
Pattern = 0;
end
#500;
$stop;
end
//Write the generated data to the file data_out.txt.
integer file_out;
initial
begin
file_out = $fopen("D:/FPGA_MATLAB/data_out.txt");
if(!file_out)
begin
$display("could not open file!");
$finish;
end
end
wire signed [31:0] data_out_signed;
assign data_out_signed = data_out;
always @(posedge clk )
begin
if(data_out_valid) begin
$fdisplay(file_out,"%d",data_out_signed);
end
end
endmodule
下面会有s1_s2_bit.txt文件的内容
3、遇到的一些问题 (还有待解决)
关于生成波数据存储方式的问题:
f1 = 0.5; %信号1频率为 500 kMZ
f2 = 5; %信号2频率为 5 MHZ
Fs = 32; %采样频率为 32 MHZ
N = 16; %量化位数
N_2 = 18;
%产生信号
t = 0:1/Fs:5; %以0为开头 1/Fs为步进值 5为结尾的一系列数 用于生成函数点
c1 = 2*pi*f1*t;
c2 = 2*pi*f2*t;
f1 = 0.5; %信号1频率为 500 kMZ
f2 = 5; %信号2频率为 5 MHZ
Fs = 32; %采样频率为 32 MHZ
N = 16; %量化位数
%产生信号
t = 0:1/Fs:5; %以0为开头 1/Fs为步进值 5为结尾的一系列数 用于生成函数点
c1 = 2*pi*f1*t;
c2 = 2*pi*f2*t;
s1 = sin(c1);
s2 = sin(c2);
s = s1+s2; %两个单波载波合成的信号
%绘图
subplot(2,2,1);
plot(c1,s1);
title('s1');
subplot(2,2,2);
plot(c2,s2);
title('s2');
s = s/max(abs(s));
subplot(2,2,3);
plot(s);
title('s');
%16比特量化
Q_s = round(s*(2^(N-1)-1));
%将生成的数以十进制写入txt文件中
fid = fopen('D:\FPGA_MATLAB\s1_s2.txt','w');
fprintf(fid,'%16d\r\n',Q_s);
fprintf(fid,";");
fclose(fid);
i = 1; % 从1开始,因为在 MATLAB 中数组索引是从1开始的
%下面进行10进制转换成16进制的操作
while i < 162
if Q_s(i) < 0
Q_s(i) = Q_s(i) + 65536;
end
i = i + 1;
end
disp(Q_s);
Q_s = dec2hex(Q_s);
disp(Q_s);
fia = fopen('D:\FPGA_MATLAB\s1_s2_bit.txt','w');
fprintf(fia,'%s\r\n',Q_s);
fprintf(fia,";");
fclose(fia);
关于带符号10进制转成16进制:dec2hex()只能转换正数
关于负数只需将10进制负数加上65536(2的16次方)就将全部数字转换成0-65535
我的理解是0-32768表述的是0-32768
而从 32769-65535表示 -32768–1
详情参考进制转换
实际上输出到s1_s2_bit.txt的内容是:
(离谱 找不到问题出在哪)
索性直接把disp显示的数据c_v到下面的文件中
以下是采用上述c_v大法的文件数据
找到问题了 最后代码这样改进:
感谢这位老哥
波形
matlab仿真的波形: