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