Browse Source

Refactoring Wishbone tests & design

* Add 1st initial version of WishBone checker unit
* Add Wishbone package with component & type declarations
* Replace WB slave register by dictionary
master
T. Meissner 6 years ago
parent
commit
e953cda1d8
7 changed files with 258 additions and 155 deletions
  1. +55
    -0
      syn/WishBoneCheckerE.vhd
  2. +9
    -13
      syn/WishBoneMasterE.vhd
  3. +96
    -0
      syn/WishBoneP.vhd
  4. +9
    -13
      syn/WishBoneSlaveE.vhd
  5. +3
    -2
      test/Makefile
  6. +11
    -0
      test/WishBoneT.tcl
  7. +75
    -127
      test/WishBoneT.vhd

+ 55
- 0
syn/WishBoneCheckerE.vhd View File

@ -0,0 +1,55 @@
library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
entity WishBoneCheckerE is
port (
--+ wishbone system if
WbRst_i : in std_logic;
WbClk_i : in std_logic;
--+ wishbone outputs
WbMCyc_i : in std_logic;
WbMStb_i : in std_logic;
WbMWe_i : in std_logic;
WbMAdr_i : in std_logic_vector;
WbMDat_i : in std_logic_vector;
--+ wishbone inputs
WbSDat_i : in std_logic_vector;
WbSAck_i : in std_logic;
WbSErr_i : in std_logic
);
end entity WishBoneCheckerE;
architecture check of WishBoneCheckerE is
begin
-- psl default clock is rising_edge(WbClk_i);
--
-- Wishbone protocol checks
--
-- psl property initialize(boolean init_state) is
-- always ({WbRst_i} |=> {init_state[+] && {WbRst_i[*]; not(WbRst_i)}});
--
-- psl RULE_3_00 : assert initialize(not(WbMCyc_i) and not(WbMStb_i) and not(WbMWe_i))
-- report "Wishbone rule 3.00 violated";
--
-- psl property reset_signal is
-- always {not(WbRst_i); WbRst_i} |=> {(WbRst_i and not(WbClk_i))[*]; WbRst_i and WbClk_i};
--
-- psl RULE_3_05 : assert reset_signal
-- report "Wishbone rule 3.05 violated";
--
-- -- psl property master_cycle_signal(boolean master_strobe, master_cyc) is
-- -- always {master_strobe} |-> {master_cyc[+] && {not(master_strobe)[->]:WbClk_i}};
-- --
-- -- psl RULE_3_25 : assert master_cycle_signal(WbMStb_i, WbMCyc_i)
-- -- report "Wishbone rule 3.25 violated";
end architecture check;

+ 9
- 13
syn/WishBoneMasterE.vhd View File

