FPGA微型板Verilog简单音频

2023-11-12

简单音调生成

该模块通过使用一个计数器生成一个1 kHz的信号,该计数器在CLK的每个刻度上都递增。 当计数器达到32,000时,将切换输出BUZZER,并将计数器重置为0。

音频输出

使用一个1-kΩ电阻器和一小段实心线将GPIO引脚P97和GND连接到与有源扬声器相连的音频引线。 导线和电阻器引线仅缠绕在音频插孔的接地和插孔插头的尖端部分周围。

您可能想使用一些排针和一个3.5mm直插式插座来做一些实质性的事情。

通用音/频率发生器

我们制作一个通用的音调发生器模块,该模块将针对您的电路板的时钟频率进行参数设置,并且还允许您指定要产生的音调作为其输入之一。

该模块的测试程序不会通过音频插孔播放生成的频率,而是会在FPGA板的三个不同引脚上生成三个不同的频率。 如果您的示波器或万用表具有频率设置,那么您将能够验证所产生的信号。 如果您不这样做,则按照“警报”项目,将其中一个“音调” NET的位置(LOC)更改为音频插孔,并通过放大器收听音调,尽管您可能很难听到12.5- kHz音调。

音调模块具有系统时钟(CLK)的输入以及要生成的音调周期(以微秒为单位)和tone_out的单个输出。 参数CLK_F用于配置模块的预分频器以适合您电路板的时钟频率。 使用周期而不是频率的原因是将频率转换为要在Verilog中计数的多个时钟周期将需要除法。 在不使用除法模块的情况下,无法在Verilog中除2的幂(1、2、4、8、16等)以外的任何东西,否则将需要除以一个时钟周期来执行。

时钟的频率是每秒的完整周期数(从0到1再回到0)。 时钟周期是一个周期所花费的时间。 因此,对于非常慢的1 Hz时钟(每秒1个周期),周期为1秒。 对于1 MHz时钟,周期为1 / 1,000,000秒或1微秒。

对于特定频率f,周期为1 / f。下表中列出的周期代表您可能希望与音频模块一起使用的一些值得注意的频率。

使用两个计数器。 预分频器计数器将时钟频率降低到2 MHz,并且计数器用于计数预分频的时钟。 预分频器生成2MHz时钟而不是1MHz时钟,因为每次到达正确的周期时,输出将被切换(0至1或1至0),从而有效地将频率减半。 这种切换可确保生成的信号具有50%的占空比。 即,方波的大小相等且高低。

tone_tester模块会创建音频模块的三个实例,每个实例都在不同的引脚上,并且以不同的频率。 实际上,period_12khz实例将产生12.5 kHz而不是12 kHz的频率。

FPGA微型板端口示意图

播放音频文件

该项目使用FPGA通过放大器播放录制的音频数据。 它介绍了一些有用的新技术,包括使用随机存取存储器(RAM)以及如何在合成期间将其与一组数据一起加载。

音频文件

音频文件的类型很多,大多数使用聪明的压缩算法来尽可能地减小文件的大小,而质量的损失则尽可能小。 简单来说,一个音频文件将只包含一系列数字,每个数字代表一个瞬间的振幅(思考电压)。 这种格式称为原始格式,因为没有花哨的数字。 下图显示了一个我说“一”字的样本数据。“一个”音频样本的波形。

每个采样点的数值都保存在一个字节(8位)中,范围为0到255之间的数字。声音是以8 kHz采样的,因此大约3,800个采样代表不到半秒的音频。

诸如Audacity(www.audacityteam.org/)之类的软件工具将使您可以录制自己的音频文件或以几乎任何格式导入音频文件,然后将结果保存为原始数据。 稍后,在“准备自己的声音”部分中,您将学习如何使用Audacity和一个小的Python脚本将原始声音文件转换为适合导入FPGA的格式。

RAM

要播放的声音将保存在FPGA的内存(RAM)中。 三个示例板上使用的所有FPGA(实际上,大多数FPGA)都有专用于RAM的FPGA芯片区域。 当ISE在您的Verilog中发现看起来像内存的reg声明时,它将使用此专用块而不是通用单元。

