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 9

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

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

powered by: WebSVN 2.1.0

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