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

Subversion Repositories w11

[/] [w11/] [tags/] [w11a_V0.7/] [rtl/] [vlib/] [simlib/] [simlib.vhd] - Blame information for rev 33

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 27 wfjm
-- $Id: simlib.vhd 599 2014-10-25 13:43:56Z mueller $
2 2 wfjm
--
3 27 wfjm
-- Copyright 2006-2014 by Walter F.J. Mueller <W.F.J.Mueller@gsi.de>
4 2 wfjm
--
5
-- This program is free software; you may redistribute and/or modify it under
6
-- the terms of the GNU General Public License as published by the Free
7
-- Software Foundation, either version 2, or at your option any later version.
8
--
9
-- This program is distributed in the hope that it will be useful, but
10
-- WITHOUT ANY WARRANTY, without even the implied warranty of MERCHANTABILITY
11
-- or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
12
-- for complete details.
13
--
14
------------------------------------------------------------------------------
15
-- Module Name:    simlib - sim
16
-- Description:    Support routines for test benches
17
--
18
-- Dependencies:   -
19
-- Test bench:     -
20
-- Target Devices: generic
21 27 wfjm
-- Tool versions:  xst 8.2-14.7; ghdl 0.18-0.31
22 8 wfjm
--
23 2 wfjm
-- Revision History: 
24
-- Date         Rev Version  Comment
25 27 wfjm
-- 2014-10-25   599   2.1.1  add wait_* procedures; writeoptint: no dat clear
26
-- 2014-10-18   597   2.1    add simfifo_*, writetrace procedures
27
-- 2014-09-06   591   2.0.1  add readint_ea() with range check
28 17 wfjm
-- 2011-12-23   444   2.0    drop CLK_CYCLE from simclk,simclkv; use integer for
29
--                           simclkcnt(CLK_CYCLE),writetimestamp(clkcyc);
30 13 wfjm
-- 2011-11-18   427   1.3.8  now numeric_std clean
31 9 wfjm
-- 2010-12-22   346   1.3.7  rename readcommand -> readdotcomm
32 8 wfjm
-- 2010-11-13   338   1.3.6  add simclkcnt; xx.x ns time in writetimestamp()
33 2 wfjm
-- 2008-03-24   129   1.3.5  CLK_CYCLE now 31 bits
34
-- 2008-03-02   121   1.3.4  added readempty (to discard rest of line)
35
-- 2007-12-27   106   1.3.3  added simclk2v
36
-- 2007-12-15   101   1.3.2  add read_ea(time), readtagval[_ea](std_logic)
37
-- 2007-10-12    88   1.3.1  avoid ieee.std_logic_unsigned, use cast to unsigned
38
-- 2007-08-28    76   1.3    added writehex and writegen
39
-- 2007-08-10    72   1.2.2  remove entity simclk, put into separate source
40
-- 2007-08-03    71   1.2.1  readgen, readtagval, readtagval2: add base arg
41
-- 2007-07-29    70   1.2    readtagval2: add tag=- support; add readword_ea,
42
--                           readoptchar, writetimestamp
43
-- 2007-07-28    69   1.1.1  rename readrest -> testempty; add readgen
44
--                           use readgen in readtagval() and readtagval2()
45
-- 2007-07-22    68   1.1    add readrest, readtagval, readtagval2
46
-- 2007-06-30    62   1.0.1  remove clock_period ect constant defs
47
-- 2007-06-14    56   1.0    Initial version (renamed from pdp11_sim.vhd)
48
------------------------------------------------------------------------------
49
 
50
library ieee;
51
use ieee.std_logic_1164.all;
52 13 wfjm
use ieee.numeric_std.all;
53 2 wfjm
use ieee.std_logic_textio.all;
54
use std.textio.all;
55
 
56
use work.slvtypes.all;
57
 
58
package simlib is
59
 
60
constant null_char : character := character'val(0);            -- '\0'
61
constant null_string : string(1 to 1) := (others=>null_char);  -- "\0"
62
 
63
procedure readwhite(                    -- read over white space
64
  L: inout line);                       -- line
65
 
66
procedure readoct(                      -- read slv in octal base (arb. length)
67
  L: inout line;                        -- line
68
  value: out std_logic_vector;          -- value to be read
69
  good: out boolean);                   -- success flag
70
 
71
procedure readhex(                      -- read slv in hex base (arb. length)
72
  L: inout line;                        -- line
73
  value: out std_logic_vector;          -- value to be read
74
  good: out boolean);                   -- success flag
75
 
76
procedure readgen(                      -- read slv generic base
77
  L: inout line;                        -- line
78
  value: out std_logic_vector;          -- value to be read
79
  good: out boolean;                    -- success flag
80
  base: in integer:= 2);                -- default base
81
 
82
procedure readcomment(
83
  L: inout line;
84
  good: out boolean);
85
 
86 9 wfjm
procedure readdotcomm(
87 2 wfjm
  L: inout line;
88
  name: out string;
89
  good: out boolean);
90
 
91
procedure readword(
92
  L: inout line;
93
  name: out string;
94
  good: out boolean);
95
 
96
procedure readoptchar(
97
  L: inout line;
98
  char: in character;
99
  good: out boolean);
100
 
101
procedure readempty(
102
  L: inout line);
103
 
104
procedure testempty(
105
  L: inout line;
106
  good: out boolean);
107
 
108
procedure testempty_ea(
109
  L: inout line);
110
 
111
procedure read_ea(
112
  L: inout line;
113
  value: out integer);
114
procedure read_ea(
115
  L: inout line;
116
  value: out time);
117
 
118 27 wfjm
procedure readint_ea(
119
  L: inout line;
120
  value: out integer;
121
  imin : in integer := integer'low;
122
  imax : in integer := integer'high);
123
 
124 2 wfjm
procedure read_ea(
125
  L: inout line;
126
  value: out std_logic);
127
procedure read_ea(
128
  L: inout line;
129
  value: out std_logic_vector);
130
 
131
procedure readoct_ea(
132
  L: inout line;
133
  value: out std_logic_vector);
134
 
135
procedure readhex_ea(
136
  L: inout line;
137
  value: out std_logic_vector);
138
 
139
procedure readgen_ea(
140
  L: inout line;
141
  value: out std_logic_vector;
142
  base: in integer:= 2);
143
 
144
procedure readword_ea(
145
  L: inout line;
146
  name: out string);
147
 
148
procedure readtagval(
149
  L: inout line;
150
  tag: in string;
151
  match: out boolean;
152
  val: out std_logic_vector;
153
  good: out boolean;
154
  base: in integer:= 2);
155
procedure readtagval_ea(
156
  L: inout line;
157
  tag: in string;
158
  match: out boolean;
159
  val: out std_logic_vector;
160
  base: in integer:= 2);
161
 
162
procedure readtagval(
163
  L: inout line;
164
  tag: in string;
165
  match: out boolean;
166
  val: out std_logic;
167
  good: out boolean);
168
procedure readtagval_ea(
169
  L: inout line;
170
  tag: in string;
171
  match: out boolean;
172
  val: out std_logic);
173
 
174
procedure readtagval2(
175
  L: inout line;
176
  tag: in string;
177
  match: out boolean;
178
  val1: out std_logic_vector;
179
  val2: out std_logic_vector;
180
  good: out boolean;
181
  base: in integer:= 2);
182
procedure readtagval2_ea(
183
  L: inout line;
184
  tag: in string;
185
  match: out boolean;
186
  val1: out std_logic_vector;
187
  val2: out std_logic_vector;
188
  base: in integer:= 2);
189
 
190
procedure writeoct(                     -- write slv in octal base (arb. length)
191
  L: inout line;                        -- line
192
  value: in std_logic_vector;           -- value to be written
193
  justified: in side:=right;            -- justification (left/right)
194
  field: in width:=0);                  -- field width
195
 
196
procedure writehex(                     -- write slv in hex base (arb. length)
197
  L: inout line;                        -- line
198
  value: in std_logic_vector;           -- value to be written
199
  justified: in side:=right;            -- justification (left/right)
200
  field: in width:=0);                  -- field width
201
 
202
procedure writegen(                     -- write slv in generic base (arb. lth)
203
  L: inout line;                        -- line
204
  value: in std_logic_vector;           -- value to be written
205
  justified: in side:=right;            -- justification (left/right)
206
  field: in width:=0;                   -- field width
207
  base: in integer:= 2);                -- default base
208
 
209 27 wfjm
procedure writetimestamp(               -- write time stamp
210
  L: inout line;                        -- line
211
  str : in string := null_string);      -- 1st string field
212 2 wfjm
 
213 27 wfjm
procedure writetimestamp(               -- write time stamp w/ clk cycle
214
  L: inout line;                        -- line
215
  clkcyc: in integer;                   -- cycle number
216
  str : in string := null_string);      -- 1st string field
217
 
218
procedure writeoptint(                  -- write int if > 0
219
  L: inout line;                        -- line
220
  str : in string;                      -- string
221
  dat : in integer;                     -- int value
222
  field: in width:=0);                  -- field width
223
 
224
procedure writetrace(                   -- debug trace - plain
225
  str : in string);                     -- string
226
procedure writetrace(                   -- debug trace - int
227
  str : in string;                      -- string
228
  dat : in integer);                    -- value
229
procedure writetrace(                   -- debug trace - slbit
230
  str : in string;                      -- string
231
  dat : in slbit);                      -- value
232
procedure writetrace(                   -- debug trace - slv
233
  str : in string;                      -- string
234
  dat : in slv);                        -- value
235
 
236
type clock_dsc is record                -- clock descriptor
237
  period : time;                        -- clock period
238
  hold   : time;                        -- hold time  = clock yo stim time
239
  setup  : time;                        -- setup time = moni to clock time
240
end record;
241
 
242
procedure wait_nextstim(                -- wait for next stim time
243
  signal clk : in slbit;                -- clock
244
  constant clk_dsc : in clock_dsc;      -- clock descriptor
245
  constant cnt : in positive := 1);     -- number of cycles to wait
246
 
247
procedure wait_nextmoni(                -- wait for next moni time
248
  signal clk : in slbit;                -- clock
249
  constant clk_dsc : in clock_dsc;      -- clock descriptor
250
  constant cnt : in positive := 1);     -- number of cycles to wait
251
 
252
procedure wait_stim2moni(               -- wait from stim to moni time
253
  signal clk : in slbit;                -- clock
254
  constant clk_dsc : in clock_dsc);     -- clock descriptor
255
 
256
procedure wait_untilsignal(             -- wait until signal
257
  signal clk : in slbit;                -- clock
258
  constant clk_dsc : in clock_dsc;      -- clock descriptor
259
  signal sig : in slbit;                -- signal
260
  constant val : in slbit;              -- value
261
  variable cnt : out natural);          -- cycle count
262
 
263
type simfifo_type is array (natural range <>, natural range<>) of std_logic;
264
 
265
procedure simfifo_put(                  -- add item to simfifo
266
  cnt : inout natural;                  -- fifo element count
267
  arr : inout simfifo_type;             -- fifo data array
268
  din : in std_logic_vector;            -- element to add
269
  val : in slbit := '1');               -- valid flag
270
 
271
procedure simfifo_get(                  -- get item from simfifo
272
  cnt : inout natural;                  -- fifo element count
273
  arr : inout simfifo_type;             -- fifo data array
274
  dout: out std_logic_vector);          -- element retrieved
275
 
276
procedure simfifo_writetest(            -- test value against simfifo and write
277
  L: inout line;                        -- line
278
  cnt : inout natural;                  -- fifo element count
279
  arr : inout simfifo_type;             -- fifo data array
280
  dat : in std_logic_vector);           -- data to test
281
 
282
procedure simfifo_dump(                 -- dump simfifo
283
  cnt : inout natural;                  -- fifo element count
284
  arr : inout simfifo_type;             -- fifo data array
285
  str : in string := null_string);      -- header text
286
 
287 2 wfjm
-- ----------------------------------------------------------------------------
288
 
289
component simclk is                   -- test bench clock generator
290
  generic (
291
    PERIOD : time := 20 ns;           -- clock period
292
    OFFSET : time := 200 ns);         -- clock offset (first up transition)
293
  port (
294
    CLK  : out slbit;                 -- clock
295
    CLK_STOP : in slbit               -- clock stop trigger
296
  );
297
end component;
298
 
299
component simclkv is                  -- test bench clock generator
300
                                      --  with variable periods
301
  port (
302
    CLK  : out slbit;                 -- clock
303
    CLK_PERIOD : in time;             -- clock period
304
    CLK_HOLD : in slbit;              -- if 1, hold clocks in 0 state
305
    CLK_STOP : in slbit               -- clock stop trigger
306
  );
307
end component;
308
 
309 8 wfjm
component simclkcnt is                -- test bench system clock cycle counter
310
  port (
311
    CLK  : in slbit;                  -- clock
312 17 wfjm
    CLK_CYCLE  : out integer          -- clock cycle number
313 8 wfjm
  );
314
end component;
315
 
316 2 wfjm
end package simlib;
317
 
318
-- ----------------------------------------------------------------------------
319
 
320
package body simlib is
321
 
322
procedure readwhite(                  -- read over white space
323
  L: inout line) is                   -- line
324
  variable ch : character;
325
begin
326
  while L'length>0 loop
327
    ch := L(L'left);
328
    exit when (ch/=' ' and ch/=HT);
329
    read(L,ch);
330
  end loop;
331
 
332
end procedure readwhite;
333
 
334
-- -------------------------------------
335
 
336
procedure readoct(                      -- read slv in octal base (arb. length)
337
  L: inout line;                        -- line 
338
  value: out std_logic_vector;          -- value to be read
339
  good: out boolean) is                 -- success flag
340
 
341
  variable nibble : std_logic_vector(2 downto 0);
342
  variable sum : std_logic_vector(31 downto 0);
343
  variable ndig : integer;              -- number of digits
344
  variable ok : boolean;
345
  variable ichar : character;
346
 
347
begin
348
 
349
  assert not value'ascending(1)
350
    report "readoct called with ascending range"
351
    severity failure;
352
  assert value'length<=32
353
    report "readoct called with value'length > 32"
354
    severity failure;
355
 
356
  readwhite(L);
357
 
358
  ndig := 0;
359
  sum := (others=>'U');
360
 
361
  while L'length>0 loop
362
    ok := true;
363
    case L(L'left) is
364
      when '0' => nibble := "000";
365
      when '1' => nibble := "001";
366
      when '2' => nibble := "010";
367
      when '3' => nibble := "011";
368
      when '4' => nibble := "100";
369
      when '5' => nibble := "101";
370
      when '6' => nibble := "110";
371
      when '7' => nibble := "111";
372
      when 'u'|'U' => nibble := "UUU";
373
      when 'x'|'X' => nibble := "XXX";
374
      when 'z'|'Z' => nibble := "ZZZ";
375
      when '-' => nibble := "---";
376
      when others => ok := false;
377
    end case;
378
 
379
    exit when not ok;
380
    read(L,ichar);
381
    ndig := ndig + 1;
382
    sum(sum'left downto 3) := sum(sum'left-3 downto 0);
383
    sum(2 downto 0) := nibble;
384
  end loop;
385
 
386
  ok := ndig>0;
387
  value := sum(value'range);
388
  good := ok;
389
 
390
end procedure readoct;
391
 
392
-- -------------------------------------
393
 
394
procedure readhex(                      -- read slv in hex base (arb. length)
395
  L: inout line;                        -- line
396
  value: out std_logic_vector;          -- value to be read
397
  good: out boolean) is                 -- success flag
398
 
399
  variable nibble : std_logic_vector(3 downto 0);
400
  variable sum : std_logic_vector(31 downto 0);
401
  variable ndig : integer;              -- number of digits
402
  variable ok : boolean;
403
  variable ichar : character;
404
 
405
begin
406
 
407
  assert not value'ascending(1)
408
    report "readhex called with ascending range"
409
    severity failure;
410
  assert value'length<=32
411
    report "readhex called with value'length > 32"
412
    severity failure;
413
 
414
  readwhite(L);
415
 
416
  ndig := 0;
417
  sum := (others=>'U');
418
 
419
  while L'length>0 loop
420
    ok := true;
421
    case L(L'left) is
422
      when '0'     => nibble := "0000";
423
      when '1'     => nibble := "0001";
424
      when '2'     => nibble := "0010";
425
      when '3'     => nibble := "0011";
426
      when '4'     => nibble := "0100";
427
      when '5'     => nibble := "0101";
428
      when '6'     => nibble := "0110";
429
      when '7'     => nibble := "0111";
430
      when '8'     => nibble := "1000";
431
      when '9'     => nibble := "1001";
432
      when 'a'|'A' => nibble := "1010";
433
      when 'b'|'B' => nibble := "1011";
434
      when 'c'|'C' => nibble := "1100";
435
      when 'd'|'D' => nibble := "1101";
436
      when 'e'|'E' => nibble := "1110";
437
      when 'f'|'F' => nibble := "1111";
438
      when 'u'|'U' => nibble := "UUUU";
439
      when 'x'|'X' => nibble := "XXXX";
440
      when 'z'|'Z' => nibble := "ZZZZ";
441
      when '-'     => nibble := "----";
442
      when others  => ok := false;
443
    end case;
444
 
445
    exit when not ok;
446
    read(L,ichar);
447
    ndig := ndig + 1;
448
    sum(sum'left downto 4) := sum(sum'left-4 downto 0);
449
    sum(3 downto 0) := nibble;
450
  end loop;
451
 
452
  ok := ndig>0;
453
  value := sum(value'range);
454
  good := ok;
455
 
456
end procedure readhex;
457
 
458
-- -------------------------------------
459
 
460
procedure readgen(                    -- read slv generic base
461 13 wfjm
  L: inout line;                      -- line
462
  value: out std_logic_vector;        -- value to be read
463
  good: out boolean;                  -- success flag
464
  base: in integer := 2) is           -- default base
465 2 wfjm
 
466
  variable nibble : std_logic_vector(3 downto 0);
467
  variable sum : std_logic_vector(31 downto 0);
468
  variable lbase : integer;           -- local base
469
  variable cbase : integer;           -- current base
470
  variable ok : boolean;
471
  variable ivalue : integer;
472
  variable ichar : character;
473 13 wfjm
 
474 2 wfjm
begin
475
 
476
  assert not value'ascending(1)
477
    report "readgen called with ascending range"
478
    severity failure;
479
  assert value'length<=32
480
    report "readgen called with value'length > 32"
481
    severity failure;
482
  assert base=2 or base=8 or base=10 or base=16
483
    report "readgen base not 2,8,10, or 16"
484
    severity failure;
485
 
486
  readwhite(L);
487
 
488
  cbase := base;
489
  lbase := 0;
490
  ok := true;
491
 
492
  if L'length >= 2 then
493
    if L(L'left+1) = '"' then
494
      case L(L'left) is
495
        when 'b'|'B' => lbase :=  2;
496
        when 'o'|'O' => lbase :=  8;
497
        when 'd'|'D' => lbase := 10;
498
        when 'x'|'X' => lbase := 16;
499
        when others => ok := false;
500
      end case;
501
    end if;
502
    if lbase /= 0 then
503
      read(L, ichar);
504
      read(L, ichar);
505
      cbase := lbase;
506
    end if;
507
  end if;
508
 
509
  if ok then
510
    case cbase is
511
      when  2 => read(L, value, ok);
512
      when  8 => readoct(L, value, ok);
513
      when 16 => readhex(L, value, ok);
514
      when 10 =>
515
        read(L, ivalue, ok);
516 13 wfjm
        -- the following if allows to enter negative integers, e.g. -1 for all-1
517
        if ivalue >= 0 then
518
          value := slv(to_unsigned(ivalue, value'length));
519
        else
520
          value := slv(to_signed(ivalue, value'length));
521
        end if;
522 2 wfjm
      when others => null;
523
    end case;
524
  end if;
525
 
526
  if ok and lbase/=0 then
527
    if L'length>0 and  L(L'left)='"' then
528
      read(L, ichar);
529
    else
530
      ok := false;
531
    end if;
532
  end if;
533
 
534
  good := ok;
535
 
536
end procedure readgen;
537
 
538
-- -------------------------------------
539
 
540
procedure readcomment(
541
  L: inout line;
542
  good: out boolean) is
543
  variable ichar : character;
544
begin
545
 
546
  readwhite(L);
547
 
548
  good := true;
549
  if L'length > 0 then
550
    good := false;
551
    if L(L'left) = '#' then
552
      good := true;
553
    elsif L(L'left) = 'C' then
554
      good := true;
555
      writeline(output, L);
556
    end if;
557
  end if;
558
 
559
end procedure readcomment;
560
 
561
-- -------------------------------------
562
 
563 9 wfjm
procedure readdotcomm(
564 2 wfjm
  L: inout line;
565
  name: out string;
566
  good: out boolean) is
567
begin
568
 
569
  for i in name'range loop
570
    name(i) := ' ';
571
  end loop;
572
  good := false;
573
 
574
  if L'length>0 and L(L'left)='.' then
575
    readword(L, name, good);
576
  end if;
577
 
578 9 wfjm
end procedure readdotcomm;
579 2 wfjm
 
580
-- -------------------------------------
581
 
582
procedure readword(
583
  L: inout line;
584
  name: out string;
585
  good: out boolean) is
586
 
587
  variable ichar : character;
588
  variable ind : integer;
589
 
590
begin
591
 
592
  assert name'ascending(1)
593
    report "readword called with descending range for name"
594
    severity failure;
595
 
596
  readwhite(L);
597
 
598
  for i in name'range loop
599
    name(i) := ' ';
600
  end loop;
601
  ind := name'left;
602
 
603
  while L'length>0 and ind<=name'right loop
604
    ichar := L(L'left);
605
    exit when ichar=' ' or ichar=',' or ichar='|';
606
    read(L,ichar);
607
    name(ind) := ichar;
608
    ind := ind + 1;
609
  end loop;
610
 
611
  good := ind /= name'left;             -- ok if one non-blank found
612
 
613
end procedure readword;
614
 
615
-- -------------------------------------
616
 
617
procedure readoptchar(
618
  L: inout line;
619
  char: in character;
620
  good: out boolean) is
621
 
622
  variable ichar : character;
623
 
624
begin
625
 
626
  good := false;
627
  if L'length > 0 then
628
    if L(L'left) = char then
629
      read(L, ichar);
630
      good := true;
631
    end if;
632
  end if;
633
 
634
end procedure readoptchar;
635
 
636
-- -------------------------------------
637
 
638
procedure readempty(
639
  L: inout line) is
640
 
641
  variable ch : character;
642
 
643
begin
644
 
645
  while L'length>0 loop               -- anything left ?
646
    read(L,ch);                         -- read and discard it
647
  end loop;
648
 
649
end procedure readempty;
650
 
651
-- -------------------------------------
652
 
653
procedure testempty(
654
  L: inout line;
655
  good: out boolean) is
656
 
657
begin
658
 
659
  readwhite(L);                       -- discard white space
660
  good := true;                       -- good if now empty
661
 
662
  if L'length > 0 then                -- anything left ?
663
    good := false;                    -- assume bad
664
    if L'length >= 2 and              -- check for "--"
665
      L(L'left)='-' and L(L'left+1)='-' then
666
      good := true;                   -- in that case comment -> good
667
    end if;
668
  end if;
669
 
670
end procedure testempty;
671
 
672
-- -------------------------------------
673
 
674
procedure testempty_ea(
675
  L: inout line) is
676
 
677
  variable ok : boolean := false;
678
 
679
begin
680
 
681
  testempty(L, ok);
682
  assert ok report "extra chars in """ & L.all & """" severity failure;
683
 
684
end procedure testempty_ea;
685
 
686
-- -------------------------------------
687
 
688
procedure read_ea(
689
  L: inout line;
690
  value: out integer) is
691
 
692
  variable ok : boolean := false;
693
 
694
begin
695
 
696
  read(L, value, ok);
697
  assert ok report "read(integer) conversion error in """ &
698
                   L.all & """" severity failure;
699
 
700
end procedure read_ea;
701
 
702
-- -------------------------------------
703
 
704
procedure read_ea(
705
  L: inout line;
706
  value: out time) is
707
 
708
  variable ok : boolean := false;
709
 
710
begin
711
 
712
  read(L, value, ok);
713
  assert ok report "read(time) conversion error in """ &
714
                   L.all & """" severity failure;
715
 
716
end procedure read_ea;
717
 
718
-- -------------------------------------
719
 
720 27 wfjm
procedure readint_ea(
721
  L: inout line;
722
  value: out integer;
723
  imin : in integer := integer'low;
724
  imax : in integer := integer'high) is
725
 
726
  variable dat : integer := 0;
727
 
728
begin
729
 
730
  read_ea(L, dat);
731
  assert dat>=imin and dat<=imax
732
    report "readint_ea range check: " &
733
            integer'image(dat) & " not in " &
734
            integer'image(imin) & ":" & integer'image(imax)
735
    severity failure;
736
  value := dat;
737
end procedure readint_ea;
738
 
739
-- -------------------------------------
740
 
741 2 wfjm
procedure read_ea(
742
  L: inout line;
743
  value: out std_logic) is
744
 
745
  variable ok : boolean := false;
746
 
747
begin
748
 
749
  read(L, value, ok);
750
  assert ok report "read(std_logic) conversion error in """ &
751
                   L.all & """" severity failure;
752
 
753
end procedure read_ea;
754
 
755
-- -------------------------------------
756
 
757
procedure read_ea(
758
  L: inout line;
759
  value: out std_logic_vector) is
760
 
761
  variable ok : boolean := false;
762
 
763
begin
764
 
765
  read(L, value, ok);
766
  assert ok report "read(std_logic_vector) conversion error in """ &
767
                   L.all & """" severity failure;
768
 
769
end procedure read_ea;
770
 
771
-- -------------------------------------
772
 
773
procedure readoct_ea(
774
  L: inout line;
775
  value: out std_logic_vector) is
776
 
777
  variable ok : boolean := false;
778
 
779
begin
780
 
781
  readoct(L, value, ok);
782
  assert ok report "readoct() conversion error in """ &
783
                   L.all & """" severity failure;
784
 
785
end procedure readoct_ea;
786
 
787
-- -------------------------------------
788
 
789
procedure readhex_ea(
790
  L: inout line;
791
  value: out std_logic_vector) is
792
 
793
  variable ok : boolean := false;
794
 
795
begin
796
 
797
  readhex(L, value, ok);
798
  assert ok report "readhex() conversion error in """ &
799
                   L.all & """" severity failure;
800
 
801
end procedure readhex_ea;
802
 
803
-- -------------------------------------
804
 
805
procedure readgen_ea(
806
  L: inout line;
807
  value: out std_logic_vector;
808
  base: in integer := 2) is
809
 
810
  variable ok : boolean := false;
811
 
812
begin
813
 
814
  readgen(L, value, ok, base);
815
  assert ok report "readgen() conversion error in """ &
816
                   L.all & """" severity failure;
817
 
818
end procedure readgen_ea;
819
 
820
-- -------------------------------------
821
 
822
procedure readword_ea(
823
  L: inout line;
824
  name: out string) is
825
 
826
  variable ok : boolean := false;
827
 
828
begin
829
 
830
  readword(L, name, ok);
831
  assert ok report "readword() read error in """ &
832
                   L.all & """" severity failure;
833
 
834
end procedure readword_ea;
835
 
836
-- -------------------------------------
837
 
838
procedure readtagval(
839
  L: inout line;
840
  tag: in string;
841
  match: out boolean;
842
  val: out std_logic_vector;
843
  good: out boolean;
844
  base: in integer:= 2) is
845
 
846
  variable itag : string(tag'range);
847
  variable ichar : character;
848
  variable imatch : boolean;
849
 
850
begin
851
 
852
  readwhite(L);
853
 
854
  for i in val'range loop
855
    val(i) := '0';
856
  end loop;
857
  good := true;
858
  imatch := false;
859
 
860
  if L'length > tag'length then
861
    imatch := L(L'left to L'left+tag'length-1) = tag and
862
              L(L'left+tag'length) = '=';
863
    if imatch then
864
      read(L, itag);
865
      read(L, ichar);
866
      readgen(L, val, good, base);
867
    end if;
868
  end if;
869
  match := imatch;
870
 
871
end procedure readtagval;
872
 
873
-- -------------------------------------
874
 
875
procedure readtagval_ea(
876
  L: inout line;
877
  tag: in string;
878
  match: out boolean;
879
  val: out std_logic_vector;
880
  base: in integer:= 2) is
881
 
882
  variable ok : boolean := false;
883
 
884
begin
885
  readtagval(L, tag, match, val, ok, base);
886
  assert ok report "readtagval(std_logic_vector) conversion error in """ &
887
                   L.all & """" severity failure;
888
end procedure readtagval_ea;
889
 
890
-- -------------------------------------
891
 
892
procedure readtagval(
893
  L: inout line;
894
  tag: in string;
895
  match: out boolean;
896
  val: out std_logic;
897
  good: out boolean) is
898
 
899
  variable itag : string(tag'range);
900
  variable ichar : character;
901
  variable imatch : boolean;
902
 
903
begin
904
 
905
  readwhite(L);
906
 
907
  val := '0';
908
  good := true;
909
  imatch := false;
910
 
911
  if L'length > tag'length then
912
    imatch := L(L'left to L'left+tag'length-1) = tag and
913
              L(L'left+tag'length) = '=';
914
    if imatch then
915
      read(L, itag);
916
      read(L, ichar);
917
      read(L, val, good);
918
    end if;
919
  end if;
920
  match := imatch;
921
 
922
end procedure readtagval;
923
 
924
-- -------------------------------------
925
 
926
procedure readtagval_ea(
927
  L: inout line;
928
  tag: in string;
929
  match: out boolean;
930
  val: out std_logic) is
931
 
932
  variable ok : boolean := false;
933
 
934
begin
935
  readtagval(L, tag, match, val, ok);
936
  assert ok report "readtagval(std_logic) conversion error in """ &
937
                   L.all & """" severity failure;
938
end procedure readtagval_ea;
939
 
940
-- -------------------------------------
941
 
942
procedure readtagval2(
943
  L: inout line;
944
  tag: in string;
945
  match: out boolean;
946
  val1: out std_logic_vector;
947
  val2: out std_logic_vector;
948
  good: out boolean;
949
  base: in integer:= 2) is
950
 
951
  variable itag : string(tag'range);
952
  variable imatch : boolean;
953
  variable igood : boolean;
954
  variable ichar : character;
955
  variable ok : boolean;
956
 
957
begin
958
 
959
  readwhite(L);
960
 
961
  for i in val1'range loop            -- zero val1
962
    val1(i) := '0';
963
  end loop;
964
  for i in val2'range loop            -- zero val2
965
    val2(i) := '0';
966
  end loop;
967
  igood := true;
968
  imatch := false;
969
 
970
  if L'length > tag'length then       -- check for tag
971
    imatch := L(L'left to L'left+tag'length-1) = tag and
972
              L(L'left+tag'length) = '=';
973
 
974
    if imatch then                      -- if found
975
      read(L, itag);                    -- remove tag
976
      read(L, ichar);                   -- remove =
977
 
978
      igood := false;
979
      readoptchar(L, '-', ok);          -- check for tag=-
980
      if ok then
981
        for i in val2'range loop        -- set mask to all 1 (ignore)
982
          val2(i) := '1';
983
        end loop;
984
        igood := true;
985
      else                              -- here if tag=bit[,bit]
986
        readgen(L, val1, igood, base);  -- read val1
987
        if igood then
988
          readoptchar(L, ',', ok);      -- check(and remove) ,
989
          if ok then
990
            readgen(L, val2, igood, base); -- and read val2
991
          end if;
992
        end if;
993
      end if;
994
    end if;
995
  end if;
996
 
997
  match := imatch;
998
  good := igood;
999
 
1000
end procedure readtagval2;
1001
 
1002
-- -------------------------------------
1003
 
1004
procedure readtagval2_ea(
1005
  L: inout line;
1006
  tag: in string;
1007
  match: out boolean;
1008
  val1: out std_logic_vector;
1009
  val2: out std_logic_vector;
1010
  base: in integer:= 2) is
1011
 
1012
  variable ok : boolean := false;
1013
 
1014
begin
1015
  readtagval2(L, tag, match, val1, val2, ok, base);
1016
  assert ok report "readtagval2() conversion error in """ &
1017
                   L.all & """" severity failure;
1018
end procedure readtagval2_ea;
1019
 
1020
-- -------------------------------------
1021
 
1022
procedure writeoct(                     -- write slv in octal base (arb. length)
1023
  L: inout line;                        -- line
1024
  value: in std_logic_vector;           -- value to be written
1025
  justified: in side:=right;            -- justification (left/right)
1026
  field: in width:=0) is                -- field width
1027
 
1028
  variable nbit : integer;              -- number of bits
1029
  variable ndig : integer;              -- number of digits
1030
  variable iwidth : integer;
1031
  variable ioffset : integer;
1032
  variable nibble : std_logic_vector(2 downto 0);
1033
  variable ochar : character;
1034
 
1035
begin
1036
 
1037
  assert not value'ascending(1)
1038
    report "writeoct called with ascending range"
1039
    severity failure;
1040
 
1041
  nbit := value'length(1);
1042
  ndig := (nbit+2)/3;
1043
  iwidth := nbit mod 3;
1044
  if iwidth = 0 then
1045
    iwidth := 3;
1046
  end if;
1047
  ioffset := value'left(1) - iwidth+1;
1048
  if justified=right and field>ndig then
1049
    for i in ndig+1 to field loop
1050
      write(L,' ');
1051
    end loop;  -- i
1052
  end if;
1053
  for i in 0 to ndig-1 loop
1054
    nibble := "000";
1055
    nibble(iwidth-1 downto 0) := value(ioffset+iwidth-1 downto ioffset);
1056
    ochar := ' ';
1057
    for i in nibble'range loop
1058
      case nibble(i) is
1059
        when 'U' => ochar := 'U';
1060
        when 'X' => ochar := 'X';
1061
        when 'Z' => ochar := 'Z';
1062
        when '-' => ochar := '-';
1063
        when others => null;
1064
      end case;
1065
    end loop;  -- i
1066
    if ochar = ' ' then
1067 13 wfjm
      write(L,to_integer(unsigned(nibble)));
1068 2 wfjm
    else
1069
      write(L,ochar);
1070
    end if;
1071
    iwidth := 3;
1072
    ioffset := ioffset - 3;
1073
  end loop;  -- i
1074
  if justified=left and field>ndig then
1075
    for i in ndig+1 to field loop
1076
      write(L,' ');
1077
    end loop;  -- i
1078
  end if;
1079
end procedure writeoct;
1080
 
1081
-- -------------------------------------
1082
 
1083
procedure writehex(                     -- write slv in hex base (arb. length)
1084
  L: inout line;                        -- line
1085
  value: in std_logic_vector;           -- value to be written
1086
  justified: in side:=right;            -- justification (left/right)
1087
  field: in width:=0) is                -- field width
1088
 
1089
  variable nbit : integer;              -- number of bits
1090
  variable ndig : integer;              -- number of digits
1091
  variable iwidth : integer;
1092
  variable ioffset : integer;
1093
  variable nibble : std_logic_vector(3 downto 0);
1094
  variable ochar : character;
1095
  variable hextab : string(1 to 16) := "0123456789abcdef";
1096
 
1097
begin
1098
 
1099
  assert not value'ascending(1)
1100
    report "writehex called with ascending range"
1101
    severity failure;
1102
 
1103
  nbit := value'length(1);
1104
  ndig := (nbit+3)/4;
1105
  iwidth := nbit mod 4;
1106
  if iwidth = 0 then
1107
    iwidth := 4;
1108
  end if;
1109
  ioffset := value'left(1) - iwidth+1;
1110
  if justified=right and field>ndig then
1111
    for i in ndig+1 to field loop
1112
      write(L,' ');
1113
    end loop;  -- i
1114
  end if;
1115
  for i in 0 to ndig-1 loop
1116
    nibble := "0000";
1117
    nibble(iwidth-1 downto 0) := value(ioffset+iwidth-1 downto ioffset);
1118
    ochar := ' ';
1119
    for i in nibble'range loop
1120
      case nibble(i) is
1121
        when 'U' => ochar := 'U';
1122
        when 'X' => ochar := 'X';
1123
        when 'Z' => ochar := 'Z';
1124
        when '-' => ochar := '-';
1125
        when others => null;
1126
      end case;
1127
    end loop;  -- i
1128
    if ochar = ' ' then
1129 13 wfjm
      write(L,hextab(to_integer(unsigned(nibble))+1));
1130 2 wfjm
    else
1131
      write(L,ochar);
1132
    end if;
1133
    iwidth := 4;
1134
    ioffset := ioffset - 4;
1135
  end loop;  -- i
1136
  if justified=left and field>ndig then
1137
    for i in ndig+1 to field loop
1138
      write(L,' ');
1139
    end loop;  -- i
1140
  end if;
1141
end procedure writehex;
1142
 
1143
-- -------------------------------------
1144
 
1145
procedure writegen(                     -- write slv in generic base (arb. lth)
1146
  L: inout line;                        -- line
1147
  value: in std_logic_vector;           -- value to be written
1148
  justified: in side:=right;            -- justification (left/right)
1149
  field: in width:=0;                   -- field width
1150
  base: in integer:=2) is               -- default base
1151
 
1152
begin
1153
 
1154
  case base is
1155
    when  2 => write(L, value, justified, field);
1156
    when  8 => writeoct(L, value, justified, field);
1157
    when 16 => writehex(L, value, justified, field);
1158
    when others => report "writegen base not 2,8, or 16"
1159
                     severity failure;
1160
  end case;
1161
 
1162
end procedure writegen;
1163
 
1164
-- -------------------------------------
1165
 
1166
procedure writetimestamp(
1167
  L: inout line;
1168 27 wfjm
  str : in string := null_string) is
1169 2 wfjm
 
1170 8 wfjm
  variable t_nsec  : integer := 0;
1171
  variable t_psec  : integer := 0;
1172
  variable t_dnsec : integer := 0;
1173
 
1174 2 wfjm
begin
1175
 
1176 8 wfjm
  t_nsec  := now / 1 ns;
1177
  t_psec  := (now - t_nsec * 1 ns) / 1 ps;
1178
  t_dnsec := t_psec/100;
1179
 
1180
  write(L, t_nsec, right, 8);
1181
  write(L,'.');
1182
  write(L, t_dnsec, right, 1);
1183
  write(L, string'(" ns"));
1184
 
1185 27 wfjm
  if str /= null_string then
1186
    write(L, str);
1187
  end if;
1188
 
1189
end procedure writetimestamp;
1190
 
1191
-- -------------------------------------
1192
 
1193
procedure writetimestamp(
1194
  L: inout line;
1195
  clkcyc: in integer;
1196
  str: in string := null_string) is
1197
 
1198
 
1199
begin
1200
 
1201
  writetimestamp(L);
1202 17 wfjm
  write(L, clkcyc, right, 7);
1203 2 wfjm
  if str /= null_string then
1204
    write(L, str);
1205
  end if;
1206
 
1207
end procedure writetimestamp;
1208
 
1209 27 wfjm
-- -------------------------------------
1210
 
1211
procedure writeoptint(                  -- write int if > 0
1212
  L: inout line;                        -- line
1213
  str : in string;                      -- string
1214
  dat : in integer;                     -- int value
1215
  field: in width:=0) is                -- field width
1216
 
1217
begin
1218
 
1219
  if dat > 0 then
1220
    write(L, str);
1221
    write(L, dat, right, field);
1222
  end if;
1223
 
1224
end procedure writeoptint;
1225
 
1226
-- -------------------------------------
1227
 
1228
procedure writetrace(                   -- debug trace - plain
1229
  str: in string) is                    -- string
1230
 
1231
  variable oline : line;
1232
 
1233
begin
1234
 
1235
  writetimestamp(oline, " ++ ");
1236
  write(oline, str);
1237
  writeline(output, oline);
1238
 
1239
end procedure writetrace;
1240
 
1241
-- -------------------------------------
1242
 
1243
procedure writetrace(                   -- debug trace - int
1244
  str: in string;                       -- string
1245
  dat : in integer) is                  -- value
1246
 
1247
  variable oline : line;
1248
 
1249
begin
1250
 
1251
  writetimestamp(oline, " ++ ");
1252
  write(oline, str);
1253
  write(oline, dat);
1254
  writeline(output, oline);
1255
 
1256
end procedure writetrace;
1257
 
1258
-- -------------------------------------
1259
 
1260
procedure writetrace(                   -- debug trace - slbit
1261
  str: in string;                       -- string
1262
  dat : in slbit) is                    -- value
1263
 
1264
  variable oline : line;
1265
 
1266
begin
1267
 
1268
  writetimestamp(oline, " ++ ");
1269
  write(oline, str);
1270
  write(oline, dat);
1271
  writeline(output, oline);
1272
 
1273
end procedure writetrace;
1274
 
1275
-- -------------------------------------
1276
 
1277
procedure writetrace(                   -- debug trace - slv
1278
  str: in string;                       -- string
1279
  dat : in slv) is                      -- value
1280
 
1281
  variable oline : line;
1282
 
1283
begin
1284
 
1285
  writetimestamp(oline, " ++ ");
1286
  write(oline, str);
1287
  write(oline, dat);
1288
  writeline(output, oline);
1289
 
1290
end procedure writetrace;
1291
 
1292
-- -------------------------------------
1293
 
1294
procedure wait_nextstim(                -- wait for next stim time
1295
  signal clk : in slbit;                -- clock
1296
  constant clk_dsc : in clock_dsc;      -- clock descriptor
1297
  constant cnt : in positive := 1) is   -- number of cycles to wait
1298
 
1299
begin
1300
 
1301
  for i in 1 to cnt loop
1302
    wait until rising_edge(clk);
1303
    wait for clk_dsc.hold;
1304
  end loop;  -- i
1305
 
1306
end procedure wait_nextstim;
1307
 
1308
-- -------------------------------------
1309
 
1310
procedure wait_nextmoni(                -- wait for next moni time
1311
  signal clk : in slbit;                -- clock
1312
  constant clk_dsc : in clock_dsc;      -- clock descriptor
1313
  constant cnt : in positive := 1) is   -- number of cycles to wait
1314
 
1315
begin
1316
 
1317
  for i in 1 to cnt loop
1318
    wait until rising_edge(clk);
1319
    wait for clk_dsc.period - clk_dsc.setup;
1320
  end loop;  -- i
1321
 
1322
end procedure wait_nextmoni;
1323
 
1324
-- -------------------------------------
1325
 
1326
procedure wait_stim2moni(               -- wait from stim to moni time
1327
  signal clk : in slbit;                -- clock
1328
  constant clk_dsc : in clock_dsc) is   -- clock descriptor
1329
 
1330
begin
1331
 
1332
  wait for clk_dsc.period - clk_dsc.hold - clk_dsc.setup;
1333
 
1334
end procedure wait_stim2moni;
1335
 
1336
-- -------------------------------------
1337
 
1338
procedure wait_untilsignal(             -- wait until signal
1339
  signal clk : in slbit;                -- clock
1340
  constant clk_dsc : in clock_dsc;      -- clock descriptor
1341
  signal sig : in slbit;                -- signal
1342
  constant val : in slbit;              -- value
1343
  variable cnt : out natural) is        -- cycle count
1344
 
1345
  variable cnt_l : natural := 0;
1346
begin
1347
 
1348
  cnt_l := 0;
1349
  while val /= sig loop
1350
    wait_nextmoni(clk, clk_dsc);
1351
    cnt_l := cnt_l + 1;
1352
  end loop;
1353
  cnt := cnt_l;
1354
 
1355
end procedure wait_untilsignal;
1356
 
1357
-- -------------------------------------
1358
 
1359
procedure simfifo_put(                  -- add item to simfifo
1360
  cnt : inout natural;                  -- fifo element count
1361
  arr : inout simfifo_type;             -- fifo data array
1362
  din : in std_logic_vector;            -- element to add
1363
  val : in slbit := '1') is             -- valid flag
1364
 
1365
  variable din_imax : integer := din'length-1;
1366
begin
1367
 
1368
  if val = '0' then
1369
    return;
1370
  end if;
1371
 
1372
  assert cnt < arr'high(1)
1373
    report "simfifo_put: fifo full"
1374
    severity failure;
1375
  assert arr'length(2) = din'length and
1376
         arr'ascending(2) = din'ascending
1377
    report "simfifo_put: arr,din range mismatch"
1378
    severity failure;
1379
 
1380
  for i in 0 to din_imax loop
1381
    arr(cnt, arr'low(2)+i) := din(din'low+i);
1382
  end loop;  -- i
1383
  cnt := cnt + 1;
1384
 
1385
end procedure simfifo_put;
1386
 
1387
-- -------------------------------------
1388
 
1389
procedure simfifo_get(                  -- get item from simfifo
1390
  cnt : inout natural;                  -- fifo element count
1391
  arr : inout simfifo_type;             -- fifo data array
1392
  dout : out std_logic_vector) is       -- element retrieved
1393
 
1394
  variable dout_imax : integer := dout'length-1;
1395
begin
1396
 
1397
  assert cnt > 0
1398
    report "simfifo_put: fifo empty"
1399
    severity failure;
1400
  assert arr'length(2) = dout'length and
1401
         arr'ascending(2) = dout'ascending
1402
    report "simfifo_put: arr,din range mismatch"
1403
    severity failure;
1404
 
1405
  for i in 0 to dout_imax loop
1406
    dout(dout'low+i) := arr(0, arr'low(2)+i);
1407
  end loop;  -- i
1408
  cnt := cnt - 1;
1409
  if cnt > 0 then
1410
    for i in 1 to cnt loop
1411
      for j in 0 to dout_imax loop
1412
        arr(i-1, arr'low(2)+j) := arr(i, arr'low(2)+j);
1413
      end loop;  -- j
1414
    end loop;  -- i
1415
  end if;
1416
 
1417
end procedure simfifo_get;
1418
 
1419
-- -------------------------------------
1420
 
1421
procedure simfifo_writetest(            -- test value against simfifo and write
1422
  L: inout line;                        -- line
1423
  cnt : inout natural;                  -- fifo element count
1424
  arr : inout simfifo_type;             -- fifo data array
1425
  dat : in std_logic_vector) is         -- data to test
1426
 
1427
  variable refdata : slv(dat'range);
1428
 
1429
begin
1430
 
1431
  if cnt = 0 then
1432
    write(L, string'("  FAIL: UNEXPECTED"));
1433
  else
1434
    simfifo_get(cnt, arr, refdata);
1435
    write(L, string'("  CHECK: "));
1436
    if dat = refdata then
1437
      write(L, string'("OK"));
1438
    else
1439
      write(L, string'("FAIL, EXP= "));
1440
      write(L, refdata);
1441
    end if;
1442
  end if;
1443
 
1444
end procedure simfifo_writetest;
1445
 
1446
-- -------------------------------------
1447
 
1448
procedure simfifo_dump(                 -- dump simfifo
1449
  cnt : inout natural;                  -- fifo element count
1450
  arr : inout simfifo_type;             -- fifo data array
1451
  str: in string := null_string) is     -- header text
1452
 
1453
  variable oline : line;
1454
  variable data : slv(arr'range(2));
1455
 
1456
begin
1457
 
1458
  writetimestamp(oline, " ++ ");
1459
  if str /= null_string then
1460
    write(oline, str);
1461
  end if;
1462
  write(oline, string'("  cnt= "));
1463
  write(oline, cnt);
1464
  write(oline, string'("  of "));
1465
  write(oline, arr'high(1));
1466
  write(oline, string'("; drange="));
1467
  write(oline, arr'left(2));
1468
  if arr'ascending(2) then
1469
    write(oline, string'(" to "));
1470
  else
1471
    write(oline, string'(" downto "));
1472
  end if;
1473
  write(oline, arr'right(2));
1474
  writeline(output, oline);
1475
 
1476
  if cnt > 0 then
1477
    for i in 0 to cnt-1 loop
1478
      for j in data'range loop
1479
        data(j) := arr(i,j);
1480
      end loop;  -- j
1481
      write(oline, string'("               - "));
1482
      write(oline, i, right, 2);
1483
      write(oline, string'(" "));
1484
      write(oline, data);
1485
      writeline(output, oline);
1486
    end loop;  -- i
1487
  end if;
1488
 
1489
end procedure simfifo_dump;
1490
 
1491 2 wfjm
end package body simlib;
1492
 

powered by: WebSVN 2.1.0

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