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

Subversion Repositories iicmb

[/] [iicmb/] [trunk/] [src_tb/] [test.vhd] - Blame information for rev 2

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

Line No. Rev Author Line
1 2 sshuv2
 
2
--==============================================================================
3
--                                                                             |
4
--    Project: IIC Multiple Bus Controller (IICMB)                             |
5
--                                                                             |
6
--    Module:  Test package.                                                   |
7
--    Version:                                                                 |
8
--             1.0,   April 29, 2016                                           |
9
--                                                                             |
10
--    Author:  Sergey Shuvalkin, (sshuv2@opencores.org)                        |
11
--                                                                             |
12
--==============================================================================
13
--==============================================================================
14
-- Copyright (c) 2016, Sergey Shuvalkin                                        |
15
-- All rights reserved.                                                        |
16
--                                                                             |
17
-- Redistribution and use in source and binary forms, with or without          |
18
-- modification, are permitted provided that the following conditions are met: |
19
--                                                                             |
20
-- 1. Redistributions of source code must retain the above copyright notice,   |
21
--    this list of conditions and the following disclaimer.                    |
22
-- 2. Redistributions in binary form must reproduce the above copyright        |
23
--    notice, this list of conditions and the following disclaimer in the      |
24
--    documentation and/or other materials provided with the distribution.     |
25
--                                                                             |
26
-- THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" |
27
-- AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE   |
28
-- IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE  |
29
-- ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE    |
30
-- LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR         |
31
-- CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF        |
32
-- SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS    |
33
-- INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN     |
34
-- CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)     |
35
-- ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE  |
36
-- POSSIBILITY OF SUCH DAMAGE.                                                 |
37
--==============================================================================
38
 
39
 
40
library ieee;
41
use ieee.std_logic_1164.all;
42
use ieee.numeric_std.all;
43
 
44
 
45
--==============================================================================
46
package test is
47
 
48
  type integer_array     is array (natural range <>) of integer;
49
  type integer_array_ptr is access integer_array;
50
  type string_ptr        is access string;
51
 
52
  type char_file         is file of character;
53
  ------------------------------------------------------------------------------
54
  -- The file type declaration above implicitly defines the following operations:
55
  -- procedure file_open (                               file f : char_file; name : in string; open_kind : in file_open_kind := read_mode);
56
  -- procedure file_open (status : out file_open_status; file f : char_file; name : in string; open_kind : in file_open_kind := read_mode);
57
  -- procedure file_close(file f : char_file);
58
  -- procedure read (file f : char_file; value : out character);
59
  -- procedure write(file f : char_file; value : in  character);
60
  -- function  endfile(file f : char_file) return boolean;
61
  ------------------------------------------------------------------------------
62
 
63
  file stdin  : char_file open read_mode  is "STD_INPUT";
64
  file stdout : char_file open write_mode is "STD_OUTPUT";
65
 
66
  ------------------------------------------------------------------------------
67
  -- Printing to a file and stdout:
68
  constant newline : string := "" & lf;
69
 
70
  procedure fprint_string(file f : char_file; value : in string);
71
  procedure print_string(value : in string);
72
  --function to_string(value : in integer; width : in positive := 1) return string;
73
  --function to_string(value : in std_logic_vector) return string;
74
 
75
  ------------------------------------------------------------------------------
76
  -- Function for converting integer to string:
77
  function to_string(value  : in integer;
78
                     format : in string  := "d";
79
                     width  : in natural := 0;
80
                     prec   : in natural := 0) return string;
81
  function to_string(value  : in std_logic;
82
                     format : in string  := "b";
83
                     width  : in natural := 0;
84
                     prec   : in natural := 0) return string;
85
  function to_string(value  : in std_logic_vector;
86
                     format : in string  := "x";
87
                     width  : in natural := 0;
88
                     prec   : in natural := 0) return string;
89
  --
90
  -- format string: [FLAGS][WIDTH][.PREC]TYPE
91
  --
92
  --     * FLAGS
93
  --        an optional sequence of characters which control output
94
  --        justification, numeric signs, trailing zeroes, and octal and hex
