基于FPGA的DDS信号发生器

news2024/11/23 7:21:18

前言

此处仅为基于Vivado实现DDS信号发生器的仿真实现,Vivado的安装请看下面的文章,这里我只是安装了一个标准版本,只要能够仿真波形即可。

FPGA开发Vivado安装教程_vivado安装 csdn-CSDN博客

DDS原理

DDS技术是一种通过数字计算生成波形信号的方法,其核心原理是利用数字相位累加器和波形查找表(ROM)生成高精度、频率可调的波形信号。DDS系统的主要组成部分包括频率控制字(Fword)、相位累加器、相位控制字(Pword)和波形查找表。

DDS的基本结构图如下所示:

在DDS系统中,频率控制字决定了输出波形的频率。频率控制字越大,相位累加器每个时钟周期增加的相位值就越大,从而输出波形的频率越高。相位累加器是DDS系统的核心部件,用于累加频率控制字。在每个时钟周期,相位累加器会将上一个周期的累加值与频率控制字相加,生成新的相位值。这个相位值用于波形查找表的地址生成。

要理解这个频率字对应的输出频率,可以使用以下公式:

f_{out}=\frac{F_{word}\times f_{clock}}{2^{N}}

其中,f_{out}是输出频率,F_{word}是频率控制字,f_{clock}是驱动DDS的时钟频率,N是相位累加器的位宽,通常是DDS设计中的一个常数。假设这里f_{clock}为50MHz,N为32位,输出频率位1MHz,那么频率控制字即为85899345(仅去整数部分)。

这里还比较了1MHz、500KHz、100KHz的正弦波信号,如下图所示。

相位控制字用于实现相位偏移,通过将相位控制字加到相位累加器的输出中,可以实现输出波形的相位偏移,从而便于同步或相位调制等应用。波形查找表存储了一个周期波形的数据,例如正弦波、方波和三角波。相位累加器的输出作为地址输入到波形查找表,查找到相应的波形数据输出。 

使用IP核生成ROM表

波形ROM模块通过查找表方式存储和输出波形数据。每种波形的数据表根据相应的波形公式预先计算并存储在ROM中。在系统运行过程中,DDS模块根据当前相位值读取ROM中的波形数据。

你可以使用软件去生成波形数据文件.coe文件。

在IP Catalog中找到ROM IP核,直接搜索即可。

修改名字,并且讲Memory Type类型改为Single Port ROM。

点击Port A Options修改宽度和深度。

 在换到Other Options选择我们刚刚生成的.coe文件路径。

接下来和之前的一样对方波和正弦波做同样的处理。然后切换到IP Sources,点击每个的.v文件

这里应当以你自己的标准为准,然后进行实例化。

DDS波形仿真

模块中实例化了三个波形生成子模块,这里应该按照你自己的方式来。

