diff --git a/rtl/eth/taxi_axis_gmii_rx.sv b/rtl/eth/taxi_axis_gmii_rx.sv index 83fc604..fbdfd95 100644 --- a/rtl/eth/taxi_axis_gmii_rx.sv +++ b/rtl/eth/taxi_axis_gmii_rx.sv @@ -51,14 +51,28 @@ module taxi_axis_gmii_rx # /* * Configuration */ + input wire logic [15:0] cfg_rx_max_pkt_len = 16'd1518, input wire logic cfg_rx_enable, /* * Status */ - output wire logic start_packet, - output wire logic error_bad_frame, - output wire logic error_bad_fcs + output wire logic rx_start_packet, + output wire logic stat_rx_byte, + output wire logic [15:0] stat_rx_pkt_len, + output wire logic stat_rx_pkt_fragment, + output wire logic stat_rx_pkt_jabber, + output wire logic stat_rx_pkt_ucast, + output wire logic stat_rx_pkt_mcast, + output wire logic stat_rx_pkt_bcast, + output wire logic stat_rx_pkt_vlan, + output wire logic stat_rx_pkt_good, + output wire logic stat_rx_pkt_bad, + output wire logic stat_rx_err_oversize, + output wire logic stat_rx_err_bad_fcs, + output wire logic stat_rx_err_bad_block, + output wire logic stat_rx_err_framing, + output wire logic stat_rx_err_preamble ); localparam USER_W = (PTP_TS_EN ? PTP_TS_W : 0) + 1; @@ -77,12 +91,12 @@ localparam [7:0] ETH_PRE = 8'h55, ETH_SFD = 8'hD5; -localparam [2:0] - STATE_IDLE = 3'd0, - STATE_PAYLOAD = 3'd1, - STATE_WAIT_LAST = 3'd2; +localparam [1:0] + STATE_IDLE = 2'd0, + STATE_PIPE = 2'd1, + STATE_PAYLOAD = 2'd2; -logic [2:0] state_reg = STATE_IDLE, state_next; +logic [1:0] state_reg = STATE_IDLE, state_next; // datapath control signals logic reset_crc; @@ -109,6 +123,16 @@ logic gmii_rx_er_d2 = 1'b0; logic gmii_rx_er_d3 = 1'b0; logic gmii_rx_er_d4 = 1'b0; +logic frame_error_reg = 1'b0, frame_error_next; +logic in_pre_reg = 1'b0, in_pre_next; +logic pre_ok_reg = 1'b0, pre_ok_next; +logic [3:0] hdr_ptr_reg = '0, hdr_ptr_next; +logic is_mcast_reg = 1'b0, is_mcast_next; +logic is_bcast_reg = 1'b0, is_bcast_next; +logic is_8021q_reg = 1'b0, is_8021q_next; +logic [15:0] frame_len_reg = '0, frame_len_next; +logic [15:0] frame_len_lim_reg = '0, frame_len_lim_next; + logic [DATA_W-1:0] m_axis_rx_tdata_reg = '0, m_axis_rx_tdata_next; logic m_axis_rx_tvalid_reg = 1'b0, m_axis_rx_tvalid_next; logic m_axis_rx_tlast_reg = 1'b0, m_axis_rx_tlast_next; @@ -116,8 +140,22 @@ logic m_axis_rx_tuser_reg = 1'b0, m_axis_rx_tuser_next; logic start_packet_int_reg = 1'b0; logic start_packet_reg = 1'b0; -logic error_bad_frame_reg = 1'b0, error_bad_frame_next; -logic error_bad_fcs_reg = 1'b0, error_bad_fcs_next; + +logic stat_rx_byte_reg = 1'b0, stat_rx_byte_next; +logic [15:0] stat_rx_pkt_len_reg = '0, stat_rx_pkt_len_next; +logic stat_rx_pkt_fragment_reg = 1'b0, stat_rx_pkt_fragment_next; +logic stat_rx_pkt_jabber_reg = 1'b0, stat_rx_pkt_jabber_next; +logic stat_rx_pkt_ucast_reg = 1'b0, stat_rx_pkt_ucast_next; +logic stat_rx_pkt_mcast_reg = 1'b0, stat_rx_pkt_mcast_next; +logic stat_rx_pkt_bcast_reg = 1'b0, stat_rx_pkt_bcast_next; +logic stat_rx_pkt_vlan_reg = 1'b0, stat_rx_pkt_vlan_next; +logic stat_rx_pkt_good_reg = 1'b0, stat_rx_pkt_good_next; +logic stat_rx_pkt_bad_reg = 1'b0, stat_rx_pkt_bad_next; +logic stat_rx_err_oversize_reg = 1'b0, stat_rx_err_oversize_next; +logic stat_rx_err_bad_fcs_reg = 1'b0, stat_rx_err_bad_fcs_next; +logic stat_rx_err_bad_block_reg = 1'b0, stat_rx_err_bad_block_next; +logic stat_rx_err_framing_reg = 1'b0, stat_rx_err_framing_next; +logic stat_rx_err_preamble_reg = 1'b0, stat_rx_err_preamble_next; logic [PTP_TS_W-1:0] ptp_ts_out_reg = '0; @@ -136,9 +174,23 @@ if (PTP_TS_EN) begin assign m_axis_rx.tuser[1 +: PTP_TS_W] = ptp_ts_out_reg; end -assign start_packet = start_packet_reg; -assign error_bad_frame = error_bad_frame_reg; -assign error_bad_fcs = error_bad_fcs_reg; +assign rx_start_packet = start_packet_reg; + +assign stat_rx_byte = stat_rx_byte_reg; +assign stat_rx_pkt_len = stat_rx_pkt_len_reg; +assign stat_rx_pkt_fragment = stat_rx_pkt_fragment_reg; +assign stat_rx_pkt_jabber = stat_rx_pkt_jabber_reg; +assign stat_rx_pkt_ucast = stat_rx_pkt_ucast_reg; +assign stat_rx_pkt_mcast = stat_rx_pkt_mcast_reg; +assign stat_rx_pkt_bcast = stat_rx_pkt_bcast_reg; +assign stat_rx_pkt_vlan = stat_rx_pkt_vlan_reg; +assign stat_rx_pkt_good = stat_rx_pkt_good_reg; +assign stat_rx_pkt_bad = stat_rx_pkt_bad_reg; +assign stat_rx_err_oversize = stat_rx_err_oversize_reg; +assign stat_rx_err_bad_fcs = stat_rx_err_bad_fcs_reg; +assign stat_rx_err_bad_block = stat_rx_err_bad_block_reg; +assign stat_rx_err_framing = stat_rx_err_framing_reg; +assign stat_rx_err_preamble = stat_rx_err_preamble_reg; taxi_lfsr #( .LFSR_W(32), @@ -149,25 +201,50 @@ taxi_lfsr #( .DATA_W(8) ) eth_crc_8 ( - .data_in(gmii_rxd_d4), + .data_in(gmii_rxd_d0), .state_in(crc_state), .data_out(), .state_out(crc_next) ); +wire crc_valid = crc_next == ~32'h2144df1c; + always_comb begin state_next = STATE_IDLE; reset_crc = 1'b0; update_crc = 1'b0; + frame_error_next = frame_error_reg; + in_pre_next = in_pre_reg; + pre_ok_next = pre_ok_reg; + hdr_ptr_next = hdr_ptr_reg; + is_mcast_next = is_mcast_reg; + is_bcast_next = is_bcast_reg; + is_8021q_next = is_8021q_reg; + frame_len_next = frame_len_reg; + frame_len_lim_next = frame_len_lim_reg; + m_axis_rx_tdata_next = '0; m_axis_rx_tvalid_next = 1'b0; m_axis_rx_tlast_next = 1'b0; m_axis_rx_tuser_next = 1'b0; - error_bad_frame_next = 1'b0; - error_bad_fcs_next = 1'b0; + stat_rx_byte_next = 1'b0; + stat_rx_pkt_len_next = '0; + stat_rx_pkt_fragment_next = 1'b0; + stat_rx_pkt_jabber_next = 1'b0; + stat_rx_pkt_ucast_next = 1'b0; + stat_rx_pkt_mcast_next = 1'b0; + stat_rx_pkt_bcast_next = 1'b0; + stat_rx_pkt_vlan_next = 1'b0; + stat_rx_pkt_good_next = 1'b0; + stat_rx_pkt_bad_next = 1'b0; + stat_rx_err_oversize_next = 1'b0; + stat_rx_err_bad_fcs_next = 1'b0; + stat_rx_err_bad_block_next = 1'b0; + stat_rx_err_framing_next = 1'b0; + stat_rx_err_preamble_next = 1'b0; if (!clk_enable) begin // clock disabled - hold state @@ -176,15 +253,95 @@ always_comb begin // MII even cycle - hold state state_next = state_reg; end else begin + + // counter to measure frame length + if (&frame_len_reg == 0) begin + frame_len_next = frame_len_reg + 1; + end + + // counter for max frame length enforcement + if (frame_len_lim_reg != 0) begin + frame_len_lim_next = frame_len_lim_reg - 1; + end + + // address and ethertype checks + if (&hdr_ptr_reg == 0) begin + hdr_ptr_next = hdr_ptr_reg + 1; + end + + case (hdr_ptr_reg) + 4'd0: begin + is_mcast_next = gmii_rxd_d4[0]; + is_bcast_next = gmii_rxd_d4 == 8'hff; + end + 4'd1: is_bcast_next = is_bcast_reg && gmii_rxd_d4 == 8'hff; + 4'd2: is_bcast_next = is_bcast_reg && gmii_rxd_d4 == 8'hff; + 4'd3: is_bcast_next = is_bcast_reg && gmii_rxd_d4 == 8'hff; + 4'd4: is_bcast_next = is_bcast_reg && gmii_rxd_d4 == 8'hff; + 4'd5: is_bcast_next = is_bcast_reg && gmii_rxd_d4 == 8'hff; + 4'd12: is_8021q_next = gmii_rxd_d4 == 8'h81; + 4'd13: is_8021q_next = is_8021q_reg && gmii_rxd_d4 == 8'h00; + default: begin + // do nothing + end + endcase + case (state_reg) STATE_IDLE: begin // idle state - wait for packet reset_crc = 1'b1; + frame_error_next = 1'b0; + frame_len_next = 1; + frame_len_lim_next = cfg_rx_max_pkt_len; + hdr_ptr_next = 0; + is_mcast_next = 1'b0; + is_bcast_next = 1'b0; + is_8021q_next = 1'b0; - if (gmii_rx_dv_d4 && !gmii_rx_er_d4 && gmii_rxd_d4 == ETH_SFD && cfg_rx_enable) begin + state_next = STATE_IDLE; + + if (gmii_rx_dv_d0) begin + if (gmii_rx_er_d0) begin + // error in preamble + in_pre_next = 1'b0; + pre_ok_next = 1'b0; + stat_rx_err_bad_block_next = 1'b1; + end else if (gmii_rxd_d0 == ETH_PRE) begin + // normal preamble + end else if (gmii_rxd_d0 == ETH_SFD) begin + // start + in_pre_next = 1'b0; + if (in_pre_reg && cfg_rx_enable) begin + state_next = STATE_PIPE; + end + end else begin + // abnormal preamble + pre_ok_next = 1'b0; + end + end else begin + // reset and wait for data + in_pre_next = 1'b1; + pre_ok_next = 1'b1; + end + end + STATE_PIPE: begin + // wait for FCS pipeline to fill + update_crc = 1'b1; + hdr_ptr_next = 0; + is_mcast_next = 1'b0; + is_bcast_next = 1'b0; + is_8021q_next = 1'b0; + + if (gmii_rx_dv && gmii_rx_er) begin + frame_error_next = 1'b1; + stat_rx_err_bad_block_next = 1'b1; + end + + if (gmii_rx_dv_d4 && !gmii_rx_er_d4 && gmii_rxd_d4 == ETH_SFD) begin + stat_rx_byte_next = 1'b1; state_next = STATE_PAYLOAD; end else begin - state_next = STATE_IDLE; + state_next = STATE_PIPE; end end STATE_PAYLOAD: begin @@ -194,42 +351,55 @@ always_comb begin m_axis_rx_tdata_next = gmii_rxd_d4; m_axis_rx_tvalid_next = 1'b1; - if (gmii_rx_dv_d4 && gmii_rx_er_d4) begin - // error - m_axis_rx_tlast_next = 1'b1; - m_axis_rx_tuser_next = 1'b1; - error_bad_frame_next = 1'b1; - state_next = STATE_WAIT_LAST; - end else if (!gmii_rx_dv) begin + stat_rx_byte_next = gmii_rx_dv; + + if (gmii_rx_dv && gmii_rx_er) begin + frame_error_next = 1'b1; + stat_rx_err_bad_block_next = 1'b1; + end + + if (!gmii_rx_dv) begin // end of packet m_axis_rx_tlast_next = 1'b1; - if (gmii_rx_er_d0 || gmii_rx_er_d1 || gmii_rx_er_d2 || gmii_rx_er_d3) begin - // error received in FCS bytes + stat_rx_pkt_len_next = frame_len_reg; + stat_rx_pkt_ucast_next = !is_mcast_reg; + stat_rx_pkt_mcast_next = is_mcast_reg && !is_bcast_reg; + stat_rx_pkt_bcast_next = is_bcast_reg; + stat_rx_pkt_vlan_next = is_8021q_reg; + stat_rx_err_oversize_next = frame_len_lim_reg == 0; + stat_rx_err_framing_next = !gmii_rx_dv_d0; + stat_rx_err_preamble_next = !pre_ok_reg; + if (frame_error_next) begin + // error m_axis_rx_tuser_next = 1'b1; - error_bad_frame_next = 1'b1; - end else if ({gmii_rxd_d0, gmii_rxd_d1, gmii_rxd_d2, gmii_rxd_d3} == ~crc_next) begin + stat_rx_pkt_fragment_next = frame_len_reg[15:6] == 0; + stat_rx_pkt_jabber_next = frame_len_lim_reg == 0; + stat_rx_pkt_bad_next = 1'b1; + end else if (crc_valid) begin // FCS good - m_axis_rx_tuser_next = 1'b0; + if (frame_len_lim_reg == 0) begin + // too long + m_axis_rx_tuser_next = 1'b1; + stat_rx_pkt_bad_next = 1'b1; + end else begin + // length OK + m_axis_rx_tuser_next = 1'b0; + stat_rx_pkt_good_next = 1'b1; + end end else begin // FCS bad m_axis_rx_tuser_next = 1'b1; - error_bad_frame_next = 1'b1; - error_bad_fcs_next = 1'b1; + stat_rx_pkt_fragment_next = frame_len_reg[15:6] == 0; + stat_rx_pkt_jabber_next = frame_len_lim_reg == 0; + stat_rx_pkt_bad_next = 1'b1; + stat_rx_err_bad_fcs_next = 1'b1; end + reset_crc = 1'b1; state_next = STATE_IDLE; end else begin state_next = STATE_PAYLOAD; end end - STATE_WAIT_LAST: begin - // wait for end of packet - - if (~gmii_rx_dv) begin - state_next = STATE_IDLE; - end else begin - state_next = STATE_WAIT_LAST; - end - end default: begin // invalid state, return to idle state_next = STATE_IDLE; @@ -241,6 +411,16 @@ end always_ff @(posedge clk) begin state_reg <= state_next; + frame_error_reg <= frame_error_next; + in_pre_reg <= in_pre_next; + pre_ok_reg <= pre_ok_next; + hdr_ptr_reg <= hdr_ptr_next; + is_mcast_reg <= is_mcast_next; + is_bcast_reg <= is_bcast_next; + is_8021q_reg <= is_8021q_next; + frame_len_reg <= frame_len_next; + frame_len_lim_reg <= frame_len_lim_next; + m_axis_rx_tdata_reg <= m_axis_rx_tdata_next; m_axis_rx_tvalid_reg <= m_axis_rx_tvalid_next; m_axis_rx_tlast_reg <= m_axis_rx_tlast_next; @@ -256,7 +436,7 @@ always_ff @(posedge clk) begin if (clk_enable) begin if (mii_select) begin - mii_odd <= !mii_odd; + mii_odd <= !mii_odd || !gmii_rx_dv; if (in_frame) begin in_frame <= gmii_rx_dv; @@ -274,20 +454,20 @@ always_ff @(posedge clk) begin gmii_rxd_d3 <= gmii_rxd_d2; gmii_rxd_d4 <= gmii_rxd_d3; - gmii_rx_dv_d0 <= gmii_rx_dv & gmii_rx_dv_d0; - gmii_rx_dv_d1 <= gmii_rx_dv_d0 & gmii_rx_dv; - gmii_rx_dv_d2 <= gmii_rx_dv_d1 & gmii_rx_dv; - gmii_rx_dv_d3 <= gmii_rx_dv_d2 & gmii_rx_dv; - gmii_rx_dv_d4 <= gmii_rx_dv_d3 & gmii_rx_dv; + gmii_rx_dv_d0 <= gmii_rx_dv; + gmii_rx_dv_d1 <= gmii_rx_dv_d0; + gmii_rx_dv_d2 <= gmii_rx_dv_d1; + gmii_rx_dv_d3 <= gmii_rx_dv_d2; + gmii_rx_dv_d4 <= gmii_rx_dv_d3; - gmii_rx_er_d0 <= gmii_rx_er | gmii_rx_er_d0; + gmii_rx_er_d0 <= gmii_rx_er; gmii_rx_er_d1 <= gmii_rx_er_d0; gmii_rx_er_d2 <= gmii_rx_er_d1; gmii_rx_er_d3 <= gmii_rx_er_d2; gmii_rx_er_d4 <= gmii_rx_er_d3; end else begin - gmii_rx_dv_d0 <= gmii_rx_dv; - gmii_rx_er_d0 <= gmii_rx_er; + gmii_rx_dv_d0 <= gmii_rx_dv & gmii_rx_dv_d0; + gmii_rx_er_d0 <= gmii_rx_er | gmii_rx_er_d0; end end else begin if (in_frame) begin @@ -304,10 +484,10 @@ always_ff @(posedge clk) begin gmii_rxd_d4 <= gmii_rxd_d3; gmii_rx_dv_d0 <= gmii_rx_dv; - gmii_rx_dv_d1 <= gmii_rx_dv_d0 & gmii_rx_dv; - gmii_rx_dv_d2 <= gmii_rx_dv_d1 & gmii_rx_dv; - gmii_rx_dv_d3 <= gmii_rx_dv_d2 & gmii_rx_dv; - gmii_rx_dv_d4 <= gmii_rx_dv_d3 & gmii_rx_dv; + gmii_rx_dv_d1 <= gmii_rx_dv_d0; + gmii_rx_dv_d2 <= gmii_rx_dv_d1; + gmii_rx_dv_d3 <= gmii_rx_dv_d2; + gmii_rx_dv_d4 <= gmii_rx_dv_d3; gmii_rx_er_d0 <= gmii_rx_er; gmii_rx_er_d1 <= gmii_rx_er_d0; @@ -323,8 +503,21 @@ always_ff @(posedge clk) begin crc_state <= crc_next; end - error_bad_frame_reg <= error_bad_frame_next; - error_bad_fcs_reg <= error_bad_fcs_next; + stat_rx_byte_reg <= stat_rx_byte_next; + stat_rx_pkt_len_reg <= stat_rx_pkt_len_next; + stat_rx_pkt_fragment_reg <= stat_rx_pkt_fragment_next; + stat_rx_pkt_jabber_reg <= stat_rx_pkt_jabber_next; + stat_rx_pkt_ucast_reg <= stat_rx_pkt_ucast_next; + stat_rx_pkt_mcast_reg <= stat_rx_pkt_mcast_next; + stat_rx_pkt_bcast_reg <= stat_rx_pkt_bcast_next; + stat_rx_pkt_vlan_reg <= stat_rx_pkt_vlan_next; + stat_rx_pkt_good_reg <= stat_rx_pkt_good_next; + stat_rx_pkt_bad_reg <= stat_rx_pkt_bad_next; + stat_rx_err_oversize_reg <= stat_rx_err_oversize_next; + stat_rx_err_bad_fcs_reg <= stat_rx_err_bad_fcs_next; + stat_rx_err_bad_block_reg <= stat_rx_err_bad_block_next; + stat_rx_err_framing_reg <= stat_rx_err_framing_next; + stat_rx_err_preamble_reg <= stat_rx_err_preamble_next; if (rst) begin state_reg <= STATE_IDLE; @@ -333,8 +526,22 @@ always_ff @(posedge clk) begin start_packet_int_reg <= 1'b0; start_packet_reg <= 1'b0; - error_bad_frame_reg <= 1'b0; - error_bad_fcs_reg <= 1'b0; + + stat_rx_byte_reg <= 1'b0; + stat_rx_pkt_len_reg <= '0; + stat_rx_pkt_fragment_reg <= 1'b0; + stat_rx_pkt_jabber_reg <= 1'b0; + stat_rx_pkt_ucast_reg <= 1'b0; + stat_rx_pkt_mcast_reg <= 1'b0; + stat_rx_pkt_bcast_reg <= 1'b0; + stat_rx_pkt_vlan_reg <= 1'b0; + stat_rx_pkt_good_reg <= 1'b0; + stat_rx_pkt_bad_reg <= 1'b0; + stat_rx_err_oversize_reg <= 1'b0; + stat_rx_err_bad_fcs_reg <= 1'b0; + stat_rx_err_bad_block_reg <= 1'b0; + stat_rx_err_framing_reg <= 1'b0; + stat_rx_err_preamble_reg <= 1'b0; in_frame <= 1'b0; mii_odd <= 1'b0; diff --git a/rtl/eth/taxi_eth_mac_1g.sv b/rtl/eth/taxi_eth_mac_1g.sv index bb2e533..d59b51d 100644 --- a/rtl/eth/taxi_eth_mac_1g.sv +++ b/rtl/eth/taxi_eth_mac_1g.sv @@ -202,14 +202,28 @@ axis_gmii_rx_inst ( /* * Configuration */ + .cfg_rx_max_pkt_len(16'd9218), .cfg_rx_enable(cfg_rx_enable), /* * Status */ - .start_packet(rx_start_packet), - .error_bad_frame(rx_error_bad_frame), - .error_bad_fcs(rx_error_bad_fcs) + .rx_start_packet(rx_start_packet), + .stat_rx_byte(), + .stat_rx_pkt_len(), + .stat_rx_pkt_fragment(), + .stat_rx_pkt_jabber(), + .stat_rx_pkt_ucast(), + .stat_rx_pkt_mcast(), + .stat_rx_pkt_bcast(), + .stat_rx_pkt_vlan(), + .stat_rx_pkt_good(), + .stat_rx_pkt_bad(rx_error_bad_frame), + .stat_rx_err_oversize(), + .stat_rx_err_bad_fcs(rx_error_bad_fcs), + .stat_rx_err_bad_block(), + .stat_rx_err_framing(), + .stat_rx_err_preamble() ); taxi_axis_gmii_tx #( diff --git a/tb/eth/taxi_axis_gmii_rx/test_taxi_axis_gmii_rx.py b/tb/eth/taxi_axis_gmii_rx/test_taxi_axis_gmii_rx.py index 25c129c..760de99 100644 --- a/tb/eth/taxi_axis_gmii_rx/test_taxi_axis_gmii_rx.py +++ b/tb/eth/taxi_axis_gmii_rx/test_taxi_axis_gmii_rx.py @@ -45,6 +45,7 @@ class TB: dut.clk_enable.setimmediatevalue(1) dut.mii_select.setimmediatevalue(0) + dut.cfg_rx_max_pkt_len.setimmediatevalue(0) dut.cfg_rx_enable.setimmediatevalue(0) async def reset(self): @@ -83,6 +84,7 @@ async def run_test(dut, payload_lengths=None, payload_data=None, ifg=12, enable_ tb.source.ifg = ifg tb.dut.mii_select.value = mii_sel + tb.dut.cfg_rx_max_pkt_len.value = 9218 tb.dut.cfg_rx_enable.value = 1 if enable_gen is not None: @@ -121,6 +123,44 @@ async def run_test(dut, payload_lengths=None, payload_data=None, ifg=12, enable_ await RisingEdge(dut.clk) +async def run_test_oversize(dut, ifg=12, enable_gen=None, mii_sel=False): + + tb = TB(dut) + + tb.source.ifg = ifg + tb.dut.cfg_rx_max_pkt_len.value = 1518 + tb.dut.cfg_rx_enable.value = 1 + + if enable_gen is not None: + tb.set_enable_generator(enable_gen()) + + await tb.reset() + + test_data = bytes(x for x in range(60)) + + for k in range(3): + test_frame = GmiiFrame.from_payload(test_data) + if k == 1: + test_frame = GmiiFrame.from_payload(bytes(x % 256 for x in range(1515))) + await tb.source.send(test_frame) + + for k in range(3): + rx_frame = await tb.sink.recv() + + if k == 1: + frame_error = rx_frame.tuser[-1] & 1 + assert frame_error + else: + frame_error = rx_frame.tuser & 1 + assert rx_frame.tdata == test_data + assert frame_error == 0 + + assert tb.sink.empty() + + await RisingEdge(dut.clk) + await RisingEdge(dut.clk) + + def size_list(): return list(range(60, 128)) + [512, 1514] + [60]*10 @@ -143,6 +183,12 @@ if cocotb.SIM_NAME: factory.add_option("mii_sel", [False, True]) factory.generate_tests() + factory = TestFactory(run_test_oversize) + factory.add_option("ifg", [12, 0]) + factory.add_option("enable_gen", [None, cycle_en]) + factory.add_option("mii_sel", [False, True]) + factory.generate_tests() + # cocotb-test diff --git a/tb/eth/taxi_axis_gmii_rx/test_taxi_axis_gmii_rx.sv b/tb/eth/taxi_axis_gmii_rx/test_taxi_axis_gmii_rx.sv index 3ead51a..4681272 100644 --- a/tb/eth/taxi_axis_gmii_rx/test_taxi_axis_gmii_rx.sv +++ b/tb/eth/taxi_axis_gmii_rx/test_taxi_axis_gmii_rx.sv @@ -41,11 +41,25 @@ logic [PTP_TS_W-1:0] ptp_ts; logic clk_enable; logic mii_select; +logic [15:0] cfg_rx_max_pkt_len; logic cfg_rx_enable; -logic start_packet; -logic error_bad_frame; -logic error_bad_fcs; +logic rx_start_packet; +logic stat_rx_byte; +logic [15:0] stat_rx_pkt_len; +logic stat_rx_pkt_fragment; +logic stat_rx_pkt_jabber; +logic stat_rx_pkt_ucast; +logic stat_rx_pkt_mcast; +logic stat_rx_pkt_bcast; +logic stat_rx_pkt_vlan; +logic stat_rx_pkt_good; +logic stat_rx_pkt_bad; +logic stat_rx_err_oversize; +logic stat_rx_err_bad_fcs; +logic stat_rx_err_bad_block; +logic stat_rx_err_framing; +logic stat_rx_err_preamble; taxi_axis_gmii_rx #( .DATA_W(DATA_W), @@ -82,14 +96,28 @@ uut ( /* * Configuration */ + .cfg_rx_max_pkt_len(cfg_rx_max_pkt_len), .cfg_rx_enable(cfg_rx_enable), /* * Status */ - .start_packet(start_packet), - .error_bad_frame(error_bad_frame), - .error_bad_fcs(error_bad_fcs) + .rx_start_packet(rx_start_packet), + .stat_rx_byte(stat_rx_byte), + .stat_rx_pkt_len(stat_rx_pkt_len), + .stat_rx_pkt_fragment(stat_rx_pkt_fragment), + .stat_rx_pkt_jabber(stat_rx_pkt_jabber), + .stat_rx_pkt_ucast(stat_rx_pkt_ucast), + .stat_rx_pkt_mcast(stat_rx_pkt_mcast), + .stat_rx_pkt_bcast(stat_rx_pkt_bcast), + .stat_rx_pkt_vlan(stat_rx_pkt_vlan), + .stat_rx_pkt_good(stat_rx_pkt_good), + .stat_rx_pkt_bad(stat_rx_pkt_bad), + .stat_rx_err_oversize(stat_rx_err_oversize), + .stat_rx_err_bad_fcs(stat_rx_err_bad_fcs), + .stat_rx_err_bad_block(stat_rx_err_bad_block), + .stat_rx_err_framing(stat_rx_err_framing), + .stat_rx_err_preamble(stat_rx_err_preamble) ); endmodule