Sigma-DeltaADC中sinc3抽取滤波器的verilog实现_2
在先前的⼀篇博客中,⽤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@(podge 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
el
begin
if(count==Dec-1)
begin
count<=0;
sigma3_Dec<=sigma3_temp;
delta1 <=delta1_temp;
delta2 <=delta2_temp;
DataOut <=delta3_temp;
end
el
begin
count<=count+1;
end
sigma1<=sigma1_temp;
sigma2<=sigma2_temp;
sigma3<=sigma3_temp;
end
end
endmodule