如何使用FPGA播放音频文件
内部集成电路音频接口(简称I2S)由飞利浦公司开发,用于通过串行接口在不同IC之间传输数字音频数据(例如从处理器到DAC)。该接口使用以下信号进行数据传输:
•SCK(串行时钟)——用于数据传输的时钟线。
•SD(串行数据)——每个数据字节的各个位通过此线路传输。
•WS(字选择)——用于定义所传输数据字的长度,同时用于标识左右音频通道。
I2S仅传输音频数据,而其他附加数据(如各总线用户的配置)则通过其他接口传输。数据传输始终单向进行,且发生在两个总线用户之间,其中总线用户需充当主控角色,并负责生成时钟信号。在包含多个发送器和接收器的复杂系统中,时钟信号由外部总线主控产生,而相应的发送器则生成数据。
所有数据均以二进制补码形式传输,且按最右边的最高有效位(MSB)优先。如果收发双方的数据宽度存在正向差异(即一方的数据宽度小于另一方),则剩余比特用0填充;若差异为负(即一方的数据宽度大于另一方),则剩余比特被忽略。根据规范,数据可同步到正或负时钟边沿,但数据始终在负时钟边沿读取。
WS信号用于选择激活通道,低相位或高相位内的所有数据将分别分配给对应的通道。具体如下:
•WS = 0 – 通道1(左)
•WS = 1 – 通道2(右)
WS信号必须在下一个数据字节的MSB之前一个时钟周期改变,以便接收端能够将数据正确读入相应通道。WS信号的时钟频率通常与音频信号的采样频率一致。
在第一部分,我将展示如何设计并使用一个简单的I2S发射器,通过CS4344立体声D/A转换器输出恒定的声音至扬声器。
要输出的声音数据存储在FPGA的块存储器中,由发射器读取后发送至D/A转换器。整个项目分为三个部分,我将逐步进行说明:
- 上层设计:集成系统时钟和I2S模块
- I2S模块:集成ROM与I2S发射器
I2S发射器
I2S发射器是本设计的下层核心,其任务是通过I2S接口传输单个数据字。
根据该设计的框图,发射器的结构如下:
数据字的大小由参数WIDTH定义。
一个三阶段状态机控制发射器,具体描述如下:
在复位期间,输出信号被清除,SCLK时钟被禁用。复位完成后,状态机从State_Reset状态切换到State_TransmitWord状态。在此状态下,机器通过I2S接口传输缓冲区Tx_Int中的内容。
一旦开始传输最后一个数据位,Ready状态将被设置为信号传输结束,并准备接收新数据。随后,机器进入State_LoadWord状态,发送缓冲区将被填充为新的数据字,从而启动新的传输。
I2S 模块
I2S 发射器由高层 I2S 模块使用,用于将数据从 ROM 传输到 D/A 转换器。
以下实体中:
参数 RATIO 和 WIDTH 分别定义了 SCLK 与 MCLK 的比例以及每个通道的数据字宽。
除了 I2S 发射器外,该模块还使用一个 ROM,可通过块存储器生成器创建,并用数据填充。这两个操作均可通过 Vivado 的 IP 集成器完成。
最后,通过“其他选项”使用正弦信号系数文件(参见附件)对 ROM 进行初始化。
I2S 模块使用状态机从 ROM 中读取数据,并将其传输至 I2S 发射器。
第一个过程用于根据 MCLK 生成发射器所需的时钟信号 SCLK。
第二个过程负责状态机的处理。在离开 Reset 状态后,状态机进入 WaitForReady 状态,等待发射器通过 Ready 信号发出就绪信号。
一旦发射器准备就绪,状态机将切换到 WaitForStart 状态,在此状态下,从 ROM 中读取当前数据字并传送到发射器。
此处显示的ROM仅包含一个通道的信息,第二个通道的数据需相应扩展。
一旦发射器清除就绪信号并开始传输数据,状态机将切换至State_IncreaseAddress状态。在此状态下,ROM地址增加1后,再返回State_WaitForReady状态。
顶层模块
最后一个组件是顶层设计,包含I2S模块和时钟生成向导。
本示例使用以下参数来控制CS4344:
•MCLK:12.288 MHz
•SCLK:1.536 MHz
•LRCLK:48 kHz
•RATIO:8
•WIDTH:16
时钟生成向导用于从可编程逻辑的振荡频率中生成12.288 MHz的时钟信号。为此,通过IP集成器插入时钟生成向导,并在VHDL代码中与完成的I2S模块一起实例化。
此时设计即可实现、上传至FPGA并进行测试。理想情况下,D/A转换器应输出480 Hz的正弦波信号,因为ROM中的信号模式长度为100个采样点,采样频率为48 kHz。通信及信号可通过示波器进行检查:
因此,可以检查音频信号。示波器的FFT功能是实现这一操作的理想工具。
在本教程的下一部分中,我们将为I2S发射器添加AXI-Stream接口,并将其连接到ZYNQ的处理系统,以从SD卡播放音频。
本文编译自hackster.io





