• 首页 首页 icon
  • 工具库 工具库 icon
    • IP查询 IP查询 icon
  • 内容库 内容库 icon
    • 快讯库 快讯库 icon
    • 精品库 精品库 icon
    • 问答库 问答库 icon
  • 更多 更多 icon
    • 服务条款 服务条款 icon

Vivado DDS IP核使用、仿真、多相处理和相关计算验证

武飞扬头像
Ca离子载体A23187
帮助1

第一次学,查询了很多CSDN网页,也问了组里的技术专家,得到了很多指导。把我的个人学习笔记在这里保存记录分享,如果有问题欢迎大家批评指正。也欢迎大家点赞评论收藏,一起进步!

1 DDS IP核的配置

创建工程,在IP核配置页面选择DDS compiler 6.0。对IP核进行配置。

学新通

如图所示配置参数。

Configuration(配置)页面,Configuration Options 有三个选项,分别是相位产生器和SIN COS查找表、单独的相位产生器、单独的sin/cos,一般选择第一个,利用IP核生成一个频率相位可调的正余弦发生器。

将System Clock系统时钟设置为250MHz,Number of Channels通道数设为1,Parameter Selection(参数选择)主要分为Hardware Parameter 和 System Parameter两种。

在System Parameter模式下,配置页面需要配置系统参数设置。共有Spurious Free Dynamic Range(SFDR)、Frequency Resolution(频率分辨率)、Noise Shaping(需不需要整形噪声选择自动模式就行)三项。其中SFDR与输出数据位宽相关,见手册表格。

学新通

Hardware Parameter模式下,Noise Shaping噪声整形选项一般选择None。Phase width指的是输出的相位宽度信息,output width 指的是输出的数据位宽;相位位宽选择32位,数据位宽采用16位。

Implementation页面,Phase Increment Programmability与Phase Offset Programmability,相位增量(即频率控制字)和相位偏移量(即相位控制字)控制模式选择,一般选择可编程模式,该模式下在valid有效时可对相位增量和相位偏移量进行配置;Output sin、cos、sin&cos根据需要选择即可。如图所示:

学新通

在Summary中检查配置无误:

学新通

2 单路正弦信号的产生

事实上,任何周期信号都可以分解为一系列正弦或余弦信号之和,正弦信号是关于相位的一个周期函数。相位和幅值的一个一个地对应关系就好比存储器中地址和存储内容的关系,如果把一个周期内每个相位对应的幅度值存入存储器当中,那么对于任意频率的正弦信号,在任意时刻,只要已知相位Φ(t),也就知道地址,就可通过查表得到s(t)。

相位累加器在每个时钟脉冲输入时,把频率控制字累加一次,相位累加器的输出数据就是信号的相位,用输出的数据作为波形存储器(ROM)的相位取样地址,这样就可以把存取在波形存储器内的波形抽样值经查找表查处,完成相位到幅值的转换。频率控制字相当于Φ(t)中的2πfc,相位控制字相当于Φ(t)中的θ0。

由于相位累加器字长的限制,相位累加器累加到一定值后,其输出将会溢出,这样波形存储器的地址就会循环一次,即意味着输出波形循环一周。故改变频率控制字即相位增量,就可以改变相位累加器的溢出时间,在时钟频率不变的条件下就可以改变输出频率。改变查表寻址的时钟频率,同样也可以改变输出波形的频率。

为了获得较高的频率分辨率,则只有增加相位累加器的字长N。

原文链接:https://blog.csdn.net/u014586651/article/details/88830115

相位累加器的字长为N,就将一个完整周期的正弦波的相位均匀分割为学新通个离散相位。如果想将频率提高到2 = 点数变为1/2(隔一个点输出一个波形)。事实上,DDS满足:

学新通

其中,fout是输出频率,fclk是系统工作时钟的频率,FTW是频率控制字,N是相位累加器的位数。对于一个IP核生成一路信号,其满足:

学新通

其中,fout为输出频率,fclk为输入ip的时钟。Δθ为相位增量(频率控制字),Bθ(n)为频率精度位数、输出相位数据的宽度(Phase Width),计算公式满足:

学新通

其中Δf为频率精度,对应IP核中Frequncy Resolution。

相位控制字满足:

学新通

其中θ为相位偏移量,N为相位累加器的位数。

在IP Symbol中检查IP核的端口,对IP核进行配置和例化。

