数字集成电路仿真实验与设计——基于FPGA的DDS信号源设计

2023-10-07 14:10

本文主要是介绍数字集成电路仿真实验与设计——基于FPGA的DDS信号源设计,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

写在之前的话:这是刚结束的课设的实验报告,代码多有参考,希望可以帮到你。(源码在文末)

一、课设目的和要求

1.加深学生对课程所学知识的理解,训练学生提高工程应用能力、设计与调测能力,最终提高分析与解决问题的能力,了解先进的EDA芯片使用方法;
2.理解dds硬件模块电路工作原理;
3.掌握硬件描述语言设计方法;
4.掌握系统调试测量方法,实现输出信号并且频率可调,实现正弦波、三角波、方波等多种信号源输出;
5.运用EDA系统软硬件工具解决工程问题的能力;

二、课设主要软硬件环境

硬件:PC机。
软件:Windows系统平台,装有Quartus、Modelsim等软件编译环境。

三、内容(包括研究背景、研究现状、思路、不同实现方案比较等)

1.研究背景
信号发生器作为一种常用的信号源设备,在测试测量领域有着广泛的应用。其为测试电路提供频率和幅度可调的测试信号,常用于电子、通信产品测试过程中。传统的信号发生器采用模拟电路构成。这种信号发生器的电路十分复杂,功能和精度相对较低,且容易受外界干扰影响。近年来,随着数字电路技术的不断发展,基于直接数字频率合成(direct digital frequency synthesis, DDS)技术的信号发生器逐步产生。DDS技术改变了传统信号的产生方式,以数字量的形式生成模拟信号,利用微控制器进行控制,大大简化了电路结构,并具有较高的灵活性。由DDS芯片构成的信号发生器具有信号种类丰富、频率及幅度调节范围广、信号稳定度高等特点。
2.研究现状
信号发生器又称信号源或振荡器,在生产实践和科技领域中有着广泛的应用。各种波形曲线均可以用三角函数方程式来表示。能够产生多种波形,如三角波、锯齿波、矩形波(含方波)、正弦波的电路被称为函数信号发生器。函数信号发生器在电路实验和设备检测中具有十分广泛的用途。例如在通信、广播、电视系统中,都需要射频(高频)发射,这里的射频波就是载波,把音频(低频)、视频信号或脉冲信号运载出去,就需要能够产生高频的振荡器。在工业、农业、生物医学等领域内,如高频感应加热、熔炼、淬火、超声诊断、核磁共振成像等,都需要功率或大或小、频率或高或低的振荡器。DDS信号发生器采用直接数字频率合成 (Direct Digital Synthesis,简称DDS)技术,把信号发生器的频率稳定度、准确度提高到与基准频率相同的水平,并且可以在很宽的频率范围内进行精细的频率调节。采用这种方法设计的信号源可工作于调制状态,可对输出电平进行调节,也可输出各种波形。一个完整周期的函数波形被存储在上面所示的存储器查找表中。
3.不同实验方案比较
方案一:采用模拟锁相环实现
模拟锁相环技术是项比较成熟的技术。应用模拟锁相环,可将基准频率倍频,或分频得到所需的频率,且调节精度可以做到相当高、稳定性也比较好。但模拟锁相环模拟电路复杂,不易调节,成本较高,并且频率调节不便且调节范围小,输出波形的毛刺较多,得不到满意的效果。
方案二:基于FPGA的dds波形发生器
设计思路:
系统模块设计:
在这里插入图片描述

采用直接数字频率合成,用 FPGA 器件作为核心控制部件,精度高稳定性好,得到波形平滑,特别是FPGA的高速度,能实现较高频率的波形。控制上更方便,可得到较宽频率范围的波形输出,步进小,外围电路简单易实现。因此采用方案二。

四、源程序(原理图)与结果讨论

