FPGA学习(五)——DDS信号发生器设计

FPGA学习(五)——DDS信号发生器设计

目录

  • FPGA学习(五)——DDS信号发生器设计
    • 一、FPGA开发中常用IP核——ROM/RAM/FIFO
      • 1、ROM简介
      • 2、ROM文件的设置
        • (1)直接编辑法
        • (2)用C语言等软件生成初始化文件
      • 3、ROM IP核配置调用
    • 二、DDS信号发生器设计
      • 1、相位累加器设计
      • 2、波形存储器ROM设计
        • (1)方波模块
        • (2)正弦波形存储器模块
      • 3、锁相环倍频电路设计
      • 4、顶层电路设计
      • 5、最终实现
      • 6、仿真波形

一、FPGA开发中常用IP核——ROM/RAM/FIFO

常见的FPGA存储器有3种,RAM(随机访问内存)ROM(只读存储器)FIFO(先入先出)

这三种存储器的区别如下

其中RAM通常都是在掉电之后就丢失数据,ROM在系统停止供电的时候仍然可以保持数据

可以向RAM和ROM中的任意位置写入数据,也可以读取任意的位置的数据

FIFO的数据先入先出,先进去的数据先出来,只能顺序写入数据,顺序的读出数据,其数据地址由内部读写指针自动加1完成,不能像普通存储器那样可以由地址线决定读取或写入某个指定的地址。

这三种存储器的应用场合

RAM和ROM常用于存储指令或者中间的数据

FIFO常用于数据传输通道中用于缓存数据,避免数据丢失,如不同速率时钟模块间的数据传输就需要用到异步FIFO

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:只提供一个独立的地址端口核一个读数据端口

image-20250420092325595

双端口ROM:有两个地址端口,和两个读数据端口

image-20250420092337748

2、ROM文件的设置

(1)直接编辑法

image-20250420092750197

image-20250420092853439

image-20250420093128626

在Edit找到Custom Fill Cells

image-20250420093900022

设置完成后,将文件保存,然后用编辑器打开看一下

image-20250420093933152

image-20250420093952032

(2)用C语言等软件生成初始化文件

当需要初始化的存储单元变多时,上述手工输入数据的方法就不太实用了。在了解mif文件的格式的基础上,可以自己编写C语言程序或者使用MATLAB程序自动生成mif文件。

image-20250420101818222

以下是产生128X8位正弦波形数据的C语言源程序 :

#include<stdio.h>
#include<math.h>
#define PI 3.141592
#define DEPTH 128 //数据深度,即存储单元的个数
#define WIDTH 8 //存储单元的宽度
int main(void)
{ 
int n, temp;
float v;
FILE *fp;
/*建立名为Data_sine.mif的新文件,允许写入数据*/
fp= fopen("Data_sine.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++)
{
/*周期为128个点的正弦波*/
v= sin(2*PI*n/DEPTH);
/*将-1~1之间的正弦波的值扩展到0~255之间*/
temp=(int)((v+1)*255/2);//v+1将数值平移到lO~2之间
/*以十六进制形式输出地址和数据*/
fprintf(fp, "%x\t:\t%x;\n",n, temp);
}
fprintf(fp,"END;\n");
fclose(fp);
}
}

编辑上述代码后生成myimf.exe文件,在资源管理器中双击运行exe文件,生成Data_sine.mif文件

image-20250420103042129

image-20250420103342471

3、ROM IP核配置调用

在Tools->IP Catalog->搜索ROM

image-20250420085753544

1-PORT单端口,2-PORT双端口,此次以单端口为例

image-20250420103637506

How wide should the ‘q’ output bus be?

How many x-bit words of memory?

配置ROM的位宽和深度

What should the memory block type be?

使用什么类型的内存

在官方资料中,有提及什么类型的芯片适合用什么类型的内存

image-20250420091525942

寄存器时钟和复位信号的设置,设置输出端q直接输出,不通过寄存器,设置时钟使能端(clken)

image-20250420103659046

Create one dock enable signal for each dock signal. Note: All registered ports are controlled by the enable signal(s)

是否创建一个时钟使能信号

Create an 'adr’asynchronous dear for the registered ports

是否创建一个清零信号

存储器初始化,并指明初始化ROM的数据文件

image-20250420103853939

使用mif文件对ROM进行初始化,文件名为黑色则为添加成功,红色则为失败

image-20250420094801226

ROM子模块参数设置完成后,为了测试其功能,新建一个顶层文件进行功能测试。代码如下:

