vhdl - VHDL 音频项目
问题描述
我正在尝试在 Nexys 4 DDR 板上尝试一个学校项目。我感兴趣的项目分为两部分:
使用板上内置的 PDM 麦克风模拟 Vu 表(分贝表)并在 16 个 LED 上显示。声音越大,点亮的 LED 越多。
通过将板上的 15 个开关转换为 15 位二进制数,生成 0 到 32,767 Hz 的声音频率(方波)。我打算使用 PWM 音频输出到扬声器来演示。
板上剩余的开关将用于在 2 种模式之间切换。我正在尝试在线研究各种项目,但大多数都不是开源的并且没有帮助。我完全不知道如何实现第一部分,并且对如何实现第二部分有一个粗略的想法。
对于第二部分,我计划使用时钟分频器来分频 100 MHz 时钟(引脚 E3),但也有点不确定如何做到这一点。理想情况下,我想以 1 Hz 的增量控制输出频率。例如,在 15 个开关输入中,如果最低有效位(我们称之为 switch[0])是唯一的 HIGH 位,则输出频率将为 1 Hz。如果 switch[1] 为 HIGH,则频率为 2 Hz。如果 switch[1] 和 switch[0] 都为 HIGH,则频率为 3 Hz。等等..
还应该说我对使用 FPGA 很陌生。
任何形式的帮助将不胜感激!
解决方案
如果您输入的音频是简单的音调,您可以使用音频信号的幅度来衡量响度;如果您有由多个频率组成的更复杂的声音,则需要先执行 FFT 以提取分量波形。从那里,选择您喜欢的频率并使用它。
对于 PWM,您有两种选择。首先是有一些计数器逻辑来创建一个新的时钟信号。不建议将此方法用于创建用于控制其他逻辑的时钟,因为它会产生严重的建立和/或保持违规。第二种是使用 PLL/DLL 从之前的时钟信号中生成新的时钟信号。这将比使用可配置逻辑生成它更稳定,并且可以根据需要用于控制其他寄存器,但它可以生成的时钟范围有限(通常为 ~1MHz 至 1GHz)。
第三个(更好的)是使用你的 100MHz 时钟,但只在特定时间启用更改;此方法的伪代码可能是:
Every (1MHz) clock cycle, counter = counter + 1
If counter = frequency value/2 (i.e. 50,000,00 for 1MHz, 16,666,666 for 3MHz, etc)
Instead, set counter to 0 and toggle the output signal
这将为您提供一个根据需要更改的信号(即每秒两次以产生 1MHz 信号),前提是您可以确定正确的频率值:)
推荐阅读
- xml - 如何在 svg 文件的中心旋转徽标圈?
- ios - 我怎样才能等到视图控制器完成呈现并关闭以运行下一行代码?
- python - 如何向 ArrayField 添加默认值数组?
- java - 双倍不在 if 条件下 - 最佳实践?
- c++ - 在主线程上启动对话框等待工作线程的结果
- javascript - React 警告:收到非布尔属性“my-optional-property”的“true”
- javascript - 使用计费周期锚计算条带按比例分配的费率
- mysql - 有没有办法为另一个操作系统创建编译文件?
- html - 按两列输入600px媒体查询时显示两个数据产品
- docker - Docker 或 symfony missconfig。错误 SQLSTATE[HY000] [2002] php_network_getaddresses: getaddrinfo failed: No such host is known