在先前的一篇博客中,用verilog写了一个sinc3滤波器,但经过深入的学习,发现之前的滤波器采用的是sinc滤波器最直接的方式,如下图1所示,这样会消耗很多硬件资源,造成极大的浪费。然后,如果使用图2的结构实现,将节省很多硬件开销。本文将基于图2结构,用verilog实现一个sinc3滤波器。
图1 Sinc3滤波器最直接的实现方式
图1 经过变换后的Sinc3滤波器实现方式
首先需要确认滤波器中的中间变量位宽,根据
Bout=N*log2(M)+Bin
(Bout为中间变量位宽,N为滤波器阶数,M为滤波器抽取率,Bin为滤波器输入位宽)
本文以3阶,抽取率为256,输入为1bit为例子,因此实现需要的滤波器变量位宽为25,由此可以得到verilog代码如下图所示:
// sinc3 filter
module sinc3
(
input DataIn,
input rst,
input clk,
output reg [24:0] DataOut
);
parameter Dec = 9'd256;
reg [24:0] sigma1;
reg [24:0] sigma2;
reg [24:0] sigma3;
reg [24:0] delta1;
reg [24:0] delta2;
reg [24:0] sigma3_Dec;
wire [24:0] sigma1_temp;
wire [24:0] sigma2_temp;
wire [24:0] sigma3_temp;
wire [24:0] delta1_temp;
wire [24:0] delta2_temp;
wire [24:0] delta3_temp;
reg [8:0] count;
assign sigma1_temp=sigma1+DataIn;
assign sigma2_temp=sigma2+sigma1_temp;
assign sigma3_temp=sigma3+sigma2_temp;
assign delta1_temp=sigma3_temp-sigma3_Dec;
assign delta2_temp=delta1_temp-delta1;
assign delta3_temp=delta2_temp-delta2;
always@(posedge clk or negedge rst)
begin
if (rst==1'b0)
begin
sigma1<=0;
sigma2<=0;
sigma3<=0;
delta1<=0;
delta2<=0;
sigma3_Dec<=0;
count<=0;
DataOut<=0;
end
else
begin
if (count==Dec-1)
begin
count<=0;
sigma3_Dec<=sigma3_temp;
delta1 <=delta1_temp;
delta2 <=delta2_temp;
DataOut <=delta3_temp;
end
else
begin
count<=count+1;
end
sigma1<=sigma1_temp;
sigma2<=sigma2_temp;
sigma3<=sigma3_temp;
end
end
endmodule
参考文献:
[1] https://mp.weixin.qq.com/s/MehgxJUv_Sf4FXCfV_tpbw
[2] https://blog.csdn.net/jiaozihao53/article/details/105376785?spm=1001.2014.3001.5501
[3] https://blog.csdn.net/gemengxia/article/details/115618640