news 2026/6/9 22:52:20

波形发生器如何构建?基于Verilog打造自己的DDS任意波形发生器

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
波形发生器如何构建?基于Verilog打造自己的DDS任意波形发生器

波形发生器在各大行业中均有使用,带来了诸多便利。对于波形发生器,小编在往期文章中做过很多介绍。本文中,主要在于探讨波形发生器的实现过程。具体而言,将介绍基于Verilog实现DDS任意波形发生器。如果你是波形发生器的爱好者,疑惑想要了解本文的探讨内容,都不妨继续往下阅读哦。

一、总体方案实现及系统框图

在该DDS电路组成上,包括基准时钟、频率累加器、相位累加器、幅度/相位转换电路。频率累加器对输入信号进行累加运算,产生频率控制数据,相位累加器对代表频率的M位二进制码进行累加运算,产生后面波形存储器所需的查表地址,幅度/相位转换电路实际上就是一个波形存储器,供查表使用,读出数据送人D/A转换器和低通滤波器。

系统设计原理框图如下:

系统设计原理框图

二、系统组成模块简介

1、顶层模块

顶层模块是系统程序的主模块,它负责将fom查找表、相位累加等模块组装在一起,通过调用的关系使它们组合成为一个有机的整体。在顶层模块中,定义了参考时钟的输入,复位端口,波形输出、频率控制字等。

2、相位累加器模块

相位累加器是决定系统性能的关键部分,主要是利用频率控制字和相位控制字来累加出寻址地址。相位累加器在基准频率信号clk的控制下以频率控制字data为步长进行累加运算,产生需要的频率控制数据,在时钟的控制下把累加的结果作为波形存储器ROM的地址,实现对波形存储器ROM的寻址。由于相位累加模块通过C语言实现比较容易,故我们没有单独成立一个模块,而是将它集成到了顶层模块的一个always语句块中:

case(choose_wave) 2‘b00:begin

sin_ena <= 1’b1;

cos_ena <= 1‘b0;

sawtooth_ena <= 1’b0;

triangle_ena <= 1‘b0;

if(ADD_B > 256) ADD_B <= 0; //关键代码,实现相位累加的功能

else ADD_B <= ADD_A + ADD_B;

end

2’b01:begin

cos_ena <= 1‘b1;

sin_ena <= 1’b0;

sawtooth_ena <= 1‘b0;

triangle_ena <= 1’b0;

if(ADD_B > 256) ADD_B <= 0; //关键代码,实现相位累加的功能

else ADD_B <= ADD_A + ADD_B;

end

2‘b10:begin

sin_ena <= 1’b0;

cos_ena <= 1‘b0;

sawtooth_ena <= 1’b1;

triangle_ena <= 1‘b0;

if(ADD_B > 256) ADD_B <= 0; //关键代码,实现相位累加的功能

else ADD_B <= ADD_A + ADD_B;

end

2’b11:begin

sin_ena <= 1‘b0;

cos_ena <= 1’b0;

sawtooth_ena <= 1‘b0;

triangle_ena <= 1’b1;

if(ADD_B > 256) ADD_B <= 0; //关键代码,实现相位累加的功能

else ADD_B <= ADD_A + ADD_B;

end

default:begin

ADD_B <= 9‘b0;

sin_ena <= 1’b0;

cos_ena <= 1‘b0;

sawtooth_ena <= 1’b0;

triangle_ena <= 1‘b0;

end

endcase

在程序中还出现了一个变量(wave_choose)这是一个用来选择所要输出波形的一个变量,通过它可以控制输出的波形种类(正弦波,余弦波,三角波,锯齿波)。但是由于在设计的时候没有考虑到存在负值的影响,导致最后综合的结果不正确,经过询问老师知道修改方法是将rom查找表中所有采样点的电压负值全部抬高,消除负值,但是由于时间的原因没有来得及修改,也不知道方案修改的结果。

3、查找表

