OpenCores
URL https://opencores.org/ocsvn/common_pkg/common_pkg/trunk

Subversion Repositories common_pkg

[/] [common_pkg/] [trunk/] [tb_common_pkg.vhd] - Blame information for rev 6

Go to most recent revision | Details | Compare with Previous | View Log

Line No. Rev Author Line
1 6 danv
-------------------------------------------------------------------------------
2
--
3
-- Copyright (C) 2011
4
-- ASTRON (Netherlands Institute for Radio Astronomy) <http://www.astron.nl/>
5
-- JIVE (Joint Institute for VLBI in Europe) <http://www.jive.nl/>
6
-- P.O.Box 2, 7990 AA Dwingeloo, The Netherlands
7
--
8
-- This program is free software: you can redistribute it and/or modify
9
-- it under the terms of the GNU General Public License as published by
10
-- the Free Software Foundation, either version 3 of the License, or
11
-- (at your option) any later version.
12
--
13
-- This program is distributed in the hope that it will be useful,
14
-- but WITHOUT ANY WARRANTY; without even the implied warranty of
15
-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16
-- GNU General Public License for more details.
17
--
18
-- You should have received a copy of the GNU General Public License
19
-- along with this program.  If not, see <http://www.gnu.org/licenses/>.
20
--
21
-------------------------------------------------------------------------------
22
 
23
LIBRARY IEEE;
24
USE IEEE.std_logic_1164.ALL;
25
USE IEEE.NUMERIC_STD.ALL;
26
USE std.textio.ALL;             -- for boolean, integer file IO
27
USE IEEE.std_logic_textio.ALL;  -- for std_logic, std_logic_vector file IO
28
USE work.common_pkg.ALL;
29
 
30
 
31
PACKAGE tb_common_pkg IS
32
 
33
  PROCEDURE proc_common_wait_some_cycles(SIGNAL clk          : IN  STD_LOGIC;
34
                                                c_nof_cycles : IN  NATURAL);
35
 
36
  PROCEDURE proc_common_wait_some_cycles(SIGNAL clk          : IN  STD_LOGIC;
37
                                                c_nof_cycles : IN  REAL);
38
 
39
  PROCEDURE proc_common_wait_some_cycles(SIGNAL clk_in       : IN  STD_LOGIC;
40
                                         SIGNAL clk_out      : IN  STD_LOGIC;
41
                                                c_nof_cycles : IN  NATURAL);
42
 
43
  PROCEDURE proc_common_wait_some_pulses(SIGNAL clk          : IN  STD_LOGIC;
44
                                         SIGNAL pulse        : IN  STD_LOGIC;
45
                                                c_nof_pulses : IN  NATURAL);
46
 
47
  PROCEDURE proc_common_wait_until_evt(SIGNAL clk    : IN  STD_LOGIC;
48
                                       SIGNAL level  : IN  STD_LOGIC);
49
 
50
  PROCEDURE proc_common_wait_until_evt(SIGNAL clk    : IN  STD_LOGIC;
51
                                       SIGNAL level  : IN  INTEGER);
52
 
53
  PROCEDURE proc_common_wait_until_evt(CONSTANT c_timeout : IN  NATURAL;
54
                                       SIGNAL   clk       : IN  STD_LOGIC;
55
                                       SIGNAL   level     : IN  STD_LOGIC);
56
 
57
  PROCEDURE proc_common_wait_until_high(CONSTANT c_timeout : IN  NATURAL;
58
                                        SIGNAL   clk       : IN  STD_LOGIC;
59
                                        SIGNAL   level     : IN  STD_LOGIC);
60
 
61
  PROCEDURE proc_common_wait_until_high(SIGNAL clk    : IN  STD_LOGIC;
62
                                        SIGNAL level  : IN  STD_LOGIC);
63
 
64
  PROCEDURE proc_common_wait_until_low(CONSTANT c_timeout : IN  NATURAL;
65
                                       SIGNAL   clk       : IN  STD_LOGIC;
66
                                       SIGNAL   level     : IN  STD_LOGIC);
67
 
68
  PROCEDURE proc_common_wait_until_low(SIGNAL clk    : IN  STD_LOGIC;
69
                                       SIGNAL level  : IN  STD_LOGIC);
70
 
71
  PROCEDURE proc_common_wait_until_hi_lo(CONSTANT c_timeout : IN  NATURAL;
72
                                         SIGNAL   clk       : IN  STD_LOGIC;
73
                                         SIGNAL   level     : IN  STD_LOGIC);
74
 
75
  PROCEDURE proc_common_wait_until_hi_lo(SIGNAL clk    : IN  STD_LOGIC;
76
                                         SIGNAL level  : IN  STD_LOGIC);
77
 
78
  PROCEDURE proc_common_wait_until_lo_hi(CONSTANT c_timeout : IN  NATURAL;
79
                                         SIGNAL   clk       : IN  STD_LOGIC;
80
                                         SIGNAL   level     : IN  STD_LOGIC);
81
 
82
  PROCEDURE proc_common_wait_until_lo_hi(SIGNAL clk    : IN  STD_LOGIC;
83
                                         SIGNAL level  : IN  STD_LOGIC);
84
 
85
  PROCEDURE proc_common_wait_until_value(CONSTANT c_value : IN  INTEGER;
86
                                         SIGNAL clk       : IN  STD_LOGIC;
87
                                         SIGNAL level     : IN  INTEGER);
88
 
89
  PROCEDURE proc_common_wait_until_value(CONSTANT c_value : IN  INTEGER;
90
                                         SIGNAL clk       : IN  STD_LOGIC;
91
                                         SIGNAL level     : IN  STD_LOGIC_VECTOR);
92
 
93
  PROCEDURE proc_common_wait_until_value(CONSTANT c_timeout : IN  NATURAL;
94
                                         CONSTANT c_value   : IN  INTEGER;
95
                                         SIGNAL clk         : IN  STD_LOGIC;
96
                                         SIGNAL level       : IN  STD_LOGIC_VECTOR);
97
 
98
  -- Wait until absolute simulation time NOW = c_time
99
  PROCEDURE proc_common_wait_until_time(SIGNAL clk      : IN  STD_LOGIC;
100
                                        CONSTANT c_time : IN  TIME);
101
 
102
  -- Exit simulation on timeout failure                                         
103
  PROCEDURE proc_common_timeout_failure(CONSTANT c_timeout : IN TIME;
104
                                        SIGNAL tb_end      : IN STD_LOGIC);
105
 
106
 
107
  -- Stop simulation using severity FAILURE when g_tb_end=TRUE, else for use in multi tb report as severity NOTE
108
  PROCEDURE proc_common_stop_simulation(SIGNAL tb_end : IN STD_LOGIC);
109
 
110
  PROCEDURE proc_common_stop_simulation(CONSTANT g_tb_end  : IN BOOLEAN;
111
                                        CONSTANT g_latency : IN NATURAL;   -- latency between tb_done and tb_)end
112
                                        SIGNAL clk         : IN STD_LOGIC;
113
                                        SIGNAL tb_done     : IN STD_LOGIC;
114
                                        SIGNAL tb_end      : OUT STD_LOGIC);
115
 
116
  PROCEDURE proc_common_stop_simulation(CONSTANT g_tb_end  : IN BOOLEAN;
117
                                        SIGNAL clk         : IN STD_LOGIC;
118
                                        SIGNAL tb_done     : IN STD_LOGIC;
119
                                        SIGNAL tb_end      : OUT STD_LOGIC);
120
 
121
  -- Handle stream ready signal, only support ready latency c_rl = 0 or 1.
122
  PROCEDURE proc_common_ready_latency(CONSTANT c_rl      : IN  NATURAL;
123
                                      SIGNAL   clk       : IN  STD_LOGIC;
124
                                      SIGNAL   enable    : IN  STD_LOGIC;  -- when '1' then active output when ready
125
                                      SIGNAL   ready     : IN  STD_LOGIC;
126
                                      SIGNAL   out_valid : OUT STD_LOGIC);
127
 
128
 
129
  -- Generate a single active, inactive pulse
130
  PROCEDURE proc_common_gen_pulse(CONSTANT c_active : IN  NATURAL;    -- pulse active for nof clk
131
                                  CONSTANT c_period : IN  NATURAL;    -- pulse period for nof clk
132
                                  CONSTANT c_level  : IN  STD_LOGIC;  -- pulse level when active
133
                                  SIGNAL   clk      : IN  STD_LOGIC;
134
                                  SIGNAL   pulse    : OUT STD_LOGIC);
135
 
136
  -- Pulse forever after rst was released
137
  PROCEDURE proc_common_gen_pulse(CONSTANT c_active : IN  NATURAL;    -- pulse active for nof clk
138
                                  CONSTANT c_period : IN  NATURAL;    -- pulse period for nof clk
139
                                  CONSTANT c_level  : IN  STD_LOGIC;  -- pulse level when active
140
                                  SIGNAL   rst      : IN  STD_LOGIC;
141
                                  SIGNAL   clk      : IN  STD_LOGIC;
142
                                  SIGNAL   pulse    : OUT STD_LOGIC);
143
 
144
  -- Generate a single '1', '0' pulse
145
  PROCEDURE proc_common_gen_pulse(SIGNAL clk   : IN  STD_LOGIC;
146
                                  SIGNAL pulse : OUT STD_LOGIC);
147
 
148
  -- Generate a periodic pulse with arbitrary duty cycle
149
  PROCEDURE proc_common_gen_duty_pulse(CONSTANT c_delay     : IN  NATURAL;    -- delay pulse for nof_clk after enable
150
                                       CONSTANT c_active    : IN  NATURAL;    -- pulse active for nof clk
151
                                       CONSTANT c_period    : IN  NATURAL;    -- pulse period for nof clk
152
                                       CONSTANT c_level     : IN  STD_LOGIC;  -- pulse level when active
153
                                       SIGNAL   rst         : IN  STD_LOGIC;
154
                                       SIGNAL   clk         : IN  STD_LOGIC;
155
                                       SIGNAL   enable      : IN  STD_LOGIC;  -- once enabled, the pulse remains enabled
156
                                       SIGNAL   pulse       : OUT STD_LOGIC);