RAM将具有许多输入地址线和输出数据线。 您在地址行上以二进制形式设置一个数字,以指定要访问的存储字节。 然后,您可以读取或写入当前选定的字节。 更改地址,即可访问其他字节的数据。 尽管RAM的全部目的是您可以对其进行读取和写入,但在此项目中,RAM在合成期间会用文件中的初始内容填充,然后保持不变。

wav_player模块

要播放声音文件,可使用一个计数器依次遍历每个地址。 然后使用PWM输出每个位置的值。 该模块具有CLK和switch_play的输入,用于在按下开关时触发要播放的声音文件:

接下来,有一个本地参数来保存音频文件中包含的数据字节数。 用于指定内存的格式类似于常规的reg声明,除了在指定名称之后还要指定数据的每个元素的大小(7:0)之外,还指定此类内存位置的数量(MEM_SIZE-1:0) 内存(memory)的:

为了控制声音文件的播放,使用了注册播放。 这充当一个触发器,用于打开和关闭到地址计数器的脉冲。 预分频器计数器用于降低电路板的时钟频率以匹配电路板的采样率。 8位计数器用作PWM计数器,而值则用于当前由address引用的存储器的内容。

下图展示了所有这些东西如何相互联系。 它还提供了有关Verilog可能合成的线索。声音文件播放器的示意图。

always块仅在播放为1时才递增预分频器计数器。如果您跳到Always块的末尾,您将看到按下“开始”按钮时发生。 假定已按下按钮,预分频器将时钟频率从50 MHz输入时钟分频到2 MHz。 然后计数器增加,并且来自当前存储位置的数据被锁存到value中。 然后将当前存储位置的值与适当设置的counter和audio_out进行比较。

这将导致PWM输出的脉冲在高振幅时较长,而在低振幅时较短。 当地址的值达到MEMORY_SIZE时,播放会被重置以停止预分频器的计时并阻止进一步的音频播放,直到再次按下该按钮:

测试

准备您的声音

准备自己的声音文件非常简单。 主要问题是使其足够短以适合RAM。 首先安装并运行Audacity。 Audacity适用于Windows,Mac和Linux,并且是免费的。 开始一个新项目,并确保将“ Project Rate”设置为8 kHz,并将录音设置为“ mono”(下图)。 单击红色的圆形“记录”按钮进行简短记录。

录制完成后,按“停止”按钮(黄色正方形),您将看到录制的波形。 如果波形有点平坦,您可以再次记录它,但可以大声讲话,或者通过选择菜单上的Effect Ampilfy…选项以数字方式放大信号。 您可能还希望从记录的开始和结束处消除任何静音,方法是选择要删除的波形部分,然后按DELETE键。

现在,您需要以非常特殊的格式导出声音文件,因此选择菜单选项“文件导出音频”。…您需要选择“其他未压缩”文件类型,然后在标题字段中选择“ RAW”(无标题),然后 在编码字段中,选择“无符号8位PCM”。 然后点击“保存”以创建文件(下图)。

您刚刚创建的文件是二进制文件,并将其放入适合$readmemh文件的格式,需要将其转换为带有两位十六进制字符串的文本文件,每行一个,如以下示例所示:

要进行此转换,您可以使用为此目的创建的Python脚本(本文源码中包含脚本)。 在运行此脚本之前,您需要安装Python。安装细节请参考Python官网,在此不赘述。

将导出的声音文件与脚本放置在同一文件夹(“实用程序/音频”),然后使用以下命令从命令行运行该程序:

第一个参数(在本例中为01_05.aiff)是要转换的声音文件的名称,第二个参数(01_05.txt)是输出文本文件。 该实用程序可以帮助您告知所生成数据的大小,以便在构建项目之前可以使用它在wav_player中设置MEM_SIZE。

源码

详情参阅 - 亚图跨际

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

