diff --git a/sim/DictP.vhd b/sim/DictP.vhd new file mode 100644 index 0000000..a161f53 --- /dev/null +++ b/sim/DictP.vhd @@ -0,0 +1,160 @@ +library ieee; + use ieee.std_logic_1164.all; + + + +package DictP is + + + type t_dict is protected + + procedure set (key : in string; data : in std_logic_vector); + procedure get (key : in string; data : out std_logic_vector); + procedure del (key : in string); + procedure init (logging : in boolean := false); + procedure clear; + impure function hasKey (key : string) return boolean; + impure function size return natural; + + end protected t_dict; + + +end package DictP; + + + +package body DictP is + + + type t_dict is protected body + + + type t_entry; + type t_entry_ptr is access t_entry; + + type t_key_ptr is access string; + type t_data_ptr is access std_logic_vector; + + type t_entry is record + key : t_key_ptr; + data : t_data_ptr; + last_entry : t_entry_ptr; + next_entry : t_entry_ptr; + end record t_entry; + + variable v_head : t_entry_ptr := null; + variable v_size : natural := 0; + variable v_logging : boolean := false; + + impure function find (key : string) return t_entry_ptr; + + procedure set (key : in string; data : in std_logic_vector) is + variable v_entry : t_entry_ptr := find(key); + begin + if (v_entry = null) then + if (v_head /= null) then + v_entry := new t_entry; + v_entry.key := new string'(key); + v_entry.data := new std_logic_vector'(data); + v_entry.last_entry := v_head; + v_entry.next_entry := v_entry; + v_head := v_entry; + v_head.last_entry.next_entry := v_head; + else + v_head := new t_entry; + v_head.key := new string'(key); + v_head.data := new std_logic_vector'(data); + v_head.last_entry := null; + v_head.next_entry := v_entry; + end if; + if (v_logging) then + report t_dict'instance_name & ": Add key " & key & " with data 0x" & to_hstring(data); + end if; + v_size := v_size + 1; + else + v_entry.data.all := data; + if (v_logging) then + report t_dict'instance_name & ": Set key " & key & " to 0x" & to_hstring(data); + end if; + end if; + end procedure set; + + procedure get (key : in string; data : out std_logic_vector) is + variable v_entry : t_entry_ptr := find(key); + begin + if(v_entry /= null) then + data := v_entry.data.all; + if v_logging then + report t_dict'instance_name & ": Got key " & key & " with data 0x" & to_hstring(v_entry.data.all); + end if; + return; + end if; + assert false; + end procedure get; + + procedure del (key : in string) is + variable v_entry : t_entry_ptr := find(key); + begin + if (v_entry /= null) then + -- remove head entry + if(v_entry.next_entry = null) then + v_entry.last_entry.next_entry := null; + v_head := v_entry.last_entry; + -- remove start entry + elsif(v_entry.last_entry = null) then + v_entry.next_entry.last_entry := null; + -- remove entry between + else + v_entry.last_entry.next_entry := v_entry.next_entry; + v_entry.next_entry.last_entry := v_entry.last_entry; + end if; + deallocate(v_entry.key); + deallocate(v_entry.data); + deallocate(v_entry); + v_size := v_size - 1; + end if; + end procedure del; + + impure function find (key : string) return t_entry_ptr is + variable v_entry : t_entry_ptr := v_head; + begin + while (v_entry /= null) loop + if(v_entry.key.all = key) then + return v_entry; + end if; + v_entry := v_entry.last_entry; + end loop; + return null; + end function find; + + procedure clear is + variable v_entry : t_entry_ptr := v_head; + variable v_entry_d : t_entry_ptr; + begin + while (v_entry /= null) loop + v_entry_d := v_entry; + del(v_entry_d.key.all); + v_entry := v_entry.last_entry; + end loop; + end procedure clear; + + impure function hasKey (key : string) return boolean is + begin + return find(key) /= null; + end function hasKey; + + impure function size return natural is + begin + return v_size; + end function size; + + procedure init (logging : in boolean := false) is + begin + v_logging := logging; + end procedure init; + + + end protected body t_dict; + + +end package body DictP; diff --git a/test/DictT.vhd b/test/DictT.vhd new file mode 100644 index 0000000..51ddf94 --- /dev/null +++ b/test/DictT.vhd @@ -0,0 +1,85 @@ +library ieee; + use ieee.std_logic_1164.all; + use ieee.numeric_std.all; + +--+ including vhdl 2008 libraries +--+ These lines can be commented out when using +--+ a simulator with built-in VHDL 2008 support +--library ieee_proposed; +-- use ieee_proposed.standard_additions.all; +-- use ieee_proposed.std_logic_1164_additions.all; +-- use ieee_proposed.numeric_std_additions.all; + +library osvvm; + use osvvm.RandomPkg.all; + +library libvhdl; + use libvhdl.DictP.all; + + + +entity DictT is +end entity DictT; + + + +architecture sim of DictT is + + + type t_scoreboard is array (natural range <>) of std_logic_vector(7 downto 0); + + shared variable sv_dict : t_dict; + + +begin + + + DictInitP : process is + begin + sv_dict.init(false); + wait; + end process DictInitP; + + + DictTestP : process is + variable v_key : string(1 to 4); + variable v_random : RandomPType; + variable v_input : std_logic_vector(7 downto 0); + variable v_output : std_logic_vector(7 downto 0); + variable v_scoreboard : t_scoreboard(0 to 256); + begin + v_random.InitSeed(v_random'instance_name); + + -- check initial emptiness + assert sv_dict.size = 0 + report "ERROR: Dict should be empty" + severity failure; + + -- fill dictionary and check count + report "INFO: Test : Fill dictionary"; + for i in 0 to 255 loop + v_input := v_random.RandSlv(8); + sv_dict.set(integer'image(i), v_input); + v_scoreboard(i) := v_input; + assert sv_dict.size = i+1 + report "ERROR: Dict should have " & to_string(i+1) & " entries" + severity failure; + end loop; + report "INFO: Test successful"; + + -- read all entries and check for correct data + report "INFO: Test : Read dictionary"; + for i in 0 to 255 loop + sv_dict.get(integer'image(i), v_output); + assert v_output = v_scoreboard(i) + report "ERROR: Got 0x" & to_hstring(v_output) & ", expected 0x" & to_hstring(v_scoreboard(i)) + severity failure; + end loop; + report "INFO: Test successful"; + + report "INFO: t_dict test finished successfully"; + wait; + end process DictTestP; + + +end architecture sim;