DDS信号发生器设计

一、基本概述

1.1 DDS简介

DDS信号发生器即直接数字频率合成(Direct Digital Frequency Synthesis,简称DDS)是一种利用数字技术生成信号的方法。它通过数字信号处理技术,将数字信号转换为模拟信号,从而生成高质量的正弦波、方波、三角波等信号。

1.2 DDS工作原理

1.2.1 核心组成部分

DDS系统主要由以下几个模块构成:

  • 相位累加器(Phase Accumulator)

  • 波形查找表(Waveform Look-Up Table, LUT)

  • 数模转换器(DAC)

  • 低通滤波器(LPF)

1.2.2 工作流程

(1)相位累加

相位累加器是DDS信号发生器的核心部分,用于生成相位信息。它由一个累加器和一个频率控制字(Frequency Control Word, FCW)组成。每次时钟周期,频率控制字会被加到累加器中,累加器的输出即为当前的相位值。

  • 输入:频率控制字(Frequency Tuning Word, FTW),由用户设定。

  • 作用:相位累加器在时钟信号(fclkfclk​)的驱动下,对FTW进行累加,生成线性递增的相位值(地址)。

  • 公式

     

    其中,NN 为相位累加器的位数(通常24~32位),决定频率分辨率。

(2)波形查找

查找表(Lookup Table, LUT)存储了正弦波或其他波形的幅度值。相位累加器的输出作为查找表的地址,查找表根据该地址输出对应的幅度值。查找表通常存储的是一个完整周期的波形数据。波形选择模块用于选择不同的波形,如正弦波、方波、三角波等。通过改变查找表的内容或逻辑控制,可以生成不同的波形。

  • 波形存储器(LUT):预存目标波形(如正弦波、方波)的离散采样值。

  • 寻址:相位累加器的输出作为地址,从LUT中读取对应的波形幅值数据。

  • 分辨率:LUT的深度和位宽影响波形精度。

(3)数模转换(DAC)

DAC将数字幅度值转换为模拟信号。DAC的分辨率(如8位、12位、16位)决定了输出信号的精度和质量。

  • 将查找表输出的数字幅值转换为模拟电压信号。

  • DAC的转换速度和位数直接影响输出信号的质量(如信噪比、谐波失真)。

(4)低通滤波

  • 滤除DAC输出的高频量化噪声和时钟馈通信号。

  • 截止频率通常略高于所需信号的最大频率。

1.2.3 输出频率计算

DDS的输出频率由以下公式决定:

  • fclkfclk​:系统时钟频率(如100 MHz)。

  • NN:相位累加器位数(如32位)。

  • FTW:频率控制字,由用户编程设置。

比如: 若 fclk=100 MHzfclk​=100MHz,N=32N=32,要输出 1 MHz1MHz 正弦波:

 1.3 常见的RAM、ROM、FIFO等IP核的参数设置和调用过程

IP软核是预先设计好的、可重复使用的数字电路模块,用于简化复杂系统的设计。它们通常以Verilog HDL或VHDL等硬件描述语言编写,可以在FPGA或ASIC中实现。

1.3.1 RAM IP核的参数设置和调用过程

RAM 是随机存取存储器(Random Access Memory)的简称,是一个易失性存储器。 RAM 工作时可以随时从任何一个指定的地址写入或读出数据,同时我们还能修改其存储的数据,即写入新的数据,这是 ROM 所并不具备的功能。在 FPGA 中这也是其与 ROM 的最大区别。ROM 是只读存储器,而 RAM 是可写可读存储器,在我们 FPGA 中使用这两个存储器主要也是要区分这一点,因为这两个存储器使用的都是我们 FPGA 内部的 RAM 资源,不同的是 ROM 是只用到了 RAM 资源的读数据端口。

 单端口RAM参数:

  • 数据宽度(Data Width):8/16/32/64位等

  • 存储深度(Depth):根据需求设置(如1024, 2048等)

  • 操作模式:通常为"Write First"、"Read First"或"No Change"

  • 初始化文件:可加载.mif或.hex文件初始化RAM内容

  • 寄存器选项:输出是否寄存(增加一个时钟周期延迟但提高时序性能)

双端口RAM参数:

  • 除单端口参数外还需设置:

    • 端口A和端口B的操作模式

    • 是否允许同时读写

    • 冲突解决策略

1.3.2 ROM IP核的参数设置和调用过程

