Verilog 学习第九节(DDS原理)

Verilog 学习第九节(DDS原理)_第1张图片
一个完整的周期,被分成了2^32 个点,输出32个点,每1ms输出一个点,得到一个完整周期的波形。2^ 32/32=2^27
B:频率控制字
Fo=Fclk/(2^ N/B)=Fclk*B/2^N

Verilog 学习第九节(DDS原理)_第2张图片
根据图像计算得:频率为1000000000/1315200=760
根据上面的公式计算得:50MHz*10^16 /2^32=762
可知计算正确~


module DDS_Module(
    input Clk,
    input Reset,
    input [31:0]P_Ctrl,
    input [11:0]X_Ctrl,
    output [13:0]data
    );
    reg [31:0]P_Ctrl_r;
    always@(posedge Clk)
    P_Ctrl_r<=P_Ctrl;
    
    reg [11:0]X_Ctrl_r;
    always@(posedge Clk)
    X_Ctrl_r<=X_Ctrl;
    
    reg [31:0]Freq_ACC;
    always@(posedge Clk or negedge Reset)begin
    if(!Reset)
    Freq_ACC<=0;
    else
    Freq_ACC<=Freq_ACC+P_Ctrl_r;
    end
    
    wire [11:0]Rom_Addr;      
    assign Rom_Addr = Freq_ACC[31:20] + X_Ctrl_r;
    
    blk_mem_gen_0 rom (
      .clka(Clk),
      .addra(Rom_Addr),
      .douta(data)
    );
    
endmodule

`timescale 1ns / 1ps


module DDS_Module_tb(
    );
    reg Clk;          
    reg Reset;       
    reg [31:0]P_Ctrl_A,P_Ctrl_B; 
    reg [11:0]X_Ctrl_A,X_Ctrl_B; 
    wire[13:0]dataA,dataB;
    
    DDS_Module DDS_ModuleA(
        .Clk(Clk),
        .Reset(Reset),
        .P_Ctrl(P_Ctrl_A),
        .X_Ctrl(X_Ctrl_A),
        .data(dataA)
        );
      DDS_Module DDS_ModuleB(
        .Clk(Clk),
        .Reset(Reset),
        .P_Ctrl(P_Ctrl_B),
        .X_Ctrl(X_Ctrl_B),
        .data(dataB)
        );
      initial Clk=0;
      always#10 Clk=!Clk;
      initial begin
      Reset=0;
      P_Ctrl_A=65536;//2的16次方
      P_Ctrl_B=65536;
      X_Ctrl_A=0;
      X_Ctrl_B=1024;
      #201
      Reset=1;
      #5000000
      P_Ctrl_A=65536*1024;//2的16次方
      P_Ctrl_B=65536*1024;
      X_Ctrl_A=0;
      X_Ctrl_B=2048;//4096为一整个相位,2048为一半
      #1000000
      $stop;
      end
endmodule

注:由于vivado软件在模拟正弦波的时候会自动补齐一些本来没有的点,所以在计算一些点的时候或者周期的时候可以把波形图像返回原来的10进制数据模式以更准确地显示~

你可能感兴趣的:(FPGA学习,学习,fpga开发)