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

Subversion Repositories pltbutils

[/] [pltbutils/] [trunk/] [src/] [vhdl/] [pltbutils_func_pkg.vhd] - Blame information for rev 101

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

Line No. Rev Author Line
1 2 pela
----------------------------------------------------------------------
2
----                                                              ----
3
---- PlTbUtils Fuctions and Procedures Package                    ----
4
----                                                              ----
5
---- This file is part of the PlTbUtils project                   ----
6
---- http://opencores.org/project,pltbutils                       ----
7
----                                                              ----
8
---- Description:                                                 ----
9
---- PlTbUtils is a collection of functions, procedures and       ----
10
---- components for easily creating stimuli and checking response ----
11
---- in automatic self-checking testbenches.                      ----
12
----                                                              ----
13
---- This file defines fuctions and procedures for controlling    ----
14
---- stimuli to a DUT and checking response.                      ----
15
----                                                              ----
16
---- To Do:                                                       ----
17
---- -                                                            ----
18
----                                                              ----
19
---- Author(s):                                                   ----
20 97 pela
---- - Per Larsson, pela.opencores@gmail.com                      ----
21 2 pela
----                                                              ----
22
----------------------------------------------------------------------
23
----                                                              ----
24 24 pela
---- Copyright (C) 2013-2014 Authors and OPENCORES.ORG            ----
25 2 pela
----                                                              ----
26
---- This source file may be used and distributed without         ----
27
---- restriction provided that this copyright statement is not    ----
28
---- removed from the file and that any derivative work contains  ----
29
---- the original copyright notice and the associated disclaimer. ----
30
----                                                              ----
31
---- This source file is free software; you can redistribute it   ----
32
---- and/or modify it under the terms of the GNU Lesser General   ----
33
---- Public License as published by the Free Software Foundation; ----
34
---- either version 2.1 of the License, or (at your option) any   ----
35
---- later version.                                               ----
36
----                                                              ----
37
---- This source is distributed in the hope that it will be       ----
38
---- useful, but WITHOUT ANY WARRANTY; without even the implied   ----
39
---- warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR      ----
40
---- PURPOSE. See the GNU Lesser General Public License for more  ----
41
---- details.                                                     ----
42
----                                                              ----
43
---- You should have received a copy of the GNU Lesser General    ----
44
---- Public License along with this source; if not, download it   ----
45
---- from http://www.opencores.org/lgpl.shtml                     ----
46
----                                                              ----
47
----------------------------------------------------------------------
48
library ieee;
49
use ieee.std_logic_1164.all;
50
use ieee.numeric_std.all;
51
use std.textio.all;
52
use work.txt_util.all;
53 24 pela
use work.pltbutils_user_cfg_pkg.all;
54 2 pela
 
55
package pltbutils_func_pkg is
56
 
57
  -- See the package body for a description of the functions and procedures.
58 101 pela
  constant C_PLTBUTILS_STRLEN       : natural :=  80;
59
  constant C_PLTBUTILS_SKIPTESTLEN  : natural := 512;
60
  constant C_PLTBUTILS_TIMEOUT      : time    :=  10 sec;
61
  constant C_WAIT_BEFORE_STOP_TIME  : time    :=   1 us;
62 36 pela
 
63
  -- Type for status- and control variable
64
  type pltbv_t is
65
    record
66
      testcase_name    : string(1 to C_PLTBUTILS_STRLEN);
67
      testcase_name_len: integer;
68
      test_num         : integer;
69
      test_name        : string(1 to C_PLTBUTILS_STRLEN);
70
      test_name_len    : integer;
71 101 pela
      skiptests        : std_logic_vector(0 to C_PLTBUTILS_SKIPTESTLEN-1);
72
      test_active      : boolean;
73 36 pela
      info             : string(1 to C_PLTBUTILS_STRLEN);
74
      info_len         : integer;
75
      test_cnt         : integer;
76 101 pela
      skiptest_cnt     : integer;
77 36 pela
      chk_cnt          : integer;
78
      err_cnt          : integer;
79
      chk_cnt_in_test  : integer;
80
      err_cnt_in_test  : integer;
81
      stop_sim         : std_logic;
82
    end record;
83
 
84
  constant C_PLTBV_INIT : pltbv_t := (
85
    (others => ' '),   -- testcase_name
86
    1,                 -- testcase_name_len
87
    0,                 -- test_num
88
    (others => ' '),   -- test_name
89
    1,                 -- test_name_len
90 101 pela
    (others => '0'),   -- skiptest
91
    true,              -- test_active
92 36 pela
    (others => ' '),   -- info
93
    1,                 -- info_len
94
    0,                 -- test_cnt
95 101 pela
    0,                 -- skiptest_cnt
96 36 pela
    0,                 -- chk_cnt
97
    0,                 -- err_cnt
98
    0,                 -- chk_cnt_in_test
99
    0,                 -- err_cnt_in_test
100
    '0'                -- stop_sim
101
  );
102
 
103
  -- Status- and control signal (subset of pltbv_t)
104
  type pltbs_t is
105
    record
106 2 pela
      test_num  : natural;
107
      test_name : string(1 to C_PLTBUTILS_STRLEN);
108
      info      : string(1 to C_PLTBUTILS_STRLEN);
109
      chk_cnt   : natural;
110
      err_cnt   : natural;
111
      stop_sim  : std_logic;
112
    end record;
113 36 pela
 
114
  constant C_PLTBS_INIT : pltbs_t := (
115
    0,                  -- test_num
116
    (others => ' '),    -- test_name    
117
    (others => ' '),    -- info
118
    0,                  -- chk_cnt
119
    0,                  -- err_cnt
120
    '0'                 -- stop_sim
121
  );
122
 
123
  -- startsim
124 2 pela
  procedure startsim(
125
    constant testcase_name      : in    string;
126 101 pela
    constant skiptests           : in    std_logic_vector;
127 36 pela
    variable pltbv              : inout pltbv_t;
128
    signal   pltbs              : out   pltbs_t
129 2 pela
  );
130 36 pela
 
131 2 pela
  -- endsim
132
  procedure endsim(
133 36 pela
    variable pltbv              : inout pltbv_t;
134
    signal   pltbs              : out   pltbs_t;
135
    constant show_success_fail  : in    boolean := false;
136 97 pela
    constant force_stop         : in    boolean := false
137 2 pela
  );
138 36 pela
 
139 24 pela
  -- starttest
140
  procedure starttest(
141
    constant num                : in    integer := -1;
142
    constant name               : in    string;
143 36 pela
    variable pltbv              : inout pltbv_t;
144
    signal   pltbs              : out   pltbs_t
145 24 pela
  );
146
  procedure starttest(
147
    constant name               : in    string;
148 36 pela
    variable pltbv              : inout pltbv_t;
149
    signal   pltbs              : out   pltbs_t
150 24 pela
  );
151
 
152 101 pela
  -- is_test_active
153
  function is_test_active(
154
    constant pltbv              : in    pltbv_t
155
  ) return boolean;
156
 
157 24 pela
  -- endtest
158
  procedure endtest(
159 36 pela
    variable pltbv              : inout pltbv_t;
160
    signal   pltbs              : out   pltbs_t
161 24 pela
  );
162
 
163 2 pela
  -- print, printv, print2
164
  procedure print(
165 6 pela
    constant active             : in    boolean;
166 2 pela
    signal   s                  : out   string;
167
    constant txt                : in    string
168
  );
169 6 pela
  procedure print(
170
    signal   s                  : out   string;
171
    constant txt                : in    string
172
  );
173 2 pela
  procedure printv(
174 6 pela
    constant active             : in    boolean;
175 2 pela
    variable s                  : out   string;
176
    constant txt                : in    string
177
  );
178
  procedure printv(
179 6 pela
    variable s                  : out   string;
180
    constant txt                : in    string
181
  );
182 2 pela
  procedure print(
183 6 pela
    constant active             : in    boolean;
184 36 pela
    variable pltbv              : inout pltbv_t;
185
    signal   pltbs              : out   pltbs_t;
186 2 pela
    constant txt                : in    string
187
  );
188 6 pela
  procedure print(
189 36 pela
    variable pltbv              : inout pltbv_t;
190
    signal   pltbs              : out   pltbs_t;
191 6 pela
    constant txt                : in    string
192
  );
193 2 pela
  procedure print2(
194 6 pela
    constant active             : in    boolean;
195 2 pela
    signal   s                  : out   string;
196
    constant txt                : in    string
197
  );
198
  procedure print2(
199 6 pela
    signal   s                  : out   string;
200
    constant txt                : in    string
201
  );
202
  procedure print2(
203
    constant active             : in    boolean;
204 36 pela
    variable pltbv              : inout pltbv_t;
205
    signal   pltbs              : out   pltbs_t;
206 2 pela
    constant txt                : in    string
207
  );
208 6 pela
  procedure print2(
209 36 pela
    variable pltbv              : inout pltbv_t;
210
    signal   pltbs              : out   pltbs_t;
211 6 pela
    constant txt                : in    string
212
  );
213 2 pela
 
214
  -- waitclks
215
  procedure waitclks(
216
    constant N                  : in    natural;
217
    signal   clk                : in    std_logic;
218 36 pela
    variable pltbv              : inout pltbv_t;
219
    signal   pltbs              : out   pltbs_t;
220 2 pela
    constant falling            : in    boolean := false;
221
    constant timeout            : in    time    := C_PLTBUTILS_TIMEOUT
222
  );
223 36 pela
 
224 6 pela
  -- waitsig
225
  procedure waitsig(
226
    signal   s                  : in    integer;
227
    constant value              : in    integer;
228
    signal   clk                : in    std_logic;
229 36 pela
    variable pltbv              : inout pltbv_t;
230
    signal   pltbs              : out   pltbs_t;
231 6 pela
    constant falling            : in    boolean := false;
232
    constant timeout            : in    time    := C_PLTBUTILS_TIMEOUT
233
  );
234
  procedure waitsig(
235
    signal   s                  : in    std_logic;
236
    constant value              : in    std_logic;
237
    signal   clk                : in    std_logic;
238 36 pela
    variable pltbv              : inout pltbv_t;
239
    signal   pltbs              : out   pltbs_t;
240 6 pela
    constant falling            : in    boolean := false;
241
    constant timeout            : in    time    := C_PLTBUTILS_TIMEOUT
242
  );
243
  procedure waitsig(
244
    signal   s                  : in    std_logic;
245
    constant value              : in    integer;
246
    signal   clk                : in    std_logic;
247 36 pela
    variable pltbv              : inout pltbv_t;
248
    signal   pltbs              : out   pltbs_t;
249 6 pela
    constant falling            : in    boolean := false;
250
    constant timeout            : in    time    := C_PLTBUTILS_TIMEOUT
251 36 pela
  );
252 6 pela
  procedure waitsig(
253
    signal   s                  : in    std_logic_vector;
254
    constant value              : in    std_logic_vector;
255
    signal   clk                : in    std_logic;
256 36 pela
    variable pltbv              : inout pltbv_t;
257
    signal   pltbs              : out   pltbs_t;
258 6 pela
    constant falling            : in    boolean := false;
259
    constant timeout            : in    time    := C_PLTBUTILS_TIMEOUT
260
  );
261
  procedure waitsig(
262
    signal   s                  : in    std_logic_vector;
263
    constant value              : in    integer;
264
    signal   clk                : in    std_logic;
265 36 pela
    variable pltbv              : inout pltbv_t;
266
    signal   pltbs              : out   pltbs_t;
267 6 pela
    constant falling            : in    boolean := false;
268
    constant timeout            : in    time    := C_PLTBUTILS_TIMEOUT
269
  );
270
  procedure waitsig(
271
    signal   s                  : in    unsigned;
272
    constant value              : in    unsigned;
273
    signal   clk                : in    std_logic;
274 36 pela
    variable pltbv              : inout pltbv_t;
275
    signal   pltbs              : out   pltbs_t;
276 6 pela
    constant falling            : in    boolean := false;
277
    constant timeout            : in    time    := C_PLTBUTILS_TIMEOUT
278 36 pela
  );
