Browse Source

DictP is now a package with generics for key & type

AHBL_BFM
T. Meissner 7 years ago
parent
commit
61eb06ee09
3 changed files with 169 additions and 183 deletions
  1. +77
    -90
      sim/DictP.vhd
  2. +36
    -34
      test/DictT.vhd
  3. +56
    -59
      test/WishBoneT.vhd

+ 77
- 90
sim/DictP.vhd View File

@ -6,29 +6,37 @@ library ieee;
package DictP is package DictP is
generic (
type KEY_TYPE;
type VALUE_TYPE;
function key_to_string(d : in KEY_TYPE) return string;
function value_to_string(d : in VALUE_TYPE) return string
);
type t_dict_key_ptr is access KEY_TYPE;
type t_dict_data_ptr is access VALUE_TYPE;
type t_dict_dir is (UP, DOWN); type t_dict_dir is (UP, DOWN);
type t_dict_error is (NO_ERROR, KEY_INVALID, KEY_NOT_FOUND);
type t_dict_iter is (TAIL, HEAD); type t_dict_iter is (TAIL, HEAD);
type t_dict_key_ptr is access string;
type t_dict_data_ptr is access std_logic_vector;
type t_dict is protected type t_dict is protected
procedure set (constant key : in string; constant data : in std_logic_vector; err : out t_dict_error);
procedure get (constant key : in string; data : out std_logic_vector; err : out t_dict_error);
procedure del (constant key : in string; err : out t_dict_error);
procedure set (constant key : in KEY_TYPE; constant data : in VALUE_TYPE);
procedure get (constant key : in KEY_TYPE; data : out VALUE_TYPE);
procedure del (constant key : in KEY_TYPE);
procedure init (constant logging : in boolean := false); procedure init (constant logging : in boolean := false);
procedure clear (err : out t_dict_error);
impure function hasKey (constant key : string) return boolean;
procedure clear;
impure function hasKey (constant key : KEY_TYPE) return boolean;
impure function size return natural; impure function size return natural;
procedure setIter(constant start : in t_dict_iter := TAIL); procedure setIter(constant start : in t_dict_iter := TAIL);
impure function iter (constant dir : t_dict_dir := UP) return string;
impure function get (constant key : string) return std_logic_vector;
impure function iter (constant dir : t_dict_dir := UP) return KEY_TYPE;
impure function get (constant key : KEY_TYPE) return VALUE_TYPE;
end protected t_dict; end protected t_dict;
procedure merge(d0 : inout t_dict; d1 : inout t_dict; d : inout t_dict; err : out t_dict_error);
procedure merge(d0 : inout t_dict; d1 : inout t_dict; d : inout t_dict);
end package DictP; end package DictP;
@ -57,62 +65,60 @@ package body DictP is
variable v_size : natural := 0; variable v_size : natural := 0;
variable v_logging : boolean := false; variable v_logging : boolean := false;
impure function find (constant key : string) return t_entry_ptr;
impure function find (constant key : KEY_TYPE) return t_entry_ptr;
procedure set (constant key : in string; constant data : in std_logic_vector; err : out t_dict_error) is
procedure set (constant key : in KEY_TYPE; constant data : in VALUE_TYPE) is
variable v_entry : t_entry_ptr := find(key); variable v_entry : t_entry_ptr := find(key);
begin begin
if (key = "") then
err := KEY_INVALID;
else
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 := null;
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 := null;
v_tail := v_head;
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;
if (v_entry = null) then
if (v_head /= null) then
v_entry := new t_entry;
v_entry.key := new KEY_TYPE'(key);
v_entry.data := new VALUE_TYPE'(data);
v_entry.last_entry := v_head;
v_entry.next_entry := null;
v_head := v_entry;
v_head.last_entry.next_entry := v_head;
else 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;
v_head := new t_entry;
v_head.key := new KEY_TYPE'(key);
v_head.data := new VALUE_TYPE'(data);
v_head.last_entry := null;
v_head.next_entry := null;
v_tail := v_head;
end if;
if (v_logging) then
report t_dict'instance_name & ": Add key " & key_to_string(key) & " with value " & value_to_string(data) & " to dictionary";
end if;
v_size := v_size + 1;
else
v_entry.data.all := data;
if (v_logging) then
report t_dict'instance_name & ": Set value of key " & key_to_string(key) & " to 0x" & value_to_string(data);
end if; end if;
err := NO_ERROR;
end if; end if;
end procedure set; end procedure set;
procedure get (constant key : in string; data : out std_logic_vector; err : out t_dict_error) is
procedure get (constant key : in KEY_TYPE; data : out VALUE_TYPE) is
variable v_entry : t_entry_ptr := find(key); variable v_entry : t_entry_ptr := find(key);
begin begin
assert v_entry /= null
report t_dict'instance_name & ": key " & key_to_string(key) & " not found"
severity failure;
if(v_entry /= null) then if(v_entry /= null) then
data := v_entry.data.all; data := v_entry.data.all;
if v_logging then if v_logging then
report t_dict'instance_name & ": Got key " & key & " with data 0x" & to_hstring(v_entry.data.all);
report t_dict'instance_name & ": Got key " & key_to_string(key) & " with value " & value_to_string(v_entry.data.all);
end if; end if;
err := NO_ERROR;
else
err := KEY_NOT_FOUND;
end if; end if;
end procedure get; end procedure get;
procedure del (constant key : in string; err : out t_dict_error) is
procedure del (constant key : in KEY_TYPE) is
variable v_entry : t_entry_ptr := find(key); variable v_entry : t_entry_ptr := find(key);
begin begin
assert v_entry /= null
report t_dict'instance_name & ": key " & key_to_string(key) & " not found"
severity failure;
if (v_entry /= null) then if (v_entry /= null) then
-- remove head entry -- remove head entry
if(v_entry.next_entry = null and v_entry.last_entry /= null) then if(v_entry.next_entry = null and v_entry.last_entry /= null) then
@ -132,13 +138,10 @@ package body DictP is
deallocate(v_entry.data); deallocate(v_entry.data);
deallocate(v_entry); deallocate(v_entry);
v_size := v_size - 1; v_size := v_size - 1;
err := NO_ERROR;
else
err := KEY_NOT_FOUND;
end if; end if;
end procedure del; end procedure del;
impure function find (constant key : string) return t_entry_ptr is
impure function find (constant key : KEY_TYPE) return t_entry_ptr is
variable v_entry : t_entry_ptr := v_head; variable v_entry : t_entry_ptr := v_head;
begin begin
while (v_entry /= null) loop while (v_entry /= null) loop
@ -150,25 +153,18 @@ package body DictP is
return null; return null;
end function find; end function find;
procedure clear (err : out t_dict_error) is
procedure clear is
variable v_entry : t_entry_ptr := v_head; variable v_entry : t_entry_ptr := v_head;
variable v_entry_d : t_entry_ptr; variable v_entry_d : t_entry_ptr;
variable v_err : t_dict_error;
begin begin
while (v_entry /= null) loop while (v_entry /= null) loop
v_entry_d := v_entry; v_entry_d := v_entry;
del(v_entry_d.key.all, v_err);
if (v_err /= NO_ERROR) then
err := v_err;
return;
else
v_entry := v_entry.last_entry;
end if;
del(v_entry_d.key.all);
v_entry := v_entry.last_entry;
end loop; end loop;
err := NO_ERROR;
end procedure clear; end procedure clear;
impure function hasKey (constant key : string) return boolean is
impure function hasKey (constant key : KEY_TYPE) return boolean is
begin begin
return find(key) /= null; return find(key) /= null;
end function hasKey; end function hasKey;
@ -192,27 +188,27 @@ package body DictP is
end if; end if;
end procedure setIter; end procedure setIter;
impure function iter (constant dir : t_dict_dir := UP) return string is
impure function iter (constant dir : t_dict_dir := UP) return KEY_TYPE is
variable v_key : t_dict_key_ptr := null; variable v_key : t_dict_key_ptr := null;
begin begin
if (v_iterator /= null) then
v_key := new string'(v_iterator.key.all);
if (dir = UP) then
v_key := new KEY_TYPE'(v_iterator.key.all);
if (dir = UP) then
if (v_iterator.next_entry /= null) then
v_iterator := v_iterator.next_entry; v_iterator := v_iterator.next_entry;
else
v_iterator := v_iterator.last_entry;
end if; end if;
return v_key.all;
else else
return "";
if (v_iterator.last_entry /= null) then
v_iterator := v_iterator.last_entry;
end if;
end if; end if;
return v_key.all;
end function iter; end function iter;
impure function get(constant key : string) return std_logic_vector is
impure function get(constant key : KEY_TYPE) return VALUE_TYPE is
variable v_entry : t_entry_ptr := find(key); variable v_entry : t_entry_ptr := find(key);
begin begin
assert v_entry /= null assert v_entry /= null
report t_dict'instance_name & ": ERROR: key " & key & " not found"
report t_dict'instance_name & ": key " & key_to_string(key) & " not found"
severity failure; severity failure;
return v_entry.data.all; return v_entry.data.all;
end function get; end function get;
@ -221,33 +217,24 @@ package body DictP is
end protected body t_dict; end protected body t_dict;
procedure merge(d0 : inout t_dict; d1 : inout t_dict; d : inout t_dict; err : out t_dict_error) is
procedure merge(d0 : inout t_dict; d1 : inout t_dict; d : inout t_dict) is
variable v_key : t_dict_key_ptr; variable v_key : t_dict_key_ptr;
variable v_data : t_dict_data_ptr; variable v_data : t_dict_data_ptr;
variable v_error : t_dict_error;
begin begin
if (d0.size > 0) then if (d0.size > 0) then
d0.setIter(TAIL); d0.setIter(TAIL);
for i in 0 to d0.size-1 loop for i in 0 to d0.size-1 loop
v_key := new string'(d0.iter(UP));
v_data := new std_logic_vector'(d0.get(v_key.all));
d.set(v_key.all, v_data.all, v_error);
if (v_error /= NO_ERROR) then
err := v_error;
return;
end if;
v_key := new KEY_TYPE'(d0.iter(UP));
v_data := new VALUE_TYPE'(d0.get(v_key.all));
d.set(v_key.all, v_data.all);
end loop; end loop;
end if; end if;
if (d1.size > 0) then if (d1.size > 0) then
d1.setIter(TAIL); d1.setIter(TAIL);
for i in 0 to d1.size-1 loop for i in 0 to d1.size-1 loop
v_key := new string'(d1.iter(UP));
v_data := new std_logic_vector'(d1.get(v_key.all));
d.set(v_key.all, v_data.all, v_error);
if (v_error /= NO_ERROR) then
err := v_error;
return;
end if;
v_key := new KEY_TYPE'(d1.iter(UP));
v_data := new VALUE_TYPE'(d1.get(v_key.all));
d.set(v_key.all, v_data.all);
end loop; end loop;
end if; end if;
end procedure merge; end procedure merge;