157
 
158
  PROCEDURE proc_common_gen_duty_pulse(CONSTANT c_active    : IN  NATURAL;    -- pulse active for nof clk
159
                                       CONSTANT c_period    : IN  NATURAL;    -- pulse period for nof clk
160
                                       CONSTANT c_level     : IN  STD_LOGIC;  -- pulse level when active
161
                                       SIGNAL   rst         : IN  STD_LOGIC;
162
                                       SIGNAL   clk         : IN  STD_LOGIC;
163
                                       SIGNAL   enable      : IN  STD_LOGIC;  -- once enabled, the pulse remains enabled
164
                                       SIGNAL   pulse       : OUT STD_LOGIC);
165
 
166
  -- Generate counter data with valid and arbitrary increment or fixed increment=1
167
  PROCEDURE proc_common_gen_data(CONSTANT c_rl        : IN  NATURAL;    -- 0, 1 are supported by proc_common_ready_latency()
168
                                 CONSTANT c_init      : IN  INTEGER;
169
                                 CONSTANT c_incr      : IN  INTEGER;
170
                                 SIGNAL   rst         : IN  STD_LOGIC;
171
                                 SIGNAL   clk         : IN  STD_LOGIC;
172
                                 SIGNAL   enable      : IN  STD_LOGIC;  -- when '0' then no valid output even when ready='1'
173
                                 SIGNAL   ready       : IN  STD_LOGIC;
174
                                 SIGNAL   out_data    : OUT STD_LOGIC_VECTOR;
175
                                 SIGNAL   out_valid   : OUT STD_LOGIC);
176
 
177
  PROCEDURE proc_common_gen_data(CONSTANT c_rl        : IN  NATURAL;    -- 0, 1 are supported by proc_common_ready_latency()
178
                                 CONSTANT c_init      : IN  INTEGER;
179
                                 SIGNAL   rst         : IN  STD_LOGIC;
180
                                 SIGNAL   clk         : IN  STD_LOGIC;
181
                                 SIGNAL   enable      : IN  STD_LOGIC;  -- when '0' then no valid output even when ready='1'
182
                                 SIGNAL   ready       : IN  STD_LOGIC;
183
                                 SIGNAL   out_data    : OUT STD_LOGIC_VECTOR;
184
                                 SIGNAL   out_valid   : OUT STD_LOGIC);
185
 
186
  -- Generate frame control
187
  PROCEDURE proc_common_sop(SIGNAL clk     : IN  STD_LOGIC;
188
                            SIGNAL in_val  : OUT STD_LOGIC;
189
                            SIGNAL in_sop  : OUT STD_LOGIC);
190
 
191
  PROCEDURE proc_common_eop(SIGNAL clk     : IN  STD_LOGIC;
192
                            SIGNAL in_val  : OUT STD_LOGIC;
193
                            SIGNAL in_eop  : OUT STD_LOGIC);
194
 
195
  PROCEDURE proc_common_val(CONSTANT c_val_len : IN NATURAL;
196
                            SIGNAL   clk       : IN  STD_LOGIC;
197
                            SIGNAL   in_val    : OUT STD_LOGIC);
198
 
199
  PROCEDURE proc_common_val_duty(CONSTANT c_hi_len  : IN NATURAL;
200
                                 CONSTANT c_lo_len  : IN NATURAL;
201
                                 SIGNAL   clk       : IN  STD_LOGIC;
202
                                 SIGNAL   in_val    : OUT STD_LOGIC);
203
 
204
  PROCEDURE proc_common_eop_flush(CONSTANT c_flush_len : IN NATURAL;
205
                                  SIGNAL   clk         : IN  STD_LOGIC;
206
                                  SIGNAL   in_val      : OUT STD_LOGIC;
207
                                  SIGNAL   in_eop      : OUT STD_LOGIC);
208
 
209
  -- Verify the DUT output incrementing data, only support ready latency c_rl = 0 or 1.
210
  PROCEDURE proc_common_verify_data(CONSTANT c_rl            : IN    NATURAL;
211
                                    SIGNAL   clk             : IN    STD_LOGIC;
212
                                    SIGNAL   verify_en       : IN    STD_LOGIC;
213
                                    SIGNAL   ready           : IN    STD_LOGIC;
214
                                    SIGNAL   out_valid       : IN    STD_LOGIC;
215
                                    SIGNAL   out_data        : IN    STD_LOGIC_VECTOR;
216
                                    SIGNAL   prev_out_data   : INOUT STD_LOGIC_VECTOR);
217
 
218
  -- Verify the DUT output valid for ready latency, only support ready latency c_rl = 0 or 1.
219
  PROCEDURE proc_common_verify_valid(CONSTANT c_rl        : IN    NATURAL;
220
                                     SIGNAL   clk         : IN    STD_LOGIC;
221
                                     SIGNAL   verify_en   : IN    STD_LOGIC;
222
                                     SIGNAL   ready       : IN    STD_LOGIC;
223
                                     SIGNAL   prev_ready  : INOUT STD_LOGIC;
224
                                     SIGNAL   out_valid   : IN    STD_LOGIC);
225
 
226
  -- Verify the DUT input to output latency for SL ctrl signals
227
  PROCEDURE proc_common_verify_latency(CONSTANT c_str         : IN    STRING;   -- e.g. "valid", "sop", "eop"
228
                                       CONSTANT c_latency     : IN    NATURAL;
229
                                       SIGNAL   clk           : IN    STD_LOGIC;
230
                                       SIGNAL   verify_en     : IN    STD_LOGIC;
231
                                       SIGNAL   in_ctrl       : IN    STD_LOGIC;
232
                                       SIGNAL   pipe_ctrl_vec : INOUT STD_LOGIC_VECTOR;  -- range [0:c_latency]
233
                                       SIGNAL   out_ctrl      : IN    STD_LOGIC);
234
 
235
  -- Verify the DUT input to output latency for SLV data signals
236
  PROCEDURE proc_common_verify_latency(CONSTANT c_str         : IN    STRING;   -- e.g. "data"
237
                                       CONSTANT c_latency     : IN    NATURAL;
238
                                       SIGNAL   clk           : IN    STD_LOGIC;
239
                                       SIGNAL   verify_en     : IN    STD_LOGIC;
240
                                       SIGNAL   in_data       : IN    STD_LOGIC_VECTOR;
241
                                       SIGNAL   pipe_data_vec : INOUT STD_LOGIC_VECTOR;  -- range [0:(1 + c_latency)*c_data_w-1]
242
                                       SIGNAL   out_data      : IN    STD_LOGIC_VECTOR);
243
 
244
  -- Verify the expected value, e.g. to check that a test has ran at all
245
  PROCEDURE proc_common_verify_value(CONSTANT mode : IN NATURAL;
246
                                     SIGNAL   clk  : IN STD_LOGIC;
247
                                     SIGNAL   en   : IN STD_LOGIC;
248
                                     SIGNAL   exp  : IN STD_LOGIC_VECTOR;
249
                                     SIGNAL   res  : IN STD_LOGIC_VECTOR);
250
  -- open, read line, close file
251
  PROCEDURE proc_common_open_file(file_status  : INOUT FILE_OPEN_STATUS;
252
                                  FILE in_file : TEXT;
253
                                  file_name    : IN STRING;
254
                                  file_mode    : IN FILE_OPEN_KIND);
255
 
256
  PROCEDURE proc_common_readline_file(file_status  : INOUT FILE_OPEN_STATUS;
257
                                      FILE in_file : TEXT;
258
                                      read_value_0 : OUT INTEGER);
259
 
260
  PROCEDURE proc_common_readline_file(file_status  : INOUT FILE_OPEN_STATUS;
261
                                      FILE in_file : TEXT;
262
                                      read_value_0 : OUT INTEGER;
263
                                      read_value_1 : OUT INTEGER);
264
 
265
  PROCEDURE proc_common_readline_file(file_status  : INOUT FILE_OPEN_STATUS;
266
                                      FILE in_file : TEXT;
267
                                      value_array  : OUT t_integer_arr;
268
                                      nof_reads    : IN  INTEGER);
269
 
270
  PROCEDURE proc_common_readline_file(file_status  : INOUT FILE_OPEN_STATUS;
271
                                      FILE in_file : TEXT;
272
                                      read_slv     : OUT STD_LOGIC_VECTOR);
273
 
274
  PROCEDURE proc_common_readline_file(file_status  : INOUT FILE_OPEN_STATUS;
275
                                      FILE in_file : TEXT;
276
                                      res_string   : OUT STRING);
277
 
278
  PROCEDURE proc_common_close_file(file_status  : INOUT FILE_OPEN_STATUS;
279
                                   FILE in_file : TEXT);
280
 
281
  -- read entire file
282
  PROCEDURE proc_common_read_integer_file(file_name              : IN  STRING;
283
                                          nof_header_lines       : NATURAL;
284
                                          nof_row                : NATURAL;
285
                                          nof_col                : NATURAL;
286
                                          SIGNAL return_array    : OUT t_integer_arr);
287
 
288
  PROCEDURE proc_common_read_mif_file(file_name           : IN  STRING;
289
                                      SIGNAL return_array : OUT t_integer_arr);
290
 
291
  -- Complex multiply function with conjugate option for input b
292
  FUNCTION func_complex_multiply(in_ar, in_ai, in_br, in_bi : STD_LOGIC_VECTOR; conjugate_b : BOOLEAN; str : STRING; g_out_dat_w : NATURAL) RETURN STD_LOGIC_VECTOR;
293
 
294
  FUNCTION func_decstring_to_integer(in_string: STRING) RETURN INTEGER;
