数字中频verilog实现

简介 Description

NCO 是numerically controlled oscillator 三个单词的缩写,数控振荡器。与其相对应的模拟电路中还有 VCO ,voltage controlled oscillator 压控振荡器。VCO主要应用在模拟电路锁相环中,而NCO主要应用在数字信号处理上(DSP)和 DDS 数字信号合成。
我这里所说的DSP是广义的,不单单包括 DSP芯片,还包括FPGA等具备DSP功能的芯片。在最新的各种通信仪器,如雷达、软件无线电SDR,测量仪器仪表,如矢量网络分析仪(VNA, 我曾经业余自制过一个版本VNA用来测量天线,和各种射频器件,可查看我其它的blog)、频谱分析仪等都有专门DSP模块,其中FPGA是主要实现方式,在对信号进行处理,如做FFT、信号分离I Q路信号都用的了NCO。
说白了,NCO就是数字计数器,然后maping出相位和幅度。

Application

求同频(与中频信号相同)信号的幅度和相位, 下面就提取IQ路信号进行说明使用,其实原理跟模拟电路一样。

假设输入信号 f i n f_{in} fin

输 入 信 号 : f i n = x ∗ s i n ( t w + △ ) 输入信号:{f_{in}= x*sin( tw+△)} fin=xsin(tw+) x是信号幅度,△是信号相位。就是我们想要计算得到大的值

中频信号 f I , f Q f_I,f_Q fI,fQ

中 频 信 号 I : f I = s i n ( t w ) 中频信号I:{f_{I}=sin(tw)}\qquad IfI=sin(tw) 中 频 信 号 Q : f Q = s i n ( t w + φ ) 中频信号Q:{f_{Q}=sin(tw+φ)} QfQ=sin(tw+φ)这里的 φ = 1 2 π φ=\frac{1}{2}π φ=21π,幅度都假设为1,方便计算

f i n f_{in} fin与I Q中频混频。

I 路 : f i I = f I ∗ f i n = x ∗ s i n ( t w + △ ) ∗ s i n ( t w ) I路 :{f_{iI}= f_I*f_{in}= x*sin( tw+△)*sin(tw)}\qquad \qquad \qquad \qquad IfiI=fIfin=xsin(tw+)sin(tw) Q 路 : f i Q = f Q ∗ f i n = x ∗ s i n ( t w + △ ) ∗ s i n ( t w + φ ) φ = 1 2 π Q路 :{f_{iQ}= f_Q*f_{in}=x*sin(tw+△)}*sin(tw+φ) \qquad φ=\frac{1}{2}π QfiQ=fQfin=xsin(tw+)sin(tw+φ)φ=21π

把上面的公式根据积化和差
I 路 : f i I = − 1 2 x ∗ c o s ( 2 t w + △ ) − 1 2 x ∗ c o s ( △ ) I路 :{f_{iI}= -\frac {1}{2} x*cos( 2tw+△) - \frac {1}{2}x*cos(△)}\qquad \qquad \qquad \qquad \qquad IfiI=21xcos(2tw+)21xcos() Q 路 : f i Q = − 1 2 x ∗ c o s ( 2 t w + △ + φ ) − 1 2 x ∗ c o s ( △ − φ ) ( φ = 1 2 π ) Q路 :{f_{iQ}=-\frac {1}{2}x*cos(2tw+△+φ)}-\frac {1}{2}x*cos(△ - φ) \qquad (φ=\frac{1}{2}π) QfiQ=21xcos(2tw++φ)21xcos(φ)(φ=21π)

