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 <seanga2@gmail.com>
This commit is contained in:
parent
ece7d6c619
commit
02069bceee
|
@ -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;
|
||||
|
|
15
rtl/pcs_rx.v
15
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;
|
||||
|
|
|
@ -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)
|
||||
|
|
25
tb/pcs_rx.py
25
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))
|
||||
|
||||
|
|
Loading…
Reference in New Issue