赞
踩
数控振荡器(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
将得到的值plot得正余弦波形如下:
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
编写测试代码如下:
`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
经过quartus ii 软件调用modelsim仿真软件验证所编写nco程序,得到结果如下:
以上就基于查表法实现了数控振荡器nco
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。