wishbone_arbiter.vhdl 1.9 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071
  1. library ieee;
  2. use ieee.std_logic_1164.all;
  3. library work;
  4. use work.wishbone_types.all;
  5. -- TODO: Use an array of master/slaves with parametric size
  6. entity wishbone_arbiter is
  7. generic(
  8. NUM_MASTERS : positive := 3
  9. );
  10. port (clk : in std_ulogic;
  11. rst : in std_ulogic;
  12. wb_masters_in : in wishbone_master_out_vector(0 to NUM_MASTERS-1);
  13. wb_masters_out : out wishbone_slave_out_vector(0 to NUM_MASTERS-1);
  14. wb_slave_out : out wishbone_master_out;
  15. wb_slave_in : in wishbone_slave_out
  16. );
  17. end wishbone_arbiter;
  18. architecture behave of wishbone_arbiter is
  19. subtype wb_arb_master_t is integer range 0 to NUM_MASTERS-1;
  20. signal candidate, selected : wb_arb_master_t;
  21. signal busy : std_ulogic;
  22. begin
  23. busy <= wb_masters_in(selected).cyc;
  24. wishbone_muxes: process(selected, candidate, busy, wb_slave_in, wb_masters_in)
  25. variable early_sel : wb_arb_master_t;
  26. begin
  27. early_sel := selected;
  28. if busy = '0' then
  29. early_sel := candidate;
  30. end if;
  31. wb_slave_out <= wb_masters_in(early_sel);
  32. for i in 0 to NUM_MASTERS-1 loop
  33. wb_masters_out(i).dat <= wb_slave_in.dat;
  34. wb_masters_out(i).ack <= wb_slave_in.ack when early_sel = i else '0';
  35. wb_masters_out(i).stall <= wb_slave_in.stall when early_sel = i else '1';
  36. end loop;
  37. end process;
  38. -- Candidate selection is dumb, priority order... we could
  39. -- instead consider some form of fairness but it's not really
  40. -- an issue at the moment.
  41. --
  42. wishbone_candidate: process(all)
  43. begin
  44. candidate <= selected;
  45. for i in NUM_MASTERS-1 downto 0 loop
  46. if wb_masters_in(i).cyc = '1' then
  47. candidate <= i;
  48. end if;
  49. end loop;
  50. end process;
  51. wishbone_arbiter_process: process(clk)
  52. begin
  53. if rising_edge(clk) then
  54. if rst = '1' then
  55. selected <= 0;
  56. elsif busy = '0' then
  57. selected <= candidate;
  58. end if;
  59. end if;
  60. end process;
  61. end behave;