-
Notifications
You must be signed in to change notification settings - Fork 10
/
i2s_top_tx.v
92 lines (79 loc) · 1.4 KB
/
i2s_top_tx.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
`include "bus_cnt_width.v"
module i2s_top_tx
(
clk_i,
rst_i,
data_i,
lr_chnl_o,
write_o,
sclk_i,
wsel_i,
sdat_o
);
parameter WORD_WIDTH = 16;
localparam CNT_WIDTH = `CLOG2(WORD_WIDTH);
input clk_i;
input rst_i;
input [WORD_WIDTH-1:0] data_i;
output lr_chnl_o;
output write_o;
input sclk_i;
input wsel_i;
output sdat_o;
wire sclk_negedge;
wire wsel_edge;
wire wsel_sync;
reg [CNT_WIDTH-1:0] bit_cnt;
reg [WORD_WIDTH-1:0] shift_reg;
signal_sync sync_sclk
(
.clk_i(clk_i),
.rst_i(rst_i),
.signal_i(sclk_i),
.signal_o(),
.valid_o(),
.edge_o(),
.posedge_o(),
.negedge_o(sclk_negedge)
);
signal_sync wsel_sclk
(
.clk_i(clk_i),
.rst_i(rst_i),
.signal_i(wsel_i),
.signal_o(wsel_sync),
.valid_o(),
.edge_o(wsel_edge),
.posedge_o(),
.negedge_o()
);
assign write_o = (bit_cnt == 0) && sclk_negedge;
assign sdat_o = shift_reg[WORD_WIDTH-1];
assign lr_chnl_o = wsel_sync;
always @ (posedge(clk_i) or posedge(rst_i)) begin
if (rst_i) begin
bit_cnt <= 0;
end
else begin
if (wsel_edge) begin
bit_cnt <= 0;
end
else if (sclk_negedge) begin
bit_cnt <= bit_cnt - 1;
end
end
end
always @ (posedge(clk_i) or posedge(rst_i)) begin
if (rst_i) begin
shift_reg <= 0;
end
else begin
if (write_o) begin
shift_reg <= data_i;
end
else if (sclk_negedge) begin
shift_reg <= {shift_reg[WORD_WIDTH-2:0], 1'b0};
end
end
end
endmodule