FPGA-based I2S to TDM8 design

I. Overview

In the field of audio applications, the application of I2S and TDM is the most basic application. Regardless of the sampling of the analog-to-digital ADC or the output of the digital-to-analog DAC, these two protocols are often used. Therefore, when entering the audio field, these basics must first Master; in this article, we mainly talk about design ideas, and only briefly introduce the timing of I2S and TDM, and then get familiar with the design ideas of these two protocols through the simulation of encoding and decoding between I2S and TDM.

2. Introduction to I2S

The I2S (Inter-IC Sound) bus, also known as the integrated circuit built-in audio bus, is a bus standard developed by Philips for audio data transmission between digital audio devices. The standard protocol of I2S is adopted in our design. (The figure below is the timing diagram of the ADC)

Master clock MCLK: It is the reference clock of LRCK and SCLK, a system should use the same MCLK to ensure clock synchronization requirements. The common frequency is 256fs or 512fs. Here fs is the frequency of the sampling rate LRCK. MCLK is 24.576MHz in this design.

Sampling rate LRCK (also known as WS): used to switch the data of the left and right channels. For the I2S standard protocol, if LRCK is 1, it means that the right channel data is transmitted, and if it is 0, it means the left channel. In the design, the falling edge of LRCK is the starting point of our frame. For I2S, the left and right channels can carry two channels of data, and each two channels of data is 1 frame. LRCK is 48KHz in this design.

Serial clock SCLK: also called bit clock BCLK, corresponding to each bit of digital audio data, the clock has a pulse. SCLK is 3.072MHz in this design.这里需要注意,不管我们实际音频数据的有效位是16bit、24bit或32bit,我们的串行SCLK都是LRCK的64倍,并且LRCK的下降沿一定是要和BCK的下降沿对齐的。

Input data DIN: For the I2s standard protocol, our data is sampled from the rising edge of the second bck clock after the LRCK falling edge arrives. In normal design, the effective bits of audio data are 24bit, because 32bit is not necessary, and it is also 24bit in this design.

insert image description here

3. Introduction to TDM

TDM is instant division multiplexing, which is an enhanced version of I2s. In our actual application, we found that one group of I2s can only transmit two channels of data, which cannot meet our needs, so the TDM protocol can meet our needs. To put it bluntly, I2s ​​is actually TDM2. The most commonly used formats are TDM8 and TDM16. The following figure is the timing diagram of our DAC, which is in TDM8 format. The rising edge of LRCK is the starting point of a frame, and one frame is 8 channels.
Main clock MCLK: The main system clock here is still 24.576MHz.
Sampling rate LRCK: The definition of the pulse width of LRCK here is a little different for each chip. For our DAC, the pulse width of LRCK can be at least 1 BCK clock cycle, and the maximum can be 255 clock cycles. The LRCK of TDM in this design is also 48KHz.
TDM8移位时钟BCK是采样率LRCK的256倍。
Bit clock BCK: Similarly, the falling edge of the shift clock bck must be aligned with the edge of LRCK. This design BDCK is 12.288MHz. 注意TDM的一帧的通道数越多,我们BCK频率会越高,对时序的要求就越高,因为一个通道占用32个bck,采样率是固定的。
Input data DIN: The alignment of the data here adopts the I2s standard format, that is, after the rising edge of LRCK, the beginning of the second bck of every 32bck is valid data.

insert image description here
For a detailed introduction to the I2S and TDM protocols, please refer to: I2S/PCM protocol and TDM mode detailed explanation , which includes left alignment, right alignment, etc.

4. Design block diagram

As shown in the figure, in order to comply with the rule of edge alignment (the upper and lower edges of LRCK are aligned with the falling edge of BCK), we need to use the falling edge of the 24.576MHz clock for frequency division processing. We have a total of 8 channels of data, 4 channels of I2S for sampling (each AD 2 channels of I2S). Then perform TDM8 encoding and output to DAC.
Please add a picture description

5. Simulation verification

1. Clock frequency division

As shown in the simulation diagram below, clk is 24.576MHz, clkout0 is the sampling clock LRCK is 48KHz, clkout1 is the bit clock BCK of I2S is 3.072MHz, clkout2 is the bit clock BCK of TDM8 is 12.288MHz. (The upper and lower edges of the sampling rate LRCK are aligned with the falling edge of BCK)

下面展示的是最简单分频处理方法的代码(干货)

module clk_div(
input clk,//24.576MHz
input rst,
output  clkout0,//48KHz
output  clkout1,//3.072MHz
output  clkout2//12.288MHz
    );

reg[9:0]cnt=0;


assign clkout0=cnt[8];
assign clkout1=cnt[2];
assign clkout2=cnt[0];

always@(negedge clk)
begin
if(rst)
cnt<=0;
else
cnt<=cnt+1;
end

endmodule

Emulation stimulus code:

module vtf_clk_div;

	// Inputs
	reg clk;
	reg rst;

	// Outputs
	wire clkout0;
	wire clkout1;
	wire clkout2;

	// Instantiate the Unit Under Test (UUT)
	clk_div uut (
		.clk(clk), 
		.rst(rst), 
		.clkout0(clkout0), 
		.clkout1(clkout1), 
		.clkout2(clkout2)
	);

	initial begin
		// Initialize Inputs
		clk = 0;
		rst = 1;

		// Wait 100 ns for global reset to finish
		#100;
       	rst = 0; 
		// Add stimulus here

	end
  always # 20.345   clk = ~clk;
endmodule

Simulation timing diagram:
Please add a picture description

