Skip to content

Commit f3956e5

Browse files
committed
added i2s tx
1 parent df068c9 commit f3956e5

File tree

6 files changed

+168
-7
lines changed

6 files changed

+168
-7
lines changed

i2s_tx.v

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
module i2s_tx #(
2+
parameter AUDIO_DW = 8
3+
) (
4+
input sck_i,
5+
input ws_i,
6+
output sd_o,
7+
input [AUDIO_DW-1:0] l_data_i,
8+
input [AUDIO_DW-1:0] r_data_i,
9+
output l_load_en_o,
10+
output r_load_en_o
11+
);
12+
reg wsd[1:0];
13+
always @(posedge sck_i) begin
14+
wsd[0] <= ws_i;
15+
wsd[1] <= wsd[0];
16+
end
17+
assign l_load_en_o = wsd[0] & !ws_i;
18+
assign r_load_en_o = !wsd[0] & ws_i;
19+
20+
wire wsp;
21+
assign wsp = wsd[0] ^ wsd[1];
22+
23+
reg [AUDIO_DW-1:0] sd_shift_reg;
24+
wire [AUDIO_DW-1:0] l_data, r_data;
25+
assign l_data = !wsd[0] ? l_data_i : {AUDIO_DW{1'b0}};
26+
assign r_data = wsd[0] ? r_data_i : {AUDIO_DW{1'b0}};
27+
28+
always @(negedge sck_i) begin
29+
if (wsp == 1) sd_shift_reg <= l_data | r_data;
30+
else sd_shift_reg <= {sd_shift_reg[AUDIO_DW-2:0], 1'b0};
31+
end
32+
assign sd_o = sd_shift_reg[AUDIO_DW-1];
33+
34+
endmodule

info.yaml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ project:
1010
- spi_slave_mem_interface.v
1111
- register_map.v
1212
- prbs15.v
13+
- i2s_tx.v
1314
top_module: "tt_um_spi_register_map" # put the name of your top module here, make it unique by prepending your github username
1415

1516
# How many tiles your design occupies? A single tile is about 167x108 uM.

src/Makefile

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ TOPLEVEL_LANG ?= verilog
99
ifneq ($(GATES),yes)
1010

1111
# this is the only part you should need to modify:
12-
VERILOG_SOURCES += $(PWD)/tb.v $(PWD)/tt_um_spi_register_map.v $(PWD)/spi_slave_mem_interface.v $(PWD)/register_map.v $(PWD)/prbs15.v
12+
VERILOG_SOURCES += $(PWD)/tb.v $(PWD)/tt_um_spi_register_map.v $(PWD)/spi_slave_mem_interface.v $(PWD)/register_map.v $(PWD)/prbs15.v $(PWD)/i2s_tx.v
1313

1414
else
1515

src/i2s_tx.v

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
module i2s_tx #(
2+
parameter AUDIO_DW = 8
3+
) (
4+
input sck_i,
5+
input ws_i,
6+
output sd_o,
7+
input [AUDIO_DW-1:0] l_data_i,
8+
input [AUDIO_DW-1:0] r_data_i,
9+
output l_load_en_o,
10+
output r_load_en_o
11+
);
12+
reg wsd[1:0];
13+
always @(posedge sck_i) begin
14+
wsd[0] <= ws_i;
15+
wsd[1] <= wsd[0];
16+
end
17+
assign l_load_en_o = wsd[0] & !ws_i;
18+
assign r_load_en_o = !wsd[0] & ws_i;
19+
20+
wire wsp;
21+
assign wsp = wsd[0] ^ wsd[1];
22+
23+
reg [AUDIO_DW-1:0] sd_shift_reg;
24+
wire [AUDIO_DW-1:0] l_data, r_data;
25+
assign l_data = !wsd[0] ? l_data_i : {AUDIO_DW{1'b0}};
26+
assign r_data = wsd[0] ? r_data_i : {AUDIO_DW{1'b0}};
27+
28+
always @(negedge sck_i) begin
29+
if (wsp == 1) sd_shift_reg <= l_data | r_data;
30+
else sd_shift_reg <= {sd_shift_reg[AUDIO_DW-2:0], 1'b0};
31+
end
32+
assign sd_o = sd_shift_reg[AUDIO_DW-1];
33+
34+
endmodule

src/tb.v

Lines changed: 51 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,11 @@ module tb();
2121
localparam MAX_CLOCKS = 1048576;
2222
localparam TEST_COUNT = 8;
2323

24+
localparam SCK_PERIOD = 62500/4;
25+
localparam WS_PERIOD = 2*AUDIO_DW*SCK_PERIOD;
26+
localparam MAX_SAMPLES = 32;
27+
localparam AUDIO_DW = 8;
28+
2429
reg clk, rst_n;
2530
reg [DATA_WIDTH-1:0] rand_addr_arr [TEST_COUNT-1:0];
2631
reg [DATA_WIDTH-1:0] rand_val_arr [NUM_CONFIG_REG+NUM_STATUS_REG-1:0];
@@ -29,15 +34,14 @@ module tb();
2934
integer count_i;
3035
reg fail_flag;
3136

32-
assign uio_in[5] = 0;
33-
assign uio_in[4] = 1;
34-
3537
reg finish;
3638

3739
initial begin
3840
finish = 0;
3941
clk = 0;
4042
rst_n = 1;
43+
sck = 0;
44+
ws = 0;
4145
#(10*CLK_PERIOD) init_design();
4246
init_spi();
4347
prbs_init();
@@ -50,16 +54,57 @@ module tb();
5054
// #(10*CLK_PERIOD) $finish;
5155
end
5256

57+
reg [AUDIO_DW-1:0] sd_buffer, recv_l_data, recv_r_data;
58+
initial begin
59+
sd_buffer = 0;
60+
end
61+
always @(posedge sck) begin
62+
sd_buffer <= {sd_buffer[AUDIO_DW-2:0], sd};
63+
end
64+
65+
reg wsd[1:0];
66+
always @(posedge sck) begin
67+
wsd[0] <= ws;
68+
wsd[1] <= wsd[0];
69+
end
70+
71+
wire wsp;
72+
assign wsp = wsd[0] ^ wsd[1];
73+
74+
reg [31:0] sample_count;
75+
initial begin
76+
sample_count = 0;
77+
end
78+
always @(negedge sck) begin
79+
if (wsp == 1'b1) begin
80+
sample_count <= sample_count + 1;
81+
if (ws == 1'b1) begin
82+
recv_l_data <= sd_buffer;
83+
$display("recv: 0x%0h", recv_l_data);
84+
85+
end else if (ws == 1'b0) begin
86+
recv_r_data <= sd_buffer;
87+
$display("recv: 0x%0h", recv_r_data);
88+
end
89+
end else if (sample_count >= MAX_SAMPLES) finish = 1;
90+
end
91+
92+
5393
reg [63:0] clk_count;
5494
initial clk_count = 0;
5595
always @(posedge clk) begin
5696
clk_count <= clk_count + 1;
5797
end
5898

5999
always #(CLK_PERIOD/2) clk = !clk;
100+
always #(SCK_PERIOD/2) sck = !sck;
101+
always #(WS_PERIOD/2) ws = !ws;
60102

61103
reg sck_i, cs_ni;
62104
wire sdi_i, sdo_o;
105+
reg sck;
106+
reg ws;
107+
wire sd;
63108

64109
// wire up the inputs and outputs
65110
// reg clk;
@@ -98,6 +143,9 @@ module tb();
98143
assign uio_in[1] = sdi_i;
99144
assign sdo_o = uio_out[2];
100145
assign uio_in[3] = cs_ni;
146+
assign uio_in[4] = sck;
147+
assign uio_in[5] = ws;
148+
assign sd = uio_out[6];
101149

102150
assign uio_oe = 8'b1100_0100;
103151

src/tt_um_spi_register_map.v

Lines changed: 47 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -46,9 +46,8 @@ module tt_um_spi_register_map (
4646
endgenerate
4747

4848
assign uio_out[7] = ^prbs_frame;
49-
assign uio_out[6] = |config_bus_o;
50-
assign status_bus_i[DATA_WIDTH*(NUM_STATUS_REG/2)-1:0] = {(DATA_WIDTH*(NUM_STATUS_REG/2)){uio_in[5]}};
51-
assign status_bus_i[DATA_WIDTH*NUM_STATUS_REG-1:DATA_WIDTH*(NUM_STATUS_REG/2)] = {(DATA_WIDTH*(NUM_STATUS_REG/2)){uio_in[4]}};
49+
assign status_bus_i[DATA_WIDTH*(NUM_STATUS_REG/2)-1:0] = {(DATA_WIDTH*(NUM_STATUS_REG/2)){1'b0}};
50+
assign status_bus_i[DATA_WIDTH*NUM_STATUS_REG-1:DATA_WIDTH*(NUM_STATUS_REG/2)] = {(DATA_WIDTH*(NUM_STATUS_REG/2)){1'b1}};
5251

5352
wire [ADDR_WIDTH-1:0] spi_addr;
5453
wire [DATA_WIDTH-1:0] spi_write_data, spi_read_data;
@@ -103,4 +102,49 @@ module tt_um_spi_register_map (
103102
.prbs_frame_o(prbs_frame)
104103
);
105104

105+
localparam AUDIO_DW = 8;
106+
107+
wire sck;
108+
assign sck = uio_in[4];
109+
wire ws;
110+
assign ws = uio_in[5];
111+
wire sd;
112+
assign uio_out[6] = sd;
113+
114+
reg [AUDIO_DW-1:0] l_data, r_data;
115+
wire l_load_en, r_load_en;
116+
117+
reg l_load_reg [1:0];
118+
reg r_load_reg [1:0];
119+
always @(posedge clk) begin
120+
if (!rst_n) begin
121+
l_load_reg[0] <= 'b0; l_load_reg[1] = 'b0;
122+
r_load_reg[0] <= 'b0; r_load_reg[1] = 'b0;
123+
end else begin
124+
l_load_reg[0] <= l_load_en; l_load_reg[1] <= l_load_reg[0];
125+
r_load_reg[0] <= r_load_en; r_load_reg[1] <= r_load_reg[0];
126+
end
127+
end
128+
wire l_load_pulse;
129+
assign l_load_pulse = l_load_reg[0] && !l_load_reg[1];
130+
wire r_load_pulse;
131+
assign r_load_pulse = r_load_reg[0] && !r_load_reg[1];
132+
133+
always @(posedge clk) begin
134+
if (l_load_pulse) l_data <= prbs_frame;
135+
if (r_load_pulse) r_data <= prbs_frame;
136+
end
137+
138+
i2s_tx #(
139+
.AUDIO_DW(AUDIO_DW)
140+
) UUT_i2s_tx (
141+
.sck_i(sck),
142+
.ws_i(ws),
143+
.sd_o(sd),
144+
.l_data_i(l_data),
145+
.r_data_i(r_data),
146+
.l_load_en_o(l_load_en),
147+
.r_load_en_o(r_load_en)
148+
);
149+
106150
endmodule

0 commit comments

Comments
 (0)