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

Subversion Repositories pltbutils

[/] [pltbutils/] [trunk/] [src/] [vhdl/] [pltbutils_func_pkg.vhd] - Diff between revs 105 and 107

Go to most recent revision | Show entire file | Details | Blame | View Log

Rev 105 Rev 107
Line 19... Line 19...
---- Author(s):                                                   ----
---- Author(s):                                                   ----
---- - Per Larsson, pela.opencores@gmail.com                      ----
---- - Per Larsson, pela.opencores@gmail.com                      ----
----                                                              ----
----                                                              ----
----------------------------------------------------------------------
----------------------------------------------------------------------
----                                                              ----
----                                                              ----
---- Copyright (C) 2013-2014 Authors and OPENCORES.ORG            ----
---- Copyright (C) 2013-2020 Authors and OPENCORES.ORG            ----
----                                                              ----
----                                                              ----
---- This source file may be used and distributed without         ----
---- This source file may be used and distributed without         ----
---- restriction provided that this copyright statement is not    ----
---- restriction provided that this copyright statement is not    ----
---- removed from the file and that any derivative work contains  ----
---- removed from the file and that any derivative work contains  ----
---- the original copyright notice and the associated disclaimer. ----
---- the original copyright notice and the associated disclaimer. ----
Line 308... Line 308...
    constant value              : in    std_logic;
    constant value              : in    std_logic;
    variable pltbv              : inout pltbv_t;
    variable pltbv              : inout pltbv_t;
    signal   pltbs              : out   pltbs_t;
    signal   pltbs              : out   pltbs_t;
    constant timeout            : in    time    := C_PLTBUTILS_TIMEOUT
    constant timeout            : in    time    := C_PLTBUTILS_TIMEOUT
  );
  );
 
  -- waitsig std_logic edge, unclocked
 
  procedure waitsig(
 
    signal   s                  : in    std_logic;
 
    variable pltbv              : inout pltbv_t;
 
    signal   pltbs              : out   pltbs_t;
 
    constant falling            : in    boolean := false;
 
    constant timeout            : in    time    := C_PLTBUTILS_TIMEOUT
 
  );
  -- check
  -- check
  procedure check(
  procedure check(
    constant rpt                : in    string;
    constant rpt                : in    string;
    constant actual             : in    integer;
    constant actual             : in    integer;
    constant expected           : in    integer;
    constant expected           : in    integer;
Line 431... Line 438...
    constant rpt                : in    string;
    constant rpt                : in    string;
    constant expr               : in    boolean;
    constant expr               : in    boolean;
    variable pltbv              : inout pltbv_t;
    variable pltbv              : inout pltbv_t;
    signal   pltbs              : out   pltbs_t
    signal   pltbs              : out   pltbs_t
  );
  );
 
  procedure check_binfile(
 
    constant rpt        : in    string;
 
    constant filename1  : in    string;
 
    constant filename2  : in    string;
 
    constant verbosity  : in    integer;
 
    variable pltbv      : inout pltbv_t;
 
    signal   pltbs      : out   pltbs_t
 
  );
 
  procedure check_txtfile(
 
    constant rpt        : in    string;
 
    constant filename1  : in    string;
 
    constant filename2  : in    string;
 
    constant verbosity  : in    integer;
 
    variable pltbv      : inout pltbv_t;
 
    signal   pltbs      : out   pltbs_t
 
  );
 
  procedure check_datfile(
 
    constant rpt        : in    string;
 
    constant filename1  : in    string;
 
    constant filename2  : in    string;
 
    constant verbosity  : in    integer;
 
    variable pltbv      : inout pltbv_t;
 
    signal   pltbs      : out   pltbs_t;
 
    constant skip_init_items : in integer := 0
 
  );
   procedure check(
   procedure check(
    constant rpt                : in    string;
    constant rpt                : in    string;
    constant expr               : in    boolean;
    constant expr               : in    boolean;
    constant actual             : in    string;
    constant actual             : in    string;
    constant expected           : in    string;
    constant expected           : in    string;
Line 480... Line 512...
    constant s                  : signed;
    constant s                  : signed;
    constant prefix             : string := "";
    constant prefix             : string := "";
    constant postfix            : string := ""
    constant postfix            : string := ""
  ) return string;
  ) return string;
 
 
  -- pltbutils internal procedure(s), do not call from user's code
  -- str
  procedure pltbs_update(
  function str(
    variable pltbv              : inout pltbv_t;
    constant n                  : integer;
    signal   pltbs              : out   pltbs_t
    constant len                : integer;
  );
    constant fillchar           : character := ' '
 
  ) return string;
 
 
  procedure stopsim(
  function str_equal (
    constant timestamp          : in time
    constant s1 : STRING;
  );
    constant s2 : STRING
 
  ) return boolean;
 
 
  procedure pltbutils_error(
end package pltbutils_func_pkg;
    constant rpt                : in string;
 
    variable pltbv              : inout pltbv_t;
 
    signal   pltbs              : out   pltbs_t
 
  );
 
 
 
  procedure startsim_msg(
package body pltbutils_func_pkg is
    constant testcase_name      : in string;
 
    constant timestamp          : in time
 
  );
 
 
 
  procedure endsim_msg(
  --==========================================================================
    constant testcase_name      : in string;
  -- pltbutils internal (private) procedures
    constant timestamp          : in time;
  -- To be called from other pltbutils procedures.
    constant num_tests          : in integer;
  -- Do not to call these from user's code.
    constant num_skiptests      : in integer;
  -- These procedures are intentionally undocumented in the specification
    constant num_checks         : in integer;
  -- document.
    constant num_errors         : in integer;
  --==========================================================================
    constant show_success_fail  : in boolean
 
  );
  procedure pltbs_update(
 
    variable pltbv              : inout pltbv_t;
 
    signal   pltbs              : out   pltbs_t
 
  ) is
 
  begin
 
    pltbs.test_num  <= pltbv.test_num;
 
    print(pltbs.test_name, pltbv.test_name);
 
    print(pltbs.info, pltbv.info);
 
    pltbs.chk_cnt   <= pltbv.chk_cnt;
 
    pltbs.err_cnt   <= pltbv.err_cnt;
 
    pltbs.stop_sim  <= pltbv.stop_sim;
 
  end procedure pltbs_update;
 
 
  procedure starttest_msg(
  procedure starttest_msg(
    constant test_num           : in integer;
    constant test_num           : in integer;
    constant test_name          : in string;
    constant test_name          : in string;
    constant timestamp          : in time
    constant timestamp          : in time
  );
  ) is
 
  begin
 
    print(lf & "Test " & str(test_num) & ": " & test_name & " (" & time'image(timestamp) & ")");
 
  end procedure starttest_msg;
 
 
  procedure skiptest_msg(
  procedure skiptest_msg(
    constant test_num           : in integer;
    constant test_num           : in integer;
    constant test_name          : in string;
    constant test_name          : in string;
    constant timestamp          : in time
    constant timestamp          : in time
  );
  ) is
 
  begin
 
    print(lf & "Skipping Test " & str(test_num) & ": " & test_name & " (" & time'image(timestamp) & ")");
 
  end procedure skiptest_msg;
 
 
  procedure endtest_msg(
  procedure endtest_msg(
    constant test_num           : in integer;
    constant test_num           : in integer;
    constant test_name          : in string;
    constant test_name          : in string;
    constant timestamp          : in time;
    constant timestamp          : in time;
    constant test_active        : in boolean;
    constant test_active        : in boolean;
    constant num_checks_in_test : in integer;
    constant num_checks_in_test : in integer;
    constant num_errors_in_test : in integer
    constant num_errors_in_test : in integer
  );
  ) is
 
  begin
 
    if test_active then
 
      print("Done with test " & str(test_num) & ": " & test_name & " (" & time'image(timestamp) & ")");
 
    end if;
 
  end procedure endtest_msg;
 
 
  procedure check_msg(
  procedure check_msg(
    constant rpt                : in string;
    constant rpt                : in string;
    constant timestamp          : in time;
    constant timestamp          : in time;
    constant expr               : in boolean;
    constant expr               : in boolean;
Line 543... Line 592...
    constant mask               : in string;
    constant mask               : in string;
    constant test_num           : in integer;
    constant test_num           : in integer;
    constant test_name          : in string;
    constant test_name          : in string;
    constant check_num          : in integer;
    constant check_num          : in integer;
    constant err_cnt_in_test    : in integer
    constant err_cnt_in_test    : in integer
  );
  ) is
 
    variable actual_str_len     : integer := 1;
 
    variable actual_str         : string(1 to actual'length+8) := (others => ' ');
 
    variable expected_str       : string(1 to expected'length+10) := (others => ' ');
 
    variable expected_str_len   : integer := 1;
 
    variable mask_str           : string(1 to mask'length+6) := (others => ' ');
 
    variable mask_str_len       : integer := 1;
 
    constant C_ACTUAL_PREFIX    : string := " Actual=";
 
    constant C_ACTUAL_POSTFIX   : string := "";
 
    constant C_EXPECTED_PREFIX  : string := " Expected=";
 
    constant C_EXPECTED_POSTFIX : string := "";
 
    constant C_MASK_PREFIX      : string := " Mask=";
 
    constant C_MASK_POSTFIX     : string := "";
 
  begin
 
    if not expr then -- Output message only if the check fails
 
      if str_equal(mask, "!NO_TAGS!") then
 
         -- if mask=!NO_TAGS!, then do not add Actual= and Expected=" tags to strings
 
         actual_str_len := actual'length;
 
         actual_str(1 to actual_str_len) := actual;
 
         expected_str_len := expected'length;
 
         expected_str(1 to expected_str_len) := expected;
 
         mask_str_len := 1;
 
      else
 
        -- Add Actual= and Expected= tags to strings
 
        if actual /= "" then
 
          --actual_str_len := 8 + actual'length;
 
          --actual_str := " Actual=" & actual;
 
            actual_str_len := C_ACTUAL_PREFIX'length + actual'length + C_ACTUAL_POSTFIX'length;
 
            actual_str(1 to actual_str_len) := C_ACTUAL_PREFIX & tcfilter(actual) & C_ACTUAL_POSTFIX;
 
        end if;
 
        if expected /= "" then
 
          --expected_str_len := 10 + expected'length;
 
          --expected_str := " Expected=" & expected;
 
          expected_str_len := C_EXPECTED_PREFIX'length + expected'length + C_EXPECTED_POSTFIX'length;
 
          expected_str(1 to expected_str_len) := C_EXPECTED_PREFIX & tcfilter(expected) & C_EXPECTED_POSTFIX;
 
        end if;
 
        if mask /= "" then
 
          --mask_str_len := 6 + mask'length;
 
          --mask_str := " Mask=" & mask;
 
          mask_str_len := C_MASK_PREFIX'length + mask'length + C_MASK_POSTFIX'length;
 
          mask_str(1 to mask_str_len) := C_MASK_PREFIX & tcfilter(mask) & C_MASK_POSTFIX;
 
        end if;
 
      end if;
 
      assert false
 
        report "Check " & str(check_num) & "; " & rpt & "; " &
 
               actual_str(1 to actual_str_len) &
 
               expected_str(1 to expected_str_len) &
 
               mask_str(1 to mask_str_len) &
 
               "  in test " & str(test_num) & " " & test_name
 
        severity error;
 
    end if;
 
  end procedure check_msg;
 
 
  procedure error_msg(
  procedure error_msg(
    constant rpt                : in string;
    constant rpt                : in string;
    constant timestamp          : in time;
    constant timestamp          : in time;
    constant test_num           : in integer;
    constant test_num           : in integer;
    constant test_name          : in string;
    constant test_name          : in string;
    constant err_cnt_in_test    : in integer
    constant err_cnt_in_test    : in integer
  );
  ) is
 
  begin
 
    assert false
 
    report rpt & " in test " & str(test_num) & ": " & test_name
 
    severity error;
 
  end procedure error_msg;
 
 
end package pltbutils_func_pkg;
  procedure pltbutils_error(
 
    constant rpt                : in string;
 
    variable pltbv              : inout pltbv_t;
 
    signal   pltbs              : out   pltbs_t
 
  ) is
 
  begin
 
    pltbv.err_cnt := pltbv.err_cnt + 1;
 
    pltbv.err_cnt_in_test := pltbv.err_cnt_in_test + 1;
 
    pltbs_update(pltbv, pltbs);
 
    if C_PLTBUTILS_USE_STD_ERROR_MSG then
 
      error_msg(rpt, now, pltbv.test_num,
 
        pltbv.test_name(1 to pltbv.test_name_len), pltbv.err_cnt_in_test);
 
    end if;
 
    if C_PLTBUTILS_USE_CUSTOM_ERROR_MSG then
 
      custom_error_msg(rpt, now, pltbv.test_num,
 
        pltbv.test_name(1 to pltbv.test_name_len), pltbv.err_cnt_in_test);
 
    end if;
 
  end procedure pltbutils_error;
 
 
 
  procedure stopsim(
 
    constant timestamp          : in time
 
  ) is
 
  begin
 
    assert false
 
    report "--- FORCE END OF SIMULATION ---" &
 
           " (ignore this false failure message, it's not a real failure)"
 
    severity failure;
 
  end procedure stopsim;
 
 
 
  procedure startsim_msg(
 
    constant testcase_name      : in string;
 
    constant timestamp          : in time
 
  ) is
 
  begin
 
    print(lf & "--- START OF SIMULATION ---");
 
    print("Testcase: " & testcase_name);
 
    print(time'image(timestamp));
 
  end procedure startsim_msg;
 
 
 
  procedure endsim_msg(
 
    constant testcase_name      : in string;
 
    constant timestamp          : in time;
 
    constant num_tests          : in integer;
 
    constant num_skiptests      : in integer;
 
    constant num_checks         : in integer;
 
    constant num_errors         : in integer;
 
    constant show_success_fail  : in boolean
 
  ) is
 
    variable l : line;
 
  begin
 
    print(lf & "--- END OF SIMULATION ---");
 
    print("Note: the results presented below are based on the PlTbUtil's check() procedure calls.");
 
    print("      The design may contain more errors, for which there are no check() calls.");
 
    write(l, timestamp, right, 14);
 
    writeline(output, l);
 
    write(l, num_tests, right, 11);
 
    write(l, string'(" Tests"));
 
    writeline(output, l);
 
    write(l, num_skiptests, right, 11);
 
    write(l, string'(" Skipped tests"));
 
    writeline(output, l);
 
    write(l, num_checks, right, 11);
 
    write(l, string'(" Checks"));
 
    writeline(output, l);
 
    write(l, num_errors, right, 11);
 
    write(l, string'(" Errors"));
 
    writeline(output, l);
 
    if show_success_fail then
 
      if num_errors = 0 and num_checks > 0 then
 
        print("*** SUCCESS ***");
 
      elsif num_checks > 0 then
 
        print("*** FAIL ***");
 
      else
 
        print("*** NO CHECKS ***");
 
      end if;
 
    end if;
 
  end procedure endsim_msg;
 
 
package body pltbutils_func_pkg is
 
 
 
 
  -- Get next item (word) in a file
 
  procedure get_file_item(
 
    file     f          :       text;
 
    variable l          : inout line;
 
    variable item       : out   string;
 
    variable item_len   : out   integer;
 
    variable line_num   : inout integer;
 
    variable item_num   : inout integer
 
  ) is
 
    variable c          : character := ' ';
 
    variable c_good     : boolean := true;
 
    variable i          : integer := 0;
 
  begin
 
    item := (item'low to item'high => ' ');
 
    item_len := 0;
 
    while i = 0 loop
 
      -- Get next line, unless we're already processing a line
 
      if l = null then
 
        exit when endfile(f);
 
        readline(f, l);
 
        line_num := line_num + 1;
 
      elsif l'length = 0 then
 
        exit when endfile(f);
 
        readline(f, l);
 
        line_num := line_num + 1;
 
      end if;
 
 
 
      -- Find next item on the line
 
      read(l, c, c_good);
 
      -- Skip leading whitespace characters
 
      while c_good and (c = ' ' or c = ht) loop
 
        read(l, c, c_good);
 
      end loop;
 
      -- Read item until next whitespace, comment character or end-of-line
 
      while c_good and c /= ' ' and c /= ht and c /= '#' loop
 
        -- If i >= item'length, an error will occur. We don't try to do anything
 
        -- about that here, because it is probably better that the user 
 
        -- find out the hard way, instead of trying to hide the problem.
 
        item(item'low + i) := c;
 
        i := i + 1;
 
        read(l, c, c_good);
 
      end loop;
 
 
 
      -- If a comment character was found, absorb the rest of the comment
 
      if c_good and c = '#' then
 
        while l'length > 0 loop
 
          read(l, c, c_good);
 
        end loop;
 
      end if;
 
      -- Update output values if item was found
 
      if i > 0 then
 
        item_len := i;
 
        item_num := item_num + 1;
 
      end if;
 
    end loop;
 
  end procedure get_file_item;
 
 
 
 
 
 
 
  --==========================================================================
 
  -- pltbutils external (public) procedures
 
  -- To be called from the user's code.
 
  --==========================================================================
 
 
  ----------------------------------------------------------------------------
  ----------------------------------------------------------------------------
  -- startsim
  -- startsim
  --
  --
  -- procedure startsim(
  -- procedure startsim(
Line 1168... Line 1413...
  --   signal   pltbs              : out   pltbs_t;
  --   signal   pltbs              : out   pltbs_t;
  --   constant falling            : in    boolean := false;
  --   constant falling            : in    boolean := false;
  --   constant timeout            : in    time    := C_PLTBUTILS_TIMEOUT
  --   constant timeout            : in    time    := C_PLTBUTILS_TIMEOUT
  -- )
  -- )
  --
  --
  -- Waits until a signal has reached a specified value after specified clock
  -- Waits until a signal has reached a specified value. In clocked variants of
  -- edge.
  -- waitsig, the signal is checked after specified clock edge (rising or falling).
 
  -- Unclocked variants are currently only available for types std_logic and std_logic_vector.
  --
  --
  -- Arguments:
  -- Arguments:
  --   s                        The signal to test.
  --   s                        The signal to test.
  --                            Supported types: integer, std_logic,
  --                            Supported types: integer, std_logic,
  --                            std_logic_vector, unsigned, signed.
  --                            std_logic_vector, unsigned, signed.
  --
  --
  --   value                    Value to wait for.
  --   value                    Value to wait for.
  --                            Same type as data or integer.
  --                            Same type as data or integer.
  --
  --
  --   clk                      The clock.
  --   clk                      The clock, only present in clocked variants of
 
  --                            waitsig.
  --
  --
  --   pltbv, pltbs             PlTbUtils' status- and control variable and
  --   pltbv, pltbs             PlTbUtils' status- and control variable and
  --                            -signal.
  --                            -signal.
  --
  --
  --   falling                  If true, waits for falling edges, otherwise
  --   falling                  If true, waits for falling edges, otherwise
Line 1395... Line 1642...
        pltbutils_error("waitsig() timeout", pltbv, pltbs);
        pltbutils_error("waitsig() timeout", pltbv, pltbs);
      end if;
      end if;
    end if;
    end if;
  end procedure waitsig;
  end procedure waitsig;
 
 
 
  -- waitsig std_logic edge, unclocked
 
  procedure waitsig(
 
    signal   s                  : in    std_logic;
 
    variable pltbv              : inout pltbv_t;
 
    signal   pltbs              : out   pltbs_t;
 
    constant falling            : in    boolean := false;
 
    constant timeout            : in    time    := C_PLTBUTILS_TIMEOUT
 
  ) is
 
    variable v_timeout_time     : time;
 
  begin
 
    if falling then
 
      wait until falling_edge(s) for timeout;
 
    else
 
      wait until rising_edge(s)  for timeout;
 
    end if;
 
    if (not ((falling and (s = '0' or s = 'L')) or ((not falling) and (s = '1' or s = 'H')))) then
 
      pltbutils_error("waitsig() timeout", pltbv, pltbs);
 
    end if;
 
  end procedure waitsig;
 
 
 
 
  ----------------------------------------------------------------------------
  ----------------------------------------------------------------------------
  -- check
  -- check
  --
  --
  -- procedure check(
  -- procedure check(
  --   constant rpt             : in    string;
  --   constant rpt             : in    string;
Line 1701... Line 1969...
  ) is
  ) is
  begin
  begin
    check(rpt, expr, "", "", "", pltbv, pltbs);
    check(rpt, expr, "", "", "", pltbv, pltbs);
  end procedure check;
  end procedure check;
 
 
 
 
 
  ----------------------------------------------------------------------------
 
  -- check files
 
  --
 
  -- procedure check_binfile | check_txtfile | check_datfile(
 
  --   constant rpt        : in    string;
 
  --   constant filename1  : in    string;
 
  --   constant filename2  : in    string;
 
  --   constant verbosity  : in    integer;
 
  --   variable pltbv      : inout pltbv_t;
 
  --   signal   pltbs      : out   pltbs_t
 
  -- )
 
  --
 
  -- Checks that the contents of a file is equal to expected contents, by 
 
  -- comparing with a reference file.
 
  -- If not equal, displays an error message and increments the error counter.
 
  -- This is useful for examining different types of files generated by
 
  -- testbench components during a simulation against reference files. 
 
  -- It can be different kinds of data sequences, video image data, etc.
 
  --
 
  -- check_binfile compares two binary files. It uses "file of character" to
 
  -- read bytes from the files. The VHDL LRM does not define how a  
 
  -- "file of character" should be written or to/read from disk. In theory,
 
  -- there is a risk that a VHDL file of character is not compatible with
 
  -- a normal binary file, but practical tests done with some popular 
 
  -- simulators have shown that they are compatible. This does not 
 
  -- guarantee that this procedure works with ALL simulators, and with
 
  -- ALL future versions of the tested simulators. Use your own judgement.
 
  --
 
  -- check_txtfile compares two text files.
 
  --
 
  -- check_datfile compares two files with data formatted as follows.
 
  -- The files contain a sequence of data items separated by whitespace
 
  -- (spaces, tabs, newlines). The files can contain comments starting with
 
  -- a hash sign (#), and ending at next newline. 
 
  -- Only the data items are compared. The types of whitespace and comments
 
  -- are ignored. This is useful for different kinds of data dumps, 
 
  -- including some image file formats such as 
 
  --   Plain PBM (Portable Bit Map - P1, http://netpbm.sourceforge.net/doc/pbm.html )
 
  --   Plain PGM (Portable Gray Map - P2, http://netpbm.sourceforge.net/doc/pgm.html )
 
  --   Plain PPM (Portable Pixel Map - P3, http://netpbm.sourceforge.net/doc/ppm.html )
 
  --
 
  -- Arguments:
 
  --   rpt                      Report message to be displayed in case of
 
  --                            mismatch.
 
  --                            It is recommended that the message is unique
 
  --                            and that it contains the name of the signal
 
  --                            or variable being checked.
 
  --
 
  --   filename1                Name of first file to be compared, 
 
  --                            including relative path from the simulator's
 
  --                            working directory.
 
  --
 
  --   filename2                Name of second file to be compared, 
 
  --                            including relative path from the simulator's
 
  --                            working directory.
 
  --
 
  --   verbosity                Controls amount of individual error reports when
 
  --                            differences between files are found, to make it 
 
  --                            possible to prevent flooding with error messages.
 
  --                            0: no individual differences reported
 
  --                            1: the first ten differences reported
 
  --                            2: all differences reported
 
  --
 
  --   pltbv, pltbs             PlTbUtils' status- and control variable and
 
  --                            -signal.
 
  --
 
  -- Examples:
 
  -- check_binfile("Data output file", "out_file.bin", "ref_file.bin", 0, pltbv, pltbs);
 
  -- check_txtfile("Result file", G_RESULT_FILE, G_REF_FILE, G_CHECKFILE_VEROBOSITY, pltbv, pltbs);
 
  -- check_datfile("Resulting image", "result_img.ppm", "ref_img.ppm", 2, pltbv, pltbs);
 
  ----------------------------------------------------------------------------
 
 
 
  -- check binary file
 
  procedure check_binfile(
 
    constant rpt        : in    string;
 
    constant filename1  : in    string;
 
    constant filename2  : in    string;
 
    constant verbosity  : in    integer;
 
    variable pltbv      : inout pltbv_t;
 
    signal   pltbs      : out   pltbs_t
 
  ) is
 
    variable v_file_errors    : integer := 0;
 
    type charfile             is file of character;
 
    file f1                   : charfile;
 
    file f2                   : charfile;
 
    variable f1_status        : file_open_status;
 
    variable f2_status        : file_open_status;
 
    variable c1               : character;
 
    variable c2               : character;
 
    variable offset1          : integer := 0;
 
    variable offset2          : integer := 0;
 
    variable error_line       : line;
 
  begin
 
    file_open(f1_status, f1, filename1, read_mode);
 
    if f1_status /= open_ok then
 
      v_file_errors := v_file_errors + 1;
 
      write(error_line, " Could not open file " & filename1 & " for reading.");
 
    else
 
      file_open(f2_status, f2, filename2, read_mode);
 
      if f2_status /= open_ok then
 
        v_file_errors := v_file_errors + 1;
 
        write(error_line, " Could not open file " & filename2 & " for reading. ");
 
        file_close(f1);
 
      end if;
 
    end if;
 
    if f1_status = open_ok and f2_status = open_ok then
 
      while not endfile(f1) and not endfile(f2) loop
 
        read(f1, c1);
 
        read(f2, c2);
 
        if c1 /= c2 then
 
          v_file_errors := v_file_errors + 1;
 
          if ((verbosity >= 2) or (verbosity = 1 and v_file_errors <= 10)) then
 
            write(error_line, " Diff offset " & integer'image(offset1) & ": " &
 
                  integer'image(character'pos(c1)) & " /= " & integer'image(character'pos(c2)) & ".");
 
          end if;
 
          if verbosity = 1 and v_file_errors = 11 then
 
            write(error_line, string'(" Further diffs suppressed."));
 
          end if;
 
        end if;
 
        offset1 := offset1 + 1;
 
        offset2 := offset2 + 1;
 
      end loop;
 
      if v_file_errors > 0 then
 
        write(error_line, " " & integer'image(v_file_errors) & " bytes differ.");
 
      end if;
 
 
 
      -- Now one or both files are at the end.
 
      -- Checking remaining size of possible non-ended file.
 
      while not endfile(f1) loop
 
        read(f1, c1);
 
        offset1 := offset1 + 1;
 
      end loop;
 
      while not endfile(f2) loop
 
        read(f2, c2);
 
        offset2 := offset2 + 1;
 
      end loop;
 
      if offset1 /= offset2 then
 
        v_file_errors := v_file_errors + 1;
 
        write(error_line, " File sizes differ: " & integer'image(offset1) &
 
                         " /= " & integer'image(offset2) & " bytes.");
 
      end if;
 
      write(error_line, " (" & filename1 & ", " & filename2 & ")");
 
    end if; -- f1_status, f2_status
 
 
 
    if f1_status = open_ok then
 
      file_close(f1);
 
    end if;
 
    if f2_status = open_ok then
 
      file_close(f2);
 
    end if;
 
 
 
    check(rpt, v_file_errors = 0, error_line.all, "", "!NO_TAGS!", pltbv, pltbs);
 
 
 
    if error_line /= null then
 
      deallocate(error_line);
 
    end if;
 
  end procedure check_binfile;
 
 
 
 
 
  -- check text file
 
  procedure check_txtfile(
 
    constant rpt        : in    string;
 
    constant filename1  : in    string;
 
    constant filename2  : in    string;
 
    constant verbosity  : in    integer;
 
    variable pltbv      : inout pltbv_t;
 
    signal   pltbs      : out   pltbs_t
 
  ) is
 
    variable v_file_errors    : integer := 0;
 
    file f1                   : text;
 
    file f2                   : text;
 
    variable f1_status        : file_open_status;
 
    variable f2_status        : file_open_status;
 
    variable l1               : line;
 
    variable l2               : line;
 
    variable line_num1        : integer := 0;
 
    variable line_num2        : integer := 0;
 
    variable error_line       : line;
 
  begin
 
    file_open(f1_status, f1, filename1, read_mode);
 
    if f1_status /= open_ok then
 
      v_file_errors := v_file_errors + 1;
 
      write(error_line, " Could not open file " & filename1 & " for reading.");
 
    else
 
      file_open(f2_status, f2, filename2, read_mode);
 
      if f2_status /= open_ok then
 
        v_file_errors := v_file_errors + 1;
 
        write(error_line, " Could not open file " & filename2 & " for reading. ");
 
        file_close(f1);
 
      end if;
 
    end if;
 
    if f1_status = open_ok and f2_status = open_ok then
 
      while not endfile(f1) and not endfile(f2) loop
 
        readline(f1, l1);
 
        readline(f2, l2);
 
        line_num1 := line_num1 + 1;
 
        line_num2 := line_num2 + 1;
 
        if l1.all /= l2.all then
 
          v_file_errors := v_file_errors + 1;
 
          if ((verbosity >= 2) or (verbosity = 1 and v_file_errors <= 10)) then
 
            write(error_line, " Diff line " & integer'image(line_num1) & ": '" &
 
                  l1.all & "'' /= '" & l2.all & "'.");
 
          end if;
 
          if verbosity = 1 and v_file_errors = 11 then
 
            write(error_line, string'(" Further diffs suppressed."));
 
          end if;
 
        end if;
 
      end loop;
 
      if v_file_errors > 0 then
 
        write(error_line, " " & integer'image(v_file_errors) & " lines differ.");
 
      end if;
 
 
 
      -- Now one or both files are at the end.
 
      -- Checking remaining size of possible non-ended file.
 
      while not endfile(f1) loop
 
        readline(f1, l1);
 
        line_num1 := line_num1 + 1;
 
      end loop;
 
      while not endfile(f2) loop
 
        readline(f2, l2);
 
        line_num2 := line_num2 + 1;
 
      end loop;
 
      if line_num1 /= line_num2 then
 
        v_file_errors := v_file_errors + 1;
 
        write(error_line, " File sizes differ: " & integer'image(line_num1) &
 
                         " /= " & integer'image(line_num2) & " lines.");
 
      end if;
 
      write(error_line, " (" & filename1 & ", " & filename2 & ")");
 
    end if; -- f1_status, f2_status
 
 
 
    if f1_status = open_ok then
 
      file_close(f1);
 
    end if;
 
    if f2_status = open_ok then
 
      file_close(f2);
 
    end if;
 
 
 
    check(rpt, v_file_errors = 0, error_line.all, "", "!NO_TAGS!", pltbv, pltbs);
 
 
 
    if error_line /= null then
 
      deallocate(error_line);
 
    end if;
 
  end procedure check_txtfile;
 
 
 
  -- check data file
 
  procedure check_datfile(
 
    constant rpt        : in    string;
 
    constant filename1  : in    string;
 
    constant filename2  : in    string;
 
    constant verbosity  : in    integer;
 
    variable pltbv      : inout pltbv_t;
 
    signal   pltbs      : out   pltbs_t;
 
    constant skip_init_items : in integer := 0
 
  ) is
 
    variable v_file_errors    : integer := 0;
 
    file f1                   : text;
 
    file f2                   : text;
 
    variable f1_status        : file_open_status;
 
    variable f2_status        : file_open_status;
 
    variable l1               : line;
 
    variable l2               : line;
 
    variable line_num1        : integer := 0;
 
    variable line_num2        : integer := 0;
 
    variable item1            : string(1 to 256);
 
    variable item2            : string(1 to 256);
 
    variable item_len1        : integer := -1;
 
    variable item_len2        : integer := -1;
 
    variable item_num1        : integer := 0;
 
    variable item_num2        : integer := 0;
 
    variable item_cnt         : integer := 0;
 
    variable error_line       : line;
 
  begin
 
    file_open(f1_status, f1, filename1, read_mode);
 
    if f1_status /= open_ok then
 
      v_file_errors := v_file_errors + 1;
 
      write(error_line, " Could not open file " & filename1 & " for reading.");
 
    else
 
      file_open(f2_status, f2, filename2, read_mode);
 
      if f2_status /= open_ok then
 
        v_file_errors := v_file_errors + 1;
 
        write(error_line, " Could not open file " & filename2 & " for reading. ");
 
        file_close(f1);
 
      end if;
 
    end if;
 
    if f1_status = open_ok and f2_status = open_ok then
 
      while item_len1 /= 0 or item_len2 /= 0 loop
 
        get_file_item(f1, l1, item1, item_len1, line_num1, item_num1);
 
        get_file_item(f2, l2, item2, item_len2, line_num2, item_num2);
 
        item_cnt := item_cnt + 1;
 
        if item_len1 > 0 and item_len2 > 0 and item_cnt > skip_init_items then
 
          if item1 /= item2 then
 
            v_file_errors := v_file_errors + 1;
 
            if ((verbosity >= 2) or (verbosity = 1 and v_file_errors <= 10)) then
 
              write(error_line, " Diff item " & integer'image(item_num1) & ": '" &
 
                  item1(1 to item_len1) & "' /= '" & item2(1 to item_len2) & "'.");
 
            end if;
 
            if verbosity = 1 and v_file_errors = 11 then
 
              write(error_line, string'(" Further diffs suppressed."));
 
            end if;
 
          end if;
 
        end if;
 
      end loop;
 
 
 
      if v_file_errors > 0 then
 
        write(error_line, " " & integer'image(v_file_errors) & " items differ.");
 
      end if;
 
 
 
      -- Now one or both files are at the end.
 
      -- Checking remaining size of possible non-ended file.
 
      while not endfile(f1) loop
 
        get_file_item(f1, l1, item1, item_len1, line_num1, item_num1);
 
      end loop;
 
      while not endfile(f2) loop
 
        get_file_item(f2, l2, item2, item_len2, line_num2, item_num2);
 
      end loop;
 
      if item_num1 /= item_num2 then
 
        v_file_errors := v_file_errors + 1;
 
        write(error_line, " File sizes differ: " & integer'image(item_num1) &
 
                         " /= " & integer'image(item_num2) & " items.");
 
      end if;
 
      write(error_line, " (" & filename1 & ", " & filename2 & ")");
 
    end if;
 
 
 
    if f1_status = open_ok then
 
      file_close(f1);
 
    end if;
 
    if f2_status = open_ok then
 
      file_close(f2);
 
    end if;
 
 
 
    check(rpt, v_file_errors = 0, error_line.all, "", "!NO_TAGS!", pltbv, pltbs);
 
 
 
    if error_line /= null then
 
      deallocate(error_line);
 
    end if;
 
  end procedure check_datfile;
 
 
 
 
  -- check base procedure
  -- check base procedure
  -- All other check procedures perform the check, and calls this procedure
  -- All other check procedures perform the check, and calls this procedure
  -- with the check result in the expr argument.
  -- with the check result in the expr argument.
  -- This procedure can also be called directly. It allow any kind of check,
  -- This procedure can also be called directly. It allows any kind of check,
  -- including less than, greater than, ranges, etc. 
  -- including less than, greater than, ranges, etc. 
  -- Your calling code must convert actual, expected and mask to strings.
  -- Your calling code must convert actual, expected and mask to strings.
  procedure check(
  procedure check(
    constant rpt                : in    string;
    constant rpt                : in    string;
    constant expr               : in    boolean;
    constant expr               : in    boolean;
Line 1749... Line 2356...
        pltbv.test_name(1 to pltbv.test_name_len), pltbv.chk_cnt, pltbv.err_cnt_in_test);
        pltbv.test_name(1 to pltbv.test_name_len), pltbv.chk_cnt, pltbv.err_cnt_in_test);
    end if;
    end if;
    pltbs_update(pltbv, pltbs);
    pltbs_update(pltbv, pltbs);
  end procedure check;
  end procedure check;
 
 
 
 
 
 
  ----------------------------------------------------------------------------
  ----------------------------------------------------------------------------
  -- to_ascending
  -- to_ascending
  --
  --
  -- function to_ascending(
  -- function to_ascending(
  --  constant s                  : std_logic_vector
  --  constant s                  : std_logic_vector
Line 1971... Line 2580...
  begin
  begin
    return hxstr(std_logic_vector(s), prefix, postfix);
    return hxstr(std_logic_vector(s), prefix, postfix);
  end function hxstr;
  end function hxstr;
 
 
  ----------------------------------------------------------------------------
  ----------------------------------------------------------------------------
  -- pltbutils internal procedures, called from other pltbutils procedures.
  -- Miscellaneous
  -- Do not to call these from user's code.
 
  -- These procedures are undocumented in the specification on purpose.
 
  ----------------------------------------------------------------------------
  ----------------------------------------------------------------------------
  procedure pltbs_update(
  -- function str converts integer n to a string with fixed length len and
    variable pltbv              : inout pltbv_t;
  -- leading fillchar
    signal   pltbs              : out   pltbs_t
  function str(
  ) is
      constant n                  : integer;
  begin
      constant len                : integer;
    pltbs.test_num  <= pltbv.test_num;
      constant fillchar           : character := ' '
    print(pltbs.test_name, pltbv.test_name);
  ) return string is
    print(pltbs.info, pltbv.info);
    variable s     : string(1 to len) := (others => fillchar);
    pltbs.chk_cnt   <= pltbv.chk_cnt;
    variable val   : integer := n;
    pltbs.err_cnt   <= pltbv.err_cnt;
    variable digit : integer;
    pltbs.stop_sim  <= pltbv.stop_sim;
  begin
  end procedure pltbs_update;
    for i in 0 to len-1 loop
 
      if val > 0 then
  procedure pltbutils_error(
        digit := val mod 10;
    constant rpt                : in string;
        val := val / 10;
    variable pltbv              : inout pltbv_t;
        s(len - i) := character'val(character'pos('0') + digit);
    signal   pltbs              : out   pltbs_t
 
  ) is
 
  begin
 
    pltbv.err_cnt := pltbv.err_cnt + 1;
 
    pltbv.err_cnt_in_test := pltbv.err_cnt_in_test + 1;
 
    pltbs_update(pltbv, pltbs);
 
    if C_PLTBUTILS_USE_STD_ERROR_MSG then
 
      error_msg(rpt, now, pltbv.test_num,
 
        pltbv.test_name(1 to pltbv.test_name_len), pltbv.err_cnt_in_test);
 
    end if;
 
    if C_PLTBUTILS_USE_CUSTOM_ERROR_MSG then
 
      custom_error_msg(rpt, now, pltbv.test_num,
 
        pltbv.test_name(1 to pltbv.test_name_len), pltbv.err_cnt_in_test);
 
    end if;
    end if;
  end procedure pltbutils_error;
    end loop;
 
    assert val = 0
  procedure stopsim(
      report "str: value " & integer'image(n) & " does not fit in string with length " & integer'image(len)
    constant timestamp          : in time
      severity error;
  ) is
    return s;
  begin
  end function str;
    assert false
 
    report "--- FORCE END OF SIMULATION ---" &
 
           " (ignore this false failure message, it's not a real failure)"
 
    severity failure;
 
  end procedure stopsim;
 
 
 
  procedure startsim_msg(
 
    constant testcase_name      : in string;
 
    constant timestamp          : in time
 
  ) is
 
  begin
 
    print(lf & "--- START OF SIMULATION ---");
 
    print("Testcase: " & testcase_name);
 
    print(time'image(timestamp));
 
  end procedure startsim_msg;
 
 
 
  procedure endsim_msg(
  -- Function str_equal returns true if strings s1 and s2 are equal, otherwise false.
    constant testcase_name      : in string;
  -- The normal VHDL string comparison s1 = s2 only works correctly if the length of 
    constant timestamp          : in time;
  -- the strings are equal. str_equal works even if the lengths differ.
    constant num_tests          : in integer;
  function str_equal (
    constant num_skiptests      : in integer;
    constant s1 : STRING;
    constant num_checks         : in integer;
    constant s2 : STRING
    constant num_errors         : in integer;
  ) return boolean is
    constant show_success_fail  : in boolean
 
  ) is
 
    variable l : line;
 
  begin
  begin
    print(lf & "--- END OF SIMULATION ---");
    if s1'length /= s2'length then
    print("Note: the results presented below are based on the PlTbUtil's check() procedure calls.");
      return FALSE;
    print("      The design may contain more errors, for which there are no check() calls.");
 
    write(l, timestamp, right, 14);
 
    writeline(output, l);
 
    write(l, num_tests, right, 11);
 
    write(l, string'(" Tests"));
 
    writeline(output, l);
 
    write(l, num_skiptests, right, 11);
 
    write(l, string'(" Skipped tests"));
 
    writeline(output, l);
 
    write(l, num_checks, right, 11);
 
    write(l, string'(" Checks"));
 
    writeline(output, l);
 
    write(l, num_errors, right, 11);
 
    write(l, string'(" Errors"));
 
    writeline(output, l);
 
    if show_success_fail then
 
      if num_errors = 0 and num_checks > 0 then
 
        print("*** SUCCESS ***");
 
      elsif num_checks > 0 then
 
        print("*** FAIL ***");
 
      else
      else
        print("*** NO CHECKS ***");
      return (s1 = s2);
      end if;
 
    end if;
 
  end procedure endsim_msg;
 
 
 
  procedure starttest_msg(
 
    constant test_num           : in integer;
 
    constant test_name          : in string;
 
    constant timestamp          : in time
 
  ) is
 
  begin
 
    print(lf & "Test " & str(test_num) & ": " & test_name & " (" & time'image(timestamp) & ")");
 
  end procedure starttest_msg;
 
 
 
  procedure skiptest_msg(
 
    constant test_num           : in integer;
 
    constant test_name          : in string;
 
    constant timestamp          : in time
 
  ) is
 
  begin
 
    print(lf & "Skipping Test " & str(test_num) & ": " & test_name & " (" & time'image(timestamp) & ")");
 
  end procedure skiptest_msg;
 
 
 
  procedure endtest_msg(
 
    constant test_num           : in integer;
 
    constant test_name          : in string;
 
    constant timestamp          : in time;
 
    constant test_active        : in boolean;
 
    constant num_checks_in_test : in integer;
 
    constant num_errors_in_test : in integer
 
  ) is
 
  begin
 
    if test_active then
 
      print("Done with test " & str(test_num) & ": " & test_name & " (" & time'image(timestamp) & ")");
 
    end if;
    end if;
  end procedure endtest_msg;
  end function str_equal;
 
 
  procedure check_msg(
 
    constant rpt                : in string;
 
    constant timestamp          : in time;
 
    constant expr               : in boolean;
 
    constant actual             : in string;
 
    constant expected           : in string;
 
    constant mask               : in string;
 
    constant test_num           : in integer;
 
    constant test_name          : in string;
 
    constant check_num          : in integer;
 
    constant err_cnt_in_test    : in integer
 
  ) is
 
    variable actual_str_len     : integer := 1;
 
    variable actual_str         : string(1 to actual'length+8) := (others => ' ');
 
    variable expected_str       : string(1 to expected'length+10) := (others => ' ');
 
    variable expected_str_len   : integer := 1;
 
    variable mask_str           : string(1 to mask'length+6) := (others => ' ');
 
    variable mask_str_len       : integer := 1;
 
  begin
 
    if not expr then -- Output message only if the check fails
 
      if actual /= "" then
 
        actual_str_len := 8 + actual'length;
 
        actual_str := " Actual=" & actual;
 
      end if;
 
      if expected /= "" then
 
        expected_str_len := 10 + expected'length;
 
        expected_str := " Expected=" & expected;
 
      end if;
 
      if mask /= "" then
 
        mask_str_len := 6 + mask'length;
 
        mask_str := " Mask=" & mask;
 
      end if;
 
      assert false
 
        report "Check " & str(check_num) & "; " & rpt & "; " &
 
               actual_str(1 to actual_str_len) &
 
               expected_str(1 to expected_str_len) &
 
               mask_str(1 to mask_str_len) &
 
               "  in test " & str(test_num) & " " & test_name
 
        severity error;
 
    end if;
 
  end procedure check_msg;
 
 
 
  procedure error_msg(
 
    constant rpt                : in string;
 
    constant timestamp          : in time;
 
    constant test_num           : in integer;
 
    constant test_name          : in string;
 
    constant err_cnt_in_test    : in integer
 
  ) is
 
  begin
 
    assert false
 
    report rpt & " in test " & str(test_num) & ": " & test_name
 
    severity error;
 
  end procedure error_msg;
 
 
 
end package body pltbutils_func_pkg;
end package body pltbutils_func_pkg;
 No newline at end of file
 No newline at end of file
 
 
 No newline at end of file
 No newline at end of file

powered by: WebSVN 2.1.0

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