diff --git a/src/gateware/cxp.py b/src/gateware/cxp.py index 28c1785..59670d8 100644 --- a/src/gateware/cxp.py +++ b/src/gateware/cxp.py @@ -28,37 +28,39 @@ class CXP_PHYS(Module, AutoCSR): @FullMemoryWE() -class CXP_Interface(Module, AutoCSR): +class CXP_Core(Module, AutoCSR): def __init__(self, phy, debug_sma, pmod_pads): - self.submodules.upconn = UpConn_Interface(phy.tx, debug_sma, pmod_pads) - self.submodules.downconn = DownConn_Interface(phy.rx, debug_sma, pmod_pads) + self.submodules.tx = TX_Pipeline(phy.tx, debug_sma, pmod_pads) + self.submodules.rx = RX_Pipeline(phy.rx, debug_sma, pmod_pads) def get_tx_port(self): - return self.upconn.bootstrap.mem.get_port(write_capable=True) + return self.tx.bootstrap.mem.get_port(write_capable=True) def get_tx_mem_size(self): + # TODO: remove this # FIXME: if tx mem size is NOT same as rx, for some reason when rx mem is writen, tx mem cannot be access anymore # and each time tx mem is read, CPU will return rx mem instead (fixed by reordering the mem allocation order) # FIXME: seems like there are address alignment issue, if tx mem size is 0x800, the mem following the tx mem cannot be read correctly # However, if tx mem is 0x2000 (same size as rx mem) the following rx mem can be read correctly - return self.upconn.bootstrap.mem.depth*self.upconn.bootstrap.mem.width // 8 # 0x800 + return self.tx.bootstrap.mem.depth*self.upconn.bootstrap.mem.width // 8 # 0x800 # return self.downconn.bootstrap.mem.depth*self.downconn.bootstrap.mem.width // 8 # 0x2000 def get_mem_size(self): return word_dw * buffer_count * buffer_depth // 8 def get_rx_port(self): - return self.downconn.bootstrap.mem.get_port(write_capable=False) + return self.rx.bootstrap.mem.get_port(write_capable=False) def get_rx_mem_size(self): - return self.downconn.bootstrap.mem.depth*self.downconn.bootstrap.mem.width // 8 + # TODO: remove this + return self.rx.bootstrap.mem.depth*self.downconn.bootstrap.mem.width // 8 - def get_rx_downconn(self): - return self.downconn + def get_rx_pipeline(self): + return self.rx -class CXP_Master(CXP_Interface): +class CXP_Master(CXP_Core): def __init__(self, phy, debug_sma, pmod_pads): - CXP_Interface.__init__(self, phy, debug_sma, pmod_pads) + CXP_Core.__init__(self, phy, debug_sma, pmod_pads) nbit_trigdelay = 8 nbit_linktrig = 1 @@ -69,31 +71,31 @@ class CXP_Master(CXP_Interface): self.sync.rio += [ If(self.rtlink.o.stb, - self.upconn.trig.delay.eq(self.rtlink.o.data[nbit_linktrig:]), - self.upconn.trig.linktrig_mode.eq(self.rtlink.o.data[:nbit_linktrig]), + self.tx.trig.delay.eq(self.rtlink.o.data[nbit_linktrig:]), + self.tx.trig.linktrig_mode.eq(self.rtlink.o.data[:nbit_linktrig]), ), - self.upconn.trig.stb.eq(self.rtlink.o.stb), + self.tx.trig.stb.eq(self.rtlink.o.stb), ] # DEBUG: out self.specials += Instance("OBUF", i_I=self.rtlink.o.stb, o_O=debug_sma.p_tx), # self.specials += Instance("OBUF", i_I=self.rtlink.o.stb, o_O=debug_sma.n_rx), -class CXP_Extension(CXP_Interface): +class CXP_Extension(CXP_Core): def __init__(self, phy, debug_sma, pmod_pads): - CXP_Interface.__init__(self, phy, debug_sma, pmod_pads) + CXP_Core.__init__(self, phy, debug_sma, pmod_pads) -class DownConn_Interface(Module, AutoCSR): +class RX_Pipeline(Module, AutoCSR): def __init__(self, phy, debug_sma, pmod_pads): - self.rx_ready = CSRStatus() + self.ready = CSRStatus() # # # gtx = phy.gtx # GTX status - self.sync += self.rx_ready.status.eq(gtx.rx_ready) + self.sync += self.ready.status.eq(gtx.rx_ready) # DEBUG: init status self.txinit_phaligndone = CSRStatus() @@ -247,7 +249,7 @@ class DownConn_Interface(Module, AutoCSR): -class UpConn_Interface(Module, AutoCSR): +class TX_Pipeline(Module, AutoCSR): def __init__(self, phy, debug_sma, pmod_pads): # Transmission Pipeline # @@ -305,8 +307,8 @@ class UpConn_Interface(Module, AutoCSR): class CXP_Frame_Pipeline(Module, AutoCSR): # optimal stream packet size is 2 KiB - Section 9.5.2 (CXP-001-2021) - def __init__(self, downconns, pmod_pads, packet_size=16384, n_buffer=1): - n_downconn = len(downconns) + def __init__(self, rx_pipelines, pmod_pads, packet_size=16384, n_buffer=1): + n_downconn = len(rx_pipelines) assert n_downconn > 0 and n_buffer > 0 # # # @@ -370,7 +372,7 @@ class CXP_Frame_Pipeline(Module, AutoCSR): self.submodules.broadcaster = broadcaster = cdr(Stream_Broadcaster(n_buffer)) # Connect pipeline - for i, d in enumerate(downconns): + for i, d in enumerate(rx_pipelines): # Assume downconns pipeline already marks the eop self.comb += d.source.connect(arbiter.sinks[i]) @@ -382,7 +384,7 @@ class CXP_Frame_Pipeline(Module, AutoCSR): # Control interface # only the simple topology MASTER:ch0, extension:ch1,2,3 is supported right now active_extensions = Signal(max=n_downconn) - self.sync += active_extensions.eq(reduce(add, [d.rx_ready.status for d in downconns[1:]])) + self.sync += active_extensions.eq(reduce(add, [rx.ready.status for rx in rx_pipelines[1:]])) self.specials += MultiReg(active_extensions, arbiter.n_ext_active, odomain="cxp_gtx_rx"), for i, id in enumerate(routing_ids):