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.
70 lines
1.9 KiB
70 lines
1.9 KiB
library ieee; |
|
use ieee.std_logic_1164.all; |
|
|
|
library work; |
|
use work.wishbone_types.all; |
|
|
|
-- TODO: Use an array of master/slaves with parametric size |
|
entity wishbone_arbiter is |
|
generic( |
|
NUM_MASTERS : positive := 3 |
|
); |
|
port (clk : in std_ulogic; |
|
rst : in std_ulogic; |
|
|
|
wb_masters_in : in wishbone_master_out_vector(0 to NUM_MASTERS-1); |
|
wb_masters_out : out wishbone_slave_out_vector(0 to NUM_MASTERS-1); |
|
|
|
wb_slave_out : out wishbone_master_out; |
|
wb_slave_in : in wishbone_slave_out |
|
); |
|
end wishbone_arbiter; |
|
|
|
architecture behave of wishbone_arbiter is |
|
subtype wb_arb_master_t is integer range 0 to NUM_MASTERS-1; |
|
signal candidate, selected : wb_arb_master_t; |
|
signal busy : std_ulogic; |
|
begin |
|
|
|
busy <= wb_masters_in(selected).cyc; |
|
|
|
wishbone_muxes: process(selected, candidate, busy, wb_slave_in, wb_masters_in) |
|
variable early_sel : wb_arb_master_t; |
|
begin |
|
early_sel := selected; |
|
if busy = '0' then |
|
early_sel := candidate; |
|
end if; |
|
wb_slave_out <= wb_masters_in(early_sel); |
|
for i in 0 to NUM_MASTERS-1 loop |
|
wb_masters_out(i).dat <= wb_slave_in.dat; |
|
wb_masters_out(i).ack <= wb_slave_in.ack when early_sel = i else '0'; |
|
wb_masters_out(i).stall <= wb_slave_in.stall when early_sel = i else '1'; |
|
end loop; |
|
end process; |
|
|
|
-- Candidate selection is dumb, priority order... we could |
|
-- instead consider some form of fairness but it's not really |
|
-- an issue at the moment. |
|
-- |
|
wishbone_candidate: process(all) |
|
begin |
|
candidate <= selected; |
|
for i in NUM_MASTERS-1 downto 0 loop |
|
if wb_masters_in(i).cyc = '1' then |
|
candidate <= i; |
|
end if; |
|
end loop; |
|
end process; |
|
|
|
wishbone_arbiter_process: process(clk) |
|
begin |
|
if rising_edge(clk) then |
|
if rst = '1' then |
|
selected <= 0; |
|
elsif busy = '0' then |
|
selected <= candidate; |
|
end if; |
|
end if; |
|
end process; |
|
end behave;
|
|
|