eth: Add timeout to AN implementation

Signed-off-by: Alex Forencich <alex@alexforencich.com>
This commit is contained in:
Alex Forencich
2026-07-02 01:33:35 -07:00
parent 9c5cdb990b
commit cd52e44ae2
13 changed files with 108 additions and 4 deletions

View File

@@ -83,8 +83,11 @@ module taxi_eth_mac_phy_1g_basex #
input wire logic an_en = 1'b1,
input wire logic an_restart = 1'b0,
input wire logic an_speedup = 1'b0,
input wire logic an_timeout_en = 1'b1,
output wire logic an_intr,
output wire logic an_running,
output wire logic an_complete,
output wire logic an_timeout,
input wire logic [15:0] an_adv_ability = 16'h0020,
output wire logic [15:0] an_lp_adv_ability,
@@ -434,8 +437,11 @@ if (AN_EN) begin : an
.an_en(an_en),
.an_restart(an_restart),
.an_speedup(an_speedup),
.an_timeout_en(an_timeout_en),
.an_intr(an_intr),
.an_running(an_running),
.an_complete(an_complete),
.an_timeout(an_timeout),
.an_adv_ability(an_adv_ability),
.an_lp_adv_ability(an_lp_adv_ability)
);

View File

@@ -96,8 +96,11 @@ module taxi_eth_mac_phy_1g_basex_fifo #
input wire logic an_en = 1'b1,
input wire logic an_restart = 1'b0,
input wire logic an_speedup = 1'b0,
input wire logic an_timeout_en = 1'b1,
output wire logic an_intr,
output wire logic an_running,
output wire logic an_complete,
output wire logic an_timeout,
input wire logic [15:0] an_adv_ability = 16'h0020,
output wire logic [15:0] an_lp_adv_ability,
@@ -369,8 +372,11 @@ mac_phy_inst (
.an_en(an_en),
.an_restart(an_restart),
.an_speedup(an_speedup),
.an_timeout_en(an_timeout_en),
.an_intr(an_intr),
.an_running(an_running),
.an_complete(an_complete),
.an_timeout(an_timeout),
.an_adv_ability(an_adv_ability),
.an_lp_adv_ability(an_lp_adv_ability),

View File

@@ -73,8 +73,11 @@ module taxi_eth_phy_1g_basex #
input wire logic an_en = 1'b1,
input wire logic an_restart = 1'b0,
input wire logic an_speedup = 1'b0,
input wire logic an_timeout_en = 1'b1,
output wire logic an_intr,
output wire logic an_running,
output wire logic an_complete,
output wire logic an_timeout,
input wire logic [15:0] an_adv_ability = 16'h0020,
output wire logic [15:0] an_lp_adv_ability,
@@ -164,8 +167,11 @@ if (AN_EN) begin : an
.an_en(an_en),
.an_restart(an_restart),
.an_speedup(an_speedup),
.an_timeout_en(an_timeout_en),
.an_intr(an_intr),
.an_running(an_running),
.an_complete(an_complete),
.an_timeout(an_timeout),
.an_adv_ability(an_adv_ability),
.an_lp_adv_ability(an_lp_adv_ability)
);

View File

