1.编写MATLB代码 生成ROM的数据
clc;clear;F1=1; %信号频率Fs=2^12; %采样频率P1=0; %信号初始相位N=2^12; %采样点数t=[0:1/Fs:(N-1)/Fs]; %采样时刻ADC=2^7 - 1; %直流分量A=2^7; %信号幅度s1=A*sin(2*pi*F1*t + pi*P1/180) + ADC; %正弦波信号s2=A*square(2*pi*F1*t + pi*P1/180) + ADC; %方波信号s3=A*sawtooth(2*pi*F1*t + pi*P1/180,0.5) + ADC; %三角波信号s4=A*sawtooth(2*pi*F1*t + pi*P1/180) + ADC; %锯齿波信号%创建mif文件fild = fopen('rom_wave.mif','wt');%写入mif文件头fprintf(fild, '%s\n','WIDTH=8;'); %位宽fprintf(fild, '%s\n\n','DEPTH=16384;'); %深度fprintf(fild, '%s\n','ADDRESS_RADIX=UNS;'); %地址格式fprintf(fild, '%s\n\n','DATA_RADIX=UNS;'); %数据格式fprintf(fild, '%s\t','CONTENT'); %地址fprintf(fild, '%s\n','BEGIN'); %开始for j = 1:4for i = 1:Nif j == 1 %打印正弦信号数据s0(i) = round(s1(i)); %对小数四舍五入以取整fprintf(fild, '\t%g\t',i-1); %地址编码endif j == 2 %打印方波信号数据s0(i) = round(s2(i)); %对小数四舍五入以取整fprintf(fild, '\t%g\t',i-1+N); %地址编码endif j == 3 %打印三角波信号数据s0(i) = round(s3(i)); %对小数四舍五入以取整fprintf(fild, '\t%g\t',i-1+(2*N)); %地址编码endif j == 4 %打印锯齿波信号数据s0(i) = round(s4(i)); %对小数四舍五入以取整fprintf(fild, '\t%g\t',i-1+(3*N)); %地址编码endif s0(i) <0 %负1强制置零s0(i) = 0endfprintf(fild, '%s\t',':'); %冒号fprintf(fild, '%d',s0(i)); %数据写入fprintf(fild, '%s\n',';'); %分号,换行endendfprintf(fild, '%s\n','END;'); %结束fclose(fild);
2.添加IP核并例化

rom_wave rom_wave_inst(.address (rom_addr ), //ROM读地址.clock (sys_clk ), //读时钟.q (dac_data ) //读出波形数据
3.编写DDS_Multi代码
/********************************************************************************名称 :DDS_Multi.v功能:四种DDS 波形发生器作者:王世阳创建日期:2021.04.25修改日期1:修改内容1:*********************************************************************************/module DDS_Multi(input wire sys_clk ,input wire sys_rst_n ,input wire [3:0] key ,output wire dac_clk ,output wire [7:0] dac_data);//DAC模块时钟assign dac_clk = ~sys_clk;parameter sin_wave = 4'b0001 ,squ_wave = 4'b0010 ,tri_wave = 4'b0100 ,saw_wave = 4'b1000 ;parameter FREQ_CTRL = 32'd42949 , //相位累加器单次累加值PHASE_CTRL = 12'd1024 ; //相位偏移量reg [31:0] fre_add ;reg [11:0] rom_addr_reg;reg [13:0] rom_addr ;//fre_add:相位累加器always@(posedge sys_clk or negedge sys_rst_n)if(sys_rst_n == 1'b0)fre_add <= 32'd0;elsefre_add <= fre_add + FREQ_CTRL;//rom_addr:ROM读地址always@(posedge sys_clk or negedge sys_rst_n)if(sys_rst_n == 1'b0)beginrom_addr <= 14'd0;rom_addr_reg <= 11'd0;endelsecase(key)sin_wave:beginrom_addr_reg <= fre_add[31:20] + PHASE_CTRL;rom_addr <= rom_addr_reg;end //正弦波squ_wave:beginrom_addr_reg <= fre_add[31:20] + PHASE_CTRL;rom_addr <= rom_addr_reg + 14'd4096;end //方波tri_wave:beginrom_addr_reg <= fre_add[31:20] + PHASE_CTRL;rom_addr <= rom_addr_reg + 14'd8192;end //三角波saw_wave:beginrom_addr_reg <= fre_add[31:20] + PHASE_CTRL;rom_addr <= rom_addr_reg + 14'd12288;end //锯齿波default:beginrom_addr_reg <= fre_add[31:20] + PHASE_CTRL;rom_addr <= rom_addr_reg;end //正弦波endcaserom_wave rom_wave_inst(.address (rom_addr ), //ROM读地址.clock (sys_clk ), //读时钟.q (dac_data ) //读出波形数据);endmodule
4.编写测试文件
`timescale 1ps/1psmodule tb_DDS_Multi();wire dac_clk ;wire [7:0] dac_data ;reg sys_clk ;reg sys_rst_n ;reg [3:0] key ;initialbeginsys_clk = 1'b0;sys_rst_n <= 1'b0;key <= 4'b0001; //选择正弦波#200;sys_rst_n <= 1'b1;endalways #10 sys_clk = ~sys_clk;DDS_Multi DDS_Multi_inst(.sys_clk (sys_clk ),.sys_rst_n (sys_rst_n ),.key (key ),.dac_clk (dac_clk ),.dac_data (dac_data ));endmodule