DDS全称为直接数字频率合成(Direct Digital Synthesis),其基本原理是在一个周期波形数据下,通过选取其中全部数据或抽样部分数据组成新的波形,由奈奎斯特采样定理可知,最低两个采样点就可以组成一个波形,但实际上最少需要4个点。其原理框图如下:
在这里插入图片描述

其主要由相位控制字、频率控制字、相位累加器、波形存储器几部分组成。
波形存储器:存储一个周期波形的离散信号;
频率控制字:用以控制生成的波形频率;
相位累加器:用来控制波形的相位累加,组成完整的波形显示;
相位控制字:用以控制波形起始位置。

实验代码:

1.DDS模块

module DDS(input		clk,input		rst_n,input		[25:0]	f_word,input		[1:0]	wave_c,input		[11:0]	p_word,input		[4:0]	amplitude,output	reg	[11:0]	dac_data	);localparam	DATA_WIDTH = 4'd12;localparam	ADDR_WIDTH = 4'd12;reg		[11:0]	addr	 ;wire	[11:0]	dac_data0;wire	[11:0]	dac_data1;wire	[11:0]	dac_data2;wire	[11:0]	dac_data3;//波形选择always @(posedge clk or negedge rst_n) beginif (!rst_n) begindac_data <= 12'd0;endelse begincase(wave_c)2'b00:dac_data <= dac_data0/amplitude;	//正弦波2'b01:dac_data <= dac_data1/amplitude;	//三角波2'b10:dac_data <= dac_data2/amplitude;	//锯齿波2'b11:dac_data <= dac_data3/amplitude;	//方波default:;endcaseendend//相位累加器reg	[31:0]	fre_acc;always @(posedge clk or negedge rst_n) beginif (!rst_n) beginfre_acc <= 0;endelse beginfre_acc <= fre_acc + f_word;endend//生成查找表地址always @(posedge clk or negedge rst_n) beginif (!rst_n) beginaddr <= 0;endelse beginaddr <= fre_acc[31:20] + p_word;endend//正弦波sin_rom #(.DATA_WIDTH(DATA_WIDTH),.ADDR_WIDTH(ADDR_WIDTH)) inst_sin_rom (.addr (addr),.clk  (clk),.q    (dac_data0));//三角波sanjiao_rom #(.DATA_WIDTH(DATA_WIDTH),.ADDR_WIDTH(ADDR_WIDTH)) inst_sanjiao_rom (.addr (addr),.clk  (clk),.q    (dac_data1));//锯齿波juchi_rom #(.DATA_WIDTH(DATA_WIDTH),.ADDR_WIDTH(ADDR_WIDTH)) inst_juchi_rom (.addr (addr),.clk  (clk),.q    (dac_data2));//方波fangbo_rom #(.DATA_WIDTH(DATA_WIDTH),.ADDR_WIDTH(ADDR_WIDTH)) inst_fangbo_rom (.addr (addr),.clk  (clk),.q    (dac_data3));
endmodule

2.频率设置模块

module F_word_set(input				clk		,input				rst_n	,input				key1_in	,output	reg	[25:0]	f_word	);wire		key_flag	;wire		key_state	;reg	[3:0]	cnt			;key_filter fword_key (.clk       (clk),.rst_n     (rst_n),.key_in    (key1_in),.key_flag  (key_flag),.key_state (key_state));always @(posedge clk or negedge rst_n) beginif (!rst_n) begincnt <= 4'd0;endelse if (key_flag) beginif (cnt==4'd10) begincnt <= 4'd0;endelse begincnt <= cnt + 1'b1;endendendalways @(posedge clk or negedge rst_n) beginif (!rst_n) beginf_word <= 0;endelse begincase(cnt)                     //x=(2^32)*20/T=(2^32)*20*f(hz)/10000000004'd0:f_word = 26'd86;		//1Hz4'd1:f_word = 26'd859;		//10Hz4'd2:f_word = 26'd8590;		//100Hz4'd3:f_word = 26'd42950;	//500Hz4'd4:f_word = 26'd85899;	//1kHz4'd5:f_word = 26'd429497;	//5kHz4'd6:f_word = 26'd858993;	//10kHz4'd7:f_word = 26'd4294967;	//50kHz4'd8:f_word = 26'd8589935;	//100kHz4'd9:f_word = 26'd17179869;	//200kHz4'd10:f_word = 26'd42949673;//500kHzdefault:;endcaseendend
endmodule

3.按键模块

module key_filter(input                   clk         ,//系统时钟50MHzinput                   rst_n       ,//系统复位input                   key_in      ,//按键输入output   reg            key_flag    ,//输出一个脉冲按键有效信号output   reg            key_state    //输出按键状态,1为未按下,0为按下
);
parameter IDLE      = 4'b0001      ;//空闲状态,读取按键按下的下降沿,读取到下降沿转到下一个状态
parameter FILTER1   = 4'b0010      ;//计数20ms状态,计数结束转到下一个状态
parameter STABLE    = 4'b0100      ;//数据稳定状态,等待按键松开上升沿,读取到上升沿转到下一个状态
parameter FILTER2   = 4'b1000      ;//计数20ms状态,计数结束转到空闲状态
parameter TIME_20MS = 20'd1000_000 ;
reg   [  3: 0]         state_c      ;//寄存器改变状态
reg   [  3: 0]         state_n      ;//现在状态
wire                   IDLE_to_FILTER1  ;//IDLE状态转到FILTER1状态条件
wire                   FILTER1_to_STABLE;//FILTER1状态转到STABLE状态条件
wire                   STABLE_to_FILTER2;//STABLE状态转到FILTER2状态条件
wire                   FILTER2_to_IDLE  ;//FILTER2状态转到IDLE状态条件
reg                    key_in_ff0   ;
reg                    key_in_ff1   ;
reg                    key_in_ff2   ;
wire                   key_in_pos   ;//检测上升沿标志
wire                   key_in_neg   ;//检测下降沿标志 
reg   [ 19: 0]         cnt          ;
wire                   add_cnt      ;
wire                   end_cnt      ;
//状态机第一段,状态转换
always  @(posedge clk or negedge rst_n)beginif(rst_n==1'b0)beginstate_c <= IDLE;endelse beginstate_c <= state_n;end
end
//状态机第二段,状态转换条件
always  @(*)begincase(state_c)IDLE   :beginif(IDLE_to_FILTER1)state_n = FILTER1;elsestate_n = state_c;endFILTER1:beginif(FILTER1_to_STABLE)state_n = STABLE;elsestate_n = state_c;endSTABLE :beginif(STABLE_to_FILTER2)state_n = FILTER2;elsestate_n = state_c;endFILTER2:beginif(FILTER2_to_IDLE)state_n = IDLE;elsestate_n = state_c;enddefault:state_n = IDLE;endcase
end 
//状态转换条件
assign IDLE_to_FILTER1   = key_in_neg   ;
assign FILTER1_to_STABLE = state_c==FILTER1 && end_cnt;
assign STABLE_to_FILTER2 = key_in_pos   ;
assign FILTER2_to_IDLE   = state_c==FILTER2 && end_cnt;
//打两拍,防止亚稳态
always  @(posedge clk or negedge rst_n)beginif(rst_n==1'b0)beginkey_in_ff0 <= 1;key_in_ff1 <= 1;key_in_ff2 <= 1;endelse beginkey_in_ff0 <= key_in;key_in_ff1 <= key_in_ff0;key_in_ff2 <= key_in_ff1;end
end
//下降沿和上升沿检测
assign key_in_pos = (state_c==STABLE) ?(key_in_ff1 && !key_in_ff2):1'b0;
assign key_in_neg = (state_c==IDLE) ?(!key_in_ff1 && key_in_ff2):1'b0;
//计数20ms
always @(posedge clk or negedge rst_n)beginif(!rst_n)begincnt <= 0;endelse if(add_cnt)beginif(end_cnt)cnt <= 0;elsecnt <= cnt + 1'b1;endelse begincnt <= 0;end
end
assign add_cnt = state_c==FILTER1 || state_c==FILTER2;       
assign end_cnt = add_cnt && cnt== TIME_20MS-1;
//key_flag按键按下输出一个脉冲信号
always  @(posedge clk or negedge rst_n)beginif(rst_n==1'b0)beginkey_flag <= 0;endelse if(state_c==FILTER1 && end_cnt) beginkey_flag <= 1;endelse beginkey_flag <= 0;end
end
//key_state按键按下状态信号
always  @(posedge clk or negedge rst_n)beginif(rst_n==1'b0)beginkey_state <= 1;endelse if(state_c==STABLE || state_c==FILTER2) beginkey_state <= 0;endelse beginkey_state <= 1;end
end
endmodule

4.顶层模块

module DDS_top(input					clk			,input					rst_n		,input					key0_in		,input					key1_in		,input					key2_in		,output	wire	[11:0]	dac_data	);wire	[1:0]	wave_c		;wire	[25:0]	f_word		;wire	[4:0]	amplitude	;DDS inst_DDS(.clk      (clk),.rst_n    (rst_n),.f_word   (f_word),.wave_c   (wave_c),.p_word   (12'd0),.amplitude(amplitude),.dac_data (dac_data));F_word_set inst_F_word_set (.clk(clk), .rst_n(rst_n), .key1_in(key1_in), .f_word(f_word));wave_set inst_wave_set (.clk(clk), .rst_n(rst_n), .key0_in(key0_in), .wave_c(wave_c));amplitude_set inst_amplitude_set(.clk	(clk)		,.rst_n	(rst_n)		,.key2_in(key2_in)	,.amplitude(amplitude)	);
endmodule

5.结果与讨论
编译结果:
在这里插入图片描述
仿真结果:
正弦波:
在这里插入图片描述
三角波:
在这里插入图片描述
锯齿波:
在这里插入图片描述
方波:
在这里插入图片描述

由图可知,按键改变后,各个波形的频率也随之改变,可见设计成功。

报告里只贴了部分代码,这里是我上传的源码,可以直接运行通过。
链接:https://pan.baidu.com/s/1DzySQriSSNpIZ5H0rfgVgQ
提取码:b7mu
–来自百度网盘超级会员V5的分享

这篇关于数字集成电路仿真实验与设计——基于FPGA的DDS信号源设计的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/158278

相关文章

Python中的可视化设计与UI界面实现

《Python中的可视化设计与UI界面实现》本文介绍了如何使用Python创建用户界面(UI),包括使用Tkinter、PyQt、Kivy等库进行基本窗口、动态图表和动画效果的实现,通过示例代码,展示... 目录从像素到界面:python带你玩转UI设计示例:使用Tkinter创建一个简单的窗口绘图魔法:用

不懂推荐算法也能设计推荐系统

本文以商业化应用推荐为例,告诉我们不懂推荐算法的产品,也能从产品侧出发, 设计出一款不错的推荐系统。 相信很多新手产品,看到算法二字,多是懵圈的。 什么排序算法、最短路径等都是相对传统的算法(注:传统是指科班出身的产品都会接触过)。但对于推荐算法,多数产品对着网上搜到的资源,都会无从下手。特别当某些推荐算法 和 “AI”扯上关系后,更是加大了理解的难度。 但,不了解推荐算法,就无法做推荐系

从去中心化到智能化:Web3如何与AI共同塑造数字生态

在数字时代的演进中,Web3和人工智能(AI)正成为塑造未来互联网的两大核心力量。Web3的去中心化理念与AI的智能化技术,正相互交织,共同推动数字生态的变革。本文将探讨Web3与AI的融合如何改变数字世界,并展望这一新兴组合如何重塑我们的在线体验。 Web3的去中心化愿景 Web3代表了互联网的第三代发展,它基于去中心化的区块链技术,旨在创建一个开放、透明且用户主导的数字生态。不同于传统

usaco 1.2 Name That Number(数字字母转化)

巧妙的利用code[b[0]-'A'] 将字符ABC...Z转换为数字 需要注意的是重新开一个数组 c [ ] 存储字符串 应人为的在末尾附上 ‘ \ 0 ’ 详见代码: /*ID: who jayLANG: C++TASK: namenum*/#include<stdio.h>#include<string.h>int main(){FILE *fin = fopen (

怎么让1台电脑共享给7人同时流畅设计

在当今的创意设计与数字内容生产领域,图形工作站以其强大的计算能力、专业的图形处理能力和稳定的系统性能,成为了众多设计师、动画师、视频编辑师等创意工作者的必备工具。 设计团队面临资源有限,比如只有一台高性能电脑时,如何高效地让七人同时流畅地进行设计工作,便成为了一个亟待解决的问题。 一、硬件升级与配置 1.高性能处理器(CPU):选择多核、高线程的处理器,例如Intel的至强系列或AMD的Ry

基于UE5和ROS2的激光雷达+深度RGBD相机小车的仿真指南(五):Blender锥桶建模

前言 本系列教程旨在使用UE5配置一个具备激光雷达+深度摄像机的仿真小车,并使用通过跨平台的方式进行ROS2和UE5仿真的通讯,达到小车自主导航的目的。本教程默认有ROS2导航及其gazebo仿真相关方面基础,Nav2相关的学习教程可以参考本人的其他博客Nav2代价地图实现和原理–Nav2源码解读之CostMap2D(上)-CSDN博客往期教程: 第一期:基于UE5和ROS2的激光雷达+深度RG

基于51单片机的自动转向修复系统的设计与实现

文章目录 前言资料获取设计介绍功能介绍设计清单具体实现截图参考文献设计获取 前言 💗博主介绍:✌全网粉丝10W+,CSDN特邀作者、博客专家、CSDN新星计划导师,一名热衷于单片机技术探索与分享的博主、专注于 精通51/STM32/MSP430/AVR等单片机设计 主要对象是咱们电子相关专业的大学生,希望您们都共创辉煌!✌💗 👇🏻 精彩专栏 推荐订阅👇🏻 单片机

SprinBoot+Vue网络商城海鲜市场的设计与实现

目录 1 项目介绍2 项目截图3 核心代码3.1 Controller3.2 Service3.3 Dao3.4 application.yml3.5 SpringbootApplication3.5 Vue 4 数据库表设计5 文档参考6 计算机毕设选题推荐7 源码获取 1 项目介绍 博主个人介绍:CSDN认证博客专家,CSDN平台Java领域优质创作者,全网30w+

STM32(十一):ADC数模转换器实验

AD单通道: 1.RCC开启GPIO和ADC时钟。配置ADCCLK分频器。 2.配置GPIO,把GPIO配置成模拟输入的模式。 3.配置多路开关,把左面通道接入到右面规则组列表里。 4.配置ADC转换器, 包括AD转换器和AD数据寄存器。单次转换,连续转换;扫描、非扫描;有几个通道,触发源是什么,数据对齐是左对齐还是右对齐。 5.ADC_CMD 开启ADC。 void RCC_AD

单片机毕业设计基于单片机的智能门禁系统的设计与实现

文章目录 前言资料获取设计介绍功能介绍程序代码部分参考 设计清单具体实现截图参考文献设计获取 前言 💗博主介绍:✌全网粉丝10W+,CSDN特邀作者、博客专家、CSDN新星计划导师,一名热衷于单片机技术探索与分享的博主、专注于 精通51/STM32/MSP430/AVR等单片机设计 主要对象是咱们电子相关专业的大学生,希望您们都共创辉煌!✌💗 👇🏻 精彩专栏 推荐订