module Sine_Signal(q_sig,address_sig,clock_sig,clken_sig);output [7:0] q_sig;output [7:0]  address_sig;input clken_sig;input clock_sig;IPROM	IPROM_inst (.address ( address_sig ),.clken ( clken_sig ),.clock ( clock_sig ),.q ( q_sig ));endmodule

注意实例化部分应该与生成的_inst.v文件内容一致。

image-20250420104345602

仿真波形如下:

image-20250420105902203

二、DDS信号发生器设计

DDS是直接数字式频率合成器(Direct Digital Synthesizer)的英文缩写,是一项关键的数字化技术。与传统的频率合成器相比,DDS具有低成本、低功耗、高分辨率和快速转换时间等优点,广泛使用在电信与电子仪器领域,是实现设备全数字化的一个关键技术。作为设计人员,我们习惯称它为信号发生器,一般用它产生正弦、锯齿、方波等不同波形或不同频率的信号波形,在电子设计和测试中得到广泛应用。
DDS的基本结构主要由相位累加器、相位调制器、波形数据表ROM、D/A转换器等四大结构组成,其中较多设计还会在数模转换器之后增加一个低通滤波器。

image-20250420112036224

1、相位累加器设计

//=====相位累加器和数据锁存器===== 
module addr_cnt(CPi,K,ROMaddr, Address); input CPi; //系统基准时钟(100MHz) input [12:0] K; //13位频率控制字 output reg [9:0] ROMaddr; //10位ROM地址 output reg [16:0] Address; //17位相位累加器地址信号 
always @(posedge CPi) 
begin Address = Address + K; ROMaddr = Address[16:7]; 
end endmodule

2、波形存储器ROM设计

(1)方波模块

由于方波的实现算法相对简单,可以不用ROM表,直接用寄存器来保存方波的输出值。方波只有高、低电平两种状态,因此只需要在一个周期的中间位置翻转电平即可。其实现原理如下:由于相位累加器的值是线性累加的,因此地址值(Address)也是线性累加的,对地址值Address进行判断,当地址值的最高位为0时,便将存储波形幅值的存储器的每一位赋值为1,否则赋值为0。具体源程序如下:

//=====方波产生模块:squwave. v ====== 
module squwave(CPi,RSTn, Address, Qsquare); input CPi; //系统基准时钟(100MHz)input RSTn;//同步清零input [16:0]Address;//17位地址输入信号output reg[11:0] Qsquare; //输出方波信号,12位
always @(posedge CPi)
if(!RSTn) Qsquare=12'h000;//同步清零
else beginif(Address<=17'hOFFFF)Qsquare=12'hFFF;//输出高电平else Qsquare=12'h000;//输出低电平
end
endmodule
(2)正弦波形存储器模块
#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;/*建立文件名为Sine1024.mif的新文件,允许写入数据,对文件名没有特殊要求,但扩展名必须为.mif*/fp=fopen("'Sine1024. mif", "w+");if(NULL== fp)printf(" Can not cr eat file!r\n");else{ printf(" File created successfully!\n");/*生成文件头,注意不要忘了“;” */fprintf(fp, "DEPTH =%od;\n",DEPTH);fprintf(fp, "WIDTH =%od;\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++) {/*周期为1024个点的正弦波*/v= sin(2*PI*n/DEPTH);/*将-1~1之间的正弦波的值扩展到0~4095之间*/temp=(int)((v+1)*4095/2);//v+1将数值平移到0~2之间/*以十六进制输出地址和数据*/fprintf(fp, "%x\t:t%x;\n",n, temp);} fprintf(fp, "END;\n");fclose(fp);//关闭文件} 
} 

3、锁相环倍频电路设计

使用QuartusPrime软件调用宏模块定制一个100MHz的锁相环模块。其过程是:选择Tool一MegaWizardPlug-InManager命令,启动MegaWizard工具,选择左栏I/O项目下的ALTPLL(嵌入式锁相环),定制一个名称为PLL100M_CP的时钟模块,该模块的输入inclk0为50MHz时钟信号,输出c0为100MHz的脉冲信号,占空比为50%,带有相位锁定指示输出端locked,模块符号如图8.7.9所示。

4、顶层电路设计

将上述各个模块逐个级联起来就可以得到波形产生器的顶层模块,其代码如下:

