Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- `timescale 1ns / 1ps
- `include "macros.vh"
- module i2s_slave #(parameter SampleSize=16)
- (
- input iClk,
- input iRst_n,
- input iLrcIn,
- input iLrcOut,
- input iBclk,
- input iDin,
- input [SampleSize-1:0] iLeftOutData,
- input [SampleSize-1:0] iRightOutData,
- output oDout,
- output [SampleSize-1:0] oLeftInData,
- output [SampleSize-1:0] oRightInData,
- output reg oLeftInReady,
- output reg oLeftOutStart,
- output reg oRightInReady,
- output reg oRightOutStart
- );
- reg [SampleSize-1 : 0] rLeftInDataSR;
- reg [SampleSize-1 : 0] rLeftOutDataSR;
- reg [SampleSize-1 : 0] rRightInDataSR;
- reg [SampleSize-1 : 0] rRightOutDataSR;
- wire [SampleSize-1 : 0] wLeftInDataSrShifted;
- wire [SampleSize-1 : 0] wLeftOutDataSrShifted;
- wire [SampleSize-1 : 0] wRightInDataSrShifted;
- wire [SampleSize-1 : 0] wRightOutDataSrShifted;
- reg rLastBclk;
- reg rLastLrcIn;
- reg rLastLrcOut;
- wire wBclkPosEdge;
- wire wBclkNegEdge;
- localparam CounterSize = `CEIL_LOG2(SampleSize+1);
- reg [CounterSize-1:0] rCntIn;
- assign wBclkPosEdge = !rLastBclk & iBclk;
- assign wBclkNegEdge = rLastBclk & !iBclk;
- assign wLrcInEdge = rLastLrcIn != iLrcIn;
- assign wLrcOutEdge = rLastLrcOut != iLrcOut;
- assign oLeftInData = rLeftInDataSR & {SampleSize{oLeftInReady}};
- assign oRightInData = rRightInDataSR & {SampleSize{oRightInReady}};
- assign wLeftInDataSrShifted = {rLeftInDataSR[SampleSize-2:0], iDin};
- assign wLeftOutDataSrShifted = {rLeftOutDataSR[SampleSize-2:0], 1'b0};
- assign wRightInDataSrShifted = {rRightInDataSR[SampleSize-2:0], iDin};
- assign wRightOutDataSrShifted = {rRightOutDataSR[SampleSize-2:0], 1'b0};
- assign oDout = iLrcOut ? rRightOutDataSR[SampleSize-1] : rLeftOutDataSR[SampleSize-1];
- always @(posedge iClk) begin
- rLastBclk <= iBclk;
- if (!iRst_n) begin
- rCntIn <= {CounterSize{1'b0}};
- oLeftOutStart <= 1'b0;
- oRightOutStart <= 1'b0;
- rLeftInDataSR <= {SampleSize{1'd0}};
- rLeftOutDataSR <= {SampleSize{1'd0}};
- rRightInDataSR <= {SampleSize{1'd0}};
- rRightOutDataSR <= {SampleSize{1'd0}};
- oLeftInReady <= 1'b0;
- oRightInReady <= 1'b0;
- rLastLrcIn <= 1'b0;
- rLastLrcOut <= 1'b0;
- end
- else begin
- if (wBclkPosEdge) begin
- rLastLrcIn <= iLrcIn;
- rLastLrcOut <= iLrcOut;
- oRightOutStart <= wLrcOutEdge & iLrcOut;
- oLeftOutStart <= wLrcOutEdge & !iLrcOut;
- if (wLrcInEdge) begin
- rCntIn <= 0;
- if (iLrcIn)
- rRightInDataSR <= {SampleSize{1'd0}};
- else
- rLeftInDataSR <= {SampleSize{1'd0}};
- end
- else begin
- if (rCntIn < SampleSize) begin
- rCntIn <= rCntIn+1;
- if (iLrcIn) // Right Channel
- rRightInDataSR <= wRightInDataSrShifted;
- else // Left Channel
- rLeftInDataSR <= wLeftInDataSrShifted;
- end
- else begin
- oRightInReady <= iLrcIn;
- oLeftInReady <= !iLrcIn;
- end
- end
- end
- else if (wBclkNegEdge) begin
- if (wLrcOutEdge) begin
- rLeftOutDataSR <= {SampleSize-1{1'b0}};
- rRightOutDataSR <= {SampleSize-1{1'b0}};
- end
- else begin
- if (iLrcOut) // Right Channel
- rRightOutDataSR <= (oRightOutStart) ? iRightOutData : wRightOutDataSrShifted;
- else // Left channel
- rLeftOutDataSR <= (oLeftOutStart) ? iLeftOutData : wLeftOutDataSrShifted;
- end
- end
- end
- end
- endmodule
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement