简书 https://www.jianshu.com/p/f5e17ee2fd25html
文章代码托管在Delta-sigma-ADC-verilog。quartus目录内包含SDcard .wav播放示例。git
FPGA实现音频输出的方式有:github
- 使用I2S DAC芯片。
- 直接经过引脚输出PWM(脉冲宽度调制)信号。
- 直接经过引脚输出PDM(脉冲密度调制)信号。
本文使用第三种方式PDM输出音频。这里使用Delta-sigma(ΔΣ)ADC产生PDM信号。ΔΣ ADC将模拟信号转成 PDM数字信号,PDM转成模拟信号只需外接低通滤波器。借用以上模拟的方法,使用FPGA进行全数字信号处理:code
读取PCM数字音频 -> ΔΣ 调制 -> 输出PDM -> 外部RC低通滤波htm
一阶ΔΣ调制器的方块图,数字滤波器改用外部RC滤波blog
ΔΣ 调制过程如上图所示,为方便解释,这里以有符号16bit PCM音频举例,16bit左边输入与1 bit DAC结果相减。1 bit DAC是指输入 1 ,输出 32767(16位有符号数最大值);输入 0 ,输出 -32768。相减结果的16bit符号数再进行一次积分,而后与 0 比大小,大于0输出1,小于等于0输出0。结果进入1 bit DAC反馈,以及输出为 1bit PDM信号。进行一次处理只输出了1bit PDM,须要将PCM数据保持住,一样的过程处理N次获得N位PDM,这N位PDM信号表明了原PCM数据的量化值。详细原理参见该文章。这里使用二阶ΔΣ:接口
二阶ΔΣ调制器的方块图ip
简单FPGA实现框图以下:ci
时钟未画出get
verilog:
/************************************************************************************ * Name :Delta sigma ADC * Description :2阶Delta sigma ADC,Generate PDM audio,din的采样率 应该比clk慢N倍, * N量化位数,N=32,64,128,256...,32bit以上时人耳听不出区别 * Interface :N/A * Origin :190811 * Author :helrori2011@gmail.com * Reference :https://www.cnblogs.com/sci-dev/p/10428042.html ************************************************************************************/ module delta_sigma_adc #( parameter W = 16//输入位宽 ) ( input wire clk , input wire rst_n , input wire signed [W-1:0] din ,//signed analog signal output reg dout //PDM signal ); wire signed [W-1:0]adc1b_max = {1'b0,{(W-1){1'b1}}}; wire signed [W-1:0]adc1b_min = {1'b1,{(W-1){1'b0}}}; wire signed [W-1:0]adc1b_out = (dout == 1'b1)?adc1b_max: (dout == 1'b0)?adc1b_min: 'bx; reg signed [W*2-1:0]inte0,inte1; wire signed [W*2-1:0]diff0 = din - adc1b_out; wire signed [W*2-1:0]rd0 = diff0 + inte0; wire signed [W*2-1:0]diff1 = rd0 - adc1b_out; wire signed [W*2-1:0]rd1 = diff1 + inte1; wire comp = (rd1 > 0)?1'b1:1'b0; always@(posedge clk or negedge rst_n)begin if ( !rst_n ) begin dout <= 1'b0; inte0 <= 'b0; inte1 <= 'b0; end else begin dout <= comp; inte0 <= rd0; inte1 <= rd1; end end endmodule
仿真:
dout=PDM
对该模块进行NATIVE FIFO接口的包装:
/************************************************************************************ * Name :PDM audio * Description :当音频采样率为48Khz,并选择量化位数为32时,clk频率=48Khz x 32 = 1.536Mhz * rdclk频率=48Khz,rddat数据速率与rdclk同样。rdclk能够由clk分频获得。 * Interface :Native FIFO * Origin :190812 * Author :helrori2011@gmail.com * Reference : ************************************************************************************/ module pdm_audio ( input wire clk ,// FREQ input wire rst_n , // connect to FIFO input wire rdaccess,// The FIFO data is ready,FIFO not empty input wire rdclk ,// FREQ/32=48Khz output reg rden , input wire [31:0] rddat ,// {L[31:16],R[15:0]},signed // microphone output wire pdm_r , output wire pdm_l ); reg [1:0]bf0; wire rdaccess_b = bf0[1]; always@(posedge rdclk or negedge rst_n)begin if(!rst_n)bf0<='b0;else bf0<={bf0,rdaccess};end always@(posedge rdclk or negedge rst_n)begin if ( !rst_n ) begin rden<=1'd0; end else begin if(rdaccess_b) rden<=1'd1; end end delta_sigma_adc #(.W ( 16 )) delta_sigma_adc_r ( .clk ( clk ), .rst_n ( rst_n ), .din ( rddat [15:0] ), .dout ( pdm_r ) ); delta_sigma_adc #(.W ( 16 )) delta_sigma_adc_l ( .clk ( clk ), .rst_n ( rst_n ), .din ( rddat [31:16] ), .dout ( pdm_l ) );
顶层使用pdm_audio.v,如需使用该模块,还须要外接32bit宽FIFO,暂存两个声道PCM数据。rdaccess用来告诉pdm_audio.v模块外部FIFO数据准备了一些,能够开始读FIFO。注意clk与rdclk频率相差N倍,N=32,64,128,256...
附 delta_sigma_adc.v的testbench:
`timescale 1ns / 1ps module tb_delta_sigma_adc; // delta_sigma_adc Parameters parameter PERIOD = 10; parameter W = 16; parameter N = 1024;//量化位数 // delta_sigma_adc Inputs reg clk = 0 ; reg rst_n = 0 ; reg signed [W-1:0] din = -32768 ; // delta_sigma_adc Outputs wire dout ; initial begin forever #(PERIOD/2) clk=~clk; end reg [31:0]cnt=0; always@(posedge clk)begin if(cnt == N-1) cnt <= 'd0; else cnt <= cnt + 1; if(cnt == N-1) din <= din + 1000; end delta_sigma_adc #( .W ( W )) u_delta_sigma_adc ( .clk ( clk ), .rst_n ( rst_n ), .din ( din [W-1:0] ), .dout ( dout ) ); initial begin $dumpfile("wave.vcd"); $dumpvars(0,tb_delta_sigma_adc); #(PERIOD*2) rst_n = 1; #(PERIOD*N*80)//65536 $finish; end endmodule
参考备忘用途
引用:http://www.noobyard.com/article/p-bxsiavpa-bz.html