vivado DDS IP核的使用及仿真-Xilinx-AMD社区-FPGA CPLD-ChipDebug

vivado DDS IP核的使用及仿真

 

参考:https://blog.csdn.net/weixin_45303812/article/details/123704440

新人第一次写文档,有错误的地方请大佬指点。

文档:Xilinx官网搜DDS

Configuration 可配置参数:

1.Configuration Options,有如下三种模式

Phase Generator and SIN/COS LUT (DDS):
相位和sin和cos的数据都是IP核自己产生

Phase Generator only:

只要相位输出
SIN/COS LUT only模式:
只需要sin/cos模块输出,但此模式需要外部不断的输入累加的相位

2.System clock  系统时钟频率,同样也是采样率

3.Number of channels 通道数,本次用的是四通道,单通道设置为1

4.Mode of operation 不太懂,没涉及到,一般选择standard

5.Parameter selection分为两种模式,Hardware Parameter 和 System Parameter

Hardware Parameter模式没用过,看起来是设置输出的数据位宽和相位位宽就可以了。

System Parameter模式:

SFDR:无杂散动态范围

简单来说就是每增加6dB,数据位宽增加1位,16位宽,就是96dB

Frequency Resolution:频率分辨率

这个决定了数据的精度,用时钟频率除以2的n次方,n为位宽,如果是多通道,再除以通道数

比如这里设置是32位宽,4通道,时钟是491.52MHz,那么可以算出来这个大约设置在0.029-0.06之间,然后左边可以看到数config_tdata的位宽变成32位,位宽更大这样输入的频率精度就更精确。

Implementation可配置参数:

1.Phase Increment Programmability:相位增量(即频率控制字)控制模式选择,一般选择固定或者可编程模式,如果是固定模式,可以通过第四个配置页Output Frequencies配置输出的频率,这里选择可编程模式,该模式下在valid有效时可对相位增量进行配置。

如图,也就是congfig配置这个,我们需要4通道,那么valid就需要持续四个时钟周期,然后每个时钟周期输入我们需要的tdata,这个参数是根据我们之前设置的精度和时钟来算。具体下面tb用到时讲。

2.Phase Offset Programmability:相位偏移量(即相位控制字)控制模式选择,暂时没用到,用法应该和频率控制字类似。

3.Output  输出: sin、cos、sin&cos字面意思,这里选sin&cos。

4.Has Phase Out :本实验不需要相位输出,不选。

其他的默认。

Detailed Implementation:设置输入输出的一些格式,需不需要ready,last等,根据需要选择即可。

Output Frequencies:输出频率,固定模式的时候设置这个。

最终配置如下:

代码部分:

调用IP核

module dds_test(
		input 						aclk								,
		input 						aresetn								,
		input 						s_axis_config_tvalid				,
		output						s_axis_config_tready				,
		input 			[31: 0] 	s_axis_config_tdata					,
		input 						s_axis_config_tlast					,
		output						m_axis_data_tvalid					,
		input 						m_axis_data_tready					,
		output			[31: 0] 	m_axis_data_tdata					,
		output						m_axis_data_tlast					,
		output						event_s_config_tlast_missing		,
		output						event_s_config_tlast_unexpected		
    );
 
dds_compiler_0 dds_0 (
  .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_tready(s_axis_config_tready),                        // output wire s_axis_config_tready
  .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_tready(m_axis_data_tready),                            // input wire m_axis_data_tready
  .m_axis_data_tdata(m_axis_data_tdata),                              // output wire [31 : 0] m_axis_data_tdata
  .m_axis_data_tlast(m_axis_data_tlast),                              // output wire m_axis_data_tlast
  .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
);
 
endmodule

 

 tb部分,生成了四路正余弦IQ信号。

其中最重要的是上文提到的参数设置。

以生成10M信号为例,我们的时钟采用的是491.52MHz,一共4路信号,那么实际采样率就是122.88MHz,我们设置的精度为32位,因此,10M信号的参数计算如下:

10/122.88 * 2^32 ≈ 32‘h 14D55555;

如果是-10M信号,由于频谱翻转,位置是122.88M-10M,计算如下

112.88/122.88 * 2^32 ≈ 32‘h EB2AAAAB

