赞
踩
此篇文章记录使用FPGA实现DDS的过程,如有错误还请批评指正,谢谢。
提示:以下是本篇文章正文内容,下面案例可供参考
DDS信号发生器采用直接数字频率合成(Direct Digital Synthesis,简称DDS)技术,把信号发生器的频率稳定度、准确度提高到与基准频率相同的水平,并且可以在很宽的频率范围内进行精细的频率调节。采用这种方法设计的信号源可工作于调制状态,可对输出电平进行调节,也可输出各种波形。
根据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_A, Data_B ); input clk; input reset; input [31:0]F_word; //频率控制字(控制频率) input [11:0]P_word; //相位控制字(控制相位,位宽由ROM数据depth决定) output [13:0]Data_A; //输出正弦波(位宽由DAC模块确定) output [13:0]Data_B; //输出三角波(位宽由DAC模块确定) //--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_sin_wave ROM_sin_wave( .clka(clk), .addra(ROM_output), .douta(Data_A) ); //--例化ROM IP核生成三角波 ROM_triangular_wave ROM_triangular_wave( .clka(clk), .addra(ROM_output), .douta(Data_B) ); endmodule
`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的读取功能选择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核。
【附件:】链接:https://pan.baidu.com/s/1r7uB4a7JYvlPkylWt_7GqA?pwd=s8j7
提取码:s8j7
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。