FPGA微型板Verilog简单音频 的相关文章

  • 「Verilog学习笔记」 Johnson Counter

    专栏前言 本专栏的内容主要是记录本人学习Verilog过程中的一些知识点 刷题网站用的是牛客网 timescale 1ns 1ns module JC counter input clk input rst n output reg 3 0
  • 解决:soundfile打开opus文件出错: File contains data in an unimplemented format.

    Python的soundfile库依赖于libsndfile库 需要安装最新版本 sudo apt get update sudo apt get install libsndfile1 如果之前已经安装soundfile 则可能采用了旧版
  • 异步FIFO设计之格雷码

    目录 二进制转格雷码 格雷码转二进制 相邻的格雷码只有1bit的差异 因此格雷码常常用于异步fifo设计中 保证afifo的读地址 或写地址 被写时钟 或读时钟 采样时最多只有1bit发生跳变 在不考虑路径延时的情况下 因为源数据 读写地址
  • 异步FIFO设计之格雷码

    目录 二进制转格雷码 格雷码转二进制 相邻的格雷码只有1bit的差异 因此格雷码常常用于异步fifo设计中 保证afifo的读地址 或写地址 被写时钟 或读时钟 采样时最多只有1bit发生跳变 在不考虑路径延时的情况下 因为源数据 读写地址
  • 用于 Verilog 或 SystemVerilog 的 TAP(测试任何协议)模块

    是否有 TAP 测试任何协议 http testanything org Verilog 的实现 那就太好了 因为这样我就可以使用证明来自动检查我的结果 更新 10 9 09 有人问为什么不使用断言 部分 TAP 为我提供了一些很好的报告
  • 如何在verilog中逐行读取文本文件?

    我有一个 SREC 文件 它是一个简单的文本文件 我想在 verilog 中逐行读取它 我怎样才能做到这一点 以下读取文件 每个时钟周期 1 行 预期的数据格式是每行一个十进制数 integer data file file handler
  • VHDL门控时钟如何避免

    我收到了避免使用门控时钟的建议 因为它可能会导致松弛和时序限制问题 但我想问一下我可以认为什么是门控时钟 例如 此代码对时钟进行门控 因为 StopCount 对它进行门控 process ModuleCLK begin if rising
  • Verilog:添加寄存器的各个位(组合逻辑,寄存器宽度可参数化)

    我正在尝试想出一种方法来添加寄存器的各个位 例如 if regA 111000 then regB 3 位的总和regA 1 Verilog或SystemVerilog中是否有可以直接使用的可综合函数 运算符来执行此操作 如果不是 那么问题
  • verilog 中的“<<”运算符

    我有一个verilog代码 其中有一行如下 parameter ADDR WIDTH 8 parameter RAM DEPTH 1 lt lt ADDR WIDTH 这里将存储什么RAM DEPTH以及什么是 lt lt 操作员在这里做
  • 如何获取值数组作为 plusargs?

    如何获取值数组作为参数 我需要从命令行获取一组未定义大小的命令 如何将这些参数放入数组或队列中 Eg CMDS READ WRITE READ N WRITE 它应该被带到一个数组中 value plusargs不支持数组 但支持字符串 看
  • 如何在 Verilog 中综合 While 循环?

    我尝试设计一个 Booth 乘法器 它在所有编译器中运行良好 包括 Modelsim Verilogger Extreme Aldec Active Hdl 和 Xilinx Isim 我知道模拟和综合是两个不同的过程 而且只有少数Veri
  • 向左旋转 verilog 大小写

    我的任务是用verilog编写一个16位ALU 当我做需要旋转操作数和进行2的补码加法和减法的部分时 我发现了困难 我知道如何用纸和铅笔解决这个问题 但我无法弄清楚如何在 Verilog 中做到这一点 例如 A表示为a15 a14 a13
  • FPGA大输入数据

    我正在尝试向 FPGA 发送 4 KB 字符串 最简单的方法是什么 是我正在使用的fpga的链接 我正在使用 Verilog 和 Quartus 您的问题的答案在很大程度上取决于将数据输入 FPGA 的内容 即使没有您需要遵守的特定协议 S
  • 在 Verilog 中判断总线是否包含单个 x 的最佳方法是什么?

    我有一个监控总线的测试台 总线内的一些信号 位 可以是 1 bx 由于多种原因 我需要知道总线内是否有任何信号是 1 bx 如果总线包含任何 x 测试 不用于综合 仅用于模拟目的 的最佳方法是什么 我曾希望我可以使用减少或然后使用 但这似乎
  • 从 OpenCV 代码到 FPGA 代码的转换是否比 Matlab 代码更容易? [关闭]

    Closed 这个问题正在寻求书籍 工具 软件库等的推荐 不满足堆栈溢出指南 help closed questions 目前不接受答案 我想做一个关于图像处理的项目 我想知道如果我想在FPGA上实现这个项目 我应该在第一阶段选择Matla
  • 我怎样才能让我的verilog移位器更通用?

    这里我有一个移位器 但现在它最多只能工作 3 位 我一直在寻找 但不知道如何让它工作最多 8 位 module shifter a b out input 7 0 a b output 7 0 out wire 7 0 out1 out2
  • 如何在 Verilog 中推断 Block RAM

    我在一个项目中遇到了一个非常具体的问题 这个问题已经困扰我好几天了 我有以下 RAM 模块的 Verilog 代码 module RAM param clk addr read write clear data in data out pa
  • reg 声明中的位顺序

    如果我需要使用 4 个 8 位数字 我会声明以下 reg reg 7 0 numbers 3 0 我对第一个和第二个声明 7 0 和 3 0 之间的区别感到很困惑 他们应该按什么顺序来 第一个是保留数字的大小 而第二个是保留数字的数量 还是
  • 使用正则表达式进行 Verilog 端口映射

    我有一个很长的端口映射 我想在其中替换一堆 SignalName i with SignalName SignalName i 我想我可以用正则表达式轻松地做到这一点 但我无法弄清楚如何做到这一点 有任何想法吗 假设 SignalData
  • 如何修复实例上的错误:未定义的变量 B?

    我想编译此 Verilog 代码 但在实例中出现错误B模块中的MultiP module error 1 Undefined variable B error 2 near Adder1 syntax error unexpected ID

