彻底理解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时,即指针已经走过一遍了,最高位翻转,此时的格雷码是 ...
随机推荐
- goland设置import规范
import 规范 引入了三种类型的包,标准库包,第三方包,程序内部包,建议采用如下方式进行组织你的包: 有顺序的引入包,不同的类型采用空格分离, 第一种标准库 第二是第三方包 第三是项目包. 在项目 ...
- 项目文章|DNA(羟)甲基化研究揭示铁离子依赖表观调控促进狼疮致病性T细胞分化|易基因
易基因(羟)甲基化DNA免疫共沉淀测序(h)MeDIP-seq研究成果见刊<Journal of Clinical Investigation> 2022年5月2日,中南大学湘雅二医院赵明 ...
- Resource wordnet not found. Please use the NLTK Downloader to obtain the resource:
第一次使用nltk的时候,出现了这样的错误: from nltk.stem.wordnet import WordNetLemmatizer lemmatizer = WordNetLemmatize ...
- iOS全埋点解决方案-时间相关
前言 我们使用"事件模型( Event 模型)"来描述用户的各种行为,事件模型包括事件( Event )和用户( User )两个核心实体.我们在描述用户行为时,往往只需要描述 ...
- Vue-router(前端路由)的两种路由模式
Vue的两种路由模式: hash.history:默认是hash模式: 前端路由(改变视图的同时不会向后端发出请求) 一.什么是hash模式和history模式? hash模式:是指url尾巴后的#号 ...
- zabbix 1.2
1.zabbix图形界面乱码问题处理 2.自定义监控项 (1)在agent端配置agent.conf 打开vim /etc/zabbix/zabbix-agent.conf 找到UserP ...
- 167. Two Sum II - Input array is sorted - LeetCode
Question 167. Two Sum II - Input array is sorted Solution 题目大意:和Two Sum一样,这里给出的数组是有序的 思路:target - nu ...
- 什么是请求参数、表单参数、url参数、header参数、Cookie参数?一文讲懂
最近在工作中对 http 的请求参数解析有了进一步的认识,写个小短文记录一下. 回顾下自己的情况,大概就是:有点点网络及编程基础,只需要加深一点点对 HTTP 协议的理解就能弄明白了. 先分享一个小故 ...
- DOM标签操作与事件与jQuery查找标签
目录 DOM之操作标签 创建标签对象 标签对象的属性 innerText与innerHTML 标签内部追加内容 属性操作 事件 常用事件 事件绑定 事件案例 jQuery简介 查找标签 基本选择器 属 ...
- Dubbo3 源码系列 -- 环境准备
Dubbo3 源码系列 -- 环境准备 前言 工作中一直使用Dubbo项目,借着这次机会通过源码的方式来学习下Dubbo的源码内容.目前市面上很多都是的Dubbo2系列的教程:就连目前的Dubbo的官 ...