Compare commits
11 Commits
97-calcula
...
master
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
bc9b04853c | ||
|
|
105484b622 | ||
|
|
8465b50712 | ||
|
|
2307dd65e2 | ||
|
|
411d091dc1 | ||
|
|
16858bbb9d | ||
|
|
6bf7fee64b | ||
|
|
5e8d91be53 | ||
|
|
6265a8090c | ||
|
|
798fb6f20f | ||
|
|
982a8b52b6 |
@@ -12,7 +12,8 @@ build:
|
|||||||
- efinity
|
- efinity
|
||||||
- linux
|
- linux
|
||||||
script:
|
script:
|
||||||
- source init_env.sh
|
# - source init_env.sh
|
||||||
|
- module load efinity/2024.1
|
||||||
- make
|
- make
|
||||||
after_script:
|
after_script:
|
||||||
- cat hw/super6502_fpga/outflow/super6502_fpga.err.log
|
- cat hw/super6502_fpga/outflow/super6502_fpga.err.log
|
||||||
|
|||||||
2
Makefile
2
Makefile
@@ -26,7 +26,7 @@ $(CC65):
|
|||||||
$(MAKE) -C sw/toolchain/cc65 -j $(shell nproc)
|
$(MAKE) -C sw/toolchain/cc65 -j $(shell nproc)
|
||||||
|
|
||||||
$(INIT_HEX): $(CC65) script/generate_rom_image.py $(HEX)
|
$(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
|
# This should get dependencies of rom, not be phony
|
||||||
.PHONY: $(HEX)
|
.PHONY: $(HEX)
|
||||||
|
|||||||
@@ -91,7 +91,9 @@ assign pre_resetn = button_resetn & vio0_resetn;
|
|||||||
|
|
||||||
assign sdram_ready = |w_sdr_state;
|
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;
|
assign o_sd_cs = '1;
|
||||||
|
|
||||||
@@ -214,11 +216,14 @@ logic [1:0] sd_controller_dma_RRESP;
|
|||||||
axil_intf ntw_reg();
|
axil_intf ntw_reg();
|
||||||
axil_intf ntw_dma();
|
axil_intf ntw_dma();
|
||||||
|
|
||||||
|
logic cpu_wrapper_reset;
|
||||||
|
always_ff @(posedge i_sysclk) cpu_wrapper_reset <= ~master_resetn;
|
||||||
|
|
||||||
|
|
||||||
cpu_wrapper u_cpu_wrapper_0(
|
cpu_wrapper u_cpu_wrapper_0(
|
||||||
.i_clk_cpu (clk_cpu),
|
.i_clk_cpu (clk_cpu),
|
||||||
.i_clk_100 (i_sysclk),
|
.i_clk_100 (i_sysclk),
|
||||||
.i_rst (~master_resetn),
|
.i_rst (cpu_wrapper_reset),
|
||||||
|
|
||||||
.o_cpu_rst (o_cpu0_reset),
|
.o_cpu_rst (o_cpu0_reset),
|
||||||
.o_cpu_rdy (o_cpu0_rdy),
|
.o_cpu_rdy (o_cpu0_rdy),
|
||||||
@@ -258,6 +263,8 @@ cpu_wrapper u_cpu_wrapper_0(
|
|||||||
.i_nmi('0)
|
.i_nmi('0)
|
||||||
);
|
);
|
||||||
|
|
||||||
|
logic crossbar_resetn;
|
||||||
|
always_ff @(posedge i_sysclk) crossbar_resetn <= master_resetn;
|
||||||
|
|
||||||
axilxbar #(
|
axilxbar #(
|
||||||
.NM(3),
|
.NM(3),
|
||||||
@@ -271,7 +278,7 @@ axilxbar #(
|
|||||||
})
|
})
|
||||||
) u_crossbar (
|
) u_crossbar (
|
||||||
.S_AXI_ACLK (i_sysclk),
|
.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_ARADDR ({cpu0_ARADDR, sd_controller_dma_ARADDR, ntw_dma.araddr }),
|
||||||
.S_AXI_ARVALID ({cpu0_ARVALID, sd_controller_dma_ARVALID, ntw_dma.arvalid }),
|
.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 #(
|
axi4_lite_rom #(
|
||||||
.ROM_SIZE(12),
|
.ROM_SIZE(12),
|
||||||
.BASE_ADDRESS(32'h0000f000),
|
.BASE_ADDRESS(32'h0000f000),
|
||||||
.ROM_INIT_FILE("init_hex.mem")
|
.ROM_INIT_FILE("init_hex.mem")
|
||||||
) u_rom (
|
) u_rom (
|
||||||
.i_clk(i_sysclk),
|
.i_clk(i_sysclk),
|
||||||
.i_rst(~master_resetn),
|
.i_rst(rom_reset),
|
||||||
|
|
||||||
.o_AWREADY(rom_awready),
|
.o_AWREADY(rom_awready),
|
||||||
.o_WREADY(rom_wready),
|
.o_WREADY(rom_wready),
|
||||||
@@ -344,12 +354,15 @@ axi4_lite_rom #(
|
|||||||
.i_WSTRB(rom_wstrb)
|
.i_WSTRB(rom_wstrb)
|
||||||
);
|
);
|
||||||
|
|
||||||
|
logic ram_reset;
|
||||||
|
always_ff @(posedge i_sysclk) ram_reset <= ~master_resetn;
|
||||||
|
|
||||||
axi4_lite_ram #(
|
axi4_lite_ram #(
|
||||||
.RAM_SIZE(9),
|
.RAM_SIZE(9),
|
||||||
.ZERO_INIT(1)
|
.ZERO_INIT(1)
|
||||||
) u_ram(
|
) u_ram(
|
||||||
.i_clk(i_sysclk),
|
.i_clk(i_sysclk),
|
||||||
.i_rst(~master_resetn),
|
.i_rst(ram_reset),
|
||||||
|
|
||||||
.o_AWREADY(ram_awready),
|
.o_AWREADY(ram_awready),
|
||||||
.o_WREADY(ram_wready),
|
.o_WREADY(ram_wready),
|
||||||
@@ -452,12 +465,15 @@ sdram_controller u_sdram_controller(
|
|||||||
|
|
||||||
logic sd_irq;
|
logic sd_irq;
|
||||||
|
|
||||||
|
logic sd_controller_wrapper_reset;
|
||||||
|
always_ff @(posedge i_sysclk) sd_controller_wrapper_reset <= ~master_resetn;
|
||||||
|
|
||||||
sd_controller_wrapper #(
|
sd_controller_wrapper #(
|
||||||
.NUMIO (1), // board as it stands is in 1 bit mode
|
.NUMIO (1), // board as it stands is in 1 bit mode
|
||||||
.BASE_ADDRESS (32'h0000E000)
|
.BASE_ADDRESS (32'h0000E000)
|
||||||
) u_sdio_top (
|
) u_sdio_top (
|
||||||
.i_clk (i_sysclk),
|
.i_clk (i_sysclk),
|
||||||
.i_reset (~master_resetn),
|
.i_reset (sd_controller_wrapper_reset),
|
||||||
|
|
||||||
.S_AXIL_AWVALID (sd_controller_ctrl_AWVALID),
|
.S_AXIL_AWVALID (sd_controller_ctrl_AWVALID),
|
||||||
.S_AXIL_AWREADY (sd_controller_ctrl_AWREADY),
|
.S_AXIL_AWREADY (sd_controller_ctrl_AWREADY),
|
||||||
@@ -506,11 +522,14 @@ sd_controller_wrapper #(
|
|||||||
.o_int (sd_irq)
|
.o_int (sd_irq)
|
||||||
);
|
);
|
||||||
|
|
||||||
|
logic network_processor_reset;
|
||||||
|
always_ff @(posedge i_sysclk) network_processor_reset <= ~master_resetn;
|
||||||
|
|
||||||
network_processor #(
|
network_processor #(
|
||||||
.NUM_TCP(4)
|
.NUM_TCP(2)
|
||||||
) u_network_processor (
|
) u_network_processor (
|
||||||
.i_clk (i_sysclk),
|
.i_clk (i_sysclk),
|
||||||
.i_rst (~master_resetn),
|
.i_rst (network_processor_reset),
|
||||||
|
|
||||||
.s_reg_axil (ntw_reg),
|
.s_reg_axil (ntw_reg),
|
||||||
.m_dma_axil (ntw_dma),
|
.m_dma_axil (ntw_dma),
|
||||||
|
|||||||
Submodule hw/super6502_fpga/src/sub/interfaces updated: 13c389dc18...e3c55d1bb2
Submodule hw/super6502_fpga/src/sub/my-fifos updated: a19156c9cd...8d960ab4bf
@@ -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.data import IP_PROTOS
|
||||||
|
|
||||||
from scapy import sendrecv
|
from scapy import sendrecv
|
||||||
@@ -18,8 +14,9 @@ from cocotbext.axi import AxiLiteBus, AxiLiteMaster, AxiLiteRam
|
|||||||
from cocotbext.eth import MiiPhy, GmiiFrame
|
from cocotbext.eth import MiiPhy, GmiiFrame
|
||||||
import struct
|
import struct
|
||||||
|
|
||||||
from scapy.layers.inet import Ether, IP, TCP
|
from scapy.layers.inet import IP, TCP
|
||||||
from scapy.layers.l2 import ARP
|
from scapy.layers.l2 import ARP, Ether
|
||||||
|
from scapy.packet import Packet
|
||||||
from scapy.utils import PcapWriter
|
from scapy.utils import PcapWriter
|
||||||
|
|
||||||
from scapy.layers.tuntap import TunTapInterface
|
from scapy.layers.tuntap import TunTapInterface
|
||||||
@@ -27,6 +24,8 @@ import logging
|
|||||||
|
|
||||||
from decimal import Decimal
|
from decimal import Decimal
|
||||||
|
|
||||||
|
import random
|
||||||
|
|
||||||
CLK_PERIOD_NS = 10
|
CLK_PERIOD_NS = 10
|
||||||
|
|
||||||
MII_CLK_PERIOD_NS = 40
|
MII_CLK_PERIOD_NS = 40
|
||||||
@@ -35,7 +34,7 @@ MII_CLK_PERIOD_NS = 40
|
|||||||
import socket
|
import socket
|
||||||
|
|
||||||
# In order for this to work, you need to run these commands:
|
# 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 a add 172.0.0.1 peer 172.0.0.2 dev tun0
|
||||||
# sudo ip link set tun0 up
|
# sudo ip link set tun0 up
|
||||||
|
|
||||||
@@ -99,6 +98,33 @@ def ip_to_hex(ip: str) -> int:
|
|||||||
async def test_irl(dut):
|
async def test_irl(dut):
|
||||||
tb = TB(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()
|
await tb.cycle_reset()
|
||||||
|
|
||||||
dut_ip = "172.0.0.2"
|
dut_ip = "172.0.0.2"
|
||||||
@@ -106,14 +132,18 @@ async def test_irl(dut):
|
|||||||
|
|
||||||
tb_mac = "02:00:00:11:22:33"
|
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 = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
|
||||||
serversocket.bind((tb_ip, 5678))
|
serversocket.bind((tb_ip, tb_port))
|
||||||
serversocket.listen(1)
|
serversocket.listen(1)
|
||||||
t = TunTapInterface('tun0')
|
t = TunTapInterface('tun0')
|
||||||
|
|
||||||
|
|
||||||
dut_port = 1234
|
###############################
|
||||||
tb_port = 5678
|
# Configure DUT Network block #
|
||||||
|
###############################
|
||||||
|
|
||||||
await tb.axil_master.write_dword(0x0, 0x1807)
|
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.psrc == dut_ip, "ARP psrc does not match expected"
|
||||||
assert arp_request.pdst == tb_ip, "ARP pdst 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 = 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(op="is-at", hwsrc=tb_mac, hwdst=dut_mac, psrc=tb_ip, pdst=dut_ip)
|
||||||
arp_response = arp_response.build()
|
arp_response = arp_response.build()
|
||||||
|
|
||||||
await tb.mii_phy.rx.send(GmiiFrame.from_payload(arp_response))
|
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
|
ip_packet = await read_tcp_from_dut()
|
||||||
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}")
|
|
||||||
|
|
||||||
t.send(ip_packet)
|
t.send(ip_packet)
|
||||||
|
|
||||||
while True:
|
while True:
|
||||||
pkt = t.recv()
|
pkt = t.recv()
|
||||||
|
assert isinstance(pkt, Packet)
|
||||||
if (pkt.proto == IP_PROTOS.tcp):
|
if (pkt.proto == IP_PROTOS.tcp):
|
||||||
break
|
break
|
||||||
print(pkt)
|
print(pkt)
|
||||||
@@ -187,29 +207,16 @@ async def test_irl(dut):
|
|||||||
|
|
||||||
await tb.mii_phy.rx.send(GmiiFrame.from_payload(tcp_synack.build()))
|
await tb.mii_phy.rx.send(GmiiFrame.from_payload(tcp_synack.build()))
|
||||||
|
|
||||||
resp = await tb.mii_phy.tx.recv() # type: GmiiFrame
|
ip_packet = await read_tcp_from_dut()
|
||||||
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}")
|
|
||||||
|
|
||||||
t.send(ip_packet)
|
t.send(ip_packet)
|
||||||
|
|
||||||
con, addr = serversocket.accept()
|
con, addr = serversocket.accept()
|
||||||
|
|
||||||
|
###############################
|
||||||
|
# Send data from DUT to host #
|
||||||
|
###############################
|
||||||
|
|
||||||
# Construct a descriptor in memry
|
# Construct a descriptor in memry
|
||||||
tb.axil_ram.write_dword(0x00000000, 0x00001000)
|
tb.axil_ram.write_dword(0x00000000, 0x00001000)
|
||||||
tb.axil_ram.write_dword(0x00000004, 64)
|
tb.axil_ram.write_dword(0x00000004, 64)
|
||||||
@@ -232,11 +239,16 @@ async def test_irl(dut):
|
|||||||
con.recv(64)
|
con.recv(64)
|
||||||
tb.log.info("Received 64 packets")
|
tb.log.info("Received 64 packets")
|
||||||
|
|
||||||
|
###############################
|
||||||
|
# Close connection from host #
|
||||||
|
###############################
|
||||||
|
|
||||||
con.close()
|
con.close()
|
||||||
serversocket.close()
|
serversocket.close()
|
||||||
|
|
||||||
while True:
|
while True:
|
||||||
pkt = t.recv()
|
pkt = t.recv()
|
||||||
|
assert isinstance(pkt, Packet)
|
||||||
if (pkt.proto == IP_PROTOS.tcp):
|
if (pkt.proto == IP_PROTOS.tcp):
|
||||||
break
|
break
|
||||||
print(pkt)
|
print(pkt)
|
||||||
@@ -249,6 +261,7 @@ async def test_irl(dut):
|
|||||||
|
|
||||||
while True:
|
while True:
|
||||||
pkt = t.recv()
|
pkt = t.recv()
|
||||||
|
assert isinstance(pkt, Packet)
|
||||||
if (pkt.proto == IP_PROTOS.tcp):
|
if (pkt.proto == IP_PROTOS.tcp):
|
||||||
break
|
break
|
||||||
print(pkt)
|
print(pkt)
|
||||||
@@ -257,6 +270,39 @@ async def test_irl(dut):
|
|||||||
|
|
||||||
await tb.mii_phy.rx.send(GmiiFrame.from_payload(tcp_fin.build()))
|
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 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()
|
||||||
|
assert isinstance(pkt, Packet)
|
||||||
|
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()))
|
||||||
|
|
||||||
|
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
|
resp = await tb.mii_phy.tx.recv() # type: GmiiFrame
|
||||||
packet = Ether(resp.get_payload())
|
packet = Ether(resp.get_payload())
|
||||||
tb.log.info(f"Packet Type: {packet.type:x}")
|
tb.log.info(f"Packet Type: {packet.type:x}")
|
||||||
@@ -276,18 +322,145 @@ async def test_irl(dut):
|
|||||||
tb.log.info(f"window: {tcp_packet.window}")
|
tb.log.info(f"window: {tcp_packet.window}")
|
||||||
tb.log.info(f"Checksum: {tcp_packet.chksum}")
|
tb.log.info(f"Checksum: {tcp_packet.chksum}")
|
||||||
|
|
||||||
t.send(ip_packet)
|
return ip_packet
|
||||||
|
|
||||||
tb.log.info("Expecting to send last ACK here")
|
|
||||||
|
|
||||||
|
def get_pkt_from_host():
|
||||||
while True:
|
while True:
|
||||||
pkt = t.recv()
|
pkt = t.recv()
|
||||||
|
assert isinstance(pkt, Packet)
|
||||||
if (pkt.proto == IP_PROTOS.tcp):
|
if (pkt.proto == IP_PROTOS.tcp):
|
||||||
break
|
break
|
||||||
print(pkt)
|
print(pkt)
|
||||||
|
return pkt
|
||||||
|
|
||||||
tcp_fin = Ether(dst=dut_mac, src=tb_mac) / pkt
|
#############################
|
||||||
|
# Reset DUT #
|
||||||
|
#############################
|
||||||
|
|
||||||
await tb.mii_phy.rx.send(GmiiFrame.from_payload(tcp_fin.build()))
|
|
||||||
|
|
||||||
await Timer(Decimal(CLK_PERIOD_NS * 1000), units='ns')
|
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)
|
||||||
|
|
||||||
|
await Timer(Decimal(CLK_PERIOD_NS * 20000), units='ns')
|
||||||
@@ -20,3 +20,5 @@ src/ip_demux_wrapper.sv
|
|||||||
src/tcp_dest_decap.sv
|
src/tcp_dest_decap.sv
|
||||||
src/tcp_parser.sv
|
src/tcp_parser.sv
|
||||||
src/checksum_calc.sv
|
src/checksum_calc.sv
|
||||||
|
src/ip_pipeline_register_wrapper.sv
|
||||||
|
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
|
||||||
@@ -11,6 +11,8 @@ module checksum_calc (
|
|||||||
);
|
);
|
||||||
|
|
||||||
logic [31:0] sum;
|
logic [31:0] sum;
|
||||||
|
logic [31:0] pre_sum;
|
||||||
|
logic [31:0] sum_next;
|
||||||
logic [15:0] sum_wrapped;
|
logic [15:0] sum_wrapped;
|
||||||
|
|
||||||
assign sum_wrapped = sum[15:0] + sum [31:16];
|
assign sum_wrapped = sum[15:0] + sum [31:16];
|
||||||
@@ -21,9 +23,14 @@ always @(posedge i_clk) begin
|
|||||||
sum <= '0;
|
sum <= '0;
|
||||||
end else begin
|
end else begin
|
||||||
if (i_enable) begin
|
if (i_enable) begin
|
||||||
sum <= sum + i_data[31:16] + i_data[15:0];
|
sum <= sum_next;
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
always_comb begin
|
||||||
|
pre_sum = i_data[31:16] + i_data[15:0];
|
||||||
|
sum_next = sum + pre_sum;
|
||||||
|
end
|
||||||
|
|
||||||
endmodule
|
endmodule
|
||||||
@@ -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
|
||||||
@@ -39,6 +39,8 @@ localparam MAC_DATA_WIDTH = 8;
|
|||||||
localparam AXIS_DATA_WIDTH = 8;
|
localparam AXIS_DATA_WIDTH = 8;
|
||||||
localparam AXIS_KEEP_WIDTH = ((AXIS_DATA_WIDTH+7)/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_tx_axis();
|
||||||
axis_intf #(.DATA_WIDTH(MAC_DATA_WIDTH)) mac_rx_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__in_t hwif_in;
|
||||||
ntw_top_regfile_pkg::ntw_top_regfile__out_t hwif_out;
|
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 (
|
ntw_top_regfile u_ntw_top_regfile (
|
||||||
.clk (i_clk),
|
.clk (i_clk),
|
||||||
.rst (i_rst),
|
.rst (i_rst),
|
||||||
|
|
||||||
.s_axil_awready (s_reg_axil.awready),
|
.s_axil_awready (reg_axil_post_reg.awready),
|
||||||
.s_axil_awvalid (s_reg_axil.awvalid),
|
.s_axil_awvalid (reg_axil_post_reg.awvalid),
|
||||||
.s_axil_awaddr (s_reg_axil.awaddr),
|
.s_axil_awaddr (reg_axil_post_reg.awaddr),
|
||||||
.s_axil_awprot (s_reg_axil.awprot),
|
.s_axil_awprot (reg_axil_post_reg.awprot),
|
||||||
.s_axil_wready (s_reg_axil.wready),
|
.s_axil_wready (reg_axil_post_reg.wready),
|
||||||
.s_axil_wvalid (s_reg_axil.wvalid),
|
.s_axil_wvalid (reg_axil_post_reg.wvalid),
|
||||||
.s_axil_wdata (s_reg_axil.wdata),
|
.s_axil_wdata (reg_axil_post_reg.wdata),
|
||||||
.s_axil_wstrb (s_reg_axil.wstrb),
|
.s_axil_wstrb (reg_axil_post_reg.wstrb),
|
||||||
.s_axil_bready (s_reg_axil.bready),
|
.s_axil_bready (reg_axil_post_reg.bready),
|
||||||
.s_axil_bvalid (s_reg_axil.bvalid),
|
.s_axil_bvalid (reg_axil_post_reg.bvalid),
|
||||||
.s_axil_bresp (s_reg_axil.bresp),
|
.s_axil_bresp (reg_axil_post_reg.bresp),
|
||||||
.s_axil_arready (s_reg_axil.arready),
|
.s_axil_arready (reg_axil_post_reg.arready),
|
||||||
.s_axil_arvalid (s_reg_axil.arvalid),
|
.s_axil_arvalid (reg_axil_post_reg.arvalid),
|
||||||
.s_axil_araddr (s_reg_axil.araddr),
|
.s_axil_araddr (reg_axil_post_reg.araddr),
|
||||||
.s_axil_arprot (s_reg_axil.arprot),
|
.s_axil_arprot (reg_axil_post_reg.arprot),
|
||||||
.s_axil_rready (s_reg_axil.rready),
|
.s_axil_rready (reg_axil_post_reg.rready),
|
||||||
.s_axil_rvalid (s_reg_axil.rvalid),
|
.s_axil_rvalid (reg_axil_post_reg.rvalid),
|
||||||
.s_axil_rdata (s_reg_axil.rdata),
|
.s_axil_rdata (reg_axil_post_reg.rdata),
|
||||||
.s_axil_rresp (s_reg_axil.rresp),
|
.s_axil_rresp (reg_axil_post_reg.rresp),
|
||||||
|
|
||||||
.hwif_in (hwif_in),
|
.hwif_in (hwif_in),
|
||||||
.hwif_out (hwif_out)
|
.hwif_out (hwif_out)
|
||||||
|
|||||||
@@ -205,6 +205,8 @@ logic [$clog2(NUM_TCP)-1:0] tcp_demux_sel;
|
|||||||
logic [15:0] tcp_dests [NUM_TCP];
|
logic [15:0] tcp_dests [NUM_TCP];
|
||||||
|
|
||||||
always_comb begin : TCP_DEST_SEL
|
always_comb begin : TCP_DEST_SEL
|
||||||
|
tcp_demux_sel = '0;
|
||||||
|
|
||||||
for (int i = 0; i < NUM_TCP; i++) begin
|
for (int i = 0; i < NUM_TCP; i++) begin
|
||||||
if (tcp_dest == tcp_dests[i]) begin
|
if (tcp_dest == tcp_dests[i]) begin
|
||||||
tcp_demux_sel = i;
|
tcp_demux_sel = i;
|
||||||
|
|||||||
@@ -100,6 +100,15 @@ always_comb begin
|
|||||||
|
|
||||||
s_ip.ip_payload_axis_tready = '0;
|
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)
|
case (state)
|
||||||
PORTS: begin
|
PORTS: begin
|
||||||
s_ip.ip_payload_axis_tready = 1;
|
s_ip.ip_payload_axis_tready = 1;
|
||||||
|
|||||||
@@ -37,7 +37,7 @@ assign pre_checksum_data.tuser = s_axis_data.tuser;
|
|||||||
|
|
||||||
axis_saf_fifo #(
|
axis_saf_fifo #(
|
||||||
.DATA_DEPTH_L2(11),
|
.DATA_DEPTH_L2(11),
|
||||||
.CTRL_DEPTH_L2(1)
|
.CTRL_DEPTH_L2(2)
|
||||||
) u_checksum_fifo (
|
) u_checksum_fifo (
|
||||||
.sclk(i_clk),
|
.sclk(i_clk),
|
||||||
.srst(i_rst),
|
.srst(i_rst),
|
||||||
@@ -67,6 +67,9 @@ logic data_checksum_clear;
|
|||||||
logic [31:0] data_checksum_data;
|
logic [31:0] data_checksum_data;
|
||||||
logic [15:0] data_checksum_final;
|
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(
|
checksum_calc u_header_checksum_calc(
|
||||||
.i_rst (i_rst),
|
.i_rst (i_rst),
|
||||||
.i_clk (i_clk),
|
.i_clk (i_clk),
|
||||||
@@ -83,18 +86,44 @@ always_ff @(posedge i_clk) begin
|
|||||||
checksum_counter <= '0;
|
checksum_counter <= '0;
|
||||||
state <= IDLE;
|
state <= IDLE;
|
||||||
data_expand <= '0;
|
data_expand <= '0;
|
||||||
|
src_ip <= '0;
|
||||||
|
dst_ip <= '0;
|
||||||
end else begin
|
end else begin
|
||||||
counter <= counter_next;
|
counter <= counter_next;
|
||||||
checksum_counter <= checksum_counter_next;
|
checksum_counter <= checksum_counter_next;
|
||||||
state <= state_next;
|
state <= state_next;
|
||||||
data_expand <= data_expand_next;
|
data_expand <= data_expand_next;
|
||||||
|
src_ip <= src_ip_next;
|
||||||
|
dst_ip <= dst_ip_next;
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
always_comb begin
|
always_comb begin
|
||||||
|
state_next = state;
|
||||||
|
|
||||||
m_ip.ip_hdr_valid = '0;
|
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_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;
|
o_packet_done = '0;
|
||||||
checksum_clear = '0;
|
checksum_clear = '0;
|
||||||
checksum_enable = '0;
|
checksum_enable = '0;
|
||||||
@@ -103,6 +132,8 @@ always_comb begin
|
|||||||
|
|
||||||
data_expand_next = data_expand;
|
data_expand_next = data_expand;
|
||||||
|
|
||||||
|
src_ip_next = src_ip;
|
||||||
|
dst_ip_next = dst_ip;
|
||||||
case (state)
|
case (state)
|
||||||
|
|
||||||
IDLE: begin
|
IDLE: begin
|
||||||
@@ -120,6 +151,9 @@ always_comb begin
|
|||||||
m_ip.ip_source_ip = i_src_ip;
|
m_ip.ip_source_ip = i_src_ip;
|
||||||
m_ip.ip_dest_ip = i_dst_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 (m_ip.ip_hdr_ready) begin
|
||||||
if (i_no_data) begin
|
if (i_no_data) begin
|
||||||
state_next = HEADER;
|
state_next = HEADER;
|
||||||
@@ -159,9 +193,9 @@ always_comb begin
|
|||||||
end
|
end
|
||||||
|
|
||||||
case (checksum_counter)
|
case (checksum_counter)
|
||||||
0: checksum_data = m_ip.ip_source_ip;
|
0: checksum_data = src_ip;
|
||||||
1: checksum_data = m_ip.ip_dest_ip;
|
1: checksum_data = dst_ip;
|
||||||
2: checksum_data = {8'b0, m_ip.ip_protocol, (i_ip_len - 16'd20)}; // tcp length, not IP length
|
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};
|
3: checksum_data = {i_source_port, i_dest_port};
|
||||||
4: checksum_data = i_seq_number;
|
4: checksum_data = i_seq_number;
|
||||||
5: checksum_data = i_ack_number;
|
5: checksum_data = i_ack_number;
|
||||||
|
|||||||
@@ -66,6 +66,13 @@ always_comb begin
|
|||||||
checksum_next = checksum;
|
checksum_next = checksum;
|
||||||
hdr_valid = '0;
|
hdr_valid = '0;
|
||||||
|
|
||||||
|
counter_next = counter;
|
||||||
|
|
||||||
|
state_next = state;
|
||||||
|
|
||||||
|
s_ip.ip_hdr_ready = '0;
|
||||||
|
s_ip.ip_payload_axis_tready = '0;
|
||||||
|
|
||||||
case (state)
|
case (state)
|
||||||
HEADER: begin
|
HEADER: begin
|
||||||
s_ip.ip_hdr_ready = '1;
|
s_ip.ip_hdr_ready = '1;
|
||||||
@@ -103,6 +110,7 @@ always_comb begin
|
|||||||
end
|
end
|
||||||
|
|
||||||
PAYLOAD: begin
|
PAYLOAD: begin
|
||||||
|
s_ip.ip_payload_axis_tready = '1;
|
||||||
if (s_ip.ip_payload_axis_tlast) begin
|
if (s_ip.ip_payload_axis_tlast) begin
|
||||||
counter_next = '0;
|
counter_next = '0;
|
||||||
state_next = HEADER;
|
state_next = HEADER;
|
||||||
|
|||||||
@@ -19,34 +19,47 @@ module tcp_rx_ctrl (
|
|||||||
output logic [31:0] o_ack_number
|
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;
|
logic [31:0] ack_num, ack_num_next;
|
||||||
assign o_ack_number = ack_num;
|
assign o_ack_number = ack_num;
|
||||||
|
|
||||||
always_ff @(posedge i_clk) begin
|
always_ff @(posedge i_clk) begin
|
||||||
if (i_rst) begin
|
if (i_rst) begin
|
||||||
ack_num <= '0;
|
ack_num <= '0;
|
||||||
|
o_rx_msg <= RX_MSG_NOP;
|
||||||
|
o_rx_msg_valid <= '0;
|
||||||
end else begin
|
end else begin
|
||||||
ack_num <= ack_num_next;
|
ack_num <= ack_num_next;
|
||||||
|
o_rx_msg <= rx_msg_next;
|
||||||
|
o_rx_msg_valid <= rx_msg_valid_next;
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
always_comb begin
|
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_hdr_valid) begin
|
||||||
if (i_flags == 8'h12) begin
|
if (i_flags == 8'h12) begin
|
||||||
o_rx_msg = RX_MSG_RECV_SYNACK;
|
rx_msg_next = RX_MSG_RECV_SYNACK;
|
||||||
o_rx_msg_valid = '1;
|
rx_msg_valid_next = '1;
|
||||||
|
|
||||||
ack_num_next = i_seq_number + 1;
|
ack_num_next = i_seq_number + 1;
|
||||||
end
|
end
|
||||||
|
|
||||||
if (i_flags == 8'h11) begin
|
if (i_flags == 8'h11) begin
|
||||||
o_rx_msg = RX_MSG_RECV_FIN;
|
rx_msg_next = RX_MSG_RECV_FIN;
|
||||||
o_rx_msg_valid = '1;
|
rx_msg_valid_next = '1;
|
||||||
|
ack_num_next = i_seq_number + 1;
|
||||||
end
|
end
|
||||||
|
|
||||||
if (i_flags == 8'h10) begin
|
if (i_flags == 8'h10) begin
|
||||||
o_rx_msg = RX_MSG_RECV_ACK;
|
rx_msg_next = RX_MSG_RECV_ACK;
|
||||||
o_rx_msg_valid = '1;
|
rx_msg_valid_next = '1;
|
||||||
end
|
end
|
||||||
|
|
||||||
end
|
end
|
||||||
|
|||||||
@@ -87,8 +87,46 @@ always_comb begin
|
|||||||
|
|
||||||
ESTABLISHED: begin
|
ESTABLISHED: begin
|
||||||
if (i_rx_msg_valid && i_rx_msg == RX_MSG_RECV_FIN) begin
|
if (i_rx_msg_valid && i_rx_msg == RX_MSG_RECV_FIN) begin
|
||||||
|
o_tx_ctrl = TX_CTRL_SEND_ACK;
|
||||||
|
o_tx_ctrl_valid = '1;
|
||||||
|
tcp_state_next = WAIT_CLOSE;
|
||||||
|
end
|
||||||
|
|
||||||
|
if (i_close) begin
|
||||||
o_tx_ctrl = TX_CTRL_SEND_FIN;
|
o_tx_ctrl = TX_CTRL_SEND_FIN;
|
||||||
o_tx_ctrl_valid = '1;
|
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
|
||||||
|
|
||||||
|
WAIT_CLOSE: begin
|
||||||
|
o_tx_ctrl = TX_CTRL_SEND_FIN;
|
||||||
|
o_tx_ctrl_valid = '1;
|
||||||
|
if (i_tx_ctrl_ack) begin // we should be doing this other places too...
|
||||||
tcp_state_next = LAST_ACK;
|
tcp_state_next = LAST_ACK;
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|||||||
@@ -30,8 +30,11 @@ module tcp_stream #(
|
|||||||
);
|
);
|
||||||
|
|
||||||
axis_intf m2s_axis();
|
axis_intf m2s_axis();
|
||||||
|
axis_intf m2s_axis_pre_reg();
|
||||||
axis_intf s2m_axis();
|
axis_intf s2m_axis();
|
||||||
|
|
||||||
|
ip_intf m_ip_tx_pre_reg();
|
||||||
|
|
||||||
axis_intf m2s_post_saf_axis();
|
axis_intf m2s_post_saf_axis();
|
||||||
axis_intf s2m_pre_saf_axis();
|
axis_intf s2m_pre_saf_axis();
|
||||||
|
|
||||||
@@ -111,6 +114,14 @@ m2s_dma #(
|
|||||||
.s_cpuif_wr_err (),
|
.s_cpuif_wr_err (),
|
||||||
|
|
||||||
.m_axil (m_m2s_axil),
|
.m_axil (m_m2s_axil),
|
||||||
|
.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)
|
.m_axis(m2s_axis)
|
||||||
);
|
);
|
||||||
|
|
||||||
@@ -204,6 +215,14 @@ tcp_packet_generator u_tcp_packet_generator (
|
|||||||
|
|
||||||
.o_packet_done (w_tx_packet_done),
|
.o_packet_done (w_tx_packet_done),
|
||||||
|
|
||||||
|
.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)
|
.m_ip(m_ip_tx)
|
||||||
);
|
);
|
||||||
|
|
||||||
|
|||||||
@@ -24,14 +24,13 @@ module tcp_tx_ctrl(
|
|||||||
input wire i_packet_done
|
input wire i_packet_done
|
||||||
);
|
);
|
||||||
|
|
||||||
assign m_axis.tdata = s_axis.tdata;
|
axis_pipeline_register_wrapper u_m2s_reg (
|
||||||
assign m_axis.tkeep = s_axis.tkeep;
|
.clk(i_clk),
|
||||||
assign m_axis.tvalid = s_axis.tvalid;
|
.rst(i_rst),
|
||||||
assign s_axis.tready = m_axis.tready;
|
|
||||||
assign m_axis.tlast = s_axis.tlast;
|
.s_axis(s_axis),
|
||||||
assign m_axis.tid = s_axis.tid;
|
.m_axis(m_axis)
|
||||||
assign m_axis.tdest = s_axis.tdest;
|
);
|
||||||
assign m_axis.tuser = s_axis.tuser;
|
|
||||||
|
|
||||||
localparam FLAG_FIN = (1 << 0);
|
localparam FLAG_FIN = (1 << 0);
|
||||||
localparam FLAG_SYN = (1 << 1);
|
localparam FLAG_SYN = (1 << 1);
|
||||||
@@ -61,6 +60,8 @@ always_comb begin
|
|||||||
state_next = state;
|
state_next = state;
|
||||||
o_no_data = '0;
|
o_no_data = '0;
|
||||||
|
|
||||||
|
o_tx_ctrl_ack = '0;
|
||||||
|
|
||||||
o_ack_number = '0;
|
o_ack_number = '0;
|
||||||
o_flags = '0;
|
o_flags = '0;
|
||||||
o_window_size = 16'h100;
|
o_window_size = 16'h100;
|
||||||
@@ -129,7 +130,7 @@ always_comb begin
|
|||||||
|
|
||||||
if (i_packet_done) begin
|
if (i_packet_done) begin
|
||||||
state_next = IDLE;
|
state_next = IDLE;
|
||||||
seq_num_next = seq_num + s_axis_len;
|
seq_num_next = seq_num + 1;
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
endcase
|
endcase
|
||||||
|
|||||||
Submodule hw/super6502_fpga/src/sub/stream_dmas updated: 92ef12aed9...cbd06e5af4
Submodule hw/super6502_fpga/src/sub/verilog-ethernet updated: 2542187ec9...e00d2466b0
@@ -1,4 +1,5 @@
|
|||||||
<efx:project xmlns:efx="http://www.efinixinc.com/enf_proj" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" name="super6502_fpga" description="" last_change_date="Mon Sep 09 2024 11:15:46 PM" location="/cluster/projects/super6502/hw/super6502_fpga" sw_version="2023.1.150" last_run_state="pass" last_run_tool="efx_pgm" last_run_flow="bitstream" config_result_in_sync="sync" design_ood="sync" place_ood="sync" route_ood="sync" xsi:schemaLocation="http://www.efinixinc.com/enf_proj enf_proj.xsd">
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<efx:project name="super6502_fpga" description="" last_change="1728874681" sw_version="2024.1.163" last_run_state="pass" last_run_flow="bitstream" config_result_in_sync="sync" design_ood="sync" place_ood="sync" route_ood="sync" xmlns:efx="http://www.efinixinc.com/enf_proj" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.efinixinc.com/enf_proj enf_proj.xsd">
|
||||||
<efx:device_info>
|
<efx:device_info>
|
||||||
<efx:family name="Trion"/>
|
<efx:family name="Trion"/>
|
||||||
<efx:device name="T20F256"/>
|
<efx:device name="T20F256"/>
|
||||||
@@ -209,6 +210,9 @@
|
|||||||
<efx:design_file name="src/sub/my-fifos/src/fifo_fwft.sv" version="default" library="default"/>
|
<efx:design_file name="src/sub/my-fifos/src/fifo_fwft.sv" version="default" library="default"/>
|
||||||
<efx:design_file name="src/sub/my-fifos/src/fifo.sv" version="default" library="default"/>
|
<efx:design_file name="src/sub/my-fifos/src/fifo.sv" version="default" library="default"/>
|
||||||
<efx:design_file name="src/sub/my-fifos/src/fwft_adapter.sv" version="default" library="default"/>
|
<efx:design_file name="src/sub/my-fifos/src/fwft_adapter.sv" version="default" library="default"/>
|
||||||
|
<efx:design_file name="src/sub/network_processor/src/ip_pipeline_register_wrapper.sv" version="default" library="default"/>
|
||||||
|
<efx:design_file name="src/sub/verilog-ethernet/lib/axis/rtl/axis_pipeline_register_wrapper.sv" version="default" library="default"/>
|
||||||
|
<efx:design_file name="src/sub/network_processor/src/axil_reg_slice.sv" version="default" library="default"/>
|
||||||
<efx:top_vhdl_arch name=""/>
|
<efx:top_vhdl_arch name=""/>
|
||||||
</efx:design_info>
|
</efx:design_info>
|
||||||
<efx:constraint_info>
|
<efx:constraint_info>
|
||||||
@@ -249,6 +253,10 @@
|
|||||||
<efx:param name="mult_input_regs_packing" value="1" value_type="e_option"/>
|
<efx:param name="mult_input_regs_packing" value="1" value_type="e_option"/>
|
||||||
<efx:param name="mult_output_regs_packing" value="1" value_type="e_option"/>
|
<efx:param name="mult_output_regs_packing" value="1" value_type="e_option"/>
|
||||||
<efx:param name="include" value="ip/sdram_controller" value_type="e_string"/>
|
<efx:param name="include" value="ip/sdram_controller" value_type="e_string"/>
|
||||||
|
<efx:param name="bram-push-tco-outreg" value="0" value_type="e_option"/>
|
||||||
|
<efx:param name="mult-auto-pipeline" value="0" value_type="e_integer"/>
|
||||||
|
<efx:param name="use-logic-for-small-mem" value="64" value_type="e_integer"/>
|
||||||
|
<efx:param name="use-logic-for-small-rom" value="64" value_type="e_integer"/>
|
||||||
<efx:defmacro name="SDIO_AXI" value="1"/>
|
<efx:defmacro name="SDIO_AXI" value="1"/>
|
||||||
<efx:defmacro name="EFINIX" value="1"/>
|
<efx:defmacro name="EFINIX" value="1"/>
|
||||||
</efx:synthesis>
|
</efx:synthesis>
|
||||||
@@ -260,6 +268,7 @@
|
|||||||
<efx:param name="seed" value="1" value_type="e_integer"/>
|
<efx:param name="seed" value="1" value_type="e_integer"/>
|
||||||
<efx:param name="placer_effort_level" value="5" value_type="e_option"/>
|
<efx:param name="placer_effort_level" value="5" value_type="e_option"/>
|
||||||
<efx:param name="max_threads" value="-1" value_type="e_integer"/>
|
<efx:param name="max_threads" value="-1" value_type="e_integer"/>
|
||||||
|
<efx:param name="print_critical_path" value="10" value_type="e_integer"/>
|
||||||
</efx:place_and_route>
|
</efx:place_and_route>
|
||||||
<efx:bitstream_generation tool_name="efx_pgm">
|
<efx:bitstream_generation tool_name="efx_pgm">
|
||||||
<efx:param name="mode" value="active" value_type="e_option"/>
|
<efx:param name="mode" value="active" value_type="e_option"/>
|
||||||
|
|||||||
Reference in New Issue
Block a user