数字中频的基本原理和FPGA的实现
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
数字中频的基本原理和FPGA 的实现
1.基本原理
数字中频主要分两部分,数字上变频(DUC )和数字下变频(DDC)。它们的主要功能是相反,但原理和实现的方法是十分相似。在R8905项目中由于采用了零中频技术,数字上变频和下变频有一些差别,数字上变频没有了NCO 模块。另外为了降低输出信号的峰均比又加入了削峰模块CFR,而CGC 模块的引入则是补偿削峰所引起的功率损失。
图1 数字上变频模块框图
在数字下变频中RSSI
模块是信号的功率检测模块,它配合AGC 电路将信号的输出功率稳定在一定范围内。
图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实现的逻辑框图如下
图4 DUC RRC滤波器实现逻辑图
其中使用了4个乘法器和四个RAM以及一个ROM来存数据。RRC_CTR_6144模块控制这些乘法器和ROM。参考代码如下:
//////////////////////////////////////////
//////////////////////////////////////////
// Date : Sat Jul 21 10:51:51 2007
//
// Author : duan chenghong
//
// Company : zte
//
// Description :
// RRC滤波器用了4个RAM和4个乘法器完成IQ两路的滤波功能,// I,Q的处理方法完全相同。数据同时写入4个RAM中,但读的地址不// 同,由于RRC滤波器的系数是对称的所以读RAM的地址也是对称的,将地址
// 对称的RAM读出数相加再和RRC滤波器系数相成再累加就可以得到最后的结果
//////////////////////////////////////////
//////////////////////////////////////////
module rrc_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 ;
input clk ; wire clk ;
input reset ; wire reset ;
input data_en ; wire data_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 ;
output rrc_en ; reg rrc_en ;
assign coef_h=coef[31:16];
assign coef_l=coef[15:0];
reg [3:0] cnt;
always@(posedge clk or negedge reset)
if(~reset)
waddr<=0;
else
if(data_en)
waddr<=waddr+1'b1;
always@(posedge clk or negedge reset)
if(~reset)
cnt<=0;
else