mirror of
https://github.com/fpganinja/taxi.git
synced 2025-12-09 08:58:40 -08:00
eth: Fix bugs in 10G MAC RX related to short IFGs
Signed-off-by: Alex Forencich <alex@alexforencich.com>
This commit is contained in:
@@ -160,6 +160,10 @@ logic [DATA_W-1:0] input_data_d1 = '0;
|
|||||||
logic [3:0] input_type_d0 = INPUT_TYPE_IDLE;
|
logic [3:0] input_type_d0 = INPUT_TYPE_IDLE;
|
||||||
logic [3:0] input_type_d1 = INPUT_TYPE_IDLE;
|
logic [3:0] input_type_d1 = INPUT_TYPE_IDLE;
|
||||||
|
|
||||||
|
logic input_start_swap = 1'b0;
|
||||||
|
logic input_start_d0 = 1'b0;
|
||||||
|
logic input_start_d1 = 1'b0;
|
||||||
|
|
||||||
logic [DATA_W-1:0] m_axis_rx_tdata_reg = '0, m_axis_rx_tdata_next;
|
logic [DATA_W-1:0] m_axis_rx_tdata_reg = '0, m_axis_rx_tdata_next;
|
||||||
logic [KEEP_W-1:0] m_axis_rx_tkeep_reg = '0, m_axis_rx_tkeep_next;
|
logic [KEEP_W-1:0] m_axis_rx_tkeep_reg = '0, m_axis_rx_tkeep_next;
|
||||||
logic m_axis_rx_tvalid_reg = 1'b0, m_axis_rx_tvalid_next;
|
logic m_axis_rx_tvalid_reg = 1'b0, m_axis_rx_tvalid_next;
|
||||||
@@ -279,7 +283,7 @@ always_comb begin
|
|||||||
// idle state - wait for packet
|
// idle state - wait for packet
|
||||||
reset_crc = 1'b1;
|
reset_crc = 1'b1;
|
||||||
|
|
||||||
if (input_type_d1 == INPUT_TYPE_START_0 && cfg_rx_enable) begin
|
if (input_start_d1 && cfg_rx_enable) begin
|
||||||
// start condition
|
// start condition
|
||||||
reset_crc = 1'b0;
|
reset_crc = 1'b0;
|
||||||
state_next = STATE_PAYLOAD;
|
state_next = STATE_PAYLOAD;
|
||||||
@@ -401,6 +405,9 @@ always_ff @(posedge clk) begin
|
|||||||
|
|
||||||
swap_data <= encoded_rx_data_masked[63:32];
|
swap_data <= encoded_rx_data_masked[63:32];
|
||||||
|
|
||||||
|
input_start_swap <= 1'b0;
|
||||||
|
input_start_d0 <= input_start_swap;
|
||||||
|
|
||||||
if (PTP_TS_EN && PTP_TS_FMT_TOD) begin
|
if (PTP_TS_EN && PTP_TS_FMT_TOD) begin
|
||||||
// ns field rollover
|
// ns field rollover
|
||||||
ptp_ts_adj_reg[15:0] <= ptp_ts_reg[15:0];
|
ptp_ts_adj_reg[15:0] <= ptp_ts_reg[15:0];
|
||||||
@@ -409,21 +416,17 @@ always_ff @(posedge clk) begin
|
|||||||
ptp_ts_adj_reg[95:48] <= ptp_ts_reg[95:48] + 1;
|
ptp_ts_adj_reg[95:48] <= ptp_ts_reg[95:48] + 1;
|
||||||
end
|
end
|
||||||
|
|
||||||
|
// start control character detection
|
||||||
if (encoded_rx_hdr == SYNC_CTRL && encoded_rx_data[7:0] == BLOCK_TYPE_START_0) begin
|
if (encoded_rx_hdr == SYNC_CTRL && encoded_rx_data[7:0] == BLOCK_TYPE_START_0) begin
|
||||||
lanes_swapped <= 1'b0;
|
lanes_swapped <= 1'b0;
|
||||||
input_type_d0 <= INPUT_TYPE_START_0;
|
input_start_d0 <= 1'b1;
|
||||||
input_data_d0 <= encoded_rx_data_masked;
|
|
||||||
end else if (encoded_rx_hdr == SYNC_CTRL && (encoded_rx_data[7:0] == BLOCK_TYPE_START_4 || encoded_rx_data[7:0] == BLOCK_TYPE_OS_START)) begin
|
end else if (encoded_rx_hdr == SYNC_CTRL && (encoded_rx_data[7:0] == BLOCK_TYPE_START_4 || encoded_rx_data[7:0] == BLOCK_TYPE_OS_START)) begin
|
||||||
lanes_swapped <= 1'b1;
|
lanes_swapped <= 1'b1;
|
||||||
delay_type_valid <= 1'b1;
|
input_start_swap <= 1'b1;
|
||||||
|
end
|
||||||
|
|
||||||
if (delay_type_valid) begin
|
// lane swapping and termination character detection
|
||||||
input_type_d0 <= delay_type;
|
if (lanes_swapped) begin
|
||||||
end else begin
|
|
||||||
input_type_d0 <= INPUT_TYPE_IDLE;
|
|
||||||
end
|
|
||||||
input_data_d0 <= {encoded_rx_data_masked[31:0], swap_data};
|
|
||||||
end else if (lanes_swapped) begin
|
|
||||||
if (delay_type_valid) begin
|
if (delay_type_valid) begin
|
||||||
input_type_d0 <= delay_type;
|
input_type_d0 <= delay_type;
|
||||||
end else if (encoded_rx_hdr == SYNC_DATA) begin
|
end else if (encoded_rx_hdr == SYNC_DATA) begin
|
||||||
@@ -616,7 +619,8 @@ always_ff @(posedge clk) begin
|
|||||||
input_type_d0 <= INPUT_TYPE_ERROR;
|
input_type_d0 <= INPUT_TYPE_ERROR;
|
||||||
end
|
end
|
||||||
|
|
||||||
if (delay_type == INPUT_TYPE_START_0 && delay_type_valid) begin
|
// capture timestamps
|
||||||
|
if (input_start_swap) begin
|
||||||
start_packet_reg <= 2'b10;
|
start_packet_reg <= 2'b10;
|
||||||
if (PTP_TS_FMT_TOD) begin
|
if (PTP_TS_FMT_TOD) begin
|
||||||
ptp_ts_reg[45:0] <= ptp_ts[45:0] + 46'(ts_inc_reg >> 1);
|
ptp_ts_reg[45:0] <= ptp_ts[45:0] + 46'(ts_inc_reg >> 1);
|
||||||
@@ -626,14 +630,13 @@ always_ff @(posedge clk) begin
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
if (input_type_d0 == INPUT_TYPE_START_0) begin
|
if (input_start_d0 && !lanes_swapped) begin
|
||||||
if (!lanes_swapped) begin
|
start_packet_reg <= 2'b01;
|
||||||
start_packet_reg <= 2'b01;
|
ptp_ts_reg <= ptp_ts;
|
||||||
ptp_ts_reg <= ptp_ts;
|
|
||||||
end
|
|
||||||
end
|
end
|
||||||
|
|
||||||
input_type_d1 <= input_type_d0;
|
input_type_d1 <= input_type_d0;
|
||||||
|
input_start_d1 <= input_start_d0;
|
||||||
input_data_d1 <= input_data_d0;
|
input_data_d1 <= input_data_d0;
|
||||||
|
|
||||||
if (reset_crc) begin
|
if (reset_crc) begin
|
||||||
@@ -662,6 +665,10 @@ always_ff @(posedge clk) begin
|
|||||||
input_type_d0 <= INPUT_TYPE_IDLE;
|
input_type_d0 <= INPUT_TYPE_IDLE;
|
||||||
input_type_d1 <= INPUT_TYPE_IDLE;
|
input_type_d1 <= INPUT_TYPE_IDLE;
|
||||||
|
|
||||||
|
input_start_swap <= 1'b0;
|
||||||
|
input_start_d0 <= 1'b0;
|
||||||
|
input_start_d1 <= 1'b0;
|
||||||
|
|
||||||
lanes_swapped <= 1'b0;
|
lanes_swapped <= 1'b0;
|
||||||
|
|
||||||
delay_type_valid <= 1'b0;
|
delay_type_valid <= 1'b0;
|
||||||
|
|||||||
@@ -326,6 +326,19 @@ always_ff @(posedge clk) begin
|
|||||||
ptp_ts_adj_reg[95:48] <= ptp_ts_reg[95:48] + 1;
|
ptp_ts_adj_reg[95:48] <= ptp_ts_reg[95:48] + 1;
|
||||||
end
|
end
|
||||||
|
|
||||||
|
// start control character detection
|
||||||
|
if (xgmii_rxc[0] && xgmii_rxd[7:0] == XGMII_START) begin
|
||||||
|
lanes_swapped <= 1'b0;
|
||||||
|
xgmii_start_d0 <= 1'b1;
|
||||||
|
|
||||||
|
framing_error_reg <= xgmii_rxc[7:1] != 0;
|
||||||
|
end else if (xgmii_rxc[4] && xgmii_rxd[39:32] == XGMII_START) begin
|
||||||
|
lanes_swapped <= 1'b1;
|
||||||
|
xgmii_start_swap <= 1'b1;
|
||||||
|
|
||||||
|
framing_error_reg <= xgmii_rxc[7:5] != 0;
|
||||||
|
end
|
||||||
|
|
||||||
// lane swapping and termination character detection
|
// lane swapping and termination character detection
|
||||||
if (lanes_swapped) begin
|
if (lanes_swapped) begin
|
||||||
xgmii_rxd_d0 <= {xgmii_rxd_masked[31:0], swap_rxd};
|
xgmii_rxd_d0 <= {xgmii_rxd_masked[31:0], swap_rxd};
|
||||||
@@ -340,7 +353,6 @@ always_ff @(posedge clk) begin
|
|||||||
term_lane_reg <= 3'(i);
|
term_lane_reg <= 3'(i);
|
||||||
term_present_reg <= 1'b1;
|
term_present_reg <= 1'b1;
|
||||||
framing_error_reg <= ({xgmii_rxc[3:0], swap_rxc} & ({CTRL_W{1'b1}} >> (CTRL_W-i))) != 0;
|
framing_error_reg <= ({xgmii_rxc[3:0], swap_rxc} & ({CTRL_W{1'b1}} >> (CTRL_W-i))) != 0;
|
||||||
lanes_swapped <= 1'b0;
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end else begin
|
end else begin
|
||||||
@@ -356,30 +368,10 @@ always_ff @(posedge clk) begin
|
|||||||
term_lane_reg <= 3'(i);
|
term_lane_reg <= 3'(i);
|
||||||
term_present_reg <= 1'b1;
|
term_present_reg <= 1'b1;
|
||||||
framing_error_reg <= (xgmii_rxc & ({CTRL_W{1'b1}} >> (CTRL_W-i))) != 0;
|
framing_error_reg <= (xgmii_rxc & ({CTRL_W{1'b1}} >> (CTRL_W-i))) != 0;
|
||||||
lanes_swapped <= 1'b0;
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
// start control character detection
|
|
||||||
if (xgmii_rxc[0] && xgmii_rxd[7:0] == XGMII_START) begin
|
|
||||||
lanes_swapped <= 1'b0;
|
|
||||||
|
|
||||||
xgmii_start_d0 <= 1'b1;
|
|
||||||
|
|
||||||
term_lane_reg <= 0;
|
|
||||||
term_present_reg <= 1'b0;
|
|
||||||
framing_error_reg <= xgmii_rxc[7:1] != 0;
|
|
||||||
end else if (xgmii_rxc[4] && xgmii_rxd[39:32] == XGMII_START) begin
|
|
||||||
lanes_swapped <= 1'b1;
|
|
||||||
|
|
||||||
xgmii_start_swap <= 1'b1;
|
|
||||||
|
|
||||||
term_lane_reg <= 0;
|
|
||||||
term_present_reg <= 1'b0;
|
|
||||||
framing_error_reg <= xgmii_rxc[7:5] != 0;
|
|
||||||
end
|
|
||||||
|
|
||||||
// capture timestamps
|
// capture timestamps
|
||||||
if (xgmii_start_swap) begin
|
if (xgmii_start_swap) begin
|
||||||
start_packet_reg <= 2'b10;
|
start_packet_reg <= 2'b10;
|
||||||
|
|||||||
@@ -109,7 +109,7 @@ async def run_test(dut, payload_lengths=None, payload_data=None, ifg=12):
|
|||||||
|
|
||||||
|
|
||||||
def size_list():
|
def size_list():
|
||||||
return list(range(60, 128)) + [512, 1514, 9214] + [60]*10
|
return list(range(60, 128)) + [512, 1514, 9214] + [60]*10 + [i for i in range(64, 73) for k in range(8)]
|
||||||
|
|
||||||
|
|
||||||
def incrementing_payload(length):
|
def incrementing_payload(length):
|
||||||
@@ -125,7 +125,7 @@ if cocotb.SIM_NAME:
|
|||||||
factory = TestFactory(run_test)
|
factory = TestFactory(run_test)
|
||||||
factory.add_option("payload_lengths", [size_list])
|
factory.add_option("payload_lengths", [size_list])
|
||||||
factory.add_option("payload_data", [incrementing_payload])
|
factory.add_option("payload_data", [incrementing_payload])
|
||||||
factory.add_option("ifg", [12, 0])
|
factory.add_option("ifg", list(range(0, 13)))
|
||||||
factory.generate_tests()
|
factory.generate_tests()
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -94,7 +94,7 @@ async def run_test(dut, payload_lengths=None, payload_data=None, ifg=12):
|
|||||||
|
|
||||||
|
|
||||||
def size_list():
|
def size_list():
|
||||||
return list(range(60, 128)) + [512, 1514, 9214] + [60]*10
|
return list(range(60, 128)) + [512, 1514, 9214] + [60]*10 + [i for i in range(64, 73) for k in range(8)]
|
||||||
|
|
||||||
|
|
||||||
def incrementing_payload(length):
|
def incrementing_payload(length):
|
||||||
@@ -110,7 +110,7 @@ if cocotb.SIM_NAME:
|
|||||||
factory = TestFactory(run_test)
|
factory = TestFactory(run_test)
|
||||||
factory.add_option("payload_lengths", [size_list])
|
factory.add_option("payload_lengths", [size_list])
|
||||||
factory.add_option("payload_data", [incrementing_payload])
|
factory.add_option("payload_data", [incrementing_payload])
|
||||||
factory.add_option("ifg", [12, 0])
|
factory.add_option("ifg", list(range(0, 13)))
|
||||||
factory.generate_tests()
|
factory.generate_tests()
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -98,7 +98,7 @@ async def run_test(dut, payload_lengths=None, payload_data=None, ifg=12):
|
|||||||
|
|
||||||
|
|
||||||
def size_list():
|
def size_list():
|
||||||
return list(range(60, 128)) + [512, 1514, 9214] + [60]*10
|
return list(range(60, 128)) + [512, 1514, 9214] + [60]*10 + [i for i in range(64, 73) for k in range(8)]
|
||||||
|
|
||||||
|
|
||||||
def incrementing_payload(length):
|
def incrementing_payload(length):
|
||||||
@@ -114,7 +114,7 @@ if cocotb.SIM_NAME:
|
|||||||
factory = TestFactory(run_test)
|
factory = TestFactory(run_test)
|
||||||
factory.add_option("payload_lengths", [size_list])
|
factory.add_option("payload_lengths", [size_list])
|
||||||
factory.add_option("payload_data", [incrementing_payload])
|
factory.add_option("payload_data", [incrementing_payload])
|
||||||
factory.add_option("ifg", [12, 0])
|
factory.add_option("ifg", list(range(0, 13)))
|
||||||
factory.generate_tests()
|
factory.generate_tests()
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user