@@ -42,8 +42,11 @@ module taxi_eth_phy_1g_basex_an #
input wire logic an_en = 1'b1,
input wire logic an_restart = 1'b0,
input wire logic an_speedup = 1'b0,
input wire logic an_timeout_en = 1'b1,
output wire logic an_intr,
output wire logic an_running,
output wire logic an_complete,
output wire logic an_timeout,
input wire logic [15:0] an_adv_ability = 16'h0020,
output wire logic [15:0] an_lp_adv_ability
);
@@ -71,19 +74,25 @@ logic [16:0] presc_cnt_reg = '0;
logic presc_pulse_reg = 1'b0;
logic [7:0] delay_cnt_reg = '0, delay_cnt_next;
logic delay_run_reg = 1'b0, delay_run_next;
logic [9:0] timeout_cnt_reg = '0, timeout_cnt_next;
logic timeout_run_reg = 1'b0, timeout_run_next;
logic [15:0] tx_an_cfg_reg = '0, tx_an_cfg_next;
logic tx_an_cfg_valid_reg = 1'b0, tx_an_cfg_valid_next;
logic an_intr_reg = 1'b0, an_intr_next;
logic an_running_reg = 1'b0, an_running_next;
logic an_complete_reg = 1'b0, an_complete_next;
logic an_timeout_reg = 1'b0, an_timeout_next;
logic [15:0] an_lp_adv_ability_reg = '0, an_lp_adv_ability_next;
assign tx_an_cfg = tx_an_cfg_reg;
assign tx_an_cfg_valid = tx_an_cfg_valid_reg;
assign an_intr = an_intr_reg;
assign an_running = an_running_reg;
assign an_complete = an_complete_reg;
assign an_timeout = an_timeout_reg;
assign an_lp_adv_ability = an_lp_adv_ability_reg;
always_comb begin
@@ -91,12 +100,16 @@ always_comb begin
delay_cnt_next = delay_cnt_reg;
delay_run_next = delay_run_reg;
timeout_cnt_next = timeout_cnt_reg;
timeout_run_next = timeout_run_reg;
tx_an_cfg_next = tx_an_cfg_reg;
tx_an_cfg_valid_next = tx_an_cfg_valid_reg && !tx_an_cfg_ready;
an_intr_next = 1'b0;
an_running_next = an_running_reg;
an_complete_next = an_complete_reg;
an_timeout_next = an_timeout_reg;
an_lp_adv_ability_next = an_lp_adv_ability_reg;
if (delay_run_reg) begin
@@ -112,10 +125,26 @@ always_comb begin
delay_cnt_next = 100;
end
if (timeout_run_reg) begin
if (presc_pulse_reg) begin
if (timeout_cnt_reg != 0) begin
timeout_cnt_next = timeout_cnt_reg - 1;
end else begin
timeout_run_next = 1'b0;
end
end
end else begin
// 100 ms timer
timeout_cnt_next = 1000;
end
case (state_reg)
STATE_START: begin
// start
an_running_next = 1'b0;
an_complete_next = 1'b0;
an_timeout_next = 1'b0;
timeout_run_next = 1'b0;
tx_an_cfg_next = '0;
@@ -128,6 +157,7 @@ always_comb begin
end else begin
// AN restart state
delay_run_next = 1'b1;
an_running_next = 1'b1;
state_next = STATE_AN_RESTART;
end
end else begin
@@ -142,6 +172,7 @@ always_comb begin
if (!delay_run_reg) begin
// link timer expired
timeout_run_next = 1'b1;
state_next = STATE_ABILITY_DET;
end else begin
state_next = STATE_AN_RESTART;
@@ -156,6 +187,10 @@ always_comb begin
// got ability advertisement from link partner
an_lp_adv_ability_next = rx_an_cfg;
state_next = STATE_ACK_DET;
end else if (!timeout_run_reg) begin
// timed out, no AN response from link partner
an_timeout_next = 1'b1;
state_next = STATE_DONE;
end else begin
state_next = STATE_ABILITY_DET;
end
@@ -200,6 +235,7 @@ always_comb begin
end
end
STATE_IDLE_DET: begin
// idle detect - wait for link to go idle
if (rx_an_ability_match && rx_an_cfg == 0) begin
// restart request from link partner
state_next = STATE_START;
@@ -212,6 +248,10 @@ always_comb begin
end
end
STATE_DONE: begin
// AN operation complete
an_running_next = 1'b0;
timeout_run_next = 1'b0;
if (rx_an_ability_match && rx_an_cfg == 0) begin
// restart request from link partner
state_next = STATE_START;
@@ -234,12 +274,16 @@ always @(posedge clk) begin
delay_cnt_reg <= delay_cnt_next;
delay_run_reg <= delay_run_next;
timeout_cnt_reg <= timeout_cnt_next;
timeout_run_reg <= timeout_run_next;
tx_an_cfg_reg <= tx_an_cfg_next;
tx_an_cfg_valid_reg <= tx_an_cfg_valid_next;
an_intr_reg <= an_intr_next;
an_running_reg <= an_running_next;
an_complete_reg <= an_complete_next;
an_timeout_reg <= an_timeout_next;
an_lp_adv_ability_reg <= an_lp_adv_ability_next;
presc_pulse_reg <= 1'b0;
@@ -257,11 +301,15 @@ always @(posedge clk) begin
presc_pulse_reg <= 1'b0;
delay_cnt_reg <= '0;
delay_run_reg <= 1'b0;
timeout_cnt_reg <= '0;
timeout_run_reg <= 1'b0;
tx_an_cfg_valid_reg <= 1'b0;
an_intr_reg <= 1'b0;
an_running_reg <= 1'b0;
an_complete_reg <= 1'b0;
an_timeout_reg <= 1'b0;
end
end

