【FPGA学习】DDS信号发生器设计

目录

一、设计原理与准备​

1.1 DDS 原理​

1.2 IP 核学习与准备​:FPGA开发中常用IP核——ROM/RAM/FIFO

2、ROM文件的设置

1.3 开发环境搭建​

二、DDS 信号发生器设计实现

2.1 系统架构设计​

2.2 代码编写与模块实现​

三、测试结果与总结​

参考文献:


引言:

在电子技术领域,信号发生器是不可或缺的工具。直接数字频率合成(Direct Digital Frequency Synthesis,DDS)技术凭借其频率转换速度快、分辨率高、相位连续性好等优势,成为信号生成的热门选择。本文将详细介绍基于 DDS 技术的信号发生器设计过程,实现正弦波和方波的合成,并满足特定频率范围与分辨率要求,同时利用嵌入式逻辑分析仪进行实时测试。

一、设计原理与准备​

1.1 DDS 原理​

DDS 的核心思想是通过数字计算和数模转换来生成模拟信号。其基本结构包括相位累加器、波形存储器(ROM)、数字模拟转换器(DAC)等。相位累加器在时钟信号的驱动下,不断进行累加操作,其输出作为波形存储器的地址,从波形存储器中读取预先存储的波形数据,再经过 DAC 转换为模拟信号输出。通过改变相位累加器的累加步长,就可以实现输出信号频率的调整。​

1.2 IP 核学习与准备​:FPGA开发中常用IP核——ROM/RAM/FIFO

常见的 FPGA 存储器有 3 种:RAM (随机访问内存)、ROM (只读存储器)、FIFO (先入先出)。这三种存储器的区别如下:

  • RAM:通常掉电后数据丢失,支持随机读写操作。根据特性可分为:

    • SRAM(静态随机存储器):速度快,无需刷新,但集成度低,常用于高速缓存
    • DRAM(动态随机存储器):需周期性刷新,集成度高,用于大容量存储
    • BRAM(块随机存储器):FPGA 内部专用存储块,低延迟、高带宽
  • ROM:系统断电后数据不丢失,数据写入需特定编程方式。在 FPGA 中常见类型:

    • MROM(掩膜只读存储器):数据由制造商写入,不可更改
    • PROM(可编程只读存储器):用户可一次性编程
    • EPROM(可擦除可编程只读存储器):通过紫外线擦除重写
    • EEPROM(电可擦可编程只读存储器):支持电信号擦除,常用于配置数据存储
  • FIFO:数据遵循先入先出原则,地址由内部指针自动管理。关键参数:

    • 满标志 (Full):指示 FIFO 已写满
    • 空标志 (Empty):指示 FIFO 已读空
    • 可编程满 / 空阈值:支持自定义触发条件
    • 同步 / 异步时钟域:分同步 FIFO(单时钟域)和异步 FIFO(跨时钟域)

应用场合对比

存储器类型典型应用场景关键优势FPGA 实现方式
RAM数据缓存、图像处理帧缓冲、高速数据暂存随机读写、高速访问BRAM、分布式 RAM
ROM波形表存储(如 DDS)、配置参数存储、查找表 (LUT)非易失性、数据稳定初始化 BRAM、专用 ROM IP 核
FIFO跨时钟域数据传输、数据流速率匹配、突发数据缓冲自动地址管理、同步隔离专用 FIFO IP 核

在 DDS 设计中:

  • ROM:用于存储预计算的正弦 / 方波波形数据,需配置为同步读模式
  • FIFO:可用于缓存 DAC 输出数据,解决时钟域不匹配问题
  • RAM:可扩展用于存储多组波形参数,支持动态切换波形类型

在调用 IP 核时,需特别注意:

  1. 同步与异步模式:跨时钟域设计必须使用异步 FIFO
  2. 深度与宽度权衡:增加深度可提高缓冲能力,但会占用更多 BRAM 资源
  3. 复位策略:合理设置同步复位或异步复位,确保系统可靠启动
  4. 数据对齐:注意数据位宽匹配,避免数据截断或扩展带来的精度损失

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

最简单的使用有效时钟CLKA、有效地址ADDRA和有效使能EA,就可以输出DOUTA

单端口ROM:只提供一个独立的地址端口核一个读数据端口

2、ROM文件的设置

1.3 开发环境搭建​

本次设计基于 DE2-115 开发板,开发环境选用 Quartus Prime 等 FPGA 开发工具。在开始设计之前,确保开发环境已经正确安装和配置,熟悉开发工具的基本操作流程,包括工程创建、IP 核调用、代码编写、编译综合、下载调试等环节,为后续的设计实现奠定基础。

二、DDS 信号发生器设计实现

2.1 系统架构设计​

根据设计要求,DDS 信号发生器系统主要由相位累加器模块、波形存储器模块、频率控制字输入模块、波形转换模块(用于生成正弦波和方波)以及嵌入式逻辑分析仪模块组成。相位累加器模块根据输入的频率控制字,在时钟信号的驱动下进行相位累加;波形存储器模块存储正弦波和方波的数字化波形数据;频率控制字输入模块接收用户设置的频率参数,生成相应的频率控制字;波形转换模块根据相位累加器的输出,从波形存储器中读取数据,并进行相应的处理,生成正弦波和方波信号;嵌入式逻辑分析仪模块用于实时采集和分析输出波形的离散数据。​

2.2 代码编写与模块实现​

在 Quartus Prime 中创建工程,按照系统架构设计,分别编写各个模块的 Verilog HDL 代码。​

  1. 相位累加器模块:根据输入的时钟信号和频率控制字,实现相位的累加功能。代码如下:
module phase_accumulator(input wire clk,input wire rst_n,input wire [31:0] freq_control_word,output reg [31:0] phase_accumulator_output
);
always @(posedge clk or negedge rst_n) beginif (!rst_n) beginphase_accumulator_output <= 32'd0;end else beginphase_accumulator_output <= phase_accumulator_output + freq_control_word;end
end
endmodule

2.DDS技术合成正弦波和方波
​ 利用DDS技术合成正弦波和方波,很多EDA软件都需要.mif文件,比如使用Quartus 调用ROM IP核产生一个正弦波就需要对ROM IP核加载.mif文件,然后从.mif文件中读取数据产生正弦波

正弦波
1)利用matlab生成ROM初始化文件mif

% 参数设置
addr_width = 10;       % ROM地址位宽(1024点)
data_width = 8;        % 数据位宽(8位)
filename = 'sine_wave.mif'; % 输出文件名% 生成正弦波数据
rom_depth = 2^addr_width;
t = linspace(0, 2*pi, rom_depth); % 0到2π的相位
sine_data = sin(t);               % 生成正弦波(范围[-1, 1])% 量化到8位无符号整数(0~255)
sine_data = round((sine_data + 1) * (2^(data_width-1) - 1));% 写入mif文件
fid = fopen(filename, 'w');
fprintf(fid, 'WIDTH=%d;\n', data_width);
fprintf(fid, 'DEPTH=%d;\n', rom_depth);
fprintf(fid, 'ADDRESS_RADIX=HEX;\n');
fprintf(fid, 'DATA_RADIX=HEX;\n\n');
fprintf(fid, 'CONTENT BEGIN\n');for addr = 0:rom_depth-1fprintf(fid, '  %04X : %02X;\n', addr, sine_data(addr+1));
endfprintf(fid, 'END;\n');
fclose(fid);
disp('mif文件生成成功!');

在运行完上面一段代码后也就在同一文件夹下生成了一个sine_wave.mif文件如下图所示

设置模块LPM_ROM参数的具体步骤如下:

1)在QuartusPrime主界面选择Tool一IPCatalog命令,在查找框内输入ROM,IP核目录(IPCatalog)栏
中会列出相关的IP核,选择ROM:1-PORT并双击,弹出保存IP设置界面,输入文件名,并选中Verilog,单击OK按钮。