295
 
296
  FUNCTION func_hexstring_to_integer(in_string: STRING) RETURN INTEGER;
297
 
298
  FUNCTION func_find_char_in_string(in_string: STRING; find_char: CHARACTER) RETURN INTEGER;
299
 
300
  FUNCTION func_find_string_in_string(in_string: STRING; find_string: STRING) RETURN BOOLEAN;
301
 
302
END tb_common_pkg;
303
 
304
 
305
PACKAGE BODY tb_common_pkg IS
306
 
307
  ------------------------------------------------------------------------------
308
  -- PROCEDURE: Wait some clock cycles
309
  ------------------------------------------------------------------------------
310
  PROCEDURE proc_common_wait_some_cycles(SIGNAL clk          : IN  STD_LOGIC;
311
                                                c_nof_cycles : IN  NATURAL) IS
312
  BEGIN
313
    FOR I IN 0 TO c_nof_cycles-1 LOOP WAIT UNTIL rising_edge(clk); END LOOP;
314
  END proc_common_wait_some_cycles;
315
 
316
  PROCEDURE proc_common_wait_some_cycles(SIGNAL clk          : IN  STD_LOGIC;
317
                                                c_nof_cycles : IN  REAL) IS
318
  BEGIN
319
    proc_common_wait_some_cycles(clk, NATURAL(c_nof_cycles));
320
  END proc_common_wait_some_cycles;
321
 
322
  PROCEDURE proc_common_wait_some_cycles(SIGNAL clk_in       : IN  STD_LOGIC;
323
                                         SIGNAL clk_out      : IN  STD_LOGIC;
324
                                                c_nof_cycles : IN  NATURAL) IS
325
  BEGIN
326
    proc_common_wait_some_cycles(clk_in, c_nof_cycles);
327
    proc_common_wait_some_cycles(clk_out, c_nof_cycles);
328
  END proc_common_wait_some_cycles;
329
 
330
  ------------------------------------------------------------------------------
331
  -- PROCEDURE: Wait some pulses
332
  ------------------------------------------------------------------------------
333
  PROCEDURE proc_common_wait_some_pulses(SIGNAL clk          : IN  STD_LOGIC;
334
                                         SIGNAL pulse        : IN  STD_LOGIC;
335
                                                c_nof_pulses : IN  NATURAL) IS
336
  BEGIN
337
    FOR I IN 0 TO c_nof_pulses-1 LOOP
338
      proc_common_wait_until_hi_lo(clk, pulse);
339
    END LOOP;
340
  END proc_common_wait_some_pulses;
341
 
342
  ------------------------------------------------------------------------------
343
  -- PROCEDURE: Wait until the level input event
344
  -- PROCEDURE: Wait until the level input is high
345
  -- PROCEDURE: Wait until the level input is low
346
  -- PROCEDURE: Wait until the       input is equal to c_value
347
  ------------------------------------------------------------------------------
348
  PROCEDURE proc_common_wait_until_evt(SIGNAL clk    : IN  STD_LOGIC;
349
                                       SIGNAL level  : IN  STD_LOGIC) IS
350
    VARIABLE v_level : STD_LOGIC := level;
351
  BEGIN
352
    WAIT UNTIL rising_edge(clk);
353
    WHILE v_level=level LOOP
354
      v_level := level;
355
      WAIT UNTIL rising_edge(clk);
356
    END LOOP;
357
  END proc_common_wait_until_evt;
358
 
359
  PROCEDURE proc_common_wait_until_evt(SIGNAL clk    : IN  STD_LOGIC;
360
                                       SIGNAL level  : IN  INTEGER) IS
361
    VARIABLE v_level : INTEGER := level;
362
  BEGIN
363
    WAIT UNTIL rising_edge(clk);
364
    WHILE v_level=level LOOP
365
      v_level := level;
366
      WAIT UNTIL rising_edge(clk);
367
    END LOOP;
368
  END proc_common_wait_until_evt;
369
 
370
  PROCEDURE proc_common_wait_until_evt(CONSTANT c_timeout : IN  NATURAL;
371
                                       SIGNAL   clk       : IN  STD_LOGIC;
372
                                       SIGNAL   level     : IN  STD_LOGIC) IS
373
    VARIABLE v_level : STD_LOGIC := level;
374
    VARIABLE v_I     : NATURAL := 0;
375
  BEGIN
376
    WAIT UNTIL rising_edge(clk);
377
    WHILE v_level=level LOOP
378
      v_level := level;
379
      WAIT UNTIL rising_edge(clk);
380
      v_I := v_I + 1;
381
      IF v_I>=c_timeout-1 THEN
382
        REPORT "COMMON : level evt timeout" SEVERITY ERROR;
383
        EXIT;
384
      END IF;
385
    END LOOP;
386
  END proc_common_wait_until_evt;
387
 
388
  PROCEDURE proc_common_wait_until_high(SIGNAL clk    : IN  STD_LOGIC;
389
                                        SIGNAL level  : IN  STD_LOGIC) IS
390
  BEGIN
391
    IF level/='1' THEN
392
      WAIT UNTIL rising_edge(clk) AND level='1';
393
    END IF;
394
  END proc_common_wait_until_high;
395
 
396
  PROCEDURE proc_common_wait_until_high(CONSTANT c_timeout : IN  NATURAL;
397
                                        SIGNAL   clk       : IN  STD_LOGIC;
398
                                        SIGNAL   level     : IN  STD_LOGIC) IS
399
  BEGIN
400
    FOR I IN 0 TO c_timeout-1 LOOP
401
      IF level='1' THEN
402
        EXIT;
403
      ELSE
404
        IF I=c_timeout-1 THEN
405
          REPORT "COMMON : level high timeout" SEVERITY ERROR;
406
        END IF;
407
        WAIT UNTIL rising_edge(clk);
408
      END IF;
409
    END LOOP;
410
  END proc_common_wait_until_high;
411
 
412
  PROCEDURE proc_common_wait_until_low(SIGNAL clk    : IN  STD_LOGIC;
413
                                       SIGNAL level  : IN  STD_LOGIC) IS
414
  BEGIN
415
    IF level/='0' THEN
416
      WAIT UNTIL rising_edge(clk) AND level='0';
417
    END IF;
418
  END proc_common_wait_until_low;
419
 
420
  PROCEDURE proc_common_wait_until_low(CONSTANT c_timeout : IN  NATURAL;
421
                                       SIGNAL   clk       : IN  STD_LOGIC;
422
                                       SIGNAL   level     : IN  STD_LOGIC) IS
423
  BEGIN
424
    FOR I IN 0 TO c_timeout-1 LOOP
425
      IF level='0' THEN
426
        EXIT;
427
      ELSE
428
        IF I=c_timeout-1 THEN
429
          REPORT "COMMON : level low timeout" SEVERITY ERROR;
430
        END IF;
431
        WAIT UNTIL rising_edge(clk);
432
      END IF;
433
    END LOOP;
434
  END proc_common_wait_until_low;
435
 
436
  PROCEDURE proc_common_wait_until_hi_lo(SIGNAL clk    : IN  STD_LOGIC;
437
                                         SIGNAL level  : IN  STD_LOGIC) IS
438
  BEGIN
439
    IF level/='1' THEN
440
      proc_common_wait_until_high(clk, level);
441
    END IF;
442
    proc_common_wait_until_low(clk, level);
443
  END proc_common_wait_until_hi_lo;
444
 
445
  PROCEDURE proc_common_wait_until_hi_lo(CONSTANT c_timeout : IN  NATURAL;
446
                                         SIGNAL   clk       : IN  STD_LOGIC;
447
                                         SIGNAL   level     : IN  STD_LOGIC) IS
448
  BEGIN
449
    IF level/='1' THEN
450
      proc_common_wait_until_high(c_timeout, clk, level);
451
    END IF;
452
    proc_common_wait_until_low(c_timeout, clk, level);
453
  END proc_common_wait_until_hi_lo;
454
 
455
  PROCEDURE proc_common_wait_until_lo_hi(SIGNAL clk    : IN  STD_LOGIC;
456
                                         SIGNAL level  : IN  STD_LOGIC) IS
457
  BEGIN
458
    IF level/='0' THEN
459
      proc_common_wait_until_low(clk, level);
460
    END IF;
461
    proc_common_wait_until_high(clk, level);
462
  END proc_common_wait_until_lo_hi;
463
 
464
  PROCEDURE proc_common_wait_until_lo_hi(CONSTANT c_timeout : IN  NATURAL;
465
                                         SIGNAL   clk       : IN  STD_LOGIC;
466
                                         SIGNAL   level     : IN  STD_LOGIC) IS
467
  BEGIN
468
    IF level/='0' THEN
469
      proc_common_wait_until_low(c_timeout, clk, level);
470
    END IF;
471
    proc_common_wait_until_high(c_timeout, clk, level);
472
  END proc_common_wait_until_lo_hi;
473
 
474
  PROCEDURE proc_common_wait_until_value(CONSTANT c_value : IN  INTEGER;
475
                                         SIGNAL clk       : IN  STD_LOGIC;
476
                                         SIGNAL level     : IN  INTEGER) IS
477
  BEGIN
478
    WHILE level/=c_value LOOP
479
      WAIT UNTIL rising_edge(clk);
480
    END LOOP;
481
  END proc_common_wait_until_value;
482
 
483
  PROCEDURE proc_common_wait_until_value(CONSTANT c_value : IN  INTEGER;
484
                                         SIGNAL clk       : IN  STD_LOGIC;
485
                                         SIGNAL level     : IN  STD_LOGIC_VECTOR) IS
486
  BEGIN
487
    WHILE SIGNED(level)/=c_value LOOP
488
      WAIT UNTIL rising_edge(clk);
489
    END LOOP;
490
  END proc_common_wait_until_value;
491
 
