wb_arbiter: Early master selection

This flips the arbiter muxes on the same cycle as a new request
comes in, thus avoiding a cycle latency.

Signed-off-by: Benjamin Herrenschmidt <benh@kernel.crashing.org>
jtag-port
Benjamin Herrenschmidt 5 years ago
parent bc2acfde2f
commit cff4b13a9b

@ -23,15 +23,23 @@ end wishbone_arbiter;
architecture behave of wishbone_arbiter is architecture behave of wishbone_arbiter is
subtype wb_arb_master_t is integer range 0 to NUM_MASTERS-1; subtype wb_arb_master_t is integer range 0 to NUM_MASTERS-1;
signal candidate, selected : wb_arb_master_t; signal candidate, selected : wb_arb_master_t;
signal busy : std_ulogic;
begin begin


wishbone_muxes: process(selected, wb_slave_in, wb_masters_in) 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 begin
wb_slave_out <= wb_masters_in(selected); 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 for i in 0 to NUM_MASTERS-1 loop
wb_masters_out(i).dat <= wb_slave_in.dat; wb_masters_out(i).dat <= wb_slave_in.dat;
wb_masters_out(i).ack <= wb_slave_in.ack when selected = i else '0'; 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 selected = i else '1'; wb_masters_out(i).stall <= wb_slave_in.stall when early_sel = i else '1';
end loop; end loop;
end process; end process;


@ -54,7 +62,7 @@ begin
if rising_edge(clk) then if rising_edge(clk) then
if rst = '1' then if rst = '1' then
selected <= 0; selected <= 0;
elsif wb_slave_out.cyc = '0' then elsif busy = '0' then
selected <= candidate; selected <= candidate;
end if; end if;
end if; end if;

Loading…
Cancel
Save