前言
用RAM實現一個DDS,從原理上來說很簡單,在實際使用的時候,可能沒有直接使用官方提供的IP核來的方便。這個博客就記錄一下,最近使用到的這個DDS IP。
1 基于相位截斷的DDS
DDS IP核的內部的基本結構如下圖所示,主要是一個基于相位截斷的DDS。在數字信號處理中,經常會使用到DDS,其內部主要有一個相位累加器,一個ROM存儲這正弦波的查找表。相位累加器在時鐘的作用下對相位進行累加,每次的累加值是通過phase increment 來指定的。累加得到的結果,通過量化器,取其高位,低位舍去,再將這個量化后的相位值,輸出到查找表,從查找表中得到最終的波形。
DDS的最終輸出的信號的頻率和系統時鐘,相位寬度和相位自增量之間滿足如下關系:
其中ΔΘ 是相位自增量,BΘ(n)是相位的位寬,也就對應這查找表的深度為2^BΘ(n)
手冊中也給出了一個例子,來舉例說明DDS的輸出頻率和這幾個系統參數之間的關系,其中系統時鐘120MHz,相位寬度為10bit,相位增量為12,輸出的頻率通過上面的式子就可以計算出來。
在實際的工程中,一般希望DDS能夠生成不停頻率的信號,例如在DDC或者DUC中,希望產生一個高頻的載波頻率,通常使用DDS來產生一個高頻的正弦信號。因此在實際使用的時候更加關注DDS的相位增量。因為通過控制相位增量就能過后產生不同的頻率。相位增量的計算公式如下。
下面以一個具體的例子來說明DDS是如何工作的。
2 DDS IP的使用和參數配置
在配置這一TAB,需要設置系統的時鐘,這個時鐘也就是上面公式當中的參考時鐘,然后可以選通道數和模式,這里就保持默認就可以了。
再之后就是期望最終生成的信號的一些參數的設置??蛇x選擇系統參數模式,或者選擇硬件參數模式,一般都選擇系統參數模式,直接方便。
在系統參數中,動態范圍最終對應這輸出信號的幅度,其計算公式如下:20lg(Amp),其中AMP就是信號的幅度。比如下圖中,動態范圍為72,那么他就可以表示幅度為4096的一個正弦信號。[20lg(4096)] = 72dB;
在下面是頻率分辨率,對應這最小的頻率變化,是由系統時鐘和相位深度計算得到的,比如系統時鐘40MHz,相位寬度為32bit,那么計算的頻率分辨率就是[40*106/(232)] = 0.01。
在實現這一TAB,可以設置相位增量是固定的還是可以更改的,相位增量能夠控制輸出的正余弦信號的頻率,這里選擇可更改的,便于在之后的使用中生成不同頻率的信號。需要注意的時候,生成的信號需要滿足奈奎斯特抽樣定理,也就是抽樣時鐘必須是被采樣信號頻率的兩倍。以這個例子來說,系統時鐘為40M,那么,最多可以生成頻率為20MHz的正余弦信號。
除了相位自增量外,初始的相位也是可以通過參數來修改的,在這里就默認不修改了。
在輸出信號的時候,可以同時輸出正余弦信號,這在正交調制解調的過程中十分有用。
除此之外,還可以輸出當前的相位。
在具體實現這一TAB中,保持默認就可以,是用來配置接口。根據手冊上描述的,可以選擇這些信號來生成不同類型的接口。這些接口都是AXI-Stream 類型的接口,只需要滿足AXIS的規則就好了。
在輸出頻率這一TAB,可以輸入期望的輸出頻率,若有多個通道,可以選擇給多個通道設定初始的頻率輸出值。這個期望頻率在前面選擇了相位增量式可編程的時候就沒什么用了。因為最終輸出的信號的頻率是通過相位增量來控制的。
到這里這個IP基本就配置完了。可以看一下總結,和最終輸出信號的接口信息。需要特別注意的就是輸出的正余弦信號在輸出總線上所占據的bit‘位。DDS IP通過一個AXIS接口同時輸出正弦信號和余弦信號。就比如在這個例子中,m_axis_data[11:0]傳輸的就是余弦信號,其中m_axis_data[11]是余弦信號的符號位。
m_axis_data[27:16]傳輸的是正弦信號,其中m_axis_data[27]是正弦信號的符號位。
3 DDS IP測試
寫個Testbench測試一下:
`timescale1ns/1ps moduletb_test_dds(); regclk; reg[31:0]frequency; regfreq_vld; wirem_axis_data_tvalid; wire[31:0]m_axis_data_tdata; wiredds_vld; wire[11:0]dds_cos; wire[11:0]dds_sin; assigndds_vld=m_axis_data_tvalid; assigndds_cos=m_axis_data_tdata[11:0]; assigndds_sin=m_axis_data_tdata[27:16]; //parameterSYS_CLK=40000000;//systemclock40M //parameterCLK_6M=6000000;//frequency6M //parameterCLK_400K=400000;//frequency400K //parameterCLK_2M=2000000;//frquency2M //parameterPHASE_WIDTH=32;//相位寬度為32bit //clock initialbegin clk=0; forever#(12.5)clk=~clk;//40Msystemclokc end initialbegin frequency='d0; freq_vld=1'b0; repeat(3000)@(posedgeclk); //產生一個頻率為400KHz的復指數 frequency=32'd42949672;//CLK_400K*(2^PHASE_WIDTH)/SYS_CLK freq_vld=1'b1; @(posedgeclk) freq_vld=1'b0; repeat(3000)@(posedgeclk); //產生一個頻率為4MHz的復指數 frequency=32'd214748364;//CLK_4M*(2^PHASE_WIDTH)/SYS_CLK freq_vld=1'b1; @(posedgeclk) freq_vld=1'b0; repeat(3000)@(posedgeclk); //產生一個頻率為6M的復指數 frequency=32'd644245094;//CLK_6M*(2^PHASE_WIDTH)/SYS_CLK freq_vld=1'b1; @(posedgeclk) freq_vld=1'b0; end dds_compiler_0inst_dds( .aclk(clk),//inputwireaclk .s_axis_config_tvalid(freq_vld),//inputwires_axis_config_tvalid .s_axis_config_tdata(frequency),//inputwire[31:0]s_axis_config_tdata .m_axis_data_tvalid(m_axis_data_tvalid),//outputwirem_axis_data_tvalid .m_axis_data_tdata(m_axis_data_tdata)//outputwire[31:0]m_axis_data_tdata ); endmodule
可以看到生成了不同頻率的正余弦信號。一開時的時候。沒有給出相位增量,所以固定輸出2M的信號,之后給出了相位增量后,輸出了400K 信號。
-
Xilinx
+關注
關注
71文章
2167瀏覽量
121301 -
DDS
+關注
關注
21文章
633瀏覽量
152630 -
IP核
+關注
關注
4文章
327瀏覽量
49485
原文標題:Xilinx DDS IP使用
文章出處:【微信號:Hack電子,微信公眾號:Hack電子】歡迎添加關注!文章轉載請注明出處。
發布評論請先 登錄
相關推薦
評論