1.實驗目的
1.1掌握直接數字頻率合成(DDS)的基本原理及其實現方法。
1.2在DE2-115 FPGA開發板上設計一個可調頻率的正弦波和方波發生器,頻率范圍10Hz~5MHz,最小分辨率小于1kHz。
1.3使用Quartus II進行仿真,并通過SignalTap II實時觀測輸出波形。
2.實驗原理
2.1 DDS(Direct Digital Frequency Synthesis)是一種通過數字方式生成高精度、高穩定度頻率信號的技術。其核心由三部分組成:
相位累加器:在時鐘驅動下累加頻率控制字(K),輸出相位值。
波形查找表(LUT):存儲波形采樣數據(如正弦波、方波)。
DAC轉換(可選):將數字波形轉換為模擬信號(本實驗僅觀測數字輸出)。
2.2輸出頻率計算公式:
K:頻率控制字(Tuning Word)
fclkfclk?:系統時鐘(50MHz)
NN:相位累加器位數(32位)
3.關鍵參數設計
3.1頻率分辨率:
3.2頻率范圍:
最小值:K=1K=1,fout=0.0116Hzfout?=0.0116Hz
最大值(Nyquist限制):fout≤25MHzfout?≤25MHz,實際設計目標5MHz。
4.實驗設計
4.1 硬件設計
(1)相位累加器
32位累加器,每個時鐘周期增加頻率控制字?KK。
輸出相位值的高10位作為LUT地址(1024點正弦表)。
(2)波形查找表(LUT)
正弦波:c生成1024點8位有符號數據(.mif文件),存儲于ROM。
方波:直接取相位累加器最高位(占空比50%)。
(3)頂層模塊
輸入:系統時鐘(50MHz)、復位信號、頻率控制字?KK、波形選擇信號。
輸出:8位數字波形數據。
4.2 關鍵代碼
4.2.1相位累加器
module addr_cnt(CPi,K,ROMaddr,Address);input CPi;input [12:0] K;output reg [9:0] ROMaddr;output reg [16:0] Address;always @(posedge CPi) beginAddress=Address+K;ROMaddr=Address[16:7];end
Endmodule
選擇Create Symbol Files for Current File
4.2.2波形存儲器ROM
方波模塊
module squwave(CPi,RSTn,Address,Qsquare);input CPi;input RSTn;input [16:0] Address;output reg [11:0] Qsquare;always @(posedge CPi)if (!RSTn)Qsquare=12'h000; else beginif(Address<=17'h0FFFF)Qsquare=12'hFFF;else Qsquare=12'h000;end
endmodule
4.2.3正弦波形存儲器
其中Sine1024.mif的代碼如下:
/*myMIF.c*/
#include <stdio.h>
#include <math.h>
#define PI 3.141592
#define DEPTH 1024
#define WIDTH 12
int main(void)
{int n,temp;float v;FILE *fp;fp=fopen("Sine1024.mif","w+");if(NULL==fp)printf("Can not creat file!\r\n");else{printf("File created successfully!\n");fprintf(fp,"DEPTH=%d;\n",DEPTH);fprintf(fp,"WIDTH=%d;\n",WIDTH);fprintf(fp,"ADDRESS_RADIX=HEX;\n");fprintf(fp,"DATA_RADIX=HEX;\n");fprintf(fp,"CONTENT\n");fprintf(fp,"BEGIN\n");for(n=0;n<DEPTH;n++){v=sin(2*PI*n/DEPTH);temp=(int)((v+1)*4095/2);fprintf(fp,"%04x : %03x;\n",n,temp);}fprintf(fp,"END;\n");fclose(fp);}}
運行.exe文件生成.mif文件
LPM_ROM定制正弦波形存儲器:
以下進行修改:
4.2.4頂層電路設計
module DDS_top (CLOCK_50,RSTn,WaveSel,K,
WaveValue,LEDG,CLOCK_100);input CLOCK_50;input RSTn;input [1:0] WaveSel;input [12:0] K;output reg [11:0] WaveValue;wire [9:0] ROMaddr/* synthesis keep */;wire [16:0] Address;wire [11:0] Qsine,Qsquare;output [0:0] LEDG;output CLOCK_100;wire CPi=CLOCK_100;PLL100M_CP PLL100M_CP_inst(.inclk0(CLOCK_50),.c0(CLOCK_100),.locked(LEDG[0]));addr_cnt U0_instance(CPi,K,ROMaddr,Address);SineROM ROM_inst(.address(ROMaddr),.clock(CPi),.q(Qsine));squwave U1(CPi,RSTn,Address,Qsquare);always @(posedge CPi)begincase(WaveSel)2'b01:WaveValue=Qsine;2'b10:WaveValue=Qsquare;default:WaveValue=Qsine;endcaseend
endmodule
4.2.5配置文件
module DE2_115_DDS_top(CLOCK_50,KEY,SW,GPIO_0,LEDG);input CLOCK_50;input [3:3] KEY;input [17:0] SW;output [12:0] GPIO_0;output [0:0] LEDG;wire CLOCK_100;assign GPIO_0[12]=CLOCK_100;wire RSTn=KEY[3];wire [1:0] WaveSel=SW[17:16];wire [12:0] K=SW[12:0];wire [11:0] WaveValue;assign GPIO_0[11:0]=WaveValue;DDS_top DE2(CLOCK_50,RSTn,WaveSel,K,WaveValue,LEDG,CLOCK_100);
endmodule
4.2.5仿真
進入界面配置