FPGA學習筆記之DDS


大綱:

  1. 什么是DDS?

DDS是直接數字式頻率合成器(Direct Digital Synthesizer)的英文縮寫,與傳統的頻率合成器相比,DDS具有低成本,高分辨率,低功耗,高分辨率,和快速轉換時間等優點,廣泛應用在電信與電子儀器領域,是實現設備全數字化的一個關鍵技術。

  1. 什么是信號發生器?

波形發生器就是一種數據信號發生器,在調試硬件的時候,常常需要加入一些信號,以觀察電路工作是否正常,加入的信號有正玄波,三角波,方波,以及任意波形。

  1. 何為調頻

調頻就是改變單位時間內完成周期性變化的次數。

  1. 何為調相

相位對於一個波來說,特定時刻在它循環周期中的位置:一種是否在波峰,波谷或他們之間的某點的標度。相位可調其實就是改變初始相位。

  1. 怎么實現任意波形的DDS

重點理解:

調頻原理

頻率可調的原理分析:

           如何得到我們想要的任意頻率的波形發生器呢?   因為事先的波形數據是存在ROM里面的,每給rom一個地址,就可以讀出ROM里的相應的數據,rom的深度是事先定好的256,地址范圍是0-255。所以DDS就是循環讀取ROM里的數據,系統時鍾是50MHZ,若每個時鍾地址加1,則有輸出的信號為50M/256=195.3K。此時的頻率就是這么大,但是我們不想要這個頻率怎么辦?

觀察上述描述,我們看到最后的輸出時鍾是由采樣時鍾和地址深度決定的,所以可以通過對這兩個地方着手更改,首先先看下采樣時鍾,原來是每個時鍾的作用下,采集數據加1,現在可以通過對時鍾計數,然后讓地址在兩個時鍾作用下采集1,這樣就可以實現分頻的目的。

說完采樣時鍾,那么看下地址深度的問題,因為地址深度是由定制ROM時,就已經確認下來的,所以不能直接更改地址深度,但是可通過更改讀取ROM的地址,使其只讀其中的一半等,也可以達到效果。  有奈奎斯特采樣原理我們知道,在做ADDA轉換的過程當中,采樣頻率要大於信號最高頻率的兩倍,才能保證信號不失真,這個方法說白了其實就是改變采樣的點數,然后達到倍頻的目的,不過因為這樣做,點數采樣的比較少,會導致波形失真。

   說完前面兩種方法,也只是實現了整數倍頻,和分數分頻的目的,並不能實現我們所說的任意分頻,那么怎么實現任意分頻呢,這里就要介紹一種相對簡單並且實用的方法。

首先需要明確的是輸出信號的頻率計算公式:

 

 

頻率控制字fword和幅度控制字pword

前面介紹的兩種方法中,一個是讓時鍾計數,時鍾記多次地址加一下,另一種是地址每次加,但是不是加1 而是2,3,4這樣的加,也可以實現分頻。不過這兩種方法都有各自的壞處,不能實現任意分頻,現在我們介紹一種比較簡單的調頻原理,前面那個公式說了輸出信號 = 50M/256。這里的256 = 2^8。所以我們的地址之前定義[7:0]就夠了,前面兩種都是通過計數的方式實現的調頻,現在我們改變下思路,可以通過改變地址位寬的方法,然后讀取的時候取數據地址的高八位,是否就可以實現功能。假設我們拓展為32位,最終輸出的地址 取高8位。那么輸出信號的最低頻率是不是 = 50M/2^32 = 0.01164HZ。如果我們想要其他的頻率,再在這個基礎上乘就行了。怎么乘前面是不是已經講過了,如果我要得到1K的,1K/0.01164 = 85911,我們讓地址計數器每個時鍾來了加85911。這樣就可以實現比較方便的調頻原理。

調相原理:

   調相相對來說比較簡單,無外乎就是改變初始相位就可以了,實現方法就是定義一個調相控制字,當復位賦初值的時候將想要的初始相位賦給地址初值就可以了,實現起來相對簡單。

   調相計算公式:

           假設是256個點則有

                                                地址初值=256*(初始相位/360)

  1. 系統框架

        

  1. Rom (單口rom)        Quarters IP核調用
  2. Mif文件生成的方法        1.Quarters自帶工具生成

               2.mifmaker 軟件生成

               3.MATLAB mif文件函數

               4.C語言  mif文件生成

  1. 代碼分析
     1 module         DDS(
     2         input        wire    sclk,
     3         input        wire    rst_n,
     4         input        wire     [7:0]    odata_1,//sine_wave
     5         input        wire     [7:0]    odata_2,//square_wave
     6         input        wire    [1:0]    flag,
     7         output    wire    [7:0]    addr_num,
     8         output    reg    [7:0]    o_wave
     9         );
    10         
    11 parameter    pword    =0;    
    12 
    13         
    14 reg    [31:0]    cnt;
    15 reg    [1:0]        flag_S;
    16 reg    [1:0]        flag_F;
    17 reg    [31:0]    fword;
    18 
    19 
    20 always @(posedge sclk    or negedge    rst_n)
    21     if(!rst_n)
    22             flag_S    <=0;
    23     else    if(flag_S==1 && flag[0])
    24             flag_S    <=0;
    25     else    if(flag[0])
    26         begin
    27             flag_S<=flag_S+1;
    28         end 
    29 
    30 always@(posedge    sclk    or negedge    rst_n)
    31         case(flag_S)
    32             0:    o_wave    <=    odata_1;
    33             1:    o_wave    <=    odata_2;
    34             default:    o_wave    <= o_wave;
    35         endcase
    36     
    37     
    38 always @(posedge sclk    or negedge    rst_n)
    39     if(!rst_n)
    40           flag_F    <=0;
    41     else if(flag_F==1 && flag[1])
    42         flag_F    <=0;
    43     else    if(flag[1])
    44         begin
    45             flag_F<=flag_F+1;
    46         end 
    47 
    48 always@(posedge    sclk    or negedge    rst_n)
    49         case(flag_F)
    50             0:    fword    <= 4295533;
    51             1:  fword <= 8591065;
    52             2:  fword <= 42955326;
    53             3:  fword <= 85910653;
    54         default: fword <= fword;
    55      endcase    
    56  
    57 always@(posedge sclk or negedge rst_n)   
    58 begin                                       
    59     if(~rst_n)                                
    60         cnt <= {pword,23'b0};                 
    61     else if(|flag)                        
    62         cnt <= {pword,23'b0};                 
    63     else                                      
    64         cnt <= cnt + fword;                      
    65 end                                         
    66                                            
    67 assign addr_num = cnt[31:24];          
    68 
    69 endmodule    
    70          

     

  2. Modelsim 仿真波形

       

 

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM