-
Notifications
You must be signed in to change notification settings - Fork 10
/
test_i2s_top_tx.v
144 lines (127 loc) · 2.62 KB
/
test_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
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
137
138
139
140
141
142
143
144
`timescale 1ns / 100ps
module test_i2s_top_tx;
localparam RST_DURATION = 50; //ns
localparam CLK_PERIOD = 10; //ns
localparam SCLK_PERIOD = 100; //ns
localparam STIMULUS_DATA_COUNT = 10;
// Inputs
reg clk_i;
reg rst_i;
reg [15:0] data_i;
reg sclk_i;
reg wsel_i;
// Outputs
wire lr_chnl_o;
wire write_o;
wire sdat_o;
// Received data
reg [15:0] data_rx [0:1];
reg indx_rx;
integer indx_bit_rx;
// Transmitted data
reg [15:0] data_tx [0:STIMULUS_DATA_COUNT-1];
integer indx_tx;
integer indx_bit_tx;
// Instantiate the Unit Under Test (UUT)
i2s_top_tx uut
(
.clk_i(clk_i),
.rst_i(rst_i),
.data_i(data_i),
.lr_chnl_o(lr_chnl_o),
.write_o(write_o),
.sclk_i(sclk_i),
.wsel_i(wsel_i),
.sdat_o(sdat_o)
);
defparam uut.WORD_WIDTH = 16;
// Reset pulse generator
initial begin : reset_generator
rst_i = 1'b1;
#(RST_DURATION);
rst_i = 1'b0;
end
// Main oscillator
initial begin : clk_generator
clk_i = 1'b0;
#(RST_DURATION);
forever begin
clk_i = #(CLK_PERIOD/2) ~clk_i;
end
end
// SCLK oscillator
initial begin : sclk_generator
sclk_i = 1'b0;
#(RST_DURATION);
forever begin
sclk_i = #(SCLK_PERIOD/2) ~sclk_i;
end
end
// WSEL generator
always @ (negedge(sclk_i) or posedge(rst_i)) begin : wsel_generator
if (rst_i) begin
wsel_i = 0;
indx_bit_tx = 15;
end
else begin
if (indx_bit_tx == 1) begin
wsel_i = ~wsel_i;
end
if (indx_bit_tx == 0) begin
indx_bit_tx = 15;
end
else begin
indx_bit_tx = indx_bit_tx - 1;
end
end
end
// I2S receiver
always @ (posedge(sclk_i) or posedge(rst_i)) begin : receiver
if (rst_i) begin
indx_rx = 1'b1;
indx_bit_rx = 0;
data_rx[0] = 0;
data_rx[1] = 0;
end
else begin
if (indx_bit_rx == 0) begin
$display("rx: %h", data_rx[indx_rx]);
indx_bit_rx = 15;
indx_rx = ~indx_rx;
end
else begin
indx_bit_rx = indx_bit_rx - 1;
end
data_rx[indx_rx][indx_bit_rx] = sdat_o;
end
end
// Parallel transmitter
always @ (posedge(clk_i) or posedge(rst_i)) begin : transmitter
if (rst_i) begin
data_i = 16'h0000;
indx_tx = 0;
read_from_file;
end
else begin
if (write_o) begin
if (indx_tx < STIMULUS_DATA_COUNT) begin
$display("tx: %h", data_i);
data_i = data_tx[indx_tx];
//$display("tx: %h", data_i);
indx_tx = indx_tx + 1;
end
else begin
$stop;
end
end
end
end
task read_from_file;
integer stimulus_file;
begin
stimulus_file = $fopen("stimulus/stimulus.txt", "r");
if (stimulus_file == 0) $finish;
if ($fscanf(stimulus_file, "%b", data_tx) == 0) $finish;
end
endtask;
endmodule