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

Subversion Repositories pltbutils

Compare Revisions

  • This comparison shows the changes necessary to convert path
    /pltbutils/branches/dev_beta0002/src/vhdl
    from Rev 88 to Rev 95
    Reverse comparison

Rev 88 → Rev 95

/pltbutils_func_pkg.vhd
0,0 → 1,1837
----------------------------------------------------------------------
---- ----
---- PlTbUtils Fuctions and Procedures Package ----
---- ----
---- This file is part of the PlTbUtils project ----
---- http://opencores.org/project,pltbutils ----
---- ----
---- Description: ----
---- PlTbUtils is a collection of functions, procedures and ----
---- components for easily creating stimuli and checking response ----
---- in automatic self-checking testbenches. ----
---- ----
---- This file defines fuctions and procedures for controlling ----
---- stimuli to a DUT and checking response. ----
---- ----
---- To Do: ----
---- - ----
---- ----
---- Author(s): ----
---- - Per Larsson, pela@opencores.org ----
---- ----
----------------------------------------------------------------------
---- ----
---- Copyright (C) 2013-2014 Authors and OPENCORES.ORG ----
---- ----
---- This source file may be used and distributed without ----
---- restriction provided that this copyright statement is not ----
---- removed from the file and that any derivative work contains ----
---- the original copyright notice and the associated disclaimer. ----
---- ----
---- This source file is free software; you can redistribute it ----
---- and/or modify it under the terms of the GNU Lesser General ----
---- Public License as published by the Free Software Foundation; ----
---- either version 2.1 of the License, or (at your option) any ----
---- later version. ----
---- ----
---- This source is distributed in the hope that it will be ----
---- useful, but WITHOUT ANY WARRANTY; without even the implied ----
---- warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR ----
---- PURPOSE. See the GNU Lesser General Public License for more ----
---- details. ----
---- ----
---- You should have received a copy of the GNU Lesser General ----
---- Public License along with this source; if not, download it ----
---- from http://www.opencores.org/lgpl.shtml ----
---- ----
----------------------------------------------------------------------
library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
use std.textio.all;
use work.txt_util.all;
use work.pltbutils_user_cfg_pkg.all;
 
package pltbutils_func_pkg is
 
-- See the package body for a description of the functions and procedures.
constant C_PLTBUTILS_STRLEN : natural := 80;
constant C_PLTBUTILS_TIMEOUT : time := 10 sec;
constant C_WAIT_BEFORE_STOP_TIME : time := 1 us;
 
-- Type for status- and control variable
type pltbv_t is
record
testcase_name : string(1 to C_PLTBUTILS_STRLEN);
testcase_name_len: integer;
test_num : integer;
test_name : string(1 to C_PLTBUTILS_STRLEN);
test_name_len : integer;
info : string(1 to C_PLTBUTILS_STRLEN);
info_len : integer;
test_cnt : integer;
chk_cnt : integer;
err_cnt : integer;
chk_cnt_in_test : integer;
err_cnt_in_test : integer;
stop_sim : std_logic;
end record;
constant C_PLTBV_INIT : pltbv_t := (
(others => ' '), -- testcase_name
1, -- testcase_name_len
0, -- test_num
(others => ' '), -- test_name
1, -- test_name_len
(others => ' '), -- info
1, -- info_len
0, -- test_cnt
0, -- chk_cnt
0, -- err_cnt
0, -- chk_cnt_in_test
0, -- err_cnt_in_test
'0' -- stop_sim
);
 
-- Status- and control signal (subset of pltbv_t)
type pltbs_t is
record
test_num : natural;
test_name : string(1 to C_PLTBUTILS_STRLEN);
info : string(1 to C_PLTBUTILS_STRLEN);
chk_cnt : natural;
err_cnt : natural;
stop_sim : std_logic;
end record;
constant C_PLTBS_INIT : pltbs_t := (
0, -- test_num
(others => ' '), -- test_name
(others => ' '), -- info
0, -- chk_cnt
0, -- err_cnt
'0' -- stop_sim
);
-- startsim
procedure startsim(
constant testcase_name : in string;
variable pltbv : inout pltbv_t;
signal pltbs : out pltbs_t
);
 
-- endsim
procedure endsim(
variable pltbv : inout pltbv_t;
signal pltbs : out pltbs_t;
constant show_success_fail : in boolean := false;
constant force : in boolean := false
);
 
-- starttest
procedure starttest(
constant num : in integer := -1;
constant name : in string;
variable pltbv : inout pltbv_t;
signal pltbs : out pltbs_t
);
procedure starttest(
constant name : in string;
variable pltbv : inout pltbv_t;
signal pltbs : out pltbs_t
);
 
-- endtest
procedure endtest(
variable pltbv : inout pltbv_t;
signal pltbs : out pltbs_t
);
 
-- print, printv, print2
procedure print(
constant active : in boolean;
signal s : out string;
constant txt : in string
);
procedure print(
signal s : out string;
constant txt : in string
);
procedure printv(
constant active : in boolean;
variable s : out string;
constant txt : in string
);
procedure printv(
variable s : out string;
constant txt : in string
);
procedure print(
constant active : in boolean;
variable pltbv : inout pltbv_t;
signal pltbs : out pltbs_t;
constant txt : in string
);
procedure print(
variable pltbv : inout pltbv_t;
signal pltbs : out pltbs_t;
constant txt : in string
);
procedure print2(
constant active : in boolean;
signal s : out string;
constant txt : in string
);
procedure print2(
signal s : out string;
constant txt : in string
);
procedure print2(
constant active : in boolean;
variable pltbv : inout pltbv_t;
signal pltbs : out pltbs_t;
constant txt : in string
);
procedure print2(
variable pltbv : inout pltbv_t;
signal pltbs : out pltbs_t;
constant txt : in string
);
 
-- waitclks
procedure waitclks(
constant N : in natural;
signal clk : 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
);
 
-- waitsig
procedure waitsig(
signal s : in integer;
constant value : in integer;
signal clk : 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
);
procedure waitsig(
signal s : in std_logic;
constant value : in std_logic;
signal clk : 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
);
procedure waitsig(
signal s : in std_logic;
constant value : in integer;
signal clk : 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
);
procedure waitsig(
signal s : in std_logic_vector;
constant value : in std_logic_vector;
signal clk : 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
);
procedure waitsig(
signal s : in std_logic_vector;
constant value : in integer;
signal clk : 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
);
procedure waitsig(
signal s : in unsigned;
constant value : in unsigned;
signal clk : 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
);
procedure waitsig(
signal s : in unsigned;
constant value : in integer;
signal clk : 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
);
procedure waitsig(
signal s : in signed;
constant value : in signed;
signal clk : 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
);
procedure waitsig(
signal s : in signed;
constant value : in integer;
signal clk : 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
procedure check(
constant rpt : in string;
constant actual : in integer;
constant expected : in integer;
variable pltbv : inout pltbv_t;
signal pltbs : out pltbs_t
);
procedure check(
constant rpt : in string;
constant actual : in std_logic;
constant expected : in std_logic;
variable pltbv : inout pltbv_t;
signal pltbs : out pltbs_t
);
procedure check(
constant rpt : in string;
constant actual : in std_logic;
constant expected : in integer;
variable pltbv : inout pltbv_t;
signal pltbs : out pltbs_t
);
procedure check(
constant rpt : in string;
constant actual : in std_logic_vector;
constant expected : in std_logic_vector;
variable pltbv : inout pltbv_t;
signal pltbs : out pltbs_t
);
procedure check(
constant rpt : in string;
constant actual : in std_logic_vector;
constant expected : in std_logic_vector;
constant mask : in std_logic_vector;
variable pltbv : inout pltbv_t;
signal pltbs : out pltbs_t
);
procedure check(
constant rpt : in string;
constant actual : in std_logic_vector;
constant expected : in integer;
variable pltbv : inout pltbv_t;
signal pltbs : out pltbs_t
);
procedure check(
constant rpt : in string;
constant actual : in std_logic_vector;
constant expected : in integer;
constant mask : in std_logic_vector;
variable pltbv : inout pltbv_t;
signal pltbs : out pltbs_t
);
procedure check(
constant rpt : in string;
constant actual : in unsigned;
constant expected : in unsigned;
variable pltbv : inout pltbv_t;
signal pltbs : out pltbs_t
);
procedure check(
constant rpt : in string;
constant actual : in unsigned;
constant expected : in integer;
variable pltbv : inout pltbv_t;
signal pltbs : out pltbs_t
);
procedure check(
constant rpt : in string;
constant actual : in signed;
constant expected : in signed;
variable pltbv : inout pltbv_t;
signal pltbs : out pltbs_t
);
procedure check(
constant rpt : in string;
constant actual : in signed;
constant expected : in integer;
variable pltbv : inout pltbv_t;
signal pltbs : out pltbs_t
);
procedure check(
constant rpt : in string;
constant actual : in string;
constant expected : in string;
variable pltbv : inout pltbv_t;
signal pltbs : out pltbs_t
);
procedure check(
constant rpt : in string;
constant expr : in boolean;
variable pltbv : inout pltbv_t;
signal pltbs : out pltbs_t
);
procedure check(
constant rpt : in string;
constant expr : in boolean;
constant actual : in string;
constant expected : in string;
constant mask : in string;
variable pltbv : inout pltbv_t;
signal pltbs : out pltbs_t
);
 
-- to_ascending
function to_ascending(
constant s : std_logic_vector
) return std_logic_vector;
function to_ascending(
constant s : unsigned
) return unsigned;
function to_ascending(
constant s : signed
) return signed;
 
-- to_descending
function to_descending(
constant s : std_logic_vector
) return std_logic_vector;
function to_descending(
constant s : unsigned
) return unsigned;
function to_descending(
constant s : signed
) return signed;
 
-- hxstr
function hxstr(
constant s : std_logic_vector;
constant prefix : string := "";
constant postfix : string := ""
) return string;
function hxstr(
constant s : unsigned;
constant prefix : string := "";
constant postfix : string := ""
) return string;
function hxstr(
constant s : signed;
constant prefix : string := "";
constant postfix : string := ""
) return string;
 
-- pltbutils internal procedure(s), do not call from user's code
procedure pltbs_update(
variable pltbv : inout pltbv_t;
signal pltbs : out pltbs_t
);
 
procedure stopsim(
constant timestamp : in time
);
 
procedure pltbutils_error(
constant rpt : in string;
variable pltbv : inout pltbv_t;
signal pltbs : out pltbs_t
);
 
procedure startsim_msg(
constant testcase_name : in string;
constant timestamp : in time
);
 
procedure endsim_msg(
constant testcase_name : in string;
constant timestamp : in time;
constant num_tests : in integer;
constant num_checks : in integer;
constant num_errors : in integer;
constant show_success_fail : in boolean
);
 
procedure starttest_msg(
constant test_num : in integer;
constant test_name : in string;
constant timestamp : in time
);
 
procedure endtest_msg(
constant test_num : in integer;
constant test_name : in string;
constant timestamp : in time;
constant num_checks_in_test : in integer;
constant num_errors_in_test : in integer
);
 
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
);
 
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
);
 
