From 798fb6f20f9b1d58e84e847c59572a7f9d507081 Mon Sep 17 00:00:00 2001 From: Byron Lathi Date: Sun, 13 Oct 2024 18:41:32 -0700 Subject: [PATCH 1/8] Get some fin support --- .../sim/cocotb/tests/scapy_irl_test.py | 287 ++++++++++++++---- .../src/tcp_state_manager.sv | 30 ++ 2 files changed, 255 insertions(+), 62 deletions(-) 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 c50aac7..c291779 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,7 +1,3 @@ -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 from scapy import sendrecv @@ -18,8 +14,9 @@ from cocotbext.axi import AxiLiteBus, AxiLiteMaster, AxiLiteRam from cocotbext.eth import MiiPhy, GmiiFrame import struct -from scapy.layers.inet import Ether, IP, TCP -from scapy.layers.l2 import ARP +from scapy.layers.inet import IP, TCP +from scapy.layers.l2 import ARP, Ether +from scapy.packet import Packet from scapy.utils import PcapWriter from scapy.layers.tuntap import TunTapInterface @@ -27,6 +24,8 @@ import logging from decimal import Decimal +import random + CLK_PERIOD_NS = 10 MII_CLK_PERIOD_NS = 40 @@ -95,10 +94,37 @@ def ip_to_hex(ip: str) -> int: return result -@cocotb.test() +# @cocotb.test() async def test_irl(dut): tb = TB(dut) + async def read_tcp_from_dut(): + 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}") + + return ip_packet + + ############################# + # Reset DUT # + ############################# + + await tb.cycle_reset() dut_ip = "172.0.0.2" @@ -106,14 +132,18 @@ async def test_irl(dut): tb_mac = "02:00:00:11:22:33" + dut_port = random.randint(1024, 65535) + tb_port = random.randint(1024, 65535) + serversocket = socket.socket(socket.AF_INET, socket.SOCK_STREAM) - serversocket.bind((tb_ip, 5678)) + serversocket.bind((tb_ip, tb_port)) serversocket.listen(1) t = TunTapInterface('tun0') - dut_port = 1234 - tb_port = 5678 + ############################### + # Configure DUT Network block # + ############################### await tb.axil_master.write_dword(0x0, 0x1807) @@ -150,35 +180,25 @@ async def test_irl(dut): assert arp_request.psrc == dut_ip, "ARP psrc does not match expected" assert arp_request.pdst == tb_ip, "ARP pdst does not match expected" + # hardcode the ARP response for now arp_response = Ether(dst=dut_mac, src=tb_mac) arp_response /= ARP(op="is-at", hwsrc=tb_mac, hwdst=dut_mac, psrc=tb_ip, pdst=dut_ip) arp_response = arp_response.build() await tb.mii_phy.rx.send(GmiiFrame.from_payload(arp_response)) - 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) + ############################### + # Start TCP handshake # + ############################### - 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}") + ip_packet = await read_tcp_from_dut() t.send(ip_packet) while True: pkt = t.recv() + assert isinstance(pkt, Packet) if (pkt.proto == IP_PROTOS.tcp): break print(pkt) @@ -187,29 +207,16 @@ async def test_irl(dut): await tb.mii_phy.rx.send(GmiiFrame.from_payload(tcp_synack.build())) - 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}") + ip_packet = await read_tcp_from_dut() t.send(ip_packet) con, addr = serversocket.accept() + ############################### + # Send data from DUT to host # + ############################### + # Construct a descriptor in memry tb.axil_ram.write_dword(0x00000000, 0x00001000) tb.axil_ram.write_dword(0x00000004, 64) @@ -232,11 +239,16 @@ async def test_irl(dut): con.recv(64) tb.log.info("Received 64 packets") + ############################### + # Close connection from host # + ############################### + con.close() serversocket.close() while True: pkt = t.recv() + assert isinstance(pkt, Packet) if (pkt.proto == IP_PROTOS.tcp): break print(pkt) @@ -249,6 +261,7 @@ async def test_irl(dut): while True: pkt = t.recv() + assert isinstance(pkt, Packet) if (pkt.proto == IP_PROTOS.tcp): break print(pkt) @@ -257,24 +270,7 @@ async def test_irl(dut): await tb.mii_phy.rx.send(GmiiFrame.from_payload(tcp_fin.build())) - 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}") + ip_packet = await read_tcp_from_dut() t.send(ip_packet) @@ -282,6 +278,7 @@ async def test_irl(dut): while True: pkt = t.recv() + assert isinstance(pkt, Packet) if (pkt.proto == IP_PROTOS.tcp): break print(pkt) @@ -291,3 +288,169 @@ async def test_irl(dut): await tb.mii_phy.rx.send(GmiiFrame.from_payload(tcp_fin.build())) await Timer(Decimal(CLK_PERIOD_NS * 1000), units='ns') + + +@cocotb.test() +async def test_close(dut): + tb = TB(dut) + + async def read_tcp_from_dut(): + 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}") + + return ip_packet + + def get_pkt_from_host(): + while True: + pkt = t.recv() + assert isinstance(pkt, Packet) + if (pkt.proto == IP_PROTOS.tcp): + break + print(pkt) + return pkt + + ############################# + # Reset DUT # + ############################# + + + await tb.cycle_reset() + + dut_ip = "172.0.0.2" + tb_ip = "172.0.0.1" + + tb_mac = "02:00:00:11:22:33" + + dut_port = random.randint(1024, 65535) + tb_port = random.randint(1024, 65535) + + serversocket = socket.socket(socket.AF_INET, socket.SOCK_STREAM) + serversocket.bind((tb_ip, tb_port)) + serversocket.listen(1) + t = TunTapInterface('tun0') + + + ############################### + # Configure DUT Network block # + ############################### + + await tb.axil_master.write_dword(0x0, 0x1807) + + await tb.axil_master.write_dword(0x200, dut_port) + await tb.axil_master.write_dword(0x204, ip_to_hex(dut_ip)) + await tb.axil_master.write_dword(0x208, tb_port) + await tb.axil_master.write_dword(0x20c, ip_to_hex(tb_ip)) + await tb.axil_master.write_dword(0x210, 0x3) + + resp = await tb.mii_phy.tx.recv() # type: GmiiFrame + + packet = Ether(resp.get_payload()) + + tb.log.info(f"Packet Type: {packet.type:x}") + + assert packet.type == 0x806, "Packet type is not ARP!" + + + arp_request = packet.payload + assert isinstance(arp_request, ARP) + + tb.log.info(f"Arp OP: {arp_request.op}") + tb.log.info(f"Arp hwsrc: {arp_request.hwsrc}") + tb.log.info(f"Arp hwdst: {arp_request.hwdst}") + tb.log.info(f"Arp psrc: {arp_request.psrc}") + tb.log.info(f"Arp pdst: {arp_request.pdst}") + + dut_mac = arp_request.hwsrc + dut_ip = arp_request.psrc + + assert arp_request.op == 1, "ARP type is not request!" + assert arp_request.hwsrc == "02:00:00:aa:bb:cc", "ARP hwsrc does not match expected" + assert arp_request.hwdst == "00:00:00:00:00:00", "ARP hwdst does not match expected" + assert arp_request.psrc == dut_ip, "ARP psrc does not match expected" + assert arp_request.pdst == tb_ip, "ARP pdst does not match expected" + + # hardcode the ARP response for now + arp_response = Ether(dst=dut_mac, src=tb_mac) + arp_response /= ARP(op="is-at", hwsrc=tb_mac, hwdst=dut_mac, psrc=tb_ip, pdst=dut_ip) + arp_response = arp_response.build() + + await tb.mii_phy.rx.send(GmiiFrame.from_payload(arp_response)) + + + ############################### + # Start TCP handshake # + ############################### + + ip_packet = await read_tcp_from_dut() + + t.send(ip_packet) + + + pkt = get_pkt_from_host() + tcp_synack = Ether(dst=dut_mac, src=tb_mac) / pkt + + await tb.mii_phy.rx.send(GmiiFrame.from_payload(tcp_synack.build())) + + ip_packet = await read_tcp_from_dut() + + t.send(ip_packet) + + con, addr = serversocket.accept() + + tb.log.info(f"con_timeout: {con.timeout}") + + ############################### + # Close connection from DUT # + ############################### + + tb.log.info("Closing connection from the DUT side") + await tb.axil_master.write_dword(0x210, 5) + + ip_packet = await read_tcp_from_dut() + + tb.log.info("Sending packet to host") + t.send(ip_packet) + + pkt = get_pkt_from_host() + tcp_synack = Ether(dst=dut_mac, src=tb_mac) / pkt + + tb.log.info("Sending reply to DUT, this should be an ACK?") + await tb.mii_phy.rx.send(GmiiFrame.from_payload(tcp_synack.build())) + + tb.log.info(tcp_synack.flags) + + # Host will send an ack first, then a finack? + + tb.log.info("Closing server socket") + con.close() + serversocket.close() + + pkt = get_pkt_from_host() + tcp_synack = Ether(dst=dut_mac, src=tb_mac) / pkt + + tb.log.info("Sending packet to DUT, this should be a FINACK?") + await tb.mii_phy.rx.send(GmiiFrame.from_payload(tcp_synack.build())) + + pkt = get_pkt_from_host() + tcp_synack = Ether(dst=dut_mac, src=tb_mac) / pkt + + ip_packet = await read_tcp_from_dut() + + tb.log.info("Sending packet to host") + t.send(ip_packet) \ 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 9240bd1..af380db 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 @@ -91,6 +91,36 @@ always_comb begin o_tx_ctrl_valid = '1; tcp_state_next = LAST_ACK; end + + if (i_close) begin + o_tx_ctrl = TX_CTRL_SEND_FIN; + o_tx_ctrl_valid = '1; + tcp_state_next = FIN_WAIT_1; + end + end + + FIN_WAIT_1: begin + if (i_rx_msg_valid) begin + if (i_rx_msg == RX_MSG_RECV_ACK) begin + tcp_state_next = FIN_WAIT_2; + end else if (i_rx_msg == RX_MSG_RECV_FIN) begin + tcp_state_next = TIME_WAIT; + o_tx_ctrl_valid = '1; + o_tx_ctrl = TX_CTRL_SEND_ACK; + end + end + end + + FIN_WAIT_2: begin + if (i_rx_msg == RX_MSG_RECV_FIN) begin + tcp_state_next = TIME_WAIT; + o_tx_ctrl = TX_CTRL_SEND_ACK; + o_tx_ctrl_valid = '1; + end + end + + TIME_WAIT: begin + tcp_state_next = IDLE; end LAST_ACK: begin From 6265a8090c016a64990ba877959fba2269169d9a Mon Sep 17 00:00:00 2001 From: Byron Lathi Date: Sun, 13 Oct 2024 18:43:12 -0700 Subject: [PATCH 2/8] Big update to try and pass timing. reduces tcp streams to 1 --- hw/super6502_fpga/src/rtl/super_6502_fpga.sv | 35 +- hw/super6502_fpga/src/sub/interfaces | 2 +- .../sim/cocotb/tests/scapy_irl_test.py | 6 +- .../src/sub/network_processor/sources.list | 4 +- .../network_processor/src/axil_reg_slice.sv | 76 +++ .../network_processor/src/checksum_calc.sv | 9 +- .../src/ip_pipeline_register_wrapper.sv | 59 ++ .../src/network_processor.sv | 48 +- .../src/tcp_packet_generator.sv | 2 +- .../sub/network_processor/src/tcp_rx_ctrl.sv | 19 +- .../src/tcp_state_manager.sv | 10 +- .../sub/network_processor/src/tcp_stream.sv | 23 +- .../sub/network_processor/src/tcp_tx_ctrl.sv | 15 +- hw/super6502_fpga/src/sub/verilog-ethernet | 2 +- hw/super6502_fpga/super6502_fpga.xml | 541 +++++++++--------- 15 files changed, 533 insertions(+), 318 deletions(-) create mode 100644 hw/super6502_fpga/src/sub/network_processor/src/axil_reg_slice.sv create mode 100644 hw/super6502_fpga/src/sub/network_processor/src/ip_pipeline_register_wrapper.sv diff --git a/hw/super6502_fpga/src/rtl/super_6502_fpga.sv b/hw/super6502_fpga/src/rtl/super_6502_fpga.sv index f8dbc20..9220ebd 100644 --- a/hw/super6502_fpga/src/rtl/super_6502_fpga.sv +++ b/hw/super6502_fpga/src/rtl/super_6502_fpga.sv @@ -91,7 +91,9 @@ assign pre_resetn = button_resetn & vio0_resetn; assign sdram_ready = |w_sdr_state; -assign master_resetn = pre_resetn & sdram_ready; +always_ff @(posedge i_sysclk) begin + master_resetn <= pre_resetn & sdram_ready; +end assign o_sd_cs = '1; @@ -214,11 +216,14 @@ logic [1:0] sd_controller_dma_RRESP; axil_intf ntw_reg(); axil_intf ntw_dma(); +logic cpu_wrapper_reset; +always_ff @(posedge i_sysclk) cpu_wrapper_reset <= ~master_resetn; + cpu_wrapper u_cpu_wrapper_0( .i_clk_cpu (clk_cpu), .i_clk_100 (i_sysclk), - .i_rst (~master_resetn), + .i_rst (cpu_wrapper_reset), .o_cpu_rst (o_cpu0_reset), .o_cpu_rdy (o_cpu0_rdy), @@ -258,6 +263,8 @@ cpu_wrapper u_cpu_wrapper_0( .i_nmi('0) ); +logic crossbar_resetn; +always_ff @(posedge i_sysclk) crossbar_resetn <= master_resetn; axilxbar #( .NM(3), @@ -271,7 +278,7 @@ axilxbar #( }) ) u_crossbar ( .S_AXI_ACLK (i_sysclk), - .S_AXI_ARESETN (master_resetn), + .S_AXI_ARESETN (crossbar_resetn), .S_AXI_ARADDR ({cpu0_ARADDR, sd_controller_dma_ARADDR, ntw_dma.araddr }), .S_AXI_ARVALID ({cpu0_ARVALID, sd_controller_dma_ARVALID, ntw_dma.arvalid }), @@ -310,13 +317,16 @@ axilxbar #( ); +logic rom_reset; +always_ff @(posedge i_sysclk) rom_reset <= ~master_resetn; + axi4_lite_rom #( .ROM_SIZE(12), .BASE_ADDRESS(32'h0000f000), .ROM_INIT_FILE("init_hex.mem") ) u_rom ( .i_clk(i_sysclk), - .i_rst(~master_resetn), + .i_rst(rom_reset), .o_AWREADY(rom_awready), .o_WREADY(rom_wready), @@ -344,12 +354,15 @@ axi4_lite_rom #( .i_WSTRB(rom_wstrb) ); +logic ram_reset; +always_ff @(posedge i_sysclk) ram_reset <= ~master_resetn; + axi4_lite_ram #( .RAM_SIZE(9), .ZERO_INIT(1) ) u_ram( .i_clk(i_sysclk), - .i_rst(~master_resetn), + .i_rst(ram_reset), .o_AWREADY(ram_awready), .o_WREADY(ram_wready), @@ -452,12 +465,15 @@ sdram_controller u_sdram_controller( logic sd_irq; +logic sd_controller_wrapper_reset; +always_ff @(posedge i_sysclk) sd_controller_wrapper_reset <= ~master_resetn; + sd_controller_wrapper #( .NUMIO (1), // board as it stands is in 1 bit mode .BASE_ADDRESS (32'h0000E000) ) u_sdio_top ( .i_clk (i_sysclk), - .i_reset (~master_resetn), + .i_reset (sd_controller_wrapper_reset), .S_AXIL_AWVALID (sd_controller_ctrl_AWVALID), .S_AXIL_AWREADY (sd_controller_ctrl_AWREADY), @@ -506,11 +522,14 @@ sd_controller_wrapper #( .o_int (sd_irq) ); +logic network_processor_reset; +always_ff @(posedge i_sysclk) network_processor_reset <= ~master_resetn; + network_processor #( - .NUM_TCP(4) + .NUM_TCP(1) ) u_network_processor ( .i_clk (i_sysclk), - .i_rst (~master_resetn), + .i_rst (network_processor_reset), .s_reg_axil (ntw_reg), .m_dma_axil (ntw_dma), diff --git a/hw/super6502_fpga/src/sub/interfaces b/hw/super6502_fpga/src/sub/interfaces index 13c389d..e3c55d1 160000 --- a/hw/super6502_fpga/src/sub/interfaces +++ b/hw/super6502_fpga/src/sub/interfaces @@ -1 +1 @@ -Subproject commit 13c389dc18b37f613113d19c0724533de772c79f +Subproject commit e3c55d1bb224762384ca97ada087d3f606ac8990 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 c291779..b65bbba 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 @@ -34,7 +34,7 @@ MII_CLK_PERIOD_NS = 40 import socket # In order for this to work, you need to run these commands: -# sudo ip tuntap add name tun0 mode tun user $USER +# sudo ip tuntap add name tun0 mode tun group netdev # sudo ip a add 172.0.0.1 peer 172.0.0.2 dev tun0 # sudo ip link set tun0 up @@ -453,4 +453,6 @@ async def test_close(dut): ip_packet = await read_tcp_from_dut() tb.log.info("Sending packet to host") - t.send(ip_packet) \ No newline at end of file + t.send(ip_packet) + + await Timer(Decimal(CLK_PERIOD_NS * 10000), units='ns') \ 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 3f46ea0..d6286bd 100644 --- a/hw/super6502_fpga/src/sub/network_processor/sources.list +++ b/hw/super6502_fpga/src/sub/network_processor/sources.list @@ -19,4 +19,6 @@ src/ip_arb_mux_wrapper.sv src/ip_demux_wrapper.sv src/tcp_dest_decap.sv src/tcp_parser.sv -src/checksum_calc.sv \ No newline at end of file +src/checksum_calc.sv +src/ip_pipeline_register_wrapper.sv +src/axil_reg_slice.sv \ No newline at end of file diff --git a/hw/super6502_fpga/src/sub/network_processor/src/axil_reg_slice.sv b/hw/super6502_fpga/src/sub/network_processor/src/axil_reg_slice.sv new file mode 100644 index 0000000..6dec744 --- /dev/null +++ b/hw/super6502_fpga/src/sub/network_processor/src/axil_reg_slice.sv @@ -0,0 +1,76 @@ +module axil_reg_slice( + input clk, + input rst, + + axil_intf.SLAVE s_axil, + axil_intf.MASTER m_axil +); + +skidbuffer #( + .DW(s_axil.AXIL_ADDR_WIDTH) +) awskid( + .i_clk(clk), + .i_reset(rst), + + .i_valid(s_axil.awvalid), + .o_ready(s_axil.awready), + .i_data(s_axil.awaddr), + .o_valid(m_axil.awvalid), + .i_ready(m_axil.awready), + .o_data(m_axil.awaddr) +); + +skidbuffer #( + .DW(s_axil.AXIL_DATA_WIDTH + s_axil.AXIL_STRB_WIDTH) +) wskid( + .i_clk(clk), + .i_reset(rst), + + .i_valid(s_axil.wvalid), + .o_ready(s_axil.wready), + .i_data({s_axil.wdata, s_axil.wstrb}), + .o_valid(m_axil.wvalid), + .i_ready(m_axil.wready), + .o_data({m_axil.wdata, m_axil.wstrb}) +); + +skidbuffer #( + .DW(s_axil.AXIL_ADDR_WIDTH) +) arskid( + .i_clk(clk), + .i_reset(rst), + + .i_valid(s_axil.arvalid), + .o_ready(s_axil.arready), + .i_data(s_axil.araddr), + .o_valid(m_axil.arvalid), + .i_ready(m_axil.arready), + .o_data(m_axil.araddr) +); + +skidbuffer #( + .DW(s_axil.AXIL_DATA_WIDTH + 2) +) rskid( + .i_clk(clk), + .i_reset(rst), + + .i_valid(m_axil.rvalid), + .o_ready(m_axil.rready), + .i_data({m_axil.rdata, m_axil.rresp}), + .o_valid(s_axil.rvalid), + .i_ready(s_axil.rready), + .o_data({s_axil.rdata, s_axil.rresp}) +); +skidbuffer #(.DW(2)) bskid( + .i_clk(clk), + .i_reset(rst), + + .i_valid(m_axil.bvalid), + .o_ready(m_axil.bready), + .i_data(m_axil.bresp), + .o_valid(s_axil.bvalid), + .i_ready(s_axil.bready), + .o_data(s_axil.bresp) +); + +endmodule \ No newline at end of file diff --git a/hw/super6502_fpga/src/sub/network_processor/src/checksum_calc.sv b/hw/super6502_fpga/src/sub/network_processor/src/checksum_calc.sv index b6097c5..d8c752c 100644 --- a/hw/super6502_fpga/src/sub/network_processor/src/checksum_calc.sv +++ b/hw/super6502_fpga/src/sub/network_processor/src/checksum_calc.sv @@ -11,6 +11,8 @@ module checksum_calc ( ); logic [31:0] sum; +logic [31:0] pre_sum; +logic [31:0] sum_next; logic [15:0] sum_wrapped; assign sum_wrapped = sum[15:0] + sum [31:16]; @@ -21,9 +23,14 @@ always @(posedge i_clk) begin sum <= '0; end else begin if (i_enable) begin - sum <= sum + i_data[31:16] + i_data[15:0]; + sum <= sum_next; end end end +always_comb begin + pre_sum = i_data[31:16] + i_data[15:0]; + sum_next = sum + pre_sum; +end + endmodule \ No newline at end of file diff --git a/hw/super6502_fpga/src/sub/network_processor/src/ip_pipeline_register_wrapper.sv b/hw/super6502_fpga/src/sub/network_processor/src/ip_pipeline_register_wrapper.sv new file mode 100644 index 0000000..8349ea1 --- /dev/null +++ b/hw/super6502_fpga/src/sub/network_processor/src/ip_pipeline_register_wrapper.sv @@ -0,0 +1,59 @@ +module ip_pipeline_register_wrapper( + input logic clk, + input logic rst, + + ip_intf.SLAVE s_ip, + ip_intf.MASTER m_ip +); + +assign m_ip.ip_hdr_valid = s_ip.ip_hdr_valid; +assign s_ip.ip_hdr_ready = m_ip.ip_hdr_ready; +assign m_ip.eth_dest_mac = s_ip.eth_dest_mac; +assign m_ip.eth_src_mac = s_ip.eth_src_mac; +assign m_ip.eth_type = s_ip.eth_type; +assign m_ip.ip_version = s_ip.ip_version; +assign m_ip.ip_ihl = s_ip.ip_ihl; +assign m_ip.ip_dscp = s_ip.ip_dscp; +assign m_ip.ip_ecn = s_ip.ip_ecn; +assign m_ip.ip_length = s_ip.ip_length; +assign m_ip.ip_identification = s_ip.ip_identification; +assign m_ip.ip_flags = s_ip.ip_flags; +assign m_ip.ip_fragment_offset = s_ip.ip_fragment_offset; +assign m_ip.ip_ttl = s_ip.ip_ttl; +assign m_ip.ip_protocol = s_ip.ip_protocol; +assign m_ip.ip_header_checksum = s_ip.ip_header_checksum; +assign m_ip.ip_source_ip = s_ip.ip_source_ip; +assign m_ip.ip_dest_ip = s_ip.ip_dest_ip; + +axis_pipeline_register #( + .DATA_WIDTH(s_ip.DATA_WIDTH), + .KEEP_WIDTH(s_ip.KEEP_WIDTH), + .ID_ENABLE(1), + .ID_WIDTH(s_ip.ID_WIDTH), + .DEST_ENABLE(1), + .DEST_WIDTH(s_ip.DEST_WIDTH), + .USER_WIDTH(s_ip.USER_WIDTH) +) u_reg ( + .clk(clk), + .rst(rst), + + .s_axis_tdata (s_ip.ip_payload_axis_tdata), + .s_axis_tkeep (s_ip.ip_payload_axis_tkeep), + .s_axis_tvalid (s_ip.ip_payload_axis_tvalid), + .s_axis_tready (s_ip.ip_payload_axis_tready), + .s_axis_tlast (s_ip.ip_payload_axis_tlast), + .s_axis_tid (s_ip.ip_payload_axis_tid), + .s_axis_tdest (s_ip.ip_payload_axis_tdest), + .s_axis_tuser (s_ip.ip_payload_axis_tuser), + + .m_axis_tdata (m_ip.ip_payload_axis_tdata), + .m_axis_tkeep (m_ip.ip_payload_axis_tkeep), + .m_axis_tvalid (m_ip.ip_payload_axis_tvalid), + .m_axis_tready (m_ip.ip_payload_axis_tready), + .m_axis_tlast (m_ip.ip_payload_axis_tlast), + .m_axis_tid (m_ip.ip_payload_axis_tid), + .m_axis_tdest (m_ip.ip_payload_axis_tdest), + .m_axis_tuser (m_ip.ip_payload_axis_tuser) +); + +endmodule \ No newline at end of file diff --git a/hw/super6502_fpga/src/sub/network_processor/src/network_processor.sv b/hw/super6502_fpga/src/sub/network_processor/src/network_processor.sv index 2b61060..9f4867c 100644 --- a/hw/super6502_fpga/src/sub/network_processor/src/network_processor.sv +++ b/hw/super6502_fpga/src/sub/network_processor/src/network_processor.sv @@ -39,6 +39,8 @@ localparam MAC_DATA_WIDTH = 8; localparam AXIS_DATA_WIDTH = 8; localparam AXIS_KEEP_WIDTH = ((AXIS_DATA_WIDTH+7)/8); +axil_intf reg_axil_post_reg(); + axis_intf #(.DATA_WIDTH(MAC_DATA_WIDTH)) mac_tx_axis(); axis_intf #(.DATA_WIDTH(MAC_DATA_WIDTH)) mac_rx_axis(); @@ -54,29 +56,37 @@ ip_intf #(.DATA_WIDTH(MAC_DATA_WIDTH)) proto_tx_ip[3](); ntw_top_regfile_pkg::ntw_top_regfile__in_t hwif_in; ntw_top_regfile_pkg::ntw_top_regfile__out_t hwif_out; +axil_reg_slice u_reg_axil_reg_slice( + .clk(i_clk), + .rst(i_rst), + + .s_axil(s_reg_axil), + .m_axil(reg_axil_post_reg) +); + ntw_top_regfile u_ntw_top_regfile ( .clk (i_clk), .rst (i_rst), - .s_axil_awready (s_reg_axil.awready), - .s_axil_awvalid (s_reg_axil.awvalid), - .s_axil_awaddr (s_reg_axil.awaddr), - .s_axil_awprot (s_reg_axil.awprot), - .s_axil_wready (s_reg_axil.wready), - .s_axil_wvalid (s_reg_axil.wvalid), - .s_axil_wdata (s_reg_axil.wdata), - .s_axil_wstrb (s_reg_axil.wstrb), - .s_axil_bready (s_reg_axil.bready), - .s_axil_bvalid (s_reg_axil.bvalid), - .s_axil_bresp (s_reg_axil.bresp), - .s_axil_arready (s_reg_axil.arready), - .s_axil_arvalid (s_reg_axil.arvalid), - .s_axil_araddr (s_reg_axil.araddr), - .s_axil_arprot (s_reg_axil.arprot), - .s_axil_rready (s_reg_axil.rready), - .s_axil_rvalid (s_reg_axil.rvalid), - .s_axil_rdata (s_reg_axil.rdata), - .s_axil_rresp (s_reg_axil.rresp), + .s_axil_awready (reg_axil_post_reg.awready), + .s_axil_awvalid (reg_axil_post_reg.awvalid), + .s_axil_awaddr (reg_axil_post_reg.awaddr), + .s_axil_awprot (reg_axil_post_reg.awprot), + .s_axil_wready (reg_axil_post_reg.wready), + .s_axil_wvalid (reg_axil_post_reg.wvalid), + .s_axil_wdata (reg_axil_post_reg.wdata), + .s_axil_wstrb (reg_axil_post_reg.wstrb), + .s_axil_bready (reg_axil_post_reg.bready), + .s_axil_bvalid (reg_axil_post_reg.bvalid), + .s_axil_bresp (reg_axil_post_reg.bresp), + .s_axil_arready (reg_axil_post_reg.arready), + .s_axil_arvalid (reg_axil_post_reg.arvalid), + .s_axil_araddr (reg_axil_post_reg.araddr), + .s_axil_arprot (reg_axil_post_reg.arprot), + .s_axil_rready (reg_axil_post_reg.rready), + .s_axil_rvalid (reg_axil_post_reg.rvalid), + .s_axil_rdata (reg_axil_post_reg.rdata), + .s_axil_rresp (reg_axil_post_reg.rresp), .hwif_in (hwif_in), .hwif_out (hwif_out) 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 d0df87c..cd301ce 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,7 +37,7 @@ assign pre_checksum_data.tuser = s_axis_data.tuser; axis_saf_fifo #( .DATA_DEPTH_L2(11), - .CTRL_DEPTH_L2(1) + .CTRL_DEPTH_L2(2) ) u_checksum_fifo ( .sclk(i_clk), .srst(i_rst), 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 189ead3..8417779 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 @@ -19,34 +19,41 @@ module tcp_rx_ctrl ( output logic [31:0] o_ack_number ); +tcp_pkg::rx_msg_t rx_msg_next; +logic rx_msg_valid_next; + logic [31:0] ack_num, ack_num_next; assign o_ack_number = ack_num; always_ff @(posedge i_clk) begin if (i_rst) begin ack_num <= '0; + o_rx_msg <= RX_MSG_NOP; + o_rx_msg_valid <= '0; end else begin ack_num <= ack_num_next; + o_rx_msg <= rx_msg_next; + o_rx_msg_valid <= rx_msg_valid_next; end end always_comb begin if (i_hdr_valid) begin if (i_flags == 8'h12) begin - o_rx_msg = RX_MSG_RECV_SYNACK; - o_rx_msg_valid = '1; + rx_msg_next = RX_MSG_RECV_SYNACK; + rx_msg_valid_next = '1; ack_num_next = i_seq_number + 1; end if (i_flags == 8'h11) begin - o_rx_msg = RX_MSG_RECV_FIN; - o_rx_msg_valid = '1; + rx_msg_next = RX_MSG_RECV_FIN; + rx_msg_valid_next = '1; end if (i_flags == 8'h10) begin - o_rx_msg = RX_MSG_RECV_ACK; - o_rx_msg_valid = '1; + rx_msg_next = RX_MSG_RECV_ACK; + rx_msg_valid_next = '1; end end 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 af380db..c2f12c6 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 @@ -87,9 +87,9 @@ always_comb begin ESTABLISHED: begin if (i_rx_msg_valid && i_rx_msg == RX_MSG_RECV_FIN) begin - o_tx_ctrl = TX_CTRL_SEND_FIN; + o_tx_ctrl = TX_CTRL_SEND_ACK; o_tx_ctrl_valid = '1; - tcp_state_next = LAST_ACK; + tcp_state_next = WAIT_CLOSE; end if (i_close) begin @@ -123,6 +123,12 @@ always_comb begin tcp_state_next = IDLE; end + WAIT_CLOSE: begin + o_tx_ctrl = TX_CTRL_SEND_FIN; + o_tx_ctrl_valid = '1; + tcp_state_next = LAST_ACK; + end + LAST_ACK: begin if (i_rx_msg_valid && i_rx_msg == RX_MSG_RECV_ACK) begin tcp_state_next = IDLE; 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 d2962fe..f1da8e2 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 @@ -30,8 +30,11 @@ module tcp_stream #( ); axis_intf m2s_axis(); +axis_intf m2s_axis_pre_reg(); axis_intf s2m_axis(); +ip_intf m_ip_tx_pre_reg(); + axis_intf m2s_post_saf_axis(); axis_intf s2m_pre_saf_axis(); @@ -111,7 +114,15 @@ m2s_dma #( .s_cpuif_wr_err (), .m_axil (m_m2s_axil), - .m_axis (m2s_axis) + .m_axis (m2s_axis_pre_reg) +); + +axis_pipeline_register_wrapper u_m2s_reg ( + .clk(clk), + .rst(rst), + + .s_axis(m2s_axis_pre_reg), + .m_axis(m2s_axis) ); @@ -204,7 +215,15 @@ tcp_packet_generator u_tcp_packet_generator ( .o_packet_done (w_tx_packet_done), - .m_ip (m_ip_tx) + .m_ip (m_ip_tx_pre_reg) +); + +ip_pipeline_register_wrapper u_tx_ip_reg ( + .clk(clk), + .rst(rst), + + .s_ip(m_ip_tx_pre_reg), + .m_ip(m_ip_tx) ); // parser 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 e35cabd..b5e54c1 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 @@ -24,14 +24,13 @@ module tcp_tx_ctrl( input wire i_packet_done ); -assign m_axis.tdata = s_axis.tdata; -assign m_axis.tkeep = s_axis.tkeep; -assign m_axis.tvalid = s_axis.tvalid; -assign s_axis.tready = m_axis.tready; -assign m_axis.tlast = s_axis.tlast; -assign m_axis.tid = s_axis.tid; -assign m_axis.tdest = s_axis.tdest; -assign m_axis.tuser = s_axis.tuser; +axis_pipeline_register_wrapper u_m2s_reg ( + .clk(clk), + .rst(rst), + + .s_axis(s_axis), + .m_axis(m_axis) +); localparam FLAG_FIN = (1 << 0); localparam FLAG_SYN = (1 << 1); diff --git a/hw/super6502_fpga/src/sub/verilog-ethernet b/hw/super6502_fpga/src/sub/verilog-ethernet index 2542187..13f6d61 160000 --- a/hw/super6502_fpga/src/sub/verilog-ethernet +++ b/hw/super6502_fpga/src/sub/verilog-ethernet @@ -1 +1 @@ -Subproject commit 2542187ec93b7bf1c1dbdfc02981aad0eb01054a +Subproject commit 13f6d6137d7c29f0482d5a692c5dcbb48cbec46d diff --git a/hw/super6502_fpga/super6502_fpga.xml b/hw/super6502_fpga/super6502_fpga.xml index 25a33b8..f8437ea 100644 --- a/hw/super6502_fpga/super6502_fpga.xml +++ b/hw/super6502_fpga/super6502_fpga.xml @@ -1,289 +1,298 @@ - + + - - - + + + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - + + + + - - + + - - + + - + - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - - - - - - + + + + + + + + - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + - - - + + + - \ No newline at end of file + From 5e8d91be53fc3fd60a8cee21521e5e3f8a3c5a7a Mon Sep 17 00:00:00 2001 From: Byron Lathi Date: Sun, 13 Oct 2024 19:50:02 -0700 Subject: [PATCH 3/8] Remove inferred latches --- hw/super6502_fpga/src/sub/my-fifos | 2 +- .../src/sub/network_processor/src/tcp.sv | 2 ++ .../network_processor/src/tcp_dest_decap.sv | 9 +++++++ .../src/tcp_packet_generator.sv | 24 ++++++++++++++++++- .../sub/network_processor/src/tcp_parser.sv | 7 ++++++ .../sub/network_processor/src/tcp_rx_ctrl.sv | 5 ++++ .../sub/network_processor/src/tcp_tx_ctrl.sv | 6 +++-- hw/super6502_fpga/src/sub/stream_dmas | 2 +- hw/super6502_fpga/super6502_fpga.xml | 2 +- 9 files changed, 53 insertions(+), 6 deletions(-) diff --git a/hw/super6502_fpga/src/sub/my-fifos b/hw/super6502_fpga/src/sub/my-fifos index a19156c..8d960ab 160000 --- a/hw/super6502_fpga/src/sub/my-fifos +++ b/hw/super6502_fpga/src/sub/my-fifos @@ -1 +1 @@ -Subproject commit a19156c9cd559faa020ea7223a9995e68b41f8c2 +Subproject commit 8d960ab4bfa1a49a00594d7ee89c4d874ccd55cc diff --git a/hw/super6502_fpga/src/sub/network_processor/src/tcp.sv b/hw/super6502_fpga/src/sub/network_processor/src/tcp.sv index 6843df1..1745cb9 100644 --- a/hw/super6502_fpga/src/sub/network_processor/src/tcp.sv +++ b/hw/super6502_fpga/src/sub/network_processor/src/tcp.sv @@ -205,6 +205,8 @@ logic [$clog2(NUM_TCP)-1:0] tcp_demux_sel; logic [15:0] tcp_dests [NUM_TCP]; always_comb begin : TCP_DEST_SEL + tcp_demux_sel = '0; + for (int i = 0; i < NUM_TCP; i++) begin if (tcp_dest == tcp_dests[i]) begin tcp_demux_sel = i; diff --git a/hw/super6502_fpga/src/sub/network_processor/src/tcp_dest_decap.sv b/hw/super6502_fpga/src/sub/network_processor/src/tcp_dest_decap.sv index 0ec4796..d6f6147 100644 --- a/hw/super6502_fpga/src/sub/network_processor/src/tcp_dest_decap.sv +++ b/hw/super6502_fpga/src/sub/network_processor/src/tcp_dest_decap.sv @@ -100,6 +100,15 @@ always_comb begin s_ip.ip_payload_axis_tready = '0; + valid = '0; + + m_ip.ip_payload_axis_tdata = '0; + m_ip.ip_payload_axis_tvalid = '0; + m_ip.ip_payload_axis_tlast = '0; + m_ip.ip_payload_axis_tuser = '0; + m_ip.ip_payload_axis_tid = '0; + m_ip.ip_payload_axis_tdest = '0; + case (state) PORTS: begin s_ip.ip_payload_axis_tready = 1; 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 cd301ce..da36efe 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 @@ -92,9 +92,31 @@ always_ff @(posedge i_clk) begin end always_comb begin + state_next = state; + m_ip.ip_hdr_valid = '0; + m_ip.ip_dscp = '0; + m_ip.ip_ecn = '0; + m_ip.ip_length = '0; + m_ip.ip_ttl = '0; + m_ip.ip_protocol = '0; + m_ip.ip_source_ip = '0; + m_ip.ip_dest_ip = '0; + + m_ip.ip_payload_axis_tdata = '0; m_ip.ip_payload_axis_tvalid = '0; - m_ip.ip_payload_axis_tlast = '0; + m_ip.ip_payload_axis_tlast = '0; + m_ip.ip_payload_axis_tuser = '0; + m_ip.ip_payload_axis_tid = '0; + m_ip.ip_payload_axis_tdest = '0; + + post_checksum_data.tready = '0; + + checksum_counter_next = checksum_counter; + checksum_data = '0; + + counter_next = counter; + o_packet_done = '0; checksum_clear = '0; checksum_enable = '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 feb98b2..cd368da 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 @@ -66,6 +66,13 @@ always_comb begin checksum_next = checksum; hdr_valid = '0; + counter_next = counter; + + state_next = state; + + s_ip.ip_hdr_ready = '0; + s_ip.ip_payload_axis_tready = '0; + case (state) HEADER: begin s_ip.ip_hdr_ready = '1; 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 8417779..767acbb 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 @@ -38,6 +38,11 @@ always_ff @(posedge i_clk) begin end always_comb begin + rx_msg_next = RX_MSG_NOP; + rx_msg_valid_next = '0; + + ack_num_next = ack_num; + if (i_hdr_valid) begin if (i_flags == 8'h12) begin rx_msg_next = RX_MSG_RECV_SYNACK; 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 b5e54c1..752d3cb 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 @@ -25,8 +25,8 @@ module tcp_tx_ctrl( ); axis_pipeline_register_wrapper u_m2s_reg ( - .clk(clk), - .rst(rst), + .clk(i_clk), + .rst(i_rst), .s_axis(s_axis), .m_axis(m_axis) @@ -60,6 +60,8 @@ always_comb begin state_next = state; o_no_data = '0; + o_tx_ctrl_ack = '0; + o_ack_number = '0; o_flags = '0; o_window_size = 16'h100; diff --git a/hw/super6502_fpga/src/sub/stream_dmas b/hw/super6502_fpga/src/sub/stream_dmas index 92ef12a..cbd06e5 160000 --- a/hw/super6502_fpga/src/sub/stream_dmas +++ b/hw/super6502_fpga/src/sub/stream_dmas @@ -1 +1 @@ -Subproject commit 92ef12aed9a11bb4418fe20646eb819d4ce0aacf +Subproject commit cbd06e5af4f80b6dadf12395f521d83ca85b4aae diff --git a/hw/super6502_fpga/super6502_fpga.xml b/hw/super6502_fpga/super6502_fpga.xml index f8437ea..730db5d 100644 --- a/hw/super6502_fpga/super6502_fpga.xml +++ b/hw/super6502_fpga/super6502_fpga.xml @@ -1,5 +1,5 @@ - + From 6bf7fee64bc96c73c9604d3e45ff51e946257abe Mon Sep 17 00:00:00 2001 From: Byron Lathi Date: Sun, 13 Oct 2024 20:01:37 -0700 Subject: [PATCH 4/8] Increase TCP count to 2 After removing all the inferred latches, we have enough space to have 2 TCP streams instead of just 1. Also we have way more timing slack. Lesson learned, inferred latches are *really* bad and you should remove them first before anything else. --- hw/super6502_fpga/src/rtl/super_6502_fpga.sv | 2 +- hw/super6502_fpga/super6502_fpga.xml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/hw/super6502_fpga/src/rtl/super_6502_fpga.sv b/hw/super6502_fpga/src/rtl/super_6502_fpga.sv index 9220ebd..908bd4e 100644 --- a/hw/super6502_fpga/src/rtl/super_6502_fpga.sv +++ b/hw/super6502_fpga/src/rtl/super_6502_fpga.sv @@ -526,7 +526,7 @@ logic network_processor_reset; always_ff @(posedge i_sysclk) network_processor_reset <= ~master_resetn; network_processor #( - .NUM_TCP(1) + .NUM_TCP(2) ) u_network_processor ( .i_clk (i_sysclk), .i_rst (network_processor_reset), diff --git a/hw/super6502_fpga/super6502_fpga.xml b/hw/super6502_fpga/super6502_fpga.xml index 730db5d..4d2ba84 100644 --- a/hw/super6502_fpga/super6502_fpga.xml +++ b/hw/super6502_fpga/super6502_fpga.xml @@ -1,5 +1,5 @@ - + From 16858bbb9d102e29901d74b99d44f9ea9821e5ea Mon Sep 17 00:00:00 2001 From: Byron Lathi Date: Sun, 13 Oct 2024 20:21:53 -0700 Subject: [PATCH 5/8] Register signals explicitly These were previously inferred latches, but now that they are not, we need to register them explicitly, otherwise they will be 0 --- .../src/tcp_packet_generator.sv | 18 +++++++++++++++--- .../sub/network_processor/src/tcp_parser.sv | 1 + 2 files changed, 16 insertions(+), 3 deletions(-) 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 da36efe..4f79837 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 @@ -67,6 +67,9 @@ logic data_checksum_clear; logic [31:0] data_checksum_data; logic [15:0] data_checksum_final; +logic [31:0] src_ip, dst_ip_next; +logic [31:0] dst_ip, src_ip_next; + checksum_calc u_header_checksum_calc( .i_rst (i_rst), .i_clk (i_clk), @@ -83,11 +86,15 @@ always_ff @(posedge i_clk) begin checksum_counter <= '0; state <= IDLE; data_expand <= '0; + src_ip <= '0; + dst_ip <= '0; end else begin counter <= counter_next; checksum_counter <= checksum_counter_next; state <= state_next; data_expand <= data_expand_next; + src_ip <= src_ip_next; + dst_ip <= dst_ip_next; end end @@ -125,6 +132,8 @@ always_comb begin data_expand_next = data_expand; + src_ip_next = src_ip; + dst_ip_next = dst_ip; case (state) IDLE: begin @@ -142,6 +151,9 @@ always_comb begin m_ip.ip_source_ip = i_src_ip; m_ip.ip_dest_ip = i_dst_ip; + src_ip_next = i_src_ip; + dst_ip_next = i_dst_ip; + if (m_ip.ip_hdr_ready) begin if (i_no_data) begin state_next = HEADER; @@ -181,9 +193,9 @@ always_comb begin end 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, (i_ip_len - 16'd20)}; // tcp length, not IP length + 0: checksum_data = src_ip; + 1: checksum_data = dst_ip; + 2: checksum_data = {8'b0, 8'h6, (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; 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 cd368da..73a26ee 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 @@ -110,6 +110,7 @@ always_comb begin end PAYLOAD: begin + s_ip.ip_payload_axis_tready = '1; if (s_ip.ip_payload_axis_tlast) begin counter_next = '0; state_next = HEADER; From 411d091dc1267d3df38a6d013f1c80cac834c40a Mon Sep 17 00:00:00 2001 From: Byron Lathi Date: Mon, 14 Oct 2024 21:11:08 -0700 Subject: [PATCH 6/8] Increase seq when sending fins --- .../sim/cocotb/tests/scapy_irl_test.py | 14 +++++++++++--- .../src/sub/network_processor/src/tcp_rx_ctrl.sv | 1 + .../sub/network_processor/src/tcp_state_manager.sv | 4 +++- .../src/sub/network_processor/src/tcp_tx_ctrl.sv | 2 +- hw/super6502_fpga/src/sub/verilog-ethernet | 2 +- 5 files changed, 17 insertions(+), 6 deletions(-) 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 b65bbba..48f75dc 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 @@ -94,7 +94,7 @@ def ip_to_hex(ip: str) -> int: return result -# @cocotb.test() +@cocotb.test() async def test_irl(dut): tb = TB(dut) @@ -270,11 +270,19 @@ async def test_irl(dut): await tb.mii_phy.rx.send(GmiiFrame.from_payload(tcp_fin.build())) + tb.log.info("Expecting to get ACK from DUT") + ip_packet = await read_tcp_from_dut() t.send(ip_packet) - tb.log.info("Expecting to send last ACK here") + tb.log.info("Expecting to get FINACK from DUT") + + ip_packet = await read_tcp_from_dut() + + t.send(ip_packet) + + tb.log.info("Expecting to get ACK from host") while True: pkt = t.recv() @@ -455,4 +463,4 @@ async def test_close(dut): tb.log.info("Sending packet to host") t.send(ip_packet) - await Timer(Decimal(CLK_PERIOD_NS * 10000), units='ns') \ No newline at end of file + await Timer(Decimal(CLK_PERIOD_NS * 20000), units='ns') \ 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 index 767acbb..60b15e6 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 @@ -54,6 +54,7 @@ always_comb begin if (i_flags == 8'h11) begin rx_msg_next = RX_MSG_RECV_FIN; rx_msg_valid_next = '1; + ack_num_next = i_seq_number + 1; end if (i_flags == 8'h10) begin 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 c2f12c6..9f19298 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 @@ -126,7 +126,9 @@ always_comb begin WAIT_CLOSE: begin o_tx_ctrl = TX_CTRL_SEND_FIN; o_tx_ctrl_valid = '1; - tcp_state_next = LAST_ACK; + if (i_tx_ctrl_ack) begin // we should be doing this other places too... + tcp_state_next = LAST_ACK; + end end LAST_ACK: begin 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 752d3cb..f6cc159 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 @@ -130,7 +130,7 @@ always_comb begin if (i_packet_done) begin state_next = IDLE; - seq_num_next = seq_num + s_axis_len; + seq_num_next = seq_num + 1; end end endcase diff --git a/hw/super6502_fpga/src/sub/verilog-ethernet b/hw/super6502_fpga/src/sub/verilog-ethernet index 13f6d61..e00d246 160000 --- a/hw/super6502_fpga/src/sub/verilog-ethernet +++ b/hw/super6502_fpga/src/sub/verilog-ethernet @@ -1 +1 @@ -Subproject commit 13f6d6137d7c29f0482d5a692c5dcbb48cbec46d +Subproject commit e00d2466b0f2ce4e10653e7a40fdc814bf422d21 From 2307dd65e2a9649e3858531ffdfabf624be490cd Mon Sep 17 00:00:00 2001 From: Byron Lathi Date: Mon, 14 Oct 2024 21:13:53 -0700 Subject: [PATCH 7/8] load efinity after init when building --- .gitlab-ci.yml | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index 742f640..7174efb 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -12,7 +12,8 @@ build: - efinity - linux script: - - source init_env.sh + # - source init_env.sh + - module load efinity/2023.1 - make after_script: - cat hw/super6502_fpga/outflow/super6502_fpga.err.log From 8465b50712519e99633965248f0d2e0630a4bc1b Mon Sep 17 00:00:00 2001 From: Byron Lathi Date: Mon, 14 Oct 2024 21:50:06 -0700 Subject: [PATCH 8/8] makefile fixes, update efinity version --- .gitlab-ci.yml | 2 +- Makefile | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index 7174efb..db995ee 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -13,7 +13,7 @@ build: - linux script: # - source init_env.sh - - module load efinity/2023.1 + - module load efinity/2024.1 - make after_script: - cat hw/super6502_fpga/outflow/super6502_fpga.err.log diff --git a/Makefile b/Makefile index 46cd215..ef47ba5 100644 --- a/Makefile +++ b/Makefile @@ -26,7 +26,7 @@ $(CC65): $(MAKE) -C sw/toolchain/cc65 -j $(shell nproc) $(INIT_HEX): $(CC65) script/generate_rom_image.py $(HEX) - python script/generate_rom_image.py -i $(HEX) -o $@ + python3 script/generate_rom_image.py -i $(HEX) -o $@ # This should get dependencies of rom, not be phony .PHONY: $(HEX)