基于verilog CIC滤波器的四倍插值的FPGA实现方案

作者:openslee
在《基于fpga的多级cic滤波器实现四倍抽取一》和《基于fpga的多级cic滤波器实现四倍抽取二》中我们先来了解滑动平均滤波器、微分器、积分器以及梳状滤波器原理以及它们的幅频响应。此篇我们将用verilog实现基于fpga的多级cic滤波器实现四倍插值。
1 cic滤波器的基本概述
cic(积分梳状)滤波器是无线通信中的常用模块,一般用于数字下变频(ddc)和数字上变频(duc)系统。cic滤波器结构简单,只有加法器、积分器和寄存器,适合于工作在搞采样率条件下,而且cic滤波器是一种基于零点相消的fir滤波器,已经被证明是在高速抽取或插值系统中非常有效的单元。
整数倍内插是先在已知抽样序列的相邻两个抽样点之间等间隔地插入(i-1)个零值点,然后进行低通滤波器,即可求得i倍内插的结果。
此篇我们采用多级cic滤波器实现整数倍内插提升采样率。
2 matlab实现cic滤波器的四倍插值
设计目标:将载波频率44.1khz的1khz sine升采样率到176.4khz。
close all clear all clc %set system parameter fs = 1000; %the frequency of the local oscillator signal fs = 44100; %sampling frequency fs1 = 176400; n = 24; %quantitative bits l = 81920; %generating an input signal t =0:1/fs:(1/fs)*(l-1); %generating the time series of sampling frequencies sc =sin(2*pi*fs*t); %a sinusoidal input signal that produces a random starting phase b =[1,-1];%comb a =[1,-1];%integerator %comb c1=filter(b,1,sc); c2=filter(b,1,c1); c3=filter(b,1,c2); y = upsample(c3,4); %integerater i1 =filter(1,a,y); i2 =filter(1,a,i1); i3 =filter(1,a,i2); sf = i3./16; f_osc =fft(sc,l); f_osc=20*log(abs(f_osc))/log(10); %换算成dbw单位 ft1=[0:(fs/l):fs/2]; %转换横坐标以hz为单位 f_osc=f_osc(1:length(ft1)); f_o =fft(sf,l); f_o=20*log(abs(f_o))/log(10); %换算成dbw单位 ft2=[0:(fs1/l):fs1/8]; %转换横坐标以hz为单位 f_o=f_o(1:length(ft2)); figure(1), subplot(211),stem(t(1:32),sc(1:32)); xlabel('时间(t)','fontsize',8); ylabel('幅度(db)','fontsize',8); title('sc','fontsize',8); subplot(212),stem(t(1:128),sf(1:128)); xlabel('时间(t)','fontsize',8); ylabel('幅度(db)','fontsize',8); title('sf','fontsize',8); figure(2), subplot(211),plot(ft1,f_osc); xlabel('频率(hz)','fontsize',8); ylabel('功率(dbw)','fontsize',8); title('原始信号信号频谱图','fontsize',8);legend('sc'); subplot(212),plot(ft2,f_o); xlabel('频率(hz)','fontsize',8); ylabel('功率(dbw)','fontsize',8); title('滤波后信号频谱图','fontsize',8);legend('sf');
3 fpga实现cic滤波器的四倍插值
fpga设计:fpga由i2s输入44.1khz的1khz sine(当然也可以是歌曲44.1khz采样率),经过i2s串转并后经过mult_cic模块进行采样率提升处理(变成176.4khz 1khz sine或者歌曲),再通过i2s_tx_master并转串送到dac 。
多级cic滤波器的结构主要由梳状滤波器+插值+积分器构成。
fpga代码:
`timescale 1ps/1ps module mult_cic#(parameter dw = 38)( input mclk,//45.1584mhz input reset_n, input signed[31:0] pcm_in,//44.1khz output signed[31:0] pcm_out //176.4khz ); wire signed [dw-1:0] temp; wire signed [dw-1:0]integrator_temp; wire signed [dw-1:0] interpolation_temp; wire signed [dw-1:0] comb_temp; assign temp = {{(dw-32){pcm_in[31]}},pcm_in}; comb#(.dw(dw)) u_comb( .mclk(mclk), .reset_n(reset_n), .din(temp), .dout(comb_temp) ); interpolation#(.dw(dw)) u_interpolation( .mclk(mclk), .reset_n(reset_n), .din(comb_temp), .dout(interpolation_temp) ); integrator#(.dw(dw)) u_integrator( .mclk(mclk), .reset_n(reset_n), .din(interpolation_temp), .dout(integrator_temp) ); //divide assign pcm_out = integrator_temp[35:4]; endmodule module integrator#(parameter dw = 38)( input mclk, input reset_n, input signed [dw-1:0] din, output signed [dw-1:0] dout ); localparam last_cycle = 256; reg [7:0] i; reg signed [dw-1:0] temp_xin1,temp_xin2,temp_xin3; wire signed [dw-1:0] i1_temp,i2_temp,i3_temp; always @(posedge mclk or negedge reset_n) begin if(reset_n == 1'b0) i <= 0; else i < = i+1; end always @(posedge mclk or negedge reset_n) begin //the first level integrator if(reset_n == 1'b0) temp_xin1 <= 0; else if(i == (last_cycle-1)) temp_xin1 <= i1_temp; end assign i1_temp = (reset_n == 1'b0)?38'b0:( din + temp_xin1); always @(posedge mclk or negedge reset_n) begin //the second level integrator if(reset_n == 1'b0) temp_xin2 <= 0; else if(i == (last_cycle-1)) temp_xin2 <= i2_temp; end assign i2_temp = (reset_n == 1'b0)?38'b0:( i1_temp + temp_xin2); always @(posedge mclk or negedge reset_n) begin //the third level integrator if(reset_n == 1'b0) temp_xin3 <= 0; else if(i == (last_cycle-1)) temp_xin3 <= i3_temp; end assign i3_temp = (reset_n == 1'b0)?38'b0:( i2_temp + temp_xin3); assign dout = i3_temp; endmodule module interpolation#(parameter dw = 38)( input mclk, input reset_n, input signed [dw-1:0] din, output signed [dw-1:0] dout ); localparam last_cycle = 256; reg [9:0] i; reg signed [dw-1:0] dout_pcm; assign dout = dout_pcm; always @(posedge mclk or negedge reset_n) begin if(reset_n == 1'b0) begin i <= 0; dout_pcm<=0; end else begin i <= i+1; if(i == (last_cycle-1)) dout_pcm<=din; //upsample(x,n)--n--4 if(i == (last_cycle*2-1)) dout_pcm<=32'b0; //upsample(x,n)--n--4 if(i == (last_cycle*3-1)) dout_pcm<=32'b0; //upsample(x,n)--n--4 if(i == (last_cycle*4-1)) dout_pcm<=32'b0; //upsample(x,n)--n--4 end end endmodule module comb#(parameter dw = 38)( input mclk, input reset_n, input signed [dw-1:0] din, output signed [dw-1:0] dout ); localparam last_cycle = 1024; reg [9:0] i;//88.2 reg signed [dw-1:0] d1,d2,d3,d4; wire signed [dw-1:0] c1,c2; always @(posedge mclk or negedge reset_n) begin if(reset_n == 1'b0) begin i <= 0; d1 <=0; d2 <=0; d3 <=0; d4 <=0; end else begin i <= i+1; if(i == (last_cycle-1)) begin d1<=din; d2<=d1; d3<=c1; d4<=c2; end end end assign c1 = (reset_n ==1'b0)?38'b0:(d1-d2);//comb1 assign c2 = (reset_n ==1'b0)?38'b0:(c1-d3);//comb2 assign dout =(reset_n ==1'b0)?38'b0:(c2-d4);//comb3 endmodule fpga仿真:
仿真输入1khz sine输出依然为1khz sine,设计成功。
至此我们可以去完成3倍抽取5倍插值等采样率转化算法。


真无线蓝牙耳机哪个牌子好?吃鸡无延迟蓝牙耳机推荐
几种振动传感器的工作原理和用途的介绍
高通弯道超车!骁龙8 Gen4性能绝了:要超越苹果M2芯片
马自达将于2020年推出首款电动汽车
大唐电信计划将电信科研院的债务转让给大唐半导体
基于verilog CIC滤波器的四倍插值的FPGA实现方案
氧传感器坏了还能开吗
基于阻塞赋值和非阻塞赋值的多级触发器级联实例
华为荣耀9手机来袭,你会继续坚持小米6吗?
上汽从北京出发 借名爵EZS将电动车技术和品牌推向全球
碳化硅基氮化镓和硅基氮化镓的区别在哪里?
五分钟看懂全新一代大众途锐技术
圣邦微电子推出逐次逼近模数转换器GM5200Q
差压式流量计的特点有哪些
电力线载波通信的外围电路设计
三洋化成工业公司计划将于2021年全面投产全树脂电池
实现自动驾驶集成传感器的6大关键点
ROHM的车载LED技术应用
移动网络多场景应用对基站设备的需求分析
有方科技出席物联网产业发展研讨会