ROM 是只读存储器(Read-Only Memory)的简称,是一种只能读出事先所存数据的固态半导体存储器。其特性是一旦储存资料就无法再将之改变或删除,且资料不会因为电源关闭而消失。而事 实上在 FPGA 中通过 IP 核生成的 ROM 或 RAM(RAM 将在下一节为大家讲解)调用的都是FPGA 内部的 RAM 资源,掉电内容都会丢失(这也很容易解释,FPGA 芯片内部本来就没有掉电非易失存储器单元)。用 IP 核生成的 ROM 模块只是提前添加了数据文件(.coe 格式)(.mf/.nex格式),在 FPGA 运行时通过数据文件给 ROM 模块初始化,才使得 ROM 模块像个“真正”的掉电非易失存储器;也正是这个原因,ROM 模块的内容必须提前在数据文件中写死,无法在电路中修改。

常见参数设置

  • 数据宽度:同RAM

  • 存储深度:同RAM

  • 初始化文件:必须提供.mif或.hex文件

  • 输出寄存器:可选是否寄存输出

1.3.3 FIFO IP核的参数设置和调用过程

   FIFO(First In First Out,即先入先出),是一种数据缓冲器,用来实现数据先入先出的读写方式。与 ROM 或 RAM 的按地址读写方式不同,FIFO 的读写遵循“先进先出”的原则,即数据按顺序写入 FIFO,先被写入的数据同样在读取的时候先被读出,所以 FIFO存储器没有地址线。FIFO 有一个写端口和一个读端口外部无需使用者控制地址,使用方便。

        FIFO 存储器主要是作为缓存,应用在同步时钟系统和异步时钟系统中,在很多的设计中都会使用,后面实例中如:多比特数据做跨时钟域的转换、前后带宽不同步等都用到了FIFO。FIFO 根据读写时钟是否相同,分为 SCFIFO(同步 FIFO)和 DCFIFO(异步FIFO),SCFIFO 的读写为同一时钟,应用在同步时钟系统中;DCFIFO 的读写时钟不同,应用在异步时钟系统中。

数据的产生模块与数据使用模块不对应时就会使用到FIFO,如两者的时钟频率不同无法在同一时钟下进行传输(多比特数据做跨时钟域的转换) ;两者的数据带宽不同下传输(前后带宽不同步)。

基本参数:

  • FIFO实现方式:基于Block RAM或Distributed RAM

  • 数据宽度:8/16/32/64位等

  • FIFO深度:16/32/64/128/256等

  • 满/空标志:设置几乎满/几乎空的阈值

高级参数:

  • 读写时钟域:同步或异步FIFO

  • 握手信号:可选是否添加数据有效信号

  • 复位类型:同步或异步复位

二、波形仿真器的设计与制作

2.1 内容与要求

采用数字频率合成(Direct Digital FrequencySynthesis,简称DDS)设计制作一个波形发生器,仿真后,在DE2-115开发板上实践。要求:
1)利用DDS技术合成正弦波和方波;
2)输出信号的频率范围为10Hz~5MHz,最小频率分辨率小于1kHz;
3)使用嵌入式逻辑分析仪SignalTap II实时测试输出波形的离散数据。

2.2 具体步骤

(1)在Quartus中创建新工程,步骤在之前的博客中有具体说明

2.2.1 相位累加器

(2)编写代码

module addr_cnt(CPi,K,ROMaddr,Address);input CPi;input [12:0] K;output reg [9:0] ROMaddr;output reg [16:0] Address;always @(posedge CPi) beginAddress=Address+K;ROMaddr=Address[16:7];end
endmodule

(3)将 addr_cnt 设置为顶层文件

将Project Navigator 设置为 Files ,之后右键addr_cnt.v ,选中 Set as Top-Level Entity

 

打开生成的.bsf文件如下图所示:

生成并打开.bsf文件

右键addr_cnt.v,在弹出的选项中选择 Create Symbol Files for Current File,之后生成的 .bsf 文件会保存在工程目录下,找到对应的文件打开即可

2.2.2 波形存储器ROM

方波模块

代码如下:

module squwave(CPi,RSTn,Address,Qsquare);input CPi;input RSTn;input [16:0] Address;output reg [11:0] Qsquare;always @(posedge CPi)if (!RSTn)Qsquare=12'h000; else beginif(Address<=17'h0FFFF)Qsquare=12'hFFF;else Qsquare=12'h000;end
endmodule

