From 07184d37df9921fa2bf729f131d276402bbb3605 Mon Sep 17 00:00:00 2001 From: Maciej Dudek Date: Thu, 10 Nov 2022 15:59:29 +0100 Subject: [PATCH] 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 --- litex/soc/interconnect/wishbone.py | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/litex/soc/interconnect/wishbone.py b/litex/soc/interconnect/wishbone.py index 359ed10b6..a659f7f36 100644 --- a/litex/soc/interconnect/wishbone.py +++ b/litex/soc/interconnect/wishbone.py @@ -166,7 +166,8 @@ class Arbiter(Module): if controllers is not None: 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 for name, size, direction in _layout: @@ -185,6 +186,8 @@ class Arbiter(Module): else: self.comb += dest.eq(source) + self.comb += self.rr.ce.eq(target.ack | ~cycs[self.rr.grant]) + # connect bus requests to round-robin selector reqs = [m.cyc for m in masters] self.comb += self.rr.request.eq(Cat(*reqs))