`timescale 1ns / 1ps

module DDS(
        Clk,
        Reset_n,
        Fword,
        Pword,
        mode,
        Data_out
    );
        input                         Clk;
        input                         Reset_n; 
        input [31:0]                  Fword;
        input [11:0]                  Pword;
        input [1:0]                   mode;  // 2位模式输入,用于选择波形
        output reg [13:0]             Data_out;  // 输出选择的波形数据
         
        // 频率控制字同步寄存器
        reg [31:0] Fword_r;
        always @(posedge Clk)
            Fword_r <= Fword;
        
        // 相位控制字同步寄存器
        reg [11:0] Pword_r;
        always @(posedge Clk)
            Pword_r <= Pword; 
        
        // 相位累加器    
        reg [31:0] Freq_ACC;
        always @(posedge Clk or negedge Reset_n)
            if (!Reset_n)
                Freq_ACC <= 0;
            else
                Freq_ACC <= Fword_r + Freq_ACC;
    
        // 波形数据表地址
        wire [11:0] Rom_Addr;      
        assign Rom_Addr = Freq_ACC[31:20] + Pword_r;
        
        // 波形数据输出
        wire [13:0] Data_sine;
        wire [13:0] Data_square;
        wire [13:0] Data_transqure;
        
        // 实例化正弦波模块
        sine_wav sine_wav (
            .clka(Clk),         // 输入时钟
            .ena(1'b1),         // 使能信号置高
            .addra(Rom_Addr),   // 输入地址
            .douta(Data_sine)   // 输出正弦波数据
        );
        
        // 实例化方波模块    
        square_wav square_wav (
            .clka(Clk),         // 输入时钟
            .ena(1'b1),         // 使能信号置高
            .addra(Rom_Addr),   // 输入地址
            .douta(Data_square) // 输出方波数据
        );
        
        // 实例化三角波模块    
        triangular_wav triangular_wav (
            .clka(Clk),            // 输入时钟
            .ena(1'b1),            // 使能信号置高
            .addra(Rom_Addr),      // 输入地址
            .douta(Data_transqure) // 输出三角波数据
        );
        
        // 多路复用器根据 mode 选择波形数据输出
        always @(*) begin
            case (mode)
                2'b00: Data_out = Data_sine;      // mode = 00 时输出正弦波
                2'b01: Data_out = Data_square;    // mode = 01 时输出方波
                2'b10: Data_out = Data_transqure; // mode = 10 时输出三角波
                default: Data_out = 14'b0;        // 默认情况下输出0
            endcase
        end

endmodule

仿真使用的tb文件

`timescale 1ns / 1ps

module DDS_tb;

       reg                         Clk;
       reg                         Reset_n; 
       reg [31:0]                  Fword;
       reg [11:0]                  Pword;
       reg [1:0]                   mode;
       wire [13:0]                 Data_out;

    DDS DDS(
        .Clk(Clk),
        .Reset_n(Reset_n),
        .Fword(Fword),
        .Pword(Pword),
        .mode(mode),
        .Data_out(Data_out)
    );

    initial Clk = 1;
    always #10 Clk = ~Clk;
    
    initial begin
        Reset_n = 0;
        Fword = 85899345;  // 1M初始频率控制字设置为较大值
        Pword = 0;
        mode = 2'b00;  // 选择正弦波
        #201
        Reset_n = 1;
        #20000
        
        Fword = 42949673;  // 500k更改频率控制字,降低频率
        #20000
        
        Fword = 8589935;  // 100k更改频率控制字,进一步降低频率
        #20000
        
        $stop;  
        
//     initial begin
//        Reset_n = 0;
//        Fword = 85899345;
//        Pword = 0;
//        mode = 2'b00;  // 正弦波
//        #201
//        Reset_n = 1;
//        #100000
        
//        mode = 2'b01;  // 方波
//        #100000
        
//        mode = 2'b10;  // 三角波
//        #100000
        
//        $stop;  
    end

endmodule

修改波的类型为模拟信号即可,对于方波这种还需要进行以下设置。

完整工程资源

按理来说,可以通过博客就完成了,但如果你比较懒,你可以从这里下载完整工程。

基于FPGA的DDS信号仿真资源-CSDN文库

因为这个模块只是一个课程设计的一部分,涉及到通过串口控制的部分由其他同学负责,因此这里仅记录我所完成的部分。我对FPGA的理解还有限,后续不会对这方面进行答疑。

参考文章

DDS原理及FPGA实现_dds fpga-CSDN博客

基于FPGA的DDS算法实现(可调幅值,附ISE联合Modelsim仿真结果)-CSDN博客

基于FPGA的DDS信号发生器-CSDN博客 

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1888423.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Linux shell编程学习笔记61: pstree 命令——显示进程树

0 前言 在 Linux shell编程学习笔记59&#xff1a; ps 获取系统进程信息&#xff0c;类似于Windows系统中的tasklist 命令https://blog.csdn.net/Purpleendurer/article/details/139696466?spm1001.2014.3001.5501 中我们研究了ps命令。在Linux中&#xff0c;通过ps命令&am…

