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:
parent
003e5e4b79
commit
db41a68f1a
|
@ -95,6 +95,7 @@ module mdio_regs (
|
||||||
reg duplex, 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 loopback_next, pdown_next, isolate_next, duplex_next, coltest_next;
|
||||||
reg descrambler_test_next, link_monitor_test_next;
|
reg descrambler_test_next, link_monitor_test_next;
|
||||||
|
reg nwl, pwl, dl, fcl, sel;
|
||||||
/* Can't meet timing at 16 bits wide */
|
/* Can't meet timing at 16 bits wide */
|
||||||
reg [COUNTER_WIDTH-1:0] nwc, pwc, dc, fcc, sec;
|
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;
|
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_latched = 0;
|
||||||
link_status_last = 0;
|
link_status_last = 0;
|
||||||
if (ENABLE_COUNTERS) begin
|
if (ENABLE_COUNTERS) begin
|
||||||
|
nwl = 0;
|
||||||
|
pwl = 0;
|
||||||
|
dl = 0;
|
||||||
|
fcl = 0;
|
||||||
|
sel = 0;
|
||||||
nwc = 0;
|
nwc = 0;
|
||||||
pwc = 0;
|
pwc = 0;
|
||||||
dc = 0;
|
dc = 0;
|
||||||
|
@ -138,11 +144,11 @@ module mdio_regs (
|
||||||
fcc_next = fcc;
|
fcc_next = fcc;
|
||||||
sec_next = sec;
|
sec_next = sec;
|
||||||
|
|
||||||
if (!(&nwc)) nwc_next = nwc + negative_wraparound;
|
if (!(&nwc)) nwc_next = nwc + nwl;
|
||||||
if (!(&pwc)) pwc_next = pwc + positive_wraparound;
|
if (!(&pwc)) pwc_next = pwc + pwl;
|
||||||
if (!(&dc)) dc_next = dc + disconnect;
|
if (!(&dc)) dc_next = dc + dl;
|
||||||
if (!(&fcc)) fcc_next = fcc + false_carrier;
|
if (!(&fcc)) fcc_next = fcc + fcl;
|
||||||
if (!(&sec)) sec_next = sec + symbol_error;
|
if (!(&sec)) sec_next = sec + sel;
|
||||||
end
|
end
|
||||||
|
|
||||||
data_read_next = 0;
|
data_read_next = 0;
|
||||||
|
@ -265,6 +271,11 @@ module mdio_regs (
|
||||||
err <= err_next;
|
err <= err_next;
|
||||||
data_read <= data_read_next;
|
data_read <= data_read_next;
|
||||||
if (ENABLE_COUNTERS) begin
|
if (ENABLE_COUNTERS) begin
|
||||||
|
nwl <= negative_wraparound;
|
||||||
|
pwl <= positive_wraparound;
|
||||||
|
dl <= disconnect;
|
||||||
|
fcl <= false_carrier;
|
||||||
|
sel <= symbol_error;
|
||||||
nwc <= nwc_next;
|
nwc <= nwc_next;
|
||||||
pwc <= pwc_next;
|
pwc <= pwc_next;
|
||||||
dc <= dc_next;
|
dc <= dc_next;
|
||||||
|
|
|
@ -60,7 +60,7 @@ async def wb_xfer(signals, addr, data=None, delay=1):
|
||||||
if data is None and signals['ack'].value:
|
if data is None and signals['ack'].value:
|
||||||
return signals['data_read'].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):
|
async def test_mdio(regs):
|
||||||
regs.cyc.value = 1
|
regs.cyc.value = 1
|
||||||
regs.stb.value = 0
|
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):
|
async def counter_test(reg, signal, edge_triggered=False, active_high=True):
|
||||||
signal.value = 1 if active_high else 0
|
signal.value = 1 if active_high else 0
|
||||||
|
await FallingEdge(regs.clk)
|
||||||
assert await xfer(reg) == 1
|
assert await xfer(reg) == 1
|
||||||
await xfer(reg, 0xfffe)
|
await xfer(reg, 0xfffe)
|
||||||
if edge_triggered:
|
if edge_triggered:
|
||||||
|
|
Loading…
Reference in New Issue