diff --git a/hw/super6502_fpga/src/sub/network_processor/sim/cocotb/tests/scapy_irl_test.py b/hw/super6502_fpga/src/sub/network_processor/sim/cocotb/tests/scapy_irl_test.py index 6024c2b..c50aac7 100644 --- a/hw/super6502_fpga/src/sub/network_processor/sim/cocotb/tests/scapy_irl_test.py +++ b/hw/super6502_fpga/src/sub/network_processor/sim/cocotb/tests/scapy_irl_test.py @@ -1,4 +1,5 @@ from http import server +from turtle import xcor from scapy.layers.inet import Ether, IP, TCP from scapy.layers.l2 import ARP from scapy.data import IP_PROTOS @@ -107,7 +108,7 @@ async def test_irl(dut): serversocket = socket.socket(socket.AF_INET, socket.SOCK_STREAM) serversocket.bind((tb_ip, 5678)) - serversocket.listen(5) + serversocket.listen(1) t = TunTapInterface('tun0') @@ -176,7 +177,10 @@ async def test_irl(dut): t.send(ip_packet) - pkt = t.recv() + while True: + pkt = t.recv() + if (pkt.proto == IP_PROTOS.tcp): + break print(pkt) tcp_synack = Ether(dst=dut_mac, src=tb_mac) / pkt @@ -206,6 +210,28 @@ async def test_irl(dut): con, addr = serversocket.accept() + # Construct a descriptor in memry + tb.axil_ram.write_dword(0x00000000, 0x00001000) + tb.axil_ram.write_dword(0x00000004, 64) + tb.axil_ram.write_dword(0x00000008, 0) + tb.axil_ram.write_dword(0x0000000c, 0) + + test_data = bytearray([x % 256 for x in range(256)]) + + tb.axil_ram.write(0x1000, test_data) + + await tb.axil_master.write_dword(0x22c, 0) + await tb.axil_master.write_dword(0x220, 0x00000000) + await tb.axil_master.write_dword(0x224, 0x00000000) + + resp = await tb.mii_phy.tx.recv() # type: GmiiFrame + packet = Ether(resp.get_payload()) + + t.send(packet.payload) + + con.recv(64) + tb.log.info("Received 64 packets") + con.close() serversocket.close() @@ -215,6 +241,18 @@ async def test_irl(dut): break print(pkt) + tcp_ack = Ether(dst=dut_mac, src=tb_mac) / pkt + + await tb.mii_phy.rx.send(GmiiFrame.from_payload(tcp_ack.build())) + + tb.log.info("Expecting to send an F here") + + while True: + pkt = t.recv() + if (pkt.proto == IP_PROTOS.tcp): + break + print(pkt) + tcp_fin = Ether(dst=dut_mac, src=tb_mac) / pkt await tb.mii_phy.rx.send(GmiiFrame.from_payload(tcp_fin.build())) @@ -240,31 +278,16 @@ async def test_irl(dut): t.send(ip_packet) - return + tb.log.info("Expecting to send last ACK here") + while True: + pkt = t.recv() + if (pkt.proto == IP_PROTOS.tcp): + break + print(pkt) + tcp_fin = Ether(dst=dut_mac, src=tb_mac) / pkt - # Construct a descriptor in memry - tb.axil_ram.write_dword(0x00000000, 0x00001000) - tb.axil_ram.write_dword(0x00000004, 64) - tb.axil_ram.write_dword(0x00000008, 0) - tb.axil_ram.write_dword(0x0000000c, 0) + await tb.mii_phy.rx.send(GmiiFrame.from_payload(tcp_fin.build())) - test_data = bytearray([x % 256 for x in range(256)]) - - tb.axil_ram.write(0x1000, test_data) - - - - await tb.axil_master.write_dword(0x22c, 0) - await tb.axil_master.write_dword(0x220, 0x00000000) - await tb.axil_master.write_dword(0x224, 0x00000000) - - resp = await tb.mii_phy.tx.recv() # type: GmiiFrame - packet = Ether(resp.get_payload()) - - t.send(packet.payload) - - # con.recv(64) - - serversocket.close() + await Timer(Decimal(CLK_PERIOD_NS * 1000), units='ns') diff --git a/hw/super6502_fpga/src/sub/network_processor/src/tcp_packet_generator.sv b/hw/super6502_fpga/src/sub/network_processor/src/tcp_packet_generator.sv index 034b2f5..d0df87c 100644 --- a/hw/super6502_fpga/src/sub/network_processor/src/tcp_packet_generator.sv +++ b/hw/super6502_fpga/src/sub/network_processor/src/tcp_packet_generator.sv @@ -4,6 +4,8 @@ module tcp_packet_generator ( axis_intf.SLAVE s_axis_data, + input wire i_no_data, + input wire [15:0] i_ip_len, input wire [31:0] i_seq_number, input wire [31:0] i_ack_number, @@ -21,8 +23,33 @@ module tcp_packet_generator ( ip_intf.MASTER m_ip ); +axis_intf #(.DATA_WIDTH(8)) pre_checksum_data(); +axis_intf #(.DATA_WIDTH(8)) post_checksum_data(); + +logic saf_ready; + +assign pre_checksum_data.tdata = s_axis_data.tdata; +assign pre_checksum_data.tkeep = s_axis_data.tkeep; +assign pre_checksum_data.tvalid = s_axis_data.tvalid & saf_ready; +assign s_axis_data.tready = pre_checksum_data.tready & saf_ready; +assign pre_checksum_data.tlast = s_axis_data.tlast; +assign pre_checksum_data.tuser = s_axis_data.tuser; + +axis_saf_fifo #( + .DATA_DEPTH_L2(11), + .CTRL_DEPTH_L2(1) +) u_checksum_fifo ( + .sclk(i_clk), + .srst(i_rst), + .s_axis(pre_checksum_data), + + .mclk(i_clk), + .mrst(i_rst), + .m_axis(post_checksum_data) +); + logic [31:0] counter, counter_next; -enum logic [1:0] {IDLE, HEADER, DATA} state, state_next; +enum logic [1:0] {IDLE, DATA_CHECKSUM, HEADER, DATA} state, state_next; logic [31:0] checksum_counter, checksum_counter_next; @@ -34,7 +61,13 @@ logic checksum_clear; logic [31:0] checksum_data; logic [15:0] checksum_final; -checksum_calc u_checksum_calc( +logic [31:0] data_expand, data_expand_next; +logic data_checksum_enable; +logic data_checksum_clear; +logic [31:0] data_checksum_data; +logic [15:0] data_checksum_final; + +checksum_calc u_header_checksum_calc( .i_rst (i_rst), .i_clk (i_clk), .i_clear (checksum_clear), @@ -49,10 +82,12 @@ always_ff @(posedge i_clk) begin counter <= '0; checksum_counter <= '0; state <= IDLE; + data_expand <= '0; end else begin counter <= counter_next; checksum_counter <= checksum_counter_next; state <= state_next; + data_expand <= data_expand_next; end end @@ -64,6 +99,10 @@ always_comb begin checksum_clear = '0; checksum_enable = '0; + saf_ready = '0; + + data_expand_next = data_expand; + case (state) IDLE: begin @@ -82,7 +121,32 @@ always_comb begin m_ip.ip_dest_ip = i_dst_ip; if (m_ip.ip_hdr_ready) begin + if (i_no_data) begin + state_next = HEADER; + end else begin + state_next = DATA_CHECKSUM; + end + end + end + end + + DATA_CHECKSUM: begin + saf_ready = '1; + + data_expand_next = {data_expand[23:0], pre_checksum_data.tdata}; + // data_expand_next = {pre_checksum_data.tdata, data_expand[31:8]}; + + if (checksum_counter[1:0] == '1) begin + checksum_enable = '1; + checksum_data = data_expand_next; + end + + + if (s_axis_data.tready & s_axis_data.tvalid) begin + checksum_counter_next = checksum_counter + 1; + if (s_axis_data.tlast) begin state_next = HEADER; + checksum_counter_next = '0; end end end @@ -97,7 +161,7 @@ always_comb begin case (checksum_counter) 0: checksum_data = m_ip.ip_source_ip; 1: checksum_data = m_ip.ip_dest_ip; - 2: checksum_data = {8'b0, m_ip.ip_protocol, 16'd20}; // tcp length, not IP length + 2: checksum_data = {8'b0, m_ip.ip_protocol, (i_ip_len - 16'd20)}; // tcp length, not IP length 3: checksum_data = {i_source_port, i_dest_port}; 4: checksum_data = i_seq_number; 5: checksum_data = i_ack_number; @@ -127,7 +191,7 @@ always_comb begin 18: m_ip.ip_payload_axis_tdata = '0; 19: begin m_ip.ip_payload_axis_tdata = '0; - m_ip.ip_payload_axis_tlast = ~s_axis_data.tvalid; // kinda hacky + m_ip.ip_payload_axis_tlast = i_no_data; // kinda hacky end endcase @@ -147,12 +211,12 @@ always_comb begin DATA: begin state_next = DATA; - s_axis_data.tready = m_ip.ip_payload_axis_tready; - m_ip.ip_payload_axis_tvalid = s_axis_data.tvalid; - m_ip.ip_payload_axis_tdata = s_axis_data.tdata; - m_ip.ip_payload_axis_tlast = s_axis_data.tlast; + post_checksum_data.tready = m_ip.ip_payload_axis_tready; + m_ip.ip_payload_axis_tvalid = post_checksum_data.tvalid; + m_ip.ip_payload_axis_tdata = post_checksum_data.tdata; + m_ip.ip_payload_axis_tlast = post_checksum_data.tlast; - if (s_axis_data.tlast && s_axis_data.tvalid && s_axis_data.tready) begin + if (post_checksum_data.tlast && post_checksum_data.tvalid && post_checksum_data.tready) begin state_next = IDLE; o_packet_done = '1; end diff --git a/hw/super6502_fpga/src/sub/network_processor/src/tcp_rx_ctrl.sv b/hw/super6502_fpga/src/sub/network_processor/src/tcp_rx_ctrl.sv index 8a46e02..189ead3 100644 --- a/hw/super6502_fpga/src/sub/network_processor/src/tcp_rx_ctrl.sv +++ b/hw/super6502_fpga/src/sub/network_processor/src/tcp_rx_ctrl.sv @@ -43,7 +43,13 @@ always_comb begin o_rx_msg = RX_MSG_RECV_FIN; o_rx_msg_valid = '1; end + + if (i_flags == 8'h10) begin + o_rx_msg = RX_MSG_RECV_ACK; + o_rx_msg_valid = '1; + end + end end -endmodule \ No newline at end of file +endmodule diff --git a/hw/super6502_fpga/src/sub/network_processor/src/tcp_state_manager.sv b/hw/super6502_fpga/src/sub/network_processor/src/tcp_state_manager.sv index 3a07f6f..9240bd1 100644 --- a/hw/super6502_fpga/src/sub/network_processor/src/tcp_state_manager.sv +++ b/hw/super6502_fpga/src/sub/network_processor/src/tcp_state_manager.sv @@ -50,6 +50,7 @@ always_comb begin tcp_state_next = tcp_state; o_tx_ctrl_valid = '0; + o_open_clr = '0; o_tx_ctrl = TX_CTRL_NOP; o_tx_ctrl_valid = '0; @@ -80,6 +81,7 @@ always_comb begin if (i_tx_ctrl_ack) begin tcp_state_next = ESTABLISHED; + o_open_clr = '1; end end @@ -92,9 +94,11 @@ always_comb begin end LAST_ACK: begin - + if (i_rx_msg_valid && i_rx_msg == RX_MSG_RECV_ACK) begin + tcp_state_next = IDLE; + end end endcase end -endmodule \ No newline at end of file +endmodule diff --git a/hw/super6502_fpga/src/sub/network_processor/src/tcp_stream.sv b/hw/super6502_fpga/src/sub/network_processor/src/tcp_stream.sv index 285a0e5..d2962fe 100644 --- a/hw/super6502_fpga/src/sub/network_processor/src/tcp_stream.sv +++ b/hw/super6502_fpga/src/sub/network_processor/src/tcp_stream.sv @@ -49,6 +49,8 @@ tcp_pkg::rx_msg_t rx_msg; logic rx_msg_valid; logic rx_msg_ack; +logic w_no_data; + logic [15:0] w_saf_pkt_len; logic [15:0] w_tx_ip_len; logic [31:0] w_tx_seq_number; @@ -166,6 +168,7 @@ tcp_tx_ctrl u_tcp_tx_ctrl ( .i_tx_ctrl_valid (tx_ctrl_valid), .o_tx_ctrl_ack (tx_ctrl_ack), + .o_no_data (w_no_data), .o_ip_len (w_tx_ip_len), .o_seq_number (w_tx_seq_number), // .o_ack_number (w_tx_ack_number), @@ -187,6 +190,7 @@ tcp_packet_generator u_tcp_packet_generator ( .s_axis_data (m_tx_ctrl_axis_data), + .i_no_data (w_no_data), .i_ip_len (w_tx_ip_len), .i_seq_number (w_tx_seq_number), .i_ack_number (w_tx_ack_number), @@ -238,4 +242,4 @@ tcp_rx_ctrl u_tcp_rx_ctrl ( // rx buffer -endmodule \ No newline at end of file +endmodule diff --git a/hw/super6502_fpga/src/sub/network_processor/src/tcp_tx_ctrl.sv b/hw/super6502_fpga/src/sub/network_processor/src/tcp_tx_ctrl.sv index 58f6abe..e35cabd 100644 --- a/hw/super6502_fpga/src/sub/network_processor/src/tcp_tx_ctrl.sv +++ b/hw/super6502_fpga/src/sub/network_processor/src/tcp_tx_ctrl.sv @@ -8,6 +8,8 @@ module tcp_tx_ctrl( input logic i_tx_ctrl_valid, output logic o_tx_ctrl_ack, + output logic o_no_data, + output logic [15:0] o_ip_len, output logic [31:0] o_seq_number, output logic [31:0] o_ack_number, @@ -57,10 +59,11 @@ end always_comb begin state_next = state; + o_no_data = '0; o_ack_number = '0; o_flags = '0; - o_window_size = 16'b1; + o_window_size = 16'h100; o_hdr_valid = '0; seq_num_next = seq_num; @@ -86,6 +89,7 @@ always_comb begin SEND_SYN: begin o_flags = FLAG_SYN; + o_no_data = '1; o_hdr_valid = '1; if (i_packet_done) begin @@ -96,6 +100,7 @@ always_comb begin SEND_ACK: begin o_flags = FLAG_ACK; + o_no_data = '1; o_hdr_valid = '1; if (i_packet_done) begin @@ -106,6 +111,7 @@ always_comb begin SEND_DATA: begin o_flags = FLAG_ACK | FLAG_PSH; + o_no_data = '0; o_ip_len = 16'd40 + s_axis_len; // default length of IP packet o_hdr_valid = '1; @@ -117,7 +123,8 @@ always_comb begin SEND_FIN: begin o_flags = FLAG_ACK | FLAG_FIN; - o_ip_len = 16'd40 + s_axis_len; // default length of IP packet + o_no_data = '1; + o_ip_len = 16'd40; // default length of IP packet o_hdr_valid = '1; if (i_packet_done) begin