代码如下所示:

  1.  
    module simu(
  2.  
    );
  3.  
     
  4.  
    reg clk;
  5.  
    reg [63:0]pinc_sin;
  6.  
    reg en_pinc;
  7.  
     
  8.  
    initial begin
  9.  
    pinc_sin={32'd715827883,32'h0fffffff};
  10.  
    en_pinc=1; //必须为1才有效
  11.  
    clk=0;
  12.  
    end
  13.  
     
  14.  
    always #2 clk=~clk;
  15.  
     
  16.  
    wire [15:0]dout_dds;
  17.  
    wire data_tvalid;
  18.  
     
  19.  
    dds_compiler_0 name(
  20.  
    .aclk(clk),
  21.  
    .s_axis_config_tvalid(en_pinc),//控制字有效信号,为1时控制字才有用。
  22.  
    .s_axis_config_tdata(pinc_sin),
  23.  
    .m_axis_data_tvalid(data_tvalid),
  24.  
    .m_axis_data_tdata(dout_dds));
  25.  
     
  26.  
    endmodule
学新通

其中,pinc_sin采用位拼接的方式配置频率控制字和相位控制字,本实验初相偏差π/3,根据相位控制字计算公式,poff=(π/3)*2^32/2π= 32'd715827883,频率控制字选择32'h0fffffff,仿真可以输出正弦波形。

学新通

3 多相DDS

在第二节中已经实现了输出250MHz的正弦波形,现在将使用多相处理,用四路250MHz的正弦波形构建一个1GHz的正弦波形。

学新通

基本原理如上图所示,在一个上升沿内并行产生四个相位,再进行相应的相幅转换。图中1-4分别代表四路信号。由图可知,对于一路信号而言,其频率控制字FTW’=4FTW,每一路信号之间有一个FTW的相位差。

配置四个与第二节完全相同的DDS核:

学新通

simu代码如下所示:

  1.  
    module simu(
  2.  
     
  3.  
      );
  4.  
     
  5.  
     
  6.  
     
  7.  
      reg clk;
  8.  
     
  9.  
      reg [63:0]pinc_sin_0;
  10.  
     
  11.  
      reg [63:0]pinc_sin_1;
  12.  
     
  13.  
      reg [63:0]pinc_sin_2;
  14.  
     
  15.  
      reg [63:0]pinc_sin_3;
  16.  
     
  17.  
     
  18.  
     
  19.  
      reg en_pinc_0;
  20.  
     
  21.  
      reg en_pinc_1;
  22.  
     
  23.  
      reg en_pinc_2;
  24.  
     
  25.  
      reg en_pinc_3;
  26.  
     
  27.  
     
  28.  
     
  29.  
      reg [15:0]q0;
  30.  
     
  31.  
     
  32.  
     
  33.  
      //存储波形数据输出为csv文件
  34.  
     
  35.  
      integer file_0;
  36.  
     
  37.  
      integer file_1;
  38.  
     
  39.  
      integer file_2;
  40.  
     
  41.  
      integer file_3;
  42.  
     
  43.  
        
  44.  
     
  45.  
     
  46.  
     
  47.  
      initial begin
  48.  
     
  49.  
      //对四个dds赋值,每个间隔dds相差FTW。频率控制字FTW'=4FTW
  50.  
     
  51.  
      pinc_sin_0={32'd715827883,32'h03fffffc};  
  52.  
      //h0fffffff=d268435455;h00ffffff=16777215;h03fffffc=d67108860
  53.  
     
  54.  
      pinc_sin_1={32'd732605098,32'h03fffffc};
  55.  
     
  56.  
      pinc_sin_2={32'd749382313,32'h03fffffc};
  57.  
     
  58.  
      pinc_sin_3={32'd766159528,32'h03fffffc};
  59.  
     
  60.  
     
  61.  
     
  62.  
      en_pinc_0=16'd1;
  63.  
     
  64.  
      en_pinc_1=16'd1;
  65.  
     
  66.  
      en_pinc_2=16'd1;
  67.  
     
  68.  
      en_pinc_3=16'd1; //必须为1才有效
  69.  
     
  70.  
     
  71.  
     
  72.  
      clk=16'd0;
  73.  
     
  74.  
      q0=16'd0;
  75.  
     
  76.  
     
  77.  
     
  78.  
      file_0=$fopen("E:/study2022/dds2/data_0.csv","w");
  79.  
     
  80.  
      file_1=$fopen("E:/study2022/dds2/data_1.csv","w");
  81.  
     
  82.  
      file_2=$fopen("E:/study2022/dds2/data_2.csv","w");
  83.  
     
  84.  
      file_3=$fopen("E:/study2022/dds2/data_3.csv","w");
  85.  
     
  86.  
      end
  87.  
     
  88.  
     
  89.  
     
  90.  
      always #2 clk=~clk;
  91.  
     
  92.  
     
  93.  
     
  94.  
      wire [15:0]dout_dds_0;
  95.  
     
  96.  
      wire [15:0]dout_dds_1;
  97.  
     
  98.  
      wire [15:0]dout_dds_2;
  99.  
     
  100.  
      wire [15:0]dout_dds_3;
  101.  
     
  102.  
      wire data_tvalid_0;
  103.  
     
  104.  
      wire data_tvalid_1;
  105.  
     
  106.  
      wire data_tvalid_2;
  107.  
     
  108.  
      wire data_tvalid_3;
  109.  
     
  110.  
     
  111.  
     
  112.  
       always @(posedge clk)begin
  113.  
     
  114.  
        if(q0 < 16'd4000)begin
  115.  
     
  116.  
            $fwrite(file_0,"%h\n",dout_dds_0);
  117.  
     
  118.  
            $fwrite(file_1,"%h\n",dout_dds_1);
  119.  
     
  120.  
            $fwrite(file_2,"%h\n",dout_dds_2);
  121.  
     
  122.  
            $fwrite(file_3,"%h\n",dout_dds_3);
  123.  
     
  124.  
            q0 <= q0 16'd1;
  125.  
     
  126.  
        end
  127.  
     
  128.  
        else begin
  129.  
     
  130.  
            q0 <= q0;
  131.  
     
  132.  
            $fclose(file_0);
  133.  
     
  134.  
            $fclose(file_1);
  135.  
     
  136.  
            $fclose(file_2);
  137.  
     
  138.  
            $fclose(file_3);
  139.  
     
  140.  
        end
  141.  
     
  142.  
      end
  143.  
     
  144.  
     
  145.  
     
  146.  
    dds_compiler_0 name0(
  147.  
     
  148.  
        .aclk(clk),
  149.  
     
  150.  
        .s_axis_config_tvalid(en_pinc_0),     //相位控制字有效信号,同。
  151.  
     
  152.  
        .s_axis_config_tdata(pinc_sin_0),
  153.  
     
  154.  
        .m_axis_data_tvalid(data_tvalid_0),
  155.  
     
  156.  
        .m_axis_data_tdata(dout_dds_0));
  157.  
     
  158.  
     
  159.  
     
  160.  
    dds_compiler_1 name1(
  161.  
     
  162.  
        .aclk(clk),
  163.  
     
  164.  
        .s_axis_config_tvalid(en_pinc_1),     //相位控制字有效信号,同。
  165.  
     
  166.  
        .s_axis_config_tdata(pinc_sin_1),
  167.  
     
  168.  
        .m_axis_data_tvalid(data_tvalid_1),
  169.  
     
  170.  
        .m_axis_data_tdata(dout_dds_1));
  171.  
     
  172.  
     
  173.  
     
  174.  
    dds_compiler_2 name2(
  175.  
     
  176.  
        .aclk(clk),
  177.  
     
  178.  
        .s_axis_config_tvalid(en_pinc_2),     //相位控制字有效信号,同。
  179.  
     
  180.  
        .s_axis_config_tdata(pinc_sin_2),
  181.  
     
  182.  
        .m_axis_data_tvalid(data_tvalid_2),
  183.  
     
  184.  
        .m_axis_data_tdata(dout_dds_2));
  185.  
     
  186.  
       
  187.  
     
  188.  
    dds_compiler_3 name3(
  189.  
     
  190.  
        .aclk(clk),
  191.  
     
  192.  
        .s_axis_config_tvalid(en_pinc_3),     //相位控制字有效信号,同。
  193.  
     
  194.  
        .s_axis_config_tdata(pinc_sin_3),
  195.  
     
  196.  
        .m_axis_data_tvalid(data_tvalid_3),
  197.  
     
  198.  
        .m_axis_data_tdata(dout_dds_3));  
  199.  
     
  200.  
    Endmodule
学新通

代码中对频率控制字、相位控制字进行了相关配置,并将输出的四路信号的相关点的数据存为csv文件。

实验波形图如图所示:

学新通

计算验证一下,FTW’=4TFW=67108860,fclk=250*10^6,N=32。

理论上的fout=FTW’*fclk/2^N=67108860*250*10^6/2^32=3.9062*10^6Hz。

观察波形图,输出信号周期为500ns-244ns=256ns,fout=1/256ns=3.9062*10^6Hz,相吻合,频率控制字设置无误。

相位初相能观察到π/3的初相,不同信号之间能观察到一个FTW的相差,频率控制字设置无误。

学新通

学新通

将保存的信号csv文件导入Matlab,对其进行交叉拼接处理,并绘制拼好后的正弦数组的频谱图。

学新通

相关Matlab代码如下所示:

  1.  
    %读取波形数值
  2.  
     
  3.  
    %num_0 = xlsread('E:/study2022/dds/data_0.xlsx',1,'B1:B511')
  4.  
     
  5.  
    %num_1 = xlsread('E:/study2022/dds/data_1.xlsx',1,'B1:B511')
  6.  
     
  7.  
    %num_2 = xlsread('E:/study2022/dds/data_2.xlsx',1,'B1:B511')
  8.  
     
  9.  
    %num_3 = xlsread('E:/study2022/dds/data_3.xlsx',1,'B1:B511')
  10.  
     
  11.  
     
  12.  
     
  13.  
    %16进制转化为10进制数
  14.  
     
  15.  
    data_0=hex2dec(data0)
  16.  
     
  17.  
    data_1=hex2dec(data1)
  18.  
     
  19.  
    data_2=hex2dec(data2)
  20.  
     
  21.  
    data_3=hex2dec(data3)
  22.  
     
  23.  
     
  24.  
     
  25.  
    %交叉合并(拼接)
  26.  
     
  27.  
    merge=[data_0'
  28.  
     
  29.  
          data_1'
  30.  
     
  31.  
          data_2'
  32.  
     
  33.  
          data_3'];
  34.  
     
  35.  
    merge=reshape(merge,[],1); %[]=length(data_0) length(data_1) length(data_2) length(data_3)
  36.  
     
  37.  
     
  38.  
     
  39.  
    %把矩阵merge转化为csv文件
  40.  
     
  41.  
    csvwrite('E:/study2022/dds2/merge.csv',merge);
  42.  
     
  43.  
     
  44.  
     
  45.  
    %画图
  46.  
     
  47.  
    for i=1:15960
  48.  
     
  49.  
        if merge(i)>32768
  50.  
     
  51.  
            merge(i)=merge(i)-65536;  %将
  52.  
     
  53.  
        else
  54.  
     
  55.  
        i=i 1;
  56.  
     
  57.  
        end
  58.  
     
  59.  
    end
  60.  
     
  61.  
    plot(merge)
  62.  
     
  63.  
     
  64.  
     
  65.  
    %对画出的图像做FFT观察频谱
  66.  
     
  67.  
    ff=20*log10(abs(fft(merge(1:15960))));
  68.  
     
  69.  
    2=abs(fft(merge(1:15960)));
  70.  
     
  71.  
     
  72.  
     
  73.  
    plot(ff)
  74.  
     
  75.  
    %plot(ff2)
学新通

其中,读取波形数值部分可以用MATLAB自带的导入工具:

学新通

绘图结果如下图所示:

学新通

 学新通

N个采样点经过FFT变换后得到N个点的以复数形式记录的FFT结果。

假设采样频率为Fs,采样点数为N。那么FFT运算的结果就是N个复数(或N个点),每一个复数就对应着一个频率值以及该频率信号的幅值和相位。

第一个点对应的频率为0Hz(即直流分量),最后一个点N的下一个点对应采样频率Fs。其中任意一个采样点n所代表的信号频率:Fn=(n-1)*Fs/N。

对实验数据进行验证,理论上输出频率为fout=3.9062MHz,根据图可观察后计算,真实输出频率fout=10^6*63/16000=3.9375MHz,考虑到绘图误差,数据在可控范围内,整体实验成功。

这篇好文章是转载于:学新通技术网

  • 版权申明: 本站部分内容来自互联网,仅供学习及演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,请提供相关证据及您的身份证明,我们将在收到邮件后48小时内删除。
  • 本站站名: 学新通技术网
  • 本文地址: /boutique/detail/tanhgfaiba
系列文章
更多 icon
同类精品
更多 icon
继续加载