FPGA学习——DE2-115开发板上设计波形发生器
1. 实验目的
- 掌握直接数字频率合成(DDS)技术的基本原理和应用。
- 使用DE2-115开发板实现正弦波和方波的生成。
- 使用SignalTap II嵌入式逻辑分析仪测试输出波形的离散数据。
2. 实验原理
- DDS技术:通过相位累加器生成相位信息,结合波形存储器(ROM)输出波形数据。
- 波形存储器:使用ROM存储正弦波和方波的采样数据。
- 频率控制:通过调整相位累加器的步长实现不同频率的输出。
3. 实验步骤
- 生成波形数据:使用C语言或MATLAB生成正弦波和方波的采样数据,并保存为MIF文件。
- 调用ROM IP核:在Quartus中生成ROM IP核,并加载生成的MIF文件。
- 设计DDS模块:实现相位累加器和波形选择逻辑。
- 顶层模块设计:将DDS模块与开发板的时钟、复位、按键等信号连接。
4. 代码实现
4.1 顶层模块代码
module DE2_115_DDS_top(input CLOCK_50,input [3:0] 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(CLOCK_50),.RSTn(RSTn),.WaveSel(WaveSel),.K(K),.WaveValue(WaveValue),.LEDG(LEDG),.CLOCK_100(CLOCK_100));
endmodule
4.2 DDS核心模块代码
module DDS_top(input CLOCK_50,input RSTn,input [1:0] WaveSel,input [12:0] K,output reg [11:0] WaveValue,output reg [0:0] LEDG,output CLOCK_100
);reg [31:0] PhaseAcc;reg [10:0] ROMAddr;reg [11:0] SineValue, SquareValue;// 时钟分频reg [24:0] ClockDiv;wire Clock_100;always @(posedge CLOCK_50 or negedge RSTn) beginif (!RSTn) beginClockDiv <= 0;end else beginif (ClockDiv == 10000000) beginClockDiv <= 0;Clock_100 <= ~Clock_100;end else beginClockDiv <= ClockDiv + 1;endendend// 相位累加器always @(posedge CLOCK_50 or negedge RSTn) beginif (!RSTn) beginPhaseAcc <= 0;end else beginPhaseAcc <= PhaseAcc + K;endend// ROM地址生成assign ROMAddr = PhaseAcc[31:21];// 波形选择always @(posedge CLOCK_50 or negedge RSTn) beginif (!RSTn) beginSineValue <= 0;SquareValue <= 0;WaveValue <= 0;LEDG <= 0;end else begincase (WaveSel)2'b00: beginWaveValue <= SineValue;LEDG <= 1'b0;end2'b01: beginWaveValue <= SquareValue;LEDG <= 1'b1;enddefault: beginWaveValue <= 0;LEDG <= 0;endendcaseendend// ROM模块rom_sine rom_sine_inst(.address(ROMAddr),.clock(CLOCK_50),.q(SineValue));rom_square rom_square_inst(.address(ROMAddr),.clock(CLOCK_50),.q(SquareValue));
endmodule
4.3 ROM模块代码
// 正弦波ROM
module rom_sine(input [10:0] address,input clock,output reg [11:0] q
);reg [11:0] mem [0:2047];initial begin$readmemb("Sine1024.mif", mem);endalways @(posedge clock) beginq <= mem[address];end
endmodule// 方波ROM
module rom_square(input [10:0] address,input clock,output reg [11:0] q
);reg [11:0] mem [0:2047];initial begin$readmemb("Square1024.mif", mem);endalways @(posedge clock) beginq <= mem[address];end
endmodule
4.4 波形数据生成代码
// 生成正弦波MIF文件
#include <stdio.h>
#include <math.h>#define PI 3.141592
#define DEPTH 1024
#define WIDTH 12int main(void)
{int n, temp;float v;FILE *fp;fp = fopen("Sine1024.mif", "w+");if (NULL == fp) {printf("Can not creat file!\r\n");return -1;} 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);}return 0;
}
5.定制ROM IP核设置
6.查看生成RTL
7.Signal Tap采样分析
8.结果