You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 

161 lines
5.5 KiB

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