基于FPGA的DDS任意波形发生器设计
从两式可以看出,正弦信号是关于相位的一个周期函数,下图更加直观的描述相位与幅度的关系,16个相位与16个幅度值相对应,即每一个相位值对应一个幅度值,比如1100对应的相位为3π/2,对应的幅度值为-1.
相位和幅值的一一对应关系就好比存储器中地址和存储内容的关系,如果把一个周期内每个相位对应的幅度值存入存储器当中,那么对于任意频率的正弦信号,在任意时刻,只要已知相位Φ(t),也就知道地址,就可通过查表得到s(t)。下图是DDS的基本结构框图:
相位累加器在每个时钟脉冲输入时,把频率控制字累加一次,相位累加器的输出数据就是信号的相位,用输出的数据作为波形存储器(ROM)的相位取样地址,这样就可以把存取在波形存储器内的波形抽样值经查找表查处,完成相位到幅值的转换。频率控制字相当于Φ(t)中的2πfc,相位控制字相当于Φ(t)中的θ0。
为了获得较高的频率分辨率,则只有增加相位累加器的字长N,故一般N都取值较大。但是受存储器容量的限制,存储器地址线的位数w不可能很大,一般都要小于N。这样存储器的地址线一般都只能接在相位累加器输出的高w位,而相位累加器输出余下的(N-W)个低位则只能被舍弃,这就是相位截断误差的来源。
频率分辨率,即频率的变化间隔
三、实现代码
module DDS (
sys_clk,
sys_rst_n,
freq_word,
phase_word,
wave_out
);
input sys_clk ; //系统工作时钟
input sys_rst_n ; //复位,低有效
input [31:0] freq_word ; //频率控制字,控制输出波形频率
input [11:0] phase_word ; //相位控制字,控制初始相位
output[9:0] wave_out ; //输出波形,位宽10bit
reg [31:0] freq_word_reg ;
reg [11:0] phase_word_reg ;
reg [31:0] phase_adder ; //相位累加器
reg [9:0] rom_address ; //存储深度2^10
always @(posedge sys_clk or negedge sys_rst_n) begin
if (sys_rst_n ==1'b0) begin
freq_word_reg <= 32'h0000;
end
else
freq_word_reg <= freq_word;
end
always @(posedge sys_clk or negedge sys_rst_n) begin
if (sys_rst_n ==1'b0) begin
phase_word_reg <= 12'h0000;
end
else
phase_word_reg <= phase_word;
end
always @(posedge sys_clk or negedge sys_rst_n) begin
if (sys_rst_n ==1'b0) begin
phase_adder <= 32'h0000;
end
else
phase_adder <= phase_adder + freq_word_reg; //对频率控制字进行累加
end
always @(posedge sys_clk or negedge sys_rst_n) begin
if (sys_rst_n ==1'b0) begin
rom_address <= 32'h0000;
end
else
rom_address <= phase_adder[31:20] + phase_word_reg;
end
sin_rom DDS_ROM_U0 (
.address (rom_address) ,
.clock (sys_clk) ,
.q (wave_out)
);
endmodule
`timescale 1 ns/ 1 ns
module DDS_tb();
reg [31:0] freq_word ;
reg [11:0] phase_word ;
reg sys_clk ;
reg sys_rst_n ;
wire [9:0] wave_out ;
DDS i1 (
.freq_word(freq_word),
.phase_word(phase_word),
.sys_clk(sys_clk),
.sys_rst_n(sys_rst_n),
.wave_out(wave_out)
);
initial
begin
sys_clk = 0;
sys_rst_n = 0;
freq_word = 0;
phase_word = 0;
#2000;
sys_rst_n = 1;
freq_word = 32'd1024; //25M
phase_word = 32'd0; //相位0度
#200000000;
freq_word = 32'd2048; //50M
phase_word = 32'd512; //相位90度
#200000000;
$stop;
end
always sys_clk = #20 ~sys_clk; //系统时钟25M
endmodule
基于FPGA的DDS任意波形发生器设计的更多相关文章
- 基于FPGA的DDS设计(一)
最近在学习基于FPGA的DDS设计,借此机会把学习过程记录下来,当作自己的学习笔记也希望能够帮助到学习DDS的小伙伴. DDS(Direct Digital Synthesizer)直接数字合成器,这 ...
- 文献翻译|Design of True Random Number Generator Based on Multi-stage Feedback Ring Oscillator(基于多级反馈环形振荡器的真随机数发生器设计)
基于多级反馈环形振荡器的真随机数发生器设计 摘要 真随机数生成器(trng)在加密系统中起着重要的作用.本文提出了一种在现场可编程门阵列(FPGA)上生成真随机数的新方法,该方法以 多级反馈环形振荡器 ...
- (DDS)正弦波形发生器——幅值、频率、相位可调(二)
(DDS)正弦波形发生器--幅值.频率.相位可调(二) 主要关于调相方面 一.项目任务: 设计一个幅值.频率.相位均可调的正弦波发生器. 频率每次增加10kHz 相位每次增加 PI/2 幅值每次增加两 ...
- (DDS)正弦波形发生器——幅值、频率、相位可调(一)
(DDS)正弦波形发生器--幅值.频率.相位可调 一.项目任务: 设计一个幅值.频率.相位均可调的正弦波发生器. 频率每次增加1kHz. 相位每次增加 2*PI/256 幅值每次增加两倍 二.文章内容 ...
- 基于FPGA的VGA可移植模块终极设计【转】
本文转载自:http://www.cnblogs.com/lueguo/p/3373643.html 略过天涯 基于FPGA的VGA可移植模块终极设计 一.VGA的诱惑 首先,VGA的驱动,这事, ...
- 基于DDS的任意波形发生器
实验原理 DDS的原理 DDS(Direct Digital Frequency Synthesizer)直接数字频率合成器,也可叫DDFS. DDS是从相位的概念直接合成所需波形的一种频率合成技术. ...
- 基于FPGA的DDS设计(二)
在DDS设计中,如果相位累加器每个时钟周期累加1,就会输出频率为195.313KHz的波形.如果每个时钟周期累加2,就会输出频率为2*195.313KHz的波形·······,如果每两个时钟周期累加1 ...
- 基于FPGA(DDS)的正弦波发生器
记录背景:昨晚快下班时,与同事rk聊起怎么用FPGA实现正弦波的输出.我第一反应是利用高频的PWM波去滤波,但感觉这样的波形精度肯定很差:后来想起之前由看过怎么用FPGA产生正弦波的技术,但怎么都想不 ...
- 基于FPGA的通信信号源的设计
通信信号源设计原理 通过设计一个DDS信号源,然后将该信号作为载波信号,再对基带信号进行2ASK.2FSK.2PSK.2DPSK调制,进而产生多种通信信号. 设计框图如下: 将PN序列进行2ASK.2 ...
随机推荐
- ubuntu 下交叉编译环境的搭建
1. 安装标准的C开发环境,由于Linux安装默认是不安装的,所以需要先安装一下(如果已经安装好的话,就可以免去这一步了): #sudo apt-get install gcc g++ libgcc1 ...
- java之异常处理、异常分类、Throwable、自定义异常
参考http://how2j.cn/k/exception/exception-trycatch/336.html 异常处理 try catch 1.将可能抛出FileNotFoundExceptio ...
- 图解Mysql语句的执行过程
当我们希望Mysql能够高性能的执行查询语句时,其实最好的方法就是搞清楚Mysql到底是怎样执行查询的.一旦理解这一点,很多的查询优化工作实际上就是遵循一些原则让查询优化器能够按照预想的合理的方式运行 ...
- [Makefile] 递归编译的Makefile的实现
转自:http://www.linuxidc.com/Linux/2017-01/139702.htm 最近写了一个递归Makefile,目的是既可以实现子模块的单独编译,也可以不做任何修改就和整个程 ...
- 无监督学习:Linear Dimension Reduction(线性降维)
一 Unsupervised Learning 把Unsupervised Learning分为两大类: 化繁为简:有很多种input,进行抽象化处理,只有input没有output 无中生有:随机给 ...
- 模板 - SPFA
SPFA可以用来判断负环或者计算带负权的最短路. 其实带负权的最短路可以用带势Dijkstra计算-- 所以SPFA基本就拿来判负环了-- #include<bits/stdc++.h> ...
- Git 分支管理 解决冲突
人生不如意之事十之八九,合并分支往往也不是一帆风顺的. 准备新的feature1分支,继续我们的新分支开发: $ git checkout -b feature1 -- 在feature1分支上修改r ...
- python 之 匿名函数
5.14 匿名函数 lambda x , y : x+y 1 匿名的目的就是要没有名字,给匿名函数赋给一个名字是没有意义的 2 匿名函数的参数规则.作用域关系与有名函数是一样的 3 匿名函数的函数体通 ...
- P5346 【XR-1】柯南家族
题目地址:P5346 [XR-1]柯南家族 Q:官方题解会咕么? A:不会!(大雾 题解环节 首先,我们假设已经求出了 \(n\) 个人聪明程度的排名. \(op = 1\) 是可以 \(O(1)\) ...
- Linux常用命令(补充)-grep
grep(global search regular expression(RE) and print out the line,全面搜索正则表达式并把行打印出来)是一种强大的文本搜索工具,它能使用正 ...