Line 4... |
Line 4... |
-- Project: IIC Multiple Bus Controller (IICMB) |
|
-- Project: IIC Multiple Bus Controller (IICMB) |
|
-- |
|
-- |
|
-- Module: Test package. |
|
-- Module: Test package. |
|
-- Version: |
|
-- Version: |
|
-- 1.0, April 29, 2016 |
|
-- 1.0, April 29, 2016 |
|
|
-- 1.1, May 10, 2016 Removed obsolete stuff |
|
-- |
|
-- |
|
-- Author: Sergey Shuvalkin, (sshuv2@opencores.org) |
|
-- Author: Sergey Shuvalkin, (sshuv2@opencores.org) |
|
-- |
|
-- |
|
--==============================================================================
|
--==============================================================================
|
--==============================================================================
|
--==============================================================================
|
Line 351... |
Line 352... |
-- as `Lu').
|
-- as `Lu').
|
------------------------------------------------------------------------------
|
------------------------------------------------------------------------------
|
|
|
-- Conversion functions
|
-- Conversion functions
|
function to_integer (value : in string) return integer;
|
function to_integer (value : in string) return integer;
|
|
|
|
|
|
|
|
|
procedure read_identifier(file f : char_file; value : inout string_ptr);
|
|
procedure read_integer(file f : char_file; value : out integer);
|
|
procedure find_token(file f : char_file; value : in string);
|
|
------------------------------------------------------------------------------
|
|
|
|
|
|
------------------------------------------------------------------------------
|
|
-- Working with commands:
|
|
------------------------------------------------------------------------------
|
|
-- First level of abstraction: tokens.
|
|
constant max_token_size : integer := 80;
|
|
type token_kind is
|
|
(
|
|
name,
|
|
integer_number,
|
|
end_of_line,
|
|
end_of_file,
|
|
start_of_comment,
|
|
separator,
|
|
not_recognized
|
|
);
|
|
|
|
type token is record
|
|
kind : token_kind;
|
|
value_ptr : string_ptr;
|
|
end record;
|
|
|
|
procedure read_token(file f : char_file; value : inout token);
|
|
procedure write_token(file f : char_file; value : inout token);
|
|
--
|
|
|
|
------------------------------------------------------------------------------
|
|
-- Second level of abstraction: commands.
|
|
-- Maximum number of arguments in a command:
|
|
constant max_args_in_command : integer := 4*1024;
|
|
|
|
-- Command type:
|
|
type command is record
|
|
time_cnt : natural; -- The time, when the command should be applied
|
|
id : string_ptr; -- Pointer to the command ID.
|
|
arg : integer_array_ptr; -- Pointer to the array of arguments.
|
|
end record;
|
|
|
|
procedure read_command(file f : char_file; id : in string; cmd : inout command);
|
|
|
|
type command_list_elem;
|
|
type command_list_elem_ptr is access command_list_elem;
|
|
type command_list_elem is record
|
|
cmd : command;
|
|
prv : command_list_elem_ptr;
|
|
nxt : command_list_elem_ptr;
|
|
end record;
|
|
type command_list is record
|
|
number : natural;
|
|
first : command_list_elem_ptr;
|
|
last : command_list_elem_ptr;
|
|
end record;
|
|
procedure init_command_list(fname : in string; variable clist : inout command_list; block_id : in string);
|
|
procedure put_command(variable clist : inout command_list; cmd : inout command);
|
|
procedure get_command(variable clist : inout command_list; cmd : inout command);
|
|
------------------------------------------------------------------------------
|
------------------------------------------------------------------------------
|
|
|
end test;
|
end test;
|
--==============================================================================
|
--==============================================================================
|
|
|
Line 459... |
Line 396... |
fprint_string(stdout, value);
|
fprint_string(stdout, value);
|
end procedure print_string;
|
end procedure print_string;
|
------------------------------------------------------------------------------
|
------------------------------------------------------------------------------
|
|
|
------------------------------------------------------------------------------
|
------------------------------------------------------------------------------
|
procedure read_integer(file f : char_file; value : out integer) is
|
|
variable buf : string(1 to 256);
|
|
variable ch0 : character;
|
|
variable idx : positive;
|
|
begin
|
|
-- Searching for first character:
|
|
while true loop
|
|
assert not(endfile(f)) report "read_integer(): Unexpected End Of File." severity failure;
|
|
read(f, ch0);
|
|
exit when ((ch0 >= '0')and(ch0 <= '9'))or(ch0 = '-');
|
|
end loop;
|
|
|
|
buf(1) := ch0;
|
|
idx := 2;
|
|
|
|
-- Reading other characters:
|
|
while (not(endfile(f))) loop
|
|
read(f, ch0);
|
|
if ((ch0 >= '0')and(ch0 <= '9'))or((ch0 >= 'a')and(ch0 <= 'f'))or((ch0 >= 'A')and(ch0 <= 'F'))or(ch0 = 'x') then
|
|
buf(idx) := ch0;
|
|
idx := idx + 1;
|
|
else
|
|
exit;
|
|
end if;
|
|
end loop;
|
|
value := to_integer(buf(1 to idx - 1));
|
|
end procedure read_integer;
|
|
------------------------------------------------------------------------------
|
|
|
|
------------------------------------------------------------------------------
|
|
procedure read_identifier(file f : char_file; value : inout string_ptr) is
|
|
variable buf : string(1 to 256);
|
|
variable ch0 : character;
|
|
variable idx : positive;
|
|
begin
|
|
-- Searching for first character:
|
|
while true loop
|
|
assert not(endfile(f)) report "read_identifier(): Unexpected End Of File." severity failure;
|
|
read(f, ch0);
|
|
exit when ((ch0 >= 'A')and(ch0 <= 'Z'))or((ch0 >= 'a')and(ch0 <= 'z'))or(ch0 = '_');
|
|
end loop;
|
|
|
|
buf(1) := ch0;
|
|
idx := 2;
|
|
|
|
-- Reading other characters:
|
|
while (not(endfile(f))) loop
|
|
read(f, ch0);
|
|
if ((ch0 >= 'A')and(ch0 <= 'Z'))or((ch0 >= 'a')and(ch0 <= 'z'))or((ch0 >= '0')and(ch0 <= '9'))or(ch0 = '_') then
|
|
buf(idx) := ch0;
|
|
idx := idx + 1;
|
|
else
|
|
exit;
|
|
end if;
|
|
end loop;
|
|
deallocate(value);
|
|
value := new string'(buf(1 to idx - 1));
|
|
end procedure read_identifier;
|
|
------------------------------------------------------------------------------
|
|
|
|
------------------------------------------------------------------------------
|
|
procedure find_token(file f : char_file; value : in string) is
|
|
variable ch0 : character;
|
|
variable idx : positive;
|
|
begin
|
|
idx := value'low;
|
|
while true loop
|
|
assert not(endfile(f)) report "find_token(" & value & "): Unexpected End Of File." severity failure;
|
|
read(f, ch0);
|
|
if (ch0 = value(idx)) then
|
|
exit when (idx = value'high);
|
|
idx := idx + 1;
|
|
else
|
|
idx := value'low;
|
|
end if;
|
|
end loop;
|
|
end procedure find_token;
|
|
------------------------------------------------------------------------------
|
|
|
|
|
|
------------------------------------------------------------------------------
|
|
function to_integer(value : in string) return integer is
|
function to_integer(value : in string) return integer is
|
variable value_local : integer := 0;
|
variable value_local : integer := 0;
|
variable start_idx : positive;
|
variable start_idx : positive;
|
variable negative : boolean;
|
variable negative : boolean;
|
begin
|
begin
|
Line 659... |
Line 515... |
-- return res_string;
|
-- return res_string;
|
--end function to_string;
|
--end function to_string;
|
|
|
|
|
------------------------------------------------------------------------------
|
------------------------------------------------------------------------------
|
-- Working with commands:
|
|
------------------------------------------------------------------------------
|
|
-- First level of abstraction: tokens.
|
|
procedure read_token(file f : char_file; value : inout token) is
|
|
variable ch0 : character;
|
|
variable idx : integer := 1;
|
|
variable end_of_token : boolean := false;
|
|
variable buf : string(1 to max_token_size);
|
|
variable kind : token_kind;
|
|
begin
|
|
deallocate(value.value_ptr);
|
|
while (idx <= max_token_size)and(end_of_token = false) loop
|
|
if (idx = 1) then
|
|
if endfile(f) then
|
|
kind := end_of_file;
|
|
end_of_token := true;
|
|
else
|
|
read(f, ch0);
|
|
next when (ch0 = ' ')or(ch0 = ht);
|
|
buf(idx) := ch0;
|
|
idx := idx + 1;
|
|
|
|
if (ch0 = '#') then
|
|
kind := start_of_comment;
|
|
end_of_token := true;
|
|
elsif ((ch0 >= '0')and(ch0 <= '9'))or(ch0 = '-') then
|
|
kind := integer_number;
|
|
elsif ((ch0 >= 'A')and(ch0 <= 'Z'))or((ch0 >= 'a')and(ch0 <= 'z'))or(ch0 = '_') then
|
|
kind := name;
|
|
elsif (ch0 = cr) then
|
|
kind := end_of_line;
|
|
elsif (ch0 = lf) then
|
|
kind := end_of_line;
|
|
end_of_token := true;
|
|
elsif (ch0 = ',')or(ch0 = '(')or(ch0 = ')')or(ch0 = '{')or(ch0 = '}')or(ch0 = ':') then
|
|
kind := separator;
|
|
end_of_token := true;
|
|
else
|
|
kind := not_recognized;
|
|
end_of_token := true;
|
|
end if;
|
|
end if;
|
|
else
|
|
if endfile(f) then
|
|
end_of_token := true;
|
|
else
|
|
read(f, ch0);
|
|
case kind is
|
|
when integer_number =>
|
|
if ((ch0 >= '0')and(ch0 <= '9'))or((ch0 >= 'a')and(ch0 <= 'f'))or((ch0 >= 'A')and(ch0 <= 'F'))or(ch0 = 'x') then
|
|
buf(idx) := ch0;
|
|
idx := idx + 1;
|
|
else
|
|
end_of_token := true;
|
|
end if;
|
|
when name =>
|
|
if ((ch0 >= 'A')and(ch0 <= 'Z'))or((ch0 >= 'a')and(ch0 <= 'z'))or((ch0 >= '0')and(ch0 <= '9'))or(ch0 = '_') then
|
|
buf(idx) := ch0;
|
|
idx := idx + 1;
|
|
else
|
|
end_of_token := true;
|
|
end if;
|
|
when end_of_line =>
|
|
if (ch0 = lf) then
|
|
buf(idx) := ch0;
|
|
idx := idx + 1;
|
|
end if;
|
|
end_of_token := true;
|
|
when others =>
|
|
end_of_token := true;
|
|
end case;
|
|
end if;
|
|
end if;
|
|
end loop;
|
|
|
|
value.kind := kind;
|
|
value.value_ptr := new string'(buf(1 to idx - 1));
|
|
end procedure read_token;
|
|
------------------------------------------------------------------------------
|
|
|
|
------------------------------------------------------------------------------
|
|
procedure write_token(file f : char_file; value : inout token) is
|
|
begin
|
|
fprint_string(f, value.value_ptr.all & ' ');
|
|
end procedure write_token;
|
|
------------------------------------------------------------------------------
|
|
--
|
|
|
|
------------------------------------------------------------------------------
|
|
-- Second level of abstraction: commands.
|
|
-- <integer_number> <name0> <name1> <{> <integer_number> ... <}>
|
|
procedure read_command(file f : char_file; id : in string; cmd : inout command) is
|
|
variable tmp_token : token;
|
|
variable token_idx : integer := 1;
|
|
variable arg_idx : integer := 1;
|
|
variable tmp_array : integer_array(1 to max_args_in_command);
|
|
begin
|
|
while true loop
|
|
read_token(f, tmp_token);
|
|
|
|
case tmp_token.kind is
|
|
when name =>
|
|
assert (token_idx /= 1) report "read_command(): identifier " &
|
|
tmp_token.value_ptr.all & " found where should be an integer number." severity failure;
|
|
assert (token_idx /= 4) report "read_command(): identifier " &
|
|
tmp_token.value_ptr.all & " found where should be an { brace." severity failure;
|
|
assert (token_idx /= 5) report "read_command(): identifier " &
|
|
tmp_token.value_ptr.all & " found where should be an } brace or an integer number." severity failure;
|
|
if (token_idx = 2) then
|
|
if (tmp_token.value_ptr.all /= id) then -- Not our command, go to the end.
|
|
while true loop
|
|
read_token(f, tmp_token);
|
|
exit when (tmp_token.kind = separator)or(tmp_token.value_ptr.all = "}");
|
|
end loop;
|
|
token_idx := 1;
|
|
else
|
|
token_idx := 3;
|
|
end if;
|
|
else
|
|
deallocate(cmd.id);
|
|
cmd.id := new string'(tmp_token.value_ptr.all);
|
|
token_idx := 4;
|
|
end if;
|
|
|
|
when integer_number =>
|
|
assert (token_idx /= 2) report "read_command(): integer number " &
|
|
tmp_token.value_ptr.all & " found where should be an identifier." severity failure;
|
|
assert (token_idx /= 3) report "read_command(): integer number " &
|
|
tmp_token.value_ptr.all & " found where should be an identifier." severity failure;
|
|
assert (token_idx /= 4) report "read_command(): integer number " &
|
|
tmp_token.value_ptr.all & " found where should be an { brace." severity failure;
|
|
if (token_idx = 1) then
|
|
cmd.time_cnt := to_integer(tmp_token.value_ptr.all);
|
|
token_idx := 2;
|
|
else
|
|
tmp_array(arg_idx) := to_integer(tmp_token.value_ptr.all);
|
|
arg_idx := arg_idx + 1;
|
|
end if;
|
|
|
|
when end_of_line =>
|
|
null;
|
|
|
|
when end_of_file =>
|
|
exit;
|
|
|
|
when start_of_comment =>
|
|
while true loop
|
|
read_token(f, tmp_token);
|
|
exit when (tmp_token.kind = end_of_line)or(tmp_token.kind = end_of_file);
|
|
end loop;
|
|
|
|
when separator =>
|
|
if (token_idx = 4)and(tmp_token.value_ptr.all = "{") then
|
|
token_idx := 5;
|
|
elsif (token_idx = 5)and(tmp_token.value_ptr.all = "}") then
|
|
token_idx := 6;
|
|
exit;
|
|
end if;
|
|
|
|
when not_recognized =>
|
|
assert false report "read_command(): unknown pattern " & tmp_token.value_ptr.all & " found." severity failure;
|
|
end case;
|
|
end loop;
|
|
|
|
assert (token_idx = 1)or(token_idx = 6) report "read_command(): Unexpected End of File." severity failure;
|
|
|
|
if (token_idx = 1) then
|
|
cmd.time_cnt := 0;
|
|
deallocate(cmd.id);
|
|
cmd.id := new string'("stop");
|
|
deallocate(cmd.arg);
|
|
else
|
|
deallocate(cmd.arg);
|
|
cmd.arg := new integer_array'(tmp_array(1 to arg_idx - 1));
|
|
end if;
|
|
end procedure read_command;
|
|
------------------------------------------------------------------------------
|
|
|
|
|
|
------------------------------------------------------------------------------
|
|
procedure put_command(variable clist : inout command_list; cmd : inout command) is
|
|
variable new_le : command_list_elem_ptr;
|
|
variable tmp : command_list_elem_ptr;
|
|
begin
|
|
new_le := new command_list_elem;
|
|
new_le.all.cmd.time_cnt := cmd.time_cnt;
|
|
new_le.all.cmd.id := new string'(cmd.id.all);
|
|
new_le.all.cmd.arg := new integer_array'(cmd.arg.all);
|
|
|
|
if (clist.number = 0) then
|
|
-- The command list is empty.
|
|
new_le.all.prv := null;
|
|
new_le.all.nxt := null;
|
|
clist.first := new_le;
|
|
clist.last := new_le;
|
|
else
|
|
-- The command list is not empty.
|
|
new_le.all.prv := clist.last;
|
|
new_le.all.nxt := null;
|
|
clist.last.all.nxt := new_le;
|
|
clist.last := new_le;
|
|
end if;
|
|
clist.number := clist.number + 1;
|
|
end procedure put_command;
|
|
------------------------------------------------------------------------------
|
|
|
|
------------------------------------------------------------------------------
|
|
procedure init_command_list(fname : in string; variable clist : inout command_list; block_id : in string) is
|
|
file cmd_data : char_file;
|
|
variable cmd : command;
|
|
begin
|
|
file_open(cmd_data, fname, read_mode);
|
|
|
|
clist.number := 0;
|
|
clist.first := null;
|
|
clist.last := null;
|
|
|
|
while (true) loop
|
|
read_command(cmd_data, block_id, cmd);
|
|
exit when (cmd.id.all = "stop");
|
|
put_command(clist, cmd);
|
|
end loop;
|
|
|
|
deallocate(cmd.id);
|
|
deallocate(cmd.arg);
|
|
file_close(cmd_data);
|
|
end procedure init_command_list;
|
|
------------------------------------------------------------------------------
|
|
|
|
------------------------------------------------------------------------------
|
|
procedure get_command(variable clist : inout command_list; cmd : inout command) is
|
|
variable old_el : command_list_elem_ptr;
|
|
begin
|
|
deallocate(cmd.id);
|
|
deallocate(cmd.arg);
|
|
if (clist.number = 0) then
|
|
cmd.time_cnt := 0;
|
|
cmd.id := new string'("stop");
|
|
else
|
|
if (clist.number = 1) then
|
|
old_el := clist.first;
|
|
clist.number := clist.number - 1;
|
|
clist.first := null;
|
|
clist.last := null;
|
|
else
|
|
old_el := clist.first;
|
|
clist.number := clist.number - 1;
|
|
clist.first := clist.first.all.nxt;
|
|
old_el.all.nxt.all.prv := null;
|
|
end if;
|
|
cmd.time_cnt := old_el.all.cmd.time_cnt;
|
|
cmd.id := new string'(old_el.all.cmd.id.all);
|
|
cmd.arg := new integer_array'(old_el.all.cmd.arg.all);
|
|
deallocate(old_el.all.cmd.id);
|
|
deallocate(old_el.all.cmd.arg);
|
|
deallocate(old_el);
|
|
end if;
|
|
end procedure get_command;
|
|
------------------------------------------------------------------------------
|
|
|
|
|
|
|
|
|
|
------------------------------------------------------------------------------
|
|
function to_string(value : in std_logic;
|
function to_string(value : in std_logic;
|
format : in string := "b";
|
format : in string := "b";
|
width : in natural := 0;
|
width : in natural := 0;
|
prec : in natural := 0) return string is
|
prec : in natural := 0) return string is
|
begin
|
begin
|