diff --git a/src/zircon/rtl/zircon_ip_rx_parse.sv b/src/zircon/rtl/zircon_ip_rx_parse.sv index 3eedb20..33aa2af 100644 --- a/src/zircon/rtl/zircon_ip_rx_parse.sv +++ b/src/zircon/rtl/zircon_ip_rx_parse.sv @@ -38,12 +38,12 @@ module zircon_ip_rx_parse # // Metadata output (64 bit blocks): // 00: flags / payload len, pkt sum // 01: RSS hash / header and payload offsets -// 02: vlan tags / dscp, ecn +// 02: vlan tags // 03: eth dst // 04: eth src, ethtype // 05: protos/hdrs with offsets // 06: protos/hdrs with offsets -// 07: ip id/fl / protocol, ttl/hl +// 07: protocol, ttl/hl / dscp, ecn, ip id/fl // 08: ipv6 dst // 09: ipv6 dst // 10: ipv6 src @@ -51,7 +51,7 @@ module zircon_ip_rx_parse # // 12: l4 ports / tcp flags // 13: tcp wnd/urg // 14: tcp seq/ack -// 15: +// 15: localparam DATA_W = s_axis_pkt.DATA_W; localparam META_W = m_axis_meta.DATA_W; @@ -176,7 +176,7 @@ logic s_axis_pkt_tready_reg = 1'b0, s_axis_pkt_tready_next; // metadata RAM localparam META_AW = 5; -logic [31:0] meta_ram_a[2**META_AW]; +logic [31:0] meta_ram_a[2**META_AW] = '{default: '0}; logic [31:0] meta_ram_a_wr_data; logic [3:0] meta_ram_a_wr_strb; logic [META_AW-1:0] meta_ram_a_wr_addr; @@ -185,7 +185,7 @@ logic [31:0] meta_ram_a_rd_data_reg = '0; logic [META_AW-1:0] meta_ram_a_rd_addr; logic meta_ram_a_rd_en; -logic [31:0] meta_ram_b[2**META_AW]; +logic [31:0] meta_ram_b[2**META_AW] = '{default: '0}; logic [31:0] meta_ram_b_wr_data; logic [3:0] meta_ram_b_wr_strb; logic [META_AW-1:0] meta_ram_b_wr_addr; @@ -504,6 +504,12 @@ always_comb begin meta_ram_b_wr_addr = {meta_wr_slot_reg[0], 4'd4}; meta_ram_b_wr_en = 1'b1; + // clear VLAN tags + meta_ram_a_wr_data = '0; + meta_ram_a_wr_strb = 4'b1111; + meta_ram_a_wr_addr = {meta_wr_slot_reg[0], 4'd2}; + meta_ram_a_wr_en = 1'b1; + l3_offset_next = offset_reg; payload_offset_next = offset_reg; @@ -580,9 +586,9 @@ always_comb begin payload_len_next = pkt_data_be[15:0] - 4; // store DSCP and ECN - meta_ram_b_wr_data = {pkt_data_be[15:0], pkt_data_be[31:16]}; - meta_ram_b_wr_strb = 4'b0001; - meta_ram_b_wr_addr = {meta_wr_slot_reg[0], 4'd2}; + meta_ram_b_wr_data = {pkt_data_be[23:0], pkt_data_be[31:24]}; + meta_ram_b_wr_strb = 4'b1000; + meta_ram_b_wr_addr = {meta_wr_slot_reg[0], 4'd7}; meta_ram_b_wr_en = 1'b1; if (pkt_data_be[31:28] == 4'd4) begin @@ -594,10 +600,10 @@ always_comb begin end STATE_IPV4_2: begin // store IP ID - meta_ram_a_wr_data = {pkt_data_be[15:0], pkt_data_be[31:16]}; - meta_ram_a_wr_strb = 4'b0011; - meta_ram_a_wr_addr = {meta_wr_slot_reg[0], 4'd7}; - meta_ram_a_wr_en = 1'b1; + meta_ram_b_wr_data = {pkt_data_be[15:0], pkt_data_be[31:16]}; + meta_ram_b_wr_strb = 4'b0011; + meta_ram_b_wr_addr = {meta_wr_slot_reg[0], 4'd7}; + meta_ram_b_wr_en = 1'b1; if (pkt_data_be[13] || pkt_data_be[12:0] != 0) begin // MF bit set or nonzero fragment offset @@ -608,10 +614,10 @@ always_comb begin end STATE_IPV4_3: begin // store TTL and protocol - meta_ram_b_wr_data = {pkt_data_be[15:0], pkt_data_be[31:16]}; // TODO check this - meta_ram_b_wr_strb = 4'b0011; - meta_ram_b_wr_addr = {meta_wr_slot_reg[0], 4'd7}; - meta_ram_b_wr_en = 1'b1; + meta_ram_a_wr_data = {pkt_data_be[15:0], pkt_data_be[31:16]}; // TODO check this + meta_ram_a_wr_strb = 4'b0011; + meta_ram_a_wr_addr = {meta_wr_slot_reg[0], 4'd7}; + meta_ram_a_wr_en = 1'b1; next_hdr_next = pkt_data_be[23:16]; @@ -693,16 +699,10 @@ always_comb begin // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ // from https://www.ietf.org/rfc/rfc2460.txt STATE_IPV6_1: begin - // store flow label - meta_ram_a_wr_data = pkt_data_be; - meta_ram_a_wr_strb = 4'b0111; - meta_ram_a_wr_addr = {meta_wr_slot_reg[0], 4'd7}; - meta_ram_a_wr_en = 1'b1; - - // store DSCP and ECN - meta_ram_b_wr_data = {24'd0, pkt_data_be[27:20]}; - meta_ram_b_wr_strb = 4'b0001; - meta_ram_b_wr_addr = {meta_wr_slot_reg[0], 4'd2}; + // store flow label, DSCP, and ECN + meta_ram_b_wr_data = {pkt_data_be[27:20], 4'd0, pkt_data_be[19:0]}; + meta_ram_b_wr_strb = 4'b1111; + meta_ram_b_wr_addr = {meta_wr_slot_reg[0], 4'd7}; meta_ram_b_wr_en = 1'b1; if (pkt_data_be[31:28] == 4'd6) begin @@ -714,10 +714,10 @@ always_comb begin end STATE_IPV6_2: begin // store next header, hop limit - meta_ram_b_wr_data = pkt_data; // TODO check this - meta_ram_b_wr_strb = 4'b0011; - meta_ram_b_wr_addr = {meta_wr_slot_reg[0], 4'd7}; - meta_ram_b_wr_en = 1'b1; + meta_ram_a_wr_data = pkt_data; // TODO check this + meta_ram_a_wr_strb = 4'b0011; + meta_ram_a_wr_addr = {meta_wr_slot_reg[0], 4'd7}; + meta_ram_a_wr_en = 1'b1; payload_len_next = pkt_data_be[31:16]; next_hdr_next = pkt_data_be[15:8]; @@ -870,8 +870,8 @@ always_comb begin end end // TCP header - // 0 1 2 3 - // 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 + // 0 1 2 3 + // 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ // | Source Port | Destination Port | // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ @@ -965,8 +965,8 @@ always_comb begin end end // UDP header - // 0 1 2 3 - // 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 + // 0 1 2 3 + // 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ // | Source Port | Destination Port | // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ diff --git a/src/zircon/rtl/zircon_ip_tx_deparse.sv b/src/zircon/rtl/zircon_ip_tx_deparse.sv index 79eef5d..bd71d84 100644 --- a/src/zircon/rtl/zircon_ip_tx_deparse.sv +++ b/src/zircon/rtl/zircon_ip_tx_deparse.sv @@ -39,13 +39,13 @@ module zircon_ip_tx_deparse # // Metadata input (64 bit blocks): // 00: flags / payload len, payload sum -// 01: -// 02: vlan tags / dscp, ecn +// 01: +// 02: vlan tags // 03: eth dst // 04: eth src, ethtype -// 05: -// 06: -// 07: ip id/fl / protocol, ttl/hl +// 05: +// 06: +// 07: protocol, ttl/hl / dscp, ecn, ip id/fl // 08: ipv6 dst // 09: ipv6 dst // 10: ipv6 src @@ -53,7 +53,7 @@ module zircon_ip_tx_deparse # // 12: l4 ports / tcp flags // 13: tcp wnd/urg // 14: tcp seq/ack -// 15: +// 15: localparam DATA_W = m_axis_pkt.DATA_W; localparam KEEP_W = m_axis_pkt.KEEP_W; @@ -193,7 +193,7 @@ logic m_axis_pkt_tlast_reg = 1'b0, m_axis_pkt_tlast_next; // metadata RAM localparam META_AW = 5; -logic [31:0] meta_ram_a[2**META_AW]; +logic [31:0] meta_ram_a[2**META_AW] = '{default: '0}; logic [31:0] meta_ram_a_wr_data; logic [3:0] meta_ram_a_wr_strb; logic [META_AW-1:0] meta_ram_a_wr_addr; @@ -203,7 +203,7 @@ logic [META_AW-1:0] meta_ram_a_rd_addr; wire [31:0] meta_ram_a_rd_data = meta_ram_a[meta_ram_a_rd_addr]; wire [31:0] meta_ram_a_rd_data_be = swab32(meta_ram_a_rd_data); -logic [31:0] meta_ram_b[2**META_AW]; +logic [31:0] meta_ram_b[2**META_AW] = '{default: '0}; logic [31:0] meta_ram_b_wr_data; logic [3:0] meta_ram_b_wr_strb; logic [META_AW-1:0] meta_ram_b_wr_addr; @@ -319,15 +319,16 @@ always_comb begin end end 4'd2: begin - // vlan tags / DSCP, ECN - meta_l3_cksum_next = 21'({8'h45, s_axis_meta.tdata[47:40]}); + // vlan tags + + meta_l3_cksum_next = 21'({8'h45, 8'd0}); // IP version, IHL meta_common_cksum_next = 21'(meta_payload_len_reg); end 4'd3: begin // eth dst - meta_l3_cksum_next = meta_l3_cksum_reg + 21'd20; + meta_l3_cksum_next = meta_l3_cksum_reg + 21'd20; // IP header length if (meta_flag_reg[FLG_UDP]) begin meta_l4_cksum_next = meta_l4_cksum_reg + 21'(meta_payload_len_reg); @@ -343,10 +344,11 @@ always_comb begin // nothing end 4'd7: begin - // IP ID/FL / protocol, TTL/HL - meta_cksum_in[31:0] = {16'd0, s_axis_meta.tdata[15:0]}; - meta_cksum_in[63:32] = {16'd0, s_axis_meta.tdata[47:40], 8'd0}; + // protocol, TTL/HL / IP ID/FL, dscp, ecn + meta_cksum_in[31:0] = {8'd0, s_axis_meta.tdata[63:56], s_axis_meta.tdata[47:32]}; // DSCP, ECN, IP ID + meta_cksum_in[63:32] = {16'd0, s_axis_meta.tdata[15:8], 8'd0}; // TTL + // protocol if (meta_flag_reg[FLG_TCP]) begin meta_common_cksum_next = meta_common_cksum_reg + 21'(PROTO_TCP); end else if (meta_flag_reg[FLG_UDP]) begin @@ -354,7 +356,7 @@ always_comb begin end else if (meta_flag_reg[FLG_ICMP]) begin meta_common_cksum_next = meta_common_cksum_reg + 21'(PROTO_ICMP); end else begin - meta_common_cksum_next = meta_common_cksum_reg + 21'(s_axis_meta.tdata[39:32]); + meta_common_cksum_next = meta_common_cksum_reg + 21'(s_axis_meta.tdata[7:0]); end end 4'd8: begin @@ -629,8 +631,8 @@ always_comb begin PKT_STATE_IPV4_1: begin data_next[7:4] = 4'd4; // version data_next[3:0] = 4'd5; // IHL - meta_ram_b_rd_addr = {meta_rd_slot_reg[0], 4'd2}; - data_next[15:8] = meta_ram_b_rd_data[23:16]; // DSCP and ECN + meta_ram_b_rd_addr = {meta_rd_slot_reg[0], 4'd7}; + data_next[15:8] = meta_ram_b_rd_data[31:24]; // DSCP and ECN data_next[31:16] = swab16(pkt_l3_len_reg); // total length data_valid_next = 1'b1; @@ -638,8 +640,8 @@ always_comb begin end PKT_STATE_IPV4_2: begin // IP ID - meta_ram_a_rd_addr = {meta_rd_slot_reg[0], 4'd7}; - data_next[15:0] = swab16(meta_ram_a_rd_data[15:0]); + meta_ram_b_rd_addr = {meta_rd_slot_reg[0], 4'd7}; + data_next[15:0] = swab16(meta_ram_b_rd_data[15:0]); data_next[31:16] = '0; // flags, fragment offset data_valid_next = 1'b1; @@ -647,9 +649,9 @@ always_comb begin end PKT_STATE_IPV4_3: begin // TTL, protocol, header checksum - meta_ram_b_rd_addr = {meta_rd_slot_reg[0], 4'd7}; - data_next[7:0] = meta_ram_b_rd_data[15:8]; // TTL - data_next[15:8] = meta_ram_b_rd_data[7:0]; // protocol + meta_ram_a_rd_addr = {meta_rd_slot_reg[0], 4'd7}; + data_next[7:0] = meta_ram_a_rd_data[15:8]; // TTL + data_next[15:8] = meta_ram_a_rd_data[7:0]; // protocol data_next[31:16] = swab16(pkt_l3_cksum_reg[15:0]); // header checksum data_valid_next = 1'b1; @@ -660,7 +662,7 @@ always_comb begin end else if (pkt_flag_reg[FLG_ICMP]) begin data_next[15:8] = PROTO_ICMP; end else begin - data_next[15:8] = meta_ram_b_rd_data[7:0]; + data_next[15:8] = meta_ram_a_rd_data[7:0]; end pkt_state_next = PKT_STATE_IPV4_4; @@ -715,19 +717,18 @@ always_comb begin PKT_STATE_IPV6_1: begin // flow label data_next[7:4] = 4'd6; // version - meta_ram_b_rd_addr = {meta_rd_slot_reg[0], 4'd2}; - {data_next[3:0], data_next[15:12]} = meta_ram_b_rd_data[23:16]; // Traffic class - meta_ram_a_rd_addr = {meta_rd_slot_reg[0], 4'd7}; - {data_next[11:8], data_next[23:16], data_next[31:24]} = meta_ram_a_rd_data[19:0]; // Flow label + meta_ram_b_rd_addr = {meta_rd_slot_reg[0], 4'd7}; + {data_next[3:0], data_next[15:12]} = meta_ram_b_rd_data[31:24]; // Traffic class + {data_next[11:8], data_next[23:16], data_next[31:24]} = meta_ram_b_rd_data[19:0]; // Flow label data_valid_next = 1'b1; pkt_state_next = PKT_STATE_IPV6_2; end PKT_STATE_IPV6_2: begin // hop limit - meta_ram_b_rd_addr = {meta_rd_slot_reg[0], 4'd7}; - data_next[31:24] = meta_ram_b_rd_data[15:8]; // hop limit - data_next[23:16] = meta_ram_b_rd_data[7:0]; // next header + meta_ram_a_rd_addr = {meta_rd_slot_reg[0], 4'd7}; + data_next[31:24] = meta_ram_a_rd_data[15:8]; // hop limit + data_next[23:16] = meta_ram_a_rd_data[7:0]; // next header data_next[15:0] = swab16(pkt_l3_len_reg); // payload length data_valid_next = 1'b1; @@ -738,7 +739,7 @@ always_comb begin end else if (pkt_flag_reg[FLG_ICMP]) begin data_next[23:16] = PROTO_IPV6_ICMP; end else begin - data_next[23:16] = meta_ram_b_rd_data[7:0]; + data_next[23:16] = meta_ram_a_rd_data[7:0]; end pkt_state_next = PKT_STATE_IPV6_3; @@ -814,8 +815,8 @@ always_comb begin end end // Build TCP header - // 0 1 2 3 - // 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 + // 0 1 2 3 + // 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ // | Source Port | Destination Port | // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ @@ -880,8 +881,8 @@ always_comb begin pkt_state_next = PKT_STATE_FINISH_1; end // Build UDP header - // 0 1 2 3 - // 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 + // 0 1 2 3 + // 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ // | Source Port | Destination Port | // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ diff --git a/src/zircon/tb/zircon_ip_rx_parse/test_zircon_ip_rx_parse.py b/src/zircon/tb/zircon_ip_rx_parse/test_zircon_ip_rx_parse.py index 66c7212..d7c66c5 100644 --- a/src/zircon/tb/zircon_ip_rx_parse/test_zircon_ip_rx_parse.py +++ b/src/zircon/tb/zircon_ip_rx_parse/test_zircon_ip_rx_parse.py @@ -288,11 +288,10 @@ async def run_test(dut): tb.log.info("L4 offset: %d (%d)", l4_offset*4+2, l4_offset) tb.log.info("Payload offset: %d (%d)", payload_offset*4+2, payload_offset) - s_tag, c_tag, dscp_ecn = struct.unpack_from('>HHB', meta.tdata, 16) + s_tag, c_tag = struct.unpack_from('>HH', meta.tdata, 16) tb.log.info("VLAN S-tag: 0x%04x", s_tag) tb.log.info("VLAN C-tag: 0x%04x", c_tag) - tb.log.info("DSCP/ECN: 0x%02x", dscp_ecn) eth_dst = meta.tdata[24:30] eth_src = meta.tdata[32:38] diff --git a/src/zircon/tb/zircon_ip_tx_deparse/test_zircon_ip_tx_deparse.py b/src/zircon/tb/zircon_ip_tx_deparse/test_zircon_ip_tx_deparse.py index 133ba31..c64d717 100644 --- a/src/zircon/tb/zircon_ip_tx_deparse/test_zircon_ip_tx_deparse.py +++ b/src/zircon/tb/zircon_ip_tx_deparse/test_zircon_ip_tx_deparse.py @@ -264,8 +264,8 @@ async def run_test(dut): meta[64:68] = scapy.utils.inet_aton(pkt[IP].dst) meta[80:84] = scapy.utils.inet_aton(pkt[IP].src) - struct.pack_into('