(DDS)正弦波形发生器——幅值、频率、相位可调(二)

博客 分享
0 265
张三
张三 2022-02-10 18:55:11
悬赏:0 积分 收藏

(DDS)正弦波形发生器——幅值、频率、相位可调(二)

* 设计一个幅值、频率、相位均可调的正弦波发生器。 * 频率每次增加10kHz * 相位每次增加 PI/2 * 幅值每次增加两倍 * ROM的深度为1024、宽度为8

(DDS)正弦波形发生器——幅值、频率、相位可调(二)

主要关于调相方面

一、项目任务:

  • 设计一个幅值、频率、相位均可调的正弦波发生器。
    • 频率每次增加10kHz
    • 相位每次增加 PI/2
    • 幅值每次增加两倍
    • ROM的深度为1024、宽度为8

二、文章内容:

  1. 完成调相模块并验证功能
  2. 完成调幅模块
  3. 按结构图来连接各个模块并仿真验证

1、调相

  • 从图像上来理解调整相位就是原函数在X轴上进行水平移动。

  • 在本项目中函数的波形图按照顺序存在ROM中,我们只要按照比例调整读取ROM的地址,即可调相。

  • 前文中我们使用32位寄存器的高8位用做ROM的地址,因此只要有按键按下,我们按照相位同比例的调整读取ROM的地址即可。

  • ROM的深度为1024、宽度为8储存标准正弦函数,那么可知其式为:

    \[% MathType!MTEF!2!1!+-% feaahqart1ev3aaatCvAUfeBSjuyZL2yd9gzLbvyNv2CaerbuLwBLn% hiov2DGi1BTfMBaeXatLxBI9gBaerbd9wDYLwzYbItLDharqqtubsr% 4rNCHbWexLMBbXgBd9gzLbvyNv2CaeHbl7mZLdGeaGqiVu0Je9sqqr% pepC0xbbL8F4rqqrFfpeea0xe9Lq-Jc9vqaqpepm0xbba9pwe9Q8fs% 0-yqaqpepae9pg0FirpepeKkFr0xfr-xfr-xb9adbaqaaeGaciGaai% aabeqaamaabaabauaakeaacaqGMbGaaiikaiaadIhacaGGPaGaeyyp% a0JaaGymaiaaikdacaaI4aGaci4CaiaacMgacaGGUbGaaiikamaala% aabaGaamiEaaqaaiaaiwdacaaIXaGaaGOmaaaacqaHapaCcaGGPaaa% aa!4ECD!{\rm{f}}(x) = 128\sin (\frac{x}{{512}}\pi )+128\]

    这里x对应的是ROM地址、y对应的是ROM中数据也即幅值。范围取x从0到1023、y从0到255。

  • 若按键一次,相位增加PI/2,则有:

    \[% MathType!MTEF!2!1!+-% feaahqart1ev3aaatCvAUfeBSjuyZL2yd9gzLbvyNv2CaerbuLwBLn% hiov2DGi1BTfMBaeXatLxBI9gBaerbd9wDYLwzYbItLDharqqtubsr% 4rNCHbWexLMBbXgBd9gzLbvyNv2CaeHbl7mZLdGeaGqiVu0Je9sqqr% pepC0xbbL8F4rqqrFfpeea0xe9Lq-Jc9vqaqpepm0xbba9pwe9Q8fs% 0-yqaqpepae9pg0FirpepeKkFr0xfr-xfr-xb9adbaqaaeGaciGaai% aabeqaamaabaabauaakqaabeqaaiaadEgacaGGOaGaamiEaiaacMca% cqGH9aqpcaaIXaGaaGOmaiaaiIdaciGGZbGaaiyAaiaac6gacaGGOa% WaaSaaaeaacaWG4baabaGaaGynaiaaigdacaaIYaaaaiabec8aWjab% gUcaRmaalaaabaGaeqiWdahabaGaaGOmaaaacaGGPaGaey4kaSIaaG% ymaiaaikdacaaI4aaabaGaaGjbVlaaysW7caaMe8UaaGjbVlaaysW7% caaMe8UaaGjbVlaaysW7caaMe8Uaeyypa0JaaGymaiaaikdacaaI4a% Gaci4CaiaacMgacaGGUbGaaiikaiaacIcadaWcaaqaaiaadIhaaeaa% caaI1aGaaGymaiaaikdaaaGaey4kaSYaaSaaaeaacaaIXaaabaGaaG% OmaaaacaGGPaGaeqiWdaNaaiykaiabgUcaRiaaigdacaaIYaGaaGio% aaqaaiaaysW7caaMe8UaaGjbVlaaysW7caaMe8UaaGjbVlaaysW7ca% aMe8UaaGjbVlabg2da9iaaigdacaaIYaGaaGioaiGacohacaGGPbGa% aiOBaiaacIcacaGGOaWaaSaaaeaacaWG4bGaey4kaSIaaGOmaiaaiw% dacaaI2aaabaGaaGynaiaaigdacaaIYaaaaiaacMcacqaHapaCcaGG% PaGaey4kaSIaaGymaiaaikdacaaI4aaaaaa!9896!\begin{array}{l}g(x) = 128\sin (\frac{x}{{512}}\pi + \frac{\pi }{2}) + 128\\\;\;\;\;\;\;\;\;\; = 128\sin ((\frac{x}{{512}} + \frac{1}{2})\pi ) + 128\\\;\;\;\;\;\;\;\;\; = 128\sin ((\frac{{x + 256}}{{512}})\pi ) + 128\end{array}\]

  • 其中绿色为f(x),紫色为调整相位后的g(x)。

  • 即每次按下按键后相当于将图像向左平移256,那么也就是按下按键后,提前读取256个地址之后的数据。

  • module phase_ctrl(    input  clk,    input  rst_n,    input  f_phase,    output  [9:0] initiala_address);assign initiala_address = 10'd256;endmodulemodule addr_ctrl(    input  clk,    input  rst_n,    input  [31:0] freq_num,    input  [9:0] initiala_address,    input  f_phase,    output [9:0] address);reg [31:0] cnt;always @(posedge clk,negedge rst_n)begin    if(rst_n == 0)        cnt <= 32'd0;    else         if(f_phase == 1)            cnt[31:22] <= cnt[31:22] + initiala_address;        else            cnt <= cnt + freq_num;end assign address = cnt[31:22];endmodule
  • 验证:选取三个变频前后的点将其与理论计算的值进行对比

    重点关注在f_phase拉高前后,正弦波上3个点(address,data)的大小

    • (43,161) (43+256,251)=(299,251)

    • (754,0) (754+256)=(1010,117)

    • (856,18) (856+256-1024,193)=(88,193)

  • 理论计算:

    • (43,161)(43,251) (754,0)(754,117) (856,18) (856,193)

    • 可以看到调相模块准确的完成了每次按键按下,相移PI/2的任务。

2、调幅

  • 这一部分在代码方面比较简单,实际验证还需要数模转换和示波器的配合,限于条件无法达到,因此只展仿真结果。

  • 在程序上要注意位宽的变化,由于不断的放大,因此将输出data设计为32位。

  • 每次按键按下。幅值放大两倍。

  • module amplitude_ctrl(    input  clk,    input  rst_n,    input  f_ampli,    input  [7:0] data_in,    output [31:0] data);reg [23:0] ampli_num;always @(posedge clk,negedge rst_n)begin    if(rst_n == 0)        ampli_num <= 24'd1;    else        if(f_ampli == 1)            ampli_num <= ampli_num * 24'd2;        else             ampli_num <= ampli_num;end assign data = ampli_num * data_in;endmodule

3、模块连接及总体功能验证

  • 系统结构图为:

  • ModelSim仿真:

    • 频率变化:

    • 相位变化:

    • 幅值变化:

  • 测试代码:

    `timescale 1ns/1nsmodule key_dds_tb();    reg  clk;    reg  rst_n;    reg  key_freq;    reg  key_phase;    reg  key_ampli;    wire [31:0] data; key_dds key_dds_inst(    .clk      (clk),    .rst_n    (rst_n),    .key_freq (key_freq),    .key_phase(key_phase),    .key_ampli(key_ampli),    .data     (data));initial clk = 1;always #10 clk = !clk;initialbegin    rst_n = 0;    key_freq   = 1;    key_phase  = 1;    key_ampli  = 1;    #200    rst_n = 1;    #200        key_freq = 1;    #10000000    key_freq = 0;    #2000    key_freq = 1;    #10000000    key_freq = 0;    #1000000    key_freq = 1;    #10000000    key_phase = 1;    #2000000    key_phase = 0;    #70000    key_phase = 1;    #11500    key_phase = 0;    #70000    key_phase = 1;    #25000    key_phase = 0;    #23333    key_phase = 1;    #1000000    key_ampli = 1;    #10000000    key_ampli = 0;    #2000    key_ampli = 1;    #1000000    #10000    $stop;    endendmodule

备注:

  • 之后有时间我想试着在屏幕上输出DDS产生的波形,看看效果。
  • mif文件
  • 按键部分的功能是进行消陡然后输出一个同系统时钟的标志信号flag。

作者:13tree

出处:https://www.cnblogs.com/13tree/

本文版权归作者所有,如需转载请保留此段声明。

posted @ 2022-02-10 17:59 13tree 阅读(12) 评论(0) 编辑 收藏 举报
回帖
    张三

    张三 (王者 段位)

    821 积分 (2)粉丝 (41)源码

     

    温馨提示

    亦奇源码

    最新会员