Browse Source

Add package & testbench for simple dictionary protected type

A new packae DictP.vhd is added which contains a simple implementation
of a dictionary type. It consists of a protected type t_dict which
contains procedures & functions which serve as methods to interact with
the protected type. The t_dict type is realised by a (double)
linked-list using access types.
The key type is string of arbitrary size, the data type is
std_logic_vector of arbitrary size. The t_dict type provides following
interface methods:

  * set: set a key/value pair
  * get: get a key/value pair
  * del: remove a key/value pair
  * init: initialise the dictionary
  * clear: remove all key/value pairs
  * hasKey: check if a key exists in the dictionary
  * size: get number of key/value pairs
pull/1/head
T. Meissner 9 years ago
parent
commit
b42ee6e1ec
2 changed files with 245 additions and 0 deletions
  1. +160
    -0
      sim/DictP.vhd
  2. +85
    -0
      test/DictT.vhd

+ 160
- 0
sim/DictP.vhd View File

@ -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;

+ 85
- 0
test/DictT.vhd View File

@ -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;

Loading…
Cancel
Save