mirror of
https://github.com/alexforencich/verilog-ethernet.git
synced 2025-01-28 07:03:08 +08:00
Rework termination character handling in XGMII RX modules
Signed-off-by: Alex Forencich <alex@alexforencich.com>
This commit is contained in:
parent
12744433de
commit
f37bb1fc8d
@ -111,10 +111,9 @@ reg [1:0] state_reg = STATE_IDLE, state_next;
|
|||||||
// datapath control signals
|
// datapath control signals
|
||||||
reg reset_crc;
|
reg reset_crc;
|
||||||
|
|
||||||
reg [3:0] last_cycle_tkeep_reg = 4'd0, last_cycle_tkeep_next;
|
reg [1:0] term_lane_reg = 0, term_lane_d0_reg = 0;
|
||||||
|
reg term_present_reg = 1'b0;
|
||||||
reg [DATA_WIDTH-1:0] xgmii_rxd_masked = {DATA_WIDTH{1'b0}};
|
reg framing_error_reg = 1'b0;
|
||||||
reg [CTRL_WIDTH-1:0] xgmii_term = {CTRL_WIDTH{1'b0}};
|
|
||||||
|
|
||||||
reg [DATA_WIDTH-1:0] xgmii_rxd_d0 = {DATA_WIDTH{1'b0}};
|
reg [DATA_WIDTH-1:0] xgmii_rxd_d0 = {DATA_WIDTH{1'b0}};
|
||||||
reg [DATA_WIDTH-1:0] xgmii_rxd_d1 = {DATA_WIDTH{1'b0}};
|
reg [DATA_WIDTH-1:0] xgmii_rxd_d1 = {DATA_WIDTH{1'b0}};
|
||||||
@ -176,63 +175,11 @@ eth_crc (
|
|||||||
.state_out(crc_next)
|
.state_out(crc_next)
|
||||||
);
|
);
|
||||||
|
|
||||||
// Mask input data
|
|
||||||
integer j;
|
|
||||||
|
|
||||||
always @* begin
|
|
||||||
for (j = 0; j < 4; j = j + 1) begin
|
|
||||||
xgmii_rxd_masked[j*8 +: 8] = xgmii_rxc[j] ? 8'd0 : xgmii_rxd[j*8 +: 8];
|
|
||||||
xgmii_term[j] = xgmii_rxc[j] && (xgmii_rxd[j*8 +: 8] == XGMII_TERM);
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
// detect control characters
|
|
||||||
reg [3:0] detect_term = 4'd0;
|
|
||||||
|
|
||||||
reg [3:0] detect_term_save;
|
|
||||||
|
|
||||||
integer i;
|
|
||||||
|
|
||||||
// mask errors to within packet
|
|
||||||
reg [3:0] control_masked;
|
|
||||||
reg [3:0] tkeep_mask;
|
|
||||||
|
|
||||||
always @* begin
|
|
||||||
casez (detect_term)
|
|
||||||
4'b0000: begin
|
|
||||||
control_masked = xgmii_rxc_d0;
|
|
||||||
tkeep_mask = 4'b1111;
|
|
||||||
end
|
|
||||||
4'bzzz1: begin
|
|
||||||
control_masked = 0;
|
|
||||||
tkeep_mask = 4'b0000;
|
|
||||||
end
|
|
||||||
4'bzz10: begin
|
|
||||||
control_masked = xgmii_rxc_d0[0];
|
|
||||||
tkeep_mask = 4'b0001;
|
|
||||||
end
|
|
||||||
4'bz100: begin
|
|
||||||
control_masked = xgmii_rxc_d0[1:0];
|
|
||||||
tkeep_mask = 4'b0011;
|
|
||||||
end
|
|
||||||
4'b1000: begin
|
|
||||||
control_masked = xgmii_rxc_d0[2:0];
|
|
||||||
tkeep_mask = 4'b0111;
|
|
||||||
end
|
|
||||||
default: begin
|
|
||||||
control_masked = xgmii_rxc_d0;
|
|
||||||
tkeep_mask = 4'b1111;
|
|
||||||
end
|
|
||||||
endcase
|
|
||||||
end
|
|
||||||
|
|
||||||
always @* begin
|
always @* begin
|
||||||
state_next = STATE_IDLE;
|
state_next = STATE_IDLE;
|
||||||
|
|
||||||
reset_crc = 1'b0;
|
reset_crc = 1'b0;
|
||||||
|
|
||||||
last_cycle_tkeep_next = last_cycle_tkeep_reg;
|
|
||||||
|
|
||||||
m_axis_tdata_next = {DATA_WIDTH{1'b0}};
|
m_axis_tdata_next = {DATA_WIDTH{1'b0}};
|
||||||
m_axis_tkeep_next = {KEEP_WIDTH{1'b1}};
|
m_axis_tkeep_next = {KEEP_WIDTH{1'b1}};
|
||||||
m_axis_tvalid_next = 1'b0;
|
m_axis_tvalid_next = 1'b0;
|
||||||
@ -251,7 +198,7 @@ always @* begin
|
|||||||
|
|
||||||
if (xgmii_start_d2 && cfg_rx_enable) begin
|
if (xgmii_start_d2 && cfg_rx_enable) begin
|
||||||
// start condition
|
// start condition
|
||||||
if (control_masked) begin
|
if (framing_error_reg) begin
|
||||||
// control or error characters in first data word
|
// control or error characters in first data word
|
||||||
m_axis_tdata_next = {DATA_WIDTH{1'b0}};
|
m_axis_tdata_next = {DATA_WIDTH{1'b0}};
|
||||||
m_axis_tkeep_next = 4'h1;
|
m_axis_tkeep_next = 4'h1;
|
||||||
@ -284,25 +231,20 @@ always @* begin
|
|||||||
m_axis_tlast_next = 1'b0;
|
m_axis_tlast_next = 1'b0;
|
||||||
m_axis_tuser_next[0] = 1'b0;
|
m_axis_tuser_next[0] = 1'b0;
|
||||||
|
|
||||||
last_cycle_tkeep_next = tkeep_mask;
|
if (framing_error_reg) begin
|
||||||
|
|
||||||
if (detect_term) begin
|
|
||||||
reset_crc = 1'b1;
|
|
||||||
end
|
|
||||||
|
|
||||||
if (control_masked) begin
|
|
||||||
// control or error characters in packet
|
// control or error characters in packet
|
||||||
m_axis_tlast_next = 1'b1;
|
m_axis_tlast_next = 1'b1;
|
||||||
m_axis_tuser_next[0] = 1'b1;
|
m_axis_tuser_next[0] = 1'b1;
|
||||||
error_bad_frame_next = 1'b1;
|
error_bad_frame_next = 1'b1;
|
||||||
reset_crc = 1'b1;
|
reset_crc = 1'b1;
|
||||||
state_next = STATE_IDLE;
|
state_next = STATE_IDLE;
|
||||||
end else if (detect_term) begin
|
end else if (term_present_reg) begin
|
||||||
if (detect_term[0]) begin
|
reset_crc = 1'b1;
|
||||||
|
if (term_lane_reg == 0) begin
|
||||||
// end this cycle
|
// end this cycle
|
||||||
m_axis_tkeep_next = 4'b1111;
|
m_axis_tkeep_next = 4'b1111;
|
||||||
m_axis_tlast_next = 1'b1;
|
m_axis_tlast_next = 1'b1;
|
||||||
if (detect_term[0] && crc_valid_save[3]) begin
|
if (term_lane_reg == 0 && crc_valid_save[3]) begin
|
||||||
// CRC valid
|
// CRC valid
|
||||||
end else begin
|
end else begin
|
||||||
m_axis_tuser_next[0] = 1'b1;
|
m_axis_tuser_next[0] = 1'b1;
|
||||||
@ -321,16 +263,16 @@ always @* begin
|
|||||||
STATE_LAST: begin
|
STATE_LAST: begin
|
||||||
// last cycle of packet
|
// last cycle of packet
|
||||||
m_axis_tdata_next = xgmii_rxd_d2;
|
m_axis_tdata_next = xgmii_rxd_d2;
|
||||||
m_axis_tkeep_next = last_cycle_tkeep_reg;
|
m_axis_tkeep_next = {KEEP_WIDTH{1'b1}} >> (CTRL_WIDTH-term_lane_d0_reg);
|
||||||
m_axis_tvalid_next = 1'b1;
|
m_axis_tvalid_next = 1'b1;
|
||||||
m_axis_tlast_next = 1'b1;
|
m_axis_tlast_next = 1'b1;
|
||||||
m_axis_tuser_next[0] = 1'b0;
|
m_axis_tuser_next[0] = 1'b0;
|
||||||
|
|
||||||
reset_crc = 1'b1;
|
reset_crc = 1'b1;
|
||||||
|
|
||||||
if ((detect_term_save[1] && crc_valid_save[0]) ||
|
if ((term_lane_d0_reg == 1 && crc_valid_save[0]) ||
|
||||||
(detect_term_save[2] && crc_valid_save[1]) ||
|
(term_lane_d0_reg == 2 && crc_valid_save[1]) ||
|
||||||
(detect_term_save[3] && crc_valid_save[2])) begin
|
(term_lane_d0_reg == 3 && crc_valid_save[2])) begin
|
||||||
// CRC valid
|
// CRC valid
|
||||||
end else begin
|
end else begin
|
||||||
m_axis_tuser_next[0] = 1'b1;
|
m_axis_tuser_next[0] = 1'b1;
|
||||||
@ -343,6 +285,8 @@ always @* begin
|
|||||||
endcase
|
endcase
|
||||||
end
|
end
|
||||||
|
|
||||||
|
integer i;
|
||||||
|
|
||||||
always @(posedge clk) begin
|
always @(posedge clk) begin
|
||||||
state_reg <= state_next;
|
state_reg <= state_next;
|
||||||
|
|
||||||
@ -356,10 +300,19 @@ always @(posedge clk) begin
|
|||||||
error_bad_frame_reg <= error_bad_frame_next;
|
error_bad_frame_reg <= error_bad_frame_next;
|
||||||
error_bad_fcs_reg <= error_bad_fcs_next;
|
error_bad_fcs_reg <= error_bad_fcs_next;
|
||||||
|
|
||||||
last_cycle_tkeep_reg <= last_cycle_tkeep_next;
|
term_lane_reg <= 0;
|
||||||
|
term_present_reg <= 1'b0;
|
||||||
|
framing_error_reg <= xgmii_rxc != 0;
|
||||||
|
|
||||||
detect_term <= xgmii_term;
|
for (i = CTRL_WIDTH-1; i >= 0; i = i - 1) begin
|
||||||
detect_term_save <= detect_term;
|
if (xgmii_rxc[i] && (xgmii_rxd[i*8 +: 8] == XGMII_TERM)) begin
|
||||||
|
term_lane_reg <= i;
|
||||||
|
term_present_reg <= 1'b1;
|
||||||
|
framing_error_reg <= (xgmii_rxc & ({CTRL_WIDTH{1'b1}} >> (CTRL_WIDTH-i))) != 0;
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
term_lane_d0_reg <= term_lane_reg;
|
||||||
|
|
||||||
if (reset_crc) begin
|
if (reset_crc) begin
|
||||||
crc_state <= 32'hFFFFFFFF;
|
crc_state <= 32'hFFFFFFFF;
|
||||||
@ -369,7 +322,9 @@ always @(posedge clk) begin
|
|||||||
|
|
||||||
crc_valid_save <= crc_valid;
|
crc_valid_save <= crc_valid;
|
||||||
|
|
||||||
xgmii_rxd_d0 <= xgmii_rxd_masked;
|
for (i = 0; i < CTRL_WIDTH; i = i + 1) begin
|
||||||
|
xgmii_rxd_d0[i*8 +: 8] <= xgmii_rxc[i] ? 8'd0 : xgmii_rxd[i*8 +: 8];
|
||||||
|
end
|
||||||
xgmii_rxc_d0 <= xgmii_rxc;
|
xgmii_rxc_d0 <= xgmii_rxc;
|
||||||
xgmii_rxd_d1 <= xgmii_rxd_d0;
|
xgmii_rxd_d1 <= xgmii_rxd_d0;
|
||||||
xgmii_rxd_d2 <= xgmii_rxd_d1;
|
xgmii_rxd_d2 <= xgmii_rxd_d1;
|
||||||
|
@ -112,8 +112,6 @@ reg [1:0] state_reg = STATE_IDLE, state_next;
|
|||||||
// datapath control signals
|
// datapath control signals
|
||||||
reg reset_crc;
|
reg reset_crc;
|
||||||
|
|
||||||
reg [7:0] last_cycle_tkeep_reg = 8'd0, last_cycle_tkeep_next;
|
|
||||||
|
|
||||||
reg lanes_swapped = 1'b0;
|
reg lanes_swapped = 1'b0;
|
||||||
reg [31:0] swap_rxd = 32'd0;
|
reg [31:0] swap_rxd = 32'd0;
|
||||||
reg [3:0] swap_rxc = 4'd0;
|
reg [3:0] swap_rxc = 4'd0;
|
||||||
@ -121,6 +119,9 @@ reg [3:0] swap_rxc_term = 4'd0;
|
|||||||
|
|
||||||
reg [DATA_WIDTH-1:0] xgmii_rxd_masked = {DATA_WIDTH{1'b0}};
|
reg [DATA_WIDTH-1:0] xgmii_rxd_masked = {DATA_WIDTH{1'b0}};
|
||||||
reg [CTRL_WIDTH-1:0] xgmii_term = {CTRL_WIDTH{1'b0}};
|
reg [CTRL_WIDTH-1:0] xgmii_term = {CTRL_WIDTH{1'b0}};
|
||||||
|
reg [2:0] term_lane_reg = 0, term_lane_d0_reg = 0;
|
||||||
|
reg term_present_reg = 1'b0;
|
||||||
|
reg framing_error_reg = 1'b0;
|
||||||
|
|
||||||
reg [DATA_WIDTH-1:0] xgmii_rxd_d0 = {DATA_WIDTH{1'b0}};
|
reg [DATA_WIDTH-1:0] xgmii_rxd_d0 = {DATA_WIDTH{1'b0}};
|
||||||
reg [DATA_WIDTH-1:0] xgmii_rxd_d1 = {DATA_WIDTH{1'b0}};
|
reg [DATA_WIDTH-1:0] xgmii_rxd_d1 = {DATA_WIDTH{1'b0}};
|
||||||
@ -197,69 +198,11 @@ always @* begin
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
// detect control characters
|
|
||||||
reg [7:0] detect_term = 8'd0;
|
|
||||||
|
|
||||||
reg [7:0] detect_term_save = 8'd0;
|
|
||||||
|
|
||||||
integer i;
|
|
||||||
|
|
||||||
// mask errors to within packet
|
|
||||||
reg [7:0] control_masked;
|
|
||||||
reg [7:0] tkeep_mask;
|
|
||||||
|
|
||||||
always @* begin
|
|
||||||
casez (detect_term)
|
|
||||||
8'b00000000: begin
|
|
||||||
control_masked = xgmii_rxc_d0;
|
|
||||||
tkeep_mask = 8'b11111111;
|
|
||||||
end
|
|
||||||
8'bzzzzzzz1: begin
|
|
||||||
control_masked = 0;
|
|
||||||
tkeep_mask = 8'b00000000;
|
|
||||||
end
|
|
||||||
8'bzzzzzz10: begin
|
|
||||||
control_masked = xgmii_rxc_d0[0];
|
|
||||||
tkeep_mask = 8'b00000001;
|
|
||||||
end
|
|
||||||
8'bzzzzz100: begin
|
|
||||||
control_masked = xgmii_rxc_d0[1:0];
|
|
||||||
tkeep_mask = 8'b00000011;
|
|
||||||
end
|
|
||||||
8'bzzzz1000: begin
|
|
||||||
control_masked = xgmii_rxc_d0[2:0];
|
|
||||||
tkeep_mask = 8'b00000111;
|
|
||||||
end
|
|
||||||
8'bzzz10000: begin
|
|
||||||
control_masked = xgmii_rxc_d0[3:0];
|
|
||||||
tkeep_mask = 8'b00001111;
|
|
||||||
end
|
|
||||||
8'bzz100000: begin
|
|
||||||
control_masked = xgmii_rxc_d0[4:0];
|
|
||||||
tkeep_mask = 8'b00011111;
|
|
||||||
end
|
|
||||||
8'bz1000000: begin
|
|
||||||
control_masked = xgmii_rxc_d0[5:0];
|
|
||||||
tkeep_mask = 8'b00111111;
|
|
||||||
end
|
|
||||||
8'b10000000: begin
|
|
||||||
control_masked = xgmii_rxc_d0[6:0];
|
|
||||||
tkeep_mask = 8'b01111111;
|
|
||||||
end
|
|
||||||
default: begin
|
|
||||||
control_masked = xgmii_rxc_d0;
|
|
||||||
tkeep_mask = 8'b11111111;
|
|
||||||
end
|
|
||||||
endcase
|
|
||||||
end
|
|
||||||
|
|
||||||
always @* begin
|
always @* begin
|
||||||
state_next = STATE_IDLE;
|
state_next = STATE_IDLE;
|
||||||
|
|
||||||
reset_crc = 1'b0;
|
reset_crc = 1'b0;
|
||||||
|
|
||||||
last_cycle_tkeep_next = last_cycle_tkeep_reg;
|
|
||||||
|
|
||||||
m_axis_tdata_next = {DATA_WIDTH{1'b0}};
|
m_axis_tdata_next = {DATA_WIDTH{1'b0}};
|
||||||
m_axis_tkeep_next = {KEEP_WIDTH{1'b1}};
|
m_axis_tkeep_next = {KEEP_WIDTH{1'b1}};
|
||||||
m_axis_tvalid_next = 1'b0;
|
m_axis_tvalid_next = 1'b0;
|
||||||
@ -282,7 +225,7 @@ always @* begin
|
|||||||
m_axis_tuser_next[1 +: PTP_TS_WIDTH] = (PTP_TS_WIDTH != 96 || ptp_ts_borrow_reg) ? ptp_ts_reg : ptp_ts_adj_reg;
|
m_axis_tuser_next[1 +: PTP_TS_WIDTH] = (PTP_TS_WIDTH != 96 || ptp_ts_borrow_reg) ? ptp_ts_reg : ptp_ts_adj_reg;
|
||||||
end
|
end
|
||||||
|
|
||||||
if (control_masked) begin
|
if (framing_error_reg) begin
|
||||||
// control or error characters in first data word
|
// control or error characters in first data word
|
||||||
m_axis_tdata_next = {DATA_WIDTH{1'b0}};
|
m_axis_tdata_next = {DATA_WIDTH{1'b0}};
|
||||||
m_axis_tkeep_next = 8'h01;
|
m_axis_tkeep_next = 8'h01;
|
||||||
@ -307,29 +250,24 @@ always @* begin
|
|||||||
m_axis_tlast_next = 1'b0;
|
m_axis_tlast_next = 1'b0;
|
||||||
m_axis_tuser_next[0] = 1'b0;
|
m_axis_tuser_next[0] = 1'b0;
|
||||||
|
|
||||||
last_cycle_tkeep_next = {4'b0000, tkeep_mask[7:4]};
|
if (framing_error_reg) begin
|
||||||
|
|
||||||
if (detect_term) begin
|
|
||||||
reset_crc = 1'b1;
|
|
||||||
end
|
|
||||||
|
|
||||||
if (control_masked) begin
|
|
||||||
// control or error characters in packet
|
// control or error characters in packet
|
||||||
m_axis_tlast_next = 1'b1;
|
m_axis_tlast_next = 1'b1;
|
||||||
m_axis_tuser_next[0] = 1'b1;
|
m_axis_tuser_next[0] = 1'b1;
|
||||||
error_bad_frame_next = 1'b1;
|
error_bad_frame_next = 1'b1;
|
||||||
reset_crc = 1'b1;
|
reset_crc = 1'b1;
|
||||||
state_next = STATE_IDLE;
|
state_next = STATE_IDLE;
|
||||||
end else if (detect_term) begin
|
end else if (term_present_reg) begin
|
||||||
if (detect_term[4:0]) begin
|
reset_crc = 1'b1;
|
||||||
|
if (term_lane_reg <= 4) begin
|
||||||
// end this cycle
|
// end this cycle
|
||||||
m_axis_tkeep_next = {tkeep_mask[3:0], 4'b1111};
|
m_axis_tkeep_next = {KEEP_WIDTH{1'b1}} >> (CTRL_WIDTH-4-term_lane_reg);
|
||||||
m_axis_tlast_next = 1'b1;
|
m_axis_tlast_next = 1'b1;
|
||||||
if ((detect_term[0] && crc_valid_save[7]) ||
|
if ((term_lane_reg == 0 && crc_valid_save[7]) ||
|
||||||
(detect_term[1] && crc_valid[0]) ||
|
(term_lane_reg == 1 && crc_valid[0]) ||
|
||||||
(detect_term[2] && crc_valid[1]) ||
|
(term_lane_reg == 2 && crc_valid[1]) ||
|
||||||
(detect_term[3] && crc_valid[2]) ||
|
(term_lane_reg == 3 && crc_valid[2]) ||
|
||||||
(detect_term[4] && crc_valid[3])) begin
|
(term_lane_reg == 4 && crc_valid[3])) begin
|
||||||
// CRC valid
|
// CRC valid
|
||||||
end else begin
|
end else begin
|
||||||
m_axis_tuser_next[0] = 1'b1;
|
m_axis_tuser_next[0] = 1'b1;
|
||||||
@ -348,16 +286,16 @@ always @* begin
|
|||||||
STATE_LAST: begin
|
STATE_LAST: begin
|
||||||
// last cycle of packet
|
// last cycle of packet
|
||||||
m_axis_tdata_next = xgmii_rxd_d1;
|
m_axis_tdata_next = xgmii_rxd_d1;
|
||||||
m_axis_tkeep_next = last_cycle_tkeep_reg;
|
m_axis_tkeep_next = {KEEP_WIDTH{1'b1}} >> (CTRL_WIDTH+4-term_lane_d0_reg);
|
||||||
m_axis_tvalid_next = 1'b1;
|
m_axis_tvalid_next = 1'b1;
|
||||||
m_axis_tlast_next = 1'b1;
|
m_axis_tlast_next = 1'b1;
|
||||||
m_axis_tuser_next[0] = 1'b0;
|
m_axis_tuser_next[0] = 1'b0;
|
||||||
|
|
||||||
reset_crc = 1'b1;
|
reset_crc = 1'b1;
|
||||||
|
|
||||||
if ((detect_term_save[5] && crc_valid_save[4]) ||
|
if ((term_lane_d0_reg == 5 && crc_valid_save[4]) ||
|
||||||
(detect_term_save[6] && crc_valid_save[5]) ||
|
(term_lane_d0_reg == 6 && crc_valid_save[5]) ||
|
||||||
(detect_term_save[7] && crc_valid_save[6])) begin
|
(term_lane_d0_reg == 7 && crc_valid_save[6])) begin
|
||||||
// CRC valid
|
// CRC valid
|
||||||
end else begin
|
end else begin
|
||||||
m_axis_tuser_next[0] = 1'b1;
|
m_axis_tuser_next[0] = 1'b1;
|
||||||
@ -367,7 +305,7 @@ always @* begin
|
|||||||
|
|
||||||
if (xgmii_start_d1) begin
|
if (xgmii_start_d1) begin
|
||||||
// start condition
|
// start condition
|
||||||
if (control_masked) begin
|
if (framing_error_reg) begin
|
||||||
// control or error characters in first data word
|
// control or error characters in first data word
|
||||||
m_axis_tdata_next = {DATA_WIDTH{1'b0}};
|
m_axis_tdata_next = {DATA_WIDTH{1'b0}};
|
||||||
m_axis_tkeep_next = 8'h01;
|
m_axis_tkeep_next = 8'h01;
|
||||||
@ -387,6 +325,8 @@ always @* begin
|
|||||||
endcase
|
endcase
|
||||||
end
|
end
|
||||||
|
|
||||||
|
integer i;
|
||||||
|
|
||||||
always @(posedge clk) begin
|
always @(posedge clk) begin
|
||||||
state_reg <= state_next;
|
state_reg <= state_next;
|
||||||
|
|
||||||
@ -400,10 +340,6 @@ always @(posedge clk) begin
|
|||||||
error_bad_frame_reg <= error_bad_frame_next;
|
error_bad_frame_reg <= error_bad_frame_next;
|
||||||
error_bad_fcs_reg <= error_bad_fcs_next;
|
error_bad_fcs_reg <= error_bad_fcs_next;
|
||||||
|
|
||||||
last_cycle_tkeep_reg <= last_cycle_tkeep_next;
|
|
||||||
|
|
||||||
detect_term_save <= detect_term;
|
|
||||||
|
|
||||||
swap_rxd <= xgmii_rxd_masked[63:32];
|
swap_rxd <= xgmii_rxd_masked[63:32];
|
||||||
swap_rxc <= xgmii_rxc[7:4];
|
swap_rxc <= xgmii_rxc[7:4];
|
||||||
swap_rxc_term <= xgmii_term[7:4];
|
swap_rxc_term <= xgmii_term[7:4];
|
||||||
@ -419,15 +355,47 @@ always @(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
|
||||||
|
|
||||||
if (xgmii_rxc[0] && xgmii_rxd[7:0] == XGMII_START) begin
|
if (lanes_swapped) begin
|
||||||
|
xgmii_rxd_d0 <= {xgmii_rxd_masked[31:0], swap_rxd};
|
||||||
|
xgmii_rxc_d0 <= {xgmii_rxc[3:0], swap_rxc};
|
||||||
|
|
||||||
|
term_lane_reg <= 0;
|
||||||
|
term_present_reg <= 1'b0;
|
||||||
|
framing_error_reg <= {xgmii_rxc[3:0], swap_rxc} != 0;
|
||||||
|
|
||||||
|
for (i = CTRL_WIDTH-1; i >= 0; i = i - 1) begin
|
||||||
|
if ({xgmii_term[3:0], swap_rxc_term} & (1 << i)) begin
|
||||||
|
term_lane_reg <= i;
|
||||||
|
term_present_reg <= 1'b1;
|
||||||
|
framing_error_reg <= ({xgmii_rxc[3:0], swap_rxc} & ({CTRL_WIDTH{1'b1}} >> (CTRL_WIDTH-i))) != 0;
|
||||||
lanes_swapped <= 1'b0;
|
lanes_swapped <= 1'b0;
|
||||||
start_packet_reg <= 2'b01;
|
end
|
||||||
|
end
|
||||||
|
end else begin
|
||||||
xgmii_rxd_d0 <= xgmii_rxd_masked;
|
xgmii_rxd_d0 <= xgmii_rxd_masked;
|
||||||
xgmii_rxc_d0 <= xgmii_rxc;
|
xgmii_rxc_d0 <= xgmii_rxc;
|
||||||
|
|
||||||
xgmii_start_d0 <= 1'b1;
|
term_lane_reg <= 0;
|
||||||
|
term_present_reg <= 1'b0;
|
||||||
|
framing_error_reg <= xgmii_rxc != 0;
|
||||||
|
|
||||||
detect_term <= xgmii_term;
|
for (i = CTRL_WIDTH-1; i >= 0; i = i - 1) begin
|
||||||
|
if (xgmii_rxc[i] && (xgmii_rxd[i*8 +: 8] == XGMII_TERM)) begin
|
||||||
|
term_lane_reg <= i;
|
||||||
|
term_present_reg <= 1'b1;
|
||||||
|
framing_error_reg <= (xgmii_rxc & ({CTRL_WIDTH{1'b1}} >> (CTRL_WIDTH-i))) != 0;
|
||||||
|
lanes_swapped <= 1'b0;
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
term_lane_d0_reg <= term_lane_reg;
|
||||||
|
|
||||||
|
if (xgmii_rxc[0] && xgmii_rxd[7:0] == XGMII_START) begin
|
||||||
|
lanes_swapped <= 1'b0;
|
||||||
|
start_packet_reg <= 2'b01;
|
||||||
|
|
||||||
|
xgmii_start_d0 <= 1'b1;
|
||||||
|
|
||||||
if (PTP_TS_WIDTH == 96) begin
|
if (PTP_TS_WIDTH == 96) begin
|
||||||
ptp_ts_reg[45:0] <= ptp_ts[45:0] + (PTP_PERIOD_NS * 2**16 + PTP_PERIOD_FNS);
|
ptp_ts_reg[45:0] <= ptp_ts[45:0] + (PTP_PERIOD_NS * 2**16 + PTP_PERIOD_FNS);
|
||||||
@ -438,29 +406,15 @@ always @(posedge clk) begin
|
|||||||
end else if (xgmii_rxc[4] && xgmii_rxd[39:32] == XGMII_START) begin
|
end else if (xgmii_rxc[4] && xgmii_rxd[39:32] == XGMII_START) begin
|
||||||
lanes_swapped <= 1'b1;
|
lanes_swapped <= 1'b1;
|
||||||
start_packet_reg <= 2'b10;
|
start_packet_reg <= 2'b10;
|
||||||
xgmii_rxd_d0 <= {xgmii_rxd_masked[31:0], swap_rxd};
|
|
||||||
xgmii_rxc_d0 <= {xgmii_rxc[3:0], swap_rxc};
|
|
||||||
|
|
||||||
xgmii_start_swap <= 1'b1;
|
xgmii_start_swap <= 1'b1;
|
||||||
|
|
||||||
detect_term <= {xgmii_term[3:0], swap_rxc_term};
|
|
||||||
|
|
||||||
if (PTP_TS_WIDTH == 96) begin
|
if (PTP_TS_WIDTH == 96) begin
|
||||||
ptp_ts_reg[45:0] <= ptp_ts[45:0] + (((PTP_PERIOD_NS * 2**16 + PTP_PERIOD_FNS) * 3) >> 1);
|
ptp_ts_reg[45:0] <= ptp_ts[45:0] + (((PTP_PERIOD_NS * 2**16 + PTP_PERIOD_FNS) * 3) >> 1);
|
||||||
ptp_ts_reg[95:48] <= ptp_ts[95:48];
|
ptp_ts_reg[95:48] <= ptp_ts[95:48];
|
||||||
end else begin
|
end else begin
|
||||||
ptp_ts_reg <= ptp_ts + (((PTP_PERIOD_NS * 2**16 + PTP_PERIOD_FNS) * 3) >> 1);
|
ptp_ts_reg <= ptp_ts + (((PTP_PERIOD_NS * 2**16 + PTP_PERIOD_FNS) * 3) >> 1);
|
||||||
end
|
end
|
||||||
end else if (lanes_swapped) begin
|
|
||||||
xgmii_rxd_d0 <= {xgmii_rxd_masked[31:0], swap_rxd};
|
|
||||||
xgmii_rxc_d0 <= {xgmii_rxc[3:0], swap_rxc};
|
|
||||||
|
|
||||||
detect_term <= {xgmii_term[3:0], swap_rxc_term};
|
|
||||||
end else begin
|
|
||||||
xgmii_rxd_d0 <= xgmii_rxd_masked;
|
|
||||||
xgmii_rxc_d0 <= xgmii_rxc;
|
|
||||||
|
|
||||||
detect_term <= xgmii_term;
|
|
||||||
end
|
end
|
||||||
|
|
||||||
if (reset_crc) begin
|
if (reset_crc) begin
|
||||||
|
Loading…
x
Reference in New Issue
Block a user