diff --git a/rtl/mdio_regs.v b/rtl/mdio_regs.v index b7f2584..56f19dc 100644 --- a/rtl/mdio_regs.v +++ b/rtl/mdio_regs.v @@ -23,7 +23,9 @@ module mdio_regs ( output reg loopback, output reg pdown, output reg isolate, - output reg coltest + output reg coltest, + output reg descrambler_test, + output reg link_monitor_test ); /* The current price of a CID is $805... */ @@ -65,6 +67,8 @@ module mdio_regs ( localparam FCCR = 19; /* Symbol Error Counter Register */ localparam SECR = 21; + /* Vendor Control Register */ + localparam VCR = 30; localparam BMCR_RESET = 15; localparam BMCR_LOOPBACK = 14; @@ -80,10 +84,16 @@ module mdio_regs ( localparam BMSR_LSTATUS = 2; localparam BMSR_EXTCAP = 0; + /* VCR Descrambler test mode */ + localparam VCR_DTEST = 15; + /* VCR Link monitor test mode */ + 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 loopback_next, pdown_next, isolate_next, duplex_next, coltest_next; + reg descrambler_test_next, link_monitor_test_next; reg [15:0] data_read_next; /* Can't meet timing at 16 bits wide */ reg [COUNTER_WIDTH-1:0] nwc, pwc, dc, fcc, sec; @@ -104,6 +114,8 @@ module mdio_regs ( fcc = 0; sec = 0; end + descrambler_test = 0; + link_monitor_test = 0; end always @(*) begin @@ -115,6 +127,8 @@ module mdio_regs ( 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; if (ENABLE_COUNTERS) begin nwc_next = nwc; @@ -163,6 +177,8 @@ module mdio_regs ( fcc_next = false_carrier_event; sec_next = symbol_error; end + descrambler_test_next = 0; + link_monitor_test_next = 0; end end end @@ -215,6 +231,15 @@ module mdio_regs ( if (cyc && stb) sec_next = we ? data_write : symbol_error; end + VCR: begin + data_read_next[VCR_DTEST] = descrambler_test; + data_read_next[VCR_LTEST] = link_monitor_test; + + if (cyc && stb && we) begin + descrambler_test_next = data_write[VCR_DTEST]; + link_monitor_test_next = data_write[VCR_LTEST]; + end + end default: begin if (EMULATE_PULLUP) begin data_read_next = 16'hFFFF; @@ -244,6 +269,8 @@ module mdio_regs ( fcc <= fcc_next; sec <= sec_next; end + descrambler_test <= descrambler_test_next; + link_monitor_test <= link_monitor_test_next; end endmodule diff --git a/tb/mdio_regs.py b/tb/mdio_regs.py index 0de0b81..385e6bc 100644 --- a/tb/mdio_regs.py +++ b/tb/mdio_regs.py @@ -19,6 +19,7 @@ PWCR = 17 DCR = 18 FCCR = 19 SECR = 21 +VCR = 30 BMCR_RESET = BIT(15) BMCR_LOOPBACK = BIT(14) @@ -34,6 +35,9 @@ BMSR_100BASEXHD = BIT(13) BMSR_LSTATUS = BIT(2) BMSR_EXTCAP = BIT(0) +VCR_DTEST = BIT(15) +VCR_LTEST = BIT(14) + @cocotb.test(timeout_time=1, timeout_unit='us') async def test_mdio(regs): regs.cyc.value = 1 @@ -65,17 +69,20 @@ async def test_mdio(regs): if data is None and regs.ack.value: return regs.data_read.value - async def bmcr_toggle(bit, signal): + async def reg_toggle(reg, bit, signal, ro_mask=0): if signal: assert not signal.value - await xfer(BMCR, bit) + await xfer(reg, bit) if signal: assert signal.value - assert await xfer(BMCR) == (BMCR_SPEED_LSB | bit) - await xfer(BMCR, 0) + assert await xfer(reg) == (ro_mask | bit) + await xfer(reg, 0) if signal: assert not signal.value + def bmcr_toggle(bit, signal): + return reg_toggle(BMCR, bit, signal, ro_mask=BMCR_SPEED_LSB) + assert await xfer(BMCR) == (BMCR_SPEED_LSB | BMCR_ISOLATE) await bmcr_toggle(BMCR_LOOPBACK, regs.loopback) await bmcr_toggle(BMCR_PDOWN, regs.pdown) @@ -123,3 +130,6 @@ async def test_mdio(regs): await counter_test(DCR, regs.link_status, True, False) await counter_test(FCCR, regs.false_carrier, True) await counter_test(SECR, regs.symbol_error) + + await reg_toggle(VCR, VCR_DTEST, regs.descrambler_test) + await reg_toggle(VCR, VCR_LTEST, regs.link_monitor_test)