或者用2^32 – 10/122.88 * 2^32 ≈ 32‘h EB2AAAAB都可以,一个意思。

此外,DDS多通道的配置是,每个时钟周期VALID有效时,输入的参数才有效,因此多通道必须一个输入时钟一个参数,最后加last。

`timescale 1ns/1ps
module dds_tb();
 
reg 						aclk								;
reg 						aresetn								;
reg 						s_axis_config_tvalid				;
wire						s_axis_config_tready				;
reg 			[31: 0] 	s_axis_config_tdata					;
reg 						s_axis_config_tlast					;
wire						m_axis_data_tvalid					;
reg 						m_axis_data_tready					;
wire			[31: 0] 	m_axis_data_tdata					;
wire						m_axis_data_tlast					;
wire						event_s_config_tlast_missing		;
wire						event_s_config_tlast_unexpected		;
 
reg    	[1 : 0]   	cnt_chan				;
reg 	[31: 0] 	m_dout_0				;
reg 	[31: 0] 	m_dout_1				;
reg 	[31: 0] 	m_dout_2				;
reg 	[31: 0] 	m_dout_3				;
 
always @(posedge aclk) begin
	if (!aresetn) begin
		cnt_chan <= 2'b0;// reset
	end
	else begin
		cnt_chan <= cnt_chan + 1'b1;
	end
end
always @(posedge aclk) begin
	if (cnt_chan == 2'b0) begin
		m_dout_0 <= m_axis_data_tdata;
	end
	else if(cnt_chan == 2'b01)begin
		m_dout_1 <= m_axis_data_tdata;
	end
	else if(cnt_chan == 2'b10)begin
		m_dout_2 <= m_axis_data_tdata;
	end
	else if(cnt_chan == 2'b11)begin
		m_dout_3 <= m_axis_data_tdata;
	end
end
 
parameter fre_ch0 = 32'h14D55555  ,//10M
          //fre_ch0 = 873813333   ,
          fre_ch1 = 32'hEB2AAAAB  ,//-10M
          fre_ch2 = 32'h29AAAAAA     ,//20M
          fre_ch3 = 32'hD6555556    ;//-20M
 
initial aclk = 1'b0;
always #(500/491.52) aclk = ~aclk;
initial begin
        aresetn = 1'b0;s_axis_config_tvalid=0;s_axis_config_tdata = 0;s_axis_config_tlast=0;m_axis_data_tready=1'b0;
		#(1000*100/491.52)   aresetn = 1'b1;
		#(1000*100/491.52)    s_axis_config_tvalid = 1;s_axis_config_tdata = fre_ch0;m_axis_data_tready=1'b1;
		#(1000/491.52) s_axis_config_tvalid = 1;s_axis_config_tdata = fre_ch1;
		#(1000/491.52) s_axis_config_tvalid = 1;s_axis_config_tdata = fre_ch2;
		#(1000/491.52) s_axis_config_tvalid = 1;s_axis_config_tdata = fre_ch3;s_axis_config_tlast=1;
		#(1000/491.52) s_axis_config_tvalid = 0;s_axis_config_tdata = 0;s_axis_config_tlast=0;
end
dds_test tb (
  .aclk(aclk),                                                       
  .aresetn(aresetn),                                                 
  .s_axis_config_tvalid(s_axis_config_tvalid),                       
  .s_axis_config_tready(s_axis_config_tready),                       
  .s_axis_config_tdata(s_axis_config_tdata),                         
  .s_axis_config_tlast(s_axis_config_tlast),                         
  .m_axis_data_tvalid(m_axis_data_tvalid),                           
  .m_axis_data_tready(m_axis_data_tready),                           
  .m_axis_data_tdata(m_axis_data_tdata),                             
  .m_axis_data_tlast(m_axis_data_tlast),                             
  .event_s_config_tlast_missing(event_s_config_tlast_missing),       
  .event_s_config_tlast_unexpected(event_s_config_tlast_unexpected)  
);
endmodule

 

仿真结果:

输出的四路信号分别为10M,-10M,20M,-20M的IQ信号,图片没拆出来,大概看个波形。

请登录后发表评论

    没有回复内容