用verilog模拟DDS产生正弦波信号
前言:
DDS:直接数字频率合成,正弦波0-2pi周期内,相位到幅度是一一对应的(这里我们使用放大后的整数幅度)。
主要思路:
个人理解,FPGA不擅长直接做数字信号计算,那样太占用片上逻辑资源,所以需要事先建立 正弦波相位-幅度 表,然后在时钟下,通过相位累加并用相位作为地址索引来查询正弦波信号表。
正弦波相位-幅度 表:
存储的是量化的正弦波在一个周期的幅度信息(幅度的地址即相位)。
幅度的地址数目决定了相位量化的误差。
而存储每一个幅度的比特数决定了幅度的量化误差。
可以通过matlab以及Xilinx的IP核向导创建。
Verilog编写的DDS模块主要由三部分组成,
- 相位累加器,用于决定输出信号频率的范围和精度;
- 正弦函数模块,用于存储经量化和离散后的正弦函数的幅值;
- 查表模块,对相位累加器的输出地址查表。
两种方法可以改变输出信号的频率:
- 改变查表寻址的时钟频率,从而改变输出波形的频率。
- 改变寻址的步长来改变输出信号的频率。
步长即为相位增量。
由累加器对相位增量进行累加,
累加器的值作为查表地址。
相位累加器是 DDS 的核心所在,前面在低于时钟频率的任意频率生成(相位累加器)中我们已经进行了叙述。
正弦函数模块包含一个周期正弦波的数字幅度信息,每个地址对应正弦波中0-2pi范围的一个相位点。查表模块把输入的地址相位信息映射成正弦波幅度的数字量信号。相位寄存器每经过 2^N/K 个时钟后回到初始状态,相应地正弦查询表经过一个循环回到初始位置,输出一个正弦波。
输出正弦波周期为fo=fc* K/2^N ,最小分辨率为f=fc/2^N。(通过fc和K控制正弦波频率精度) 其中,N 为累加器位宽,K 为步长,fc 为时钟频率。计数模(最大值):M=2^N。
一般正弦波表幅度地址位宽与累加的查表地址位宽不同,按前者位宽取后者对应高位的位宽即可。(具体见实例)
先用matlab生成1024点的正弦波数据:
clc;clear;
N = 10; %储存单元地址线
depth=2^N; %存储单元;
widths=N; %数据宽度为8位;
index = linspace(0,pi*2,depth);
sin_value = sin(index);
sin_value = sin_value * (depth/2 -1); %扩大正弦幅度值
sin_value = fix((sin_value)+0.5);
plot(sin_value);
number = [0:depth];
fid=fopen('sin_table.coe','w+');
fprintf(fid,'memory_initialization_radix=10;\n');
fprintf(fid,'memory_initialization_vector=\n');
for i = 1 : depth - 1
fprintf(fid, '%d,\n', sin_value(i));
end
fprintf(fid, '%d;', sin_value(depth));
fclose(fid);
Verilog程序
1、adder.v文件,相位累加模块
`timescale 1ns/1ps
/***************************************
晶振频率 fc = 100MHz
输出频率 fo = 1kHz(根据需要可以设为任意值)
控制参数 K = (fo*2^N)/fc = 42950
参数 N = 2^32,(32为计数器的位宽)
****************************************/
module PHASE_ADDER(
input clk,
input rst,
output reg [31:0] cnt,
output reg clk_out
);
always @(posedge clk or posedge rst)
if(rst)
cnt <= 0;
else
cnt <= cnt + 32'd42950; //计数器步长K
always @(posedge clk or posedge rst)
if(rst)
clk_out <= 1'b0;
else if(cnt < 32'h7FFF_FFFF)
clk_out <= 1'b0;
else
clk_out <= 1'b1;
endmodule
2、dds_top.v顶层设计
`timescale 10ns /1ns
module dds_top(
input rst,
input clk,
output signed [15:0] sine_o
);
wire [31:0] phase; //32bit内部连接线,传递相位增量
wire clk_out;
wire [9:0] addr; //10bit相位信息
PHASE_ADDER U_PHASE_ADDER(
.clk (clk ),
.rst (rst ),
.cnt (phase ),
.clk_out(clk_out)
);
assign addr = phase[31:22];//addr 10bit
DDS_Table U_DDS_Table(
.clka(clk), // input wire clka
.addra(addr), // input wire [9 : 0] addra
.douta(sine_o) // output wire [15 : 0] douta
);
endmodule
3、仿真测试文件
`timescale 1ns/1ps
module TB;
reg clk;
reg rst;
wire clk_out;
dds_top U_dds_top(
.clk (clk ),
.rst (rst )
);
initial begin
clk = 0;
rst = 0;
#4 rst = 1;
#3 rst = 0;
end
always #5 clk = ~clk;
endmodule
matlab生成正弦数据:

vivado和Modelsim联合仿真结果:

用verilog模拟DDS产生正弦波信号的更多相关文章
- verilog 实现DDS
一.DDS的原理 直接数字频率合成器(DDS),功能是通过输入频率输入字从而实现改变输出信号的频率的功能,它所利用的原理就是虽然对于一段正弦信号来说其幅度值是非线性的,但是其相位的值却是线性增加的,如 ...
- modelsim脚本文件的编写
第一章 ModelSim介 绍 本指南是为 ModelSim5.5f版本编写的,该版本运行于UNIX和Microsoft Windows 95/98/Me/NT/2000的操作系统环境中.本指南覆盖了 ...
- 中国澳门sinox很多平台CAD制图、PCB电路板、IC我知道了、HDL硬件描述语言叙述、电路仿真和设计软件,元素分析表
中国澳门sinox很多平台CAD制图.PCB电路板.IC我知道了.HDL硬件描述语言叙述.电路仿真和设计软件,元素分析表,可打开眼世界. 最近的研究sinox执行windows版protel,powe ...
- 搭建Modelsim SE仿真环境-使用do文件仿真
本章我们介绍仿真环境搭建是基于Modelsim SE的.Modelsim有很多版本,比如说Modelsim-Altera,但是笔者还是建议大家使用Modelsim-SE,Modelsim-Altera ...
- 彻底理解DDS(信号发生器)的fpga实现(verilog设计代码)
DDS(Direct Digital Synthesis)是一种把一系列数字信号通过D/A转换器转换成模拟信号的数字合成技术. 它有查表法和计算法两种基本合成方法.在这里主要记录DDS查表法的fpga ...
- 基于小脚丫DDS 调频 调幅 调相 切换波形 AD5601输出模拟波形
先讲讲里面的矩阵键盘,矩阵键盘列有下拉电阻,默认全为0000,默认行输入为1111,当有按键按下的时候,列输入会被拉高,这时控制行的输出做行扫描,电子琴用key_flag_r0电平作为使能,这里用ke ...
- psoc做dds
今天用psoc做了dds,现在总结一下. 1dds用到的相位累加器是用verilog写的,本来准备用一下datapath,这是和fpga不一样的一点,用了类似alu的结构,但是看手册后发现,虽然可以执 ...
- FPGA内部IP核DDS
项目当中需要正弦信号与余弦信号,首先想到了DDS芯片,例如AD9833.AD9834.由于还需要用FPGA 做一些数据处理,后来干脆直接用FPGA 内部的DDSIP核,同时根据IP核内部的相位累加 ...
- 基于DDS的任意波形发生器
实验原理 DDS的原理 DDS(Direct Digital Frequency Synthesizer)直接数字频率合成器,也可叫DDFS. DDS是从相位的概念直接合成所需波形的一种频率合成技术. ...
随机推荐
- Codeforces Round #367 (Div. 2) Hard problem
Hard problem 题意: 有n个字符串,对第i个字符串进行反转操作代价为ci. 要使n个字符串按照字典序从小到大排列,最小的代价是多少. 题解: 反转就是reverse操作,比如说45873反 ...
- alpha融合
//alpha融合 //作者:sandy //时间:2015-10-6 //将一只狗的头像融合在蜗牛头上 #include <cv.h> #include <highgui.h> ...
- RabbitMQ介绍1 - 由来
RabbitMQ是一个异步消息通信中间件,用erlang语言开发,实现了AMQP(Advanced Message Queue )协议,是一个开源产品,官方网站:http://www.rabbitmq ...
- SKD
1, 软件开发工具包 软件开发工具包(Software Development Kit,即SDK)一般是一些被软件工程师用于为特定的软件包.软件框架.硬件平台.操作系统等建立应用软件的开发工具的集合. ...
- ubuntu14.04 wifi频繁掉线解决
uname -r sudo lspci -knn sudo lshw -numeric -class network sudo ifconfig -a sudo route -nv sudo rfki ...
- 立体匹配:关于Middlebury提供的源码的简化后的结构
- 源码解读—LinkedList
学习了一下linkedList的源码,做下记录. java底层实现的是双向环链表,程序定义了一个header,来保存头结点,header.next指向最后一个节点(最后插入到),header.prev ...
- 页面设计--RadioButton
RadioButton单选控件支持多分组模式 属性如下图 设计: web显示效果图:
- 【转】java内部类的作用
http://andy136566.iteye.com/blog/1061951/ 推荐一. 定义 放在一个类的内部的类我们就叫内部类. 二. 作用 1.内部类可以很好的实现隐藏 一般的非内部类,是不 ...
- X86平台下嵌入式linux触摸屏解决方案(usb触摸屏控制器+完美校准方案+触摸屏QTE开发环境搭建)
一直在用X86平台,真心不想用WINCE和XPE,一些大的硬件供应商都不提供linux平台下的技术支持,比如研华的3343PC104系列的板子... 开发的问题如下: 1 USB控制器目前只有台湾和竹 ...