DDS IP核使用并使用matlab测试

通过查阅几篇CSDN找到使用方法,在此记录一下。

FPGA数字信号处理基础----Xilinx DDS IP使用_dds ip 脉冲信号-CSDN博客

DDS的理解及IP核的使用_dds ip核-CSDN博客

Vivado的前仿真数据导入到matlab中进行分析 - 知乎 (zhihu.com)

1.configuration

①Configuration option:一共三个模式

Phase Generator and SIN/COS LUT (DDS):

在IP核内部集成好相位累加器与sin/cos模块,只需要在GUI中配置好需要生成的频率即可,可选择单独输出sin,或cos,也可以两个曲线正交输出。

Phase Generator only:

例化的 IP 核只有一个相位累加器,IP核不断输出相位累加的结果

SIN/COS LUT only模式:

例化的IP核只有一个sin/cos模块,需要外部不断的输入累加的相位

②System clock 系统时钟(同时也是采样频率),直接影响DDS输出波形的频率

③Number of channels 通道数,一般默认为1

④Mode of operation 分为两种模式,详情可翻阅Xilinx的官方手册,一般选择标准operation模式

标准operation模式下。

rasterized模式下,把分母换成可直接调控的M,方便输出一些整数频率波形。

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

Hardware Parameter模式下需要选择是否需要整形噪声Noise Shaping以及输出的相位位宽核数据位宽

System Parameter模式包含Spurious Free Dynamic Range(SFDR)、Frequency Resolution(频率分辨率)、Noise Shaping三种需要配置的参数,SFDR与输出的数据位宽有关,Frequency Resolution与相位位宽有关,通过下面表格可以通过输出位宽算出SFDR

Dither为抖动法,以增加底噪为代价减小SFDR

Taylor是泰勒级数法,201405 (ceaj.org)

Auto为自动选择

system parameter可以选择输出频率,不过需要的参数多,为了方便并且使用泰勒级数法就选择了Hardware Paramete,在Hardware Paramete中输出频率需要通过公式计算:

2.implementation

可以设置为编程模式或者固定模式,编程模式可以在运行过程中改变输出频率。

3.写入相角增量

4.计算过程

本次生成10M信号,激发时钟为100M时钟。使用16位相位宽度

得到角度增量为6554 换成二进制写入3的相角增量即可

5.可以看到生成的频率,

生成数据为12位宽,其中第11位是符号位。

运行代码:

