国产高云FPGA基于麦克风阵列采集

本文章为笔者学习国产高云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滤波器的信息可以查看:

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验证音频正确性

总结:通过此次实验可以基本采集多麦克风阵列的音频信号,并通过上位机进行验证,其声音信号的信噪比与麦克风标定基本一致,底噪较小,能够精准采集单频、扫频、人声。

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值