发布日期:2022-05-14
module top (
input wire clk,
input wire rst_n
);
//Registers Declarations
reg [9:0] addr_1;
reg [9:0] addr_2;
reg [14:0] data_sum;
reg [14:0] delay_pipeline1 ;
reg [14:0] delay_pipeline2 ;
reg [14:0] delay_pipeline3 ;
reg [14:0] delay_pipeline4 ;
reg [14:0] delay_pipeline5 ;
reg [14:0] delay_pipeline6 ;
reg [14:0] delay_pipeline7 ;
reg [14:0] delay_pipeline8 ;
reg [14:0] delay_pipeline9 ;
reg [14:0] delay_pipeline10 ;
reg [14:0] delay_pipeline11 ;
reg [14:0] delay_pipeline12 ;
reg [14:0] delay_pipeline13 ;
reg [14:0] delay_pipeline14 ;
reg [14:0] delay_pipeline15 ;
reg [14:0] delay_pipeline16 ;
reg [14:0] delay_pipeline17 ;
reg signed [22:0] multi_data1 ;//乘积结果
reg signed [22:0] multi_data2 ;
reg signed [22:0] multi_data3 ;
reg signed [22:0] multi_data4 ;
reg signed [22:0] multi_data5 ;
reg signed [22:0] multi_data6 ;
reg signed [22:0] multi_data7 ;
reg signed [22:0] multi_data8 ;
reg signed [22:0] multi_data9 ;
reg signed [22:0] multi_data10 ;
reg signed [22:0] multi_data11 ;
reg signed [22:0] multi_data12 ;
reg signed [22:0] multi_data13 ;
reg signed [22:0] multi_data14 ;
reg signed [22:0] multi_data15 ;
reg signed [22:0] multi_data16 ;
reg signed [22:0] multi_data17 ;
reg signed [22:0] FIR_OUT;
//---Wiredsignaldeclaration
wire [13:0] data_1;
wire [13:0] data_2;
wire[7:0] coeff1 = 8d86; //滤波器系数
wire[7:0] coeff2 = 8d5;
wire[7:0] coeff3 = 8d6;
wire[7:0] coeff4 = 8d6;
wire[7:0] coeff5 = 8d6;
wire[7:0] coeff6 = 8d6;
wire[7:0] coeff7 = 8d6;
wire[7:0] coeff8 = 8d6;
wire[7:0] coeff9 = 8d6;
wire[7:0] coeff10 = 8d6;
wire[7:0] coeff11 = 8d6;
wire[7:0] coeff12 = 8d6;
wire[7:0] coeff13 = 8d6;
wire[7:0] coeff14 = 8d6;
wire[7:0] coeff15 = 8d6;
wire[7:0] coeff16 = 8d5;
wire[7:0] coeff17 = 8d86;
always @ (posedge clk or negedge rst_n) begin
if (!rst_n)
begin
addr_1 <= 10d0;
addr_2 <= 10d0;
end
else
begin
addr_1 <= addr_1+10d41; //2m
addr_2 <= addr_2+10d20; //1m
end
end
always @ (posedge clk or negedge rst_n) begin
if (!rst_n)
data_sum <= 15d0;
else
data_sum <= data_1 + data_2;
end
always @ (posedge clk or negedge rst_n) begin
if (!rst_n)
begin
delay_pipeline1 <= 15d0;
delay_pipeline2 <= 15d0;
delay_pipeline3 <= 15d0;
delay_pipeline4 <= 15d0;
delay_pipeline5 <= 15d0;
delay_pipeline6 <= 15d0;
delay_pipeline7 <= 15d0;
delay_pipeline8 <= 15d0;
delay_pipeline9 <= 15d0;
delay_pipeline10 <= 15d0;
delay_pipeline11 <= 15d0;
delay_pipeline12 <= 15d0;
delay_pipeline13 <= 15d0;
delay_pipeline14 <= 15d0;
delay_pipeline15 <= 15d0;
delay_pipeline16 <= 15d0;
delay_pipeline17 <= 15d0;
end
else
begin
delay_pipeline1 <= data_sum;
delay_pipeline2 <= delay_pipeline1;
delay_pipeline3 <= delay_pipeline2;
delay_pipeline4 <= delay_pipeline3;
delay_pipeline5 <= delay_pipeline4;
delay_pipeline6 <= delay_pipeline5;
delay_pipeline7 <= delay_pipeline6;
delay_pipeline8 <= delay_pipeline7;
delay_pipeline9 <= delay_pipeline8;
delay_pipeline10 <= delay_pipeline9;
delay_pipeline11 <= delay_pipeline10;
delay_pipeline12 <= delay_pipeline11;
delay_pipeline13 <= delay_pipeline12;
delay_pipeline14 <= delay_pipeline13;
delay_pipeline15 <= delay_pipeline14;
delay_pipeline16 <= delay_pipeline15;
delay_pipeline17 <= delay_pipeline16;
end
end
always @ (posedge clk or negedge rst_n) begin
if (!rst_n)
begin
multi_data1 <= 23d0;//乘积结果
multi_data2 <= 23d0;
multi_data3 <= 23d0;
multi_data4 <= 23d0;
multi_data5 <= 23d0;
multi_data6 <= 23d0;
multi_data7 <= 23d0;
multi_data8 <= 23d0;
multi_data9 <= 23d0;
multi_data10 <= 23d0;
multi_data11 <= 23d0;
multi_data12 <= 23d0;
multi_data13 <= 23d0;
multi_data14 <= 23d0;
multi_data15 <= 23d0;
multi_data16 <= 23d0;
multi_data17 <= 23d0;
end
else
begin
multi_data1 <= delay_pipeline1 coeff1;//乘积结果
multi_data2 <= delay_pipeline2 coeff2;
multi_data3 <= delay_pipeline3 coeff3;
multi_data4 <= delay_pipeline4 coeff4;
multi_data5 <= delay_pipeline5 coeff5;
multi_data6 <= delay_pipeline6 coeff6;
multi_data7 <= delay_pipeline7 coeff7;
multi_data8 <= delay_pipeline8 coeff8;
multi_data9 <= delay_pipeline9 coeff9;
multi_data10 <= delay_pipeline10 coeff10;
multi_data11 <= delay_pipeline11 coeff11;
multi_data12 <= delay_pipeline12 coeff12;
multi_data13 <= delay_pipeline13 coeff13;
multi_data14 <= delay_pipeline14 coeff14;
multi_data15 <= delay_pipeline15 coeff15;
multi_data16 <= delay_pipeline16 coeff16;
multi_data17 <= delay_pipeline17 coeff17;
end
end
always @ (posedge clk or negedge rst_n) begin
if (!rst_n)
FIR_OUT <= 23d0;
else
FIR_OUT <= multi_data1+multi_data2+multi_data3+multi_data4+multi_data5+multi_data6+multi_data7
+multi_data8+multi_data9+multi_data10+multi_data11+multi_data12+multi_data13+multi_data14+multi_data15
+multi_data16+multi_data17;
end
rom_1 u_rom_1(
.address (addr_1 ),
.clock (clk ),
.q (data_1 )
);
rom_1 u_rom_2(
.address (addr_2 ),
.clock (clk ),
.q (data_2 )
);
endmodule
仿真结果: FIR_OUT 为滤波后的效果。
1 : 采样IP核的形式完成滤波实验,需要使用MATLAB配置参数,以MIF格式的文件放置到IP中进行配置。
Docunmentation : FIR的IP核使用手册.
Coefficient File Path : 防止配置后的MIF文件。
因为 可编程逻辑芯片 并不支持浮点数的运算,所以需要对抽头系数进行量化处理,在 Filter arithmetic 中选择 Fixed-point, Number word length 中可以输入的是字长,当输入 8 时,点击 Apply,可以看到有较大的偏差。所以将数值改为 16。
导出需要配置的数据 :
将数据文件改成.MIF文件格式,给予eLinx软件使用。
此处存储为十六进制数据,如果不是喜欢十六进制,强烈建议使用二进制进行存储。
IP核配置页面 :
测试程序:
module fir_top(
input wire clk,
input wire rst_n
);
//---- Registers Declarations ----
reg [9:0] addr_1;
reg [9:0] addr_2;
reg [14:0] data_sum;
//--------Wired signal declaration --------
wire sink_ready;
wire sink_valid;
wire [37:0] source_data;
wire source_ready;
wire source_valid;
wire [13:0] data_1;
wire [13:0] data_2;
assign sink_valid = sink_ready;
always @ (posedge clk or negedge rst_n) begin
if (!rst_n)
begin
addr_1 <= 10d0;
addr_2 <= 10d0;
end
else if (sink_ready)
begin
addr_1 <= addr_1+10d10; //0.5m
addr_2 <= addr_2+10d20; //1m
end
end
always @ (posedge clk or negedge rst_n) begin
if (!rst_n)
data_sum <= 15d0;
else
data_sum <= data_1 + data_2;
end
m4k_1 u_rom_1(
.address (addr_1 ),
.clock (clk ),
.q (data_1 )
);
m4k_1 u_rom_2(
.address (addr_2 ),
.clock (clk ),
.q (data_2 )
);
fir_1 u_fir_1(
.clk (clk ),
//用以给 FIR 滤波器内部寄存器提 供时钟信号
.rst_n (rst_n ),
//低有效复位信号。在时钟上升沿 复位 FIR 滤波器。信号至少持续一 个时钟周期
.sink_data (data_sum ),
//输入采样数据
.sink_ready (sink_ready ),
//当滤波器准备好接收数据的时 候,FIR 滤波器会拉高这个信号
.sink_valid (sink_valid ),
//要输入数据的时候,同时拉高这 个信号。
.sink_error (),
//输入错误信号可以忽略
.source_data (source_data ),
//滤波器输出。数据位宽由参数设 置决定
.source_ready (1b1 ),
//流水处理模式下,滤波器准备好 接受数据的时候,拉高这个信号
.source_valid (source_valid),
//当要输出数据的时候,FIR 滤波器 拉高这个信号
.source_error ()
//输出错误信号可以忽略
);
Endmodule