-
Notifications
You must be signed in to change notification settings - Fork 0
/
myI2STx_v1_0.v
136 lines (118 loc) · 3.83 KB
/
myI2STx_v1_0.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
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
`timescale 1 ns / 1 ps
// s00_axis_aclk = 100 MHz
// MCLK = 10 cycles => 10 MHz
// BCLK = 40 cycles => 2.5MHz
// => 32 bit = 1280 cycles => f_sample = 1/(1280*2*10e-9) = 39.0625 kHz
// A single transfer is 32 bit wide:
// The left channel is in the upper 16 bits, the right channel is in the lower 16 bits.
module myI2STx_v1_0 #
(
// Users to add parameters here
// User parameters ends
// Do not modify the parameters beyond this line
// Parameters of Axi Slave Bus Interface S00_AXIS
parameter integer C_S00_AXIS_TDATA_WIDTH = 32
)
(
// I2S Interface
input mclk,
output reg bclk = 1,
output reg lrclk = 1,
output reg sdata = 0,
// User ports ends
// Do not modify the ports beyond this line
// Ports of Axi Slave Bus Interface S00_AXIS
input wire s00_axis_aclk,
input wire s00_axis_aresetn,
output reg s00_axis_tready = 0,
input wire [C_S00_AXIS_TDATA_WIDTH-1 : 0] s00_axis_tdata,
input wire [(C_S00_AXIS_TDATA_WIDTH/8)-1 : 0] s00_axis_tstrb,
input wire s00_axis_tlast,
input wire s00_axis_tvalid
);
reg mclkdelay = 0;
reg halfclk = 0;
reg [0:0]counter = 0;
reg [15:0]ramp = 16'hFFFF;
reg [15:0]shiftreg = 0;
reg [4:0]bitcounter = 0;
reg [2:0] state = 0;
reg [31:0] buffer = 0;
reg bufvalid = 0;
localparam S0 = 0;
localparam S1 = 1;
localparam S2 = 2;
localparam S3 = 3;
localparam S4 = 4;
always @(posedge s00_axis_aclk) begin
if (bufvalid==0 && s00_axis_tready==0) begin
s00_axis_tready <= 1;
end else if (bufvalid==0 && s00_axis_tready==1 && s00_axis_tvalid==1) begin
s00_axis_tready <= 0;
buffer <= s00_axis_tdata;
bufvalid <= 1;
end
if (mclk==1 && !mclkdelay) begin
counter <= counter+1;
if (counter == 0) begin
halfclk <= 1;
end
mclkdelay <= mclk;
end else begin
halfclk <= 0;
mclkdelay <= mclk;
end
//if (halfclk==1) begin
// bclk = !bclk;
//end
if (halfclk==1) begin
case(state)
S0: begin
if (bufvalid==1) begin
bufvalid <= 0;
bitcounter <= 0;
lrclk <= 0;
bclk <= 0;
sdata <= 0;
state <= S1;
shiftreg <= buffer[31:16];
end
end
S1: begin
bclk <= 1;
state <= S2;
end
S2: begin
bclk <= 0;
sdata <= shiftreg[15];
bitcounter <= bitcounter+1;
state <= S3;
end
S3: begin
bclk <= 1;
shiftreg <= shiftreg<<1;
if (bitcounter==31) begin
if (lrclk==0) begin
state <= S4;
end else begin
state <= S0;
end
end else begin
state <= S2;
end
end
S4: begin
bitcounter <= 0;
lrclk <= 1;
bclk <= 0;
sdata <= 0;
state <= S1;
shiftreg <= buffer[15:0];
end
default:begin
state <= S0;
end
endcase
end
end
endmodule