forked from M-Labs/artiq
1
0
Fork 0

cri: add routing table support

This commit is contained in:
Sebastien Bourdeauducq 2018-09-09 16:26:48 +08:00
parent df61b85988
commit d5577ec0d0
1 changed files with 52 additions and 10 deletions

View File

@ -2,6 +2,7 @@
from migen import * from migen import *
from migen.genlib.record import * from migen.genlib.record import *
from migen.genlib.cdc import MultiReg
from misoc.interconnect.csr import * from misoc.interconnect.csr import *
@ -109,8 +110,8 @@ class KernelInitiator(Module, AutoCSR):
self.sync += If(self.counter_update.re, self.counter.status.eq(tsc.full_ts_cri)) self.sync += If(self.counter_update.re, self.counter.status.eq(tsc.full_ts_cri))
class CRIDecoder(Module): class CRIDecoder(Module, AutoCSR):
def __init__(self, slaves=2, master=None): def __init__(self, slaves=2, master=None, mode="async", enable_routing=False):
if isinstance(slaves, int): if isinstance(slaves, int):
slaves = [Interface() for _ in range(slaves)] slaves = [Interface() for _ in range(slaves)]
if master is None: if master is None:
@ -118,10 +119,41 @@ class CRIDecoder(Module):
self.slaves = slaves self.slaves = slaves
self.master = master self.master = master
slave_bits = bits_for(len(slaves)-1)
if enable_routing:
self.routing_destination = CSRStorage(8)
self.routing_hop = CSR(slave_bits)
# # # # # #
selected = Signal(8, reset_less=True) # routing
self.sync += selected.eq(self.master.chan_sel[16:]) selected = Signal(slave_bits)
if enable_routing:
self.specials.routing_table = Memory(slave_bits, 8)
rtp_csr = self.routing_table.get_port(write_capable=True)
self.specials += rtp_csr
self.comb += [
rtp_csr.adr.eq(self.routing_destination.storage),
rtp_csr.dat_w.eq(self.routing_hop.r),
rtp_csr.we.eq(self.routing_hop.re),
self.routing_hop.w.eq(rtp_csr.dat_r)
]
if mode == "async":
rtp_decoder = self.routing_table.get_port()
elif mode == "sync":
rtp_decoder = self.routing_table.get_port(clock_domain="rtio")
else:
raise ValueError
self.specials += rtp_decoder
self.comb += [
rtp_decoder.adr.eq(self.master.chan_sel[16:]),
selected.eq(rtp_decoder.dat_r)
]
else:
self.sync += selected.eq(self.master.chan_sel[16:])
# master -> slave # master -> slave
for n, slave in enumerate(slaves): for n, slave in enumerate(slaves):
@ -141,7 +173,7 @@ class CRIDecoder(Module):
class CRISwitch(Module, AutoCSR): class CRISwitch(Module, AutoCSR):
def __init__(self, masters=2, slave=None): def __init__(self, masters=2, slave=None, mode="async"):
if isinstance(masters, int): if isinstance(masters, int):
masters = [Interface() for _ in range(masters)] masters = [Interface() for _ in range(masters)]
if slave is None: if slave is None:
@ -153,6 +185,15 @@ class CRISwitch(Module, AutoCSR):
# # # # # #
if mode == "async":
selected = self.selected.storage
elif mode == "sync":
self.selected.storage.attr.add("no_retiming")
selected = Signal.like(self.selected.storage)
self.specials += MultiReg(self.selected.storage, selected, "rtio")
else:
raise ValueError
if len(masters) == 1: if len(masters) == 1:
self.comb += masters[0].connect(slave) self.comb += masters[0].connect(slave)
else: else:
@ -160,7 +201,7 @@ class CRISwitch(Module, AutoCSR):
for name, size, direction in layout: for name, size, direction in layout:
if direction == DIR_M_TO_S: if direction == DIR_M_TO_S:
choices = Array(getattr(m, name) for m in masters) choices = Array(getattr(m, name) for m in masters)
self.comb += getattr(slave, name).eq(choices[self.selected.storage]) self.comb += getattr(slave, name).eq(choices[selected])
# connect slave->master signals # connect slave->master signals
for name, size, direction in layout: for name, size, direction in layout:
@ -170,11 +211,12 @@ class CRISwitch(Module, AutoCSR):
dest = getattr(m, name) dest = getattr(m, name)
self.comb += dest.eq(source) self.comb += dest.eq(source)
class CRIInterconnectShared(Module): class CRIInterconnectShared(Module):
def __init__(self, masters=2, slaves=2): def __init__(self, masters=2, slaves=2, mode="async", enable_routing=False):
shared = Interface() shared = Interface()
self.submodules.switch = CRISwitch(masters, shared) self.submodules.switch = CRISwitch(masters, shared, mode)
self.submodules.decoder = CRIDecoder(slaves, shared) self.submodules.decoder = CRIDecoder(slaves, shared, mode, enable_routing)
def get_csrs(self): def get_csrs(self):
return self.switch.get_csrs() return self.switch.get_csrs() + self.decoder.get_csrs()