William Yang:从区块链先锋到艺术平台创始人

在区块链技术和加密货币市场飞速发展的今天&#xff0c;William Yang无疑是这一领域的佼佼者。他不仅在学术和媒体领域取得了显著成就&#xff0c;更在创业之路上不断探索&#xff0c;成为了业内知名的KOL&#xff08;关键意见领袖&#xff09;。今天&#xff0c;我们有幸采访到…

排序算法系列一:选择排序、插入排序 与 希尔排序

目录 零、说在前面 一、理论部分 1.1&#xff1a;选择排序 1.1.1&#xff1a;算法解读&#xff1a; 1.1.2&#xff1a;时间复杂度 1.1.3&#xff1a;优缺点&#xff1a; 1.1.4&#xff1a;代码&#xff1a; 1.2&#xff1a;插入排序 1.2.1&#xff1a;算法解读&#x…

mysql-sql-第十五周

学习目标&#xff1a; sql 学习内容&#xff1a; 41.查询没有学全所有课程的同学的信息 select *from students where students.stunm not in (select score.stunm from score group by score.stunm having count(score.counm) (select count(counm) from course)) 42.查询…

【C++/STL深度剖析】stack和queue的详细概念和使用(图文详解,初学者必看!!)

目录 一、前言 二、stack 的详细解析 &#x1f525; stack的介绍&#x1f525; &#x1f525; stack的构造&#x1f525; &#x1f525; stack的常用接口&#x1f525; &#x1f4a7;push &#x1f4a7;top &#x1f4a7;pop &#x1f4a7;empty &#x1f4a7;size…

违规停放智能监测摄像机

对于现代城市管理来说&#xff0c;违规停放智能监测摄像机正逐渐成为解决交通拥堵和城市管理难题的重要工具。这类摄像机通过先进的视觉识别和数据分析技术&#xff0c;有效监控和管理道路上的车辆停放行为&#xff0c;对提升城市交通运行效率和改善市民出行环境具有显著的意义…

pytorch-ResNet18简单复现

目录 1. ResNet block2. ResNet18网络结构3. 完整代码3.1 网络代码3.2 训练代码 1. ResNet block ResNet block有两个convolution和一个short cut层&#xff0c;如下图&#xff1a; 代码&#xff1a; class ResBlk(nn.Module):def __init__(self, ch_in, ch_out, stride):su…

锻炼 读书笔记 番外 身体激素及神经递质

最近在读《锻炼》的时候&#xff0c;对于各种激素很感兴趣&#xff0c;多巴胺、内啡肽、荷尔蒙、肾上腺素、褪黑素、皮质醇、糖化、氧化等等。索性认真梳理下它们是什么&#xff0c;思考当处于心流状态时&#xff0c;人体发生什么样的变化&#xff0c;分泌什么激素&#xff1f;…

Milvus ConnectionRefusedError: how to connect locally

题意&#xff1a;怎样在本地连接到 Milvus 数据库。连接 Milvus 数据库被拒绝的错误 问题背景&#xff1a; I am trying to run a RAG pipeline using haystack & Milvus. 我正在尝试使用 haystack 和 Milvus 运行一个 RAG&#xff08;检索增强型生成&#xff09;管道。 …

10 - Python文件编程和异常

文件和异常 在实际开发中&#xff0c;常常需要对程序中的数据进行持久化操作&#xff0c;而实现数据持久化最直接简单的方式就是将数据保存到文件中。说到“文件”这个词&#xff0c;可能需要先科普一下关于文件系统的知识&#xff0c;对于这个概念&#xff0c;维基百科上给出…

重温被Mamba带火的SSM:HiPPO的一些遗留问题

©PaperWeekly 原创 作者 | 苏剑林 单位 | 科学空间 研究方向 | NLP、神经网络 书接上文&#xff0c;在上一篇文章《重温被Mamba带火的SSM&#xff1a;线性系统和HiPPO矩阵》中&#xff0c;我们详细讨论了 HiPPO 逼近框架其 HiPPO 矩阵的推导&#xff0c;其原理是通过正交…

