2 use ieee.std_logic_1164.all;
5 use work.wishbone_types.all;
7 -- TODO: Use an array of master/slaves with parametric size
8 entity wishbone_arbiter is
10 NUM_MASTERS : positive := 3
12 port (clk : in std_ulogic;
15 wb_masters_in : in wishbone_master_out_vector(0 to NUM_MASTERS-1);
16 wb_masters_out : out wishbone_slave_out_vector(0 to NUM_MASTERS-1);
18 wb_slave_out : out wishbone_master_out;
19 wb_slave_in : in wishbone_slave_out
23 architecture behave of wishbone_arbiter is
24 subtype wb_arb_master_t is integer range 0 to NUM_MASTERS-1;
25 signal candidate, selected : wb_arb_master_t;
26 signal busy : std_ulogic;
29 busy <= wb_masters_in(selected).cyc;
31 wishbone_muxes: process(selected, candidate, busy, wb_slave_in, wb_masters_in)
32 variable early_sel : wb_arb_master_t;
34 early_sel := selected;
36 early_sel := candidate;
38 wb_slave_out <= wb_masters_in(early_sel);
39 for i in 0 to NUM_MASTERS-1 loop
40 wb_masters_out(i).dat <= wb_slave_in.dat;
41 wb_masters_out(i).ack <= wb_slave_in.ack when early_sel = i else '0';
42 wb_masters_out(i).stall <= wb_slave_in.stall when early_sel = i else '1';
46 -- Candidate selection is dumb, priority order... we could
47 -- instead consider some form of fairness but it's not really
48 -- an issue at the moment.
50 wishbone_candidate: process(all)
52 candidate <= selected;
53 for i in NUM_MASTERS-1 downto 0 loop
54 if wb_masters_in(i).cyc = '1' then
60 wishbone_arbiter_process: process(clk)
62 if rising_edge(clk) then
66 selected <= candidate;