Fix Wishbone arbiter

Right now, when multiple masters want to access the bus,
access is granted to one of them, and is not revoked until
selected master has finished all of its transactions (cyc goes low).

This state causes master starvation if access is granted to high
bandwidth master, like cpu in busy loop.

This commit makes it so access to bus is revoked when pending transaction
is finished (ack and cyc are high) or when selected master is idle.

Signed-off-by: Maciej Dudek <mdudek@antmicro.com>
This commit is contained in:
Maciej Dudek 2022-11-10 15:59:29 +01:00 committed by Michal Sieron
parent 05b0c59607
commit 07184d37df
1 changed files with 4 additions and 1 deletions

View File

@ -166,7 +166,8 @@ class Arbiter(Module):
if controllers is not None: if controllers is not None:
masters = controllers masters = controllers
self.submodules.rr = roundrobin.RoundRobin(len(masters)) self.submodules.rr = roundrobin.RoundRobin(len(masters), roundrobin.SP_CE)
cycs = Array(m.cyc for m in masters)
# mux master->slave signals # mux master->slave signals
for name, size, direction in _layout: for name, size, direction in _layout:
@ -185,6 +186,8 @@ class Arbiter(Module):
else: else:
self.comb += dest.eq(source) self.comb += dest.eq(source)
self.comb += self.rr.ce.eq(target.ack | ~cycs[self.rr.grant])
# connect bus requests to round-robin selector # connect bus requests to round-robin selector
reqs = [m.cyc for m in masters] reqs = [m.cyc for m in masters]
self.comb += self.rr.request.eq(Cat(*reqs)) self.comb += self.rr.request.eq(Cat(*reqs))