将该模块设置为顶层文件,并编译生成 .bsf 如下图:

正弦波形存储器

首先编译一个C程序( Dev C++ 或者别的编译器都行),编译之前建议先在对应的Quartus工程目录下新建一个文件夹,将C程序保存在该文件夹内

/*myMIF.c*/
#include <stdio.h>
#include <math.h>
#define PI 3.141592
#define DEPTH 1024
#define WIDTH 12
int main(void)
{int n,temp;float v;FILE *fp;fp=fopen("Sine1024.mif","w+");if(NULL==fp)printf("Can not creat file!\r\n");else{printf("File created successfully!\n");fprintf(fp,"DEPTH=%d;\n",DEPTH);fprintf(fp,"WIDTH=%d;\n",WIDTH);fprintf(fp,"ADDRESS_RADIX=HEX;\n");fprintf(fp,"DATA_RADIX=HEX;\n");fprintf(fp,"CONTENT\n");fprintf(fp,"BEGIN\n");for(n=0;n<DEPTH;n++){v=sin(2*PI*n/DEPTH);temp=(int)((v+1)*4095/2);fprintf(fp,"%04x : %03x;\n",n,temp);}fprintf(fp,"END;\n");fclose(fp);}} 

 编译运行以上代码,会生成 myMIF.exe文件以及Sine 1024.mif 文件,如下图:

使用Quartus调用LPM_ROM定制正弦波形存储器:点击Tools--->IP Catalog,并在IP Catalog搜索框搜索 ROM ,双击 找到 ROM 1-PORT并双击

在弹出的弹框里面修改命名,如下图所示:

点击OK,会弹出如下界面:

修改以下参数:

取消 ‘q’output port的勾选

点击 Browse..,并选中之前生成好的 Sine1024.mif

之后一直Next,直到 Finish,ROM配置完成

锁相环倍频电路

在IP Catalog 搜索栏中搜索 ALTPLL,选中 ALTPLL 并双击

修改如图所示的参数 

之后一直 Next 默认选项,直到出现以下界面,修改Clock multi...的参数

之后也是一直默认选项,直到 Finish

2.2.3 顶层电路设计

代码如下:

module DDS_top (CLOCK_50,RSTn,WaveSel,K,
WaveValue,LEDG,CLOCK_100);input CLOCK_50;input RSTn;input [1:0] WaveSel;input [12:0] K;output reg [11:0] WaveValue;wire [9:0] ROMaddr/* synthesis keep */;wire [16:0] Address;wire [11:0] Qsine,Qsquare;output [0:0] LEDG;output CLOCK_100;wire CPi=CLOCK_100;myALTPLL PLL100M_CP_inst(.inclk0(CLOCK_50),.c0(CLOCK_100),.locked(LEDG[0]));addr_cnt U0_instance(CPi,K,ROMaddr,Address);myROM ROM_inst(.address(ROMaddr),.clock(CPi),.q(Qsine));squwave U1(CPi,RSTn,Address,Qsquare);always @(posedge CPi)begincase(WaveSel)2'b01:WaveValue=Qsine;2'b10:WaveValue=Qsquare;default:WaveValue=Qsine;endcaseend
endmodule

跟之前一样,将该模块设置为顶层文件并进行编译

三、DE2-115设计实现

配置引脚

可以直接导入DE2_115_pin_assignments.csv文件进行配置,也可以手动进行配置

module DE2_115_DDS_top(CLOCK_50,KEY,SW,GPIO_0,LEDG);input CLOCK_50;input [3:3] KEY;input [17:0] SW;output [12:0] GPIO_0;output [0:0] LEDG;wire CLOCK_100;assign GPIO_0[12]=CLOCK_100;wire RSTn=KEY[3];wire [1:0] WaveSel=SW[17:16];wire [12:0] K=SW[12:0];wire [11:0] WaveValue;assign GPIO_0[11:0]=WaveValue;DDS_top DE2(CLOCK_50,RSTn,WaveSel,K,WaveValue,LEDG,CLOCK_100);
endmodule

引脚配置完成要再次编译运行

接下来就可以使用SignalTap ll实时测试输出波形的离散数据,选择Tools-->SignalTap ll Logic Analyzer

右键 Setup 上方空白处,点击 Add Node... 进行添加

全部确认无误后,保存文件并编译(要连接开发板)

波形图如下:

四、总结

