之前的文章對dds ip 的結(jié)構(gòu)、精度、參數(shù)、接口進(jìn)行了詳細(xì)的說明,本文通過例化仿真對該IP的實(shí)際使用進(jìn)行演示。本文例化固定模式和可配置模式兩種模式分別例化ip并仿真,說明該IP的應(yīng)用。
1、固定模式:
該模式下IP的參數(shù)設(shè)置如下圖,時(shí)鐘頻率設(shè)置為100Mhz,兩個(gè)通道時(shí)分復(fù)用,SFDR 60dB.
然后相位、相位偏差全部選擇固定模式,
輸出頻率配置為1Mhz和2Mhz:
設(shè)置完之后再summary這里可以看到該IP的實(shí)現(xiàn)細(xì)節(jié),輸出位寬10bit,2ch,沒ch的時(shí)鐘速率是50Mhz,使用一個(gè)M18K的BROM實(shí)現(xiàn)查找表等等的一些細(xì)節(jié)。
在additional summary里邊可以看到相應(yīng)的頻率控制字和實(shí)際精度,因?yàn)楫?dāng)前設(shè)置的時(shí)標(biāo)準(zhǔn)模式不是柵格(rasterized)模式,所以輸出是有頻偏的。
上述設(shè)置生成的IP端口如下,輸入端口為時(shí)鐘復(fù)位信號,輸出sin cos和phase值。
dds_compiler_0 your_instance_name (
.aclk(aclk), // input wire aclk
.aresetn(aresetn), // input wire aresetn
.m_axis_data_tvalid(m_axis_data_tvalid), // output wire m_axis_data_tvalid
.m_axis_data_tdata(m_axis_data_tdata), // output wire [31 : 0] m_axis_data_tdata
.m_axis_phase_tvalid(m_axis_phase_tvalid), // output wire m_axis_phase_tvalid
.m_axis_phase_tdata(m_axis_phase_tdata) // output wire [31 : 0] m_axis_phase_tdata
);
這個(gè)IP的tb就非常簡單了,只有提供時(shí)鐘復(fù)位即可,但是輸出時(shí)時(shí)分復(fù)用的,所以tb對輸出信號進(jìn)行了處理將兩路輸出分開了,方便波形觀察,如下:
`timescale 1ns/100ps
module tb_dds_fix_normal ;
reg aclk = 'd0;
reg aresetn = 'd0;
wire m_axis_data_tvalid ;
wire [31 : 0] m_axis_data_tdata ;
wire m_axis_phase_tvalid ;
wire [31 : 0] m_axis_phase_tdata ;
always #1 aclk = ~aclk;
initial
begin
#100;
aresetn =1'b1;
end
dds_compiler_0 dds_compiler_0 (
.aclk (aclk ), // input wire aclk
.aresetn (aresetn ), // input wire aresetn
.m_axis_data_tvalid (m_axis_data_tvalid ), // output wire m_axis_data_tvalid
.m_axis_data_tdata (m_axis_data_tdata ), // output wire [31 : 0] m_axis_data_tdata
.m_axis_phase_tvalid (m_axis_phase_tvalid ), // output wire m_axis_phase_tvalid
.m_axis_phase_tdata (m_axis_phase_tdata ) // output wire [31 : 0] m_axis_phase_tdata
);
reg S_ch0_valid ;
reg [15:0] S_ch0_cos ;
reg [15:0] S_ch0_sin ;
reg [31:0] S_ch0_pha ;
reg [15:0] S_ch1_cos ;
reg [15:0] S_ch1_sin ;
reg [31:0] S_ch1_pha ;
always @(posedge aclk)
if(!aresetn)
S_ch0_valid <= 1'b1;
else if(m_axis_data_tvalid)
S_ch0_valid <= ~S_ch0_valid;
always @(posedge aclk)
if(S_ch0_valid)
begin
S_ch0_cos <= m_axis_data_tdata[15:0] ;
S_ch0_sin <= m_axis_data_tdata[31:16] ;
S_ch0_pha <= m_axis_phase_tdata ;
S_ch1_cos <= S_ch1_cos ;
S_ch1_sin <= S_ch1_sin ;
S_ch1_pha <= S_ch1_pha ;
end
else
begin
S_ch0_cos <= S_ch0_cos ;
S_ch0_sin <= S_ch0_sin ;
S_ch0_pha <= S_ch0_pha ;
S_ch1_cos <= m_axis_data_tdata[15:0] ;
S_ch1_sin <= m_axis_data_tdata[31:16] ;
S_ch1_pha <= m_axis_phase_tdata ;
end
endmodule
仿真波形如下:
2、相位可配置模式:
該模式將相位偏差和相位步進(jìn)設(shè)置為axi配置模式,如下圖,其它配置保持不變:
生成的端口如下,該模式下增加了config端口,用于phase信息的配置:
dds_compiler_cfg your_instance_name (
.aclk(aclk), // input wire aclk
.aresetn(aresetn), // input wire aresetn
.s_axis_config_tvalid(s_axis_config_tvalid), // input wire s_axis_config_tvalid
.s_axis_config_tdata(s_axis_config_tdata), // input wire [31 : 0] s_axis_config_tdata
.s_axis_config_tlast(s_axis_config_tlast), // input wire s_axis_config_tlast
.m_axis_data_tvalid(m_axis_data_tvalid), // output wire m_axis_data_tvalid
.m_axis_data_tdata(m_axis_data_tdata), // output wire [31 : 0] m_axis_data_tdata
.m_axis_phase_tvalid(m_axis_phase_tvalid), // output wire m_axis_phase_tvalid
.m_axis_phase_tdata(m_axis_phase_tdata), // output wire [15 : 0] m_axis_phase_tdata
.event_s_config_tlast_missing(event_s_config_tlast_missing), // output wire event_s_config_tlast_missing
.event_s_config_tlast_unexpected(event_s_config_tlast_unexpected) // output wire event_s_config_tlast_unexpected
);
這時(shí),需要對tb進(jìn)行相應(yīng)的修改,增加config的配置,如下,新增一個(gè)11bit的計(jì)數(shù)器,計(jì)滿后對兩個(gè)通道的phase值進(jìn)行翻倍:
reg aclk = 'd0;
reg aresetn = 'd0;
reg s_axis_config_tvalid= 'd0;
reg [31 : 0] s_axis_config_tdata = {{16'd1310},{16'd1310}};
reg s_axis_config_tlast = 'd0;
wire m_axis_data_tvalid ;
wire [31 : 0] m_axis_data_tdata ;
wire m_axis_phase_tvalid ;
wire [15 : 0] m_axis_phase_tdata ;
always #1 aclk = ~aclk;
initial
begin
#100;
aresetn =1'b1;
end
reg [10:0] S_clk_cnt ;
always @(posedge aclk)
if(!aresetn)
S_clk_cnt <= 'd3;
else
S_clk_cnt <= S_clk_cnt + 'd1;
always @(posedge aclk)
s_axis_config_tvalid <= ((S_clk_cnt==0)||(S_clk_cnt==1));
always @(posedge aclk)
s_axis_config_tlast <= (S_clk_cnt==1);
always @(posedge aclk)
if(s_axis_config_tvalid)
s_axis_config_tdata <= s_axis_config_tdata + s_axis_config_tdata;
dds_compiler_cfg your_instance_name (
.aclk (aclk ), // input wire aclk
.aresetn (aresetn ), // input wire aresetn
.s_axis_config_tvalid (s_axis_config_tvalid ), // input wire s_axis_config_tvalid
.s_axis_config_tdata (s_axis_config_tdata ), // input wire [31 : 0] s_axis_config_tdata
.s_axis_config_tlast (s_axis_config_tlast ), // input wire s_axis_config_tlast
.m_axis_data_tvalid (m_axis_data_tvalid ), // output wire m_axis_data_tvalid
.m_axis_data_tdata (m_axis_data_tdata ), // output wire [31 : 0] m_axis_data_tdata
.m_axis_phase_tvalid (m_axis_phase_tvalid ), // output wire m_axis_phase_tvalid
.m_axis_phase_tdata (m_axis_phase_tdata ), // output wire [15 : 0] m_axis_phase_tdata
.event_s_config_tlast_missing (event_s_config_tlast_missing ), // output wire event_s_config_tlast_missing
.event_s_config_tlast_unexpected (event_s_config_tlast_unexpected) // output wire event_s_config_tlast_unexpected
);
仿真結(jié)果如下如,可以看到隨著phase步進(jìn)的不斷累加,兩個(gè)通道的輸出頻率也在不斷增加.
好了,本文就寫的這里,希望通著這一系列的文章能幫助大家深入理解并正確使用DDS IP,詳細(xì)的仿真過程可參考B站視頻。
-
FPGA
+關(guān)注
關(guān)注
1629文章
21729瀏覽量
602986 -
Xilinx
+關(guān)注
關(guān)注
71文章
2167瀏覽量
121303 -
仿真
+關(guān)注
關(guān)注
50文章
4070瀏覽量
133552 -
DDS
+關(guān)注
關(guān)注
21文章
633瀏覽量
152630
發(fā)布評論請先 登錄
相關(guān)推薦
評論