-- Simple wishbone verification IP
|
|
-- For use with GHDL only
|
|
-- Suitable for simulation & formal verification
|
|
-- Copyright 2021 by Torsten Meissner (programming@goodcleanfun.de)
|
|
|
|
library ieee;
|
|
use ieee.std_logic_1164.all;
|
|
use ieee.numeric_std.all;
|
|
|
|
|
|
|
|
package wishbone_pkg is
|
|
|
|
|
|
type t_slv_array is array (natural range <>) of std_logic_vector;
|
|
|
|
type t_wb_syscon is record
|
|
Reset : std_logic;
|
|
Clk : std_logic;
|
|
end record;
|
|
|
|
type t_wb_master is record
|
|
Cyc : std_logic;
|
|
Stb : std_logic;
|
|
We : std_logic;
|
|
Lock : std_logic;
|
|
Adr : std_logic_vector;
|
|
Dat : std_logic_vector;
|
|
Sel : std_logic_vector;
|
|
Tgc : std_logic_vector;
|
|
Tga : std_logic_vector;
|
|
Tgd : std_logic_vector;
|
|
end record;
|
|
|
|
type t_wb_slave is record
|
|
Ack : std_logic;
|
|
Err : std_logic;
|
|
Rty : std_logic;
|
|
Dat : std_logic_vector;
|
|
Tgd : std_logic_vector;
|
|
end record;
|
|
|
|
|
|
function to_string(wb : t_wb_master) return string;
|
|
function to_string(wb : t_wb_slave) return string;
|
|
|
|
procedure log_wishbone (signal clk : std_logic; master : t_wb_master; slave : t_wb_slave);
|
|
|
|
|
|
procedure cycle (signal syscon : in t_wb_syscon;
|
|
signal master : out t_wb_master;
|
|
signal slave : in t_wb_slave;
|
|
Wen : in std_logic;
|
|
Adr : in std_logic_vector;
|
|
WDat : in std_logic_vector;
|
|
RDat : out std_logic_vector);
|
|
|
|
procedure single_cycle (signal syscon : in t_wb_syscon;
|
|
signal master : out t_wb_master;
|
|
signal slave : in t_wb_slave;
|
|
Wen : in std_logic;
|
|
Adr : in std_logic_vector;
|
|
WDat : in std_logic_vector;
|
|
RDat : out std_logic_vector);
|
|
|
|
procedure block_cycle (signal syscon : in t_wb_syscon;
|
|
signal master : out t_wb_master;
|
|
signal slave : in t_wb_slave;
|
|
Wen : in std_logic;
|
|
Adr : in t_slv_array;
|
|
WDat : in t_slv_array;
|
|
RDat : out t_slv_array);
|
|
|
|
end package wishbone_pkg;
|
|
|
|
|
|
|
|
package body wishbone_pkg is
|
|
|
|
|
|
procedure cycle (signal syscon : in t_wb_syscon;
|
|
signal master : out t_wb_master;
|
|
signal slave : in t_wb_slave;
|
|
Wen : in std_logic;
|
|
Adr : in std_logic_vector;
|
|
WDat : in std_logic_vector;
|
|
RDat : out std_logic_vector) is
|
|
begin
|
|
master.Cyc <= '1';
|
|
master.Stb <= '1';
|
|
master.We <= Wen;
|
|
master.Adr <= Adr;
|
|
master.Dat <= WDat;
|
|
wait until rising_edge(syscon.Clk) and (slave.Ack or slave.Err or slave.Rty) = '1';
|
|
RDat := slave.Dat;
|
|
end procedure cycle;
|
|
|
|
procedure single_cycle (signal syscon : in t_wb_syscon;
|
|
signal master : out t_wb_master;
|
|
signal slave : in t_wb_slave;
|
|
Wen : in std_logic;
|
|
Adr : in std_logic_vector;
|
|
WDat : in std_logic_vector;
|
|
RDat : out std_logic_vector) is
|
|
begin
|
|
cycle(syscon, master, slave, Wen, Adr, WDat, RDat);
|
|
master.Cyc <= '0';
|
|
master.Stb <= '0';
|
|
master.We <= '0';
|
|
master.Adr <= (master.Adr'range => '0');
|
|
master.Dat <= (master.Dat'range => '0');
|
|
wait until rising_edge(syscon.Clk);
|
|
end procedure single_cycle;
|
|
|
|
procedure block_cycle (signal syscon : in t_wb_syscon;
|
|
signal master : out t_wb_master;
|
|
signal slave : in t_wb_slave;
|
|
Wen : in std_logic;
|
|
Adr : in t_slv_array;
|
|
WDat : in t_slv_array;
|
|
RDat : out t_slv_array) is
|
|
begin
|
|
assert Adr'length = WDat'length and WDat'length = RDat'length;
|
|
for i in Adr'low to Adr'high-1 loop
|
|
cycle(syscon, master, slave, Wen, Adr(i), WDat(i), RDat(i));
|
|
end loop;
|
|
single_cycle(syscon, master, slave, Wen, Adr(Adr'high), WDat(WDat'high), RDat(RDat'high));
|
|
end procedure block_cycle;
|
|
|
|
function to_string(wb : t_wb_master) return string is
|
|
begin
|
|
return "Cyc: " & to_string(wb.Cyc) & LF &
|
|
"Stb: " & to_string(wb.Stb) & LF &
|
|
"We: " & to_string(wb.We) & LF &
|
|
"Lock: " & to_string(wb.Lock) & LF &
|
|
"Adr: " & to_hstring(wb.Adr) & LF &
|
|
"Dat: " & to_hstring(wb.Dat) & LF &
|
|
"Sel: " & to_hstring(wb.Sel) & LF &
|
|
"Tgc: " & to_hstring(wb.Tgc) & LF &
|
|
"Tga: " & to_hstring(wb.Tga) & LF &
|
|
"Tgd: " & to_hstring(wb.Tgd);
|
|
end function to_string;
|
|
|
|
function to_string(wb : t_wb_slave) return string is
|
|
begin
|
|
return "Ack: " & to_string(wb.Ack) & LF &
|
|
"Err: " & to_string(wb.Err) & LF &
|
|
"Rty: " & to_string(wb.Rty) & LF &
|
|
"Dat: " & to_hstring(wb.Dat) & LF &
|
|
"Tgd: " & to_hstring(wb.Tgd);
|
|
end function to_string;
|
|
|
|
procedure log_wishbone (signal clk : std_logic; master : t_wb_master; slave : t_wb_slave) is
|
|
begin
|
|
wait until rising_edge(clk);
|
|
report "Wishbone master:" & LF & to_string(master);
|
|
report "Wishbone slave:" & LF & to_string(slave);
|
|
end procedure log_wishbone;
|
|
|
|
|
|
end package body wishbone_pkg;
|