通过这次DDS信号发生器的设计和实现,学习了数字信号处理的强大能力和FPGA设计的灵活性。从理论学习到实际操作,我不仅了解到了DDS技术的基本原理和实现方法,还学会了如何在Quartus软件中进行模块化设计和引脚配置。这次实践让我认识到了细节的重要性,每一个小的配置错误都可能导致整个系统无法正常工作。

参考博客:

20【FPGA】FPGA开发中常用的IP核——PLL/ROM/RAM/FIFO_fpga ip核-CSDN博客

【DE2-115】Verilog实现DDS+Quartus仿真波形-CSDN博客

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/web/76033.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

生成式AI:如何用大模型呼叫系统提升销售转化率?

生成式AI技术正以惊人的速度重塑商业版图。从智能助手到自动化营销&#xff0c;从数据分析到客户洞察&#xff0c;生成式AI正在颠覆传统商业模式&#xff0c;云蝠智能以大模型、智能体为核心技术,致力于为百万企业提供语音互动智能体平台与解决方案&#xff0c;为企业在销售转化…

OOP丨《Java编程思想》阅读笔记Chapter 6 : 访问权限控制

《Java编程思想》Chapter 6 : 访问权限控制 1. 前言 1.1. 访问权限控制的等级1.2. package关键字的引入 2. 包&#xff1a;库单元 2.1. 代码组织2.2. 包名的创建 3. Java访问权限修饰词 3.1. 包访问权限3.2. public: 接口访问权限3.3. private: 你无法访问3.4. protected: 继承…

reconic 天空 模型

目录 推理代码&#xff1a; EnvLight 代码&#xff1a; 推理代码&#xff1a; sky_model self.models["Sky"]outputs["rgb_sky"] sky_model(image_info)outputs["rgb_sky_blend"] outputs["rgb_sky"] * (1.0 - outputs["opa…

从服务器多线程批量下载文件到本地

1、客户端安装 aria2 下载地址&#xff1a;aria2 解压文件&#xff0c;然后将文件目录添加到系统环境变量Path中&#xff0c;然后打开cmd&#xff0c;输入&#xff1a;aria2c 文件地址&#xff0c;就可以下载文件了 2、服务端配置nginx文件服务器 server {listen 8080…

C++ | 可变模板参数

1. 为什么需要可变模板参数&#xff1f; 在C11之前&#xff0c;若想实现一个接受任意数量参数的函数&#xff0c;只能依赖va_list等C风格可变参数&#xff0c;但这种方式类型不安全且难以调试。例如printf函数&#xff1a; printf("%d %f %s", 10, 3.14, "hel…

【机器学习】每日一讲-朴素贝叶斯公式

文章目录 **一、朴素贝叶斯公式详解****1. 贝叶斯定理基础****2. 从贝叶斯定理到分类任务****3. 特征独立性假设****4. 条件概率的估计** **二、在AI领域的作用****1. 文本分类与自然语言处理&#xff08;NLP&#xff09;****2. 推荐系统****3. 医疗与生物信息学****4. 实时监控…

AI Agents系列之AI代理的类型

在本文中,我们将探讨不同类型的 AI 代理,包括它们的实现、实际应用、优势和局限性。从简单反射代理到多代理系统,我们将了解这些模型如何推动自动化、决策制定和智能问题解决。 文章目录 1. AI代理的类型1.1 简单反射代理1.1.1 实现**1.1.2 优势****1.1.3 局限性**1.2 基于…

C# --- IEnumerable 和 IEnumerator

C# --- IEnumerable 和 IEnumerator IEnumerableIEnumeratorIEnumerable 和 IEnumerator 的作用手动实现 IEnumerableIEnumerable vs. IQueryable为什么有了ienumerator还需要ienumerable IEnumerable 在C#中&#xff0c;IEnumerable 是一个核心接口&#xff0c;用于表示一个可…

镜舟科技助力某大型电网企业破解数据架构升级难题,打造国产化湖仓标杆

在 “十四五” 规划全面推进国产化替代的背景下&#xff0c;某大型电网企业联合镜舟科技与腾讯云&#xff0c;基于全球领先的开源分析型数据库 StarRocks 及腾讯 TBDS 大数据平台&#xff0c;构建电力行业国产化湖仓一体架构。该项目实现 PB 级电力数据的统一管理&#xff0c;为…

Spark-SQL核心编程3