279 6 pela
  procedure waitsig(
280
    signal   s                  : in    unsigned;
281
    constant value              : in    integer;
282
    signal   clk                : in    std_logic;
283 36 pela
    variable pltbv              : inout pltbv_t;
284
    signal   pltbs              : out   pltbs_t;
285 6 pela
    constant falling            : in    boolean := false;
286
    constant timeout            : in    time    := C_PLTBUTILS_TIMEOUT
287
  );
288
  procedure waitsig(
289
    signal   s                  : in    signed;
290
    constant value              : in    signed;
291
    signal   clk                : in    std_logic;
292 36 pela
    variable pltbv              : inout pltbv_t;
293
    signal   pltbs              : out   pltbs_t;
294 6 pela
    constant falling            : in    boolean := false;
295
    constant timeout            : in    time    := C_PLTBUTILS_TIMEOUT
296
  );
297
  procedure waitsig(
298
    signal   s                  : in    signed;
299
    constant value              : in    integer;
300
    signal   clk                : in    std_logic;
301 36 pela
    variable pltbv              : inout pltbv_t;
302
    signal   pltbs              : out   pltbs_t;
303 6 pela
    constant falling            : in    boolean := false;
304
    constant timeout            : in    time    := C_PLTBUTILS_TIMEOUT
305 36 pela
  );
306 97 pela
  procedure waitsig(
307
    signal   s                  : in    std_logic;
308
    constant value              : in    std_logic;
309
    variable pltbv              : inout pltbv_t;
310
    signal   pltbs              : out   pltbs_t;
311
    constant timeout            : in    time    := C_PLTBUTILS_TIMEOUT
312
  );
313 36 pela
 
314 2 pela
  -- check
315
  procedure check(
316
    constant rpt                : in    string;
317 24 pela
    constant actual             : in    integer;
318 2 pela
    constant expected           : in    integer;
319 36 pela
    variable pltbv              : inout pltbv_t;
320
    signal   pltbs              : out   pltbs_t
321
  );
322 2 pela
  procedure check(
323
    constant rpt                : in    string;
324 24 pela
    constant actual             : in    std_logic;
325 2 pela
    constant expected           : in    std_logic;
326 36 pela
    variable pltbv              : inout pltbv_t;
327
    signal   pltbs              : out   pltbs_t
328
  );
329 2 pela
  procedure check(
330
    constant rpt                : in    string;
331 24 pela
    constant actual             : in    std_logic;
332 2 pela
    constant expected           : in    integer;
333 36 pela
    variable pltbv              : inout pltbv_t;
334
    signal   pltbs              : out   pltbs_t
335
  );
336 2 pela
  procedure check(
337
    constant rpt                : in    string;
338 24 pela
    constant actual             : in    std_logic_vector;
339 2 pela
    constant expected           : in    std_logic_vector;
340 36 pela
    variable pltbv              : inout pltbv_t;
341
    signal   pltbs              : out   pltbs_t
342 2 pela
  );
343
  procedure check(
344
    constant rpt                : in    string;
345 24 pela
    constant actual             : in    std_logic_vector;
346 2 pela
    constant expected           : in    std_logic_vector;
347
    constant mask               : in    std_logic_vector;
348 36 pela
    variable pltbv              : inout pltbv_t;
349
    signal   pltbs              : out   pltbs_t
350 2 pela
  );
351
  procedure check(
352
    constant rpt                : in    string;
353 24 pela
    constant actual             : in    std_logic_vector;
354 2 pela
    constant expected           : in    integer;
355 36 pela
    variable pltbv              : inout pltbv_t;
356
    signal   pltbs              : out   pltbs_t
357
  );
358 2 pela
  procedure check(
359
    constant rpt                : in    string;
360 24 pela
    constant actual             : in    std_logic_vector;
361 2 pela
    constant expected           : in    integer;
362
    constant mask               : in    std_logic_vector;
363 36 pela
    variable pltbv              : inout pltbv_t;
364
    signal   pltbs              : out   pltbs_t
365
  );
366 2 pela
  procedure check(
367
    constant rpt                : in    string;
368 24 pela
    constant actual             : in    unsigned;
369 2 pela
    constant expected           : in    unsigned;
370 36 pela
    variable pltbv              : inout pltbv_t;
371
    signal   pltbs              : out   pltbs_t
372 2 pela
  );
373
  procedure check(
374
    constant rpt                : in    string;
375 24 pela
    constant actual             : in    unsigned;
376 2 pela
    constant expected           : in    integer;
377 36 pela
    variable pltbv              : inout pltbv_t;
378
    signal   pltbs              : out   pltbs_t
379
  );
380 2 pela
  procedure check(
381
    constant rpt                : in    string;
382 24 pela
    constant actual             : in    signed;
383 2 pela
    constant expected           : in    signed;
384 36 pela
    variable pltbv              : inout pltbv_t;
385
    signal   pltbs              : out   pltbs_t
386 2 pela
  );
387
  procedure check(
388
    constant rpt                : in    string;
389 24 pela
    constant actual             : in    signed;
390 2 pela
    constant expected           : in    integer;
391 36 pela
    variable pltbv              : inout pltbv_t;
392
    signal   pltbs              : out   pltbs_t
393
  );
394 2 pela
  procedure check(
395
    constant rpt                : in    string;
396 99 pela
    constant actual             : in    boolean;
397
    constant expected           : in    boolean;
398
    variable pltbv              : inout pltbv_t;
399
    signal   pltbs              : out   pltbs_t
400
  );
401
  procedure check(
402
    constant rpt                : in    string;
403
    constant actual             : in    boolean;
404
    constant expected           : in    integer;
405
    variable pltbv              : inout pltbv_t;
406
    signal   pltbs              : out   pltbs_t
407
  );
408
  procedure check(
409
    constant rpt                : in    string;
410
    constant actual             : in    time;
411
    constant expected           : in    time;
412
    variable pltbv              : inout pltbv_t;
413
    signal   pltbs              : out   pltbs_t
414
  );
415
  procedure check(
416
    constant rpt                : in    string;
417
    constant actual             : in    time;
418
    constant expected           : in    time;
419
    constant tolerance          : in    time;
420
    variable pltbv              : inout pltbv_t;
421
    signal   pltbs              : out   pltbs_t
422
  );
423
  procedure check(
424
    constant rpt                : in    string;
425 88 pela
    constant actual             : in    string;
426
    constant expected           : in    string;
427
    variable pltbv              : inout pltbv_t;
428
    signal   pltbs              : out   pltbs_t
429
  );
430
  procedure check(
431
    constant rpt                : in    string;
432 2 pela
    constant expr               : in    boolean;
433 36 pela
    variable pltbv              : inout pltbv_t;
434
    signal   pltbs              : out   pltbs_t
435 2 pela
  );
436 24 pela
   procedure check(
437
    constant rpt                : in    string;
438
    constant expr               : in    boolean;
439
    constant actual             : in    string;
440
    constant expected           : in    string;
441
    constant mask               : in    string;
442 36 pela
    variable pltbv              : inout pltbv_t;
443
    signal   pltbs              : out   pltbs_t
444 24 pela
  );
445 36 pela
 
446 14 pela
  -- to_ascending
447
  function to_ascending(
448
    constant s                  : std_logic_vector
449
  ) return std_logic_vector;
450
  function to_ascending(
451
    constant s                  : unsigned
452
  ) return unsigned;
453
  function to_ascending(
454
    constant s                  : signed
455
  ) return signed;
456 2 pela
 
457 14 pela
  -- to_descending
458
  function to_descending(
459
    constant s                  : std_logic_vector
460
  ) return std_logic_vector;
461
  function to_descending(
462
    constant s                  : unsigned
463
  ) return unsigned;
464
  function to_descending(
465
    constant s                  : signed
466
  ) return signed;
467 36 pela
 
468 14 pela
  -- hxstr
469
  function hxstr(
470
    constant s                  : std_logic_vector;
471 24 pela
    constant prefix             : string := "";
472
    constant postfix            : string := ""
473 14 pela
  ) return string;
474
  function hxstr(
475
    constant s                  : unsigned;
476 24 pela
    constant prefix             : string := "";
477
    constant postfix            : string := ""
478 14 pela
  ) return string;
479
  function hxstr(
480
    constant s                  : signed;
481 24 pela
    constant prefix             : string := "";
482
    constant postfix            : string := ""
483 14 pela
  ) return string;
484
 
485 2 pela
  -- pltbutils internal procedure(s), do not call from user's code
486 36 pela
  procedure pltbs_update(
487
    variable pltbv              : inout pltbv_t;
488
    signal   pltbs              : out   pltbs_t
489 2 pela
  );
490 24 pela
 
491 36 pela
  procedure stopsim(
492
    constant timestamp          : in time
493
  );
494
 
495
  procedure pltbutils_error(
496
    constant rpt                : in string;
497
    variable pltbv              : inout pltbv_t;
498
    signal   pltbs              : out   pltbs_t
499
  );
500
 
501 24 pela
  procedure startsim_msg(
502
    constant testcase_name      : in string;
503
    constant timestamp          : in time
504
  );
505 36 pela
 
506 24 pela
  procedure endsim_msg(
507
    constant testcase_name      : in string;
508
    constant timestamp          : in time;
509
    constant num_tests          : in integer;
510 101 pela
    constant num_skiptests      : in integer;
511 24 pela
    constant num_checks         : in integer;
512
    constant num_errors         : in integer;
513
    constant show_success_fail  : in boolean
514
  );
515 36 pela
 
516 24 pela
  procedure starttest_msg(
517
    constant test_num           : in integer;
518
    constant test_name          : in string;
519
    constant timestamp          : in time
520
  );
521 36 pela
 
522 101 pela
  procedure skiptest_msg(
523
    constant test_num           : in integer;
524
    constant test_name          : in string;
525
    constant timestamp          : in time
526
  );
527
 
528 24 pela
  procedure endtest_msg(
529
    constant test_num           : in integer;
530
    constant test_name          : in string;
531
    constant timestamp          : in time;
532 101 pela
    constant test_active        : in boolean;
533 24 pela
    constant num_checks_in_test : in integer;
534
    constant num_errors_in_test : in integer
535 36 pela
  );
536
 
537 24 pela
  procedure check_msg(
538
    constant rpt                : in string;
539 36 pela
    constant timestamp          : in time;
540
    constant expr               : in boolean;
541 24 pela
    constant actual             : in string;
542
    constant expected           : in string;
543
    constant mask               : in string;
544 36 pela
    constant test_num           : in integer;
545 24 pela
    constant test_name          : in string;
546
    constant check_num          : in integer;
547
    constant err_cnt_in_test    : in integer
548
  );
549
 
550
  procedure error_msg(
551
    constant rpt                : in string;
552
    constant timestamp          : in time;
553 36 pela
    constant test_num           : in integer;
554 24 pela
    constant test_name          : in string;
555
    constant err_cnt_in_test    : in integer
556
  );
557 36 pela
 
558 2 pela
end package pltbutils_func_pkg;
559
 
560
package body pltbutils_func_pkg is
561
 
562
  ----------------------------------------------------------------------------
563
  -- startsim
564
  --
565
  -- procedure startsim(
566
  --   constant testcase_name      : in    string;
567 101 pela
  --   constant skiptests          : in    std_logic_vector;
568 36 pela
  --   variable pltbv              : inout pltbv_t;
569
  --   signal   pltbs              : out   pltbs_t
570 2 pela
  -- )
571
  --
572
  -- Displays a message at start of simulation message, and initializes
573 36 pela
  -- PlTbUtils' status and control variable and -signal.
574 2 pela
  -- Call startsim() only once.
575
  --
576
  -- Arguments:
577
  --   testcase_name            Name of the test case, e.g. "tc1".
578
  --
579 101 pela
  --   skiptests                std_logic_vector for marking tests that should
580
  --                            be skipped. The leftmost bit has position 0,
581
  --                            and position numbers increment to the right.
582
  --                            A '1' indicates that the test with the same
583
  --                            number as the position should be skipped.
584
  --                            Note that there is usually no test which has
585
  --                            number 0, so bit zero in the vector is usually
