滤波器:对特定的频率或者特定频率以外的频率进行消除电路。从功能的角度,数字滤波器对输入离散信号的数字代码进行运算处理,以达到滤除频带外信号的目的。
有限冲激响应(FIR)滤波器的系统函数:
H
(
z
)
=
y
(
z
)
/
x
(
z
)
=
a
+
b
/
z
1
+
c
/
z
2
H(z)=y(z)/x(z)=a+b/z^1 +c/z^2
H(z)=y(z)/x(z)=a+b/z1+c/z2
y(z)和x(z)分别表输入和输出信号;a,b,c表示抽头系数;z^1 和z^2 表示延迟,其中z^1 表示延迟一个时钟周期,z^2 表示延迟2个时钟周期。
1.串行滤波器
- 对于输入序列X[n]的FIR滤波器,X[n]是输入数据流。各级的输入连接和输出连接被称为抽头,系数(b0,b1,…,bn)被称为抽头系数;
- M阶滤波器将会有M+1个抽头;
- 乘累加,即通过移位寄存器用每个时钟边沿处的数据流采样值乘以抽头系数,然后将它们累加形成输出Y[n];
- 数据的输入速率 = 系统时钟频率/滤波器长度(M+1),例如8阶滤波器,系统时钟为24MHz,则数据的输入频率(采样速率)为3MHz;
- 串行滤波器的数据处理速度较慢;
- 注意在8阶滤波器中,抽头系数是具有对称性的,b0=b8,b1=b7,…b3=b5;所以在乘累加时,可以先将输入信号相加,再与抽头系数相乘,减少乘法器电路的数量和芯片面积。
//位宽为4 bit的8阶滤波器
//组成:
// * 移位寄存器模块 :用于存储串行进入滤波器的数据
// * 乘加计算模块:用于进行滤波器FIR计算
//顶层模块
module FIR(data_out,data_in,clk,rst_n);
input [3:0]data_in;
input clk,rst_n;
output [9:0]data_out;
wire [9:0]data_out;
wire [3:0]sample_0,sample_1,sample_2,sample_3,sample_4,
sample_5,sample_6,sample_7,sample_8;
shift_register U1(.data_in(data_in),.clk(clk),.rst_n(rst_n),.sample_0(sample_0),
.sample_1(sample_1),.sample_2(sample_2),.sample_3(sample_3),
.sample_4(sample_4),.sample_5(sample_5),.sample_6(sample_6),
.sample_7(sample_7),.sample_8(sample_8));
caculator U2(.sample_0(sample_0),.sample_1(sample_1),.sample_2(sample_2),
.sample_4(sample_4),.sample_5(sample_5),.sample_6(sample_6),
.sample_7(sample_7),.sample_8(sample_8),.data_out(data_out));
endmodule
//移位寄存器模块
module shift_register(data_in,clk,rst_n,sample_0,
sample_1,sample_2,sample_3,
sample_4,sample_5,sample_6,
sample_7,sample_8,);
input [3:0]data_in;
input clk,rst_n;
output [3:0]sample_0,sample_1,sample_2,sample_3,sample_4,
sample_5,sample_6,sample_7,sample_8;
reg [3:0]sample_0,sample_1,sample_2,sample_3,sample_4,
sample_5,sample_6,sample_7,sample_8;
always@(posedge clk or negedge rst_n)begin
if(!rst_n)begin
sample_0 <= 4'b0;
sample_1 <= 4'b0;
sample_2 <= 4'b0;
sample_3 <= 4'b0;
sample_4 <= 4'b0;
sample_5 <= 4'b0;
sample_6 <= 4'b0;
sample_7 <= 4'b0;
sample_8 <= 4'b0;
end
else begin//移位
sample_0 <= data_in;
sample_1 <= sample_0;
sample_2 <= sample_1;
sample_3 <= sample_2;
sample_4 <= sample_3;
sample_5 <= sample_4;
sample_6 <= sample_5;
sample_7 <= sample_6;
sample_8 <= sample_7;
end
end
endmodule
//caculator模块用于进行8输入信号与抽头系数的乘累加,并产生滤波后的信号data_out
//在8阶滤波器中,抽头系数是具有对称性的,b0=b8,b1=b7,b2=b6,b3=b5;
//所以在乘累加时,可以先将输入信号相加,再与抽头系数相乘,减少乘法器电路的数量和芯片面积
module caculator(sample_0,sample_1,sample_2,sample_3,sample_4,
sample_5,sample_6,sample_7,sample_8,data_out);
input sample_0,sample_1,sample_2,sample_3,sample_4,
sample_5,sample_6,sample_7,sample_8;
output [9:0]data_out;
wire [9:0]data_out;
wire [3:0]out_tmp_1,out_tmp_2,out_tmp_3,out_tmp_4,out_tmp_5;
wire [7:0]out1,out2,out3,out4,out5;
parameter b0 = 4'b0010;//定义抽头系数
parameter b1 = 4'b0011;
parameter b2 = 4'b0110;
parameter b3 = 4'b1010;
parameter b4 = 4'b1100;
mul_tree U1(.mul_a(b0),.mul_b(out_tmp_1),.mul_out(out1));
mul_tree U2(.mul_a(b1),.mul_b(out_tmp_2),.mul_out(out2));
mul_tree U3(.mul_a(b2),.mul_b(out_tmp_3),.mul_out(out3));
mul_tree U4(.mul_a(b3),.mul_b(out_tmp_4),.mul_out(out4));
mul_tree U5(.mul_a(b4),.mul_b(out_tmp_5),.mul_out(out5));
assign out_tmp_1 = sample_0 + sample_8;
assign out_tmp_2 = sample_1 + sample_7;
assign out_tmp_3 = sample_2 + sample_6;
assign out_tmp_4 = sample_3 + sample_5;
assign data_out = out1 + out2 + out3 + out4 + out5;
endmodule
//4位乘加器模块
module addtree(mul_a,mul_b,mul_out);
input [3:0]mul_a,mul_b;
output [7:0]mul_out;
wire [7:0]mul_out;
wire [7:0]stored0,stored1,stored2,stored3;
wire [7:0]add01,add23;
assign stored3 = mul_b[3]?{1'b0,mul_a,3'b0}:8'b0;//第4位乘结果,低位补齐3个0
assign stored2 = mul_b[2]?{1'b0,mul_a,2'b0}:8'b0;//第3位乘结果,低位补齐2个0
assign stored1 = mul_b[1]?{1'b0,mul_a,1'b0}:8'b0;
assign stored0 = mul_b[0]?{1'b0,mul_a} :8'b0;
assign add01 = stored0 + stored1;
assign add23 = stored2 + stored3;
assign mul_out = add01 + add23;
endmodule
2.并行滤波器
待整理