+ 36
- 34
test/DictT.vhd View File

@ -2,19 +2,12 @@ library ieee;
use ieee.std_logic_1164.all; use ieee.std_logic_1164.all;
use ieee.numeric_std.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; library osvvm;
use osvvm.RandomPkg.all; use osvvm.RandomPkg.all;
library libvhdl; library libvhdl;
use libvhdl.DictP.all;
@ -28,6 +21,20 @@ architecture sim of DictT is
type t_scoreboard is array (natural range <>) of std_logic_vector(7 downto 0); type t_scoreboard is array (natural range <>) of std_logic_vector(7 downto 0);
function to_string(d : string) return string is
begin
return d;
end function to_string;
package StringSlvDict is new libvhdl.DictP
generic map (KEY_TYPE => string,
VALUE_TYPE => std_logic_vector,
key_to_string => to_string,
value_to_string => to_hstring);
use StringSlvDict.all;
shared variable sv_dict : t_dict; shared variable sv_dict : t_dict;
shared variable sv_dact : t_dict; shared variable sv_dact : t_dict;
shared variable sv_duct : t_dict; shared variable sv_duct : t_dict;
@ -36,6 +43,7 @@ architecture sim of DictT is
begin begin
DictInitP : process is DictInitP : process is
begin begin
sv_dict.init(false); sv_dict.init(false);
@ -47,11 +55,11 @@ begin
DictTestP : process is DictTestP : process is
variable v_key : t_dict_key_ptr; variable v_key : t_dict_key_ptr;
variable v_last_key : t_dict_key_ptr;
variable v_random : RandomPType; variable v_random : RandomPType;
variable v_input : std_logic_vector(7 downto 0); variable v_input : std_logic_vector(7 downto 0);
variable v_output : std_logic_vector(7 downto 0); variable v_output : std_logic_vector(7 downto 0);
variable v_scoreboard : t_scoreboard(0 to 511); variable v_scoreboard : t_scoreboard(0 to 511);
variable v_error : t_dict_error;
begin begin
v_random.InitSeed(v_random'instance_name); v_random.InitSeed(v_random'instance_name);
@ -60,19 +68,11 @@ begin
report "ERROR: Dict should be empty" report "ERROR: Dict should be empty"
severity failure; severity failure;
-- The dict shouldn_t accept an empty key string
report "INFO: Test 0: Try to set an entry with empty key string";
sv_dict.set("", x"0123456789", v_error);
assert v_error = KEY_INVALID
report "ERROR: Key '' should raise a KEY_INVALID error"
severity failure;
report "INFO: Test successful";
-- fill dictionary and check count -- fill dictionary and check count
report "INFO: Test 1: Fill dictionary"; report "INFO: Test 1: Fill dictionary";
for i in 0 to 255 loop for i in 0 to 255 loop
v_input := v_random.RandSlv(8); v_input := v_random.RandSlv(8);
sv_dict.set(integer'image(i), v_input, v_error);
sv_dict.set(integer'image(i), v_input);
v_scoreboard(i) := v_input; v_scoreboard(i) := v_input;
assert sv_dict.size = i+1 assert sv_dict.size = i+1
report "ERROR: Dict should have " & to_string(i+1) & " entries" report "ERROR: Dict should have " & to_string(i+1) & " entries"
@ -83,7 +83,7 @@ begin
-- read all entries and check for correct data -- read all entries and check for correct data
report "INFO: Test 2: Read dictionary"; report "INFO: Test 2: Read dictionary";
for i in 0 to 255 loop for i in 0 to 255 loop
sv_dict.get(integer'image(i), v_output, v_error);
sv_dict.get(integer'image(i), v_output);
assert v_output = v_scoreboard(i) assert v_output = v_scoreboard(i)
report "ERROR: Got 0x" & to_hstring(v_output) & ", expected 0x" & to_hstring(v_scoreboard(i)) report "ERROR: Got 0x" & to_hstring(v_output) & ", expected 0x" & to_hstring(v_scoreboard(i))
severity failure; severity failure;
@ -93,9 +93,9 @@ begin
-- overwrite a key/value pair -- overwrite a key/value pair
report "INFO: Test 3: Overwrite a entry"; report "INFO: Test 3: Overwrite a entry";
v_input := v_random.RandSlv(8); v_input := v_random.RandSlv(8);
sv_dict.set("128", v_input, v_error);
sv_dict.set("128", v_input);
v_scoreboard(128) := v_input; v_scoreboard(128) := v_input;
sv_dict.get("128", v_output, v_error);
sv_dict.get("128", v_output);
assert v_output = v_scoreboard(128) assert v_output = v_scoreboard(128)
report "ERROR: Got 0x" & to_hstring(v_output) & ", expected 0x" & to_hstring(v_scoreboard(128)) report "ERROR: Got 0x" & to_hstring(v_output) & ", expected 0x" & to_hstring(v_scoreboard(128))
severity failure; severity failure;
@ -121,14 +121,15 @@ begin
assert v_key.all = integer'image(i) assert v_key.all = integer'image(i)
report "ERROR: Got key " & v_key.all & ", expected " & integer'image(i) report "ERROR: Got key " & v_key.all & ", expected " & integer'image(i)
severity failure; severity failure;
sv_dict.get(v_key.all, v_output, v_error);
sv_dict.get(v_key.all, v_output);
assert v_key.all = integer'image(i) and v_output = v_scoreboard(i) assert v_key.all = integer'image(i) and v_output = v_scoreboard(i)
report "ERROR: Got 0x" & to_hstring(v_output) & ", expected 0x" & to_hstring(v_scoreboard(i)) report "ERROR: Got 0x" & to_hstring(v_output) & ", expected 0x" & to_hstring(v_scoreboard(i))
severity failure; severity failure;
end loop; end loop;
v_last_key := v_key;
v_key := new string'(sv_dict.iter(UP)); v_key := new string'(sv_dict.iter(UP));
assert v_key.all = ""
report "ERROR: Got key " & v_key.all & ", expected empty key"
assert v_key.all = v_last_key.all
report "ERROR: Got key " & v_key.all & ", expected key" & v_last_key.all
severity failure; severity failure;
report "INFO: Test successful"; report "INFO: Test successful";
@ -140,14 +141,15 @@ begin
assert v_key.all = integer'image(i) assert v_key.all = integer'image(i)
report "ERROR: Got key " & v_key.all & ", expected " & integer'image(i) report "ERROR: Got key " & v_key.all & ", expected " & integer'image(i)
severity failure; severity failure;
sv_dict.get(v_key.all, v_output, v_error);
sv_dict.get(v_key.all, v_output);
assert v_key.all = integer'image(i) and v_output = v_scoreboard(i) assert v_key.all = integer'image(i) and v_output = v_scoreboard(i)
report "ERROR: Got 0x" & to_hstring(v_output) & ", expected 0x" & to_hstring(v_scoreboard(i)) report "ERROR: Got 0x" & to_hstring(v_output) & ", expected 0x" & to_hstring(v_scoreboard(i))
severity failure; severity failure;
end loop; end loop;
v_last_key := v_key;
v_key := new string'(sv_dict.iter(DOWN)); v_key := new string'(sv_dict.iter(DOWN));
assert v_key.all = ""
report "ERROR: Got key " & v_key.all & ", expected empty key"
assert v_key.all = v_last_key.all
report "ERROR: Got key " & v_key.all & ", expected key" & v_last_key.all
severity failure; severity failure;
deallocate(v_key); deallocate(v_key);
report "INFO: Test successful"; report "INFO: Test successful";
@ -157,17 +159,17 @@ begin
report "INFO: Test 7: Merge dictionaries"; report "INFO: Test 7: Merge dictionaries";
for i in 256 to 511 loop for i in 256 to 511 loop
v_input := v_random.RandSlv(8); v_input := v_random.RandSlv(8);
sv_dact.set(integer'image(i), v_input, v_error);
sv_dact.set(integer'image(i), v_input);
v_scoreboard(i) := v_input; v_scoreboard(i) := v_input;
assert sv_dact.size = i-255 assert sv_dact.size = i-255
report "ERROR: Dict should have " & to_string(i-255) & " entries" report "ERROR: Dict should have " & to_string(i-255) & " entries"
severity failure; severity failure;
end loop; end loop;
-- merge dictionaries -- merge dictionaries
merge(sv_dict, sv_dact, sv_duct, v_error);
merge(sv_dict, sv_dact, sv_duct);
-- read all entries and check for correct data -- read all entries and check for correct data
for i in 0 to 511 loop for i in 0 to 511 loop
sv_duct.get(integer'image(i), v_output, v_error);
sv_duct.get(integer'image(i), v_output);
assert v_output = v_scoreboard(i) assert v_output = v_scoreboard(i)
report "ERROR: Got 0x" & to_hstring(v_output) & ", expected 0x" & to_hstring(v_scoreboard(i)) report "ERROR: Got 0x" & to_hstring(v_output) & ", expected 0x" & to_hstring(v_scoreboard(i))
severity failure; severity failure;
@ -176,7 +178,7 @@ begin
-- Remove key/value pair from head of dictionary -- Remove key/value pair from head of dictionary
report "INFO: Test 8: Removing entry from head of dictionary"; report "INFO: Test 8: Removing entry from head of dictionary";
sv_dict.del("255", v_error);
sv_dict.del("255");
assert not(sv_dict.hasKey("255")) assert not(sv_dict.hasKey("255"))
report "ERROR: Key 255 shouldn't exist in dictionary" report "ERROR: Key 255 shouldn't exist in dictionary"
severity failure; severity failure;
@ -184,7 +186,7 @@ begin
-- Remove key/value pair from head of dictionary -- Remove key/value pair from head of dictionary
report "INFO: Test 9: Removing entry from middle of dictionary"; report "INFO: Test 9: Removing entry from middle of dictionary";
sv_dict.del("127", v_error);
sv_dict.del("127");
assert not(sv_dict.hasKey("127")) assert not(sv_dict.hasKey("127"))
report "ERROR: Key 127 shouldn't exist in dictionary" report "ERROR: Key 127 shouldn't exist in dictionary"
severity failure; severity failure;
@ -192,7 +194,7 @@ begin
-- Remove key/value pair from head of dictionary -- Remove key/value pair from head of dictionary
report "INFO: Test 10: Removing entry from beginning of dictionary"; report "INFO: Test 10: Removing entry from beginning of dictionary";
sv_dict.del("0", v_error);
sv_dict.del("0");
assert not(sv_dict.hasKey("0")) assert not(sv_dict.hasKey("0"))
report "ERROR: Key 0 shouldn't exist in dictionary" report "ERROR: Key 0 shouldn't exist in dictionary"
severity failure; severity failure;
@ -200,7 +202,7 @@ begin
-- Remove key/value pair from head of dictionary -- Remove key/value pair from head of dictionary
report "INFO: Test 11: Clear all entries from dictionary"; report "INFO: Test 11: Clear all entries from dictionary";
sv_dict.clear(v_error);
sv_dict.clear;
assert sv_dict.size = 0 assert sv_dict.size = 0
report "ERROR: Dict should be empty" report "ERROR: Dict should be empty"
severity failure; severity failure;


+ 56
- 59
test/WishBoneT.vhd View File

@ -2,14 +2,6 @@ library ieee;
use ieee.std_logic_1164.all; use ieee.std_logic_1164.all;
use ieee.numeric_std.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; library osvvm;
use osvvm.RandomPkg.all; use osvvm.RandomPkg.all;
use osvvm.CoveragePkg.all; use osvvm.CoveragePkg.all;
@ -18,9 +10,11 @@ library libvhdl;
use libvhdl.AssertP.all; use libvhdl.AssertP.all;
use libvhdl.SimP.all; use libvhdl.SimP.all;
use libvhdl.QueueP.all; use libvhdl.QueueP.all;
use libvhdl.DictP.all;
use libvhdl.UtilsP.all; use libvhdl.UtilsP.all;
library std;
use std.env.all;
entity WishBoneT is entity WishBoneT is
@ -90,7 +84,6 @@ architecture sim of WishBoneT is
); );
end component WishBoneSlaveE; end component WishBoneSlaveE;
--* testbench global clock period --* testbench global clock period
constant C_PERIOD : time := 5 ns; constant C_PERIOD : time := 5 ns;
--* Wishbone data width --* Wishbone data width
@ -98,23 +91,26 @@ architecture sim of WishBoneT is
--* Wishbone address width --* Wishbone address width
constant C_ADDRESS_WIDTH : natural := 8; constant C_ADDRESS_WIDTH : natural := 8;
type t_wishbone is record
--+ wishbone outputs
Cyc : std_logic;
Stb : std_logic;
We : std_logic;
Adr : std_logic_vector(C_ADDRESS_WIDTH-1 downto 0);
WDat : std_logic_vector(C_DATA_WIDTH-1 downto 0);
--+ wishbone inputs
RDat : std_logic_vector(C_DATA_WIDTH-1 downto 0);
Ack : std_logic;
Err : std_logic;
end record t_wishbone;
signal s_wishbone : t_wishbone := ('Z', 'Z', 'Z', (others => 'Z'), (others => 'Z'), (others => 'Z'), 'Z', 'Z');
--* testbench global clock --* testbench global clock
signal s_wb_clk : std_logic := '1'; signal s_wb_clk : std_logic := '1';
--* testbench global reset --* testbench global reset
signal s_wb_reset : std_logic := '1'; signal s_wb_reset : std_logic := '1';
--+ test done array with entry for each test
signal s_test_done : boolean;
signal s_wb_cyc : std_logic;
signal s_wb_stb : std_logic;
signal s_wb_we : std_logic;
signal s_wb_adr : std_logic_vector(C_ADDRESS_WIDTH-1 downto 0);
signal s_wb_master_data : std_logic_vector(C_DATA_WIDTH-1 downto 0);
signal s_wb_slave_data : std_logic_vector(C_DATA_WIDTH-1 downto 0);
signal s_wb_ack : std_logic;
signal s_wb_err : std_logic;
signal s_master_local_wen : std_logic; signal s_master_local_wen : std_logic;
signal s_master_local_ren : std_logic; signal s_master_local_ren : std_logic;
signal s_master_local_adress : std_logic_vector(C_ADDRESS_WIDTH-1 downto 0); signal s_master_local_adress : std_logic_vector(C_ADDRESS_WIDTH-1 downto 0);
@ -131,15 +127,23 @@ architecture sim of WishBoneT is
type t_register is array (0 to integer'(2**C_ADDRESS_WIDTH-1)) of std_logic_vector(C_DATA_WIDTH-1 downto 0); type t_register is array (0 to integer'(2**C_ADDRESS_WIDTH-1)) of std_logic_vector(C_DATA_WIDTH-1 downto 0);
shared variable sv_wishbone_queue : t_list_queue; shared variable sv_wishbone_queue : t_list_queue;
shared variable sv_wishbone_dict : t_dict;
shared variable sv_coverage : CovPType;
package IntSlvDict is new libvhdl.DictP
generic map (KEY_TYPE => integer,
VALUE_TYPE => std_logic_vector,
key_to_string => to_string,
value_to_string => to_hstring);
shared variable sv_wishbone_dict : IntSlvDict.t_dict;
shared variable sv_coverage : CovPType;
begin begin
--* testbench global clock --* testbench global clock
s_wb_clk <= not(s_wb_clk) after C_PERIOD/2 when not(s_test_done) else '0';
s_wb_clk <= not(s_wb_clk) after C_PERIOD/2;
--* testbench global reset --* testbench global reset
s_wb_reset <= '0' after C_PERIOD * 5; s_wb_reset <= '0' after C_PERIOD * 5;
@ -157,7 +161,6 @@ begin
variable v_wbmaster_address : integer; variable v_wbmaster_address : integer;
variable v_master_local_adress : std_logic_vector(C_ADDRESS_WIDTH-1 downto 0); variable v_master_local_adress : std_logic_vector(C_ADDRESS_WIDTH-1 downto 0);
variable v_wbmaster_data : std_logic_vector(C_DATA_WIDTH-1 downto 0); variable v_wbmaster_data : std_logic_vector(C_DATA_WIDTH-1 downto 0);
variable v_error : t_dict_error;
begin begin
v_random.InitSeed(v_random'instance_name); v_random.InitSeed(v_random'instance_name);
v_wbmaster_data := (others => '0'); v_wbmaster_data := (others => '0');
@ -182,10 +185,7 @@ begin
s_master_local_wen <= '0'; s_master_local_wen <= '0';
wait until rising_edge(s_wb_clk) and s_master_local_ack = '1'; wait until rising_edge(s_wb_clk) and s_master_local_ack = '1';
sv_wishbone_queue.push(uint_to_slv(v_wbmaster_address, C_ADDRESS_WIDTH)); sv_wishbone_queue.push(uint_to_slv(v_wbmaster_address, C_ADDRESS_WIDTH));
sv_wishbone_dict.set(integer'image(v_wbmaster_address), v_wbmaster_data, v_error);
assert v_error = NO_ERROR
report "ERROR: key error"
severity failure;
sv_wishbone_dict.set(v_wbmaster_address, v_wbmaster_data);
sv_coverage.ICover(v_wbmaster_address); sv_coverage.ICover(v_wbmaster_address);
end loop; end loop;
-- read back and check the wishbone slave registers -- read back and check the wishbone slave registers
@ -197,10 +197,7 @@ begin
s_master_local_adress <= (others => '0'); s_master_local_adress <= (others => '0');
s_master_local_ren <= '0'; s_master_local_ren <= '0';
wait until rising_edge(s_wb_clk) and s_master_local_ack = '1'; wait until rising_edge(s_wb_clk) and s_master_local_ack = '1';
sv_wishbone_dict.get(integer'image(slv_to_uint(v_master_local_adress)), v_wbmaster_data, v_error);
assert v_error = NO_ERROR
report "ERROR: key error"
severity failure;
sv_wishbone_dict.get(slv_to_uint(v_master_local_adress), v_wbmaster_data);
assert_equal(s_master_local_dout, v_wbmaster_data); assert_equal(s_master_local_dout, v_wbmaster_data);
end loop; end loop;
-- test local write & read at the same time -- test local write & read at the same time
@ -215,7 +212,7 @@ begin
report "INFO: Test successfully finished!"; report "INFO: Test successfully finished!";
sv_coverage.SetMessage("WishboneT coverage results"); sv_coverage.SetMessage("WishboneT coverage results");
sv_coverage.WriteBin; sv_coverage.WriteBin;
s_test_done <= true;
finish;
wait; wait;
end process WbMasterLocalP; end process WbMasterLocalP;
@ -230,15 +227,15 @@ begin
WbRst_i => s_wb_reset, WbRst_i => s_wb_reset,
WbClk_i => s_wb_clk, WbClk_i => s_wb_clk,
--+ wishbone outputs --+ wishbone outputs
WbCyc_o => s_wb_cyc,
WbStb_o => s_wb_stb,
WbWe_o => s_wb_we,
WbAdr_o => s_wb_adr,
WbDat_o => s_wb_master_data,
WbCyc_o => s_wishbone.Cyc,
WbStb_o => s_wishbone.Stb,
WbWe_o => s_wishbone.We,
WbAdr_o => s_wishbone.Adr,
WbDat_o => s_wishbone.WDat,
--+ wishbone inputs --+ wishbone inputs
WbDat_i => s_wb_slave_data,
WbAck_i => s_wb_ack,
WbErr_i => s_wb_err,
WbDat_i => s_wishbone.RDat,
WbAck_i => s_wishbone.Ack,
WbErr_i => s_wishbone.Err,
--+ local register if --+ local register if
LocalWen_i => s_master_local_wen, LocalWen_i => s_master_local_wen,
LocalRen_i => s_master_local_ren, LocalRen_i => s_master_local_ren,
@ -258,18 +255,18 @@ begin
wait until (s_master_local_wen = '1' or s_master_local_ren = '1') and rising_edge(s_wb_clk); wait until (s_master_local_wen = '1' or s_master_local_ren = '1') and rising_edge(s_wb_clk);
v_master_local_adress := s_master_local_adress; v_master_local_adress := s_master_local_adress;
v_master_local_data := s_master_local_din; v_master_local_data := s_master_local_din;
v_valid_access := s_master_local_wen xor s_master_local_ren;
v_valid_access := s_master_local_wen xor s_master_local_ren;
wait until rising_edge(s_wb_clk); wait until rising_edge(s_wb_clk);
WB_CYC : assert v_valid_access = s_wb_cyc
report "ERROR: Wishbone cycle should be 0b" & to_string(v_valid_access) & " instead of 0b" & to_string(s_wb_cyc)
WB_CYC : assert v_valid_access = s_wishbone.Cyc
report "ERROR: Wishbone cycle should be 0b" & to_string(v_valid_access) & " instead of 0b" & to_string(s_wishbone.Cyc)
severity failure; severity failure;
if (v_valid_access = '1') then if (v_valid_access = '1') then
WB_ADDR : assert s_wb_adr = v_master_local_adress
report "ERROR: Wishbone address 0x" & to_hstring(s_wb_adr) & " differ from local address 0x" & to_hstring(v_master_local_adress)
WB_ADDR : assert s_wishbone.Adr = v_master_local_adress
report "ERROR: Wishbone address 0x" & to_hstring(s_wishbone.Adr) & " differ from local address 0x" & to_hstring(v_master_local_adress)
severity failure; severity failure;
if (s_wb_we = '1') then
WB_DATA : assert s_wb_master_data = v_master_local_data
report "ERROR: Wishbone data 0x" & to_hstring(s_wb_master_data) & " differ from local data 0x" & to_hstring(v_master_local_data)
if (s_wishbone.We = '1') then
WB_DATA : assert s_wishbone.WDat = v_master_local_data
report "ERROR: Wishbone data 0x" & to_hstring(s_wishbone.WDat) & " differ from local data 0x" & to_hstring(v_master_local_data)
severity failure; severity failure;
end if; end if;
end if; end if;
@ -286,15 +283,15 @@ begin
WbRst_i => s_wb_reset, WbRst_i => s_wb_reset,
WbClk_i => s_wb_clk, WbClk_i => s_wb_clk,
--+ wishbone inputs --+ wishbone inputs
WbCyc_i => s_wb_cyc,
WbStb_i => s_wb_stb,
WbWe_i => s_wb_we,
WbAdr_i => s_wb_adr,
WbDat_i => s_wb_master_data,
WbCyc_i => s_wishbone.Cyc,
WbStb_i => s_wishbone.Stb,
WbWe_i => s_wishbone.We,
WbAdr_i => s_wishbone.Adr,
WbDat_i => s_wishbone.WDat,
--* wishbone outputs --* wishbone outputs
WbDat_o => s_wb_slave_data,
WbAck_o => s_wb_ack,
WbErr_o => s_wb_err,
WbDat_o => s_wishbone.RDat,
WbAck_o => s_wishbone.Ack,
WbErr_o => s_wishbone.Err,
--+ local register if --+ local register if
LocalWen_o => s_slave_local_wen, LocalWen_o => s_slave_local_wen,
LocalRen_o => s_slave_local_ren, LocalRen_o => s_slave_local_ren,


Loading…
Cancel
Save