1251 lines
42 KiB
VHDL
1251 lines
42 KiB
VHDL
-- See the file "LICENSE" for the full license governing this code. --
|
|
|
|
library ieee;
|
|
use ieee.STD_LOGIC_1164.ALL;
|
|
use ieee.numeric_std.all;
|
|
use ieee.math_real.all;
|
|
use ieee.std_logic_textio.all;
|
|
|
|
library std;
|
|
use std.standard.all;
|
|
use std.textio.all;
|
|
|
|
library work;
|
|
use work.wishbone.all;
|
|
use work.config.all;
|
|
use work.txt_util.all;
|
|
use work.lt16x32_internal.all;
|
|
use work.lt16x32_global.all;
|
|
|
|
-- Whishbone Testing Package
|
|
package wb_tp is
|
|
constant READY: std_logic := '1'; --ready signal from mem which will be converted to msti.ack
|
|
constant NREADY: std_logic := '0';
|
|
type access_type is (NO_ACC, RD_ACC, WR_ACC, SIM_ACC);
|
|
---------------------------------------------------------------
|
|
--
|
|
-- Prototype: Function
|
|
--
|
|
---------------------------------------------------------------
|
|
|
|
function slvi_chk_quiet(
|
|
signal slvi_vector : wb_slv_in_vector;
|
|
constant ScrnOut : boolean := false;
|
|
constant InstancePath: string := "slvi_chk_quiet "
|
|
) return boolean;
|
|
|
|
function msti_chk_quiet(
|
|
signal msti_vector : wb_mst_in_vector;
|
|
constant ScrnOut : boolean := false;
|
|
constant InstancePath: string := "msti_chk_quiet "
|
|
) return boolean;
|
|
|
|
function msto_chk_quiet(
|
|
signal msto_vector : wb_mst_out_vector;
|
|
constant ScrnOut : boolean := false;
|
|
constant InstancePath: string := "msto_chk_quiet "
|
|
) return boolean ;
|
|
|
|
function core2wbmo_chk(
|
|
signal wbadr : std_logic_vector(31 downto 0);
|
|
signal wbsz : std_logic_vector(1 downto 0);
|
|
signal wbwrdat : std_logic_vector(31 downto 0);
|
|
signal msto : wb_mst_out_type;
|
|
constant we : access_type := NO_ACC;
|
|
constant ScrnOut : boolean := false;
|
|
constant InstancePath: string := "core2wbmo_chk "
|
|
) return boolean ;
|
|
|
|
function slvi_chk_all(
|
|
signal slvo : wb_slv_out_vector; -- for address map check
|
|
signal msto : wb_mst_out_vector;
|
|
signal slvi : wb_slv_in_vector;
|
|
constant mst_mask_vector : std_logic_vector(0 to NWBMST-1) := b"0000";
|
|
constant ScrnOut : boolean := false;
|
|
constant InstancePath : string := "slvi_chk_all "
|
|
|
|
) return boolean;
|
|
|
|
function msti_chk_all (
|
|
signal msti : wb_mst_in_vector;
|
|
signal msto : wb_mst_out_vector;
|
|
signal slvo : wb_slv_out_vector; -- response from selected slave (if no addr map, no slave never been selected !!)
|
|
constant mst_mask_vector : std_logic_vector(0 to NWBMST-1) := b"0000";
|
|
constant ScrnOut : boolean := false;
|
|
constant InstancePath : string := "msti_chk_all "
|
|
) return boolean;
|
|
|
|
function wbmi2core_chk(
|
|
signal wb2core : dmem_core;
|
|
constant we : access_type := NO_ACC;
|
|
signal mo_sel : std_logic_vector(WB_SEL_WIDTH-1 downto 0);
|
|
signal mi_ack : std_logic;
|
|
signal resp_rddat : std_logic_vector(memory_width - 1 downto 0);
|
|
constant ScrnOut : boolean := false;
|
|
constant InstancePath: string := "wbmi2core_chk "
|
|
) return boolean;
|
|
|
|
function wb2mem_chk(
|
|
signal wb2mem : core_dmem;
|
|
signal slvi : wb_slv_in_type;
|
|
constant we : access_type := NO_ACC;
|
|
constant ScrnOut : boolean := false;
|
|
constant InstancePath: string := "wb2mem_chk "
|
|
) return boolean;
|
|
|
|
function gmst_idx_fn (
|
|
signal msto : wb_mst_out_vector;
|
|
constant mst_mask_vector : std_logic_vector(0 to NWBMST-1) := b"0000";
|
|
constant ScrnOut : boolean := false;
|
|
constant InstancePath : string := "gmst_idx_fn "
|
|
) return integer ;
|
|
|
|
function wbszconv_chk(
|
|
signal size : in std_logic_vector(1 downto 0);
|
|
constant ScrnOut : boolean := false;
|
|
constant InstancePath: string := "wbszconv_chk"
|
|
) return boolean;
|
|
|
|
---------------------------------------------------------------
|
|
--
|
|
-- Prototype: Procedure
|
|
--
|
|
---------------------------------------------------------------
|
|
procedure gencore2mem_req (
|
|
signal core2dmem :out core_dmem;
|
|
--
|
|
constant req_acc :in access_type := NO_ACC;
|
|
constant rd_adr :in std_logic_vector(memory_width - 1 downto 0) := (others=>'0');
|
|
constant rd_sz :in std_logic_vector(1 downto 0) := "00";
|
|
--
|
|
constant wr_adr :in std_logic_vector(memory_width - 1 downto 0):= (others=>'0');
|
|
constant wr_sz :in std_logic_vector(1 downto 0):= "00";
|
|
constant wr_dat :in std_logic_vector(memory_width - 1 downto 0):= (others=>'-');
|
|
--
|
|
constant ScrnOut :in boolean := false;
|
|
constant InstancePath :in string := "gencore2mem_req "
|
|
|
|
);
|
|
--
|
|
procedure genwb2core (
|
|
signal msti :out wb_mst_in_type;
|
|
--
|
|
constant req_acc :in access_type := NO_ACC;
|
|
constant rd_sz :in std_logic_vector(1 downto 0) := "00";
|
|
constant wb_sel :in std_logic_vector(WB_SEL_WIDTH-1 downto 0);
|
|
--
|
|
constant read_data :in std_logic_vector(memory_width - 1 downto 0);
|
|
constant ready :in std_logic := '0';
|
|
constant ScrnOut :in boolean := false;
|
|
constant InstancePath :in string := "genwb2core"
|
|
);
|
|
--
|
|
procedure genmst_req (
|
|
signal mst_out :out wb_mst_out_type;
|
|
constant req_idx :in integer := 0;
|
|
constant we :in std_logic;
|
|
constant adr :in std_logic_vector(WB_ADR_WIDTH-1 downto 0);
|
|
constant dat :in std_logic_vector(WB_PORT_SIZE-1 downto 0);
|
|
constant sel :in std_logic_vector(WB_SEL_WIDTH-1 downto 0);
|
|
constant ScrnOut :in boolean := false;
|
|
constant InstancePath :in string := "genmst_req "
|
|
);
|
|
--
|
|
procedure list_all_mst_req (
|
|
signal msto : in wb_mst_out_vector;
|
|
constant mst_mask_vector : std_logic_vector(0 to NWBMST-1) := b"0000";
|
|
constant ScrnOut : boolean := false;
|
|
constant InstancePath : string := "list_all_mst_req "
|
|
);
|
|
|
|
procedure generate_sync_wb_single_write(
|
|
signal msto : out wb_mst_out_type;
|
|
signal slvo : in wb_slv_out_type;
|
|
signal clk : in std_logic;
|
|
signal writedata : std_logic_vector(WB_PORT_SIZE-1 downto 0);
|
|
constant SIZE : std_logic_vector(WB_ADR_BOUND-1 downto 0) := "10";
|
|
constant ADR_OFFSET : integer := 0 -- Offset added to the access address
|
|
);
|
|
|
|
procedure generate_sync_wb_burst_write(
|
|
signal msto : out wb_mst_out_type;
|
|
signal slvo : in wb_slv_out_type;
|
|
signal clk : in std_logic;
|
|
signal writedata : std_logic_vector(WB_PORT_SIZE-1 downto 0);
|
|
constant NUMBURSTS : positive := 4;
|
|
constant SIZE : std_logic_vector(WB_ADR_BOUND-1 downto 0) := "10";
|
|
constant ADR_OFFSET : integer := 0 -- Offset added to the access address
|
|
);
|
|
|
|
procedure generate_sync_wb_single_read(
|
|
signal msto : out wb_mst_out_type; -- Slave input
|
|
signal slvo : in wb_slv_out_type; -- Slave output
|
|
signal clk : in std_logic;
|
|
signal readdata : out std_logic_vector(WB_PORT_SIZE -1 downto 0);
|
|
constant ADR_OFFSET : integer := 0; -- Offset added to the access address
|
|
constant SIZE : std_logic_vector(WB_ADR_BOUND-1 downto 0) := "10"
|
|
);
|
|
|
|
procedure generate_sync_wb_burst_read(
|
|
signal msto : out wb_mst_out_type; -- Slave input
|
|
signal slvo : in wb_slv_out_type; -- Slave output
|
|
signal clk : in std_logic;
|
|
signal readdata : out std_logic_vector(WB_PORT_SIZE -1 downto 0);
|
|
constant NUMBURSTS : positive := 4;
|
|
constant ADR_OFFSET : integer := 0; -- Offset added to the access address
|
|
constant SIZE : std_logic_vector(WB_ADR_BOUND-1 downto 0) := "10"
|
|
);
|
|
|
|
end wb_tp;
|
|
|
|
package body wb_tp is
|
|
|
|
---------------------------------------------------------------
|
|
-- Function: slvi_chk_quiet(slvi_vector)
|
|
--
|
|
-- Check if there is any request (cyc) to any slave
|
|
---------------------------------------------------------------
|
|
function slvi_chk_quiet(
|
|
signal slvi_vector : wb_slv_in_vector;
|
|
constant ScrnOut : boolean := false;
|
|
constant InstancePath: string := "slvi_chk_quiet "
|
|
) return boolean is
|
|
variable L: Line;
|
|
begin
|
|
for i in 0 to NWBSLV-1 loop
|
|
if slvi_vector(i).cyc /= '0' then
|
|
if ScrnOut then
|
|
write(L, Now, Right, 15);
|
|
write(L, " : " & InstancePath);
|
|
write(L, String'("E00: slv(" & integer'image(i) & ") should not get any request !!!"));
|
|
writeline(output, L);
|
|
end if;
|
|
return false;
|
|
end if;
|
|
end loop;
|
|
|
|
return true;
|
|
end function;
|
|
|
|
---------------------------------------------------------------
|
|
-- Function: msti_chk_quiet(msti_vector)
|
|
--
|
|
-- Check if there is any request (ack) to any master
|
|
---------------------------------------------------------------
|
|
function msti_chk_quiet(
|
|
signal msti_vector : wb_mst_in_vector;
|
|
constant ScrnOut : boolean := false;
|
|
constant InstancePath: string := "msti_chk_quiet "
|
|
) return boolean is
|
|
variable L: Line;
|
|
begin
|
|
for i in 0 to NWBMST-1 loop
|
|
if msti_vector(i).ack /= '0' then
|
|
if ScrnOut then
|
|
write(L, Now, Right, 15);
|
|
write(L, " : " & InstancePath);
|
|
write(L, String'("E00: mst(" & integer'image(i) & ") should not get any ack !!!"));
|
|
writeline(output, L);
|
|
end if;
|
|
return false;
|
|
end if;
|
|
end loop;
|
|
|
|
return true;
|
|
end function;
|
|
|
|
---------------------------------------------------------------
|
|
-- Function: msto_chk_quiet(mst_mask_vector)
|
|
--
|
|
-- check if there is any master request (no need to assert error as it will be handle in fn caller)
|
|
-- Any master that is disable, wb_intercon will not assert the request (cyc) for that master
|
|
-- true = wb_intercon will consider that master as quiet as it either is inactive or sends no request (cyc= 0)
|
|
---------------------------------------------------------------
|
|
function msto_chk_quiet(
|
|
signal msto_vector : wb_mst_out_vector;
|
|
constant ScrnOut : boolean := false;
|
|
constant InstancePath: string := "msto_chk_quiet "
|
|
) return boolean is
|
|
variable L: Line;
|
|
begin
|
|
for i in 0 to NWBMST-1 loop
|
|
if msto_vector(i).cyc = '1' then
|
|
if ScrnOut then
|
|
write(L, Now, Right, 15);
|
|
write(L, " : " & InstancePath);
|
|
write(L, String'("E00: mst(" & integer'image(i) & ") should not send any request!!!"));
|
|
writeline(output, L);
|
|
end if;
|
|
return false;
|
|
end if;
|
|
end loop;
|
|
|
|
return true;
|
|
end function;
|
|
|
|
---------------------------------------------------------------
|
|
-- Function: core2wbmo_chk(wbadr, wbsz, wb_wrdat, msto, ACC)
|
|
-- This function checks control signals (stb, cyc, we) of core-to-wb conversion for single master(core)
|
|
-- Esp made for module "core2wb.vhd"
|
|
--
|
|
-- SIM_ACC handles same as WR_ACC
|
|
---------------------------------------------------------------
|
|
function core2wbmo_chk(
|
|
signal wbadr : std_logic_vector(31 downto 0);
|
|
signal wbsz : std_logic_vector(1 downto 0);
|
|
signal wbwrdat : std_logic_vector(31 downto 0);
|
|
signal msto : wb_mst_out_type;
|
|
constant we : access_type := NO_ACC;
|
|
constant ScrnOut : boolean := false;
|
|
constant InstancePath: string := "core2wbmo_chk "
|
|
) return boolean is
|
|
variable L: Line;
|
|
begin
|
|
if we = RD_ACC then -- read
|
|
if msto.stb = '1' and msto.cyc = '1' and msto.we = '0' and
|
|
msto.adr = wbadr(memory_width - 1 downto WB_ADR_BOUND) and
|
|
msto.sel = gen_select(wbadr(1 downto 0), wbsz)
|
|
then
|
|
return true;
|
|
else
|
|
if ScrnOut then
|
|
write(L, Now, Right, 15);
|
|
write(L, " : " & InstancePath);
|
|
write(L, String'("E00: Read req - "));
|
|
if not(msto.stb = '1' and msto.cyc = '1' and msto.we = '0') then
|
|
write(L, String'("(msto.stb, msto.cyc, msto.we) should be (1, 1, 0) "));
|
|
end if;
|
|
if (msto.adr /= wbadr(memory_width - 1 downto WB_ADR_BOUND)) then
|
|
write(L, String'("Mismatch addr: (msto.adr, wbadr) = (" &
|
|
hstr(msto.adr) & ", " &
|
|
hstr(wbadr(memory_width - 1 downto WB_ADR_BOUND)) & ") "));
|
|
end if;
|
|
if (msto.sel /= gen_select(wbadr(1 downto 0), wbsz)) then
|
|
write(L, String'("Mismatch sel: (msto.sel, wbadr(1:0)) = (" &
|
|
str(msto.sel) & ", " &
|
|
str(gen_select(wbadr(1 downto 0), wbsz)) & ")"));
|
|
end if;
|
|
writeline(output, L);
|
|
end if;
|
|
end if;
|
|
elsif we = WR_ACC or we = SIM_ACC then -- write/sim
|
|
if msto.stb = '1' and msto.cyc = '1' and msto.we = '1' and
|
|
msto.adr = wbadr(memory_width - 1 downto WB_ADR_BOUND) and
|
|
msto.sel = gen_select(wbadr(1 downto 0), wbsz) and
|
|
msto.dat = enc_wb_dat(wbadr(1 downto 0), wbsz, wbwrdat) -- optional since mainly check from sel signal
|
|
then
|
|
return true;
|
|
else
|
|
if ScrnOut then
|
|
write(L, Now, Right, 15);
|
|
write(L, " : " & InstancePath);
|
|
if we = WR_ACC then
|
|
write(L, String'("E01: Write req - "));
|
|
else
|
|
write(L, String'("E02: Simultaneous req - "));
|
|
end if;
|
|
if not(msto.stb = '1' and msto.cyc = '1' and msto.we = '1') then
|
|
write(L, String'("(msto.stb, msto.cyc, msto.we) should be (1, 1, 1) "));
|
|
end if;
|
|
if (msto.adr /= wbadr(memory_width - 1 downto WB_ADR_BOUND)) then
|
|
write(L, String'("Mismatch addr: (msto.adr, wbadr) = (" &
|
|
hstr(msto.adr) & ", " &
|
|
hstr(wbadr(memory_width - 1 downto WB_ADR_BOUND)) & ") "));
|
|
end if;
|
|
if (msto.sel /= gen_select(wbadr(1 downto 0), wbsz)) then
|
|
write(L, String'("Mismatch sel: (msto.sel, wbadr(1:0)) = (" &
|
|
str(msto.sel) & ", " &
|
|
str(gen_select(wbadr(1 downto 0), wbsz)) & ") "));
|
|
end if;
|
|
if (msto.dat /= enc_wb_dat(wbadr(1 downto 0), wbsz, wbwrdat)) then
|
|
write(L, String'("Mismatch data: (msto.dat, wb_wrdat) = (" &
|
|
hstr(msto.dat) & ", " &
|
|
hstr(enc_wb_dat(wbadr(1 downto 0), wbsz, wbwrdat)) & ")"));
|
|
end if;
|
|
writeline(output, L);
|
|
end if;
|
|
end if;
|
|
else
|
|
if msto.stb = '0' and msto.cyc = '0' and msto.we = '0' then
|
|
return true;
|
|
else
|
|
if ScrnOut then
|
|
write(L, Now, Right, 15);
|
|
write(L, " : " & InstancePath);
|
|
write(L, String'("E03: No request - (msto.stb, msto.cyc, msto.we) should be (0, 0, 0)"));
|
|
writeline(output, L);
|
|
end if;
|
|
end if;
|
|
end if;
|
|
|
|
return false;
|
|
end function;
|
|
|
|
|
|
---------------------------------------------------------------
|
|
-- Function: slvi_chk_all(slvo_vector, msto_vector, slvi_vector, mst_mask_vector, opt:instancepath, opt:scrnout)
|
|
--
|
|
-- slv_in check (out from wb_intercon)
|
|
-- This function checks if there is only selected slave from granted master gets the request signal (adr map) (cyc = 1)
|
|
-- Other slaves whose address is not mapped then should receive nothing (cyc = 0)
|
|
-- slv exist check by slvo(i).wbcfg(31 downto 24) must be x"FF" which will be called by wb_membar in order to reformat the mask addr of the slave
|
|
---------------------------------------------------------------
|
|
function slvi_chk_all(
|
|
signal slvo : wb_slv_out_vector; -- for address map check
|
|
signal msto : wb_mst_out_vector;
|
|
signal slvi : wb_slv_in_vector;
|
|
constant mst_mask_vector : std_logic_vector(0 to NWBMST-1) := b"0000";
|
|
constant ScrnOut : boolean := false;
|
|
constant InstancePath : string := "slvi_chk_all "
|
|
) return boolean is
|
|
variable madr, sadr : std_logic_vector(31 downto 0) := (others=>'0'); -- for display purpose only
|
|
variable gmst_idx : integer range 0 to NWBMST-1;
|
|
variable ssel_idx : integer range 0 to NWBSLV-1;
|
|
variable slv_found : boolean := false;
|
|
variable L : Line;
|
|
begin
|
|
|
|
if msto_chk_quiet(msto) = true then -- No request from all master, No need to continue check slvi
|
|
if slvi_chk_quiet(slvi) = false then
|
|
if ScrnOut then
|
|
write(L, Now, Right, 15);
|
|
write(L, " : " & InstancePath);
|
|
write(L, String'("E00: No request from any master"));
|
|
writeline(output, L);
|
|
end if;
|
|
return false;
|
|
end if;
|
|
else
|
|
gmst_idx := gmst_idx_fn(msto, mst_mask_vector);
|
|
madr := msto(gmst_idx).adr & "00";
|
|
|
|
-- compare, search for selected slave
|
|
for i in 0 to NWBSLV-1 loop
|
|
sadr := slvo(i).wbcfg(63 downto 34) & "00" ;
|
|
if ScrnOut then
|
|
write(L, Now, Right, 15);
|
|
write(L, " : " & InstancePath);
|
|
write(L, String'(
|
|
"[addr_cmp] slv(" & integer'image(i) &
|
|
") with its address: " & hstr(sadr) &
|
|
" mst(" & integer'image(gmst_idx) &
|
|
") with its address: " & hstr(madr)));
|
|
writeline(output, L);
|
|
end if;
|
|
if (slvadrmap(slvo(i).wbcfg, msto(gmst_idx).adr) = true) and slvo(i).wbcfg(31 downto 24) = x"FF" then
|
|
slv_found := true;
|
|
ssel_idx := i;
|
|
end if;
|
|
|
|
end loop;
|
|
-- end compare
|
|
|
|
if (slv_found = true) then
|
|
if (slvi(ssel_idx).cyc /= '1') then
|
|
if ScrnOut then
|
|
write(L, Now, Right, 15);
|
|
write(L, " : " & InstancePath);
|
|
write(L, String'("E01: No request from master(" & integer'image(gmst_idx) &
|
|
") for slv(" & integer'image(ssel_idx) & ")"));
|
|
writeline(output, L);
|
|
end if;
|
|
return false;
|
|
end if;
|
|
else
|
|
if (slvi(ssel_idx).cyc /= '0') then
|
|
if ScrnOut then
|
|
write(L, Now, Right, 15);
|
|
write(L, " : " & InstancePath);
|
|
write(L, String'("E02: request address " & hstr(madr) & " not map with any slave, there should be no request signal " &
|
|
"from the granted master (" & integer'image(gmst_idx) & ")"));
|
|
writeline(output, L);
|
|
end if;
|
|
return false;
|
|
end if;
|
|
end if;
|
|
|
|
end if;
|
|
|
|
return true;
|
|
end function;
|
|
|
|
---------------------------------------------------------------
|
|
-- Function: msti_chk_all(msti_vector, msto_vector, slvo_vector, mst_mask_vector)
|
|
--
|
|
-- Check msti
|
|
-- This function check if there is only granted master get the ack from selected slave (ack = 1)
|
|
-- Other master should not receive asserted ack signal from all slave (ack = 0)
|
|
-- slv exist check by slvo(i).wbcfg(31 downto 24) must be x"FF" which will be called by wb_membar in order to reformat the mask addr of the slave
|
|
---------------------------------------------------------------
|
|
function msti_chk_all (
|
|
signal msti : wb_mst_in_vector;
|
|
signal msto : wb_mst_out_vector;
|
|
signal slvo : wb_slv_out_vector; -- response from selected slave (if no addr map, no slave never been selected !!)
|
|
constant mst_mask_vector : std_logic_vector(0 to NWBMST-1) := b"0000";
|
|
constant ScrnOut : boolean := false;
|
|
constant InstancePath : string := "msti_chk_all "
|
|
) return boolean is
|
|
variable madr, sadr : std_logic_vector(31 downto 0) := (others=>'0'); -- for display purpose only
|
|
variable gmst_idx : integer range 0 to NWBMST-1;
|
|
variable ssel_idx : integer range 0 to NWBSLV-1;
|
|
variable slv_found : boolean := false;
|
|
variable L : Line;
|
|
begin
|
|
|
|
if (msto_chk_quiet(msto) = true) then -- No request from all master, No need to continue check slvi
|
|
if msti_chk_quiet(msti) = false then
|
|
if ScrnOut then
|
|
write(L, Now, Right, 15);
|
|
write(L, " : " & InstancePath);
|
|
write(L, String'("E00: No request from any master"));
|
|
writeline(output, L);
|
|
end if;
|
|
return false;
|
|
end if;
|
|
else
|
|
-- Get master index of granted master
|
|
gmst_idx := gmst_idx_fn(msto, mst_mask_vector);
|
|
madr := msto(gmst_idx).adr & "00";
|
|
|
|
-- compare, search for selected slave
|
|
for i in 0 to NWBSLV-1 loop
|
|
sadr := slvo(i).wbcfg(63 downto 34) & "00" ; -- for disp on report only
|
|
|
|
if ScrnOut then
|
|
write(L, Now, Right, 15);
|
|
write(L, " : " & InstancePath);
|
|
write(L, String'("[addr_cmp] slv(" & integer'image(i) &
|
|
") with its address: " & hstr(sadr) &
|
|
" mst(" & integer'image(gmst_idx) &
|
|
") with its address: " & hstr(madr)));
|
|
writeline(output, L);
|
|
end if;
|
|
|
|
if (slvadrmap(slvo(i).wbcfg, msto(gmst_idx).adr) = true) and slvo(i).wbcfg(31 downto 24) = x"FF" then
|
|
slv_found := true;
|
|
ssel_idx := i; -- ssel_idx wont update immediately need to be next iteration ??
|
|
end if;
|
|
end loop;
|
|
-- end compare
|
|
|
|
for i in 0 to NWBMST-1 loop
|
|
if (i = gmst_idx) then
|
|
-- handle for no grant like this case m3 = disable, cyc = 1 and m2 = enable, cyc = 0 -> no grant (correct) => no need to assert the error
|
|
-- for master that really request although it's inactive,
|
|
if msto(i).cyc = '1' then
|
|
if slv_found = true then
|
|
--if msti(i).ack /= '1' and slvo(ssel_idx).ack /= '1' and slv_found /= true then
|
|
if msti(i).ack /= '1' and slvo(ssel_idx).ack /= '1' then
|
|
if ScrnOut then
|
|
write(L, Now, Right, 15);
|
|
write(L, " : " & InstancePath);
|
|
write(L, String'("E01: no Ack to granted master(" & integer'image(i) & ") from slv (" & integer'image(ssel_idx) & ")"));
|
|
writeline(output, L);
|
|
end if;
|
|
return false;
|
|
end if;
|
|
else
|
|
if ScrnOut then
|
|
write(L, Now, Right, 15);
|
|
write(L, " : " & InstancePath);
|
|
write(L, String'("E02: request address " & hstr(madr) & " not map with any slave, there should be no request signal " &
|
|
"from the granted master (" & integer'image(gmst_idx) & ")"));
|
|
writeline(output, L);
|
|
end if;
|
|
return false;
|
|
end if;
|
|
end if;
|
|
else -- non grant master (ack must be 0)
|
|
if msti(i).ack /= '0' then
|
|
if ScrnOut then
|
|
write(L, Now, Right, 15);
|
|
write(L, " : " & InstancePath);
|
|
write(L, String'("E03: mst(" & integer'image(i) & ") should not have any response from any slv !!!"));
|
|
writeline(output, L);
|
|
end if;
|
|
return false;
|
|
end if;
|
|
end if;
|
|
end loop;
|
|
end if;
|
|
return true;
|
|
end function;
|
|
|
|
---------------------------------------------------------------
|
|
-- Function: wbmi2core_chk(wb2core, we, mo_sel, mo_dat, mi_ack, resp_rddat)
|
|
--
|
|
-- This function checks response signal conversion from memory(wb_msti) to core(in_dmem_core)
|
|
-- esp made for core2wb.vhd testing
|
|
-- *** For SIM_ACC, the function has not supported so far. It MUST be manually put either RD_ACC or WR_ACC
|
|
-- 1st ack of SIM_ACC, fn should verify as write (ack)
|
|
-- 2nd ack of SIM_ACC, fn should verify as read (ack, rd_dat)
|
|
---------------------------------------------------------------
|
|
function wbmi2core_chk(
|
|
signal wb2core : dmem_core;
|
|
constant we : access_type := NO_ACC;
|
|
signal mo_sel : std_logic_vector(WB_SEL_WIDTH-1 downto 0);
|
|
signal mi_ack : std_logic;
|
|
signal resp_rddat : std_logic_vector(memory_width - 1 downto 0);
|
|
constant ScrnOut : boolean := false;
|
|
constant InstancePath: string := "wbmi2core_chk "
|
|
) return boolean is
|
|
variable L: Line;
|
|
begin
|
|
if we = RD_ACC then -- read
|
|
if wb2core.ready = mi_ack and
|
|
wb2core.read_data = dec_wb_dat(mo_sel, resp_rddat) -- optional since mainly check from sel signal
|
|
then
|
|
return true;
|
|
else
|
|
if ScrnOut then
|
|
write(L, Now, Right, 15);
|
|
write(L, " : " & InstancePath);
|
|
if we = RD_ACC then
|
|
write(L, String'("E00: Read req - "));
|
|
else
|
|
write(L, String'("E00: Sim req (read) - "));
|
|
end if;
|
|
if wb2core.ready = mi_ack then
|
|
write(L, String'("Mismacth read data: msti.dat = " & hstr(wb2core.read_data) & ", resp_rddat = " & hstr(dec_wb_dat(mo_sel, resp_rddat))));
|
|
end if;
|
|
if wb2core.read_data /= dec_wb_dat(mo_sel, resp_rddat) then
|
|
write(L, String'(" Incorrect ack. ready = " & str(wb2core.ready) & ", msti.ack = "& str(mi_ack)));
|
|
end if;
|
|
writeline(output, L);
|
|
end if;
|
|
end if;
|
|
elsif we = WR_ACC then -- write
|
|
if wb2core.ready = mi_ack then
|
|
return true;
|
|
else
|
|
if ScrnOut then
|
|
write(L, Now, Right, 15);
|
|
write(L, " : " & InstancePath);
|
|
write(L, String'("E01: Write req - Incorrect ack. (ready = " & str(wb2core.ready) & ", msti.ack = "& str(mi_ack)));
|
|
writeline(output, L);
|
|
end if;
|
|
end if;
|
|
elsif we = SIM_ACC then -- check only SIMACC_WR and for SIMACC_RD, use same as RD_ACC
|
|
if wb2core.ready = '0' and mi_ack = '1' then
|
|
return true;
|
|
else
|
|
if ScrnOut then
|
|
write(L, Now, Right, 15);
|
|
write(L, " : " & InstancePath);
|
|
write(L, String'("E02: Write req - Incorrect ack. (in_dmem.ready, msti.ack) should be = (0, 1) since the request is not complete yet"));
|
|
writeline(output, L);
|
|
end if;
|
|
end if;
|
|
else -- we = NO_ACC
|
|
if wb2core.ready = '1' then
|
|
return true;
|
|
else
|
|
if ScrnOut then
|
|
write(L, Now, Right, 15);
|
|
write(L, " : " & InstancePath);
|
|
write(L, String'("E03: No request - wb2core.ready should always assert"));
|
|
writeline(output, L);
|
|
end if;
|
|
end if;
|
|
end if;
|
|
|
|
return false;
|
|
end function;
|
|
---------------------------------------------------------------
|
|
-- Function: wb2mem_chk(wb2mem, slvi, we)
|
|
--
|
|
-- This function checks control signals (stb, cyc, we) of wb-to-mem conversion for single slave(memory)
|
|
-- Esp made for mem2wb.vhd testing
|
|
---------------------------------------------------------------
|
|
function wb2mem_chk(
|
|
signal wb2mem : core_dmem;
|
|
signal slvi : wb_slv_in_type;
|
|
constant we : access_type := NO_ACC;
|
|
constant ScrnOut : boolean := false;
|
|
constant InstancePath: string := "wb2mem_chk "
|
|
) return boolean is
|
|
variable L: Line;
|
|
begin
|
|
if we = RD_ACC then -- read
|
|
if wb2mem.read_en = '1' and
|
|
wb2mem.read_addr(WB_ADR_WIDTH-1 downto WB_ADR_BOUND) = slvi.adr and
|
|
wbszconv_chk(wb2mem.read_size) and
|
|
wb2mem.write_en = '0' then
|
|
return true;
|
|
else
|
|
if ScrnOut then
|
|
write(L, Now, Right, 15);
|
|
write(L, " : " & InstancePath);
|
|
write(L, String'( "E00: Read req - wrong conversion from WB to MEMORY. wb_adr = " &
|
|
hstr(wb2mem.read_addr) &
|
|
" ,slvi.adr = " &
|
|
hstr(slvi.adr) &
|
|
" ,wb.read_en = "
|
|
));
|
|
writeline(output, L);
|
|
end if;
|
|
end if;
|
|
elsif we = WR_ACC then -- write
|
|
if wb2mem.write_en = '1' and
|
|
wb2mem.write_addr(WB_ADR_WIDTH-1 downto WB_ADR_BOUND) = slvi.adr and
|
|
wbszconv_chk(wb2mem.write_size) and
|
|
wb2mem.write_data = dec_wb_dat(slvi.sel, slvi.dat) and
|
|
wb2mem.read_en = '0' then
|
|
return true;
|
|
else
|
|
if ScrnOut then
|
|
write(L, Now, Right, 15);
|
|
write(L, " : " & InstancePath);
|
|
write(L, String'("E01: Write req - "));
|
|
if wb2mem.write_en /= '1' then
|
|
write(L, String'("Write_en should be active, "));
|
|
end if;
|
|
|
|
writeline(output, L);
|
|
end if;
|
|
end if;
|
|
elsif we = NO_ACC then
|
|
if wb2mem.read_en = '0' and
|
|
wb2mem.write_en = '0' then
|
|
return true;
|
|
else
|
|
if ScrnOut then
|
|
write(L, Now, Right, 15);
|
|
write(L, " : " & InstancePath);
|
|
write(L, String'("E02: No request"));
|
|
writeline(output, L);
|
|
end if;
|
|
end if;
|
|
else
|
|
if wb2mem.read_en = '1' and
|
|
wb2mem.write_en = '1' then
|
|
return true;
|
|
else
|
|
if ScrnOut then
|
|
write(L, Now, Right, 15);
|
|
write(L, " : " & InstancePath);
|
|
write(L, String'("E03: Sim request"));
|
|
writeline(output, L);
|
|
end if;
|
|
end if;
|
|
end if;
|
|
|
|
return false;
|
|
end function;
|
|
|
|
---------------------------------------------------------------
|
|
-- Function: gmst_idx = gmst_idx_fn(msto, mst_mask_vector, grant)
|
|
--
|
|
-- return: index of master that get the grant (highest priority/index number)
|
|
-- this index get the highest priority w/o checking active status (mst_mask_vector) ???
|
|
---------------------------------------------------------------
|
|
function gmst_idx_fn (
|
|
signal msto : wb_mst_out_vector;
|
|
constant mst_mask_vector : std_logic_vector(0 to NWBMST-1) := b"0000";
|
|
constant ScrnOut : boolean := false;
|
|
constant InstancePath : string := "gmst_idx_fn "
|
|
) return integer is
|
|
variable gnt_idx :integer range 0 to NWBMST-1;
|
|
variable L : Line;
|
|
begin
|
|
|
|
for i in 0 to NWBMST-1 loop
|
|
if(msto(i).cyc='1' and mst_mask_vector(i) = '1' )then
|
|
gnt_idx := i;
|
|
end if;
|
|
end loop;
|
|
|
|
if ScrnOut then
|
|
write(L, Now, Right, 15);
|
|
write(L, " : " & InstancePath);
|
|
write(L, String'("master grant idx: "& integer'image(gnt_idx)));
|
|
writeline(output, L);
|
|
end if;
|
|
|
|
return gnt_idx;
|
|
end function;
|
|
|
|
---------------------------------------------------------------
|
|
-- Function: wbszconv_chk = wbszconv_chk(size)
|
|
--
|
|
-- return:
|
|
--
|
|
-- remark: Internal use in wb_tp itself
|
|
---------------------------------------------------------------
|
|
function wbszconv_chk(
|
|
signal size : in std_logic_vector(1 downto 0);
|
|
constant ScrnOut : boolean := false;
|
|
constant InstancePath: string := "wbszconv_chk"
|
|
) return boolean is
|
|
variable L: Line;
|
|
begin
|
|
case WB_PORT_GRAN is
|
|
when 8 =>
|
|
if size = "00" then return true; end if;
|
|
when 16 =>
|
|
if size = "01" then return true; end if;
|
|
when 32 =>
|
|
if size = "10" then return true; end if;
|
|
when 64 =>
|
|
if size = "11" then return true; end if;
|
|
end case;
|
|
|
|
if ScrnOut then
|
|
write(L, Now, Right, 15);
|
|
write(L, " : " & InstancePath);
|
|
write(L, String'("E00: wb port gran doesn't match with port gran of core or memory"));
|
|
writeline(output, L);
|
|
end if;
|
|
|
|
return false;
|
|
end function;
|
|
---------------------------------------------------------------
|
|
-- Function: corewb_conv_chk(core2wb_in, msto)
|
|
--
|
|
---------------------------------------------------------------
|
|
-- function corewb_conv_chk(
|
|
-- core2wb_in : core_dmem;
|
|
-- msto : wb_mst_out_type;
|
|
-- constant InstancePath : string := "corewb_conv_chk";
|
|
-- constant ScrnOut : boolean := false
|
|
-- ) return boolean is
|
|
-- variable result : boolean := false;
|
|
-- variable L : Line;
|
|
-- begin
|
|
--
|
|
-- --check enable
|
|
--
|
|
--
|
|
-- write_data : std_logic_vector(memory_width - 1 downto 0);
|
|
-- write_addr : std_logic_vector(memory_width - 1 downto 0);
|
|
-- write_size : std_logic_vector(1 downto 0);
|
|
-- write_en : std_logic;
|
|
--
|
|
--
|
|
-- read_addr : std_logic_vector(memory_width - 1 downto 0);
|
|
-- read_size : std_logic_vector(1 downto 0);
|
|
-- read_en : std_logic;
|
|
--
|
|
-- if ScrnOut then
|
|
-- write(L, Now, Right, 15);
|
|
-- write(L, " : " & InstancePath);
|
|
-- write(L, String'(" xxxxx"));
|
|
-- writeline(output, L);
|
|
-- end if;
|
|
-- return false;
|
|
-- end if;
|
|
--
|
|
--
|
|
-- return result;
|
|
-- end function;
|
|
--
|
|
|
|
---------------------------------------------------------------
|
|
-- Procedure: gencore2mem_req(req_acc, rd_adr, rd_sz, wr_adr, wr_sz, wr_dat)
|
|
-- gencore2mem_req(XX_ACC, x"AAAAAAAA", "00", x"AAAAAAAA", "00", x"DDDDDDDD")
|
|
--
|
|
---------------------------------------------------------------
|
|
procedure gencore2mem_req (
|
|
signal core2dmem :out core_dmem;
|
|
--
|
|
constant req_acc :in access_type := NO_ACC;
|
|
constant rd_adr :in std_logic_vector(memory_width - 1 downto 0) := (others=>'0');
|
|
constant rd_sz :in std_logic_vector(1 downto 0) := "00";
|
|
--
|
|
constant wr_adr :in std_logic_vector(memory_width - 1 downto 0):= (others=>'0');
|
|
constant wr_sz :in std_logic_vector(1 downto 0):= "00";
|
|
constant wr_dat :in std_logic_vector(memory_width - 1 downto 0):= (others=>'-');
|
|
--
|
|
constant ScrnOut :in boolean := false;
|
|
constant InstancePath :in string := "gencore2mem_req "
|
|
) is
|
|
variable L: Line;
|
|
begin
|
|
|
|
if ScrnOut then
|
|
write(L, Now, Right, 15);
|
|
write(L, " : " & InstancePath);
|
|
case(req_acc) is
|
|
when RD_ACC =>
|
|
write(L, String'("RD request: adr: " & hstr(rd_adr)));
|
|
when WR_ACC =>
|
|
write(L, String'("WR request: adr: " & hstr(wr_adr) & " WR data: " & hstr(wr_dat)));
|
|
when SIM_ACC =>
|
|
write(L, String'("SIM, RD request: adr: " & hstr(rd_adr)));
|
|
write(L, String'("SIM, WR request: adr: " & hstr(wr_adr) & " WR data: " & hstr(wr_dat)));
|
|
when others =>
|
|
write(L, String'("NO request"));
|
|
end case;
|
|
writeline(output, L);
|
|
end if;
|
|
|
|
case(req_acc) is
|
|
when RD_ACC =>
|
|
core2dmem.read_en <= '1'; core2dmem.write_en <= '0';
|
|
when WR_ACC =>
|
|
core2dmem.read_en <= '0'; core2dmem.write_en <= '1';
|
|
when SIM_ACC =>
|
|
core2dmem.read_en <= '1'; core2dmem.write_en <= '1';
|
|
when others =>
|
|
core2dmem.read_en <= '0'; core2dmem.write_en <= '0';
|
|
end case;
|
|
|
|
-- leave data and adr as it is, although enable = 0
|
|
core2dmem.read_addr <= rd_adr;
|
|
core2dmem.read_size <= rd_sz;
|
|
--
|
|
core2dmem.write_addr <= wr_adr;
|
|
core2dmem.write_size <= wr_sz;
|
|
core2dmem.write_data <= wr_dat;
|
|
|
|
end gencore2mem_req;
|
|
|
|
---------------------------------------------------------------
|
|
-- Procedure: genwb2core(msti, req_acc, rd_sz, wb_sel, read_data, ready)
|
|
--
|
|
-- similar to function 'dec_wb_dat' in wishbone.vhd
|
|
---------------------------------------------------------------
|
|
procedure genwb2core (
|
|
signal msti :out wb_mst_in_type;
|
|
--
|
|
constant req_acc :in access_type := NO_ACC;
|
|
constant rd_sz :in std_logic_vector(1 downto 0) := "00";
|
|
constant wb_sel :in std_logic_vector(WB_SEL_WIDTH-1 downto 0);
|
|
--
|
|
constant read_data :in std_logic_vector(memory_width - 1 downto 0);
|
|
constant ready :in std_logic := '0';
|
|
constant ScrnOut :in boolean := false;
|
|
constant InstancePath :in string := "genwb2core"
|
|
) is
|
|
variable L :Line;
|
|
variable mi :wb_mst_in_type;
|
|
begin
|
|
mi.ack := ready;
|
|
--gen data based on sel and size
|
|
mi.dat := (others=>'0');
|
|
if req_acc = RD_ACC then
|
|
--read
|
|
case (rd_sz) is
|
|
when "00" =>
|
|
mi.dat( 7 downto 0) := read_data( 7 downto 0);
|
|
if wb_sel = "0001" then mi.dat( 7 downto 0) := read_data( 7 downto 0);
|
|
elsif wb_sel = "0010" then mi.dat(15 downto 8) := read_data(15 downto 8);
|
|
elsif wb_sel = "0100" then mi.dat(23 downto 16) := read_data(23 downto 16);
|
|
elsif wb_sel = "1000" then mi.dat(31 downto 24) := read_data(31 downto 24);
|
|
else mi.dat := (others=>'0');
|
|
end if;
|
|
when "01" =>
|
|
if wb_sel = "0001" then mi.dat(15 downto 0) := read_data(15 downto 0);
|
|
elsif wb_sel = "0010" then mi.dat(31 downto 16) := read_data(31 downto 16);
|
|
elsif wb_sel = "0011" then mi.dat(23 downto 8) := read_data(23 downto 8);
|
|
else mi.dat := (others=>'0');
|
|
end if;
|
|
when "10" =>
|
|
mi.dat := read_data;
|
|
when others =>
|
|
mi.dat := (others=>'0');
|
|
end case;
|
|
|
|
if ScrnOut then
|
|
write(L, Now, Right, 15);
|
|
write(L, " : " & InstancePath);
|
|
write(L, String'("RD resp: RD data: " &
|
|
hstr(mi.dat) & ", sel: " &
|
|
str(wb_sel) & ", rd_sz: " &
|
|
str(rd_sz) & ", ack = " &
|
|
str(mi.ack)));
|
|
writeline(output, L);
|
|
end if;
|
|
|
|
else
|
|
mi.dat := (others=>'0');
|
|
if ScrnOut then
|
|
write(L, Now, Right, 15);
|
|
write(L, " : " & InstancePath);
|
|
write(L, String'("WR resp: ack = " & str(mi.ack)));
|
|
writeline(output, L);
|
|
end if;
|
|
|
|
end if;
|
|
|
|
msti <= mi;
|
|
|
|
|
|
end genwb2core;
|
|
---------------------------------------------------------------
|
|
-- Procedure: genmst_req(msto(req_mst_idx),req_mst_idx, we, adr, dat, sel)
|
|
--
|
|
-- Master read/Write req function for wb_intercon_tb
|
|
-- CAUTION: input slave address as 32 bits instaed of 30 bits to be readable
|
|
---------------------------------------------------------------
|
|
procedure genmst_req (
|
|
signal mst_out :out wb_mst_out_type;
|
|
constant req_idx :in integer := 0;
|
|
constant we :in std_logic;
|
|
constant adr :in std_logic_vector(WB_ADR_WIDTH-1 downto 0);
|
|
constant dat :in std_logic_vector(WB_PORT_SIZE-1 downto 0);
|
|
constant sel :in std_logic_vector(WB_SEL_WIDTH-1 downto 0);
|
|
constant ScrnOut :in boolean := false;
|
|
constant InstancePath :in string := "genmst_req "
|
|
) is
|
|
variable L: Line;
|
|
begin
|
|
if ScrnOut then
|
|
write(L, Now, Right, 15);
|
|
write(L, " : " & InstancePath);
|
|
write(L, String'("Master(" & integer'image(req_idx) &") Request address: " & hstr(adr)));
|
|
writeline(output, L);
|
|
end if;
|
|
|
|
mst_out <= wbm_out_none; -- initial
|
|
mst_out.adr <= adr(31 downto 2);
|
|
mst_out.sel <= sel;
|
|
mst_out.stb <= '1';
|
|
mst_out.cyc <= '1';
|
|
-- mst_out.wbidx <= req_idx;
|
|
|
|
if we = '0' then -- read
|
|
mst_out.we <= '0';
|
|
mst_out.dat <= (others=>'-');
|
|
else -- write
|
|
mst_out.we <= '1';
|
|
mst_out.dat <= dat;
|
|
end if;
|
|
end genmst_req;
|
|
|
|
---------------------------------------------------------------
|
|
-- Procedure: list_all_mst_req(msto_vector, mst_mask_vector);
|
|
--
|
|
-- Utility procedure to list all master request(s)
|
|
---------------------------------------------------------------
|
|
procedure list_all_mst_req (
|
|
signal msto : in wb_mst_out_vector;
|
|
constant mst_mask_vector : std_logic_vector(0 to NWBMST-1) := b"0000";
|
|
constant ScrnOut : boolean := false;
|
|
constant InstancePath : string := "list_all_mst_req "
|
|
) is
|
|
variable mstat :integer range 0 to 1 := 0; -- for disp purpose
|
|
variable madr : std_logic_vector(31 downto 0) := (others=> '0');
|
|
variable noreq: boolean := true;
|
|
variable L : Line;
|
|
begin
|
|
|
|
for i in 0 to NWBMST-1 loop
|
|
if msto(i).cyc = '1' then
|
|
if mst_mask_vector(i) = '0' then
|
|
mstat := 0;
|
|
else
|
|
mstat := 1;
|
|
end if;
|
|
madr := msto(i).adr & "00";
|
|
if ScrnOut then
|
|
write(L, Now, Right, 15);
|
|
write(L, " : " & InstancePath);
|
|
write(L, String'("Request mst(" & integer'image(i) & "), addr: " & hstr(madr) & " with status: " & integer'image(mstat)));
|
|
writeline(output, L);
|
|
end if;
|
|
noreq := false;
|
|
end if;
|
|
end loop;
|
|
|
|
if noreq and ScrnOut then
|
|
write(L, Now, Right, 15);
|
|
write(L, " : " & InstancePath);
|
|
write(L, String'("No request"));
|
|
writeline(output, L);
|
|
end if;
|
|
|
|
end list_all_mst_req;
|
|
|
|
procedure generate_sync_wb_single_write(
|
|
signal msto : out wb_mst_out_type;
|
|
signal slvo : in wb_slv_out_type;
|
|
signal clk : in std_logic;
|
|
signal writedata : std_logic_vector(WB_PORT_SIZE-1 downto 0);
|
|
constant size : std_logic_vector(WB_ADR_BOUND-1 downto 0) := "10";
|
|
constant adr_offset : integer := 0 -- Offset added to the access address
|
|
) is
|
|
variable adr : std_logic_vector(31 downto 0);
|
|
variable sel : std_logic_vector(WB_SEL_WIDTH downto 0);
|
|
begin
|
|
adr := slvo.wbcfg(63 downto 32);
|
|
adr := std_logic_vector(unsigned(adr) + adr_offset);
|
|
|
|
--continue if rising edge active, else wait for it
|
|
--allows subsequent procedure calls without waiting for next edge
|
|
if not rising_edge(clk) then
|
|
wait until rising_edge(clk);
|
|
end if;
|
|
|
|
msto <= wbm_out_none;
|
|
msto.cyc <= '1';
|
|
msto.stb <= '1';
|
|
msto.we <= '1';
|
|
msto.sel <= gen_select(adr(1 downto 0),size);
|
|
msto.adr <= adr(31 downto 2);
|
|
msto.dat <= enc_wb_dat(adr(1 downto 0),size,writedata);
|
|
|
|
wait until rising_edge(clk);
|
|
wait until slvo.ack = '1' for 100 ns;
|
|
assert slvo.ack = '1' report "Slave did not ACK the write properly within 10 wait states";
|
|
|
|
wait until rising_edge(clk);
|
|
|
|
msto.cyc <= '0';
|
|
msto.stb <= '0';
|
|
msto.we <= '-';
|
|
msto.sel <= (others=>'-');
|
|
msto.dat <= (others=>'-');
|
|
msto.adr <= (others=>'-');
|
|
end procedure;
|
|
|
|
procedure generate_sync_wb_burst_write(
|
|
signal msto : out wb_mst_out_type;
|
|
signal slvo : in wb_slv_out_type;
|
|
signal clk : in std_logic;
|
|
signal writedata : std_logic_vector(WB_PORT_SIZE-1 downto 0);
|
|
constant NUMBURSTS : positive := 4;
|
|
constant SIZE : std_logic_vector(WB_ADR_BOUND-1 downto 0) := "10";
|
|
constant ADR_OFFSET : integer := 0 -- Offset added to the access address
|
|
) is
|
|
variable adr : std_logic_vector(31 downto 0);
|
|
variable sel : std_logic_vector(WB_SEL_WIDTH downto 0);
|
|
variable i : integer := 1;
|
|
begin
|
|
adr := slvo.wbcfg(63 downto 32);
|
|
adr := std_logic_vector(unsigned(adr) + ADR_OFFSET);
|
|
|
|
--continue if rising edge active, else wait for it
|
|
--allows subsequent procedure calls without waiting for next edge
|
|
if not rising_edge(clk) then
|
|
wait until rising_edge(clk);
|
|
end if;
|
|
|
|
msto <= wbm_out_none;
|
|
msto.cyc <= '1';
|
|
msto.stb <= '1';
|
|
msto.we <= '1';
|
|
msto.sel <= gen_select(adr(1 downto 0),SIZE);
|
|
msto.adr <= adr(31 downto 2);
|
|
msto.dat <= enc_wb_dat(adr(1 downto 0),SIZE,writedata);
|
|
msto.cti <= "010";
|
|
|
|
while i /= NUMBURSTS loop
|
|
wait until rising_edge(clk);
|
|
wait until slvo.ack = '1' for 1 ps;
|
|
adr := std_logic_vector(unsigned(adr) + 4);
|
|
msto.adr <= adr(31 downto 2);
|
|
msto.dat <= enc_wb_dat(adr(1 downto 0),SIZE,std_logic_vector(unsigned(writedata)+i));
|
|
i := i+1;
|
|
end loop;
|
|
|
|
msto.cti <= "111";
|
|
wait until rising_edge(clk);
|
|
msto.stb <= '0';
|
|
msto.cti <= (others => '-');
|
|
msto.dat <= (others => '-');
|
|
msto.sel <= (others => '-');
|
|
wait until rising_edge(clk);
|
|
if slvo.ack = '1' then
|
|
msto <= wbm_out_none;
|
|
end if;
|
|
|
|
end procedure;
|
|
|
|
procedure generate_sync_wb_single_read(
|
|
signal msto : out wb_mst_out_type; -- Slave input
|
|
signal slvo : in wb_slv_out_type; -- Slave output
|
|
signal clk : in std_logic;
|
|
signal readdata : out std_logic_vector(WB_PORT_SIZE -1 downto 0);
|
|
constant adr_offset : integer := 0; -- Offset added to the access address
|
|
constant size : std_logic_vector(WB_ADR_BOUND-1 downto 0) := "10"
|
|
) is
|
|
variable sel : std_logic_vector(WB_SEL_WIDTH-1 downto 0);
|
|
variable adr : std_logic_vector(31 downto 0);
|
|
begin
|
|
adr := slvo.wbcfg(63 downto 32);
|
|
adr := std_logic_vector(unsigned(adr) + adr_offset);
|
|
sel := gen_select(adr(1 downto 0),size);
|
|
|
|
--allow subsequent reads
|
|
if not rising_edge(clk) then
|
|
wait until rising_edge(clk);
|
|
end if;
|
|
|
|
msto <= wbm_out_none;
|
|
msto.cyc <= '1';
|
|
msto.stb <= '1';
|
|
msto.we <= '0';
|
|
msto.sel <= sel;
|
|
msto.adr <= adr;
|
|
|
|
wait until rising_edge(clk);
|
|
wait until slvo.ack='1' for 100 ns;
|
|
assert slvo.ack='1' report "Slave did not ACK the read properly within 10 wait states";
|
|
if slvo.ack='1' then
|
|
readdata <= dec_wb_dat(sel,slvo.dat);
|
|
else
|
|
readdata <= (others=>'X');
|
|
end if;
|
|
wait until rising_edge(clk);
|
|
msto.cyc <= '0';
|
|
msto.stb <= '0';
|
|
msto.we <= '-';
|
|
msto.sel <= (others=>'-');
|
|
msto.dat <= (others=>'-');
|
|
msto.adr <= (others=>'-');
|
|
end procedure;
|
|
|
|
procedure generate_sync_wb_burst_read(
|
|
signal msto : out wb_mst_out_type; -- Slave input
|
|
signal slvo : in wb_slv_out_type; -- Slave output
|
|
signal clk : in std_logic;
|
|
signal readdata : out std_logic_vector(WB_PORT_SIZE -1 downto 0);
|
|
constant NUMBURSTS : positive := 4;
|
|
constant ADR_OFFSET : integer := 0; -- Offset added to the access address
|
|
constant SIZE : std_logic_vector(WB_ADR_BOUND-1 downto 0) := "10"
|
|
) is
|
|
variable sel : std_logic_vector(WB_SEL_WIDTH-1 downto 0);
|
|
variable adr : std_logic_vector(31 downto 0);
|
|
variable i : integer := 1;
|
|
begin
|
|
adr := slvo.wbcfg(63 downto 32);
|
|
adr := std_logic_vector(unsigned(adr) + ADR_OFFSET);
|
|
sel := gen_select(adr(1 downto 0),SIZE);
|
|
|
|
--allow subsequent reads
|
|
if not rising_edge(clk) then
|
|
wait until rising_edge(clk);
|
|
end if;
|
|
|
|
msto <= wbm_out_none;
|
|
msto.cyc <= '1';
|
|
msto.stb <= '1';
|
|
msto.we <= '0';
|
|
msto.sel <= sel;
|
|
msto.adr <= adr;
|
|
msto.cti <= "010";
|
|
|
|
while i /= NUMBURSTS loop
|
|
wait until rising_edge(clk);
|
|
adr := std_logic_vector(unsigned(adr) + 4);
|
|
msto.adr <= adr(31 downto 2);
|
|
readdata <= dec_wb_dat(sel,slvo.dat);
|
|
i := i+1;
|
|
end loop;
|
|
|
|
msto.cti <= "111";
|
|
wait until rising_edge(clk);
|
|
msto.stb <= '0';
|
|
msto.cti <= (others => '-');
|
|
msto.dat <= (others => '-');
|
|
msto.sel <= (others => '-');
|
|
if slvo.ack = '1' then
|
|
readdata <= dec_wb_dat(sel,slvo.dat);
|
|
end if;
|
|
wait until rising_edge(clk);
|
|
msto <= wbm_out_none;
|
|
end procedure;
|
|
|
|
end wb_tp;
|