View File

@@ -137,8 +137,11 @@ module taxi_eth_mac_1g_basex_us #
input wire logic an_en[CNT] = '{CNT{1'b1}},
input wire logic an_restart[CNT] = '{CNT{1'b0}},
input wire logic an_speedup[CNT] = '{CNT{1'b0}},
input wire logic an_timeout_en[CNT] = '{CNT{1'b1}},
output wire logic an_intr[CNT],
output wire logic an_running[CNT],
output wire logic an_complete[CNT],
output wire logic an_timeout[CNT],
input wire logic [15:0] an_adv_ability[CNT] = '{CNT{16'h0020}},
output wire logic [15:0] an_lp_adv_ability[CNT],
@@ -532,8 +535,11 @@ for (genvar n = 0; n < CNT; n = n + 1) begin : ch
.an_en(an_en[n]),
.an_restart(an_restart[n]),
.an_speedup(an_speedup[n]),
.an_timeout_en(an_timeout_en[n]),
.an_intr(an_intr[n]),
.an_running(an_running[n]),
.an_complete(an_complete[n]),
.an_timeout(an_timeout[n]),
.an_adv_ability(an_adv_ability[n]),
.an_lp_adv_ability(an_lp_adv_ability[n]),

View File

@@ -150,8 +150,11 @@ module taxi_eth_mac_1g_basex_us_ch #
input wire logic an_en = 1'b1,
input wire logic an_restart = 1'b0,
input wire logic an_speedup = 1'b0,
input wire logic an_timeout_en = 1'b1,
output wire logic an_intr,
output wire logic an_running,
output wire logic an_complete,
output wire logic an_timeout,
input wire logic [15:0] an_adv_ability = 16'h0020,
output wire logic [15:0] an_lp_adv_ability,
@@ -627,8 +630,11 @@ if (COMBINED_MAC_PCS) begin : mac
.an_en(an_en),
.an_restart(an_restart),
.an_speedup(an_speedup),
.an_timeout_en(an_timeout_en),
.an_intr(an_intr),
.an_running(an_running),
.an_complete(an_complete),
.an_timeout(an_timeout),
.an_adv_ability(an_adv_ability),
.an_lp_adv_ability(an_lp_adv_ability),

View File

@@ -130,6 +130,7 @@ class TB:
dut.an_en.setimmediatevalue([0]*4)
dut.an_restart.setimmediatevalue([0]*4)
dut.an_speedup.setimmediatevalue([1]*4)
dut.an_timeout_en.setimmediatevalue([1]*4)
dut.an_adv_ability.setimmediatevalue([0x0020]*4)
dut.stat_rx_fifo_drop.setimmediatevalue([0]*4)
@@ -786,6 +787,7 @@ async def run_test_an(dut, port=0):
tb.dut.an_en[port].value = 1
tb.dut.an_restart[port].value = 0
tb.dut.an_speedup[port].value = 1
tb.dut.an_timeout_en[port].value = 1
tb.dut.an_adv_ability[port].value = 0x0020
await tb.reset()

View File

