基于FPGA的DDS RTL设计

Posted XiaoMing_sususu

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了基于FPGA的DDS RTL设计相关的知识,希望对你有一定的参考价值。

DDS 的RTL设计


DDS:结构如上图
首先将你需要的波形(正弦波,方波,自定义波形)存入ROM,基于物理储存结构一般一个周期采样点为2^N次方,比如取512个点。

假设采样时钟的频率为fc,频率控制字为M,相位累加寄存器的位宽为n,则相位累加器中的最大值为2^n-1,当超过该值时,相位累加寄存器中的值就会溢出,然后从0开始计数。
因为采样时钟的频率为fc,频率控制字为M,则每隔1/fc,相位累计寄存器中的值就增加M,所以,在1s内,相位累加寄存器中的值增加的大小为(1/(1/fc))M = fc * M,又因为寄存器中最大表示的值为2^n-1,所以可以计算出1s内溢出的次数为fc * M / 2^n,因为寄存器中的值从0增加到 2^n-1,刚好输出一个周期的正弦波信号。所以,寄存器溢出的次数就是输出正弦波的周期数。
1s内输出正弦波的周期数就为DDS输出的正弦波的频率,也就是我们的目标频率 f0 = fc * M / 2^n。
此时频率控制字为:M = (2^ n / fc )
f0;
此时计算出来输出频率为1Hz的频率控制字 M(1Hz) = 2^n / fc;
此时输出为最小分辨率为1hz 可输出 1hz任意倍数的频率

fc:板卡时钟源频率
f0:输出频率 根据奈奎斯特采样率 理论极限最大输出f0 为fc/ 2;
n:累加寄存器的位宽
N:Rom的存储深度

RTL代码如下

module DDS_1(
         input clk,
         input rst_n,
         input [31:0]Fword,
         input [7:0]Pword,
         output [7:0]DA_data
    );
    reg [31:0]r_Fword;//f
    reg [8:0]r_Pword; //p
    reg [31:0]F_cnt; //
    wire [8:0]addr_rom;
  always @(posedge clk or negedge rst_n )
    begin
    if(!rst_n)
    begin
         r_Fword <= 0;
         r_Pword <= 0;
     end
    else
    begin
         r_Fword <= Fword;
         r_Pword <=  Pword;
      end
    end
 always @(posedge clk or negedge rst_n )
 begin
    if(!rst_n)
      F_cnt <= 32'b0;
    else 
      F_cnt <= F_cnt + r_Fword;
 end
assign addr_rom   = F_cnt[31:23] + r_Pword;
 Sin_rom rom_ip_inst
    (
     .clka (clk ), //inoput clka
     .addra (addr_rom ), //input [7:0] addra
     .douta (DA_data ) //output [7:0] dout
     );
endmodule

如果需要扫频:
思路为:

         r_Fword <=  (Output_Hz*  M(1hz)); 修改Output_Hz
          M(1hz)为输出频率为1Hz的频率控制字

对于相位只需要修改r_Pword;此时r_Pword占ROM地址的几分之几 初始相位就是几分之几*2pi; 例如Rom所存储正弦波一个周期点数为512点:r_Pword = 128 那么初始相位为:128/512 *2pi = pi/2;

以上是关于基于FPGA的DDS RTL设计的主要内容,如果未能解决你的问题,请参考以下文章

基于FPGA和DDS技术的波形产生

(DDS)正弦波形发生器——幅值频率相位可调

基于FPGA和DDS技术的波形产生(仿真部分)

基于FPGA的DDS波形发生器可以用modelsim进行功能仿真吗?

ZYNQ从入门到秃头09 DDS IP 数字波形合成(基于ALINX 7020 && AN108)

FPGA教程案例28基于FPGA的DDS直接数字频率合成器之一——原理介绍