i2s
I2S简单介绍及接收端代码实现
简介
I2S(Inter-IC Sound)是一种数字音频传输协议,通常用于在数字音频设备之间传输音频数据。它是一种同步的串行数据传输协议,用于将音频信号从一个设备传输到另一个设备,例如从麦克风到音频编解码器、音频接口到音频处理器等。
接口定义
- SCLK:对应数字音频的每一位数据,$f_{SCLK}=2采样频率采样位宽$。
- LRCLK:用于同步左右声道的采样数据,低电平为左声道,高电平为右声道。
- SDATA:使用二补码表示的音频数据。
- MCLK:高速率主时钟
接口时序
可以看到LRCLK跳变后的第一个SCLK周期没有数据写入。
代码实现
- 定义模块接口和内部寄存器,并通过异或LRCLK检测边沿信号
- 对LRCLK延迟一拍采集,并产生计数信号
- 将串行数据写入寄存器中,输出并行数据和接收完成信号
完整代码
module i2s_receive #(
parameter WL = 6'd32 //采样位宽
) (
input rst,
input sclk,
input lrclk,
input sdata_in,
output reg rx_done,
output reg [31:0] data_out
);
reg lrclk_d0;
reg [ 5:0] rx_cnt;
reg [31:0] data_out_t;
wire lrc_edge; // 边沿信号检测
assign lrc_edge = lrclk ^ lrclk_d0; // LRC信号的边沿检测
always @(posedge sclk or negedge rst) begin
if (!rst) begin
lrclk_d0 <= 1'b0;
end else lrclk_d0 <= lrclk;
end
always @(posedge sclk or negedge rst) begin
if (!rst) begin
rx_cnt <= 6'd0;
end else if (lrc_edge == 1'b1) rx_cnt <= 6'd0;
else if (rx_cnt < 6'd35) rx_cnt <= rx_cnt + 1'b1;
end
always @(posedge sclk or posedge rst) begin
if (rst) begin
data_out_t <= 32'b0;
end
else if (rx_cnt < WL) begin
data_out_t[WL-1'd1-rx_cnt] <= sdata_in;
end
end
always @(posedge sclk or negedge rst) begin
if (!rst) begin
rx_done <= 1'b0;
data_out <= 32'b0;
end else if (rx_cnt == 6'd31) begin
rx_done <= 1'b1;
data_out <= data_out_t;
end else rx_done <= 1'b0;
end
endmodule