492
  PROCEDURE proc_common_wait_until_value(CONSTANT c_timeout : IN  NATURAL;
493
                                         CONSTANT c_value   : IN  INTEGER;
494
                                         SIGNAL clk         : IN  STD_LOGIC;
495
                                         SIGNAL level       : IN  STD_LOGIC_VECTOR) IS
496
  BEGIN
497
    FOR I IN 0 TO c_timeout-1 LOOP
498
      IF SIGNED(level)=c_value THEN
499
        EXIT;
500
      ELSE
501
        IF I=c_timeout-1 THEN
502
          REPORT "COMMON : level value timeout" SEVERITY ERROR;
503
        END IF;
504
        WAIT UNTIL rising_edge(clk);
505
      END IF;
506
    END LOOP;
507
  END proc_common_wait_until_value;
508
 
509
  PROCEDURE proc_common_wait_until_time(SIGNAL clk      : IN  STD_LOGIC;
510
                                        CONSTANT c_time : IN  TIME) IS
511
  BEGIN
512
    WHILE NOW < c_time LOOP
513
      WAIT UNTIL rising_edge(clk);
514
    END LOOP;
515
  END PROCEDURE;
516
 
517
  PROCEDURE proc_common_timeout_failure(CONSTANT c_timeout : IN TIME;
518
                                        SIGNAL tb_end      : IN STD_LOGIC) IS
519
  BEGIN
520
    WHILE tb_end='0' LOOP
521
      ASSERT NOW < c_timeout REPORT "Test bench timeout." SEVERITY FAILURE;
522
      WAIT FOR 1 us;
523
    END LOOP;
524
  END PROCEDURE;
525
 
526
  PROCEDURE proc_common_stop_simulation(SIGNAL tb_end : IN STD_LOGIC) IS
527
  BEGIN
528
    WAIT UNTIL tb_end='1';
529
    -- For modelsim_regression_test_vhdl.py:
530
    -- The tb_end will stop the test verification bases on error or failure. The wait is necessary to
531
    -- stop the simulation using failure, without causing the test to fail.
532
    WAIT FOR 1 ns;
533
    REPORT "Tb simulation finished." SEVERITY FAILURE;
534
    WAIT;
535
  END PROCEDURE;
536
 
537
  PROCEDURE proc_common_stop_simulation(CONSTANT g_tb_end  : IN BOOLEAN;
538
                                        CONSTANT g_latency : IN NATURAL;
539
                                        SIGNAL clk         : IN STD_LOGIC;
540
                                        SIGNAL tb_done     : IN STD_LOGIC;
541
                                        SIGNAL tb_end      : OUT STD_LOGIC) IS
542
  BEGIN
543
    -- Wait until simulation indicates done
544
    proc_common_wait_until_high(clk, tb_done);
545
 
546
    -- Wait some more cycles
547
    proc_common_wait_some_cycles(clk, g_latency);
548
 
549
    -- Stop the simulation or only report NOTE
550
    tb_end <= '1';
551
    -- For modelsim_regression_test_vhdl.py:
552
    -- The tb_end will stop the test verification bases on error or failure. The wait is necessary to
553
    -- stop the simulation using failure, without causing the test to fail.
554
    WAIT FOR 1 ns;
555
    IF g_tb_end=FALSE THEN
556
      REPORT "Tb Simulation finished." SEVERITY NOTE;
557
    ELSE
558
      REPORT "Tb Simulation finished." SEVERITY FAILURE;
559
    END IF;
560
    WAIT;
561
  END PROCEDURE;
562
 
563
  PROCEDURE proc_common_stop_simulation(CONSTANT g_tb_end  : IN BOOLEAN;
564
                                        SIGNAL clk         : IN STD_LOGIC;
565
                                        SIGNAL tb_done     : IN STD_LOGIC;
566
                                        SIGNAL tb_end      : OUT STD_LOGIC) IS
567
  BEGIN
568
    proc_common_stop_simulation(g_tb_end, 0, clk, tb_done, tb_end);
569
  END PROCEDURE;
570
 
571
  ------------------------------------------------------------------------------
572
  -- PROCEDURE: Handle stream ready signal for data valid
573
  -- . output active when ready='1' and enable='1'
574
  -- . only support ready latency c_rl = 0 or 1
575
  ------------------------------------------------------------------------------
576
  PROCEDURE proc_common_ready_latency(CONSTANT c_rl      : IN  NATURAL;
577
                                      SIGNAL   clk       : IN  STD_LOGIC;
578
                                      SIGNAL   enable    : IN  STD_LOGIC;
579
                                      SIGNAL   ready     : IN  STD_LOGIC;
580
                                      SIGNAL   out_valid : OUT STD_LOGIC) IS
581
  BEGIN
582
    -- skip ready cycles until enable='1'
583
    out_valid <= '0';
584
    WHILE enable='0' LOOP
585
      IF c_rl=0 THEN
586
        WAIT UNTIL rising_edge(clk);
587
        WHILE ready /= '1' LOOP
588
          WAIT UNTIL rising_edge(clk);
589
        END LOOP;
590
      END IF;
591
      IF c_rl=1 THEN
592
        WHILE ready /= '1' LOOP
593
          WAIT UNTIL rising_edge(clk);
594
        END LOOP;
595
        WAIT UNTIL rising_edge(clk);
596
      END IF;
597
    END LOOP;
598
    -- active output when ready
599
    IF c_rl=0 THEN
600
      out_valid <= '1';
601
      WAIT UNTIL rising_edge(clk);
602
      WHILE ready /= '1' LOOP
603
        WAIT UNTIL rising_edge(clk);
604
      END LOOP;
605
    END IF;
606
    IF c_rl=1 THEN
607
      WHILE ready /= '1' LOOP
608
        out_valid <= '0';
609
        WAIT UNTIL rising_edge(clk);
610
      END LOOP;
611
      out_valid <= '1';
612
      WAIT UNTIL rising_edge(clk);
613
    END IF;
614
  END proc_common_ready_latency;
615
 
616
  ------------------------------------------------------------------------------
617
  -- PROCEDURE: Generate a single active, inactive pulse
618
  ------------------------------------------------------------------------------
619
  PROCEDURE proc_common_gen_pulse(CONSTANT c_active  : IN  NATURAL;    -- pulse active for nof clk
620
                                  CONSTANT c_period  : IN  NATURAL;    -- pulse period for nof clk
621
                                  CONSTANT c_level   : IN  STD_LOGIC;  -- pulse level when active
622
                                  SIGNAL   clk       : IN  STD_LOGIC;
623
                                  SIGNAL   pulse     : OUT STD_LOGIC) IS
624
    VARIABLE v_cnt : NATURAL RANGE 0 TO c_period := 0;
625
  BEGIN
626
    WHILE v_cnt<c_period LOOP
627
      IF v_cnt<c_active THEN
628
        pulse <= c_level;
629
      ELSE
630
        pulse <= NOT c_level;
631
      END IF;
632
      v_cnt := v_cnt+1;
633
      WAIT UNTIL rising_edge(clk);
634
    END LOOP;
635
  END proc_common_gen_pulse;
636
 
637
  -- Pulse forever after rst was released
638
  PROCEDURE proc_common_gen_pulse(CONSTANT c_active  : IN  NATURAL;    -- pulse active for nof clk
639
                                  CONSTANT c_period  : IN  NATURAL;    -- pulse period for nof clk
640
                                  CONSTANT c_level   : IN  STD_LOGIC;  -- pulse level when active
641
                                  SIGNAL   rst       : IN  STD_LOGIC;
642
                                  SIGNAL   clk       : IN  STD_LOGIC;
643
                                  SIGNAL   pulse     : OUT STD_LOGIC) IS
644
    VARIABLE v_cnt : NATURAL RANGE 0 TO c_period := 0;
645
  BEGIN
646
    pulse <= NOT c_level;
647
    IF rst='0' THEN
648
      WAIT UNTIL rising_edge(clk);
649
      WHILE TRUE LOOP
650
        proc_common_gen_pulse(c_active, c_period, c_level, clk, pulse);
651
      END LOOP;
652
    END IF;
653
  END proc_common_gen_pulse;
654
 
655
  -- pulse '1', '0'
656
  PROCEDURE proc_common_gen_pulse(SIGNAL clk   : IN  STD_LOGIC;
657
                                  SIGNAL pulse : OUT STD_LOGIC) IS
658
  BEGIN
659
    proc_common_gen_pulse(1, 2, '1', clk, pulse);
660
  END proc_common_gen_pulse;
661
 
662
  ------------------------------------------------------------------------------
663
  -- PROCEDURE: Generate a periodic pulse with arbitrary duty cycle
664
  ------------------------------------------------------------------------------
665
  PROCEDURE proc_common_gen_duty_pulse(CONSTANT c_delay     : IN  NATURAL;    -- delay pulse for nof_clk after enable
666
                                       CONSTANT c_active    : IN  NATURAL;    -- pulse active for nof clk
667
                                       CONSTANT c_period    : IN  NATURAL;    -- pulse period for nof clk
668
                                       CONSTANT c_level     : IN  STD_LOGIC;  -- pulse level when active
669
                                       SIGNAL   rst         : IN  STD_LOGIC;
670
                                       SIGNAL   clk         : IN  STD_LOGIC;
671
                                       SIGNAL   enable      : IN  STD_LOGIC;
672
                                       SIGNAL   pulse       : OUT STD_LOGIC) IS
673
    VARIABLE v_cnt : NATURAL RANGE 0 TO c_period-1 := 0;
674
  BEGIN
675
    pulse <= NOT c_level;
676
    IF rst='0' THEN
677
      proc_common_wait_until_high(clk, enable);    -- if enabled then continue immediately else wait here
678
      proc_common_wait_some_cycles(clk, c_delay);  -- apply initial c_delay. Once enabled, the pulse remains enabled
679
      WHILE TRUE LOOP
