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

Subversion Repositories vhld_tb

[/] [vhld_tb/] [trunk/] [source/] [tb_pkg_body.vhd] - Blame information for rev 2

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

Line No. Rev Author Line
1 2 sckoarn
-------------------------------------------------------------------------------
2
--             Copyright 2007  Ken Campbell
3
-------------------------------------------------------------------------------
4
-- $Author: sckoarn $
5
--
6
-- $Date: 2007-04-06 04:06:48 $
7
--
8
-- $Name: not supported by cvs2svn $
9
--
10
-- $Id: tb_pkg_body.vhd,v 1.1.1.1 2007-04-06 04:06:48 sckoarn Exp $
11
--
12
-- $Source: /home/marcus/revision_ctrl_test/oc_cvs/cvs/vhld_tb/source/tb_pkg_body.vhd,v $
13
--
14
-- Description :  The the testbench package body file.
15
--                Initial GNU release.
16
--
17
------------------------------------------------------------------------------
18
--This file is part of The VHDL Test Bench.
19
--
20
--    The VHDL Test Bench is free software; you can redistribute it and/or modify
21
--    it under the terms of the GNU General Public License as published by
22
--    the Free Software Foundation; either version 2 of the License, or
23
--    (at your option) any later version.
24
--
25
--    Foobar is distributed in the hope that it will be useful,
26
--    but WITHOUT ANY WARRANTY; without even the implied warranty of
27
--    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
28
--    GNU General Public License for more details.
29
--
30
--    You should have received a copy of the GNU General Public License
31
--    along with The VHDL Test Bench; if not, write to the Free Software
32
--    Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
33
-------------------------------------------------------------------------------
34
-- Revision History:
35
-- $Log: not supported by cvs2svn $
36
--
37
-------------------------------------------------------------------------------
38
 
39
package body tb_pkg is
40
 
41
-------------------------------------------------------------------------------
42
-- FUNCTION Defs
43
-------------------------------------------------------------------------------
44
--  is_digit
45
 function is_digit(constant c: in character) return boolean is
46
   variable rtn : boolean;
47
 begin
48
   if (c >= '0' and c <= '9') then
49
        rtn := true;
50
   else
51
        rtn := false;
52
   end if;
53
   return rtn;
54
 end is_digit;
55
--------------------------------------
56
-- is_space 
57
 function is_space(constant c: in character) return boolean is
58
   variable rtn : boolean;
59
 begin
60
   if(c = ' ' or c = ht) then
61
        rtn := true;
62
   else
63
        rtn := false;
64
   end if;
65
   return rtn;
66
 end is_space;
67
---------------------------------------------------------------
68
function ew_to_slv(value : in integer;
69
                   length : in integer) return std_logic_vector is
70
    variable result : std_logic_vector((length - 1) downto 0);
71
    variable temp   : natural;
72
    variable power  : natural;
73
 
74
  begin
75
    assert(length > 1)
76
      report LF & "Error: ew_to_slv, Bit length must be greater than 1 to form a vector! "
77
    severity failure;
78
    temp :=  value;
79
    for i in (length - 1) downto 0 loop
80
      power  :=  2**i;
81
      if(temp > ((2**i) - 1)) then
82
        result(i) := '1';
83
        temp :=  temp - ((2**i) - 1);
84
      else
85
        result(i) := '0';
86
      end if;
87
    end loop;
88
 
89
    return result;
90
  end ew_to_slv;
91
------------------------------------------------------------------------------
92
--  to_char
93
  function ew_to_char(int: integer) return character is
94
    variable c: character;
95
  begin
96
    c := nul;
97
    case int is
98
      when 0 => c := '0';
99
      when 1 => c := '1';
100
      when 2 => c := '2';
101
      when 3 => c := '3';
102
      when 4 => c := '4';
103
      when 5 => c := '5';
104
      when 6 => c := '6';
105
      when 7 => c := '7';
106
      when 8 => c := '8';
107
      when 9 => c := '9';
108
      when 10 => c := 'A';
109
      when 11 => c := 'B';
110
      when 12 => c := 'C';
111
      when 13 => c := 'D';
112
      when 14 => c := 'E';
113
      when 15 => c := 'F';
114
      when others =>
115
         assert(false)
116
           report LF & "Error: ew_to_char was given a non Number didgit."
117
         severity failure;
118
    end case;
119
 
120
    return c;
121
  end ew_to_char;
122
 
123
-------------------------------------------------------------------------------
124
--  to_string function  integer
125
  function to_str(int: integer) return string is
126
  begin
127
    return ew_to_str(int,dec) ;
128
  end to_str ;
129
 
130
-------------------------------------------------------------------------------
131
--  ew_str_cat
132
  function ew_str_cat(s1: stm_text;
133
                      s2: text_field) return stm_text is
134
 
135
    variable i:  integer;
136
    variable j:  integer;
137
    variable sc: stm_text;
138
 
139
  begin
140
    sc := s1;
141
    i := 1;
142
    while(sc(i) /= nul) loop
143
      i := i + 1;
144
    end loop;
145
    j := 1;
146
    while(s2(j) /= nul) loop
147
      sc(i) := s2(j);
148
      i := i + 1;
149
      j := j + 1;
150
    end loop;
151
 
152
    return sc;
153
  end ew_str_cat;
154
 
155
-------------------------------------------------------------------------------
156
-- fld_len    field length
157
--          inputs :  string of type text_field
158
--          return :  integer number of non 'nul' chars
159
function fld_len(s : in text_field) return integer is
160
    variable i:  integer := 1;
161
  begin
162
    while(s(i) /= nul) loop
163
      i := i + 1;
164
    end loop;
165
    return (i - 1);
166
  end fld_len;
167
------------------------------------------------------------------------------
168
-- c2int   convert character to integer
169
function c2int(c: in character) return integer is
170
  variable i:  integer;
171
begin
172
  i := -1;
173
  case c is
174
    when '0' => i := 0;
175
    when '1' => i := 1;
176
    when '2' => i := 2;
177
    when '3' => i := 3;
178
    when '4' => i := 4;
179
    when '5' => i := 5;
180
    when '6' => i := 6;
181
    when '7' => i := 7;
182
    when '8' => i := 8;
183
    when '9' => i := 9;
184
    when others =>
185
      assert(false)
186
        report LF & "Error: c2int was given a non Number didgit."
187
      severity failure;
188
  end case;
189
  return i;
190
end c2int;
191
-------------------------------------------------------------------------------
192
-- str2integer   Convert a string to integer number.
193
--   inputs  :  string
194
--   output  :  int value
195
function str2integer(str: in string) return integer is
196
  variable l:   integer;
197
  variable j:   integer := 1;
198
  variable rtn: integer := 0;
199
begin
200
  l := fld_len(str);
201
 
202
  for i in l downto 1 loop
203
    rtn := rtn + (c2int(str(j)) *(10**(i - 1)));
204
    j := j + 1;
205
  end loop;
206
 
207
  return rtn;
208
end str2integer;
209
-------------------------------------------------------------------------------
210
-- hex2integer    convert hex Stimulus field to integer
211
--          inputs :  string of type text_field containing only Hex numbers
212
--          return :  integer value
213
function hex2integer(hex_number:  in text_field;
214
                     file_name:   in text_line;
215
                     line:        in integer) return integer is
216
    variable len:         integer;
217
    variable temp_field:  text_field;
218
    variable temp_int:    integer;
219
    variable power:       integer;
220
    variable int_number:  integer;
221
  begin
222
     len      := fld_len(hex_number);
223
     power    := 0;
224
     temp_int := 0;
225
     for i in len downto 1 loop
226
       case hex_number(i) is
227
         when '0' =>
228
           int_number  := 0;
229
         when '1' =>
230
           int_number  := 1;
231
         when '2' =>
232
           int_number  := 2;
233
         when '3' =>
234
           int_number  := 3;
235
         when '4' =>
236
           int_number  := 4;
