Signal where a '1' on the i-th bit represents an incoming request from the i-th device.
grant : Signal(range(n))
Signal that equals to the index of the device which is currently granted access.
+ stb : Signal()
+ Strobe signal to enable granting access to the next device requesting. Externally driven.
"""
def __init__(self, n):
self.n = n
self.request = Signal(n)
self.grant = Signal(range(n))
+ self.stb = Signal()
def elaborate(self, platform):
m = Module()
- with m.Switch(self.grant):
- for i in range(self.n):
- with m.Case(i):
- with m.If(~self.request[i]):
- for j in reversed(range(i+1, i+self.n)):
- t = j % self.n
- with m.If(self.request[t]):
- m.d.sync += self.grant.eq(t)
+ with m.If(self.stb):
+ with m.Switch(self.grant):
+ for i in range(self.n):
+ with m.Case(i):
+ with m.If(~self.request[i]):
+ for j in reversed(range(i+1, i+self.n)):
+ # If i+1 <= j < n, then t == j; (after i)
+ # If n <= j < i+n, then t == j - n (before i)
+ t = j % self.n
+ with m.If(self.request[t]):
+ m.d.sync += self.grant.eq(t)
return m
\ No newline at end of file
if self._scheduler == "rr":
m.submodules.scheduler = scheduler = RoundRobin(self._next_index)
grant = Signal(self._next_index)
- m.d.comb += grant.eq(scheduler.grant)
+ m.d.comb += [
+ # CYC should not be indefinitely asserted. (See RECOMMENDATION 3.05, Wishbone B4)
+ scheduler.stb.eq(~self.bus.cyc),
+ grant.eq(scheduler.grant)
+ ]
for signal_name, (_, signal_direction) in self.bus.layout.fields.items():
# FANOUT signals: only mux the granted master with the interface
if signal_direction == Direction.FANOUT:
- master_signals = Array(getattr(master_bus, signal_name)
- for __, (___, master_bus)
+ master_signals = Array(getattr(master_bus, signal_name)
+ for __, (___, master_bus)
in self._masters.items())
m.d.comb += getattr(self.bus, signal_name).eq(master_signals[grant])
# FANIN signals: ACK and ERR are ORed to all masters;
for target_bus in targets:
self._targets.append(target_bus)
-
+
self.arbiter = Arbiter(
addr_width=self.addr_width,
data_width=self.data_width,
self.arbiter.bus.connect(self.decoder.bus)
)
- return m
\ No newline at end of file
+ return m