//=DDS的顶层模块:DDS top.V =
module DDS top(CLOCK 50, RSTn, WaveSel,K,WaveValue, LEDG, CLOCK 100);
input CLOCK 5O;
input RSTn;
input [1:0] WaveSel;
input [12:0] K;
output reg [1l:0] WaveValue;
wire [9:0] ROMaddr;
wire [16:0]Address;
wire[11:0]Qsine,Qquar;
output [0:0]LEDG;
output CLOCK_100;
wire CPi = CLOCK_100;
PLL100M_CP PLL100M_CP_inst (.inclk0(CLOCK 50 );
//50MHz时钟输入.c0(CLOCK_100),
//100MHz时钟输出.locked (LEDG[O])
);
addr_cnt U0_instance(CPi,K,ROMaddr, Address);
SineROM ROM_inst (.adres (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;endcase
end
endmodule

5、最终实现

使用DE2-115开发板来验证上述设计。用析出的50MHz晶振作为时钟输入,用KEY3控制方波清零,用SW12~SW0设置频率控制字,SW7、SW6用来选择输出波形的各类,用LEDGe作为 PLL的相位锁定指示。为方便引脚分配,新建一个顶层文件:

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

6、仿真波形

image-20250420122810587

image-20250420122821497

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

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

相关文章

【Vue】从 MVC 到 MVVM:前端架构演变与 Vue 的实践之路

个人博客&#xff1a;haichenyi.com。感谢关注 一. 目录 一–目录二–架构模式的演变背景​三–MVC&#xff1a;经典的分层起点​四–MVP&#xff1a;面向接口的解耦尝试​五–MVVM&#xff1a;数据驱动的终极形态​​六–Vue&#xff1a;MVVM 的现代化实践​​​ 二. 架构模…

【算法】快速排序、归并排序(非递归版)

目录 一、快速排序&#xff08;非递归&#xff09; 1.原理 2.实现 2.1 stack 2.2 partition(array,left,right) 2.3 pivot - 1 > left 二、归并排序&#xff08;非递归&#xff09; 1.原理 2.实现 2.1 gap 2.1.1 i 2*gap 2.1.2 gap * 2 2.1.3 gap < array.…

CasualLanguage Model和Seq2Seq模型的区别

**问题1&#xff1a;**Causal Language Modeling 和 Conditional Generation 、Sequence Classification 的区别是什么&#xff1f; 因果语言模型(Causal Language Model)&#xff1a; 预测给定文本序列中的下一个字符&#xff0c;一般用于文本生成、补全句子等&#xff0c;模型…

【计算机视觉】三维视觉项目 - Colmap二维图像重建三维场景

COLMAP 3D重建 项目概述项目功能项目运行方式1. 环境准备2. 编译 COLMAP3. 数据准备4. 运行 COLMAP 常见问题及解决方法1. **编译问题**2. **运行问题**3. **数据问题** 项目实战建议项目参考文献 项目概述 COLMAP 是一个开源的三维重建软件&#xff0c;专注于 Structure-from…

状态管理最佳实践:Bloc架构实践

状态管理最佳实践&#xff1a;Bloc架构实践 引言 Bloc (Business Logic Component) 是Flutter中一种强大的状态管理解决方案&#xff0c;它基于响应式编程思想&#xff0c;通过分离业务逻辑和UI表现层来实现清晰的代码架构。本文将深入探讨Bloc的核心概念、实现原理和最佳实践…

Python多任务编程:进程全面详解与实战指南

1. 进程基础概念 1.1 什么是进程&#xff1f; 进程(Process)是指正在执行的程序&#xff0c;是程序执行过程中的一次指令、数据集等的集合。简单来说&#xff0c;进程就是程序的一次执行过程&#xff0c;它是一个动态的概念。 想象你打开电脑上的音乐播放器听歌&#xff0c;…

Linux 网络基础(二) (传输协议层:UDP、TCP)

目录 一、传输层的意义 二、端口号 1、五元组标识一个通信 2、端口号范围划分 3、知名端口号&#xff08;Well-Know Port Number&#xff09; &#xff08;1&#xff09;查看端口号 4、绑定端口号数目问题 5、pidof & netstat 命令 &#xff08;1&#xff09;ne…

得佳胜哲讯科技 SAP项目启动会:胶带智造新起点 数字转型新征程

在全球制造业加速向数字化、智能化转型的浪潮中&#xff0c;胶带制造行业正迎来以“自动化生产、数据化运营、智能化决策”为核心的新变革。工业互联网、大数据分析与智能装备的深度融合&#xff0c;正推动胶带制造从传统生产模式向“柔性化生产精准质量控制全链路追溯”的智慧…

大数据学习栈记——MapReduce技术

本文介绍hadoop中的MapReduce技术的应用&#xff0c;使用java API。操作系统&#xff1a;Ubuntu24.04。 MapReduce概述 MapReduce概念 MapReduce是一个分布式运算程序的编程框架&#xff0c;核心功能是将用户编写的业务逻辑代码和自带默认组件整合成一个完整的分布式运算程序…

Centos9 离线安装 MYSQL8

centos 9 离线安装 mysql 8 参考教程 1. 官网下载mysql 下载地址 2. 将文件传输到Centos中解压 软件全部安装到了/opt中 在opt中新建mysql目录&#xff0c;解压到mysql目录中 tar -xvf mysql压缩文件 mysql[rootcentoshost mysql]# ls mysql-community-client-8.4.5-1.e…

helm的go模板语法学习

1、helm chart 1.0、什么是helm&#xff1f; 介绍&#xff1a;就是个包管理器。理解为java的maven、linux的yum就好。 安装方法也可参见官网&#xff1a; https://helm.sh/docs/intro/install 通过前面的演示我们知道&#xff0c;有了helm之后应用的安装、升级、查看、停止都…

display的一些学习记录

收集的SDM的log&#xff1a; 01-01 00:00:15.311 933 933 I SDM : Creating Display HW Composer HAL 01-01 00:00:15.311 933 933 I SDM : Scheduler priority settings completed 01-01 00:00:15.311 933 933 I SDM : Configuring RPC threadpool 0…

【Rust 精进之路之第2篇-初体验】安装、配置与 Hello Cargo:踏出 Rust 开发第一步

系列&#xff1a; Rust 精进之路&#xff1a;构建可靠、高效软件的底层逻辑 **作者&#xff1a;**码觉客 发布日期&#xff1a; 2025-04-20 引言&#xff1a;磨刀不误砍柴工&#xff0c;装备先行&#xff01; 在上一篇文章中&#xff0c;我们一起探索了 Rust 诞生的缘由&…

【深度学习】计算机视觉(17)——ViT理解与应用

文章目录 Embedding1 概念2 Q&A &#xff08;1&#xff09;3 Positional Encoding4 Q&A &#xff08;2&#xff09; ViT样例及Embedding可视化理解1 简化ViT练习2 CLS Token3 Embedding可视化4 多头注意力可视化 Embedding技术体系结构参考来源 在研究中对特征的编码和…

肖特基二极管详解:原理、作用、应用与选型要点

一、肖特基二极管的基本定义 肖特基二极管&#xff08;Schottky Diode&#xff09; 是一种基于金属-半导体结&#xff08;肖特基势垒&#xff09;的二极管&#xff0c;其核心特性是低正向压降&#xff08;Vf≈0.3V&#xff09;和超快开关速度。 结构特点&#xff1a;阳极采用金…

DeepSeek在数据仓库的10大应用场景

一、智能数据集成与清洗 多源数据整合&#xff1a;DeepSeek能够从多种数据源中提取、转换和加载数据&#xff0c;实现跨系统数据的高效整合。 数据清洗与标准化&#xff1a;通过智能算法自动识别并纠正数据中的错误、不一致性和缺失值&#xff0c;提升数据质量。 二、数据仓…

提示词构成要素对大语言模型跨模态内容生成质量的影响

提示词构成要素对大语言模型跨模态内容生成质量的影响 提示词清晰度、具象性与质量正相关 限定指向性要素优于引导指向性要素 大语言模型生成内容保真度偏差 以讯飞星火大模型为实验平台,选取100名具备技术素养的人员,从提示词分类、构成要素和实践原则归纳出7种提示词组…

BeautifulSoup 库的使用——python爬虫

文章目录 写在前面python 爬虫BeautifulSoup库是什么BeautifulSoup的安装解析器对比BeautifulSoup的使用BeautifulSoup 库中的4种类获取标签获取指定标签获取标签的的子标签获取标签的的父标签(上行遍历)获取标签的兄弟标签(平行遍历)获取注释根据条件查找标签根据CSS选择器查找…

关于MacOS使用Homebrew的详细介绍

Homebrew 是 macOS&#xff08;和 Linux&#xff09;上最流行的包管理工具&#xff08;Package Manager&#xff09;&#xff0c;用于快速安装、更新和管理各种开发工具、命令行程序、开源软件等。它类似于&#xff1a; Ubuntu/Debian 的 aptCentOS/RHEL 的 yumWindows 的 Cho…

最新扣子空间实操指南

一、首先要先获取到内部测试的邀请码&#xff0c; 我们先打开扣子空间官网&#xff1a;https://space.coze.cn/ 输入邀请码后进入该页面&#xff1a; 它这里支持文件上传&#xff0c;扩展里面有很多插件&#xff0c;页支持MCP各种插件. 探索模式有两种&#xff0c;一种是ai自…