forked from M-Labs/artiq-zynq
cxp pipeline: add tx_command_packet
This commit is contained in:
parent
f88e431c16
commit
6d421a1041
|
@ -49,27 +49,6 @@ class Code_Source(Module):
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
|
|
||||||
class Trigger_ACK(Module):
|
|
||||||
def __init__(self, layout):
|
|
||||||
self.ack = Signal()
|
|
||||||
|
|
||||||
# # #
|
|
||||||
|
|
||||||
# Section 9.3.2 (CXP-001-2021)
|
|
||||||
# Send 4x K28.6 and 4x 0x01 as trigger packet ack
|
|
||||||
self.submodules.code_src = code_src = Code_Source(layout)
|
|
||||||
self.submodules.k_code_inserter = k_code_inserter = Code_Inserter(layout)
|
|
||||||
self.comb += [
|
|
||||||
code_src.stb.eq(self.ack),
|
|
||||||
code_src.data.eq(0x01),
|
|
||||||
code_src.k.eq(0),
|
|
||||||
k_code_inserter.data.eq(K(28, 6)),
|
|
||||||
k_code_inserter.k.eq(1),
|
|
||||||
|
|
||||||
code_src.source.connect(k_code_inserter.sink)
|
|
||||||
]
|
|
||||||
|
|
||||||
self.source = k_code_inserter.source
|
|
||||||
|
|
||||||
class Code_Inserter(Module):
|
class Code_Inserter(Module):
|
||||||
def __init__(self, layout, insert_infront=True, counts=4):
|
def __init__(self, layout, insert_infront=True, counts=4):
|
||||||
|
@ -203,3 +182,111 @@ class CXPCRC32(Module):
|
||||||
class CXPCRC32Inserter(LiteEthMACCRCInserter):
|
class CXPCRC32Inserter(LiteEthMACCRCInserter):
|
||||||
def __init__(self, layout):
|
def __init__(self, layout):
|
||||||
LiteEthMACCRCInserter.__init__(self, CXPCRC32, layout)
|
LiteEthMACCRCInserter.__init__(self, CXPCRC32, layout)
|
||||||
|
|
||||||
|
class TX_Trigger(Module, AutoCSR):
|
||||||
|
def __init__(self, layout):
|
||||||
|
self.trig_stb = Signal()
|
||||||
|
self.delay = Signal(8)
|
||||||
|
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)),
|
||||||
|
)
|
||||||
|
]
|
||||||
|
|
||||||
|
tx_pipeline = [ code_src, inserter_twice, inserter_once]
|
||||||
|
|
||||||
|
for s, d in zip(tx_pipeline, tx_pipeline[1:]):
|
||||||
|
self.comb += s.source.connect(d.sink)
|
||||||
|
|
||||||
|
self.source = tx_pipeline[-1].source
|
||||||
|
|
||||||
|
class Trigger_ACK(Module):
|
||||||
|
def __init__(self, layout):
|
||||||
|
self.ack = Signal()
|
||||||
|
|
||||||
|
# # #
|
||||||
|
|
||||||
|
# Section 9.3.2 (CXP-001-2021)
|
||||||
|
# Send 4x K28.6 and 4x 0x01 as trigger packet ack
|
||||||
|
self.submodules.code_src = code_src = Code_Source(layout)
|
||||||
|
self.submodules.k_code_inserter = k_code_inserter = Code_Inserter(layout)
|
||||||
|
self.comb += [
|
||||||
|
code_src.stb.eq(self.ack),
|
||||||
|
code_src.data.eq(0x01),
|
||||||
|
code_src.k.eq(0),
|
||||||
|
k_code_inserter.data.eq(K(28, 6)),
|
||||||
|
k_code_inserter.k.eq(1),
|
||||||
|
|
||||||
|
code_src.source.connect(k_code_inserter.sink)
|
||||||
|
]
|
||||||
|
|
||||||
|
self.source = k_code_inserter.source
|
||||||
|
|
||||||
|
class TX_Command_Packet(Module, AutoCSR):
|
||||||
|
def __init__(self, layout, 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(layout, 2)
|
||||||
|
|
||||||
|
self.submodules.crc_inserter = crc_inserters = CXPCRC32Inserter(layout)
|
||||||
|
self.submodules.pak_type = pak_type = Code_Inserter(layout)
|
||||||
|
self.submodules.pak_wrp = pak_wrp = Packet_Wrapper(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
|
||||||
|
|
Loading…
Reference in New Issue