1.编写MATLB代码 生成ROM的数据

    1. clc;
    2. clear;
    3. F1=1; %信号频率
    4. Fs=2^12; %采样频率
    5. P1=0; %信号初始相位
    6. N=2^12; %采样点数
    7. t=[0:1/Fs:(N-1)/Fs]; %采样时刻
    8. ADC=2^7 - 1; %直流分量
    9. A=2^7; %信号幅度
    10. s1=A*sin(2*pi*F1*t + pi*P1/180) + ADC; %正弦波信号
    11. s2=A*square(2*pi*F1*t + pi*P1/180) + ADC; %方波信号
    12. s3=A*sawtooth(2*pi*F1*t + pi*P1/180,0.5) + ADC; %三角波信号
    13. s4=A*sawtooth(2*pi*F1*t + pi*P1/180) + ADC; %锯齿波信号
    14. %创建mif文件
    15. fild = fopen('rom_wave.mif','wt');
    16. %写入mif文件头
    17. fprintf(fild, '%s\n','WIDTH=8;'); %位宽
    18. fprintf(fild, '%s\n\n','DEPTH=16384;'); %深度
    19. fprintf(fild, '%s\n','ADDRESS_RADIX=UNS;'); %地址格式
    20. fprintf(fild, '%s\n\n','DATA_RADIX=UNS;'); %数据格式
    21. fprintf(fild, '%s\t','CONTENT'); %地址
    22. fprintf(fild, '%s\n','BEGIN'); %开始
    23. for j = 1:4
    24. for i = 1:N
    25. if j == 1 %打印正弦信号数据
    26. s0(i) = round(s1(i)); %对小数四舍五入以取整
    27. fprintf(fild, '\t%g\t',i-1); %地址编码
    28. end
    29. if j == 2 %打印方波信号数据
    30. s0(i) = round(s2(i)); %对小数四舍五入以取整
    31. fprintf(fild, '\t%g\t',i-1+N); %地址编码
    32. end
    33. if j == 3 %打印三角波信号数据
    34. s0(i) = round(s3(i)); %对小数四舍五入以取整
    35. fprintf(fild, '\t%g\t',i-1+(2*N)); %地址编码
    36. end
    37. if j == 4 %打印锯齿波信号数据
    38. s0(i) = round(s4(i)); %对小数四舍五入以取整
    39. fprintf(fild, '\t%g\t',i-1+(3*N)); %地址编码
    40. end
    41. if s0(i) <0 %负1强制置零
    42. s0(i) = 0
    43. end
    44. fprintf(fild, '%s\t',':'); %冒号
    45. fprintf(fild, '%d',s0(i)); %数据写入
    46. fprintf(fild, '%s\n',';'); %分号,换行
    47. end
    48. end
    49. fprintf(fild, '%s\n','END;'); %结束
    50. fclose(fild);

    2.添加IP核并例化
    image.png
    image.png

    1. rom_wave rom_wave_inst
    2. (
    3. .address (rom_addr ), //ROM读地址
    4. .clock (sys_clk ), //读时钟
    5. .q (dac_data ) //读出波形数据

    3.编写DDS_Multi代码

    1. /********************************************************************************
    2. 名称 :DDS_Multi.v
    3. 功能:四种DDS 波形发生器
    4. 作者:王世阳
    5. 创建日期:2021.04.25
    6. 修改日期1:
    7. 修改内容1:
    8. *********************************************************************************/
    9. module DDS_Multi
    10. (
    11. input wire sys_clk ,
    12. input wire sys_rst_n ,
    13. input wire [3:0] key ,
    14. output wire dac_clk ,
    15. output wire [7:0] dac_data
    16. );
    17. //DAC模块时钟
    18. assign dac_clk = ~sys_clk;
    19. parameter sin_wave = 4'b0001 ,
    20. squ_wave = 4'b0010 ,
    21. tri_wave = 4'b0100 ,
    22. saw_wave = 4'b1000 ;
    23. parameter FREQ_CTRL = 32'd42949 , //相位累加器单次累加值
    24. PHASE_CTRL = 12'd1024 ; //相位偏移量
    25. reg [31:0] fre_add ;
    26. reg [11:0] rom_addr_reg;
    27. reg [13:0] rom_addr ;
    28. //fre_add:相位累加器
    29. always@(posedge sys_clk or negedge sys_rst_n)
    30. if(sys_rst_n == 1'b0)
    31. fre_add <= 32'd0;
    32. else
    33. fre_add <= fre_add + FREQ_CTRL;
    34. //rom_addr:ROM读地址
    35. always@(posedge sys_clk or negedge sys_rst_n)
    36. if(sys_rst_n == 1'b0)
    37. begin
    38. rom_addr <= 14'd0;
    39. rom_addr_reg <= 11'd0;
    40. end
    41. else
    42. case(key)
    43. sin_wave:
    44. begin
    45. rom_addr_reg <= fre_add[31:20] + PHASE_CTRL;
    46. rom_addr <= rom_addr_reg;
    47. end //正弦波
    48. squ_wave:
    49. begin
    50. rom_addr_reg <= fre_add[31:20] + PHASE_CTRL;
    51. rom_addr <= rom_addr_reg + 14'd4096;
    52. end //方波
    53. tri_wave:
    54. begin
    55. rom_addr_reg <= fre_add[31:20] + PHASE_CTRL;
    56. rom_addr <= rom_addr_reg + 14'd8192;
    57. end //三角波
    58. saw_wave:
    59. begin
    60. rom_addr_reg <= fre_add[31:20] + PHASE_CTRL;
    61. rom_addr <= rom_addr_reg + 14'd12288;
    62. end //锯齿波
    63. default:
    64. begin
    65. rom_addr_reg <= fre_add[31:20] + PHASE_CTRL;
    66. rom_addr <= rom_addr_reg;
    67. end //正弦波
    68. endcase
    69. rom_wave rom_wave_inst
    70. (
    71. .address (rom_addr ), //ROM读地址
    72. .clock (sys_clk ), //读时钟
    73. .q (dac_data ) //读出波形数据
    74. );
    75. endmodule

    4.编写测试文件

    1. `timescale 1ps/1ps
    2. module tb_DDS_Multi();
    3. wire dac_clk ;
    4. wire [7:0] dac_data ;
    5. reg sys_clk ;
    6. reg sys_rst_n ;
    7. reg [3:0] key ;
    8. initial
    9. begin
    10. sys_clk = 1'b0;
    11. sys_rst_n <= 1'b0;
    12. key <= 4'b0001; //选择正弦波
    13. #200;
    14. sys_rst_n <= 1'b1;
    15. end
    16. always #10 sys_clk = ~sys_clk;
    17. DDS_Multi DDS_Multi_inst
    18. (
    19. .sys_clk (sys_clk ),
    20. .sys_rst_n (sys_rst_n ),
    21. .key (key ),
    22. .dac_clk (dac_clk ),
    23. .dac_data (dac_data )
    24. );
    25. endmodule

    image.png
    image.png