-
Notifications
You must be signed in to change notification settings - Fork 0
/
Extrapolator_tb.vhd
340 lines (269 loc) · 9.1 KB
/
Extrapolator_tb.vhd
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
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
library IEEE;
use IEEE.STD_LOGIC_1164.all;
use IEEE.NUMERIC_STD.all;
use IEEE.STD_LOGIC_TEXTIO.all;
use STD.TEXTIO.all;
library work;
use work.Extrapolator_Package.all;
-- ###############################################################################################
-- TESTING PARAMETERS
-- ###############################################################################################
entity Extrapolator_tb is
GENERIC(
-- Testbench Parameters
DEBUG_ON : boolean := false; -- Enable for debug messages
INPUT_FILE : string := "./inputs.txt"; -- This is a list of the test vector files that need to be loaded
MAX_COUNT : integer := 2**12; -- Max number of words allowed in input test vector
MAX_TV : integer := 8; -- Max number of test vectors that can be loaded
META_ON_RIGHT : boolean := true; -- Enable if metadata bit is on the right in the files
-- Disable if metadata bit is on the left in the files
INCREMENT_L0ID : boolean := true; -- Enable if you want test bench to increment L0ID on each loop
TEST_RESET : boolean := false; -- Enable if you want test bench to send periodic resets
TEST_BP : boolean := false; -- Enable if you want test bench to send periodic back pressure
IDLE_WORD : std_logic_vector(63 downto 0) := X"0000DEAD0000BEEF";
CONSTANT_LATENCY : integer := 30;
-- Extrapolator Parameters
N_CONNECTIONS : INTEGER := 1;
FAST_MODE : BOOLEAN := false
);
end;
architecture behav of Extrapolator_tb is
COMPONENT Extrapolator_Main
GENERIC (
N_CONNECTIONS : INTEGER := 1;
FAST_MODE : BOOLEAN := false
);
PORT (
clk: in STD_LOGIC;
reset: in STD_LOGIC;
din: in STD_LOGIC_VECTOR(63 downto 0);
metadata: in STD_LOGIC;
valid_data: in STD_LOGIC;
ready: out STD_LOGIC;
halt_out: out STD_LOGIC;
SectorID_8L_to_HBM:out STD_LOGIC_VECTOR(SectorID_8L_Length-1 downto 0);
read_request_to_HBM:out STD_LOGIC;
Constants_from_HBM : in constant_array;
ModuleID_from_HBM : in module_array;
SectorID_8L_from_HBM : in STD_LOGIC_VECTOR(SectorID_8L_Length-1 downto 0);
SectorID_13L_from_HBM : in STD_LOGIC_VECTOR(SectorID_13L_Length-1 downto 0);
Constants_Ready_from_HBM : in STD_LOGIC;
ssid_out: out ssid_array;
halt_in: in STD_LOGIC
);
END COMPONENT ;
SIGNAL clk : std_logic := '0';
SIGNAL rst : std_logic := '0';
SIGNAL din : std_logic_vector(63 downto 0) := (others => '0');
SIGNAL metadata : std_logic := '0';
SIGNAL valid_data : std_logic := '0';
SIGNAL ready : std_logic;
SIGNAL halt_out : std_logic;
SIGNAL halt_in : std_logic := '0';
SIGNAL ssid_out : ssid_array;
SIGNAL TV_index : integer := 0;
SIGNAL word_index : integer := 0;
SIGNAL L0ID_count : integer := 0;
TYPE test_vector is array (MAX_COUNT-1 downto 0) of std_logic_vector(67 downto 0);
TYPE data_array is array (MAX_TV-1 downto 0) of test_vector;
SIGNAL text_data : data_array := (others => (others => (others => '0')));
TYPE vector_length is array (MAX_TV-1 downto 0) of integer;
SIGNAL TV_length : vector_length := (others => 0);
SIGNAL TV_loaded : integer := 0;
SIGNAL TV_sending : boolean := false;
SIGNAL SectorID_8L_to_HBM : STD_LOGIC_VECTOR(SectorID_8L_Length-1 downto 0);
SIGNAL read_request_to_HBM : STD_LOGIC;
SIGNAL Constants_from_HBM : constant_array := (others => (others => (others => '0')));
SIGNAL ModuleID_from_HBM : module_array := (others => (others => '0'));
SIGNAL SectorID_8L_from_HBM : STD_LOGIC_VECTOR(SectorID_8L_Length-1 downto 0) := (others => '0');
SIGNAL SectorID_13L_from_HBM : STD_LOGIC_VECTOR(SectorID_13L_Length-1 downto 0) := (others => '0');
SIGNAL Constants_Ready_from_HBM : STD_LOGIC := '0';
SIGNAL read_pipe : STD_LOGIC_VECTOR(CONSTANT_LATENCY-1 downto 0) := (others => '0');
begin
Extrapolator : Extrapolator_Main
GENERIC MAP (
N_CONNECTIONS => N_CONNECTIONS,
FAST_MODE => FAST_MODE
)
PORT MAP (
clk => clk,
reset => rst,
din => din,
metadata => metadata,
valid_data => valid_data,
ready => ready,
halt_out => halt_out,
SectorID_8L_to_HBM => SectorID_8L_to_HBM,
read_request_to_HBM => read_request_to_HBM,
Constants_from_HBM => Constants_from_HBM,
ModuleID_from_HBM => ModuleID_from_HBM,
SectorID_8L_from_HBM => SectorID_8L_from_HBM,
SectorID_13L_from_HBM => SectorID_13L_from_HBM,
Constants_Ready_from_HBM => Constants_Ready_from_HBM,
ssid_out => ssid_out,
halt_in => halt_in
);
clock : PROCESS
begin
wait for 10 ns; clk <= not clk;
end PROCESS clock;
reset : PROCESS
begin
wait for 5 ns; rst <= '1'; -- Initial reset
wait for 20 ns; rst <= '0';
if (TEST_RESET) then -- Periodic resets
while (TEST_RESET) loop
wait for 5000 ns; rst <= '1';
wait for 500 ns; rst <= '0';
end loop;
else
wait;
end if;
end PROCESS reset;
back_pressure : PROCESS
begin
if (TEST_BP) then -- Periodic back pressure
while (TEST_BP) loop
wait for 1000 ns; halt_in <= '1';
wait for 200 ns; halt_in <= '0';
end loop;
else
wait;
end if;
end PROCESS back_pressure;
-- This process reads the test vectors from a text file.
-- Contents of the files are placed in a large 3D array of registers
-- at the beginning of the simulation
file_read : PROCESS
file input_list : text open read_mode is INPUT_FILE;
variable word : line;
variable filename : line;
variable word_vector : std_logic_vector(67 downto 0);
variable N_files : integer;
variable count : integer := 0;
variable file_count : integer := 0;
file read_file : text;
variable debug : line;
begin
file_count := 0;
report "Reading input TVs from " &INPUT_FILE;
while (not endfile(input_list)) loop
readline(input_list, filename);
report filename.all &" will be loaded";
file_open(read_file, filename.all, read_mode);
count := 0;
while (not endfile(read_file)) loop
readline(read_file, word);
if (DEBUG_ON) then
write(debug, count);
report "Word " &debug.all &" is " &word.all;
debug := null;
end if;
hread(word, word_vector);
text_data(file_count)(count) <= word_vector;
count := count + 1;
end loop;
TV_length(file_count) <= count; -- Extracts the length of the test vector
file_close(read_file);
report "Closing " &filename.all;
file_count := file_count + 1;
end loop;
if (DEBUG_ON) then
write(debug, file_count);
report "Total number of files read is " &debug.all;
debug := null;
end if;
TV_loaded <= file_count;
file_close(input_list);
report "Closing " &INPUT_FILE;
wait;
end PROCESS file_read;
-- Test vector is placed on the input stream, one word per clock edge
-- Idle words are placed on the input stream during resets and when back pressured
data_stream : process(clk)
begin
if( rst = '1') then
TV_index <= 0;
word_index <= 0;
L0ID_count <= 0;
din <= IDLE_WORD;
metadata <= '0';
valid_data <= '0';
elsif( rising_edge(clk) ) then
if (halt_out = '0') then
if (ready = '1') then
TV_sending <= true;
end if;
if (TV_sending) then
valid_data <= '1';
if (META_ON_RIGHT) then
din <= text_data(TV_index)(word_index)(67 downto 4);
metadata <= text_data(TV_index)(word_index)(0);
else
metadata <= text_data(TV_index)(word_index)(64);
din <= text_data(TV_index)(word_index)(63 downto 0);
end if;
if (word_index = TV_length(TV_index)-1) then
word_index <= 0;
L0ID_count <= L0ID_count + 1;
TV_sending <= false;
if (TV_index = TV_loaded-1) then
TV_index <= 0;
else
TV_index <= TV_index + 1;
end if;
else
word_index <= word_index + 1;
end if;
if (INCREMENT_L0ID and word_index = 0) then
din(39 downto 0) <= std_logic_vector(to_unsigned(L0ID_count, 40));
end if;
else
din <= IDLE_WORD;
metadata <= '0';
valid_data <= '0';
word_index <= 0;
TV_index <= TV_index;
end if;
else -- back pressured
din <= IDLE_WORD;
metadata <= '0';
valid_data <= '0';
word_index <= word_index;
TV_index <= TV_index;
end if;
end if;
end process data_stream;
Generate_Constants : process(clk)
begin
if( rst = '1') then
Constants_from_HBM <= (others => (others => (others => '0')));
ModuleID_from_HBM <= (others => (others => '0'));
SectorID_8L_from_HBM <= (others => '0');
SectorID_13L_from_HBM <= (others => '0');
Constants_Ready_from_HBM <= '0';
read_pipe <= (others => '0');
elsif( rising_edge(clk) ) then
if (read_request_to_HBM = '1') then
SectorID_8L_from_HBM <= SectorID_8L_to_HBM;
for ii in N_Matrix_Row-1 downto 0 loop
for jj in N_Matrix_Col downto 0 loop
Constants_from_HBM(ii)(jj) <= TWO_float; -- one
end loop;
end loop;
for ii in N_Layers_Extrapolated-1 downto 0 loop
ModuleID_from_HBM(ii) <= std_logic_vector(to_unsigned(1000*ii+122, ModuleID_Length));
end loop;
SectorID_13L_from_HBM <= (others => '0');
for ii in SectorID_8L_Length-1 downto 0 loop
SectorID_13L_from_HBM(SectorID_8L_Length-ii-1) <= SectorID_8L_to_HBM(ii);
end loop;
end if;
read_pipe(CONSTANT_LATENCY-1) <= read_request_to_HBM;
for ii in CONSTANT_LATENCY-1 downto 1 loop
read_pipe(ii-1) <= read_pipe(ii);
end loop;
Constants_Ready_from_HBM <= read_pipe(0);
end if;
end process Generate_Constants;
end behav;