mdio_regs: Delay counter signals by one clock

The counters in this module end up on the critical path a lot.  The
counters themselves take 3-4 ns to compute, but routing the increment
signal to the counter eats up a lot of slack. Register the increment signal
for a clock to let it cross the FPGA without affecting the counter timing.

Signed-off-by: Sean Anderson <seanga2@gmail.com>
This commit is contained in:
Sean Anderson 2023-03-05 20:35:35 -05:00
parent 003e5e4b79
commit db41a68f1a
2 changed files with 18 additions and 6 deletions

View File

@ -95,6 +95,7 @@ module mdio_regs (
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 nwl, pwl, dl, fcl, sel;
/* Can't meet timing at 16 bits wide */
reg [COUNTER_WIDTH-1:0] nwc, pwc, dc, fcc, sec;
reg [COUNTER_WIDTH-1:0] nwc_next, pwc_next, dc_next, fcc_next, sec_next;
@ -110,6 +111,11 @@ module mdio_regs (
link_status_latched = 0;
link_status_last = 0;
if (ENABLE_COUNTERS) begin
nwl = 0;
pwl = 0;
dl = 0;
fcl = 0;
sel = 0;
nwc = 0;
pwc = 0;
dc = 0;
@ -138,11 +144,11 @@ module mdio_regs (
fcc_next = fcc;
sec_next = sec;
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;
if (!(&sec)) sec_next = sec + symbol_error;
if (!(&nwc)) nwc_next = nwc + nwl;
if (!(&pwc)) pwc_next = pwc + pwl;
if (!(&dc)) dc_next = dc + dl;
if (!(&fcc)) fcc_next = fcc + fcl;
if (!(&sec)) sec_next = sec + sel;
end
data_read_next = 0;
@ -265,6 +271,11 @@ module mdio_regs (
err <= err_next;
data_read <= data_read_next;
if (ENABLE_COUNTERS) begin
nwl <= negative_wraparound;
pwl <= positive_wraparound;
dl <= disconnect;
fcl <= false_carrier;
sel <= symbol_error;
nwc <= nwc_next;
pwc <= pwc_next;
dc <= dc_next;

View File

@ -60,7 +60,7 @@ async def wb_xfer(signals, addr, data=None, delay=1):
if data is None and signals['ack'].value:
return signals['data_read'].value
@cocotb.test(timeout_time=1, timeout_unit='us')
@cocotb.test(timeout_time=2, timeout_unit='us')
async def test_mdio(regs):
regs.cyc.value = 1
regs.stb.value = 0
@ -127,6 +127,7 @@ async def test_mdio(regs):
async def counter_test(reg, signal, edge_triggered=False, active_high=True):
signal.value = 1 if active_high else 0
await FallingEdge(regs.clk)
assert await xfer(reg) == 1
await xfer(reg, 0xfffe)
if edge_triggered: