zoukankan      html  css  js  c++  java
  • FPGA学习笔记. DDS

    DDS原理

      直接数字式频率合成器(Direct Digital Synthesizer)

    频率计算公式

      Fout = FW * Fclk / 2^N

    Fout 输出频率, Fw 频率控制字, N 位数 精度 Fclk / 2^N

    设计思路

    设置一个计数cnt作累加,Fw频率控制字,作为计数步长。

    时钟clk下,cnt <= cnt + Fw.

    设输入时钟是100mHz,目标Fo为115200Hz,计数器为32位,据上面的公式可以得出

    Fw = Fo * 2^32  /  Fc = 115200 * 2^32 / (100*10^6) = 4947802.3249992

    取整 Fw = 4947802,

    占空比为50%,cnt <= 2^N ,Fo = 0 ; cnt > 2^N ,Fo = 1。

    添加一个block menery IP,存放 正弦波相位-幅度 表,由相位累加来查询地址。

    生成COE文件

    位宽32bit 深度2^12,code

    clear;
    close all;
    %%
    width = 32; %data width
    N = 12;     %addr witdh
    depth = 2^N;%memery depth
    x = linspace(0,2*pi,depth);
    y_sin = sin(x)+1;
    y_sin_q=round(y_sin*(2^(width-1)));
    fid = fopen('CosWaveWid32Def2e12.coe','w');
    %write header
    fprintf(fid,'MEMORY_INITIALIZATION_RADIX=16;
    ');
    fprintf(fid,'MEMORY_INITIALIZATION_VECTOR=
    ');
    %write data
    if(fid>0)
        fprintf(fid,'%x,
    ',y_sin_q);
    end
    fclose(fid);

    verilog 程序

    累加与查询地址

     1 /*
     2 fc = 100MHz
     3 fo = 1kHz 
     4 N  = 32 (width)
     5 fw = (fo * 2^N) / fc = 42949.67296 => 42950 
     6 
     7 */
     8 module DdsTopV
     9 #(
    10     parameter COUNTWIDTH = 32,
    11     parameter FW = 32'd429497 
    12 )
    13 (
    14     input  wire clk,
    15     input  wire rst_n,
    16     output reg  clk_out,
    17 //    output wire [11:0] addr,
    18     output wire [31:0] phase,
    19     output wire [31:0] sin_o
    20     );
    21 
    22 //wire [31:0] phase;
    23 wire [11:0] addr;
    24 reg [COUNTWIDTH-1:0] cnt;
    25  
    26 //相位累加
    27 always @(posedge clk or posedge rst_n) 
    28 begin
    29     if(!rst_n)
    30         cnt <= 0;
    31     else
    32         cnt <= cnt + FW;  //计数器步长FW
    33 end
    34 //clk_out 
    35 always @(posedge clk or posedge rst_n)
    36 begin
    37     if(!rst_n)
    38         clk_out <= 1'b0;
    39     else if(cnt < 32'h7FFF_FFFF)
    40         clk_out <= 1'b0;
    41     else
    42         clk_out <= 1'b1;
    43 end   
    44 
    45 assign phase = cnt;
    46 assign addr = {phase[31:20]};
    47 
    48 blk_mem_gen_0 blk_mem_gen_0(
    49     .clka(clk),
    50     .addra(addr),
    51     .douta(sin_o)
    52     );
    53 
    54 endmodule

    TestBench

     1 module testbench();
     2 
     3 reg clk;
     4 reg rst_n;
     5 wire clk_out;
     6 //wire [11:0] addr;
     7 wire [31:0] phase;
     8 wire [31:0] sin_o;
     9 
    10 
    11 /*
    12 Fo = 115200Hz
    13 Fw = 4947802.3
    14 */
    15 DdsTopV 
    16 #(
    17 //    .COUNTWIDTH(32'd32),
    18     .FW(32'd4947802) 
    19 )
    20 uut
    21 (
    22     .clk(clk),
    23     .rst_n(rst_n),
    24     .phase (phase),
    25 //    .addr(addr),
    26     .clk_out(clk_out),
    27     .sin_o(sin_o)
    28     );
    29 
    30     initial begin
    31     clk = 0;
    32     rst_n = 0;
    33     #15 rst_n=1; 
    34     end
    35     
    36     always  #10 clk=~clk; 
    37 
    38 endmodule

    设置Block Memery

    仿真结果

    via

    https://www.cnblogs.com/christsong/p/5536995.html

  • 相关阅读:
    一个浏览器循环刷新网页的例子
    Ajax和JSON基础
    HTML-第三章构建模块小结
    HTML-元素属性
    入前端坑的第一天
    JZOJ 【2021.11.10NOIP提高组联考】
    LG P2633 Count on a tree
    JZOJ 7339.改试卷
    [CEOI2017] Building Bridges
    拉格朗日插值法
  • 原文地址:https://www.cnblogs.com/protogenoi/p/9084708.html
Copyright © 2011-2022 走看看