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 16

Details | Compare with Previous | View Log

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

powered by: WebSVN 2.1.0

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