95
  --        prefixes.  The flag characters are minus (`-'), plus (`+'), space
96
  --        ( ), zero (`0'), and sharp (`#').  They can appear in any
97
  --        combination.
98
  --
99
  --       `-'   The result of the conversion is left justified, and the right
100
  --             is padded with blanks.  If you do not use this flag, the
101
  --             result is right justified, and padded on the left.
102
  --
103
  --       `+'   The result of a signed conversion (as determined by TYPE)
104
  --             will always begin with a plus or minus sign.  (If you do not
105
  --             use this flag, positive values do not begin with a plus sign.)
106
  --
107
  --       `" " (space)'
108
  --             If the first character of a signed conversion specification
109
  --             is not a sign, or if a signed conversion results in no
110
  --             characters, the result will begin with a space.  If the space
111
  --             ( ) flag and the plus (`+') flag both appear, the space flag
112
  --             is ignored.
113
  --
114
  --       `0'   Leading zeroes are used to pad the field width (following any
115
  --             indication of sign or base); no spaces are used for padding.
116
  --             If the zero (`0') and minus (`-') flags both appear, the zero
117
  --             (`0') flag will be ignored.  If a precision PREC is specified,
118
  --             the zero (`0') flag is ignored.  Note that `0' is interpreted
119
  --             as a flag, not as the beginning of a field width.
120
  --   
121
  --       `#'   The result is to be converted to an alternative form,
122
  --             depending on the conversion type character:
123
  --
124
  --            `b'   result will have a `b' prefix.
125
  --
126
  --            `o'   increases precision to force the first digit of the
127
  --                  result to be a zero.
128
  --
129
  --            `x'   result will have a `0x' prefix.
130
  --
131
  --            `X'   result will have a `0X' prefix.
132
  --
133
  --            `all others'
134
  --                  ignored.
135
  --
136
  --     * WIDTH
137
  --        WIDTH is an optional minimum field width.  You can either specify
138
  --        it directly as a decimal integer, or indirectly by using instead
139
  --        an asterisk (`*'), in which case the 'width' argument is used as
140
  --        the field width.
141
  --
142
  --     * PREC
143
  --        an optional field; if present, it is introduced with "." (a
144
  --        period).  This field gives the minimum number of digits of an
145
  --        integer to print.  You can specify the precision either directly as
146
  --        a decimal integer or indirectly by using an asterisk (`*'), in which
147
  --        case a 'prec' argument is used as the precision.  If only a period
148
  --        is specified the precision is zero.
149
  --
150
  --     * TYPE
151
  --        TYPE field specifies what kind of conversion to_string() performs.
152
  --        Here is a table of these:
153
  --
154
  --       `b'   prints a unsigned binary integer;
155
  --
156
  --       `d'   prints a signed decimal integer; (same as `i')
157
  --
158
  --       `i'   prints a signed decimal integer; (same as `d')
159
  --
160
  --       `o'   prints an unsigned octal integer;
161
  --
162
  --       `u'   prints an unsigned decimal integer;
163
  --
164
  --       `x'   prints an unsigned hexadecimal integer (using `abcdef' as
165
  --             digits beyond `9');
166
  --
167
  --       `X'   prints an unsigned hexadecimal integer (using `ABCDEF' as
168
  --             digits beyond `9');
169
  ------------------------------------------------------------------------------
170
 
171
 
172
  ------------------------------------------------------------------------------
173
  -- format: [FLAGS][WIDTH][.PREC][SIZE][TYPE]
174
  --
175
  --     * FLAGS
176
  --
177
  --        an optional sequence of characters which control output
178
  --        justification, numeric signs, decimal points, trailing zeroes, and
179
  --        octal and hex prefixes.  The flag characters are minus (`-'), plus
180
  --        (`+'), space ( ), zero (`0'), and sharp (`#').  They can appear in
181
  --        any combination.
182
  --
183
  --       `-'
184
  --             The result of the conversion is left justified, and the right
185
  --             is padded with blanks.  If you do not use this flag, the
186
  --             result is right justified, and padded on the left.
187
  --
188
  --       `+'
189
  --             The result of a signed conversion (as determined by TYPE)
190
  --             will always begin with a plus or minus sign.  (If you do not
191
  --             use this flag, positive values do not begin with a plus sign.)
192
  --
193
  --       `" " (space)'
194
  --             If the first character of a signed conversion specification
195
  --             is not a sign, or if a signed conversion results in no
196
  --             characters, the result will begin with a space.  If the space
197
  --             ( ) flag and the plus (`+') flag both appear, the space flag
198
  --             is ignored.
199
  --
200
  --       `0'
201
  --             If the TYPE character is `d', `i', `o', `u', `x', `X', `e',
202
  --             `E', `f', `g', or `G': leading zeroes, are used to pad the
203
  --             field width (following any indication of sign or base); no
204
  --             spaces are used for padding.  If the zero (`0') and minus
205
  --             (`-') flags both appear, the zero (`0') flag will be ignored.
206
  --             For `d', `i', `o', `u', `x', and `X' conversions, if a
207
  --             precision PREC is specified, the zero (`0') flag is ignored.
208
  --             Note that `0' is interpreted as a flag, not as the beginning
209
  --             of a field width.
210
  --   
211
  --       `#'
212
  --             The result is to be converted to an alternative form,
213
  --             according to the next character:
214
  --
215
  --            `0'
216
  --                  increases precision to force the first digit of the
217
  --                  result to be a zero.
218
  --
219
  --            `x'
220
  --                  a non-zero result will have a `0x' prefix.
221
  --
222
  --            `X'
223
  --                  a non-zero result will have a `0X' prefix.
224
  --
225
  --            `e, E or f'
226
  --                  The result will always contain a decimal point even if
227
  --                  no digits follow the point.  (Normally, a decimal point
228
  --                  appears only if a digit follows it.)  Trailing zeroes
229
  --                  are removed.
230
  --
231
  --            `g or G'
232
  --                  same as `e' or `E', but trailing zeroes are not removed.
233
  --
234
  --            `all others'
235
  --                  undefined.
236
  --
237
  --      * WIDTH
238
  --
239
  --        WIDTH is an optional minimum field width.  You can either specify
240
  --        it directly as a decimal integer, or indirectly by using instead
241
  --        an asterisk (`*'), in which case an `int' argument is used as the
242
  --        field width.  Negative field widths are not supported; if you
243
  --        attempt to specify a negative field width, it is interpreted as a
244
  --        minus (`-') flag followed by a positive field width.
245
  --
246
  --      * PREC
247
  --
248
  --        an optional field; if present, it is introduced with ``.'' (a
249
  --        period). This field gives the maximum number of characters to
250
  --        print in a conversion; the minimum number of digits of an integer
251
  --        to print, for conversions with TYPE `d', `i', `o', `u', `x', and
252
  --        `X'; the maximum number of significant digits, for the `g' and `G'
253
  --        conversions; or the number of digits to print after the decimal
254
  --        point, for `e', `E', and `f' conversions.  You can specify the
255
  --        precision either directly as a decimal integer or indirectly by
256
  --        using an asterisk (`*'), in which case an `int' argument is used
257
  --        as the precision.  Supplying a negative precision is equivalent to
258
  --        omitting the precision.  If only a period is specified the
259
  --        precision is zero.  If a precision appears with any other
260
  --        conversion TYPE than those listed here, the behavior is undefined.
261
  --
262
  --      * SIZE
263
  --
264
  --        `h', `l', and `L' are optional size characters which override the
265
  --        default way that `printf' interprets the data type of the
266
  --        corresponding argument.  `h' forces the following `d', `i', `o',
267
  --        `u', `x' or `X' conversion TYPE to apply to a `short' or `unsigned
268
  --        short'. `h' also forces a following `n' TYPE to apply to a pointer
269
  --        to a `short'. Similarily, an `l' forces the following `d', `i',
270
  --        `o', `u', `x' or `X' conversion TYPE to apply to a `long' or
271
  --        `unsigned long'.  `l' also forces a following `n' TYPE to apply to
272
  --        a pointer to a `long'.  `l' with `c', `s' is equivalent to `C',
273
  --        `S' respectively.  If an `h' or an `l' appears with another
274
  --        conversion specifier, the behavior is undefined.  `L' forces a
275
  --        following `e', `E', `f', `g' or `G' conversion TYPE to apply to a
276
  --        `long double' argument.  If `L' appears with any other conversion
277
  --        TYPE, the behavior is undefined.
278
  --
279
  --      * TYPE
280
  --
281
  --        TYPE specifies what kind of conversion `printf' performs.  Here is
282
  --        a table of these:
283
  --
284
  --       `%'
285
  --             prints the percent character (`%')
286
  --
287
  --       `c'
288
  --             prints ARG as single character
289
  --
290
  --       `C'
291
  --             prints wchar_t ARG as single multibyte character
292
  --
293
  --       `s'
294
  --             prints characters until precision is reached or a null
295
  --             terminator is encountered; takes a string pointer
296
  --
297
  --       `S'
298
  --             converts wchar_t characters to multibyte output characters
299
  --             until precision is reached or a null wchar_t terminator is
300
  --             encountered; takes a wchar_t pointer
301
  --
302
  --       `d'
303
  --             prints a signed decimal integer; takes an `int' (same as `i')
304
  --
305
  --       `i'
306
  --             prints a signed decimal integer; takes an `int' (same as `d')
307
  --
308
  --       `o'
309
  --             prints a signed octal integer; takes an `int'
310
  --
311
  --       `u'
312
  --             prints an unsigned decimal integer; takes an `int'
313
  --
314
  --       `x'
315
  --             prints an unsigned hexadecimal integer (using `abcdef' as
316
  --             digits beyond `9'); takes an `int'
317
  --
318
  --       `X'
319
  --             prints an unsigned hexadecimal integer (using `ABCDEF' as
320
  --             digits beyond `9'); takes an `int'
321
  --
322
  --       `f'
323
  --             prints a signed value of the form `[-]9999.9999'; takes a
324
  --             floating-point number
325
  --
326
  --       `e'
327
  --             prints a signed     value of the form
328
  --             `[-]9.9999e[+|-]999'; takes a floating-point number
329
  --
330
  --       `E'
331
  --             prints the same way as `e', but using `E' to introduce the
332
  --             exponent; takes a floating-point number
333
  --
334
  --       `g'
335
  --             prints a signed value in either `f' or `e' form, based on
336
  --             given value and precision--trailing zeros and the decimal
337
  --             point are printed only if necessary; takes a floating-point
338
  --             number
339
  --
340
  --       `G'
341
  --             prints the same way as `g', but using `E' for the exponent if
342
  --             an exponent is needed; takes a floating-point number
343
  --
344
  --       `n'
345
  --             stores (in the same object) a count of the characters written;
346
  --             takes a pointer to `int'
347
  --
348
  --       `p'
349
  --             prints a pointer in an implementation-defined format.  This
350
  --             implementation treats the pointer as an `unsigned long' (same
351
  --             as `Lu').
352
  ------------------------------------------------------------------------------
353
 
354
  -- Conversion functions
355
  function to_integer         (value : in string) return integer;
356
 
357
 
358
 
359
 
360
  procedure read_identifier(file f : char_file; value : inout string_ptr);
361
  procedure read_integer(file f : char_file; value : out integer);
362
  procedure find_token(file f : char_file; value : in string);
363
  ------------------------------------------------------------------------------
364
 
365
 
366
  ------------------------------------------------------------------------------
367
  -- Working with commands:
368
  ------------------------------------------------------------------------------
369
  -- First level of abstraction: tokens.
370
  constant max_token_size : integer := 80;
371
  type token_kind is
372
  (
373
    name,
374
    integer_number,
375
    end_of_line,
376
    end_of_file,
377
    start_of_comment,
378
    separator,
379
    not_recognized
380
  );
381
 
382
  type token is record
383
    kind      : token_kind;
384
    value_ptr : string_ptr;
385
  end record;
386
 
387
  procedure read_token(file f : char_file; value : inout token);
388
  procedure write_token(file f : char_file; value : inout token);
389
  --
390
 
391
  ------------------------------------------------------------------------------
392
  -- Second level of abstraction: commands.
393
  -- Maximum number of arguments in a command:
394
  constant max_args_in_command : integer := 4*1024;
395
 
396
  -- Command type:
397
  type command is record
398
    time_cnt : natural;               -- The time, when the command should be applied
399
    id       : string_ptr;            -- Pointer to the command ID.
400
    arg      : integer_array_ptr; -- Pointer to the array of arguments.
401
  end record;
402
 
403
  procedure read_command(file f : char_file; id : in string; cmd : inout command);
404
 
405
  type command_list_elem;
406
  type command_list_elem_ptr is access command_list_elem;
407
  type command_list_elem is record
408
    cmd      : command;
409
    prv      : command_list_elem_ptr;
410
    nxt      : command_list_elem_ptr;
411
  end record;
412
  type command_list is record
413
    number   : natural;
414
    first    : command_list_elem_ptr;
415
    last     : command_list_elem_ptr;
416
  end record;
417
  procedure init_command_list(fname : in string; variable clist : inout command_list; block_id : in string);
418
  procedure put_command(variable clist : inout command_list; cmd : inout command);
419
  procedure get_command(variable clist : inout command_list; cmd : inout command);
420
  ------------------------------------------------------------------------------
421
 
422
end test;
423
--==============================================================================
424
 
425
--==============================================================================
426
package body test is
427
 
428
  constant hexadecimal_chars : string(1 to 32) := "0123456789abcdef0123456789ABCDEF";
429
 
430
  ------------------------------------------------------------------------------
431
  function to_character(value : in std_logic) return character is
432
  begin
433
    case value is
434
      when 'U' => return 'U';
435
      when 'X' => return 'X';
436
      when '0' => return '0';
437
      when '1' => return '1';
438
      when 'Z' => return 'Z';
439
      when 'W' => return 'W';
440
      when 'L' => return 'L';
441
      when 'H' => return 'H';
442
      when '-' => return '-';
443
    end case;
444
  end function to_character;
445
  ------------------------------------------------------------------------------
446
 
447
  ------------------------------------------------------------------------------
448
  procedure fprint_string (file f : char_file; value : in string) is
449
  begin
450
    for i in value'low to value'high loop
451
      write(f, value(i));
452
    end loop;
453
  end procedure fprint_string;
454
  ------------------------------------------------------------------------------
455
 
456
  ------------------------------------------------------------------------------
457
  procedure print_string(value : in string) is
458
  begin
459
    fprint_string(stdout, value);
460
  end procedure print_string;
461
  ------------------------------------------------------------------------------
462
 
463
  ------------------------------------------------------------------------------
464
  procedure read_integer(file f : char_file; value : out integer) is
465
    variable buf  : string(1 to 256);
466
    variable ch0  : character;
467
    variable idx  : positive;
468
  begin
469
    -- Searching for first character:
470
    while true loop
471
      assert not(endfile(f)) report "read_integer(): Unexpected End Of File." severity failure;
472
      read(f, ch0);
473
      exit when ((ch0 >= '0')and(ch0 <= '9'))or(ch0 = '-');
474
    end loop;
475
 
476
    buf(1) := ch0;
477
    idx    := 2;
478
 
479
    -- Reading other characters:
480
    while (not(endfile(f))) loop
481
      read(f, ch0);
482
      if ((ch0 >= '0')and(ch0 <= '9'))or((ch0 >= 'a')and(ch0 <= 'f'))or((ch0 >= 'A')and(ch0 <= 'F'))or(ch0 = 'x') then
483
        buf(idx) := ch0;
484
        idx := idx + 1;
485
      else
486
        exit;
487
      end if;
488
    end loop;
489
    value := to_integer(buf(1 to idx - 1));
490
  end procedure read_integer;
491
  ------------------------------------------------------------------------------
492
 
493
  ------------------------------------------------------------------------------
494
  procedure read_identifier(file f : char_file; value : inout string_ptr) is
495
    variable buf  : string(1 to 256);
496
    variable ch0  : character;
497
    variable idx  : positive;
498
  begin
499
    -- Searching for first character:
500
    while true loop
501
      assert not(endfile(f)) report "read_identifier(): Unexpected End Of File." severity failure;
502
      read(f, ch0);
503
      exit when ((ch0 >= 'A')and(ch0 <= 'Z'))or((ch0 >= 'a')and(ch0 <= 'z'))or(ch0 = '_');
504
    end loop;
505
 
506
    buf(1) := ch0;
507
    idx    := 2;
508
 
509
    -- Reading other characters:
510
    while (not(endfile(f))) loop
511
      read(f, ch0);
512
      if ((ch0 >= 'A')and(ch0 <= 'Z'))or((ch0 >= 'a')and(ch0 <= 'z'))or((ch0 >= '0')and(ch0 <= '9'))or(ch0 = '_') then
513
        buf(idx) := ch0;
514
        idx := idx + 1;
515
      else
516
        exit;
517
      end if;
518
    end loop;
519
    deallocate(value);
520
    value := new string'(buf(1 to idx - 1));
521
  end procedure read_identifier;
522
  ------------------------------------------------------------------------------
523
 
524
  ------------------------------------------------------------------------------
525
  procedure find_token(file f : char_file; value : in string) is
526
    variable ch0  : character;
527
    variable idx  : positive;
528
  begin
529
    idx := value'low;
530
    while true loop
531
      assert not(endfile(f)) report "find_token(" & value & "): Unexpected End Of File." severity failure;
532
      read(f, ch0);
533
      if (ch0 = value(idx)) then
534
        exit when (idx = value'high);
535
        idx := idx + 1;
536
      else
537
        idx := value'low;
538
      end if;
539
    end loop;
540
  end procedure find_token;
541
  ------------------------------------------------------------------------------
542
 
543
 
544
  ------------------------------------------------------------------------------
545
  function to_integer(value : in string) return integer is
546
    variable value_local : integer := 0;
547
    variable start_idx   : positive;
548
    variable negative    : boolean;
549
  begin
550
    if (value'right > 2)and(value(1) = '0')and(value(2) = 'x') then -- hex format
551
      start_idx := 3;
552
 
553
      for i in start_idx to value'right loop
554
        if    (value(i) >= 'a')and(value(i) <= 'f') then
555
          value_local := (16 * value_local) + (character'pos(value(i)) - character'pos('a') + 10);
556
        elsif (value(i) >= 'A')and(value(i) <= 'F') then
557
          value_local := (16 * value_local) + (character'pos(value(i)) - character'pos('A') + 10);
558
        else
559
          value_local := (16 * value_local) + (character'pos(value(i)) - character'pos('0'));
560
        end if;
561
      end loop;
562
    else
563
      if (value(1) = '-') then
564
        negative  := true;
565
        start_idx := 2;
566
      else
567
        negative  := false;
568
        start_idx := 1;
569
      end if;
570
 
571
      for i in start_idx to value'right loop
572
        value_local := (10 * value_local) + (character'pos(value(i)) - character'pos('0'));
573
      end loop;
574
 
575
      if (negative) then
576
        value_local := (-1) * value_local;
577
      end if;
578
    end if;
579
 
580
    return value_local;
581
  end function to_integer;
582
  ------------------------------------------------------------------------------
583
 
584
  --function to_string(value : in integer; width : in positive := 1) return string is
585
  --  variable idx  : positive;
586
  --  variable buf  : string(1 to 80);
587
  --  variable negative : boolean := (value < 0);
588
  --  variable value_local : integer := abs(value);
589
  --begin
590
  --  idx := 80;
591
 
592
  --  if (value_local = 0) then
593
  --    buf(idx) := '0';
594
  --    idx := idx - 1;
595
  --  end if;
596
 
597
  --  while (value_local /= 0) loop
598
  --    buf(idx) := character'val((value_local rem 10) + character'pos('0'));
599
  --    value_local := value_local / 10;
600
  --    idx := idx - 1;
601
  --  end loop;
602
 
603
  --  if (negative) then
604
  --    buf(idx) := '-';
605
  --    idx := idx - 1;
606
  --  end if;
607
 
608
  --  while ((80 - idx) < width) loop
609
  --    buf(idx) := ' ';
610
  --    idx := idx - 1;
611
  --  end loop;
612
 
613
  --  buf(1 to (80 - idx)) := buf((1 + idx) to 80);
614
 
615
  --  return buf(1 to (80 - idx));
616
  --end function to_string;
617
 
618
  --function to_string(value : in std_logic_vector) return string is
619
  --  variable res_string : string((((value'length + 3)/4) + 2) downto 1);
620
  --  variable res_idx    : positive;
621
  --  variable hex_digit  : integer;
622
  --begin
623
 
624
  --  hex_digit := 0;
625
  --  res_idx   := 1;
626
  --  for idx in value'right to value'left loop
627
  --    if    (value(idx)  = '1') then
628
  --      hex_digit := hex_digit + 2**((idx - value'right) rem 4);
629
  --    elsif (value(idx) /= '0') then
630
  --      hex_digit := hex_digit + 100;
631
  --    end if;
632
  --    if (((idx - value'right) rem 4) = 3)or(idx = value'left) then
633
  --      case hex_digit is
634
  --        when  0     => res_string(res_idx) := '0';
635
  --        when  1     => res_string(res_idx) := '1';
636
  --        when  2     => res_string(res_idx) := '2';
637
  --        when  3     => res_string(res_idx) := '3';
638
  --        when  4     => res_string(res_idx) := '4';
639
  --        when  5     => res_string(res_idx) := '5';
640
  --        when  6     => res_string(res_idx) := '6';
641
  --        when  7     => res_string(res_idx) := '7';
642
  --        when  8     => res_string(res_idx) := '8';
643
  --        when  9     => res_string(res_idx) := '9';
644
  --        when 10     => res_string(res_idx) := 'A';
645
  --        when 11     => res_string(res_idx) := 'B';
646
  --        when 12     => res_string(res_idx) := 'C';
647
  --        when 13     => res_string(res_idx) := 'D';
648
  --        when 14     => res_string(res_idx) := 'E';
649
  --        when 15     => res_string(res_idx) := 'F';
650
  --        when others => res_string(res_idx) := 'X';
651
  --      end case;
652
  --      hex_digit := 0;
653
  --      res_idx   := res_idx + 1;
654
  --    end if;
655
  --  end loop;
656
  --  res_string(res_string'left)     := '0';
657
  --  res_string(res_string'left - 1) := 'x';
658
 
659
  --  return res_string;
660
  --end function to_string;
661
 
662
 
663
  ------------------------------------------------------------------------------
664
  -- Working with commands:
665
  ------------------------------------------------------------------------------
666
  -- First level of abstraction: tokens.
667
  procedure read_token(file f : char_file; value : inout token) is
668
    variable ch0  : character;
669
    variable idx  : integer := 1;
670
    variable end_of_token : boolean := false;
671
    variable buf  : string(1 to max_token_size);
672
    variable kind : token_kind;
673
  begin
674
    deallocate(value.value_ptr);
675
    while (idx <= max_token_size)and(end_of_token = false) loop
676
      if (idx = 1) then
677
        if endfile(f) then
678
          kind         := end_of_file;
679
          end_of_token := true;
680
        else
681
          read(f, ch0);
682
          next when (ch0 = ' ')or(ch0 = ht);
683
          buf(idx) := ch0;
684
          idx := idx + 1;
685
 
686
          if    (ch0 = '#') then
687
            kind         := start_of_comment;
688
            end_of_token := true;
689
          elsif ((ch0 >= '0')and(ch0 <= '9'))or(ch0 = '-') then
690
            kind         := integer_number;
691
          elsif ((ch0 >= 'A')and(ch0 <= 'Z'))or((ch0 >= 'a')and(ch0 <= 'z'))or(ch0 = '_') then
692
            kind         := name;
693
          elsif (ch0 = cr) then
694
            kind         := end_of_line;
695
          elsif (ch0 = lf) then
696
            kind         := end_of_line;
697
            end_of_token := true;
698
          elsif (ch0 = ',')or(ch0 = '(')or(ch0 = ')')or(ch0 = '{')or(ch0 = '}')or(ch0 = ':') then
699
            kind         := separator;
700
            end_of_token := true;
701
          else
702
            kind         := not_recognized;
703
            end_of_token := true;
704
          end if;
705
        end if;
706
      else
707
        if endfile(f) then
708
          end_of_token := true;
709
        else
710
          read(f, ch0);
711
          case kind is
712
            when integer_number =>
713
              if ((ch0 >= '0')and(ch0 <= '9'))or((ch0 >= 'a')and(ch0 <= 'f'))or((ch0 >= 'A')and(ch0 <= 'F'))or(ch0 = 'x') then
714
                buf(idx) := ch0;
715
                idx := idx + 1;
716
              else
717
                end_of_token := true;
718
              end if;
719
            when name           =>
720
              if ((ch0 >= 'A')and(ch0 <= 'Z'))or((ch0 >= 'a')and(ch0 <= 'z'))or((ch0 >= '0')and(ch0 <= '9'))or(ch0 = '_') then
721
                buf(idx) := ch0;
722
                idx := idx + 1;
723
              else
724
                end_of_token := true;
725
              end if;
726
            when end_of_line    =>
727
              if (ch0 = lf) then
728
                buf(idx) := ch0;
729
                idx := idx + 1;
730
              end if;
731
              end_of_token := true;
732
            when others         =>
733
              end_of_token := true;
734
          end case;
735
        end if;
736
      end if;
737
    end loop;
738
 
739
    value.kind      := kind;
740
    value.value_ptr := new string'(buf(1 to idx - 1));
741
  end procedure read_token;
742
  ------------------------------------------------------------------------------
743
 
744
  ------------------------------------------------------------------------------
745
  procedure write_token(file f : char_file; value : inout token) is
746
  begin
747
    fprint_string(f, value.value_ptr.all & ' ');
748
  end procedure write_token;
749
  ------------------------------------------------------------------------------
750
  --
751
 
752
  ------------------------------------------------------------------------------
753
  -- Second level of abstraction: commands.
754
  -- <integer_number> <name0> <name1> <{> <integer_number> ... <}>
755
  procedure read_command(file f : char_file; id : in string; cmd : inout command) is
756
    variable tmp_token : token;
757
    variable token_idx : integer := 1;
758
    variable arg_idx   : integer := 1;
759
    variable tmp_array : integer_array(1 to max_args_in_command);
760
  begin
761
    while true loop
762
      read_token(f, tmp_token);
763
 
764
      case tmp_token.kind is
765
        when name             =>
766
          assert (token_idx /= 1) report "read_command(): identifier " &
767
                                         tmp_token.value_ptr.all & " found where should be an integer number." severity failure;
768
          assert (token_idx /= 4) report "read_command(): identifier " &
769
                                         tmp_token.value_ptr.all & " found where should be an { brace." severity failure;
770
          assert (token_idx /= 5) report "read_command(): identifier " &
771
                                         tmp_token.value_ptr.all & " found where should be an } brace or an integer number." severity failure;
772
          if (token_idx = 2) then
773
            if (tmp_token.value_ptr.all /= id) then -- Not our command, go to the end.
774
              while true loop
775
                read_token(f, tmp_token);
776
                exit when (tmp_token.kind = separator)or(tmp_token.value_ptr.all = "}");
777
              end loop;
778
              token_idx := 1;
779
            else
780
              token_idx := 3;
781
            end if;
782
          else
783
            deallocate(cmd.id);
784
            cmd.id := new string'(tmp_token.value_ptr.all);
785
            token_idx := 4;
786
          end if;
787
 
788
        when integer_number   =>
789
          assert (token_idx /= 2) report "read_command(): integer number " &
790
                                         tmp_token.value_ptr.all & " found where should be an identifier." severity failure;
791
          assert (token_idx /= 3) report "read_command(): integer number " &
792
                                         tmp_token.value_ptr.all & " found where should be an identifier." severity failure;
793
          assert (token_idx /= 4) report "read_command(): integer number " &
794
                                         tmp_token.value_ptr.all & " found where should be an { brace." severity failure;
795
          if (token_idx = 1) then
796
            cmd.time_cnt := to_integer(tmp_token.value_ptr.all);
797
            token_idx := 2;
798
          else
799
            tmp_array(arg_idx) := to_integer(tmp_token.value_ptr.all);
800
            arg_idx := arg_idx + 1;
801
          end if;
802
 
803
        when end_of_line      =>
804
          null;
805
 
806
        when end_of_file      =>
807
          exit;
808
 
809
        when start_of_comment =>
810
          while true loop
811
            read_token(f, tmp_token);
812
            exit when (tmp_token.kind = end_of_line)or(tmp_token.kind = end_of_file);
813
          end loop;
814
 
815
        when separator        =>
816
          if (token_idx = 4)and(tmp_token.value_ptr.all = "{") then
817
            token_idx := 5;
818
          elsif (token_idx = 5)and(tmp_token.value_ptr.all = "}") then
819
            token_idx := 6;
820
            exit;
821
          end if;
822
 
823
        when not_recognized   =>
824
          assert false report "read_command(): unknown pattern " & tmp_token.value_ptr.all & " found." severity failure;
825
      end case;
826
    end loop;
827
 
828
    assert (token_idx = 1)or(token_idx = 6) report "read_command(): Unexpected End of File." severity failure;
829
 
830
    if (token_idx = 1) then
831
      cmd.time_cnt := 0;
832
      deallocate(cmd.id);
833
      cmd.id := new string'("stop");
834
      deallocate(cmd.arg);
835
    else
836
      deallocate(cmd.arg);
837
      cmd.arg := new integer_array'(tmp_array(1 to arg_idx - 1));
838
    end if;
839
  end procedure read_command;
840
  ------------------------------------------------------------------------------
841
 
842
 
843
  ------------------------------------------------------------------------------
844
  procedure put_command(variable clist : inout command_list; cmd : inout command) is
845
    variable new_le : command_list_elem_ptr;
846
    variable tmp    : command_list_elem_ptr;
847
  begin
848
    new_le                  := new command_list_elem;
849
    new_le.all.cmd.time_cnt := cmd.time_cnt;
850
    new_le.all.cmd.id       := new string'(cmd.id.all);
851
    new_le.all.cmd.arg      := new integer_array'(cmd.arg.all);
852
 
853
    if (clist.number = 0) then
854
      -- The command list is empty.
855
      new_le.all.prv      := null;
856
      new_le.all.nxt      := null;
857
      clist.first         := new_le;
858
      clist.last          := new_le;
859
    else
860
      -- The command list is not empty.
861
      new_le.all.prv      := clist.last;
862
      new_le.all.nxt      := null;
863
      clist.last.all.nxt  := new_le;
864
      clist.last          := new_le;
865
    end if;
866
    clist.number   := clist.number + 1;
867
  end procedure put_command;
868
  ------------------------------------------------------------------------------
869
 
870
  ------------------------------------------------------------------------------
871
  procedure init_command_list(fname : in string; variable clist : inout command_list; block_id : in string) is
872
    file     cmd_data : char_file;
873
    variable cmd      : command;
874
  begin
875
    file_open(cmd_data, fname, read_mode);
876
 
877
    clist.number   := 0;
878
    clist.first    := null;
879
    clist.last     := null;
880
 
881
    while (true) loop
882
      read_command(cmd_data, block_id, cmd);
883
      exit when (cmd.id.all = "stop");
884
      put_command(clist, cmd);
885
    end loop;
886
 
887
    deallocate(cmd.id);
888
    deallocate(cmd.arg);
889
    file_close(cmd_data);
890
  end procedure init_command_list;
891
  ------------------------------------------------------------------------------
892
 
893
  ------------------------------------------------------------------------------
894
  procedure get_command(variable clist : inout command_list; cmd : inout command) is
895
    variable old_el : command_list_elem_ptr;
896
  begin
897
    deallocate(cmd.id);
898
    deallocate(cmd.arg);
899
    if (clist.number = 0) then
900
      cmd.time_cnt := 0;
901
      cmd.id       := new string'("stop");
902
    else
903
      if (clist.number = 1) then
904
        old_el         := clist.first;
905
        clist.number   := clist.number - 1;
906
        clist.first    := null;
907
        clist.last     := null;
908
      else
909
        old_el         := clist.first;
910
        clist.number   := clist.number - 1;
911
        clist.first    := clist.first.all.nxt;
912
        old_el.all.nxt.all.prv := null;
913
      end if;
914
      cmd.time_cnt := old_el.all.cmd.time_cnt;
915
      cmd.id       := new string'(old_el.all.cmd.id.all);
916
      cmd.arg      := new integer_array'(old_el.all.cmd.arg.all);
917
      deallocate(old_el.all.cmd.id);
918
      deallocate(old_el.all.cmd.arg);
919
      deallocate(old_el);
920
    end if;
921
  end procedure get_command;
922
  ------------------------------------------------------------------------------
923
 
924
 
925
 
926
 
927
  ------------------------------------------------------------------------------
928
  function to_string(value  : in std_logic;
929
                     format : in string  := "b";
930
                     width  : in natural := 0;
931
                     prec   : in natural := 0) return string is
932
  begin
933
    return to_string("" & value, format, width, prec);
934
  end function to_string;
935
  ------------------------------------------------------------------------------
936
 
937
  ------------------------------------------------------------------------------
938
  function sel(arg0 : boolean; arg1 : integer; arg2 : integer) return integer is
939
  begin
940
    if (arg0) then return arg1; else return arg2; end if;
941
  end function sel;
942
  ------------------------------------------------------------------------------
943
 
944
  ------------------------------------------------------------------------------
945
  function sel(arg0 : boolean; arg1 : std_logic; arg2 : std_logic) return std_logic is
946
  begin
947
    if (arg0) then return arg1; else return arg2; end if;
948
  end function sel;
949
  ------------------------------------------------------------------------------
950
 
951
  ------------------------------------------------------------------------------
952
  function sel(arg0 : boolean; arg1 : character; arg2 : character) return character is
953
  begin
954
    if (arg0) then return arg1; else return arg2; end if;
955
  end function sel;
956
  ------------------------------------------------------------------------------
957
 
958
  ------------------------------------------------------------------------------
959
  function max(arg0 : integer; arg1 : integer) return integer is
960
  begin
961
    return sel(arg0 > arg1, arg0, arg1);
962
  end function max;
963
  ------------------------------------------------------------------------------
964
 
965
  ------------------------------------------------------------------------------
966
  function signed_num_bits(arg : integer) return positive is
967
    variable nbits : natural := 1;
968
    variable n     : natural := sel(arg < 0, -(arg + 1), arg);
969
  begin
970
    while (n > 0) loop
971
      nbits := nbits + 1;
972
      n     := n / 2;
973
    end loop;
974
    return nbits;
975
  end function signed_num_bits;
976
  ------------------------------------------------------------------------------
977
 
978
  ------------------------------------------------------------------------------
979
  function to_string(value  : in integer;
980
                     format : in string  := "d";
981
                     width  : in natural := 0;
982
                     prec   : in natural := 0) return string is
983
    variable tmp      : std_logic_vector(signed_num_bits(integer'high) - 1 downto 0);
984
    variable negative : std_logic := sel(value < 0, '1', '0');
985
    variable n        : natural   := sel(value < 0, -(value + 1), value);
986
  begin
987
    for i in tmp'right to tmp'left loop
988
      tmp(i) := sel(((n mod 2) = 0), negative, not(negative));
989
      n      := n / 2;
990
    end loop;
991
    return to_string(tmp, format, width, prec);
992
  end function to_string;
993
  ------------------------------------------------------------------------------
994
 
995
  ------------------------------------------------------------------------------
996
  function to_string(value  : in std_logic_vector;
997
                     format : in string  := "x";
998
                     width  : in natural := 0;
999
                     prec   : in natural := 0) return string is
1000
    -- Flags:
1001
    variable minus_flag             : boolean := false;
1002
    variable plus_flag              : boolean := false;
1003
    variable space_flag             : boolean := false;
1004
    variable zero_flag              : boolean := false;
1005
    variable sharp_flag             : boolean := false;
1006
    -- Width:
1007
    variable width_local            : natural := 0;
1008
    -- Precision:
1009
    variable prec_local             : natural := 0;
1010
    -- Conversion Type:
1011
    type conversion_type_type is (unsigned_binary, signed_decimal, unsigned_octal, unsigned_decimal, unsigned_hexadecimal_0, unsigned_hexadecimal_1);
1012
    variable type_local             : conversion_type_type := signed_decimal;
1013
    --
1014
    --
1015
    variable value_local            : std_logic_vector(value'length - 1 downto 0);
1016
    variable idx                    : integer;
1017
    variable number_buffer          : string(1 to value'length);
1018
    variable sign_buffer            : string(1 to 2);
1019
    variable result_ptr             : string_ptr;
1020
    --
1021
    variable space_padding_0        : integer;
1022
    variable sign_chars             : integer;
1023
    variable zero_padding           : integer;
1024
    variable number_chars           : integer;
1025
    variable space_padding_1        : integer;
1026
  begin
1027
    idx := format'low;
1028
 
1029
    -- Parse format string:
1030
    ---- Read flags:
1031
    while (true) loop
1032
      case format(idx) is
1033
        when '-' =>
1034
          if (minus_flag) then report "'-' flag was aready set before" severity warning; else minus_flag := true; end if;
1035
        when '+' =>
1036
          if (plus_flag ) then report "'+' flag was aready set before" severity warning; else plus_flag  := true; end if;
1037
        when ' ' =>
1038
          if (space_flag) then report "' ' flag was aready set before" severity warning; else space_flag := true; end if;
1039
        when '0' =>
1040
          if (zero_flag ) then report "'0' flag was aready set before" severity warning; else zero_flag  := true; end if;
1041
        when '#' =>
1042
          if (sharp_flag) then report "'#' flag was aready set before" severity warning; else sharp_flag := true; end if;
1043
        when others => exit;
1044
      end case;
1045
      if (idx < format'high) then idx := idx + 1; else report "Unexpected end of format string." severity error; end if;
1046
    end loop;
1047
 
1048
    if (space_flag and plus_flag) then
1049
      report "' ' flag is ignored due to presence of '+' flag" severity warning;
1050
      space_flag := false;
1051
    end if;
1052
 
1053
    if (minus_flag and zero_flag) then
1054
      report "'0' flag is ignored due to presence of '-' flag" severity warning;
1055
      zero_flag := false;
1056
    end if;
1057
 
1058
    ---- Read width:
1059
    if (format(idx) = '*') then
1060
      width_local     := width;
1061
      if (idx < format'high) then idx := idx + 1; else report "Unexpected end of format string." severity error; end if;
1062
    else
1063
      while (true) loop
1064
        case format(idx) is
1065
          when '0' | '1' | '2' | '3' | '4' | '5' | '6' | '7' | '8' | '9' =>
1066
            width_local := (width_local * 10) + (character'pos(format(idx)) - character'pos('0'));
1067
            if (idx < format'high) then idx := idx + 1; else report "Unexpected end of format string." severity error; end if;
1068
          when others => exit;
1069
        end case;
1070
      end loop;
1071
    end if;
1072
 
1073
    ---- Read precision:
1074
    if (format(idx) = '.') then
1075
      prec_local     := 0;
1076
      if (zero_flag) then
1077
        report "'0' flag is ignored due to presence of PREC field" severity warning;
1078
        zero_flag := false;
1079
      end if;
1080
      if (idx < format'high) then idx := idx + 1; else report "Unexpected end of format string." severity error; end if;
1081
      if (format(idx) = '*') then
1082
        prec_local     := prec;
1083
        if (idx < format'high) then idx := idx + 1; else report "Unexpected end of format string." severity error; end if;
1084
      else
1085
        while (true) loop
1086
          case format(idx) is
1087
            when '0' | '1' | '2' | '3' | '4' | '5' | '6' | '7' | '8' | '9' =>
1088
              prec_local := (prec_local * 10) + (character'pos(format(idx)) - character'pos('0'));
1089
              if (idx < format'high) then idx := idx + 1; else report "Unexpected end of format string." severity error; end if;
1090
            when others => exit;
1091
          end case;
1092
        end loop;
1093
      end if;
1094
    end if;
1095
 
1096
    ---- Read type:
1097
    case format(idx) is
1098
      when 'b'       =>
1099
        type_local     := unsigned_binary;
1100
      when 'd' | 'i' =>
1101
        type_local     := signed_decimal;
1102
        if (sharp_flag) then
1103
          report "'#' flag is ignored due to signed decimal conversion type" severity warning;
1104
          sharp_flag := false;
1105
        end if;
1106
      when 'o'       =>
1107
        type_local     := unsigned_octal;
1108
      when 'u'       =>
1109
        type_local     := unsigned_decimal;
1110
        if (sharp_flag) then
1111
          report "'#' flag is ignored due to unsigned decimal conversion type" severity warning;
1112
          sharp_flag := false;
1113
        end if;
1114
      when 'x'       =>
1115
        type_local     := unsigned_hexadecimal_0;
1116
      when 'X'       =>
1117
        type_local     := unsigned_hexadecimal_1;
1118
      when others    =>
1119
        report "Unknown conversion type character: " & format(idx) severity error;
1120
        type_local     := signed_decimal;
1121
    end case;
1122
    assert (idx = format'high) report "Extra characters in format string" severity warning;
1123
 
1124
    ---- Obtain number string:
1125
    case type_local is
1126
      when unsigned_binary =>
1127
        -- Fill number buffer:
1128
        value_local := value;
1129
        idx         := 1;
1130
 
1131
        while (true) loop
1132
          number_buffer(idx) := to_character(value_local(0));
1133
          value_local := '0' & value_local(value_local'high downto 1);
1134
          idx := idx + 1;
1135
          exit when (value_local = (value_local'range => '0'));
1136
        end loop;
1137
 
1138
        -- Fill sign buffer:
1139
        if (sharp_flag) then
1140
          sign_chars     := 1;
1141
          sign_buffer(1) := 'b';
1142
        else
1143
          sign_chars      := 0;
1144
        end if;
1145
 
1146
      when signed_decimal         =>
1147
        -- Fill number buffer:
1148
        value_local := std_logic_vector(abs(signed(value)));
1149
        idx         := 1;
1150
 
1151
        while (true) loop
1152
          number_buffer(idx) := hexadecimal_chars(to_integer(unsigned(value_local) rem 10) + 1);
1153
          value_local := std_logic_vector(unsigned(value_local) / 10);
1154
          idx := idx + 1;
1155
          exit when (value_local = (value_local'range => '0'));
1156
        end loop;
1157
 
1158
        -- Fill sign buffer:
1159
        if (signed(value) < 0) then
1160
          sign_buffer(1) := '-';
1161
        elsif (plus_flag) then
1162
          sign_buffer(1) := '+';
1163
        else
1164
          sign_buffer(1) := ' ';
1165
        end if;
1166
        sign_chars      := sel(signed(value) < 0, 1, sel(plus_flag or space_flag, 1, 0));
1167
 
1168
      when unsigned_octal         =>
1169
        -- Fill number buffer:
1170
        value_local := value;
1171
        idx         := 1;
1172
 
1173
        while (true) loop
1174
          number_buffer(idx) := hexadecimal_chars(to_integer(unsigned(value_local) rem 8) + 1);
1175
          value_local := std_logic_vector(unsigned(value_local) / 8);
1176
          idx := idx + 1;
1177
          exit when (value_local = (value_local'range => '0'));
1178
        end loop;
1179
 
1180
        -- Fill sign buffer:
1181
        sign_chars      := 0;
1182
        prec_local      := sel(sharp_flag and (prec_local < idx), idx, prec_local);
1183
 
1184
      when unsigned_decimal       =>
1185
        -- Fill number buffer:
1186
        value_local := value;
1187
        idx         := 1;
1188
 
1189
        while (true) loop
1190
          number_buffer(idx) := hexadecimal_chars(to_integer(unsigned(value_local) rem 10) + 1);
1191
          value_local := std_logic_vector(unsigned(value_local) / 10);
1192
          idx := idx + 1;
1193
          exit when (value_local = (value_local'range => '0'));
1194
        end loop;
1195
 
1196
        -- Fill sign buffer:
1197
        sign_chars      := 0;
1198
 
1199
      when unsigned_hexadecimal_0 | unsigned_hexadecimal_1 =>
1200
        -- Fill number buffer:
1201
        value_local := value;
1202
        idx         := 1;
1203
 
1204
        while (true) loop
1205
          number_buffer(idx) := hexadecimal_chars(to_integer(unsigned(value_local) rem 16) + sel(type_local = unsigned_hexadecimal_0, 1, 17));
1206
          value_local := std_logic_vector(unsigned(value_local) / 16);
1207
          idx := idx + 1;
1208
          exit when (value_local = (value_local'range => '0'));
1209
        end loop;
1210
 
1211
        -- Fill sign buffer:
1212
        if (sharp_flag) then
1213
          sign_chars     := 2;
1214
          sign_buffer(1) := '0';
1215
          sign_buffer(2) := sel(type_local = unsigned_hexadecimal_0, 'x', 'X');
1216
        else
1217
          sign_chars      := 0;
1218
        end if;
1219
 
1220
    end case;
1221
 
1222
    --
1223
    number_chars    := idx - 1;
1224
    zero_padding    := max(prec_local - number_chars, 0);
1225
    space_padding_0 := sel(minus_flag, 0, max(width_local - (sign_chars + zero_padding + number_chars), 0));
1226
    space_padding_1 := sel(minus_flag, max(width_local - (sign_chars + zero_padding + number_chars), 0), 0);
1227
 
1228
    --
1229
    result_ptr := new string(1 to space_padding_0 + sign_chars + zero_padding + number_chars + space_padding_1);
1230
 
1231
    -- fill the space padding 0:
1232
    for i in 1 to space_padding_0 loop
1233
      result_ptr.all(i) := ' ';
1234
    end loop;
1235
    -- put sign chars:
1236
    for i in 1 to sign_chars loop
1237
      result_ptr.all(space_padding_0 + i) := sign_buffer(i);
1238
    end loop;
1239
    -- fill zero poadding:
1240
    for i in 1 to zero_padding loop
1241
      result_ptr.all(space_padding_0 + sign_chars + i) := '0';
1242
    end loop;
1243
    -- put number chars:
1244
    for i in 1 to number_chars loop
1245
      result_ptr.all(space_padding_0 + sign_chars + zero_padding + i) := number_buffer(idx - i);
1246
    end loop;
1247
    -- fill the space padding 1:
1248
    for i in 1 to space_padding_1 loop
1249
      result_ptr.all(space_padding_0 + sign_chars + zero_padding + number_chars + i) := ' ';
1250
    end loop;
1251
 
1252
    return result_ptr.all;
1253
 
1254
  end function to_string;
1255
  ------------------------------------------------------------------------------
1256
 
1257
end test;
1258
--==============================================================================
1259
 

powered by: WebSVN 2.1.0

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