3).输入mif文件中宽度和深度,要匹配上(8、1024)

4).全不选择即可,next

DDS模块设计

module dds_sine_wave (input clk,         // 系统时钟input reset,       // 复位input [31:0] fcw,  // 频率控制字(Frequency Control Word)output [7:0] wave_out // 正弦波输出
);// 相位累加器(32位)
reg [31:0] phase_accumulator;// 相位累加器更新
always @(posedge clk or posedge reset) beginif (reset)phase_accumulator <= 32'd0;elsephase_accumulator <= phase_accumulator + fcw;
end// 取高10位作为ROM地址(相位截断)
wire [9:0] rom_address = phase_accumulator[31:22];// 实例化ROM
rom_sine_wave rom_inst (.address(rom_address),.clock(clk),.q(wave_out)
);endmodule

 Testbench仿真

`timescale 1ns/1nsmodule tb_dds_sine_wave;// 输入信号
reg clk;
reg reset;
reg [31:0] fcw;// 输出信号
wire [7:0] wave_out;// 例化DDS模块
dds_sine_wave uut (.clk(clk),.reset(reset),.fcw(fcw),.wave_out(wave_out)
);// 时钟生成(50MHz)
initial beginclk = 0;forever #10 clk = ~clk; // 20ns周期 → 50MHz
end// 仿真流程
initial begin// 初始化reset = 1;fcw = 32'h0000_0000; // 初始频率控制字#100;reset = 0;// 设置fcw生成1kHz正弦波(示例值)// Fout = (50e6 * fcw) / 2^32 → fcw = Fout * 2^32 / 50e6fcw = 32'h00A3D70A; // 对应约1kHz// 仿真运行(至少覆盖多个周期)#2000000; // 仿真2ms(观察2个完整周期)$stop;
endendmodule

添加仿真文件:

 

然后一直ok到底

仿真效果

三、测试结果与总结​

经过仿真和开发板实践测试,DDS 信号发生器能够成功生成正弦波和方波信号,输出信号的频率范围满足 10Hz~5MHz 的要求,最小频率分辨率小于 1kHz。通过嵌入式逻辑分析仪采集到的离散数据,也与设计预期相符,证明了设计的有效性和准确性。​

在设计过程中,深入学习了 DDS 技术的原理和 IP 核的使用方法,掌握了 FPGA 开发的全流程。同时,也遇到了一些问题,如 IP 核参数设置不合理导致波形失真、代码逻辑错误等,通过查阅资料和调试解决了这些问题。本次设计为进一步深入研究 DDS 技术和 FPGA 应用奠定了坚实的基础,后续可以在此基础上进行功能扩展,如增加更多类型的波形生成、提高频率分辨率等。​

以上分享了 DDS 信号发生器的设计过程。如有不妥之处还望各位海涵。祝好!

参考文献:

用FPGA实现dds的方案详解(保姆级入门教学)(VIVADO18.3、quartus13.1)_fpga开发_Jefferymeng-2048 AI社区

FPGA中级项目1——IP核(ROM 与 RAM)

【FIFO IP系列】FIFO IP参数配置与使用示例

【FPGA基础学习】DDS信号发生器设计-CSDN博客

DDS信号发生器原理与经典DDS信号发生器设计方案-CSDN博客

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

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

相关文章

pyqt 简单条码系统

生产数据管理系统说明 系统概述 这是一个基于PyQt5和pyodbc开发的生产数据管理系统&#xff0c;主要用于管理生产过程中的物料绑定和查询操作。系统提供了上料绑定和下料查询功能&#xff0c;支持与SQL Server数据库交互&#xff0c;实现数据的插入、查询、更新和删除操作。界…

【unitrix】 4.1 类型级加一操作(Add1.rs)

一、原码 这段代码实现了一个类型级的加一操作(Add1 trait)&#xff0c;用于在Rust的类型系统中进行数值加一运算。 //! 加一操作特质实现 / Increment operation trait implementation //! //! 说明&#xff1a; //! 1. Z0、P1,、N1 1&#xff0c;常规计算 //! 2. …

git工作中常用

1.管理本地文件 git init//初始化生成一个本地仓库 git add * //添加到暂存区 git commit–m “message” //提交到本地仓库 2.删除本地分支 git branch -d local_branch_name3.隐藏及解除隐藏 git stashgit stash pop4.远程新建分支&#xff0c;在本地签出时候怎么看到 …

Golang 中接口嵌套的详细说明和使用示例

在 Go 语言中&#xff0c;接口嵌套&#xff08;也称为接口组合&#xff09;是一种强大的特性&#xff0c;它允许你通过组合现有接口来创建新的接口。这种方式遵循了 Go 的组合优于继承的设计哲学。 接口嵌套的基本概念 接口嵌套是指在一个接口中嵌入其他接口&#xff0c;从而…

数智管理学(二十四)

第二章 数智化重塑管理的核心 第三节 动态资源配置与实时优化 在当今数智化浪潮的席卷下&#xff0c;企业管理面临着前所未有的变革与挑战。资源配置作为企业管理的核心环节之一&#xff0c;其方式和效率直接影响着企业的运营成本、生产效率和市场竞争力。传统的静态资源配置…

Redis 各版本差异及性能测试指标对比

Redis 各版本差异及性能测试指标对比 Redis 主要版本差异 Redis 2.x 系列 主要特性&#xff1a; 支持主从复制支持简单的持久化(RDB和AOF)发布/订阅功能事务支持 局限性&#xff1a; 单线程模型集群功能有限 Redis 3.x 系列 重大改进&#xff1a; 引入Redis Cluster(官方…

Python图形化秒表:使用Turtle打造精确计时工具

⏱️ 编程基础第一期《6-30》–简易计时器/秒表&#xff0c;这是一个使用Python的turtle和time模块实现的简易计时器/秒表程序&#xff0c;提供简洁的数字时间显示。 目录 &#x1f31f; 功能特点&#x1f680; 使用方法&#x1f9e9; 程序架构设计&#x1f4bb; 代码详解窗口和…

【轨物方案】轨物科技|LoRaWAN 赋能智能光伏清扫,解锁电站高效运维新时代

在大型集中式光伏电站的广袤土地上&#xff0c;清扫机器人的高效运行是保障发电效率的关键。然而&#xff0c;传统的无线通信方式在这些偏远、无4G/5G信号覆盖的区域&#xff0c;往往步履维艰。作为专注于工业物联网解决方案的轨物科技&#xff0c;我们深知这些痛点&#xff0c…

Python函数实战:从基础到高级应用

Python-函数 Python 中可以使用def关键字来定义函数。 函数定义规则&#xff1a; 函数代码块以 def 关键词开头&#xff0c;后接函数标识符名称和圆括号 ()。任何传入参数和自变量必须放在圆括号中间&#xff0c;圆括号之间可以用于定义参数。函数的第一行语句可以选择性地使…

Mac在局域网中突然很慢(包括SMB、NFS、SCP、SSH、Ping等场景均很慢)

今天 SMB 又突然好慢&#xff0c;大概只有 8-9 MB/s&#xff0c;而苹果 SMB 很容易突然很慢是出了名的。我就想装 NFS&#xff0c;但是 NFS 弄好之后还是很慢&#xff0c;我服了&#xff0c;我就检查了scp等场景&#xff0c;都很慢&#xff0c;但是互联网下载速度还是很快的。 …

UMAP:用于降维的均匀流形近似和投影实验

关键词&#xff1a; Uniform Manifold Approximation and Projection (UMAP)&#xff1a;均匀流形近似与投影 一、说明 对于降维&#xff0c;首先看数据集是否线性&#xff0c;如果是线性的用pca降维&#xff1b;如果是非线性数据&#xff0c;t-SNE或者UMAP&#xff0c;本文针…

【Datawhale组队学习202506】YOLO-Master task03 IOU总结

系列文章目录 task01 导学课程 task02 YOLO系列发展线 文章目录 系列文章目录前言1 功能分块1.1 骨干网络 Backbone1.2 颈部网络 Neck1.3 头部网络 Head1.3.1 边界框回归头1.3.2 分类头 2 关键概念3 典型算法3.1 NMS3.2 IoU 总结 前言 Datawhale是一个专注于AI与数据科学的开…

Spring IOC容器核心揭秘:BeanFactory创建、配置加载解析并注册为BeanDefinition

文章目录 一、为何这个阶段如此重要&#xff1f;二、整体流程全景图三、源码级深度解析1. BeanFactory的诞生源码入口&#xff1a;refresh()方法核心方法&#xff1a;obtainFreshBeanFactory()核心实现&#xff1a;refreshBeanFactory()BeanFactory实例化 2. ★ 核心&#xff1…

解锁n8n:开启工作流自动化的无限可能(5/6)

文章摘要&#xff1a;n8n 是一款开源低代码工作流自动化平台&#xff0c;通过可视化拖放节点创建复杂工作流&#xff0c;无需大量代码。具有强大集成能力、数据转换、错误处理等功能&#xff0c;适用于数据同步、客户关系管理、IT 自动化等场景。相比 Zapier、IFTTT 等工具&…

数据赋能(308)——合作共享——数据交流

概述 重要性如下&#xff1a; 信息准确性&#xff1a;数据交流原则确保在数据传递过程中信息的准确性&#xff0c;这是决策和业务活动的基础。决策支持&#xff1a;准确的数据交流为决策提供有力支持&#xff0c;帮助组织做出更明智的决策。业务效率&#xff1a;有效的数据交…

TCP流量控制与拥塞控制:核心机制与区别

一、TCP流量控制&#xff08;Flow Control&#xff09; 定义&#xff1a;通过调节发送方的发送速率&#xff0c;确保接收方能够及时处理数据&#xff0c;避免缓冲区溢出。 本质&#xff1a;解决发送方与接收方之间的"端到端"速率匹配问题。 1. 实现机制&#xff1a…

iOS多端兼容性调试:一次iOS性能优化分工具协作排查过程

在多技术栈混合开发日益普及的今天&#xff0c;iOS应用中越来越多地集成了WebView、Flutter、React Native甚至小程序模块。而这些模块带来的复杂性&#xff0c;不仅体现在UI适配&#xff0c;还包括数据同步、系统权限管理、线程调度等方面的问题。 本文记录的是我们在处理一个…

秋招Day14 - MySQL - 索引

索引为什么能够提高MySQL的查询效率&#xff1f; 索引可以理解为目录&#xff0c;通过索引可以快速定位数据&#xff0c;避免全表扫描 一般是B树结构&#xff0c;查找效率是O(log n)。 索引还能加速排序、分组、连接等操作。 create index idx_name on students(name); 能简…

第5天:LSTM预测火灾温度

&#x1f368; 本文为&#x1f517;365天深度学习训练营 中的学习记录博客&#x1f356; 原作者&#xff1a;K同学啊 目标 复用LSTM模型实现火灾温度预测 具体实现 &#xff08;一&#xff09;环境 语言环境&#xff1a;Python 3.10 编 译 器: PyCharm 框 架: Pytorch &am…

目标检测之YOLOV11自定义数据使用OBB训练与验证

一、前置条件与环境准备 在开始训练前&#xff0c;确保已完成以下准备《目标检测之YOLOV11自定义数据预处理——从原始标注到YOLO-OBB格式转换与验证》&#xff1a; 数据目录结构&#xff1a; yolov11/ ├── datasets/ │ └── shrimp/ │ ├── images/ │ …