@@ -115,8 +115,11 @@ taxi_axis_if #(.DATA_W(DATA_W), .USER_EN(1), .USER_W(RX_USER_W)) m_axis_rx[CNT](
logic an_en[CNT];
logic an_restart[CNT];
logic an_speedup[CNT];
logic an_timeout_en[CNT];
logic an_intr[CNT];
logic an_running[CNT];
logic an_complete[CNT];
logic an_timeout[CNT];
logic [15:0] an_adv_ability[CNT];
logic [15:0] an_lp_adv_ability[CNT];
@@ -356,8 +359,11 @@ uut (
.an_en(an_en),
.an_restart(an_restart),
.an_speedup(an_speedup),
.an_timeout_en(an_timeout_en),
.an_intr(an_intr),
.an_running(an_running),
.an_complete(an_complete),
.an_timeout(an_timeout),
.an_adv_ability(an_adv_ability),
.an_lp_adv_ability(an_lp_adv_ability),

View File

@@ -108,6 +108,7 @@ class TB:
dut.an_en.setimmediatevalue(0)
dut.an_restart.setimmediatevalue(0)
dut.an_speedup.setimmediatevalue(1)
dut.an_timeout_en.setimmediatevalue(1)
dut.an_adv_ability.setimmediatevalue(0x0020)
dut.stat_rx_fifo_drop.setimmediatevalue(0)
@@ -715,6 +716,7 @@ async def run_test_an(dut, gbx_cfg=None):
tb.dut.an_en.value = 1
tb.dut.an_restart.value = 0
tb.dut.an_speedup.value = 1
tb.dut.an_timeout_en.value = 1
tb.dut.an_adv_ability.value = 0x0020
await tb.reset()

View File

@@ -77,8 +77,11 @@ logic serdes_rx_reset_req;
logic an_en;
logic an_restart;
logic an_speedup;
logic an_timeout_en;
logic an_intr;
logic an_running;
logic an_complete;
logic an_timeout;
logic [15:0] an_adv_ability;
logic [15:0] an_lp_adv_ability;
@@ -276,8 +279,11 @@ uut (
.an_en(an_en),
.an_restart(an_restart),
.an_speedup(an_speedup),
.an_timeout_en(an_timeout_en),
.an_intr(an_intr),
.an_running(an_running),
.an_complete(an_complete),
.an_timeout(an_timeout),
.an_adv_ability(an_adv_ability),
.an_lp_adv_ability(an_lp_adv_ability),

View File

@@ -106,6 +106,7 @@ class TB:
dut.an_en.setimmediatevalue(0)
dut.an_restart.setimmediatevalue(0)
dut.an_speedup.setimmediatevalue(1)
dut.an_timeout_en.setimmediatevalue(1)
dut.an_adv_ability.setimmediatevalue(0x0020)
dut.cfg_tx_pad_en.setimmediatevalue(0)
@@ -274,6 +275,7 @@ async def run_test_an(dut, gbx_cfg=None):
tb.dut.an_en.value = 1
tb.dut.an_restart.value = 0
tb.dut.an_speedup.value = 1
tb.dut.an_timeout_en.value = 1
tb.dut.an_adv_ability.value = 0x0020
await tb.reset()

View File

@@ -91,8 +91,11 @@ logic serdes_rx_reset_req;
logic an_en;
logic an_restart;
logic an_speedup;
logic an_timeout_en;
logic an_intr;
logic an_running;
logic an_complete;
logic an_timeout;
logic [15:0] an_adv_ability;
logic [15:0] an_lp_adv_ability;
@@ -218,8 +221,11 @@ uut (
.an_en(an_en),
.an_restart(an_restart),
.an_speedup(an_speedup),
.an_timeout_en(an_timeout_en),
.an_intr(an_intr),
.an_running(an_running),
.an_complete(an_complete),
.an_timeout(an_timeout),
.an_adv_ability(an_adv_ability),
.an_lp_adv_ability(an_lp_adv_ability),

View File

@@ -75,10 +75,11 @@ class TB:
gbx_cfg=gbx_cfg
)
dut.an_en.value = 0
dut.an_restart.value = 0
dut.an_speedup.value = 1
dut.an_adv_ability.value = 0x0020
dut.an_en.setimmediatevalue(0)
dut.an_restart.setimmediatevalue(0)
dut.an_speedup.setimmediatevalue(1)
dut.an_timeout_en.setimmediatevalue(1)
dut.an_adv_ability.setimmediatevalue(0x0020)
dut.cfg_tx_prbs31_enable.setimmediatevalue(0)
dut.cfg_rx_prbs31_enable.setimmediatevalue(0)
@@ -166,6 +167,7 @@ async def run_test_an(dut):
tb.dut.an_en.value = 1
tb.dut.an_restart.value = 0
tb.dut.an_speedup.value = 1
tb.dut.an_timeout_en.value = 1
tb.dut.an_adv_ability.value = 0x0020
await tb.reset()