1
0
Fork 0

downconn GW: fix timing violation

testing tx: add buffer to improve timing
testing tx: send idle more frequently
downconn GW: remove unneeded stb signal
downconn GW: add docs
This commit is contained in:
morgan 2024-10-24 17:06:21 +08:00
parent 0969a62aee
commit cbd3058c83
1 changed files with 22 additions and 14 deletions

View File

@ -56,9 +56,12 @@ class Receiver(Module):
self.source = stream.Endpoint(word_layout) self.source = stream.Endpoint(word_layout)
data_valid = Signal()
self.sync.cxp_gtx_rx += [ self.sync.cxp_gtx_rx += [
data_valid.eq(gtx.comma_checker.rxfsm.ongoing("READY")),
self.source.stb.eq(0), self.source.stb.eq(0),
If(gtx.rx_ready & self.source.ack & ~((gtx.decoders[0].d == 0xBC) & (gtx.decoders[0].k == 1)), If(data_valid & self.source.ack & ~((gtx.decoders[0].d == 0xBC) & (gtx.decoders[0].k == 1)),
self.source.stb.eq(1), self.source.stb.eq(1),
self.source.data.eq(Cat(gtx.decoders[i].d for i in range(4))), self.source.data.eq(Cat(gtx.decoders[i].d for i in range(4))),
self.source.k.eq(Cat(gtx.decoders[i].k for i in range(4))), self.source.k.eq(Cat(gtx.decoders[i].k for i in range(4))),
@ -66,17 +69,22 @@ class Receiver(Module):
] ]
# DEBUG: tx fifos for loopback # DEBUG: tx fifos for loopback
# fw -> fifo (sys) -> cdc fifo -> gtx tx # fw -> -> cdc fifo -> buffered fifo -> gtx tx
tx_fifo = stream.AsyncFIFO(word_layout, 512) cdc_fifo = stream.AsyncFIFO(word_layout, 512)
self.submodules += ClockDomainsRenamer({"write": "sys", "read": "cxp_gtx_tx"})(tx_fifo) self.submodules += ClockDomainsRenamer({"write": "sys", "read": "cxp_gtx_tx"})(cdc_fifo)
self.sink = tx_fifo.sink self.sink = cdc_fifo.sink
self.tx_stb_sys = Signal()
txstb = Signal()
self.specials += MultiReg(self.tx_stb_sys, txstb, odomain="cxp_gtx_tx")
word_count = Signal(max=100) # fix timing violation
cdr = ClockDomainsRenamer("cxp_gtx_tx")
self.submodules.buf = tx_fifo = cdr(stream.SyncFIFO(word_layout, 2, buffered=True))
self.comb += [
cdc_fifo.source.connect(tx_fifo.sink),
]
idle_period = 50 # press in word
word_count = Signal(max=idle_period)
# JANK: fix the every 98th word got eaten # JANK: fix the every 98th word got eaten
# cnt 97 98 99 0 # cnt 97 98 99 0
@ -85,11 +93,11 @@ class Receiver(Module):
self.sync.cxp_gtx_tx += [ self.sync.cxp_gtx_tx += [
tx_fifo.source.ack.eq(0), tx_fifo.source.ack.eq(0),
If(word_count == 99, If(word_count == idle_period-1,
word_count.eq(word_count.reset), word_count.eq(word_count.reset),
).Else( ).Else(
If(tx_fifo.source.stb & txstb, If(tx_fifo.source.stb,
If(word_count != 98, tx_fifo.source.ack.eq(1)), If(word_count != idle_period-2, tx_fifo.source.ack.eq(1)),
word_count.eq(word_count + 1), word_count.eq(word_count + 1),
) )
) )
@ -97,7 +105,7 @@ class Receiver(Module):
# NOTE: prevent the first word send twice due to stream stb delay # NOTE: prevent the first word send twice due to stream stb delay
self.comb += [ self.comb += [
If((tx_fifo.source.stb & tx_fifo.source.ack & (word_count != 99)), If((tx_fifo.source.stb & tx_fifo.source.ack & (word_count != idle_period-1)),
gtx.encoder.d[0].eq(tx_fifo.source.data[:8]), gtx.encoder.d[0].eq(tx_fifo.source.data[:8]),
gtx.encoder.d[1].eq(tx_fifo.source.data[8:16]), gtx.encoder.d[1].eq(tx_fifo.source.data[8:16]),
gtx.encoder.d[2].eq(tx_fifo.source.data[16:24]), gtx.encoder.d[2].eq(tx_fifo.source.data[16:24]),