-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathi2s_rx.v
82 lines (72 loc) · 1.67 KB
/
i2s_rx.v
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
// I2S Receiver
// by Tomek Szczęsny 2022
//
// Typically connected to external pins, it receives I2S signals and
// has buffered output L and R channel PCM frames.
//
// As per I2S standard, this receiver is compatible with any bit depth of the
// sender, by either ignoring excessive LSBs or concatenating missing LSB
// zeroes.
//
// +------------------+
// sck --->| |===> l[b]
// | |
// ws --->| i2s_rx |===> r[b]
// | |
// sd --->| |---> ock
// +------------------+
//
// Parameters:
// b - Output PCM bit depth (b < 64) (16)
//
// Ports:
// sck - I2S Continuous Serial Clock
// ws - I2S Word Select
// sd - I2S Serial Data
// l[b] - Left channel PCM output
// r[b] - Right channel PCM output
// ock - Output clk. Posedge and negedge on r[b] and l[b] update, respectively.
//
`ifndef _i2s_rx_v_
`define _i2s_rx_v_
module i2s_rx(
input wire sck,
input wire ws,
input wire sd,
output reg [b-1:0] l = 0,
output reg [b-1:0] r = 0,
output reg ock = 0
);
parameter b = 16;
reg [b-1:0] rxbuf = 0; // Receiver buffer
reg ch = 0; // Last WS state
reg [5:0] cnt = 0; // Bit counter for current word
reg dump = 0; // Schedule output dump on next sck cycle
always @ (posedge sck)
begin
ch <= ws;
if (cnt < b) begin
rxbuf[b-1-cnt] <= sd;
end
if (cnt == 0) begin
rxbuf[b-2:0] <= 0;
end
if (ch != ws) begin
dump <= 1;
cnt <= 0;
end else begin
cnt <= cnt + 1;
dump <= 0;
if (dump == 1) begin
if (ws == 0) begin
r <= rxbuf;
ock <= 1;
end else begin
l <= rxbuf;
ock <= 0;
end
end
end
end
endmodule
`endif