VIVADO IP核之DDS直接数字频率合成器使用详解

VIVADO IP核之DDS直接数字频率合成器使用详解

目录

前言

一、DDS基本知识

二、DDS IP核使用之SIN COS LUT only

三、DDS IP核之SIN COS LUT only仿真

四、DDS IP核使用之Phase Generator and SIN COS LUT

五、DDS IP核之Phase Generator and SIN COS LUT仿真

总结


前言

        在数字调制解调,数字上下变频,软件无线电等应用中,均需要用到不同频率的正弦信号或者复正弦信号,VIVADO中的DDS IP核便可以产生不同频率的正弦信号,同时还可以用来计算三角函数值,本文将仔细介绍该IP核的使用,同时将该IP核计算的结果导入MATLAB中分析以验证该IP核被正确使用。


提示:以下是本篇文章正文内容,欢迎各位阅读,转载请附上链接。

一、DDS基本知识

        DDS的核心原理是通过数字计算直接生成波形数据,然后将这些数据转换为模拟信号。其基本组成包括:

相位累加器(Phase Accumulator):

        相位累加器负责生成波形的相位信息。它是一个寄存器,每个时钟周期都会根据相位增量(Phase Increment)进行累加,累加的结果表示当前波形的相位。相位增量决定了输出信号的频率。
波形查找表(Waveform Lookup Table, LUT):

        查找表存储了一周期波形的离散采样点,如正弦波的采样值。相位累加器的输出被用作查找表的地址,从而得到当前相位对应的波形幅度值。

数模转换器(Digital-to-Analog Converter, DAC):

        查找表输出的数字波形幅度值经过数模转换器转换成模拟信号。DAC的分辨率决定了输出波形的精度。

低通滤波器:

        DAC输出的是离散的步进信号,通过低通滤波器可以去除高频成分,得到平滑的模拟波形。

在VIVADO DDS IP核中,只有前两个,产生的是数字信号。

        假设f_{clk}为工作时钟频率(采样频率),N为相位增量控制字位数,K为相位增量控制字,则生成正弦波信号的频率为:

f_0=\frac{K}{2^N}\cdot f_{clk}

频率分辨率为f_{clk}/2^N

不理解这个公式的可以从周期出发理解:

T_0=\frac{2^N}{K}*T_{clk}

二、DDS IP核使用之SIN COS LUT only

        IP核命名为DDS_test,配置选项选择SIN COS LUT only,这个是用来计算三角函数值的。Nosie shaping选择无,另外一种是泰勒技术纠正,可以提高精度。相位控制字位宽和输出位宽均设置16位。

        输出选择sin和cos都选择输出,极性那项如果勾选negative就会将原本的三角函数值乘上-1,相当于与正确的三角函数值差了一个负号。幅度选择选全范围,若选择另外一个就会导致计算出来的三角函数值是正确三角函数值的一半,比如sin(30°)就会变成0.25。

        根据手册提供的内容,当选择sin和cos都输出时,sin在高位,cos在低位。<<<<<<表示补的符号位。

以上设置完成后,剩下参数保持默认,生成IP核即可。

三、DDS IP核之SIN COS LUT only仿真

        创建一个tb文件对其仿真。代码如下:

`timescale 1ns / 1ps
//
// Company: 
// Engineer: 
// 
// Create Date: 2024/08/08 14:59:00
// Design Name: 
// Module Name: tb_DDS_test
// Project Name: 
// Target Devices: 
// Tool Versions: 
// Description: 
// 
// Dependencies: 
// 
// Revision:
// Revision 0.01 - File Created
// Additional Comments:
// 
//


module tb_DDS_test( );

parameter PERIOD=2;      

reg clk = 1;

initial
begin
    forever #(PERIOD/2)  clk=~clk;
end

wire m_axis_data_tvalid;
wire [31 : 0] m_axis_data_tdata;

wire [15:0] m_axis_data_tdata_cos;
wire [15:0] m_axis_data_tdata_sin;

assign m_axis_data_tdata_cos=m_axis_data_tdata[15:0];
assign m_axis_data_tdata_sin=m_axis_data_tdata[31:16];

reg s_axis_phase_tvalid=0;
reg [15 : 0] s_axis_phase_tdata=0;

initial
begin
    #(PERIOD*5)
    forever 
    begin
        @(posedge clk) 
        begin
            s_axis_phase_tvalid<=1;
            s_axis_phase_tdata<=16'd61455;
        end
    end 
end




DDS_test u_DDS_test (
  .aclk(clk),                                 // input wire aclk
  .s_axis_phase_tvalid(s_axis_phase_tvalid),  // input wire s_axis_phase_tvalid
  .s_axis_phase_tdata(s_axis_phase_tdata),    // input wire [15 : 0] s_axis_phase_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 [31 : 0] m_axis_data_tdata
);

endmodule

仿真结果如下,更改格式s_axis_phase_tdata设置为无符号十进制数,m_axis_data_tdata_sin和m_axis_data_tdata_cos设置为小数位为15位的定点数。

相位控制字是61455,位控制字位宽是16位,那么此时对应的三角函数值在matlab由以下代码验证

a=61455;

b=a/(2^16-1)

b*360

bsin=sind(b*360)

bcos=cosd(b*360)

运行可得到,可见结果与VIVADO 仿真结果一致。

从以上仿真,我们可以知道,当相位控制字字长为N位时,输入的相位控制字范围为0~2^N-1,对应0-360°,输出就是正确的三角函数值,范围为-1~1。

另外,再说一点,用DDS IP核来计算三角函数值比用查ROM表得到三角函数值所耗的资源少的多。

四、DDS IP核使用之Phase Generator and SIN COS LUT

        将相位增量设置为可编程,这样就由程序控制输出正弦波的频率,相位增量就是相位控制字,不需要相位偏置。S_AXIS_CONFIG里面就是编程控制的相位增量。

其他参数保持默认,直接生成IP核。

五、DDS IP核之Phase Generator and SIN COS LUT仿真

         创建一个tb文件对其仿真。代码如下:

`timescale 1ns / 1ps
//
// Company: 
// Engineer: 
// 
// Create Date: 2024/08/08 16:24:30
// Design Name: 
// Module Name: tb_DDS_waveform_test
// Project Name: 
// Target Devices: 
// Tool Versions: 
// Description: 
// 
// Dependencies: 
// 
// Revision:
// Revision 0.01 - File Created
// Additional Comments:
// 
//


module tb_DDS_waveform_test(

    );

parameter PERIOD=2;      

reg clk = 1;

initial
begin
    forever #(PERIOD/2)  clk=~clk;
end

reg s_axis_config_tvalid=0;
reg [15 : 0] s_axis_config_tdata=0;
wire m_axis_data_tvalid;
wire [31 : 0] m_axis_data_tdata;
wire m_axis_phase_tvalid;
wire [15 : 0] m_axis_phase_tdata;

wire [15:0] m_axis_data_tdata_cos;
wire [15:0] m_axis_data_tdata_sin;

assign m_axis_data_tdata_cos=m_axis_data_tdata[15:0];
assign m_axis_data_tdata_sin=m_axis_data_tdata[31:16];

initial
begin
    #(PERIOD*5)
    forever 
    begin
        @(posedge clk) 
        begin
            s_axis_config_tvalid<=1;
            s_axis_config_tdata<=16'd6554;
        end
    end 
end

integer dout_file;
initial begin
    dout_file=$fopen("E:/play_vivado/DDS_test/Readme/datacos.txt");    //打开所创建的文件,修改为自己想存储的位置
    if(dout_file == 0)
    begin 
        $display ("can not open the file!");    //创建文件失败,显示can not open the file!
        $stop;
    end
end

always @(posedge clk)
begin
    if(m_axis_phase_tvalid)        
       $fdisplay(dout_file,"%d",$signed(m_axis_data_tdata_cos));    //保存有符号数据
end


DDS_waveform_test u_DDS_waveform_test (
  .aclk(clk),                                   // input wire aclk
  .s_axis_config_tvalid(s_axis_config_tvalid),  // input wire s_axis_config_tvalid
  .s_axis_config_tdata(s_axis_config_tdata),    // 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 [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
);

endmodule

相位控制字为6554,根据公式可得输出正弦波的频率为

f_0=\frac{6554}{2^{16}}\times 100MHz=10MHz

仿真所得波形如下:

在仿真文件里面自己设置的路径下找到datacos.txt(注意要运行仿真一小会儿才会有这个文件),用MATLAB去画它的频谱。

clc;

clear;

close all;

a=61455;

b=a/(2^16-1)

b*360

bsin=sind(b*360)

bcos=cosd(b*360)

vivado_datacos = importdata('datacos.txt'); %read files

vivado_datacos1=vivado_datacos(7:10240)/2^15;

Fs=100000000;

N=length(vivado_datacos1); %信号长度,采样点数

y_fft=fft(vivado_datacos1,N); %快速傅里叶变换

df=Fs/N; %计算谱线间隔

f1=0:df:Fs-df;

f1=f1-Fs/2;

% subplot(1,2,1);

v=abs(fftshift(y_fft))/N;

plot(f1,20*log10(v));

grid on;

xlabel("频率/Hz");ylabel("幅度/dB");

可得频谱图如下:

可见该正弦波频率为10MHz,IP核使用正确。


总结

        以上就是本文的全部内容,详细介绍了DDS IP核的使用,它可以拿来计算三角函数值,也可以用来产生正弦波形。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

迎风打盹儿

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值