multiplexer: rewrite/simplify CommandChooser

This commit is contained in:
Florent Kermarrec 2016-05-02 15:37:12 +02:00
parent fb98d12241
commit 3177f7964f
1 changed files with 26 additions and 21 deletions

View File

@ -16,36 +16,45 @@ class _CommandChooser(Module):
self.want_reads = Signal() self.want_reads = Signal()
self.want_writes = Signal() self.want_writes = Signal()
self.want_cmds = Signal() self.want_cmds = Signal()
# NB: cas/ras/we are 0 when valid is inactive # cas/ras/we are 0 when valid is inactive
self.cmd = cmd = stream.Endpoint(cmd_request_rw_layout(len(requests[0].a), self.cmd = cmd = stream.Endpoint(cmd_request_rw_layout(len(requests[0].a),
len(requests[0].ba))) len(requests[0].ba)))
# # # # # #
rr = RoundRobin(len(requests), SP_CE) n = len(requests)
self.submodules += rr
for i, req in enumerate(requests): valids = Signal(n)
self.comb += rr.request[i].eq(req.valid & ((req.is_cmd & self.want_cmds) | for i, request in enumerate(requests):
((req.is_read == self.want_reads) | command = request.is_cmd & self.want_cmds
(req.is_write == self.want_writes)))) read = request.is_read == self.want_reads
write = request.is_write == self.want_writes
self.comb += valids[i].eq(request.valid & (command | (read & write)))
valid = Signal()
self.comb += valid.eq(Array(req.valid for req in requests)[rr.grant]) arbiter = RoundRobin(n, SP_CE)
self.submodules += arbiter
choices = Array(valids[i] for i in range(n))
self.comb += [
arbiter.request.eq(valids),
cmd.valid.eq(choices[arbiter.grant])
]
for name in ["a", "ba", "is_read", "is_write", "is_cmd"]: for name in ["a", "ba", "is_read", "is_write", "is_cmd"]:
choices = Array(getattr(req, name) for req in requests) choices = Array(getattr(req, name) for req in requests)
self.comb += getattr(cmd, name).eq(choices[rr.grant]) self.comb += getattr(cmd, name).eq(choices[arbiter.grant])
for name in ["cas", "ras", "we"]: for name in ["cas", "ras", "we"]:
# we should only assert those signals when valid is 1 # we should only assert those signals when valid is 1
choices = Array(getattr(req, name) for req in requests) choices = Array(getattr(req, name) for req in requests)
self.comb += If(cmd.valid, getattr(cmd, name).eq(choices[rr.grant])) self.comb += If(cmd.valid, getattr(cmd, name).eq(choices[arbiter.grant]))
self.comb += cmd.valid.eq(valid \
& ((cmd.is_cmd & self.want_cmds) | ((cmd.is_read == self.want_reads) \
& (cmd.is_write == self.want_writes))))
self.comb += [If(cmd.valid & cmd.ready & (rr.grant == i), req.ready.eq(1)) for i, request in enumerate(requests):
for i, req in enumerate(requests)] self.comb += \
self.comb += rr.ce.eq(cmd.ready) If(cmd.valid & cmd.ready & (arbiter.grant == i),
request.ready.eq(1)
)
self.comb += arbiter.ce.eq(cmd.ready)
class _Steerer(Module): class _Steerer(Module):
@ -91,10 +100,6 @@ class Multiplexer(Module, AutoCSR):
requests = [bm.cmd for bm in bank_machines] requests = [bm.cmd for bm in bank_machines]
self.submodules.choose_cmd = choose_cmd = _CommandChooser(requests) self.submodules.choose_cmd = choose_cmd = _CommandChooser(requests)
self.submodules.choose_req = choose_req = _CommandChooser(requests) self.submodules.choose_req = choose_req = _CommandChooser(requests)
self.comb += [
choose_cmd.want_reads.eq(0),
choose_cmd.want_writes.eq(0)
]
if phy_settings.nphases == 1: if phy_settings.nphases == 1:
self.comb += [ self.comb += [
choose_cmd.want_cmds.eq(1), choose_cmd.want_cmds.eq(1),