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设计代码)的更多相关文章

  1. 全数字锁相环(DPLL)的原理简介以及verilog设计代码

    随着数字电路技术的发展,数字锁相环在调制解调.频率合成.FM 立体声解码.彩色副载波同步.图象处理等各个方面得到了广泛的应用.数字锁相环不仅吸收了数字电路可靠性高.体积小.价格低等优点,还解决了模拟锁 ...

  2. 自己动手写CPU(基于FPGA与Verilog)

    大三上学期开展了数字系统设计的课程,下学期便要求自己写一个单周期CPU和一个多周期CPU,既然要学,就记录一下学习的过程. CPU--中央处理器,顾名思义,是计算机中最重要的一部分,功能就是周而复始地 ...

  3. 【小梅哥FPGA进阶教程】第十一章 四通道幅频相可调DDS信号发生器

    十一.四通道幅频相可调DDS信号发生器 本文由山东大学研友袁卓贡献,特此感谢 实验目标 实现多通道可调信号发生器 实验平台 芯航线FPGA核心板.ADDA模块 实验现象 实现基于FPGA的多通道可调信 ...

  4. 浅谈Verilog HDL代码编写风格

    消失了好久,没有写文章,也没有做笔记,因为最近再赶一个比赛,时间很紧,昨天周六终于结束了,所以趁着周末这会儿有时间,写点东西,记录下来.首先我学习FPGA才一年多,我知道自己没有资格谈论一些比较深层次 ...

  5. Verilog设计Valid-Ready握手协议

    转自http://ninghechuan.com 我不生产知识,我只是知识的搬运工. Handshake Protocol握手协议!为了保证数据传输过程中准确无误,我们需要加上握手信号来控制信号的传输 ...

  6. Xilinx FPGA 的PCIE 设计

    写在前面 近两年来和几个单位接触下来,发现PCIe还是一个比较常用的,有些难度的案例,主要是涉及面比较广,需要了解逻辑设计.高速总线.Linux和Windows的驱动设计等相关知识. 这篇文章主要针对 ...

  7. Verilog设计分频器(面试必看)

    分频器是指使输出信号频率为输入信号频率整数分之一的电子电路.在许多电子设备中如电子钟.频率合成器等,需要各种不同频率的信号协同工作,常用的方法是以稳定度高的晶体振荡器为主振源,通过变换得到所需要的各种 ...

  8. FPGA异步时钟设计中的同步策略

    1 引言    基于FPGA的数字系统设计中大都推荐采用同步时序的设计,也就是单时钟系统.但是实际的工程中,纯粹单时钟系统设计的情况很少,特别是设计模块与外围芯片的通信中,跨时钟域的情况经常不可避免. ...

  9. FPGA Asynchronous FIFO设计思路(2)

    FPGA Asynchronous FIFO设计思路(2) 首先讨论格雷码的编码方式: 先看4bit的格雷码,当MSB为0时,正向计数,当MSB为1时,即指针已经走过一遍了,最高位翻转,此时的格雷码是 ...

随机推荐

  1. jQuery.extend()[$.extend()]

    jQuery.extend(target, object1[,objectN]);jQuery.extend([deep], target, object1[,objectN]);jQuery.ext ...

  2. 1903021121-刘明伟 实验二 JAVA第2周作业—代码插入

    项目 内容 课程班级博客链接 19信计班(本)  作业要求链接  第2周作业 要求 截图(只截运行结果) 扩展阅读 https://www.cnblogs.com/thelovelybugfly/p/ ...

  3. django小项目,使用paramiko自动备份网络设备配置

    原来公司开发团队人员众多,有专门对接运维需求的开发人员,现在想要实现些功能可(只)以(能)自己写了-_- |   周末在家无事,用django搞个简单的功能练练手 django安装,配置 sudo p ...

  4. 好客租房21-react组件的两种创建方式(函数组件)

    1使用函数创建组件 函数组件:使用js的函数或者箭头函数创建的组件 约定1:函数组件名称必须以 开头 约定2:函数组件必须有返回值 表示该组件的结构 如果返回值为null 表示不渲染任何内容 2.1使 ...

  5. [2021-TKK 暑期训练第一场] 1585:下馆子-3

    题目做了超链接 参考官方题解,作部分优化 下馆子 -3 题意: 给定n组数据,由name,time构成 当只有一个最大值时,输出该同学 当不止有一个最大值时,输出最先大于等于max次的同学 题解: 考 ...

  6. 04C++核心编程(二-泛型编程)

    Day08 笔记 1 函数模板 1.1 泛型编程 – 模板技术 特点:类型参数化 1.2 template< typename T > 告诉编译器后面紧跟着的函数或者类中出现T,不要报错, ...

  7. springSecurity + jwt + redis 前后端分离用户认证和授权

    记录一下使用springSecurity搭建用户认证和授权的代码... 技术栈使用springSecurity + redis + JWT + mybatisPlus 部分代码来自:https://b ...

  8. 队列的java实现

    今天老师提出一个问题,就是如何用java实现队列呢?我在网上找了许多资料,发现java也是可以很轻松的实现队列. 如下代码: package com; import java.util.Collect ...

  9. C++编码规范(本人自定义)

    C++编码规范 1.变量名用camelCase命名法(即lowerCamelCase,小驼峰拼写法)命名. 即小写字母开头,如果变量名是复合词,第二个单词的首字母大写. 举例: int digitsC ...

  10. ruoyi前后端分离版:添加新页面,不需登录也可访问

    添加QRcode页面代码 <template> <div class="register"> <el-form ref="registerF ...