586
  --                            ignored.
587
  --                            This argument is normally fed by a generic.
588
  --                            If no tests should be skipped, a zero-length 
589
  --                            vector is allowed, ("").
590
  --                          
591 36 pela
  --   pltbv, pltbs             PlTbUtils' status- and control variable and
592
  --                            -signal.
593 2 pela
  --
594
  -- NOTE:
595
  -- The start-of-simulation message is not only intended to be informative
596
  -- for humans. It is also intended to be searched for by scripts,
597
  -- e.g. for collecting results from a large number of regression tests.
598
  -- For this reason, the message must be consistent and unique.
599
  --
600
  -- DO NOT MODIFY the message "--- START OF SIMULATION ---".
601
  -- DO NOT OUTPUT AN IDENTICAL MESSAGE anywhere else.
602
  --
603 101 pela
  -- Examples:
604
  -- startsim("tc1", "", pltbv, pltbs);
605
  -- startsim("tc2", G_SKIPTESTS, pltbv, pltbs); -- G_SKIPTESTS is a generic
606 2 pela
  ----------------------------------------------------------------------------
607
  procedure startsim(
608
    constant testcase_name      : in    string;
609 101 pela
    constant skiptests          : in    std_logic_vector;
610 36 pela
    variable pltbv              : inout pltbv_t;
611
    signal   pltbs              : out   pltbs_t
612 2 pela
  ) is
613 36 pela
    variable timestamp          : time;
614 101 pela
    variable v_ignored_skiptest : boolean := false;
615 2 pela
  begin
616 24 pela
    timestamp := now;
617 36 pela
    pltbv := C_PLTBV_INIT;
618
    printv(pltbv.testcase_name, testcase_name);
619
    pltbv.testcase_name_len := testcase_name'length;
620
    printv(pltbv.test_name, "START OF SIMULATION");
621
    pltbv.test_name_len     := 19;
622
    printv(pltbv.info, testcase_name);
623 101 pela
    if skiptests'length > 0 then
624
      for i in skiptests'low to skiptests'high loop
625
        if i >= pltbv.skiptests'low and i <= pltbv.skiptests'high then
626
          pltbv.skiptests(i) := skiptests(i);
627
        else
628
          if pltbv.skiptests(i) = '1' then
629
            v_ignored_skiptest := true;
630
          end if;
631
        end if;
632
      end loop;
633
      if v_ignored_skiptest then
634
        assert false
635
          report "Some SKIPTESTS flags ignored. Max " &
636
                 integer'image(pltbv.skiptests'length) & " flag bits supported."
637
          severity warning;
638
      end if;
639
    end if;
640 36 pela
    pltbv.info_len          := testcase_name'length;
641
    pltbs_update(pltbv, pltbs);
642 24 pela
    if C_PLTBUTILS_USE_STD_STARTSIM_MSG then
643
      startsim_msg(testcase_name, timestamp);
644
    end if;
645
    if C_PLTBUTILS_USE_CUSTOM_STARTSIM_MSG then
646
      custom_startsim_msg(testcase_name, timestamp);
647
    end if;
648 2 pela
  end procedure startsim;
649
 
650
  ----------------------------------------------------------------------------
651
  -- endsim
652
  --
653
  -- procedure endsim(
654 36 pela
  --   variable pltbv              : inout pltbv_t;
655
  --   signal   pltbs              : out   pltbs_t;
656 2 pela
  --   constant show_success_fail  : in  boolean := false;
657 97 pela
  --   constant force_stop         : in  boolean := false
658 2 pela
  -- )
659
  --
660
  -- Displays a message at end of simulation message, presents the simulation
661 36 pela
  -- results, and stops the simulation.
662 2 pela
  -- Call endsim() it only once.
663
  --
664 36 pela
  -- Arguments:
665
  --   pltbv, pltbs             PlTbUtils' status- and control variable and
666
  --                            -signal.
667 2 pela
  --
668 36 pela
  --   show_success_fail        If true, endsim() shows "*** SUCCESS ***",
669 2 pela
  --                            "*** FAIL ***", or "*** NO CHECKS ***".
670
  --                            Optional, default is false.
671
  --
672 97 pela
  --   force_stop               If true, forces the simulation to stop using an
673 2 pela
  --                            assert failure statement. Use this option only
674
  --                            if the normal way of stopping the simulation
675
  --                            doesn't work (see below).
676
  --                            Optional, default is false.
677
  --
678
  -- The testbench should be designed so that all clocks stop when endsim()
679 36 pela
  -- sets the signal pltbs.stop_sim to '1'. This should stop the simulator.
680 97 pela
  -- In some cases that doesn't work, then set the force_stop argument to true,
681
  -- which causes a false assert failure, which should stop the simulator.
682 2 pela
  -- Scripts searching transcript logs for errors and failures, should ignore
683
  -- the failure with "--- FORCE END OF SIMULATION ---" as part of the report.
684
  --
685
  -- NOTE:
686
  -- The end-of-simulation messages and success/fail messages are not only
687
  -- intended to be informative for humans. They are also intended to be
688
  -- searched for by scripts, e.g. for collecting results from a large number
689
  -- of regression tests.
690
  -- For this reason, the message must be consistent and unique.
691
  --
692 36 pela
  -- DO NOT MODIFY the messages "--- END OF SIMULATION ---",
693 2 pela
  -- "*** SUCCESS ***", "*** FAIL ***", "*** NO CHECKS ***".
694
  -- DO NOT OUTPUT IDENTICAL MESSAGES anywhere else.
695
  --
696
  -- Examples:
697 36 pela
  -- endsim(pltbv, pltbs);
698
  -- endsim(pltbv, pltbs, true);
699
  -- endsim(pltbv, pltbs, true, true);
700 2 pela
  ----------------------------------------------------------------------------
701
  procedure endsim(
702 36 pela
    variable pltbv              : inout pltbv_t;
703
    signal   pltbs              : out   pltbs_t;
704
    constant show_success_fail  : in    boolean := false;
705 97 pela
    constant force_stop         : in    boolean := false
706 2 pela
  ) is
707 24 pela
    variable timestamp : time;
708 2 pela
  begin
709 24 pela
    timestamp := now;
710
    if C_PLTBUTILS_USE_STD_ENDSIM_MSG then
711 36 pela
      endsim_msg(pltbv.testcase_name(1 to pltbv.testcase_name_len), timestamp,
712 101 pela
        pltbv.test_cnt, pltbv.skiptest_cnt, pltbv.chk_cnt, pltbv.err_cnt,
713
        show_success_fail);
714 24 pela
    end if;
715
    if C_PLTBUTILS_USE_CUSTOM_ENDSIM_MSG then
716 36 pela
      custom_endsim_msg(pltbv.testcase_name(1 to pltbv.testcase_name_len), timestamp,
717 101 pela
        pltbv.test_cnt, pltbv.skiptest_cnt, pltbv.chk_cnt, pltbv.err_cnt,
718
        show_success_fail);
719 24 pela
    end if;
720 36 pela
    pltbv.test_num      := 0;
721
    printv(pltbv.test_name, "END OF SIMULATION");
722
    pltbv.test_name_len := 17;
723
    pltbv.stop_sim      := '1';
724
    pltbs_update(pltbv, pltbs);
725 2 pela
    wait for C_WAIT_BEFORE_STOP_TIME;
726 97 pela
    if force_stop then
727 24 pela
      if C_PLTBUTILS_USE_STD_STOPSIM then
728
        stopsim(now);
729
      end if;
730
      if C_PLTBUTILS_USE_CUSTOM_STOPSIM then
731
        custom_stopsim(now);
732
      end if;
733
    end if;
734 2 pela
    wait;
735
  end procedure endsim;
736
 
737
  ----------------------------------------------------------------------------
738 24 pela
  -- starttest
739 2 pela
  --
740 24 pela
  -- procedure starttest(
741 2 pela
  --   constant num                : in    integer := -1;
742
  --   constant name               : in    string;
743 36 pela
  --   variable pltbv              : inout pltbv_t;
744
  --   signal   pltbs              : out   pltbs_t
745
  -- )
746 2 pela
  --
747
  -- Sets a number (optional) and a name for a test. The number and name will
748
  -- be printed to the screen, and displayed in the simulator's waveform
749 36 pela
  -- window.
750 2 pela
  -- The test number and name is also included if there errors reported by the
751
  -- check() procedure calls.
752
  --
753 36 pela
  -- Arguments:
754 2 pela
  --   num                      Test number. Optional, default is to increment
755
  --                            the current test number.
756
  --
757
  --   name                     Test name.
758
  --
759 36 pela
  --   pltbv, pltbs             PlTbUtils' status- and control variable and
760
  --                            -signal.
761 2 pela
  --
762
  -- If the test number is omitted, a new test number is automatically
763 36 pela
  -- computed by incrementing the current test number.
764 2 pela
  -- Manually setting the test number may make it easier to find the test code
765
  -- in the testbench code, though.
766
  --
767
  -- Examples:
768 36 pela
  -- starttest("Reset test", pltbv, pltbs);
769
  -- starttest(1, "Reset test", pltbv, pltbs);
770 2 pela
  ----------------------------------------------------------------------------
771 24 pela
  procedure starttest(
772 2 pela
    constant num                : in    integer := -1;
773
    constant name               : in    string;
774 36 pela
    variable pltbv              : inout pltbv_t;
775
    signal   pltbs              : out   pltbs_t
776 2 pela
  ) is
777 24 pela
    variable timestamp : time;
778 2 pela
  begin
779 24 pela
    timestamp := now;
780 2 pela
    if num = -1 then
781 36 pela
      pltbv.test_num := pltbv.test_num + 1;
782 2 pela
    else
783 36 pela
      pltbv.test_num := num;
784 2 pela
    end if;
785 36 pela
    printv(pltbv.test_name, name);
786
    pltbv.test_name_len := name'length;
787
    pltbv.chk_cnt_in_test := 0;
788
    pltbv.err_cnt_in_test := 0;
789 101 pela
    pltbv.test_active := true;
790
    if num >= pltbv.skiptests'low and num <= pltbv.skiptests'high then
791
      if pltbv.skiptests(num) = '1' then
792
        pltbv.test_active := false;
793
      end if;
794 24 pela
    end if;
795 101 pela
    if pltbv.test_active then
796
      pltbv.test_cnt := pltbv.test_cnt + 1;
797
      pltbs_update(pltbv, pltbs);
798
      if C_PLTBUTILS_USE_STD_STARTTEST_MSG then
799
        starttest_msg(pltbv.test_num, name, timestamp);
800
      end if;
801
      if C_PLTBUTILS_USE_CUSTOM_STARTTEST_MSG then
802
        custom_starttest_msg(pltbv.test_num, name, timestamp);
803
      end if;
804
    else
805
      pltbv.skiptest_cnt := pltbv.skiptest_cnt + 1;
806
      pltbs_update(pltbv, pltbs);
807
      if C_PLTBUTILS_USE_STD_SKIPTEST_MSG then
808
        skiptest_msg(pltbv.test_num, name, timestamp);
809
      end if;
810
      if C_PLTBUTILS_USE_CUSTOM_SKIPTEST_MSG then
811
        custom_skiptest_msg(pltbv.test_num, name, timestamp);
812
      end if;
813 24 pela
    end if;
814
  end procedure starttest;
815 36 pela
 
816 24 pela
  procedure starttest(
817
    constant name               : in    string;
818 36 pela
    variable pltbv              : inout pltbv_t;
819
    signal   pltbs              : out   pltbs_t
820 24 pela
  ) is
821
  begin
822 36 pela
    starttest(-1, name, pltbv, pltbs);
823 24 pela
  end procedure starttest;
824 36 pela
 
825 2 pela
  ----------------------------------------------------------------------------
826 101 pela
  -- is_test_active
827
  --
828
  -- function is_test_active(
829
  --   constant pltbv              : in    pltbv_t
830
  -- ) return boolean
831
  --
832
  -- Returns true if a test is active (not skipped), otherwise false.
833
  --
834
  -- Arguments:
835
  --   pltbv                     PlTbUtils' status- and control variable.
836
  --
837
  -- Example:
838
  -- starttest(3, "Example test", pltbv, pltbs);
839
  -- if is_test_active(pltbv) then
840
  --   ... test code ...
841
  -- end if;
842
  -- endtest(pltbv, pltbs);
843
  ----------------------------------------------------------------------------
844
  function is_test_active(
845
    constant pltbv              : in    pltbv_t
846
  ) return boolean is
847
  begin
848
    return pltbv.test_active;
849
  end function is_test_active;
850
 
851
  ----------------------------------------------------------------------------
852 24 pela
  -- endtest
853
  --
854
  -- procedure endtest(
855 36 pela
  --   variable pltbv              : inout pltbv_t;
856
  --   signal   pltbs              : out   pltbs_t
857
  -- )
858 24 pela
  --
859
  -- Prints an end-of-test message to the screen.
860
  --
861 36 pela
  -- Arguments:
862
  --   pltbv, pltbs             PlTbUtils' status- and control variable and
863
  --                            -signal.
864 24 pela
  --
865
  -- Example:
866 36 pela
  -- endtest(pltbv, pltbs);
867 24 pela
  ----------------------------------------------------------------------------
868
  procedure endtest(
869 36 pela
    variable pltbv              : inout pltbv_t;
870
    signal   pltbs              : out   pltbs_t
871 24 pela
  ) is
872
    variable timestamp : time;
873
  begin
874
    timestamp := now;
875
    if C_PLTBUTILS_USE_STD_ENDTEST_MSG then
876 36 pela
      endtest_msg(pltbv.test_num, pltbv.test_name(1 to pltbv.test_name_len),
877 101 pela
        timestamp, pltbv.test_active, pltbv.chk_cnt_in_test, pltbv.err_cnt_in_test);
878 36 pela
    end if;
879 24 pela
    if C_PLTBUTILS_USE_CUSTOM_ENDTEST_MSG then
880 36 pela
      custom_endtest_msg(pltbv.test_num, pltbv.test_name(1 to pltbv.test_name_len),
881 101 pela
        timestamp, pltbv.test_active, pltbv.chk_cnt_in_test, pltbv.err_cnt_in_test);
882 36 pela
    end if;
883 101 pela
    pltbv.test_active := true;
884 36 pela
    printv(pltbv.test_name, " ");
885
    pltbv.test_name_len := 1;
886
    pltbs_update(pltbv, pltbs);
887
  end procedure endtest;
888 24 pela
 
889
  ----------------------------------------------------------------------------
890 2 pela
  -- print printv print2
891
  --
892 36 pela
  -- procedure print(
893 2 pela
  --   signal   s                  : out   string;
894
  --   constant txt                : in    string
895 36 pela
  -- )
896 2 pela
  --
897 36 pela
  -- procedure print(
898 6 pela
  --   constant active             : in    boolean;
899
  --   signal   s                  : out   string;
900
  --   constant txt                : in    string
901 36 pela
  -- )
902 6 pela
  --
903 2 pela
  -- procedure print(
904 36 pela
  --   variable pltbv              : inout pltbv_t;
905
  --   signal   pltbs              : out   pltbs_t;
906 2 pela
  --   constant txt                : in    string
907
  -- )
908
  --
909 6 pela
  -- procedure print(
910
  --   constant active             : in    boolean;
911 36 pela
  --   variable pltbv              : inout pltbv_t;
912
  --   signal   pltbs              : out   pltbs_t;
913 6 pela
  --   constant txt                : in    string
914
  -- )
915
  --
916 2 pela
  -- procedure printv(
917
  --   variable s                  : out   string;
918
  --   constant txt                : in    string
919
  -- )
920
  --
921 6 pela
  -- procedure printv(
922
  --   constant active             : in    boolean;
923
  --   variable s                  : out   string;
924
  --   constant txt                : in    string
925
  -- )
926
  --
927 36 pela
  -- procedure print2(
928 2 pela
  --   signal   s                  : out   string;
929
  --   constant txt                : in    string
930
  -- )
931
  --
932 36 pela
  -- procedure print2(
933 6 pela
  --   constant active             : in    boolean;
934
  --   signal   s                  : out   string;
935
  --   constant txt                : in    string
936
  -- )
937
  --
938 36 pela
  -- procedure print2(
939
  --   variable pltbv              : inout pltbv_t;
940
  --   signal   pltbs              : out   pltbs_t;
941 2 pela
  --   constant txt                : in    string
942
  -- )
943
  --
944 36 pela
  -- procedure print2(
945 6 pela
  --   constant active             : in    boolean;
946 36 pela
  --   variable pltbv              : inout pltbv_t;
947
  --   signal   pltbs              : out   pltbs_t;
948 6 pela
  --   constant txt                : in    string
949
  -- )
950
  --
951 2 pela
  -- print() prints text messages to a signal for viewing in the simulator's
952
  -- waveform window. printv() does the same thing, but to a variable instead.
953 36 pela
  -- print2() prints both to a signal and to the transcript window.
954
  -- The type of the output can be string or pltbv_t+pltbs_t.
955 2 pela
  --
956 36 pela
  -- Arguments:
957
  --   s                        Signal or variable of type string to be
958 2 pela
  --                            printed to.
959
  --
960
  --   txt                      The text.
961
  --
962 6 pela
  --   active                   The text is only printed if active is true.
963
  --                            Useful for debug switches, etc.
964
  --
965 36 pela
  --   pltbv, pltbs             PlTbUtils' status- and control variable and
966
  --                            -signal.
967 2 pela
  --
968 36 pela
  -- If the string txt is longer than the signal s, the text will be truncated.
969
  -- If txt is shorter, s will be padded with spaces.
970 2 pela
  --
971
  -- Examples:
972
  -- print(msg, "Hello, world"); -- Prints to signal msg
973 36 pela
  -- print(G_DEBUG, msg, "Hello, world"); -- Prints to signal msg if
974 6 pela
  --                                      -- generic G_DEBUG is true
975 2 pela
  -- printv(v_msg, "Hello, world"); -- Prints to variable msg
976 36 pela
  -- print(pltbv, pltbs, "Hello, world"); -- Prints to "info" in waveform window
977
  -- print2(msg, "Hello, world"); -- Prints to signal and transcript window
978
  -- print2(pltbv, pltbs, "Hello, world"); -- Prints to "info" in waveform and
979 2 pela
  --                                      -- transcript windows
980
  ----------------------------------------------------------------------------
981
  procedure print(
982 6 pela
    constant active             : in    boolean;
983 2 pela
    signal   s                  : out   string;
984
    constant txt                : in    string
985
  ) is
986
    variable j : positive := txt 'low;
987
  begin
988 6 pela
    if active then
989
      for i in s'range loop
990
        if j <= txt 'high then
991
          s(i) <= txt (j);
992
        else
993
          s(i) <= ' ';
994
        end if;
995
        j := j + 1;
996
      end loop;
997
    end if;
998 2 pela
  end procedure print;
999 36 pela
 
1000 6 pela
  procedure print(
1001
    signal   s                  : out   string;
1002
    constant txt                : in    string
1003
  ) is
1004
  begin
1005
    print(true, s, txt);
1006
  end procedure print;
1007 36 pela
 
1008 2 pela
  procedure printv(
1009 6 pela
    constant active             : in    boolean;
1010 2 pela
    variable s                  : out   string;
1011
    constant txt                : in    string
1012
  ) is
1013
    variable j : positive := txt 'low;
1014
  begin
1015 6 pela
    if active then
1016
      for i in s'range loop
1017
        if j <= txt 'high then
1018
          s(i) := txt (j);
1019
        else
1020
          s(i) := ' ';
1021
        end if;
1022
        j := j + 1;
1023
      end loop;
1024
    end if;
1025 2 pela
  end procedure printv;
1026 36 pela
 
1027 6 pela
  procedure printv(
1028
    variable s                  : out   string;
1029
    constant txt                : in    string
1030
  ) is
1031
  begin
1032
    printv(true, s, txt);
1033 2 pela
  end procedure printv;
1034
 
1035 36 pela
  -- Print to info element in pltbv/pltbs, which shows up in waveform window
1036 2 pela
  procedure print(
1037 6 pela
    constant active             : in    boolean;
1038 36 pela
    variable pltbv              : inout pltbv_t;
1039
    signal   pltbs              : out   pltbs_t;
1040 2 pela
    constant txt                : in    string
1041
  ) is
1042
    variable j : positive := txt 'low;
1043
  begin
1044 6 pela
    if active then
1045 36 pela
      printv(pltbv.info, txt);
1046
      pltbv.info_len := txt'length;
1047
      pltbs_update(pltbv, pltbs);
1048 6 pela
    end if;
1049 2 pela
  end procedure print;
1050 6 pela
 
1051
  procedure print(
1052 36 pela
    variable pltbv              : inout pltbv_t;
1053
    signal   pltbs              : out   pltbs_t;
1054 6 pela
    constant txt                : in    string
1055
  ) is
1056
  begin
1057 36 pela
    print(true, pltbv, pltbs, txt);
1058
  end procedure print;
1059
 
1060 2 pela
  procedure print2(
1061 6 pela
    constant active             : in    boolean;
1062 2 pela
    signal   s                  : out   string;
1063
    constant txt                : in    string
1064
  ) is
1065
  begin
1066 36 pela
    if active then
1067
      print(s, txt);
1068 6 pela
      print(txt);
1069
    end if;
1070 2 pela
  end procedure print2;
1071
 
1072
  procedure print2(
1073 6 pela
    signal   s                  : out   string;
1074
    constant txt                : in    string
1075
  ) is
1076
  begin
1077 97 pela
    print2(true, s, txt);
1078 36 pela
  end procedure print2;
1079
 
1080 6 pela
  procedure print2(
1081
    constant active             : in    boolean;
1082 36 pela
    variable pltbv              : inout pltbv_t;
1083
    signal   pltbs              : out   pltbs_t;
1084 2 pela
    constant txt                : in    string
1085
  ) is
1086
  begin
1087 36 pela
    print(active, pltbv, pltbs, txt);
1088
    print(active, txt);
1089 2 pela
  end procedure print2;
1090
 
1091 6 pela
  procedure print2(
1092 36 pela
    variable pltbv              : inout pltbv_t;
1093
    signal   pltbs              : out   pltbs_t;
1094 6 pela
    constant txt                : in    string
1095
  ) is
1096
  begin
1097 97 pela
    print2(true, pltbv, pltbs, txt);
1098 36 pela
  end procedure print2;
1099 6 pela
 
1100 2 pela
  ----------------------------------------------------------------------------
1101
  -- waitclks
1102
  --
1103
  -- procedure waitclks(
1104
  --   constant n                  : in    natural;
1105
  --   signal   clk                : in    std_logic;
1106 36 pela
  --   variable pltbv              : inout pltbv_t;
1107
  --   signal   pltbs              : out   pltbs_t;
1108 2 pela
  --   constant falling            : in    boolean := false;
1109
  --   constant timeout            : in    time    := C_PLTBUTILS_TIMEOUT
1110
  -- )
1111
  --
1112
  -- Waits specified amount of clock cycles of the specified clock.
1113
  -- Or, to be more precise, a specified number of specified clock edges of
1114
  -- the specified clock.
1115
  --
1116 36 pela
  -- Arguments:
1117 2 pela
  --   n                        Number of rising or falling clock edges to wait.
1118
  --
1119
  --   clk                      The clock to wait for.
1120
  --
1121 36 pela
  --   pltbv, pltbs             PlTbUtils' status- and control variable and
1122
  --                            -signal.
1123 2 pela
  --
1124
  --   falling                  If true, waits for falling edges, otherwise
1125
  --                            rising edges. Optional, default is false.
1126
  --
1127
  --   timeout                  Timeout time, in case the clock is not working.
1128 36 pela
  --                            Optional, default is C_PLTBUTILS_TIMEOUT.
1129 2 pela
  --
1130
  -- Examples:
1131 36 pela
  -- waitclks(5, sys_clk, pltbv, pltbs);