本模块实现的是一个rom存贮器,用于存储采样的波形数据,并提供地址查找的功能。具体实现的过程:

1) 首先使用数学工具计算得到波形采样点,生成mif文件

2) 导入数据采样点,给每一个采样点分配地址,并提供外部寻址的接口,此过程可以通过Quartas Ⅱ来辅助完成

由于我们组的设计时在modelsim下进行的,modelsim面向的是仿真,它不会产生所谓的“rom”这种实际的电路,所以我们没有采用这样的方法,而是简单的使用case语句来实现。虽然这样也能得到预期的效果,但是它却没有真正的生成一个“rom”,根据我组的综合结果来看,使用case语句生成的是一个与输入相关的复杂的逻辑网络,而不是rom那样有一定规则的电路结构。一下是我们使用C语言产生采样点的程序:

void main(){ int i,j = 0;;

FILE *fp;

fp=fopen(“data.txt”,“w”);

for(i=0;i<=256;i++){

//j=255*sin(2*3.14159/256*i)+0.5;//四舍五入

fprintf(fp,“i=%d,\tj=%d\n”,i,j); }

fclose(fp); }

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/6/9 13:12:20

强烈安利MBA必用TOP10一键生成论文工具

强烈安利MBA必用TOP10一键生成论文工具 2026年MBA论文写作工具测评&#xff1a;为何需要这份榜单&#xff1f; 在MBA学习过程中&#xff0c;撰写高质量的论文是每位学生必须面对的挑战。随着AI技术的发展&#xff0c;越来越多的工具被引入到学术写作中&#xff0c;但如何选择真…

作者头像 李华
网站建设 2026/6/5 15:33:43

[STM32C0] 【STM32C092RC 测评】FDCAN Loopback测试

CAN同样可以进行Loopback测试&#xff0c;我们首先连接一下CAN的基本概念。 控制器局域网总线&#xff08;CAN&#xff09;作为专为实时应用量身打造的串行通讯协议&#xff0c;在工业及自动化领域扮演着至关重要的角色。仅需简单的双绞线&#xff0c;它便能实现信号的高…

作者头像 李华
网站建设 2026/6/5 15:13:04

Flutter Column 组件详解

Flutter Column 组件详解 Column 是 Flutter 中最常用的垂直布局组件&#xff0c;用于将子组件按垂直方向排列。 基本结构 Column( children: <Widget>[ // 子组件列表 Widget1(), Widget2(), Widget3(), ], )核心属性详解 1. children (必填) Column( children: [ …

作者头像 李华
网站建设 2026/6/5 20:29:13

【论文阅读】AbsoluteZero: ReinforcedSelf-play Reasoningwith Zero Data

【论文阅读】AbsoluteZero: ReinforcedSelf-play Reasoningwith Zero Data 1 发表时间与团队2 问题背景与核心思路3 具体设计3.1 模型设计3.2 self play设计 4. 实验5 结论6 有趣的发现 1 发表时间与团队 发表时间&#xff1a;2025年10月&#xff08;arXiv v3 版本日期为2025年…

作者头像 李华
网站建设 2026/6/9 20:52:54

美国护照照片太大怎么办?美国护照规格要求

办理美国护照时&#xff0c;很多人都会在照片环节卡壳 —— 提交的照片要么提示文件过大无法上传审核&#xff0c;要么自行压缩后画质模糊被驳回&#xff0c;还不清楚美国护照照片的专属规格要求&#xff0c;白白耽误办理进度。 美国护照照片有明确的官方规范&#xff1a;尺寸…

作者头像 李华
网站建设 2026/6/5 21:23:17

香橙派到手如何通过网线实现与电脑连接

首先我们需要先配置好自己电脑" Internet协i议版本4&#xff08;TCP/Pv4&#xff09;"我们先要打开自己电脑的控制面板&#xff0c;然后选择网络和Internet&#xff0c;然后选择网络连接&#xff0c;你要先插上网线与香橙派连接上&#xff0c;然后右键以太网选择属性…

作者头像 李华