前言
本文根據(jù)DDS的相關(guān)手冊構(gòu)建仿真工程,包括單通道工程、多通道工程、使用DDS進(jìn)行混頻操作。
單通道IP配置
新建一個(gè)空白工程,FPGA型號(hào)任意,添加DDS IP到工程中,雙擊打開配置項(xiàng)界面。 該界面可以配置DDS的相關(guān)配置選項(xiàng)和基本的一些參數(shù)。 這里重點(diǎn)說下常配置的參數(shù)。
- 系統(tǒng)時(shí)鐘:為DDS工作的系統(tǒng)時(shí)鐘。
- 通道數(shù)量:根據(jù)設(shè)計(jì)需求選擇通道數(shù)量。
- 無雜散動(dòng)態(tài)范圍(SFDR):這里輸入對應(yīng)數(shù)值可以進(jìn)行計(jì)算出輸出DDS數(shù)據(jù)的位寬,N代表DDS輸出的位寬數(shù)。 利用下面公式可以對45進(jìn)行換算,經(jīng)過計(jì)算N=7.47,向上取整得到輸出位寬為8。
- 頻率分辨率 :頻率分辨率用于控制最小的分辨辨精度。
配置完成基本信息配置下一頁,基本保持默認(rèn)即可,這里只想查看波形,所以相位輸出就關(guān)閉。
第三頁配置保持默認(rèn)即可。
第四頁輸出頻率配置,這里設(shè)置輸出10M
在總結(jié)也中可以看到輸出信號(hào)的相關(guān)信息,這里可以簡要計(jì)算下phase width的28Bits如何來的。 該參數(shù)和DDS的工作頻率以及啟用通道,還有頻率分辨率有關(guān)。 通過下述式子,可以變形求得當(dāng)前設(shè)置下Frequency Resolution。 DDS時(shí)鐘為100MHz,通道為1,相位位寬28Bits,換算得到頻率分辨率為0.37252902984619140625。 向上取整數(shù),則得到當(dāng)前設(shè)置的0.4Hz的分辨率。 已知頻率分辨率也可以換算位寬,不過此時(shí)得到的位寬是按2的次方去取整。
同時(shí)根據(jù)前面的相關(guān)參數(shù)可以計(jì)算向量增量。 帶入設(shè)置的參數(shù)可計(jì)算到增量的數(shù)值大小。
單通道實(shí)例
頂層調(diào)用
按上述IP配置配置完成后在top層進(jìn)行實(shí)例化,然后即可完成單通道DDS的調(diào)用使用。 頂層模塊調(diào)用代碼如下:
module top(
input clk
);
wire m_axis_data_tvalid_ch1;
wire [7:0] m_axis_data_tdata_ch1;
//單通道測試
dds_compiler_0 ch1_dds(
.aclk(clk), // input wire aclk
.m_axis_data_tvalid(m_axis_data_tvalid_ch1), // output wire m_axis_data_tvalid
.m_axis_data_tdata(m_axis_data_tdata_ch1) // output wire [7 : 0] m_axis_data_tdata
);
endmodule
編寫仿真
編寫testbench,由于頂層只給了一個(gè)時(shí)鐘的輸入端口,所以只需要對時(shí)鐘進(jìn)行仿真設(shè)計(jì),單通道DDS測試如下:
`timescale 1ns / 1ps
module tb_top;
// top Parameters
parameter PERIOD = 10;
// top Inputs
reg clk = 0 ;
// top Outputs
initial
begin
forever #(PERIOD/2) clk=~clk;
end
top u_top (
.clk(clk)
);
initial
begin
#10000;
$finish;
end
endmodule
編寫完成后直接點(diǎn)擊運(yùn)行仿真測試即可。
測試結(jié)果
運(yùn)行仿真查看波形結(jié)果,將頂層例化模塊的波形添加到波形窗口,可以得到數(shù)字模式下的十六進(jìn)制顯示的數(shù)值,可將數(shù)值轉(zhuǎn)化為波形顯示方便觀察。
設(shè)置下數(shù)據(jù)的進(jìn)制格式和顯示模式,這里修改通道數(shù)據(jù)為analog 模式,進(jìn)制修改為有符號(hào)十進(jìn)制。
修改后添加游標(biāo),可以觀察到輸出波形周期為100ns,也即10MHz,輸出波形頻率和設(shè)置一致。
多通道實(shí)例
重新打開IP配置界面或者新建一個(gè)DDS IP,修改通道數(shù),這里設(shè)置為3。 使能相位輸出信號(hào),查看下相位變化情況。 因?yàn)镈DS的IP核多通道之間是分時(shí)復(fù)用的,所以在細(xì)節(jié)實(shí)現(xiàn)配置界面最好使能通道ID以供進(jìn)行正常輸出單個(gè)通道的信號(hào)波形。 其余可以保持默認(rèn)。
配置輸出頻率為10MHz、3MHz、4MHz。
配置完成點(diǎn)擊OK,對模塊進(jìn)行例化。
頂層調(diào)用
頂層模塊調(diào)用代碼如下:
module top(
input clk
);
wire m_axis_data_tvalid_ch1;
wire [7:0] m_axis_data_tdata_ch1;
wire m_axis_data_tvalid_ch3;
wire [7 : 0] m_axis_data_tdata_ch3;
wire [1 : 0] m_axis_data_tuser_ch3;
wire m_axis_phase_tvalid_ch3;
wire [31 : 0] m_axis_phase_tdata_ch3;
wire [1 : 0] m_axis_phase_tuser_ch3;
//多通道測試
dds_compiler_1 multi_ch_dds(
.aclk(clk), // input wire aclk
.m_axis_data_tvalid(m_axis_data_tvalid_ch3), // output wire m_axis_data_tvalid
.m_axis_data_tdata(m_axis_data_tdata_ch3), // output wire [7 : 0] m_axis_data_tdata
.m_axis_data_tuser(m_axis_data_tuser_ch3), // output wire [1 : 0] m_axis_data_tuser
.m_axis_phase_tvalid(m_axis_phase_tvalid_ch3), // output wire m_axis_phase_tvalid
.m_axis_phase_tdata(m_axis_phase_tdata_ch3), // output wire [31 : 0] m_axis_phase_tdata
.m_axis_phase_tuser(m_axis_phase_tuser_ch3) // output wire [1 : 0] m_axis_phase_tuser
);
仿真測試
仿真文件可以保持單通道測試不變,點(diǎn)擊運(yùn)行行為級(jí)仿真,添加信號(hào)波形可觀察到下面的情況。 數(shù)據(jù)并不是直接得到的正弦波形,而是雜亂無章的。
放大tuser信號(hào)可觀察到,數(shù)據(jù)和相位通道的tuser信號(hào)是周期變化的,這里的tuser信號(hào)是代表IP設(shè)置中的chen ID,所以是分時(shí)復(fù)用輸出3個(gè)通道的信號(hào)所以要編寫簡單邏輯對信號(hào)進(jìn)行分選。
頂層模塊修改
可根據(jù)tuser為判斷條件對輸出數(shù)據(jù)進(jìn)行一步寄存,從而得到三個(gè)通道的波形數(shù)據(jù)。 代碼如下:
module top(
input clk
);
//多通道測試
dds_compiler_1 multi_ch_dds(
.aclk(clk), // input wire aclk
.m_axis_data_tvalid(m_axis_data_tvalid_ch3), // output wire m_axis_data_tvalid
.m_axis_data_tdata(m_axis_data_tdata_ch3), // output wire [7 : 0] m_axis_data_tdata
.m_axis_data_tuser(m_axis_data_tuser_ch3), // output wire [1 : 0] m_axis_data_tuser
.m_axis_phase_tvalid(m_axis_phase_tvalid_ch3), // output wire m_axis_phase_tvalid
.m_axis_phase_tdata(m_axis_phase_tdata_ch3), // output wire [31 : 0] m_axis_phase_tdata
.m_axis_phase_tuser(m_axis_phase_tuser_ch3) // output wire [1 : 0] m_axis_phase_tuser
);
reg [7 : 0] data10MHz;
reg [7 : 0] data3MHz;
reg [7 : 0] data4MHz;
always @(posedge clk) begin
case(m_axis_data_tuser_ch3)
0:data10MHz<=m_axis_data_tdata_ch3;
1:data3MHz<=m_axis_data_tdata_ch3;
2:data4MHz<=m_axis_data_tdata_ch3;
endcase
end
reg [31 : 0] phase10MHz;
reg [31 : 0] phase3MHz;
reg [31 : 0] phase4MHz;
always @(posedge clk) begin
case(m_axis_data_tuser_ch3)
0:phase10MHz<=m_axis_phase_tdata_ch3;
1:phase3MHz<=m_axis_phase_tdata_ch3;
2:phase4MHz<=m_axis_phase_tdata_ch3;
endcase
end
波形如下,從圖中可看出,經(jīng)過邏輯分選后,三個(gè)通道的波形輸出正常,這里可看到相比單通道輸出10MHz信號(hào)的正弦波,此時(shí)輸出的波形不能從時(shí)域中看出正弦波形的周期,原因是當(dāng)啟用多個(gè)通道后,系統(tǒng)鐘要除以通道數(shù)量才是對應(yīng)通道的參考鐘,此時(shí)設(shè)置了100MHz為工作時(shí)鐘,使能3個(gè)通道, 所以單個(gè)通道的參考鐘為33.333MHz,對于10MHz的信號(hào)來說,相當(dāng)于一個(gè)周期僅有三個(gè)點(diǎn),所以無法正常觀察到時(shí)域特性,但是頻域特性依舊存在。
混頻實(shí)例
混頻原理
在對輸入中頻信號(hào)需要進(jìn)行頻譜搬移, 需要使用混頻操作, 將頻譜搬移到高頻或者低頻, 其實(shí)就好比一輛車開在高速路還是低速路, 高頻低頻就是載波, 承載信息的載體。 在數(shù)字信號(hào)處理中, 頻譜的搬移就是將一個(gè)本震信號(hào)和一個(gè)輸入信號(hào), 進(jìn)行混頻, 這樣就可以得到一個(gè)復(fù)合的信號(hào), 這里通過公式開看這個(gè)復(fù)合信號(hào)。
這里的α和β就是指的兩個(gè)頻率信號(hào),當(dāng)互相相乘得到兩個(gè)頻率信號(hào),一個(gè)是α + β,另一個(gè)是α – β。 上圖的標(biāo)識(shí)的 fout 信號(hào)應(yīng)該是 f1+f2 和 f1-f2 的復(fù)合信號(hào) 。
使用多通道實(shí)例中輸出的3MHz和4Mhz,進(jìn)行混頻操作,得到1MHz和7MHz的混合信號(hào)。 調(diào)用乘法器進(jìn)行混頻乘法操作。
頂層模塊
module top(
input clk
);
wire m_axis_data_tvalid_ch3;
wire [7 : 0] m_axis_data_tdata_ch3;
wire [1 : 0] m_axis_data_tuser_ch3;
wire m_axis_phase_tvalid_ch3;
wire [31 : 0] m_axis_phase_tdata_ch3;
wire [1 : 0] m_axis_phase_tuser_ch3;
//多通道測試
dds_compiler_1 multi_ch_dds(
.aclk(clk), // input wire aclk
.m_axis_data_tvalid(m_axis_data_tvalid_ch3), // output wire m_axis_data_tvalid
.m_axis_data_tdata(m_axis_data_tdata_ch3), // output wire [7 : 0] m_axis_data_tdata
.m_axis_data_tuser(m_axis_data_tuser_ch3), // output wire [1 : 0] m_axis_data_tuser
.m_axis_phase_tvalid(m_axis_phase_tvalid_ch3), // output wire m_axis_phase_tvalid
.m_axis_phase_tdata(m_axis_phase_tdata_ch3), // output wire [31 : 0] m_axis_phase_tdata
.m_axis_phase_tuser(m_axis_phase_tuser_ch3) // output wire [1 : 0] m_axis_phase_tuser
);
reg [7 : 0] data10MHz;
reg [7 : 0] data3MHz;
reg [7 : 0] data4MHz;
always @(posedge clk) begin
case(m_axis_data_tuser_ch3)
0:data10MHz<=m_axis_data_tdata_ch3;
1:data3MHz<=m_axis_data_tdata_ch3;
2:data4MHz<=m_axis_data_tdata_ch3;
endcase
end
reg [31 : 0] phase10MHz;
reg [31 : 0] phase3MHz;
reg [31 : 0] phase4MHz;
always @(posedge clk) begin
case(m_axis_data_tuser_ch3)
0:phase10MHz<=m_axis_phase_tdata_ch3;
1:phase3MHz<=m_axis_phase_tdata_ch3;
2:phase4MHz<=m_axis_phase_tdata_ch3;
endcase
end
//混頻測試
wire [15 : 0] mixer_singal;
mult_gen_0 mult_mixer (
.CLK(clk), // input wire CLK
.A(data3MHz), // input wire [7 : 0] A
.B(data4MHz), // input wire [7 : 0] B
.P(mixer_singal) // output wire [15 : 0] P
);
endmodule
仿真測試
仿真文件可以保持單通道測試不變,點(diǎn)擊運(yùn)行行為級(jí)仿真,添加信號(hào)波形修改波形設(shè)置,可得到混頻后的信號(hào)效果。
-
數(shù)字信號(hào)處理
+關(guān)注
關(guān)注
15文章
553瀏覽量
45763 -
仿真
+關(guān)注
關(guān)注
50文章
4023瀏覽量
133337 -
分辨率
+關(guān)注
關(guān)注
2文章
1031瀏覽量
41866 -
時(shí)鐘
+關(guān)注
關(guān)注
10文章
1714瀏覽量
131275 -
DDS
+關(guān)注
關(guān)注
21文章
629瀏覽量
152483
發(fā)布評論請先 登錄
相關(guān)推薦
評論