1
0
Fork 0

downconn GW: add tx&rx packet for debug

This commit is contained in:
morgan 2024-09-16 12:39:29 +08:00
parent dddea53d26
commit ca32914917
1 changed files with 75 additions and 41 deletions

View File

@ -4,8 +4,10 @@ from migen.genlib.resetsync import AsyncResetSynchronizer
from misoc.cores.code_8b10b import Encoder, Decoder
from misoc.interconnect.csr import *
from misoc.interconnect import stream
from artiq.gateware.drtio.transceiver.gtx_7series_init import *
from cxp_pipeline import downconn_layout
from functools import reduce
from operator import add
@ -45,7 +47,6 @@ class CXP_DownConn_PHY(Module, AutoCSR):
# TODO: add extension gtx connections
# TODO: add connection interface
# TODO: Connect slave cxp_gtx_rx clock tgt
# checkout channel interfaces & drtio_gtx
@ -99,9 +100,35 @@ class CXP_DownConn_PHY(Module, AutoCSR):
),
]
self.sources = []
for n, gtx in enumerate(self.gtxs):
# gtx rx -> fifo out -> cdc out
fifo_out = stream.SyncFIFO(downconn_layout, 128)
self.submodules += ClockDomainsRenamer("cxp_gtx_rx")(fifo_out)
cdc_out = stream.AsyncFIFO(downconn_layout, 128)
self.submodules += ClockDomainsRenamer({"write": "cxp_gtx_rx", "read": "sys"})(cdc_out)
self.sources.append(cdc_out)
self.comb += fifo_out.source.connect(cdc_out.sink)
for i in range(4):
self.sync.cxp_gtx_rx += [
fifo_out.sink.stb.eq(0),
# don't store idle word in fifo
If(gtx.rx_ready & fifo_out.sink.ack & (gtx.decoders[0].d != 0xBC),
fifo_out.sink.stb.eq(1),
fifo_out.sink.data[i*8:(i*8)+8].eq(gtx.decoders[i].d),
fifo_out.sink.k[i].eq(gtx.decoders[i].k),
),
]
# DEBUG: tx of gtx is not used in CXP
# DEBUG: txusrclk PLL DRG
self.txpll_reset = CSRStorage()
@ -118,6 +145,9 @@ class CXP_DownConn_PHY(Module, AutoCSR):
self.txinit_phaligndone = CSRStatus()
self.rxinit_phaligndone = CSRStatus()
self.tx_stb = CSRStorage()
self.sinks = []
for n, gtx in enumerate(self.gtxs):
self.comb += [
gtx.txpll_reset.eq(self.txpll_reset.storage),
@ -137,6 +167,47 @@ class CXP_DownConn_PHY(Module, AutoCSR):
self.loopback_mode = CSRStorage(3)
self.comb += gtx.loopback_mode.eq(self.loopback_mode.storage)
# DEBUG: datain
# fw -> fifo (sys) -> cdc fifo -> fifo in -> gtx tx
fifo_in = stream.AsyncFIFO(downconn_layout, 128)
self.submodules += ClockDomainsRenamer({"write": "sys", "read": "cxp_gtx_tx"})(fifo_in)
self.sinks.append(fifo_in)
# TODO: why there this send an extra 0xFB word
txstb = Signal()
self.specials += MultiReg(self.tx_stb.storage, txstb, odomain="cxp_gtx_tx")
self.sync.cxp_gtx_tx += [
fifo_in.source.ack.eq(0),
If(fifo_in.source.stb & txstb,
fifo_in.source.ack.eq(1),
)
]
self.comb += [
If(fifo_in.source.stb & fifo_in.source.ack,
gtx.encoder.d[0].eq(fifo_in.source.data[:8]),
gtx.encoder.d[1].eq(fifo_in.source.data[8:16]),
gtx.encoder.d[2].eq(fifo_in.source.data[16:24]),
gtx.encoder.d[3].eq(fifo_in.source.data[24:]),
gtx.encoder.k[0].eq(fifo_in.source.k[0]),
gtx.encoder.k[1].eq(fifo_in.source.k[1]),
gtx.encoder.k[2].eq(fifo_in.source.k[2]),
gtx.encoder.k[3].eq(fifo_in.source.k[3]),
).Else(
# NOTE: IDLE WORD
gtx.encoder.d[0].eq(0xBC),
gtx.encoder.k[0].eq(1),
gtx.encoder.d[1].eq(0x3C),
gtx.encoder.k[1].eq(1),
gtx.encoder.d[2].eq(0x3C),
gtx.encoder.k[2].eq(1),
gtx.encoder.d[3].eq(0xB5),
gtx.encoder.k[3].eq(0),
)
]
# DEBUG: IO SMA & PMOD
if n == 0:
self.specials += [
@ -144,9 +215,9 @@ class CXP_DownConn_PHY(Module, AutoCSR):
# Instance("OBUF", i_I=gtx.cd_cxp_gtx_tx.clk, o_O=debug_sma.n_rx),
# # pmod 0-7 pin
# Instance("OBUF", i_I=gtx.comma_checker.comma_aligned, o_O=pmod_pads[0]),
# Instance("OBUF", i_I=gtx.comma_checker.comma_det, o_O=pmod_pads[1]),
# Instance("OBUF", i_I=gtx.comma_checker.restart_sys, o_O=pmod_pads[2]),
Instance("OBUF", i_I=txstb, o_O=pmod_pads[0]),
Instance("OBUF", i_I=fifo_in.source.stb, o_O=pmod_pads[1]),
Instance("OBUF", i_I=fifo_in.source.ack, o_O=pmod_pads[2]),
# Instance("OBUF", i_I=gtx.comma_checker.aligner_en, o_O=pmod_pads[3]),
# Instance("OBUF", i_I=gtx.comma_checker.check_reset, o_O=pmod_pads[4]),
# Instance("OBUF", i_I=gtx.comma_checker.has_comma, o_O=pmod_pads[5]),
@ -159,43 +230,6 @@ class CXP_DownConn_PHY(Module, AutoCSR):
# Instance("OBUF", i_I=gtx.dready, o_O=pmod_pads[3]),
]
# DEBUG: datain
self.sync.cxp_gtx_tx += [
gtx.encoder.d[0].eq(0xBC),
gtx.encoder.k[0].eq(1),
gtx.encoder.d[1].eq(0x3C),
gtx.encoder.k[1].eq(1),
gtx.encoder.d[2].eq(0x3C),
gtx.encoder.k[2].eq(1),
gtx.encoder.d[3].eq(0xB5),
gtx.encoder.k[3].eq(0),
]
for i in range(4):
gtx.decoders[i].input.attr.add("no_retiming")
gtx.decoders[i].d.attr.add("no_retiming")
gtx.decoders[i].k.attr.add("no_retiming")
rxdata_name = "rxdata_" + str(i)
rxdata_csr = CSRStatus(10, name=rxdata_name)
setattr(self, rxdata_name, rxdata_csr)
decoded_name = "decoded_data_" + str(i)
decoded_csr = CSRStatus(8, name=decoded_name)
setattr(self, decoded_name, decoded_csr)
k_name = "rxdata_" + str(i)
k_csr = CSRStatus(1, name=k_name)
setattr(self, k_name, k_csr)
self.sync.cxp_gtx_rx += [
rxdata_csr.status.eq(gtx.decoders[i].input),
decoded_csr.status.eq(gtx.decoders[i].d),
k_csr.status.eq(gtx.decoders[i].k),
]
class QPLL(Module, AutoCSR):
def __init__(self, refclk, sys_clk_freq):
self.clk = Signal()