diff --git a/hw/super6502_fpga/src/sub/network_processor/sim/cocotb/tests/tcp_test.py b/hw/super6502_fpga/src/sub/network_processor/sim/cocotb/tests/tcp_test.py index a56e3bb..c48c9be 100644 --- a/hw/super6502_fpga/src/sub/network_processor/sim/cocotb/tests/tcp_test.py +++ b/hw/super6502_fpga/src/sub/network_processor/sim/cocotb/tests/tcp_test.py @@ -138,4 +138,22 @@ async def test_simple(dut): await tb.mii_phy.rx.send(GmiiFrame.from_payload(tcp_synack)) - await Timer(Decimal(CLK_PERIOD_NS * 800), units='ns') \ No newline at end of file + resp = await tb.mii_phy.tx.recv() # type: GmiiFrame + packet = Ether(resp.get_payload()) + tb.log.info(f"Packet Type: {packet.type:x}") + + + ip_packet = packet.payload + assert isinstance(ip_packet, IP) + + tcp_packet = ip_packet.payload + assert isinstance(tcp_packet, TCP) + + tb.log.info(f"Source Port: {tcp_packet.sport}") + tb.log.info(f"Dest Port: {tcp_packet.dport}") + tb.log.info(f"Seq: {tcp_packet.seq}") + tb.log.info(f"Ack: {tcp_packet.ack}") + tb.log.info(f"Data Offs: {tcp_packet.dataofs}") + tb.log.info(f"flags: {tcp_packet.flags}") + tb.log.info(f"window: {tcp_packet.window}") + tb.log.info(f"Checksum: {tcp_packet.chksum}") \ No newline at end of file diff --git a/hw/super6502_fpga/src/sub/network_processor/sources.list b/hw/super6502_fpga/src/sub/network_processor/sources.list index 85b8566..26e756d 100644 --- a/hw/super6502_fpga/src/sub/network_processor/sources.list +++ b/hw/super6502_fpga/src/sub/network_processor/sources.list @@ -9,6 +9,7 @@ src/regs/ntw_top_regfile.sv src/network_processor.sv src/tcp_pkg.sv src/tcp_tx_ctrl.sv +src/tcp_rx_ctrl.sv src/tcp_packet_generator.sv src/tcp_state_manager.sv src/tcp_stream.sv 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 78345d3..38bf067 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 @@ -37,11 +37,15 @@ end always_comb begin m_ip.ip_hdr_valid = '0; + m_ip.ip_payload_axis_tvalid = '0; + m_ip.ip_payload_axis_tlast = '0; o_packet_done = '0; case (state) IDLE: begin + counter_next = '0; + if (i_hdr_valid) begin m_ip.ip_hdr_valid = '1; m_ip.ip_dscp = '0; diff --git a/hw/super6502_fpga/src/sub/network_processor/src/tcp_parser.sv b/hw/super6502_fpga/src/sub/network_processor/src/tcp_parser.sv index 5e63944..feb98b2 100644 --- a/hw/super6502_fpga/src/sub/network_processor/src/tcp_parser.sv +++ b/hw/super6502_fpga/src/sub/network_processor/src/tcp_parser.sv @@ -2,10 +2,114 @@ module tcp_parser( input wire i_clk, input wire i_rst, - ip_intf.SLAVE s_ip + ip_intf.SLAVE s_ip, + + axis_intf.MASTER m_axis, + + output wire [31:0] o_seq_number, + output wire [31:0] o_ack_number, + output wire [7:0] o_flags, + output wire [15:0] o_window_size, + output wire o_hdr_valid ); -assign s_ip.ip_hdr_ready = '1; -assign s_ip.ip_payload_axis_tready = '1; +enum logic {HEADER, PAYLOAD} state, state_next; + +logic [4:0] counter, counter_next; + +logic hdr_valid; + +logic [31:0] sequence_num, sequence_num_next; +logic [31:0] ack_num, ack_num_next; +logic [3:0] data_offs, data_offs_next; +logic [7:0] flags, flags_next; +logic [15:0] window_size, window_size_next; +logic [15:0] checksum, checksum_next; + + +assign o_seq_number = sequence_num; +assign o_ack_number = ack_num; +assign o_flags = flags; +assign o_window_size = window_size; +assign o_hdr_valid = hdr_valid; + +always_ff @(posedge i_clk) begin + if (i_rst) begin + state <= HEADER; + counter <= '0; + + sequence_num <= '0; + ack_num <= '0; + data_offs <= '0; + flags <= '0; + window_size <= '0; + checksum <= '0; + end else begin + state <= state_next; + counter <= counter_next; + + sequence_num <= sequence_num_next; + ack_num <= ack_num_next; + data_offs <= data_offs_next; + flags <= flags_next; + window_size <= window_size_next; + checksum <= checksum_next; + end +end + +always_comb begin + sequence_num_next = sequence_num; + ack_num_next = ack_num; + data_offs_next = data_offs; + flags_next = flags; + window_size_next = window_size; + checksum_next = checksum; + hdr_valid = '0; + + case (state) + HEADER: begin + s_ip.ip_hdr_ready = '1; + s_ip.ip_payload_axis_tready = '1; + + if (s_ip.ip_payload_axis_tvalid) begin + counter_next = counter + 1; + + case (counter) + 4: sequence_num_next = {s_ip.ip_payload_axis_tdata, sequence_num[23:0]}; + 5: sequence_num_next = {sequence_num[31:24], s_ip.ip_payload_axis_tdata, sequence_num[15:0]}; + 6: sequence_num_next = {sequence_num[31:16], s_ip.ip_payload_axis_tdata, sequence_num[7:0]}; + 7: sequence_num_next = {sequence_num[31:8], s_ip.ip_payload_axis_tdata}; + 4: ack_num_next = {s_ip.ip_payload_axis_tdata, ack_num[23:0]}; + 5: ack_num_next = {ack_num[31:24], s_ip.ip_payload_axis_tdata, ack_num[15:0]}; + 6: ack_num_next = {ack_num[31:16], s_ip.ip_payload_axis_tdata, ack_num[8:0]}; + 7: ack_num_next = {ack_num[31:8], s_ip.ip_payload_axis_tdata}; + 12: data_offs_next = s_ip.ip_payload_axis_tdata[7:4]; + 13: flags_next = s_ip.ip_payload_axis_tdata; + 14: window_size_next = {s_ip.ip_payload_axis_tdata, window_size[7:0]}; + 15: window_size_next = {window_size[15:8], s_ip.ip_payload_axis_tdata}; + 16: checksum_next = {s_ip.ip_payload_axis_tdata, checksum[7:0]}; + 17: checksum_next = {checksum[15:8], s_ip.ip_payload_axis_tdata}; + 19: begin + state_next = PAYLOAD; + hdr_valid = '1; + end + endcase + + if (s_ip.ip_payload_axis_tlast) begin + counter_next = '0; + state_next = HEADER; // if we see last then we are done, its possible to have no data + end + end + end + + PAYLOAD: begin + if (s_ip.ip_payload_axis_tlast) begin + counter_next = '0; + state_next = HEADER; + end + end + endcase +end + endmodule \ No newline at end of file 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 new file mode 100644 index 0000000..c1c642e --- /dev/null +++ b/hw/super6502_fpga/src/sub/network_processor/src/tcp_rx_ctrl.sv @@ -0,0 +1,27 @@ +module tcp_rx_ctrl ( + input wire i_clk, + input wire i_rst, + + output tcp_pkg::rx_msg_t o_rx_msg, + output logic o_rx_msg_valid, + input logic i_rx_msg_ack, + + input wire [31:0] i_seq_number, + input wire [31:0] i_ack_number, + input wire [15:0] i_source_port, + input wire [15:0] i_dest_port, + input wire [7:0] i_flags, + input wire [15:0] i_window_size, + input wire i_hdr_valid +); + +always_ff @(posedge i_clk) begin + if (i_hdr_valid) begin + if (i_flags & 8'h12) begin + o_rx_msg = RX_MSG_RECV_SYNACK; + o_rx_msg_valid = '1; + end + end +end + +endmodule \ No newline at end of file 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 789cfd7..3851802 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 @@ -23,7 +23,8 @@ module tcp_state_manager( enum logic [3:0] { IDLE, SYN_RCVD, // In this design, this state should not be reached! - SYN_SENT, + SYN_SENT_1, + SYN_SENT_2, ESTABLISHED, WAIT_CLOSE, LAST_ACK, @@ -62,13 +63,28 @@ always_comb begin o_tx_ctrl_valid = '1; if (i_tx_ctrl_ack) begin - tcp_state_next = SYN_SENT; + tcp_state_next = SYN_SENT_1; end end end - SYN_SENT: begin - // $display("SYN_SENT not implemented"); + SYN_SENT_1: begin + if (i_rx_msg_valid && i_rx_msg== RX_MSG_RECV_SYNACK) begin + tcp_state_next = SYN_SENT_2; + end + end + + SYN_SENT_2: begin + o_tx_ctrl = TX_CTRL_SEND_ACK; + o_tx_ctrl_valid = '1; + + if (i_tx_ctrl_ack) begin + tcp_state_next = ESTABLISHED; + end + end + + ESTABLISHED: begin + end endcase end 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 69d8d1a..e5aaec8 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 @@ -33,6 +33,7 @@ axis_intf m2s_axis(); axis_intf s2m_axis(); axis_intf m2s_post_saf_axis(); +axis_intf s2m_pre_saf_axis(); // regs tcp_stream_regs_pkg::tcp_stream_regs__in_t hwif_in; @@ -42,6 +43,10 @@ tcp_pkg::tx_ctrl_t tx_ctrl; logic tx_ctrl_valid; logic tx_ctrl_ack; +tcp_pkg::rx_msg_t rx_msg; +logic rx_msg_valid; +logic rx_msg_ack; + logic [31:0] w_tx_seq_number; logic [31:0] w_tx_ack_number; logic [7:0] w_tx_flags; @@ -49,7 +54,12 @@ logic [15:0] w_tx_window_size; logic w_tx_hdr_valid; logic w_tx_packet_done; -tcp_pkg::rx_msg_t rx_msg; +logic [31:0] w_rx_seq_number; +logic [31:0] w_rx_ack_number; +logic [7:0] w_rx_flags; +logic [15:0] w_rx_window_size; +logic w_rx_hdr_valid; + assign o_tcp_port = hwif_out.source_port.d.value; @@ -113,7 +123,11 @@ tcp_state_manager u_tcp_state_manager ( .o_tx_ctrl (tx_ctrl), .o_tx_ctrl_valid (tx_ctrl_valid), - .i_tx_ctrl_ack (tx_ctrl_ack) + .i_tx_ctrl_ack (tx_ctrl_ack), + + .i_rx_msg (rx_msg), + .i_rx_msg_valid (rx_msg_valid), + .o_rx_msg_ack (rx_msg_ack) ); @@ -199,10 +213,31 @@ tcp_parser u_tcp_parser ( .i_clk (clk), .i_rst (rst), - .s_ip (s_ip_rx) + .s_ip (s_ip_rx), + .m_axis (s2m_pre_saf_axis), + + .o_seq_number (w_rx_seq_number), + .o_ack_number (w_rx_ack_number), + .o_flags (w_rx_flags), + .o_window_size (w_rx_window_size), + .o_hdr_valid (w_rx_hdr_valid) ); // rx control +tcp_rx_ctrl u_tcp_rx_ctrl ( + .i_clk (clk), + .i_rst (rst), + + .o_rx_msg (rx_msg), + .o_rx_msg_valid (rx_msg_valid), + .i_rx_msg_ack (rx_msg_ack), + + .i_seq_number (w_rx_seq_number), + .i_ack_number (w_rx_ack_number), + .i_flags (w_rx_flags), + .i_window_size (w_rx_window_size), + .i_hdr_valid (w_rx_hdr_valid) +); // rx buffer 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 d20bbfe..96df70f 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 @@ -26,7 +26,7 @@ localparam FLAG_URG = (1 << 5); localparam FLAG_ECE = (1 << 6); localparam FLAG_CWR = (1 << 7); -enum logic [2:0] {IDLE, SEND_SYN} state, state_next; +enum logic [2:0] {IDLE, SEND_SYN, SEND_ACK} state, state_next; always_ff @(posedge i_clk) begin if (i_rst) begin @@ -50,6 +50,7 @@ always_comb begin case (i_tx_ctrl) TX_CTRL_SEND_SYN: state_next = SEND_SYN; + TX_CTRL_SEND_ACK: state_next = SEND_ACK; endcase end end @@ -62,6 +63,15 @@ always_comb begin state_next = IDLE; end end + + SEND_ACK: begin + o_flags = FLAG_ACK; + o_hdr_valid = '1; + + if (i_packet_done) begin + state_next = IDLE; + end + end endcase end diff --git a/hw/super6502_fpga/src/sub/network_processor/src/tx_control.sv b/hw/super6502_fpga/src/sub/network_processor/src/tx_control.sv deleted file mode 100644 index e69de29..0000000