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