Compare commits
12 Commits
97-calcula
...
102-new-bo
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
21efb8ace8 | ||
|
|
bc9b04853c | ||
|
|
105484b622 | ||
|
|
8465b50712 | ||
|
|
2307dd65e2 | ||
|
|
411d091dc1 | ||
|
|
16858bbb9d | ||
|
|
6bf7fee64b | ||
|
|
5e8d91be53 | ||
|
|
6265a8090c | ||
|
|
798fb6f20f | ||
|
|
982a8b52b6 |
1
.gitignore
vendored
1
.gitignore
vendored
@@ -8,6 +8,7 @@
|
|||||||
*.map
|
*.map
|
||||||
*.list
|
*.list
|
||||||
*.bin
|
*.bin
|
||||||
|
*.hex
|
||||||
*.o
|
*.o
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -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
|
||||||
|
|||||||
4
Makefile
4
Makefile
@@ -1,4 +1,4 @@
|
|||||||
ROM_TARGET=test_code/loop_test
|
ROM_TARGET=bootloader
|
||||||
|
|
||||||
INIT_HEX=hw/super6502_fpga/init_hex.mem
|
INIT_HEX=hw/super6502_fpga/init_hex.mem
|
||||||
HEX=sw/$(ROM_TARGET)/$(notdir $(ROM_TARGET)).bin
|
HEX=sw/$(ROM_TARGET)/$(notdir $(ROM_TARGET)).bin
|
||||||
@@ -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),
|
||||||
|
|||||||
@@ -23,7 +23,7 @@ all: waves
|
|||||||
|
|
||||||
waves: $(TB_NAME)
|
waves: $(TB_NAME)
|
||||||
# ./$(TB_NAME) -fst
|
# ./$(TB_NAME) -fst
|
||||||
./obj_dir/Vsim_top
|
./obj_dir/Vsim_top | tee run.log
|
||||||
|
|
||||||
$(TB_NAME): $(SUPER6502_FPGA_SOURCES) $(SIM_SOURCES) $(COPY_FILES) $(SD_IMAGE)
|
$(TB_NAME): $(SUPER6502_FPGA_SOURCES) $(SIM_SOURCES) $(COPY_FILES) $(SD_IMAGE)
|
||||||
# $(IVERILOG) -g2005-sv $(FLAGS) -s $@ -o $@ $(INCLUDE) $(SUPER6502_FPGA_SOURCES) $(SIM_SOURCES) -I ../../
|
# $(IVERILOG) -g2005-sv $(FLAGS) -s $@ -o $@ $(INCLUDE) $(SUPER6502_FPGA_SOURCES) $(SIM_SOURCES) -I ../../
|
||||||
|
|||||||
@@ -197,8 +197,12 @@ initial begin
|
|||||||
button_resetn <= '0;
|
button_resetn <= '0;
|
||||||
repeat(10) @(clk_cpu);
|
repeat(10) @(clk_cpu);
|
||||||
button_resetn <= '1;
|
button_resetn <= '1;
|
||||||
repeat(20000) @(posedge clk_cpu);
|
repeat(2000) @(posedge clk_cpu);
|
||||||
$finish();
|
$finish();
|
||||||
end
|
end
|
||||||
|
|
||||||
|
always @(posedge w_cpu0_sync) begin
|
||||||
|
$display("[%t] CPU Executed %x:%x", $time(), w_cpu0_addr, w_cpu0_data_from_dut);
|
||||||
|
end
|
||||||
|
|
||||||
endmodule
|
endmodule
|
||||||
|
|||||||
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"/>
|
||||||
|
|||||||
19
sw/Makefile
Normal file
19
sw/Makefile
Normal file
@@ -0,0 +1,19 @@
|
|||||||
|
SD_IMAGE = sd_image.bin
|
||||||
|
BOOTLOADER = bootloader/bootloader.bin
|
||||||
|
|
||||||
|
all: $(SD_IMAGE) $(BOOTLOADER)
|
||||||
|
|
||||||
|
$(BOOTLOADER):
|
||||||
|
$(MAKE) -C bootloader bootloader.bin
|
||||||
|
|
||||||
|
$(SD_IMAGE):
|
||||||
|
dd if=/dev/zero of=$@ bs=1M count=256
|
||||||
|
/sbin/mkfs.vfat $@
|
||||||
|
udisksctl loop-setup --file $@
|
||||||
|
udisksctl mount -b /dev/loop1
|
||||||
|
udisksctl unmount -b /dev/loop1
|
||||||
|
udisksctl loop-delete -b /dev/loop1
|
||||||
|
|
||||||
|
clean:
|
||||||
|
rm -rf $(SD_IMAGE)
|
||||||
|
rm -rf $(BOOTLOADER)
|
||||||
38
sw/bootloader/Makefile
Normal file
38
sw/bootloader/Makefile
Normal file
@@ -0,0 +1,38 @@
|
|||||||
|
CC=../toolchain/cc65/bin/cl65
|
||||||
|
LD=../toolchain/cc65/bin/cl65
|
||||||
|
CFLAGS=-T -t none -I. --cpu "65C02"
|
||||||
|
LDFLAGS=-C link.ld -m $(NAME).map
|
||||||
|
|
||||||
|
NAME=bootloader
|
||||||
|
|
||||||
|
BIN=$(NAME).bin
|
||||||
|
HEX=$(NAME).hex
|
||||||
|
|
||||||
|
LISTS=lists
|
||||||
|
|
||||||
|
SRCS=$(wildcard *.s) $(wildcard *.c)
|
||||||
|
SRCS+=$(wildcard **/*.s) $(wildcard **/*.c)
|
||||||
|
OBJS+=$(patsubst %.s,%.o,$(filter %s,$(SRCS)))
|
||||||
|
OBJS+=$(patsubst %.c,%.o,$(filter %c,$(SRCS)))
|
||||||
|
|
||||||
|
all: $(HEX)
|
||||||
|
|
||||||
|
$(HEX): $(BIN)
|
||||||
|
objcopy --input-target=binary --output-target=verilog $(BIN) $(HEX)
|
||||||
|
|
||||||
|
$(BIN): $(OBJS)
|
||||||
|
$(CC) $(CFLAGS) $(LDFLAGS) $(OBJS) -o $@
|
||||||
|
|
||||||
|
%.o: %.c $(LISTS)
|
||||||
|
$(CC) $(CFLAGS) -l $(LISTS)/$<.list -c $< -o $@
|
||||||
|
|
||||||
|
%.o: %.s $(LISTS)
|
||||||
|
$(CC) $(CFLAGS) -l $(LISTS)/$<.list -c $< -o $@
|
||||||
|
|
||||||
|
$(LISTS):
|
||||||
|
mkdir -p $(addprefix $(LISTS)/,$(sort $(dir $(SRCS))))
|
||||||
|
|
||||||
|
.PHONY: clean
|
||||||
|
clean:
|
||||||
|
rm -rf $(OBJS) $(BIN) $(HEX) $(LISTS) $(NAME).map
|
||||||
|
|
||||||
25
sw/bootloader/bootloader.s
Normal file
25
sw/bootloader/bootloader.s
Normal file
@@ -0,0 +1,25 @@
|
|||||||
|
.export _init, _nmi_int, _irq_int
|
||||||
|
|
||||||
|
.segment "VECTORS"
|
||||||
|
|
||||||
|
.addr _nmi_int ; NMI vector
|
||||||
|
.addr _init ; Reset vector
|
||||||
|
.addr _irq_int ; IRQ/BRK vector
|
||||||
|
|
||||||
|
SDRAM= $200
|
||||||
|
|
||||||
|
.code
|
||||||
|
|
||||||
|
_nmi_int:
|
||||||
|
_irq_int:
|
||||||
|
|
||||||
|
_init:
|
||||||
|
lda #$00
|
||||||
|
@start:
|
||||||
|
sta SDRAM
|
||||||
|
cmp SDRAM
|
||||||
|
bne @end
|
||||||
|
ina
|
||||||
|
bra @start
|
||||||
|
|
||||||
|
@end: bra @end
|
||||||
30
sw/bootloader/link.ld
Normal file
30
sw/bootloader/link.ld
Normal file
@@ -0,0 +1,30 @@
|
|||||||
|
MEMORY
|
||||||
|
{
|
||||||
|
RAM: start = $0000, size = $200;
|
||||||
|
ROM: start = $F000, size = $1000, file = %O;
|
||||||
|
}
|
||||||
|
|
||||||
|
SEGMENTS {
|
||||||
|
ZEROPAGE: load = RAM, type = zp, define = yes;
|
||||||
|
DATA: load = ROM, type = rw, define = yes;
|
||||||
|
CODE: load = ROM, type = ro;
|
||||||
|
RODATA: load = ROM, type = ro;
|
||||||
|
VECTORS: load = ROM, type = ro, start = $FFFA;
|
||||||
|
}
|
||||||
|
|
||||||
|
FEATURES {
|
||||||
|
CONDES: segment = STARTUP,
|
||||||
|
type = constructor,
|
||||||
|
label = __CONSTRUCTOR_TABLE__,
|
||||||
|
count = __CONSTRUCTOR_COUNT__;
|
||||||
|
CONDES: segment = STARTUP,
|
||||||
|
type = destructor,
|
||||||
|
label = __DESTRUCTOR_TABLE__,
|
||||||
|
count = __DESTRUCTOR_COUNT__;
|
||||||
|
}
|
||||||
|
|
||||||
|
SYMBOLS {
|
||||||
|
# Define the stack size for the application
|
||||||
|
__STACKSIZE__: value = $0200, type = weak;
|
||||||
|
__STACKSTART__: type = weak, value = $0800; # 2k stack
|
||||||
|
}
|
||||||
39
sw/kernel/Makefile
Normal file
39
sw/kernel/Makefile
Normal file
@@ -0,0 +1,39 @@
|
|||||||
|
CC=../toolchain/cc65/bin/cl65
|
||||||
|
LD=../toolchain/cc65/bin/cl65
|
||||||
|
CFLAGS=-T -t none -I. --cpu "65C02"
|
||||||
|
LDFLAGS=-C link.ld -m $(NAME).map
|
||||||
|
|
||||||
|
NAME=bootloader
|
||||||
|
|
||||||
|
BIN=$(NAME).bin
|
||||||
|
HEX=$(NAME).hex
|
||||||
|
|
||||||
|
LISTS=lists
|
||||||
|
|
||||||
|
SRCS=$(wildcard *.s) $(wildcard *.c)
|
||||||
|
SRCS+=$(wildcard **/*.s) $(wildcard **/*.c)
|
||||||
|
OBJS+=$(patsubst %.s,%.o,$(filter %s,$(SRCS)))
|
||||||
|
OBJS+=$(patsubst %.c,%.o,$(filter %c,$(SRCS)))
|
||||||
|
|
||||||
|
# Make sure the kernel linked to correct address, no relocation!
|
||||||
|
all: $(HEX)
|
||||||
|
|
||||||
|
$(HEX): $(BIN)
|
||||||
|
objcopy --input-target=binary --output-target=verilog $(BIN) $(HEX)
|
||||||
|
|
||||||
|
$(BIN): $(OBJS)
|
||||||
|
$(CC) $(CFLAGS) $(LDFLAGS) $(OBJS) -o $@
|
||||||
|
|
||||||
|
%.o: %.c $(LISTS)
|
||||||
|
$(CC) $(CFLAGS) -l $(LISTS)/$<.list -c $< -o $@
|
||||||
|
|
||||||
|
%.o: %.s $(LISTS)
|
||||||
|
$(CC) $(CFLAGS) -l $(LISTS)/$<.list -c $< -o $@
|
||||||
|
|
||||||
|
$(LISTS):
|
||||||
|
mkdir -p $(addprefix $(LISTS)/,$(sort $(dir $(SRCS))))
|
||||||
|
|
||||||
|
.PHONY: clean
|
||||||
|
clean:
|
||||||
|
rm -rf $(OBJS) $(BIN) $(HEX) $(LISTS) $(NAME).map
|
||||||
|
|
||||||
9
sw/kernel/kernel.s
Normal file
9
sw/kernel/kernel.s
Normal file
@@ -0,0 +1,9 @@
|
|||||||
|
.segment "ENTRY"
|
||||||
|
|
||||||
|
.addr main
|
||||||
|
|
||||||
|
|
||||||
|
.code
|
||||||
|
|
||||||
|
main:
|
||||||
|
bra main
|
||||||
30
sw/kernel/link.ld
Normal file
30
sw/kernel/link.ld
Normal file
@@ -0,0 +1,30 @@
|
|||||||
|
MEMORY
|
||||||
|
{
|
||||||
|
RAM: start = $0000, size = $200;
|
||||||
|
KERNEL: start = $8000, size = $7000, file = %O;
|
||||||
|
}
|
||||||
|
|
||||||
|
SEGMENTS {
|
||||||
|
ZEROPAGE: load = RAM, type = zp, define = yes;
|
||||||
|
ENTRY: load = KERNEL, type = ro, start = $8000;
|
||||||
|
DATA: load = KERNEL, type = rw, define = yes;
|
||||||
|
CODE: load = KERNEL, type = ro;
|
||||||
|
RODATA: load = KERNEL, type = ro;
|
||||||
|
}
|
||||||
|
|
||||||
|
FEATURES {
|
||||||
|
CONDES: segment = STARTUP,
|
||||||
|
type = constructor,
|
||||||
|
label = __CONSTRUCTOR_TABLE__,
|
||||||
|
count = __CONSTRUCTOR_COUNT__;
|
||||||
|
CONDES: segment = STARTUP,
|
||||||
|
type = destructor,
|
||||||
|
label = __DESTRUCTOR_TABLE__,
|
||||||
|
count = __DESTRUCTOR_COUNT__;
|
||||||
|
}
|
||||||
|
|
||||||
|
SYMBOLS {
|
||||||
|
# Define the stack size for the application
|
||||||
|
__STACKSIZE__: value = $0200, type = weak;
|
||||||
|
__STACKSTART__: type = weak, value = $0800; # 2k stack
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user