可变频率正弦信号发生器的FPGA实现(Quartus)

2023-10-29

一、说明

实现平台:Quartus17.1、MATLAB2021a和Modelsim SE-64 10.4

二、内容

1. 产生一个完整周期的正弦波信号,并保存为*.mif文件;

2. 设计一个ROM,将正弦波信号文件初始化如该ROM中;

3. 设计一正弦波信号发生器,按照读取步长,产生频率可变的正弦波信号;

4.编写测试文件,通过modelsim查看波形。

三、步骤

(1)设计要求

  •  要求设计一个可变频率的正弦波产生器,主要参数为:
  • 50MHz的主时钟clock,低电平有效复位,reset;
  • 输出正弦波,8位输出;
  • 通过改变读地址的步进值,使输出的正弦波频率可变。

(2)设计思路

        采用top_down设计思想,将正弦波产生器分为三个模块。分别是顶层模块A_sin_gen,子模块B1_addr和子模B2_sin。

 图1 设计的总体框图

       其中顶层模块主要定义输入输出关系,划分两个子模块的接口,搭建起两个子模块的框架,整个设计要素如图2所示:

 图2 顶层模块A_sin_gen的设计要素

       子模块B1_addr主要用来产生对ROM的寻址。按照时钟街拍,改变寻址的步进,就可以改变输出正弦波的频率。该模块可以采用简单的向上计数器产生。模块设计要素如图3所示:

图3. 子模块B1_addr的设计要素 

        子模块B2_sin则主要用LPM_ROM宏模块产生。

(3)具体实现

  1. 首先通过MATLAB产生产生长度1024,8Bits位宽的正弦信号,并生成mif文件,代码如下:
%%产生长度1024,8Bits位宽的正弦信号,并生成mif文件

depth =1024;                                %存储器的单元数1024
widths = 8;                                 %数据宽度为8位
fidc = fopen('sine.mif','wt');              %给文件命名
fprintf(fidc , 'depth = %d;\n',depth);      %在文件中打印 "depth=1024;"
fprintf(fidc, 'width = %d;\n',widths);      %在文件中打印  width=8;”
fprintf(fidc, 'address_radix = UNS;\n');    %在文件中打印  address_radix = UNS;”
fprintf(fidc,'data_radix = UNS;\n');        %在文件中打印  “data_radix = UNS;”
fprintf(fidc,'content begin\n');            %在文件中打印   content begin 

for(x = 1 : depth)
fprintf(fidc,'%d:%d;\n',x-1,round(127*sin(2*pi*(x-1)/256)+128));
end
fprintf(fidc, 'end;');
fclose(fidc);

2.打开quartus新建工程,首先设计顶层模块,代码如下:

//-------------------------------------
//Date:Nov,15th,2022-----------------
//Author:Zhuzi------------------------
//Description:Generate variable frequency sine wave.
//Version:1.0--------------------------
//-------------------------------------

module a_sin_gen(clk,rst_n,sin_wave);
	input 				clk;            //时钟信号50MHz
	input 				rst_n;          //复位信号
	output [7:0] 		sin_wave;       //正弦信号

	wire   [9:0] 		RD_addr;        //rom地址
	wire   [7:0] 		sin_out;	    //读取正弦信号
	
B1_addr u1(                             //例化模块1
	.clk	(clk),
	.rst_n	(rst_n),
	.RD_addr(RD_addr)	
);

B2_sin u2(                              //例化模块2
	.clk	(clk),
	.add_in	(RD_addr),
	.sin_out(sin_out)
);

assign sin_wave = sin_out;              //输出正弦信号
	
endmodule	

​

3.接着按顺序设计模块1和模块2。子模块B1_addr用来产生对ROM的寻址,代码如下:

module B1_addr(clk,rst_n,RD_addr);
	input 			clk;
	input 			rst_n;
	output 	[9:0] 	RD_addr;

	parameter 		step = 5;//ROM寻址步长
	reg 	[9:0] 	addr;

assign RD_addr = addr;

always @(posedge clk or negedge rst_n)begin
	if(!rst_n)
		addr <= 0;
	else addr <= addr + step;
end

endmodule

4.子模块B2_sin需要调用LPM_ROM宏功能模块,根据设计要求,ROM核的设置如下:

 

 子模块B2_sin代码如下:

module B2_sin(clk,add_in,sin_out);
	input 			clk;
	input 	[9:0] 	add_in;
	output 	[7:0] 	sin_out;
	
sin_rom_p u3(
	.address(add_in),
	.clock(clk),
	.q(sin_out)
);