`timescale 1ns / 1ps



module dds_top(
    input                  i_clk                  ,
    input                  i_rst_n                ,
    output                 m_axis_data_tvalid     ,
    output  [11:0]         dout_sin   
 );
//wire [11:0]     dout_sin                ;
wire           ro_dout_vaild              ;
wire [15:0]     m_axis_data_tdata       ;
wire            m_axis_data_tvalid      ;

wire [15:0]     m_axis_phase_tdata      ;
wire            m_axis_phase_tvalid     ;

assign dout_sin = m_axis_data_tdata[11:0];
    dds_compiler_0 dds_u0(
  .aclk(i_clk),                                  // input wire aclk
  .s_axis_config_tvalid(1'd0),  // input wire s_axis_config_tvalid
  .s_axis_config_tdata(16'd0),    // input wire [15 : 0] s_axis_config_tdata
  .m_axis_data_tvalid(m_axis_data_tvalid),      // output wire m_axis_data_tvalid
  .m_axis_data_tdata(m_axis_data_tdata),        // output wire [15 : 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
);
endmodule

测试代码:把数据保存在txt里方便观察


module tb_dds(

    );


	reg clk;

	initial begin
		clk = 0;
		forever #(5) clk = ~clk; // 100M system clokc
	end
integer real_out_file;
// integer imag_out_file;
 wire[11:0]real_data;
initial
begin
    real_out_file = $fopen("./dds_out_real.txt","w");//定义需要保存的路径和文件名
    // imag_out_file = $fopen("./fft_out_imag.txt","w");//定义需要保存的路径和文件名
    #4500 $fclose(real_out_file) ;//在数据有效结束后关闭文件句柄
    // $fclose(imag_out_file) ;//在数据有效结束后关闭文件句柄
end
 
always @(posedge clk ) begin
    if(real_data_tvalid)begin
        $fdisplay(real_out_file,"%b",real_data);//将数据保存为二进制
      //  $fdisplay(imag_out_file,"%b",imag_data);//将数据保存为二进制
    end
end



dds_top dds_top_u (
  .i_clk(clk),                                  	// input wire aclk
  .i_rst_n(1'd1),
  .m_axis_data_tvalid(real_data_tvalid),
  .dout_sin(real_data)
);
endmodule

matlab代码:

clear
clc
close all
data_out = txtread_fi('dds_out_real2.txt',12,0);%12为有符号定点数的总长度,0为小数位的长度 只影响幅度
fs = 100000000;      %采样率
N = length(data_out);      %采样点数
n = 0:N-1;
t = n/fs;           %时间序列
f = n*fs/N;         %频率序列
Y = fft(data_out);         %对M进行FFT变换
fshift = (-N/2:N/2-1)*fs/N;
y = fftshift(Y);    %以0为中心循环平移
y_abs = 10*log10(abs(y));
figure;
subplot(2,1,1);
plot(t,data_out);          %时域波形
title('时域波形');xlabel('时间/s');ylabel('幅值');
subplot(2,1,2);
plot(fshift,y_abs);          %频域波形
title('频域波形');xlabel('频率/s');ylabel('幅值');

function data_out = txtread_fi(txt_file_path,total_bits_num,fraction_bits_num)

% 打开文件
fileID = fopen(txt_file_path, 'r');

% 使用 textscan 函数读取文件
data_cell = textscan(fileID, '%s', 'delimiter', '\n');

% 获取行数
line_count = numel(data_cell{1});

% 关闭文件
fclose(fileID);
text = fileread(txt_file_path);

data = [];
for i = 1:line_count
    data = [data;text((total_bits_num+2)*(i-1)+1:(total_bits_num+2)*(i-1)+total_bits_num)];
end

data_out = data2fix(data,fraction_bits_num);

end

function [data_out] = data2fix(data_in,fraction_bits_num)
    [m,~] = size(data_in);
    data_out = zeros(m,1);
    for data_index = 1:m
%         x = dec2bin(data_in(data_index),total_bits_num);
        x = data_in(data_index,:);
        x_init = zeros(size(x));
        y = 0;
        if(str2num(x(1))==0)
            for i = 1:length(x)
                x_init(i) = str2num(x(i));
            end

            for i = 1:length(x)
                y = y+2^(length(x)-i)*x_init(i);
            end
        else
            for i = 1:length(x)
                if(str2num(x(i))==1)
                    x_init(i) = 0;
                else
                    x_init(i) = 1;
                end
            end
            add_bit_last = 1;
            for i = 1:length(x)
                if((x_init(length(x)+1-i))&&(add_bit_last==1))
                    x_init(length(x)+1-i) = 0;
                    add_bit_last = 1;
                else
                    x_init(length(x)+1-i) = x_init(length(x)+1-i)+add_bit_last;
                    add_bit_last = 0;
                end
            end

            for i = 1:length(x)
                y = y+2^(length(x)-i)*x_init(i);
            end
            y = -y;
        end
        data_out(data_index) = y/(2^(fraction_bits_num));
    end
end

运行结果:

  • 14
    点赞
  • 13
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
Vivado是一款由Xilinx开发的集成电路设计工具,用于设计和实现FPGA和SoC。DDS IP核是Vivado中的一个IP核,用于生成数字频率合成器。根据引用\[2\]中的代码,可以看出DDS IP核的配置是通过控制字来实现的。控制字的值决定了输出信号的频率和相位。在引用\[3\]中的tb文件中,可以看到控制字的值被设置为66和6666,这将影响DDS IP核生成的输出信号的频率。通过修改控制字的值,可以实现不同的频率输出。在Vivado中使用DDS IP核,需要将IP核添加到设计中,并根据需求配置IP核的参数,如控制字的值、时钟频率等。然后,将设计综合、实现和生成比特流文件,最后下载到目标设备中进行验证和测试。 #### 引用[.reference_title] - *1* *2* [Vivado DDS IP核使用、仿真、多相处理和相关计算验证](https://blog.csdn.net/Popplio/article/details/126711613)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^control_2,239^v3^insert_chatgpt"}} ] [.reference_item] - *3* [FPGA自学笔记--DDS ip核使用(vivado)](https://blog.csdn.net/lgk1996/article/details/123245246)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^control_2,239^v3^insert_chatgpt"}} ] [.reference_item] [ .reference_list ]

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值