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

Subversion Repositories pltbutils

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

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 107 pela
---- Copyright (C) 2013-2020 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 107 pela
  -- waitsig std_logic edge, unclocked
314
  procedure waitsig(
315
    signal   s                  : in    std_logic;
316
    variable pltbv              : inout pltbv_t;
317
    signal   pltbs              : out   pltbs_t;
318
    constant falling            : in    boolean := false;
319
    constant timeout            : in    time    := C_PLTBUTILS_TIMEOUT
320
  );
321 2 pela
  -- check
322
  procedure check(
323
    constant rpt                : in    string;
324 24 pela
    constant actual             : in    integer;
325 2 pela
    constant expected           : in    integer;
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    std_logic;
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;
339 2 pela
    constant expected           : in    integer;
340 36 pela
    variable pltbv              : inout pltbv_t;
341
    signal   pltbs              : out   pltbs_t
342
  );
343 2 pela
  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 36 pela
    variable pltbv              : inout pltbv_t;
348
    signal   pltbs              : out   pltbs_t
349 2 pela
  );
350
  procedure check(
351
    constant rpt                : in    string;
352 24 pela
    constant actual             : in    std_logic_vector;
353 2 pela
    constant expected           : in    std_logic_vector;
354
    constant mask               : in    std_logic_vector;
355 36 pela
    variable pltbv              : inout pltbv_t;
356
    signal   pltbs              : out   pltbs_t
357 2 pela
  );
358
  procedure check(
359
    constant rpt                : in    string;
360 24 pela
    constant actual             : in    std_logic_vector;
361 2 pela
    constant expected           : in    integer;
362 36 pela
    variable pltbv              : inout pltbv_t;
363
    signal   pltbs              : out   pltbs_t
364
  );
365 2 pela
  procedure check(
366
    constant rpt                : in    string;
367 24 pela
    constant actual             : in    std_logic_vector;
368 2 pela
    constant expected           : in    integer;
369
    constant mask               : in    std_logic_vector;
370 36 pela
    variable pltbv              : inout pltbv_t;
371
    signal   pltbs              : out   pltbs_t
372
  );
373 2 pela
  procedure check(
374
    constant rpt                : in    string;
375 24 pela
    constant actual             : in    unsigned;
376 2 pela
    constant expected           : in    unsigned;
377 36 pela
    variable pltbv              : inout pltbv_t;
378
    signal   pltbs              : out   pltbs_t
379 2 pela
  );
380
  procedure check(
381
    constant rpt                : in    string;
382 24 pela
    constant actual             : in    unsigned;
383 2 pela
    constant expected           : in    integer;
384 36 pela
    variable pltbv              : inout pltbv_t;
385
    signal   pltbs              : out   pltbs_t
386
  );
387 2 pela
  procedure check(
388
    constant rpt                : in    string;
389 24 pela
    constant actual             : in    signed;
390 2 pela
    constant expected           : in    signed;
391 36 pela
    variable pltbv              : inout pltbv_t;
392
    signal   pltbs              : out   pltbs_t
393 2 pela
  );
394
  procedure check(
395
    constant rpt                : in    string;
396 24 pela
    constant actual             : in    signed;
397 2 pela
    constant expected           : in    integer;
398 36 pela
    variable pltbv              : inout pltbv_t;
399
    signal   pltbs              : out   pltbs_t
400
  );
401 2 pela
  procedure check(
402
    constant rpt                : in    string;
403 99 pela
    constant actual             : in    boolean;
404
    constant expected           : in    boolean;
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    boolean;
411
    constant expected           : in    integer;
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
    variable pltbv              : inout pltbv_t;
420
    signal   pltbs              : out   pltbs_t
421
  );
422
  procedure check(
423
    constant rpt                : in    string;
424
    constant actual             : in    time;
425
    constant expected           : in    time;
426
    constant tolerance          : in    time;
427
    variable pltbv              : inout pltbv_t;
428
    signal   pltbs              : out   pltbs_t
429
  );
430
  procedure check(
431
    constant rpt                : in    string;
432 88 pela
    constant actual             : in    string;
433
    constant expected           : in    string;
434
    variable pltbv              : inout pltbv_t;
435
    signal   pltbs              : out   pltbs_t
436
  );
437
  procedure check(
438
    constant rpt                : in    string;
439 2 pela
    constant expr               : in    boolean;
440 36 pela
    variable pltbv              : inout pltbv_t;
441
    signal   pltbs              : out   pltbs_t
442 2 pela
  );
443 107 pela
  procedure check_binfile(
444
    constant rpt        : in    string;
445
    constant filename1  : in    string;
446
    constant filename2  : in    string;
447
    constant verbosity  : in    integer;
448
    variable pltbv      : inout pltbv_t;
449
    signal   pltbs      : out   pltbs_t
450
  );
451
  procedure check_txtfile(
452
    constant rpt        : in    string;
453
    constant filename1  : in    string;
454
    constant filename2  : in    string;
455
    constant verbosity  : in    integer;
456
    variable pltbv      : inout pltbv_t;
457
    signal   pltbs      : out   pltbs_t
458
  );
459
  procedure check_datfile(
460
    constant rpt        : in    string;
461
    constant filename1  : in    string;
462
    constant filename2  : in    string;
463
    constant verbosity  : in    integer;
464
    variable pltbv      : inout pltbv_t;
465
    signal   pltbs      : out   pltbs_t;
466
    constant skip_init_items : in integer := 0
467
  );
468
  procedure check(
469 24 pela
    constant rpt                : in    string;
470
    constant expr               : in    boolean;
471
    constant actual             : in    string;
472
    constant expected           : in    string;
473
    constant mask               : in    string;
474 36 pela
    variable pltbv              : inout pltbv_t;
475
    signal   pltbs              : out   pltbs_t
476 24 pela
  );
477 36 pela
 
478 14 pela
  -- to_ascending
479
  function to_ascending(
480
    constant s                  : std_logic_vector
481
  ) return std_logic_vector;
482
  function to_ascending(
483
    constant s                  : unsigned
484
  ) return unsigned;
485
  function to_ascending(
486
    constant s                  : signed
487
  ) return signed;
488 2 pela
 
489 14 pela
  -- to_descending
490
  function to_descending(
491
    constant s                  : std_logic_vector
492
  ) return std_logic_vector;
493
  function to_descending(
494
    constant s                  : unsigned
495
  ) return unsigned;
496
  function to_descending(
497
    constant s                  : signed
498
  ) return signed;
499 36 pela
 
500 14 pela
  -- hxstr
501
  function hxstr(
502
    constant s                  : std_logic_vector;
503 24 pela
    constant prefix             : string := "";
504
    constant postfix            : string := ""
505 14 pela
  ) return string;
506
  function hxstr(
507
    constant s                  : unsigned;
508 24 pela
    constant prefix             : string := "";
509
    constant postfix            : string := ""
510 14 pela
  ) return string;
511
  function hxstr(
512
    constant s                  : signed;
513 24 pela
    constant prefix             : string := "";
514
    constant postfix            : string := ""
515 14 pela
  ) return string;
516
 
517 107 pela
  -- str
518
  function str(
519
    constant n                  : integer;
520
    constant len                : integer;
521
    constant fillchar           : character := ' '
522
  ) return string;
523 24 pela
 
524 107 pela
  function str_equal (
525
    constant s1 : STRING;
526
    constant s2 : STRING
527
  ) return boolean;
528 36 pela
 
529 107 pela
end package pltbutils_func_pkg;
530
 
531
package body pltbutils_func_pkg is
532
 
533
  --==========================================================================
534
  -- pltbutils internal (private) procedures
535
  -- To be called from other pltbutils procedures.
536
  -- Do not to call these from user's code.
537
  -- These procedures are intentionally undocumented in the specification
538
  -- document.
539
  --==========================================================================
540
 
541
  procedure pltbs_update(
542 36 pela
    variable pltbv              : inout pltbv_t;
543
    signal   pltbs              : out   pltbs_t
544 107 pela
  ) is
545
  begin
546
    pltbs.test_num  <= pltbv.test_num;
547
    print(pltbs.test_name, pltbv.test_name);
548
    print(pltbs.info, pltbv.info);
549
    pltbs.chk_cnt   <= pltbv.chk_cnt;
550
    pltbs.err_cnt   <= pltbv.err_cnt;
551
    pltbs.stop_sim  <= pltbv.stop_sim;
552
  end procedure pltbs_update;
553 36 pela
 
554 107 pela
    procedure starttest_msg(
555 24 pela
    constant test_num           : in integer;
556
    constant test_name          : in string;
557
    constant timestamp          : in time
558 107 pela
  ) is
559
  begin
560
    print(lf & "Test " & str(test_num) & ": " & test_name & " (" & time'image(timestamp) & ")");
561
  end procedure starttest_msg;
562 36 pela
 
563 101 pela
  procedure skiptest_msg(
564
    constant test_num           : in integer;
565
    constant test_name          : in string;
566
    constant timestamp          : in time
567 107 pela
  ) is
568
  begin
569
    print(lf & "Skipping Test " & str(test_num) & ": " & test_name & " (" & time'image(timestamp) & ")");
570
  end procedure skiptest_msg;
571 101 pela
 
572 24 pela
  procedure endtest_msg(
573
    constant test_num           : in integer;
574
    constant test_name          : in string;
575
    constant timestamp          : in time;
576 101 pela
    constant test_active        : in boolean;
577 24 pela
    constant num_checks_in_test : in integer;
578
    constant num_errors_in_test : in integer
579 107 pela
  ) is
580
  begin
581
    if test_active then
582
      print("Done with test " & str(test_num) & ": " & test_name & " (" & time'image(timestamp) & ")");
583
    end if;
584
  end procedure endtest_msg;
585 36 pela
 
586 24 pela
  procedure check_msg(
587
    constant rpt                : in string;
588 36 pela
    constant timestamp          : in time;
589
    constant expr               : in boolean;
590 24 pela
    constant actual             : in string;
591
    constant expected           : in string;
592
    constant mask               : in string;
593 36 pela
    constant test_num           : in integer;
594 24 pela
    constant test_name          : in string;
595
    constant check_num          : in integer;
596
    constant err_cnt_in_test    : in integer
597 107 pela
  ) is
598
    variable actual_str_len     : integer := 1;
599
    variable actual_str         : string(1 to actual'length+8) := (others => ' ');
600
    variable expected_str       : string(1 to expected'length+10) := (others => ' ');
601
    variable expected_str_len   : integer := 1;
602
    variable mask_str           : string(1 to mask'length+6) := (others => ' ');
603
    variable mask_str_len       : integer := 1;
604
    constant C_ACTUAL_PREFIX    : string := " Actual=";
605
    constant C_ACTUAL_POSTFIX   : string := "";
606
    constant C_EXPECTED_PREFIX  : string := " Expected=";
607
    constant C_EXPECTED_POSTFIX : string := "";
608
    constant C_MASK_PREFIX      : string := " Mask=";
609
    constant C_MASK_POSTFIX     : string := "";
610
  begin
611
    if not expr then -- Output message only if the check fails
612
      if str_equal(mask, "!NO_TAGS!") then
613
         -- if mask=!NO_TAGS!, then do not add Actual= and Expected=" tags to strings
614
         actual_str_len := actual'length;
615
         actual_str(1 to actual_str_len) := actual;
616
         expected_str_len := expected'length;
617
         expected_str(1 to expected_str_len) := expected;
618
         mask_str_len := 1;
619
      else
620
        -- Add Actual= and Expected= tags to strings
621
        if actual /= "" then
622
          --actual_str_len := 8 + actual'length;
623
          --actual_str := " Actual=" & actual;
624
            actual_str_len := C_ACTUAL_PREFIX'length + actual'length + C_ACTUAL_POSTFIX'length;
625
            actual_str(1 to actual_str_len) := C_ACTUAL_PREFIX & tcfilter(actual) & C_ACTUAL_POSTFIX;
626
        end if;
627
        if expected /= "" then
628
          --expected_str_len := 10 + expected'length;
629
          --expected_str := " Expected=" & expected;
630
          expected_str_len := C_EXPECTED_PREFIX'length + expected'length + C_EXPECTED_POSTFIX'length;
631
          expected_str(1 to expected_str_len) := C_EXPECTED_PREFIX & tcfilter(expected) & C_EXPECTED_POSTFIX;
632
        end if;
633
        if mask /= "" then
634
          --mask_str_len := 6 + mask'length;
635
          --mask_str := " Mask=" & mask;
636
          mask_str_len := C_MASK_PREFIX'length + mask'length + C_MASK_POSTFIX'length;
637
          mask_str(1 to mask_str_len) := C_MASK_PREFIX & tcfilter(mask) & C_MASK_POSTFIX;
638
        end if;
639
      end if;
640
      assert false
641
        report "Check " & str(check_num) & "; " & rpt & "; " &
642
               actual_str(1 to actual_str_len) &
643
               expected_str(1 to expected_str_len) &
644
               mask_str(1 to mask_str_len) &
645
               "  in test " & str(test_num) & " " & test_name
646
        severity error;
647
    end if;
648
  end procedure check_msg;
649 24 pela
 
650
  procedure error_msg(
651
    constant rpt                : in string;
652
    constant timestamp          : in time;
653 36 pela
    constant test_num           : in integer;
654 24 pela
    constant test_name          : in string;
655
    constant err_cnt_in_test    : in integer
656 107 pela
  ) is
657
  begin
658
    assert false
659
    report rpt & " in test " & str(test_num) & ": " & test_name
660
    severity error;
661
  end procedure error_msg;
662 36 pela
 
663 107 pela
  procedure pltbutils_error(
664
    constant rpt                : in string;
665
    variable pltbv              : inout pltbv_t;
666
    signal   pltbs              : out   pltbs_t
667
  ) is
668
  begin
669
    pltbv.err_cnt := pltbv.err_cnt + 1;
670
    pltbv.err_cnt_in_test := pltbv.err_cnt_in_test + 1;
671
    pltbs_update(pltbv, pltbs);
672
    if C_PLTBUTILS_USE_STD_ERROR_MSG then
673
      error_msg(rpt, now, pltbv.test_num,
674
        pltbv.test_name(1 to pltbv.test_name_len), pltbv.err_cnt_in_test);
675
    end if;
676
    if C_PLTBUTILS_USE_CUSTOM_ERROR_MSG then
677
      custom_error_msg(rpt, now, pltbv.test_num,
678
        pltbv.test_name(1 to pltbv.test_name_len), pltbv.err_cnt_in_test);
679
    end if;
680
  end procedure pltbutils_error;
681 2 pela
 
682 107 pela
  procedure stopsim(
683
    constant timestamp          : in time
684
  ) is
685
  begin
686
    assert false
687
    report "--- FORCE END OF SIMULATION ---" &
688
           " (ignore this false failure message, it's not a real failure)"
689
    severity failure;
690
  end procedure stopsim;
691 2 pela
 
692 107 pela
  procedure startsim_msg(
693
    constant testcase_name      : in string;
694
    constant timestamp          : in time
695
  ) is
696
  begin
697
    print(lf & "--- START OF SIMULATION ---");
698
    print("Testcase: " & testcase_name);
699
    print(time'image(timestamp));
700
  end procedure startsim_msg;
701
 
702
  procedure endsim_msg(
703
    constant testcase_name      : in string;
704
    constant timestamp          : in time;
705
    constant num_tests          : in integer;
706
    constant num_skiptests      : in integer;
707
    constant num_checks         : in integer;
708
    constant num_errors         : in integer;
709
    constant show_success_fail  : in boolean
710
  ) is
711
    variable l : line;
712
  begin
713
    print(lf & "--- END OF SIMULATION ---");
714
    print("Note: the results presented below are based on the PlTbUtil's check() procedure calls.");
715
    print("      The design may contain more errors, for which there are no check() calls.");
716
    write(l, timestamp, right, 14);
717
    writeline(output, l);
718
    write(l, num_tests, right, 11);
719
    write(l, string'(" Tests"));
720
    writeline(output, l);
721
    write(l, num_skiptests, right, 11);
722
    write(l, string'(" Skipped tests"));
723
    writeline(output, l);
724
    write(l, num_checks, right, 11);
725
    write(l, string'(" Checks"));
726
    writeline(output, l);
727
    write(l, num_errors, right, 11);
728
    write(l, string'(" Errors"));
729
    writeline(output, l);
730
    if show_success_fail then
731
      if num_errors = 0 and num_checks > 0 then
732
        print("*** SUCCESS ***");
733
      elsif num_checks > 0 then
734
        print("*** FAIL ***");
735
      else
736
        print("*** NO CHECKS ***");
737
      end if;
738
    end if;
739
  end procedure endsim_msg;
740
 
741
 
742
 
743
  -- Get next item (word) in a file
744
  procedure get_file_item(
745
    file     f          :       text;
746
    variable l          : inout line;
747
    variable item       : out   string;
748
    variable item_len   : out   integer;
749
    variable line_num   : inout integer;
750
    variable item_num   : inout integer
751
  ) is
752
    variable c          : character := ' ';
753
    variable c_good     : boolean := true;
754
    variable i          : integer := 0;
755
  begin
756
    item := (item'low to item'high => ' ');
757
    item_len := 0;
758
    while i = 0 loop
759
      -- Get next line, unless we're already processing a line
760
      if l = null then
761
        exit when endfile(f);
762
        readline(f, l);
763
        line_num := line_num + 1;
764
      elsif l'length = 0 then
765
        exit when endfile(f);
766
        readline(f, l);
767
        line_num := line_num + 1;
768
      end if;
769
 
770
      -- Find next item on the line
771
      read(l, c, c_good);
772
      -- Skip leading whitespace characters
773
      while c_good and (c = ' ' or c = ht) loop
774
        read(l, c, c_good);
775
      end loop;
776
      -- Read item until next whitespace, comment character or end-of-line
777
      while c_good and c /= ' ' and c /= ht and c /= '#' loop
778
        -- If i >= item'length, an error will occur. We don't try to do anything
779
        -- about that here, because it is probably better that the user 
780
        -- find out the hard way, instead of trying to hide the problem.
781
        item(item'low + i) := c;
782
        i := i + 1;
783
        read(l, c, c_good);
784
      end loop;
785
 
786
      -- If a comment character was found, absorb the rest of the comment
787
      if c_good and c = '#' then
788
        while l'length > 0 loop
789
          read(l, c, c_good);
790
        end loop;
791
      end if;
792
      -- Update output values if item was found
793
      if i > 0 then
794
        item_len := i;
795
        item_num := item_num + 1;
796
      end if;
797
    end loop;
798
  end procedure get_file_item;
799
 
800
 
801
 
802
  --==========================================================================
803
  -- pltbutils external (public) procedures
804
  -- To be called from the user's code.
805
  --==========================================================================
806
 
807 2 pela
  ----------------------------------------------------------------------------
808
  -- startsim
809
  --
810
  -- procedure startsim(
811
  --   constant testcase_name      : in    string;
812 101 pela
  --   constant skiptests          : in    std_logic_vector;
813 36 pela
  --   variable pltbv              : inout pltbv_t;
814
  --   signal   pltbs              : out   pltbs_t
815 2 pela
  -- )
816
  --
817
  -- Displays a message at start of simulation message, and initializes
818 36 pela
  -- PlTbUtils' status and control variable and -signal.
819 2 pela
  -- Call startsim() only once.
820
  --
821
  -- Arguments:
822
  --   testcase_name            Name of the test case, e.g. "tc1".
823
  --
824 101 pela
  --   skiptests                std_logic_vector for marking tests that should
825
  --                            be skipped. The leftmost bit has position 0,
826
  --                            and position numbers increment to the right.
827
  --                            A '1' indicates that the test with the same
828
  --                            number as the position should be skipped.
829
  --                            Note that there is usually no test which has
830
  --                            number 0, so bit zero in the vector is usually
831
  --                            ignored.
832
  --                            This argument is normally fed by a generic.
833
  --                            If no tests should be skipped, a zero-length 
834
  --                            vector is allowed, ("").
835
  --                          
836 36 pela
  --   pltbv, pltbs             PlTbUtils' status- and control variable and
837
  --                            -signal.
838 2 pela
  --
839
  -- NOTE:
840
  -- The start-of-simulation message is not only intended to be informative
841
  -- for humans. It is also intended to be searched for by scripts,
842
  -- e.g. for collecting results from a large number of regression tests.
843
  -- For this reason, the message must be consistent and unique.
844
  --
845
  -- DO NOT MODIFY the message "--- START OF SIMULATION ---".
846
  -- DO NOT OUTPUT AN IDENTICAL MESSAGE anywhere else.
847
  --
848 101 pela
  -- Examples:
849
  -- startsim("tc1", "", pltbv, pltbs);
850
  -- startsim("tc2", G_SKIPTESTS, pltbv, pltbs); -- G_SKIPTESTS is a generic
851 2 pela
  ----------------------------------------------------------------------------
852
  procedure startsim(
853
    constant testcase_name      : in    string;
854 101 pela
    constant skiptests          : in    std_logic_vector;
855 36 pela
    variable pltbv              : inout pltbv_t;
856
    signal   pltbs              : out   pltbs_t
857 2 pela
  ) is
858 36 pela
    variable timestamp          : time;
859 101 pela
    variable v_ignored_skiptest : boolean := false;
860 2 pela
  begin
861 24 pela
    timestamp := now;
862 36 pela
    pltbv := C_PLTBV_INIT;
863
    printv(pltbv.testcase_name, testcase_name);
864
    pltbv.testcase_name_len := testcase_name'length;
865
    printv(pltbv.test_name, "START OF SIMULATION");
866
    pltbv.test_name_len     := 19;
867
    printv(pltbv.info, testcase_name);
868 101 pela
    if skiptests'length > 0 then
869
      for i in skiptests'low to skiptests'high loop
870
        if i >= pltbv.skiptests'low and i <= pltbv.skiptests'high then
871
          pltbv.skiptests(i) := skiptests(i);
872
        else
873
          if pltbv.skiptests(i) = '1' then
874
            v_ignored_skiptest := true;
875
          end if;
876
        end if;
877
      end loop;
878
      if v_ignored_skiptest then
879
        assert false
880
          report "Some SKIPTESTS flags ignored. Max " &
881
                 integer'image(pltbv.skiptests'length) & " flag bits supported."
882
          severity warning;
883
      end if;
884
    end if;
885 36 pela
    pltbv.info_len          := testcase_name'length;
886
    pltbs_update(pltbv, pltbs);
887 24 pela
    if C_PLTBUTILS_USE_STD_STARTSIM_MSG then
888
      startsim_msg(testcase_name, timestamp);
889
    end if;
890
    if C_PLTBUTILS_USE_CUSTOM_STARTSIM_MSG then
891
      custom_startsim_msg(testcase_name, timestamp);
892
    end if;
893 2 pela
  end procedure startsim;
894
 
895
  ----------------------------------------------------------------------------
896
  -- endsim
897
  --
898
  -- procedure endsim(
899 36 pela
  --   variable pltbv              : inout pltbv_t;
900
  --   signal   pltbs              : out   pltbs_t;
901 2 pela
  --   constant show_success_fail  : in  boolean := false;
902 97 pela
  --   constant force_stop         : in  boolean := false
903 2 pela
  -- )
904
  --
905
  -- Displays a message at end of simulation message, presents the simulation
906 36 pela
  -- results, and stops the simulation.
907 2 pela
  -- Call endsim() it only once.
908
  --
909 36 pela
  -- Arguments:
910
  --   pltbv, pltbs             PlTbUtils' status- and control variable and
911
  --                            -signal.
912 2 pela
  --
913 36 pela
  --   show_success_fail        If true, endsim() shows "*** SUCCESS ***",
914 2 pela
  --                            "*** FAIL ***", or "*** NO CHECKS ***".
915
  --                            Optional, default is false.
916
  --
917 97 pela
  --   force_stop               If true, forces the simulation to stop using an
918 2 pela
  --                            assert failure statement. Use this option only
919
  --                            if the normal way of stopping the simulation
920
  --                            doesn't work (see below).
921
  --                            Optional, default is false.
922
  --
923
  -- The testbench should be designed so that all clocks stop when endsim()
924 36 pela
  -- sets the signal pltbs.stop_sim to '1'. This should stop the simulator.
925 97 pela
  -- In some cases that doesn't work, then set the force_stop argument to true,
926
  -- which causes a false assert failure, which should stop the simulator.
927 2 pela
  -- Scripts searching transcript logs for errors and failures, should ignore
928
  -- the failure with "--- FORCE END OF SIMULATION ---" as part of the report.
929
  --
930
  -- NOTE:
931
  -- The end-of-simulation messages and success/fail messages are not only
932
  -- intended to be informative for humans. They are also intended to be
933
  -- searched for by scripts, e.g. for collecting results from a large number
934
  -- of regression tests.
935
  -- For this reason, the message must be consistent and unique.
936
  --
937 36 pela
  -- DO NOT MODIFY the messages "--- END OF SIMULATION ---",
938 2 pela
  -- "*** SUCCESS ***", "*** FAIL ***", "*** NO CHECKS ***".
939
  -- DO NOT OUTPUT IDENTICAL MESSAGES anywhere else.
940
  --
941
  -- Examples:
942 36 pela
  -- endsim(pltbv, pltbs);
943
  -- endsim(pltbv, pltbs, true);
944
  -- endsim(pltbv, pltbs, true, true);
945 2 pela
  ----------------------------------------------------------------------------
946
  procedure endsim(
947 36 pela
    variable pltbv              : inout pltbv_t;
948
    signal   pltbs              : out   pltbs_t;
949
    constant show_success_fail  : in    boolean := false;
950 97 pela
    constant force_stop         : in    boolean := false
951 2 pela
  ) is
952 24 pela
    variable timestamp : time;
953 2 pela
  begin
954 24 pela
    timestamp := now;
955
    if C_PLTBUTILS_USE_STD_ENDSIM_MSG then
956 36 pela
      endsim_msg(pltbv.testcase_name(1 to pltbv.testcase_name_len), timestamp,
957 101 pela
        pltbv.test_cnt, pltbv.skiptest_cnt, pltbv.chk_cnt, pltbv.err_cnt,
958
        show_success_fail);
959 24 pela
    end if;
960
    if C_PLTBUTILS_USE_CUSTOM_ENDSIM_MSG then
961 36 pela
      custom_endsim_msg(pltbv.testcase_name(1 to pltbv.testcase_name_len), timestamp,
962 101 pela
        pltbv.test_cnt, pltbv.skiptest_cnt, pltbv.chk_cnt, pltbv.err_cnt,
963
        show_success_fail);
964 24 pela
    end if;
965 36 pela
    pltbv.test_num      := 0;
966
    printv(pltbv.test_name, "END OF SIMULATION");
967
    pltbv.test_name_len := 17;
968
    pltbv.stop_sim      := '1';
969
    pltbs_update(pltbv, pltbs);
970 2 pela
    wait for C_WAIT_BEFORE_STOP_TIME;
971 97 pela
    if force_stop then
972 24 pela
      if C_PLTBUTILS_USE_STD_STOPSIM then
973
        stopsim(now);
974
      end if;
975
      if C_PLTBUTILS_USE_CUSTOM_STOPSIM then
976
        custom_stopsim(now);
977
      end if;
978
    end if;
979 2 pela
    wait;
980
  end procedure endsim;
981
 
982
  ----------------------------------------------------------------------------
983 24 pela
  -- starttest
984 2 pela
  --
985 24 pela
  -- procedure starttest(
986 2 pela
  --   constant num                : in    integer := -1;
987
  --   constant name               : in    string;
988 36 pela
  --   variable pltbv              : inout pltbv_t;
989
  --   signal   pltbs              : out   pltbs_t
990
  -- )
991 2 pela
  --
992
  -- Sets a number (optional) and a name for a test. The number and name will
993
  -- be printed to the screen, and displayed in the simulator's waveform
994 36 pela
  -- window.
995 2 pela
  -- The test number and name is also included if there errors reported by the
996
  -- check() procedure calls.
997
  --
998 36 pela
  -- Arguments:
999 2 pela
  --   num                      Test number. Optional, default is to increment
1000
  --                            the current test number.
1001
  --
1002
  --   name                     Test name.
1003
  --
1004 36 pela
  --   pltbv, pltbs             PlTbUtils' status- and control variable and
1005
  --                            -signal.
1006 2 pela
  --
1007
  -- If the test number is omitted, a new test number is automatically
1008 36 pela
  -- computed by incrementing the current test number.
1009 2 pela
  -- Manually setting the test number may make it easier to find the test code
1010
  -- in the testbench code, though.
1011
  --
1012
  -- Examples:
1013 36 pela
  -- starttest("Reset test", pltbv, pltbs);
1014
  -- starttest(1, "Reset test", pltbv, pltbs);
1015 2 pela
  ----------------------------------------------------------------------------
1016 24 pela
  procedure starttest(
1017 2 pela
    constant num                : in    integer := -1;
1018
    constant name               : in    string;
1019 36 pela
    variable pltbv              : inout pltbv_t;
1020
    signal   pltbs              : out   pltbs_t
1021 2 pela
  ) is
1022 24 pela
    variable timestamp : time;
1023 2 pela
  begin
1024 24 pela
    timestamp := now;
1025 2 pela
    if num = -1 then
1026 36 pela
      pltbv.test_num := pltbv.test_num + 1;
1027 2 pela
    else
1028 36 pela
      pltbv.test_num := num;
1029 2 pela
    end if;
1030 36 pela
    printv(pltbv.test_name, name);
1031
    pltbv.test_name_len := name'length;
1032
    pltbv.chk_cnt_in_test := 0;
1033
    pltbv.err_cnt_in_test := 0;
1034 101 pela
    pltbv.test_active := true;
1035 105 pela
    if pltbv.test_num >= pltbv.skiptests'low and pltbv.test_num <= pltbv.skiptests'high then
1036
      if pltbv.skiptests(pltbv.test_num) = '1' then
1037 101 pela
        pltbv.test_active := false;
1038
      end if;
1039 24 pela
    end if;
1040 101 pela
    if pltbv.test_active then
1041
      pltbv.test_cnt := pltbv.test_cnt + 1;
1042
      pltbs_update(pltbv, pltbs);
1043
      if C_PLTBUTILS_USE_STD_STARTTEST_MSG then
1044
        starttest_msg(pltbv.test_num, name, timestamp);
1045
      end if;
1046
      if C_PLTBUTILS_USE_CUSTOM_STARTTEST_MSG then
1047
        custom_starttest_msg(pltbv.test_num, name, timestamp);
1048
      end if;
1049
    else
1050
      pltbv.skiptest_cnt := pltbv.skiptest_cnt + 1;
1051
      pltbs_update(pltbv, pltbs);
1052
      if C_PLTBUTILS_USE_STD_SKIPTEST_MSG then
1053
        skiptest_msg(pltbv.test_num, name, timestamp);
1054
      end if;
1055
      if C_PLTBUTILS_USE_CUSTOM_SKIPTEST_MSG then
1056
        custom_skiptest_msg(pltbv.test_num, name, timestamp);
1057
      end if;
1058 24 pela
    end if;
1059
  end procedure starttest;
1060 36 pela
 
1061 24 pela
  procedure starttest(
1062
    constant name               : in    string;
1063 36 pela
    variable pltbv              : inout pltbv_t;
1064
    signal   pltbs              : out   pltbs_t
1065 24 pela
  ) is
1066
  begin
1067 36 pela
    starttest(-1, name, pltbv, pltbs);
1068 24 pela
  end procedure starttest;
1069 36 pela
 
1070 2 pela
  ----------------------------------------------------------------------------
1071 101 pela
  -- is_test_active
1072
  --
1073
  -- function is_test_active(
1074
  --   constant pltbv              : in    pltbv_t
1075
  -- ) return boolean
1076
  --
1077
  -- Returns true if a test is active (not skipped), otherwise false.
1078
  --
1079
  -- Arguments:
1080
  --   pltbv                     PlTbUtils' status- and control variable.
1081
  --
1082
  -- Example:
1083
  -- starttest(3, "Example test", pltbv, pltbs);
1084
  -- if is_test_active(pltbv) then
1085
  --   ... test code ...
1086
  -- end if;
1087
  -- endtest(pltbv, pltbs);
1088
  ----------------------------------------------------------------------------
1089
  function is_test_active(
1090
    constant pltbv              : in    pltbv_t
1091
  ) return boolean is
1092
  begin
1093
    return pltbv.test_active;
1094
  end function is_test_active;
1095
 
1096
  ----------------------------------------------------------------------------
1097 24 pela
  -- endtest
1098
  --
1099
  -- procedure endtest(
1100 36 pela
  --   variable pltbv              : inout pltbv_t;
1101
  --   signal   pltbs              : out   pltbs_t
1102
  -- )
1103 24 pela
  --
1104
  -- Prints an end-of-test message to the screen.
1105
  --
1106 36 pela
  -- Arguments:
1107
  --   pltbv, pltbs             PlTbUtils' status- and control variable and
1108
  --                            -signal.
1109 24 pela
  --
1110
  -- Example:
1111 36 pela
  -- endtest(pltbv, pltbs);
1112 24 pela
  ----------------------------------------------------------------------------
1113
  procedure endtest(
1114 36 pela
    variable pltbv              : inout pltbv_t;
1115
    signal   pltbs              : out   pltbs_t
1116 24 pela
  ) is
1117
    variable timestamp : time;
1118
  begin
1119
    timestamp := now;
1120
    if C_PLTBUTILS_USE_STD_ENDTEST_MSG then
1121 36 pela
      endtest_msg(pltbv.test_num, pltbv.test_name(1 to pltbv.test_name_len),
1122 101 pela
        timestamp, pltbv.test_active, pltbv.chk_cnt_in_test, pltbv.err_cnt_in_test);
1123 36 pela
    end if;
1124 24 pela
    if C_PLTBUTILS_USE_CUSTOM_ENDTEST_MSG then
1125 36 pela
      custom_endtest_msg(pltbv.test_num, pltbv.test_name(1 to pltbv.test_name_len),
1126 101 pela
        timestamp, pltbv.test_active, pltbv.chk_cnt_in_test, pltbv.err_cnt_in_test);
1127 36 pela
    end if;
1128 101 pela
    pltbv.test_active := true;
1129 36 pela
    printv(pltbv.test_name, " ");
1130
    pltbv.test_name_len := 1;
1131
    pltbs_update(pltbv, pltbs);
1132
  end procedure endtest;
1133 24 pela
 
1134
  ----------------------------------------------------------------------------
1135 2 pela
  -- print printv print2
1136
  --
1137 36 pela
  -- procedure print(
1138 2 pela
  --   signal   s                  : out   string;
1139
  --   constant txt                : in    string
1140 36 pela
  -- )
1141 2 pela
  --
1142 36 pela
  -- procedure print(
1143 6 pela
  --   constant active             : in    boolean;
1144
  --   signal   s                  : out   string;
1145
  --   constant txt                : in    string
1146 36 pela
  -- )
1147 6 pela
  --
1148 2 pela
  -- procedure print(
1149 36 pela
  --   variable pltbv              : inout pltbv_t;
1150
  --   signal   pltbs              : out   pltbs_t;
1151 2 pela
  --   constant txt                : in    string
1152
  -- )
1153
  --
1154 6 pela
  -- procedure print(
1155
  --   constant active             : in    boolean;
1156 36 pela
  --   variable pltbv              : inout pltbv_t;
1157
  --   signal   pltbs              : out   pltbs_t;
1158 6 pela
  --   constant txt                : in    string
1159
  -- )
1160
  --
1161 2 pela
  -- procedure printv(
1162
  --   variable s                  : out   string;
1163
  --   constant txt                : in    string
1164
  -- )
1165
  --
1166 6 pela
  -- procedure printv(
1167
  --   constant active             : in    boolean;
1168
  --   variable s                  : out   string;
1169
  --   constant txt                : in    string
1170
  -- )
1171
  --
1172 36 pela
  -- procedure print2(
1173 2 pela
  --   signal   s                  : out   string;
1174
  --   constant txt                : in    string
1175
  -- )
1176
  --
1177 36 pela
  -- procedure print2(
1178 6 pela
  --   constant active             : in    boolean;
1179
  --   signal   s                  : out   string;
1180
  --   constant txt                : in    string
1181
  -- )
1182
  --
1183 36 pela
  -- procedure print2(
1184
  --   variable pltbv              : inout pltbv_t;
1185
  --   signal   pltbs              : out   pltbs_t;
1186 2 pela
  --   constant txt                : in    string
1187
  -- )
1188
  --
1189 36 pela
  -- procedure print2(
1190 6 pela
  --   constant active             : in    boolean;
1191 36 pela
  --   variable pltbv              : inout pltbv_t;
1192
  --   signal   pltbs              : out   pltbs_t;
1193 6 pela
  --   constant txt                : in    string
1194
  -- )
1195
  --
1196 2 pela
  -- print() prints text messages to a signal for viewing in the simulator's
1197
  -- waveform window. printv() does the same thing, but to a variable instead.
1198 36 pela
  -- print2() prints both to a signal and to the transcript window.
1199
  -- The type of the output can be string or pltbv_t+pltbs_t.
1200 2 pela
  --
1201 36 pela
  -- Arguments:
1202
  --   s                        Signal or variable of type string to be
1203 2 pela
  --                            printed to.
1204
  --
1205
  --   txt                      The text.
1206
  --
1207 6 pela
  --   active                   The text is only printed if active is true.
1208
  --                            Useful for debug switches, etc.
1209
  --
1210 36 pela
  --   pltbv, pltbs             PlTbUtils' status- and control variable and
1211
  --                            -signal.
1212 2 pela
  --
1213 36 pela
  -- If the string txt is longer than the signal s, the text will be truncated.
1214
  -- If txt is shorter, s will be padded with spaces.
1215 2 pela
  --
1216
  -- Examples:
1217
  -- print(msg, "Hello, world"); -- Prints to signal msg
1218 36 pela
  -- print(G_DEBUG, msg, "Hello, world"); -- Prints to signal msg if
1219 6 pela
  --                                      -- generic G_DEBUG is true
1220 2 pela
  -- printv(v_msg, "Hello, world"); -- Prints to variable msg
1221 36 pela
  -- print(pltbv, pltbs, "Hello, world"); -- Prints to "info" in waveform window
1222
  -- print2(msg, "Hello, world"); -- Prints to signal and transcript window
1223
  -- print2(pltbv, pltbs, "Hello, world"); -- Prints to "info" in waveform and
1224 2 pela
  --                                      -- transcript windows
1225
  ----------------------------------------------------------------------------
1226
  procedure print(
1227 6 pela
    constant active             : in    boolean;
1228 2 pela
    signal   s                  : out   string;
1229
    constant txt                : in    string
1230
  ) is
1231
    variable j : positive := txt 'low;
1232
  begin
1233 6 pela
    if active then
1234
      for i in s'range loop
1235
        if j <= txt 'high then
1236
          s(i) <= txt (j);
1237
        else
1238
          s(i) <= ' ';
1239
        end if;
1240
        j := j + 1;
1241
      end loop;
1242
    end if;
1243 2 pela
  end procedure print;
1244 36 pela
 
1245 6 pela
  procedure print(
1246
    signal   s                  : out   string;
1247
    constant txt                : in    string
1248
  ) is
1249
  begin
1250
    print(true, s, txt);
1251
  end procedure print;
1252 36 pela
 
1253 2 pela
  procedure printv(
1254 6 pela
    constant active             : in    boolean;
1255 2 pela
    variable s                  : out   string;
1256
    constant txt                : in    string
1257
  ) is
1258
    variable j : positive := txt 'low;
1259
  begin
1260 6 pela
    if active then
1261
      for i in s'range loop
1262
        if j <= txt 'high then
1263
          s(i) := txt (j);
1264
        else
1265
          s(i) := ' ';
1266
        end if;
1267
        j := j + 1;
1268
      end loop;
1269
    end if;
1270 2 pela
  end procedure printv;
1271 36 pela
 
1272 6 pela
  procedure printv(
1273
    variable s                  : out   string;
1274
    constant txt                : in    string
1275
  ) is
1276
  begin
1277
    printv(true, s, txt);
1278 2 pela
  end procedure printv;
1279
 
1280 36 pela
  -- Print to info element in pltbv/pltbs, which shows up in waveform window
1281 2 pela
  procedure print(
1282 6 pela
    constant active             : in    boolean;
1283 36 pela
    variable pltbv              : inout pltbv_t;
1284
    signal   pltbs              : out   pltbs_t;
1285 2 pela
    constant txt                : in    string
1286
  ) is
1287
    variable j : positive := txt 'low;
1288
  begin
1289 6 pela
    if active then
1290 36 pela
      printv(pltbv.info, txt);
1291
      pltbv.info_len := txt'length;
1292
      pltbs_update(pltbv, pltbs);
1293 6 pela
    end if;
1294 2 pela
  end procedure print;
1295 6 pela
 
1296
  procedure print(
1297 36 pela
    variable pltbv              : inout pltbv_t;
1298
    signal   pltbs              : out   pltbs_t;
1299 6 pela
    constant txt                : in    string
1300
  ) is
1301
  begin
1302 36 pela
    print(true, pltbv, pltbs, txt);
1303
  end procedure print;
1304
 
1305 2 pela
  procedure print2(
1306 6 pela
    constant active             : in    boolean;
1307 2 pela
    signal   s                  : out   string;
1308
    constant txt                : in    string
1309
  ) is
1310
  begin
1311 36 pela
    if active then
1312
      print(s, txt);
1313 6 pela
      print(txt);
1314
    end if;
1315 2 pela
  end procedure print2;
1316
 
1317
  procedure print2(
1318 6 pela
    signal   s                  : out   string;
1319
    constant txt                : in    string
1320
  ) is
1321
  begin
1322 97 pela
    print2(true, s, txt);
1323 36 pela
  end procedure print2;
1324
 
1325 6 pela
  procedure print2(
1326
    constant active             : in    boolean;
1327 36 pela
    variable pltbv              : inout pltbv_t;
1328
    signal   pltbs              : out   pltbs_t;
1329 2 pela
    constant txt                : in    string
1330
  ) is
1331
  begin
1332 36 pela
    print(active, pltbv, pltbs, txt);
1333
    print(active, txt);
1334 2 pela
  end procedure print2;
1335
 
1336 6 pela
  procedure print2(
1337 36 pela
    variable pltbv              : inout pltbv_t;
1338
    signal   pltbs              : out   pltbs_t;
1339 6 pela
    constant txt                : in    string
1340
  ) is
1341
  begin
1342 97 pela
    print2(true, pltbv, pltbs, txt);
1343 36 pela
  end procedure print2;
1344 6 pela
 
1345 2 pela
  ----------------------------------------------------------------------------
1346
  -- waitclks
1347
  --
1348
  -- procedure waitclks(
1349
  --   constant n                  : in    natural;
1350
  --   signal   clk                : in    std_logic;
1351 36 pela
  --   variable pltbv              : inout pltbv_t;
1352
  --   signal   pltbs              : out   pltbs_t;
1353 2 pela
  --   constant falling            : in    boolean := false;
1354
  --   constant timeout            : in    time    := C_PLTBUTILS_TIMEOUT
1355
  -- )
1356
  --
1357
  -- Waits specified amount of clock cycles of the specified clock.
1358
  -- Or, to be more precise, a specified number of specified clock edges of
1359
  -- the specified clock.
1360
  --
1361 36 pela
  -- Arguments:
1362 2 pela
  --   n                        Number of rising or falling clock edges to wait.
1363
  --
1364
  --   clk                      The clock to wait for.
1365
  --
1366 36 pela
  --   pltbv, pltbs             PlTbUtils' status- and control variable and
1367
  --                            -signal.
1368 2 pela
  --
1369
  --   falling                  If true, waits for falling edges, otherwise
1370
  --                            rising edges. Optional, default is false.
1371
  --
1372
  --   timeout                  Timeout time, in case the clock is not working.
1373 36 pela
  --                            Optional, default is C_PLTBUTILS_TIMEOUT.
1374 2 pela
  --
1375
  -- Examples:
1376 36 pela
  -- waitclks(5, sys_clk, pltbv, pltbs);
1377
  -- waitclks(5, sys_clk, pltbv, pltbs true);
1378
  -- waitclks(5, sys_clk, pltbv, pltbs, true, 1 ms);
1379 2 pela
  ----------------------------------------------------------------------------
1380
  procedure waitclks(
1381
    constant n                  : in    natural;
1382
    signal   clk                : in    std_logic;
1383 36 pela
    variable pltbv              : inout pltbv_t;
1384
    signal   pltbs              : out   pltbs_t;
1385 2 pela
    constant falling            : in    boolean := false;
1386
    constant timeout            : in    time    := C_PLTBUTILS_TIMEOUT
1387
  ) is
1388
    variable i                  : natural := n;
1389
    variable v_timeout_time     : time;
1390
  begin
1391
    v_timeout_time := now + timeout;
1392
    while i > 0 loop
1393 6 pela
      if falling then
1394 2 pela
        wait until falling_edge(clk) for timeout / n;
1395
      else
1396
        wait until rising_edge(clk)  for timeout / n;
1397
      end if;
1398
      i := i - 1;
1399
    end loop;
1400
    if now >= v_timeout_time then
1401 36 pela
      pltbutils_error("waitclks() timeout", pltbv, pltbs);
1402 2 pela
    end if;
1403
  end procedure waitclks;
1404 36 pela
 
1405 6 pela
  ----------------------------------------------------------------------------
1406
  -- waitsig
1407
  --
1408
  -- procedure waitsig(
1409
  --   signal   s                  : in    integer|std_logic|std_logic_vector|unsigned|signed;
1410
  --   constant value              : in    integer|std_logic|std_logic_vector|unsigned|signed;
1411
  --   signal   clk                : in    std_logic;
1412 36 pela
  --   variable pltbv              : inout pltbv_t;
1413
  --   signal   pltbs              : out   pltbs_t;
1414 6 pela
  --   constant falling            : in    boolean := false;
1415
  --   constant timeout            : in    time    := C_PLTBUTILS_TIMEOUT
1416
  -- )
1417
  --
1418 107 pela
  -- Waits until a signal has reached a specified value. In clocked variants of
1419
  -- waitsig, the signal is checked after specified clock edge (rising or falling).
1420
  -- Unclocked variants are currently only available for types std_logic and std_logic_vector.
1421 6 pela
  --
1422 36 pela
  -- Arguments:
1423 6 pela
  --   s                        The signal to test.
1424 36 pela
  --                            Supported types: integer, std_logic,
1425 6 pela
  --                            std_logic_vector, unsigned, signed.
1426
  --
1427
  --   value                    Value to wait for.
1428
  --                            Same type as data or integer.
1429
  --
1430 107 pela
  --   clk                      The clock, only present in clocked variants of
1431
  --                            waitsig.
1432 6 pela
  --
1433 36 pela
  --   pltbv, pltbs             PlTbUtils' status- and control variable and
1434
  --                            -signal.
1435 6 pela
  --
1436
  --   falling                  If true, waits for falling edges, otherwise
1437
  --                            rising edges. Optional, default is false.
1438
  --
1439
  --   timeout                  Timeout time, in case the clock is not working.
1440 36 pela
  --                            Optional, default is C_PLTBUTILS_TIMEOUT.
1441 6 pela
  --
1442
  -- Examples:
1443 36 pela
  -- waitsig(wr_en, '1', sys_clk, pltbv, pltbs);
1444
  -- waitsig(rd_en,   1, sys_clk, pltbv, pltbs, true);
1445
  -- waitclks(full, '1', sys_clk, pltbv, pltbs, true, 1 ms);
1446
  ----------------------------------------------------------------------------
1447 97 pela
  -- waitsig integer, clocked
1448 6 pela
  procedure waitsig(
1449
    signal   s                  : in    integer;
1450
    constant value              : in    integer;
1451
    signal   clk                : in    std_logic;
1452 36 pela
    variable pltbv              : inout pltbv_t;
1453
    signal   pltbs              : out   pltbs_t;
1454 6 pela
    constant falling            : in    boolean := false;
1455
    constant timeout            : in    time    := C_PLTBUTILS_TIMEOUT
1456
  ) is
1457
    variable v_timeout_time     : time;
1458
  begin
1459
    v_timeout_time := now + timeout;
1460
    l1 : loop
1461 36 pela
      waitclks(1, clk, pltbv, pltbs, falling, timeout);
1462 6 pela
      exit l1 when s = value or now >= v_timeout_time;
1463
    end loop;
1464
    if now >= v_timeout_time then
1465 36 pela
      pltbutils_error("waitsig() timeout", pltbv, pltbs);
1466 6 pela
    end if;
1467
  end procedure waitsig;
1468
 
1469 97 pela
  -- waitsig std_logic, clocked
1470 6 pela
  procedure waitsig(
1471
    signal   s                  : in    std_logic;
1472
    constant value              : in    std_logic;
1473
    signal   clk                : in    std_logic;
1474 36 pela
    variable pltbv              : inout pltbv_t;
1475
    signal   pltbs              : out   pltbs_t;
1476 6 pela
    constant falling            : in    boolean := false;
1477
    constant timeout            : in    time    := C_PLTBUTILS_TIMEOUT
1478
  ) is
1479
    variable v_timeout_time     : time;
1480
  begin
1481
    v_timeout_time := now + timeout;
1482
    l1 : loop
1483 36 pela
      waitclks(1, clk, pltbv, pltbs, falling, timeout);
1484 6 pela
      exit l1 when s = value or now >= v_timeout_time;
1485
    end loop;
1486
    if now >= v_timeout_time then
1487 36 pela
      pltbutils_error("waitsig() timeout", pltbv, pltbs);
1488 6 pela
    end if;
1489
  end procedure waitsig;
1490 36 pela
 
1491 97 pela
  -- waitsig std_logic against integer, clocked
1492 6 pela
  procedure waitsig(
1493
    signal   s                  : in    std_logic;
1494
    constant value              : in    integer;
1495
    signal   clk                : in    std_logic;
1496 36 pela
    variable pltbv              : inout pltbv_t;
1497
    signal   pltbs              : out   pltbs_t;
1498 6 pela
    constant falling            : in    boolean := false;
1499
    constant timeout            : in    time    := C_PLTBUTILS_TIMEOUT
1500
  ) is
1501
    variable v_value            : std_logic;
1502
    variable v_timeout_time     : time;
1503
  begin
1504
    case value is
1505
      when 0      => v_value := '0';
1506
      when 1      => v_value := '1';
1507
      when others => v_value := 'X';
1508
    end case;
1509
    if v_value /= 'X' then
1510 36 pela
      waitsig(s, v_value, clk, pltbv, pltbs, falling, timeout);
1511 6 pela
    else
1512 36 pela
      pltbutils_error("waitsig() timeout", pltbv, pltbs);
1513 6 pela
    end if;
1514 36 pela
  end procedure waitsig;
1515
 
1516 97 pela
  -- waitsig std_logic_vector, clocked
1517 6 pela
  procedure waitsig(
1518
    signal   s                  : in    std_logic_vector;
1519
    constant value              : in    std_logic_vector;
1520
    signal   clk                : in    std_logic;
1521 36 pela
    variable pltbv              : inout pltbv_t;
1522
    signal   pltbs              : out   pltbs_t;
1523 6 pela
    constant falling            : in    boolean := false;
1524
    constant timeout            : in    time    := C_PLTBUTILS_TIMEOUT
1525
  ) is
1526
    variable v_timeout_time     : time;
1527
  begin
1528
    v_timeout_time := now + timeout;
1529
    l1 : loop
1530 36 pela
      waitclks(1, clk, pltbv, pltbs, falling, timeout);
1531 6 pela
      exit l1 when s = value or now >= v_timeout_time;
1532
    end loop;
1533
    if now >= v_timeout_time then
1534 36 pela
      pltbutils_error("waitsig() timeout", pltbv, pltbs);
1535 6 pela
    end if;
1536 36 pela
  end procedure waitsig;
1537 6 pela
 
1538 97 pela
  -- waitsig std_logic_vector against integer, clocked
1539 6 pela
  procedure waitsig(
1540
    signal   s                  : in    std_logic_vector;
1541
    constant value              : in    integer;
1542
    signal   clk                : in    std_logic;
1543 36 pela
    variable pltbv              : inout pltbv_t;
1544
    signal   pltbs              : out   pltbs_t;
1545 6 pela
    constant falling            : in    boolean := false;
1546
    constant timeout            : in    time    := C_PLTBUTILS_TIMEOUT
1547
  ) is
1548
    variable v_timeout_time     : time;
1549
  begin
1550 36 pela
    waitsig(s, std_logic_vector(to_unsigned(value, s'length)), clk,
1551
            pltbv, pltbs, falling, timeout);
1552
  end procedure waitsig;
1553
 
1554 97 pela
  -- waitsig unsigned, clocked
1555 6 pela
  procedure waitsig(
1556
    signal   s                  : in    unsigned;
1557
    constant value              : in    unsigned;
1558
    signal   clk                : in    std_logic;
1559 36 pela
    variable pltbv              : inout pltbv_t;
1560
    signal   pltbs              : out   pltbs_t;
1561 6 pela
    constant falling            : in    boolean := false;
1562
    constant timeout            : in    time    := C_PLTBUTILS_TIMEOUT
1563
  ) is
1564
    variable v_timeout_time     : time;
1565
  begin
1566
    v_timeout_time := now + timeout;
1567
    l1 : loop
1568 36 pela
      waitclks(1, clk, pltbv, pltbs, falling, timeout);
1569 6 pela
      exit l1 when s = value or now >= v_timeout_time;
1570
    end loop;
1571
    if now >= v_timeout_time then
1572 36 pela
      pltbutils_error("waitsig() timeout", pltbv, pltbs);
1573 6 pela
    end if;
1574 36 pela
  end procedure waitsig;
1575
 
1576 97 pela
  -- waitsig unsigned against integer, clocked
1577 6 pela
  procedure waitsig(
1578
    signal   s                  : in    unsigned;
1579
    constant value              : in    integer;
1580
    signal   clk                : in    std_logic;
1581 36 pela
    variable pltbv              : inout pltbv_t;
1582
    signal   pltbs              : out   pltbs_t;
1583 6 pela
    constant falling            : in    boolean := false;
1584
    constant timeout            : in    time    := C_PLTBUTILS_TIMEOUT
1585
  ) is
1586
    variable v_timeout_time     : time;
1587
  begin
1588 36 pela
    waitsig(s, to_unsigned(value, s'length), clk,
1589
            pltbv, pltbs, falling, timeout);
1590
  end procedure waitsig;
1591
 
1592 97 pela
  -- waitsig signed, clocked
1593 6 pela
  procedure waitsig(
1594
    signal   s                  : in    signed;
1595
    constant value              : in    signed;
1596
    signal   clk                : in    std_logic;
1597 36 pela
    variable pltbv              : inout pltbv_t;
1598
    signal   pltbs              : out   pltbs_t;
1599 6 pela
    constant falling            : in    boolean := false;
1600
    constant timeout            : in    time    := C_PLTBUTILS_TIMEOUT
1601
  ) is
1602
    variable v_timeout_time     : time;
1603
  begin
1604
    v_timeout_time := now + timeout;
1605
    l1 : loop
1606 36 pela
      waitclks(1, clk, pltbv, pltbs, falling, timeout);
1607 6 pela
      exit l1 when s = value or now >= v_timeout_time;
1608
    end loop;
1609
    if now >= v_timeout_time then
1610 36 pela
      pltbutils_error("waitsig() timeout", pltbv, pltbs);
1611 6 pela
    end if;
1612 36 pela
  end procedure waitsig;
1613 6 pela
 
1614 97 pela
  -- waitsig signed against integer, clocked
1615 6 pela
  procedure waitsig(
1616
    signal   s                  : in    signed;
1617
    constant value              : in    integer;
1618
    signal   clk                : in    std_logic;
1619 36 pela
    variable pltbv              : inout pltbv_t;
1620
    signal   pltbs              : out   pltbs_t;
1621 6 pela
    constant falling            : in    boolean := false;
1622
    constant timeout            : in    time    := C_PLTBUTILS_TIMEOUT
1623
  ) is
1624
    variable v_timeout_time     : time;
1625
  begin
1626 36 pela
    waitsig(s, to_signed(value, s'length), clk,
1627
            pltbv, pltbs, falling, timeout);
1628
  end procedure waitsig;
1629
 
1630 97 pela
  -- waitsig std_logic, unclocked
1631
  procedure waitsig(
1632
    signal   s                  : in    std_logic;
1633
    constant value              : in    std_logic;
1634
    variable pltbv              : inout pltbv_t;
1635
    signal   pltbs              : out   pltbs_t;
1636
    constant timeout            : in    time    := C_PLTBUTILS_TIMEOUT
1637
  ) is
1638
  begin
1639
    if s /= value then
1640
      wait until s = value for timeout;
1641
      if s /= value then
1642
        pltbutils_error("waitsig() timeout", pltbv, pltbs);
1643
      end if;
1644
    end if;
1645
  end procedure waitsig;
1646
 
1647 107 pela
  -- waitsig std_logic edge, unclocked
1648
  procedure waitsig(
1649
    signal   s                  : in    std_logic;
1650
    variable pltbv              : inout pltbv_t;
1651
    signal   pltbs              : out   pltbs_t;
1652
    constant falling            : in    boolean := false;
1653
    constant timeout            : in    time    := C_PLTBUTILS_TIMEOUT
1654
  ) is
1655
    variable v_timeout_time     : time;
1656
  begin
1657
    if falling then
1658
      wait until falling_edge(s) for timeout;
1659
    else
1660
      wait until rising_edge(s)  for timeout;
1661
    end if;
1662
    if (not ((falling and (s = '0' or s = 'L')) or ((not falling) and (s = '1' or s = 'H')))) then
1663
      pltbutils_error("waitsig() timeout", pltbv, pltbs);
1664
    end if;
1665
  end procedure waitsig;
1666
 
1667
 
1668 2 pela
  ----------------------------------------------------------------------------
1669
  -- check
1670
  --
1671
  -- procedure check(
1672 36 pela
  --   constant rpt             : in    string;
1673 99 pela
  --   constant actual          : in    integer|std_logic|std_logic_vector|unsigned|signed|boolean|time|string;
1674
  --   constant expected        : in    integer|std_logic|std_logic_vector|unsigned|signed|boolean|time|string;
1675 36 pela
  --   variable pltbv           : inout pltbv_t;
1676
  --   signal   pltbs           : out   pltbs_t
1677
  -- )
1678 2 pela
  --
1679
  -- procedure check(
1680 36 pela
  --   constant rpt             : in    string;
1681
  --   constant actual          : in    std_logic_vector;
1682
  --   constant expected        : in    std_logic_vector;
1683
  --   constant mask            : in    std_logic_vector;
1684
  --   variable pltbv           : inout pltbv_t;
1685
  --   signal   pltbs           : out   pltbs_t
1686
  -- )
1687 2 pela
  --
1688
  -- procedure check(
1689 36 pela
  --   constant rpt             : in    string;
1690 99 pela
  --   constant actual          : in    time;
1691
  --   constant expected        : in    time;
1692
  --   constant tolerance       : in    time;
1693
  --   variable pltbv           : inout pltbv_t;
1694
  --   signal   pltbs           : out   pltbs_t
1695
  -- )
1696
  --
1697
  -- procedure check(
1698
  --   constant rpt             : in    string;
1699 36 pela
  --   constant expr            : in    boolean;
1700
  --   variable pltbv           : inout pltbv_t;
1701
  --   signal   pltbs           : out   pltbs_t
1702 2 pela
  -- )
1703
  --
1704
  -- Checks that the value of a signal or variable is equal to expected.
1705
  -- If not equal, displays an error message and increments the error counter.
1706
  --
1707 36 pela
  -- Arguments:
1708
  --   rpt                      Report message to be displayed in case of
1709
  --                            mismatch.
1710 2 pela
  --                            It is recommended that the message is unique
1711
  --                            and that it contains the name of the signal
1712 36 pela
  --                            or variable being checked.
1713
  --                            The message should NOT contain the expected
1714
  --                            value, becase check() prints that
1715 2 pela
  --                            automatically.
1716
  --
1717 24 pela
  --   actual                   The signal or variable to be checked.
1718 36 pela
  --                            Supported types: integer, std_logic,
1719 99 pela
  --                            std_logic_vector, unsigned, signed, boolean,
1720
  --                            time, string.
1721 2 pela
  --
1722 36 pela
  --   expected                 Expected value.
1723 2 pela
  --                            Same type as data or integer.
1724
  --
1725 36 pela
  --   mask                     Bit mask and:ed to data and expected
1726 2 pela
  --                            before comparison.
1727
  --                            Optional if data is std_logic_vector.
1728
  --                            Not allowed for other types.
1729
  --
1730 99 pela
  --   tolerance                Allowed tolerance. Checks that
1731
  --                            expected - tolerance <= actual <= expected + tolerance
1732
  --                            is true.
1733
  -- 
1734 2 pela
  --   expr                     boolean expression for checking.
1735
  --                            This makes it possible to check any kind of
1736
  --                            expresion, not just equality.
1737
  --
1738 36 pela
  --   pltbv, pltbs             PlTbUtils' status- and control variable and
1739
  --                            -signal.
1740
  --
1741 2 pela
  -- Examples:
1742 36 pela
  -- check("dat_o after reset", dat_o, 0, pltbv, pltbs);
1743 2 pela
  -- -- With mask:
1744 36 pela
  -- check("Status field in reg_o after start", reg_o, x"01", x"03", pltbv, pltbs);
1745 2 pela
  -- -- Boolean expression:
1746 36 pela
  -- check("Counter after data burst", cnt_o > 10, pltbv, pltbs);
1747 2 pela
  ----------------------------------------------------------------------------
1748
  -- check integer
1749
  procedure check(
1750
    constant rpt                : in    string;
1751 24 pela
    constant actual             : in    integer;
1752 2 pela
    constant expected           : in    integer;
1753 36 pela
    variable pltbv              : inout pltbv_t;
1754
    signal   pltbs              : out   pltbs_t
1755 2 pela
  ) is
1756
  begin
1757 36 pela
    check(rpt, actual = expected, str(actual), str(expected), "", pltbv, pltbs);
1758 2 pela
  end procedure check;
1759
 
1760
  -- check std_logic
1761
  procedure check(
1762
    constant rpt                : in    string;
1763 24 pela
    constant actual             : in    std_logic;
1764 2 pela
    constant expected           : in    std_logic;
1765 36 pela
    variable pltbv              : inout pltbv_t;
1766
    signal   pltbs              : out   pltbs_t
1767 2 pela
  ) is
1768
  begin
1769 36 pela
    check(rpt, actual = expected, str(actual), str(expected), "", pltbv, pltbs);
1770 2 pela
  end procedure check;
1771 36 pela
 
1772 2 pela
  -- check std_logic against integer
1773
  procedure check(
1774
    constant rpt                : in    string;
1775 24 pela
    constant actual             : in    std_logic;
1776 2 pela
    constant expected           : in    integer;
1777 36 pela
    variable pltbv              : inout pltbv_t;
1778
    signal   pltbs              : out   pltbs_t
1779 2 pela
  ) is
1780
  begin
1781 24 pela
    check(rpt, ((actual = '0' and expected = 0) or (actual = '1' and expected = 1)),
1782 36 pela
          str(actual), str(expected), "", pltbv, pltbs);
1783
  end procedure check;
1784
 
1785 2 pela
  -- check std_logic_vector
1786
  procedure check(
1787
    constant rpt                : in    string;
1788 24 pela
    constant actual             : in    std_logic_vector;
1789 2 pela
    constant expected           : in    std_logic_vector;
1790 36 pela
    variable pltbv              : inout pltbv_t;
1791
    signal   pltbs              : out   pltbs_t
1792 2 pela
  ) is
1793
  begin
1794 36 pela
    check(rpt, actual = expected, hxstr(actual, "0x"), hxstr(expected, "0x"), "", pltbv, pltbs);
1795 2 pela
  end procedure check;
1796 36 pela
 
1797 2 pela
  -- check std_logic_vector with mask
1798
  procedure check(
1799
    constant rpt                : in    string;
1800 24 pela
    constant actual             : in    std_logic_vector;
1801 2 pela
    constant expected           : in    std_logic_vector;
1802
    constant mask               : in    std_logic_vector;
1803 36 pela
    variable pltbv              : inout pltbv_t;
1804
    signal   pltbs              : out   pltbs_t
1805 2 pela
  ) is
1806
  begin
1807 24 pela
    check(rpt, (actual and mask) = (expected and mask),
1808 36 pela
          hxstr(actual, "0x"), hxstr(expected, "0x"), hxstr(mask, "0x"), pltbv, pltbs);
1809
  end procedure check;
1810
 
1811 2 pela
  -- check std_logic_vector against integer
1812
  procedure check(
1813
    constant rpt                : in    string;
1814 24 pela
    constant actual             : in    std_logic_vector;
1815 2 pela
    constant expected           : in    integer;
1816 36 pela
    variable pltbv              : inout pltbv_t;
1817
    signal   pltbs              : out   pltbs_t
1818 2 pela
  ) is
1819
  begin
1820 36 pela
    check(rpt, actual, std_logic_vector(to_signed(expected, actual'length)), pltbv, pltbs);
1821 2 pela
  end procedure check;
1822
 
1823
  -- check std_logic_vector with mask against integer
1824
  procedure check(
1825
    constant rpt                : in    string;
1826 24 pela
    constant actual             : in    std_logic_vector;
1827 2 pela
    constant expected           : in    integer;
1828
    constant mask               : in    std_logic_vector;
1829 36 pela
    variable pltbv              : inout pltbv_t;
1830
    signal   pltbs              : out   pltbs_t
1831 2 pela
  ) is
1832
  begin
1833 36 pela
    check(rpt, actual, std_logic_vector(to_signed(expected, actual'length)), mask, pltbv, pltbs);
1834 2 pela
  end procedure check;
1835 36 pela
 
1836 2 pela
  -- check unsigned
1837
  procedure check(
1838
    constant rpt                : in    string;
1839 24 pela
    constant actual             : in    unsigned;
1840 2 pela
    constant expected           : in    unsigned;
1841 36 pela
    variable pltbv              : inout pltbv_t;
1842
    signal   pltbs              : out   pltbs_t
1843 2 pela
  ) is
1844
  begin
1845 36 pela
    check(rpt, actual = expected, hxstr(actual, "0x"), hxstr(expected, "0x"), "", pltbv, pltbs);
1846 2 pela
  end procedure check;
1847 36 pela
 
1848 2 pela
  -- check unsigned against integer
1849
  procedure check(
1850
    constant rpt                : in    string;
1851 24 pela
    constant actual             : in    unsigned;
1852 2 pela
    constant expected           : in    integer;
1853 36 pela
    variable pltbv              : inout pltbv_t;
1854
    signal   pltbs              : out   pltbs_t
1855 2 pela
  ) is
1856
  begin
1857 36 pela
    check(rpt, actual, to_unsigned(expected, actual'length), pltbv, pltbs);
1858
  end procedure check;
1859
 
1860 2 pela
  -- check signed
1861
  procedure check(
1862
    constant rpt                : in    string;
1863 24 pela
    constant actual             : in    signed;
1864 2 pela
    constant expected           : in    signed;
1865 36 pela
    variable pltbv              : inout pltbv_t;
1866
    signal   pltbs              : out   pltbs_t
1867 2 pela
  ) is
1868
  begin
1869 36 pela
    check(rpt, actual = expected, hxstr(actual, "0x"), hxstr(expected, "0x"), "", pltbv, pltbs);
1870 2 pela
  end procedure check;
1871 36 pela
 
1872 2 pela
  -- check signed against integer
1873 24 pela
  -- TODO: find the bug reported by tb_pltbutils when expected  is negative (-1):
1874 2 pela
  --       ** Error: (vsim-86) numstd_conv_unsigned_nu: NATURAL arg value is negative (-1)
1875
  procedure check(
1876
    constant rpt                : in    string;
1877 24 pela
    constant actual             : in    signed;
1878 2 pela
    constant expected           : in    integer;
1879 36 pela
    variable pltbv              : inout pltbv_t;
1880
    signal   pltbs              : out   pltbs_t
1881 2 pela
  ) is
1882
  begin
1883 36 pela
    check(rpt, actual, to_signed(expected, actual'length), pltbv, pltbs);
1884
  end procedure check;
1885 99 pela
 
1886
  -- check boolean
1887
  procedure check(
1888
    constant rpt                : in    string;
1889
    constant actual             : in    boolean;
1890
    constant expected           : in    boolean;
1891
    variable pltbv              : inout pltbv_t;
1892
    signal   pltbs              : out   pltbs_t
1893
  ) is
1894
  begin
1895
    check(rpt, actual = expected, str(actual), str(expected), "", pltbv, pltbs);
1896
  end procedure check;
1897
 
1898
  -- check boolean against integer
1899
  procedure check(
1900
    constant rpt                : in    string;
1901
    constant actual             : in    boolean;
1902
    constant expected           : in    integer;
1903
    variable pltbv              : inout pltbv_t;
1904
    signal   pltbs              : out   pltbs_t
1905
  ) is
1906
  begin
1907
    check(rpt, ((actual = false and expected = 0) or (actual = true and expected = 1)),
1908
          str(actual), str(expected), "", pltbv, pltbs);
1909
  end procedure check;
1910
 
1911
  -- check time
1912
  procedure check(
1913
    constant rpt                : in    string;
1914
    constant actual             : in    time;
1915
    constant expected           : in    time;
1916
    variable pltbv              : inout pltbv_t;
1917
    signal   pltbs              : out   pltbs_t
1918
  ) is
1919
  begin
1920
    check(rpt, actual = expected, time'image(actual), time'image(expected), "", pltbv, pltbs);
1921
  end procedure check;
1922
 
1923
  -- check time with tolerance
1924
  procedure check(
1925
    constant rpt                : in    string;
1926
    constant actual             : in    time;
1927
    constant expected           : in    time;
1928
    constant tolerance          : in    time;
1929
    variable pltbv              : inout pltbv_t;
1930
    signal   pltbs              : out   pltbs_t
1931
  ) is
1932
  begin
1933
    check(rpt, ((actual >= expected-tolerance) and (actual <= expected+tolerance)),
1934
          time'image(actual), time'image(expected) & " +/- " & time'image(tolerance), "", pltbv, pltbs);
1935
  end procedure check;
1936 88 pela
 
1937
  -- check string
1938
  procedure check(
1939
    constant rpt                : in    string;
1940
    constant actual             : in    string;
1941
    constant expected           : in    string;
1942
    variable pltbv              : inout pltbv_t;
1943
    signal   pltbs              : out   pltbs_t
1944
  ) is
1945
    variable mismatch : boolean := false;
1946
  begin
1947
    if actual'length /= expected'length then
1948
      mismatch := true;
1949
    else
1950
      for i in 0 to actual'length-1 loop
1951
        if actual(i+actual'low) /= expected(i+expected'low) then
1952
          mismatch := true;
1953
          exit;
1954
        end if;
1955
      end loop;
1956
    end if;
1957
    check(rpt, not mismatch, actual, expected, "", pltbv, pltbs);
1958
  end procedure check;
1959
 
1960 2 pela
  -- check with boolean expression
1961 99 pela
  -- Check signal or variable with a boolean expression as argument expr.
1962
  -- This allowes any kind of check, including less than, greater than,
1963
  -- ranges, etc. But there are no clear messages in case of mismatch.
1964 2 pela
  procedure check(
1965
    constant rpt                : in    string;
1966
    constant expr               : in    boolean;
1967 36 pela
    variable pltbv              : inout pltbv_t;
1968
    signal   pltbs              : out   pltbs_t
1969 2 pela
  ) is
1970
  begin
1971 36 pela
    check(rpt, expr, "", "", "", pltbv, pltbs);
1972
  end procedure check;
1973
 
1974 107 pela
 
1975
  ----------------------------------------------------------------------------
1976
  -- check files
1977
  --
1978
  -- procedure check_binfile | check_txtfile | check_datfile(
1979
  --   constant rpt        : in    string;
1980
  --   constant filename1  : in    string;
1981
  --   constant filename2  : in    string;
1982
  --   constant verbosity  : in    integer;
1983
  --   variable pltbv      : inout pltbv_t;
1984
  --   signal   pltbs      : out   pltbs_t
1985
  -- )
1986
  --
1987
  -- Checks that the contents of a file is equal to expected contents, by 
1988
  -- comparing with a reference file.
1989
  -- If not equal, displays an error message and increments the error counter.
1990
  -- This is useful for examining different types of files generated by
1991
  -- testbench components during a simulation against reference files. 
1992
  -- It can be different kinds of data sequences, video image data, etc.
1993
  --
1994
  -- check_binfile compares two binary files. It uses "file of character" to
1995
  -- read bytes from the files. The VHDL LRM does not define how a  
1996
  -- "file of character" should be written or to/read from disk. In theory,
1997
  -- there is a risk that a VHDL file of character is not compatible with
1998
  -- a normal binary file, but practical tests done with some popular 
1999
  -- simulators have shown that they are compatible. This does not 
2000
  -- guarantee that this procedure works with ALL simulators, and with
2001
  -- ALL future versions of the tested simulators. Use your own judgement.
2002
  --
2003
  -- check_txtfile compares two text files.
2004
  --
2005
  -- check_datfile compares two files with data formatted as follows.
2006
  -- The files contain a sequence of data items separated by whitespace
2007
  -- (spaces, tabs, newlines). The files can contain comments starting with
2008
  -- a hash sign (#), and ending at next newline. 
2009
  -- Only the data items are compared. The types of whitespace and comments
2010
  -- are ignored. This is useful for different kinds of data dumps, 
2011
  -- including some image file formats such as 
2012
  --   Plain PBM (Portable Bit Map - P1, http://netpbm.sourceforge.net/doc/pbm.html )
2013
  --   Plain PGM (Portable Gray Map - P2, http://netpbm.sourceforge.net/doc/pgm.html )
2014
  --   Plain PPM (Portable Pixel Map - P3, http://netpbm.sourceforge.net/doc/ppm.html )
2015
  --
2016
  -- Arguments:
2017
  --   rpt                      Report message to be displayed in case of
2018
  --                            mismatch.
2019
  --                            It is recommended that the message is unique
2020
  --                            and that it contains the name of the signal
2021
  --                            or variable being checked.
2022
  --
2023
  --   filename1                Name of first file to be compared, 
2024
  --                            including relative path from the simulator's
2025
  --                            working directory.
2026
  --
2027
  --   filename2                Name of second file to be compared, 
2028
  --                            including relative path from the simulator's
2029
  --                            working directory.
2030
  --
2031
  --   verbosity                Controls amount of individual error reports when
2032
  --                            differences between files are found, to make it 
2033
  --                            possible to prevent flooding with error messages.
2034
  --                            0: no individual differences reported
2035
  --                            1: the first ten differences reported
2036
  --                            2: all differences reported
2037
  --
2038
  --   pltbv, pltbs             PlTbUtils' status- and control variable and
2039
  --                            -signal.
2040
  --
2041
  -- Examples:
2042
  -- check_binfile("Data output file", "out_file.bin", "ref_file.bin", 0, pltbv, pltbs);
2043
  -- check_txtfile("Result file", G_RESULT_FILE, G_REF_FILE, G_CHECKFILE_VEROBOSITY, pltbv, pltbs);
2044
  -- check_datfile("Resulting image", "result_img.ppm", "ref_img.ppm", 2, pltbv, pltbs);
2045
  ----------------------------------------------------------------------------
2046
 
2047
  -- check binary file
2048
  procedure check_binfile(
2049
    constant rpt        : in    string;
2050
    constant filename1  : in    string;
2051
    constant filename2  : in    string;
2052
    constant verbosity  : in    integer;
2053
    variable pltbv      : inout pltbv_t;
2054
    signal   pltbs      : out   pltbs_t
2055
  ) is
2056
    variable v_file_errors    : integer := 0;
2057
    type charfile             is file of character;
2058
    file f1                   : charfile;
2059
    file f2                   : charfile;
2060
    variable f1_status        : file_open_status;
2061
    variable f2_status        : file_open_status;
2062
    variable c1               : character;
2063
    variable c2               : character;
2064
    variable offset1          : integer := 0;
2065
    variable offset2          : integer := 0;
2066
    variable error_line       : line;
2067
  begin
2068
    file_open(f1_status, f1, filename1, read_mode);
2069
    if f1_status /= open_ok then
2070
      v_file_errors := v_file_errors + 1;
2071
      write(error_line, " Could not open file " & filename1 & " for reading.");
2072
    else
2073
      file_open(f2_status, f2, filename2, read_mode);
2074
      if f2_status /= open_ok then
2075
        v_file_errors := v_file_errors + 1;
2076
        write(error_line, " Could not open file " & filename2 & " for reading. ");
2077
        file_close(f1);
2078
      end if;
2079
    end if;
2080
    if f1_status = open_ok and f2_status = open_ok then
2081
      while not endfile(f1) and not endfile(f2) loop
2082
        read(f1, c1);
2083
        read(f2, c2);
2084
        if c1 /= c2 then
2085
          v_file_errors := v_file_errors + 1;
2086
          if ((verbosity >= 2) or (verbosity = 1 and v_file_errors <= 10)) then
2087
            write(error_line, " Diff offset " & integer'image(offset1) & ": " &
2088
                  integer'image(character'pos(c1)) & " /= " & integer'image(character'pos(c2)) & ".");
2089
          end if;
2090
          if verbosity = 1 and v_file_errors = 11 then
2091
            write(error_line, string'(" Further diffs suppressed."));
2092
          end if;
2093
        end if;
2094
        offset1 := offset1 + 1;
2095
        offset2 := offset2 + 1;
2096
      end loop;
2097
      if v_file_errors > 0 then
2098
        write(error_line, " " & integer'image(v_file_errors) & " bytes differ.");
2099
      end if;
2100
 
2101
      -- Now one or both files are at the end.
2102
      -- Checking remaining size of possible non-ended file.
2103
      while not endfile(f1) loop
2104
        read(f1, c1);
2105
        offset1 := offset1 + 1;
2106
      end loop;
2107
      while not endfile(f2) loop
2108
        read(f2, c2);
2109
        offset2 := offset2 + 1;
2110
      end loop;
2111
      if offset1 /= offset2 then
2112
        v_file_errors := v_file_errors + 1;
2113
        write(error_line, " File sizes differ: " & integer'image(offset1) &
2114
                         " /= " & integer'image(offset2) & " bytes.");
2115
      end if;
2116
      write(error_line, " (" & filename1 & ", " & filename2 & ")");
2117
    end if; -- f1_status, f2_status
2118
 
2119
    if f1_status = open_ok then
2120
      file_close(f1);
2121
    end if;
2122
    if f2_status = open_ok then
2123
      file_close(f2);
2124
    end if;
2125
 
2126
    check(rpt, v_file_errors = 0, error_line.all, "", "!NO_TAGS!", pltbv, pltbs);
2127
 
2128
    if error_line /= null then
2129
      deallocate(error_line);
2130
    end if;
2131
  end procedure check_binfile;
2132
 
2133
 
2134
  -- check text file
2135
  procedure check_txtfile(
2136
    constant rpt        : in    string;
2137
    constant filename1  : in    string;
2138
    constant filename2  : in    string;
2139
    constant verbosity  : in    integer;
2140
    variable pltbv      : inout pltbv_t;
2141
    signal   pltbs      : out   pltbs_t
2142
  ) is
2143
    variable v_file_errors    : integer := 0;
2144
    file f1                   : text;
2145
    file f2                   : text;
2146
    variable f1_status        : file_open_status;
2147
    variable f2_status        : file_open_status;
2148
    variable l1               : line;
2149
    variable l2               : line;
2150
    variable line_num1        : integer := 0;
2151
    variable line_num2        : integer := 0;
2152
    variable error_line       : line;
2153
  begin
2154
    file_open(f1_status, f1, filename1, read_mode);
2155
    if f1_status /= open_ok then
2156
      v_file_errors := v_file_errors + 1;
2157
      write(error_line, " Could not open file " & filename1 & " for reading.");
2158
    else
2159
      file_open(f2_status, f2, filename2, read_mode);
2160
      if f2_status /= open_ok then
2161
        v_file_errors := v_file_errors + 1;
2162
        write(error_line, " Could not open file " & filename2 & " for reading. ");
2163
        file_close(f1);
2164
      end if;
2165
    end if;
2166
    if f1_status = open_ok and f2_status = open_ok then
2167
      while not endfile(f1) and not endfile(f2) loop
2168
        readline(f1, l1);
2169
        readline(f2, l2);
2170
        line_num1 := line_num1 + 1;
2171
        line_num2 := line_num2 + 1;
2172
        if l1.all /= l2.all then
2173
          v_file_errors := v_file_errors + 1;
2174
          if ((verbosity >= 2) or (verbosity = 1 and v_file_errors <= 10)) then
2175
            write(error_line, " Diff line " & integer'image(line_num1) & ": '" &
2176
                  l1.all & "'' /= '" & l2.all & "'.");
2177
          end if;
2178
          if verbosity = 1 and v_file_errors = 11 then
2179
            write(error_line, string'(" Further diffs suppressed."));
2180
          end if;
2181
        end if;
2182
      end loop;
2183
      if v_file_errors > 0 then
2184
        write(error_line, " " & integer'image(v_file_errors) & " lines differ.");
2185
      end if;
2186
 
2187
      -- Now one or both files are at the end.
2188
      -- Checking remaining size of possible non-ended file.
2189
      while not endfile(f1) loop
2190
        readline(f1, l1);
2191
        line_num1 := line_num1 + 1;
2192
      end loop;
2193
      while not endfile(f2) loop
2194
        readline(f2, l2);
2195
        line_num2 := line_num2 + 1;
2196
      end loop;
2197
      if line_num1 /= line_num2 then
2198
        v_file_errors := v_file_errors + 1;
2199
        write(error_line, " File sizes differ: " & integer'image(line_num1) &
2200
                         " /= " & integer'image(line_num2) & " lines.");
2201
      end if;
2202
      write(error_line, " (" & filename1 & ", " & filename2 & ")");
2203
    end if; -- f1_status, f2_status
2204
 
2205
    if f1_status = open_ok then
2206
      file_close(f1);
2207
    end if;
2208
    if f2_status = open_ok then
2209
      file_close(f2);
2210
    end if;
2211
 
2212
    check(rpt, v_file_errors = 0, error_line.all, "", "!NO_TAGS!", pltbv, pltbs);
2213
 
2214
    if error_line /= null then
2215
      deallocate(error_line);
2216
    end if;
2217
  end procedure check_txtfile;
2218
 
2219
  -- check data file
2220
  procedure check_datfile(
2221
    constant rpt        : in    string;
2222
    constant filename1  : in    string;
2223
    constant filename2  : in    string;
2224
    constant verbosity  : in    integer;
2225
    variable pltbv      : inout pltbv_t;
2226
    signal   pltbs      : out   pltbs_t;
2227
    constant skip_init_items : in integer := 0
2228
  ) is
2229
    variable v_file_errors    : integer := 0;
2230
    file f1                   : text;
2231
    file f2                   : text;
2232
    variable f1_status        : file_open_status;
2233
    variable f2_status        : file_open_status;
2234
    variable l1               : line;
2235
    variable l2               : line;
2236
    variable line_num1        : integer := 0;
2237
    variable line_num2        : integer := 0;
2238
    variable item1            : string(1 to 256);
2239
    variable item2            : string(1 to 256);
2240
    variable item_len1        : integer := -1;
2241
    variable item_len2        : integer := -1;
2242
    variable item_num1        : integer := 0;
2243
    variable item_num2        : integer := 0;
2244
    variable item_cnt         : integer := 0;
2245
    variable error_line       : line;
2246
  begin
2247
    file_open(f1_status, f1, filename1, read_mode);
2248
    if f1_status /= open_ok then
2249
      v_file_errors := v_file_errors + 1;
2250
      write(error_line, " Could not open file " & filename1 & " for reading.");
2251
    else
2252
      file_open(f2_status, f2, filename2, read_mode);
2253
      if f2_status /= open_ok then
2254
        v_file_errors := v_file_errors + 1;
2255
        write(error_line, " Could not open file " & filename2 & " for reading. ");
2256
        file_close(f1);
2257
      end if;
2258
    end if;
2259
    if f1_status = open_ok and f2_status = open_ok then
2260
      while item_len1 /= 0 or item_len2 /= 0 loop
2261
        get_file_item(f1, l1, item1, item_len1, line_num1, item_num1);
2262
        get_file_item(f2, l2, item2, item_len2, line_num2, item_num2);
2263
        item_cnt := item_cnt + 1;
2264
        if item_len1 > 0 and item_len2 > 0 and item_cnt > skip_init_items then
2265
          if item1 /= item2 then
2266
            v_file_errors := v_file_errors + 1;
2267
            if ((verbosity >= 2) or (verbosity = 1 and v_file_errors <= 10)) then
2268
              write(error_line, " Diff item " & integer'image(item_num1) & ": '" &
2269
                  item1(1 to item_len1) & "' /= '" & item2(1 to item_len2) & "'.");
2270
            end if;
2271
            if verbosity = 1 and v_file_errors = 11 then
2272
              write(error_line, string'(" Further diffs suppressed."));
2273
            end if;
2274
          end if;
2275
        end if;
2276
      end loop;
2277
 
2278
      if v_file_errors > 0 then
2279
        write(error_line, " " & integer'image(v_file_errors) & " items differ.");
2280
      end if;
2281
 
2282
      -- Now one or both files are at the end.
2283
      -- Checking remaining size of possible non-ended file.
2284
      while not endfile(f1) loop
2285
        get_file_item(f1, l1, item1, item_len1, line_num1, item_num1);
2286
      end loop;
2287
      while not endfile(f2) loop
2288
        get_file_item(f2, l2, item2, item_len2, line_num2, item_num2);
2289
      end loop;
2290
      if item_num1 /= item_num2 then
2291
        v_file_errors := v_file_errors + 1;
2292
        write(error_line, " File sizes differ: " & integer'image(item_num1) &
2293
                         " /= " & integer'image(item_num2) & " items.");
2294
      end if;
2295
      write(error_line, " (" & filename1 & ", " & filename2 & ")");
2296
    end if;
2297
 
2298
    if f1_status = open_ok then
2299
      file_close(f1);
2300
    end if;
2301
    if f2_status = open_ok then
2302
      file_close(f2);
2303
    end if;
2304
 
2305
    check(rpt, v_file_errors = 0, error_line.all, "", "!NO_TAGS!", pltbv, pltbs);
2306
 
2307
    if error_line /= null then
2308
      deallocate(error_line);
2309
    end if;
2310
  end procedure check_datfile;
2311
 
2312
 
2313 99 pela
  -- check base procedure
2314
  -- All other check procedures perform the check, and calls this procedure
2315
  -- with the check result in the expr argument.
2316 107 pela
  -- This procedure can also be called directly. It allows any kind of check,
2317 99 pela
  -- including less than, greater than, ranges, etc. 
2318
  -- Your calling code must convert actual, expected and mask to strings.
2319 24 pela
  procedure check(
2320
    constant rpt                : in    string;
2321
    constant expr               : in    boolean;
2322
    constant actual             : in    string;
2323
    constant expected           : in    string;
2324
    constant mask               : in    string;
2325 36 pela
    variable pltbv              : inout pltbv_t;
2326
    signal   pltbs              : out   pltbs_t
2327 24 pela
  ) is
2328 36 pela
    variable timestamp          : time;
2329 24 pela
  begin
2330 36 pela
    timestamp := now;
2331
    pltbv.chk_cnt := pltbv.chk_cnt + 1;
2332
    pltbv.chk_cnt_in_test := pltbv.chk_cnt_in_test + 1;
2333 101 pela
    if not is_test_active(pltbv) then
2334
      pltbv.err_cnt := pltbv.err_cnt + 1;
2335
      pltbv.err_cnt_in_test := pltbv.err_cnt_in_test + 1;
2336
      if C_PLTBUTILS_USE_STD_CHECK_MSG then
2337
        check_msg("check() executed in skipped test, missing if clause?", timestamp, false, "", "", "", pltbv.test_num,
2338
          pltbv.test_name(1 to pltbv.test_name_len), pltbv.chk_cnt, pltbv.err_cnt_in_test);
2339
      end if;
2340
      if C_PLTBUTILS_USE_CUSTOM_CHECK_MSG then
2341
        custom_check_msg("check() executed in skipped test, missing if clause?", timestamp, false, "", "", "", pltbv.test_num,
2342
          pltbv.test_name(1 to pltbv.test_name_len), pltbv.chk_cnt, pltbv.err_cnt_in_test);
2343
      end if;
2344
    end if;
2345 2 pela
    if not expr then
2346 36 pela
      pltbv.err_cnt := pltbv.err_cnt + 1;
2347
      pltbv.err_cnt_in_test := pltbv.err_cnt_in_test + 1;
2348 2 pela
    end if;
2349 36 pela
    pltbs_update(pltbv, pltbs);
2350 24 pela
    if C_PLTBUTILS_USE_STD_CHECK_MSG then
2351 36 pela
      check_msg(rpt, timestamp, expr, actual, expected, mask, pltbv.test_num,
2352
        pltbv.test_name(1 to pltbv.test_name_len), pltbv.chk_cnt, pltbv.err_cnt_in_test);
2353 24 pela
    end if;
2354
    if C_PLTBUTILS_USE_CUSTOM_CHECK_MSG then
2355 36 pela
      custom_check_msg(rpt, timestamp, expr, actual, expected, mask, pltbv.test_num,
2356
        pltbv.test_name(1 to pltbv.test_name_len), pltbv.chk_cnt, pltbv.err_cnt_in_test);
2357 24 pela
    end if;
2358 36 pela
    pltbs_update(pltbv, pltbs);
2359 24 pela
  end procedure check;
2360 36 pela
 
2361 107 pela
 
2362
 
2363 2 pela
  ----------------------------------------------------------------------------
2364 14 pela
  -- to_ascending
2365
  --
2366
  -- function to_ascending(
2367
  --  constant s                  : std_logic_vector
2368
  -- ) return std_logic_vector;
2369
  --
2370
  -- function to_ascending(
2371
  --  constant s                  : unsigned
2372
  -- ) return unsigned
2373
  --
2374
  -- function to_ascending(
2375
  --  constant s                  : signed
2376
  -- ) return signed;
2377
  --
2378 97 pela
  -- Converts a vector to ascending range ("to-range").
2379 14 pela
  -- The argument s can have ascending or descending range.
2380 97 pela
  -- E.g. an argument defined as a std_logic_vector(3 downto 1) 
2381
  -- will be returned as a std_logic_vector(1 to 3).
2382
  --
2383
  -- Arguments: 
2384
  --   s             Constant, signal or variable to convert
2385
  --
2386
  -- Return value:   Converted value
2387
  --
2388
  -- Examples:
2389
  -- ascending_sig <= to_ascending(descending_sig);
2390
  -- ascending_var := to_ascending(descending_var);
2391 14 pela
  ----------------------------------------------------------------------------
2392
  function to_ascending(
2393
    constant s                  : std_logic_vector
2394
  ) return std_logic_vector is
2395 18 pela
    variable r : std_logic_vector(s'low to s'high);
2396 14 pela
  begin
2397
    for i in r'range loop
2398
      r(i) := s(i);
2399
    end loop;
2400
    return r;
2401
  end function to_ascending;
2402
 
2403
  function to_ascending(
2404
    constant s                  : unsigned
2405
  ) return unsigned is
2406 18 pela
    variable r : unsigned(s'low to s'high);
2407 14 pela
  begin
2408
    for i in r'range loop
2409
      r(i) := s(i);
2410
    end loop;
2411
    return r;
2412
  end function to_ascending;
2413
 
2414
  function to_ascending(
2415
    constant s                  : signed
2416
  ) return signed is
2417 18 pela
    variable r : signed(s'low to s'high);
2418 14 pela
  begin
2419
    for i in r'range loop
2420
      r(i) := s(i);
2421
    end loop;
2422
    return r;
2423
  end function to_ascending;
2424
 
2425
  ----------------------------------------------------------------------------
2426
  -- to_descending
2427
  --
2428
  -- function to_descending(
2429
  --  constant s                  : std_logic_vector
2430
  -- ) return std_logic_vector;
2431
  --
2432
  -- function to_descending(
2433
  --  constant s                  : unsigned
2434
  -- ) return unsigned
2435
  --
2436
  -- function to_descending(
2437
  --  constant s                  : signed
2438
  -- ) return signed;
2439
  --
2440 97 pela
  -- Converts a vector to descending range ("downto-range").
2441 14 pela
  -- The argument s can have ascending or descending range.
2442 97 pela
  -- E.g. an argument defined as a std_logic_vector(1 to 3) 
2443
  -- will be returned as a std_logic_vector(3 downto 1).
2444
  --
2445
  -- Arguments: 
2446
  --   s             Constant, signal or variable to convert
2447
  --
2448
  -- Return value:   Converted value
2449
  --
2450
  -- Examples:
2451
  -- descending_sig <= to_descending(ascending_sig);
2452
  -- descending_var := to_descending(ascending_var);
2453 14 pela
  ----------------------------------------------------------------------------
2454
  function to_descending(
2455
    constant s                  : std_logic_vector
2456
  ) return std_logic_vector is
2457 18 pela
    variable r : std_logic_vector(s'high downto s'low);
2458 14 pela
  begin
2459
    for i in r'range loop
2460
      r(i) := s(i);
2461
    end loop;
2462
    return r;
2463
  end function to_descending;
2464 36 pela
 
2465 14 pela
  function to_descending(
2466
    constant s                  : unsigned
2467
  ) return unsigned is
2468 18 pela
    variable r : unsigned(s'high downto s'low);
2469 14 pela
  begin
2470
    for i in r'range loop
2471
      r(i) := s(i);
2472
    end loop;
2473
    return r;
2474
  end function to_descending;
2475
 
2476
  function to_descending(
2477
    constant s                  : signed
2478
  ) return signed is
2479 18 pela
    variable r : signed(s'high downto s'low);
2480 14 pela
  begin
2481
    for i in r'range loop
2482
      r(i) := s(i);
2483
    end loop;
2484
    return r;
2485
  end function to_descending;
2486 36 pela
 
2487 14 pela
  ----------------------------------------------------------------------------
2488
  -- hxstr
2489
  -- function hxstr(
2490
  --  constant s                  : std_logic_vector;
2491 24 pela
  --  constant prefix             : string := "";
2492
  --  constant postfix            : string := ""
2493 14 pela
  -- ) return string;
2494
  --
2495
  -- function hxstr(
2496
  --  constant s                  : unsigned;
2497 24 pela
  --  constant prefix             : string := "";
2498
  --  constant postfix            : string := ""
2499 14 pela
  -- ) return string;
2500
  --
2501
  -- function hxstr(
2502
  --  constant s                  : signed;
2503 24 pela
  --  constant prefix             : string := "";
2504
  --  constant postfix            : string := ""
2505 14 pela
  -- ) return string;
2506
  --
2507 97 pela
  -- Converts a vector to a string in hexadecimal format.
2508
  -- An optional prefix can be specified, e.g. "0x", as well as a suffix.
2509 14 pela
  --
2510 97 pela
  -- The input argument can have ascending range ( "to-range" ) or descending range
2511
  -- ("downto-range"). There is no vector length limitation.
2512 14 pela
  --
2513 97 pela
  -- Arguments: 
2514
  --   s             Constant, signal or variable to convert
2515 14 pela
  --
2516 97 pela
  -- Return value:   Converted value
2517
  --
2518 14 pela
  -- Examples:
2519
  -- print("value=" & hxstr(s));
2520
  -- print("value=" & hxstr(s, "0x"));
2521 97 pela
  -- print("value=" & hxstr(s, "16#", "#"));
2522 14 pela
  ----------------------------------------------------------------------------
2523
  function hxstr(
2524
    constant s                  : std_logic_vector;
2525 24 pela
    constant prefix             : string := "";
2526
    constant postfix            : string := ""
2527 14 pela
  ) return string is
2528 97 pela
    variable hexstr             : string(1 to (s'length+3)/4);
2529
    variable nibble_aligned_s   : std_logic_vector(((s'length+3)/4)*4-1 downto 0) := (others => '0');
2530
    variable nibble             : std_logic_vector(3 downto 0);
2531 14 pela
  begin
2532 97 pela
    nibble_aligned_s(s'length-1 downto 0) := to_descending(s);
2533
    for i in 0 to nibble_aligned_s'high/4 loop
2534
      nibble := nibble_aligned_s(4*i + 3 downto 4*i);
2535
      case nibble is
2536
        when "0000" => hexstr(hexstr'high-i) := '0';
2537
        when "0001" => hexstr(hexstr'high-i) := '1';
2538
        when "0010" => hexstr(hexstr'high-i) := '2';
2539
        when "0011" => hexstr(hexstr'high-i) := '3';
2540
        when "0100" => hexstr(hexstr'high-i) := '4';
2541
        when "0101" => hexstr(hexstr'high-i) := '5';
2542
        when "0110" => hexstr(hexstr'high-i) := '6';
2543
        when "0111" => hexstr(hexstr'high-i) := '7';
2544
        when "1000" => hexstr(hexstr'high-i) := '8';
2545
        when "1001" => hexstr(hexstr'high-i) := '9';
2546
        when "1010" => hexstr(hexstr'high-i) := 'A';
2547
        when "1011" => hexstr(hexstr'high-i) := 'B';
2548
        when "1100" => hexstr(hexstr'high-i) := 'C';
2549
        when "1101" => hexstr(hexstr'high-i) := 'D';
2550
        when "1110" => hexstr(hexstr'high-i) := 'E';
2551
        when "1111" => hexstr(hexstr'high-i) := 'F';
2552
        when "UUUU" => hexstr(hexstr'high-i) := 'U';
2553
        when "XXXX" => hexstr(hexstr'high-i) := 'X';
2554
        when "ZZZZ" => hexstr(hexstr'high-i) := 'Z';
2555
        when "WWWW" => hexstr(hexstr'high-i) := 'W';
2556
        when "LLLL" => hexstr(hexstr'high-i) := 'L';
2557
        when "HHHH" => hexstr(hexstr'high-i) := 'H';
2558
        when "----" => hexstr(hexstr'high-i) := '-';
2559
        when others => hexstr(hexstr'high-i) := '?';
2560
        -- TODO: handle vectors where nibble_aligned_s'length > a'length and the highest nibble are all equal characters such as "XXX"
2561
      end case;
2562
    end loop;
2563
    return prefix & hexstr & postfix;
2564 14 pela
  end function hxstr;
2565 36 pela
 
2566 14 pela
  function hxstr(
2567
    constant s                  : unsigned;
2568 24 pela
    constant prefix             : string := "";
2569
    constant postfix            : string := ""
2570 14 pela
  ) return string is
2571
  begin
2572 97 pela
    return hxstr(std_logic_vector(s), prefix, postfix);
2573 14 pela
  end function hxstr;
2574 36 pela
 
2575 14 pela
  function hxstr(
2576
    constant s                  : signed;
2577 24 pela
    constant prefix             : string := "";
2578
    constant postfix            : string := ""
2579 14 pela
  ) return string is
2580
  begin
2581 97 pela
    return hxstr(std_logic_vector(s), prefix, postfix);
2582 14 pela
  end function hxstr;
2583 36 pela
 
2584 14 pela
  ----------------------------------------------------------------------------
2585 107 pela
  -- Miscellaneous
2586 2 pela
  ----------------------------------------------------------------------------
2587 107 pela
  -- function str converts integer n to a string with fixed length len and
2588
  -- leading fillchar
2589
  function str(
2590
      constant n                  : integer;
2591
      constant len                : integer;
2592
      constant fillchar           : character := ' '
2593
  ) return string is
2594
    variable s     : string(1 to len) := (others => fillchar);
2595
    variable val   : integer := n;
2596
    variable digit : integer;
2597 2 pela
  begin
2598 107 pela
    for i in 0 to len-1 loop
2599
      if val > 0 then
2600
        digit := val mod 10;
2601
        val := val / 10;
2602
        s(len - i) := character'val(character'pos('0') + digit);
2603 24 pela
      end if;
2604 107 pela
    end loop;
2605
    assert val = 0
2606
      report "str: value " & integer'image(n) & " does not fit in string with length " & integer'image(len)
2607
      severity error;
2608
    return s;
2609
  end function str;
2610 36 pela
 
2611 107 pela
  -- Function str_equal returns true if strings s1 and s2 are equal, otherwise false.
2612
  -- The normal VHDL string comparison s1 = s2 only works correctly if the length of 
2613
  -- the strings are equal. str_equal works even if the lengths differ.
2614
  function str_equal (
2615
    constant s1 : STRING;
2616
    constant s2 : STRING
2617
  ) return boolean is
2618 24 pela
  begin
2619 107 pela
    if s1'length /= s2'length then
2620
      return FALSE;
2621
    else
2622
      return (s1 = s2);
2623 101 pela
    end if;
2624 107 pela
  end function str_equal;
2625 36 pela
 
2626 107 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.