@ -4,10 +4,6 @@ library ieee;
entity WishBoneMasterE is
generic (
G_ADR_WIDTH : positive := 8; --* address bus width
G_DATA_WIDTH : positive := 8 --* data bus width
);
port (
--+ wishbone system if
WbRst_i : in std_logic;
@ -16,18 +12,18 @@ entity WishBoneMasterE is
WbCyc_o : out std_logic;
WbStb_o : out std_logic;
WbWe_o : out std_logic;
WbAdr_o : out std_logic_vector(G_ADR_WIDTH-1 downto 0);
WbDat_o : out std_logic_vector(G_DATA_WIDTH-1 downto 0);
WbAdr_o : out std_logic_vector;
WbDat_o : out std_logic_vector;
--+ wishbone inputs
WbDat_i : in std_logic_vector(G_DATA_WIDTH-1 downto 0);
WbDat_i : in std_logic_vector;
WbAck_i : in std_logic;
WbErr_i : in std_logic;
--+ local register if
LocalWen_i : in std_logic;
LocalRen_i : in std_logic;
LocalAdress_i : in std_logic_vector(G_ADR_WIDTH-1 downto 0);
LocalData_i : in std_logic_vector(G_DATA_WIDTH-1 downto 0);
LocalData_o : out std_logic_vector(G_DATA_WIDTH-1 downto 0);
LocalAdress_i : in std_logic_vector;
LocalData_i : in std_logic_vector;
LocalData_o : out std_logic_vector;
LocalAck_o : out std_logic;
LocalError_o : out std_logic
);
@ -83,7 +79,7 @@ begin
--+ combinatoral local register if outputs
LocalData_o <= WbDat_i when s_wb_master_fsm = DATA else (others => '0');
LocalData_o <= WbDat_i when s_wb_master_fsm = DATA else (LocalData_o'range => '0');
LocalError_o <= WbErr_i when s_wb_master_fsm /= IDLE else '0';
LocalAck_o <= WbAck_i when (s_wb_master_fsm = ADDRESS or s_wb_master_fsm = DATA) and WbErr_i = '0' else '0';
@ -98,8 +94,8 @@ begin
begin
if(rising_edge(WbClk_i)) then
if(WbRst_i = '1') then
WbAdr_o <= (others => '0');
WbDat_o <= (others => '0');
WbAdr_o <= (WbAdr_o'range => '0');
WbDat_o <= (WbDat_o'range => '0');
s_wb_wen <= '0';
else
if (s_wb_master_fsm = IDLE) then


+ 96
- 0
syn/WishBoneP.vhd View File

@ -0,0 +1,96 @@
library ieee;
use ieee.std_logic_1164.all;
package WishBoneP is
component WishBoneMasterE is
port (
--+ wishbone system if
WbRst_i : in std_logic;
WbClk_i : in std_logic;
--+ wishbone outputs
WbCyc_o : out std_logic;
WbStb_o : out std_logic;
WbWe_o : out std_logic;
WbAdr_o : out std_logic_vector;
WbDat_o : out std_logic_vector;
--+ wishbone inputs
WbDat_i : in std_logic_vector;
WbAck_i : in std_logic;
WbErr_i : in std_logic;
--+ local register if
LocalWen_i : in std_logic;
LocalRen_i : in std_logic;
LocalAdress_i : in std_logic_vector;
LocalData_i : in std_logic_vector;
LocalData_o : out std_logic_vector;
LocalAck_o : out std_logic;
LocalError_o : out std_logic
);
end component WishBoneMasterE;
component WishBoneSlaveE is
port (
--+ wishbone system if
WbRst_i : in std_logic;
WbClk_i : in std_logic;
--+ wishbone inputs
WbCyc_i : in std_logic;
WbStb_i : in std_logic;
WbWe_i : in std_logic;
WbAdr_i : in std_logic_vector;
WbDat_i : in std_logic_vector;
--* wishbone outputs
WbDat_o : out std_logic_vector;
WbAck_o : out std_logic;
WbErr_o : out std_logic;
--+ local register if
LocalWen_o : out std_logic;
LocalRen_o : out std_logic;
LocalAdress_o : out std_logic_vector;
LocalData_o : out std_logic_vector;
LocalData_i : in std_logic_vector
);
end component WishBoneSlaveE;
component WishBoneCheckerE is
port (
--+ wishbone system if
WbRst_i : in std_logic;
WbClk_i : in std_logic;
--+ wishbone outputs
WbMCyc_i : in std_logic;
WbMStb_i : in std_logic;
WbMWe_i : in std_logic;
WbMAdr_i : in std_logic_vector;
WbMDat_i : in std_logic_vector;
--+ wishbone inputs
WbSDat_i : in std_logic_vector;
WbSAck_i : in std_logic;
WbSErr_i : in std_logic
);
end component WishBoneCheckerE;
type t_wishbone_if is record
--+ wishbone outputs
Cyc : std_logic;
Stb : std_logic;
We : std_logic;
Adr : std_logic_vector;
WDat : std_logic_vector;
--+ wishbone inputs
RDat : std_logic_vector;
Ack : std_logic;
Err : std_logic;
end record t_wishbone_if;
end package WishBoneP;

+ 9
- 13
syn/WishBoneSlaveE.vhd View File

@ -5,10 +5,6 @@ library ieee;
entity WishBoneSlaveE is
generic (
G_ADR_WIDTH : positive := 8; --* address bus width
G_DATA_WIDTH : positive := 8 --* data bus width
);
port (
--+ wishbone system if
WbRst_i : in std_logic;
@ -17,18 +13,18 @@ entity WishBoneSlaveE is
WbCyc_i : in std_logic;
WbStb_i : in std_logic;
WbWe_i : in std_logic;
WbAdr_i : in std_logic_vector(G_ADR_WIDTH-1 downto 0);
WbDat_i : in std_logic_vector(G_DATA_WIDTH-1 downto 0);
WbAdr_i : in std_logic_vector;
WbDat_i : in std_logic_vector;
--+ wishbone outputs
WbDat_o : out std_logic_vector(G_DATA_WIDTH-1 downto 0);
WbDat_o : out std_logic_vector;
WbAck_o : out std_logic;
WbErr_o : out std_logic;
--+ local register if
LocalWen_o : out std_logic;
LocalRen_o : out std_logic;
LocalAdress_o : out std_logic_vector(G_ADR_WIDTH-1 downto 0);
LocalData_o : out std_logic_vector(G_DATA_WIDTH-1 downto 0);
LocalData_i : in std_logic_vector(G_DATA_WIDTH-1 downto 0)
LocalAdress_o : out std_logic_vector;
LocalData_o : out std_logic_vector;
LocalData_i : in std_logic_vector
);
end entity WishBoneSlaveE;
@ -79,11 +75,11 @@ begin
--+ local register if outputs
LocalWen_o <= WbWe_i when s_wb_slave_fsm = ADDRESS and s_wb_active else '0';
LocalRen_o <= not(WbWe_i) when s_wb_slave_fsm = ADDRESS and s_wb_active else '0';
LocalAdress_o <= WbAdr_i when s_wb_slave_fsm /= IDLE and s_wb_active else (others => '0');
LocalData_o <= WbDat_i when s_wb_slave_fsm = ADDRESS and s_wb_active and WbWe_i = '1' else (others => '0');
LocalAdress_o <= WbAdr_i when s_wb_slave_fsm /= IDLE and s_wb_active else (LocalAdress_o'range => '0');
LocalData_o <= WbDat_i when s_wb_slave_fsm = ADDRESS and s_wb_active and WbWe_i = '1' else (LocalData_o'range => '0');
--+ wishbone if outputs
WbDat_o <= LocalData_i when s_wb_slave_fsm = DATA and WbWe_i = '0' else (others => '0');
WbDat_o <= LocalData_i when s_wb_slave_fsm = DATA and WbWe_i = '0' else (WbDat_o'range => '0');
WbAck_o <= '1' when s_wb_slave_fsm = DATA or (s_wb_slave_fsm = ADDRESS and s_wb_active and WbWe_i = '1') else '0';
WbErr_o <= '0';


+ 3
- 2
test/Makefile View File

@ -69,8 +69,9 @@ spi: spit
wishbonet: OsvvmContext.o AssertP.o SimP.o QueueP.o DictP.o UtilsP.o \
$(SYN_SRC)/WishBoneMasterE.vhd $(SYN_SRC)/WishBoneSlaveE.vhd WishBoneT.vhd
ghdl -a --std=$(VHD_STD) -fpsl $(SYN_SRC)/WishBoneMasterE.vhd $(SYN_SRC)/WishBoneSlaveE.vhd
$(SYN_SRC)/WishBoneP.vhd $(SYN_SRC)/WishBoneMasterE.vhd $(SYN_SRC)/WishBoneSlaveE.vhd WishBoneT.vhd
ghdl -a --std=$(VHD_STD) -fpsl $(SYN_SRC)/WishBoneP.vhd
ghdl -a --std=$(VHD_STD) -fpsl $(SYN_SRC)/WishBoneCheckerE.vhd $(SYN_SRC)/WishBoneMasterE.vhd $(SYN_SRC)/WishBoneSlaveE.vhd
ghdl -a --std=$(VHD_STD) -fpsl WishBoneT.vhd
ghdl -e --std=$(VHD_STD) $@


+ 11
- 0
test/WishBoneT.tcl View File

@ -0,0 +1,11 @@
set signals [list]
lappend signals "top.WishBoneT.s_wb_reset"
lappend signals "top.WishBoneT.s_wb_clk"
lappend signals "top.WishBoneT.s_wishbone.cyc"
lappend signals "top.WishBoneT.s_wishbone.stb"
lappend signals "top.WishBoneT.s_wishbone.we"
lappend signals "top.WishBoneT.s_wishbone.ack"
lappend signals "top.WishBoneT.s_wishbone.adr"
lappend signals "top.WishBoneT.s_wishbone.wdat"
lappend signals "top.WishBoneT.s_wishbone.rdat"
set num_added [ gtkwave::addSignalsFromList $signals ]

+ 75
- 127
test/WishBoneT.vhd View File

@ -11,6 +11,9 @@ library libvhdl;
use libvhdl.SimP.all;
use libvhdl.UtilsP.all;
library work;
use work.WishBoneP.all;
library std;
use std.env.all;
@ -24,65 +27,6 @@ end entity WishBoneT;
architecture sim of WishBoneT is
component WishBoneMasterE is
generic (
G_ADR_WIDTH : positive := 8; --* address bus width
G_DATA_WIDTH : positive := 8 --* data bus width
);
port (
--+ wishbone system if
WbRst_i : in std_logic;
WbClk_i : in std_logic;
--+ wishbone outputs
WbCyc_o : out std_logic;
WbStb_o : out std_logic;
WbWe_o : out std_logic;
WbAdr_o : out std_logic_vector(G_ADR_WIDTH-1 downto 0);
WbDat_o : out std_logic_vector(G_DATA_WIDTH-1 downto 0);
--+ wishbone inputs
WbDat_i : in std_logic_vector(G_DATA_WIDTH-1 downto 0);
WbAck_i : in std_logic;
WbErr_i : in std_logic;
--+ local register if
LocalWen_i : in std_logic;
LocalRen_i : in std_logic;
LocalAdress_i : in std_logic_vector(G_ADR_WIDTH-1 downto 0);
LocalData_i : in std_logic_vector(G_DATA_WIDTH-1 downto 0);
LocalData_o : out std_logic_vector(G_DATA_WIDTH-1 downto 0);
LocalAck_o : out std_logic;
LocalError_o : out std_logic
);
end component WishBoneMasterE;
component WishBoneSlaveE is
generic (
G_ADR_WIDTH : positive := 8; --* address bus width
G_DATA_WIDTH : positive := 8 --* data bus width
);
port (
--+ wishbone system if
WbRst_i : in std_logic;
WbClk_i : in std_logic;
--+ wishbone inputs
WbCyc_i : in std_logic;
WbStb_i : in std_logic;
WbWe_i : in std_logic;
WbAdr_i : in std_logic_vector(G_ADR_WIDTH-1 downto 0);
WbDat_i : in std_logic_vector(G_DATA_WIDTH-1 downto 0);
--* wishbone outputs
WbDat_o : out std_logic_vector(G_DATA_WIDTH-1 downto 0);
WbAck_o : out std_logic;
WbErr_o : out std_logic;
--+ local register if
LocalWen_o : out std_logic;
LocalRen_o : out std_logic;
LocalAdress_o : out std_logic_vector(G_ADR_WIDTH-1 downto 0);
LocalData_o : out std_logic_vector(G_DATA_WIDTH-1 downto 0);
LocalData_i : in std_logic_vector(G_DATA_WIDTH-1 downto 0)
);
end component WishBoneSlaveE;
--* testbench global clock period
constant C_PERIOD : time := 5 ns;
--* Wishbone data width
@ -90,20 +34,11 @@ architecture sim of WishBoneT is
--* Wishbone address width
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');
signal s_wishbone : t_wishbone_if(
Adr(C_ADDRESS_WIDTH-1 downto 0),
WDat(C_DATA_WIDTH-1 downto 0),
RDat(C_DATA_WIDTH-1 downto 0)
);
--* testbench global clock
signal s_wb_clk : std_logic := '1';
@ -123,8 +58,6 @@ architecture sim of WishBoneT is
signal s_slave_local_dout : std_logic_vector(C_DATA_WIDTH-1 downto 0);
signal s_slave_local_din : 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);
package SlvQueue is new libvhdl.QueueP
generic map (
@ -136,12 +69,13 @@ architecture sim of WishBoneT is
shared variable sv_wishbone_queue : SlvQueue.t_list_queue;
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);
generic map (KEY_TYPE => natural,
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_wb_master_dict : IntSlvDict.t_dict;
shared variable sv_wb_slave_dict : IntSlvDict.t_dict;
shared variable sv_coverage : CovPType;
@ -158,7 +92,8 @@ begin
QueueInitP : process is
begin
sv_wishbone_queue.init(false);
sv_wishbone_dict.init(false);
sv_wb_master_dict.init(false);
sv_wb_slave_dict.init(false);
wait;
end process QueueInitP;
@ -192,7 +127,7 @@ begin
s_master_local_wen <= '0';
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_dict.set(v_wbmaster_address, v_wbmaster_data);
sv_wb_master_dict.set(v_wbmaster_address, v_wbmaster_data);
sv_coverage.ICover(v_wbmaster_address);
end loop;
-- read back and check the wishbone slave registers
@ -204,7 +139,7 @@ begin
s_master_local_adress <= (others => '0');
s_master_local_ren <= '0';
wait until rising_edge(s_wb_clk) and s_master_local_ack = '1';
sv_wishbone_dict.get(slv_to_uint(v_master_local_adress), v_wbmaster_data);
sv_wb_master_dict.get(slv_to_uint(v_master_local_adress), v_wbmaster_data);
assert_equal(s_master_local_dout, v_wbmaster_data);
end loop;
-- test local write & read at the same time
@ -225,10 +160,6 @@ begin
i_WishBoneMasterE : WishBoneMasterE
generic map (
G_ADR_WIDTH => C_ADDRESS_WIDTH,
G_DATA_WIDTH => C_DATA_WIDTH
)
port map (
--+ wishbone system if
WbRst_i => s_wb_reset,
@ -254,37 +185,33 @@ begin
);
WishBoneBusMonitorP : process is
variable v_master_local_adress : std_logic_vector(C_ADDRESS_WIDTH-1 downto 0);
variable v_master_local_data : std_logic_vector(C_DATA_WIDTH-1 downto 0);
variable v_valid_access : std_logic;
begin
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_data := s_master_local_din;
v_valid_access := s_master_local_wen xor s_master_local_ren;
wait until rising_edge(s_wb_clk);
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)
WishBoneBusMonitorP : process is
variable v_master_local_adress : std_logic_vector(C_ADDRESS_WIDTH-1 downto 0);
variable v_master_local_data : std_logic_vector(C_DATA_WIDTH-1 downto 0);
variable v_valid_access : std_logic;
begin
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_data := s_master_local_din;
v_valid_access := s_master_local_wen xor s_master_local_ren;
wait until rising_edge(s_wb_clk);
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;
if (v_valid_access = '1') then
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;
if (v_valid_access = '1') then
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)
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;
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;
end if;
end if;
end process WishBoneBusMonitorP;
end if;
end process WishBoneBusMonitorP;
i_WishBoneSlaveE : WishBoneSlaveE
generic map (
G_ADR_WIDTH => C_ADDRESS_WIDTH,
G_DATA_WIDTH => C_DATA_WIDTH
)
i_WishBoneSlaveE : WishBoneSlaveE
port map (
--+ wishbone system if
WbRst_i => s_wb_reset,
@ -308,21 +235,42 @@ begin
);
WbSlaveLocalP : process is
variable v_register : t_register := (others => (others => '0'));
begin
wait until rising_edge(s_wb_clk);
if (s_wb_reset = '1') then
v_register := (others => (others => '0'));
s_slave_local_din <= (others => '0');
else
if (s_slave_local_wen = '1') then
v_register(slv_to_uint(s_slave_local_adress)) := s_slave_local_dout;
elsif (s_slave_local_ren = '1') then
s_slave_local_din <= v_register(slv_to_uint(s_slave_local_adress));
end if;
WbSlaveLocalP : process is
variable v_data : std_logic_vector(s_slave_local_din'range);
begin
wait until rising_edge(s_wb_clk);
if (s_wb_reset = '1') then
s_slave_local_din <= (others => '0');
else
if (s_slave_local_wen = '1') then
sv_wb_slave_dict.set(slv_to_uint(s_slave_local_adress), s_slave_local_dout);
elsif (s_slave_local_ren = '1') then
WB_SLAVE_REG : assert sv_wb_slave_dict.hasKey(slv_to_uint(s_slave_local_adress))
report "ERROR: Requested register at addr 0x" & to_hstring(s_slave_local_adress) & " not written before"
severity failure;
sv_wb_slave_dict.get(slv_to_uint(s_slave_local_adress), v_data);
s_slave_local_din <= v_data;
end if;
end process WbSlaveLocalP;
end if;
end process WbSlaveLocalP;
i_WishBoneChecker : WishBoneCheckerE
port map (
--+ wishbone system if
WbRst_i => s_wb_reset,
WbClk_i => s_wb_clk,
--+ wishbone outputs
WbMCyc_i => s_wishbone.Cyc,
WbMStb_i => s_wishbone.Stb,
WbMWe_i => s_wishbone.We,
WbMAdr_i => s_wishbone.Adr,
WbMDat_i => s_wishbone.WDat,
--+ wishbone inputs
WbSDat_i => s_wishbone.RDat,
WbSAck_i => s_wishbone.Ack,
WbSErr_i => s_wishbone.Err
);
end architecture sim;

Loading…
Cancel
Save