mdio_regs: Fix ack/err generation

ack/err can only be combinatorial if data_read is also combinatorial.
I suspect doing that will kill my Fmax, so register ack/err.

Fixes: d9602b6 ("Add MII management functions")
Signed-off-by: Sean Anderson <seanga2@gmail.com>
This commit is contained in:
Sean Anderson 2023-03-05 20:30:14 -05:00
parent 924079cabd
commit 003e5e4b79
2 changed files with 24 additions and 15 deletions

View File

@ -90,15 +90,18 @@ module mdio_regs (
localparam VCR_LTEST = 14; localparam VCR_LTEST = 14;
integer i; integer i;
reg ack_next, err_next;
reg [15:0] data_read_next;
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 [15:0] data_read_next;
/* 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;
initial begin initial begin
ack = 0;
err = 0;
loopback = 0; loopback = 0;
pdown = 0; pdown = 0;
isolate = 1; isolate = 1;
@ -143,8 +146,8 @@ module mdio_regs (
end end
data_read_next = 0; data_read_next = 0;
ack = cyc && stb; ack_next = cyc && stb;
err = 0; err_next = 0;
case (addr) case (addr)
BMCR: begin BMCR: begin
data_read_next[BMCR_LOOPBACK] = loopback; data_read_next[BMCR_LOOPBACK] = loopback;
@ -154,7 +157,7 @@ module mdio_regs (
data_read_next[BMCR_DUPLEX] = duplex; data_read_next[BMCR_DUPLEX] = duplex;
data_read_next[BMCR_COLTEST] = coltest; data_read_next[BMCR_COLTEST] = coltest;
if (ack && we) begin if (ack_next && we) begin
loopback_next = data_write[BMCR_LOOPBACK]; loopback_next = data_write[BMCR_LOOPBACK];
pdown_next = data_write[BMCR_PDOWN]; pdown_next = data_write[BMCR_PDOWN];
isolate_next = data_write[BMCR_ISOLATE]; isolate_next = data_write[BMCR_ISOLATE];
@ -186,7 +189,7 @@ module mdio_regs (
data_read_next[BMSR_LSTATUS] = link_status_latched; data_read_next[BMSR_LSTATUS] = link_status_latched;
data_read_next[BMSR_EXTCAP] = 1; data_read_next[BMSR_EXTCAP] = 1;
if (ack && !we) if (ack_next && !we)
link_status_latched_next = link_status; link_status_latched_next = link_status;
end end
ID1: begin ID1: begin
@ -202,38 +205,38 @@ module mdio_regs (
NWCR: if (ENABLE_COUNTERS) begin NWCR: if (ENABLE_COUNTERS) begin
data_read_next = nwc; data_read_next = nwc;
if (ack) if (ack_next)
nwc_next = we ? data_write : negative_wraparound; nwc_next = we ? data_write : negative_wraparound;
end end
PWCR: if (ENABLE_COUNTERS) begin PWCR: if (ENABLE_COUNTERS) begin
data_read_next = pwc; data_read_next = pwc;
if (ack) if (ack_next)
pwc_next = we ? data_write : positive_wraparound; pwc_next = we ? data_write : positive_wraparound;
end end
DCR: if (ENABLE_COUNTERS) begin DCR: if (ENABLE_COUNTERS) begin
data_read_next = dc; data_read_next = dc;
if (ack) if (ack_next)
dc_next = we ? data_write : disconnect; dc_next = we ? data_write : disconnect;
end end
FCCR: if (ENABLE_COUNTERS) begin FCCR: if (ENABLE_COUNTERS) begin
data_read_next = fcc; data_read_next = fcc;
if (ack) if (ack_next)
fcc_next = we ? data_write : false_carrier; fcc_next = we ? data_write : false_carrier;
end end
SECR: if (ENABLE_COUNTERS) begin SECR: if (ENABLE_COUNTERS) begin
data_read_next = sec; data_read_next = sec;
if (ack) if (ack_next)
sec_next = we ? data_write : symbol_error; sec_next = we ? data_write : symbol_error;
end end
VCR: begin VCR: begin
data_read_next[VCR_DTEST] = descrambler_test; data_read_next[VCR_DTEST] = descrambler_test;
data_read_next[VCR_LTEST] = link_monitor_test; data_read_next[VCR_LTEST] = link_monitor_test;
if (ack && we) begin if (ack_next && we) begin
descrambler_test_next = data_write[VCR_DTEST]; descrambler_test_next = data_write[VCR_DTEST];
link_monitor_test_next = data_write[VCR_LTEST]; link_monitor_test_next = data_write[VCR_LTEST];
end end
@ -242,8 +245,8 @@ module mdio_regs (
if (EMULATE_PULLUP) begin if (EMULATE_PULLUP) begin
data_read_next = 16'hFFFF; data_read_next = 16'hFFFF;
end else begin end else begin
err = ack; err_next = ack_next;
ack = 0; ack_next = 0;
data_read_next = 16'hXXXX; data_read_next = 16'hXXXX;
end end
end end
@ -258,6 +261,8 @@ module mdio_regs (
coltest <= coltest_next; coltest <= coltest_next;
link_status_latched <= link_status_latched_next; link_status_latched <= link_status_latched_next;
link_status_last <= link_status; link_status_last <= link_status;
ack <= ack_next;
err <= err_next;
data_read <= data_read_next; data_read <= data_read_next;
if (ENABLE_COUNTERS) begin if (ENABLE_COUNTERS) begin
nwc <= nwc_next; nwc <= nwc_next;

View File

@ -37,7 +37,7 @@ BMSR_EXTCAP = BIT(0)
VCR_DTEST = BIT(15) VCR_DTEST = BIT(15)
VCR_LTEST = BIT(14) VCR_LTEST = BIT(14)
async def wb_xfer(signals, addr, data=None): async def wb_xfer(signals, addr, data=None, delay=1):
await FallingEdge(signals['clk']) await FallingEdge(signals['clk'])
signals['stb'].value = 1 signals['stb'].value = 1
signals['addr'].value = addr signals['addr'].value = addr
@ -47,7 +47,11 @@ async def wb_xfer(signals, addr, data=None):
signals['we'].value = 1 signals['we'].value = 1
signals['data_write'].value = data signals['data_write'].value = data
await FallingEdge(signals['clk']) for _ in range(delay + 1):
await FallingEdge(signals['clk'])
if signals['ack'].value or signals['err'].value:
break
assert signals['ack'].value or signals['err'].value assert signals['ack'].value or signals['err'].value
signals['stb'].value = 0 signals['stb'].value = 0
signals['we'].value = LogicArray('X') signals['we'].value = LogicArray('X')