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核。