From 4eed5e99f4b5af0d28bc6fa193521f8fa75702a9 Mon Sep 17 00:00:00 2001 From: morgan Date: Thu, 27 Jun 2024 16:50:15 +0800 Subject: [PATCH] cxp upconn: put encoder with tx_fifos --- src/gateware/cxp_upconn.py | 80 ++++++++++++++++++++++++++------------ 1 file changed, 55 insertions(+), 25 deletions(-) diff --git a/src/gateware/cxp_upconn.py b/src/gateware/cxp_upconn.py index 3f35fee..809925c 100644 --- a/src/gateware/cxp_upconn.py +++ b/src/gateware/cxp_upconn.py @@ -10,9 +10,10 @@ from misoc.interconnect.csr import * IDLE_WORDS = [ #[data, k] [0b10111100, 1], #K28.5 - [0b00111100, 1], #K28.1 - [0b00111100, 1], #K28.1 - [0b10111100, 0], #D28.5 + [0b10111100, 1], #K28.5 + # [0b00111100, 1], #K28.1 + # [0b00111100, 1], #K28.1 + # [0b10111100, 0], #D28.5 ] @@ -66,7 +67,7 @@ class CXP_UpConn(Module, AutoCSR): tx_en = Signal() tx_bitcount = Signal(max=10) tx_reg = Signal(10) - idleidx = Signal(max=len(IDLE_WORDS)) + wordidx = Signal(max=len(IDLE_WORDS)) # startup sequence self.fsm.act("WAIT_TX_ENABLE", @@ -79,7 +80,7 @@ class CXP_UpConn(Module, AutoCSR): NextValue(self.encoder.d, IDLE_WORDS[0][0]), NextValue(self.encoder.k, IDLE_WORDS[0][1]), NextValue(self.encoder.disp_in, 0), - NextValue(idleidx, 1), + NextValue(wordidx, 1), NextState("START_TX") ) @@ -91,32 +92,44 @@ class CXP_UpConn(Module, AutoCSR): ) + # 0 lv interrupt at char boundary 10bit + # other lv interrupt at word boundary 40bit + + cur_disp = Signal() + + # TODO: only allow trigger packet to do character interrupt and other priority level to only interrupt word + # ISSUE: what if 2lv is transmitting 2nd char & 1lv interrupt its? # CXP 2.1 section 9.2.4 self.sync.cxp_upconn += [ + self.tx_fifos.disp_in.eq(cur_disp), + self.encoder.disp_in.eq(cur_disp), If(tx_en, o.eq(tx_reg[0]), tx_reg.eq(Cat(tx_reg[1:], 0)), tx_bitcount.eq(tx_bitcount + 1), If(tx_bitcount == 8, - # TODO: only allow trigger packet to do character interrupt and other priority level to only interrupt word - If(~self.tx_fifos.pe.n, - self.encoder.d.eq(self.tx_fifos.source_data[self.tx_fifos.pe.o][:8]), - self.encoder.k.eq(self.tx_fifos.source_data[self.tx_fifos.pe.o][8]), - self.tx_fifos.source_ack[self.tx_fifos.pe.o].eq(1), - ).Else( - self.encoder.d.eq(Array(IDLE_WORDS)[idleidx][0]), - self.encoder.k.eq(Array(IDLE_WORDS)[idleidx][1]), - If(idleidx != len(IDLE_WORDS), - idleidx.eq(idleidx + 1) + If(self.tx_fifos.pe.n, + self.encoder.d.eq(Array(IDLE_WORDS)[wordidx][0]), + self.encoder.k.eq(Array(IDLE_WORDS)[wordidx][1]), + If(wordidx != len(IDLE_WORDS), + wordidx.eq(wordidx + 1), ).Else( - idleidx.eq(0) - ) - ) + wordidx.eq(0), + ), + ), ).Elif(tx_bitcount == 9, tx_bitcount.eq(0), - tx_reg.eq(self.encoder.output), - self.encoder.disp_in.eq(self.encoder.disp_out), + If(self.tx_fifos.pe.n, + # idle word + tx_reg.eq(self.encoder.output), + cur_disp.eq(self.encoder.disp_out), + ).Else( + # from fifos + tx_reg.eq(self.tx_fifos.source_data[self.tx_fifos.pe.o]), + self.tx_fifos.source_ack[self.tx_fifos.pe.o].eq(1), + cur_disp.eq(self.tx_fifos.disp_out[self.tx_fifos.pe.o]), + ), ) ).Else( o.eq(0) @@ -126,7 +139,13 @@ class CXP_UpConn(Module, AutoCSR): self.encoded_data = CSRStatus(10) self.sync.cxp_upconn +=[ If(tx_bitcount == 9, - self.encoded_data.status.eq(self.encoder.output), + If(self.tx_fifos.pe.n, + # idle word + self.encoded_data.status.eq(self.encoder.output), + ).Else( + # from fifos + self.encoded_data.status.eq(self.tx_fifos.source_data[self.tx_fifos.pe.o]), + ), ) ] @@ -138,8 +157,8 @@ class CXP_UpConn(Module, AutoCSR): self.comb += [ eighth_bit.eq(tx_bitcount == 8), ninth_bit.eq(tx_bitcount == 9), - idle_3.eq(idleidx == 3), - idle_2.eq(idleidx == 2), + idle_3.eq(wordidx == 3), + idle_2.eq(wordidx == 2), ] self.specials += [ # debug sma @@ -168,6 +187,10 @@ class CXP_UpConn(Module, AutoCSR): class TxFIFOs(Module, AutoCSR): def __init__(self, nfifos, fifo_depth): + + self.disp_in = Signal() + self.disp_out = Array(Signal() for _ in range(nfifos)) + self.sink_stb = Signal(nfifos) self.sink_ack = Signal(nfifos) self.sink_data = [Signal(9) for _ in range(nfifos)] @@ -175,14 +198,16 @@ class TxFIFOs(Module, AutoCSR): # data & ack will be used dynamically during runtime, cannot use python array self.source_stb = Signal(nfifos) self.source_ack = Array(Signal() for _ in range(nfifos)) - self.source_data = Array(Signal(9) for _ in range(nfifos)) + self.source_data = Array(Signal(10) for _ in range(nfifos)) # # # for i in range(nfifos): cdr = ClockDomainsRenamer({"write": "sys", "read": "cxp_upconn"}) fifo = cdr(stream.AsyncFIFO([("data", 9)], fifo_depth)) + encoder = ClockDomainsRenamer("cxp_upconn")(SingleEncoder(True)) setattr(self.submodules, "tx_fifo" + str(i), fifo) + setattr(self.submodules, "tx_encoder" + str(i), encoder) self.comb += [ fifo.sink.stb.eq(self.sink_stb[i]), self.sink_ack[i].eq(fifo.sink.ack), @@ -190,7 +215,12 @@ class TxFIFOs(Module, AutoCSR): self.source_stb[i].eq(fifo.source.stb), fifo.source.ack.eq(self.source_ack[i]), - self.source_data[i].eq(fifo.source.data), + + encoder.d.eq(fifo.source.data[:8]), + encoder.k.eq(fifo.source.data[8]), + encoder.disp_in.eq(self.disp_in), + self.disp_out[i].eq(encoder.disp_out), + self.source_data[i].eq(encoder.output), ] # reset ack after asserted self.sync.cxp_upconn += If(self.source_ack[i], self.source_ack[i].eq(0))