end package pltbutils_func_pkg;
 
package body pltbutils_func_pkg is
 
----------------------------------------------------------------------------
-- startsim
--
-- procedure startsim(
-- constant testcase_name : in string;
-- variable pltbv : inout pltbv_t;
-- signal pltbs : out pltbs_t
-- )
--
-- Displays a message at start of simulation message, and initializes
-- PlTbUtils' status and control variable and -signal.
-- Call startsim() only once.
--
-- Arguments:
-- testcase_name Name of the test case, e.g. "tc1".
--
-- pltbv, pltbs PlTbUtils' status- and control variable and
-- -signal.
--
-- NOTE:
-- The start-of-simulation message is not only intended to be informative
-- for humans. It is also intended to be searched for by scripts,
-- e.g. for collecting results from a large number of regression tests.
-- For this reason, the message must be consistent and unique.
--
-- DO NOT MODIFY the message "--- START OF SIMULATION ---".
-- DO NOT OUTPUT AN IDENTICAL MESSAGE anywhere else.
--
-- Example:
-- startsim("tc1", pltbv, pltbs);
----------------------------------------------------------------------------
procedure startsim(
constant testcase_name : in string;
variable pltbv : inout pltbv_t;
signal pltbs : out pltbs_t
) is
variable timestamp : time;
begin
timestamp := now;
pltbv := C_PLTBV_INIT;
printv(pltbv.testcase_name, testcase_name);
pltbv.testcase_name_len := testcase_name'length;
printv(pltbv.test_name, "START OF SIMULATION");
pltbv.test_name_len := 19;
printv(pltbv.info, testcase_name);
pltbv.info_len := testcase_name'length;
pltbs_update(pltbv, pltbs);
if C_PLTBUTILS_USE_STD_STARTSIM_MSG then
startsim_msg(testcase_name, timestamp);
end if;
if C_PLTBUTILS_USE_CUSTOM_STARTSIM_MSG then
custom_startsim_msg(testcase_name, timestamp);
end if;
end procedure startsim;
 
----------------------------------------------------------------------------
-- endsim
--
-- procedure endsim(
-- variable pltbv : inout pltbv_t;
-- signal pltbs : out pltbs_t;
-- constant show_success_fail : in boolean := false;
-- constant force : in boolean := false
-- )
--
-- Displays a message at end of simulation message, presents the simulation
-- results, and stops the simulation.
-- Call endsim() it only once.
--
-- Arguments:
-- pltbv, pltbs PlTbUtils' status- and control variable and
-- -signal.
--
-- show_success_fail If true, endsim() shows "*** SUCCESS ***",
-- "*** FAIL ***", or "*** NO CHECKS ***".
-- Optional, default is false.
--
-- force If true, forces the simulation to stop using an
-- assert failure statement. Use this option only
-- if the normal way of stopping the simulation
-- doesn't work (see below).
-- Optional, default is false.
--
-- The testbench should be designed so that all clocks stop when endsim()
-- sets the signal pltbs.stop_sim to '1'. This should stop the simulator.
-- In some cases that doesn't work, then set the force argument to true, which
-- causes a false assert failure, which should stop the simulator.
-- Scripts searching transcript logs for errors and failures, should ignore
-- the failure with "--- FORCE END OF SIMULATION ---" as part of the report.
--
-- NOTE:
-- The end-of-simulation messages and success/fail messages are not only
-- intended to be informative for humans. They are also intended to be
-- searched for by scripts, e.g. for collecting results from a large number
-- of regression tests.
-- For this reason, the message must be consistent and unique.
--
-- DO NOT MODIFY the messages "--- END OF SIMULATION ---",
-- "*** SUCCESS ***", "*** FAIL ***", "*** NO CHECKS ***".
-- DO NOT OUTPUT IDENTICAL MESSAGES anywhere else.
--
-- Examples:
-- endsim(pltbv, pltbs);
-- endsim(pltbv, pltbs, true);
-- endsim(pltbv, pltbs, true, true);
----------------------------------------------------------------------------
procedure endsim(
variable pltbv : inout pltbv_t;
signal pltbs : out pltbs_t;
constant show_success_fail : in boolean := false;
constant force : in boolean := false
) is
variable timestamp : time;
begin
timestamp := now;
if C_PLTBUTILS_USE_STD_ENDSIM_MSG then
endsim_msg(pltbv.testcase_name(1 to pltbv.testcase_name_len), timestamp,
pltbv.test_cnt, pltbv.chk_cnt, pltbv.err_cnt, show_success_fail);
end if;
if C_PLTBUTILS_USE_CUSTOM_ENDSIM_MSG then
custom_endsim_msg(pltbv.testcase_name(1 to pltbv.testcase_name_len), timestamp,
pltbv.test_cnt, pltbv.chk_cnt, pltbv.err_cnt, show_success_fail);
end if;
pltbv.test_num := 0;
printv(pltbv.test_name, "END OF SIMULATION");
pltbv.test_name_len := 17;
pltbv.stop_sim := '1';
pltbs_update(pltbv, pltbs);
wait for C_WAIT_BEFORE_STOP_TIME;
if force then
if C_PLTBUTILS_USE_STD_STOPSIM then
stopsim(now);
end if;
if C_PLTBUTILS_USE_CUSTOM_STOPSIM then
custom_stopsim(now);
end if;
end if;
wait;
end procedure endsim;
 
----------------------------------------------------------------------------
-- starttest
--
-- procedure starttest(
-- constant num : in integer := -1;
-- constant name : in string;
-- variable pltbv : inout pltbv_t;
-- signal pltbs : out pltbs_t
-- )
--
-- Sets a number (optional) and a name for a test. The number and name will
-- be printed to the screen, and displayed in the simulator's waveform
-- window.
-- The test number and name is also included if there errors reported by the
-- check() procedure calls.
--
-- Arguments:
-- num Test number. Optional, default is to increment
-- the current test number.
--
-- name Test name.
--
-- pltbv, pltbs PlTbUtils' status- and control variable and
-- -signal.
--
-- If the test number is omitted, a new test number is automatically
-- computed by incrementing the current test number.
-- Manually setting the test number may make it easier to find the test code
-- in the testbench code, though.
--
-- Examples:
-- starttest("Reset test", pltbv, pltbs);
-- starttest(1, "Reset test", pltbv, pltbs);
----------------------------------------------------------------------------
procedure starttest(
constant num : in integer := -1;
constant name : in string;
variable pltbv : inout pltbv_t;
signal pltbs : out pltbs_t
) is
variable timestamp : time;
begin
timestamp := now;
if num = -1 then
pltbv.test_num := pltbv.test_num + 1;
else
pltbv.test_num := num;
end if;
printv(pltbv.test_name, name);
pltbv.test_name_len := name'length;
pltbv.test_cnt := pltbv.test_cnt + 1;
pltbv.chk_cnt_in_test := 0;
pltbv.err_cnt_in_test := 0;
pltbs_update(pltbv, pltbs);
if C_PLTBUTILS_USE_STD_STARTTEST_MSG then
starttest_msg(pltbv.test_num, name, timestamp);
end if;
if C_PLTBUTILS_USE_CUSTOM_STARTTEST_MSG then
custom_starttest_msg(pltbv.test_num, name, timestamp);
end if;
end procedure starttest;
 
procedure starttest(
constant name : in string;
variable pltbv : inout pltbv_t;
signal pltbs : out pltbs_t
) is
begin
starttest(-1, name, pltbv, pltbs);
end procedure starttest;
 
----------------------------------------------------------------------------
-- endtest
--
-- procedure endtest(
-- variable pltbv : inout pltbv_t;
-- signal pltbs : out pltbs_t
-- )
--
-- Prints an end-of-test message to the screen.
--
-- Arguments:
-- pltbv, pltbs PlTbUtils' status- and control variable and
-- -signal.
--
-- Example:
-- endtest(pltbv, pltbs);
----------------------------------------------------------------------------
procedure endtest(
variable pltbv : inout pltbv_t;
signal pltbs : out pltbs_t
) is
variable timestamp : time;
begin
timestamp := now;
if C_PLTBUTILS_USE_STD_ENDTEST_MSG then
endtest_msg(pltbv.test_num, pltbv.test_name(1 to pltbv.test_name_len),
timestamp, pltbv.chk_cnt_in_test, pltbv.err_cnt_in_test);
end if;
if C_PLTBUTILS_USE_CUSTOM_ENDTEST_MSG then
custom_endtest_msg(pltbv.test_num, pltbv.test_name(1 to pltbv.test_name_len),
timestamp, pltbv.chk_cnt_in_test, pltbv.err_cnt_in_test);
end if;
printv(pltbv.test_name, " ");
pltbv.test_name_len := 1;
pltbs_update(pltbv, pltbs);
end procedure endtest;
 
----------------------------------------------------------------------------
-- print printv print2
--
-- procedure print(
-- signal s : out string;
-- constant txt : in string
-- )
--
-- procedure print(
-- constant active : in boolean;
-- signal s : out string;
-- constant txt : in string
-- )
--
-- procedure print(
-- variable pltbv : inout pltbv_t;
-- signal pltbs : out pltbs_t;
-- constant txt : in string
-- )
--
-- procedure print(
-- constant active : in boolean;
-- variable pltbv : inout pltbv_t;
-- signal pltbs : out pltbs_t;
-- constant txt : in string
-- )
--
-- procedure printv(
-- variable s : out string;
-- constant txt : in string
-- )
--
-- procedure printv(
-- constant active : in boolean;
-- variable s : out string;
-- constant txt : in string
-- )
--
-- procedure print2(
-- signal s : out string;
-- constant txt : in string
-- )
--
-- procedure print2(
-- constant active : in boolean;
-- signal s : out string;
-- constant txt : in string
-- )
--
-- procedure print2(
-- variable pltbv : inout pltbv_t;
-- signal pltbs : out pltbs_t;
-- constant txt : in string
-- )
--
-- procedure print2(
-- constant active : in boolean;
-- variable pltbv : inout pltbv_t;
-- signal pltbs : out pltbs_t;
-- constant txt : in string
-- )
--
-- print() prints text messages to a signal for viewing in the simulator's
-- waveform window. printv() does the same thing, but to a variable instead.
-- print2() prints both to a signal and to the transcript window.
-- The type of the output can be string or pltbv_t+pltbs_t.
--
-- Arguments:
-- s Signal or variable of type string to be
-- printed to.
--
-- txt The text.
--
-- active The text is only printed if active is true.
-- Useful for debug switches, etc.
--
-- pltbv, pltbs PlTbUtils' status- and control variable and
-- -signal.
--
-- If the string txt is longer than the signal s, the text will be truncated.
-- If txt is shorter, s will be padded with spaces.
--
-- Examples:
-- print(msg, "Hello, world"); -- Prints to signal msg
-- print(G_DEBUG, msg, "Hello, world"); -- Prints to signal msg if
-- -- generic G_DEBUG is true
-- printv(v_msg, "Hello, world"); -- Prints to variable msg
-- print(pltbv, pltbs, "Hello, world"); -- Prints to "info" in waveform window
-- print2(msg, "Hello, world"); -- Prints to signal and transcript window
-- print2(pltbv, pltbs, "Hello, world"); -- Prints to "info" in waveform and
-- -- transcript windows
----------------------------------------------------------------------------
procedure print(
constant active : in boolean;
signal s : out string;
constant txt : in string
) is
variable j : positive := txt 'low;
begin
if active then
for i in s'range loop
if j <= txt 'high then
s(i) <= txt (j);
else
s(i) <= ' ';
end if;
j := j + 1;
end loop;
end if;
end procedure print;
 
procedure print(
signal s : out string;
constant txt : in string
) is
begin
print(true, s, txt);
end procedure print;
 
procedure printv(
constant active : in boolean;
variable s : out string;
constant txt : in string
) is
variable j : positive := txt 'low;
begin
if active then
for i in s'range loop
if j <= txt 'high then
s(i) := txt (j);
else
s(i) := ' ';
end if;
j := j + 1;
end loop;
end if;
end procedure printv;
 
procedure printv(
variable s : out string;
constant txt : in string
) is
begin
printv(true, s, txt);
end procedure printv;
 
-- Print to info element in pltbv/pltbs, which shows up in waveform window
procedure print(
constant active : in boolean;
variable pltbv : inout pltbv_t;
signal pltbs : out pltbs_t;
constant txt : in string
) is
variable j : positive := txt 'low;
begin
if active then
printv(pltbv.info, txt);
pltbv.info_len := txt'length;
pltbs_update(pltbv, pltbs);
end if;
end procedure print;
 
procedure print(
variable pltbv : inout pltbv_t;
signal pltbs : out pltbs_t;
constant txt : in string
) is
begin
print(true, pltbv, pltbs, txt);
end procedure print;
 
procedure print2(
constant active : in boolean;
signal s : out string;
constant txt : in string
) is
begin
if active then
print(s, txt);
print(txt);
end if;
end procedure print2;
 
procedure print2(
signal s : out string;
constant txt : in string
) is
begin
print(true, s, txt);
end procedure print2;
 
procedure print2(
constant active : in boolean;
variable pltbv : inout pltbv_t;
signal pltbs : out pltbs_t;
constant txt : in string
) is
begin
print(active, pltbv, pltbs, txt);
print(active, txt);
end procedure print2;
 
procedure print2(
variable pltbv : inout pltbv_t;
signal pltbs : out pltbs_t;
constant txt : in string
) is
begin
print(true, pltbv, pltbs, txt);
end procedure print2;
 
