本文章为笔者学习国产高云FPGA的学习记录,如有不妥请指正。
闲来无事记录一下前段时间使用fpga采集麦克风阵列拾音的demo。使用高云GW2A系列开发板,采集64阵列MEMS数字麦克风信号,并通过以太网发送上位机进行验证。
1、PDM2PCM
1.1介绍PDM与PCM
首先我们要明确的是麦克风采集的原始音频是PDM脉冲信号,为了便于后续处理使用高云自带的IP核PDM2PCM对原始数据进行转换。
下面简单介绍一下两种类型。
PDM是一种不同的音频编码方式,它将模拟音频信号转换为脉冲序列,其中脉冲的密度表示音频信号的幅度变化。PDM编码中,每个采样点都用一个脉冲表示,脉冲的密度或者称为脉冲宽度表示音频信号的幅度。PDM编码的音频数据以高速脉冲序列进行传输和存储,需要通过滤波器进行后续处理才能得到原始音频信号。
PCM是一种常见的音频编码方式,它将模拟音频信号按照一定的采样率进行采样,并将每个采样值量化为离散的数字值。PCM使用固定的位数来表示每个采样值,例如16位PCM表示每个采样值用16位二进制数表示。因此,PCM编码的音频数据以固定的比特率进行传输和存储。
1.2PDM2PCM的实现
PDM2PCM 的实现是由 CIC Filter 以及 CIC Compensation Filter 两部分 组成。
CIC 滤波器是滑动平均滤波器的一种有效实现。
图 1-1 CIC Filter
如图 1-1 所示,CIC Filter 是由多阶积分滤波器和梳状滤波器级联而成的 滤波器。PDM2PCM 使用的抽取结构的 CIC filter,输入信号先后经过积分器, 降采样,以及梳状滤波器进行处理。
传递函数为:
图 1-2 Integrator Filter
积分器,如图 1-2 所示。积分器是单极点的 IIR 滤波器。状态方程为 𝑦[𝑛] = 𝑦[𝑛 − 1] + 𝑥[𝑛] 其中𝑦[𝑛]为当前状态输出,𝑦[𝑛 − 1]为上一次的输出,𝑥[𝑛]为当前输入。 传递函数为:
图 1-3 Comb Filter
梳状滤波器,如图 2-3 所示。梳状滤波器是对称 FIR 滤波器。状态方程 为: 𝑦[𝑛] = 𝑥[𝑛] − 𝑥[𝑛 − 𝑀] 其中𝑦[𝑛]为当前状态输出,𝑥[𝑛]为当前输入,𝑥[𝑛 − 𝑀]为 n-M 时刻的 x 输入。 传递函数为:
图 1-4 CIC Compensation Filter
更多关于CIC滤波器的信息可以查看:
- CIC Filter Introduction
-
Altera - Understanding CIC Compensation Filters,其中给出了生成CIC Compensation Filter Coefficients的MATLAB脚本
1.3 PDM2PCM ip核配置
- PDM 输入通道的数目可配置(1-8 个通道);
- PDM 的边沿识别方式可配置(上升沿识别,下降沿识别,双边沿识别);
- 可自定义加载 CIC Compensation Filter 的系数。
- PDM2PCM 的最大频率主要根据所用器件的速度等级(speed grade of the devices)确定,可达 80M。
- PDM2PCM 的延迟主要由配置参数来确定。
1.4PDM2PCM时序
1.41 PDM2PCM 单边沿时序
PDM2PCM IP,根据用户需要输出 PDM 时钟信号(out_pdm_sclk)。 通过获取多组通道的 PDM 输入有效数据(in_pdm_data[0-N])进行上/下 边沿采样,IP 经过一段处理时间,输出多组通道的有效数据,每组 0 通道以 同步信号( out_pcm_sync )进行区分。
1.42 PDM2PCM 双边沿时序
PDM2PCM IP,根据用户需要输出 PDM 时钟信号(out_pdm_sclk)。 通过获取多组通道的 PDM 输入有效数据(in_pdm_data[0-N])进行双边 沿采样,IP 经过一段处理时间,输出多组通道的有效数据,每组 0 通道以同 步信号( out_pcm_sync )进行区分。
更多ip用户指南可以查看:Gowin PDM2PCM (gowinsemi.com.cn)
2.FPGA设计模块
参考顶层代码如下:
包含PLL锁相环模块、pdm2pcm模块、fifo缓存模块、以太网发送模块
module top #(
parameter PDM_CHANNEL = 'd8,
parameter PCM_BITN = 'd16,
parameter PCM_DATA_pagNum = 16'd1024,
parameter PDM2PCM_IP = 'd4
) (
input sys_clk,
input rst_n,
input [PDM2PCM_IP*PDM_CHANNEL-1:0] pdm_data,
output [PDM_BLOCK-1:0] PDM_CLK,PDM_GND,
input RGMII_RXC,
output RGMII_GTXCLK,
output [3:0] RGMII_TXD,
output RGMII_TXEN
);
localparam PDM_BLOCK = 8;
assign PDM_GND = {PDM_BLOCK{1'b0}};
assign PDM_CLK = {PDM_BLOCK{pdm_clk}};
clk_gen clk_gen_1(
.clk50m(sys_clk),
.rst_n(rst_n),
.clk125m(GMII_GTXCLK),
.clk60m(clk60m),
.clkout1(pdm_clk)
);
//pdm2pcm
wire [PCM_BITN*PDM2PCM_IP-1:0] pcm_data_pag;
pdm2pcm_ctrl #(
.PDM_CHANNEL(PDM_CHANNEL),
.PDM2PCM_IP (PDM2PCM_IP),
.PCM_BITN (PCM_BITN)
)pdm2pcm_ctrl_i0(
.sys_clk (clk60m),
.rst_n (rst_n),
.ce (1'b1),
.PDM_SCLK (pdm_clk),
.pdm_data (pdm_data),
.out_pcm_valid_o(out_pcm_valid_o),
.out_pcm_sync_o (out_pcm_sync_o),
.pcm_data_pag (pcm_data_pag)
);
//fifo
wire [11:0] pcm_data_Rnum;
wire [7:0] tx_data;
fifo_ctrl #(
.PDM_CHANNEL(PDM_CHANNEL),
.PDM2PCM_IP (PDM2PCM_IP),
.PCM_BITN (PCM_BITN)
)fifo_ctrl_i0(
.rst (!rst_n) ,
.sys_clk (sys_clk),
.GMII_GTXCLK (GMII_GTXCLK) ,
.pcm_data (pcm_data_pag) ,
.pcm_vaild (out_pcm_valid_o) ,//pcm_vaild
.pcm_sync (out_pcm_sync_o) ,
.RdEn (tx_req),
.pcm_data_Rnum (pcm_data_Rnum),
.pcm_data_send (tx_data)
);
//udp_send
wire [15:0] tx_byte_num = PCM_DATA_pagNum;
assign tx_start_en = (pcm_data_Rnum > tx_byte_num-'b1) ? 1:0;
wire [7:0] GMII_TXD;
udp udp_i0(
.rst_n (rst_n), //复位信号,低电平有效
.gmii_tx_clk (GMII_GTXCLK), //GMII发送数据时钟
.gmii_tx_en (GMII_TXEN), //GMII输出数据有效信号
.gmii_txd (GMII_TXD), //GMII输出数据
.tx_start_en (tx_start_en), //以太网开始发送信号
.tx_data (tx_data), //以太网待发送数据
.tx_byte_num (tx_byte_num), //以太网发送的有效字节数 单位:byte
.tx_done (tx_done), //以太网发送完成信号
.tx_req (tx_req) //读数据请求信号
);
rgmii_tx u_rgmii_tx(
.gmii_tx_clk (GMII_GTXCLK ),
.gmii_tx_en (GMII_TXEN ),
.gmii_txd (GMII_TXD ),
.rgmii_txc (RGMII_GTXCLK ),
.rgmii_tx_ctl (RGMII_TXEN),
.rgmii_txd (RGMII_TXD )
);
endmodule
3.验证
该实验验证通过wireshark抓包获取原始音频数据并导入matlab进行解析,通过matlab解析成.mp4音频文件并导入AU进行音频分析,查看其每个声道的波形以及信噪比。
3.1 wireshark抓取udp发送数据
3.2 matlab解析抓包数据
3.3 导入AU验证音频正确性
总结:通过此次实验可以基本采集多麦克风阵列的音频信号,并通过上位机进行验证,其声音信号的信噪比与麦克风标定基本一致,底噪较小,能够精准采集单频、扫频、人声。