一、調用步驟
1、打開Quartus
右上角搜索ROM,如圖所示
2、點擊后會彈出如圖所示
其中文件路徑需要選擇你自己的
3、點擊OK彈出如圖所示
圖中紅色改為12與1024
4、然后一直點NEXT,直到下圖
這里要選擇后綴為 .mif的文件
5、用C語言生成 .mif文件
// 生成1024點正弦波表(C程序)
#include <stdio.h>
#include <math.h>#define PI 3.14159265358979323846
#define DEPTH 1024 // ROM深度
#define WIDTH 12 // 數據寬度(12位)int main() {FILE *fp = fopen("sine_rom.mif", "w");if (!fp) return -1;fprintf(fp, "WIDTH=%d;\nDEPTH=%d;\nADDRESS_RADIX=HEX;\nDATA_RADIX=HEX;\nCONTENT BEGIN\n", WIDTH, DEPTH);for (int i = 0; i < DEPTH; i++) {float phase = (float)i / DEPTH * 2 * PI;short value = (short)(sin(phase) * (pow(2, WIDTH-1) - 1));fprintf(fp, "%03x : %03x;\n", i, value & 0xFFF);}fprintf(fp, "END;\n");fclose(fp);return 0;
}
然后運行.c文件,會在文件所在目錄下生成一個.mif文件,然后你就在第4步中選擇它就行。
然后一直next,直到finish
二 、核心模塊
1、相位累加器
module phase_accumulator (input wire clk, // 50MHz系統時鐘input wire [23:0] K, // 頻率控制字(24位)output reg [23:0] phase // 相位累加值
);always @(posedge clk) beginphase <= phase + K; // 相位累加end
endmodule
2、波形選擇器
module waveform_selector (input wire [23:0] phase, // 相位地址(24位)input wire sel, // 波形選擇(0:正弦,1:方波)output reg [11:0] data_out
);reg [11:0] sine_data; // 正弦波數據reg [11:0] square_data; // 方波數據// 正弦ROMreg [11:0] sine_rom [0:1023];initial begin$readmemh("sine_rom.mif", sine_rom);endassign sine_data = sine_rom[phase[22:12]]; // 取中間12位地址// 方波ROMreg [11:0] square_rom [0:1023];initial begin$readmemh("square_rom.mif", square_rom);endassign square_data = square_rom[phase[22:12]];always @(*) beginif (sel) data_out = square_data;else data_out = sine_data;end
endmodule
3、時鐘分頻器
module clock_divider (input wire clk_in, // 50MHz輸入時鐘output reg clk_out // 分頻后的時鐘(10MHz)
);reg [1:0] cnt;always @(posedge clk_in) begincnt <= cnt + 1;if (cnt == 2'b11) // 分頻系數為4(50MHz → 12.5MHz),或調整為5(10MHz)clk_out <= ~clk_out;end
endmodule
4、頂層模塊
module dds_top (input wire clk_50m, // 系統時鐘(50MHz)input wire [23:0] K, // 頻率控制字(來自撥碼開關)input wire sel, // 波形選擇(按鈕控制)output reg [11:0] dac_data // DAC數據輸出
);wire [23:0] phase; // 相位累加值wire clk_out; // 分頻后的時鐘// 相位累加器phase_accumulator phase_acc (.clk(clk_50m),.K(K),.phase(phase));// 波形選擇器waveform_selector wave_sel (.phase(phase),.sel(sel),.data_out(dac_data));// 時鐘分頻(可選,用于DAC時鐘)clock_divider clk_div (.clk_in(clk_50m),.clk_out(clk_out) // 連接到DAC時鐘輸入);
endmodule
5、波形圖
參考博客https://blog.csdn.net/weixin_50722839/article/details/109960391