彻底理解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时,即指针已经走过一遍了,最高位翻转,此时的格雷码是 ...
随机推荐
- 关于Spring-JDBC测试类的简单封装
关于Spring-JDBC测试类的简单封装 1.简单封装 /** * Created with IntelliJ IDEA. * * @Author: Suhai * @Date: 2022/04/0 ...
- 团队Arpha3
队名:观光队 组长博客 作业博客 组员实践情况 王耀鑫 **过去两天完成了哪些任务 ** 文字/口头描述 完成服务器连接数据库部分代码 展示GitHub当日代码/文档签入记录 接下来的计划 服务器网络 ...
- 面试官问:浏览器输入 URL 回车之后发生了什么?
一个执着于技术的公众号 前言 这个问题已经是老生常谈了,更是经常被作为面试的压轴题出现,网上也有很多文章,但最近闲的无聊,然后就自己做了一篇笔记,感觉比之前理解更透彻了. 注意:本文的步骤是建立在,请 ...
- 论文解读(NGCF)《LightGCN: Simplifying and Powering Graph Convolution Network for Recommendation》
论文信息 论文标题:LightGCN: Simplifying and Powering Graph Convolution Network for Recommendation论文作者:Xiangn ...
- 探索ABP基础架构
为了了解应用程序是如何配置和初始化,本文将探讨ASP.NET Core和ABP框架最基本的构建模块.我们将从 ASP.NET Core 的 Startup类开始了解为什么我们需要模块化系统,以及 AB ...
- 一、深入学习c++先要练好的内功
掌握进程虚拟地址空间区域的划分 课程讲的内容建立在x86 32位的Linux系统下. 任何的编程语言会产生两种东西:指令和数据.磁盘上的可执行文件在启动时都会加载到内存当中,但是不会加载到物理内存中, ...
- 软件项目管理 ——1.2.PMBOK与软件项目管理知识体系
软件项目管理 --1.2.PMBOK与软件项目管理知识体系 归档于软件项目管理初级学习路线 第一章 软件项目管理基本概念 <初级学习路线合集 > @ 目录 软件项目管理 --1.2.PMB ...
- 463. Island Perimeter - LeetCode
Question 463. Island Perimeter Solution 题目大意:给出一个二维数组1表示陆地0表示海,求陆地的周长 思路: 重新构造一张地图grid2即一个二维数组,比原数组大 ...
- 好客租房48-组件的props(基本使用)
组件是封闭的 要接受外部数据应该通过props来实现 props的作用:接受传递给组件的数据 传递数据:给组件标签添加属性 接收数据:函数组件通过参数props接收数据 类组件通过this.props ...
- Calico网络插件
以下大部分是本人参考各种资料{官方文档.书籍}对知识的汇总和整理,其中有理解错误的地方请大神留言和指正,嘿嘿~~ 1.概述 参考文档:https://projectcalico.docs.tigera ...