基於FPGA的DDS任意波形發生器設計


一、簡介
      DDS技術最初是作為頻率合成技術提出的,由於其易於控制 ,相位連續,輸出頻率穩定度高,分辨率高, 頻率轉換速度快等優點,現在被廣泛應用於任意波形發生器(AWG)。基於DDS技術的任意波形發生器用高速存儲器作為查找表,通過高速D/A轉換器來合成出存儲在存儲器內的波形。所以它不僅能產生正弦、余弦、方波、三角波和鋸齒波等常見波形,而且還可以利用各種編輯手段,產生傳統函數發生器所不能產生的真正意義上的任意波形。

二、原理
    根據傅立葉變換定理可知,任何周期信號都可以分解為一系列正弦或余弦信號之和,不失一般性,以正弦信號的產生為例詳細說明直接數字頻率合成技術的原理。比如一個頻率為fc的正弦信號,其時域表達式為:
其相位表達式為:

從兩式可以看出,正弦信號是關於相位的一個周期函數,下圖更加直觀的描述相位與幅度的關系,16個相位與16個幅度值相對應,即每一個相位值對應一個幅度值,比如1100對應的相位為3π/2,對應的幅度值為-1.


相位和幅值的一一對應關系就好比存儲器中地址和存儲內容的關系,如果把一個周期內每個相位對應的幅度值存入存儲器當中,那么對於任意頻率的正弦信號,在任意時刻,只要已知相位Φ(t),也就知道地址,就可通過查表得到s(t)。下圖是DDS的基本結構框圖:

    相位累加器在每個時鍾脈沖輸入時,把頻率控制字累加一次,相位累加器的輸出數據就是信號的相位,用輸出的數據作為波形存儲器(ROM)的相位取樣地址,這樣就可以把存取在波形存儲器內的波形抽樣值經查找表查處,完成相位到幅值的轉換。頻率控制字相當於 Φ(t)中的2πfc,相位控制字相當於Φ(t)中的θ0。
    由於相位累加器字長的限制,相位累加器累加到一定值后,其輸出將會溢出, 這樣波形存儲器的地址就會循環一次,即意味着輸出波形循環一周。故改變頻率控制 字即相位增量,就可以改變相位累加器的溢出時間,在時鍾頻率不變的條件下就 可以改變輸出頻率。改變查表尋址的時鍾頻率,同樣也可以改變輸出波形的頻率。
    為了獲得較高的頻率分辨率,則只有增加相位累加器 的字長N,故一般N都取值較大。但是受存儲器容量的限制,存儲器地址線的 位數w不可能很大,一般都要小於N。這樣存儲器的地址線一般都只能接在相 位累加器輸出的高w位,而相位累加器輸出余下的(N-W)個低位則只能被舍 棄,這就是相位截斷誤差的來源。
    DDS模塊的輸出頻率f out 是系統工作頻率f c 、相位累加器位數N及頻率控制字K滿足如下關系

                                                                                               

頻率分辨率,即頻率的變化間隔

                                                                                             

三、實現代碼
       利用matlab或者Guagle_wave工具生成波形文件,存入ROM。基於Quartus II平台,並且調用了ROM核。
   
   
   
           
  1. module DDS (
  2. sys_clk,
  3. sys_rst_n,
  4. freq_word,
  5. phase_word,
  6. wave_out
  7. );
  8. input sys_clk ; //系統工作時鍾
  9. input sys_rst_n ; //復位,低有效
  10. input [31:0] freq_word ; //頻率控制字,控制輸出波形頻率
  11. input [11:0] phase_word ; //相位控制字,控制初始相位
  12. output[9:0] wave_out ; //輸出波形,位寬10bit
  13. reg [31:0] freq_word_reg ;
  14. reg [11:0] phase_word_reg ;
  15. reg [31:0] phase_adder ; //相位累加器
  16. reg [9:0] rom_address ; //存儲深度2^10
  17. always @(posedge sys_clk or negedge sys_rst_n) begin
  18. if (sys_rst_n ==1'b0) begin
  19. freq_word_reg <= 32'h0000;
  20. end
  21. else
  22. freq_word_reg <= freq_word;
  23. end
  24. always @(posedge sys_clk or negedge sys_rst_n) begin
  25. if (sys_rst_n ==1'b0) begin
  26. phase_word_reg <= 12'h0000;
  27. end
  28. else
  29. phase_word_reg <= phase_word;
  30. end
  31. always @(posedge sys_clk or negedge sys_rst_n) begin
  32. if (sys_rst_n ==1'b0) begin
  33. phase_adder <= 32'h0000;
  34. end
  35. else
  36. phase_adder <= phase_adder + freq_word_reg; //對頻率控制字進行累加
  37. end
  38. always @(posedge sys_clk or negedge sys_rst_n) begin
  39. if (sys_rst_n ==1'b0) begin
  40. rom_address <= 32'h0000;
  41. end
  42. else
  43. rom_address <= phase_adder[31:20] + phase_word_reg;
  44. end
  45. sin_rom DDS_ROM_U0 (
  46. .address (rom_address) ,
  47. .clock (sys_clk) ,
  48. .q (wave_out)
  49. );
  50. endmodule
測試文件代碼
   
   
   
           
  1. `timescale 1 ns/ 1 ns
  2. module DDS_tb();
  3. reg [31:0] freq_word ;
  4. reg [11:0] phase_word ;
  5. reg sys_clk ;
  6. reg sys_rst_n ;
  7. wire [9:0] wave_out ;
  8. DDS i1 (
  9. .freq_word(freq_word),
  10. .phase_word(phase_word),
  11. .sys_clk(sys_clk),
  12. .sys_rst_n(sys_rst_n),
  13. .wave_out(wave_out)
  14. );
  15. initial
  16. begin
  17. sys_clk = 0;
  18. sys_rst_n = 0;
  19. freq_word = 0;
  20. phase_word = 0;
  21. #2000;
  22. sys_rst_n = 1;
  23. freq_word = 32'd1024; //25M
  24. phase_word = 32'd0; //相位0度
  25. #200000000;
  26. freq_word = 32'd2048; //50M
  27. phase_word = 32'd512; //相位90度
  28. #200000000;
  29. $stop;
  30. end
  31. always sys_clk = #20 ~sys_clk; //系統時鍾25M
  32. endmodule
仿真波形如下:
           
改變ROM中的波形數據就可以輸出相對應的波形。

參考資料: A Technical Tutorialon Digital Signal Synthesis
               無線通信FPGA設計
 





免責聲明!

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



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