CIC濾波器是無線通信中的常用模塊,一般用于數字下變頻(DDC)和數字上變頻(DUC)系統。隨著現代無線通信中數據速率的增加,它的應用變得尤為重要。CIC濾波器的結構簡單,沒有乘法器,只有加法器、積分器和寄存器,適合于工作在高采樣率條件下,而且CIC濾波器是一種基于零點相消的FIR濾波器,已經被證明是在高速抽取或插值系統中非常有效的單元。 我們首先產生一個采樣率Fs=0.78125Mhz,頻率Fout=0.078125Mhz的樣本信號,對其進行16倍插值。這就涉及到直接頻率合成器DDS的知識:
上圖的RAM部分存放通過MATLAB生成一個周期完整正弦波的離散點。Fc采樣時鐘:本模塊用一個50MHZ的采樣時鐘,即每隔20ns,從RAM中讀出一個采樣值。這里記住還有一種通過使能信號去讀取ram的值,這個時候的Fc一定不能用時鐘信號50M去算,而應該以使能信號頻率去計算,下面會詳細體現。
相位累加器:顧名思義,在這里完成相位累加的功能,相位累加器的溢出頻率就是DDS輸出的信號頻率,位寬為N。
頻率控制字M:決定輸出頻率,相當于相位累加器地址addr步進值。
目標頻率:Fout=Fs*M/2^N,對于這個公式我們可以這么理解,一秒內相位累加器的累加值為Fs*M,而寄存器最大值為2^(N-1),溢出次數為Fs*M/2^N,因為寄存器中的值從0增加到2^(N-1),剛好輸出一個周期的正弦波信號。所以,寄存器溢出的次數就是輸出正弦波的周期數。
接下來我們來實現它,首先用MATLAB產生一個完整周期的正弦波樣本,將其存入ROM。具體實現方法參見這篇文章:如何用MATLAB產生FPGA設計中所需的coe xtmif文件
clc; clear all; N=2^8; s_p=0:255;%正弦波一個周期的采樣點數 ROM深度256,位寬8 sin_data=sin(2*pi*s_p/N); fix_p_sin_data=fix(sin_data*127); for i=1:N if fix_p_sin_data(i)<0 fix_p_sin_data(i)=N+fix_p_sin_data(i);%有符號數--得+ else fix_p_sin_data(i)=fix_p_sin_data(i); end end fid = fopen('sin.coe','w');% 打開一個.coe文件 % 存放在ROM中的.coe文件第一行必須是這個字符串,10表示10進制,可以改成其他進制 fprintf(fid,'memory_initialization_radix = 10; '); % 存放在ROM中的.coe文件第二行必須是這個字符串 fprintf(fid,'memory_initialization_vector = '); % 把前255個數據寫入.coe文件中,并用逗號隔開,為了方便知道數據的個數,每行只寫一個數據 fprintf(fid,'%d, ',fix_p_sin_data(1:end-1)); % 把最后一個數據寫入.coe文件中,并用分號結尾 fprintf(fid,'%d; ',fix_p_sin_data(end)); fclose(fid);??%?關閉文件指針
在VIVADO中調用ROM IP核,存放一個周期正弦波的信息:
這一步加載我們用MATLAB生成的coe文件,如果加載的coe文件錯誤,箭頭指的地方會報紅。創建完rom后例化仿真:
module dds( input wire clk, input wire rst_n, output wire [7:0] o_wave ); reg [7:0] addr; always @(posedge clk)begin if(!rst_n) addr <= 8'd0; else addr <= addr + 1'b1; end sp_ram_256x8 sp_ram_256x8 ( .clka(clk), // input wire clka .addra(addr ), // input wire [7 : 0] addra .douta(o_wave) // output wire [7 : 0] douta );
仿真圖如下:
接下來我們首先產生一個采樣率Fs=0.78125Mhz,頻率Fout=0.078125Mhz的樣本信號:
module gen_sin( input wire sclk, input wire rst_n, output wire [7:0] data_o, output reg data_v ); parameter DIV_NUM=6'd63;//50M/64=0.78125M采樣率 //FC = 0.078125Mhz信號頻率 //FS = 0.78125Mhz采樣頻率 parameter FRQ_W_1M=32'd429496730; //2^32*(0.078125)/0.78125//fc=M*fs/2^32 reg [31:0] phase_sum_1m; wire [7:0] addr_1m; wire [7:0] o_wave_1m; reg [5:0] div_cnt; reg s_flag; //分頻產生0.78125M采樣率 always @(posedge sclk or negedge rst_n) if(rst_n == 1'b0) div_cnt <= 'd0; else if(div_cnt == DIV_NUM) div_cnt <= 'd0; else div_cnt <= div_cnt + 1'b1; //梳狀濾波器驅動脈沖 always @(posedge sclk or negedge rst_n) if(rst_n == 1'b0) s_flag <= 1'b0; else if(div_cnt == 6'd0) s_flag <= 1'b1; else s_flag <= 1'b0; always @(posedge sclk or negedge rst_n) if(rst_n == 1'b0) data_v <= 1'b0; else data_v <= 1'b1; assign data_o = o_wave_1m;//0.78125 // //相位累加器 always @(posedge sclk or negedge rst_n) if(rst_n == 1'b0) phase_sum_1m<='d0; else if(s_flag == 1'b1) phase_sum_1m <= phase_sum_1m + FRQ_W_1M ; //相位 assign addr_1m=phase_sum_1m[31:24]; sp_ram_256x8 sp_ram_256x8 ( .clka(sclk), // input wire clka .addra(addr_1m), // input wire [7 : 0] addra .douta(o_wave_1m) // output wire [7 : 0] douta ); endmodule數字信號的頻譜是周期性的,且周期等于數據的采樣頻率。整數倍零值內插當然不能簡單地等同于提高了數據采樣頻率,在插值過程中,頻譜會以采樣頻率進行壓縮,可能會引起頻譜混疊,通過內插、低通濾波處理后,即可得到正確的經高速采樣后的數字信號。如下圖所示:

所以多速率信號處理過程的關鍵是設計滿足要求的抗混疊濾波器。即抽取或內插處理后,在有用信號頻段內不產生頻譜混疊。同時要求濾波器占用硬件資源少且運算速度快,一般只要有效增加濾波器的階數,可以設計出滿足指標要求的各種抗混疊濾波器。CIC(積分梳狀)濾波器及半帶濾波器因為具有運算速度快、占用資源少等特點,在多速率信號處理中得到了廣泛的應用。其沖激響應為:
它的抽頭系數只有1或者0。 直接用MATLAB仿真觀察,分析一下 CIC 濾波器的頻譜特性,可得到其幅頻特性。
根據上述公式在MATLAB中編寫如下代碼觀察濾波器抑制情況:
clc; clear all; R=16; M=1; N=3; n=0500-1; w=pi*n/(length(n)); num=sin(R*M*w/2); den=sin(w/2); H=(num./den).^N; ABS_H=abs(H); mag=20*log10(ABS_H/max(ABS_H)); plot(w/pi,mag); grid on; axis([0,1,-200,0]);
由上圖可知,對帶外信號有很好的抑制效果。
在進行Verilog實現時,首先要把具體電路結構映射出來,CIC濾波器具體實現框圖如下,系數為1:
按照上述框圖進行編碼,對上述生成的樣本信號(采樣率Fs=0.78125Mhz,頻率Fout=0.078125Mhz的樣本信號)進行16倍插值濾波處理(FS采樣率提高,信號頻率Fout不變),涉及代碼均參考V3學社尤老師,讀者可訪問文后提供的網址學習參考:
module cic_interpolate( input wire sclk,//50M input wire rst_n, input wire [7:0] data_in, input wire data_v, output wire [19:0] data_out ); parameter W=20; parameter DIV_NUM=6'd63;//50M/64=0.78125M parameter DIV_NUM_I=3'd3; //BIN + N*log2(R)=8+3*4=20; reg [W-1:0] comb1; reg [W-1:0] comb2; reg [W-1:0] comb3; reg [W-1:0] integ1; reg [W-1:0] integ2; reg [W-1:0] integ3; wire [W-1:0] comb1_w; wire [W-1:0] comb2_w; wire [W-1:0] comb3_w; wire [W-1:0] integ1_w; wire [W-1:0] integ2_w; wire [W-1:0] integ3_w; reg [5:0] div_cnt; reg s_flag; reg s_flag_i; //此計數器用于控制分頻,為梳狀濾波器和積分濾波器提供驅動脈沖 always @(posedge sclk or negedge rst_n) if(rst_n == 1'b0) div_cnt <= 'd0; else if(div_cnt == DIV_NUM) div_cnt <= 'd0; else div_cnt <= div_cnt + 1'b1; //梳狀濾波器驅動脈沖 always @(posedge sclk or negedge rst_n) if(rst_n == 1'b0) s_flag <= 1'b0; else if(div_cnt == 6'd0) s_flag <= 1'b1; else s_flag <= 1'b0; //積分濾波器驅動脈沖 always @(posedge sclk or negedge rst_n) if(rst_n == 1'b0) s_flag_i <= 1'b0; else if(div_cnt[1:0] == 2'd0) s_flag_i <= 1'b1; else s_flag_i <= 1'b0; //梳狀濾波器的寄存器 always @(posedge sclk or negedge rst_n) if(rst_n == 1'b0) comb1<='d0; else if(data_v == 1'b1 && s_flag == 1'b1) comb1<= {{12{data_in[7]}},data_in}; else if(data_v == 1'b0) comb1<='d0; always @(posedge sclk or negedge rst_n) if(rst_n == 1'b0) comb2<='d0; else if(data_v == 1'b1 && s_flag == 1'b1) comb2<= comb1_w; else if(data_v == 1'b0) comb2<='d0; always @(posedge sclk or negedge rst_n) if(rst_n == 1'b0) comb3<='d0; else if(data_v == 1'b1 && s_flag == 1'b1) comb3<= comb2_w; else if(data_v == 1'b0) comb3<='d0; //寄存器間的組合邏輯 assign comb1_w= {{12{data_in[7]}},data_in}-comb1; assign comb2_w= comb1_w-comb2; assign comb3_w= comb2_w-comb3; //積分濾波器間的組合邏輯 assign integ1_w=comb3_w + integ1; assign integ2_w=integ1_w + integ2; assign integ3_w=integ2_w + integ3; //插值后的結果輸出 assign data_out = integ3_w; //積分濾波器的寄存器 always @(posedge sclk or negedge rst_n) if(rst_n == 1'b0) begin integ1<='d0; integ2<='d0; integ3<='d0; end else if(data_v == 1'b1 && s_flag_i == 1'b1)begin integ1<=integ1_w; integ2<=integ2_w; integ3<=integ3_w; ??end endmodule
對上述模塊進行仿真:紅框為插值前,綠框為插值后效果,直觀的看到輸出信號更加平滑細膩:
-
FPGA
+關注
關注
1640文章
21907瀏覽量
611549 -
濾波器
+關注
關注
162文章
7997瀏覽量
180367 -
頻率合成器
+關注
關注
5文章
230瀏覽量
32646 -
無線通信
+關注
關注
58文章
4685瀏覽量
144668 -
DDS
+關注
關注
22文章
645瀏覽量
153724
原文標題:CIC插值濾波器與直接頻率合成器DDS的FPGA實現
文章出處:【微信號:Hack電子,微信公眾號:Hack電子】歡迎添加關注!文章轉載請注明出處。
發布評論請先 登錄
相關推薦
AD9164BBCZ 直接數字頻率合成器
什么是頻率合成器
如何采用DDS實現頻率合成器的設計?
AD9850 DDS 頻率合成器的原理及應用
基于FPGA的直接數字頻率合成器的設計和實現

基于FPGA的直接數字頻率合成器的設計和實現

基于DDS驅動PLL結構的寬帶頻率合成器的設計與實現

評論