680
        WAIT UNTIL rising_edge(clk);
681
        IF v_cnt<c_active THEN
682
          pulse <= c_level;
683
        ELSE
684
          pulse <= NOT c_level;
685
        END IF;
686
        IF v_cnt<c_period-1 THEN
687
          v_cnt := v_cnt+1;
688
        ELSE
689
          v_cnt := 0;
690
        END IF;
691
      END LOOP;
692
    END IF;
693
  END proc_common_gen_duty_pulse;
694
 
695
  PROCEDURE proc_common_gen_duty_pulse(CONSTANT c_active    : IN  NATURAL;    -- pulse active for nof clk
696
                                       CONSTANT c_period    : IN  NATURAL;    -- pulse period for nof clk
697
                                       CONSTANT c_level     : IN  STD_LOGIC;  -- pulse level when active
698
                                       SIGNAL   rst         : IN  STD_LOGIC;
699
                                       SIGNAL   clk         : IN  STD_LOGIC;
700
                                       SIGNAL   enable      : IN  STD_LOGIC;
701
                                       SIGNAL   pulse       : OUT STD_LOGIC) IS
702
  BEGIN
703
    proc_common_gen_duty_pulse(0, c_active, c_period, c_level, rst, clk, enable, pulse);
704
  END proc_common_gen_duty_pulse;
705
 
706
  ------------------------------------------------------------------------------
707
  -- PROCEDURE: Generate counter data with valid
708
  -- . Output counter data dependent on enable and ready
709
  ------------------------------------------------------------------------------
710
  -- arbitrary c_incr
711
  PROCEDURE proc_common_gen_data(CONSTANT c_rl        : IN  NATURAL;    -- 0, 1 are supported by proc_common_ready_latency()
712
                                 CONSTANT c_init      : IN  INTEGER;
713
                                 CONSTANT c_incr      : IN  INTEGER;
714
                                 SIGNAL   rst         : IN  STD_LOGIC;
715
                                 SIGNAL   clk         : IN  STD_LOGIC;
716
                                 SIGNAL   enable      : IN  STD_LOGIC;  -- when '0' then no valid output even when ready='1'
717
                                 SIGNAL   ready       : IN  STD_LOGIC;
718
                                 SIGNAL   out_data    : OUT STD_LOGIC_VECTOR;
719
                                 SIGNAL   out_valid   : OUT STD_LOGIC) IS
720
    CONSTANT c_data_w  : NATURAL := out_data'LENGTH;
721
    VARIABLE v_data    : STD_LOGIC_VECTOR(c_data_w-1 DOWNTO 0):= TO_SVEC(c_init, c_data_w);
722
  BEGIN
723
    out_valid <= '0';
724
    out_data  <= v_data;
725
    IF rst='0' THEN
726
      WAIT UNTIL rising_edge(clk);
727
      WHILE TRUE LOOP
728
        out_data <= v_data;
729
        proc_common_ready_latency(c_rl, clk, enable, ready, out_valid);
730
        v_data := INCR_UVEC(v_data, c_incr);
731
      END LOOP;
732
    END IF;
733
  END proc_common_gen_data;
734
 
735
  -- c_incr = 1
736
  PROCEDURE proc_common_gen_data(CONSTANT c_rl        : IN  NATURAL;    -- 0, 1 are supported by proc_common_ready_latency()
737
                                 CONSTANT c_init      : IN  INTEGER;
738
                                 SIGNAL   rst         : IN  STD_LOGIC;
739
                                 SIGNAL   clk         : IN  STD_LOGIC;
740
                                 SIGNAL   enable      : IN  STD_LOGIC;  -- when '0' then no valid output even when ready='1'
741
                                 SIGNAL   ready       : IN  STD_LOGIC;
742
                                 SIGNAL   out_data    : OUT STD_LOGIC_VECTOR;
743
                                 SIGNAL   out_valid   : OUT STD_LOGIC) IS
744
  BEGIN
745
    proc_common_gen_data(c_rl, c_init, 1, rst, clk, enable, ready, out_data, out_valid);
746
  END proc_common_gen_data;
747
 
748
 
749
  ------------------------------------------------------------------------------
750
  -- PROCEDURE: Generate frame control
751
  ------------------------------------------------------------------------------
752
  PROCEDURE proc_common_sop(SIGNAL clk     : IN  STD_LOGIC;
753
                            SIGNAL in_val  : OUT STD_LOGIC;
754
                            SIGNAL in_sop  : OUT STD_LOGIC) IS
755
  BEGIN
756
    in_val <= '1';
757
    in_sop <= '1';
758
    proc_common_wait_some_cycles(clk, 1);
759
    in_sop <= '0';
760
  END proc_common_sop;
761
 
762
  PROCEDURE proc_common_eop(SIGNAL clk     : IN  STD_LOGIC;
763
                            SIGNAL in_val  : OUT STD_LOGIC;
764
                            SIGNAL in_eop  : OUT STD_LOGIC) IS
765
  BEGIN
766
    in_val <= '1';
767
    in_eop <= '1';
768
    proc_common_wait_some_cycles(clk, 1);
769
    in_val <= '0';
770
    in_eop <= '0';
771
  END proc_common_eop;
772
 
773
  PROCEDURE proc_common_val(CONSTANT c_val_len : IN NATURAL;
774
                            SIGNAL   clk       : IN  STD_LOGIC;
775
                            SIGNAL   in_val    : OUT STD_LOGIC) IS
776
  BEGIN
777
    in_val <= '1';
778
    proc_common_wait_some_cycles(clk, c_val_len);
779
    in_val <= '0';
780
  END proc_common_val;
781
 
782
  PROCEDURE proc_common_val_duty(CONSTANT c_hi_len  : IN NATURAL;
783
                                 CONSTANT c_lo_len  : IN NATURAL;
784
                                 SIGNAL   clk       : IN  STD_LOGIC;
785
                                 SIGNAL   in_val    : OUT STD_LOGIC) IS
786
  BEGIN
787
    in_val <= '1';
788
    proc_common_wait_some_cycles(clk, c_hi_len);
789
    in_val <= '0';
790
    proc_common_wait_some_cycles(clk, c_lo_len);
791
  END proc_common_val_duty;
792
 
793
  PROCEDURE proc_common_eop_flush(CONSTANT c_flush_len : IN NATURAL;
794
                                  SIGNAL   clk         : IN  STD_LOGIC;
795
                                  SIGNAL   in_val      : OUT STD_LOGIC;
796
                                  SIGNAL   in_eop      : OUT STD_LOGIC) IS
797
  BEGIN
798
    -- . eop
799
    proc_common_eop(clk, in_val, in_eop);
800
    -- . flush after in_eop to empty the shift register
801
    proc_common_wait_some_cycles(clk, c_flush_len);
802
  END proc_common_eop_flush;
803
 
804
 
805
  ------------------------------------------------------------------------------
806
  -- PROCEDURE: Verify incrementing data
807
  ------------------------------------------------------------------------------
808
  PROCEDURE proc_common_verify_data(CONSTANT c_rl            : IN    NATURAL;
809
                                    SIGNAL   clk             : IN    STD_LOGIC;
810
                                    SIGNAL   verify_en       : IN    STD_LOGIC;
811
                                    SIGNAL   ready           : IN    STD_LOGIC;
812
                                    SIGNAL   out_valid       : IN    STD_LOGIC;
813
                                    SIGNAL   out_data        : IN    STD_LOGIC_VECTOR;
814
                                    SIGNAL   prev_out_data   : INOUT STD_LOGIC_VECTOR) IS
