参考文献:
1,基于FPGA的串行FIR滤波器设计与实现
2,FPGA实现FIR滤波器
`timescale 1ns / 1ps
//
// Company:
// Engineer:
//
// Create Date: 2023/11/21 22:55:41
// Design Name:
// Module Name: fir_tops
// Project Name:
// Target Devices:
// Tool Versions:
// Description:
//
// Dependencies:
//
// Revision:
// Revision 0.01 - File Created
// Additional Comments:
//
//
module fir_tops(
input i_clk,
input i_rst,
input signed [1:0] i_din, // signed是默认的,
// 表示这个变量是有符号的,
// 可以用来存储整数和负数
output signed [15:0] o_dout
);
// 滤波器系数
parameter b0 = 14'd82;
parameter b1 = 14'd317;
parameter b2 = 14'd788;
parameter b3 = 14'd1023;
parameter b4 = 14'd788;
parameter b5 = 14'd317;
parameter b6 = 14'd82;
reg signed [1:0] x0;
reg signed [1:0] x1;
reg signed [1:0] x2;
reg signed [1:0] x3;
reg signed [1:0] x4;
reg signed [1:0] x5;
reg signed [1:0] x6;
// 延迟
always@(posedge i_clk or posedge i_rst) begin
if(i_rst) begin
x0 <= 2'd0;
x1 <= 2'd0;
x2 <= 2'd0;
x3 <= 2'd0;
x4 <= 2'd0;
x5 <= 2'd0;
x6 <= 2'd0;
end
else begin // 移位
x0 <= i_din;
x1 <= x0;
x2 <= x1;
x3 <= x2;
x4 <= x3;
x5 <= x4;
x6 <= x5;
end
end
// 使用乘法器ip核计算乘法
wire signed [15:0] r0;
multer u0_multer(
.CLK (i_clk), // input wire CLK
.A (x0), // input wire [1:0] A
.B (b0), // input wire [13:0] B
.SCLR (i_rst), // input wire SCLR
.P (r0) // output wire [15:0] P
);
wire signed [15:0] r1;
multer u1_multer(
.CLK (i_clk), // input wire CLK
.A (x1), // input wire [1:0] A
.B (b1), // input wire [13:0] B
.SCLR (i_rst), // input wire SCLR
.P (r1) // output wire [15:0] P
);
wire signed [15:0] r2;
multer u2_multer(
.CLK (i_clk), // input wire CLK
.A (x2), // input wire [1:0] A
.B (b2), // input wire [13:0] B
.SCLR (i_rst), // input wire SCLR
.P (r2) // output wire [15:0] P
);
wire signed [15:0] r3;
multer u3_multer(
.CLK (i_clk), // input wire CLK
.A (x3), // input wire [1:0] A
.B (b3), // input wire [13:0] B
.SCLR (i_rst), // input wire SCLR
.P (r3) // output wire [15:0] P
);
wire signed [15:0] r4;
multer u4_multer(
.CLK (i_clk), // input wire CLK
.A (x4), // input wire [1:0] A
.B (b4), // input wire [13:0] B
.SCLR (i_rst), // input wire SCLR
.P (r4) // output wire [15:0] P
);
wire signed [15:0] r5;
multer u5_multer(
.CLK (i_clk), // input wire CLK
.A (x5), // input wire [1:0] A
.B (b5), // input wire [13:0] B
.SCLR (i_rst), // input wire SCLR
.P (r5) // output wire [15:0] P
);
wire signed [15:0] r6;
multer u6_multer(
.CLK (i_clk), // input wire CLK
.A (x6), // input wire [1:0] A
.B (b6), // input wire [13:0] B
.SCLR (i_rst), // input wire SCLR
.P (r6) // output wire [15:0] P
);
assign o_dout = r0 + r1 + r2 + r3 + r4 + r5 + r6;
endmodule
`timescale 1ns / 1ps
//
// Company:
// Engineer:
//
// Create Date: 2023/11/21 22:55:41
// Design Name:
// Module Name: fir_tops
// Project Name:
// Target Devices:
// Tool Versions:
// Description:
//
// Dependencies:
//
// Revision:
// Revision 0.01 - File Created
// Additional Comments:
//
//
module fir_tops(
input i_clk,
input i_rst,
input signed [1:0] i_din, // signed是默认的,
// 表示这个变量是有符号的,
// 可以用来存储整数和负数
output signed [15:0] o_dout
);
// 滤波器系数
parameter b0 = 14'd82;
parameter b1 = 14'd317;
parameter b2 = 14'd788;
parameter b3 = 14'd1023;
parameter b4 = 14'd788;
parameter b5 = 14'd317;
parameter b6 = 14'd82;
reg signed [1:0] x0;
reg signed [1:0] x1;
reg signed [1:0] x2;
reg signed [1:0] x3;
reg signed [1:0] x4;
reg signed [1:0] x5;
reg signed [1:0] x6;
// 延迟
always@(posedge i_clk or posedge i_rst) begin
if(i_rst) begin
x0 <= 2'd0;
x1 <= 2'd0;
x2 <= 2'd0;
x3 <= 2'd0;
x4 <= 2'd0;
x5 <= 2'd0;
x6 <= 2'd0;
end
else begin // 移位
x0 <= i_din;
x1 <= x0;
x2 <= x1;
x3 <= x2;
x4 <= x3;
x5 <= x4;
x6 <= x5;
end
end
// 使用乘法器ip核计算乘法
wire signed [15:0] r0;
multer u0_multer(
.CLK (i_clk), // input wire CLK
.A (x0), // input wire [1:0] A
.B (b0), // input wire [13:0] B
.SCLR (i_rst), // input wire SCLR
.P (r0) // output wire [15:0] P
);
wire signed [15:0] r1;
multer u1_multer(
.CLK (i_clk), // input wire CLK
.A (x1), // input wire [1:0] A
.B (b1), // input wire [13:0] B
.SCLR (i_rst), // input wire SCLR
.P (r1) // output wire [15:0] P
);
wire signed [15:0] r2;
multer u2_multer(
.CLK (i_clk), // input wire CLK
.A (x2), // input wire [1:0] A
.B (b2), // input wire [13:0] B
.SCLR (i_rst), // input wire SCLR
.P (r2) // output wire [15:0] P
);
wire signed [15:0] r3;
multer u3_multer(
.CLK (i_clk), // input wire CLK
.A (x3), // input wire [1:0] A
.B (b3), // input wire [13:0] B
.SCLR (i_rst), // input wire SCLR
.P (r3) // output wire [15:0] P
);
wire signed [15:0] r4;
multer u4_multer(
.CLK (i_clk), // input wire CLK
.A (x4), // input wire [1:0] A
.B (b4), // input wire [13:0] B
.SCLR (i_rst), // input wire SCLR
.P (r4) // output wire [15:0] P
);
wire signed [15:0] r5;
multer u5_multer(
.CLK (i_clk), // input wire CLK
.A (x5), // input wire [1:0] A
.B (b5), // input wire [13:0] B
.SCLR (i_rst), // input wire SCLR
.P (r5) // output wire [15:0] P
);
wire signed [15:0] r6;
multer u6_multer(
.CLK (i_clk), // input wire CLK
.A (x6), // input wire [1:0] A
.B (b6), // input wire [13:0] B
.SCLR (i_rst), // input wire SCLR
.P (r6) // output wire [15:0] P
);
assign o_dout = r0 + r1 + r2 + r3 + r4 + r5 + r6;
endmodule
注意:
1,输出波形有误差,需要修改;
2,vivado对IP catalog
进行了调用;这里要注重调用的方法。
3,测试代码结合起来理解输出波形。
使用zynq-7000的IP核: