(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;
    endmodule module 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/1ns
    module 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; initial
    begin
    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;
    end endmodule

备注:

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

作者:13tree

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

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

(DDS)正弦波形发生器——幅值、频率、相位可调(二)的更多相关文章

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

    (DDS)正弦波形发生器--幅值.频率.相位可调 一.项目任务: 设计一个幅值.频率.相位均可调的正弦波发生器. 频率每次增加1kHz. 相位每次增加 2*PI/256 幅值每次增加两倍 二.文章内容 ...

  2. 基于FPGA的DDS任意波形发生器设计

    一.简介       DDS技术最初是作为频率合成技术提出的,由于其易于控制,相位连续,输出频率稳定度高,分辨率高, 频率转换速度快等优点,现在被广泛应用于任意波形发生器(AWG).基于DDS技术的任 ...

  3. 基于DDS的任意波形发生器

    实验原理 DDS的原理 DDS(Direct Digital Frequency Synthesizer)直接数字频率合成器,也可叫DDFS. DDS是从相位的概念直接合成所需波形的一种频率合成技术. ...

  4. FFT之频率与幅值的确定(转)

    FFT之后得到的是什么数 FFT之后得到的那一串复数是波形对应频率下的幅度特征,注意这个是幅度特征不是复制,下面要讲两个问题:1.如何获取频率,2.如何获取幅值 获取频率 FFT变换如何获取频率?傅里 ...

  5. STM32 基DMA的DAC波形发生器

    DAC是STM32系列的一个基本外设,可以将数字信号转化成模拟信号,这次我将使用DAC来输出一个特定波形. 首先确定工作方法,由于我目前在做的简易示波器在输出波形的同时还需要显示输入信号,所以不能占用 ...

  6. 在Modelsim波形中查看值

    在Modelsim的波形中查看值时,可以利用右键选择变量的数据类型.如果变量值为0,可以选择unsigned类型观察,可以1位显示0. 长度较大的数据以十六进制显示时,即使值为0,也依然显示为长度较长 ...

  7. JAVA之旅(三)——数组,堆栈内存结构,静态初始化,遍历,最值,选择/冒泡排序,二维数组,面向对象思想

    JAVA之旅(三)--数组,堆栈内存结构,静态初始化,遍历,最值,选择/冒泡排序,二维数组,面向对象思想 我们继续JAVA之旅 一.数组 1.概念 数组就是同一种类型数据的集合,就是一个容器 数组的好 ...

  8. Matlab绘制幅值谱和相位谱

    1. 对于直接给出频响函数的情况 这里以滑动平均的频响函数作为例子,滑动窗口为[0, 4]. 上式中M2=4. >> w=0:0.001:2*pi; >> h1=1-exp(- ...

  9. numpy 傅立叶得到幅值和频率

    做个备份,对 numpy 不熟,每次都找函数找半天. 代码里分几块: 1. 从 argc[1] 的文档中读取数据,并转化为 float.文档中有 2001 行,第一行为头,后面 2000 个是采样数据 ...

随机推荐

  1. JPEG原理详解 (转载)

    JPEG算法解密 by jinchao   图片压缩有多重要,可能很多人可能并没有一个直观上的认识,举个例子,一张800X800大小的普通图片,如果未经压缩,大概在1.7MB左右,这个体积如果存放文本 ...

  2. freeswitch APR-UTIL库线程池实现分析

    概述 freeswitch的核心源代码是基于apr库开发的,在不同的系统上有很好的移植性. APR库在之前的文章中已经介绍过了,APR-UTIL库是和APR并列的工具库,它们都是由APACHE开源出来 ...

  3. CS5265 demoboard|CS5265测试板电路参考|CS5265 Typec转HDMI 4K60HZ方案

    CS5265是TYPEC转HDMI2.0音视频转换芯片,CS5265符合DP1.4协议,且输出的视频信号是HDMI2.0 即4K60HZ  CS5265集成了DP1.4兼容接收机和HDMI2.0b兼容 ...

  4. Java初学者作业——定义一个计算器类, 实现计算器类中加、 减、 乘、 除的运算方法, 每个方法能够接收2个参数。

    返回本章节 返回作业目录 需求说明: 定义一个计算器类, 实现计算器类中加. 减. 乘. 除的运算方法, 每个方法能够接收2个参数. 实现思路: 定义计算器类. 定义计算器类中加.减.乘.除的方法. ...

  5. Gradle sync failed (3 s 402 ms) - Android Studio问题解决方法

    问题:Gradle同步失败 解决方法: 删除gradle-wrpper.jar中的 implementation 'com.android.support:design:30.+' 最后在Build中 ...

  6. Spring Boot 整合 Fisco Bcos(区块链)

    简介 FISCO BCOS是由国内企业主导研发.对外开源.安全可控的企业级金融联盟链底层平台,由金链盟开源工作组协作打造,并于2017年正式对外开源. 目前,成熟的区块链的平台不少,之所以选择FISC ...

  7. mysql 5.7.29 在centos7.6下超简单的本地yum源安装与配置

    目录 生成yum源元数据 从网易镜像站下载MySQL 5.7 的 bundle包 创建文件 mysql-local.repo 执行yum install命令 生成yum源元数据 createrepo ...

  8. nuxt服务端渲染

    <template> <div class="page"> page is search <ul> <li v-for="(it ...

  9. Linux上天之路(十四)之Linux数据处理

    主要内容 数据检索 数据排序 数据去重 重定向 1. 数据检索 常和管道协作的命令 – grep grep:用于搜索模式参数指定的内容,并将匹配的行输出到屏幕或者重定向文件中,常和管道协作的命令 – ...

  10. HDU 2099 整除的尾数(枚举 & 暴搜)

    原题链接:http://acm.hdu.edu.cn/showproblem.php?pid=2099 思路分析:这道题的解法可以说是相当暴力了,但也有一些小坑,以下几点萌新们值得留意一下: 1. 仔 ...