Note: The parameters of this design are: d=2,r=5,n=3; clock frequency is 50mhz, the input signal is signed 8 bits, according to the formula Bmax=bin+n*log (2,r*d), can get bmax=18;
1,cic decimation Filter principle
A lot of information on the Internet, do not say. The focus is on the transfer function, and the structure of each part.
2,simulink Simulation
Model Diagram
Spectrum Meter Display Results
3,CIC Filter Verilog Code
Module Cic_dec (clk,rst_n,datain,dataout);
Input clk,rst_n;
input [7:0] datain;
Output [7:0] dataout;
reg [17:0] data_buff;
[Email protected] (Posedge CLK or Negedge rst_n)
Begin
if (!rst_n)
data_buff<=0;
Else
data_buff<={{10{datain[7]}},datain};
End
reg [17:0] integ1_result;
[Email protected] (Posedge CLK or Negedge rst_n)
Begin
if (!rst_n)
integ1_result<=0;
Else
integ1_result<=data_buff+integ1_result;
End
reg [17:0] integ2_result;
[Email protected] (Posedge CLK or Negedge rst_n)
Begin
if (!rst_n)
integ2_result<=0;
Else
integ2_result<=integ1_result+integ2_result;
End
reg [17:0] integ3_result;
[Email protected] (Posedge CLK or Negedge rst_n)
Begin
if (!rst_n)
integ3_result<=0;
Else
integ3_result<=integ2_result+integ3_result;
End
Integrator End
Decimation start
Reg Dec_flag;
reg [17:0] dec_result;
reg [2:0] cnt1;
[Email protected] (Posedge CLK or Negedge rst_n)
Begin
if (!rst_n)
cnt1<=0;
else if (cnt1==3 ' D4)
cnt1<=0;
Else
Cnt1<=cnt1+1 ' B1;
End
[Email protected] (Posedge CLK or Negedge rst_n)
Begin
if (!rst_n)
dec_result<=0;
else if (cnt1==3 ' D4)
dec_result<=integ3_result;
End
[Email protected] (Posedge CLK or Negedge rst_n)
Begin
if (!rst_n)
Dec_flag<=1 ' B0;
else if (cnt1==3 ' D4)
Dec_flag<=1 ' B1;
Else
Dec_flag<=1 ' B0;
End
Decimation End
Comb filter Begin
reg [2:0] cnt2;
[Email protected] (Posedge CLK or Negedge rst_n)
Begin
if (!rst_n)
cnt2<=0;
else if (Dec_flag)
cnt2<=0;
Else
Cnt2<=cnt2+1 ' B1;
End
reg [17:0] comb1_delay1;
reg [17:0] comb1_delay2;
reg [17:0] comb1_result;
[Email protected] (Posedge CLK or Negedge rst_n)//first Comb
Begin
if (!rst_n)
Begin
comb1_delay1<=0;
comb1_delay2<=0;
End
else if (cnt2==3 ' D3)
Begin
comb1_delay1<=dec_result;
comb1_delay2<=comb1_delay1;
End
End
[Email protected] (Posedge CLK or Negedge rst_n)
Begin
if (!rst_n)
comb1_result<=0;
else if (Dec_flag)
comb1_result<=dec_result-comb1_delay2;
End
Reg [17:0] comb2_delay1;
Reg [17:0] comb2_delay2;
Reg [17:0] comb2_result;
[email protected] (Posedge CLK or Negedge rst_n)//second comb
Begin
if (!rst_n)
Begin
Comb2_ delay1<=0;
comb2_delay2<=0;
End
Else if (cnt2==3 ' D3)
begin
Comb2_delay1<=comb1_result;
comb2_delay2<=comb2_delay1;
End
End
[email protected] (Posedge CLK or Negedge rst_n)
Begin
if (!rst_n)
comb2_result<= 0;
Else if (dec_flag)
Comb2_result<=comb1_result-comb2_delay2;
End
reg [17:0] comb3_delay1;
reg [17:0] comb3_delay2;
reg [17:0] comb3_result;
[Email protected] (Posedge CLK or Negedge rst_n)//third Comb
Begin
if (!rst_n)
Begin
comb3_delay1<=0;
comb3_delay2<=0;
End
else if (cnt2==3 ' D3)
Begin
comb3_delay1<=comb2_result;
comb3_delay2<=comb3_delay1;
End
End
[Email protected] (Posedge CLK or Negedge rst_n)
Begin
if (!rst_n)
comb3_result<=0;
else if (Dec_flag)
comb3_result<=comb2_result-comb3_delay2;
End
reg [7:0] dataout_buff;
[Email protected] (Posedge CLK or Negedge rst_n)
Begin
if (!rst_n)
dataout_buff<=0;
Else
Dataout_buff<= (Comb3_result[17:0]+{!comb3_result[17],{9{comb3_result[17]}}) >>10;
End
Assign Dataout=dataout_buff;
Endmodule
4,matlab generated sine wave file sampling frequency 50m, sine frequency 1m
0=1e6;
Fs=50e6;
n=fs/f0;
n=0:n-1;
t=n/fs;
width=8;
Sinwave=sin (2*pi*f0*t);
Sindata = Round (sinwave. * (2^ (width-1)-1));
For I=1:n
if (Sindata (i) <0)
Sindata (i) =2^width+sindata (i);
Else
Sindata (i) =sindata (i);
End
End
Fid=fopen (' Sindata.txt ', ' a ');
For I=1:n
fprintf (FID, '%x \ n ', Sindata (i));
i=i+1;
End
Fclose (FID);
5,verilog read waveform file generates sine wave
Module Sin_gen (clk,rst_n,sin_out);
Input clk,rst_n;
Output [7:0] sin_out;
Parameter N = 50;
reg [7:0] mem[0:n-1];
Initial
Begin
$READMEMH ("Sindata.txt", mem);
End
reg [7:0] sin_out_buff;
reg [5:0] I;
[Email protected] (Posedge CLK or Negedge rst_n)
Begin
if (!rst_n)
Begin
sin_out_buff<=0;
I<=6 ' D0;
End
Else
Begin
sin_out_buff<=mem[i];
if (i==6 ' D49)
I<=6 ' D0;
Else
I<=i+1 ' B1;
End
End
Assign Sin_out=sin_out_buff;
Endmodule
6, Testbench
' Timescale 1ns/1ps
Module Testbench ();
Reg Clk,rst_n;
Initial
Begin
clk=0;
Forever #10 CLK=~CLK;
End
Initial
Begin
rst_n=0;
#50 Rst_n=1 ' B1;
End
Wire [7:0] sin_out;
Sin_gen U0_sin_gen (. CLK (CLK),. Rst_n (Rst_n),. Sin_out (Sin_out));
Wire [7:0] data_out;
Cic_dec U0_cic_dec (. CLK (CLK),. Rst_n (Rst_n),. DataIn (Sin_out),. Dataout (Data_out));
reg [10:0] CNT;
[Email protected] (Posedge CLK or Negedge rst_n)
Begin
if (!rst_n)
cnt<=0;
else if (cnt==11 ' d1024)
cnt<=cnt;
Else
Cnt<=cnt+1 ' B1;
End
Integer FID;
Initial
Begin
Fid= $fopen ("Dataout.txt", "a");
End
[Email protected] (Posedge CLK)
Begin
$fwrite (FID, "%x \ n", data_out);
End
[Email protected] (Posedge CLK)
Begin
if (cnt==11 ' d1024)
Begin
$fclose (FID);
$stop;
End
End
Endmodule
7,modelsim Simulation Waveform
Matlab and Modelsim-linked CIC decimation filter