DDS---相位累加器、ROM查找表的FPGA实现

作者:金牛区福生殡葬服务部 来源:www.cdfsbz.com 发布时间:2017-09-02 11:45:40
DDS---相位累加器、ROM查找表的FPGA实现

\

图1 DDS原理框图

首先谈一下DDS(直接数字式频率合成器)的原理,如图1所示。 由相位累加器、ROM查找表、高速DAC、低通滤波器(LPF)组成。 设频率控制字的宽度为 N bits,则频率控制字的取值范围:0~2^N。 相位累加器是一个计数器,宽度一般要超过N+1位(抽样定理),在参考时钟Fref 的上升沿,计数器自增一次,步长为频率控制字对应的值。

相位累加器的输出 作为 R0M查找表的 “地址输入”,ROM查找表中存储了任意波形的 “ 幅值 - 相位 ” 对应表,相位累加器提供相位,ROM查找表根据这个相位输出对应的幅值。 设相位累加器的宽度为M位,即将2*pi 等分成 2^M 份,频率控制字为 K,即累加器步长为 K。则输出频率 Fout = Fref / (2^M) * K。 当K=1时,是最小输出频率,Fout = Fref / (2^M);其他输出频率都是这个频率的整倍数。

后面的高速DA和LPF就不是FPGA所做的事情了,就不赘述了。

下面我们通过VIVADO仿真一个简单的DDS工程:

1 建立一个VIVADO工程

2 设计相位累加器,Verilog HDL代码如下:

module PhaseAdder(
input clk,
input rst,
input [10:0]FreqCtrl, //频率控制字,相位累加步长
output [11:0]phase
);

reg [11:0]phase_reg = 0;
assign phase = phase_reg;
always@(posedge rst or posedge clk)
begin
if(rst)
phase_reg <= 12'd0;
else
phase_reg <= phase_reg + FreqCtrl; //溢出循环
end
endmodule

说明:clk就是框图的Fref,可以连接FPGA板载晶振,或通过晶振分频后倍频后的时钟

rst是复位引脚,因为basys3板上的按键接的是下拉电阻,所以这边的复位信号是高电平有效

FreqCtrl是频率控制字,可以通过MCU提供,在程序中,作为计数器的累加步长。

phase是相位累加器的实时输出,作为ROM查找表的地址,因为本工程将正弦信号经4096点抽样,所以相位累加器的地址为12位(2^12 = 4096)

3 设计ROM查找表

通过Matlab将正弦信号作4096点抽样,并生成" .coe "文件(Quartus II是要求“ .mif ”文件,VIVADO是要求" .coe "文件,但最终还是要转换成“ .mif ”文件),

用于初始化ROM。

Matlab代码如下:

n = 0:4095 ;
yn = sin(2*pi/4096*n) ;


yn = round((yn+1)*2047);


plot(n,yn);


fid = fopen('rom.coe','wt');
fprintf(fid,'memory_initialization_radix = 10;\nmemory_initialization_vector = ');


for i = 1 : 4096
if mod(i-1,16) == 0
fprintf(fid,'\n');
end
fprintf(fid,'%4d,',yn(i));
end

生成COE文件之后,在VIVADO软件中添加IP核,如下图,双击Distributed Memory Generator

\

出现下列界面,设置ROM的深度(抽样点数)和数据的宽度(根据高速DA的数据口宽度而定!!!)

\

然后点击第3个选项卡(RST & Initialization),添加刚才由matlab生成的COE文件,Radix可以选择 2 , 10 , 16,代表COE文件中的数据进制。设置完成后点击OK即可。

\

至此,我们已经成功 生成 并 初始化 了 ROM查找表,其vhd端口声明如下。我们可以在顶层文件中直接例化这个ROM查找表。

\

4 设计顶层文件,串接相位累加器,代码如下:



module DDS(
input clk,
input rst,
input [10:0]FreqCtrl,
output [11:0]waveform
);

wire [11:0]phase;
PhaseAdder u_PhaseAdder
(
.clk (clk),
.rst (rst),
.FreqCtrl (FreqCtrl),
.phase (phase)
);
DDS_ROM u_DDS_ROM
(
.a (phase[11:0]),
.spo (waveform)
);
endmodule

至此,我们整个的工程设计完毕,Sources结构图如下图所示:

\

RTL Analysis 如下:

\

5 添加仿真文件,编写testbench,代码如下:



module simu(


);

reg clk = 0;
always #5 clk <= ~clk; //100 MHz

reg rst = 0;

reg [10:0]FreqCtrl = 1;
wire [11:0]waveform;

DDS u_DDS
(
.clk (clk),
.rst (rst),
.FreqCtrl (FreqCtrl),
.waveform (waveform)
);

endmodule

点击 Run Simulation 观察波形图:可见频率控制字FreqCtrl = 1时,在40960ns中输出 1个 正弦周期。

\

修改频率控制字FreqCtrl = 2,重新仿真,如下图:可见频率控制字FreqCtrl = 2时,在40960ns中输出 2个 正弦周期。

\

企业建站2800元起,携手武汉肥猫科技,做一个有见地的颜值派!更多优惠请戳:荆门网站制作 http://jingmen.666rj.com

  • 上一篇:蘑菇预装器实战经验:浅析电脑装机员快速赚钱攻略
  • 下一篇:最后一页
  • 
    COPYRIGHT © 2015 金牛区福生殡葬服务部 ALL RIGHTS RESERVED.
    购买cdfsbz.com友情链接、项目合作请联系客服QQ:2500-38-100 邮箱:2500-38-100#QQ.com(#换@)
    本站所有原创信息,未经许可请勿任意转载或复制使用 网站地图 技术支持:肥猫科技
    精彩专题:网站建设
    购买本站友情链接、项目合作请联系客服QQ:2500-38-100