815
    VARIABLE v_exp_data : STD_LOGIC_VECTOR(out_data'RANGE);
816
  BEGIN
817
    IF rising_edge(clk) THEN
818
      -- out_valid must be active, because only the out_data will it differ from the previous out_data
819
      IF out_valid='1' THEN
820
        -- for ready_latency = 1 out_valid indicates new data
821
        -- for ready_latency = 0 out_valid only indicates new data when it is confirmed by ready
822
        IF c_rl=1 OR (c_rl=0 AND ready='1') THEN
823
          prev_out_data <= out_data;
824
          v_exp_data := INCR_UVEC(prev_out_data, 1);  -- increment first then compare to also support increment wrap around
825
          IF verify_en='1' AND UNSIGNED(out_data) /= UNSIGNED(v_exp_data) THEN
826
            REPORT "COMMON : Wrong out_data count" SEVERITY ERROR;
827
          END IF;
828
        END IF;
829
      END IF;
830
    END IF;
831
  END proc_common_verify_data;
832
 
833
 
834
  ------------------------------------------------------------------------------
835
  -- PROCEDURE: Verify the DUT output valid
836
  -- . only support ready latency c_rl = 0 or 1
837
  ------------------------------------------------------------------------------
838
  PROCEDURE proc_common_verify_valid(CONSTANT c_rl        : IN    NATURAL;
839
                                     SIGNAL   clk         : IN    STD_LOGIC;
840
                                     SIGNAL   verify_en   : IN    STD_LOGIC;
841
                                     SIGNAL   ready       : IN    STD_LOGIC;
842
                                     SIGNAL   prev_ready  : INOUT STD_LOGIC;
843
                                     SIGNAL   out_valid   : IN    STD_LOGIC) IS
844
  BEGIN
845
    IF rising_edge(clk) THEN
846
      -- for ready latency c_rl = 1 out_valid may only be asserted after ready
847
      -- for ready latency c_rl = 0 out_valid may always be asserted
848
      prev_ready <= '0';
849
      IF c_rl=1 THEN
850
        prev_ready <= ready;
851
        IF verify_en='1' AND out_valid='1' THEN
852
          IF prev_ready/='1' THEN
853
            REPORT "COMMON : Wrong ready latency between ready and out_valid" SEVERITY ERROR;
854
          END IF;
855
        END IF;
856
      END IF;
857
    END IF;
858
  END proc_common_verify_valid;
859
 
860
 
861
  ------------------------------------------------------------------------------
862
  -- PROCEDURE: Verify the DUT input to output latency
863
  ------------------------------------------------------------------------------
864
  -- for SL ctrl
865
  PROCEDURE proc_common_verify_latency(CONSTANT c_str         : IN    STRING;   -- e.g. "valid", "sop", "eop"
866
                                       CONSTANT c_latency     : IN    NATURAL;
867
                                       SIGNAL   clk           : IN    STD_LOGIC;
868
                                       SIGNAL   verify_en     : IN    STD_LOGIC;
869
                                       SIGNAL   in_ctrl       : IN    STD_LOGIC;
870
                                       SIGNAL   pipe_ctrl_vec : INOUT STD_LOGIC_VECTOR;  -- range [0:c_latency]
871
                                       SIGNAL   out_ctrl      : IN    STD_LOGIC) IS
872
  BEGIN
873
    IF rising_edge(clk) THEN
874
      pipe_ctrl_vec <= in_ctrl & pipe_ctrl_vec(0 TO c_latency-1);  -- note: pipe_ctrl_vec(c_latency) is a dummy place holder to avoid [0:-1] range
875
      IF verify_en='1' THEN
876
        IF c_latency=0 THEN
877
          IF in_ctrl/=out_ctrl THEN
878
            REPORT "COMMON : Wrong zero latency between input " & c_str & " and output " & c_str SEVERITY ERROR;
879
          END IF;
880
        ELSE
881
          IF pipe_ctrl_vec(c_latency-1)/=out_ctrl THEN
882
            REPORT "COMMON : Wrong latency between input " & c_str & " and output " & c_str SEVERITY ERROR;
883
          END IF;
884
        END IF;
885
      END IF;
886
    END IF;
887
  END proc_common_verify_latency;
888
 
889
 
890
  -- for SLV data
891
  PROCEDURE proc_common_verify_latency(CONSTANT c_str         : IN    STRING;   -- e.g. "data"
892
                                       CONSTANT c_latency     : IN    NATURAL;
893
                                       SIGNAL   clk           : IN    STD_LOGIC;
894
                                       SIGNAL   verify_en     : IN    STD_LOGIC;
895
                                       SIGNAL   in_data       : IN    STD_LOGIC_VECTOR;
896
                                       SIGNAL   pipe_data_vec : INOUT STD_LOGIC_VECTOR;  -- range [0:(1 + c_latency)*c_data_w-1]
897
                                       SIGNAL   out_data      : IN    STD_LOGIC_VECTOR) IS
898
    CONSTANT c_data_w     : NATURAL := in_data'LENGTH;
899
    CONSTANT c_data_vec_w : NATURAL := pipe_data_vec'LENGTH;  -- = (1 + c_latency) * c_data_w
900
  BEGIN
901
    IF rising_edge(clk) THEN
902
      pipe_data_vec <= in_data & pipe_data_vec(0 TO c_data_vec_w-c_data_w-1);  -- note: pipe_data_vec(c_latency) is a dummy place holder to avoid [0:-1] range
903
      IF verify_en='1' THEN
904
        IF c_latency=0 THEN
905
          IF UNSIGNED(in_data)/=UNSIGNED(out_data) THEN
906
            REPORT "COMMON : Wrong zero latency between input " & c_str & " and output " & c_str SEVERITY ERROR;
907
          END IF;
908
        ELSE
909
          IF UNSIGNED(pipe_data_vec(c_data_vec_w-c_data_w-c_data_w TO c_data_vec_w-c_data_w-1))/=UNSIGNED(out_data) THEN
910
            REPORT "COMMON : Wrong latency between input " & c_str & " and output " & c_str SEVERITY ERROR;
911
          END IF;
912
        END IF;
913
      END IF;
914
    END IF;
915
  END proc_common_verify_latency;
916
 
917
  ------------------------------------------------------------------------------
918
  -- PROCEDURE: Verify the expected value
919
  -- . e.g. to check that a test has ran at all
920
  ------------------------------------------------------------------------------
921
  PROCEDURE proc_common_verify_value(CONSTANT mode : IN NATURAL;
922
                                     SIGNAL   clk  : IN STD_LOGIC;
923
                                     SIGNAL   en   : IN STD_LOGIC;
924
                                     SIGNAL   exp  : IN STD_LOGIC_VECTOR;
925
                                     SIGNAL   res  : IN STD_LOGIC_VECTOR) IS
926
  BEGIN
927
    IF rising_edge(clk) THEN
928
      IF en='1' THEN
929
        IF mode = 0 AND UNSIGNED(res) /= UNSIGNED(exp) THEN
930
          REPORT "COMMON : Wrong result value" SEVERITY ERROR;             -- == (equal)
931
        END IF;
932
        IF mode = 1 AND UNSIGNED(res) < UNSIGNED(exp) THEN
933
          REPORT "COMMON : Wrong result value too small" SEVERITY ERROR;   -- >= (at least)
934
        END IF;
935
      END IF;
936
    END IF;
937
  END proc_common_verify_value;
938
 
939
  ------------------------------------------------------------------------------
940
  -- PROCEDURE: Opens a file for access and reports fail or success of opening. 
941
  ------------------------------------------------------------------------------
942
  PROCEDURE proc_common_open_file( file_status  : INOUT FILE_OPEN_STATUS;
943
                                   FILE in_file : TEXT;
944
                                   file_name    : IN    STRING;
945
                                   file_mode    : IN    FILE_OPEN_KIND) IS
946
  BEGIN
947
    IF file_status=OPEN_OK THEN
948
      file_close(in_file);
949
    END IF;
950
    file_open (file_status, in_file, file_name, file_mode);
951
    IF file_status=OPEN_OK THEN
952
      REPORT "COMMON : File opened " SEVERITY NOTE;
953
    ELSE
954
      REPORT "COMMON : Unable to open file " SEVERITY FAILURE;
955
    END IF;
956
  END proc_common_open_file;
957
 
958
 ------------------------------------------------------------------------------
959
  -- PROCEDURE: Reads an integer from a file. 
960
  ------------------------------------------------------------------------------
961
  PROCEDURE proc_common_readline_file(file_status  : INOUT FILE_OPEN_STATUS;
962
                                      FILE in_file : TEXT;
963
                                      read_value_0 : OUT INTEGER) IS
964
     VARIABLE v_line : LINE;
965
     VARIABLE v_good : BOOLEAN;
966
  BEGIN
967
    IF file_status/=OPEN_OK THEN
968
      REPORT "COMMON : File is not opened " SEVERITY FAILURE;
969
    ELSE
970
      IF ENDFILE(in_file) THEN
971
        REPORT "COMMON : end of file " SEVERITY NOTE;
972
      ELSE
973
        READLINE(in_file, v_line);
974
        READ(v_line, read_value_0, v_good);
975
        IF v_good = FALSE THEN
976
          REPORT "COMMON : Read from line unsuccessful " SEVERITY FAILURE;
977
        END IF;
978
      END IF;
979
    END IF;
980
  END proc_common_readline_file;
981
 
982
  ------------------------------------------------------------------------------
983
  -- PROCEDURE: Reads two integers from two columns in a file. 
984
  ------------------------------------------------------------------------------
985
  PROCEDURE proc_common_readline_file(file_status  : INOUT FILE_OPEN_STATUS;
986
                                      FILE in_file : TEXT;
987
                                      read_value_0 : OUT INTEGER;
988
                                      read_value_1 : OUT INTEGER) IS
989
     VARIABLE v_line : LINE;
990
     VARIABLE v_good : BOOLEAN;
991
  BEGIN
992
    IF file_status/=OPEN_OK THEN
993
      REPORT "COMMON : File is not opened " SEVERITY FAILURE;
994
    ELSE
995
      IF ENDFILE(in_file) THEN
996
        REPORT "COMMON : end of file " SEVERITY NOTE;
997
      ELSE
998
        READLINE(in_file, v_line);
999
        READ(v_line, read_value_0, v_good);
1000
        IF v_good = FALSE THEN
1001
          REPORT "COMMON : Read from line unsuccessful " SEVERITY FAILURE;
1002
        END IF;
1003
        READ(v_line, read_value_1, v_good);
1004
        IF v_good = FALSE THEN
1005
          REPORT "COMMON : Read from line unsuccessful " SEVERITY FAILURE;
1006
        END IF;
1007
      END IF;
1008
    END IF;
1009
  END proc_common_readline_file;
1010
 
1011
------------------------------------------------------------------------------
1012
  -- PROCEDURE: Reads an array of integer from a file. 
1013
  ------------------------------------------------------------------------------
1014
  PROCEDURE proc_common_readline_file(file_status  : INOUT FILE_OPEN_STATUS;
1015
                                      FILE in_file : TEXT;
1016
                                      value_array  : OUT t_integer_arr;
1017
                                      nof_reads    : IN  INTEGER) IS
1018
     VARIABLE v_line : LINE;
1019
     VARIABLE v_good : BOOLEAN;
1020
  BEGIN
1021
    IF file_status/=OPEN_OK THEN
1022
      REPORT "COMMON : File is not opened " SEVERITY FAILURE;
1023
    ELSE
1024
      IF ENDFILE(in_file) THEN
1025
        REPORT "COMMON : end of file " SEVERITY NOTE;
1026
      ELSE
1027
        READLINE(in_file, v_line);
1028
        FOR I IN 0 TO nof_reads - 1 LOOP
1029
          READ(v_line, value_array(I), v_good);
1030
          IF v_good = FALSE THEN
1031
            REPORT "COMMON : Read from line unsuccessful " SEVERITY FAILURE;
1032
          END IF;
1033
        END LOOP;
1034
      END IF;
1035
    END IF;
1036
  END proc_common_readline_file;
1037
 
1038
  ------------------------------------------------------------------------------
1039
  -- PROCEDURE: Reads an std_logic_vector from a file
1040
  ------------------------------------------------------------------------------
1041
  PROCEDURE proc_common_readline_file(file_status  : INOUT FILE_OPEN_STATUS;
1042
                                      FILE in_file : TEXT;
1043
                                      read_slv     : OUT STD_LOGIC_VECTOR) IS
1044
     VARIABLE v_line : LINE;
1045
     VARIABLE v_good : BOOLEAN;
1046
  BEGIN
1047
    IF file_status/=OPEN_OK THEN
1048
      REPORT "COMMON : File is not opened " SEVERITY FAILURE;
1049
    ELSE
1050
      IF ENDFILE(in_file) THEN
1051
        REPORT "COMMON : end of file " SEVERITY NOTE;
1052
      ELSE
1053
        READLINE(in_file, v_line);
1054
        READ(v_line, read_slv, v_good);
1055
        IF v_good = FALSE THEN
1056
          REPORT "COMMON : Read from line unsuccessful " SEVERITY FAILURE;
1057
        END IF;
1058
      END IF;
1059
    END IF;
1060
  END proc_common_readline_file;
1061
 
1062
  ------------------------------------------------------------------------------
1063
  -- PROCEDURE: Reads a string of any length from a file pointer. 
1064
  ------------------------------------------------------------------------------
1065
  PROCEDURE proc_common_readline_file(file_status  : INOUT FILE_OPEN_STATUS;
1066
                                      FILE in_file : TEXT;
1067
                                      res_string   : OUT STRING) IS
1068
    VARIABLE v_line    : LINE;
1069
    VARIABLE v_char    : CHARACTER;
1070
    VARIABLE is_string : BOOLEAN;
1071
  BEGIN
1072
    IF file_status/=OPEN_OK THEN
1073
      REPORT "COMMON : File is not opened " SEVERITY FAILURE;
1074
    ELSE
1075
      IF ENDFILE(in_file) THEN
1076
        REPORT "COMMON : end of file " SEVERITY NOTE;
1077
      ELSE
1078
        readline(in_file, v_line);
1079
        -- clear the contents of the result string
1080
        FOR I IN res_string'RANGE LOOP
1081
            res_string(I) := ' ';
1082
        END LOOP;
1083
        -- read all characters of the line, up to the length  
1084
        -- of the results string
1085
        FOR I IN res_string'RANGE LOOP
1086
           read(v_line, v_char, is_string);
1087
           IF NOT is_string THEN -- found end of line
1088
              EXIT;
1089
           END IF;
1090
           res_string(I) := v_char;
1091
        END LOOP;
1092
      END IF;
1093
    END IF;
1094
  END proc_common_readline_file;
1095
 
1096
 
1097
  ------------------------------------------------------------------------------
1098
  -- PROCEDURE: Closes a file. 
1099
  ------------------------------------------------------------------------------
1100
  PROCEDURE proc_common_close_file(file_status  : INOUT FILE_OPEN_STATUS;
1101
                                   FILE in_file : TEXT) IS
1102
  BEGIN
1103
    IF file_status/=OPEN_OK THEN
1104
      REPORT "COMMON : File was not opened " SEVERITY WARNING;
1105
    END IF;
1106
    FILE_CLOSE(in_file);
1107
    REPORT "COMMON : File closed " SEVERITY NOTE;
1108
  END proc_common_close_file;
1109
 
1110
  ------------------------------------------------------------------------------
1111
  -- PROCEDURE: Reads the integer data from nof_rows with nof_col values per
1112
  --            row from a file and returns it row by row in an array of
1113
  --            integers.
1114
  ------------------------------------------------------------------------------
1115
  PROCEDURE proc_common_read_integer_file(file_name              : IN  STRING;
1116
                                          nof_header_lines       : NATURAL;
1117
                                          nof_row                : NATURAL;
1118
                                          nof_col                : NATURAL;
1119
                                          SIGNAL return_array    : OUT t_integer_arr) IS
1120
    VARIABLE v_file_status : FILE_OPEN_STATUS;
1121
    FILE     v_in_file     : TEXT;
1122
    VARIABLE v_input_line  : LINE;
1123
    VARIABLE v_string      : STRING(1 TO 80);
1124
    VARIABLE v_row_arr     : t_integer_arr(0 TO nof_col-1);
1125
  BEGIN
1126
    IF file_name/="UNUSED" AND file_name/="unused" THEN
1127
      -- Open the file for reading
1128
      proc_common_open_file(v_file_status, v_in_file, file_name, READ_MODE);
1129
      -- Read and skip the header
1130
      FOR J IN 0 TO nof_header_lines-1  LOOP
1131
        proc_common_readline_file(v_file_status, v_in_file, v_string);
1132
      END LOOP;
1133
      FOR J IN 0 TO nof_row-1  LOOP
1134
        proc_common_readline_file(v_file_status, v_in_file, v_row_arr, nof_col);
1135
        FOR I IN 0 TO nof_col-1 LOOP
1136
          return_array(J*nof_col + I) <= v_row_arr(I);  -- use loop to be independent of t_integer_arr downto or to range
1137
        END LOOP;
1138
        IF ENDFILE(v_in_file) THEN
1139
          IF J/=nof_row-1 THEN
1140
            REPORT "COMMON : Unexpected end of file" SEVERITY FAILURE;
1141
          END IF;
1142
          EXIT;
1143
        END IF;
1144
      END LOOP;
1145
      -- Close the file 
1146
      proc_common_close_file(v_file_status, v_in_file);
1147
    ELSE
1148
      return_array <= (return_array'RANGE=>0);
1149
    END IF;
1150
  END proc_common_read_integer_file;
1151
 
1152
  ------------------------------------------------------------------------------
1153
  -- PROCEDURE: Reads the data column from a .mif file and returns it in an 
1154
  --            array of integers
1155
  ------------------------------------------------------------------------------
1156
  PROCEDURE proc_common_read_mif_file(        file_name    : IN  STRING;
1157
                                       SIGNAL return_array : OUT t_integer_arr) IS
1158
    VARIABLE v_file_status : FILE_OPEN_STATUS;
1159
    FILE     v_in_file     : TEXT;
1160
    VARIABLE v_input_line  : LINE;
1161
    VARIABLE v_string      : STRING(1 TO 80);
1162
    VARIABLE v_mem_width   : NATURAL := 0;
1163
    VARIABLE v_mem_depth   : NATURAL := 0;
1164
    VARIABLE v_up_bound    : NATURAL := 0;
1165
    VARIABLE v_low_bound   : NATURAL := 0;
1166
    VARIABLE v_end_header  : BOOLEAN := FALSE;
1167
    VARIABLE v_char        : CHARACTER;
1168
  BEGIN
1169
    -- Open the .mif file for reading
1170
    proc_common_open_file(v_file_status, v_in_file, file_name, READ_MODE);
1171
    -- Read the header.
1172
    WHILE NOT v_end_header LOOP
1173
      proc_common_readline_file(v_file_status, v_in_file, v_string);
1174
      IF(func_find_string_in_string(v_string, "WIDTH=")) THEN                              -- check for "WIDTH=" 
1175
        v_up_bound  := func_find_char_in_string(v_string, ';');
1176
        v_low_bound := func_find_char_in_string(v_string, '=');
1177
        v_mem_width := func_decstring_to_integer(v_string(v_low_bound+1 TO v_up_bound-1));
1178
      ELSIF(func_find_string_in_string(v_string, "DEPTH=")) THEN                           -- check for "DEPTH=" 
1179
        v_up_bound  := func_find_char_in_string(v_string, ';');
1180
        v_low_bound := func_find_char_in_string(v_string, '=');
1181
        v_mem_depth := func_decstring_to_integer(v_string(v_low_bound+1 TO v_up_bound-1));
1182
      ELSIF(func_find_string_in_string(v_string, "CONTENT BEGIN")) THEN
1183
        v_end_header := TRUE;
1184
      END IF;
1185
    END LOOP;
1186
    -- Read the data           
1187
    FOR I IN 0 TO v_mem_depth-1  LOOP
1188
      proc_common_readline_file(v_file_status, v_in_file, v_string);                 -- Read the next line from the file. 
1189
      v_low_bound     := func_find_char_in_string(v_string, ':');   -- Find the left position of the string that contains the data field
1190
      v_up_bound      := func_find_char_in_string(v_string, ';');   -- Find the right position of the string that contains the data field           
1191
      return_array(I) <= func_hexstring_to_integer(v_string(v_low_bound+1 TO v_up_bound-1));
1192
    END LOOP;
1193
    -- Close the file 
1194
    proc_common_close_file(v_file_status, v_in_file);
1195
  END proc_common_read_mif_file;
1196
 
1197
  ------------------------------------------------------------------------------
1198
  -- FUNCTION: Complex multiply with conjugate option for input b
1199
  ------------------------------------------------------------------------------
1200
  FUNCTION func_complex_multiply(in_ar, in_ai, in_br, in_bi : STD_LOGIC_VECTOR; conjugate_b : BOOLEAN; str : STRING; g_out_dat_w : NATURAL) RETURN STD_LOGIC_VECTOR IS
1201
    -- Function: Signed complex multiply
1202
    --   p = a * b       when g_conjugate_b = FALSE
1203
    --     = (ar + j ai) * (br + j bi)
1204
    --     =  ar*br - ai*bi + j ( ar*bi + ai*br)
1205
    --
1206
    --   p = a * conj(b) when g_conjugate_b = TRUE
1207
    --     = (ar + j ai) * (br - j bi)
1208
    --     =  ar*br + ai*bi + j (-ar*bi + ai*br)
1209
    -- From mti_numeric_std.vhd follows:
1210
    -- . SIGNED * --> output width = 2 * input width
1211
    -- . SIGNED + --> output width = largest(input width)
1212
    CONSTANT c_in_w      : NATURAL := in_ar'LENGTH;  -- all input have same width
1213
    CONSTANT c_res_w     : NATURAL := 2*c_in_w+1;    -- *2 for multiply, +1 for sum of two products
1214
    VARIABLE v_ar        : SIGNED(c_in_w-1 DOWNTO 0);
1215
    VARIABLE v_ai        : SIGNED(c_in_w-1 DOWNTO 0);
1216
    VARIABLE v_br        : SIGNED(c_in_w-1 DOWNTO 0);
1217
    VARIABLE v_bi        : SIGNED(c_in_w-1 DOWNTO 0);
1218
    VARIABLE v_result_re : SIGNED(c_res_w-1 DOWNTO 0);
1219
    VARIABLE v_result_im : SIGNED(c_res_w-1 DOWNTO 0);
1220
  BEGIN
1221
    -- Calculate expected result
1222
    v_ar := RESIZE_NUM(SIGNED(in_ar), c_in_w);
1223
    v_ai := RESIZE_NUM(SIGNED(in_ai), c_in_w);
1224
    v_br := RESIZE_NUM(SIGNED(in_br), c_in_w);
1225
    v_bi := RESIZE_NUM(SIGNED(in_bi), c_in_w);
1226
    IF conjugate_b=FALSE THEN
1227
      v_result_re := RESIZE_NUM(v_ar*v_br, c_res_w) - v_ai*v_bi;
1228
      v_result_im := RESIZE_NUM(v_ar*v_bi, c_res_w) + v_ai*v_br;
1229
    ELSE
1230
      v_result_re := RESIZE_NUM(v_ar*v_br, c_res_w) + v_ai*v_bi;
1231
      v_result_im := RESIZE_NUM(v_ai*v_br, c_res_w) - v_ar*v_bi;
1232
    END IF;
1233
    -- Note that for the product needs as many bits as the sum of the input widths. However the
1234
    -- sign bit is then only needed for the case that both inputs have the largest negative
1235
    -- values, only then the MSBits will be "01". For all other inputs the MSbits will always
1236
    -- be "00" for positive numbers or "11" for negative numbers. MSbits "10" can not occur.
1237
    -- For largest negative inputs the complex multiply result becomes:
1238
    --
1239
    --   3b inputs                --> 6b products     --> c_res_w = 7b
1240
    --     -4 *   -4 +   -4 *   -4 =     +16 +     +16 =      +64       -- most negative valued inputs
1241
    --   b100 * b100 + b100 * b100 = b010000 + b010000 = b0100000
1242
    --
1243
    --   --> if g_out_dat_w = 6b then
1244
    --       a) IEEE unsigned resizing skips   the MSbits so b0100000 = +64 becomes b_100000 = -64
1245
    --       b) IEEE signed resizing preserves the MSbit  so b0100000 = +64 becomes b0_00000 = 0