由上面的公式可以看出:混频之后每一路信号就分变为 直流和交流叠加的信号,就 I 路 I路 I而言,交流信号 − 1 2 x ∗ c o s ( 2 t w + △ ) -\frac {1}{2} x*cos( 2tw+△) 21xcos(2tw+), 直流信号 − 1 2 x ∗ c o s ( △ − φ ) -\frac {1}{2}x*cos(△ - φ) 21xcos(φ)。因为 ( φ = 1 2 π ) (φ=\frac{1}{2}π) (φ=21π), − 1 2 x ∗ c o s ( △ − φ ) → 1 2 x ∗ s i n ( △ ) -\frac {1}{2}x*cos(△ - φ) \to\frac {1}{2}x*sin(△) 21xcos(φ)21xsin() 可得Q路
Q 路 : f i Q = − 1 2 x ∗ s i n ( 2 t w + △ ) + 1 2 x ∗ s i n ( △ ) Q路 :{f_{iQ}=-\frac {1}{2}x*sin(2tw+△)}+\frac {1}{2}x*sin(△ ) QfiQ=21xsin(2tw+)+21xsin()
做累加 s u m ( I ) = ∑ t = 0 T − 1 [ − 1 2 x ∗ c o s ( 2 t w + △ ) − 1 2 x ∗ c o s ( △ ) ] T = N ∗ F R E Q s a m p l i n g F R E Q i f sum(I)=\displaystyle \sum_{t=0}^{T-1} [-\frac {1}{2} x*cos( 2tw+△) - \frac {1}{2}x*cos(△)] \qquad T = \frac {N *FREQ_{sampling}}{FREQ_{if}} sum(I)=t=0T1[21xcos(2tw+)21xcos()]T=FREQifNFREQsampling s u m ( I ) = − T ∗ 1 2 x ∗ c o s ( △ ) sum(I)= -T* \frac {1}{2}x*cos(△)\qquad \qquad \qquad \qquad \qquad \qquad \qquad \qquad \qquad \qquad \qquad sum(I)=T21xcos()
s u m ( Q ) = ∑ t = 0 T − 1 [ − 1 2 x ∗ s i n ( 2 t w + △ ) + 1 2 x ∗ s i n ( △ ) ] T = N ∗ F R E Q s a m p l i n g F R E Q i f sum(Q)=\displaystyle \sum_{t=0}^{T-1} [-\frac {1}{2} x*sin( 2tw+△) + \frac {1}{2}x*sin(△)] \qquad T = \frac {N *FREQ_{sampling}}{FREQ_{if}} sum(Q)=t=0T1[21xsin(2tw+)+21xsin()]T=FREQifNFREQsampling s u m ( Q ) = T ∗ 1 2 x ∗ s i n ( △ ) sum(Q)= T* \frac {1}{2}x*sin(△)\qquad \qquad \qquad \qquad \qquad \qquad \qquad \qquad \qquad \qquad \qquad sum(Q)=T21xsin()
到此为止我们可以求出相位 △ = a r c t a n ( T ∗ 1 2 x ∗ s i n ( △ ) T ∗ 1 2 x ∗ c o s ( △ ) ) → a r c t a n ( − s u m ( I ) s u m ( Q ) ) △ = arctan(\frac{ T* \frac {1}{2}x*sin(△)}{T* \frac {1}{2}x*cos(△)}) \to arctan(-\frac {sum(I)}{sum(Q)}) =arctan(T21xcos()T21xsin())arctan(sum(Q)sum(I))
得到相位就能求出幅度 x x x 的值了。
x = 1 T 2 ∗ s u m ( Q ) s i n ( △ ) x =\frac{1}{T} \frac{2*sum(Q)}{sin(△)} x=T1sin()2sum(Q)

verilog IF实现

module NCO_2MHZ
#(
parameter THRESHOLD = 8'd23,//40 - 1,CLK=48MHz
QUADRATURE_START = 8'd6 // 40*1/4 - 1
)
(
    input RST,
    input CLK,
	output PHASE_START, //if sin = 0, output a pulse
    output [7:0] SIN_COUNTER,
	output [7:0] COS_COUNTER,
	output signed [11:0] SIN_VALUE,
	output signed [11:0] COS_VALUE
    );
	
reg [7:0] SinCountorReg;
reg [7:0] CosCountorReg;
reg [11:0] SinVlaue[THRESHOLD:0];

initial begin
SinVlaue[0] = 12'd0;
SinVlaue[1] = 12'd530;
SinVlaue[2] = 12'd1024;
SinVlaue[3] = 12'd1447;
SinVlaue[4] = 12'd1773;
SinVlaue[5] = 12'd1977;
SinVlaue[6] = 12'd2047;
SinVlaue[7] = 12'd1977;
SinVlaue[8] = 12'd1773;
SinVlaue[9] = 12'd1447;
SinVlaue[10] = 12'd1024;
SinVlaue[11] = 12'd530;
SinVlaue[12] = 12'd0;
SinVlaue[13] = -12'd530;
SinVlaue[14] = -12'd1024;
SinVlaue[15] = -12'd1447;
SinVlaue[16] = -12'd1773;
SinVlaue[17] = -12'd1977;
SinVlaue[18] = -12'd2047;
SinVlaue[19] = -12'd1977;
SinVlaue[20] = -12'd1773;
SinVlaue[21] = -12'd1447;
SinVlaue[22] = -12'd1024;
SinVlaue[23] = -12'd530;

end
	
always@(posedge CLK,negedge RST)
begin
	if(!RST)
		begin
			SinCountorReg = 0;
			CosCountorReg = QUADRATURE_START;
		end
	else
		begin
		   if(SinCountorReg == THRESHOLD)
				begin 
					SinCountorReg = 0;
				end
			else
				begin
					SinCountorReg =  SinCountorReg + 8'd1;
				end
			
		   if(CosCountorReg == THRESHOLD)
				begin
				   CosCountorReg =0;
				end
			else
				begin
				  CosCountorReg =  CosCountorReg + 8'd1;
				end
				
		end		



end
assign SIN_COUNTER = SinCountorReg;
assign COS_COUNTER = CosCountorReg;
assign SIN_VALUE = SinVlaue[SinCountorReg];
assign COS_VALUE = SinVlaue[CosCountorReg];
endmodule

Ending

上面的NCO是我的VNA中FPGA中使用的代码。由于水平有限,只能暂时提供verilog的代码了。其原理还是很简单的。
当然这个NCO

parameter THRESHOLD = 8'd23,//40 - 1,CLK=48MHz
QUADRATURE_START = 8'd6 // 40*1/4 - 1  

修改这两个值就能修改IF 的频率。当然你也以设置为reg 类型,外部可编程(SDR和DDS就是这样应用的)。ram maping 部分我用的12bits 的输出值。对我的项目来说可能够用了。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值