随机推荐

  • Pnpm:高性能的 npm

    pnpm 英文里面的意思叫做 performant npm 意味 高性能的 npm 官网地址可以参考 https pnpm io 什么是pnpm Pnpm 本质上就是一个包管理器 这一点跟 npm yarn 没有区别 但它作为杀手锏的两个优
  • python中对于bool布尔值的取反

    背景 根据公司业务的需求 需要做一个对于mysql数据库的大批量更新 脚本嘛也是干干单单 使用了redis的队列做缓存 可以异步并发的多任务进行更新 有点难受的地方在于 请求访问时 因为一些网速 速率之内的原因 导致正常的数据会请求失败 处
  • 游戏在计算机丢失,运行游戏时提示丢失d3dx9_43.dll的多种解决方法

    很多人遇到dll文件被丢失首先想到的就是电脑被中毒了 电脑被入侵了 其实往往都是自己对电脑的认识不够深而导致遇到一些小故障就盲目不知道该如何下手 当然遇到没有找到d3dx9 43 dll我们该怎么办呢 下面就来好好认识这个d3dx9 43
  • layui table默认选中指定行

    表格默认选中行 在回调里写入 done function res curr count tableData res data data field id css display none var data res data var num
  • win10系统谷歌浏览器怎么用不了?谷歌浏览器打不开网页的解决方法

    1 我们下载好谷歌浏览器后 搜索时 界面一直卡在主界面 一直在刷新 就是弹不出东西 2 通过设置来是谷歌浏览器可以进行搜索 点击右上角的三个小黑点 在下拉界面中点击 设置 3 在 地址了使用的搜索引擎 后面 点击Google后面的小三角 选
  • 【Linux】进程地址空间

    需要云服务器等云产品来学习Linux的同学可以移步 gt 腾讯云 lt gt 阿里云 lt gt 华为云 lt 官网 轻量型云服务器低至112元 年 新用户首次下单享超低折扣 目录 一 虚拟地址 二 对进程地址空间的理解 三 32位下的进程
  • STM32CubeMX时钟源的选择

    使用STM32CubeMX进行时钟源RCC配置的时候 可以选择使用内部时钟或外部时钟 当程序对时钟精度要求较高时 通常使用外部时钟 下拉选框如下图 Disable 禁用外部时钟 BYPASS Clock Resource 外部有源晶振 旁路
  • 在windows上使用ubuntu(非虚拟机模式)

    工具 wsl ubuntu20 04 步骤 在powershell下执行wsl install等待进度条完成 在控制面板 gt 程序 gt 启用或者关闭windos功能 勾选适用于Linux的windos子系统 任务栏的搜索框输入Micro
  • python实验总结_python实训总结和体会_python实训心得体会 - CSDN

    1 字符串格式化表达式 功能 生成一个特定格式的字符串运算符 语法格式 格式化字符串 参数值或格式化字符串 参数值1 参数值2 参数值3 描述 左边是字符串的格式 右边是参数值 当有多个参数值 使用括号 分离格式字符串并使用一个逗号 分隔格
  • MySQL删除数据库

    删除数据库是指在数据库系统中删除已经存在的数据库 数据库删除之后 原来分配的空间将被收回 需要注意的是 数据库删除之后该数据库中所有的表和数据都将被删除 因此删除数据库要特别小心 一 通过SQL语句 MySQL中 删除数据库通过SQL语句D
  • tensorflow学习(二)——训练分类时,对图像进行增强(基于tf.image存在的一些问题)

    0 写作目的 好记性不如烂笔头 1 图像分类时 图像的数据增强 在博主进行图像增强时 存在一些问题 和大家分享一下 1 1 使用tensorflow自带的读取图像函数存在的问题 如果采用直接读取图像的方式 使用tf image进行读取图像
  • zookeeper介绍

    1 简介 Zookeeper 分布式服务框架是Apache Hadoop 的一个子项目 它主要是用来解决分布式应用中经常遇到的一些数据管理问题 如 统一命名服务 状态同步服务 集群管理 分布式应用配置项的管理等 Zookeeper 作为一个
  • Spring-Data-Jpa AuditingEntityListener @CreatedDate @LastModifiedDate 用法

    import com fasterxml jackson annotation JsonIgnoreProperties import org hibernate validator constraints NotBlank import
  • OpenStack学习笔记(二)计算服务NOVA

    本篇记录OpenStack的计算服务NOVA一些内容 很多看不懂 汗 只捡一小部分记录 一 逻辑图 OpenStack 计算服务NOVA 是基础设施服务IAAS的主要部分 采用Python实现 1 因为认证 与OpenStack 身份认证k
  • 如何将GB7714-2015格式的参考文献表转换为bib文件

    如何将GB7714 2015格式的参考文献表转换为bib文件 1 背景 latex使用参考文献是一个自动化的工作 但建立和维护bib文件其实一个长期的积累活动 有些参考文献的bibtex数据是存在 比如从各类学术网站上可以下载到 但有些网站
  • NIO-DO Java 线上笔试(编程)题,蔚来汽车

    NIO DO Java 线上笔试 编程 题 1 使用二分查找的方式来定位某一元素 2 请用你熟悉的开发语言 完成如下题目 输入 若干个集合 各集合中的元素不会重复 输出 求这些集合的笛卡尔积例如 输入 N个集合 这里N 3 a b x y
  • Laravel-Dcat-layer 手写的弹窗样式

    Dcat admin框架下重新写的弹窗样式 实现设置固定最大高度弹窗滚动 实现更好的页面效果 public function layer return lt lt
  • python使用KDDockWidget

    编译原理 KDDockWidget是一个C 库 通过shiboken转成python的绑定支持 针对特殊版本 需要在cmake文件中增加一些变量 注 本次编译 Qt版本统一指定为6 4 2 库支持Qt gt 5 12或6 2 0以上版本 下
  • yolov5数据集制作

    yolov5 数据集的格式 每个图像的标注信息存储在一个独立的txt文件中 每个txt文件的名称应该与其对应的图像名称相同 只是文件扩展名不同 例如 对于名为 image1 jpg 的图像 其标注信息应存储在名为 image1 txt 的t
  • FPGA微型板Verilog简单音频

    简单音调生成 该模块通过使用一个计数器生成一个1 kHz的信号 该计数器在CLK的每个刻度上都递增 当计数器达到32 000时 将切换输出BUZZER 并将计数器重置为0 音频输出 使用一个1 k 电阻器和一小段实心线将GPIO引脚P97和