1246
    --       c) detect MSbits = "01" to clip max positive to get                    _b011111 = +63
1247
    -- Option a) seems to map best on the FPGA hardware multiplier IP.
1248
    IF str="RE" THEN
1249
      RETURN STD_LOGIC_VECTOR(RESIZE_NUM(v_result_re, g_out_dat_w));  -- conform option a)
1250
    ELSE
1251
      RETURN STD_LOGIC_VECTOR(RESIZE_NUM(v_result_im, g_out_dat_w));  -- conform option a)
1252
    END IF;
1253
  END;
1254
 
1255
  ------------------------------------------------------------------------------
1256
  -- FUNCTION: Converts the decimal value represented in a string to an integer value. 
1257
  ------------------------------------------------------------------------------
1258
  FUNCTION func_decstring_to_integer(in_string: STRING) RETURN INTEGER IS
1259
    CONSTANT c_nof_digits : NATURAL := in_string'LENGTH;   -- Define the length of the string
1260
    VARIABLE v_char       : CHARACTER;
1261
    VARIABLE v_weight     : INTEGER := 1;
1262
    VARIABLE v_return_int : INTEGER := 0;
1263
  BEGIN
1264
    -- Walk through the string character by character. 
1265
    FOR I IN c_nof_digits-1 DOWNTO 0 LOOP