1132
  -- waitclks(5, sys_clk, pltbv, pltbs true);
1133
  -- waitclks(5, sys_clk, pltbv, pltbs, true, 1 ms);
1134 2 pela
  ----------------------------------------------------------------------------
1135
  procedure waitclks(
1136
    constant n                  : in    natural;
1137
    signal   clk                : in    std_logic;
1138 36 pela
    variable pltbv              : inout pltbv_t;
1139
    signal   pltbs              : out   pltbs_t;
1140 2 pela
    constant falling            : in    boolean := false;
1141
    constant timeout            : in    time    := C_PLTBUTILS_TIMEOUT
1142
  ) is
1143
    variable i                  : natural := n;
1144
    variable v_timeout_time     : time;
1145
  begin
1146
    v_timeout_time := now + timeout;
1147
    while i > 0 loop
1148 6 pela
      if falling then
1149 2 pela
        wait until falling_edge(clk) for timeout / n;
1150
      else
1151
        wait until rising_edge(clk)  for timeout / n;
1152
      end if;
1153
      i := i - 1;
1154
    end loop;
1155
    if now >= v_timeout_time then
1156 36 pela
      pltbutils_error("waitclks() timeout", pltbv, pltbs);
1157 2 pela
    end if;
1158
  end procedure waitclks;
1159 36 pela
 
1160 6 pela
  ----------------------------------------------------------------------------
1161
  -- waitsig
1162
  --
1163
  -- procedure waitsig(
1164
  --   signal   s                  : in    integer|std_logic|std_logic_vector|unsigned|signed;
1165
  --   constant value              : in    integer|std_logic|std_logic_vector|unsigned|signed;
1166
  --   signal   clk                : in    std_logic;
1167 36 pela
  --   variable pltbv              : inout pltbv_t;
1168
  --   signal   pltbs              : out   pltbs_t;
1169 6 pela
  --   constant falling            : in    boolean := false;
1170
  --   constant timeout            : in    time    := C_PLTBUTILS_TIMEOUT
1171
  -- )
1172
  --
1173
  -- Waits until a signal has reached a specified value after specified clock
1174
  -- edge.
1175
  --
1176 36 pela
  -- Arguments:
1177 6 pela
  --   s                        The signal to test.
1178 36 pela
  --                            Supported types: integer, std_logic,
1179 6 pela
  --                            std_logic_vector, unsigned, signed.
1180
  --
1181
  --   value                    Value to wait for.
1182
  --                            Same type as data or integer.
1183
  --
1184
  --   clk                      The clock.
1185
  --
1186 36 pela
  --   pltbv, pltbs             PlTbUtils' status- and control variable and
1187
  --                            -signal.
1188 6 pela
  --
1189
  --   falling                  If true, waits for falling edges, otherwise
1190
  --                            rising edges. Optional, default is false.
1191
  --
1192
  --   timeout                  Timeout time, in case the clock is not working.
1193 36 pela
  --                            Optional, default is C_PLTBUTILS_TIMEOUT.
1194 6 pela
  --
1195
  -- Examples:
1196 36 pela
  -- waitsig(wr_en, '1', sys_clk, pltbv, pltbs);
1197
  -- waitsig(rd_en,   1, sys_clk, pltbv, pltbs, true);
1198
  -- waitclks(full, '1', sys_clk, pltbv, pltbs, true, 1 ms);
1199
  ----------------------------------------------------------------------------
1200 97 pela
  -- waitsig integer, clocked
1201 6 pela
  procedure waitsig(
1202
    signal   s                  : in    integer;
1203
    constant value              : in    integer;
1204
    signal   clk                : in    std_logic;
1205 36 pela
    variable pltbv              : inout pltbv_t;
1206
    signal   pltbs              : out   pltbs_t;
1207 6 pela
    constant falling            : in    boolean := false;
1208
    constant timeout            : in    time    := C_PLTBUTILS_TIMEOUT
1209
  ) is
1210
    variable v_timeout_time     : time;
1211
  begin
1212
    v_timeout_time := now + timeout;
1213
    l1 : loop
1214 36 pela
      waitclks(1, clk, pltbv, pltbs, falling, timeout);
1215 6 pela
      exit l1 when s = value or now >= v_timeout_time;
1216
    end loop;
1217
    if now >= v_timeout_time then
1218 36 pela
      pltbutils_error("waitsig() timeout", pltbv, pltbs);
1219 6 pela
    end if;
1220
  end procedure waitsig;
1221
 
1222 97 pela
  -- waitsig std_logic, clocked
1223 6 pela
  procedure waitsig(
1224
    signal   s                  : in    std_logic;
1225
    constant value              : in    std_logic;
1226
    signal   clk                : in    std_logic;
1227 36 pela
    variable pltbv              : inout pltbv_t;
1228
    signal   pltbs              : out   pltbs_t;
1229 6 pela
    constant falling            : in    boolean := false;
1230
    constant timeout            : in    time    := C_PLTBUTILS_TIMEOUT
1231
  ) is
1232
    variable v_timeout_time     : time;
1233
  begin
1234
    v_timeout_time := now + timeout;
1235
    l1 : loop
1236 36 pela
      waitclks(1, clk, pltbv, pltbs, falling, timeout);
1237 6 pela
      exit l1 when s = value or now >= v_timeout_time;
1238
    end loop;
1239
    if now >= v_timeout_time then
1240 36 pela
      pltbutils_error("waitsig() timeout", pltbv, pltbs);
1241 6 pela
    end if;
1242
  end procedure waitsig;
1243 36 pela
 
1244 97 pela
  -- waitsig std_logic against integer, clocked
1245 6 pela
  procedure waitsig(
1246
    signal   s                  : in    std_logic;
1247
    constant value              : in    integer;
1248
    signal   clk                : in    std_logic;
1249 36 pela
    variable pltbv              : inout pltbv_t;
1250
    signal   pltbs              : out   pltbs_t;
1251 6 pela
    constant falling            : in    boolean := false;
1252
    constant timeout            : in    time    := C_PLTBUTILS_TIMEOUT
1253
  ) is
1254
    variable v_value            : std_logic;
1255
    variable v_timeout_time     : time;
1256
  begin
1257
    case value is
1258
      when 0      => v_value := '0';
1259
      when 1      => v_value := '1';
1260
      when others => v_value := 'X';
1261
    end case;
1262
    if v_value /= 'X' then
1263 36 pela
      waitsig(s, v_value, clk, pltbv, pltbs, falling, timeout);
1264 6 pela
    else
1265 36 pela
      pltbutils_error("waitsig() timeout", pltbv, pltbs);
1266 6 pela
    end if;
1267 36 pela
  end procedure waitsig;
1268
 
1269 97 pela
  -- waitsig std_logic_vector, clocked
1270 6 pela
  procedure waitsig(
1271
    signal   s                  : in    std_logic_vector;
1272
    constant value              : in    std_logic_vector;
1273
    signal   clk                : in    std_logic;
1274 36 pela
    variable pltbv              : inout pltbv_t;
1275
    signal   pltbs              : out   pltbs_t;
1276 6 pela
    constant falling            : in    boolean := false;
1277
    constant timeout            : in    time    := C_PLTBUTILS_TIMEOUT
1278
  ) is
1279
    variable v_timeout_time     : time;
1280
  begin
1281
    v_timeout_time := now + timeout;
1282
    l1 : loop
1283 36 pela
      waitclks(1, clk, pltbv, pltbs, falling, timeout);
1284 6 pela
      exit l1 when s = value or now >= v_timeout_time;
1285
    end loop;
1286
    if now >= v_timeout_time then
1287 36 pela
      pltbutils_error("waitsig() timeout", pltbv, pltbs);
1288 6 pela
    end if;
1289 36 pela
  end procedure waitsig;
1290 6 pela
 
1291 97 pela
  -- waitsig std_logic_vector against integer, clocked
1292 6 pela
  procedure waitsig(
1293
    signal   s                  : in    std_logic_vector;
1294
    constant value              : in    integer;
1295
    signal   clk                : in    std_logic;
1296 36 pela
    variable pltbv              : inout pltbv_t;
1297
    signal   pltbs              : out   pltbs_t;
1298 6 pela
    constant falling            : in    boolean := false;
1299
    constant timeout            : in    time    := C_PLTBUTILS_TIMEOUT
1300
  ) is
1301
    variable v_timeout_time     : time;
1302
  begin
