mdio_regs: Add register to enable test modes

This adds a register allowing us to control the test modes of the
descrambler and link monitor.

Signed-off-by: Sean Anderson <seanga2@gmail.com>
This commit is contained in:
Sean Anderson 2022-11-02 17:42:16 -04:00
parent 7d35e07401
commit db30c5f8ba
2 changed files with 42 additions and 5 deletions

View File

@ -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

View File

@ -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)