1266
      v_char := in_string(I+in_string'LOW);
1267
      CASE v_char IS
1268
         WHEN '0' => v_return_int := v_return_int + 0*v_weight;
1269
         WHEN '1' => v_return_int := v_return_int + 1*v_weight;
1270
         WHEN '2' => v_return_int := v_return_int + 2*v_weight;
1271
         WHEN '3' => v_return_int := v_return_int + 3*v_weight;
1272
         WHEN '4' => v_return_int := v_return_int + 4*v_weight;
1273
         WHEN '5' => v_return_int := v_return_int + 5*v_weight;
1274
         WHEN '6' => v_return_int := v_return_int + 6*v_weight;
1275
         WHEN '7' => v_return_int := v_return_int + 7*v_weight;
1276
         WHEN '8' => v_return_int := v_return_int + 8*v_weight;
1277
         WHEN '9' => v_return_int := v_return_int + 9*v_weight;
1278
         WHEN OTHERS => NULL;
1279
      END CASE;
1280
      IF (v_char /= ' ') THEN      -- Only increment the weight when the character is NOT a spacebar. 
1281
        v_weight := v_weight*10;   -- Addapt the weight for the next decimal digit.
1282
      END IF;
1283
    END LOOP;
1284
    RETURN(v_return_int);
1285
  END FUNCTION func_decstring_to_integer;
1286
 
1287
  ------------------------------------------------------------------------------
1288
  -- FUNCTION: Converts the hexadecimal value represented in a string to an integer value. 
1289
  ------------------------------------------------------------------------------
1290
  FUNCTION func_hexstring_to_integer(in_string: STRING) RETURN INTEGER IS
1291
    CONSTANT c_nof_digits : NATURAL := in_string'LENGTH;  -- Define the length of the string
1292
    VARIABLE v_char       : CHARACTER;
1293
    VARIABLE v_weight     : INTEGER := 1;
1294
    VARIABLE v_return_int : INTEGER := 0;
1295
  BEGIN
1296
    -- Walk through the string character by character. 
1297
    FOR I IN c_nof_digits-1 DOWNTO 0 LOOP
1298
      v_char := in_string(I+in_string'LOW);
1299
      CASE v_char IS
1300
         WHEN '0' => v_return_int := v_return_int + 0*v_weight;
1301
         WHEN '1' => v_return_int := v_return_int + 1*v_weight;
1302
         WHEN '2' => v_return_int := v_return_int + 2*v_weight;
1303
         WHEN '3' => v_return_int := v_return_int + 3*v_weight;
1304
         WHEN '4' => v_return_int := v_return_int + 4*v_weight;
1305
         WHEN '5' => v_return_int := v_return_int + 5*v_weight;
1306
         WHEN '6' => v_return_int := v_return_int + 6*v_weight;
1307
         WHEN '7' => v_return_int := v_return_int + 7*v_weight;
1308
         WHEN '8' => v_return_int := v_return_int + 8*v_weight;
1309
         WHEN '9' => v_return_int := v_return_int + 9*v_weight;
1310
         WHEN 'A' | 'a' => v_return_int := v_return_int + 10*v_weight;
1311
         WHEN 'B' | 'b' => v_return_int := v_return_int + 11*v_weight;
1312
         WHEN 'C' | 'c' => v_return_int := v_return_int + 12*v_weight;
1313
         WHEN 'D' | 'd' => v_return_int := v_return_int + 13*v_weight;
1314
         WHEN 'E' | 'e' => v_return_int := v_return_int + 14*v_weight;
1315
         WHEN 'F' | 'f' => v_return_int := v_return_int + 15*v_weight;
1316
         WHEN OTHERS => NULL;
1317
      END CASE;
1318
      IF (v_char /= ' ') THEN     -- Only increment the weight when the character is NOT a spacebar. 
1319
        v_weight := v_weight*16;  -- Addapt the weight for the next hexadecimal digit.                   
1320
      END IF;
1321
    END LOOP;
1322
    RETURN(v_return_int);
1323
  END FUNCTION func_hexstring_to_integer;
1324
 
1325
  ------------------------------------------------------------------------------
1326
  -- FUNCTION: Finds the first instance of a given character in a string 
1327
  --           and returns its position. 
1328
  ------------------------------------------------------------------------------
1329
  FUNCTION func_find_char_in_string(in_string: STRING; find_char: CHARACTER) RETURN INTEGER IS
1330
    VARIABLE v_char_position : INTEGER := 0;
1331
  BEGIN
1332
    FOR I IN 1 TO in_string'LENGTH LOOP
1333
      IF(in_string(I) = find_char) THEN
1334
        v_char_position := I;
1335
      END IF;
1336
    END LOOP;
1337
    RETURN(v_char_position);
1338
  END FUNCTION func_find_char_in_string;
1339
 
1340
  ------------------------------------------------------------------------------
1341
  -- FUNCTION: Checks if a string(find_string) is part of a larger string(in_string).
1342
  --           The result is returned as a BOOLEAN. 
1343
  ------------------------------------------------------------------------------
1344
  FUNCTION func_find_string_in_string(in_string: STRING; find_string: STRING) RETURN BOOLEAN IS
1345
    CONSTANT c_in_length     : NATURAL := in_string'LENGTH;   -- Define the length of the string to search in
1346
    CONSTANT c_find_length   : NATURAL := find_string'LENGTH; -- Define the length of the string to be find
1347
    VARIABLE v_found_it      : BOOLEAN := FALSE;
1348
  BEGIN
1349
    FOR I IN 1 TO c_in_length-c_find_length LOOP
1350
      IF(in_string(I TO (I+c_find_length-1)) = find_string) THEN
1351
        v_found_it := TRUE;
1352
      END IF;
1353
    END LOOP;
1354
    RETURN(v_found_it);
1355
  END FUNCTION func_find_string_in_string;
1356
 
1357
END tb_common_pkg;
1358
 

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.