2.I2S to TDM8 function module

The source code of 4-way I2S to 1-way TDM8 will not be released here. If you want to see it, you can click the following link to get it: I2S to TDM8 code .
In the stimulus file, the 8 channels of data_vld1~data_vld8 defined correspond to the 8 channels of 4-channel I2s. For details, see the simulation timing diagram.
Emulation stimulus code:


module vtf_i2s_to_tdm8;

	// Inputs
	reg reset;
	wire MCLK;//TDM8的BCK
	wire LRCK;
	wire SCLK;//I2S的BCK
	reg DATA1;//第一路I2s数据输入
	reg DATA2;//第二路I2s数据输入
	reg DATA3;//第三路I2s数据输入
	reg DATA4;//第四路I2s数据输入

	// Outputs
	wire flag;
	wire DATA_OUT;
/
   
    reg clk;
	reg LRCK_dly1;
	reg LRCK_dly2;
	reg [63:0] TMPA;
	reg [63:0] TMPB;
	reg [63:0] TMPC;
	reg [63:0] TMPD;
	wire clk_48k_negedge;
/定义的8个数据通过4路I2S发送出去(ch1/ch2第一路、ch3/ch4第二路、
    ch5/ch6第二路、ch7/ch8第二路)

localparam data_vld1=32'hf111_1F00;//ch1
localparam data_vld2=32'hf333_3F00;//ch2
localparam data_vld3=32'hf555_5F00;//ch3
localparam data_vld4=32'hf777_7F00;//ch4
localparam data_vld5=32'hf999_9F00;//ch5
localparam data_vld6=32'hfBBB_BF00;//ch6
localparam data_vld7=32'hfCCC_CF00;//ch7
localparam data_vld8=32'hfDDD_DF00;//ch8
	// Instantiate the Unit Under Test (UUT)
	i2s_to_tdm8 uut (
		.reset(reset), 
		.MCLK(MCLK), 
		.LRCK(LRCK), 
		.SCLK(SCLK), 
		.DATA1(DATA1), 
		.DATA2(DATA2), 
		.DATA3(DATA3), 
		.DATA4(DATA4), 
		.flag(flag), 
		.DATA_OUT(DATA_OUT)
	);
///调用上面的分频模块	
		clk_div clk_div_inst (
		.clk(clk), 
		.rst(reset), 
		.clkout0(LRCK), //48KHz
		.clkout1(SCLK), //3.072MHz
		.clkout2(MCLK)//12.288MHz
	);



	initial begin
		// Initialize Inputs
		reset = 1;
		clk = 0;
		DATA1 = 0;
		DATA2 = 0;
		DATA3 = 0;
		DATA4 = 0;
      LRCK_dly1=0;
		LRCK_dly2=0;
		TMPA=0;
		TMPB=0;
		TMPC=0;
		TMPD=0;
		// Wait 100 ns for global reset to finish
		#100;
       reset =0; 
		// Add stimulus here

	end
    always # 20.345   clk = ~clk;   
	 always @(posedge SCLK)
	 begin
	LRCK_dly1 <=LRCK;
	LRCK_dly2 <=LRCK_dly1;
	 end
	assign clk_48k_negedge =~LRCK_dly1&LRCK_dly2;
	 
	always @(negedge SCLK) 
	 begin
	 if(clk_48k_negedge)begin
	   DATA1<=data_vld1[31];
		TMPA<={
    
    data_vld1[30:0],data_vld2,1'b0};
		end
		else begin
	   TMPA<=TMPA<<1;
		DATA1<=TMPA[63];
      end		
	 end
	 
	always @(negedge SCLK) 
	 begin
	 if(clk_48k_negedge)begin
	   DATA2<=data_vld3[31];
		TMPB<={
    
    data_vld3[30:0],data_vld4,1'b0};
		end
		else begin
	   TMPB<={
    
    TMPB[62:0],1'b1};	 
		DATA2<=TMPB[63];
		end
	 end
	 
	always @(negedge SCLK) 
	 begin
	 if(clk_48k_negedge)begin
	   DATA3<=data_vld5[31];
		TMPC<={
    
    data_vld5[30:0],data_vld6,1'b0};
		end
		else begin
	   TMPC<={
    
    TMPC[62:0],1'b1};	 
		DATA3<=TMPC[63];
		end 
	 end
	 
	always @(negedge SCLK) 
	 begin
	 if(clk_48k_negedge)begin
	   DATA4<=data_vld7[31];
		TMPD<={
    
    data_vld7[30:0],data_vld8,1'b0};
		end
		else begin
	   TMPD<={
    
    TMPD[62:0],1'b1};	 
		DATA4<=TMPD[63];
		end	 
	 end	 
endmodule

Timing simulation diagram:
For I2S timing, the falling edge of LRCK is the beginning of a frame, DATA1~DATA4 are 4-way I2S input data, and the channel correspondence is shown in the figure; for TDM8 timing, the rising edge of LRCK is the start of a frame At the beginning, DATA_OUT is the output data of TDM8, and the channel correspondence here is as shown in the figure.
Please add a picture description
For the majority of bloggers, the introduction of the application of I2S to 1-channel TDM8 is finished here, and the application can be expanded, such as: 8-channel I2S to 1-channel TDM16, 8-channel I2S to 2-channel TDM8, etc. As long as the timing is understood, it can be used easily. It's simple, everyone can do their own research, and welcome to discuss if you have any questions.

Guess you like

Origin blog.csdn.net/qq_43618170/article/details/127784253
Recommended