endmodule

 5.程序设计完成后点击综合,只要综合完成即可进行下一步。

设计完成后可以看到RTL原理图如下所示,基本符合预期。

 6.TestBench程序编写如下:

`timescale 1 ns/ 1 ns
module a_sin_gen_vlg_tst();

reg             clk;
reg             rst_n;                                           
wire [7:0]     sin_wave;
                        
a_sin_gen i1 (  
	.clk(clk),
	.rst_n(rst_n),
	.sin_wave(sin_wave)
);

initial                                                
begin                                                  
	clk = 0;
	rst_n = 0;
	#100;
	rst_n = 1;	
end 
                                                   
always #10 clk = ~clk;
                                                   
endmodule

(4)仿真结果 

 1.修改子模块1中的parameter参数即可改变步长,当ROM寻址步长为10时,测试仿真波形如下图所示:

2. 当ROM寻址步长为5时,测试仿真波形如下图所示:

通过上述结果可知,改变寻址步长即可调整产生正弦波的频率,表明实验成功。 

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

可变频率正弦信号发生器的FPGA实现(Quartus) 的相关文章

  • 使用 libsvm 交叉验证后重新训练

    我知道交叉验证用于选择好的参数 找到它们后 我需要在不使用 v 选项的情况下重新训练整个数据 但我面临的问题是 在使用 v 选项训练后 我得到了交叉验证精度 例如 85 没有模型 我看不到 C 和 gamma 的值 在这种情况下我该如何重新
  • 如何将Matlab代码库与Android集成?

    我有一个算法和 MATLAB 中的一些其他代码 我想在我的 Android 应用程序中使用它 我怎样才能做到这一点 我可以从 MATLAB 制作 jar 文件以便与 Android 一起使用吗 我必须做点别的事吗 如果您还有其他产品 适用于
  • 如何使用Matlab提高PSD的分辨率

    我有音频信号 我用 Matlab 读取该信号 并使用 pwelch 获取其 PSD 这是我正在使用的代码 x Fs audioread audioFile wav x x 1 mono xPSD f pwelch x hamming 512
  • Microsoft Visual C++ 2008 和 R2007b 的 Mex 类型

    我想对 vs2008 和 matlab2007b 使用 mex 类型 我尝试了下面的代码 include
  • 查找数组中元素之间的平均差异的有效方法

    希望标题不会让人困惑 通过例子来展示很简单 我有一个像这样的行向量 1 5 6 我想找到每个元素之间的平均差异 此示例中的差异为 4 和 1 因此平均值为 2 5 这是一个小例子 我的行向量可能非常大 我是 MatLab 新手 那么有没有一
  • matlab矩阵中求子矩阵的通用方法

    我正在寻找一种 好 方法来在更大的矩阵 任意维数 中找到矩阵 模式 Example total rand 3 4 5 sub total 2 3 1 3 3 4 现在我希望这样的事情发生 loc matrixFind total sub 在
  • 如何读取 10 位原始图像?其中包含 RGB-IR 数据

    我想知道如何从我的 10 位原始 它有 rgb ir 图像数据 数据中提取 RGB 图像 如何使用 Python 或 MATLAB 进行阅读 拍摄时的相机分辨率为 1280x720 室内照片图片下载 https drive google c
  • opencv中矩阵的超快中值(与matlab一样快)

    我正在 openCV 中编写一些代码 想要找到一个非常大的矩阵数组 单通道灰度 浮点数 的中值 我尝试了几种方法 例如对数组进行排序 使用 std sort 和选择中间条目 但与 matlab 中的中值函数相比 它非常慢 准确地说 在 ma
  • 在 Matlab 中快速加载大块二进制文件

    我有一些相当大的 int16 格式的数据文件 256 个通道 大约 75 1 亿个样本 每个文件约 40 50 GB 左右 它以平面二进制格式编写 因此结构类似于 CH1S1 CH2S1 CH3S1 CH256S1 CH1S2 CH2S2
  • 如何从绘图处理程序中绘图?

    我有绘图的处理程序或图形的处理程序 例子 h plot 1 0 2 10 xx get h xx DisplayName Annotation 1x1 handle Color 0 0 1 LineStyle LineWidth 0 500
  • 通过傅里叶空间填充进行插值

    我最近尝试在 matlab 上实现一个在傅立叶域中使用零填充的插值方法的简单示例 但我无法正常工作 我总是有一个小的频移 在傅里叶空间中几乎不可见 但它在时空上产生了巨大的误差 由于傅里叶空间中的零填充似乎是一种常见 且快速 的插值方法 因
  • 为什么matlab的mldivide比dgels好这么多?

    Solve Ax b 真正的双 A是超定的 Mx2 其中 M gt gt 2 b是MX1 我运行了大量的数据mldivide 并且结果非常好 我用 MKL 写了一个 mex 例程LAPACKE dgels但它远没有那么好 结果有大量噪音 并
  • 在 Matlab 中显示有理数

    我有两个整数 m n 它们一起形成 m n 形式的有理数 现在我只想以这种理性的形式在 Matlab 中显示它们 我可以通过这样做来做到这一点 char sym m n 所以 如果 例如m 1 n 2 Matlab将显示1 2 然而 如果m
  • 优化 MATLAB 代码(嵌套 for 循环计算相似度矩阵)

    我正在 MATLAB 中基于欧几里德距离计算相似度矩阵 我的代码如下 for i 1 N M N is the size of the matrix x for whose elements I am computing similarit
  • 为什么 MATLAB 本机函数 cov(协方差矩阵计算)使用与我预期不同的除数?

    给定一个 M 维和 N 个样本的数据矩阵数据 例如 data randn N M 我可以计算协方差矩阵 data mu data ones N 1 mean data cov matrix data mu data mu N 如果我使用原生
  • 从 imread 返回的 ndims

    我正在从文件夹中选取图像 尺寸为128 128 为此 我使用以下代码行 FileName PathName uigetfile jpg Select the Cover Image file fullfile PathName FileNa
  • 归一化互相关的基础知识

    我正在尝试使用范数校正2 归一化互相关 http en wikipedia org wiki Cross correlation Normalized cross correlation 来自 MATLAB 用于计算发育中胚胎中移动形状的速
  • MATLAB 可执行文件太慢

    我使用以下命令将 MATLAB 程序转换为基于控制台的应用程序deploytool在 MATLAB 中 MATLAB m文件执行大约需要 2 秒 但在我将其转换为可执行文件并调用 exe 执行需要45秒 太长了 我想将 MATLAB 程序与
  • Matlab 一个图上有多个图例 2014b

    我想在一个地块上有多个传说 该解决方案在 2014b 版本之前完美运行 我试图弄清楚如何使用手柄优雅地制作它 但到目前为止还没有成功 欢迎任何想法 2013b 的示例 x 1 50 y1 sin x 2 y2 cos x 2 f figur
  • 从 MATLAB 调用 Java?

    我想要Matlab程序调用java文件 最好有一个例子 需要考虑三种情况 Java 内置库 也就是说 任何描述的here http docs oracle com javase 6 docs api 这些项目可以直接调用 例如 map ja

随机推荐

  • QT子线程中使用主线程的方法

    QT子线程中使用主线程的方法 QMetaObject invokeMethod p setText Q ARG const QString strNum 使用QMetaObject invokeMethod方法将setText函数在主线程运
  • 机器学习——信息熵与信息增益

    问 信息熵越大说明其纯度越高 答 错误 信息熵越小 说明数据集的纯度越高 信息熵是衡量数据集纯度的指标之一 它是对数据集中所有类别出现概率进行加权平均所得到的一个值 信息熵是度量样本集合纯度 不确定度最常用的指标之一 但要注意 信息熵越小
  • 【Mac】mac安装redis客户端 Error: Cask ‘rdm‘ is unavailable: No Cask with this name exist

    1 概述 mac安装redis客户端 rdm 报错如下 lcc lcc brew cask install rdm Updating Homebrew Error Cask rdm is unavailable No Cask with t
  • java——线程池

    一 线程池 线程池可以看做是线程的集合 它的工作主要是控制运行的线程的数量 处理过程中将任务放入队列 然后在线程创建后 启动这些任务 如果线程数量超过了最大数量超出数量的线程排队等候 等其它线程执行完毕 再从队列中取出任务来执行 他的主要特
  • 重写equal()时为什么也得重写hashCode()之深度解读equal方法与hashCode方法渊源

    今天这篇文章我们打算来深度解读一下equal方法以及其关联方法hashCode 我们准备从以下几点入手分析 1 equals 的所属以及内部原理 即Object中equals方法的实现原理 说起equals方法 我们都知道是超类Object
  • Android Hierarchy Viewer

    Android的SDK工具包中 有很多十分有用的工具 可以帮助程序员开发和测试Android应用程序 大大提高其工作效率 其中的一款叫Hierachy Viewer的可视化调试工具 可以很方便地帮助开发者分析 设计 调试和调整UI界面 提高
  • 高斯低通频率域滤波

    基本原理 频率域滤波 即将原图像通过傅里叶变换 转换至频率域 在频率域利用该域特有的性质进行处理 再通过傅里叶反变换把处理后的图像返回至空间域 所以 频率域的操作是在图像的傅里叶变换上执行 而不是在图像本身上执行 高斯低通滤波器传递函数表达
  • 跟着 iLogtail 学习设计模式

    设计模式是软件开发中的重要经验总结 Gang of Four GoF 提出的经典设计模式则被誉为设计模式中的 圣经 但是设计模式往往是以抽象和理论化的方式呈现 对于初学者或者没有太多实战经验的开发者来说 直接学习设计模式往往会显得枯燥乏味
  • c++ parse html,c++ - QT parse html to txt file - Stack Overflow

    I think it s always best if you actually attempt at something and post up your code to serve as a starting point But I m
  • 小径

    尽入夏 绕竹篱 已是桃花稀落 笑到西川 此去随所遇 不羡青山不拜仙 园中花草 草木香幽 清风独得朝暮暖 蕲水携来四季春 云岩宫阙 尽是人间 峰峦断却处 本是一脉之水 两侧命不相同 一水之门 几多思量 几多判却 一方玲珑剔透 嬉水无痕 一方藻
  • 计算机网络——第四章

    网络层 主要任务是把分组从源端传送到目的端 为分组交换网上的不同主机提供通信服务 传输单位是数据报 功能 1 路由选择与分组转发 2 异构网络互联 3 拥塞控制 若所有节点都来不及接受分组 而要丢弃大量分组的话 网络就处于拥塞状态 因此要采
  • python数据库-NumPy与Matplotlib库

    NumPy 1 导入numpy库 import numpy as np python中用import导入库 这里的意思是将怒骂朋友作为np导入 通过这样的形式 之后使用numpy相关方法用np使用 2 生成numpy数组 import nu
  • LeetCode--数组类算法:删除排序数组中的重复项 II

    题目 给定一个排序数组 你需要在原地删除重复出现的元素 使得每个元素最多出现两次 返回移除后数组的新长度 不要使用额外的数组空间 你必须在原地修改输入数组并在使用 O 1 额外空间的条件下完成 示例一 给定 nums 1 1 1 2 2 3
  • 梳理webpack

    一 入门 1 项目初始化 新建一个目录 初始化npm npm init 此时会需要填入一些项目的基本描述 webpack是运行在node环境中的 我们需要安装以下两个npm包 npm i D webpack webpack cli 生成no
  • 【mcuclub】扫码枪-(型号:M100(1D)-TTL)(型号:GM861S)

    一 实物图 型号 M100 1D TTL 只能扫描一维条形码 二 原理图 编号 名称 功能 1 VCC 电源正 2 GND 电源地 3 TXD 串口数据发送引脚 接单片机上的RX引脚 4 RXD 串口数据接收引脚 接单片机上的TX引脚 三
  • Unity 处理mono内存(堆内存)泄露问题

    先讲解一下mono特性 一个很重要的信息 mono内存从系统里面申请的内存不会返回给系统 mono内存不足的时候会预申请内存 内存大小不定有可能10m有可能5m 最近优化一个mono内存泄露问题 引起mono一直撑大多数都是内存泄露 要不就
  • ArrayBlockingQueue和LinkedBlockingQueue

    ArrayBlockingQueue ArrayBlockingQueue是一个用数组实现的有界阻塞队列 其是线程安全的 内部通过 互斥锁 保护竞争资源 此队列按照先进先出 FIFO 的原则对元素进行排序 队列的头部是在队列中存在时间最长的
  • el-tabs组件切换之前拦截函数异常踩坑记录

    背景 产品需求在离开当前tab之前要对页面填写信息进行校验 若没有任何改动则可以直接切换tab 若有改动 则需要在跳转之前进行拦截 提示用户 当前页面信息未保存 确定离开吗 确定或取消由用户选择 代码实现
  • 逆向工程核心原理——DLL注入——创建远程线程

    什么是DLL注入 dll注入是一种将Windows动态链接库注入到目标进程中的技术 具体的说 就是将dll文件加载到一个进程的虚拟地址空间中 对某个进程进行dll注入 也就意味着dll模块与该进程共用一个进程空间 则这个dll文件就有了操纵
  • 可变频率正弦信号发生器的FPGA实现(Quartus)

    一 说明 实现平台 Quartus17 1 MATLAB2021a和Modelsim SE 64 10 4 二 内容 1 产生一个完整周期的正弦波信号 并保存为 mif文件 2 设计一个ROM 将正弦波信号文件初始化如该ROM中 3 设计一