DDS结构的FPGA实现
- 前言
- 一、DDS是什么?
- 二、DDS基本结构
- 三、基于FPGA实现
- 四、TB文件展示
- 五、仿真波形展示
- 六、ROM-IP核的配置
前言
此篇文章记录使用FPGA实现DDS的过程,如有错误还请批评指正,谢谢。
提示:以下是本篇文章正文内容,下面案例可供参考
一、DDS是什么?
DDS信号发生器采用直接数字频率合成(Direct Digital Synthesis,简称DDS)技术,把信号发生器的频率稳定度、准确度提高到与基准频率相同的水平,并且可以在很宽的频率范围内进行精细的频率调节。采用这种方法设计的信号源可工作于调制状态,可对输出电平进行调节,也可输出各种波形。
二、DDS基本结构
三、基于FPGA实现
根据DDS原理图可以得出如下代码:
`timescale 1ns / 1ps
//
// Create Date: 2022/11/28 17:34:46
// Module Name: DDS_design
// Revision:VIVADO 2018.3
//
module DDS_design(
clk,
reset,
F_word,
P_word,
Data
);
input clk;
input reset;
input [31:0] F_word;//频率控制字
input [11:0]P_word;//相位控制字
output [13:0]Data;
//--F_word、P_word经过一个同步寄存器-------------------------------------------------------------------------------------------------------------------
reg [31:0] Fword;
always @ (posedge clk )
Fword <= F_word ;
reg [11:0] Pword;
always @ (posedge clk )
Pword <= P_word ;
//----------------------------------------------------------------------------------------------------------------------------------------------------
//--phase_acc-相位累加器------------------------------------------------------------------------------------------------------------------------------
reg [31:0]phase_acc;
always @ (posedge clk or negedge reset )
if (!reset)
phase_acc <= 0;
else
phase_acc <= phase_acc + Fword;
//----------------------------------------------------------------------------------------------------------------------------------------------------
//--ROM_output波形数据表-------------------------------------------------------------------------------------------------------------------------------
wire [11:0]ROM_output;
assign ROM_output = phase_acc[31:20] + Pword;
//----------------------------------------------------------------------------------------------------------------------------------------------------
//--例化ROM IP核生成正弦波
ROM_WD ROM_WD(
.clka(clk),
.addra(ROM_output),
.douta(Data)
);
//--例化ROM IP核生成三角波
blk_mem_gen_0 ROM_triangular_wave(
.clka(clk),
.addra(ROM_output),
.douta(Data_B)
);
endmodule
四、TB文件展示
`timescale 1ns / 1ps
//
// Company:
// Engineer:
//
// Create Date: 2022/11/28 19:31:25
// Design Name:
// Module Name: DDS_design_tb
//
module DDS_design_tb();
reg clk;
reg reset;
reg [31:0] F_word_A,F_word_B;
reg [11:0] P_word_A,P_word_B;
wire [13:0]DataA,DataB,DataC,DataD;
DDS_design DDS_design_1(
.clk(clk),
.reset(reset),
.F_word(F_word_A),
.P_word(P_word_A),
.Data_A(DataA),
.Data_B(DataB)
);
DDS_design DDS_design_2(
.clk(clk),
.reset(reset),
.F_word(F_word_B),
.P_word(P_word_B),
.Data_A(DataC),
.Data_B(DataD)
);
initial clk = 1;
always #10 clk = ~clk;
initial begin
reset = 0;
F_word_A = 65536;
P_word_A = 0;
F_word_B = 65536;
P_word_B = 1024;
#201;
reset = 1;
#20000000;
F_word_A = 524288;
P_word_A = 0;
F_word_B = 524288;
P_word_B = 2048;
#20000000;
$stop;
end
endmodule
此处对设计源文件例化两次,便于观察相位不同时的波形图像。
五、仿真波形展示
根据两个波形图比对当设置频率( F_word_A = F_word_B = 65536)一样时,相位相差(P_word_A = 0 P_word_B = 1024(总数据量为4096))π/2。下图中蓝、黄竖线之间时间为一个正弦波的时钟周期1.31072ms根据频率计算公式:F = 1/t(HZ)=(1/1.31072)1000 (HZ)=762.9395(HZ)
根据 F_word = 65536 可计算出 F = (F_wordF_clk)/2^N = (65536*50000000)/(2 ^32) = 762.9395(HZ)
F_clk为FPGA开发板时钟频率50MHZ,N为32位相位累加器[31:0]phase_acc。具体计算方法如下图所示,
至此验证成功。
六、ROM-IP核的配置
在第三章节尾段例化了一个ROM的IP核,用于添加初始正弦波波值。此处配置如下:
此处只用ROM的读取功能选择Single port ROM即可。
Port A Width为输出Data的位宽,根据代码中[13:0]Data此处选择14位即可,Port A Depth为个数由代码中 [11:0]ROM_output选取4096即可。
此处加载初始数据,使用软件生成正弦波数据(可使用matlab或网上搜索提供的软件)对应数据为14位位宽,数据个数为4096。
此处为资源使用情况。
点击Generate生成对应ROM的IP核。