数据加载与保存 通用方式&#xff1a; SparkSQL 提供了通用的保存数据和数据加载的方式。这里的通用指的是使用相同的API&#xff0c;根据不同的参数读取和保存不同格式的数据&#xff0c;SparkSQL 默认读取和保存的文件格式为parquet 数据加载方法&#xff1a; spark.read.lo…

使用HTML + CSS + JS,编写一个台球追分计分器

目录 一.代码 二.效果展示 三.该计分器的优点 一.代码 <!DOCTYPE html> <html lang"zh-CN"><head><meta charset"UTF-8"><meta name"viewport" content"widthdevice-width, initial-scale1.0"><…

LLM小白自学笔记:1.两种指令微调

一、LoRA 简单来说&#xff0c;LoRA不直接调整个大模型的全部参数&#xff08;那样太费资源&#xff09;&#xff0c;而是在模型的某些层&#xff08;通常是注意力层&#xff09;加个“旁路”——两个小的矩阵&#xff08;低秩矩阵&#xff09;。训练时只更新这俩小矩阵&#x…

2026《数据结构》考研复习笔记一(C++基础知识)

C基础知识复习 一、数据类型二、修饰符和运算符三、Lambda函数和表达式四、数学函数五、字符串六、结构体 一、数据类型 1.1基本类型 基本类型 描述 字节&#xff08;位数&#xff09; 范围 char 字符类型&#xff0c;存储ASCLL字符 1&#xff08;8位&#xff09; -128…

基于骨骼识别的危险动作报警分析系统

基于骨骼识别的危险动作报警分析系统 【包含内容】 【一】项目提供完整源代码及详细注释 【二】系统设计思路与实现说明 【三】基于骨骼识别算法的实时危险行为预警方案 【技术栈】 ①&#xff1a;系统环境&#xff1a;Windows 10/11、macOS Ventura、Ubuntu 20.04 ②&#x…

【双指针】四数之和(medium)

四数之和&#xff08;medium&#xff09; 题⽬描述&#xff1a;解法&#xff08;排序 双指针&#xff09;算法思路&#xff1a; C 算法代码&#xff1a;Java 算法代码&#xff1a; 题⽬链接&#xff1a;18. 四数之和 题⽬描述&#xff1a; 给你⼀个由 n 个整数组成的数组 num…

Flask+Influxdb+grafna构建电脑性能实时监控系统

Influx下载地址&#xff0c;这里下载了以下版本influxdb-1.8.5_windows_amd64.zip 运行前需要先启动Influx数据库&#xff1a; 管理员方式运行cmd->F:->cd F:\influxdb\influxdb-1.8.5-1->influxd -config influxdb.conf&#xff0c;以influxdb.conf配置文件启动数…

如何在Keil中配置国民技术N32G系列MCU开发环境

如何在Keil及Jlink中搭建国民技术N32G系列MCU开发环境 根据自己的MCU型号&#xff08;我这里的型号是N32G452REL7&#xff09;访问国民技术官网&#xff0c;依次从N32G通用MCU-技术资源-固件和软件-软件开发套件&#xff0c;获取对应MCU型号的SDK&#xff0c;也可点击这里从网盘…

微软承认Win11出现极端错误,只能强制关机或重装系统

最近&#xff0c;不少使用 Windows 11 的用户反映&#xff0c;在系统更新后&#xff0c;“Windows Hello”突然失效&#xff0c;原本便捷的人脸识别和PIN登录功能统统无法使用。更糟的是&#xff0c;有人在重置系统后直接被挡在系统门外&#xff0c;这让人不禁发问&#xff1a;…

【android bluetooth 协议分析 02】【bluetooth hal 层详解 1】【uart 介绍】

一、什么是 UART&#xff1f; UART&#xff08;Universal Asynchronous Receiver/Transmitter&#xff09; 是一种 串行通信协议&#xff0c;它的特点是通信时不需要专门的时钟信号&#xff08;叫做“异步”通信&#xff09;&#xff0c;常用于两个设备之间的简单数据通信&…

天元证券|奶粉行业结构性回暖 乳企竞速全龄化、国际化

在过去几年中&#xff0c;中国婴配粉市场经历了量价齐增&#xff0c;量减价增&#xff0c;量减价减的三个周期。历经多年行业深度洗牌与竞争格局重塑&#xff0c;2024年中国婴配粉市场回暖态势愈发清晰可辨。 日前&#xff0c;包括中国飞鹤、澳优、健合集团在内的多家奶粉股披露…