数字中频的基本原理和FPGA的实现1.基本原理数字中频主要分两部分,数字上变频(DUC)和数字下变频(DDC)。它们的主要功能是相反,但原理和实现的方法是十分相似。在R8905项目中由于采用了零中频技术,数字上变频和下变频有一些差别,数字上变频没有了NCO模块。另外为了降低输出信号的峰均比又加入了削峰模块CFR,而CGC模块的引入则是补偿削峰所引起的功率损失。CPRI接口处理RCF2倍内插HB2倍内插CFRCGCCIC54倍内插3.84M7.68M15.36M61.44M图1数字上变频模块框图在数字下变频中RSSI模块是信号的功率检测模块,它配合AGC电路将信号的输出功率稳定在一定范围内。NCOCIC54倍抽取HB2倍抽取RRCAGCRSSI61.44M15.36M7.68Mcpri图2数字下变频模块框图在DDC和DUC中主要使用3种滤波器分别是RRC,HB和CIC,它们个自有个自的特点。RRC滤波器一般来讲阶数比较多,多用于低频处。由于它的阶数比较多,所以可以得到比较锐利的带通特性,但它所用的乘法器比较多。CIC滤波器不需要乘法器,但它的带内不是很平坦,适合用在高频处。而HB滤波器的特性正好在它们之间,它有约一半的系数是0可以讲乘法器的个数减少一半。削峰模块CFR实际上也是一组滤波器,它的功能是将CDMA信号中的峰值信号减小一些,以减小输出信号的峰均比,使射频功率放大器的效率更高。削峰的模块框图如图3图3单级削峰示意图削峰的原理是这样的一个复信号(I,Q)如果它的模大于某个门限,就将其减去这个门限得到一个复信号(dI,dQ),否则(dI,dQ)=(0,0)。将(dI,dQ)送到fir滤波器中,fir滤波器是一个低通滤波器将峰值限定在一定的带宽内,防止影响临道。将原信号(I,Q)减去滤波后的信号(fir_i,fir_q)就得到了削峰的值。如果有必要这这样的削峰可以连续做几次,在R8905设计中削峰用了两次。2.滤波器的设计由于在滤波的同时还有内插和抽取,所以充分利用这一特性可以减少FPGA使用的资源。另外滤波器的系数一般都是对称的,可以将头和尾的数相加再乘滤波器的系数,这样可以大大减少乘法器的使用。以R8905中的上变频RRC为例来说明:设a(n)为RRC滤波器的系数而x(n)为3.84M输入数据则考虑了内插后的滤波器的数学表达式为y=a(0)*x(n)+a(1)*0+a(2)*x(n-1)+.........+a(n-1)*0+a(0)*x(0)=a(0)*(x(n)+x(0))+a(2)*(x(n-1)+x(1))......其FPGA实现的逻辑框图如下图4DUCRRC滤波器实现逻辑图其中使用了4个乘法器和四个RAM以及一个ROM来存数据。RRC_CTR_6144模块控制这些乘法器和ROM。参考代码如下://////////////////////////////////////////////////////////////////////////////////////Date:SatJul2110:51:512007////Author:duanchenghong////Company:zte////Description://RRC滤波器用了4个RAM和4个乘法器完成IQ两路的滤波功能,//I,Q的处理方法完全相同。数据同时写入4个RAM中,但读的地址不//同,由于RRC滤波器的系数是对称的所以读RAM的地址也是对称的,将地址//对称的RAM读出数相加再和RRC滤波器系数相成再累加就可以得到最后的结果////////////////////////////////////////////////////////////////////////////////////modulerrc_ctr_6144(waddr,raddr0,raddr1,raddr2,raddr3,clk,reset,data_en,dat0_out,dat1_out,dat2_out,dat3_out,coef,raddr_coef,ih,il,qh,ql,coef_h,coef_l,mih,mil,mqh,mql,idat,qdat,rrc_en);output[5:0]waddr;reg[5:0]waddr;output[5:0]raddr0;wire[5:0]raddr0;output[5:0]raddr1;wire[5:0]raddr1;output[5:0]raddr2;wire[5:0]raddr2;output[5:0]raddr3;wire[5:0]raddr3;inputclk;wireclk;inputreset;wirereset;inputdata_en;wiredata_en;input[31:0]dat0_out;wire[31:0]dat0_out;input[31:0]dat1_out;wire[31:0]dat1_out;input[31:0]dat2_out;wire[31:0]dat2_out;input[31:0]dat3_out;wire[31:0]dat3_out;input[31:0]coef;wire[31:0]coef;output[3:0]raddr_coef;wire[3:0]raddr_coef;output[16:0]ih;reg[16:0]ih;output[16:0]il;reg[16:0]il;output[16:0]qh;reg[16:0]qh;output[16:0]ql;reg[16:0]ql;output[15:0]coef_h;wire[15:0]coef_h;output[15:0]coef_l;wire[15:0]coef_l;input[32:0]mih;wire[32:0]mih;input[32:0]mil;wire[32:0]mil;input[32:0]mqh;wire[32:0]mqh;input[32:0]mql;wire[32:0]mql;output[15:0]idat;reg[15:0]idat;output[15:0]qdat;reg[15:0]qdat;outputrrc_en;regrrc_en;assigncoef_h=coef[31:16];assigncoef_l=coef[15:0];reg[3:0]cnt;always@(posedgeclkornegedgereset)if(~reset)waddr=0;elseif(data_en)waddr=waddr+1'b1;always@(posedgeclkornegedgereset)if(~reset)cnt=0;elseif(data_en)cnt=0;elsecnt=cnt+1'b1;assignraddr_coef=cnt[3]?cnt-3:cnt-1'b1;//系数的地址assignraddr0=cnt[3]?waddr-23+cnt[2:0]:waddr-23+cnt[2:0]-1;assignraddr1=cnt[3]?waddr-23+cnt[2:0]+6:waddr-23+cnt[2:0]+6-1;assignraddr2=cnt[3]?waddr-cnt[2:0]-1:waddr-cnt[2:0]-1;assignraddr3=cnt[3]?waddr-cnt[2:0]-6-1:waddr-cnt[2:0]-6-1;//4个RAM的读地址always@(posedgeclkornegedgereset)if(~reset)ih=0;elseih={dat0_out[31],dat0_out[31:16]}+{dat2_out[31],dat2_out[31:16]};always@(posedgeclkornegedgereset)if(~reset)il=0;elseil={dat1_out[31],dat1_out[31:16]}+{dat3_out[31],dat3_out[31:16]};always@(posedgeclkornegedgereset)if(~reset)qh=0;elseqh={dat0_out[15],dat0_out[15:0]}+{dat2_out[15],dat2_out[15:0]};always@(posedgeclkornegedgereset)if(~reset)ql=0;elseql={dat1_out[15],dat1_out[15:0]}+{dat3_out[15],dat3_out[15:0]};//为防止相加溢出,补一位wire[35:0]ex_mih,ex_mil,ex_mqh,ex_mql;assignex_mih=mih[32]?{3'b111,mih}:{3'b000,mih};assignex_mil=mil[32]?{3'b111,mil}:{3'b000,mil};assignex_mqh=mqh[32]?{3'b111,mqh}:{3'b000,mqh};assignex_mql=mql[32]?{3'b111,mql}:{3'b000,mql};//为防止累加溢出,补3位reg[35:0]sum_ih,sum_il,sum_qh,sum_ql;always@(posedgeclkornegedgereset)if(~reset)sum_ih=0;elseif(cnt[2:0]==3'b001)sum_ih=0;elsesum_ih=sum_ih+ex_mih;always@(posedgeclkornegedgereset)if(~reset)sum_il=0;elseif(cnt[2:0]==3'b001)sum_il=0;elsesum_il=sum_il+ex_mil;always@(posedgeclkornegedgereset)if(~reset)sum_qh=0;elseif(cnt[2:0]==3'b001)sum_qh=0;elsesum_qh=sum_qh+ex_mqh;always@(posedgeclkornegedgereset)if(~reset)sum_ql=0;elseif(cnt[2:0]==3'b001)sum_ql=0;elsesum_ql=sum_ql+ex_mql;always@(posedgeclkornegedgereset)if(~reset)rrc_en=0;elseif(cnt[2:0]==3'b000)rrc_en=1'b1;elserrc_en=0;//产生RRC滤波器输出数据使能信号always@(posedgeclkornegedgereset)if(~reset)idat=0;elseif(cnt[2:0]==3'b000)idat=(((sum_ih+sum_il)13)+1'b1)1;always@(posedgeclkornegedgereset)if(~reset)qdat=0;elseif(cnt[2:0]==3'b000)qdat=(((sum_qh+sum_ql)13)+1'b1)1;//产生I,Q两路数据并对末位进行四舍五入endmodule如果是半带滤波器,考虑到内插在奇数拍时有y=a(0)*x(n)+0*0+a(2)*x(n-1)+.........+0*0+a(0)*x(0)=a(0)*(x(n)+x(0))+a(2)*(x(n-1)+x(1))......而在偶数拍有y=a(0)*0+0*x(n-1)+a(2)*0+....+a(m)x(m)+0...+0;及只有中间项有数,其他各项不是系数为0,就是数据为0,且中间项的系数一般是0.5,利用这一点可以减少FPGA的资源。HB滤波器的设计和RRC十分相似,如下图图5HB滤波器设计框图而CIC滤波器相对简单些,它实际上就是一些加法和一些减法,其设计框图如图6所示图