彻底理解DDS(信号发生器)的fpga实现(verilog设计代码)
DDS(Direct Digital Synthesis)是一种把一系列数字信号通过D/A转换器转换成模拟信号的数字合成技术。
它有查表法和计算法两种基本合成方法。在这里主要记录DDS查表法的fpga实现。
查表法:由于ROM查询法结构简单,只需要在ROM中存放不同相位对应的幅度序列,然后通过相位累加器的输出对其寻址,经过数/模转换和低通滤波(LPF)输出便可以得到所需要的模拟信号。

查表法示意图:

设计:
输入:频率控制字f,相位控制字,系统时钟Fclk,复位信号reset
输出:幅度数据dout。
关系:Tout = M * Tclk 即 Fout = Fclk / M 。其中,M为一个波形的离散点数。

简单解释一下:比如我们把一个正弦波形分为16个点,而ROM容量为8,那么我们的点数间隔就要取16 / 8 = 2 ,即频率控制字为 2 。
细节:由于在设计时点数间隔不一定为1,即相位累加器的值可能大于ROM容量,所以我们要取它的高位到ROM中取相位对应的幅度点。如:频率控制字=4,则相位累加器的值为:0(00000),4(00100),8(01000),12(010100) ....... 也就是说因为步进4(100),后两位将一直保持不变,高位每次加1(1个4),可以类比十进制理解:每次加10:000,010,020,030...最后一位不变。
代码实现:
module DDS_Module(
clk ,
reset ,
f_ctrl ,
p_ctrl ,
dout
);
input clk ;
input reset ;
input [2:0]f_ctrl ;//(取值限制为2的倍数)
input [9:0]p_ctrl ;
output [9:0]dout ; //频率控制字寄存器(频率)(大于1的时候,后面相位累加器输出到实时相位时要砍掉它的位宽)
reg [2:0]f_regist ;//(取值限制为2的倍数)
always @ (posedge clk)
f_regist <= f_ctrl ; //相位累加器 (f * t)
reg [12:0]p_add ;
always@(posedge clk or negedge reset )
if(!reset )
p_add <= 0 ;
else
p_add <= p_add + f_regist ; //相位控制字寄存器(初始相位)(相位偏移量)
reg [9:0]p_regist ;
always @ (posedge clk)
p_regist <= p_ctrl ; //实时相位
reg [9:0]p_now ;
always@(posedge clk or negedge reset )
if(!reset )
p_now <= 0 ;
else
p_now <= p_add[12:3] + p_regist ; //取相位累加器的前10位,因为f每次+4,后三位是不变的 DDS_ROM DDS_ROM(
.clka(clk),
.addra(p_now),
.douta(dout)
); endmodule
这里是需要引用ROM的IP核的,上节内容。
`timescale 1ns / 1ps
module DDS_tb(
);
reg clk ;
reg reset ;
reg [2:0]f_ctrl1 ;
reg [2:0]f_ctrl2 ;
reg [9:0]p_ctrl1 ;
reg [9:0]p_ctrl2 ;
wire [9:0]dout1 ;
wire [9:0]dout2 ;
DDS_Module DDS_Module1(
.clk(clk) ,
.reset(reset) ,
.f_ctrl(f_ctrl1) ,
.p_ctrl(p_ctrl1) ,
.dout(dout1)
); DDS_Module DDS_Module2(
.clk(clk) ,
.reset(reset) ,
.f_ctrl(f_ctrl2) ,
.p_ctrl(p_ctrl2) ,
.dout(dout2)
); initial clk = 1 ;
always #10 clk = !clk ;
initial begin
reset = 0 ;
f_ctrl1 = 0 ;
p_ctrl1 = 0 ;
f_ctrl2 = 0 ;
p_ctrl2 = 0 ;
#201 ;
reset = 1 ;
#201 ;
f_ctrl1 = 3'd4;
p_ctrl1 = 10'd0 ;
f_ctrl2 = 3'd4;
p_ctrl2 = 10'd0 ;
#90000 ;
#90000 ;
#90000 ;
#90000 ;
f_ctrl1 = 3'd4;
p_ctrl1 = 10'd0 ;
f_ctrl2 = 3'd4;
p_ctrl2 = 10'd256 ;
#90000 ;
#90000 ;
#90000 ;
f_ctrl1 = 3'd4;
p_ctrl1 = 10'd0 ;
f_ctrl2 = 3'd4;
p_ctrl2 = 10'd512 ;
#90000 ;
#90000 ;
#90000 ;
$stop;
end
endmodule
效果:分别是相位差 0° ,90 °,180°

彻底理解DDS(信号发生器)的fpga实现(verilog设计代码)的更多相关文章
- 全数字锁相环(DPLL)的原理简介以及verilog设计代码
随着数字电路技术的发展,数字锁相环在调制解调.频率合成.FM 立体声解码.彩色副载波同步.图象处理等各个方面得到了广泛的应用.数字锁相环不仅吸收了数字电路可靠性高.体积小.价格低等优点,还解决了模拟锁 ...
- 自己动手写CPU(基于FPGA与Verilog)
大三上学期开展了数字系统设计的课程,下学期便要求自己写一个单周期CPU和一个多周期CPU,既然要学,就记录一下学习的过程. CPU--中央处理器,顾名思义,是计算机中最重要的一部分,功能就是周而复始地 ...
- 【小梅哥FPGA进阶教程】第十一章 四通道幅频相可调DDS信号发生器
十一.四通道幅频相可调DDS信号发生器 本文由山东大学研友袁卓贡献,特此感谢 实验目标 实现多通道可调信号发生器 实验平台 芯航线FPGA核心板.ADDA模块 实验现象 实现基于FPGA的多通道可调信 ...
- 浅谈Verilog HDL代码编写风格
消失了好久,没有写文章,也没有做笔记,因为最近再赶一个比赛,时间很紧,昨天周六终于结束了,所以趁着周末这会儿有时间,写点东西,记录下来.首先我学习FPGA才一年多,我知道自己没有资格谈论一些比较深层次 ...
- Verilog设计Valid-Ready握手协议
转自http://ninghechuan.com 我不生产知识,我只是知识的搬运工. Handshake Protocol握手协议!为了保证数据传输过程中准确无误,我们需要加上握手信号来控制信号的传输 ...
- Xilinx FPGA 的PCIE 设计
写在前面 近两年来和几个单位接触下来,发现PCIe还是一个比较常用的,有些难度的案例,主要是涉及面比较广,需要了解逻辑设计.高速总线.Linux和Windows的驱动设计等相关知识. 这篇文章主要针对 ...
- Verilog设计分频器(面试必看)
分频器是指使输出信号频率为输入信号频率整数分之一的电子电路.在许多电子设备中如电子钟.频率合成器等,需要各种不同频率的信号协同工作,常用的方法是以稳定度高的晶体振荡器为主振源,通过变换得到所需要的各种 ...
- FPGA异步时钟设计中的同步策略
1 引言 基于FPGA的数字系统设计中大都推荐采用同步时序的设计,也就是单时钟系统.但是实际的工程中,纯粹单时钟系统设计的情况很少,特别是设计模块与外围芯片的通信中,跨时钟域的情况经常不可避免. ...
- FPGA Asynchronous FIFO设计思路(2)
FPGA Asynchronous FIFO设计思路(2) 首先讨论格雷码的编码方式: 先看4bit的格雷码,当MSB为0时,正向计数,当MSB为1时,即指针已经走过一遍了,最高位翻转,此时的格雷码是 ...
随机推荐
- python实现基于smtp发送邮件
[前言] 在某些项目中,我们需要实现发送邮件的功能,比如: 爬虫结束后,发送邮件通知 定时发送邮件提醒待办事项 某项业务逻辑触发邮件通知 今天我们就分享如何基于smtp借助163邮箱来发送邮件 [实现 ...
- VMware安装Ubuntu20(图文教程,超详细)
VMware安装Ubuntu20(图文教程,超详细) 此文讲述使用 VMware 工具安装 Ubuntu 系列虚拟机,不同位数和不同版本的 Ubuntu 安装过程相差无几,这里以 Ubuntu20 6 ...
- 一条更新的SQL如何执行
开源Linux 一个执着于技术的公众号 一条SQL的执行流程如图所示 如图所示:MySQL数据库主要分为两个层级:服务层和存储引擎层 •服务层:server层包括连接器.查询缓存.分析器.优化器.执行 ...
- typeScript类型总结
1.对象类型 {} 用来指定对象中可以包含哪些属性,在属性名后加?表示属性是可选的 语法:{属性名:属性值类型,属性名:属性值类型} 示例: let a:{name:string,age?:numbe ...
- GET 与 POST 其实没有什么区别
GET 与 POST 其实没有什么区别 本文写于 2020 年 12 月 30 日 GET 与 POST 是两种 HTTP 方法,并且是最常用的两种. 今天在使用 Postman 测试 api 的时候 ...
- 小米 pro 笔记本双硬盘设置引导盘
功能键 F2 进入 BIOS F12 进入 Boot 选项 步骤 小米 Pro 默认是开启了 UEFI,如果 Boot 选项没有显示出期望的系统盘,那么就是这个系统盘没有 UEFI 分区,按照这个文档 ...
- Install Ubuntu on Windows Subsystem for Linux
安装参考 ubuntu.com/wsl microsoft/wsl/install-manual microsoft/terminal 错误解决方案 github/启动 WSL 2时警告"参 ...
- CentOS下Python管理
一.升级Python 查看系统版本 cat /etc/redhat-release CentOS Linux release 7.4.1708 (Core) 查看Python版本 python -V ...
- .NET MAUI 正式版GA发布
.NET MAUI – 一个代码库,多个平台 欢迎使用 .NET 多平台应用 UI.此版本标志着我们统一 .NET 平台的多年旅程中的新里程碑.现在,您和超过 500 万其他 .NET 开发人员拥有了 ...
- javaweb开发案例
1.实验3 (1)当运行Servlet时,碰到"空指针异常"错误怎么处理? 答:应提示用户操作有误,或设置对象值为空字符串或一个默认值,或是不执行某操作,直接跳转到其他处理中. ( ...