----------------------------------------------------------------------------
-- waitclks
--
-- procedure waitclks(
-- constant n : in natural;
-- signal clk : 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
-- )
--
-- Waits specified amount of clock cycles of the specified clock.
-- Or, to be more precise, a specified number of specified clock edges of
-- the specified clock.
--
-- Arguments:
-- n Number of rising or falling clock edges to wait.
--
-- clk The clock to wait for.
--
-- pltbv, pltbs PlTbUtils' status- and control variable and
-- -signal.
--
-- falling If true, waits for falling edges, otherwise
-- rising edges. Optional, default is false.
--
-- timeout Timeout time, in case the clock is not working.
-- Optional, default is C_PLTBUTILS_TIMEOUT.
--
-- Examples:
-- waitclks(5, sys_clk, pltbv, pltbs);
-- waitclks(5, sys_clk, pltbv, pltbs true);
-- waitclks(5, sys_clk, pltbv, pltbs, true, 1 ms);
----------------------------------------------------------------------------
procedure waitclks(
constant n : in natural;
signal clk : 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 i : natural := n;
variable v_timeout_time : time;
begin
v_timeout_time := now + timeout;
while i > 0 loop
if falling then
wait until falling_edge(clk) for timeout / n;
else
wait until rising_edge(clk) for timeout / n;
end if;
i := i - 1;
end loop;
if now >= v_timeout_time then
pltbutils_error("waitclks() timeout", pltbv, pltbs);
end if;
end procedure waitclks;
 
----------------------------------------------------------------------------
-- waitsig
--
-- procedure waitsig(
-- signal s : in integer|std_logic|std_logic_vector|unsigned|signed;
-- constant value : in integer|std_logic|std_logic_vector|unsigned|signed;
-- signal clk : 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
-- )
--
-- Waits until a signal has reached a specified value after specified clock
-- edge.
--
-- Arguments:
-- s The signal to test.
-- Supported types: integer, std_logic,
-- std_logic_vector, unsigned, signed.
--
-- value Value to wait for.
-- Same type as data or integer.
--
-- clk The clock.
--
-- pltbv, pltbs PlTbUtils' status- and control variable and
-- -signal.
--
-- falling If true, waits for falling edges, otherwise
-- rising edges. Optional, default is false.
--
-- timeout Timeout time, in case the clock is not working.
-- Optional, default is C_PLTBUTILS_TIMEOUT.
--
-- Examples:
-- waitsig(wr_en, '1', sys_clk, pltbv, pltbs);
-- waitsig(rd_en, 1, sys_clk, pltbv, pltbs, true);
-- waitclks(full, '1', sys_clk, pltbv, pltbs, true, 1 ms);
----------------------------------------------------------------------------
procedure waitsig(
signal s : in integer;
constant value : in integer;
signal clk : 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
v_timeout_time := now + timeout;
l1 : loop
waitclks(1, clk, pltbv, pltbs, falling, timeout);
exit l1 when s = value or now >= v_timeout_time;
end loop;
if now >= v_timeout_time then
pltbutils_error("waitsig() timeout", pltbv, pltbs);
end if;
end procedure waitsig;
 
procedure waitsig(
signal s : in std_logic;
constant value : in std_logic;
signal clk : 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
v_timeout_time := now + timeout;
l1 : loop
waitclks(1, clk, pltbv, pltbs, falling, timeout);
exit l1 when s = value or now >= v_timeout_time;
end loop;
if now >= v_timeout_time then
pltbutils_error("waitsig() timeout", pltbv, pltbs);
end if;
end procedure waitsig;
 
procedure waitsig(
signal s : in std_logic;
constant value : in integer;
signal clk : 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_value : std_logic;
variable v_timeout_time : time;
begin
case value is
when 0 => v_value := '0';
when 1 => v_value := '1';
when others => v_value := 'X';
end case;
if v_value /= 'X' then
waitsig(s, v_value, clk, pltbv, pltbs, falling, timeout);
else
pltbutils_error("waitsig() timeout", pltbv, pltbs);
end if;
end procedure waitsig;
 
procedure waitsig(
signal s : in std_logic_vector;
constant value : in std_logic_vector;
signal clk : 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
v_timeout_time := now + timeout;
l1 : loop
waitclks(1, clk, pltbv, pltbs, falling, timeout);
exit l1 when s = value or now >= v_timeout_time;
end loop;
if now >= v_timeout_time then
pltbutils_error("waitsig() timeout", pltbv, pltbs);
end if;
end procedure waitsig;
 
procedure waitsig(
signal s : in std_logic_vector;
constant value : in integer;
signal clk : 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
waitsig(s, std_logic_vector(to_unsigned(value, s'length)), clk,
pltbv, pltbs, falling, timeout);
end procedure waitsig;
 
procedure waitsig(
signal s : in unsigned;
constant value : in unsigned;
signal clk : 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
v_timeout_time := now + timeout;
l1 : loop
waitclks(1, clk, pltbv, pltbs, falling, timeout);
exit l1 when s = value or now >= v_timeout_time;
end loop;
if now >= v_timeout_time then
pltbutils_error("waitsig() timeout", pltbv, pltbs);
end if;
end procedure waitsig;
 
procedure waitsig(
signal s : in unsigned;
constant value : in integer;
signal clk : 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
waitsig(s, to_unsigned(value, s'length), clk,
pltbv, pltbs, falling, timeout);
end procedure waitsig;
 
procedure waitsig(
signal s : in signed;
constant value : in signed;
signal clk : 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
v_timeout_time := now + timeout;
l1 : loop
waitclks(1, clk, pltbv, pltbs, falling, timeout);
exit l1 when s = value or now >= v_timeout_time;
end loop;
if now >= v_timeout_time then
pltbutils_error("waitsig() timeout", pltbv, pltbs);
end if;
end procedure waitsig;
 
procedure waitsig(
signal s : in signed;
constant value : in integer;
signal clk : 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
waitsig(s, to_signed(value, s'length), clk,
pltbv, pltbs, falling, timeout);
end procedure waitsig;
 
----------------------------------------------------------------------------
-- check
--
-- procedure check(
-- constant rpt : in string;
-- constant actual : in integer|std_logic|std_logic_vector|unsigned|signed|string;
-- constant expected : in integer|std_logic|std_logic_vector|unsigned|signed|string;
-- variable pltbv : inout pltbv_t;
-- signal pltbs : out pltbs_t
-- )
--
-- procedure check(
-- constant rpt : in string;
-- constant actual : in std_logic_vector;
-- constant expected : in std_logic_vector;
-- constant mask : in std_logic_vector;
-- variable pltbv : inout pltbv_t;
-- signal pltbs : out pltbs_t
-- )
--
-- procedure check(
-- constant rpt : in string;
-- constant expr : in boolean;
-- variable pltbv : inout pltbv_t;
-- signal pltbs : out pltbs_t
-- )
--
-- Checks that the value of a signal or variable is equal to expected.
-- If not equal, displays an error message and increments the error counter.
--
-- 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.
-- The message should NOT contain the expected
-- value, becase check() prints that
-- automatically.
--
-- actual The signal or variable to be checked.
-- Supported types: integer, std_logic,
-- std_logic_vector, unsigned, signed.
--
-- expected Expected value.
-- Same type as data or integer.
--
-- mask Bit mask and:ed to data and expected
-- before comparison.
-- Optional if data is std_logic_vector.
-- Not allowed for other types.
--
-- expr boolean expression for checking.
-- This makes it possible to check any kind of
-- expresion, not just equality.
--
-- pltbv, pltbs PlTbUtils' status- and control variable and
-- -signal.
--
-- Examples:
-- check("dat_o after reset", dat_o, 0, pltbv, pltbs);
-- -- With mask:
-- check("Status field in reg_o after start", reg_o, x"01", x"03", pltbv, pltbs);
-- -- Boolean expression:
-- check("Counter after data burst", cnt_o > 10, pltbv, pltbs);
----------------------------------------------------------------------------
-- check integer
procedure check(
constant rpt : in string;
constant actual : in integer;
constant expected : in integer;
variable pltbv : inout pltbv_t;
signal pltbs : out pltbs_t
) is
begin
check(rpt, actual = expected, str(actual), str(expected), "", pltbv, pltbs);
end procedure check;
 
-- check std_logic
procedure check(
constant rpt : in string;
constant actual : in std_logic;
constant expected : in std_logic;
variable pltbv : inout pltbv_t;
signal pltbs : out pltbs_t
) is
begin
check(rpt, actual = expected, str(actual), str(expected), "", pltbv, pltbs);
end procedure check;
 
-- check std_logic against integer
procedure check(
constant rpt : in string;
constant actual : in std_logic;
constant expected : in integer;
variable pltbv : inout pltbv_t;
signal pltbs : out pltbs_t
) is
begin
check(rpt, ((actual = '0' and expected = 0) or (actual = '1' and expected = 1)),
str(actual), str(expected), "", pltbv, pltbs);
end procedure check;
 
-- check std_logic_vector
procedure check(
constant rpt : in string;
constant actual : in std_logic_vector;
constant expected : in std_logic_vector;
variable pltbv : inout pltbv_t;
signal pltbs : out pltbs_t
) is
begin
check(rpt, actual = expected, hxstr(actual, "0x"), hxstr(expected, "0x"), "", pltbv, pltbs);
end procedure check;
 
-- check std_logic_vector with mask
procedure check(
constant rpt : in string;
constant actual : in std_logic_vector;
constant expected : in std_logic_vector;
constant mask : in std_logic_vector;
variable pltbv : inout pltbv_t;
signal pltbs : out pltbs_t
) is
begin
check(rpt, (actual and mask) = (expected and mask),
hxstr(actual, "0x"), hxstr(expected, "0x"), hxstr(mask, "0x"), pltbv, pltbs);
end procedure check;
 
-- check std_logic_vector against integer
procedure check(
constant rpt : in string;
constant actual : in std_logic_vector;
constant expected : in integer;
variable pltbv : inout pltbv_t;
signal pltbs : out pltbs_t
) is
begin
check(rpt, actual, std_logic_vector(to_signed(expected, actual'length)), pltbv, pltbs);
end procedure check;
 
-- check std_logic_vector with mask against integer
procedure check(
constant rpt : in string;
constant actual : in std_logic_vector;
constant expected : in integer;
constant mask : in std_logic_vector;
variable pltbv : inout pltbv_t;
signal pltbs : out pltbs_t
) is
begin
check(rpt, actual, std_logic_vector(to_signed(expected, actual'length)), mask, pltbv, pltbs);
end procedure check;
 
-- check unsigned
procedure check(
constant rpt : in string;
constant actual : in unsigned;
constant expected : in unsigned;
variable pltbv : inout pltbv_t;
signal pltbs : out pltbs_t
) is
begin
check(rpt, actual = expected, hxstr(actual, "0x"), hxstr(expected, "0x"), "", pltbv, pltbs);
end procedure check;
 
-- check unsigned against integer
procedure check(
constant rpt : in string;
constant actual : in unsigned;
constant expected : in integer;
variable pltbv : inout pltbv_t;
signal pltbs : out pltbs_t
) is
begin
check(rpt, actual, to_unsigned(expected, actual'length), pltbv, pltbs);
end procedure check;
 
-- check signed
procedure check(
constant rpt : in string;
constant actual : in signed;
constant expected : in signed;
variable pltbv : inout pltbv_t;
signal pltbs : out pltbs_t
) is
begin
check(rpt, actual = expected, hxstr(actual, "0x"), hxstr(expected, "0x"), "", pltbv, pltbs);
end procedure check;
 
-- check signed against integer
-- TODO: find the bug reported by tb_pltbutils when expected is negative (-1):
-- ** Error: (vsim-86) numstd_conv_unsigned_nu: NATURAL arg value is negative (-1)
procedure check(
constant rpt : in string;
constant actual : in signed;
constant expected : in integer;
variable pltbv : inout pltbv_t;
signal pltbs : out pltbs_t
) is
begin
check(rpt, actual, to_signed(expected, actual'length), pltbv, pltbs);
end procedure check;
-- check string
procedure check(
constant rpt : in string;
constant actual : in string;
constant expected : in string;
variable pltbv : inout pltbv_t;
signal pltbs : out pltbs_t
) is
variable mismatch : boolean := false;
begin
if actual'length /= expected'length then
mismatch := true;
else
for i in 0 to actual'length-1 loop
if actual(i+actual'low) /= expected(i+expected'low) then
mismatch := true;
exit;
end if;
end loop;
end if;
check(rpt, not mismatch, actual, expected, "", pltbv, pltbs);
end procedure check;
-- check with boolean expression
-- Check signal or variable with a boolean expression as argument C_EXPR.
-- This allowes any kind of check.
procedure check(
constant rpt : in string;
constant expr : in boolean;
variable pltbv : inout pltbv_t;
signal pltbs : out pltbs_t
) is
begin
check(rpt, expr, "", "", "", pltbv, pltbs);
end procedure check;
 
procedure check(
constant rpt : in string;
constant expr : in boolean;
constant actual : in string;
constant expected : in string;
constant mask : in string;
variable pltbv : inout pltbv_t;
signal pltbs : out pltbs_t
) is
variable timestamp : time;
begin
timestamp := now;
pltbv.chk_cnt := pltbv.chk_cnt + 1;
pltbv.chk_cnt_in_test := pltbv.chk_cnt_in_test + 1;
if not expr then
pltbv.err_cnt := pltbv.err_cnt + 1;
pltbv.err_cnt_in_test := pltbv.err_cnt_in_test + 1;
end if;
pltbs_update(pltbv, pltbs);
if C_PLTBUTILS_USE_STD_CHECK_MSG then
check_msg(rpt, timestamp, expr, actual, expected, mask, pltbv.test_num,
pltbv.test_name(1 to pltbv.test_name_len), pltbv.chk_cnt, pltbv.err_cnt_in_test);
end if;
if C_PLTBUTILS_USE_CUSTOM_CHECK_MSG then
custom_check_msg(rpt, timestamp, expr, actual, expected, mask, pltbv.test_num,
pltbv.test_name(1 to pltbv.test_name_len), pltbv.chk_cnt, pltbv.err_cnt_in_test);
end if;
pltbs_update(pltbv, pltbs);
end procedure check;
 
----------------------------------------------------------------------------
-- to_ascending
--
-- function to_ascending(
-- constant s : std_logic_vector
-- ) return std_logic_vector;
--
-- function to_ascending(
-- constant s : unsigned
-- ) return unsigned
--
-- function to_ascending(
-- constant s : signed
-- ) return signed;
--
-- Converts a signal or variable to ascending range ("to-range").
-- The argument s can have ascending or descending range.
----------------------------------------------------------------------------
function to_ascending(
constant s : std_logic_vector
) return std_logic_vector is
variable r : std_logic_vector(s'low to s'high);
begin
for i in r'range loop
r(i) := s(i);
end loop;
return r;
end function to_ascending;
 
function to_ascending(
constant s : unsigned
) return unsigned is
variable r : unsigned(s'low to s'high);
begin
for i in r'range loop
r(i) := s(i);
end loop;
return r;
end function to_ascending;
 
function to_ascending(
constant s : signed
) return signed is
variable r : signed(s'low to s'high);
begin
for i in r'range loop
r(i) := s(i);
end loop;
return r;
end function to_ascending;
 
----------------------------------------------------------------------------
-- to_descending
--
-- function to_descending(
-- constant s : std_logic_vector
-- ) return std_logic_vector;
--
-- function to_descending(
-- constant s : unsigned
-- ) return unsigned
--
-- function to_descending(
-- constant s : signed
-- ) return signed;
--
-- Converts a signal or variable to descending range ("downto-range").
-- The argument s can have ascending or descending range.
----------------------------------------------------------------------------
function to_descending(
constant s : std_logic_vector
) return std_logic_vector is
variable r : std_logic_vector(s'high downto s'low);
begin
for i in r'range loop
r(i) := s(i);
end loop;
return r;
end function to_descending;
 
function to_descending(
constant s : unsigned
) return unsigned is
variable r : unsigned(s'high downto s'low);
begin
for i in r'range loop
r(i) := s(i);
end loop;
return r;
end function to_descending;
 
function to_descending(
constant s : signed
) return signed is
variable r : signed(s'high downto s'low);
begin
for i in r'range loop
r(i) := s(i);
end loop;
return r;
end function to_descending;
 
----------------------------------------------------------------------------
-- hxstr
-- function hxstr(
-- constant s : std_logic_vector;
-- constant prefix : string := "";
-- constant postfix : string := ""
-- ) return string;
--
-- function hxstr(
-- constant s : unsigned;
-- constant prefix : string := "";
-- constant postfix : string := ""
-- ) return string;
--
-- function hxstr(
-- constant s : signed;
-- constant prefix : string := "";
-- constant postfix : string := ""
-- ) return string;
--
-- Converts a signal to a string in hexadecimal format.
-- An optional prefix can be specified, e.g. "0x".
--
-- The signal can have ascending range ( "to-range" ) or descending range
-- ("downto-range").
--
-- hxstr is a wrapper function for hstr in txt_util.
-- hstr only support std_logic_vector with descending range.
--
-- Examples:
-- print("value=" & hxstr(s));
-- print("value=" & hxstr(s, "0x"));
----------------------------------------------------------------------------
function hxstr(
constant s : std_logic_vector;
constant prefix : string := "";
constant postfix : string := ""
) return string is
begin
return prefix & hstr(to_descending(s)) & postfix;
end function hxstr;
 
function hxstr(
constant s : unsigned;
constant prefix : string := "";
constant postfix : string := ""
) return string is
begin
return prefix & hstr(to_descending(std_logic_vector(s))) & postfix;
end function hxstr;
 
function hxstr(
constant s : signed;
constant prefix : string := "";
constant postfix : string := ""
) return string is
begin
return prefix & hstr(to_descending(std_logic_vector(s))) & postfix;
end function hxstr;
 
----------------------------------------------------------------------------
-- pltbutils internal procedure(s), called from other pltbutils procedures.
-- Do not to call this/these from user's code.
-- This/these procedures are undocumented in the specification on purpose.
----------------------------------------------------------------------------
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 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_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_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;
 
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 endtest_msg(
constant test_num : in integer;
constant test_name : in string;
constant timestamp : in time;
constant num_checks_in_test : in integer;
constant num_errors_in_test : in integer
) is
begin
print("Done with test " & str(test_num) & ": " & test_name & " (" & time'image(timestamp) & ")");
end procedure endtest_msg;
 
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;
/pltbutils_user_cfg_pkg.vhd
0,0 → 1,324
----------------------------------------------------------------------
---- ----
---- PlTbUtils User Configuration Package ----
---- ----
---- This file is part of the PlTbUtils project ----
---- http://opencores.org/project,pltbutils ----
---- ----
---- Description: ----
---- PlTbUtils is a collection of functions, procedures and ----
---- components for easily creating stimuli and checking response ----
---- in automatic self-checking testbenches. ----
---- ----
---- This file defines the user's customizations. ----
---- ----
---- If the user wishes to modify anything in this file, it is ----
---- recommended that he/she first copies it to another directory ----
---- and modifies the copy. Also make sure that the simulator ----
---- read the modified file instead of the original. ----
---- This makes it easier to update pltbutils to new versions ----
---- without destroying the customizations. ----
---- ----
---- To Do: ----
---- - ----
---- ----
---- Author(s): ----
---- - Per Larsson, pela@opencores.org ----
---- ----
----------------------------------------------------------------------
---- ----
---- Copyright (C) 2014 Authors and OPENCORES.ORG ----
---- ----
---- This source file may be used and distributed without ----
---- restriction provided that this copyright statement is not ----
---- removed from the file and that any derivative work contains ----
---- the original copyright notice and the associated disclaimer. ----
---- ----
---- This source file is free software; you can redistribute it ----
---- and/or modify it under the terms of the GNU Lesser General ----
---- Public License as published by the Free Software Foundation; ----
---- either version 2.1 of the License, or (at your option) any ----
---- later version. ----
---- ----
---- This source is distributed in the hope that it will be ----
---- useful, but WITHOUT ANY WARRANTY; without even the implied ----
---- warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR ----
---- PURPOSE. See the GNU Lesser General Public License for more ----
---- details. ----
---- ----
---- You should have received a copy of the GNU Lesser General ----
---- Public License along with this source; if not, download it ----
---- from http://www.opencores.org/lgpl.shtml ----
---- ----
----------------------------------------------------------------------
library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
--use std.textio.all;
--use std.env.all; -- Uncomment if using stop or finish in custom_stopsim() below.
use work.txt_util.all;
 
package pltbutils_user_cfg_pkg is
 
--- Constants ---
-- The user is free to modify the values to fit his/her requirements.
constant C_PLTBUTILS_USE_STD_STARTSIM_MSG : boolean := true;
constant C_PLTBUTILS_USE_STD_ENDSIM_MSG : boolean := true;
constant C_PLTBUTILS_USE_STD_STARTTEST_MSG : boolean := true;
constant C_PLTBUTILS_USE_STD_ENDTEST_MSG : boolean := true;
constant C_PLTBUTILS_USE_STD_CHECK_MSG : boolean := true;
constant C_PLTBUTILS_USE_STD_ERROR_MSG : boolean := true;
constant C_PLTBUTILS_USE_STD_STOPSIM : boolean := true;
constant C_PLTBUTILS_USE_CUSTOM_STARTSIM_MSG : boolean := false;
constant C_PLTBUTILS_USE_CUSTOM_ENDSIM_MSG : boolean := false;
constant C_PLTBUTILS_USE_CUSTOM_STARTTEST_MSG : boolean := false;
constant C_PLTBUTILS_USE_CUSTOM_ENDTEST_MSG : boolean := false;
constant C_PLTBUTILS_USE_CUSTOM_CHECK_MSG : boolean := false;
constant C_PLTBUTILS_USE_CUSTOM_ERROR_MSG : boolean := false;
constant C_PLTBUTILS_USE_CUSTOM_STOPSIM : boolean := false;
 
--- Procedure declarations ---
-- The user should NOT modify these.
procedure custom_stopsim(
constant timestamp : in time
);
procedure custom_startsim_msg(
constant testcase_name : in string;
constant timestamp : in time
);
procedure custom_endsim_msg(
constant testcase_name : in string;
constant timestamp : in time;
constant num_tests : in integer;
constant num_checks : in integer;
constant num_errors : in integer;
constant show_success_fail : in boolean
);
procedure custom_starttest_msg(
constant test_num : in integer;
constant test_name : in string;
constant timestamp : in time
);
procedure custom_endtest_msg(
constant test_num : in integer;
constant test_name : in string;
constant timestamp : in time;
constant num_checks_in_test : in integer;
constant num_errors_in_test : in integer
);
procedure custom_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
);
procedure custom_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
);
--- User's function and procedure declarations ---
-- Example for use with TeamCity. Remove, modify or replace
-- to suit other other continous integration tools or scripts, if you need to.
function tcfilter(
constant s : string
) return string;
 
end package pltbutils_user_cfg_pkg;
 
package body pltbutils_user_cfg_pkg is
 
--- Procedure definitions ---
-- The user should NOT modify the arguments,
-- but the behaviour is free to modify to fit the user's requirements.
procedure custom_stopsim(
constant timestamp : in time
) is
begin
-- The best way to stop a simulation differs between different simulators.
-- Below are some examples. Modify to suit your simulator.
-- Works with some simulators that supports VHDL-2008.
-- Requires that 'use std.env.all' at the top of the file is uncommented.
--stop;
-- Works with some simulators that support VHDL-2008.
-- Requires that 'use std.env.all' at the top of the file is uncommented.
--finish;
-- Works in all simulators known by the author, but ugly.
assert false
report "--- FORCE END OF SIMULATION ---" &
" (ignore this false failure message, it's not a real failure)"
severity failure;
end procedure custom_stopsim;
 
-- Example custom messages for TeamCity.
-- Edit to suit other continous integration tools or scripts, if you need to.
-- General TeamCity information: http://www.jetbrains.com/teamcity/
-- http://en.wikipedia.org/wiki/Teamcity
-- TeamCity test reporting: http://confluence.jetbrains.com/display/TCD8/Build+Script+Interaction+with+TeamCity#BuildScriptInteractionwithTeamCity-ReportingTests
procedure custom_startsim_msg(
constant testcase_name : in string;
constant timestamp : in time
) is
begin
print("##teamcity[testSuiteStarted name='" & tcfilter(testcase_name) & "']");
end procedure custom_startsim_msg;
 
procedure custom_endsim_msg(
constant testcase_name : in string;
constant timestamp : in time;
constant num_tests : in integer;
constant num_checks : in integer;
constant num_errors : in integer;
constant show_success_fail : in boolean
) is
begin
-- TeamCity ignores all arguments except testcase_name
print("##teamcity[testSuiteFinished name='" & tcfilter(testcase_name) & "']");
end procedure custom_endsim_msg;
procedure custom_starttest_msg(
constant test_num : in integer;
constant test_name : in string;
constant timestamp : in time
) is
begin
-- TeamCity ignores test_num and timestamp
print("##teamcity[testStarted name='" & tcfilter(test_name) & "']");
end procedure custom_starttest_msg;
 
procedure custom_endtest_msg(
constant test_num : in integer;
constant test_name : in string;
constant timestamp : in time;
constant num_checks_in_test : in integer;
constant num_errors_in_test : in integer
) is
begin
-- TeamCity ignores all arguments except test_name
print("##teamcity[testFinished name='" & tcfilter(test_name) & "']");
end procedure custom_endtest_msg;
 
procedure custom_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 comparison_str : string(1 to 32) := (others => ' ');
variable comparison_str_len : integer := 1;
variable actual_str : string(1 to 32) := (others => ' ');
variable actual_str_len : integer := 1;
variable expected_str : string(1 to 32) := (others => ' ');
variable expected_str_len : integer := 1;
variable mask_str : string(1 to 32) := (others => ' ');
variable mask_str_len : integer := 1;
begin
if not expr then -- Output message only if the check fails
if err_cnt_in_test <= 1 then -- TeamCity allows max one error message per test
if actual /= "" then
actual_str_len := 10 + actual'length;
actual_str(1 to actual_str_len) := " actual='" & tcfilter(actual) & "'";
end if;
if expected /= "" then
comparison_str_len := 26;
comparison_str(1 to comparison_str_len) := " type='comparisonFailure' ";
expected_str_len := 12 + expected'length;
expected_str(1 to expected_str_len) := " expected='" & tcfilter(expected) & "'";
end if;
if mask /= "" then
mask_str_len := 17 + mask'length;
mask_str(1 to mask_str_len) := " details='mask=" & tcfilter(mask) & "' ";
end if;
print("##teamcity[testFailed" &
comparison_str(1 to comparison_str_len) &
"name='" & tcfilter(test_name) & "' " &
"message='" & tcfilter(rpt) & "' " &
expected_str(1 to expected_str_len) &
actual_str(1 to actual_str_len) &
mask_str(1 to mask_str_len) &
"]");
else
print("(TeamCity error message filtered out, because max one message is allowed for each test)");
end if;
end if;
end procedure custom_check_msg;
procedure custom_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
if err_cnt_in_test <= 1 then -- TeamCity allows max one error message per test
print("##teamcity[testFailed" &
"name='" & tcfilter(test_name) & "' " &
"message='" & tcfilter(rpt) & "']");
else
print("(TeamCity error message filtered out, because max one message is allowed for each test)");
end if;
end procedure custom_error_msg;
--- User's function and procedure definitions ---
-- Example for use with TeamCity. Remove, modify or replace
-- to suit other other continous integration tools or scripts, if you need to.
 
-- TeamCity string filter. Filters out characters which are not allowed in TeamCity messages.
-- Search for "escaped values" in
-- http://confluence.jetbrains.com/display/TCD8/Build+Script+Interaction+with+TeamCity#BuildScriptInteractionwithTeamCity-ReportingTests
-- The TeamCity escape character is not used, because that changes the length of the string.
-- The VHDL code can be simplified if it doesn't have to deal with changes of string
-- lengths.
function tcfilter(
constant s : string
) return string is
variable r : string(s'range) := (others => (' '));
begin
for i in s'range loop
if s(i) = ''' then
r(i) := '`';
elsif s(i) = lf or s(i) = cr then
r(i) := ' ';
elsif s(i) = '|' then
r(i) := '/';
elsif s(i) = '[' then
r(i) := '{';
elsif s(i) = ']' then
r(i) := '}';
else
r(i) := s(i);
end if;
end loop;
return r;
end function tcfilter;
end package body pltbutils_user_cfg_pkg;
/pltbutils_files.lst
0,0 → 1,5
txt_util.vhd
pltbutils_user_cfg_pkg.vhd
pltbutils_func_pkg.vhd
pltbutils_comp.vhd
pltbutils_comp_pkg.vhd
/pltbutils_comp_pkg.vhd
0,0 → 1,86
----------------------------------------------------------------------
---- ----
---- PlTbUtils Component Declarations ----
---- ----
---- This file is part of the PlTbUtils project ----
---- http://opencores.org/project,pltbutils ----
---- ----
---- Description: ----
---- PlTbUtils is a collection of functions, procedures and ----
---- components for easily creating stimuli and checking response ----
---- in automatic self-checking testbenches. ----
---- ----
---- This file declares testbench components, which are defined ----
---- in pltbutils_comp.vhd . ----
---- "use" this file in your testbech, e.g. ----
---- use work.pltbutils_comp_pkg.all; ----
---- ----
---- ----
---- To Do: ----
---- - ----
---- ----
---- Author(s): ----
---- - Per Larsson, pela@opencores.org ----
---- ----
----------------------------------------------------------------------
---- ----
---- Copyright (C) 2013 Authors and OPENCORES.ORG ----
---- ----
---- This source file may be used and distributed without ----
---- restriction provided that this copyright statement is not ----
---- removed from the file and that any derivative work contains ----
---- the original copyright notice and the associated disclaimer. ----
---- ----
---- This source file is free software; you can redistribute it ----
---- and/or modify it under the terms of the GNU Lesser General ----
---- Public License as published by the Free Software Foundation; ----
---- either version 2.1 of the License, or (at your option) any ----
---- later version. ----
---- ----
---- This source is distributed in the hope that it will be ----
---- useful, but WITHOUT ANY WARRANTY; without even the implied ----
---- warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR ----
---- PURPOSE. See the GNU Lesser General Public License for more ----
---- details. ----
---- ----
---- You should have received a copy of the GNU Lesser General ----
---- Public License along with this source; if not, download it ----
---- from http://www.opencores.org/lgpl.shtml ----
---- ----
----------------------------------------------------------------------
 
library ieee;
use ieee.std_logic_1164.all;
 
package pltbutils_comp_pkg is
 
-- See pltbutils_comp.vhd for a description of the components.
 
component pltbutils_clkgen is
generic (
G_PERIOD : time := 10 ns;
G_INITVALUE : std_logic := '0'
);
port (
clk_o : out std_logic;
clk_n_o : out std_logic;
stop_sim_i : in std_logic
);
end component pltbutils_clkgen;
-- Instansiation template
-- (copy to your own file and remove the comment characters):
--pltbutils_clkgen0 : pltbutils_clkgen
-- generic map (
-- G_PERIOD => G_PERIOD,
-- G_INITVALUE => '0'
-- )
-- port map (
-- clk_o => clk,
-- clk_n_o => clk_n,
-- stop_sim_i => stop_sim
-- );
 
end package pltbutils_comp_pkg;
 
 
/pltbutils_comp.vhd
0,0 → 1,85
----------------------------------------------------------------------
---- ----
---- PlTbUtils Components ----
---- ----
---- This file is part of the PlTbUtils project ----
---- http://opencores.org/project,pltbutils ----
---- ----
---- Description: ----
---- PlTbUtils is a collection of functions, procedures and ----
---- components for easily creating stimuli and checking response ----
---- in automatic self-checking testbenches. ----
---- ----
---- pltbutils_comp.vhd (this file) defines testbench components. ----
---- ----
---- ----
---- To Do: ----
---- - ----
---- ----
---- Author(s): ----
---- - Per Larsson, pela@opencores.org ----
---- ----
----------------------------------------------------------------------
---- ----
---- Copyright (C) 2013 Authors and OPENCORES.ORG ----
---- ----
---- This source file may be used and distributed without ----
---- restriction provided that this copyright statement is not ----
---- removed from the file and that any derivative work contains ----
---- the original copyright notice and the associated disclaimer. ----
---- ----
---- This source file is free software; you can redistribute it ----
---- and/or modify it under the terms of the GNU Lesser General ----
---- Public License as published by the Free Software Foundation; ----
---- either version 2.1 of the License, or (at your option) any ----
---- later version. ----
---- ----
---- This source is distributed in the hope that it will be ----
---- useful, but WITHOUT ANY WARRANTY; without even the implied ----
---- warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR ----
---- PURPOSE. See the GNU Lesser General Public License for more ----
---- details. ----
---- ----
---- You should have received a copy of the GNU Lesser General ----
---- Public License along with this source; if not, download it ----
---- from http://www.opencores.org/lgpl.shtml ----
---- ----
----------------------------------------------------------------------
 
----------------------------------------------------------------------
-- pltbutils_clkgen
-- Creates a clock for use in a testbech.
-- A non-inverted as well as an inverted output is available,
-- use one or both depending on if you need a single-ended or
-- differential clock.
-- The clock stops when input port stop_sim goes '1'.
-- This makes the simulator stop (unless there are other infinite
-- processes running in the simulation).
----------------------------------------------------------------------
library ieee;
use ieee.std_logic_1164.all;
 
entity pltbutils_clkgen is
generic (
G_PERIOD : time := 10 ns;
G_INITVALUE : std_logic := '0'
);
port (
clk_o : out std_logic;
clk_n_o : out std_logic;
stop_sim_i : in std_logic
);
end entity pltbutils_clkgen;
 
architecture bhv of pltbutils_clkgen is
constant C_HALF_PERIOD : time := G_PERIOD / 2;
signal clk : std_logic := G_INITVALUE;
begin
 
clk <= not clk and not stop_sim_i after C_HALF_PERIOD;
clk_o <= clk;
clk_n_o <= not clk;
 
end architecture bhv;
 
 
/txt_util.vhd
0,0 → 1,881
----------------------------------------------------------------------
---- ----
---- txt_util.vhd ----
---- ----
---- This file is part of the PlTbUtils project ----
---- http://opencores.org/project,pltbutils ----
---- ----
---- Description: ----
---- PlTbUtils is a collection of functions, procedures and ----
---- components for easily creating stimuli and checking response ----
---- in automatic self-checking testbenches. ----
---- ----
---- This file defines useful functions an procedures for text ----
---- handling text in VHDL. ----
---- ----
---- To Do: ----
---- - ----
---- ----
---- Source: ----
---- http://www.mrc.uidaho.edu/mrc/people/jff/vhdl_info/txt_util.vhd -
---- Thanks to Stefan Doll and James F. Frenzel. ---- ----
----------------------------------------------------------------------
--
-- Disclaimer: Derived from txt_util.vhd on www.stefanvhdl.com
--
-- Revision History:
--
-- 1.0 URL: http://www.stefanvhdl.com/vhdl/vhdl/txt_util.vhd
--
-- 1.1 Modified str_read() to prevent extra character (JFF)
--
-- 1.2 Added is_whitespace() and strip_whitespace() (JFF)
--
-- 1.3 Added first_string() and chomp() (JFF)
--
-- 1.4 Added hex string and integer string conversion (JFF)
--
----------------------------------------------------------------
 
library ieee;
use ieee.std_logic_1164.all;
use std.textio.all;
 
package txt_util is
 
-- prints a message to the screen
procedure print(text: string);
 
-- prints the message when active
-- useful for debug switches
procedure print(active: boolean; text: string);
 
-- converts std_logic into a character
function chr(sl: std_logic) return character;
 
-- converts std_logic into a string (1 to 1)
function str(sl: std_logic) return string;
 
-- converts std_logic_vector into a string (binary base)
function str(slv: std_logic_vector) return string;
 
-- converts boolean into a string
function str(b: boolean) return string;
 
-- converts an integer into a single character
-- (can also be used for hex conversion and other bases)
function chr(int: integer) return character;
 
-- converts integer into string using specified base
function str(int: integer; base: integer) return string;
 
-- converts integer to string, using base 10
function str(int: integer) return string;
 
-- convert std_logic_vector into a string in hex format
function hstr(slv: std_logic_vector) return string;
 
 
-- functions to manipulate strings
-----------------------------------
 
-- convert a character to upper case
function to_upper(c: character) return character;
 
-- convert a character to lower case
function to_lower(c: character) return character;
 
-- convert a string to upper case
function to_upper(s: string) return string;
 
-- convert a string to lower case
function to_lower(s: string) return string;
-- checks if whitespace (JFF)
function is_whitespace(c: character) return boolean;
-- remove leading whitespace (JFF)
function strip_whitespace(s: string) return string;
-- return first nonwhitespace substring (JFF)
function first_string(s: string) return string;
-- finds the first non-whitespace substring in a string and (JFF)
-- returns both the substring and the original with the substring removed
procedure chomp(variable s: inout string; variable shead: out string);
 
-- functions to convert strings into other formats
--------------------------------------------------
-- converts a character into std_logic
function to_std_logic(c: character) return std_logic;
-- converts a hex character into std_logic_vector (JFF)
function chr_to_slv(c: character) return std_logic_vector;
-- converts a character into int (JFF)
function chr_to_int(c: character) return integer;
-- converts a binary string into std_logic_vector
function to_std_logic_vector(s: string) return std_logic_vector;
-- converts a hex string into std_logic_vector (JFF)
function hstr_to_slv(s: string) return std_logic_vector;
-- converts a decimal string into an integer (JFF)
function str_to_int(s: string) return integer;
 
 
-- file I/O
-----------
-- read variable length string from input file
procedure str_read(file in_file: TEXT;
res_string: out string);
-- print string to a file and start new line
procedure print(file out_file: TEXT;
new_string: in string);
-- print character to a file and start new line
procedure print(file out_file: TEXT;
char: in character);
end txt_util;
 
 
 
 
package body txt_util is
 
 
 
 
-- prints text to the screen
 
procedure print(text: string) is
variable msg_line: line;
begin
write(msg_line, text);
writeline(output, msg_line);
end print;
 
 
 
 
-- prints text to the screen when active
 
procedure print(active: boolean; text: string) is
begin
if active then
print(text);
end if;
end print;
 
 
-- converts std_logic into a character
 
function chr(sl: std_logic) return character is
variable c: character;
begin
case sl is
when 'U' => c:= 'U';
when 'X' => c:= 'X';
when '0' => c:= '0';
when '1' => c:= '1';
when 'Z' => c:= 'Z';
when 'W' => c:= 'W';
when 'L' => c:= 'L';
when 'H' => c:= 'H';
when '-' => c:= '-';
end case;
return c;
end chr;
 
 
 
-- converts std_logic into a string (1 to 1)
 
function str(sl: std_logic) return string is
variable s: string(1 to 1);
begin
s(1) := chr(sl);
return s;
end str;
 
 
 
-- converts std_logic_vector into a string (binary base)
-- (this also takes care of the fact that the range of
-- a string is natural while a std_logic_vector may
-- have an integer range)
 
function str(slv: std_logic_vector) return string is
variable result : string (1 to slv'length);
variable r : integer;
begin
r := 1;
for i in slv'range loop
result(r) := chr(slv(i));
r := r + 1;
end loop;
return result;
end str;
 
 
function str(b: boolean) return string is
 
begin
if b then
return "true";
else
return "false";
end if;
end str;
 
 
-- converts an integer into a character
-- for 0 to 9 the obvious mapping is used, higher
-- values are mapped to the characters A-Z
-- (this is usefull for systems with base > 10)
-- (adapted from Steve Vogwell's posting in comp.lang.vhdl)
 
function chr(int: integer) return character is
variable c: character;
begin
case int is
when 0 => c := '0';
when 1 => c := '1';
when 2 => c := '2';
when 3 => c := '3';
when 4 => c := '4';
when 5 => c := '5';
when 6 => c := '6';
when 7 => c := '7';
when 8 => c := '8';
when 9 => c := '9';
when 10 => c := 'A';
when 11 => c := 'B';
when 12 => c := 'C';
when 13 => c := 'D';
when 14 => c := 'E';
when 15 => c := 'F';
when 16 => c := 'G';
when 17 => c := 'H';
when 18 => c := 'I';
when 19 => c := 'J';
when 20 => c := 'K';
when 21 => c := 'L';
when 22 => c := 'M';
when 23 => c := 'N';
when 24 => c := 'O';
when 25 => c := 'P';
when 26 => c := 'Q';
when 27 => c := 'R';
when 28 => c := 'S';
when 29 => c := 'T';
when 30 => c := 'U';
when 31 => c := 'V';
when 32 => c := 'W';
when 33 => c := 'X';
when 34 => c := 'Y';
when 35 => c := 'Z';
when others => c := '?';
end case;
return c;
end chr;
 
 
 
-- convert integer to string using specified base
-- (adapted from Steve Vogwell's posting in comp.lang.vhdl)
 
function str(int: integer; base: integer) return string is
 
variable temp: string(1 to 10);
variable num: integer;
variable abs_int: integer;
variable len: integer := 1;
variable power: integer := 1;
 
begin
 
-- bug fix for negative numbers
abs_int := abs(int);
 
num := abs_int;
 
while num >= base loop -- Determine how many
len := len + 1; -- characters required
num := num / base; -- to represent the
end loop ; -- number.
 
for i in len downto 1 loop -- Convert the number to
temp(i) := chr(abs_int/power mod base); -- a string starting
power := power * base; -- with the right hand
end loop ; -- side.
 
-- return result and add sign if required
if int < 0 then
return '-'& temp(1 to len);
else
return temp(1 to len);
end if;
 
end str;
 
 
-- convert integer to string, using base 10
function str(int: integer) return string is
 
begin
 
return str(int, 10) ;
 
end str;
 
 
 
-- converts a std_logic_vector into a hex string.
function hstr(slv: std_logic_vector) return string is
variable hexlen: integer;
variable longslv : std_logic_vector(67 downto 0) := (others => '0');
variable hex : string(1 to 16);
variable fourbit : std_logic_vector(3 downto 0);
begin
hexlen := (slv'left+1)/4;
if (slv'left+1) mod 4 /= 0 then
hexlen := hexlen + 1;
end if;
longslv(slv'left downto 0) := slv;
for i in (hexlen -1) downto 0 loop
fourbit := longslv(((i*4)+3) downto (i*4));
case fourbit is
when "0000" => hex(hexlen -I) := '0';
when "0001" => hex(hexlen -I) := '1';
when "0010" => hex(hexlen -I) := '2';
when "0011" => hex(hexlen -I) := '3';
when "0100" => hex(hexlen -I) := '4';
when "0101" => hex(hexlen -I) := '5';
when "0110" => hex(hexlen -I) := '6';
when "0111" => hex(hexlen -I) := '7';
when "1000" => hex(hexlen -I) := '8';
when "1001" => hex(hexlen -I) := '9';
when "1010" => hex(hexlen -I) := 'A';
when "1011" => hex(hexlen -I) := 'B';
when "1100" => hex(hexlen -I) := 'C';
when "1101" => hex(hexlen -I) := 'D';
when "1110" => hex(hexlen -I) := 'E';
when "1111" => hex(hexlen -I) := 'F';
when "ZZZZ" => hex(hexlen -I) := 'z';
when "UUUU" => hex(hexlen -I) := 'u';
when "XXXX" => hex(hexlen -I) := 'x';
when others => hex(hexlen -I) := '?';
end case;
end loop;
return hex(1 to hexlen);
end hstr;
 
 
 
-- functions to manipulate strings
-----------------------------------
 
 
-- convert a character to upper case
 
function to_upper(c: character) return character is
 
variable u: character;
 
begin
 
case c is
when 'a' => u := 'A';
when 'b' => u := 'B';
when 'c' => u := 'C';
when 'd' => u := 'D';
when 'e' => u := 'E';
when 'f' => u := 'F';
when 'g' => u := 'G';
when 'h' => u := 'H';
when 'i' => u := 'I';
when 'j' => u := 'J';
when 'k' => u := 'K';
when 'l' => u := 'L';
when 'm' => u := 'M';
when 'n' => u := 'N';
when 'o' => u := 'O';
when 'p' => u := 'P';
when 'q' => u := 'Q';
when 'r' => u := 'R';
when 's' => u := 'S';
when 't' => u := 'T';
when 'u' => u := 'U';
when 'v' => u := 'V';
when 'w' => u := 'W';
when 'x' => u := 'X';
when 'y' => u := 'Y';
when 'z' => u := 'Z';
when others => u := c;
end case;
 
return u;
 
end to_upper;
 
 
-- convert a character to lower case
 
function to_lower(c: character) return character is
 
variable l: character;
 
begin
 
case c is
when 'A' => l := 'a';
when 'B' => l := 'b';
when 'C' => l := 'c';
when 'D' => l := 'd';
when 'E' => l := 'e';
when 'F' => l := 'f';
when 'G' => l := 'g';
when 'H' => l := 'h';
when 'I' => l := 'i';
when 'J' => l := 'j';
when 'K' => l := 'k';
when 'L' => l := 'l';
when 'M' => l := 'm';
when 'N' => l := 'n';
when 'O' => l := 'o';
when 'P' => l := 'p';
when 'Q' => l := 'q';
when 'R' => l := 'r';
when 'S' => l := 's';
when 'T' => l := 't';
when 'U' => l := 'u';
when 'V' => l := 'v';
when 'W' => l := 'w';
when 'X' => l := 'x';
when 'Y' => l := 'y';
when 'Z' => l := 'z';
when others => l := c;
end case;
 
return l;
 
end to_lower;
 
 
 
-- convert a string to upper case
 
function to_upper(s: string) return string is
 
variable uppercase: string (s'range);
 
begin
 
for i in s'range loop
uppercase(i):= to_upper(s(i));
end loop;
return uppercase;
 
end to_upper;
 
 
 
-- convert a string to lower case
 
function to_lower(s: string) return string is
 
variable lowercase: string (s'range);
 
begin
 
for i in s'range loop
lowercase(i):= to_lower(s(i));
end loop;
return lowercase;
 
end to_lower;
-- checks if whitespace (JFF)
function is_whitespace(c: character) return boolean is
begin
if (c = ' ') or (c = HT) then
return true;
else return false;
end if;
end is_whitespace;
-- remove leading whitespace (JFF)
function strip_whitespace(s: string) return string is
variable stemp : string (s'range);
variable j, k : positive := 1;
begin
-- fill stemp with blanks
for i in s'range loop
stemp(i) := ' ';
end loop;
-- find first non-whitespace in s
for i in s'range loop
if is_whitespace(s(i)) then
j := j + 1;
else exit;
end if;
end loop;
-- j points to first non-whitespace
-- copy remainder of s into stemp
-- starting at 1
for i in j to s'length loop
stemp(k) := s(i);
k := k + 1;
end loop;
return stemp;
end strip_whitespace;
 
 
-- return first non-whitespacesubstring (JFF)
function first_string(s: string) return string is
variable stemp, s2 : string (s'range);
begin
-- fill s2 with blanks
for i in s'range loop
s2(i) := ' ';
end loop;
-- remove leading whitespace
stemp := strip_whitespace(s);
-- copy until first whitespace
for i in stemp'range loop
if not is_whitespace(stemp(i)) then
s2(i) := stemp(i);
else exit;
end if;
end loop;
return s2;
 
end first_string;
-- removes first non-whitespace string from a string (JFF)
 
procedure chomp(variable s: inout string; variable shead: out string) is
 
variable stemp, stemp2 : string (s'range);
variable j, k : positive := 1;
 
begin
-- fill stemp and stemp2 with blanks
for i in s'range loop
stemp(i) := ' '; stemp2(i) := ' ';
end loop;
stemp := strip_whitespace(s);
shead := first_string(stemp);
 
-- find first whitespace in stemp
for i in stemp'range loop
if not is_whitespace(stemp(i)) then
j := j + 1;
else exit;
end if;
end loop;
-- j points to first whitespace
-- copy remainder of stemp into stemp2
-- starting at 1
for i in j to stemp'length loop
stemp2(k) := stemp(i);
k := k + 1;
end loop;
s := stemp2;
end chomp;
 
 
 
-- functions to convert strings into other types
 
 
-- converts a character into a std_logic
 
function to_std_logic(c: character) return std_logic is
variable sl: std_logic;
begin
case c is
when 'U' =>
sl := 'U';
when 'X' =>
sl := 'X';
when '0' =>
sl := '0';
when '1' =>
sl := '1';
when 'Z' =>
sl := 'Z';
when 'W' =>
sl := 'W';
when 'L' =>
sl := 'L';
when 'H' =>
sl := 'H';
when '-' =>
sl := '-';
when others =>
sl := 'X';
end case;
return sl;
end to_std_logic;
 
 
-- converts a character into std_logic_vector (JFF)
function chr_to_slv(c: character) return std_logic_vector is
variable slv: std_logic_vector(3 downto 0);
begin
case c is
when '0' =>
slv := "0000";
when '1' =>
slv := "0001";
when '2' =>
slv := "0010";
when '3' =>
slv := "0011";
when '4' =>
slv := "0100";
when '5' =>
slv := "0101";
when '6' =>
slv := "0110";
when '7' =>
slv := "0111";
when '8' =>
slv := "1000";
when '9' =>
slv := "1001";
when 'A' | 'a' =>
slv := "1010";
when 'B' | 'b' =>
slv := "1011";
when 'C' | 'c' =>
slv := "1100";
when 'D' | 'd' =>
slv := "1101";
when 'E' | 'e' =>
slv := "1110";
when 'F' | 'f' =>
slv := "1111";
when others => null;
end case;
return slv;
end chr_to_slv;
 
-- converts a character into int (JFF)
function chr_to_int(c: character) return integer is
variable x: integer;
begin
case c is
when '0' =>
x := 0;
when '1' =>
x := 1;
when '2' =>
x := 2;
when '3' =>
x := 3;
when '4' =>
x := 4;
when '5' =>
x := 5;
when '6' =>
x := 6;
when '7' =>
x := 7;
when '8' =>
x := 8;
when '9' =>
x := 9;
when others => null;
end case;
return x;
end chr_to_int;
 
 
-- converts a binary string into std_logic_vector
 
function to_std_logic_vector(s: string) return std_logic_vector is
variable slv: std_logic_vector(s'high-s'low downto 0);
variable k: integer;
begin
k := s'high-s'low;
for i in s'range loop
slv(k) := to_std_logic(s(i));
k := k - 1;
end loop;
return slv;
end to_std_logic_vector;
-- converts a hex string into std_logic_vector (JFF)
function hstr_to_slv(s: string) return std_logic_vector is
variable slv: std_logic_vector(((s'length*4)-1) downto 0) := (others => '0');
variable k: integer;
begin
for i in s'range loop
slv := slv((slv'length - 5) downto 0) & chr_to_slv(s(i));
end loop;
return slv;
end hstr_to_slv;
-- converts a decimal string into an integer (JFF)
function str_to_int(s: string) return integer is
variable k: integer;
begin
k := 0;
for i in s'range loop
k := (k*10) + chr_to_int(s(i));
end loop;
return k;
end str_to_int;
 
----------------
-- file I/O --
----------------
 
 
 
-- read variable length string from input file
procedure str_read(file in_file: TEXT;
res_string: out string) is
variable l: line;
variable c: character;
variable is_string: boolean;
begin
readline(in_file, l);
-- clear the contents of the result string
for i in res_string'range loop
res_string(i) := ' ';
end loop;
-- read all characters of the line, up to the length
-- of the results string
for i in res_string'range loop
 
-- JFF - new
--
read(l, c, is_string);
if is_string then res_string(i) := c;
else exit;
end if;
 
-- JFF - was duplicating the last char if no
-- space at the end of the line
--
-- read(l, c, is_string);
-- res_string(i) := c;
-- if not is_string then -- found end of line
-- exit;
-- end if;
 
end loop;
end str_read;
 
 
-- print string to a file
procedure print(file out_file: TEXT;
new_string: in string) is
variable l: line;
begin
write(l, new_string);
writeline(out_file, l);
end print;
 
 
-- print character to a file and start new line
procedure print(file out_file: TEXT;
char: in character) is
variable l: line;
begin
write(l, char);
writeline(out_file, l);
end print;
 
 
 
-- appends contents of a string to a file until line feed occurs
-- (LF is considered to be the end of the string)
 
procedure str_write(file out_file: TEXT;
new_string: in string) is
begin
for i in new_string'range loop
print(out_file, new_string(i));
if new_string(i) = LF then -- end of string
exit;
end if;
end loop;
end str_write;
 
 
 
 
end txt_util;
 
 
 
 

powered by: WebSVN 2.1.0

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