1
0
Fork 0

cxp: add trig to upconn & remove tx_command_packet

This commit is contained in:
morgan 2024-09-03 12:49:30 +08:00
parent 6d421a1041
commit d84c7c9523
1 changed files with 38 additions and 139 deletions

View File

@ -8,8 +8,6 @@ from cxp_pipeline import *
class CXP(Module, AutoCSR):
def __init__(self, refclk, downconn_pads, upconn_pads, sys_clk_freq, debug_sma, pmod_pads):
self.submodules.trig = TX_Trigger(cxp_phy_layout())
self.submodules.upconn = UpConn_Interface(upconn_pads, sys_clk_freq, debug_sma, pmod_pads)
self.submodules.downconn = CXP_DownConn(refclk, downconn_pads, sys_clk_freq, debug_sma, pmod_pads)
@ -17,9 +15,6 @@ class CXP(Module, AutoCSR):
# TODO: add link layer
# TODO: remove this and put it in upconn_interface
def cxp_phy_layout():
return [("data", 8), ("k", 1)]
class UpConn_Interface(Module, AutoCSR):
def __init__(self, upconn_pads, sys_clk_freq, debug_sma, pmod_pads, fifos_depth=64):
@ -31,7 +26,9 @@ class UpConn_Interface(Module, AutoCSR):
# # #
self.submodules.upconn_phy = upconn_phy = CXP_UpConn_PHY(upconn_pads, sys_clk_freq, debug_sma, pmod_pads, cxp_phy_layout(), fifos_depth)
layout = [("data", 8), ("k", 1)]
self.submodules.upconn_phy = upconn_phy = CXP_UpConn_PHY(upconn_pads, sys_clk_freq, debug_sma, pmod_pads, layout, fifos_depth)
self.sync += [
upconn_phy.bitrate2x_enable.eq(self.bitrate2x_enable.storage),
@ -45,8 +42,36 @@ class UpConn_Interface(Module, AutoCSR):
# Packet FIFOs with transmission priority
# 0: Trigger packet
# NOTE: 0 Trigger packet
self.submodules.trig = trig = TX_Trigger(layout)
# DEBUG: INPUT
self.trig_stb = CSR()
self.trig_delay = CSRStorage(8)
self.linktrigger = CSRStorage(2)
self.sync += [
trig.trig_stb.eq(self.trig_stb.re),
trig.delay.eq(self.trig_delay.storage),
trig.linktrig_mode.eq(self.linktrigger.storage),
]
# DEBUG: OUTPUT
self.submodules.trig_out = trig_out = stream.SyncFIFO(layout, 64)
self.comb += trig.source.connect(trig_out.sink)
self.trig_inc = CSR()
self.trig_dout_pak = CSRStatus(8)
self.trig_kout_pak = CSRStatus()
self.trig_dout_valid = CSRStatus()
self.sync += [
# output
trig_out.source.ack.eq(self.trig_inc.re),
self.trig_dout_pak.status.eq(trig_out.source.data),
self.trig_kout_pak.status.eq(trig_out.source.k),
self.trig_dout_valid.status.eq(trig_out.source.stb),
]
self.symbol0 = CSR(9)
self.sync += [
upconn_phy.tx_fifos.sink[0].stb.eq(self.symbol0.re),
@ -55,9 +80,9 @@ class UpConn_Interface(Module, AutoCSR):
]
# 1: IO acknowledgment for trigger packet
# NOTE: 1 IO acknowledgment for trigger packet
self.submodules.trig_ack = trig_ack = Trigger_ACK(cxp_phy_layout())
self.submodules.trig_ack = trig_ack = Trigger_ACK(layout)
# DEBUG: INPUT
self.ack = CSR()
@ -66,7 +91,7 @@ class UpConn_Interface(Module, AutoCSR):
]
# DEBUG: OUTPUT
self.submodules.trig_ack_out = trig_ack_out = stream.SyncFIFO(cxp_phy_layout(), 64)
self.submodules.trig_ack_out = trig_ack_out = stream.SyncFIFO(layout, 64)
self.comb += trig_ack.source.connect(trig_ack_out.sink)
self.trig_ack_inc = CSR()
self.trig_ack_dout_pak = CSRStatus(8)
@ -88,7 +113,7 @@ class UpConn_Interface(Module, AutoCSR):
upconn_phy.tx_fifos.sink[1].k.eq(self.symbol1.r[8]),
]
# 2: All other packets
# NOTE: 2 All other packets
# Control is not timing dependent, all the link layer is done in firmware
# Table 54 (CXP-001-2021)
@ -99,11 +124,11 @@ class UpConn_Interface(Module, AutoCSR):
# section 9.6.1.2 (CXP-001-2021)
# tags implementation is on firmware
self.submodules.command = command = TX_Command_Packet(pmod_pads)
self.submodules.command = command = TX_Command_Packet(layout, pmod_pads)
# DEBUG: OUTPUT
self.submodules.command_out = command_out = stream.SyncFIFO(cxp_phy_layout(), 64)
self.submodules.command_out = command_out = stream.SyncFIFO(layout, 64)
self.comb += command.source.connect(command_out.sink)
self.command_inc = CSR()
@ -138,129 +163,3 @@ class UpConn_Interface(Module, AutoCSR):
upconn_phy.tx_fifos.sink[2].data.eq(self.symbol2.r[:8]),
upconn_phy.tx_fifos.sink[2].k.eq(self.symbol2.r[8]),
]
def K(x, y):
return ((y << 5) | x)
# TODO: move this to cxp_pipeline, since it used K(x, y) :<
class TX_Trigger(Module, AutoCSR):
def __init__(self, layout):
# This module is mostly control by gateware
self.trig_stb = Signal()
self.delay = Signal(8) # FIXME: use source instead
self.linktrig_mode = Signal(max=4)
# # #
self.submodules.code_src = code_src = Code_Source(layout, counts=3)
self.comb += [
code_src.stb.eq(self.trig_stb),
code_src.data.eq(self.delay),
code_src.k.eq(0)
]
self.submodules.inserter_once = inserter_once = Code_Inserter(layout, counts=1)
self.submodules.inserter_twice = inserter_twice = Code_Inserter(layout, counts=2)
self.comb += [
inserter_once.k.eq(1),
inserter_twice.k.eq(1),
If((self.linktrig_mode == 0) | (self.linktrig_mode == 2),
inserter_once.data.eq(K(28, 2)),
inserter_twice.data.eq(K(28, 4)),
).Else(
inserter_once.data.eq(K(28, 4)),
inserter_twice.data.eq(K(28, 2)),
)
]
self.submodules.buf_out = buf_out = stream.SyncFIFO(layout, 64)
tx_pipeline = [ code_src, inserter_twice, inserter_once, buf_out]
for s, d in zip(tx_pipeline, tx_pipeline[1:]):
self.comb += s.source.connect(d.sink)
self.source = tx_pipeline[-1].source
# DEBUG: INPUT
self.stb = CSR()
self.trig_delay = CSRStorage(8)
self.linktrigger = CSRStorage(2)
self.sync += [
self.trig_stb.eq(self.stb.re),
self.delay.eq(self.trig_delay.storage),
self.linktrig_mode.eq(self.linktrigger.storage),
]
# DEBUG: OUTPUT
self.inc = CSR()
self.dout_pak = CSRStatus(8)
self.kout_pak = CSRStatus()
self.dout_valid = CSRStatus()
self.sync += [
# output
buf_out.source.ack.eq(self.inc.re),
self.dout_pak.status.eq(buf_out.source.data),
self.kout_pak.status.eq(buf_out.source.k),
self.dout_valid.status.eq(buf_out.source.stb),
]
class TX_Command_Packet(Module, AutoCSR):
def __init__(self, pmod_pads):
self.packet_type = CSRStorage(8)
self.din_len = CSRStorage(6)
self.din_data = CSR(8)
self.din_k = CSRStorage()
self.din_ready = CSRStatus()
# # #
# a buf is used to simulated a proper endpoint which hold source.stb high as long as data is available
# otherwise, CSR.re only hold when CSR is written to and it cannot act as a proper source
self.submodules.buf_in = buf_in = stream.SyncFIFO(cxp_phy_layout(), 2)
self.submodules.crc_inserter = crc_inserters = CXPCRC32Inserter(cxp_phy_layout())
self.submodules.pak_type = pak_type = Code_Inserter(cxp_phy_layout())
self.submodules.pak_wrp = pak_wrp = Packet_Wrapper(cxp_phy_layout())
len = Signal(6, reset=1)
self.sync += [
self.din_ready.status.eq(buf_in.sink.ack),
buf_in.sink.stb.eq(0),
If(self.din_data.re,
If(len == self.din_len.storage,
len.eq(len.reset),
buf_in.sink.eop.eq(1),
).Else(
len.eq(len + 1),
buf_in.sink.eop.eq(0),
),
buf_in.sink.stb.eq(1),
buf_in.sink.data.eq(self.din_data.r),
buf_in.sink.k.eq(self.din_k.storage),
),
]
self.comb += [
pak_type.data.eq(self.packet_type.storage),
pak_type.k.eq(0),
]
tx_pipeline = [ buf_in, crc_inserters, pak_type, pak_wrp]
for s, d in zip(tx_pipeline, tx_pipeline[1:]):
self.comb += s.source.connect(d.sink)
self.source = tx_pipeline[-1].source