当前位置:   article > 正文

FPGA中Verilog HDL/VHDL实现NCO(数字控制振荡器)_verilog实现nco

verilog实现nco

数控振荡器(NCO,numerically controlled oscillator)软件无线接收机,直接频率合成器(DDS),快速傅里叶变换(FFT)的重要组成部分,NCO采用全数字技术实现,具有分辨率高,频率切换快,相位噪声低等优点。
一般实现NCO的方法是查表法,即实现计算好各个相位的正余弦值存储在查找表中,然后通过寻址输出相应的正余弦值。
下面利用查表法分两步实现一个基于FPGA以及VerilogHDL语言的NCO。
1.利用matlab软件将所需要的相位的正余弦值计算好待用
其中利用matlab产生正余弦值的程序如下:

clear,clc,close all
%%设置参数
sam_clk=20; %%采样频率
out_freq=1;%%输出频率
data_width=18;%%数据位宽, 量化位数
N=20;
%%计算正弦值
sin_1=-sin(([0:N])*2*pi*out_freq/sam_clk);
sin_1_out=round(sin_1*2^(data_width-1));
 %%计算余弦值
cos_1=cos(([0:N])*2*pi*out_freq/sam_clk);
cos_1_out=round(cos_1*2^(data_width-1));
%%调整输出格式
sin=[sin_1_out];
cos=[cos_1_out];

sin_bin=zeros(1,2001);
cos_bin=zeros(1,2001);
sin_bin=[];
cos_bin=[];
for cnt=1:20
sin_bin=[sin_bin    ; dec2binPN(sin(cnt),18)];
end 
for cnt=1:20
cos_bin=[cos_bin    ; dec2binPN(cos(cnt),18)];
end 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26

将得到的值plot得正余弦波形如下:
matlab中得到的正余弦波形
2.FPGA中实现nco
首先将上一步matlab中生成的数据导出,存入mif表中,然后在quartus中调用两个rom并用mif分别进行初始化,然后通过程序调用这两个rom,分别根据地址输出对应的值,编写的verilog HDL程序如下:

module nco(
     input clk,
	 input nco_en,
	 input rst,
	 
	 output [17:0]nco_I,
	 output [17:0]nco_Q
);
     
	 reg [4:0]addr;
	 
	 always@(posedge clk or negedge rst)
	 if(rst==1'b0)
	    begin 
	     addr<=5'd0;  
		end 
	 else 
	    begin 
		    if(nco_en==1'b0) 
			  addr<=5'd0;
			else 
			  begin 
			    if(addr==5'd19) 
				  addr<=5'd0;
				else 
				  addr<=addr+1'd1;
			  end 
		end 
		
	 wire [17:0] nco_I_temp;
	 wire [17:0] nco_Q_temp;
	 
	 rom_I  my_rom_I(
	                .address(addr),
	                .clock(clk),
	                .q(nco_I_temp));
					
	 rom_Q  my_rom_Q(
	                .address(addr),
	                .clock(clk),
	                .q(nco_Q_temp));
					
	assign nco_I=nco_I_temp;
	assign nco_Q=nco_Q_temp;

endmodule
	 
	 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48

编写测试代码如下:

`timescale 1ps/1ps
`define clock_period  20 

module nco_tb;
        reg rst;
		  reg clk;
		  reg nco_en;

		  wire [17:0]nco_I;
		  wire [17:0]nco_Q;
		  
	nco  my_nco(
         .clk(clk),
	      .nco_en(nco_en),
	      .rst(rst),
			.nco_I(nco_I),
	      .nco_Q(nco_Q));
			
		  initial 
		     begin 
		        clk=1'b1;
			  end 
		   always #(`clock_period/2) clk=~clk;	  
			
			initial 
			   begin 
				   rst=1'b0;
				   #(`clock_period*10)
					rst=1'b1;
					nco_en=1'b1;
					#(`clock_period*200)
					$stop;
				 end 
endmodule		   
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34

经过quartus ii 软件调用modelsim仿真软件验证所编写nco程序,得到结果如下:
仿真得到的nco输出正余弦波形
以上就基于查表法实现了数控振荡器nco

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/花生_TL007/article/detail/625463
推荐阅读
相关标签
  

闽ICP备14008679号