1
0
mirror of https://github.com/corundum/corundum.git synced 2025-01-16 08:12:53 +08:00

merged changes in eth

This commit is contained in:
Alex Forencich 2022-07-25 16:39:32 -07:00
commit 11a989d27a
8 changed files with 460 additions and 915 deletions

View File

@ -190,21 +190,19 @@ reg error_bad_fcs_reg = 1'b0, error_bad_fcs_next;
reg rx_bad_block_reg = 1'b0;
reg [PTP_TS_WIDTH-1:0] ptp_ts_reg = 0;
reg [PTP_TS_WIDTH-1:0] ptp_ts_adj_reg = 0;
reg ptp_ts_borrow_reg = 0;
reg [31:0] crc_state = 32'hFFFFFFFF;
reg [31:0] crc_state3 = 32'hFFFFFFFF;
wire [31:0] crc_next0;
wire [31:0] crc_next1;
wire [31:0] crc_next2;
wire [31:0] crc_next3;
wire [31:0] crc_next7;
wire [31:0] crc_next[7:0];
wire crc_valid0 = crc_next0 == ~32'h2144df1c;
wire crc_valid1 = crc_next1 == ~32'h2144df1c;
wire crc_valid2 = crc_next2 == ~32'h2144df1c;
wire crc_valid3 = crc_next3 == ~32'h2144df1c;
wire crc_valid7 = crc_next7 == ~32'h2144df1c;
wire crc_valid0 = crc_next[0] == ~32'h2144df1c;
wire crc_valid1 = crc_next[1] == ~32'h2144df1c;
wire crc_valid2 = crc_next[2] == ~32'h2144df1c;
wire crc_valid3 = crc_next[3] == ~32'h2144df1c;
wire crc_valid7 = crc_next[7] == ~32'h2144df1c;
reg crc_valid7_save = 1'b0;
@ -219,69 +217,28 @@ assign error_bad_frame = error_bad_frame_reg;
assign error_bad_fcs = error_bad_fcs_reg;
assign rx_bad_block = rx_bad_block_reg;
lfsr #(
.LFSR_WIDTH(32),
.LFSR_POLY(32'h4c11db7),
.LFSR_CONFIG("GALOIS"),
.LFSR_FEED_FORWARD(0),
.REVERSE(1),
.DATA_WIDTH(8),
.STYLE("AUTO")
)
eth_crc_8 (
.data_in(input_data_crc[7:0]),
.state_in(crc_state3),
.data_out(),
.state_out(crc_next0)
);
generate
genvar n;
lfsr #(
.LFSR_WIDTH(32),
.LFSR_POLY(32'h4c11db7),
.LFSR_CONFIG("GALOIS"),
.LFSR_FEED_FORWARD(0),
.REVERSE(1),
.DATA_WIDTH(16),
.STYLE("AUTO")
)
eth_crc_16 (
.data_in(input_data_crc[15:0]),
.state_in(crc_state3),
.data_out(),
.state_out(crc_next1)
);
for (n = 0; n < 4; n = n + 1) begin : crc
lfsr #(
.LFSR_WIDTH(32),
.LFSR_POLY(32'h4c11db7),
.LFSR_CONFIG("GALOIS"),
.LFSR_FEED_FORWARD(0),
.REVERSE(1),
.DATA_WIDTH(8*(n+1)),
.STYLE("AUTO")
)
eth_crc (
.data_in(input_data_crc[0 +: 8*(n+1)]),
.state_in(crc_state3),
.data_out(),
.state_out(crc_next[n])
);
end
lfsr #(
.LFSR_WIDTH(32),
.LFSR_POLY(32'h4c11db7),
.LFSR_CONFIG("GALOIS"),
.LFSR_FEED_FORWARD(0),
.REVERSE(1),
.DATA_WIDTH(24),
.STYLE("AUTO")
)
eth_crc_24 (
.data_in(input_data_crc[23:0]),
.state_in(crc_state3),
.data_out(),
.state_out(crc_next2)
);
lfsr #(
.LFSR_WIDTH(32),
.LFSR_POLY(32'h4c11db7),
.LFSR_CONFIG("GALOIS"),
.LFSR_FEED_FORWARD(0),
.REVERSE(1),
.DATA_WIDTH(32),
.STYLE("AUTO")
)
eth_crc_32 (
.data_in(input_data_crc[31:0]),
.state_in(crc_state3),
.data_out(),
.state_out(crc_next3)
);
endgenerate
lfsr #(
.LFSR_WIDTH(32),
@ -293,10 +250,10 @@ lfsr #(
.STYLE("AUTO")
)
eth_crc_64 (
.data_in(input_data_d0[63:0]),
.data_in(input_data_d0),
.state_in(crc_state),
.data_out(),
.state_out(crc_next7)
.state_out(crc_next[7])
);
always @* begin
@ -321,7 +278,7 @@ always @* begin
reset_crc = 1'b1;
if (PTP_TS_ENABLE) begin
m_axis_tuser_next[1 +: PTP_TS_WIDTH] = ptp_ts_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
if (input_type_d1 == INPUT_TYPE_START_0) begin
@ -340,13 +297,18 @@ always @* begin
m_axis_tlast_next = 1'b0;
m_axis_tuser_next[0] = 1'b0;
if (input_type_d0[3]) begin
// INPUT_TYPE_TERM_*
reset_crc = 1'b1;
update_crc_last = 1'b1;
end
if (input_type_d0 == INPUT_TYPE_DATA) begin
state_next = STATE_PAYLOAD;
end else if (input_type_d0[3]) begin
// INPUT_TYPE_TERM_*
if (input_type_d0 <= INPUT_TYPE_TERM_4) begin
// end this cycle
reset_crc = 1'b1;
case (input_type_d0)
INPUT_TYPE_TERM_0: m_axis_tkeep_next = 8'b00001111;
INPUT_TYPE_TERM_1: m_axis_tkeep_next = 8'b00011111;
@ -369,7 +331,6 @@ always @* begin
state_next = STATE_IDLE;
end else begin
// need extra cycle
update_crc_last = 1'b1;
state_next = STATE_LAST;
end
end else begin
@ -434,10 +395,12 @@ always @(posedge clk) begin
swap_data <= {8'd0, encoded_rx_data[63:40]};
end
if (PTP_TS_WIDTH == 96 && $signed({1'b0, ptp_ts_reg[45:16]}) - $signed(31'd1000000000) > 0) begin
if (PTP_TS_ENABLE && PTP_TS_WIDTH == 96) begin
// ns field rollover
ptp_ts_reg[45:16] <= $signed({1'b0, ptp_ts_reg[45:16]}) - $signed(31'd1000000000);
ptp_ts_reg[95:48] <= ptp_ts_reg[95:48] + 1;
ptp_ts_adj_reg[15:0] <= ptp_ts_reg[15:0];
{ptp_ts_borrow_reg, ptp_ts_adj_reg[45:16]} <= $signed({1'b0, ptp_ts_reg[45:16]}) - $signed(31'd1000000000);
ptp_ts_adj_reg[47:46] <= 0;
ptp_ts_adj_reg[95:48] <= ptp_ts_reg[95:48] + 1;
end
if (encoded_rx_hdr == SYNC_CTRL && encoded_rx_data[7:0] == BLOCK_TYPE_START_0) begin
@ -571,13 +534,13 @@ always @(posedge clk) begin
if (reset_crc) begin
crc_state <= 32'hFFFFFFFF;
end else begin
crc_state <= crc_next7;
crc_state <= crc_next[7];
end
if (update_crc_last) begin
crc_state3 <= crc_next3;
crc_state3 <= crc_next[3];
end else begin
crc_state3 <= crc_next7;
crc_state3 <= crc_next[7];
end
crc_valid7_save <= crc_valid7;
@ -596,9 +559,6 @@ always @(posedge clk) begin
error_bad_fcs_reg <= 1'b0;
rx_bad_block_reg <= 1'b0;
crc_state <= 32'hFFFFFFFF;
crc_state3 <= 32'hFFFFFFFF;
input_type_d0 <= INPUT_TYPE_IDLE;
input_type_d1 <= INPUT_TYPE_IDLE;

View File

@ -87,6 +87,9 @@ module axis_baser_tx_64 #
output wire error_underflow
);
localparam EMPTY_WIDTH = $clog2(KEEP_WIDTH);
localparam MIN_LEN_WIDTH = $clog2(MIN_FRAME_LENGTH-4-KEEP_WIDTH+1);
// bus width assertions
initial begin
if (DATA_WIDTH != 64) begin
@ -105,10 +108,6 @@ initial begin
end
end
localparam MIN_FL_NOCRC = MIN_FRAME_LENGTH-4;
localparam MIN_FL_NOCRC_MS = MIN_FL_NOCRC & 16'hfff8;
localparam MIN_FL_NOCRC_LS = MIN_FL_NOCRC & 16'h0007;
localparam [7:0]
ETH_PRE = 8'h55,
ETH_SFD = 8'hD5;
@ -179,10 +178,7 @@ reg [2:0] state_reg = STATE_IDLE, state_next;
reg reset_crc;
reg update_crc;
reg swap_lanes;
reg unswap_lanes;
reg lanes_swapped = 1'b0;
reg swap_lanes_reg = 1'b0, swap_lanes_next;
reg [31:0] swap_data = 32'd0;
reg delay_type_valid = 1'b0;
@ -190,8 +186,8 @@ reg [3:0] delay_type = OUTPUT_TYPE_IDLE;
reg [DATA_WIDTH-1:0] s_axis_tdata_masked;
reg [DATA_WIDTH-1:0] s_tdata_reg = {DATA_WIDTH{1'b0}}, s_tdata_next;
reg [7:0] s_tkeep_reg = 8'd0, s_tkeep_next;
reg [DATA_WIDTH-1:0] s_tdata_reg = 0, s_tdata_next;
reg [EMPTY_WIDTH-1:0] s_empty_reg = 0, s_empty_next;
reg [DATA_WIDTH-1:0] fcs_output_data_0;
reg [DATA_WIDTH-1:0] fcs_output_data_1;
@ -200,9 +196,7 @@ reg [3:0] fcs_output_type_1;
reg [7:0] ifg_offset;
reg extra_cycle;
reg [15:0] frame_ptr_reg = 16'd0, frame_ptr_next;
reg [MIN_LEN_WIDTH-1:0] frame_min_count_reg = 0, frame_min_count_next;
reg [7:0] ifg_count_reg = 8'd0, ifg_count_next;
reg [1:0] deficit_idle_count_reg = 2'd0, deficit_idle_count_next;
@ -210,20 +204,15 @@ reg [1:0] deficit_idle_count_reg = 2'd0, deficit_idle_count_next;
reg s_axis_tready_reg = 1'b0, s_axis_tready_next;
reg [PTP_TS_WIDTH-1:0] m_axis_ptp_ts_reg = 0, m_axis_ptp_ts_next;
reg [PTP_TS_WIDTH-1:0] m_axis_ptp_ts_adj_reg = 0, m_axis_ptp_ts_adj_next;
reg [PTP_TAG_WIDTH-1:0] m_axis_ptp_ts_tag_reg = 0, m_axis_ptp_ts_tag_next;
reg m_axis_ptp_ts_valid_reg = 1'b0, m_axis_ptp_ts_valid_next;
reg m_axis_ptp_ts_valid_int_reg = 1'b0, m_axis_ptp_ts_valid_int_next;
reg m_axis_ptp_ts_borrow_reg = 1'b0, m_axis_ptp_ts_borrow_next;
reg [31:0] crc_state = 32'hFFFFFFFF;
wire [31:0] crc_next0;
wire [31:0] crc_next1;
wire [31:0] crc_next2;
wire [31:0] crc_next3;
wire [31:0] crc_next4;
wire [31:0] crc_next5;
wire [31:0] crc_next6;
wire [31:0] crc_next7;
wire [31:0] crc_next[7:0];
reg [DATA_WIDTH-1:0] encoded_tx_data_reg = {{8{CTRL_IDLE}}, BLOCK_TYPE_CTRL};
reg [HDR_WIDTH-1:0] encoded_tx_hdr_reg = SYNC_CTRL;
@ -239,153 +228,48 @@ assign s_axis_tready = s_axis_tready_reg;
assign encoded_tx_data = encoded_tx_data_reg;
assign encoded_tx_hdr = encoded_tx_hdr_reg;
assign m_axis_ptp_ts = PTP_TS_ENABLE ? m_axis_ptp_ts_reg : 0;
assign m_axis_ptp_ts = PTP_TS_ENABLE ? ((PTP_TS_WIDTH != 96 || m_axis_ptp_ts_borrow_reg) ? m_axis_ptp_ts_reg : m_axis_ptp_ts_adj_reg) : 0;
assign m_axis_ptp_ts_tag = PTP_TAG_ENABLE ? m_axis_ptp_ts_tag_reg : 0;
assign m_axis_ptp_ts_valid = PTP_TS_ENABLE || PTP_TAG_ENABLE ? m_axis_ptp_ts_valid_reg : 1'b0;
assign start_packet = start_packet_reg;
assign error_underflow = error_underflow_reg;
lfsr #(
.LFSR_WIDTH(32),
.LFSR_POLY(32'h4c11db7),
.LFSR_CONFIG("GALOIS"),
.LFSR_FEED_FORWARD(0),
.REVERSE(1),
.DATA_WIDTH(8),
.STYLE("AUTO")
)
eth_crc_8 (
.data_in(s_tdata_reg[7:0]),
.state_in(crc_state),
.data_out(),
.state_out(crc_next0)
);
generate
genvar n;
lfsr #(
.LFSR_WIDTH(32),
.LFSR_POLY(32'h4c11db7),
.LFSR_CONFIG("GALOIS"),
.LFSR_FEED_FORWARD(0),
.REVERSE(1),
.DATA_WIDTH(16),
.STYLE("AUTO")
)
eth_crc_16 (
.data_in(s_tdata_reg[15:0]),
.state_in(crc_state),
.data_out(),
.state_out(crc_next1)
);
for (n = 0; n < 8; n = n + 1) begin : crc
lfsr #(
.LFSR_WIDTH(32),
.LFSR_POLY(32'h4c11db7),
.LFSR_CONFIG("GALOIS"),
.LFSR_FEED_FORWARD(0),
.REVERSE(1),
.DATA_WIDTH(8*(n+1)),
.STYLE("AUTO")
)
eth_crc (
.data_in(s_tdata_reg[0 +: 8*(n+1)]),
.state_in(crc_state),
.data_out(),
.state_out(crc_next[n])
);
end
lfsr #(
.LFSR_WIDTH(32),
.LFSR_POLY(32'h4c11db7),
.LFSR_CONFIG("GALOIS"),
.LFSR_FEED_FORWARD(0),
.REVERSE(1),
.DATA_WIDTH(24),
.STYLE("AUTO")
)
eth_crc_24 (
.data_in(s_tdata_reg[23:0]),
.state_in(crc_state),
.data_out(),
.state_out(crc_next2)
);
endgenerate
lfsr #(
.LFSR_WIDTH(32),
.LFSR_POLY(32'h4c11db7),
.LFSR_CONFIG("GALOIS"),
.LFSR_FEED_FORWARD(0),
.REVERSE(1),
.DATA_WIDTH(32),
.STYLE("AUTO")
)
eth_crc_32 (
.data_in(s_tdata_reg[31:0]),
.state_in(crc_state),
.data_out(),
.state_out(crc_next3)
);
lfsr #(
.LFSR_WIDTH(32),
.LFSR_POLY(32'h4c11db7),
.LFSR_CONFIG("GALOIS"),
.LFSR_FEED_FORWARD(0),
.REVERSE(1),
.DATA_WIDTH(40),
.STYLE("AUTO")
)
eth_crc_40 (
.data_in(s_tdata_reg[39:0]),
.state_in(crc_state),
.data_out(),
.state_out(crc_next4)
);
lfsr #(
.LFSR_WIDTH(32),
.LFSR_POLY(32'h4c11db7),
.LFSR_CONFIG("GALOIS"),
.LFSR_FEED_FORWARD(0),
.REVERSE(1),
.DATA_WIDTH(48),
.STYLE("AUTO")
)
eth_crc_48 (
.data_in(s_tdata_reg[47:0]),
.state_in(crc_state),
.data_out(),
.state_out(crc_next5)
);
lfsr #(
.LFSR_WIDTH(32),
.LFSR_POLY(32'h4c11db7),
.LFSR_CONFIG("GALOIS"),
.LFSR_FEED_FORWARD(0),
.REVERSE(1),
.DATA_WIDTH(56),
.STYLE("AUTO")
)
eth_crc_56 (
.data_in(s_tdata_reg[55:0]),
.state_in(crc_state),
.data_out(),
.state_out(crc_next6)
);
lfsr #(
.LFSR_WIDTH(32),
.LFSR_POLY(32'h4c11db7),
.LFSR_CONFIG("GALOIS"),
.LFSR_FEED_FORWARD(0),
.REVERSE(1),
.DATA_WIDTH(64),
.STYLE("AUTO")
)
eth_crc_64 (
.data_in(s_tdata_reg[63:0]),
.state_in(crc_state),
.data_out(),
.state_out(crc_next7)
);
function [3:0] keep2count;
function [2:0] keep2empty;
input [7:0] k;
casez (k)
8'bzzzzzzz0: keep2count = 4'd0;
8'bzzzzzz01: keep2count = 4'd1;
8'bzzzzz011: keep2count = 4'd2;
8'bzzzz0111: keep2count = 4'd3;
8'bzzz01111: keep2count = 4'd4;
8'bzz011111: keep2count = 4'd5;
8'bz0111111: keep2count = 4'd6;
8'b01111111: keep2count = 4'd7;
8'b11111111: keep2count = 4'd8;
8'bzzzzzzz0: keep2empty = 3'd7;
8'bzzzzzz01: keep2empty = 3'd7;
8'bzzzzz011: keep2empty = 3'd6;
8'bzzzz0111: keep2empty = 3'd5;
8'bzzz01111: keep2empty = 3'd4;
8'bzz011111: keep2empty = 3'd3;
8'bz0111111: keep2empty = 3'd2;
8'b01111111: keep2empty = 3'd1;
8'b11111111: keep2empty = 3'd0;
endcase
endfunction
@ -400,78 +284,62 @@ end
// FCS cycle calculation
always @* begin
casez (s_tkeep_reg)
8'bzzzzzz01: begin
fcs_output_data_0 = {24'd0, ~crc_next0[31:0], s_tdata_reg[7:0]};
casez (s_empty_reg)
3'd7: begin
fcs_output_data_0 = {24'd0, ~crc_next[0][31:0], s_tdata_reg[7:0]};
fcs_output_data_1 = 64'd0;
fcs_output_type_0 = OUTPUT_TYPE_TERM_5;
fcs_output_type_1 = OUTPUT_TYPE_IDLE;
ifg_offset = 8'd3;
extra_cycle = 1'b0;
end
8'bzzzzz011: begin
fcs_output_data_0 = {16'd0, ~crc_next1[31:0], s_tdata_reg[15:0]};
3'd6: begin
fcs_output_data_0 = {16'd0, ~crc_next[1][31:0], s_tdata_reg[15:0]};
fcs_output_data_1 = 64'd0;
fcs_output_type_0 = OUTPUT_TYPE_TERM_6;
fcs_output_type_1 = OUTPUT_TYPE_IDLE;
ifg_offset = 8'd2;
extra_cycle = 1'b0;
end
8'bzzzz0111: begin
fcs_output_data_0 = {8'd0, ~crc_next2[31:0], s_tdata_reg[23:0]};
3'd5: begin
fcs_output_data_0 = {8'd0, ~crc_next[2][31:0], s_tdata_reg[23:0]};
fcs_output_data_1 = 64'd0;
fcs_output_type_0 = OUTPUT_TYPE_TERM_7;
fcs_output_type_1 = OUTPUT_TYPE_IDLE;
ifg_offset = 8'd1;
extra_cycle = 1'b0;
end
8'bzzz01111: begin
fcs_output_data_0 = {~crc_next3[31:0], s_tdata_reg[31:0]};
3'd4: begin
fcs_output_data_0 = {~crc_next[3][31:0], s_tdata_reg[31:0]};
fcs_output_data_1 = 64'd0;
fcs_output_type_0 = OUTPUT_TYPE_DATA;
fcs_output_type_1 = OUTPUT_TYPE_TERM_0;
ifg_offset = 8'd8;
extra_cycle = 1'b1;
end
8'bzz011111: begin
fcs_output_data_0 = {~crc_next4[23:0], s_tdata_reg[39:0]};
fcs_output_data_1 = {56'd0, ~crc_next4[31:24]};
3'd3: begin
fcs_output_data_0 = {~crc_next[4][23:0], s_tdata_reg[39:0]};
fcs_output_data_1 = {56'd0, ~crc_next[4][31:24]};
fcs_output_type_0 = OUTPUT_TYPE_DATA;
fcs_output_type_1 = OUTPUT_TYPE_TERM_1;
ifg_offset = 8'd7;
extra_cycle = 1'b1;
end
8'bz0111111: begin
fcs_output_data_0 = {~crc_next5[15:0], s_tdata_reg[47:0]};
fcs_output_data_1 = {48'd0, ~crc_next5[31:16]};
3'd2: begin
fcs_output_data_0 = {~crc_next[5][15:0], s_tdata_reg[47:0]};
fcs_output_data_1 = {48'd0, ~crc_next[5][31:16]};
fcs_output_type_0 = OUTPUT_TYPE_DATA;
fcs_output_type_1 = OUTPUT_TYPE_TERM_2;
ifg_offset = 8'd6;
extra_cycle = 1'b1;
end
8'b01111111: begin
fcs_output_data_0 = {~crc_next6[7:0], s_tdata_reg[55:0]};
fcs_output_data_1 = {40'd0, ~crc_next6[31:8]};
3'd1: begin
fcs_output_data_0 = {~crc_next[6][7:0], s_tdata_reg[55:0]};
fcs_output_data_1 = {40'd0, ~crc_next[6][31:8]};
fcs_output_type_0 = OUTPUT_TYPE_DATA;
fcs_output_type_1 = OUTPUT_TYPE_TERM_3;
ifg_offset = 8'd5;
extra_cycle = 1'b1;
end
8'b11111111: begin
3'd0: begin
fcs_output_data_0 = s_tdata_reg;
fcs_output_data_1 = {32'd0, ~crc_next7[31:0]};
fcs_output_data_1 = {32'd0, ~crc_next[7][31:0]};
fcs_output_type_0 = OUTPUT_TYPE_DATA;
fcs_output_type_1 = OUTPUT_TYPE_TERM_4;
ifg_offset = 8'd4;
extra_cycle = 1'b1;
end
default: begin
fcs_output_data_0 = 64'd0;
fcs_output_data_1 = 64'd0;
fcs_output_type_0 = OUTPUT_TYPE_ERROR;
fcs_output_type_1 = OUTPUT_TYPE_ERROR;
ifg_offset = 8'd0;
extra_cycle = 1'b1;
end
endcase
end
@ -482,10 +350,9 @@ always @* begin
reset_crc = 1'b0;
update_crc = 1'b0;
swap_lanes = 1'b0;
unswap_lanes = 1'b0;
swap_lanes_next = swap_lanes_reg;
frame_ptr_next = frame_ptr_reg;
frame_min_count_next = frame_min_count_reg;
ifg_count_next = ifg_count_reg;
deficit_idle_count_next = deficit_idle_count_reg;
@ -493,12 +360,14 @@ always @* begin
s_axis_tready_next = 1'b0;
s_tdata_next = s_tdata_reg;
s_tkeep_next = s_tkeep_reg;
s_empty_next = s_empty_reg;
m_axis_ptp_ts_next = m_axis_ptp_ts_reg;
m_axis_ptp_ts_adj_next = m_axis_ptp_ts_adj_reg;
m_axis_ptp_ts_tag_next = m_axis_ptp_ts_tag_reg;
m_axis_ptp_ts_valid_next = 1'b0;
m_axis_ptp_ts_valid_int_next = 1'b0;
m_axis_ptp_ts_borrow_next = m_axis_ptp_ts_borrow_reg;
output_data_next = s_tdata_reg;
output_type_next = OUTPUT_TYPE_IDLE;
@ -506,19 +375,18 @@ always @* begin
start_packet_next = 2'b00;
error_underflow_next = 1'b0;
if (m_axis_ptp_ts_valid_int_reg) begin
m_axis_ptp_ts_valid_next = 1'b1;
if (PTP_TS_WIDTH == 96 && $signed({1'b0, m_axis_ptp_ts_reg[45:16]}) - $signed(31'd1000000000) > 0) begin
// ns field rollover
m_axis_ptp_ts_next[45:16] = $signed({1'b0, m_axis_ptp_ts_reg[45:16]}) - $signed(31'd1000000000);
m_axis_ptp_ts_next[95:48] = m_axis_ptp_ts_reg[95:48] + 1;
end
if (PTP_TS_ENABLE && PTP_TS_WIDTH == 96) begin
m_axis_ptp_ts_valid_next = m_axis_ptp_ts_valid_int_reg;
m_axis_ptp_ts_adj_next[15:0] = m_axis_ptp_ts_reg[15:0];
{m_axis_ptp_ts_borrow_next, m_axis_ptp_ts_adj_next[45:16]} = $signed({1'b0, m_axis_ptp_ts_reg[45:16]}) - $signed(31'd1000000000);
m_axis_ptp_ts_adj_next[47:46] = 0;
m_axis_ptp_ts_adj_next[95:48] = m_axis_ptp_ts_reg[95:48] + 1;
end
case (state_reg)
STATE_IDLE: begin
// idle state - wait for data
frame_ptr_next = 16'd8;
frame_min_count_next = MIN_FRAME_LENGTH-4-KEEP_WIDTH;
reset_crc = 1'b1;
s_axis_tready_next = 1'b1;
@ -526,33 +394,35 @@ always @* begin
output_type_next = OUTPUT_TYPE_IDLE;
s_tdata_next = s_axis_tdata_masked;
s_tkeep_next = s_axis_tkeep;
s_empty_next = keep2empty(s_axis_tkeep);
if (s_axis_tvalid) begin
// XGMII start and preamble
if (ifg_count_reg > 8'd0) begin
// need to send more idles - swap lanes
swap_lanes = 1'b1;
if (swap_lanes_reg) begin
// lanes swapped
if (PTP_TS_WIDTH == 96) begin
m_axis_ptp_ts_next[45:0] = ptp_ts[45:0] + (((PTP_PERIOD_NS * 2**16 + PTP_PERIOD_FNS) * 3) >> 1);
m_axis_ptp_ts_next[95:48] = ptp_ts[95:48];
m_axis_ptp_ts_tag_next = s_axis_tuser >> 1;
m_axis_ptp_ts_valid_int_next = 1'b1;
end else begin
m_axis_ptp_ts_next = ptp_ts + (((PTP_PERIOD_NS * 2**16 + PTP_PERIOD_FNS) * 3) >> 1);
m_axis_ptp_ts_tag_next = s_axis_tuser >> 1;
m_axis_ptp_ts_valid_next = 1'b1;
end
m_axis_ptp_ts_tag_next = s_axis_tuser >> 1;
m_axis_ptp_ts_valid_int_next = 1'b1;
start_packet_next = 2'b10;
end else begin
// no more idles - unswap
unswap_lanes = 1'b1;
// lanes not swapped
if (PTP_TS_WIDTH == 96) begin
m_axis_ptp_ts_next[45:0] = ptp_ts[45:0] + (PTP_PERIOD_NS * 2**16 + PTP_PERIOD_FNS);
m_axis_ptp_ts_next[95:48] = ptp_ts[95:48];
m_axis_ptp_ts_tag_next = s_axis_tuser >> 1;
m_axis_ptp_ts_valid_int_next = 1'b1;
end else begin
m_axis_ptp_ts_next = ptp_ts + (PTP_PERIOD_NS * 2**16 + PTP_PERIOD_FNS);
m_axis_ptp_ts_tag_next = s_axis_tuser >> 1;
m_axis_ptp_ts_valid_next = 1'b1;
end
m_axis_ptp_ts_tag_next = s_axis_tuser >> 1;
m_axis_ptp_ts_valid_int_next = 1'b1;
start_packet_next = 2'b01;
end
output_data_next = {ETH_SFD, {7{ETH_PRE}}};
@ -560,9 +430,9 @@ always @* begin
s_axis_tready_next = 1'b1;
state_next = STATE_PAYLOAD;
end else begin
swap_lanes_next = 1'b0;
ifg_count_next = 8'd0;
deficit_idle_count_next = 2'd0;
unswap_lanes = 1'b1;
state_next = STATE_IDLE;
end
end
@ -571,35 +441,36 @@ always @* begin
update_crc = 1'b1;
s_axis_tready_next = 1'b1;
frame_ptr_next = frame_ptr_reg + 16'd8;
if (frame_min_count_reg > KEEP_WIDTH) begin
frame_min_count_next = frame_min_count_reg - KEEP_WIDTH;
end else begin
frame_min_count_next = 0;
end
output_data_next = s_tdata_reg;
output_type_next = OUTPUT_TYPE_DATA;
s_tdata_next = s_axis_tdata_masked;
s_tkeep_next = s_axis_tkeep;
s_empty_next = keep2empty(s_axis_tkeep);
if (s_axis_tvalid) begin
if (s_axis_tlast) begin
frame_ptr_next = frame_ptr_reg + keep2count(s_axis_tkeep);
s_axis_tready_next = 1'b0;
if (s_axis_tuser[0]) begin
output_type_next = OUTPUT_TYPE_ERROR;
frame_ptr_next = 16'd0;
ifg_count_next = 8'd8;
state_next = STATE_IFG;
end else begin
s_axis_tready_next = 1'b0;
if (ENABLE_PADDING && (frame_ptr_reg < MIN_FL_NOCRC_MS || (frame_ptr_reg == MIN_FL_NOCRC_MS && keep2count(s_axis_tkeep) < MIN_FL_NOCRC_LS))) begin
s_tkeep_next = 8'hff;
frame_ptr_next = frame_ptr_reg + 16'd8;
if (frame_ptr_reg < (MIN_FL_NOCRC_LS > 0 ? MIN_FL_NOCRC_MS : MIN_FL_NOCRC_MS-8)) begin
if (ENABLE_PADDING && frame_min_count_reg) begin
if (frame_min_count_reg > KEEP_WIDTH) begin
s_empty_next = 0;
state_next = STATE_PAD;
end else begin
s_tkeep_next = 8'hff >> ((8-MIN_FL_NOCRC_LS) % 8);
if (keep2empty(s_axis_tkeep) > KEEP_WIDTH-frame_min_count_reg) begin
s_empty_next = KEEP_WIDTH-frame_min_count_reg;
end
state_next = STATE_FCS_1;
end
end else begin
@ -612,7 +483,6 @@ always @* begin
end else begin
// tvalid deassert, fail frame
output_type_next = OUTPUT_TYPE_ERROR;
frame_ptr_next = 16'd0;
ifg_count_next = 8'd8;
error_underflow_next = 1'b1;
state_next = STATE_WAIT_END;
@ -626,16 +496,16 @@ always @* begin
output_type_next = OUTPUT_TYPE_DATA;
s_tdata_next = 64'd0;
s_tkeep_next = 8'hff;
s_empty_next = 0;
update_crc = 1'b1;
frame_ptr_next = frame_ptr_reg + 16'd8;
if (frame_ptr_reg < (MIN_FL_NOCRC_LS > 0 ? MIN_FL_NOCRC_MS : MIN_FL_NOCRC_MS-8)) begin
if (frame_min_count_reg > KEEP_WIDTH) begin
frame_min_count_next = frame_min_count_reg - KEEP_WIDTH;
state_next = STATE_PAD;
end else begin
s_tkeep_next = 8'hff >> ((8-MIN_FL_NOCRC_LS) % 8);
frame_min_count_next = 0;
s_empty_next = KEEP_WIDTH-frame_min_count_reg;
state_next = STATE_FCS_1;
end
end
@ -646,10 +516,8 @@ always @* begin
output_data_next = fcs_output_data_0;
output_type_next = fcs_output_type_0;
frame_ptr_next = 16'd0;
ifg_count_next = (ifg_delay > 8'd12 ? ifg_delay : 8'd12) - ifg_offset + (lanes_swapped ? 8'd4 : 8'd0) + deficit_idle_count_reg;
if (extra_cycle) begin
ifg_count_next = (ifg_delay > 8'd12 ? ifg_delay : 8'd12) - ifg_offset + (swap_lanes_reg ? 8'd4 : 8'd0) + deficit_idle_count_reg;
if (s_empty_reg <= 4) begin
state_next = STATE_FCS_2;
end else begin
state_next = STATE_IFG;
@ -663,7 +531,6 @@ always @* begin
output_type_next = fcs_output_type_1;
reset_crc = 1'b1;
frame_ptr_next = 16'd0;
if (ENABLE_DIC) begin
if (ifg_count_next > 8'd7) begin
@ -671,9 +538,11 @@ always @* begin
end else begin
if (ifg_count_next >= 8'd4) begin
deficit_idle_count_next = ifg_count_next - 8'd4;
swap_lanes_next = 1'b1;
end else begin
deficit_idle_count_next = ifg_count_next;
ifg_count_next = 8'd0;
swap_lanes_next = 1'b0;
end
s_axis_tready_next = 1'b1;
state_next = STATE_IDLE;
@ -683,6 +552,7 @@ always @* begin
state_next = STATE_IFG;
end else begin
s_axis_tready_next = 1'b1;
swap_lanes_next = ifg_count_next != 0;
state_next = STATE_IDLE;
end
end
@ -703,9 +573,11 @@ always @* begin
end else begin
if (ifg_count_next >= 8'd4) begin
deficit_idle_count_next = ifg_count_next - 8'd4;
swap_lanes_next = 1'b1;
end else begin
deficit_idle_count_next = ifg_count_next;
ifg_count_next = 8'd0;
swap_lanes_next = 1'b0;
end
s_axis_tready_next = 1'b1;
state_next = STATE_IDLE;
@ -715,6 +587,7 @@ always @* begin
state_next = STATE_IFG;
end else begin
s_axis_tready_next = 1'b1;
swap_lanes_next = ifg_count_next != 0;
state_next = STATE_IDLE;
end
end
@ -741,9 +614,11 @@ always @* begin
end else begin
if (ifg_count_next >= 8'd4) begin
deficit_idle_count_next = ifg_count_next - 8'd4;
swap_lanes_next = 1'b1;
end else begin
deficit_idle_count_next = ifg_count_next;
ifg_count_next = 8'd0;
swap_lanes_next = 1'b0;
end
s_axis_tready_next = 1'b1;
state_next = STATE_IDLE;
@ -753,6 +628,7 @@ always @* begin
state_next = STATE_IFG;
end else begin
s_axis_tready_next = 1'b1;
swap_lanes_next = ifg_count_next != 0;
state_next = STATE_IDLE;
end
end
@ -769,20 +645,22 @@ end
always @(posedge clk) begin
state_reg <= state_next;
frame_ptr_reg <= frame_ptr_next;
swap_lanes_reg <= swap_lanes_next;
ifg_count_reg <= ifg_count_next;
deficit_idle_count_reg <= deficit_idle_count_next;
s_tdata_reg <= s_tdata_next;
s_tkeep_reg <= s_tkeep_next;
s_empty_reg <= s_empty_next;
s_axis_tready_reg <= s_axis_tready_next;
m_axis_ptp_ts_reg <= m_axis_ptp_ts_next;
m_axis_ptp_ts_adj_reg <= m_axis_ptp_ts_adj_next;
m_axis_ptp_ts_tag_reg <= m_axis_ptp_ts_tag_next;
m_axis_ptp_ts_valid_reg <= m_axis_ptp_ts_valid_next;
m_axis_ptp_ts_valid_int_reg <= m_axis_ptp_ts_valid_int_next;
m_axis_ptp_ts_borrow_reg <= m_axis_ptp_ts_borrow_next;
start_packet_reg <= start_packet_next;
error_underflow_reg <= error_underflow_next;
@ -792,8 +670,7 @@ always @(posedge clk) begin
swap_data <= output_data_next[63:32];
if (swap_lanes || (lanes_swapped && !unswap_lanes)) begin
lanes_swapped <= 1'b1;
if (swap_lanes_reg) begin
output_data_reg <= {output_data_next[31:0], swap_data};
if (delay_type_valid) begin
output_type_reg <= delay_type;
@ -811,7 +688,6 @@ always @(posedge clk) begin
output_type_reg <= output_type_next;
end
end else begin
lanes_swapped <= 1'b0;
output_data_reg <= output_data_next;
output_type_reg <= output_type_next;
end
@ -878,13 +754,13 @@ always @(posedge clk) begin
if (reset_crc) begin
crc_state <= 32'hFFFFFFFF;
end else if (update_crc) begin
crc_state <= crc_next7;
crc_state <= crc_next[7];
end
if (rst) begin
state_reg <= STATE_IDLE;
frame_ptr_reg <= 16'd0;
swap_lanes_reg <= 1'b0;
ifg_count_reg <= 8'd0;
deficit_idle_count_reg <= 2'd0;
@ -903,10 +779,6 @@ always @(posedge clk) begin
start_packet_reg <= 2'b00;
error_underflow_reg <= 1'b0;
crc_state <= 32'hFFFFFFFF;
lanes_swapped <= 1'b0;
delay_type_valid <= 1'b0;
delay_type <= OUTPUT_TYPE_IDLE;
end

View File

@ -327,8 +327,6 @@ always @(posedge clk) begin
error_bad_frame_reg <= 1'b0;
error_bad_fcs_reg <= 1'b0;
crc_state <= 32'hFFFFFFFF;
mii_locked <= 1'b0;
mii_odd <= 1'b0;

View File

@ -88,6 +88,8 @@ module axis_gmii_tx #
output wire error_underflow
);
localparam MIN_LEN_WIDTH = $clog2(MIN_FRAME_LENGTH-4-1+1);
// bus width assertions
initial begin
if (DATA_WIDTH != 8) begin
@ -121,7 +123,8 @@ reg [7:0] s_tdata_reg = 8'd0, s_tdata_next;
reg mii_odd_reg = 1'b0, mii_odd_next;
reg [3:0] mii_msn_reg = 4'b0, mii_msn_next;
reg [15:0] frame_ptr_reg = 16'd0, frame_ptr_next;
reg [7:0] frame_ptr_reg = 0, frame_ptr_next;
reg [MIN_LEN_WIDTH-1:0] frame_min_count_reg = 0, frame_min_count_next;
reg [7:0] gmii_txd_reg = 8'd0, gmii_txd_next;
reg gmii_tx_en_reg = 1'b0, gmii_tx_en_next;
@ -178,6 +181,7 @@ always @* begin
mii_msn_next = mii_msn_reg;
frame_ptr_next = frame_ptr_reg;
frame_min_count_next = frame_min_count_reg;
s_axis_tready_next = 1'b0;
@ -212,11 +216,14 @@ always @* begin
STATE_IDLE: begin
// idle state - wait for packet
reset_crc = 1'b1;
mii_odd_next = 1'b0;
frame_ptr_next = 1;
frame_min_count_next = MIN_FRAME_LENGTH-4-1;
if (s_axis_tvalid) begin
mii_odd_next = 1'b1;
frame_ptr_next = 16'd1;
gmii_txd_next = ETH_PRE;
gmii_tx_en_next = 1'b1;
state_next = STATE_PREAMBLE;
@ -229,18 +236,18 @@ always @* begin
reset_crc = 1'b1;
mii_odd_next = 1'b1;
frame_ptr_next = frame_ptr_reg + 16'd1;
frame_ptr_next = frame_ptr_reg + 1;
gmii_txd_next = ETH_PRE;
gmii_tx_en_next = 1'b1;
if (frame_ptr_reg == 16'd6) begin
if (frame_ptr_reg == 6) begin
s_axis_tready_next = 1'b1;
s_tdata_next = s_axis_tdata;
state_next = STATE_PREAMBLE;
end else if (frame_ptr_reg == 16'd7) begin
end else if (frame_ptr_reg == 7) begin
// end of preamble; start payload
frame_ptr_next = 16'd0;
frame_ptr_next = 0;
if (s_axis_tready_reg) begin
s_axis_tready_next = 1'b1;
s_tdata_next = s_axis_tdata;
@ -262,7 +269,10 @@ always @* begin
s_axis_tready_next = 1'b1;
mii_odd_next = 1'b1;
frame_ptr_next = frame_ptr_reg + 16'd1;
if (frame_min_count_reg) begin
frame_min_count_next = frame_min_count_reg - 1;
end
gmii_txd_next = s_tdata_reg;
gmii_tx_en_next = 1'b1;
@ -274,7 +284,6 @@ always @* begin
s_axis_tready_next = !s_axis_tready_reg;
if (s_axis_tuser[0]) begin
gmii_tx_er_next = 1'b1;
frame_ptr_next = 1'b0;
state_next = STATE_IFG;
end else begin
state_next = STATE_LAST;
@ -285,7 +294,6 @@ always @* begin
end else begin
// tvalid deassert, fail frame
gmii_tx_er_next = 1'b1;
frame_ptr_next = 16'd0;
error_underflow_next = 1'b1;
state_next = STATE_WAIT_END;
end
@ -296,16 +304,16 @@ always @* begin
update_crc = 1'b1;
mii_odd_next = 1'b1;
frame_ptr_next = frame_ptr_reg + 16'd1;
gmii_txd_next = s_tdata_reg;
gmii_tx_en_next = 1'b1;
if (ENABLE_PADDING && frame_ptr_reg < MIN_FRAME_LENGTH-5) begin
if (ENABLE_PADDING && frame_min_count_reg) begin
frame_min_count_next = frame_min_count_reg - 1;
s_tdata_next = 8'd0;
state_next = STATE_PAD;
end else begin
frame_ptr_next = 16'd0;
frame_ptr_next = 0;
state_next = STATE_FCS;
end
end
@ -314,17 +322,17 @@ always @* begin
update_crc = 1'b1;
mii_odd_next = 1'b1;
frame_ptr_next = frame_ptr_reg + 16'd1;
gmii_txd_next = 8'd0;
gmii_tx_en_next = 1'b1;
s_tdata_next = 8'd0;
if (frame_ptr_reg < MIN_FRAME_LENGTH-5) begin
if (frame_min_count_reg) begin
frame_min_count_next = frame_min_count_reg - 1;
state_next = STATE_PAD;
end else begin
frame_ptr_next = 16'd0;
frame_ptr_next = 0;
state_next = STATE_FCS;
end
end
@ -332,7 +340,7 @@ always @* begin
// send FCS
mii_odd_next = 1'b1;
frame_ptr_next = frame_ptr_reg + 16'd1;
frame_ptr_next = frame_ptr_reg + 1;
case (frame_ptr_reg)
2'd0: gmii_txd_next = ~crc_state[7:0];
@ -345,17 +353,15 @@ always @* begin
if (frame_ptr_reg < 3) begin
state_next = STATE_FCS;
end else begin
frame_ptr_next = 16'd0;
frame_ptr_next = 0;
state_next = STATE_IFG;
end
end
STATE_WAIT_END: begin
// wait for end of frame
reset_crc = 1'b1;
mii_odd_next = 1'b1;
frame_ptr_next = frame_ptr_reg + 16'd1;
frame_ptr_next = frame_ptr_reg + 1;
s_axis_tready_next = 1'b1;
if (s_axis_tvalid) begin
@ -376,10 +382,8 @@ always @* begin
STATE_IFG: begin
// send IFG
reset_crc = 1'b1;
mii_odd_next = 1'b1;
frame_ptr_next = frame_ptr_reg + 16'd1;
frame_ptr_next = frame_ptr_reg + 1;
if (frame_ptr_reg < ifg_delay-1) begin
state_next = STATE_IFG;
@ -400,6 +404,7 @@ always @(posedge clk) begin
state_reg <= state_next;
frame_ptr_reg <= frame_ptr_next;
frame_min_count_reg <= frame_min_count_next;
m_axis_ptp_ts_reg <= m_axis_ptp_ts_next;
m_axis_ptp_ts_tag_reg <= m_axis_ptp_ts_tag_next;
@ -428,8 +433,6 @@ always @(posedge clk) begin
if (rst) begin
state_reg <= STATE_IDLE;
frame_ptr_reg <= 16'd0;
s_axis_tready_reg <= 1'b0;
m_axis_ptp_ts_valid_reg <= 1'b0;
@ -439,8 +442,6 @@ always @(posedge clk) begin
start_packet_reg <= 1'b0;
error_underflow_reg <= 1'b0;
crc_state <= 32'hFFFFFFFF;
end
end

View File

@ -128,15 +128,12 @@ reg error_bad_fcs_reg = 1'b0, error_bad_fcs_next;
reg [31:0] crc_state = 32'hFFFFFFFF;
wire [31:0] crc_next0;
wire [31:0] crc_next1;
wire [31:0] crc_next2;
wire [31:0] crc_next3;
wire [31:0] crc_next[3:0];
wire crc_valid0 = crc_next0 == ~32'h2144df1c;
wire crc_valid1 = crc_next1 == ~32'h2144df1c;
wire crc_valid2 = crc_next2 == ~32'h2144df1c;
wire crc_valid3 = crc_next3 == ~32'h2144df1c;
wire crc_valid0 = crc_next[0] == ~32'h2144df1c;
wire crc_valid1 = crc_next[1] == ~32'h2144df1c;
wire crc_valid2 = crc_next[2] == ~32'h2144df1c;
wire crc_valid3 = crc_next[3] == ~32'h2144df1c;
reg crc_valid0_save = 1'b0;
reg crc_valid1_save = 1'b0;
@ -155,69 +152,28 @@ assign error_bad_fcs = error_bad_fcs_reg;
wire last_cycle = state_reg == STATE_LAST;
lfsr #(
.LFSR_WIDTH(32),
.LFSR_POLY(32'h4c11db7),
.LFSR_CONFIG("GALOIS"),
.LFSR_FEED_FORWARD(0),
.REVERSE(1),
.DATA_WIDTH(8),
.STYLE("AUTO")
)
eth_crc_8 (
.data_in(xgmii_rxd_d0[7:0]),
.state_in(crc_state),
.data_out(),
.state_out(crc_next0)
);
generate
genvar n;
lfsr #(
.LFSR_WIDTH(32),
.LFSR_POLY(32'h4c11db7),
.LFSR_CONFIG("GALOIS"),
.LFSR_FEED_FORWARD(0),
.REVERSE(1),
.DATA_WIDTH(16),
.STYLE("AUTO")
)
eth_crc_16 (
.data_in(xgmii_rxd_d0[15:0]),
.state_in(crc_state),
.data_out(),
.state_out(crc_next1)
);
for (n = 0; n < 4; n = n + 1) begin : crc
lfsr #(
.LFSR_WIDTH(32),
.LFSR_POLY(32'h4c11db7),
.LFSR_CONFIG("GALOIS"),
.LFSR_FEED_FORWARD(0),
.REVERSE(1),
.DATA_WIDTH(8*(n+1)),
.STYLE("AUTO")
)
eth_crc (
.data_in(xgmii_rxd_d0[0 +: 8*(n+1)]),
.state_in(crc_state),
.data_out(),
.state_out(crc_next[n])
);
end
lfsr #(
.LFSR_WIDTH(32),
.LFSR_POLY(32'h4c11db7),
.LFSR_CONFIG("GALOIS"),
.LFSR_FEED_FORWARD(0),
.REVERSE(1),
.DATA_WIDTH(24),
.STYLE("AUTO")
)
eth_crc_24 (
.data_in(xgmii_rxd_d0[23:0]),
.state_in(crc_state),
.data_out(),
.state_out(crc_next2)
);
lfsr #(
.LFSR_WIDTH(32),
.LFSR_POLY(32'h4c11db7),
.LFSR_CONFIG("GALOIS"),
.LFSR_FEED_FORWARD(0),
.REVERSE(1),
.DATA_WIDTH(32),
.STYLE("AUTO")
)
eth_crc_32 (
.data_in(xgmii_rxd_d0[31:0]),
.state_in(crc_state),
.data_out(),
.state_out(crc_next3)
);
endgenerate
// detect control characters
reg [3:0] detect_term = 4'd0;
@ -319,6 +275,10 @@ always @* begin
last_cycle_tkeep_next = tkeep_mask;
if (detect_term) begin
reset_crc = 1'b1;
end
if (control_masked) begin
// control or error characters in packet
m_axis_tlast_next = 1'b1;
@ -329,7 +289,6 @@ always @* begin
end else if (detect_term) begin
if (detect_term[0]) begin
// end this cycle
reset_crc = 1'b1;
m_axis_tkeep_next = 4'b1111;
m_axis_tlast_next = 1'b1;
if (detect_term[0] && crc_valid3_save) begin
@ -397,7 +356,7 @@ always @(posedge clk) begin
if (reset_crc) begin
crc_state <= 32'hFFFFFFFF;
end else begin
crc_state <= crc_next3;
crc_state <= crc_next[3];
end
crc_valid0_save <= crc_valid0;
@ -421,8 +380,6 @@ always @(posedge clk) begin
error_bad_frame_reg <= 1'b0;
error_bad_fcs_reg <= 1'b0;
crc_state <= 32'hFFFFFFFF;
xgmii_rxc_d0 <= {CTRL_WIDTH{1'b0}};
xgmii_rxc_d1 <= {CTRL_WIDTH{1'b0}};
end

View File

@ -132,21 +132,19 @@ reg error_bad_frame_reg = 1'b0, error_bad_frame_next;
reg error_bad_fcs_reg = 1'b0, error_bad_fcs_next;
reg [PTP_TS_WIDTH-1:0] ptp_ts_reg = 0;
reg [PTP_TS_WIDTH-1:0] ptp_ts_adj_reg = 0;
reg ptp_ts_borrow_reg = 0;
reg [31:0] crc_state = 32'hFFFFFFFF;
reg [31:0] crc_state3 = 32'hFFFFFFFF;
wire [31:0] crc_next0;
wire [31:0] crc_next1;
wire [31:0] crc_next2;
wire [31:0] crc_next3;
wire [31:0] crc_next7;
wire [31:0] crc_next[7:0];
wire crc_valid0 = crc_next0 == ~32'h2144df1c;
wire crc_valid1 = crc_next1 == ~32'h2144df1c;
wire crc_valid2 = crc_next2 == ~32'h2144df1c;
wire crc_valid3 = crc_next3 == ~32'h2144df1c;
wire crc_valid7 = crc_next7 == ~32'h2144df1c;
wire crc_valid0 = crc_next[0] == ~32'h2144df1c;
wire crc_valid1 = crc_next[1] == ~32'h2144df1c;
wire crc_valid2 = crc_next[2] == ~32'h2144df1c;
wire crc_valid3 = crc_next[3] == ~32'h2144df1c;
wire crc_valid7 = crc_next[7] == ~32'h2144df1c;
reg crc_valid7_save = 1'b0;
@ -160,69 +158,28 @@ assign start_packet = start_packet_reg;
assign error_bad_frame = error_bad_frame_reg;
assign error_bad_fcs = error_bad_fcs_reg;
lfsr #(
.LFSR_WIDTH(32),
.LFSR_POLY(32'h4c11db7),
.LFSR_CONFIG("GALOIS"),
.LFSR_FEED_FORWARD(0),
.REVERSE(1),
.DATA_WIDTH(8),
.STYLE("AUTO")
)
eth_crc_8 (
.data_in(xgmii_rxd_crc[7:0]),
.state_in(crc_state3),
.data_out(),
.state_out(crc_next0)
);
generate
genvar n;
lfsr #(
.LFSR_WIDTH(32),
.LFSR_POLY(32'h4c11db7),
.LFSR_CONFIG("GALOIS"),
.LFSR_FEED_FORWARD(0),
.REVERSE(1),
.DATA_WIDTH(16),
.STYLE("AUTO")
)
eth_crc_16 (
.data_in(xgmii_rxd_crc[15:0]),
.state_in(crc_state3),
.data_out(),
.state_out(crc_next1)
);
for (n = 0; n < 4; n = n + 1) begin : crc
lfsr #(
.LFSR_WIDTH(32),
.LFSR_POLY(32'h4c11db7),
.LFSR_CONFIG("GALOIS"),
.LFSR_FEED_FORWARD(0),
.REVERSE(1),
.DATA_WIDTH(8*(n+1)),
.STYLE("AUTO")
)
eth_crc (
.data_in(xgmii_rxd_crc[0 +: 8*(n+1)]),
.state_in(crc_state3),
.data_out(),
.state_out(crc_next[n])
);
end
lfsr #(
.LFSR_WIDTH(32),
.LFSR_POLY(32'h4c11db7),
.LFSR_CONFIG("GALOIS"),
.LFSR_FEED_FORWARD(0),
.REVERSE(1),
.DATA_WIDTH(24),
.STYLE("AUTO")
)
eth_crc_24 (
.data_in(xgmii_rxd_crc[23:0]),
.state_in(crc_state3),
.data_out(),
.state_out(crc_next2)
);
lfsr #(
.LFSR_WIDTH(32),
.LFSR_POLY(32'h4c11db7),
.LFSR_CONFIG("GALOIS"),
.LFSR_FEED_FORWARD(0),
.REVERSE(1),
.DATA_WIDTH(32),
.STYLE("AUTO")
)
eth_crc_32 (
.data_in(xgmii_rxd_crc[31:0]),
.state_in(crc_state3),
.data_out(),
.state_out(crc_next3)
);
endgenerate
lfsr #(
.LFSR_WIDTH(32),
@ -234,10 +191,10 @@ lfsr #(
.STYLE("AUTO")
)
eth_crc_64 (
.data_in(xgmii_rxd_crc[63:0]),
.data_in(xgmii_rxd_crc),
.state_in(crc_state),
.data_out(),
.state_out(crc_next7)
.state_out(crc_next[7])
);
// detect control characters
@ -323,7 +280,7 @@ always @* begin
// start condition
if (PTP_TS_ENABLE) begin
m_axis_tuser_next[1 +: PTP_TS_WIDTH] = ptp_ts_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
if (control_masked) begin
@ -353,6 +310,11 @@ always @* begin
last_cycle_tkeep_next = {4'b0000, tkeep_mask[7:4]};
if (detect_term) begin
reset_crc = 1'b1;
update_crc_last = 1'b1;
end
if (control_masked) begin
// control or error characters in packet
m_axis_tlast_next = 1'b1;
@ -363,7 +325,6 @@ always @* begin
end else if (detect_term) begin
if (detect_term[4:0]) begin
// end this cycle
reset_crc = 1'b1;
m_axis_tkeep_next = {tkeep_mask[3:0], 4'b1111};
m_axis_tlast_next = 1'b1;
if ((detect_term[0] && crc_valid7_save) ||
@ -380,7 +341,6 @@ always @* begin
state_next = STATE_IDLE;
end else begin
// need extra cycle
update_crc_last = 1'b1;
state_next = STATE_LAST;
end
end else begin
@ -449,10 +409,12 @@ always @(posedge clk) begin
swap_rxd <= xgmii_rxd[63:32];
swap_rxc <= xgmii_rxc[7:4];
if (PTP_TS_WIDTH == 96 && $signed({1'b0, ptp_ts_reg[45:16]}) - $signed(31'd1000000000) > 0) begin
if (PTP_TS_ENABLE && PTP_TS_WIDTH == 96) begin
// ns field rollover
ptp_ts_reg[45:16] <= $signed({1'b0, ptp_ts_reg[45:16]}) - $signed(31'd1000000000);
ptp_ts_reg[95:48] <= ptp_ts_reg[95:48] + 1;
ptp_ts_adj_reg[15:0] <= ptp_ts_reg[15:0];
{ptp_ts_borrow_reg, ptp_ts_adj_reg[45:16]} <= $signed({1'b0, ptp_ts_reg[45:16]}) - $signed(31'd1000000000);
ptp_ts_adj_reg[47:46] <= 0;
ptp_ts_adj_reg[95:48] <= ptp_ts_reg[95:48] + 1;
end
if (xgmii_rxc[0] && xgmii_rxd[7:0] == XGMII_START) begin
@ -512,13 +474,13 @@ always @(posedge clk) begin
if (reset_crc) begin
crc_state <= 32'hFFFFFFFF;
end else begin
crc_state <= crc_next7;
crc_state <= crc_next[7];
end
if (update_crc_last) begin
crc_state3 <= crc_next3;
crc_state3 <= crc_next[3];
end else begin
crc_state3 <= crc_next7;
crc_state3 <= crc_next[7];
end
crc_valid7_save <= crc_valid7;
@ -539,9 +501,6 @@ always @(posedge clk) begin
error_bad_frame_reg <= 1'b0;
error_bad_fcs_reg <= 1'b0;
crc_state <= 32'hFFFFFFFF;
crc_state3 <= 32'hFFFFFFFF;
xgmii_rxc_d0 <= {CTRL_WIDTH{1'b0}};
xgmii_rxc_d1 <= {CTRL_WIDTH{1'b0}};

View File

@ -85,6 +85,9 @@ module axis_xgmii_tx_32 #
output wire error_underflow
);
localparam EMPTY_WIDTH = $clog2(KEEP_WIDTH);
localparam MIN_LEN_WIDTH = $clog2(MIN_FRAME_LENGTH-4-CTRL_WIDTH+1);
// bus width assertions
initial begin
if (DATA_WIDTH != 32) begin
@ -98,10 +101,6 @@ initial begin
end
end
localparam MIN_FL_NOCRC = MIN_FRAME_LENGTH-4;
localparam MIN_FL_NOCRC_MS = MIN_FL_NOCRC & 16'hfffc;
localparam MIN_FL_NOCRC_LS = MIN_FL_NOCRC & 16'h0003;
localparam [7:0]
ETH_PRE = 8'h55,
ETH_SFD = 8'hD5;
@ -131,8 +130,8 @@ reg update_crc;
reg [DATA_WIDTH-1:0] s_axis_tdata_masked;
reg [DATA_WIDTH-1:0] s_tdata_reg ={DATA_WIDTH{1'b0}}, s_tdata_next;
reg [KEEP_WIDTH-1:0] s_tkeep_reg = {KEEP_WIDTH{1'b0}}, s_tkeep_next;
reg [DATA_WIDTH-1:0] s_tdata_reg = 0, s_tdata_next;
reg [EMPTY_WIDTH-1:0] s_empty_reg = 0, s_empty_next;
reg [DATA_WIDTH-1:0] fcs_output_txd_0;
reg [DATA_WIDTH-1:0] fcs_output_txd_1;
@ -143,7 +142,7 @@ reg [7:0] ifg_offset;
reg extra_cycle;
reg [15:0] frame_ptr_reg = 16'd0, frame_ptr_next;
reg [MIN_LEN_WIDTH-1:0] frame_min_count_reg = 0, frame_min_count_next;
reg [7:0] ifg_count_reg = 8'd0, ifg_count_next;
reg [1:0] deficit_idle_count_reg = 2'd0, deficit_idle_count_next;
@ -156,10 +155,7 @@ reg m_axis_ptp_ts_valid_reg = 1'b0, m_axis_ptp_ts_valid_next;
reg [31:0] crc_state = 32'hFFFFFFFF;
wire [31:0] crc_next0;
wire [31:0] crc_next1;
wire [31:0] crc_next2;
wire [31:0] crc_next3;
wire [31:0] crc_next[3:0];
reg [DATA_WIDTH-1:0] xgmii_txd_reg = {CTRL_WIDTH{XGMII_IDLE}}, xgmii_txd_next;
reg [CTRL_WIDTH-1:0] xgmii_txc_reg = {CTRL_WIDTH{1'b1}}, xgmii_txc_next;
@ -179,78 +175,37 @@ assign m_axis_ptp_ts_valid = PTP_TS_ENABLE || PTP_TAG_ENABLE ? m_axis_ptp_ts_val
assign start_packet = start_packet_reg;
assign error_underflow = error_underflow_reg;
lfsr #(
.LFSR_WIDTH(32),
.LFSR_POLY(32'h4c11db7),
.LFSR_CONFIG("GALOIS"),
.LFSR_FEED_FORWARD(0),
.REVERSE(1),
.DATA_WIDTH(8),
.STYLE("AUTO")
)
eth_crc_8 (
.data_in(s_tdata_reg[7:0]),
.state_in(crc_state),
.data_out(),
.state_out(crc_next0)
);
generate
genvar n;
lfsr #(
.LFSR_WIDTH(32),
.LFSR_POLY(32'h4c11db7),
.LFSR_CONFIG("GALOIS"),
.LFSR_FEED_FORWARD(0),
.REVERSE(1),
.DATA_WIDTH(16),
.STYLE("AUTO")
)
eth_crc_16 (
.data_in(s_tdata_reg[15:0]),
.state_in(crc_state),
.data_out(),
.state_out(crc_next1)
);
for (n = 0; n < 4; n = n + 1) begin : crc
lfsr #(
.LFSR_WIDTH(32),
.LFSR_POLY(32'h4c11db7),
.LFSR_CONFIG("GALOIS"),
.LFSR_FEED_FORWARD(0),
.REVERSE(1),
.DATA_WIDTH(8*(n+1)),
.STYLE("AUTO")
)
eth_crc (
.data_in(s_tdata_reg[0 +: 8*(n+1)]),
.state_in(crc_state),
.data_out(),
.state_out(crc_next[n])
);
end
lfsr #(
.LFSR_WIDTH(32),
.LFSR_POLY(32'h4c11db7),
.LFSR_CONFIG("GALOIS"),
.LFSR_FEED_FORWARD(0),
.REVERSE(1),
.DATA_WIDTH(24),
.STYLE("AUTO")
)
eth_crc_24 (
.data_in(s_tdata_reg[23:0]),
.state_in(crc_state),
.data_out(),
.state_out(crc_next2)
);
endgenerate
lfsr #(
.LFSR_WIDTH(32),
.LFSR_POLY(32'h4c11db7),
.LFSR_CONFIG("GALOIS"),
.LFSR_FEED_FORWARD(0),
.REVERSE(1),
.DATA_WIDTH(32),
.STYLE("AUTO")
)
eth_crc_32 (
.data_in(s_tdata_reg[31:0]),
.state_in(crc_state),
.data_out(),
.state_out(crc_next3)
);
function [2:0] keep2count;
function [1:0] keep2empty;
input [3:0] k;
casez (k)
4'bzzz0: keep2count = 3'd0;
4'bzz01: keep2count = 3'd1;
4'bz011: keep2count = 3'd2;
4'b0111: keep2count = 3'd3;
4'b1111: keep2count = 3'd4;
4'bzzz0: keep2empty = 2'd3;
4'bzz01: keep2empty = 2'd3;
4'bz011: keep2empty = 2'd2;
4'b0111: keep2empty = 2'd1;
4'b1111: keep2empty = 2'd0;
endcase
endfunction
@ -265,47 +220,39 @@ end
// FCS cycle calculation
always @* begin
casez (s_tkeep_reg)
4'bzz01: begin
fcs_output_txd_0 = {~crc_next0[23:0], s_tdata_reg[7:0]};
fcs_output_txd_1 = {{2{XGMII_IDLE}}, XGMII_TERM, ~crc_next0[31:24]};
casez (s_empty_reg)
2'd3: begin
fcs_output_txd_0 = {~crc_next[0][23:0], s_tdata_reg[7:0]};
fcs_output_txd_1 = {{2{XGMII_IDLE}}, XGMII_TERM, ~crc_next[0][31:24]};
fcs_output_txc_0 = 4'b0000;
fcs_output_txc_1 = 4'b1110;
ifg_offset = 8'd3;
extra_cycle = 1'b0;
end
4'bz011: begin
fcs_output_txd_0 = {~crc_next1[15:0], s_tdata_reg[15:0]};
fcs_output_txd_1 = {XGMII_IDLE, XGMII_TERM, ~crc_next1[31:16]};
2'd2: begin
fcs_output_txd_0 = {~crc_next[1][15:0], s_tdata_reg[15:0]};
fcs_output_txd_1 = {XGMII_IDLE, XGMII_TERM, ~crc_next[1][31:16]};
fcs_output_txc_0 = 4'b0000;
fcs_output_txc_1 = 4'b1100;
ifg_offset = 8'd2;
extra_cycle = 1'b0;
end
4'b0111: begin
fcs_output_txd_0 = {~crc_next2[7:0], s_tdata_reg[23:0]};
fcs_output_txd_1 = {XGMII_TERM, ~crc_next2[31:8]};
2'd1: begin
fcs_output_txd_0 = {~crc_next[2][7:0], s_tdata_reg[23:0]};
fcs_output_txd_1 = {XGMII_TERM, ~crc_next[2][31:8]};
fcs_output_txc_0 = 4'b0000;
fcs_output_txc_1 = 4'b1000;
ifg_offset = 8'd1;
extra_cycle = 1'b0;
end
4'b1111: begin
2'd0: begin
fcs_output_txd_0 = s_tdata_reg;
fcs_output_txd_1 = ~crc_next3;
fcs_output_txd_1 = ~crc_next[3];
fcs_output_txc_0 = 4'b0000;
fcs_output_txc_1 = 4'b0000;
ifg_offset = 8'd4;
extra_cycle = 1'b1;
end
default: begin
fcs_output_txd_0 = {CTRL_WIDTH{XGMII_ERROR}};
fcs_output_txd_1 = {CTRL_WIDTH{XGMII_ERROR}};
fcs_output_txc_0 = {CTRL_WIDTH{1'b1}};
fcs_output_txc_1 = {CTRL_WIDTH{1'b1}};
ifg_offset = 8'd0;
extra_cycle = 1'b0;
end
endcase
end
@ -315,7 +262,7 @@ always @* begin
reset_crc = 1'b0;
update_crc = 1'b0;
frame_ptr_next = frame_ptr_reg;
frame_min_count_next = frame_min_count_reg;
ifg_count_next = ifg_count_reg;
deficit_idle_count_next = deficit_idle_count_reg;
@ -323,7 +270,7 @@ always @* begin
s_axis_tready_next = 1'b0;
s_tdata_next = s_tdata_reg;
s_tkeep_next = s_tkeep_reg;
s_empty_next = s_empty_reg;
m_axis_ptp_ts_next = m_axis_ptp_ts_reg;
m_axis_ptp_ts_tag_next = m_axis_ptp_ts_tag_reg;
@ -345,7 +292,7 @@ always @* begin
case (state_reg)
STATE_IDLE: begin
// idle state - wait for data
frame_ptr_next = 16'd4;
frame_min_count_next = MIN_FRAME_LENGTH-4-CTRL_WIDTH;
reset_crc = 1'b1;
// XGMII idle
@ -353,7 +300,7 @@ always @* begin
xgmii_txc_next = {CTRL_WIDTH{1'b1}};
s_tdata_next = s_axis_tdata_masked;
s_tkeep_next = s_axis_tkeep;
s_empty_next = keep2empty(s_axis_tkeep);
if (s_axis_tvalid) begin
// XGMII start and preamble
@ -371,7 +318,7 @@ always @* begin
// send preamble
s_tdata_next = s_axis_tdata_masked;
s_tkeep_next = s_axis_tkeep;
s_empty_next = keep2empty(s_axis_tkeep);
xgmii_txd_next = {ETH_SFD, {3{ETH_PRE}}};
xgmii_txc_next = 4'b0000;
@ -384,36 +331,37 @@ always @* begin
update_crc = 1'b1;
s_axis_tready_next = 1'b1;
frame_ptr_next = frame_ptr_reg + 16'd4;
if (frame_min_count_reg > CTRL_WIDTH) begin
frame_min_count_next = frame_min_count_reg - CTRL_WIDTH;
end else begin
frame_min_count_next = 0;
end
xgmii_txd_next = s_tdata_reg;
xgmii_txc_next = 4'b0000;
s_tdata_next = s_axis_tdata_masked;
s_tkeep_next = s_axis_tkeep;
s_empty_next = keep2empty(s_axis_tkeep);
if (s_axis_tvalid) begin
if (s_axis_tlast) begin
frame_ptr_next = frame_ptr_reg + keep2count(s_axis_tkeep);
s_axis_tready_next = 1'b0;
if (s_axis_tuser[0]) begin
xgmii_txd_next = {XGMII_TERM, {3{XGMII_ERROR}}};
xgmii_txc_next = 4'b1111;
frame_ptr_next = 16'd0;
ifg_count_next = 8'd10;
state_next = STATE_IFG;
end else begin
s_axis_tready_next = 1'b0;
if (ENABLE_PADDING && (frame_ptr_reg < MIN_FL_NOCRC_MS || (frame_ptr_reg == MIN_FL_NOCRC_MS && keep2count(s_axis_tkeep) < MIN_FL_NOCRC_LS))) begin
s_tkeep_next = 4'hf;
frame_ptr_next = frame_ptr_reg + 16'd4;
if (frame_ptr_reg < (MIN_FL_NOCRC_LS > 0 ? MIN_FL_NOCRC_MS : MIN_FL_NOCRC_MS-4)) begin
if (ENABLE_PADDING && frame_min_count_reg) begin
if (frame_min_count_reg > CTRL_WIDTH) begin
s_empty_next = 0;
state_next = STATE_PAD;
end else begin
s_tkeep_next = 4'hf >> ((4-MIN_FL_NOCRC_LS) % 4);
if (keep2empty(s_axis_tkeep) > CTRL_WIDTH-frame_min_count_reg) begin
s_empty_next = CTRL_WIDTH-frame_min_count_reg;
end
state_next = STATE_FCS_1;
end
end else begin
@ -427,7 +375,6 @@ always @* begin
// tvalid deassert, fail frame
xgmii_txd_next = {XGMII_TERM, {3{XGMII_ERROR}}};
xgmii_txc_next = 4'b1111;
frame_ptr_next = 16'd0;
ifg_count_next = 8'd10;
error_underflow_next = 1'b1;
state_next = STATE_WAIT_END;
@ -441,16 +388,16 @@ always @* begin
xgmii_txc_next = {CTRL_WIDTH{1'b0}};
s_tdata_next = 32'd0;
s_tkeep_next = 4'hf;
s_empty_next = 0;
update_crc = 1'b1;
frame_ptr_next = frame_ptr_reg + 16'd4;
if (frame_ptr_reg < (MIN_FL_NOCRC_LS > 0 ? MIN_FL_NOCRC_MS : MIN_FL_NOCRC_MS-4)) begin
if (frame_min_count_reg > CTRL_WIDTH) begin
frame_min_count_next = frame_min_count_reg - CTRL_WIDTH;
state_next = STATE_PAD;
end else begin
s_tkeep_next = 4'hf >> ((4-MIN_FL_NOCRC_LS) % 4);
frame_min_count_next = 0;
s_empty_next = CTRL_WIDTH-frame_min_count_reg;
state_next = STATE_FCS_1;
end
end
@ -461,8 +408,6 @@ always @* begin
xgmii_txd_next = fcs_output_txd_0;
xgmii_txc_next = fcs_output_txc_0;
frame_ptr_next = 16'd0;
ifg_count_next = (ifg_delay > 8'd12 ? ifg_delay : 8'd12) - ifg_offset + deficit_idle_count_reg;
state_next = STATE_FCS_2;
end
@ -473,8 +418,6 @@ always @* begin
xgmii_txd_next = fcs_output_txd_1;
xgmii_txc_next = fcs_output_txc_1;
frame_ptr_next = 16'd0;
if (extra_cycle) begin
state_next = STATE_FCS_3;
end else begin
@ -488,9 +431,6 @@ always @* begin
xgmii_txd_next = {{3{XGMII_IDLE}}, XGMII_TERM};
xgmii_txc_next = 4'b1111;
reset_crc = 1'b1;
frame_ptr_next = 16'd0;
if (ENABLE_DIC) begin
if (ifg_count_next > 8'd3) begin
state_next = STATE_IFG;
@ -516,8 +456,6 @@ always @* begin
ifg_count_next = 8'd0;
end
reset_crc = 1'b1;
if (ENABLE_DIC) begin
if (ifg_count_next > 8'd3) begin
state_next = STATE_IFG;
@ -544,8 +482,6 @@ always @* begin
ifg_count_next = 8'd0;
end
reset_crc = 1'b1;
if (s_axis_tvalid) begin
if (s_axis_tlast) begin
s_axis_tready_next = 1'b0;
@ -578,13 +514,11 @@ end
always @(posedge clk) begin
state_reg <= state_next;
frame_ptr_reg <= frame_ptr_next;
ifg_count_reg <= ifg_count_next;
deficit_idle_count_reg <= deficit_idle_count_next;
s_tdata_reg <= s_tdata_next;
s_tkeep_reg <= s_tkeep_next;
s_empty_reg <= s_empty_next;
s_axis_tready_reg <= s_axis_tready_next;
@ -595,7 +529,7 @@ always @(posedge clk) begin
if (reset_crc) begin
crc_state <= 32'hFFFFFFFF;
end else if (update_crc) begin
crc_state <= crc_next3;
crc_state <= crc_next[3];
end
xgmii_txd_reg <= xgmii_txd_next;
@ -607,8 +541,6 @@ always @(posedge clk) begin
if (rst) begin
state_reg <= STATE_IDLE;
frame_ptr_reg <= 16'd0;
ifg_count_reg <= 8'd0;
deficit_idle_count_reg <= 2'd0;
@ -621,8 +553,6 @@ always @(posedge clk) begin
start_packet_reg <= 1'b0;
error_underflow_reg <= 1'b0;
crc_state <= 32'hFFFFFFFF;
end
end

View File

@ -87,6 +87,9 @@ module axis_xgmii_tx_64 #
output wire error_underflow
);
localparam EMPTY_WIDTH = $clog2(KEEP_WIDTH);
localparam MIN_LEN_WIDTH = $clog2(MIN_FRAME_LENGTH-4-CTRL_WIDTH+1);
// bus width assertions
initial begin
if (DATA_WIDTH != 64) begin
@ -100,10 +103,6 @@ initial begin
end
end
localparam MIN_FL_NOCRC = MIN_FRAME_LENGTH-4;
localparam MIN_FL_NOCRC_MS = MIN_FL_NOCRC & 16'hfff8;
localparam MIN_FL_NOCRC_LS = MIN_FL_NOCRC & 16'h0007;
localparam [7:0]
ETH_PRE = 8'h55,
ETH_SFD = 8'hD5;
@ -129,17 +128,14 @@ reg [2:0] state_reg = STATE_IDLE, state_next;
reg reset_crc;
reg update_crc;
reg swap_lanes;
reg unswap_lanes;
reg lanes_swapped = 1'b0;
reg swap_lanes_reg = 1'b0, swap_lanes_next;
reg [31:0] swap_txd = 32'd0;
reg [3:0] swap_txc = 4'd0;
reg [DATA_WIDTH-1:0] s_axis_tdata_masked;
reg [DATA_WIDTH-1:0] s_tdata_reg = {DATA_WIDTH{1'b0}}, s_tdata_next;
reg [KEEP_WIDTH-1:0] s_tkeep_reg = {KEEP_WIDTH{1'b0}}, s_tkeep_next;
reg [DATA_WIDTH-1:0] s_tdata_reg = 0, s_tdata_next;
reg [EMPTY_WIDTH-1:0] s_empty_reg = 0, s_empty_next;
reg [DATA_WIDTH-1:0] fcs_output_txd_0;
reg [DATA_WIDTH-1:0] fcs_output_txd_1;
@ -148,9 +144,7 @@ reg [CTRL_WIDTH-1:0] fcs_output_txc_1;
reg [7:0] ifg_offset;
reg extra_cycle;
reg [15:0] frame_ptr_reg = 16'd0, frame_ptr_next;
reg [MIN_LEN_WIDTH-1:0] frame_min_count_reg = 0, frame_min_count_next;
reg [7:0] ifg_count_reg = 8'd0, ifg_count_next;
reg [1:0] deficit_idle_count_reg = 2'd0, deficit_idle_count_next;
@ -158,20 +152,15 @@ reg [1:0] deficit_idle_count_reg = 2'd0, deficit_idle_count_next;
reg s_axis_tready_reg = 1'b0, s_axis_tready_next;
reg [PTP_TS_WIDTH-1:0] m_axis_ptp_ts_reg = 0, m_axis_ptp_ts_next;
reg [PTP_TS_WIDTH-1:0] m_axis_ptp_ts_adj_reg = 0, m_axis_ptp_ts_adj_next;
reg [PTP_TAG_WIDTH-1:0] m_axis_ptp_ts_tag_reg = 0, m_axis_ptp_ts_tag_next;
reg m_axis_ptp_ts_valid_reg = 1'b0, m_axis_ptp_ts_valid_next;
reg m_axis_ptp_ts_valid_int_reg = 1'b0, m_axis_ptp_ts_valid_int_next;
reg m_axis_ptp_ts_borrow_reg = 1'b0, m_axis_ptp_ts_borrow_next;
reg [31:0] crc_state = 32'hFFFFFFFF;
wire [31:0] crc_next0;
wire [31:0] crc_next1;
wire [31:0] crc_next2;
wire [31:0] crc_next3;
wire [31:0] crc_next4;
wire [31:0] crc_next5;
wire [31:0] crc_next6;
wire [31:0] crc_next7;
wire [31:0] crc_next[7:0];
reg [DATA_WIDTH-1:0] xgmii_txd_reg = {CTRL_WIDTH{XGMII_IDLE}}, xgmii_txd_next;
reg [CTRL_WIDTH-1:0] xgmii_txc_reg = {CTRL_WIDTH{1'b1}}, xgmii_txc_next;
@ -184,153 +173,48 @@ assign s_axis_tready = s_axis_tready_reg;
assign xgmii_txd = xgmii_txd_reg;
assign xgmii_txc = xgmii_txc_reg;
assign m_axis_ptp_ts = PTP_TS_ENABLE ? m_axis_ptp_ts_reg : 0;
assign m_axis_ptp_ts = PTP_TS_ENABLE ? ((PTP_TS_WIDTH != 96 || m_axis_ptp_ts_borrow_reg) ? m_axis_ptp_ts_reg : m_axis_ptp_ts_adj_reg) : 0;
assign m_axis_ptp_ts_tag = PTP_TAG_ENABLE ? m_axis_ptp_ts_tag_reg : 0;
assign m_axis_ptp_ts_valid = PTP_TS_ENABLE || PTP_TAG_ENABLE ? m_axis_ptp_ts_valid_reg : 1'b0;
assign start_packet = start_packet_reg;
assign error_underflow = error_underflow_reg;
lfsr #(
.LFSR_WIDTH(32),
.LFSR_POLY(32'h4c11db7),
.LFSR_CONFIG("GALOIS"),
.LFSR_FEED_FORWARD(0),
.REVERSE(1),
.DATA_WIDTH(8),
.STYLE("AUTO")
)
eth_crc_8 (
.data_in(s_tdata_reg[7:0]),
.state_in(crc_state),
.data_out(),
.state_out(crc_next0)
);
generate
genvar n;
lfsr #(
.LFSR_WIDTH(32),
.LFSR_POLY(32'h4c11db7),
.LFSR_CONFIG("GALOIS"),
.LFSR_FEED_FORWARD(0),
.REVERSE(1),
.DATA_WIDTH(16),
.STYLE("AUTO")
)
eth_crc_16 (
.data_in(s_tdata_reg[15:0]),
.state_in(crc_state),
.data_out(),
.state_out(crc_next1)
);
for (n = 0; n < 8; n = n + 1) begin : crc
lfsr #(
.LFSR_WIDTH(32),
.LFSR_POLY(32'h4c11db7),
.LFSR_CONFIG("GALOIS"),
.LFSR_FEED_FORWARD(0),
.REVERSE(1),
.DATA_WIDTH(8*(n+1)),
.STYLE("AUTO")
)
eth_crc (
.data_in(s_tdata_reg[0 +: 8*(n+1)]),
.state_in(crc_state),
.data_out(),
.state_out(crc_next[n])
);
end
lfsr #(
.LFSR_WIDTH(32),
.LFSR_POLY(32'h4c11db7),
.LFSR_CONFIG("GALOIS"),
.LFSR_FEED_FORWARD(0),
.REVERSE(1),
.DATA_WIDTH(24),
.STYLE("AUTO")
)
eth_crc_24 (
.data_in(s_tdata_reg[23:0]),
.state_in(crc_state),
.data_out(),
.state_out(crc_next2)
);
endgenerate
lfsr #(
.LFSR_WIDTH(32),
.LFSR_POLY(32'h4c11db7),
.LFSR_CONFIG("GALOIS"),
.LFSR_FEED_FORWARD(0),
.REVERSE(1),
.DATA_WIDTH(32),
.STYLE("AUTO")
)
eth_crc_32 (
.data_in(s_tdata_reg[31:0]),
.state_in(crc_state),
.data_out(),
.state_out(crc_next3)
);
lfsr #(
.LFSR_WIDTH(32),
.LFSR_POLY(32'h4c11db7),
.LFSR_CONFIG("GALOIS"),
.LFSR_FEED_FORWARD(0),
.REVERSE(1),
.DATA_WIDTH(40),
.STYLE("AUTO")
)
eth_crc_40 (
.data_in(s_tdata_reg[39:0]),
.state_in(crc_state),
.data_out(),
.state_out(crc_next4)
);
lfsr #(
.LFSR_WIDTH(32),
.LFSR_POLY(32'h4c11db7),
.LFSR_CONFIG("GALOIS"),
.LFSR_FEED_FORWARD(0),
.REVERSE(1),
.DATA_WIDTH(48),
.STYLE("AUTO")
)
eth_crc_48 (
.data_in(s_tdata_reg[47:0]),
.state_in(crc_state),
.data_out(),
.state_out(crc_next5)
);
lfsr #(
.LFSR_WIDTH(32),
.LFSR_POLY(32'h4c11db7),
.LFSR_CONFIG("GALOIS"),
.LFSR_FEED_FORWARD(0),
.REVERSE(1),
.DATA_WIDTH(56),
.STYLE("AUTO")
)
eth_crc_56 (
.data_in(s_tdata_reg[55:0]),
.state_in(crc_state),
.data_out(),
.state_out(crc_next6)
);
lfsr #(
.LFSR_WIDTH(32),
.LFSR_POLY(32'h4c11db7),
.LFSR_CONFIG("GALOIS"),
.LFSR_FEED_FORWARD(0),
.REVERSE(1),
.DATA_WIDTH(64),
.STYLE("AUTO")
)
eth_crc_64 (
.data_in(s_tdata_reg[63:0]),
.state_in(crc_state),
.data_out(),
.state_out(crc_next7)
);
function [3:0] keep2count;
function [2:0] keep2empty;
input [7:0] k;
casez (k)
8'bzzzzzzz0: keep2count = 4'd0;
8'bzzzzzz01: keep2count = 4'd1;
8'bzzzzz011: keep2count = 4'd2;
8'bzzzz0111: keep2count = 4'd3;
8'bzzz01111: keep2count = 4'd4;
8'bzz011111: keep2count = 4'd5;
8'bz0111111: keep2count = 4'd6;
8'b01111111: keep2count = 4'd7;
8'b11111111: keep2count = 4'd8;
8'bzzzzzzz0: keep2empty = 3'd7;
8'bzzzzzz01: keep2empty = 3'd7;
8'bzzzzz011: keep2empty = 3'd6;
8'bzzzz0111: keep2empty = 3'd5;
8'bzzz01111: keep2empty = 3'd4;
8'bzz011111: keep2empty = 3'd3;
8'bz0111111: keep2empty = 3'd2;
8'b01111111: keep2empty = 3'd1;
8'b11111111: keep2empty = 3'd0;
endcase
endfunction
@ -345,78 +229,62 @@ end
// FCS cycle calculation
always @* begin
casez (s_tkeep_reg)
8'bzzzzzz01: begin
fcs_output_txd_0 = {{2{XGMII_IDLE}}, XGMII_TERM, ~crc_next0[31:0], s_tdata_reg[7:0]};
casez (s_empty_reg)
3'd7: begin
fcs_output_txd_0 = {{2{XGMII_IDLE}}, XGMII_TERM, ~crc_next[0][31:0], s_tdata_reg[7:0]};
fcs_output_txd_1 = {8{XGMII_IDLE}};
fcs_output_txc_0 = 8'b11100000;
fcs_output_txc_1 = 8'b11111111;
ifg_offset = 8'd3;
extra_cycle = 1'b0;
end
8'bzzzzz011: begin
fcs_output_txd_0 = {XGMII_IDLE, XGMII_TERM, ~crc_next1[31:0], s_tdata_reg[15:0]};
3'd6: begin
fcs_output_txd_0 = {XGMII_IDLE, XGMII_TERM, ~crc_next[1][31:0], s_tdata_reg[15:0]};
fcs_output_txd_1 = {8{XGMII_IDLE}};
fcs_output_txc_0 = 8'b11000000;
fcs_output_txc_1 = 8'b11111111;
ifg_offset = 8'd2;
extra_cycle = 1'b0;
end
8'bzzzz0111: begin
fcs_output_txd_0 = {XGMII_TERM, ~crc_next2[31:0], s_tdata_reg[23:0]};
3'd5: begin
fcs_output_txd_0 = {XGMII_TERM, ~crc_next[2][31:0], s_tdata_reg[23:0]};
fcs_output_txd_1 = {8{XGMII_IDLE}};
fcs_output_txc_0 = 8'b10000000;
fcs_output_txc_1 = 8'b11111111;
ifg_offset = 8'd1;
extra_cycle = 1'b0;
end
8'bzzz01111: begin
fcs_output_txd_0 = {~crc_next3[31:0], s_tdata_reg[31:0]};
3'd4: begin
fcs_output_txd_0 = {~crc_next[3][31:0], s_tdata_reg[31:0]};
fcs_output_txd_1 = {{7{XGMII_IDLE}}, XGMII_TERM};
fcs_output_txc_0 = 8'b00000000;
fcs_output_txc_1 = 8'b11111111;
ifg_offset = 8'd8;
extra_cycle = 1'b1;
end
8'bzz011111: begin
fcs_output_txd_0 = {~crc_next4[23:0], s_tdata_reg[39:0]};
fcs_output_txd_1 = {{6{XGMII_IDLE}}, XGMII_TERM, ~crc_next4[31:24]};
3'd3: begin
fcs_output_txd_0 = {~crc_next[4][23:0], s_tdata_reg[39:0]};
fcs_output_txd_1 = {{6{XGMII_IDLE}}, XGMII_TERM, ~crc_next[4][31:24]};
fcs_output_txc_0 = 8'b00000000;
fcs_output_txc_1 = 8'b11111110;
ifg_offset = 8'd7;
extra_cycle = 1'b1;
end
8'bz0111111: begin
fcs_output_txd_0 = {~crc_next5[15:0], s_tdata_reg[47:0]};
fcs_output_txd_1 = {{5{XGMII_IDLE}}, XGMII_TERM, ~crc_next5[31:16]};
3'd2: begin
fcs_output_txd_0 = {~crc_next[5][15:0], s_tdata_reg[47:0]};
fcs_output_txd_1 = {{5{XGMII_IDLE}}, XGMII_TERM, ~crc_next[5][31:16]};
fcs_output_txc_0 = 8'b00000000;
fcs_output_txc_1 = 8'b11111100;
ifg_offset = 8'd6;
extra_cycle = 1'b1;
end
8'b01111111: begin
fcs_output_txd_0 = {~crc_next6[7:0], s_tdata_reg[55:0]};
fcs_output_txd_1 = {{4{XGMII_IDLE}}, XGMII_TERM, ~crc_next6[31:8]};
3'd1: begin
fcs_output_txd_0 = {~crc_next[6][7:0], s_tdata_reg[55:0]};
fcs_output_txd_1 = {{4{XGMII_IDLE}}, XGMII_TERM, ~crc_next[6][31:8]};
fcs_output_txc_0 = 8'b00000000;
fcs_output_txc_1 = 8'b11111000;
ifg_offset = 8'd5;
extra_cycle = 1'b1;
end
8'b11111111: begin
3'd0: begin
fcs_output_txd_0 = s_tdata_reg;
fcs_output_txd_1 = {{3{XGMII_IDLE}}, XGMII_TERM, ~crc_next7[31:0]};
fcs_output_txd_1 = {{3{XGMII_IDLE}}, XGMII_TERM, ~crc_next[7][31:0]};
fcs_output_txc_0 = 8'b00000000;
fcs_output_txc_1 = 8'b11110000;
ifg_offset = 8'd4;
extra_cycle = 1'b1;
end
default: begin
fcs_output_txd_0 = {CTRL_WIDTH{XGMII_ERROR}};
fcs_output_txd_1 = {CTRL_WIDTH{XGMII_ERROR}};
fcs_output_txc_0 = {CTRL_WIDTH{1'b1}};
fcs_output_txc_1 = {CTRL_WIDTH{1'b1}};
ifg_offset = 8'd0;
extra_cycle = 1'b1;
end
endcase
end
@ -427,10 +295,9 @@ always @* begin
reset_crc = 1'b0;
update_crc = 1'b0;
swap_lanes = 1'b0;
unswap_lanes = 1'b0;
swap_lanes_next = swap_lanes_reg;
frame_ptr_next = frame_ptr_reg;
frame_min_count_next = frame_min_count_reg;
ifg_count_next = ifg_count_reg;
deficit_idle_count_next = deficit_idle_count_reg;
@ -438,12 +305,14 @@ always @* begin
s_axis_tready_next = 1'b0;
s_tdata_next = s_tdata_reg;
s_tkeep_next = s_tkeep_reg;
s_empty_next = s_empty_reg;
m_axis_ptp_ts_next = m_axis_ptp_ts_reg;
m_axis_ptp_ts_adj_next = m_axis_ptp_ts_adj_reg;
m_axis_ptp_ts_tag_next = m_axis_ptp_ts_tag_reg;
m_axis_ptp_ts_valid_next = 1'b0;
m_axis_ptp_ts_valid_int_next = 1'b0;
m_axis_ptp_ts_borrow_next = m_axis_ptp_ts_borrow_reg;
// XGMII idle
xgmii_txd_next = {CTRL_WIDTH{XGMII_IDLE}};
@ -452,19 +321,18 @@ always @* begin
start_packet_next = 2'b00;
error_underflow_next = 1'b0;
if (m_axis_ptp_ts_valid_int_reg) begin
m_axis_ptp_ts_valid_next = 1'b1;
if (PTP_TS_WIDTH == 96 && $signed({1'b0, m_axis_ptp_ts_reg[45:16]}) - $signed(31'd1000000000) > 0) begin
// ns field rollover
m_axis_ptp_ts_next[45:16] = $signed({1'b0, m_axis_ptp_ts_reg[45:16]}) - $signed(31'd1000000000);
m_axis_ptp_ts_next[95:48] = m_axis_ptp_ts_reg[95:48] + 1;
end
if (PTP_TS_ENABLE && PTP_TS_WIDTH == 96) begin
m_axis_ptp_ts_valid_next = m_axis_ptp_ts_valid_int_reg;
m_axis_ptp_ts_adj_next[15:0] = m_axis_ptp_ts_reg[15:0];
{m_axis_ptp_ts_borrow_next, m_axis_ptp_ts_adj_next[45:16]} = $signed({1'b0, m_axis_ptp_ts_reg[45:16]}) - $signed(31'd1000000000);
m_axis_ptp_ts_adj_next[47:46] = 0;
m_axis_ptp_ts_adj_next[95:48] = m_axis_ptp_ts_reg[95:48] + 1;
end
case (state_reg)
STATE_IDLE: begin
// idle state - wait for data
frame_ptr_next = 16'd8;
frame_min_count_next = MIN_FRAME_LENGTH-4-CTRL_WIDTH;
reset_crc = 1'b1;
s_axis_tready_next = 1'b1;
@ -473,33 +341,35 @@ always @* begin
xgmii_txc_next = {CTRL_WIDTH{1'b1}};
s_tdata_next = s_axis_tdata_masked;
s_tkeep_next = s_axis_tkeep;
s_empty_next = keep2empty(s_axis_tkeep);
if (s_axis_tvalid) begin
// XGMII start and preamble
if (ifg_count_reg > 8'd0) begin
// need to send more idles - swap lanes
swap_lanes = 1'b1;
if (swap_lanes_reg) begin
// lanes swapped
if (PTP_TS_WIDTH == 96) begin
m_axis_ptp_ts_next[45:0] = ptp_ts[45:0] + (((PTP_PERIOD_NS * 2**16 + PTP_PERIOD_FNS) * 3) >> 1);
m_axis_ptp_ts_next[95:48] = ptp_ts[95:48];
m_axis_ptp_ts_tag_next = s_axis_tuser >> 1;
m_axis_ptp_ts_valid_int_next = 1'b1;
end else begin
m_axis_ptp_ts_next = ptp_ts + (((PTP_PERIOD_NS * 2**16 + PTP_PERIOD_FNS) * 3) >> 1);
m_axis_ptp_ts_tag_next = s_axis_tuser >> 1;
m_axis_ptp_ts_valid_next = 1'b1;
end
m_axis_ptp_ts_tag_next = s_axis_tuser >> 1;
m_axis_ptp_ts_valid_int_next = 1'b1;
start_packet_next = 2'b10;
end else begin
// no more idles - unswap
unswap_lanes = 1'b1;
// lanes not swapped
if (PTP_TS_WIDTH == 96) begin
m_axis_ptp_ts_next[45:0] = ptp_ts[45:0] + (PTP_PERIOD_NS * 2**16 + PTP_PERIOD_FNS);
m_axis_ptp_ts_next[95:48] = ptp_ts[95:48];
m_axis_ptp_ts_tag_next = s_axis_tuser >> 1;
m_axis_ptp_ts_valid_int_next = 1'b1;
end else begin
m_axis_ptp_ts_next = ptp_ts + (PTP_PERIOD_NS * 2**16 + PTP_PERIOD_FNS);
m_axis_ptp_ts_tag_next = s_axis_tuser >> 1;
m_axis_ptp_ts_valid_next = 1'b1;
end
m_axis_ptp_ts_tag_next = s_axis_tuser >> 1;
m_axis_ptp_ts_valid_int_next = 1'b1;
start_packet_next = 2'b01;
end
xgmii_txd_next = {ETH_SFD, {6{ETH_PRE}}, XGMII_START};
@ -507,9 +377,9 @@ always @* begin
s_axis_tready_next = 1'b1;
state_next = STATE_PAYLOAD;
end else begin
swap_lanes_next = 1'b0;
ifg_count_next = 8'd0;
deficit_idle_count_next = 2'd0;
unswap_lanes = 1'b1;
state_next = STATE_IDLE;
end
end
@ -518,36 +388,37 @@ always @* begin
update_crc = 1'b1;
s_axis_tready_next = 1'b1;
frame_ptr_next = frame_ptr_reg + 16'd8;
if (frame_min_count_reg > CTRL_WIDTH) begin
frame_min_count_next = frame_min_count_reg - CTRL_WIDTH;
end else begin
frame_min_count_next = 0;
end
xgmii_txd_next = s_tdata_reg;
xgmii_txc_next = 8'b00000000;
s_tdata_next = s_axis_tdata_masked;
s_tkeep_next = s_axis_tkeep;
s_empty_next = keep2empty(s_axis_tkeep);
if (s_axis_tvalid) begin
if (s_axis_tlast) begin
frame_ptr_next = frame_ptr_reg + keep2count(s_axis_tkeep);
s_axis_tready_next = 1'b0;
if (s_axis_tuser[0]) begin
xgmii_txd_next = {{3{XGMII_IDLE}}, XGMII_TERM, {4{XGMII_ERROR}}};
xgmii_txc_next = 8'b11111111;
frame_ptr_next = 16'd0;
ifg_count_next = 8'd8;
state_next = STATE_IFG;
end else begin
s_axis_tready_next = 1'b0;
if (ENABLE_PADDING && (frame_ptr_reg < MIN_FL_NOCRC_MS || (frame_ptr_reg == MIN_FL_NOCRC_MS && keep2count(s_axis_tkeep) < MIN_FL_NOCRC_LS))) begin
s_tkeep_next = 8'hff;
frame_ptr_next = frame_ptr_reg + 16'd8;
if (frame_ptr_reg < (MIN_FL_NOCRC_LS > 0 ? MIN_FL_NOCRC_MS : MIN_FL_NOCRC_MS-8)) begin
if (ENABLE_PADDING && frame_min_count_reg) begin
if (frame_min_count_reg > CTRL_WIDTH) begin
s_empty_next = 0;
state_next = STATE_PAD;
end else begin
s_tkeep_next = 8'hff >> ((8-MIN_FL_NOCRC_LS) % 8);
if (keep2empty(s_axis_tkeep) > CTRL_WIDTH-frame_min_count_reg) begin
s_empty_next = CTRL_WIDTH-frame_min_count_reg;
end
state_next = STATE_FCS_1;
end
end else begin
@ -561,7 +432,6 @@ always @* begin
// tvalid deassert, fail frame
xgmii_txd_next = {{3{XGMII_IDLE}}, XGMII_TERM, {4{XGMII_ERROR}}};
xgmii_txc_next = 8'b11111111;
frame_ptr_next = 16'd0;
ifg_count_next = 8'd8;
error_underflow_next = 1'b1;
state_next = STATE_WAIT_END;
@ -575,16 +445,16 @@ always @* begin
xgmii_txc_next = {CTRL_WIDTH{1'b0}};
s_tdata_next = 64'd0;
s_tkeep_next = 8'hff;
s_empty_next = 0;
update_crc = 1'b1;
frame_ptr_next = frame_ptr_reg + 16'd8;
if (frame_ptr_reg < (MIN_FL_NOCRC_LS > 0 ? MIN_FL_NOCRC_MS : MIN_FL_NOCRC_MS-8)) begin
if (frame_min_count_reg > CTRL_WIDTH) begin
frame_min_count_next = frame_min_count_reg - CTRL_WIDTH;
state_next = STATE_PAD;
end else begin
s_tkeep_next = 8'hff >> ((8-MIN_FL_NOCRC_LS) % 8);
frame_min_count_next = 0;
s_empty_next = CTRL_WIDTH-frame_min_count_reg;
state_next = STATE_FCS_1;
end
end
@ -595,10 +465,8 @@ always @* begin
xgmii_txd_next = fcs_output_txd_0;
xgmii_txc_next = fcs_output_txc_0;
frame_ptr_next = 16'd0;
ifg_count_next = (ifg_delay > 8'd12 ? ifg_delay : 8'd12) - ifg_offset + (lanes_swapped ? 8'd4 : 8'd0) + deficit_idle_count_reg;
if (extra_cycle) begin
ifg_count_next = (ifg_delay > 8'd12 ? ifg_delay : 8'd12) - ifg_offset + (swap_lanes_reg ? 8'd4 : 8'd0) + deficit_idle_count_reg;
if (s_empty_reg <= 4) begin
state_next = STATE_FCS_2;
end else begin
state_next = STATE_IFG;
@ -611,18 +479,17 @@ always @* begin
xgmii_txd_next = fcs_output_txd_1;
xgmii_txc_next = fcs_output_txc_1;
reset_crc = 1'b1;
frame_ptr_next = 16'd0;
if (ENABLE_DIC) begin
if (ifg_count_next > 8'd7) begin
state_next = STATE_IFG;
end else begin
if (ifg_count_next >= 8'd4) begin
deficit_idle_count_next = ifg_count_next - 8'd4;
swap_lanes_next = 1'b1;
end else begin
deficit_idle_count_next = ifg_count_next;
ifg_count_next = 8'd0;
swap_lanes_next = 1'b0;
end
s_axis_tready_next = 1'b1;
state_next = STATE_IDLE;
@ -632,6 +499,7 @@ always @* begin
state_next = STATE_IFG;
end else begin
s_axis_tready_next = 1'b1;
swap_lanes_next = ifg_count_next != 0;
state_next = STATE_IDLE;
end
end
@ -644,17 +512,17 @@ always @* begin
ifg_count_next = 8'd0;
end
reset_crc = 1'b1;
if (ENABLE_DIC) begin
if (ifg_count_next > 8'd7) begin
state_next = STATE_IFG;
end else begin
if (ifg_count_next >= 8'd4) begin
deficit_idle_count_next = ifg_count_next - 8'd4;
swap_lanes_next = 1'b1;
end else begin
deficit_idle_count_next = ifg_count_next;
ifg_count_next = 8'd0;
swap_lanes_next = 1'b0;
end
s_axis_tready_next = 1'b1;
state_next = STATE_IDLE;
@ -664,6 +532,7 @@ always @* begin
state_next = STATE_IFG;
end else begin
s_axis_tready_next = 1'b1;
swap_lanes_next = ifg_count_next != 0;
state_next = STATE_IDLE;
end
end
@ -678,8 +547,6 @@ always @* begin
ifg_count_next = 8'd0;
end
reset_crc = 1'b1;
if (s_axis_tvalid) begin
if (s_axis_tlast) begin
s_axis_tready_next = 1'b0;
@ -690,9 +557,11 @@ always @* begin
end else begin
if (ifg_count_next >= 8'd4) begin
deficit_idle_count_next = ifg_count_next - 8'd4;
swap_lanes_next = 1'b1;
end else begin
deficit_idle_count_next = ifg_count_next;
ifg_count_next = 8'd0;
swap_lanes_next = 1'b0;
end
s_axis_tready_next = 1'b1;
state_next = STATE_IDLE;
@ -702,6 +571,7 @@ always @* begin
state_next = STATE_IFG;
end else begin
s_axis_tready_next = 1'b1;
swap_lanes_next = ifg_count_next != 0;
state_next = STATE_IDLE;
end
end
@ -718,36 +588,38 @@ end
always @(posedge clk) begin
state_reg <= state_next;
frame_ptr_reg <= frame_ptr_next;
swap_lanes_reg <= swap_lanes_next;
frame_min_count_reg <= frame_min_count_next;
ifg_count_reg <= ifg_count_next;
deficit_idle_count_reg <= deficit_idle_count_next;
s_tdata_reg <= s_tdata_next;
s_tkeep_reg <= s_tkeep_next;
s_empty_reg <= s_empty_next;
s_axis_tready_reg <= s_axis_tready_next;
m_axis_ptp_ts_reg <= m_axis_ptp_ts_next;
m_axis_ptp_ts_adj_reg <= m_axis_ptp_ts_adj_next;
m_axis_ptp_ts_tag_reg <= m_axis_ptp_ts_tag_next;
m_axis_ptp_ts_valid_reg <= m_axis_ptp_ts_valid_next;
m_axis_ptp_ts_valid_int_reg <= m_axis_ptp_ts_valid_int_next;
m_axis_ptp_ts_borrow_reg <= m_axis_ptp_ts_borrow_next;
if (reset_crc) begin
crc_state <= 32'hFFFFFFFF;
end else if (update_crc) begin
crc_state <= crc_next7;
crc_state <= crc_next[7];
end
swap_txd <= xgmii_txd_next[63:32];
swap_txc <= xgmii_txc_next[7:4];
if (swap_lanes || (lanes_swapped && !unswap_lanes)) begin
lanes_swapped <= 1'b1;
if (swap_lanes_reg) begin
xgmii_txd_reg <= {xgmii_txd_next[31:0], swap_txd};
xgmii_txc_reg <= {xgmii_txc_next[3:0], swap_txc};
end else begin
lanes_swapped <= 1'b0;
xgmii_txd_reg <= xgmii_txd_next;
xgmii_txc_reg <= xgmii_txc_next;
end
@ -758,7 +630,7 @@ always @(posedge clk) begin
if (rst) begin
state_reg <= STATE_IDLE;
frame_ptr_reg <= 16'd0;
swap_lanes_reg <= 1'b0;
ifg_count_reg <= 8'd0;
deficit_idle_count_reg <= 2'd0;
@ -773,10 +645,6 @@ always @(posedge clk) begin
start_packet_reg <= 2'b00;
error_underflow_reg <= 1'b0;
crc_state <= 32'hFFFFFFFF;
lanes_swapped <= 1'b0;
end
end