MySQL的Geometry数据处理之WKB方案

MySQL的Geometry数据处理之WKT方案&#xff1a;https://blog.csdn.net/qq_42402854/article/details/140134357 MySQL的Geometry数据处理之WKT方案中&#xff0c;介绍WTK方案的优点&#xff0c;也感受到它的繁琐和缺陷。比如&#xff1a; 需要借助 ST_GeomFromText和 ST_AsTex…

Gradio 教程四:Building Generative AI Applications with Gradio

文章目录 一、使用interface构建NLP应用1.1 构建文本摘要应用1.1.1 设置API密钥1.1.2 调用文本摘要API1.1.3 运行本地模型获取响应1.1.4 使用interface构建应用 1.2 构建命名实体识别应用1.2.1 调用NER任务API1.2.2 使用interface构建应用1.2.3 加入额外函数&#xff0c;合并to…

C语言实战 | 用户管理系统

近期推出的青少年防沉迷系统&#xff0c;采用统一运行模式和功能标准。在“青少年模式”下&#xff0c;未成年人的上网时段、时长、功能和浏览内容等方面都有明确的规范。防沉迷系统为青少年打开可控的网络空间。 01、综合案例 防沉迷系统的基础是需要一个用户管理系统管理用户…

Unity3d C#实现基于UGUI ScrollRect的轮播图效果功能(含源码)

前言 轮播功能是一种常见的页面组件&#xff0c;用于在页面中显示多张图片/素材并自动或手动进行切换&#xff0c;以提高页面的美观度和用户体验。主要的功能是&#xff1a;自动/手动切换;平滑的切换效果;导航指示器等。可惜Unity的UGUI系统里没有现成的实现该功能&#xff0c…

[Labview] 改写表格内容并储存覆盖Excel

在上一个功能的基础上&#xff0c;新增表格改写保存功能 [Labview] Excel读表 & 输出表单中选中的单元格内容https://blog.csdn.net/Katrina419/article/details/140120584 Excel修改前&#xff1a; 修改保存后&#xff0c;动态改写储存Excel&#xff0c;并重新写入新的表…

使用antd的<Form/>组件获取富文本编辑器输入的数据

前端开发中&#xff0c;嵌入富文本编辑器时&#xff0c;可以通过富文本编辑器自身的事件处理函数将数据传输给后端。有时候&#xff0c;场景稍微复杂点&#xff0c;比如一个输入页面除了要保存富文本编辑器的内容到后端&#xff0c;可能还有一些其他输入组件获取到的数据也一并…

Go - 8.func 函数使用

目录 一.引言 二.func 定义 三.func 实践 1.多个返回值 2.命名返回值 3.可变参数 四.总结 一.引言 函数是编程语言中的基本构建块&#xff0c;用于将代码组织成可重用的逻辑单元。函数可以接受输入参数&#xff0c;执行特定的操作&#xff0c;并返回结果。在 Go 语言&a…

设计IC行业SAP软件如何处理芯片成本计算

在集成电路(IC)设计与制造行业中&#xff0c;精确的成本计算对于维持健康的财务状况、优化生产流程以及保持市场竞争力至关重要。SAP软件&#xff0c;作为一种全面的企业资源规划(ERP)解决方案&#xff0c;为IC行业提供了强大且灵活的成本计算工具。以下是SAP软件如何处理芯片成…

【python】OpenCV—Feature Detection and Matching

参考学习来自OpenCV基础&#xff08;23&#xff09;特征检测与匹配 文章目录 1 背景介绍2 Harris角点检测3 Shi-Tomasi角点检测4 Fast 角点检测5 BRIEF 特征描述子6 ORB(Oriented Fast and Rotated Brief) 特征描述子7 SIFT(Scale Invariant Feature Transform) 特征描述子8 SU…