From 02069bceeea460d44b7cc79675e0471923cc6641 Mon Sep 17 00:00:00 2001 From: Sean Anderson Date: Sat, 5 Nov 2022 11:57:54 -0400 Subject: [PATCH] pcs: Add false_carrier signal This adds an explicit false carrier signal. Trying to determine this condition the MDIO signals is tricky because BAD_SSD can last over several cycles of CE. To make things easier, add a signal which is high only once per event. Signed-off-by: Sean Anderson --- rtl/mdio_regs.v | 11 ++++------- rtl/pcs_rx.v | 15 +++++++++++---- tb/mdio_regs.py | 2 +- tb/pcs_rx.py | 25 ++++++++++++++++++------- 4 files changed, 34 insertions(+), 19 deletions(-) diff --git a/rtl/mdio_regs.v b/rtl/mdio_regs.v index 56f19dc..9118470 100644 --- a/rtl/mdio_regs.v +++ b/rtl/mdio_regs.v @@ -90,8 +90,7 @@ module mdio_regs ( localparam VCR_LTEST = 14; integer i; - reg duplex, false_carrier_last, false_carrier_event; - reg link_status_latched, link_status_latched_next, link_status_last, disconnect; + reg duplex, link_status_latched, link_status_latched_next, link_status_last, disconnect; reg loopback_next, pdown_next, isolate_next, duplex_next, coltest_next; reg descrambler_test_next, link_monitor_test_next; reg [15:0] data_read_next; @@ -126,7 +125,6 @@ module mdio_regs ( coltest_next = coltest; link_status_latched_next = link_status_latched && link_status; disconnect = link_status_last && !link_status; - false_carrier_event = false_carrier && !false_carrier_last; descrambler_test_next = descrambler_test; link_monitor_test_next = link_monitor_test; @@ -140,7 +138,7 @@ module mdio_regs ( if (!(&nwc)) nwc_next = nwc + negative_wraparound; if (!(&pwc)) pwc_next = pwc + positive_wraparound; if (!(&dc)) dc_next = dc + disconnect; - if (!(&fcc)) fcc_next = fcc + false_carrier_event; + if (!(&fcc)) fcc_next = fcc + false_carrier; if (!(&sec)) sec_next = sec + symbol_error; end @@ -174,7 +172,7 @@ module mdio_regs ( nwc_next = negative_wraparound; pwc_next = positive_wraparound; dc_next = disconnect; - fcc_next = false_carrier_event; + fcc_next = false_carrier; sec_next = symbol_error; end descrambler_test_next = 0; @@ -223,7 +221,7 @@ module mdio_regs ( data_read_next = fcc; if (cyc && stb) - fcc_next = we ? data_write : false_carrier_event; + fcc_next = we ? data_write : false_carrier; end SECR: if (ENABLE_COUNTERS) begin data_read_next = sec; @@ -260,7 +258,6 @@ module mdio_regs ( coltest <= coltest_next; link_status_latched <= link_status_latched_next; link_status_last <= link_status; - false_carrier_last <= false_carrier; data_read <= data_read_next; if (ENABLE_COUNTERS) begin nwc <= nwc_next; diff --git a/rtl/pcs_rx.v b/rtl/pcs_rx.v index a718a07..820bd49 100644 --- a/rtl/pcs_rx.v +++ b/rtl/pcs_rx.v @@ -190,7 +190,8 @@ module pcs_rx ( input link_status, /* Internal */ - output reg rx + output reg rx, + output reg false_carrier ); localparam IDLE = 0; @@ -210,7 +211,7 @@ module pcs_rx ( reg [2:0] state, state_next; initial state = IDLE; /* Whether we are aligned and receiving */ - reg rx_next; + reg rx_next, false_carrier_next; pcs_rx_bits rx_bits ( .clk(clk), @@ -261,6 +262,7 @@ module pcs_rx ( state_next = state; valid_next = valid; err_next = 0; + false_carrier_next = 0; `define BAD_SSD begin \ state_next = BAD_SSD; \ @@ -279,8 +281,10 @@ end ce_next = 0; if (unaligned == { `CODE_I, `CODE_J }) state_next = START_J; - else + else begin `BAD_SSD; + false_carrier_next = 1; + end end end BAD_SSD: begin @@ -293,8 +297,10 @@ end if (aligned[4:0] == `CODE_K) begin state_next = START_K; valid_next = 1; - end else + end else begin `BAD_SSD; + false_carrier_next = indicate; + end if (!indicate) state_next = START_J; @@ -371,6 +377,7 @@ end rx <= rx_next; state <= state_next; ce <= ce_next; + false_carrier <= false_carrier_next; if (ce_next) begin data <= data_next; valid <= valid_next; diff --git a/tb/mdio_regs.py b/tb/mdio_regs.py index 385e6bc..cff6287 100644 --- a/tb/mdio_regs.py +++ b/tb/mdio_regs.py @@ -128,7 +128,7 @@ async def test_mdio(regs): await counter_test(PWCR, regs.positive_wraparound) await xfer(DCR) # Clear DCR from the BMSR testing await counter_test(DCR, regs.link_status, True, False) - await counter_test(FCCR, regs.false_carrier, True) + await counter_test(FCCR, regs.false_carrier) await counter_test(SECR, regs.symbol_error) await reg_toggle(VCR, VCR_DTEST, regs.descrambler_test) diff --git a/tb/pcs_rx.py b/tb/pcs_rx.py index 50b4f36..e81116d 100644 --- a/tb/pcs_rx.py +++ b/tb/pcs_rx.py @@ -22,20 +22,28 @@ def frame(data): return itertools.chain( (Code('J'), Code('K')), # Chop off the SSD - as_codes(data[2:]), + as_codes(itertools.islice(data, 2, None)), (Code('T'), Code('R')), ) -async def mii_recv_packet(pcs): - while not (pcs.ce.value and pcs.valid.value): +async def mii_recv_packet(pcs, signals=None): + if signals is None: + signals = { + 'ce': pcs.ce, + 'err': pcs.err, + 'data': pcs.data, + 'valid': pcs.valid, + } + + while not (signals['ce'].value and signals['valid'].value): await RisingEdge(pcs.clk) - while pcs.valid.value: - if pcs.ce.value: - if pcs.err.value: + while signals['valid'].value: + if signals['ce'].value: + if signals['err'].value: yield None else: - yield pcs.data.value + yield signals['data'].value await RisingEdge(pcs.clk) async def pcs_send_codes(pcs, codes, valids): @@ -68,11 +76,14 @@ async def test_rx(pcs, valids): assert packet == await alist(mii_recv_packet(pcs)) + false_carriers = 0 for _ in range(3): while not (pcs.rx.value and pcs.err.value and pcs.ce.value): await RisingEdge(pcs.clk) + false_carriers += pcs.false_carrier.value assert pcs.data.value == 0xE await FallingEdge(pcs.rx) + assert false_carriers == 3 assert [0x5, 0x5, None] == await alist(mii_recv_packet(pcs))