1303 36 pela
    waitsig(s, std_logic_vector(to_unsigned(value, s'length)), clk,
1304
            pltbv, pltbs, falling, timeout);
1305
  end procedure waitsig;
1306
 
1307 97 pela
  -- waitsig unsigned, clocked
1308 6 pela
  procedure waitsig(
1309
    signal   s                  : in    unsigned;
1310
    constant value              : in    unsigned;
1311
    signal   clk                : in    std_logic;
1312 36 pela
    variable pltbv              : inout pltbv_t;
1313
    signal   pltbs              : out   pltbs_t;
1314 6 pela
    constant falling            : in    boolean := false;
1315
    constant timeout            : in    time    := C_PLTBUTILS_TIMEOUT
1316
  ) is
1317
    variable v_timeout_time     : time;
1318
  begin
1319
    v_timeout_time := now + timeout;
1320
    l1 : loop
1321 36 pela
      waitclks(1, clk, pltbv, pltbs, falling, timeout);
1322 6 pela
      exit l1 when s = value or now >= v_timeout_time;
1323
    end loop;
1324
    if now >= v_timeout_time then
1325 36 pela
      pltbutils_error("waitsig() timeout", pltbv, pltbs);
1326 6 pela
    end if;
1327 36 pela
  end procedure waitsig;
1328
 
1329 97 pela
  -- waitsig unsigned against integer, clocked
1330 6 pela
  procedure waitsig(
1331
    signal   s                  : in    unsigned;
1332
    constant value              : in    integer;
1333
    signal   clk                : in    std_logic;
1334 36 pela
    variable pltbv              : inout pltbv_t;
1335
    signal   pltbs              : out   pltbs_t;
1336 6 pela
    constant falling            : in    boolean := false;
1337
    constant timeout            : in    time    := C_PLTBUTILS_TIMEOUT
1338
  ) is
1339
    variable v_timeout_time     : time;
1340
  begin
1341 36 pela
    waitsig(s, to_unsigned(value, s'length), clk,
1342
            pltbv, pltbs, falling, timeout);
1343
  end procedure waitsig;
1344
 
1345 97 pela
  -- waitsig signed, clocked
1346 6 pela
  procedure waitsig(
1347
    signal   s                  : in    signed;
1348
    constant value              : in    signed;
1349
    signal   clk                : in    std_logic;
1350 36 pela
    variable pltbv              : inout pltbv_t;
1351
    signal   pltbs              : out   pltbs_t;
1352 6 pela
    constant falling            : in    boolean := false;
1353
    constant timeout            : in    time    := C_PLTBUTILS_TIMEOUT
1354
  ) is
1355
    variable v_timeout_time     : time;
1356
  begin
1357
    v_timeout_time := now + timeout;
1358
    l1 : loop
1359 36 pela
      waitclks(1, clk, pltbv, pltbs, falling, timeout);
1360 6 pela
      exit l1 when s = value or now >= v_timeout_time;
1361
    end loop;
1362
    if now >= v_timeout_time then
1363 36 pela
      pltbutils_error("waitsig() timeout", pltbv, pltbs);
1364 6 pela
    end if;
1365 36 pela
  end procedure waitsig;
1366 6 pela
 
1367 97 pela
  -- waitsig signed against integer, clocked
1368 6 pela
  procedure waitsig(
1369
    signal   s                  : in    signed;
1370
    constant value              : in    integer;
1371
    signal   clk                : in    std_logic;
1372 36 pela
    variable pltbv              : inout pltbv_t;
1373
    signal   pltbs              : out   pltbs_t;
1374 6 pela
    constant falling            : in    boolean := false;
1375
    constant timeout            : in    time    := C_PLTBUTILS_TIMEOUT
1376
  ) is
1377
    variable v_timeout_time     : time;
1378
  begin
1379 36 pela
    waitsig(s, to_signed(value, s'length), clk,
1380
            pltbv, pltbs, falling, timeout);
1381
  end procedure waitsig;
1382
 
1383 97 pela
  -- waitsig std_logic, unclocked
1384
  procedure waitsig(
1385
    signal   s                  : in    std_logic;
1386
    constant value              : in    std_logic;
1387
    variable pltbv              : inout pltbv_t;
1388
    signal   pltbs              : out   pltbs_t;
1389
    constant timeout            : in    time    := C_PLTBUTILS_TIMEOUT
1390
  ) is
1391
  begin
1392
    if s /= value then
1393
      wait until s = value for timeout;
1394
      if s /= value then
1395
        pltbutils_error("waitsig() timeout", pltbv, pltbs);
1396
      end if;
1397
    end if;
1398
  end procedure waitsig;
1399
 
1400 2 pela
  ----------------------------------------------------------------------------
1401
  -- check
1402
  --
1403
  -- procedure check(
1404 36 pela
  --   constant rpt             : in    string;
1405 99 pela
  --   constant actual          : in    integer|std_logic|std_logic_vector|unsigned|signed|boolean|time|string;
1406
  --   constant expected        : in    integer|std_logic|std_logic_vector|unsigned|signed|boolean|time|string;
1407 36 pela
  --   variable pltbv           : inout pltbv_t;
1408
  --   signal   pltbs           : out   pltbs_t
1409
  -- )
1410 2 pela
  --
1411
  -- procedure check(
1412 36 pela
  --   constant rpt             : in    string;
1413
  --   constant actual          : in    std_logic_vector;
1414
  --   constant expected        : in    std_logic_vector;
1415
  --   constant mask            : in    std_logic_vector;
1416
  --   variable pltbv           : inout pltbv_t;
1417
  --   signal   pltbs           : out   pltbs_t
1418
  -- )
1419 2 pela
  --
1420
  -- procedure check(
1421 36 pela
  --   constant rpt             : in    string;
1422 99 pela
  --   constant actual          : in    time;
1423
  --   constant expected        : in    time;
1424
  --   constant tolerance       : in    time;
1425
  --   variable pltbv           : inout pltbv_t;
1426
  --   signal   pltbs           : out   pltbs_t
1427
  -- )
1428
  --
1429
  -- procedure check(
1430
  --   constant rpt             : in    string;
1431 36 pela
  --   constant expr            : in    boolean;
1432
  --   variable pltbv           : inout pltbv_t;
1433
  --   signal   pltbs           : out   pltbs_t
1434 2 pela
  -- )
1435
  --
1436
  -- Checks that the value of a signal or variable is equal to expected.
1437
  -- If not equal, displays an error message and increments the error counter.
1438
  --
1439 36 pela
  -- Arguments:
1440
  --   rpt                      Report message to be displayed in case of
1441
  --                            mismatch.
1442 2 pela
  --                            It is recommended that the message is unique
1443
  --                            and that it contains the name of the signal
1444 36 pela
  --                            or variable being checked.
1445
  --                            The message should NOT contain the expected
1446
  --                            value, becase check() prints that
1447 2 pela
  --                            automatically.
1448
  --
1449 24 pela
  --   actual                   The signal or variable to be checked.
1450 36 pela
  --                            Supported types: integer, std_logic,
1451 99 pela
  --                            std_logic_vector, unsigned, signed, boolean,
1452
  --                            time, string.
1453 2 pela
  --
1454 36 pela
  --   expected                 Expected value.
1455 2 pela
  --                            Same type as data or integer.
1456
  --
1457 36 pela
  --   mask                     Bit mask and:ed to data and expected
1458 2 pela
  --                            before comparison.
1459
  --                            Optional if data is std_logic_vector.
1460
  --                            Not allowed for other types.
1461
  --
1462 99 pela
  --   tolerance                Allowed tolerance. Checks that
1463
  --                            expected - tolerance <= actual <= expected + tolerance
1464
  --                            is true.
1465
  -- 
1466 2 pela
  --   expr                     boolean expression for checking.
1467
  --                            This makes it possible to check any kind of
1468
  --                            expresion, not just equality.
1469
  --
1470 36 pela
  --   pltbv, pltbs             PlTbUtils' status- and control variable and
1471
  --                            -signal.
1472
  --
1473 2 pela
  -- Examples:
1474 36 pela
  -- check("dat_o after reset", dat_o, 0, pltbv, pltbs);
1475 2 pela
  -- -- With mask:
1476 36 pela
  -- check("Status field in reg_o after start", reg_o, x"01", x"03", pltbv, pltbs);
1477 2 pela
  -- -- Boolean expression:
1478 36 pela
  -- check("Counter after data burst", cnt_o > 10, pltbv, pltbs);
1479 2 pela
  ----------------------------------------------------------------------------
1480
  -- check integer
1481
  procedure check(
1482
    constant rpt                : in    string;
1483 24 pela
    constant actual             : in    integer;
1484 2 pela
    constant expected           : in    integer;
1485 36 pela
    variable pltbv              : inout pltbv_t;
1486
    signal   pltbs              : out   pltbs_t
1487 2 pela
  ) is
1488
  begin
1489 36 pela
    check(rpt, actual = expected, str(actual), str(expected), "", pltbv, pltbs);
1490 2 pela
  end procedure check;
1491
 
1492
  -- check std_logic
1493
  procedure check(
1494
    constant rpt                : in    string;
1495 24 pela
    constant actual             : in    std_logic;
1496 2 pela
    constant expected           : in    std_logic;
1497 36 pela
    variable pltbv              : inout pltbv_t;
1498
    signal   pltbs              : out   pltbs_t
1499 2 pela
  ) is
1500
  begin
1501 36 pela
    check(rpt, actual = expected, str(actual), str(expected), "", pltbv, pltbs);
1502 2 pela
  end procedure check;
1503 36 pela
 
1504 2 pela
  -- check std_logic against integer
1505
  procedure check(
1506
    constant rpt                : in    string;
1507 24 pela
    constant actual             : in    std_logic;
1508 2 pela
    constant expected           : in    integer;
1509 36 pela
    variable pltbv              : inout pltbv_t;
1510
    signal   pltbs              : out   pltbs_t
1511 2 pela
  ) is
1512
  begin
1513 24 pela
    check(rpt, ((actual = '0' and expected = 0) or (actual = '1' and expected = 1)),
1514 36 pela
          str(actual), str(expected), "", pltbv, pltbs);
1515
  end procedure check;
1516
 
1517 2 pela
  -- check std_logic_vector
1518
  procedure check(
1519
    constant rpt                : in    string;
1520 24 pela
    constant actual             : in    std_logic_vector;
1521 2 pela
    constant expected           : in    std_logic_vector;
1522 36 pela
    variable pltbv              : inout pltbv_t;
1523
    signal   pltbs              : out   pltbs_t
1524 2 pela
  ) is
1525
  begin
1526 36 pela
    check(rpt, actual = expected, hxstr(actual, "0x"), hxstr(expected, "0x"), "", pltbv, pltbs);
1527 2 pela
  end procedure check;
1528 36 pela
 
1529 2 pela
  -- check std_logic_vector with mask
1530
  procedure check(
1531
    constant rpt                : in    string;
1532 24 pela
    constant actual             : in    std_logic_vector;
1533 2 pela
    constant expected           : in    std_logic_vector;
1534
    constant mask               : in    std_logic_vector;
1535 36 pela
    variable pltbv              : inout pltbv_t;
1536
    signal   pltbs              : out   pltbs_t
1537 2 pela
  ) is
1538
  begin
1539 24 pela
    check(rpt, (actual and mask) = (expected and mask),
1540 36 pela
          hxstr(actual, "0x"), hxstr(expected, "0x"), hxstr(mask, "0x"), pltbv, pltbs);
1541
  end procedure check;
1542
 
1543 2 pela
  -- check std_logic_vector against integer
1544
  procedure check(
1545
    constant rpt                : in    string;
1546 24 pela
    constant actual             : in    std_logic_vector;
1547 2 pela
    constant expected           : in    integer;
1548 36 pela
    variable pltbv              : inout pltbv_t;
1549
    signal   pltbs              : out   pltbs_t
1550 2 pela
  ) is
1551
  begin
1552 36 pela
    check(rpt, actual, std_logic_vector(to_signed(expected, actual'length)), pltbv, pltbs);
1553 2 pela
  end procedure check;
1554
 
1555
  -- check std_logic_vector with mask against integer
1556
  procedure check(
1557
    constant rpt                : in    string;
1558 24 pela
    constant actual             : in    std_logic_vector;
1559 2 pela
    constant expected           : in    integer;
1560
    constant mask               : in    std_logic_vector;
1561 36 pela
    variable pltbv              : inout pltbv_t;
1562
    signal   pltbs              : out   pltbs_t
1563 2 pela
  ) is
1564
  begin
1565 36 pela
    check(rpt, actual, std_logic_vector(to_signed(expected, actual'length)), mask, pltbv, pltbs);
1566 2 pela
  end procedure check;
1567 36 pela
 
1568 2 pela
  -- check unsigned
1569
  procedure check(
1570
    constant rpt                : in    string;
1571 24 pela
    constant actual             : in    unsigned;
1572 2 pela
    constant expected           : in    unsigned;
1573 36 pela
    variable pltbv              : inout pltbv_t;
1574
    signal   pltbs              : out   pltbs_t
1575 2 pela
  ) is
1576
  begin
1577 36 pela
    check(rpt, actual = expected, hxstr(actual, "0x"), hxstr(expected, "0x"), "", pltbv, pltbs);
1578 2 pela
  end procedure check;
1579 36 pela
 
1580 2 pela
  -- check unsigned against integer
1581
  procedure check(
1582
    constant rpt                : in    string;
1583 24 pela
    constant actual             : in    unsigned;
1584 2 pela
    constant expected           : in    integer;
1585 36 pela
    variable pltbv              : inout pltbv_t;
1586
    signal   pltbs              : out   pltbs_t
1587 2 pela
  ) is
1588
  begin
1589 36 pela
    check(rpt, actual, to_unsigned(expected, actual'length), pltbv, pltbs);
1590
  end procedure check;
1591
 
1592 2 pela
  -- check signed
1593
  procedure check(
1594
    constant rpt                : in    string;
1595 24 pela
    constant actual             : in    signed;
1596 2 pela
    constant expected           : in    signed;
1597 36 pela
    variable pltbv              : inout pltbv_t;
1598
    signal   pltbs              : out   pltbs_t
1599 2 pela
  ) is
1600
  begin
1601 36 pela
    check(rpt, actual = expected, hxstr(actual, "0x"), hxstr(expected, "0x"), "", pltbv, pltbs);
1602 2 pela
  end procedure check;
1603 36 pela
 
1604 2 pela
  -- check signed against integer
1605 24 pela
  -- TODO: find the bug reported by tb_pltbutils when expected  is negative (-1):
1606 2 pela
  --       ** Error: (vsim-86) numstd_conv_unsigned_nu: NATURAL arg value is negative (-1)
1607
  procedure check(
1608
    constant rpt                : in    string;
1609 24 pela
    constant actual             : in    signed;
1610 2 pela
    constant expected           : in    integer;
1611 36 pela
    variable pltbv              : inout pltbv_t;
1612
    signal   pltbs              : out   pltbs_t
1613 2 pela
  ) is
1614
  begin
1615 36 pela
    check(rpt, actual, to_signed(expected, actual'length), pltbv, pltbs);
1616
  end procedure check;
1617 99 pela
 
1618
  -- check boolean
1619
  procedure check(
1620
    constant rpt                : in    string;
1621
    constant actual             : in    boolean;
1622
    constant expected           : in    boolean;
1623
    variable pltbv              : inout pltbv_t;
1624
    signal   pltbs              : out   pltbs_t
1625
  ) is
1626
  begin
1627
    check(rpt, actual = expected, str(actual), str(expected), "", pltbv, pltbs);
1628
  end procedure check;
1629
 
1630
  -- check boolean against integer
1631
  procedure check(
1632
    constant rpt                : in    string;
1633
    constant actual             : in    boolean;
1634
    constant expected           : in    integer;
1635
    variable pltbv              : inout pltbv_t;
1636
    signal   pltbs              : out   pltbs_t
1637
  ) is
1638
  begin
1639
    check(rpt, ((actual = false and expected = 0) or (actual = true and expected = 1)),
1640
          str(actual), str(expected), "", pltbv, pltbs);
1641
  end procedure check;
1642
 
1643
  -- check time
1644
  procedure check(
1645
    constant rpt                : in    string;
1646
    constant actual             : in    time;
1647
    constant expected           : in    time;
1648
    variable pltbv              : inout pltbv_t;
1649
    signal   pltbs              : out   pltbs_t
1650
  ) is
1651
  begin
1652
    check(rpt, actual = expected, time'image(actual), time'image(expected), "", pltbv, pltbs);
1653
  end procedure check;
1654
 
1655
  -- check time with tolerance
1656
  procedure check(
1657
    constant rpt                : in    string;
1658
    constant actual             : in    time;
1659
    constant expected           : in    time;
1660
    constant tolerance          : in    time;
1661
    variable pltbv              : inout pltbv_t;
1662
    signal   pltbs              : out   pltbs_t
1663
  ) is
1664
  begin
1665
    check(rpt, ((actual >= expected-tolerance) and (actual <= expected+tolerance)),
1666
          time'image(actual), time'image(expected) & " +/- " & time'image(tolerance), "", pltbv, pltbs);
1667
  end procedure check;
1668 88 pela
 
1669
  -- check string
1670
  procedure check(
1671
    constant rpt                : in    string;
1672
    constant actual             : in    string;
1673
    constant expected           : in    string;
1674
    variable pltbv              : inout pltbv_t;
1675
    signal   pltbs              : out   pltbs_t
1676
  ) is
1677
    variable mismatch : boolean := false;
1678
  begin
1679
    if actual'length /= expected'length then
1680
      mismatch := true;
1681
    else
1682
      for i in 0 to actual'length-1 loop
1683
        if actual(i+actual'low) /= expected(i+expected'low) then
1684
          mismatch := true;
1685
          exit;
1686
        end if;
1687
      end loop;
1688
    end if;
1689
    check(rpt, not mismatch, actual, expected, "", pltbv, pltbs);
1690
  end procedure check;
1691
 
1692 2 pela
  -- check with boolean expression
1693 99 pela
  -- Check signal or variable with a boolean expression as argument expr.
1694
  -- This allowes any kind of check, including less than, greater than,
1695
  -- ranges, etc. But there are no clear messages in case of mismatch.
1696 2 pela
  procedure check(
1697
    constant rpt                : in    string;
1698
    constant expr               : in    boolean;
1699 36 pela
    variable pltbv              : inout pltbv_t;
1700
    signal   pltbs              : out   pltbs_t
1701 2 pela
  ) is
1702
  begin
1703 36 pela
    check(rpt, expr, "", "", "", pltbv, pltbs);
1704
  end procedure check;
1705
 
1706 99 pela
  -- check base procedure
1707
  -- All other check procedures perform the check, and calls this procedure
1708
  -- with the check result in the expr argument.
1709
  -- This procedure can also be called directly. It allow any kind of check,
1710
  -- including less than, greater than, ranges, etc. 
1711
  -- Your calling code must convert actual, expected and mask to strings.
1712 24 pela
  procedure check(
1713
    constant rpt                : in    string;
1714
    constant expr               : in    boolean;
1715
    constant actual             : in    string;
1716
    constant expected           : in    string;
1717
    constant mask               : in    string;
1718 36 pela
    variable pltbv              : inout pltbv_t;
1719
    signal   pltbs              : out   pltbs_t
1720 24 pela
  ) is
1721 36 pela
    variable timestamp          : time;
1722 24 pela
  begin
1723 36 pela
    timestamp := now;
1724
    pltbv.chk_cnt := pltbv.chk_cnt + 1;
1725
    pltbv.chk_cnt_in_test := pltbv.chk_cnt_in_test + 1;
1726 101 pela
    if not is_test_active(pltbv) then
1727
      pltbv.err_cnt := pltbv.err_cnt + 1;
1728
      pltbv.err_cnt_in_test := pltbv.err_cnt_in_test + 1;
1729
      if C_PLTBUTILS_USE_STD_CHECK_MSG then
1730
        check_msg("check() executed in skipped test, missing if clause?", timestamp, false, "", "", "", pltbv.test_num,
1731
          pltbv.test_name(1 to pltbv.test_name_len), pltbv.chk_cnt, pltbv.err_cnt_in_test);
1732
      end if;
1733
      if C_PLTBUTILS_USE_CUSTOM_CHECK_MSG then
1734
        custom_check_msg("check() executed in skipped test, missing if clause?", timestamp, false, "", "", "", pltbv.test_num,
1735
          pltbv.test_name(1 to pltbv.test_name_len), pltbv.chk_cnt, pltbv.err_cnt_in_test);
1736
      end if;
1737
    end if;
1738 2 pela
    if not expr then
1739 36 pela
      pltbv.err_cnt := pltbv.err_cnt + 1;
1740
      pltbv.err_cnt_in_test := pltbv.err_cnt_in_test + 1;
1741 2 pela
    end if;
1742 36 pela
    pltbs_update(pltbv, pltbs);
1743 24 pela
    if C_PLTBUTILS_USE_STD_CHECK_MSG then
1744 36 pela
      check_msg(rpt, timestamp, expr, actual, expected, mask, pltbv.test_num,
1745
        pltbv.test_name(1 to pltbv.test_name_len), pltbv.chk_cnt, pltbv.err_cnt_in_test);
1746 24 pela
    end if;
1747
    if C_PLTBUTILS_USE_CUSTOM_CHECK_MSG then
1748 36 pela
      custom_check_msg(rpt, timestamp, expr, actual, expected, mask, pltbv.test_num,
1749
        pltbv.test_name(1 to pltbv.test_name_len), pltbv.chk_cnt, pltbv.err_cnt_in_test);
1750 24 pela
    end if;
1751 36 pela
    pltbs_update(pltbv, pltbs);
1752 24 pela
  end procedure check;
1753 36 pela
 
1754 2 pela
  ----------------------------------------------------------------------------
1755 14 pela
  -- to_ascending
1756
  --
1757
  -- function to_ascending(
1758
  --  constant s                  : std_logic_vector
1759
  -- ) return std_logic_vector;
1760
  --
1761
  -- function to_ascending(
1762
  --  constant s                  : unsigned
1763
  -- ) return unsigned
1764
  --
1765
  -- function to_ascending(
1766
  --  constant s                  : signed
1767
  -- ) return signed;
1768
  --
1769 97 pela
  -- Converts a vector to ascending range ("to-range").
1770 14 pela
  -- The argument s can have ascending or descending range.
1771 97 pela
  -- E.g. an argument defined as a std_logic_vector(3 downto 1) 
1772
  -- will be returned as a std_logic_vector(1 to 3).
1773
  --
1774
  -- Arguments: 
1775
  --   s             Constant, signal or variable to convert
1776
  --
1777
  -- Return value:   Converted value
1778
  --
1779
  -- Examples:
1780
  -- ascending_sig <= to_ascending(descending_sig);
1781
  -- ascending_var := to_ascending(descending_var);
1782 14 pela
  ----------------------------------------------------------------------------
1783
  function to_ascending(
1784
    constant s                  : std_logic_vector
1785
  ) return std_logic_vector is
1786 18 pela
    variable r : std_logic_vector(s'low to s'high);
1787 14 pela
  begin
1788
    for i in r'range loop
1789
      r(i) := s(i);
1790
    end loop;
1791
    return r;
1792
  end function to_ascending;
1793
 
1794
  function to_ascending(
1795
    constant s                  : unsigned
1796
  ) return unsigned is
1797 18 pela
    variable r : unsigned(s'low to s'high);
1798 14 pela
  begin
1799
    for i in r'range loop
1800
      r(i) := s(i);
1801
    end loop;
1802
    return r;
1803
  end function to_ascending;
1804
 
1805
  function to_ascending(
1806
    constant s                  : signed
1807
  ) return signed is
1808 18 pela
    variable r : signed(s'low to s'high);
1809 14 pela
  begin
1810
    for i in r'range loop
1811
      r(i) := s(i);
1812
    end loop;
1813
    return r;
1814
  end function to_ascending;
1815
 
1816
  ----------------------------------------------------------------------------
1817
  -- to_descending
1818
  --
1819
  -- function to_descending(
1820
  --  constant s                  : std_logic_vector
1821
  -- ) return std_logic_vector;
1822
  --
1823
  -- function to_descending(
1824
  --  constant s                  : unsigned
1825
  -- ) return unsigned
1826
  --
1827
  -- function to_descending(
1828
  --  constant s                  : signed
1829
  -- ) return signed;
1830
  --
1831 97 pela
  -- Converts a vector to descending range ("downto-range").
1832 14 pela
  -- The argument s can have ascending or descending range.
1833 97 pela
  -- E.g. an argument defined as a std_logic_vector(1 to 3) 
1834
  -- will be returned as a std_logic_vector(3 downto 1).
1835
  --
1836
  -- Arguments: 
1837
  --   s             Constant, signal or variable to convert
1838
  --
1839
  -- Return value:   Converted value
1840
  --
1841
  -- Examples:
1842
  -- descending_sig <= to_descending(ascending_sig);
1843
  -- descending_var := to_descending(ascending_var);
1844 14 pela
  ----------------------------------------------------------------------------
1845
  function to_descending(
1846
    constant s                  : std_logic_vector
1847
  ) return std_logic_vector is
1848 18 pela
    variable r : std_logic_vector(s'high downto s'low);
1849 14 pela
  begin
1850
    for i in r'range loop
1851
      r(i) := s(i);
1852
    end loop;
1853
    return r;
1854
  end function to_descending;
1855 36 pela
 
1856 14 pela
  function to_descending(
1857
    constant s                  : unsigned
1858
  ) return unsigned is
1859 18 pela
    variable r : unsigned(s'high downto s'low);
1860 14 pela
  begin
1861
    for i in r'range loop
1862
      r(i) := s(i);
1863
    end loop;
1864
    return r;
1865
  end function to_descending;
1866
 
1867
  function to_descending(
1868
    constant s                  : signed
1869
  ) return signed is
1870 18 pela
    variable r : signed(s'high downto s'low);
1871 14 pela
  begin
1872
    for i in r'range loop
1873
      r(i) := s(i);
1874
    end loop;
1875
    return r;
1876
  end function to_descending;
1877 36 pela
 
1878 14 pela
  ----------------------------------------------------------------------------
1879
  -- hxstr
1880
  -- function hxstr(
1881
  --  constant s                  : std_logic_vector;
1882 24 pela
  --  constant prefix             : string := "";
1883
  --  constant postfix            : string := ""
1884 14 pela
  -- ) return string;
1885
  --
1886
  -- function hxstr(
1887
  --  constant s                  : unsigned;
1888 24 pela
  --  constant prefix             : string := "";
1889
  --  constant postfix            : string := ""
1890 14 pela
  -- ) return string;
1891
  --
1892
  -- function hxstr(
1893
  --  constant s                  : signed;
1894 24 pela
  --  constant prefix             : string := "";
1895
  --  constant postfix            : string := ""
1896 14 pela
  -- ) return string;
1897
  --
1898 97 pela
  -- Converts a vector to a string in hexadecimal format.
1899
  -- An optional prefix can be specified, e.g. "0x", as well as a suffix.
1900 14 pela
  --
1901 97 pela
  -- The input argument can have ascending range ( "to-range" ) or descending range
1902
  -- ("downto-range"). There is no vector length limitation.
1903 14 pela
  --
1904 97 pela
  -- Arguments: 
1905
  --   s             Constant, signal or variable to convert
1906 14 pela
  --
1907 97 pela
  -- Return value:   Converted value
1908
  --
1909 14 pela
  -- Examples:
1910
  -- print("value=" & hxstr(s));
1911
  -- print("value=" & hxstr(s, "0x"));
1912 97 pela
  -- print("value=" & hxstr(s, "16#", "#"));
1913 14 pela
  ----------------------------------------------------------------------------
1914
  function hxstr(
1915
    constant s                  : std_logic_vector;
1916 24 pela
    constant prefix             : string := "";
1917
    constant postfix            : string := ""
1918 14 pela
  ) return string is
1919 97 pela
    variable hexstr             : string(1 to (s'length+3)/4);
1920
    variable nibble_aligned_s   : std_logic_vector(((s'length+3)/4)*4-1 downto 0) := (others => '0');
1921
    variable nibble             : std_logic_vector(3 downto 0);
1922 14 pela
  begin
1923 97 pela
    nibble_aligned_s(s'length-1 downto 0) := to_descending(s);
1924
    for i in 0 to nibble_aligned_s'high/4 loop
1925
      nibble := nibble_aligned_s(4*i + 3 downto 4*i);
1926
      case nibble is
1927
        when "0000" => hexstr(hexstr'high-i) := '0';
1928
        when "0001" => hexstr(hexstr'high-i) := '1';
1929
        when "0010" => hexstr(hexstr'high-i) := '2';
1930
        when "0011" => hexstr(hexstr'high-i) := '3';
1931
        when "0100" => hexstr(hexstr'high-i) := '4';
1932
        when "0101" => hexstr(hexstr'high-i) := '5';
1933
        when "0110" => hexstr(hexstr'high-i) := '6';
1934
        when "0111" => hexstr(hexstr'high-i) := '7';
1935
        when "1000" => hexstr(hexstr'high-i) := '8';
1936
        when "1001" => hexstr(hexstr'high-i) := '9';
1937
        when "1010" => hexstr(hexstr'high-i) := 'A';
1938
        when "1011" => hexstr(hexstr'high-i) := 'B';
1939
        when "1100" => hexstr(hexstr'high-i) := 'C';
1940
        when "1101" => hexstr(hexstr'high-i) := 'D';
1941
        when "1110" => hexstr(hexstr'high-i) := 'E';
1942
        when "1111" => hexstr(hexstr'high-i) := 'F';
1943
        when "UUUU" => hexstr(hexstr'high-i) := 'U';
1944
        when "XXXX" => hexstr(hexstr'high-i) := 'X';
1945
        when "ZZZZ" => hexstr(hexstr'high-i) := 'Z';
1946
        when "WWWW" => hexstr(hexstr'high-i) := 'W';
1947
        when "LLLL" => hexstr(hexstr'high-i) := 'L';
1948
        when "HHHH" => hexstr(hexstr'high-i) := 'H';
1949
        when "----" => hexstr(hexstr'high-i) := '-';
1950
        when others => hexstr(hexstr'high-i) := '?';
1951
        -- TODO: handle vectors where nibble_aligned_s'length > a'length and the highest nibble are all equal characters such as "XXX"
1952
      end case;
1953
    end loop;
1954
    return prefix & hexstr & postfix;
1955 14 pela
  end function hxstr;
1956 36 pela
 
1957 14 pela
  function hxstr(
1958
    constant s                  : unsigned;
1959 24 pela
    constant prefix             : string := "";
1960
    constant postfix            : string := ""
1961 14 pela
  ) return string is
1962
  begin
1963 97 pela
    return hxstr(std_logic_vector(s), prefix, postfix);
1964 14 pela
  end function hxstr;
1965 36 pela
 
1966 14 pela
  function hxstr(
1967
    constant s                  : signed;
1968 24 pela
    constant prefix             : string := "";
1969
    constant postfix            : string := ""
1970 14 pela
  ) return string is
1971
  begin
1972 97 pela
    return hxstr(std_logic_vector(s), prefix, postfix);
1973 14 pela
  end function hxstr;
1974 36 pela
 
1975 14 pela
  ----------------------------------------------------------------------------
1976 97 pela
  -- pltbutils internal procedures, called from other pltbutils procedures.
1977
  -- Do not to call these from user's code.
1978
  -- These procedures are undocumented in the specification on purpose.
1979 2 pela
  ----------------------------------------------------------------------------
1980 36 pela
  procedure pltbs_update(
1981
    variable pltbv              : inout pltbv_t;
1982
    signal   pltbs              : out   pltbs_t
1983
  ) is
1984 2 pela
  begin
1985 36 pela
    pltbs.test_num  <= pltbv.test_num;
1986
    print(pltbs.test_name, pltbv.test_name);
1987
    print(pltbs.info, pltbv.info);
1988
    pltbs.chk_cnt   <= pltbv.chk_cnt;
1989
    pltbs.err_cnt   <= pltbv.err_cnt;
1990
    pltbs.stop_sim  <= pltbv.stop_sim;
1991
  end procedure pltbs_update;
1992
 
1993
  procedure pltbutils_error(
1994
    constant rpt                : in string;
1995
    variable pltbv              : inout pltbv_t;
1996
    signal   pltbs              : out   pltbs_t
1997
  ) is
1998
  begin
1999
    pltbv.err_cnt := pltbv.err_cnt + 1;
2000
    pltbv.err_cnt_in_test := pltbv.err_cnt_in_test + 1;
2001
    pltbs_update(pltbv, pltbs);
2002
    if C_PLTBUTILS_USE_STD_ERROR_MSG then
2003
      error_msg(rpt, now, pltbv.test_num,
2004
        pltbv.test_name(1 to pltbv.test_name_len), pltbv.err_cnt_in_test);
2005
    end if;
2006
    if C_PLTBUTILS_USE_CUSTOM_ERROR_MSG then
2007
      custom_error_msg(rpt, now, pltbv.test_num,
2008
        pltbv.test_name(1 to pltbv.test_name_len), pltbv.err_cnt_in_test);
2009
    end if;
2010
  end procedure pltbutils_error;
2011
 
2012
  procedure stopsim(
2013
    constant timestamp          : in time
2014
  ) is
2015
  begin
2016
    assert false
2017
    report "--- FORCE END OF SIMULATION ---" &
2018
           " (ignore this false failure message, it's not a real failure)"
2019
    severity failure;
2020
  end procedure stopsim;
2021
 
2022 24 pela
  procedure startsim_msg(
2023
    constant testcase_name      : in string;
2024
    constant timestamp          : in time
2025
  ) is
2026
  begin
2027
    print(lf & "--- START OF SIMULATION ---");
2028
    print("Testcase: " & testcase_name);
2029
    print(time'image(timestamp));
2030
  end procedure startsim_msg;
2031
 
2032
  procedure endsim_msg(
2033
    constant testcase_name      : in string;
2034
    constant timestamp          : in time;
2035
    constant num_tests          : in integer;
2036 101 pela
    constant num_skiptests      : in integer;
2037 24 pela
    constant num_checks         : in integer;
2038
    constant num_errors         : in integer;
2039
    constant show_success_fail  : in boolean
2040
  ) is
2041
    variable l : line;
2042
  begin
2043
    print(lf & "--- END OF SIMULATION ---");
2044 36 pela
    print("Note: the results presented below are based on the PlTbUtil's check() procedure calls.");
2045 24 pela
    print("      The design may contain more errors, for which there are no check() calls.");
2046
    write(l, timestamp, right, 14);
2047
    writeline(output, l);
2048
    write(l, num_tests, right, 11);
2049
    write(l, string'(" Tests"));
2050
    writeline(output, l);
2051 101 pela
    write(l, num_skiptests, right, 11);
2052
    write(l, string'(" Skipped tests"));
2053
    writeline(output, l);
2054 24 pela
    write(l, num_checks, right, 11);
2055
    write(l, string'(" Checks"));
2056
    writeline(output, l);
2057
    write(l, num_errors, right, 11);
2058
    write(l, string'(" Errors"));
2059
    writeline(output, l);
2060
    if show_success_fail then
2061
      if num_errors = 0 and num_checks > 0 then
2062
        print("*** SUCCESS ***");
2063
      elsif num_checks > 0 then
2064
        print("*** FAIL ***");
2065
      else
2066
        print("*** NO CHECKS ***");
2067
      end if;
2068 36 pela
    end if;
2069 24 pela
  end procedure endsim_msg;
2070 36 pela
 
2071 24 pela
  procedure starttest_msg(
2072
    constant test_num           : in integer;
2073
    constant test_name          : in string;
2074
    constant timestamp          : in time
2075
  ) is
2076
  begin
2077 36 pela
    print(lf & "Test " & str(test_num) & ": " & test_name & " (" & time'image(timestamp) & ")");
2078 24 pela
  end procedure starttest_msg;
2079 36 pela
 
2080 101 pela
  procedure skiptest_msg(
2081
    constant test_num           : in integer;
2082
    constant test_name          : in string;
2083
    constant timestamp          : in time
2084
  ) is
2085
  begin
2086
    print(lf & "Skipping Test " & str(test_num) & ": " & test_name & " (" & time'image(timestamp) & ")");
2087
  end procedure skiptest_msg;
2088
 
2089 24 pela
  procedure endtest_msg(
2090
    constant test_num           : in integer;
2091
    constant test_name          : in string;
2092
    constant timestamp          : in time;
2093 101 pela
    constant test_active        : in boolean;
2094 24 pela
    constant num_checks_in_test : in integer;
2095
    constant num_errors_in_test : in integer
2096
  ) is
2097
  begin
2098 101 pela
    if test_active then
2099
      print("Done with test " & str(test_num) & ": " & test_name & " (" & time'image(timestamp) & ")");
2100
    end if;
2101 24 pela
  end procedure endtest_msg;
2102 36 pela
 
2103 24 pela
  procedure check_msg(
2104
    constant rpt                : in string;
2105 36 pela
    constant timestamp          : in time;
2106
    constant expr               : in boolean;
2107 24 pela
    constant actual             : in string;
2108
    constant expected           : in string;
2109
    constant mask               : in string;
2110 36 pela
    constant test_num           : in integer;
2111 24 pela
    constant test_name          : in string;
2112
    constant check_num          : in integer;
2113
    constant err_cnt_in_test    : in integer
2114
  ) is
2115
    variable actual_str_len     : integer := 1;
2116 88 pela
    variable actual_str         : string(1 to actual'length+8) := (others => ' ');
2117
    variable expected_str       : string(1 to expected'length+10) := (others => ' ');
2118 24 pela
    variable expected_str_len   : integer := 1;
2119 88 pela
    variable mask_str           : string(1 to mask'length+6) := (others => ' ');
2120 24 pela
    variable mask_str_len       : integer := 1;
2121
  begin
2122
    if not expr then -- Output message only if the check fails
2123
      if actual /= "" then
2124
        actual_str_len := 8 + actual'length;
2125 88 pela
        actual_str := " Actual=" & actual;
2126 36 pela
      end if;
2127 24 pela
      if expected /= "" then
2128
        expected_str_len := 10 + expected'length;
2129 88 pela
        expected_str := " Expected=" & expected;
2130 36 pela
      end if;
2131 24 pela
      if mask /= "" then
2132
        mask_str_len := 6 + mask'length;
2133 88 pela
        mask_str := " Mask=" & mask;
2134 36 pela
      end if;
2135 24 pela
      assert false
2136
        report "Check " & str(check_num) & "; " & rpt & "; " &
2137 36 pela
               actual_str(1 to actual_str_len) &
2138 24 pela
               expected_str(1 to expected_str_len) &
2139
               mask_str(1 to mask_str_len) &
2140
               "  in test " & str(test_num) & " " & test_name
2141
        severity error;
2142
    end if;
2143 36 pela
  end procedure check_msg;
2144
 
2145 24 pela
  procedure error_msg(
2146
    constant rpt                : in string;
2147
    constant timestamp          : in time;
2148 36 pela
    constant test_num           : in integer;
2149 24 pela
    constant test_name          : in string;
2150
    constant err_cnt_in_test    : in integer
2151
  ) is
2152
  begin
2153
    assert false
2154
    report rpt & " in test " & str(test_num) & ": " & test_name
2155
    severity error;
2156
  end procedure error_msg;
2157 36 pela
 
2158 2 pela
end package body pltbutils_func_pkg;

powered by: WebSVN 2.1.0

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