237
         when '5' =>
238
           int_number  := 5;
239
         when '6' =>
240
           int_number  := 6;
241
         when '7' =>
242
           int_number  := 7;
243
         when '8' =>
244
           int_number  := 8;
245
         when '9' =>
246
           int_number  := 9;
247
         when 'a' | 'A'=>
248
           int_number  := 10;
249
         when 'b' | 'B'=>
250
           int_number  := 11;
251
         when 'c' | 'C'=>
252
           int_number  := 12;
253
         when 'd' | 'D'=>
254
           int_number  := 13;
255
         when 'e' | 'E'=>
256
           int_number  := 14;
257
         when 'f' | 'F'=>
258
           int_number  := 15;
259
         when others =>
260
         assert(false)
261
           report LF & "Error: hex2integer found non Hex didgit on line "
262
                     & (integer'image(line)) & " of file " & file_name
263
         severity failure;
264
       end case;
265
 
266
       temp_int  := temp_int + (int_number *(16 ** power));
267
       power     := power + 1;
268
     end loop;
269
 
270
     return temp_int;
271
  end hex2integer;
272
-------------------------------------------------------------------------------
273
-- convert character to 4 bit vector
274
--   input    character
275
--   output   std_logic_vector  4 bits
276
function c2std_vec(c: in character) return std_logic_vector is
277
begin
278
  case c is
279
    when '0' =>  return "0000";
280
    when '1' =>  return "0001";
281
    when '2' =>  return "0010";
282
    when '3' =>  return "0011";
283
    when '4' =>  return "0100";
284
    when '5' =>  return "0101";
285
    when '6' =>  return "0110";
286
    when '7' =>  return "0111";
287
    when '8' =>  return "1000";
288
    when '9' =>  return "1001";
289
    when 'a' | 'A' =>  return "1010";
290
    when 'b' | 'B' =>  return "1011";
291
    when 'c' | 'C' =>  return "1100";
292
    when 'd' | 'D' =>  return "1101";
293
    when 'e' | 'E' =>  return "1110";
294
    when 'f' | 'F' =>  return "1111";
295
    when others =>
296
     assert(false)
297
       report LF & "Error: c2std_vec found non Hex didgit on file line "
298
     severity failure;
299
     return "XXXX";
300
  end case;
301
end c2std_vec;
302
-------------------------------------------------------------------------------
303
--  std_vec2c  convert 4 bit std_vector to a character
304
--     input  std_logic_vector 4 bits
305
--     output  character
306
function std_vec2c(vec: in std_logic_vector(3 downto 0)) return character is
307
begin
308
  case vec is
309
    when "0000" => return '0';
310
    when "0001" => return '1';
311
    when "0010" => return '2';
312
    when "0011" => return '3';
313
    when "0100" => return '4';
314
    when "0101" => return '5';
315
    when "0110" => return '6';
316
    when "0111" => return '7';
317
    when "1000" => return '8';
318
    when "1001" => return '9';
319
    when "1010" => return 'A';
320
    when "1011" => return 'B';
321
    when "1100" => return 'C';
322
    when "1101" => return 'D';
323
    when "1110" => return 'E';
324
    when "1111" => return 'F';
325
    when others =>
326
     assert(false)
327
       report LF & "Error: std_vec2c found non-binary didgit in vec "
328
     severity failure;
329
     return 'X';
330
  end case;
331
end std_vec2c;
332
-------------------------------------------------------------------------------
333
-- bin2integer    convert bin Stimulus field to integer
334
--          inputs :  string of type text_field containing only binary numbers
335
--          return :  integer value
336
function bin2integer(bin_number:  in text_field;
337
                     file_name:   in text_line;
338
                     line:        in integer) return integer is
339
    variable len:         integer;
340
    variable temp_field:  text_field;
341
    variable temp_int:    integer;
342
    variable power:       integer;
343
    variable int_number:  integer;
344
  begin
345
     len      := fld_len(bin_number);
346
     power    := 0;
347
     temp_int := 0;
348
     for i in len downto 1 loop
349
       case bin_number(i) is
350
         when '0' =>
351
           int_number  := 0;
352
         when '1' =>
353
           int_number  := 1;
354
         when others =>
355
         assert(false)
356
           report LF & "Error: bin2integer found non Binary didgit on line "
357
                     & (integer'image(line)) & " of file " & file_name
358
         severity failure;
359
       end case;
360
 
361
       temp_int  := temp_int + (int_number *(2 ** power));
362
       power     := power + 1;
363
     end loop;
364
 
365
     return temp_int;
366
  end bin2integer;
367
-------------------------------------------------------------------------------
368
-- stim_to_integer    convert Stimulus field to integer
369
--          inputs :  string of type text_field "stimulus format of number"
370
--          return :  integer value
371
function stim_to_integer(field:      in text_field;
372
                         file_name:  in text_line;
373
                         line:       in integer) return integer is
374
    variable len:       integer;
375
    variable text:      text_field;
376
    variable value:     integer := 1;
377
    variable temp_str : string(1 to 48);
378
  begin
379
    len := fld_len(field);
380
 
381
    case field(1) is
382
      when 'x' | 'h' =>
383
        value := 2;
384
        while(field(value) /= nul) loop
385
          temp_str(value - 1) := field(value);
386
          value := value + 1;
387
        end loop;
388
        value  := hex2integer(temp_str,file_name,line);
389
      when 'b' =>
390
        value := 2;
391
        while(field(value) /= nul) loop
392
          temp_str(value - 1) := field(value);
393
          value := value + 1;
394
        end loop;
395
        value  := bin2integer(temp_str,file_name,line);
396
      when others =>
397
--        value  := from_string(field(1 to len));
398
        value  := str2integer(field);
399
    end case;
400
    return value;
401
  end stim_to_integer;
402
 
403
-------------------------------------------------------------------------------
404
--  to_str function  with base parameter
405
--     Convert integer to number base
406
  function ew_to_str(int: integer; b: base) return text_field is
407
 
408
    variable temp  : text_field ;
409
    variable temp1 : text_field ;
410
    variable radix : integer := 0;
411
    variable num   : integer := 0;
412
    variable power : integer := 1;
413
    variable len   : integer := 1;
414
    variable pre   : string(1 to 2);
415
    variable i     : integer;
416
    variable j     : integer;
417
    variable vec   : std_logic_vector(31 downto 0);
418
 
419
  begin
420
 
421
    num := int;
422
    temp := (others => nul);
423
    case b is
424
      when bin =>
425
        radix := 2;                -- depending on what
426
        pre := "0b";
427
      when oct =>
428
        radix := 8;                -- base the number is
429
        pre := "0o";
430
      when hex =>
431
        radix := 16;               -- to be displayed as
432
        pre := "0x";
433
      when dec =>
434
        radix := 10;               -- choose a radix range
435
        pre := (others => nul);
436
    end case ;
437
    -- Now jump through Hoops because of sign
438
    if(num < 0 and b = hex) then
439
      vec := std_logic_vector(conv_unsigned(int, 32));
440
      temp(1) := std_vec2c(vec(31 downto 28));
441
      temp(2) := std_vec2c(vec(27 downto 24));
442
      temp(3) := std_vec2c(vec(23 downto 20));
443
      temp(4) := std_vec2c(vec(19 downto 16));
444
      temp(5) := std_vec2c(vec(15 downto 12));
445
      temp(6) := std_vec2c(vec(11 downto 8));
446
      temp(7) := std_vec2c(vec(7 downto 4));
447
      temp(8) := std_vec2c(vec(3 downto 0));
448
    else
449
      while num >= radix loop                   -- determine how many
450
        len := len + 1;                        -- characters required
451
        num := num / radix;                    -- to represent the
452
      end loop ;                                -- number.
453
      for i in len downto 1 loop                -- convert the number to
454
        temp(i) := ew_to_char(int/power mod radix); -- a string starting
455
        power := power * radix;                 -- with the right hand
456
      end loop ;                                -- side.
457
    end if;
458
    -- add prefix if is one
459
    if(pre(1) /= nul) then
460
      temp1 := temp;
461
      i := 1;
462
      j := 3;
463
      temp(1 to 2) := pre;
464
      while(temp1(i) /= nul) loop
465
        temp(j) := temp1(i);
466
        i := i + 1;
467
        j := j + 1;
468
      end loop;
469
    end if;
470
 
471
    return temp;
472
 
473
  end ew_to_str ;
474
 
475
-------------------------------------------------------------------------------
476
-- Procedure to print instruction records to stdout  *for debug*
477
  procedure print_inst(variable inst  :  in stim_line_ptr) is
478
    variable l:    text_line;
479
    variable l_i:  integer := 1;
480
    variable j:    integer := 1;
481
  begin
482
    while (inst.instruction(j) /= nul) loop
483
      l(l_i) := inst.instruction(j);
484
      j   := j +1;
485
      l_i := l_i + 1;
486
    end loop;
487
 
488
    l(l_i) := ' ';
489
    l_i := l_i + 1;
490
    j   := 1;
491
    -- field one
492
    if(inst.inst_field_1(1) /= nul) then
493
      while (inst.inst_field_1(j) /= nul) loop
494
        l(l_i) := inst.inst_field_1(j);
495
        j   := j +1;
496
        l_i := l_i + 1;
497
      end loop;
498
      l(l_i) := ' ';
499
      l_i := l_i + 1;
500
      j   := 1;
501
      -- field two
502
      if(inst.inst_field_2(1) /= nul) then
503
        while (inst.inst_field_2(j) /= nul) loop
504
          l(l_i) := inst.inst_field_2(j);
505
          j   := j +1;
506
          l_i := l_i + 1;
507
        end loop;
508
        l(l_i) := ' ';
509
        l_i := l_i + 1;
510
        j   := 1;
511
        -- field three
512
        if(inst.inst_field_3(1) /= nul) then
513
          while (inst.inst_field_3(j) /= nul) loop
514
            l(l_i) := inst.inst_field_3(j);
515
            j   := j +1;
516
            l_i := l_i + 1;
517
          end loop;
518
          l(l_i) := ' ';
519
          l_i := l_i + 1;
520
          j   := 1;
521
          -- field four
522
          if(inst.inst_field_4(1) /= nul) then
523
            while (inst.inst_field_4(j) /= nul) loop
524
              l(l_i) := inst.inst_field_4(j);
525
              j   := j +1;
526
              l_i := l_i + 1;
527
            end loop;
528
          end if;
529
        end if;
530
      end if;
531
    end if;
532
    print(l);
533
 
534
    print("   Sequence Number: " & to_str(inst.line_number) &
535
          "  File Line Number: " & to_str(inst.file_line));
536
    if(inst.num_of_lines > 0) then
537
      print("   Number of Lines: " & to_str(inst.num_of_lines));
538
    end if;
539
  end print_inst;
540
 
541
--------------------------------------------------------------------------------
542
--  access_variable
543
--     inputs:
544
--               Text field containing variable
545
--     outputs:
546
--               value  $VAR  returns Value of VAR
547
--               value  VAR   returns index of VAR
548
--
549
--               valid  is 1 if valid 0 if not
550
  procedure access_variable(variable var_list : in  var_field_ptr;
551
                            variable var      : in text_field;
552
                            variable value    : out integer;
553
                            variable valid    : out integer) is
554
    variable l          : integer;
555
    variable l_2        : integer;
556
    variable var_ptr    : var_field_ptr;
557
    variable temp_field : text_field;
558
    variable ptr        : integer := 0;  -- 0 is index, 1 is pointer
559
  begin
560
    l      := fld_len(var);
561
    valid  := 0;
562
    -- if the variable is a special
563
    if(var(1) = '=') then
564
          value  := 0;
565
          valid  := 1;
566
    elsif(var(1 to 2) = ">=") then
567
          value  := 4;
568
          valid  := 1;
569
    elsif(var(1 to 2) = "<=") then
570
          value  := 5;
571
          valid  := 1;
572
    elsif(var(1) = '>') then
573
          value  := 1;
574
          valid  := 1;
575
    elsif(var(1) = '<') then
576
          value  := 2;
577
          valid  := 1;
578
    elsif(var(1 to 2) = "!=") then
579
          value  := 3;
580
          valid  := 1;
581
 
582
    else
583
      if(var(1) = '$') then
584
        ptr := 1; -- this is a pointer
585
        for i in 2 to l loop
586
          temp_field(i-1) := var(i);
587
        end loop;
588
      else
589
        temp_field  :=  var;
590
      end if;
591
 
592
      var_ptr := var_list;
593
      while(var_ptr.next_rec  /= null) loop
594
        -- if we have a match
595
        if(temp_field = var_ptr.var_name) then
596
          if(ptr = 1) then
597
            value  := var_ptr.var_value;
598
            valid  := 1;
599
          else
600
            value  := var_ptr.var_index;
601
            valid  := 1;
602
          end if;
603
          exit;
604
        end if;
605
        var_ptr := var_ptr.next_rec;
606
      end loop;
607
 
608
      -- if we have a match and was the last record
609
      if(var_ptr.next_rec  = null and temp_field = var_ptr.var_name) then
610
        if(ptr = 1) then
611
          value  := var_ptr.var_value;
612
          valid  := 1;
613
        else
614
          value  := var_ptr.var_index;
615
          valid  := 1;
616
        end if;
617
      end if;
618
    end if;
619
  end access_variable;
620
--------------------------------------------------------------------------------
621
--  index_variable
622
--     inputs:
623
--               index:  the index of the variable being accessed
624
--     outputs:
625
--               Variable Value
626
--               valid  is 1 if valid 0 if not
627
  procedure index_variable(variable var_list : in  var_field_ptr;
628
                           variable index    : in  integer;
629
                           variable value    : out integer;
630
                           variable valid    : out integer) is
631
    variable ptr:  var_field_ptr;
632
  begin
633
    ptr    :=  var_list;
634
    valid  :=  0;
635
    while(ptr.next_rec  /= null) loop
636
      if(ptr.var_index = index) then
637
        value :=  ptr.var_value;
638
        valid :=  1;
639
        exit;
640
      end if;
641
      ptr  :=  ptr.next_rec;
642
    end loop;
643
    if(ptr.var_index = index) then
644
      value :=  ptr.var_value;
645
      valid :=  1;
646
    end if;
647
  end index_variable;
648
 
649
--------------------------------------------------------------------------------
650
--  update_variable
651
--     inputs:
652
--               index:  the index of the variable being updated
653
--     outputs:
654
--               valid  is 1 if valid 0 if not
655
  procedure update_variable(variable var_list : in  var_field_ptr;
656
                           variable index    : in  integer;
657
                           variable value    : in  integer;
658
                           variable valid    : out integer) is
659
    variable ptr:  var_field_ptr;
660
  begin
661
    ptr    :=  var_list;
662
    valid  :=  0;
663
    while(ptr.next_rec  /= null) loop
664
      if(ptr.var_index = index) then
665
        ptr.var_value :=  value;
666
        valid :=  1;
667
        exit;
668
      end if;
669
      ptr  :=  ptr.next_rec;
670
    end loop;
671
    -- check the current one
672
    if(ptr.var_index = index) then
673
      ptr.var_value :=  value;
674
      valid :=  1;
675
    end if;
676
  end update_variable;
677
 
678
-------------------------------------------------------------------------------
679
-- Read a line from a file
680
--   inputs  :   file of type text
681
--   outputs :   The line of type text_line
682
  procedure file_read_line(file file_name: text;
683
                           variable file_line: out text_line
684
                          ) is
685
    variable index:  integer;             -- index into string
686
    variable rline:  line;
687
 
688
  begin
689
 
690
    index := 1;  -- set index to begin of string
691
    file_line := (others => nul);
692
    if(not endfile(file_name)) then
693
      readline(file_name,rline);
694
 
695
      while(rline'right /= (index - 1) and rline'length /= 0) loop
696
        file_line(index) := rline(index);
697
        index    := index + 1;
698
      end loop;
699
    end if;
700
  end file_read_line;
701
 
702
  ------------------------------------------------------------------------------
703
  -- procedure to break a line down in to text fields
704
  procedure tokenize_line(variable text_line:   in  text_line;
705
                          variable token1:      out text_field;
706
                          variable token2:      out text_field;
707
                          variable token3:      out text_field;
708
                          variable token4:      out text_field;
709
                          variable token5:      out text_field;
710
                          variable token6:      out text_field;
711
                          variable token7:      out text_field;
712
                          variable txt_ptr:     out stm_text_ptr;
713
                          variable valid:       out integer) is
714
    variable token_index:     integer  :=  0;
715
    variable current_token:   text_field;
716
    variable token_number:    integer  :=  0;
717
    variable c:               string(1 to 2);
718
    variable comment_found:   integer  :=  0;
719
    variable txt_found:       integer  :=  0;
720
    variable j:               integer;
721
 
722
  begin
723
    -- null outputs
724
    token1  :=  (others => nul);
725
    token2  :=  (others => nul);
726
    token3  :=  (others => nul);
727
    token4  :=  (others => nul);
728
    token5  :=  (others => nul);
729
    token6  :=  (others => nul);
730
    token7  :=  (others => nul);
731
    txt_ptr :=  null;
732
    valid   :=  0;
733
    txt_found  :=  0;
734
    j := 1;
735
 
736
    -- loop for max number of char
737
    for i in 1 to text_line'high loop
738
      -- collect for comment test ** assumed no line will be max 256
739
      c(1)  := text_line(i);
740
      c(2)  := text_line(i + 1);  -- or this line will blow up
741
      if(c = "--") then
742
        comment_found  :=  1;
743
        exit;
744
      end if;
745
      -- if is begin text char '"'
746
      if(c(1) = '"') then  --"  <-- this double quote is just to fix highlighting.
747
        txt_found := 1;
748
        txt_ptr := new stm_text;
749
        next;
750
      end if;
751
 
752
      -- if we have found a txt string
753
      if (txt_found = 1 and text_line(i) /= nul) then
754
        -- if string too long, prevent tool hang, truncate and notify
755
        if(j > c_stm_text_len) then
756
          print("tokenize_line: truncated txt line, it was larger than c_stm_text_len");
757
          exit;
758
        end if;
759
        txt_ptr(j) := text_line(i);
760
        j := j + 1;
761
      -- if is a character store in the right token
762
      elsif(is_space(text_line(i)) = false and text_line(i) /= nul) then
763
        token_index  := token_index + 1;
764
        current_token(token_index)    := text_line(i);
765
      -- else is a space, deal with pointers
766
      elsif(is_space(text_line(i + 1)) = false and text_line(i + 1) /= nul) then
767
        case token_number is
768
          when 0 =>
769
            if(token_index /= 0) then
770
              token1  :=  current_token;
771
              current_token  :=  (others => nul);
772
              token_number := 1;
773
              valid        := 1;
774
              token_index  := 0;
775
            end if;
776
          when 1 =>
777
            token2  :=  current_token;
778
            current_token  :=  (others => nul);
779
            token_number := 2;
780
            valid        := 2;
781
            token_index  := 0;
782
          when 2 =>
783
            token3  :=  current_token;
784
            current_token  :=  (others => nul);
785
            token_number := 3;
786
            valid        := 3;
787
            token_index  := 0;
788
          when 3 =>
789
            token4  :=  current_token;
790
            current_token  :=  (others => nul);
791
            token_number := 4;
792
            valid        := 4;
793
            token_index  := 0;
794
          when 4 =>
795
            token5  :=  current_token;
796
            current_token  :=  (others => nul);
797
            token_number := 5;
798
            valid        := 5;
799
            token_index  := 0;
800
          when 5 =>
801
            token6  :=  current_token;
802
            current_token  :=  (others => nul);
803
            token_number := 6;
804
            valid        := 6;
805
            token_index  := 0;
806
          when 6 =>
807
            token7  :=  current_token;
808
            current_token  :=  (others => nul);
809
            token_number := 7;
810
            valid        := 7;
811
            token_index  := 0;
812
          when 7 =>
813
          when others =>
814
            null;
815
        end case;
816
      end if;
817
      -- break from loop if is null
818
      if(text_line(i) = nul) then
819
        if(token_index /= 0) then
820
          case token_number is
821
            when 0 =>
822
              token1  :=  current_token;
823
              valid   := 1;
824
            when 1 =>
825
              token2  :=  current_token;
826
              valid   := 2;
827
            when 2 =>
828
              token3  :=  current_token;
829
              valid   := 3;
830
            when 3 =>
831
              token4  :=  current_token;
832
              valid   := 4;
833
            when 4 =>
834
              token5  :=  current_token;
835
              valid   := 5;
836
            when 5 =>
837
              token6  :=  current_token;
838
              valid   := 6;
839
            when 6 =>
840
              token7  :=  current_token;
841
              valid   := 7;
842
            when others =>
843
              null;
844
          end case;
845
        end if;
846
        exit;
847
      end if;
848
    end loop;
849
    -- did we find a comment and there is a token
850
    if(comment_found = 1) then
851
      if(token_index /= 0) then
852
        case token_number is
853
          when 0 =>
854
            token1  :=  current_token;
855
            valid   := 1;
856
          when 1 =>
857
            token2  :=  current_token;
858
            valid   := 2;
859
          when 2 =>
860
            token3  :=  current_token;
861
            valid   := 3;
862
          when 3 =>
863
            token4  :=  current_token;
864
            valid   := 4;
865
          when 4 =>
866
            token5  :=  current_token;
867
            valid   := 5;
868
          when 5 =>
869
            token6  :=  current_token;
870
            valid   := 6;
871
          when 6 =>
872
            token7  :=  current_token;
873
            valid   := 7;
874
          when others =>
875
            null;
876
        end case;
877
      end if;
878
    end if;
879
  end tokenize_line;
880
-------------------------------------------------------------------------------
881
-- Add a new instruction to the instruction list
882
--   inputs  :   
883
--   outputs :   
884
  procedure define_instruction(variable inst_set: inout inst_def_ptr;
885
                               constant inst:     in    string;
886
                               constant args:     in    integer) is
887
    variable v_inst_ptr:    inst_def_ptr;
888
    variable v_prev_ptr:    inst_def_ptr;
889
    variable v_new_ptr:     inst_def_ptr;
890
    variable v_temp_inst:   inst_def_ptr;
891
    variable v_length:      integer;
892
    variable v_list_size:   integer;
893
    variable v_dup_error:   boolean;
894
 
895
  begin
896
    assert(inst'high <= max_field_len)
897
      report LF & "Error: Creation of Instruction of length greater than Max_field_len attemped!!" &
898
             LF & "This Max is currently set to " & (integer'image(max_field_len))
899
    severity failure;
900
    -- get to the last element and test is not exsiting
901
    v_temp_inst :=  inst_set;
902
    v_inst_ptr  :=  inst_set;
903
    -- zero the size
904
    v_list_size :=  0;
905
    while(v_inst_ptr /= null) loop
906
      -- if there is a chance of a duplicate command
907
      if(v_inst_ptr.instruction_l = inst'high) then
908
        v_dup_error := true;
909
        for i in 1 to inst'high loop
910
          if(v_inst_ptr.instruction(i) /= inst(i)) then
911
            v_dup_error := false;
912
          end if;
913
        end loop;
914
        -- if we find a duplicate, die
915
        assert(v_dup_error = false)
916
          report LF & "Error: Duplicate instruction definition attempted!"
917
        severity failure;
918
      end if;
919
      v_prev_ptr  := v_inst_ptr;  -- store for pointer updates
920
      v_inst_ptr  := v_inst_ptr.next_rec;
921
      v_list_size :=  v_list_size + 1;
922
    end loop;
923
 
924
    -- add the new instruction
925
    v_new_ptr   := new inst_def;
926
    -- if this is the first command return new pointer
927
    if(v_list_size = 0) then
928
      v_temp_inst :=  v_new_ptr;
929
    -- else write new pointer to next_rec
930
    else
931
      v_prev_ptr.next_rec  :=  v_new_ptr;
932
    end if;
933
    v_new_ptr.instruction_l := inst'high;
934
    v_new_ptr.params        := args;
935
    -- copy the instruction text into field
936
    for i in 1 to v_new_ptr.instruction_l loop
937
      v_new_ptr.instruction(i) := inst(i);
938
    end loop;
939
    -- return the pointer
940
    inst_set  :=  v_temp_inst;
941
 
942
  end define_instruction;
943
 
944
--------------------------------------------------------------------------------
945
--  Check for valid instruction in the list of instructions
946
procedure check_valid_inst(variable inst     :  in text_field;
947
                           variable inst_set :  in inst_def_ptr;
948
                           variable token_num:  in integer;
949
                           variable line_num :  in integer;
950
                           variable name     :  in text_line) is
951
    variable l :     integer  := 0;
952
    variable seti:   inst_def_ptr;
953
    variable match:  integer  := 0;
954
    variable ilv:    integer  := 0;  -- inline variable
955
  begin
956
    -- create useable pointer
957
    seti  := inst_set;
958
    -- count up the characters in inst
959
    l := fld_len(inst);
960
      -- if this is a referance variable -- handle in add variable Proc
961
    if(inst(l) = ':') then
962
      match  := 1;
963
      ilv    := 1;
964
    else
965
      -- process list till null next
966
      while (seti.next_rec /= null) loop
967
        if(seti.instruction_l = l) then
968
          match  := 1;
969
          for j in 1 to l loop
970
            if(seti.instruction(j) /= inst(j)) then
971
              match  := 0;
972
            end if;
973
          end loop;
974
        end if;
975
        if(match = 0) then
976
          seti  := seti.next_rec;
977
        else
978
          exit;
979
        end if;
980
      end loop;
981
      -- check current one
982
      if(seti.instruction_l = l and match = 0) then
983
        match  := 1;
984
        for j in 1 to l loop
985
          if(seti.instruction(j) /= inst(j)) then
986
            match  := 0;
987
          end if;
988
        end loop;
989
      end if;
990
    end if;
991
 
992
    -- if we had a match, check the number of paramiters
993
    if(match = 1 and ilv = 0) then
994
      assert(seti.params = (token_num - 1))
995
        report LF & "Error: Undefined Instruction was found, incorrect number of fields passed!" & LF &
996
                    "This is found on line " & (integer'image(line_num)) & " in file " & name & LF
997
      severity failure;
998
    end if;
999
 
1000
    -- if we find a duplicate, die
1001
    assert(match = 1)
1002
      report LF & "Error: Undefined Instruction on line " & (integer'image(line_num)) &
1003
                  " found in input file " & name & LF
1004
    severity failure;
1005
  end check_valid_inst;
1006
 
1007
--------------------------------------------------------------------------------
1008
--  add_variable
1009
--    This procedure adds a variable to the variable list.  This is localy
1010
--    available at this time.
1011
procedure add_variable(variable var_list  :   inout  var_field_ptr;
1012
                       variable p1        :  in text_field;  -- should be var name
1013
                       variable p2        :  in text_field;  -- should be value
1014
                       variable token_num :  in integer;
1015
                       variable sequ_num  :  in integer;
1016
                       variable line_num  :  in integer;
1017
                       variable name      :  in text_line;
1018
                       variable length    :  in integer) is
1019
 
1020
    variable temp_var:       var_field_ptr;
1021
    variable current_ptr:    var_field_ptr;
1022
    variable index:          integer := 1;
1023
 
1024
  begin
1025
    -- if this is NOT the first one
1026
    if(var_list /= null) then
1027
      current_ptr  := var_list;
1028
      index        := index + 1;
1029
      if(p1(length) /= ':') then  -- is not an inline variable
1030
        while(current_ptr.next_rec /= null) loop
1031
          -- if we have defined the current before then die
1032
          assert(current_ptr.var_name /= p1)
1033
            report LF & "Error: Attemping to add a duplicate Variable definition "
1034
                      & " on line " & (integer'image(line_num)) & " of file " & name
1035
          severity failure;
1036
 
1037
          current_ptr  :=  current_ptr.next_rec;
1038
          index  := index + 1;
1039
        end loop;
1040
        -- if we have defined the current before then die. This checks the last one
1041
        assert(current_ptr.var_name /= p1)
1042
          report LF & "Error: Attemping to add a duplicate Variable definition "
1043
                    & " on line " & (integer'image(line_num)) & " of file " & name
1044
        severity failure;
1045
 
1046
        temp_var              := new var_field;
1047
        temp_var.var_name     := p1;  -- direct write of text_field
1048
        temp_var.var_value    := stim_to_integer(p2,name,line_num); -- convert text_field to integer
1049
        temp_var.var_index    := index;
1050
        current_ptr.next_rec  :=  temp_var;
1051
      else
1052
        while(current_ptr.next_rec /= null) loop
1053
          -- if we have defined the current before then die
1054
          assert(current_ptr.var_name(1 to (length - 1)) /= p1(1 to (length - 1)))
1055
            report LF & "Error: Attemping to add a duplicate Inline Variable definition "
1056
                      & " on line " & (integer'image(line_num)) & " of file " & name
1057
          severity failure;
1058
 
1059
          current_ptr  :=  current_ptr.next_rec;
1060
          index  := index + 1;
1061
        end loop;
1062
        -- if we have defined the current before then die. This checks the last one
1063
        assert(current_ptr.var_name(1 to (length - 1)) /= p1(1 to (length - 1)))
1064
          report LF & "Error: Attemping to add a duplicate Inline Variable definition "
1065
                    & " on line " & (integer'image(line_num)) & " of file " & name
1066
        severity failure;
1067
 
1068
        temp_var              := new var_field;
1069
        temp_var.var_name(1 to (length - 1))     := p1(1 to (length - 1));
1070
        temp_var.var_value    := sequ_num;
1071
        temp_var.var_index    := index;
1072
        current_ptr.next_rec  :=  temp_var;
1073
      end if;
1074
    -- this is the first one
1075
    else
1076
      if(p1(length) /= ':') then  -- is not an inline variable
1077
        temp_var            := new var_field;
1078
        temp_var.var_name   := p1;  -- direct write of text_field
1079
        temp_var.var_index  := index;
1080
        temp_var.var_value  := stim_to_integer(p2,name,line_num); -- convert text_field to integer
1081
        var_list  :=  temp_var;
1082
      else
1083
        temp_var              := new var_field;
1084
        temp_var.var_name(1 to (length - 1))     := p1(1 to (length - 1));
1085
        temp_var.var_value    := sequ_num;
1086
        temp_var.var_index    := index;
1087
        var_list              :=  temp_var;
1088
      end if;
1089
    end if;
1090
  end add_variable;
1091
--------------------------------------------------------------------------------
1092
--  add_instruction
1093
--    This is the procedure that adds the instruction to the linked list of
1094
--    instructions.  Also Variable addition are called and or handled.
1095
--    the instruction sequence Link list.
1096
--     inputs:
1097
--               stim_line_ptr   is the pointer to the instruction List
1098
--               inst            is the instruction token
1099
--               p1              paramitor one, corrisponds to field one of stimulus
1100
--               p2              paramitor one, corrisponds to field two of stimulus
1101
--               p3              paramitor one, corrisponds to field three of stimulus
1102
--               p4              paramitor one, corrisponds to field four of stimulus
1103
--               p5              paramitor one, corrisponds to field three of stimulus
1104
--               p6              paramitor one, corrisponds to field four of stimulus
1105
--               str_ptr         pointer to string for print instruction
1106
--               token_num       the number of tokens, including instruction
1107
--               sequ_num        is the stimulus file line referance  ie program line number
1108
--               line_num        Line number in the text file
1109
--     outputs:
1110
--               none.  Error will terminate sim
1111
  procedure add_instruction(variable inst_list  :  inout stim_line_ptr;
1112
                            variable var_list   :  inout var_field_ptr;
1113
                            variable inst       :  in text_field;
1114
                            variable p1         :  in text_field;
1115
                            variable p2         :  in text_field;
1116
                            variable p3         :  in text_field;
1117
                            variable p4         :  in text_field;
1118
                            variable p5         :  in text_field;
1119
                            variable p6         :  in text_field;
1120
                            variable str_ptr    :  in stm_text_ptr;
1121
                            variable token_num  :  in integer;
1122
                            variable sequ_num   :  inout integer;
1123
                            variable line_num   :  in integer;
1124
                            variable file_name  :  in text_line) is
1125
--   variable temp_string:     string;
1126
   variable temp_stim_line:  stim_line_ptr;
1127
   variable temp_current:    stim_line_ptr;
1128
   variable valid:           integer;
1129
   variable l:               integer;
1130
 begin
1131
   valid  := 1;
1132
   l := fld_len(inst);
1133
   temp_current  :=  inst_list;
1134
   -- take care of special cases
1135
   if(inst(1 to l) = "DEFINE_VAR") then
1136
     l := fld_len(p1);
1137
     --  Add the variable to the Variable pool, not considered an instruction
1138
     add_variable(var_list,p1,p2,token_num,sequ_num,line_num,file_name,l);
1139
   elsif(inst(l) = ':') then
1140
     add_variable(var_list,inst,p1,token_num,sequ_num,line_num,file_name,l);
1141
     valid := 0;
1142
   end if;
1143
 
1144
   if(valid = 1) then
1145
     -- prepare the new record
1146
     temp_stim_line  := new stim_line;
1147
     temp_stim_line.instruction   := inst;
1148
     temp_stim_line.inst_field_1  := p1;
1149
     temp_stim_line.inst_field_2  := p2;
1150
     temp_stim_line.inst_field_3  := p3;
1151
     temp_stim_line.inst_field_4  := p4;
1152
     temp_stim_line.inst_field_5  := p5;
1153
     temp_stim_line.inst_field_6  := p6;
1154
     temp_stim_line.txt           := str_ptr;
1155
     temp_stim_line.line_number   := sequ_num;
1156
     temp_stim_line.file_name     := file_name;
1157
     temp_stim_line.file_line     := line_num;
1158
 
1159
     -- if is not the first instruction
1160
     if(inst_list /= null) then
1161
       while(temp_current.next_rec /= null) loop
1162
         temp_current  := temp_current.next_rec;
1163
       end loop;
1164
       temp_current.next_rec  :=  temp_stim_line;
1165
       inst_list.num_of_lines :=  inst_list.num_of_lines + 1;
1166
     -- other wise is first instruction to be added
1167
     else
1168
       inst_list  :=  temp_stim_line;
1169
       inst_list.num_of_lines := 1;
1170
     end if;
1171
     sequ_num  :=  sequ_num + 1;
1172
--     print_inst(temp_stim_line);  -- for debug
1173
   end if;
1174
 
1175
 end add_instruction;
1176
--------------------------------------------------------------------------------
1177
--  The read include file procedure
1178
--    This is the main procedure for reading, parcing, checking and returning
1179
--    the instruction sequence Link list.
1180
  procedure read_include_file(variable name:       text_line;
1181
                              variable sequ_numb:  inout integer;
1182
                              variable inst_set:   inout inst_def_ptr;
1183
                              variable var_list:   inout var_field_ptr;
1184
                              variable inst_sequ:  inout stim_line_ptr;
1185
                              variable status:     inout integer) is
1186
    variable l:          text_line; -- the line
1187
    variable l_num:      integer;   -- line number file
1188
    variable sequ_line:  integer;   -- line number program
1189
    variable t1:         text_field;
1190
    variable t2:         text_field;
1191
    variable t3:         text_field;
1192
    variable t4:         text_field;
1193
    variable t5:         text_field;
1194
    variable t6:         text_field;
1195
    variable t7:         text_field;
1196
    variable t_txt:      stm_text_ptr;
1197
    variable valid:      integer;
1198
    variable v_inst_ptr: inst_def_ptr;
1199
    variable v_var_prt:  var_field_ptr;
1200
    variable v_sequ_ptr: stim_line_ptr;
1201
    variable v_len:      integer;
1202
    variable v_stat:     file_open_status;
1203
 
1204
  begin
1205
    sequ_line  :=  sequ_numb;
1206
 
1207
    file_open(v_stat, include_file, name, read_mode);
1208
    if(v_stat /= open_ok) then
1209
      print("Error: Unable to open include file  " & name);
1210
      status   :=  1;
1211
      return;
1212
    end if;
1213
    l_num      :=  1;  -- initialize line number
1214
 
1215
    v_inst_ptr :=  inst_set;
1216
    v_var_prt  :=  var_list;
1217
    v_sequ_ptr :=  inst_sequ;
1218
 
1219
    -- while not the end of file read it
1220
    while(not endfile(include_file)) loop
1221
      file_read_line(include_file,l);
1222
      --  tokenize the line
1223
      tokenize_line(l,t1,t2,t3,t4,t5,t6,t7,t_txt,valid);
1224
      v_len  := fld_len(t1);
1225
      if(t1(1 to v_len) = "INCLUDE") then
1226
        print("Nested INCLUDE statement found: " & t2);
1227
       assert(false)
1228
         report LF & "Error: Nested INCLUDE statements are not supported at this time."
1229
       severity failure;
1230
 
1231
      -- if there was valid tokens
1232
      elsif(valid /= 0) then
1233
        check_valid_inst(t1, v_inst_ptr, valid, l_num, name);
1234
        add_instruction(v_sequ_ptr,v_var_prt,t1,t2,t3,t4,t5,t6,t7,t_txt,valid,sequ_line,l_num,name);
1235
      end if;
1236
      l_num  :=  l_num + 1;
1237
    end loop; -- end loop read file
1238
    file_close(include_file);
1239
    sequ_numb  :=  sequ_line;
1240
    inst_set   :=  v_inst_ptr;
1241
    var_list   :=  v_var_prt;
1242
    inst_sequ  :=  v_sequ_ptr;
1243
  end read_include_file;
1244
 
1245
--------------------------------------------------------------------------------
1246
--  The read instruction file procedure
1247
--    This is the main procedure for reading, parcing, checking and returning
1248
--    the instruction sequence Link list.
1249
  procedure read_instruction_file(constant file_name:  string;
1250
                                  variable inst_set:   inout inst_def_ptr;
1251
                                  variable var_list:   inout var_field_ptr;
1252
                                  variable inst_sequ:  inout stim_line_ptr) is
1253
    variable l:          text_line; -- the line
1254
    variable l_num:      integer;   -- line number file
1255
    variable sequ_line:  integer;   -- line number program
1256
    variable t1:         text_field;
1257
    variable t2:         text_field;
1258
    variable t3:         text_field;
1259
    variable t4:         text_field;
1260
    variable t5:         text_field;
1261
    variable t6:         text_field;
1262
    variable t7:         text_field;
1263
    variable t_txt:      stm_text_ptr;
1264
    variable valid:      integer;
1265
    variable v_ostat:    integer;
1266
    variable v_inst_ptr: inst_def_ptr;
1267
    variable v_var_prt:  var_field_ptr;
1268
    variable v_sequ_ptr: stim_line_ptr;
1269
    variable v_len:      integer;
1270
    variable v_stat:     file_open_status;
1271
    variable v_name:     text_line;
1272
    variable v_iname:    text_line;
1273
 
1274
  begin
1275
    -- open the stimulus_file and check
1276
    file_open(v_stat, stimulus, file_name, read_mode);
1277
    assert(v_stat = open_ok)
1278
      report LF & "Error: Unable to open stimulus_file  " & file_name
1279
    severity failure;
1280
    -- copy file name to type text_line
1281
    for i in 1 to file_name'high loop
1282
      v_name(i)  := file_name(i);
1283
    end loop;
1284
 
1285
    l_num      :=  1;
1286
    sequ_line  :=  1;
1287
    v_ostat    :=  0;
1288
 
1289
    v_inst_ptr :=  inst_set;
1290
    v_var_prt  :=  var_list;
1291
    v_sequ_ptr :=  inst_sequ;
1292
 
1293
    -- while not the end of file read it
1294
    while(not endfile(stimulus)) loop
1295
      file_read_line(stimulus,l);
1296
      --  tokenize the line
1297
      tokenize_line(l,t1,t2,t3,t4,t5,t6,t7,t_txt,valid);
1298
      v_len  := fld_len(t1);
1299
      -- if there is an INCLUDE instruction
1300
      if(t1(1 to v_len) = "INCLUDE") then
1301
        if(valid = 2) then
1302
          v_iname  := (others => nul);
1303
          for i in 1 to max_field_len loop
1304
            v_iname(i) := t2(i);
1305
          end loop;
1306
        else
1307
          v_iname  := (others => nul);
1308
          for i in 1 to c_stm_text_len loop
1309
            v_iname(i) := t_txt(i);
1310
          end loop;
1311
        end if;
1312
        print("INCLUDE found: Loading file " & v_iname);
1313
        read_include_file(v_iname,sequ_line,v_inst_ptr,v_var_prt,v_sequ_ptr,v_ostat);
1314
        -- if include file not found
1315
        if(v_ostat = 1) then
1316
          exit;
1317
        end if;
1318
      -- if there was valid tokens
1319
      elsif(valid /= 0) then
1320
        check_valid_inst(t1, v_inst_ptr, valid, l_num, v_name);
1321
        add_instruction(v_sequ_ptr,v_var_prt,t1,t2,t3,t4,t5,t6,t7,t_txt,valid,sequ_line,l_num,v_name);
1322
      end if;
1323
      l_num  :=  l_num + 1;
1324
    end loop; -- end loop read file
1325
 
1326
    file_close(stimulus);  -- close the file when done
1327
 
1328
    assert(v_ostat = 0)
1329
      report LF & "Include file not found! Test Terminated" & LF
1330
    severity failure;
1331
 
1332
    inst_set   :=  v_inst_ptr;
1333
    var_list   :=  v_var_prt;
1334
    inst_sequ  :=  v_sequ_ptr;
1335
  end read_instruction_file;
1336
 
1337
------------------------------------------------------------------------------
1338
-- access_inst_sequ
1339
--  This procedure accesses the instruction sequence and returns the parameters
1340
--  as the exsist related to the variables state.
1341
  procedure access_inst_sequ(variable inst_sequ  :  in  stim_line_ptr;
1342
                             variable var_list   :  in  var_field_ptr;
1343
                             variable sequ_num   :  in  integer;
1344
                             variable inst       :  out text_field;
1345
                             variable p1         :  out integer;
1346
                             variable p2         :  out integer;
1347
                             variable p3         :  out integer;
1348
                             variable p4         :  out integer;
1349
                             variable p5         :  out integer;
1350
                             variable p6         :  out integer;
1351
                             variable txt        :  out stm_text_ptr;
1352
                             variable inst_len   :  out integer;
1353
                             variable fname      :  out text_line;
1354
                             variable file_line  :  out integer
1355
                             ) is
1356
    variable temp_text_field:     text_field;
1357
    variable temp_var:            text_field;
1358
    variable inst_ptr:            stim_line_ptr;
1359
    variable valid:               integer;
1360
    variable line:                integer;  -- value of the file_line
1361
    variable file_name:           text_line;
1362
  begin
1363
--    inst_ptr  :=  inst_sequ;
1364
--    while(inst_ptr.next_rec /= null) loop
1365
--      print_inst(inst_ptr);
1366
--      inst_ptr := inst_ptr.next_rec;
1367
--    end loop;
1368
   -- get to the instruction indicated by sequ_num
1369
    inst_ptr  :=  inst_sequ;
1370
    while(inst_ptr.next_rec /= null) loop
1371
      if(inst_ptr.line_number = sequ_num) then
1372
        exit;
1373
      else
1374
        inst_ptr := inst_ptr.next_rec;
1375
      end if;
1376
    end loop;
1377
    -- output the instruction and its length
1378
    inst := inst_ptr.instruction;
1379
    inst_len := fld_len(inst_ptr.instruction);
1380
    file_line := inst_ptr.file_line;
1381
    line      := inst_ptr.file_line;
1382
    file_name := inst_ptr.file_name;
1383
    fname     := inst_ptr.file_name;
1384
    txt       := inst_ptr.txt;
1385
    -- load parameter one
1386
    temp_text_field  :=  inst_ptr.inst_field_1;
1387
    if(temp_text_field(1) /= nul) then
1388
      -- if this is a numaric field convert to integer
1389
      if(temp_text_field(1) = 'x' or temp_text_field(1) = 'h' or
1390
         temp_text_field(1) = 'b') then
1391
        p1 := stim_to_integer(temp_text_field,file_name,line);
1392
      elsif(is_digit(temp_text_field(1)) = true) then
1393
        p1 := stim_to_integer(temp_text_field,file_name,line);
1394
      else  -- else is a variable, get the value or halt incase of error
1395
        access_variable(var_list,temp_text_field,p1,valid);
1396
        assert(valid = 1)
1397
          report LF & "Error: First variable on stimulus line " & (integer'image(line))
1398
                    & " is not valid!!" & LF & "In file " & file_name
1399
        severity failure;
1400
      end if;
1401
    end if;
1402
    -- load parameter two
1403
    temp_text_field  :=  inst_ptr.inst_field_2;
1404
    if(temp_text_field(1) /= nul) then
1405
      -- if this is a numaric field convert to integer
1406
      if(temp_text_field(1) = 'x' or temp_text_field(1) = 'h' or
1407
         temp_text_field(1) = 'b') then
1408
        p2 := stim_to_integer(temp_text_field,file_name,line);
1409
      elsif(is_digit(temp_text_field(1)) = true) then
1410
        p2 := stim_to_integer(temp_text_field,file_name,line);
1411
      else  -- else is a variable, get the value or halt incase of error
1412
        access_variable(var_list,temp_text_field,p2,valid);
1413
        assert(valid = 1)
1414
          report LF & "Error: Second variable on stimulus line " & (integer'image(line))
1415
                    & " is not valid!!" & LF & "In file " & file_name
1416
        severity failure;
1417
      end if;
1418
    end if;
1419
    -- load parameter three
1420
    temp_text_field  :=  inst_ptr.inst_field_3;
1421
    if(temp_text_field(1) /= nul) then
1422
      -- if this is a numaric field convert to integer
1423
      if(temp_text_field(1) = 'x' or temp_text_field(1) = 'h' or
1424
         temp_text_field(1) = 'b') then
1425
        p3 := stim_to_integer(temp_text_field,file_name,line);
1426
      elsif(is_digit(temp_text_field(1)) = true) then
1427
        p3 := stim_to_integer(temp_text_field,file_name,line);
1428
      else  -- else is a variable, get the value or halt incase of error
1429
        access_variable(var_list,temp_text_field,p3,valid);
1430
        assert(valid = 1)
1431
          report LF & "Error: Third variable on stimulus line " & (integer'image(line))
1432
                    & " is not valid!!" & LF & "In file " & file_name
1433
        severity failure;
1434
      end if;
1435
    end if;
1436
    -- load parameter four
1437
    temp_text_field  :=  inst_ptr.inst_field_4;
1438
    if(temp_text_field(1) /= nul) then
1439
      -- if this is a numaric field convert to integer
1440
      if(temp_text_field(1) = 'x' or temp_text_field(1) = 'h' or
1441
         temp_text_field(1) = 'b') then
1442
        p4 := stim_to_integer(temp_text_field,file_name,line);
1443
      elsif(is_digit(temp_text_field(1)) = true) then
1444
        p4 := stim_to_integer(temp_text_field,file_name,line);
1445
      else  -- else is a variable, get the value or halt incase of error
1446
        access_variable(var_list,temp_text_field,p4,valid);
1447
        assert(valid = 1)
1448
          report LF & "Error: Forth variable on stimulus line " & (integer'image(line))
1449
                    & " is not valid!!" & LF & "In file " & file_name
1450
        severity failure;
1451
      end if;
1452
    end if;
1453
    -- load parameter five
1454
    temp_text_field  :=  inst_ptr.inst_field_5;
1455
    if(temp_text_field(1) /= nul) then
1456
      -- if this is a numaric field convert to integer
1457
      if(temp_text_field(1) = 'x' or temp_text_field(1) = 'h' or
1458
         temp_text_field(1) = 'b') then
1459
        p5 := stim_to_integer(temp_text_field,file_name,line);
1460
      elsif(is_digit(temp_text_field(1)) = true) then
1461
        p5 := stim_to_integer(temp_text_field,file_name,line);
1462
      else  -- else is a variable, get the value or halt incase of error
1463
        access_variable(var_list,temp_text_field,p5,valid);
1464
        assert(valid = 1)
1465
          report LF & "Error: Fifth variable on stimulus line " & (integer'image(line))
1466
                    & " is not valid!!" & LF & "In file " & file_name
1467
        severity failure;
1468
      end if;
1469
    end if;
1470
    -- load parameter six
1471
    temp_text_field  :=  inst_ptr.inst_field_6;
1472
    if(temp_text_field(1) /= nul) then
1473
      -- if this is a numaric field convert to integer
1474
      if(temp_text_field(1) = 'x' or temp_text_field(1) = 'h' or
1475
         temp_text_field(1) = 'b') then
1476
        p6 := stim_to_integer(temp_text_field,file_name,line);
1477
      elsif(is_digit(temp_text_field(1)) = true) then
1478
        p6 := stim_to_integer(temp_text_field,file_name,line);
1479
      else  -- else is a variable, get the value or halt incase of error
1480
        access_variable(var_list,temp_text_field,p6,valid);
1481
        assert(valid = 1)
1482
          report LF & "Error: Sixth variable on stimulus line " & (integer'image(line))
1483
                    & " is not valid!!" & LF & "In file " & file_name
1484
        severity failure;
1485
      end if;
1486
    end if;
1487
  end access_inst_sequ;
1488
 
1489
-------------------------------------------------------------------------
1490
-- dump inst_sequ
1491
--  This procedure dumps to the simulation window the current instruction
1492
--  sequence.  The whole thing will be dumped, which could be big.
1493
--   ** intended for testbench development debug **
1494
  procedure dump_inst_sequ(variable inst_sequ  :  in  stim_line_ptr) is
1495
    variable v_sequ  :  stim_line_ptr;
1496
  begin
1497
    v_sequ  :=  inst_sequ;
1498
    while(v_sequ.next_rec /= null) loop
1499
      print("-----------------------------------------------------------------");
1500
      print("Instruction is " & v_sequ.instruction & "     Par1: "   & v_sequ.inst_field_1 &
1501
      "     Par2: "   & v_sequ.inst_field_2 & "     Par3: "   & v_sequ.inst_field_3 &
1502
      "     Par4: "   & v_sequ.inst_field_4);
1503
      print("Line Number: " & to_str(v_sequ.line_number) & "     File Line Number: " & to_str(v_sequ.file_line) &
1504
      "     File Name: " & v_sequ.file_name);
1505
 
1506
      v_sequ  :=  v_sequ.next_rec;
1507
    end loop;
1508
    -- get the last one
1509
    print("-----------------------------------------------------------------");
1510
    print("Instruction is " & v_sequ.instruction & "     Par1: "   & v_sequ.inst_field_1 &
1511
    "     Par2: "   & v_sequ.inst_field_2 & "     Par3: "   & v_sequ.inst_field_3 &
1512
    "     Par4: "   & v_sequ.inst_field_4);
1513
    print("Line Number: " & to_str(v_sequ.line_number) & "     File Line Number: " & to_str(v_sequ.file_line) &
1514
    "     File Name: " & v_sequ.file_name);
1515
  end dump_inst_sequ;
1516
 
1517
-------------------------------------------------------------------------------
1518
-- Procedure to print messages to stdout
1519
  procedure print(s: in string) is
1520
    variable l: line;
1521
  begin
1522
    write(l, s);
1523
    writeline(output,l);
1524
  end print;
1525
 
1526
-------------------------------------------------------------------------------
1527
--  procedure to print to the stdout the txt pointer
1528
  procedure txt_print(variable ptr: in stm_text_ptr) is
1529
    variable txt_str      : stm_text;
1530
  begin
1531
 
1532
    if (ptr /= null) then
1533
      txt_str := (others => nul);
1534
      for i in 1 to 128 loop
1535
        if (ptr(i) = nul) then
1536
          exit;
1537
        end if;
1538
        txt_str(i) := ptr(i);
1539
      end loop;
1540
      print(txt_str);
1541
    end if;
1542
  end txt_print;
1543
 
1544
-------------------------------------------------------------------------------
1545
--  procedure to print to the stdout the txt pointer, and
1546
--     sub any variables found
1547
  procedure txt_print_wvar(variable var_list : in var_field_ptr;
1548
                           variable ptr      : in stm_text_ptr;
1549
                           constant b        : in base) is
1550
 
1551
    variable i:          integer;
1552
    variable j:          integer;
1553
    variable k:          integer;
1554
    variable txt_str:    stm_text;
1555
    variable tmp_str:    stm_text;
1556
    variable v1:         integer;
1557
    variable valid:      integer;
1558
    variable tmp_field:  text_field;
1559
    variable tmp_i:      integer;
1560
 
1561
  begin
1562
    if(ptr /= null) then
1563
      i := 1;
1564
      j := 1;
1565
      txt_str := (others => nul);
1566
      while(i <= 128 and j <= 128) loop
1567
        if(ptr(i) /= '$') then
1568
          txt_str(j) := ptr(i);
1569
          i := i + 1;
1570
          j := j + 1;
1571
        else
1572
          tmp_field := (others => nul);
1573
          tmp_i := 1;
1574
          tmp_field(tmp_i) := ptr(i);
1575
          i := i + 1;
1576
          tmp_i := tmp_i + 1;
1577
          -- parse to the next space
1578
          while(ptr(i) /= ' ' and ptr(i) /= nul) loop
1579
            tmp_field(tmp_i) := ptr(i);
1580
            i := i + 1;
1581
            tmp_i := tmp_i + 1;
1582
          end loop;
1583
          access_variable(var_list,tmp_field,v1,valid);
1584
          assert(valid = 1)
1585
            report LF & "Invalid Variable found in stm_text_ptr: ignoring."
1586
          severity warning;
1587
 
1588
          if(valid = 1) then
1589
 
1590
            txt_str :=  ew_str_cat(txt_str, ew_to_str(v1, b));
1591
            k := 1;
1592
            while(txt_str(k) /= nul) loop
1593
              k := k + 1;
1594
            end loop;
1595
            j := k;
1596
          end if;
1597
        end if;
1598
      end loop;
1599
      -- print the created string
1600
      print(txt_str);
1601
    end if;
1602
  end txt_print_wvar;
1603
 
1604
end tb_pkg;
1605
 

powered by: WebSVN 2.1.0

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