Merge branch '93-network-processor' into 'AXI-Rewrite'

Resolve "Network Processor"

Closes #93

See merge request bslathi19/super6502!74
This commit is contained in:
Byron Lathi
2024-10-15 05:07:36 +00:00
72 changed files with 6971 additions and 215 deletions

13
.gitignore vendored
View File

@@ -17,9 +17,22 @@
*.gtkw
*debug_profile*
# Drawio temp files.
*.bkp
*.dtmp
*.mem
sim_top
# Allow sources.list specifically
!*sources.list
# Cocotb
sim_build
*.fst
__pycache__
*.vcd
*.fst.*
results.xml
html
*.pcapng

View File

@@ -7,15 +7,20 @@ stages:
build:
stage: build
when: manual
tags:
- efinity
- linux
script:
- source init_env.sh
# - source init_env.sh
- module load efinity/2024.1
- make
after_script:
- cat hw/super6502_fpga/outflow/super6502_fpga.err.log
sim:
stage: sim
needs: []
tags:
- linux
- efinity
@@ -23,3 +28,18 @@ sim:
- source init_env.sh
- make sim
ntw_sim:
stage: sim
needs: []
tags:
- linux
script:
- source init_env.sh
- cd hw/super6502_fpga/src/sub/network_processor/sim/cocotb
- make -j `nproc`
artifacts:
when: always
paths:
- hw/super6502_fpga/src/sub/network_processor/sim/cocotb/results.xml
reports:
junit: hw/super6502_fpga/src/sub/network_processor/sim/cocotb/results.xml

12
.gitmodules vendored
View File

@@ -13,3 +13,15 @@
[submodule "hw/super6502_fpga/src/sub/sdspi"]
path = hw/super6502_fpga/src/sub/sd_controller_wrapper/sdspi
url = ../sdspi.git
[submodule "hw/super6502_fpga/src/sub/verilog-ethernet"]
path = hw/super6502_fpga/src/sub/verilog-ethernet
url = ../verilog-ethernet.git
[submodule "hw/super6502_fpga/src/sub/stream_dmas"]
path = hw/super6502_fpga/src/sub/stream_dmas
url = ../stream_dmas.git
[submodule "hw/super6502_fpga/src/sub/interfaces"]
path = hw/super6502_fpga/src/sub/interfaces
url = ../interfaces.git
[submodule "hw/super6502_fpga/src/sub/my-fifos"]
path = hw/super6502_fpga/src/sub/my-fifos
url = ../my-fifos.git

View File

@@ -1,4 +1,4 @@
ROM_TARGET=test_code/sd_controller_test
ROM_TARGET=test_code/loop_test
INIT_HEX=hw/super6502_fpga/init_hex.mem
HEX=sw/$(ROM_TARGET)/$(notdir $(ROM_TARGET)).bin
@@ -26,7 +26,7 @@ $(CC65):
$(MAKE) -C sw/toolchain/cc65 -j $(shell nproc)
$(INIT_HEX): $(CC65) script/generate_rom_image.py $(HEX)
python script/generate_rom_image.py -i $(HEX) -o $@
python3 script/generate_rom_image.py -i $(HEX) -o $@
# This should get dependencies of rom, not be phony
.PHONY: $(HEX)

View File

@@ -1,3 +1,4 @@
outflow
work_*
.lock
obj_dir

View File

@@ -2,4 +2,9 @@ create_clock -period 5.00 i_sdrclk
create_clock -period 5.00 i_tACclk
create_clock -period 10.00 i_sysclk
create_clock -period 40.00 mii_rx_clk
create_clock -period 40.00 mii_tx_clk
set_clock_groups -exclusive -group {i_sysclk i_sdrclk i_tACclk} -group {mii_tx_clk} -group {mii_rx_clk}
create_generated_clock -source i_sysclk -divide_by 50 clk_cpu

View File

@@ -1,35 +1,11 @@
src/sub/interfaces/sources.list
src/rtl/super_6502_fpga.sv
src/sub/cpu_wrapper/cpu_wrapper.sv
src/sub/rtl-common/src/rtl/async_fifo.sv
src/sub/rtl-common/src/rtl/axi4_lite_ram.sv
src/sub/rtl-common/src/rtl/axi4_lite_rom.sv
src/sub/rtl-common/src/rtl/ff_cdc.sv
src/sub/rtl-common/src/rtl/shallow_async_fifo.sv
src/sub/rtl-common/src/rtl/sync_fifo.sv
src/sub/rtl-common/src/rtl/axi4_lite_to_apb4.sv
ip/sdram_controller/sdram_controller.v
src/sub/wb2axip/rtl/axilxbar.v
src/sub/wb2axip/rtl/addrdecode.v
src/sub/wb2axip/rtl/skidbuffer.v
src/sub/sd_controller_wrapper/sd_controller_wrapper.sv
src/sub/sd_controller_wrapper/shadow_regs.sv
src/sub/sd_controller_wrapper/sdspi/rtl/sdckgen.v
src/sub/sd_controller_wrapper/sdspi/rtl/sddma_rxgears.v
src/sub/sd_controller_wrapper/sdspi/rtl/sddma.v
src/sub/sd_controller_wrapper/sdspi/rtl/sdrxframe.v
src/sub/sd_controller_wrapper/sdspi/rtl/sdtxframe.v
src/sub/sd_controller_wrapper/sdspi/rtl/sddma_s2mm.v
src/sub/sd_controller_wrapper/sdspi/rtl/sddma_s2mm_axi.v
src/sub/sd_controller_wrapper/sdspi/rtl/afifo.v
src/sub/sd_controller_wrapper/sdspi/rtl/sddma_txgears.v
src/sub/sd_controller_wrapper/sdspi/rtl/sdskid.v
src/sub/sd_controller_wrapper/sdspi/rtl/sdfrontend.v
src/sub/sd_controller_wrapper/sdspi/rtl/spicmd.v
src/sub/sd_controller_wrapper/sdspi/rtl/sdaxil.v
src/sub/sd_controller_wrapper/sdspi/rtl/sddma_mm2s.v
src/sub/sd_controller_wrapper/sdspi/rtl/sddma_mm2s_axi.v
src/sub/sd_controller_wrapper/sdspi/rtl/sdio_top.v
src/sub/sd_controller_wrapper/sdspi/rtl/sdwb.v
src/sub/sd_controller_wrapper/sdspi/rtl/sdio.v
src/sub/sd_controller_wrapper/sdspi/rtl/sdcmd.v
src/sub/sd_controller_wrapper/sdspi/rtl/sdfifo.v
src/sub/cpu_wrapper/sources.list
src/sub/network_processor/sources.list
src/sub/rtl-common/sources.list
src/sub/sd_controller_wrapper/sources.list
src/sub/wb2axip/sources.list
src/sub/verilog-ethernet/sources.list
src/sub/stream_dmas/sources.list
src/sub/my-fifos/sources.list

View File

@@ -43,8 +43,26 @@ module super6502_fpga(
input i_sd_dat,
output o_sd_dat,
output o_sd_dat_oe,
output o_sd_clk
// input i_sd_cd
output o_sd_clk,
// input i_sd_cd,
//MII Interface
input wire mii_rx_clk,
input wire [3:0] mii_rxd,
input wire mii_rx_dv,
input wire mii_rx_er,
input wire mii_tx_clk,
output wire [3:0] mii_txd,
output wire mii_tx_en,
output wire mii_tx_er,
// MDIO Interface
input i_Mdi,
output o_Mdo,
output o_MdoEn,
output o_Mdc,
output phy_rstn
);
@@ -73,7 +91,9 @@ assign pre_resetn = button_resetn & vio0_resetn;
assign sdram_ready = |w_sdr_state;
assign master_resetn = pre_resetn & sdram_ready;
always_ff @(posedge i_sysclk) begin
master_resetn <= pre_resetn & sdram_ready;
end
assign o_sd_cs = '1;
@@ -193,11 +213,17 @@ logic sd_controller_dma_RREADY;
logic [DATA_WIDTH-1:0] sd_controller_dma_RDATA;
logic [1:0] sd_controller_dma_RRESP;
axil_intf ntw_reg();
axil_intf ntw_dma();
logic cpu_wrapper_reset;
always_ff @(posedge i_sysclk) cpu_wrapper_reset <= ~master_resetn;
cpu_wrapper u_cpu_wrapper_0(
.i_clk_cpu (clk_cpu),
.i_clk_100 (i_sysclk),
.i_rst (~master_resetn),
.i_rst (cpu_wrapper_reset),
.o_cpu_rst (o_cpu0_reset),
.o_cpu_rdy (o_cpu0_rdy),
@@ -237,64 +263,70 @@ cpu_wrapper u_cpu_wrapper_0(
.i_nmi('0)
);
logic crossbar_resetn;
always_ff @(posedge i_sysclk) crossbar_resetn <= master_resetn;
axilxbar #(
.NM(2),
.NS(4),
.NM(3),
.NS(5),
.SLAVE_ADDR({
{32'h000001ff, 32'h00000000},
{32'h0000ffff, 32'h0000f000},
{32'h0000dfff, 32'h00000200},
{32'h0000e03f, 32'h0000e000}
{32'h0000e03f, 32'h0000e000},
{32'h0000e3ff, 32'h0000e200}
})
) u_crossbar (
.S_AXI_ACLK (i_sysclk),
.S_AXI_ARESETN (master_resetn),
.S_AXI_ARESETN (crossbar_resetn),
.S_AXI_ARADDR ({cpu0_ARADDR, sd_controller_dma_ARADDR }),
.S_AXI_ARVALID ({cpu0_ARVALID, sd_controller_dma_ARVALID }),
.S_AXI_ARREADY ({cpu0_ARREADY, sd_controller_dma_ARREADY }),
.S_AXI_RDATA ({cpu0_RDATA, sd_controller_dma_RDATA }),
.S_AXI_RRESP ({cpu0_RRESP, sd_controller_dma_RRESP }),
.S_AXI_RVALID ({cpu0_RVALID, sd_controller_dma_RVALID }),
.S_AXI_RREADY ({cpu0_RREADY, sd_controller_dma_RREADY }),
.S_AXI_AWADDR ({cpu0_AWADDR, sd_controller_dma_AWADDR }),
.S_AXI_AWREADY ({cpu0_AWREADY, sd_controller_dma_AWREADY }),
.S_AXI_AWVALID ({cpu0_AWVALID, sd_controller_dma_AWVALID }),
.S_AXI_WVALID ({cpu0_WVALID, sd_controller_dma_WVALID }),
.S_AXI_WREADY ({cpu0_WREADY, sd_controller_dma_WREADY }),
.S_AXI_WDATA ({cpu0_WDATA, sd_controller_dma_WDATA }),
.S_AXI_WSTRB ({cpu0_WSTRB, sd_controller_dma_WSTRB }),
.S_AXI_BRESP ({cpu0_BRESP, sd_controller_dma_BRESP }),
.S_AXI_BVALID ({cpu0_BVALID, sd_controller_dma_BVALID }),
.S_AXI_BREADY ({cpu0_BREADY, sd_controller_dma_BREADY }),
.M_AXI_ARADDR ({ram_araddr, rom_araddr, sdram_ARADDR, sd_controller_ctrl_ARADDR }),
.M_AXI_ARVALID ({ram_arvalid, rom_arvalid, sdram_ARVALID, sd_controller_ctrl_ARVALID }),
.M_AXI_ARREADY ({ram_arready, rom_arready, sdram_ARREADY, sd_controller_ctrl_ARREADY }),
.M_AXI_RDATA ({ram_rdata, rom_rdata, sdram_RDATA, sd_controller_ctrl_RDATA }),
.M_AXI_RRESP ({ram_rresp, rom_rresp, sdram_RRESP, sd_controller_ctrl_RRESP }),
.M_AXI_RVALID ({ram_rvalid, rom_rvalid, sdram_RVALID, sd_controller_ctrl_RVALID }),
.M_AXI_RREADY ({ram_rready, rom_rready, sdram_RREADY, sd_controller_ctrl_RREADY }),
.M_AXI_AWADDR ({ram_awaddr, rom_awaddr, sdram_AWADDR, sd_controller_ctrl_AWADDR }),
.M_AXI_AWVALID ({ram_awvalid, rom_awvalid, sdram_AWVALID, sd_controller_ctrl_AWVALID }),
.M_AXI_AWREADY ({ram_awready, rom_awready, sdram_AWREADY, sd_controller_ctrl_AWREADY }),
.M_AXI_WDATA ({ram_wdata, rom_wdata, sdram_WDATA, sd_controller_ctrl_WDATA }),
.M_AXI_WVALID ({ram_wvalid, rom_wvalid, sdram_WVALID, sd_controller_ctrl_WVALID }),
.M_AXI_WREADY ({ram_wready, rom_wready, sdram_WREADY, sd_controller_ctrl_WREADY }),
.M_AXI_WSTRB ({ram_wstrb, rom_wstrb, sdram_WSTRB, sd_controller_ctrl_WSTRB }),
.M_AXI_BRESP ({ram_bresp, rom_bresp, sdram_BRESP, sd_controller_ctrl_BRESP }),
.M_AXI_BVALID ({ram_bvalid, rom_bvalid, sdram_BVALID, sd_controller_ctrl_BVALID }),
.M_AXI_BREADY ({ram_bready, rom_bready, sdram_BREADY, sd_controller_ctrl_BREADY })
.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_ARREADY ({cpu0_ARREADY, sd_controller_dma_ARREADY, ntw_dma.arready }),
.S_AXI_RDATA ({cpu0_RDATA, sd_controller_dma_RDATA, ntw_dma.rdata }),
.S_AXI_RRESP ({cpu0_RRESP, sd_controller_dma_RRESP, ntw_dma.rresp }),
.S_AXI_RVALID ({cpu0_RVALID, sd_controller_dma_RVALID, ntw_dma.rvalid }),
.S_AXI_RREADY ({cpu0_RREADY, sd_controller_dma_RREADY, ntw_dma.rready }),
.S_AXI_AWADDR ({cpu0_AWADDR, sd_controller_dma_AWADDR, ntw_dma.awaddr }),
.S_AXI_AWVALID ({cpu0_AWVALID, sd_controller_dma_AWVALID, ntw_dma.awvalid }),
.S_AXI_AWREADY ({cpu0_AWREADY, sd_controller_dma_AWREADY, ntw_dma.awready }),
.S_AXI_WVALID ({cpu0_WVALID, sd_controller_dma_WVALID, ntw_dma.wvalid }),
.S_AXI_WDATA ({cpu0_WDATA, sd_controller_dma_WDATA, ntw_dma.wdata }),
.S_AXI_WREADY ({cpu0_WREADY, sd_controller_dma_WREADY, ntw_dma.wready }),
.S_AXI_WSTRB ({cpu0_WSTRB, sd_controller_dma_WSTRB, ntw_dma.wstrb }),
.S_AXI_BRESP ({cpu0_BRESP, sd_controller_dma_BRESP, ntw_dma.bresp }),
.S_AXI_BVALID ({cpu0_BVALID, sd_controller_dma_BVALID, ntw_dma.bvalid }),
.S_AXI_BREADY ({cpu0_BREADY, sd_controller_dma_BREADY, ntw_dma.bready }),
.M_AXI_ARADDR ({ram_araddr, rom_araddr, sdram_ARADDR, sd_controller_ctrl_ARADDR, ntw_reg.araddr }),
.M_AXI_ARVALID ({ram_arvalid, rom_arvalid, sdram_ARVALID, sd_controller_ctrl_ARVALID, ntw_reg.arvalid }),
.M_AXI_ARREADY ({ram_arready, rom_arready, sdram_ARREADY, sd_controller_ctrl_ARREADY, ntw_reg.arready }),
.M_AXI_RDATA ({ram_rdata, rom_rdata, sdram_RDATA, sd_controller_ctrl_RDATA, ntw_reg.rdata }),
.M_AXI_RRESP ({ram_rresp, rom_rresp, sdram_RRESP, sd_controller_ctrl_RRESP, ntw_reg.rresp }),
.M_AXI_RVALID ({ram_rvalid, rom_rvalid, sdram_RVALID, sd_controller_ctrl_RVALID, ntw_reg.rvalid }),
.M_AXI_RREADY ({ram_rready, rom_rready, sdram_RREADY, sd_controller_ctrl_RREADY, ntw_reg.rready }),
.M_AXI_AWADDR ({ram_awaddr, rom_awaddr, sdram_AWADDR, sd_controller_ctrl_AWADDR, ntw_reg.awaddr }),
.M_AXI_AWVALID ({ram_awvalid, rom_awvalid, sdram_AWVALID, sd_controller_ctrl_AWVALID, ntw_reg.awvalid }),
.M_AXI_AWREADY ({ram_awready, rom_awready, sdram_AWREADY, sd_controller_ctrl_AWREADY, ntw_reg.awready }),
.M_AXI_WDATA ({ram_wdata, rom_wdata, sdram_WDATA, sd_controller_ctrl_WDATA, ntw_reg.wdata }),
.M_AXI_WVALID ({ram_wvalid, rom_wvalid, sdram_WVALID, sd_controller_ctrl_WVALID, ntw_reg.wvalid }),
.M_AXI_WREADY ({ram_wready, rom_wready, sdram_WREADY, sd_controller_ctrl_WREADY, ntw_reg.wready }),
.M_AXI_WSTRB ({ram_wstrb, rom_wstrb, sdram_WSTRB, sd_controller_ctrl_WSTRB, ntw_reg.wstrb }),
.M_AXI_BRESP ({ram_bresp, rom_bresp, sdram_BRESP, sd_controller_ctrl_BRESP, ntw_reg.bresp }),
.M_AXI_BVALID ({ram_bvalid, rom_bvalid, sdram_BVALID, sd_controller_ctrl_BVALID, ntw_reg.bvalid }),
.M_AXI_BREADY ({ram_bready, rom_bready, sdram_BREADY, sd_controller_ctrl_BREADY, ntw_reg.bready })
);
logic rom_reset;
always_ff @(posedge i_sysclk) rom_reset <= ~master_resetn;
axi4_lite_rom #(
.ROM_SIZE(12),
.BASE_ADDRESS(32'h0000f000),
.ROM_INIT_FILE("init_hex.mem")
) u_rom (
.i_clk(i_sysclk),
.i_rst(~master_resetn),
.i_rst(rom_reset),
.o_AWREADY(rom_awready),
.o_WREADY(rom_wready),
@@ -322,12 +354,15 @@ axi4_lite_rom #(
.i_WSTRB(rom_wstrb)
);
logic ram_reset;
always_ff @(posedge i_sysclk) ram_reset <= ~master_resetn;
axi4_lite_ram #(
.RAM_SIZE(9),
.ZERO_INIT(1)
) u_ram(
.i_clk(i_sysclk),
.i_rst(~master_resetn),
.i_rst(ram_reset),
.o_AWREADY(ram_awready),
.o_WREADY(ram_wready),
@@ -430,12 +465,15 @@ sdram_controller u_sdram_controller(
logic sd_irq;
logic sd_controller_wrapper_reset;
always_ff @(posedge i_sysclk) sd_controller_wrapper_reset <= ~master_resetn;
sd_controller_wrapper #(
.NUMIO (1), // board as it stands is in 1 bit mode
.BASE_ADDRESS (32'h0000E000)
) u_sdio_top (
.i_clk (i_sysclk),
.i_reset (~master_resetn),
.i_reset (sd_controller_wrapper_reset),
.S_AXIL_AWVALID (sd_controller_ctrl_AWVALID),
.S_AXIL_AWREADY (sd_controller_ctrl_AWREADY),
@@ -484,4 +522,33 @@ sd_controller_wrapper #(
.o_int (sd_irq)
);
endmodule
logic network_processor_reset;
always_ff @(posedge i_sysclk) network_processor_reset <= ~master_resetn;
network_processor #(
.NUM_TCP(2)
) u_network_processor (
.i_clk (i_sysclk),
.i_rst (network_processor_reset),
.s_reg_axil (ntw_reg),
.m_dma_axil (ntw_dma),
.mii_rx_clk (mii_rx_clk),
.mii_rxd (mii_rxd),
.mii_rx_dv (mii_rx_dv),
.mii_rx_er (mii_rx_er),
.mii_tx_clk (mii_tx_clk),
.mii_txd (mii_txd),
.mii_tx_en (mii_tx_en),
.mii_tx_er (mii_tx_er),
.i_Mdi (i_Mdi),
.o_Mdo (o_Mdo),
.o_MdoEn (o_MdoEn),
.o_Mdc (o_Mdc),
.phy_rstn (phy_rstn)
);
endmodule

View File

@@ -1,25 +1,34 @@
FPGA_SRCS_LIST=../../sources.list
SIM_SRCS_LIST=sources.list
BAD_SOURCES_LIST=stubs.list
SUPER6502_FPGA_SOURCES=$(foreach file, $(shell cat $(FPGA_SRCS_LIST)), ../../$(file))
SUPER6502_FPGA_SOURCES=$(shell rtl-manifest $(FPGA_SRCS_LIST))
BAD_SOURCES=$(shell rtl-manifest $(BAD_SOURCES_LIST))
GOOD_FPGA_SOURCES=$(filter-out $(BAD_SOURCES), $(SUPER6502_FPGA_SOURCES))
SIM_SOURCES=$(shell cat $(SIM_SRCS_LIST))
INCLUDE=include/sdram_controller_define.vh
TB_NAME=sim_top
TB_NAME=./obj_dir/Vsim_top
COPY_FILES=addr_map.mem init_hex.mem
SD_IMAGE=sd_image.bin
FLAGS=-DSIM -DRTL_SIM -DVERILATOR -DSDIO_AXI
# IVERILOG=$(REPO_TOP)/../iverilog/local/bin/iverilog -v
IVERILOG=iverilog
all: waves
waves: $(TB_NAME)
./$(TB_NAME) -fst
# ./$(TB_NAME) -fst
./obj_dir/Vsim_top
$(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 ../../
verilator --binary $(FLAGS) $(INCLUDE) $(GOOD_FPGA_SOURCES) $(SIM_SOURCES) +incdir+../../ -Wno-BLKANDNBLK -Wno-fatal -j 16 --top sim_top --trace-fst -Wno-ASSIGNDLY
$(SD_IMAGE):
dd if=/dev/urandom bs=1 count=65536 of=$(SD_IMAGE)
@@ -34,3 +43,4 @@ clean:
rm -rf $(COPY_FILES)
rm -rf $(TB_NAME)
rm -rf sim_top.vcd
rm -rf obj_dir

View File

@@ -0,0 +1,105 @@
module sdram_controller (
input i_aresetn,
input i_sysclk,
input i_sdrclk,
input i_tACclk,
output o_pll_reset,
input i_pll_locked,
output o_sdr_state,
input i_AXI4_AWVALID,
output o_AXI4_AWREADY,
input [23:0] i_AXI4_AWADDR,
input i_AXI4_WVALID,
output o_AXI4_WREADY,
input [31:0] i_AXI4_WDATA,
input [3:0] i_AXI4_WSTRB,
output o_AXI4_BVALID,
input i_AXI4_BREADY,
input i_AXI4_ARVALID,
output o_AXI4_ARREADY,
input [23:0] i_AXI4_ARADDR,
output o_AXI4_RVALID,
input i_AXI4_RREADY,
output [31:0] o_AXI4_RDATA,
input i_AXI4_WLAST,
output o_AXI4_RLAST,
input [3:0] i_AXI4_AWID,
input [2:0] i_AXI4_AWSIZE,
input [3:0] i_AXI4_ARID,
input [7:0] i_AXI4_ARLEN,
input [2:0] i_AXI4_ARSIZE,
input [1:0] i_AXI4_ARBURST,
input [7:0] i_AXI4_AWLEN,
output [3:0] o_AXI4_RID,
output [3:0] o_AXI4_BID,
output [1:0] o_sdr_CKE,
output [1:0] o_sdr_n_CS,
output [1:0] o_sdr_n_RAS,
output [1:0] o_sdr_n_CAS,
output [1:0] o_sdr_n_WE,
output [3:0] o_sdr_BA,
output [25:0] o_sdr_ADDR,
output [31:0] o_sdr_DATA,
output [31:0] o_sdr_DATA_oe,
input [31:0] i_sdr_DATA,
output [3:0] o_sdr_DQM
);
assign o_sdr_state = '1;
assign o_AXI4_RLAST = '0;
assign o_AXI4_RID = '0;
assign o_AXI4_BID = '0;
assign o_sdr_CKE = '0;
assign o_sdr_n_CS = '0;
assign o_sdr_n_RAS = '0;
assign o_sdr_n_CAS = '0;
assign o_sdr_n_WE = '0;
assign o_sdr_BA = '0;
assign o_sdr_ADDR = '0;
assign o_sdr_DATA = '0;
assign o_sdr_DATA_oe = '0;
assign o_sdr_DQM = '0;
axi4_lite_ram #(
.RAM_SIZE(25),
.ZERO_INIT(1)
) u_sdram_emu (
.i_clk(i_sysclk),
.i_rst(~i_aresetn),
.o_AWREADY(o_AXI4_AWREADY),
.o_WREADY(o_AXI4_WREADY),
.o_BVALID(o_AXI4_BVALID),
.i_BREADY(i_AXI4_BREADY),
.o_BRESP(o_BRESP),
.i_ARVALID(i_AXI4_ARVALID),
.o_ARREADY(o_AXI4_ARREADY),
.i_ARADDR(i_AXI4_ARADDR),
.i_ARPROT('0),
.o_RVALID(o_AXI4_RVALID),
.i_RREADY(i_AXI4_RREADY),
.o_RDATA(o_AXI4_RDATA),
.o_RRESP(o_AXI4_RRESP),
.i_AWVALID(i_AXI4_AWVALID),
.i_AWADDR(i_AXI4_AWADDR),
.i_AWPROT('0),
.i_WVALID(i_AXI4_WVALID),
.i_WDATA(i_AXI4_WDATA),
.i_WSTRB(i_AXI4_WSTRB)
);
endmodule

View File

@@ -87,6 +87,7 @@ logic [DQ_GROUP -1:0] w_sdr_DQM;
wire [DQ_GROUP *DQ_WIDTH -1:0] w_sdr_DQ;
// ^ Has to be wire because of tristate/inout stuff
/*
genvar i, j;
generate
for (i=0; i<DQ_GROUP*DQ_WIDTH; i=i+1)
@@ -111,7 +112,7 @@ generate
);
end
endgenerate
*/
// potential sd card sim here?
@@ -179,13 +180,15 @@ IOBUF dat_buf (
.IO(w_sd_dat)
);
wire [2:0] w_sd_dat_unused;
mdl_sdio #(
.LGMEMSZ(16),
.MEMFILE("sd_image.bin")
) u_sd_card_emu (
.sd_clk(o_sd_clk),
.sd_cmd(w_sd_cmd),
.sd_dat(w_sd_dat)
.sd_dat({w_sd_dat_unused, w_sd_dat})
);
initial begin
@@ -198,4 +201,4 @@ initial begin
$finish();
end
endmodule
endmodule

View File

@@ -1,9 +1,9 @@
hvl/sim_top.sv
sub/verilog-6502/ALU.v
sub/verilog-6502/cpu_65c02.v
sub/sim_sdram/generic_sdr.v
hvl/sdram_sram.sv
../sub/sd_controller_wrapper/sdspi/bench/verilog/mdl_sdio.v
../sub/sd_controller_wrapper/sdspi/bench/verilog/mdl_sdcmd.v
../sub/sd_controller_wrapper/sdspi/bench/verilog/mdl_sdrx.v
../sub/sd_controller_wrapper/sdspi/bench/verilog/mdl_sdtx.v
../sub/sd_controller_wrapper/sdspi/bench/verilog/IOBUF.v
../sub/sd_controller_wrapper/sdspi/bench/verilog/IOBUF.v

View File

View File

@@ -1127,19 +1127,19 @@ parameter mem_sizes = 2**(ROW_BITS+COL_BITS) - 1;
tCMS = 1.5, // CS#, RAS#, CAS#, WE#, DQM# Setup Time
tDH = 0.8, // Data-in Hold Time
tDS = 1.5; // Data-in Setup Time
$width (posedge Clk, tCH);
$width (negedge Clk, tCL);
$period (negedge Clk, tCK3);
$period (posedge Clk, tCK3);
$setuphold(posedge Clk, Cke, tCKS, tCKH);
$setuphold(posedge Clk, Cs_n, tCMS, tCMH);
$setuphold(posedge Clk, Cas_n, tCMS, tCMH);
$setuphold(posedge Clk, Ras_n, tCMS, tCMH);
$setuphold(posedge Clk, We_n, tCMS, tCMH);
$setuphold(posedge Clk, Addr, tAS, tAH);
$setuphold(posedge Clk, Ba, tAS, tAH);
$setuphold(posedge Clk, Dqm, tCMS, tCMH);
$setuphold(posedge Dq_chk, Dq, tDS, tDH);
// $width (posedge Clk, tCH);
// $width (negedge Clk, tCL);
// $period (negedge Clk, tCK3);
// $period (posedge Clk, tCK3);
// $setuphold(posedge Clk, Cke, tCKS, tCKH);
// $setuphold(posedge Clk, Cs_n, tCMS, tCMH);
// $setuphold(posedge Clk, Cas_n, tCMS, tCMH);
// $setuphold(posedge Clk, Ras_n, tCMS, tCMH);
// $setuphold(posedge Clk, We_n, tCMS, tCMH);
// $setuphold(posedge Clk, Addr, tAS, tAH);
// $setuphold(posedge Clk, Ba, tAS, tAH);
// $setuphold(posedge Clk, Dqm, tCMS, tCMH);
// $setuphold(posedge Dq_chk, Dq, tDS, tDH);
endspecify
endmodule

View File

@@ -0,0 +1,106 @@
/**************************************************************************
*
* File Name: sdr.v
* Version: 2.2
* Date: October 12th, 2010
* Model: BUS Functional
* Simulator: Model Technology
*
* Dependencies: None
*
* Email: modelsupport@micron.com
* Company: Micron Technology, Inc.
*
* Description: Micron SDRAM Verilog model
*
* Limitation: - Doesn't check for refresh timing
*
* Note: - Set simulator resolution to "ps" accuracy
* - Set Debug = 0 to disable $display messages
*
* Disclaimer: THESE DESIGNS ARE PROVIDED "AS IS" WITH NO WARRANTY
* WHATSOEVER AND MICRON SPECIFICALLY DISCLAIMS ANY
* IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR
* A PARTICULAR PURPOSE, OR AGAINST INFRINGEMENT.
*
* Copyright <EFBFBD> 2001 Micron Semiconductor Products, Inc.
* All rights researved
*
* Rev Author Date Changes
* --- -------------------------- ---------------------------------------
* 2.3 SH 05/12/2016 - Update tAC, tHZ timing
* Micron Technology Inc.
*
* 2.2 SH 10/12/2010 - Combine all parts into sdr_parameters.vh
* Micron Technology Inc.
*
* 2.1 SH 06/06/2002 - Typo in bank multiplex
* Micron Technology Inc.
*
* 2.0 SH 04/30/2002 - Second release
* Micron Technology Inc.
*
**************************************************************************/
`timescale 1ns / 1ps
`define x8
`define CLK_200
`define SYS_CLK_100
module generic_sdr (Dq, Addr, Ba, Clk, Cke, Cs_n, Ras_n, Cas_n, We_n, Dqm);
`include "include/sdram_controller_define.vh"
parameter tCK = 1000/fCK_MHz; // tCK ns Nominal Clock Cycle Time
`ifdef CLK_200
parameter real tAC3 = 4.5; // tAC3 ns Access time from CLK (pos edge) CL = 3
parameter real tAC2 = 4.5; // tAC2 ns Access time from CLK (pos edge) CL = 2
parameter real tAC1 = 4.5; // tAC1 ns Parameter definition for compilation - CL = 1 illegal for sg75
`elsif CLK_166
parameter real tAC3 = 5.4; // tAC3 ns Access time from CLK (pos edge) CL = 3
parameter real tAC2 = 5.4; // tAC2 ns Access time from CLK (pos edge) CL = 2
parameter real tAC1 = 5.4; // tAC1 ns Parameter definition for compilation - CL = 1 illegal for sg75
`elsif CLK_133
parameter real tAC3 = 6.0; // tAC3 ns Access time from CLK (pos edge) CL = 3
parameter real tAC2 = 6.0; // tAC2 ns Access time from CLK (pos edge) CL = 2
parameter real tAC1 = 6.0; // tAC1 ns Parameter definition for compilation - CL = 1 illegal for sg75
`endif
`ifdef CLK_200
parameter real tHZ3 = 4.5; // tHZ3 ns Data Out High Z time - CL = 3
parameter real tHZ2 = 4.5; // tHZ2 ns Data Out High Z time - CL = 2
parameter real tHZ1 = 4.5; // tHZ1 ns Parameter definition for compilation - CL = 1 illegal for sg75
`elsif CLK_166
parameter real tHZ3 = 5.4; // tHZ3 ns Data Out High Z time - CL = 3
parameter real tHZ2 = 5.4; // tHZ2 ns Data Out High Z time - CL = 2
parameter real tHZ1 = 5.4; // tHZ1 ns Parameter definition for compilation - CL = 1 illegal for sg75
`elsif CLK_133
parameter real tHZ3 = 6.0; // tHZ3 ns Data Out High Z time - CL = 3
parameter real tHZ2 = 6.0; // tHZ2 ns Data Out High Z time - CL = 2
parameter real tHZ1 = 6.0; // tHZ1 ns Parameter definition for compilation - CL = 1 illegal for sg75
`endif
parameter tOH = 2.7; // tOH ns Data Out Hold time
parameter tRRD = 2.0; // tRRD tCK Active bank a to Active bank b command time (2 * tCK)
parameter tWRa = tCK; // tWR ns Write recovery time (auto-precharge mode - must add 1 CLK)
parameter tWRm = 2*tCK; // tWR ns Write recovery time
parameter ADDR_BITS = ROW_WIDTH; // Set this parameter to control how many Address bits are used
parameter ROW_BITS = ROW_WIDTH; // Set this parameter to control how many Row bits are used
parameter COL_BITS = COL_WIDTH; // Set this parameter to control how many Column bits are used
parameter DQ_BITS = DQ_WIDTH; // Set this parameter to control how many Data bits are used
parameter DM_BITS = 1; // Set this parameter to control how many DM bits are used
parameter BA_BITS = BA_WIDTH; // Bank bits
parameter mem_sizes = 2**(ROW_BITS+COL_BITS) - 1;
input Clk;
input Cke;
input Cs_n;
input Ras_n;
input Cas_n;
input We_n;
input [ADDR_BITS - 1 : 0] Addr;
input [BA_BITS - 1 : 0] Ba;
inout [DQ_BITS - 1 : 0] Dq;
input [DM_BITS - 1 : 0] Dqm;
endmodule

View File

@@ -0,0 +1 @@
cpu_wrapper.sv

View File

@@ -0,0 +1,164 @@
<mxfile host="Electron" modified="2024-08-20T05:13:27.279Z" agent="Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) draw.io/21.2.8 Chrome/112.0.5615.165 Electron/24.2.0 Safari/537.36" etag="ixB1A9XLpoNPfgontKOY" version="21.2.8" type="device">
<diagram name="Page-1" id="6PukHK6WJVPqU_tSf8UC">
<mxGraphModel dx="708" dy="486" grid="1" gridSize="10" guides="1" tooltips="1" connect="1" arrows="1" fold="1" page="1" pageScale="1" pageWidth="850" pageHeight="1100" math="0" shadow="0">
<root>
<mxCell id="0" />
<mxCell id="1" parent="0" />
<mxCell id="xWUiTusR7ZZWym1XTSiP-26" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;exitX=1;exitY=0.25;exitDx=0;exitDy=0;entryX=0.25;entryY=1;entryDx=0;entryDy=0;fillColor=#fa6800;strokeColor=#C73500;" edge="1" parent="1" source="xWUiTusR7ZZWym1XTSiP-2" target="xWUiTusR7ZZWym1XTSiP-20">
<mxGeometry relative="1" as="geometry" />
</mxCell>
<mxCell id="xWUiTusR7ZZWym1XTSiP-2" value="TCP" style="rounded=0;whiteSpace=wrap;html=1;" vertex="1" parent="1">
<mxGeometry x="560" y="360" width="160" height="80" as="geometry" />
</mxCell>
<mxCell id="xWUiTusR7ZZWym1XTSiP-6" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;entryX=0;entryY=0.5;entryDx=0;entryDy=0;fillColor=#d80073;strokeColor=#A50040;startArrow=classic;startFill=1;" edge="1" parent="1" source="xWUiTusR7ZZWym1XTSiP-3" target="xWUiTusR7ZZWym1XTSiP-4">
<mxGeometry relative="1" as="geometry" />
</mxCell>
<mxCell id="xWUiTusR7ZZWym1XTSiP-7" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;exitX=0.75;exitY=1;exitDx=0;exitDy=0;entryX=0;entryY=0.5;entryDx=0;entryDy=0;fillColor=#d80073;strokeColor=#A50040;startArrow=classic;startFill=1;" edge="1" parent="1" source="xWUiTusR7ZZWym1XTSiP-3" target="xWUiTusR7ZZWym1XTSiP-2">
<mxGeometry relative="1" as="geometry" />
</mxCell>
<mxCell id="xWUiTusR7ZZWym1XTSiP-9" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;exitX=0.25;exitY=1;exitDx=0;exitDy=0;entryX=0;entryY=0.5;entryDx=0;entryDy=0;fillColor=#d80073;strokeColor=#A50040;startArrow=classic;startFill=1;" edge="1" parent="1" source="xWUiTusR7ZZWym1XTSiP-3" target="xWUiTusR7ZZWym1XTSiP-5">
<mxGeometry relative="1" as="geometry" />
</mxCell>
<mxCell id="xWUiTusR7ZZWym1XTSiP-3" value="axi4 xbar" style="shape=trapezoid;perimeter=trapezoidPerimeter;whiteSpace=wrap;html=1;fixedSize=1;rotation=-90;" vertex="1" parent="1">
<mxGeometry x="360" y="500" width="120" height="40" as="geometry" />
</mxCell>
<mxCell id="xWUiTusR7ZZWym1XTSiP-32" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;exitX=1;exitY=0.25;exitDx=0;exitDy=0;entryX=0.5;entryY=1;entryDx=0;entryDy=0;fillColor=#fa6800;strokeColor=#C73500;" edge="1" parent="1" source="xWUiTusR7ZZWym1XTSiP-4" target="xWUiTusR7ZZWym1XTSiP-20">
<mxGeometry relative="1" as="geometry">
<Array as="points">
<mxPoint x="750" y="500" />
<mxPoint x="750" y="410" />
</Array>
</mxGeometry>
</mxCell>
<mxCell id="xWUiTusR7ZZWym1XTSiP-4" value="UDP" style="rounded=0;whiteSpace=wrap;html=1;" vertex="1" parent="1">
<mxGeometry x="560" y="480" width="160" height="80" as="geometry" />
</mxCell>
<mxCell id="xWUiTusR7ZZWym1XTSiP-33" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;exitX=1;exitY=0.25;exitDx=0;exitDy=0;entryX=0.75;entryY=1;entryDx=0;entryDy=0;fillColor=#fa6800;strokeColor=#C73500;" edge="1" parent="1" source="xWUiTusR7ZZWym1XTSiP-5" target="xWUiTusR7ZZWym1XTSiP-20">
<mxGeometry relative="1" as="geometry">
<Array as="points">
<mxPoint x="760" y="620" />
<mxPoint x="760" y="440" />
</Array>
</mxGeometry>
</mxCell>
<mxCell id="xWUiTusR7ZZWym1XTSiP-5" value="Other IP Type" style="rounded=0;whiteSpace=wrap;html=1;" vertex="1" parent="1">
<mxGeometry x="560" y="600" width="160" height="80" as="geometry" />
</mxCell>
<mxCell id="xWUiTusR7ZZWym1XTSiP-62" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;exitX=0;exitY=0.75;exitDx=0;exitDy=0;entryX=1;entryY=0.5;entryDx=0;entryDy=0;fillColor=#e3c800;strokeColor=#B09500;" edge="1" parent="1" source="xWUiTusR7ZZWym1XTSiP-10" target="xWUiTusR7ZZWym1XTSiP-54">
<mxGeometry relative="1" as="geometry" />
</mxCell>
<mxCell id="xWUiTusR7ZZWym1XTSiP-10" value="MAC" style="whiteSpace=wrap;html=1;aspect=fixed;" vertex="1" parent="1">
<mxGeometry x="1160" y="480" width="80" height="80" as="geometry" />
</mxCell>
<mxCell id="xWUiTusR7ZZWym1XTSiP-24" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;exitX=0;exitY=0.75;exitDx=0;exitDy=0;entryX=0.5;entryY=0;entryDx=0;entryDy=0;fillColor=#fa6800;strokeColor=#C73500;" edge="1" parent="1" source="xWUiTusR7ZZWym1XTSiP-15" target="xWUiTusR7ZZWym1XTSiP-21">
<mxGeometry relative="1" as="geometry" />
</mxCell>
<mxCell id="xWUiTusR7ZZWym1XTSiP-15" value="IP" style="rounded=0;whiteSpace=wrap;html=1;" vertex="1" parent="1">
<mxGeometry x="920" y="480" width="80" height="80" as="geometry" />
</mxCell>
<mxCell id="xWUiTusR7ZZWym1XTSiP-23" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;entryX=0;entryY=0.25;entryDx=0;entryDy=0;fillColor=#fa6800;strokeColor=#C73500;" edge="1" parent="1" source="xWUiTusR7ZZWym1XTSiP-20" target="xWUiTusR7ZZWym1XTSiP-15">
<mxGeometry relative="1" as="geometry" />
</mxCell>
<mxCell id="xWUiTusR7ZZWym1XTSiP-20" value="ip arb" style="shape=trapezoid;perimeter=trapezoidPerimeter;whiteSpace=wrap;html=1;fixedSize=1;rotation=90;" vertex="1" parent="1">
<mxGeometry x="800" y="390" width="120" height="40" as="geometry" />
</mxCell>
<mxCell id="xWUiTusR7ZZWym1XTSiP-27" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;exitX=0.75;exitY=1;exitDx=0;exitDy=0;entryX=1;entryY=0.75;entryDx=0;entryDy=0;fillColor=#fa6800;strokeColor=#C73500;" edge="1" parent="1" source="xWUiTusR7ZZWym1XTSiP-21" target="xWUiTusR7ZZWym1XTSiP-5">
<mxGeometry relative="1" as="geometry" />
</mxCell>
<mxCell id="xWUiTusR7ZZWym1XTSiP-28" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;exitX=0.25;exitY=1;exitDx=0;exitDy=0;entryX=1;entryY=0.75;entryDx=0;entryDy=0;fillColor=#fa6800;strokeColor=#C73500;" edge="1" parent="1" source="xWUiTusR7ZZWym1XTSiP-21" target="xWUiTusR7ZZWym1XTSiP-2">
<mxGeometry relative="1" as="geometry">
<Array as="points">
<mxPoint x="810" y="600" />
<mxPoint x="810" y="420" />
</Array>
</mxGeometry>
</mxCell>
<mxCell id="xWUiTusR7ZZWym1XTSiP-31" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;entryX=1;entryY=0.75;entryDx=0;entryDy=0;exitX=0.5;exitY=1;exitDx=0;exitDy=0;fillColor=#fa6800;strokeColor=#C73500;" edge="1" parent="1" source="xWUiTusR7ZZWym1XTSiP-21" target="xWUiTusR7ZZWym1XTSiP-4">
<mxGeometry relative="1" as="geometry">
<Array as="points">
<mxPoint x="800" y="630" />
<mxPoint x="800" y="540" />
</Array>
</mxGeometry>
</mxCell>
<mxCell id="xWUiTusR7ZZWym1XTSiP-21" value="ip demux" style="shape=trapezoid;perimeter=trapezoidPerimeter;whiteSpace=wrap;html=1;fixedSize=1;rotation=90;" vertex="1" parent="1">
<mxGeometry x="800" y="610" width="120" height="40" as="geometry" />
</mxCell>
<mxCell id="xWUiTusR7ZZWym1XTSiP-58" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;entryX=0;entryY=0.5;entryDx=0;entryDy=0;fillColor=#008a00;strokeColor=#005700;exitX=1;exitY=0.25;exitDx=0;exitDy=0;" edge="1" parent="1" source="xWUiTusR7ZZWym1XTSiP-15" target="xWUiTusR7ZZWym1XTSiP-53">
<mxGeometry relative="1" as="geometry">
<mxPoint x="1120" y="500" as="sourcePoint" />
</mxGeometry>
</mxCell>
<mxCell id="xWUiTusR7ZZWym1XTSiP-43" value="" style="endArrow=classic;html=1;rounded=0;fillColor=#d80073;strokeColor=#A50040;" edge="1" parent="1">
<mxGeometry width="50" height="50" relative="1" as="geometry">
<mxPoint x="560" y="760" as="sourcePoint" />
<mxPoint x="640.03" y="760" as="targetPoint" />
</mxGeometry>
</mxCell>
<mxCell id="xWUiTusR7ZZWym1XTSiP-44" value="axi4-lite" style="edgeLabel;html=1;align=center;verticalAlign=middle;resizable=0;points=[];" vertex="1" connectable="0" parent="xWUiTusR7ZZWym1XTSiP-43">
<mxGeometry x="0.2037" y="2" relative="1" as="geometry">
<mxPoint x="-8" y="-8" as="offset" />
</mxGeometry>
</mxCell>
<mxCell id="xWUiTusR7ZZWym1XTSiP-45" value="" style="endArrow=classic;html=1;rounded=0;fillColor=#e3c800;strokeColor=#B09500;" edge="1" parent="1">
<mxGeometry width="50" height="50" relative="1" as="geometry">
<mxPoint x="680" y="760" as="sourcePoint" />
<mxPoint x="760.03" y="760" as="targetPoint" />
</mxGeometry>
</mxCell>
<mxCell id="xWUiTusR7ZZWym1XTSiP-46" value="axi4-stream" style="edgeLabel;html=1;align=center;verticalAlign=middle;resizable=0;points=[];" vertex="1" connectable="0" parent="xWUiTusR7ZZWym1XTSiP-45">
<mxGeometry x="0.2037" y="2" relative="1" as="geometry">
<mxPoint x="-8" y="-8" as="offset" />
</mxGeometry>
</mxCell>
<mxCell id="xWUiTusR7ZZWym1XTSiP-47" value="" style="endArrow=classic;html=1;rounded=0;fillColor=#0050ef;strokeColor=#001DBC;" edge="1" parent="1">
<mxGeometry width="50" height="50" relative="1" as="geometry">
<mxPoint x="800.03" y="760" as="sourcePoint" />
<mxPoint x="880.03" y="760" as="targetPoint" />
</mxGeometry>
</mxCell>
<mxCell id="xWUiTusR7ZZWym1XTSiP-48" value="arp" style="edgeLabel;html=1;align=center;verticalAlign=middle;resizable=0;points=[];" vertex="1" connectable="0" parent="xWUiTusR7ZZWym1XTSiP-47">
<mxGeometry x="0.2037" y="2" relative="1" as="geometry">
<mxPoint x="-8" y="-8" as="offset" />
</mxGeometry>
</mxCell>
<mxCell id="xWUiTusR7ZZWym1XTSiP-49" value="" style="endArrow=classic;html=1;rounded=0;fillColor=#fa6800;strokeColor=#C73500;" edge="1" parent="1">
<mxGeometry width="50" height="50" relative="1" as="geometry">
<mxPoint x="920.03" y="760" as="sourcePoint" />
<mxPoint x="1000.03" y="760" as="targetPoint" />
</mxGeometry>
</mxCell>
<mxCell id="xWUiTusR7ZZWym1XTSiP-50" value="ip-stream" style="edgeLabel;html=1;align=center;verticalAlign=middle;resizable=0;points=[];" vertex="1" connectable="0" parent="xWUiTusR7ZZWym1XTSiP-49">
<mxGeometry x="0.2037" y="2" relative="1" as="geometry">
<mxPoint x="-8" y="-8" as="offset" />
</mxGeometry>
</mxCell>
<mxCell id="xWUiTusR7ZZWym1XTSiP-51" value="" style="endArrow=classic;html=1;rounded=0;fillColor=#008a00;strokeColor=#005700;" edge="1" parent="1">
<mxGeometry width="50" height="50" relative="1" as="geometry">
<mxPoint x="1040" y="760" as="sourcePoint" />
<mxPoint x="1120" y="760" as="targetPoint" />
</mxGeometry>
</mxCell>
<mxCell id="xWUiTusR7ZZWym1XTSiP-52" value="eth-stream" style="edgeLabel;html=1;align=center;verticalAlign=middle;resizable=0;points=[];" vertex="1" connectable="0" parent="xWUiTusR7ZZWym1XTSiP-51">
<mxGeometry x="0.2037" y="2" relative="1" as="geometry">
<mxPoint x="-8" y="-8" as="offset" />
</mxGeometry>
</mxCell>
<mxCell id="xWUiTusR7ZZWym1XTSiP-60" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;entryX=0;entryY=0.25;entryDx=0;entryDy=0;fillColor=#e3c800;strokeColor=#B09500;" edge="1" parent="1" source="xWUiTusR7ZZWym1XTSiP-53" target="xWUiTusR7ZZWym1XTSiP-10">
<mxGeometry relative="1" as="geometry" />
</mxCell>
<mxCell id="xWUiTusR7ZZWym1XTSiP-53" value="eth_axis_tx" style="rounded=0;whiteSpace=wrap;html=1;" vertex="1" parent="1">
<mxGeometry x="1040" y="480" width="80" height="40" as="geometry" />
</mxCell>
<mxCell id="xWUiTusR7ZZWym1XTSiP-59" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;entryX=1;entryY=0.75;entryDx=0;entryDy=0;fillColor=#008a00;strokeColor=#005700;" edge="1" parent="1" source="xWUiTusR7ZZWym1XTSiP-54" target="xWUiTusR7ZZWym1XTSiP-15">
<mxGeometry relative="1" as="geometry">
<mxPoint x="1120" y="540" as="targetPoint" />
</mxGeometry>
</mxCell>
<mxCell id="xWUiTusR7ZZWym1XTSiP-54" value="eth_axis_rx" style="rounded=0;whiteSpace=wrap;html=1;" vertex="1" parent="1">
<mxGeometry x="1040" y="520" width="80" height="40" as="geometry" />
</mxCell>
</root>
</mxGraphModel>
</diagram>
</mxfile>

Binary file not shown.

After

Width:  |  Height:  |  Size: 50 KiB

View File

@@ -0,0 +1,55 @@
# Network Processor
The network processor terminates TCP connections.
## Theory of Operation
Configuration is loaded statically into one of the available TCP
## Components
### TCP State Manager
The TCP State manager is responsible for maintaining the TCP State. It facilitates
communication between the RX control and TX control. The most important thing that
the TCP State manager does is request the socket structures from memory, and load
these values into the RX and TX control, and vice-versa.
When the TCP State Manager sees i_tx_ctx_ptr_valid, it will read i_tx_ctx_ptr and then
DMA that struct into it's local memory. It will then look up the port in the CAM. If
the port is not present, it will write it. If the CAM is full, then we set a flag in
the context saying that the socket was not opened successfully.
#### Clock and Reset
| Clock Name | Clock Frequency |
|---------------|---------------|
| System Clock | 100MHz |
| Reset Name | Purpose |
|-----------|------------|
| rst_n | General Reset |
#### Regfile Inputs
All of the registers go through the tcp state manager.
#### Other Signals
| Signal Name | Direction | Description |
| ----------- | --------- | ----------- |
| o_send_type | O | Type of packet to create |
| o_send_valid | O | Send a packet |
| o_seq_num | O | Current sequence number |
| i_seq_num | I | Next sequence number |
| i_seq_num_we | I | Write new sequence number |
| o_ack_num | O | Current ack number |
| i_ack_num | I | Next ack number |
| i_ack_num_we | I | Write new ack number |
| i_recvd_type | I | Received packet type from RX control. Bitmask from packet. |
| i_recvd_valid | I | Recieved type valid |
| o_tx_port | O | TX port output to TX Packet Gen |
| o_tx_ip | O | TX IP Address |
| o_rx_port | O | RX port output to RX Parser |
| o_rx_ip | O | RX IP. Local IP of device |

View File

@@ -0,0 +1,574 @@
<mxfile host="Electron" modified="2024-08-30T01:36:46.743Z" agent="Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) draw.io/21.2.8 Chrome/112.0.5615.165 Electron/24.2.0 Safari/537.36" etag="v0ewGMV_NAF0fF2QkYBg" version="21.2.8" type="device">
<diagram name="Page-1" id="8lX2gjxiGhIz8fm0OWgg">
<mxGraphModel dx="1794" dy="648" grid="1" gridSize="10" guides="1" tooltips="1" connect="1" arrows="1" fold="1" page="1" pageScale="1" pageWidth="850" pageHeight="1100" math="0" shadow="0">
<root>
<mxCell id="0" />
<mxCell id="1" parent="0" />
<mxCell id="hUmURhrymKCytomf8O3q-317" value="" style="group;fillColor=default;" parent="1" vertex="1" connectable="0">
<mxGeometry x="130" y="200" width="610" height="400" as="geometry" />
</mxCell>
<mxCell id="hUmURhrymKCytomf8O3q-318" value="" style="group;strokeColor=default;fillColor=none;container=0;" parent="hUmURhrymKCytomf8O3q-317" vertex="1" connectable="0">
<mxGeometry width="610" height="400" as="geometry" />
</mxCell>
<mxCell id="hUmURhrymKCytomf8O3q-321" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;fillColor=#e3c800;strokeColor=#B09500;" parent="hUmURhrymKCytomf8O3q-317" target="hUmURhrymKCytomf8O3q-340" edge="1">
<mxGeometry relative="1" as="geometry">
<mxPoint y="120" as="sourcePoint" />
</mxGeometry>
</mxCell>
<mxCell id="hUmURhrymKCytomf8O3q-322" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;fillColor=#e3c800;strokeColor=#B09500;" parent="hUmURhrymKCytomf8O3q-317" source="hUmURhrymKCytomf8O3q-339" edge="1">
<mxGeometry relative="1" as="geometry">
<mxPoint y="340" as="targetPoint" />
</mxGeometry>
</mxCell>
<mxCell id="hUmURhrymKCytomf8O3q-323" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;fillColor=#fa6800;strokeColor=#C73500;movable=1;resizable=1;rotatable=1;deletable=1;editable=1;locked=0;connectable=1;" parent="hUmURhrymKCytomf8O3q-317" source="hUmURhrymKCytomf8O3q-324" edge="1">
<mxGeometry relative="1" as="geometry">
<mxPoint x="610" y="120" as="targetPoint" />
</mxGeometry>
</mxCell>
<mxCell id="hUmURhrymKCytomf8O3q-324" value="Packet Generator" style="rounded=0;whiteSpace=wrap;html=1;movable=1;resizable=1;rotatable=1;deletable=1;editable=1;locked=0;connectable=1;container=0;" parent="hUmURhrymKCytomf8O3q-317" vertex="1">
<mxGeometry x="430" y="80.07" width="120" height="80" as="geometry" />
</mxCell>
<mxCell id="hUmURhrymKCytomf8O3q-325" value="" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;fillColor=#e3c800;strokeColor=#B09500;movable=1;resizable=1;rotatable=1;deletable=1;editable=1;locked=0;connectable=1;" parent="hUmURhrymKCytomf8O3q-317" source="hUmURhrymKCytomf8O3q-326" target="hUmURhrymKCytomf8O3q-324" edge="1">
<mxGeometry relative="1" as="geometry" />
</mxCell>
<mxCell id="hUmURhrymKCytomf8O3q-326" value="TX Control" style="rounded=0;whiteSpace=wrap;html=1;movable=1;resizable=1;rotatable=1;deletable=1;editable=1;locked=0;connectable=1;container=0;" parent="hUmURhrymKCytomf8O3q-317" vertex="1">
<mxGeometry x="310" y="100.07" width="80" height="40" as="geometry" />
</mxCell>
<mxCell id="hUmURhrymKCytomf8O3q-327" value="" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;fillColor=#e3c800;strokeColor=#B09500;movable=1;resizable=1;rotatable=1;deletable=1;editable=1;locked=0;connectable=1;exitX=1;exitY=0.5;exitDx=0;exitDy=0;" parent="hUmURhrymKCytomf8O3q-317" source="hUmURhrymKCytomf8O3q-340" target="hUmURhrymKCytomf8O3q-326" edge="1">
<mxGeometry relative="1" as="geometry">
<mxPoint x="270.0000000000002" y="120.06999999999994" as="sourcePoint" />
</mxGeometry>
</mxCell>
<mxCell id="hUmURhrymKCytomf8O3q-328" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;entryX=0.5;entryY=1;entryDx=0;entryDy=0;movable=1;resizable=1;rotatable=1;deletable=1;editable=1;locked=0;connectable=1;" parent="hUmURhrymKCytomf8O3q-317" source="hUmURhrymKCytomf8O3q-330" target="hUmURhrymKCytomf8O3q-326" edge="1">
<mxGeometry relative="1" as="geometry" />
</mxCell>
<mxCell id="hUmURhrymKCytomf8O3q-329" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;exitX=0.75;exitY=0;exitDx=0;exitDy=0;entryX=0.25;entryY=1;entryDx=0;entryDy=0;movable=1;resizable=1;rotatable=1;deletable=1;editable=1;locked=0;connectable=1;" parent="hUmURhrymKCytomf8O3q-317" source="hUmURhrymKCytomf8O3q-330" target="hUmURhrymKCytomf8O3q-324" edge="1">
<mxGeometry relative="1" as="geometry" />
</mxCell>
<mxCell id="hUmURhrymKCytomf8O3q-330" value="TCP State Manager" style="rounded=0;whiteSpace=wrap;html=1;movable=1;resizable=1;rotatable=1;deletable=1;editable=1;locked=0;connectable=1;container=0;" parent="hUmURhrymKCytomf8O3q-317" vertex="1">
<mxGeometry x="310" y="200.07" width="80" height="40" as="geometry" />
</mxCell>
<mxCell id="hUmURhrymKCytomf8O3q-331" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;exitX=0.25;exitY=0;exitDx=0;exitDy=0;entryX=1;entryY=0.5;entryDx=0;entryDy=0;movable=1;resizable=1;rotatable=1;deletable=1;editable=1;locked=0;connectable=1;" parent="hUmURhrymKCytomf8O3q-317" source="hUmURhrymKCytomf8O3q-332" target="hUmURhrymKCytomf8O3q-330" edge="1">
<mxGeometry relative="1" as="geometry" />
</mxCell>
<mxCell id="hUmURhrymKCytomf8O3q-332" value="Parser" style="rounded=0;whiteSpace=wrap;html=1;movable=1;resizable=1;rotatable=1;deletable=1;editable=1;locked=0;connectable=1;container=0;" parent="hUmURhrymKCytomf8O3q-317" vertex="1">
<mxGeometry x="430" y="320.07000000000005" width="120" height="40" as="geometry" />
</mxCell>
<mxCell id="hUmURhrymKCytomf8O3q-333" value="" style="endArrow=classic;html=1;rounded=0;entryX=1;entryY=0.5;entryDx=0;entryDy=0;fillColor=#fa6800;strokeColor=#C73500;movable=1;resizable=1;rotatable=1;deletable=1;editable=1;locked=0;connectable=1;" parent="hUmURhrymKCytomf8O3q-317" target="hUmURhrymKCytomf8O3q-332" edge="1">
<mxGeometry width="50" height="50" relative="1" as="geometry">
<mxPoint x="610" y="340" as="sourcePoint" />
<mxPoint x="530" y="180.07" as="targetPoint" />
</mxGeometry>
</mxCell>
<mxCell id="hUmURhrymKCytomf8O3q-334" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;entryX=0.5;entryY=1;entryDx=0;entryDy=0;movable=1;resizable=1;rotatable=1;deletable=1;editable=1;locked=0;connectable=1;" parent="hUmURhrymKCytomf8O3q-317" source="hUmURhrymKCytomf8O3q-335" target="hUmURhrymKCytomf8O3q-330" edge="1">
<mxGeometry relative="1" as="geometry" />
</mxCell>
<mxCell id="hUmURhrymKCytomf8O3q-335" value="RX Control" style="rounded=0;whiteSpace=wrap;html=1;movable=1;resizable=1;rotatable=1;deletable=1;editable=1;locked=0;connectable=1;container=0;" parent="hUmURhrymKCytomf8O3q-317" vertex="1">
<mxGeometry x="310" y="320.07000000000005" width="80" height="40" as="geometry" />
</mxCell>
<mxCell id="hUmURhrymKCytomf8O3q-336" value="" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;fillColor=#fa6800;strokeColor=#C73500;movable=1;resizable=1;rotatable=1;deletable=1;editable=1;locked=0;connectable=1;" parent="hUmURhrymKCytomf8O3q-317" source="hUmURhrymKCytomf8O3q-332" target="hUmURhrymKCytomf8O3q-335" edge="1">
<mxGeometry relative="1" as="geometry" />
</mxCell>
<mxCell id="hUmURhrymKCytomf8O3q-337" value="" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;fillColor=#e3c800;strokeColor=#B09500;movable=1;resizable=1;rotatable=1;deletable=1;editable=1;locked=0;connectable=1;entryX=1;entryY=0.5;entryDx=0;entryDy=0;" parent="hUmURhrymKCytomf8O3q-317" source="hUmURhrymKCytomf8O3q-335" target="hUmURhrymKCytomf8O3q-339" edge="1">
<mxGeometry relative="1" as="geometry">
<mxPoint x="270.0000000000002" y="340.07000000000016" as="targetPoint" />
</mxGeometry>
</mxCell>
<mxCell id="hUmURhrymKCytomf8O3q-338" value="REGS" style="rounded=0;whiteSpace=wrap;html=1;movable=1;resizable=1;rotatable=1;deletable=1;editable=1;locked=0;connectable=1;container=0;" parent="hUmURhrymKCytomf8O3q-317" vertex="1">
<mxGeometry x="290" y="20.069999999999993" width="120" height="60" as="geometry" />
</mxCell>
<mxCell id="hUmURhrymKCytomf8O3q-339" value="Ring Buffer Manager" style="rounded=0;whiteSpace=wrap;html=1;container=0;" parent="hUmURhrymKCytomf8O3q-317" vertex="1">
<mxGeometry x="80" y="310" width="120" height="60" as="geometry" />
</mxCell>
<mxCell id="hUmURhrymKCytomf8O3q-340" value="Ring Buffer Manager" style="rounded=0;whiteSpace=wrap;html=1;container=0;" parent="hUmURhrymKCytomf8O3q-317" vertex="1">
<mxGeometry x="80" y="90.07" width="120" height="60" as="geometry" />
</mxCell>
<mxCell id="hUmURhrymKCytomf8O3q-348" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;entryX=0.625;entryY=1;entryDx=0;entryDy=0;entryPerimeter=0;startArrow=classic;startFill=1;endArrow=none;endFill=0;fillColor=#6a00ff;strokeColor=#3700CC;" parent="1" edge="1">
<mxGeometry relative="1" as="geometry">
<mxPoint x="620.03" y="160" as="targetPoint" />
<mxPoint x="620.03" y="250" as="sourcePoint" />
</mxGeometry>
</mxCell>
<mxCell id="hUmURhrymKCytomf8O3q-293" value="" style="group;fillColor=default;" parent="1" vertex="1" connectable="0">
<mxGeometry x="140" y="210" width="610" height="400" as="geometry" />
</mxCell>
<mxCell id="hUmURhrymKCytomf8O3q-294" value="" style="group;strokeColor=default;fillColor=none;container=0;" parent="hUmURhrymKCytomf8O3q-293" vertex="1" connectable="0">
<mxGeometry width="610" height="400" as="geometry" />
</mxCell>
<mxCell id="hUmURhrymKCytomf8O3q-297" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;fillColor=#e3c800;strokeColor=#B09500;" parent="hUmURhrymKCytomf8O3q-293" target="hUmURhrymKCytomf8O3q-316" edge="1">
<mxGeometry relative="1" as="geometry">
<mxPoint y="120" as="sourcePoint" />
</mxGeometry>
</mxCell>
<mxCell id="hUmURhrymKCytomf8O3q-298" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;fillColor=#e3c800;strokeColor=#B09500;" parent="hUmURhrymKCytomf8O3q-293" source="hUmURhrymKCytomf8O3q-315" edge="1">
<mxGeometry relative="1" as="geometry">
<mxPoint y="340" as="targetPoint" />
</mxGeometry>
</mxCell>
<mxCell id="hUmURhrymKCytomf8O3q-299" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;fillColor=#fa6800;strokeColor=#C73500;movable=1;resizable=1;rotatable=1;deletable=1;editable=1;locked=0;connectable=1;" parent="hUmURhrymKCytomf8O3q-293" source="hUmURhrymKCytomf8O3q-300" edge="1">
<mxGeometry relative="1" as="geometry">
<mxPoint x="610" y="120" as="targetPoint" />
</mxGeometry>
</mxCell>
<mxCell id="hUmURhrymKCytomf8O3q-300" value="Packet Generator" style="rounded=0;whiteSpace=wrap;html=1;movable=1;resizable=1;rotatable=1;deletable=1;editable=1;locked=0;connectable=1;container=0;" parent="hUmURhrymKCytomf8O3q-293" vertex="1">
<mxGeometry x="430" y="80.07" width="120" height="80" as="geometry" />
</mxCell>
<mxCell id="hUmURhrymKCytomf8O3q-301" value="" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;fillColor=#e3c800;strokeColor=#B09500;movable=1;resizable=1;rotatable=1;deletable=1;editable=1;locked=0;connectable=1;" parent="hUmURhrymKCytomf8O3q-293" source="hUmURhrymKCytomf8O3q-302" target="hUmURhrymKCytomf8O3q-300" edge="1">
<mxGeometry relative="1" as="geometry" />
</mxCell>
<mxCell id="hUmURhrymKCytomf8O3q-302" value="TX Control" style="rounded=0;whiteSpace=wrap;html=1;movable=1;resizable=1;rotatable=1;deletable=1;editable=1;locked=0;connectable=1;container=0;" parent="hUmURhrymKCytomf8O3q-293" vertex="1">
<mxGeometry x="310" y="100.07" width="80" height="40" as="geometry" />
</mxCell>
<mxCell id="hUmURhrymKCytomf8O3q-303" value="" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;fillColor=#e3c800;strokeColor=#B09500;movable=1;resizable=1;rotatable=1;deletable=1;editable=1;locked=0;connectable=1;exitX=1;exitY=0.5;exitDx=0;exitDy=0;" parent="hUmURhrymKCytomf8O3q-293" source="hUmURhrymKCytomf8O3q-316" target="hUmURhrymKCytomf8O3q-302" edge="1">
<mxGeometry relative="1" as="geometry">
<mxPoint x="270.0000000000002" y="120.06999999999994" as="sourcePoint" />
</mxGeometry>
</mxCell>
<mxCell id="hUmURhrymKCytomf8O3q-304" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;entryX=0.5;entryY=1;entryDx=0;entryDy=0;movable=1;resizable=1;rotatable=1;deletable=1;editable=1;locked=0;connectable=1;" parent="hUmURhrymKCytomf8O3q-293" source="hUmURhrymKCytomf8O3q-306" target="hUmURhrymKCytomf8O3q-302" edge="1">
<mxGeometry relative="1" as="geometry" />
</mxCell>
<mxCell id="hUmURhrymKCytomf8O3q-305" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;exitX=0.75;exitY=0;exitDx=0;exitDy=0;entryX=0.25;entryY=1;entryDx=0;entryDy=0;movable=1;resizable=1;rotatable=1;deletable=1;editable=1;locked=0;connectable=1;" parent="hUmURhrymKCytomf8O3q-293" source="hUmURhrymKCytomf8O3q-306" target="hUmURhrymKCytomf8O3q-300" edge="1">
<mxGeometry relative="1" as="geometry" />
</mxCell>
<mxCell id="hUmURhrymKCytomf8O3q-306" value="TCP State Manager" style="rounded=0;whiteSpace=wrap;html=1;movable=1;resizable=1;rotatable=1;deletable=1;editable=1;locked=0;connectable=1;container=0;" parent="hUmURhrymKCytomf8O3q-293" vertex="1">
<mxGeometry x="310" y="200.07" width="80" height="40" as="geometry" />
</mxCell>
<mxCell id="hUmURhrymKCytomf8O3q-307" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;exitX=0.25;exitY=0;exitDx=0;exitDy=0;entryX=1;entryY=0.5;entryDx=0;entryDy=0;movable=1;resizable=1;rotatable=1;deletable=1;editable=1;locked=0;connectable=1;" parent="hUmURhrymKCytomf8O3q-293" source="hUmURhrymKCytomf8O3q-308" target="hUmURhrymKCytomf8O3q-306" edge="1">
<mxGeometry relative="1" as="geometry" />
</mxCell>
<mxCell id="hUmURhrymKCytomf8O3q-308" value="Parser" style="rounded=0;whiteSpace=wrap;html=1;movable=1;resizable=1;rotatable=1;deletable=1;editable=1;locked=0;connectable=1;container=0;" parent="hUmURhrymKCytomf8O3q-293" vertex="1">
<mxGeometry x="430" y="320.07000000000005" width="120" height="40" as="geometry" />
</mxCell>
<mxCell id="hUmURhrymKCytomf8O3q-309" value="" style="endArrow=classic;html=1;rounded=0;entryX=1;entryY=0.5;entryDx=0;entryDy=0;fillColor=#fa6800;strokeColor=#C73500;movable=1;resizable=1;rotatable=1;deletable=1;editable=1;locked=0;connectable=1;" parent="hUmURhrymKCytomf8O3q-293" target="hUmURhrymKCytomf8O3q-308" edge="1">
<mxGeometry width="50" height="50" relative="1" as="geometry">
<mxPoint x="610" y="340" as="sourcePoint" />
<mxPoint x="530" y="180.07" as="targetPoint" />
</mxGeometry>
</mxCell>
<mxCell id="hUmURhrymKCytomf8O3q-310" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;entryX=0.5;entryY=1;entryDx=0;entryDy=0;movable=1;resizable=1;rotatable=1;deletable=1;editable=1;locked=0;connectable=1;" parent="hUmURhrymKCytomf8O3q-293" source="hUmURhrymKCytomf8O3q-311" target="hUmURhrymKCytomf8O3q-306" edge="1">
<mxGeometry relative="1" as="geometry" />
</mxCell>
<mxCell id="hUmURhrymKCytomf8O3q-311" value="RX Control" style="rounded=0;whiteSpace=wrap;html=1;movable=1;resizable=1;rotatable=1;deletable=1;editable=1;locked=0;connectable=1;container=0;" parent="hUmURhrymKCytomf8O3q-293" vertex="1">
<mxGeometry x="310" y="320.07000000000005" width="80" height="40" as="geometry" />
</mxCell>
<mxCell id="hUmURhrymKCytomf8O3q-312" value="" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;fillColor=#fa6800;strokeColor=#C73500;movable=1;resizable=1;rotatable=1;deletable=1;editable=1;locked=0;connectable=1;" parent="hUmURhrymKCytomf8O3q-293" source="hUmURhrymKCytomf8O3q-308" target="hUmURhrymKCytomf8O3q-311" edge="1">
<mxGeometry relative="1" as="geometry" />
</mxCell>
<mxCell id="hUmURhrymKCytomf8O3q-313" value="" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;fillColor=#e3c800;strokeColor=#B09500;movable=1;resizable=1;rotatable=1;deletable=1;editable=1;locked=0;connectable=1;entryX=1;entryY=0.5;entryDx=0;entryDy=0;" parent="hUmURhrymKCytomf8O3q-293" source="hUmURhrymKCytomf8O3q-311" target="hUmURhrymKCytomf8O3q-315" edge="1">
<mxGeometry relative="1" as="geometry">
<mxPoint x="270.0000000000002" y="340.07000000000016" as="targetPoint" />
</mxGeometry>
</mxCell>
<mxCell id="hUmURhrymKCytomf8O3q-314" value="REGS" style="rounded=0;whiteSpace=wrap;html=1;movable=1;resizable=1;rotatable=1;deletable=1;editable=1;locked=0;connectable=1;container=0;" parent="hUmURhrymKCytomf8O3q-293" vertex="1">
<mxGeometry x="290" y="20.069999999999993" width="120" height="60" as="geometry" />
</mxCell>
<mxCell id="hUmURhrymKCytomf8O3q-315" value="Ring Buffer Manager" style="rounded=0;whiteSpace=wrap;html=1;container=0;" parent="hUmURhrymKCytomf8O3q-293" vertex="1">
<mxGeometry x="80" y="310" width="120" height="60" as="geometry" />
</mxCell>
<mxCell id="hUmURhrymKCytomf8O3q-316" value="Ring Buffer Manager" style="rounded=0;whiteSpace=wrap;html=1;container=0;" parent="hUmURhrymKCytomf8O3q-293" vertex="1">
<mxGeometry x="80" y="90.07" width="120" height="60" as="geometry" />
</mxCell>
<mxCell id="hUmURhrymKCytomf8O3q-347" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;entryX=0.625;entryY=1;entryDx=0;entryDy=0;entryPerimeter=0;startArrow=classic;startFill=1;endArrow=none;endFill=0;fillColor=#6a00ff;strokeColor=#3700CC;" parent="1" edge="1">
<mxGeometry relative="1" as="geometry">
<mxPoint x="629.95" y="160" as="targetPoint" />
<mxPoint x="629.95" y="250" as="sourcePoint" />
</mxGeometry>
</mxCell>
<mxCell id="hUmURhrymKCytomf8O3q-269" value="" style="group;fillColor=default;" parent="1" vertex="1" connectable="0">
<mxGeometry x="150" y="220" width="610" height="400" as="geometry" />
</mxCell>
<mxCell id="hUmURhrymKCytomf8O3q-270" value="" style="group;strokeColor=default;fillColor=none;container=0;" parent="hUmURhrymKCytomf8O3q-269" vertex="1" connectable="0">
<mxGeometry width="610" height="400" as="geometry" />
</mxCell>
<mxCell id="hUmURhrymKCytomf8O3q-273" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;fillColor=#e3c800;strokeColor=#B09500;" parent="hUmURhrymKCytomf8O3q-269" target="hUmURhrymKCytomf8O3q-292" edge="1">
<mxGeometry relative="1" as="geometry">
<mxPoint y="120" as="sourcePoint" />
</mxGeometry>
</mxCell>
<mxCell id="hUmURhrymKCytomf8O3q-274" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;fillColor=#e3c800;strokeColor=#B09500;" parent="hUmURhrymKCytomf8O3q-269" source="hUmURhrymKCytomf8O3q-291" edge="1">
<mxGeometry relative="1" as="geometry">
<mxPoint y="340" as="targetPoint" />
</mxGeometry>
</mxCell>
<mxCell id="hUmURhrymKCytomf8O3q-275" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;fillColor=#fa6800;strokeColor=#C73500;movable=1;resizable=1;rotatable=1;deletable=1;editable=1;locked=0;connectable=1;" parent="hUmURhrymKCytomf8O3q-269" source="hUmURhrymKCytomf8O3q-276" edge="1">
<mxGeometry relative="1" as="geometry">
<mxPoint x="610" y="120" as="targetPoint" />
</mxGeometry>
</mxCell>
<mxCell id="hUmURhrymKCytomf8O3q-276" value="Packet Generator" style="rounded=0;whiteSpace=wrap;html=1;movable=1;resizable=1;rotatable=1;deletable=1;editable=1;locked=0;connectable=1;container=0;" parent="hUmURhrymKCytomf8O3q-269" vertex="1">
<mxGeometry x="430" y="80.07" width="120" height="80" as="geometry" />
</mxCell>
<mxCell id="hUmURhrymKCytomf8O3q-277" value="" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;fillColor=#e3c800;strokeColor=#B09500;movable=1;resizable=1;rotatable=1;deletable=1;editable=1;locked=0;connectable=1;" parent="hUmURhrymKCytomf8O3q-269" source="hUmURhrymKCytomf8O3q-278" target="hUmURhrymKCytomf8O3q-276" edge="1">
<mxGeometry relative="1" as="geometry" />
</mxCell>
<mxCell id="hUmURhrymKCytomf8O3q-278" value="TX Control" style="rounded=0;whiteSpace=wrap;html=1;movable=1;resizable=1;rotatable=1;deletable=1;editable=1;locked=0;connectable=1;container=0;" parent="hUmURhrymKCytomf8O3q-269" vertex="1">
<mxGeometry x="310" y="100.07" width="80" height="40" as="geometry" />
</mxCell>
<mxCell id="hUmURhrymKCytomf8O3q-279" value="" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;fillColor=#e3c800;strokeColor=#B09500;movable=1;resizable=1;rotatable=1;deletable=1;editable=1;locked=0;connectable=1;exitX=1;exitY=0.5;exitDx=0;exitDy=0;" parent="hUmURhrymKCytomf8O3q-269" source="hUmURhrymKCytomf8O3q-292" target="hUmURhrymKCytomf8O3q-278" edge="1">
<mxGeometry relative="1" as="geometry">
<mxPoint x="270.0000000000002" y="120.06999999999994" as="sourcePoint" />
</mxGeometry>
</mxCell>
<mxCell id="hUmURhrymKCytomf8O3q-280" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;entryX=0.5;entryY=1;entryDx=0;entryDy=0;movable=1;resizable=1;rotatable=1;deletable=1;editable=1;locked=0;connectable=1;" parent="hUmURhrymKCytomf8O3q-269" source="hUmURhrymKCytomf8O3q-282" target="hUmURhrymKCytomf8O3q-278" edge="1">
<mxGeometry relative="1" as="geometry" />
</mxCell>
<mxCell id="hUmURhrymKCytomf8O3q-281" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;exitX=0.75;exitY=0;exitDx=0;exitDy=0;entryX=0.25;entryY=1;entryDx=0;entryDy=0;movable=1;resizable=1;rotatable=1;deletable=1;editable=1;locked=0;connectable=1;" parent="hUmURhrymKCytomf8O3q-269" source="hUmURhrymKCytomf8O3q-282" target="hUmURhrymKCytomf8O3q-276" edge="1">
<mxGeometry relative="1" as="geometry" />
</mxCell>
<mxCell id="hUmURhrymKCytomf8O3q-282" value="TCP State Manager" style="rounded=0;whiteSpace=wrap;html=1;movable=1;resizable=1;rotatable=1;deletable=1;editable=1;locked=0;connectable=1;container=0;" parent="hUmURhrymKCytomf8O3q-269" vertex="1">
<mxGeometry x="310" y="200.07" width="80" height="40" as="geometry" />
</mxCell>
<mxCell id="hUmURhrymKCytomf8O3q-283" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;exitX=0.25;exitY=0;exitDx=0;exitDy=0;entryX=1;entryY=0.5;entryDx=0;entryDy=0;movable=1;resizable=1;rotatable=1;deletable=1;editable=1;locked=0;connectable=1;" parent="hUmURhrymKCytomf8O3q-269" source="hUmURhrymKCytomf8O3q-284" target="hUmURhrymKCytomf8O3q-282" edge="1">
<mxGeometry relative="1" as="geometry" />
</mxCell>
<mxCell id="hUmURhrymKCytomf8O3q-284" value="Parser" style="rounded=0;whiteSpace=wrap;html=1;movable=1;resizable=1;rotatable=1;deletable=1;editable=1;locked=0;connectable=1;container=0;" parent="hUmURhrymKCytomf8O3q-269" vertex="1">
<mxGeometry x="430" y="320.07000000000005" width="120" height="40" as="geometry" />
</mxCell>
<mxCell id="hUmURhrymKCytomf8O3q-285" value="" style="endArrow=classic;html=1;rounded=0;entryX=1;entryY=0.5;entryDx=0;entryDy=0;fillColor=#fa6800;strokeColor=#C73500;movable=1;resizable=1;rotatable=1;deletable=1;editable=1;locked=0;connectable=1;" parent="hUmURhrymKCytomf8O3q-269" target="hUmURhrymKCytomf8O3q-284" edge="1">
<mxGeometry width="50" height="50" relative="1" as="geometry">
<mxPoint x="610" y="340" as="sourcePoint" />
<mxPoint x="530" y="180.07" as="targetPoint" />
</mxGeometry>
</mxCell>
<mxCell id="hUmURhrymKCytomf8O3q-286" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;entryX=0.5;entryY=1;entryDx=0;entryDy=0;movable=1;resizable=1;rotatable=1;deletable=1;editable=1;locked=0;connectable=1;" parent="hUmURhrymKCytomf8O3q-269" source="hUmURhrymKCytomf8O3q-287" target="hUmURhrymKCytomf8O3q-282" edge="1">
<mxGeometry relative="1" as="geometry" />
</mxCell>
<mxCell id="hUmURhrymKCytomf8O3q-287" value="RX Control" style="rounded=0;whiteSpace=wrap;html=1;movable=1;resizable=1;rotatable=1;deletable=1;editable=1;locked=0;connectable=1;container=0;" parent="hUmURhrymKCytomf8O3q-269" vertex="1">
<mxGeometry x="310" y="320.07000000000005" width="80" height="40" as="geometry" />
</mxCell>
<mxCell id="hUmURhrymKCytomf8O3q-288" value="" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;fillColor=#fa6800;strokeColor=#C73500;movable=1;resizable=1;rotatable=1;deletable=1;editable=1;locked=0;connectable=1;" parent="hUmURhrymKCytomf8O3q-269" source="hUmURhrymKCytomf8O3q-284" target="hUmURhrymKCytomf8O3q-287" edge="1">
<mxGeometry relative="1" as="geometry" />
</mxCell>
<mxCell id="hUmURhrymKCytomf8O3q-289" value="" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;fillColor=#e3c800;strokeColor=#B09500;movable=1;resizable=1;rotatable=1;deletable=1;editable=1;locked=0;connectable=1;entryX=1;entryY=0.5;entryDx=0;entryDy=0;" parent="hUmURhrymKCytomf8O3q-269" source="hUmURhrymKCytomf8O3q-287" target="hUmURhrymKCytomf8O3q-291" edge="1">
<mxGeometry relative="1" as="geometry">
<mxPoint x="270.0000000000002" y="340.07000000000016" as="targetPoint" />
</mxGeometry>
</mxCell>
<mxCell id="hUmURhrymKCytomf8O3q-290" value="REGS" style="rounded=0;whiteSpace=wrap;html=1;movable=1;resizable=1;rotatable=1;deletable=1;editable=1;locked=0;connectable=1;container=0;" parent="hUmURhrymKCytomf8O3q-269" vertex="1">
<mxGeometry x="290" y="20.069999999999993" width="120" height="60" as="geometry" />
</mxCell>
<mxCell id="hUmURhrymKCytomf8O3q-291" value="Ring Buffer Manager" style="rounded=0;whiteSpace=wrap;html=1;container=0;" parent="hUmURhrymKCytomf8O3q-269" vertex="1">
<mxGeometry x="80" y="310" width="120" height="60" as="geometry" />
</mxCell>
<mxCell id="hUmURhrymKCytomf8O3q-292" value="Ring Buffer Manager" style="rounded=0;whiteSpace=wrap;html=1;container=0;" parent="hUmURhrymKCytomf8O3q-269" vertex="1">
<mxGeometry x="80" y="90.07" width="120" height="60" as="geometry" />
</mxCell>
<mxCell id="wy1xcPKCa-p-PBI3JPLa-142" value="" style="endArrow=none;html=1;rounded=0;entryX=0.667;entryY=1;entryDx=0;entryDy=0;entryPerimeter=0;startArrow=classic;startFill=1;endFill=0;fillColor=#fa6800;strokeColor=#C73500;exitX=0.333;exitY=0.999;exitDx=0;exitDy=0;exitPerimeter=0;" parent="1" edge="1">
<mxGeometry width="50" height="50" relative="1" as="geometry">
<mxPoint x="740.0000000000005" y="540.027868852459" as="sourcePoint" />
<mxPoint x="840.0000000000005" y="539.9978688524591" as="targetPoint" />
</mxGeometry>
</mxCell>
<mxCell id="wy1xcPKCa-p-PBI3JPLa-143" value="" style="endArrow=none;html=1;rounded=0;entryX=0.584;entryY=1;entryDx=0;entryDy=0;entryPerimeter=0;startArrow=classic;startFill=1;endFill=0;fillColor=#fa6800;strokeColor=#C73500;exitX=0.416;exitY=0.999;exitDx=0;exitDy=0;exitPerimeter=0;" parent="1" edge="1">
<mxGeometry width="50" height="50" relative="1" as="geometry">
<mxPoint x="750.0000000000005" y="550.027868852459" as="sourcePoint" />
<mxPoint x="840.0000000000005" y="549.9978688524591" as="targetPoint" />
</mxGeometry>
</mxCell>
<mxCell id="wy1xcPKCa-p-PBI3JPLa-144" value="" style="endArrow=none;html=1;rounded=0;entryX=0.5;entryY=1;entryDx=0;entryDy=0;startArrow=classic;startFill=1;endFill=0;fillColor=#fa6800;strokeColor=#C73500;" parent="1" edge="1">
<mxGeometry width="50" height="50" relative="1" as="geometry">
<mxPoint x="760" y="560" as="sourcePoint" />
<mxPoint x="840" y="560" as="targetPoint" />
</mxGeometry>
</mxCell>
<mxCell id="hUmURhrymKCytomf8O3q-360" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;fillColor=#d80073;strokeColor=#A50040;" parent="1" target="wy1xcPKCa-p-PBI3JPLa-122" edge="1">
<mxGeometry relative="1" as="geometry">
<mxPoint x="630" y="80" as="sourcePoint" />
</mxGeometry>
</mxCell>
<mxCell id="wy1xcPKCa-p-PBI3JPLa-122" value="APB Decoder" style="rounded=0;whiteSpace=wrap;html=1;" parent="1" vertex="1">
<mxGeometry x="550" y="120" width="160" height="40" as="geometry" />
</mxCell>
<mxCell id="wy1xcPKCa-p-PBI3JPLa-129" value="" style="strokeWidth=2;html=1;shape=mxgraph.flowchart.annotation_2;align=left;labelPosition=right;pointerEvents=1;rotation=135;" parent="1" vertex="1">
<mxGeometry x="750" y="170" width="30" height="70" as="geometry" />
</mxCell>
<mxCell id="wy1xcPKCa-p-PBI3JPLa-130" value="N" style="text;html=1;strokeColor=none;fillColor=none;align=center;verticalAlign=middle;whiteSpace=wrap;rounded=0;" parent="1" vertex="1">
<mxGeometry x="750" y="170" width="60" height="30" as="geometry" />
</mxCell>
<mxCell id="wy1xcPKCa-p-PBI3JPLa-170" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;fillColor=#fa6800;strokeColor=#C73500;" parent="1" source="wy1xcPKCa-p-PBI3JPLa-132" edge="1">
<mxGeometry relative="1" as="geometry">
<mxPoint x="1040" y="340" as="targetPoint" />
</mxGeometry>
</mxCell>
<mxCell id="wy1xcPKCa-p-PBI3JPLa-132" value="ip arb" style="shape=trapezoid;perimeter=trapezoidPerimeter;whiteSpace=wrap;html=1;fixedSize=1;rotation=-90;flipH=1;flipV=1;" parent="1" vertex="1">
<mxGeometry x="800" y="320.03" width="120" height="40.07" as="geometry" />
</mxCell>
<mxCell id="wy1xcPKCa-p-PBI3JPLa-133" value="ip demux" style="shape=trapezoid;perimeter=trapezoidPerimeter;whiteSpace=wrap;html=1;fixedSize=1;rotation=-90;flipH=1;flipV=1;" parent="1" vertex="1">
<mxGeometry x="800" y="540" width="120" height="40" as="geometry" />
</mxCell>
<mxCell id="wy1xcPKCa-p-PBI3JPLa-134" value="" style="endArrow=none;html=1;rounded=0;entryX=0.667;entryY=1;entryDx=0;entryDy=0;entryPerimeter=0;startArrow=classic;startFill=1;endFill=0;fillColor=#fa6800;strokeColor=#C73500;exitX=0.333;exitY=0.999;exitDx=0;exitDy=0;exitPerimeter=0;" parent="1" source="wy1xcPKCa-p-PBI3JPLa-132" edge="1">
<mxGeometry width="50" height="50" relative="1" as="geometry">
<mxPoint x="810" y="320.03" as="sourcePoint" />
<mxPoint x="770" y="320.03" as="targetPoint" />
</mxGeometry>
</mxCell>
<mxCell id="wy1xcPKCa-p-PBI3JPLa-135" value="" style="endArrow=none;html=1;rounded=0;entryX=0.584;entryY=1;entryDx=0;entryDy=0;entryPerimeter=0;startArrow=classic;startFill=1;endFill=0;fillColor=#fa6800;strokeColor=#C73500;exitX=0.416;exitY=0.999;exitDx=0;exitDy=0;exitPerimeter=0;" parent="1" source="wy1xcPKCa-p-PBI3JPLa-132" edge="1">
<mxGeometry width="50" height="50" relative="1" as="geometry">
<mxPoint x="820" y="330.03" as="sourcePoint" />
<mxPoint x="770" y="330.03" as="targetPoint" />
</mxGeometry>
</mxCell>
<mxCell id="wy1xcPKCa-p-PBI3JPLa-136" value="" style="endArrow=none;html=1;rounded=0;entryX=0.5;entryY=1;entryDx=0;entryDy=0;startArrow=classic;startFill=1;endFill=0;fillColor=#fa6800;strokeColor=#C73500;" parent="1" edge="1">
<mxGeometry width="50" height="50" relative="1" as="geometry">
<mxPoint x="840" y="340" as="sourcePoint" />
<mxPoint x="770" y="340.03" as="targetPoint" />
</mxGeometry>
</mxCell>
<mxCell id="wy1xcPKCa-p-PBI3JPLa-137" value="" style="endArrow=none;html=1;rounded=0;entryX=0.417;entryY=1;entryDx=0;entryDy=0;entryPerimeter=0;startArrow=classic;startFill=1;endFill=0;fillColor=#fa6800;strokeColor=#C73500;" parent="1" edge="1">
<mxGeometry width="50" height="50" relative="1" as="geometry">
<mxPoint x="840" y="350.03" as="sourcePoint" />
<mxPoint x="770" y="350.03" as="targetPoint" />
</mxGeometry>
</mxCell>
<mxCell id="wy1xcPKCa-p-PBI3JPLa-145" value="" style="endArrow=none;html=1;rounded=0;entryX=0.417;entryY=1;entryDx=0;entryDy=0;entryPerimeter=0;startArrow=classic;startFill=1;endFill=0;fillColor=#fa6800;strokeColor=#C73500;" parent="1" edge="1">
<mxGeometry width="50" height="50" relative="1" as="geometry">
<mxPoint x="770.0000000000005" y="570.0578688524588" as="sourcePoint" />
<mxPoint x="840.0000000000005" y="570.0578688524588" as="targetPoint" />
</mxGeometry>
</mxCell>
<mxCell id="hUmURhrymKCytomf8O3q-357" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;fillColor=#d80073;strokeColor=#A50040;" parent="1" target="hUmURhrymKCytomf8O3q-23" edge="1">
<mxGeometry relative="1" as="geometry">
<mxPoint x="-120.00000000000023" y="340.06999999999994" as="sourcePoint" />
</mxGeometry>
</mxCell>
<mxCell id="hUmURhrymKCytomf8O3q-23" value="M2S DMA" style="whiteSpace=wrap;html=1;aspect=fixed;" parent="1" vertex="1">
<mxGeometry x="-80" y="300.07" width="80" height="80" as="geometry" />
</mxCell>
<mxCell id="hUmURhrymKCytomf8O3q-346" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;entryX=0.625;entryY=1;entryDx=0;entryDy=0;entryPerimeter=0;startArrow=classic;startFill=1;endArrow=none;endFill=0;fillColor=#6a00ff;strokeColor=#3700CC;" parent="1" edge="1">
<mxGeometry relative="1" as="geometry">
<mxPoint x="640.03" y="160" as="targetPoint" />
<mxPoint x="640.03" y="250" as="sourcePoint" />
</mxGeometry>
</mxCell>
<mxCell id="hUmURhrymKCytomf8O3q-358" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;fillColor=#d80073;strokeColor=#A50040;" parent="1" source="hUmURhrymKCytomf8O3q-24" edge="1">
<mxGeometry relative="1" as="geometry">
<mxPoint x="-120.00000000000023" y="560" as="targetPoint" />
</mxGeometry>
</mxCell>
<mxCell id="hUmURhrymKCytomf8O3q-24" value="S2M DMA" style="whiteSpace=wrap;html=1;aspect=fixed;" parent="1" vertex="1">
<mxGeometry x="-80" y="520" width="80" height="80" as="geometry" />
</mxCell>
<mxCell id="hUmURhrymKCytomf8O3q-268" value="" style="group;fillColor=default;" parent="1" vertex="1" connectable="0">
<mxGeometry x="159.97" y="230" width="610" height="400" as="geometry" />
</mxCell>
<mxCell id="hUmURhrymKCytomf8O3q-99" value="" style="group;strokeColor=default;fillColor=none;container=0;" parent="hUmURhrymKCytomf8O3q-268" vertex="1" connectable="0">
<mxGeometry width="610" height="400" as="geometry" />
</mxCell>
<mxCell id="hUmURhrymKCytomf8O3q-21" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;fillColor=#e3c800;strokeColor=#B09500;" parent="hUmURhrymKCytomf8O3q-268" target="hUmURhrymKCytomf8O3q-13" edge="1">
<mxGeometry relative="1" as="geometry">
<mxPoint y="120" as="sourcePoint" />
</mxGeometry>
</mxCell>
<mxCell id="hUmURhrymKCytomf8O3q-22" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;fillColor=#e3c800;strokeColor=#B09500;" parent="hUmURhrymKCytomf8O3q-268" source="hUmURhrymKCytomf8O3q-16" edge="1">
<mxGeometry relative="1" as="geometry">
<mxPoint y="340" as="targetPoint" />
</mxGeometry>
</mxCell>
<mxCell id="wy1xcPKCa-p-PBI3JPLa-84" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;fillColor=#fa6800;strokeColor=#C73500;movable=1;resizable=1;rotatable=1;deletable=1;editable=1;locked=0;connectable=1;" parent="hUmURhrymKCytomf8O3q-268" source="wy1xcPKCa-p-PBI3JPLa-85" edge="1">
<mxGeometry relative="1" as="geometry">
<mxPoint x="610" y="120" as="targetPoint" />
</mxGeometry>
</mxCell>
<mxCell id="wy1xcPKCa-p-PBI3JPLa-85" value="Packet Generator" style="rounded=0;whiteSpace=wrap;html=1;movable=1;resizable=1;rotatable=1;deletable=1;editable=1;locked=0;connectable=1;container=0;" parent="hUmURhrymKCytomf8O3q-268" vertex="1">
<mxGeometry x="430" y="80.07" width="120" height="80" as="geometry" />
</mxCell>
<mxCell id="wy1xcPKCa-p-PBI3JPLa-87" value="" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;fillColor=#e3c800;strokeColor=#B09500;movable=1;resizable=1;rotatable=1;deletable=1;editable=1;locked=0;connectable=1;" parent="hUmURhrymKCytomf8O3q-268" source="wy1xcPKCa-p-PBI3JPLa-88" target="wy1xcPKCa-p-PBI3JPLa-85" edge="1">
<mxGeometry relative="1" as="geometry" />
</mxCell>
<mxCell id="wy1xcPKCa-p-PBI3JPLa-88" value="TX Control" style="rounded=0;whiteSpace=wrap;html=1;movable=1;resizable=1;rotatable=1;deletable=1;editable=1;locked=0;connectable=1;container=0;" parent="hUmURhrymKCytomf8O3q-268" vertex="1">
<mxGeometry x="310" y="100.07" width="80" height="40" as="geometry" />
</mxCell>
<mxCell id="wy1xcPKCa-p-PBI3JPLa-89" value="" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;fillColor=#e3c800;strokeColor=#B09500;movable=1;resizable=1;rotatable=1;deletable=1;editable=1;locked=0;connectable=1;exitX=1;exitY=0.5;exitDx=0;exitDy=0;" parent="hUmURhrymKCytomf8O3q-268" source="hUmURhrymKCytomf8O3q-13" target="wy1xcPKCa-p-PBI3JPLa-88" edge="1">
<mxGeometry relative="1" as="geometry">
<mxPoint x="270.0000000000002" y="120.06999999999994" as="sourcePoint" />
</mxGeometry>
</mxCell>
<mxCell id="wy1xcPKCa-p-PBI3JPLa-90" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;entryX=0.5;entryY=1;entryDx=0;entryDy=0;movable=1;resizable=1;rotatable=1;deletable=1;editable=1;locked=0;connectable=1;" parent="hUmURhrymKCytomf8O3q-268" source="wy1xcPKCa-p-PBI3JPLa-92" target="wy1xcPKCa-p-PBI3JPLa-88" edge="1">
<mxGeometry relative="1" as="geometry" />
</mxCell>
<mxCell id="wy1xcPKCa-p-PBI3JPLa-91" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;exitX=0.75;exitY=0;exitDx=0;exitDy=0;entryX=0.25;entryY=1;entryDx=0;entryDy=0;movable=1;resizable=1;rotatable=1;deletable=1;editable=1;locked=0;connectable=1;" parent="hUmURhrymKCytomf8O3q-268" source="wy1xcPKCa-p-PBI3JPLa-92" target="wy1xcPKCa-p-PBI3JPLa-85" edge="1">
<mxGeometry relative="1" as="geometry" />
</mxCell>
<mxCell id="wy1xcPKCa-p-PBI3JPLa-92" value="TCP State Manager" style="rounded=0;whiteSpace=wrap;html=1;movable=1;resizable=1;rotatable=1;deletable=1;editable=1;locked=0;connectable=1;container=0;" parent="hUmURhrymKCytomf8O3q-268" vertex="1">
<mxGeometry x="310" y="200.07" width="80" height="40" as="geometry" />
</mxCell>
<mxCell id="wy1xcPKCa-p-PBI3JPLa-93" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;exitX=0.25;exitY=0;exitDx=0;exitDy=0;entryX=0.75;entryY=1;entryDx=0;entryDy=0;movable=1;resizable=1;rotatable=1;deletable=1;editable=1;locked=0;connectable=1;" parent="hUmURhrymKCytomf8O3q-268" source="wy1xcPKCa-p-PBI3JPLa-94" target="wy1xcPKCa-p-PBI3JPLa-92" edge="1">
<mxGeometry relative="1" as="geometry" />
</mxCell>
<mxCell id="wy1xcPKCa-p-PBI3JPLa-94" value="Parser" style="rounded=0;whiteSpace=wrap;html=1;movable=1;resizable=1;rotatable=1;deletable=1;editable=1;locked=0;connectable=1;container=0;" parent="hUmURhrymKCytomf8O3q-268" vertex="1">
<mxGeometry x="430" y="320.07000000000005" width="120" height="40" as="geometry" />
</mxCell>
<mxCell id="wy1xcPKCa-p-PBI3JPLa-95" value="" style="endArrow=classic;html=1;rounded=0;entryX=1;entryY=0.5;entryDx=0;entryDy=0;fillColor=#fa6800;strokeColor=#C73500;movable=1;resizable=1;rotatable=1;deletable=1;editable=1;locked=0;connectable=1;" parent="hUmURhrymKCytomf8O3q-268" target="wy1xcPKCa-p-PBI3JPLa-94" edge="1">
<mxGeometry width="50" height="50" relative="1" as="geometry">
<mxPoint x="610" y="340" as="sourcePoint" />
<mxPoint x="530" y="180.07" as="targetPoint" />
</mxGeometry>
</mxCell>
<mxCell id="wy1xcPKCa-p-PBI3JPLa-96" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;entryX=0.5;entryY=1;entryDx=0;entryDy=0;movable=1;resizable=1;rotatable=1;deletable=1;editable=1;locked=0;connectable=1;" parent="hUmURhrymKCytomf8O3q-268" source="wy1xcPKCa-p-PBI3JPLa-97" target="wy1xcPKCa-p-PBI3JPLa-92" edge="1">
<mxGeometry relative="1" as="geometry" />
</mxCell>
<mxCell id="wy1xcPKCa-p-PBI3JPLa-97" value="RX Control" style="rounded=0;whiteSpace=wrap;html=1;movable=1;resizable=1;rotatable=1;deletable=1;editable=1;locked=0;connectable=1;container=0;" parent="hUmURhrymKCytomf8O3q-268" vertex="1">
<mxGeometry x="310" y="320.07000000000005" width="80" height="40" as="geometry" />
</mxCell>
<mxCell id="wy1xcPKCa-p-PBI3JPLa-98" value="" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;fillColor=#fa6800;strokeColor=#C73500;movable=1;resizable=1;rotatable=1;deletable=1;editable=1;locked=0;connectable=1;" parent="hUmURhrymKCytomf8O3q-268" source="wy1xcPKCa-p-PBI3JPLa-94" target="wy1xcPKCa-p-PBI3JPLa-97" edge="1">
<mxGeometry relative="1" as="geometry" />
</mxCell>
<mxCell id="wy1xcPKCa-p-PBI3JPLa-101" value="" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;fillColor=#e3c800;strokeColor=#B09500;movable=1;resizable=1;rotatable=1;deletable=1;editable=1;locked=0;connectable=1;entryX=1;entryY=0.5;entryDx=0;entryDy=0;" parent="hUmURhrymKCytomf8O3q-268" source="wy1xcPKCa-p-PBI3JPLa-97" target="hUmURhrymKCytomf8O3q-16" edge="1">
<mxGeometry relative="1" as="geometry">
<mxPoint x="270.0000000000002" y="340.07000000000016" as="targetPoint" />
</mxGeometry>
</mxCell>
<mxCell id="wy1xcPKCa-p-PBI3JPLa-102" value="REGS" style="rounded=0;whiteSpace=wrap;html=1;movable=1;resizable=1;rotatable=1;deletable=1;editable=1;locked=0;connectable=1;container=0;" parent="hUmURhrymKCytomf8O3q-268" vertex="1">
<mxGeometry x="430" y="9.999999999999993" width="120" height="60" as="geometry" />
</mxCell>
<mxCell id="hUmURhrymKCytomf8O3q-16" value="4k/128 SAF" style="rounded=0;whiteSpace=wrap;html=1;container=0;" parent="hUmURhrymKCytomf8O3q-268" vertex="1">
<mxGeometry x="80" y="310" width="120" height="60" as="geometry" />
</mxCell>
<mxCell id="hUmURhrymKCytomf8O3q-13" value="4k/128 SAF" style="rounded=0;whiteSpace=wrap;html=1;container=0;" parent="hUmURhrymKCytomf8O3q-268" vertex="1">
<mxGeometry x="80" y="90.07" width="120" height="60" as="geometry" />
</mxCell>
<mxCell id="hUmURhrymKCytomf8O3q-345" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;startArrow=classic;startFill=1;endArrow=none;endFill=0;fillColor=#6a00ff;strokeColor=#3700CC;exitX=0.5;exitY=0;exitDx=0;exitDy=0;entryX=0.625;entryY=1;entryDx=0;entryDy=0;entryPerimeter=0;" parent="1" source="wy1xcPKCa-p-PBI3JPLa-102" target="wy1xcPKCa-p-PBI3JPLa-122" edge="1">
<mxGeometry relative="1" as="geometry">
<mxPoint x="650" y="170" as="targetPoint" />
<Array as="points" />
<mxPoint x="730.0000000000002" y="270" as="sourcePoint" />
</mxGeometry>
</mxCell>
<mxCell id="hUmURhrymKCytomf8O3q-349" value="" style="endArrow=classic;html=1;rounded=0;fillColor=#e3c800;strokeColor=#B09500;exitX=1;exitY=0.25;exitDx=0;exitDy=0;" parent="1" edge="1" source="hUmURhrymKCytomf8O3q-23">
<mxGeometry width="50" height="50" relative="1" as="geometry">
<mxPoint x="80" y="320.03" as="sourcePoint" />
<mxPoint x="130" y="320.03" as="targetPoint" />
</mxGeometry>
</mxCell>
<mxCell id="hUmURhrymKCytomf8O3q-350" value="" style="endArrow=classic;html=1;rounded=0;fillColor=#e3c800;strokeColor=#B09500;exitX=1;exitY=0.374;exitDx=0;exitDy=0;exitPerimeter=0;" parent="1" edge="1" source="hUmURhrymKCytomf8O3q-23">
<mxGeometry width="50" height="50" relative="1" as="geometry">
<mxPoint x="80" y="330" as="sourcePoint" />
<mxPoint x="140" y="330" as="targetPoint" />
</mxGeometry>
</mxCell>
<mxCell id="hUmURhrymKCytomf8O3q-351" value="" style="endArrow=classic;html=1;rounded=0;fillColor=#e3c800;strokeColor=#B09500;exitX=1;exitY=0.5;exitDx=0;exitDy=0;" parent="1" edge="1" source="hUmURhrymKCytomf8O3q-23">
<mxGeometry width="50" height="50" relative="1" as="geometry">
<mxPoint x="80" y="340" as="sourcePoint" />
<mxPoint x="150" y="340" as="targetPoint" />
</mxGeometry>
</mxCell>
<mxCell id="hUmURhrymKCytomf8O3q-352" value="" style="endArrow=classic;html=1;rounded=0;fillColor=#e3c800;strokeColor=#B09500;exitX=1;exitY=0.624;exitDx=0;exitDy=0;exitPerimeter=0;" parent="1" edge="1" source="hUmURhrymKCytomf8O3q-23">
<mxGeometry width="50" height="50" relative="1" as="geometry">
<mxPoint x="80" y="350" as="sourcePoint" />
<mxPoint x="160" y="350" as="targetPoint" />
</mxGeometry>
</mxCell>
<mxCell id="hUmURhrymKCytomf8O3q-353" value="" style="endArrow=classic;html=1;rounded=0;fillColor=#e3c800;strokeColor=#B09500;entryX=1;entryY=0.25;entryDx=0;entryDy=0;" parent="1" edge="1" target="hUmURhrymKCytomf8O3q-24">
<mxGeometry width="50" height="50" relative="1" as="geometry">
<mxPoint x="129.97" y="540" as="sourcePoint" />
<mxPoint x="79.97" y="540" as="targetPoint" />
</mxGeometry>
</mxCell>
<mxCell id="hUmURhrymKCytomf8O3q-354" value="" style="endArrow=classic;html=1;rounded=0;fillColor=#e3c800;strokeColor=#B09500;entryX=1;entryY=0.375;entryDx=0;entryDy=0;entryPerimeter=0;" parent="1" edge="1" target="hUmURhrymKCytomf8O3q-24">
<mxGeometry width="50" height="50" relative="1" as="geometry">
<mxPoint x="139.97" y="549.97" as="sourcePoint" />
<mxPoint x="79.97" y="549.97" as="targetPoint" />
</mxGeometry>
</mxCell>
<mxCell id="hUmURhrymKCytomf8O3q-355" value="" style="endArrow=classic;html=1;rounded=0;fillColor=#e3c800;strokeColor=#B09500;entryX=1;entryY=0.5;entryDx=0;entryDy=0;" parent="1" edge="1" target="hUmURhrymKCytomf8O3q-24">
<mxGeometry width="50" height="50" relative="1" as="geometry">
<mxPoint x="149.97" y="559.97" as="sourcePoint" />
<mxPoint x="10" y="560" as="targetPoint" />
</mxGeometry>
</mxCell>
<mxCell id="hUmURhrymKCytomf8O3q-356" value="" style="endArrow=classic;html=1;rounded=0;fillColor=#e3c800;strokeColor=#B09500;entryX=1;entryY=0.625;entryDx=0;entryDy=0;entryPerimeter=0;" parent="1" edge="1" target="hUmURhrymKCytomf8O3q-24">
<mxGeometry width="50" height="50" relative="1" as="geometry">
<mxPoint x="159.97" y="569.97" as="sourcePoint" />
<mxPoint x="79.97" y="569.97" as="targetPoint" />
</mxGeometry>
</mxCell>
<mxCell id="1vVpc469gqlHnz9TW-pm-9" value="" style="endArrow=classic;html=1;rounded=0;fillColor=#d80073;strokeColor=#A50040;" parent="1" edge="1">
<mxGeometry width="50" height="50" relative="1" as="geometry">
<mxPoint x="159.97" y="720" as="sourcePoint" />
<mxPoint x="240" y="720" as="targetPoint" />
</mxGeometry>
</mxCell>
<mxCell id="1vVpc469gqlHnz9TW-pm-11" value="axi4-lite" style="edgeLabel;html=1;align=center;verticalAlign=middle;resizable=0;points=[];" parent="1vVpc469gqlHnz9TW-pm-9" vertex="1" connectable="0">
<mxGeometry x="0.2037" y="2" relative="1" as="geometry">
<mxPoint x="-8" y="-8" as="offset" />
</mxGeometry>
</mxCell>
<mxCell id="1vVpc469gqlHnz9TW-pm-12" value="" style="endArrow=classic;html=1;rounded=0;fillColor=#e3c800;strokeColor=#B09500;" parent="1" edge="1">
<mxGeometry width="50" height="50" relative="1" as="geometry">
<mxPoint x="279.97" y="720" as="sourcePoint" />
<mxPoint x="360" y="720" as="targetPoint" />
</mxGeometry>
</mxCell>
<mxCell id="1vVpc469gqlHnz9TW-pm-13" value="axi4-stream" style="edgeLabel;html=1;align=center;verticalAlign=middle;resizable=0;points=[];" parent="1vVpc469gqlHnz9TW-pm-12" vertex="1" connectable="0">
<mxGeometry x="0.2037" y="2" relative="1" as="geometry">
<mxPoint x="-8" y="-8" as="offset" />
</mxGeometry>
</mxCell>
<mxCell id="1vVpc469gqlHnz9TW-pm-14" value="" style="endArrow=classic;html=1;rounded=0;fillColor=#0050ef;strokeColor=#001DBC;" parent="1" edge="1">
<mxGeometry width="50" height="50" relative="1" as="geometry">
<mxPoint x="400" y="720" as="sourcePoint" />
<mxPoint x="480" y="720" as="targetPoint" />
</mxGeometry>
</mxCell>
<mxCell id="1vVpc469gqlHnz9TW-pm-15" value="cpuif" style="edgeLabel;html=1;align=center;verticalAlign=middle;resizable=0;points=[];" parent="1vVpc469gqlHnz9TW-pm-14" vertex="1" connectable="0">
<mxGeometry x="0.2037" y="2" relative="1" as="geometry">
<mxPoint x="-8" y="-8" as="offset" />
</mxGeometry>
</mxCell>
<mxCell id="1vVpc469gqlHnz9TW-pm-16" value="" style="endArrow=classic;html=1;rounded=0;fillColor=#fa6800;strokeColor=#C73500;" parent="1" edge="1">
<mxGeometry width="50" height="50" relative="1" as="geometry">
<mxPoint x="520" y="720" as="sourcePoint" />
<mxPoint x="600" y="720" as="targetPoint" />
</mxGeometry>
</mxCell>
<mxCell id="1vVpc469gqlHnz9TW-pm-17" value="ip-stream" style="edgeLabel;html=1;align=center;verticalAlign=middle;resizable=0;points=[];" parent="1vVpc469gqlHnz9TW-pm-16" vertex="1" connectable="0">
<mxGeometry x="0.2037" y="2" relative="1" as="geometry">
<mxPoint x="-8" y="-8" as="offset" />
</mxGeometry>
</mxCell>
<mxCell id="DDA_X_hQHvZcJVnLFhaM-8" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;entryX=0.5;entryY=1;entryDx=0;entryDy=0;fillColor=#fa6800;strokeColor=#C73500;" parent="1" source="DDA_X_hQHvZcJVnLFhaM-3" target="wy1xcPKCa-p-PBI3JPLa-133" edge="1">
<mxGeometry relative="1" as="geometry" />
</mxCell>
<mxCell id="DDA_X_hQHvZcJVnLFhaM-3" value="port mapper" style="rounded=0;whiteSpace=wrap;html=1;" parent="1" vertex="1">
<mxGeometry x="920" y="540" width="80" height="40" as="geometry" />
</mxCell>
<mxCell id="DDA_X_hQHvZcJVnLFhaM-4" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;entryX=0.375;entryY=0;entryDx=0;entryDy=0;entryPerimeter=0;" parent="1" source="wy1xcPKCa-p-PBI3JPLa-92" target="DDA_X_hQHvZcJVnLFhaM-3" edge="1">
<mxGeometry relative="1" as="geometry" />
</mxCell>
<mxCell id="DDA_X_hQHvZcJVnLFhaM-5" value="" style="endArrow=classic;html=1;rounded=0;entryX=0.5;entryY=0;entryDx=0;entryDy=0;" parent="1" target="DDA_X_hQHvZcJVnLFhaM-3" edge="1">
<mxGeometry width="50" height="50" relative="1" as="geometry">
<mxPoint x="770" y="440" as="sourcePoint" />
<mxPoint x="780" y="410" as="targetPoint" />
<Array as="points">
<mxPoint x="960" y="440" />
</Array>
</mxGeometry>
</mxCell>
<mxCell id="DDA_X_hQHvZcJVnLFhaM-6" value="" style="endArrow=classic;html=1;rounded=0;entryX=0.625;entryY=0;entryDx=0;entryDy=0;entryPerimeter=0;" parent="1" target="DDA_X_hQHvZcJVnLFhaM-3" edge="1">
<mxGeometry width="50" height="50" relative="1" as="geometry">
<mxPoint x="770" y="430" as="sourcePoint" />
<mxPoint x="970" y="550" as="targetPoint" />
<Array as="points">
<mxPoint x="970" y="430" />
</Array>
</mxGeometry>
</mxCell>
<mxCell id="DDA_X_hQHvZcJVnLFhaM-7" value="" style="endArrow=classic;html=1;rounded=0;entryX=0.75;entryY=0;entryDx=0;entryDy=0;" parent="1" target="DDA_X_hQHvZcJVnLFhaM-3" edge="1">
<mxGeometry width="50" height="50" relative="1" as="geometry">
<mxPoint x="770" y="420" as="sourcePoint" />
<mxPoint x="980" y="560" as="targetPoint" />
<Array as="points">
<mxPoint x="980" y="420" />
</Array>
</mxGeometry>
</mxCell>
<mxCell id="DDA_X_hQHvZcJVnLFhaM-9" value="" style="endArrow=classic;html=1;rounded=0;entryX=1;entryY=0.5;entryDx=0;entryDy=0;fillColor=#fa6800;strokeColor=#C73500;" parent="1" target="DDA_X_hQHvZcJVnLFhaM-3" edge="1">
<mxGeometry width="50" height="50" relative="1" as="geometry">
<mxPoint x="1040" y="560" as="sourcePoint" />
<mxPoint x="1020" y="520" as="targetPoint" />
</mxGeometry>
</mxCell>
</root>
</mxGraphModel>
</diagram>
</mxfile>

Binary file not shown.

After

Width:  |  Height:  |  Size: 142 KiB

View File

@@ -0,0 +1,24 @@
RTL_SRCS_LIST=$(REPO_TOP)/hw/super6502_fpga/sources.list
SIM_SRCS_LIST=tb/sources.list
RTL_SOURCES=$(shell rtl-manifest $(RTL_SRCS_LIST))
SIM_SOURCES=$(shell rtl-manifest $(SIM_SRCS_LIST))
VERILOG_SOURCES= $(INTF_SOURCES) $(RTL_SOURCES) $(SIM_SOURCES)
TOPLEVEL_LANG ?= verilog
SIM ?= verilator
EXTRA_ARGS += --trace --trace-fst --trace-structs -Wno-fatal -Wno-PINMISSING
TOPLEVEL = tb_top
GPI_IMPL := vpi
export PYTHONPATH := $(PWD)/tests:$(PYTHONPATH)
export TOPLEVEL_LANG
MODULE=scapy_irl_test
include $(shell cocotb-config --makefiles)/Makefile.sim

View File

@@ -0,0 +1 @@
tb_top.sv

View File

@@ -0,0 +1,120 @@
module tb_top(
input wire clk,
input wire rst,
output wire s_regs_axil_awready,
input wire s_regs_axil_awvalid,
input wire [31:0] s_regs_axil_awaddr,
input wire [2:0] s_regs_axil_awprot,
output wire s_regs_axil_wready,
input wire s_regs_axil_wvalid,
input wire [31:0] s_regs_axil_wdata,
input wire [3:0] s_regs_axil_wstrb,
input wire s_regs_axil_bready,
output wire s_regs_axil_bvalid,
output wire [1:0] s_regs_axil_bresp,
output wire s_regs_axil_arready,
input wire s_regs_axil_arvalid,
input wire [31:0] s_regs_axil_araddr,
input wire [2:0] s_regs_axil_arprot,
input wire s_regs_axil_rready,
output wire s_regs_axil_rvalid,
output wire [31:0] s_regs_axil_rdata,
output wire [1:0] s_regs_axil_rresp,
input wire m_dma_axil_awready,
output wire m_dma_axil_awvalid,
output wire [31:0] m_dma_axil_awaddr,
output wire [2:0] m_dma_axil_awprot,
input wire m_dma_axil_wready,
output wire m_dma_axil_wvalid,
output wire [31:0] m_dma_axil_wdata,
output wire [3:0] m_dma_axil_wstrb,
output wire m_dma_axil_bready,
input wire m_dma_axil_bvalid,
input wire [1:0] m_dma_axil_bresp,
input wire m_dma_axil_arready,
output wire m_dma_axil_arvalid,
output wire [31:0] m_dma_axil_araddr,
output wire [2:0] m_dma_axil_arprot,
output wire m_dma_axil_rready,
input wire m_dma_axil_rvalid,
input wire [31:0] m_dma_axil_rdata,
input wire [1:0] m_dma_axil_rresp,
//MII Interface
input wire mii_rx_clk,
input wire [3:0] mii_rxd,
input wire mii_rx_dv,
input wire mii_rx_er,
input wire mii_tx_clk,
output wire [3:0] mii_txd,
output wire mii_tx_en,
output wire mii_tx_er
);
axil_intf regs_axil();
axil_intf dma_axil();
assign dma_axil.awready = m_dma_axil_awready;
assign m_dma_axil_awvalid = dma_axil.awvalid;
assign m_dma_axil_awaddr = dma_axil.awaddr;
assign m_dma_axil_awprot = dma_axil.awprot;
assign dma_axil.wready = m_dma_axil_wready;
assign m_dma_axil_wvalid = dma_axil.wvalid;
assign m_dma_axil_wdata = dma_axil.wdata;
assign m_dma_axil_wstrb = dma_axil.wstrb;
assign m_dma_axil_bready = dma_axil.bready;
assign dma_axil.bvalid = m_dma_axil_bvalid;
assign dma_axil.bresp = m_dma_axil_bresp;
assign dma_axil.arready = m_dma_axil_arready;
assign m_dma_axil_arvalid = dma_axil.arvalid;
assign m_dma_axil_araddr = dma_axil.araddr;
assign m_dma_axil_arprot = dma_axil.arprot;
assign m_dma_axil_rready = dma_axil.rready;
assign dma_axil.rvalid = m_dma_axil_rvalid;
assign dma_axil.rdata = m_dma_axil_rdata;
assign dma_axil.rresp = m_dma_axil_rresp;
assign s_regs_axil_awready = regs_axil.awready;
assign regs_axil.awvalid = s_regs_axil_awvalid;
assign regs_axil.awaddr = s_regs_axil_awaddr;
assign regs_axil.awprot = s_regs_axil_awprot;
assign s_regs_axil_wready = regs_axil.wready;
assign regs_axil.wvalid = s_regs_axil_wvalid;
assign regs_axil.wdata = s_regs_axil_wdata;
assign regs_axil.wstrb = s_regs_axil_wstrb;
assign regs_axil.bready = s_regs_axil_bready;
assign s_regs_axil_bvalid = regs_axil.bvalid;
assign s_regs_axil_bresp = regs_axil.bresp;
assign s_regs_axil_arready = regs_axil.arready;
assign regs_axil.arvalid = s_regs_axil_arvalid;
assign regs_axil.araddr = s_regs_axil_araddr;
assign regs_axil.arprot = s_regs_axil_arprot;
assign regs_axil.rready = s_regs_axil_rready;
assign s_regs_axil_rvalid = regs_axil.rvalid;
assign s_regs_axil_rdata = regs_axil.rdata;
assign s_regs_axil_rresp = regs_axil.rresp;
network_processor #(
.NUM_TCP(4)
) u_network_processor (
.i_clk (clk),
.i_rst (rst),
.s_reg_axil (regs_axil),
.m_dma_axil (dma_axil),
.mii_rx_clk (mii_rx_clk),
.mii_rxd (mii_rxd),
.mii_rx_dv (mii_rx_dv),
.mii_rx_er (mii_rx_er),
.mii_tx_clk (mii_tx_clk),
.mii_txd (mii_txd),
.mii_tx_en (mii_tx_en),
.mii_tx_er (mii_tx_er)
);
endmodule

View File

@@ -0,0 +1,466 @@
from scapy.data import IP_PROTOS
from scapy import sendrecv
from scapy.config import conf
from scapy.supersocket import L3RawSocket
import cocotb
from cocotb.clock import Clock
from cocotb.triggers import Timer
from cocotb.triggers import RisingEdge
from cocotbext.axi import AxiLiteBus, AxiLiteMaster, AxiLiteRam
from cocotbext.eth import MiiPhy, GmiiFrame
import struct
from scapy.layers.inet import IP, TCP
from scapy.layers.l2 import ARP, Ether
from scapy.packet import Packet
from scapy.utils import PcapWriter
from scapy.layers.tuntap import TunTapInterface
import logging
from decimal import Decimal
import random
CLK_PERIOD_NS = 10
MII_CLK_PERIOD_NS = 40
import socket
# In order for this to work, you need to run these commands:
# sudo ip tuntap add name tun0 mode tun group netdev
# sudo ip a add 172.0.0.1 peer 172.0.0.2 dev tun0
# sudo ip link set tun0 up
def main():
serversocket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
serversocket.bind(("172.0.0.1", 5678))
serversocket.listen(5)
t = TunTapInterface('tun0')
tcp_syn = IP(src="172.0.0.2", dst="172.0.0.1")/TCP(sport=1234, dport=5678, seq=0, ack=0, flags="S")
t.send(tcp_syn)
pkt = t.recv()
print(pkt)
if __name__ == "__main__":
main()
class TB:
def __init__(self, dut):
self.dut = dut
self.log = logging.getLogger("cocotb.tb")
self.log.setLevel(logging.DEBUG)
cocotb.start_soon(Clock(dut.clk, CLK_PERIOD_NS, units="ns").start())
cocotb.start_soon(Clock(dut.mii_rx_clk, MII_CLK_PERIOD_NS, units="ns").start())
cocotb.start_soon(Clock(dut.mii_tx_clk, MII_CLK_PERIOD_NS, units="ns").start())
self.axil_master = AxiLiteMaster(AxiLiteBus.from_prefix(dut, "s_regs_axil"), dut.clk, dut.rst)
self.axil_ram = AxiLiteRam(AxiLiteBus.from_prefix(dut, "m_dma_axil"), dut.clk, dut.rst, size=2**16)
self.mii_phy = MiiPhy(dut.mii_txd, dut.mii_tx_er, dut.mii_tx_en, dut.mii_tx_clk,
dut.mii_rxd, dut.mii_rx_er, dut.mii_rx_dv, dut.mii_rx_clk, None, speed=100e6)
async def cycle_reset(self):
self.dut.rst.setimmediatevalue(0)
await RisingEdge(self.dut.clk) # type: ignore
await RisingEdge(self.dut.clk) # type: ignore
self.dut.rst.value = 1
await RisingEdge(self.dut.clk) # type: ignore
await RisingEdge(self.dut.clk) # type: ignore
self.dut.rst.value = 0
await RisingEdge(self.dut.clk) # type: ignore
await RisingEdge(self.dut.clk) # type: ignore
def ip_to_hex(ip: str) -> int:
octets = [int(i) for i in ip.split(".")]
result = int.from_bytes(struct.pack("BBBB", octets[0], octets[1], octets[2], octets[3]))
return result
@cocotb.test()
async def test_irl(dut):
tb = TB(dut)
async def read_tcp_from_dut():
resp = await tb.mii_phy.tx.recv() # type: GmiiFrame
packet = Ether(resp.get_payload())
tb.log.info(f"Packet Type: {packet.type:x}")
ip_packet = packet.payload
assert isinstance(ip_packet, IP)
tcp_packet = ip_packet.payload
assert isinstance(tcp_packet, TCP)
tb.log.info(f"Source Port: {tcp_packet.sport}")
tb.log.info(f"Dest Port: {tcp_packet.dport}")
tb.log.info(f"Seq: {tcp_packet.seq}")
tb.log.info(f"Ack: {tcp_packet.ack}")
tb.log.info(f"Data Offs: {tcp_packet.dataofs}")
tb.log.info(f"flags: {tcp_packet.flags}")
tb.log.info(f"window: {tcp_packet.window}")
tb.log.info(f"Checksum: {tcp_packet.chksum}")
return ip_packet
#############################
# Reset DUT #
#############################
await tb.cycle_reset()
dut_ip = "172.0.0.2"
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)
while True:
pkt = t.recv()
assert isinstance(pkt, Packet)
if (pkt.proto == IP_PROTOS.tcp):
break
print(pkt)
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()
###############################
# Send data from DUT to host #
###############################
# Construct a descriptor in memry
tb.axil_ram.write_dword(0x00000000, 0x00001000)
tb.axil_ram.write_dword(0x00000004, 64)
tb.axil_ram.write_dword(0x00000008, 0)
tb.axil_ram.write_dword(0x0000000c, 0)
test_data = bytearray([x % 256 for x in range(256)])
tb.axil_ram.write(0x1000, test_data)
await tb.axil_master.write_dword(0x22c, 0)
await tb.axil_master.write_dword(0x220, 0x00000000)
await tb.axil_master.write_dword(0x224, 0x00000000)
resp = await tb.mii_phy.tx.recv() # type: GmiiFrame
packet = Ether(resp.get_payload())
t.send(packet.payload)
con.recv(64)
tb.log.info("Received 64 packets")
###############################
# Close connection from host #
###############################
con.close()
serversocket.close()
while True:
pkt = t.recv()
assert isinstance(pkt, Packet)
if (pkt.proto == IP_PROTOS.tcp):
break
print(pkt)
tcp_ack = Ether(dst=dut_mac, src=tb_mac) / pkt
await tb.mii_phy.rx.send(GmiiFrame.from_payload(tcp_ack.build()))
tb.log.info("Expecting to send an F here")
while True:
pkt = t.recv()
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()))
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
packet = Ether(resp.get_payload())
tb.log.info(f"Packet Type: {packet.type:x}")
ip_packet = packet.payload
assert isinstance(ip_packet, IP)
tcp_packet = ip_packet.payload
assert isinstance(tcp_packet, TCP)
tb.log.info(f"Source Port: {tcp_packet.sport}")
tb.log.info(f"Dest Port: {tcp_packet.dport}")
tb.log.info(f"Seq: {tcp_packet.seq}")
tb.log.info(f"Ack: {tcp_packet.ack}")
tb.log.info(f"Data Offs: {tcp_packet.dataofs}")
tb.log.info(f"flags: {tcp_packet.flags}")
tb.log.info(f"window: {tcp_packet.window}")
tb.log.info(f"Checksum: {tcp_packet.chksum}")
return ip_packet
def get_pkt_from_host():
while True:
pkt = t.recv()
assert isinstance(pkt, Packet)
if (pkt.proto == IP_PROTOS.tcp):
break
print(pkt)
return pkt
#############################
# Reset DUT #
#############################
await tb.cycle_reset()
dut_ip = "172.0.0.2"
tb_ip = "172.0.0.1"
tb_mac = "02:00:00:11:22:33"
dut_port = random.randint(1024, 65535)
tb_port = random.randint(1024, 65535)
serversocket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
serversocket.bind((tb_ip, tb_port))
serversocket.listen(1)
t = TunTapInterface('tun0')
###############################
# Configure DUT Network block #
###############################
await tb.axil_master.write_dword(0x0, 0x1807)
await tb.axil_master.write_dword(0x200, dut_port)
await tb.axil_master.write_dword(0x204, ip_to_hex(dut_ip))
await tb.axil_master.write_dword(0x208, tb_port)
await tb.axil_master.write_dword(0x20c, ip_to_hex(tb_ip))
await tb.axil_master.write_dword(0x210, 0x3)
resp = await tb.mii_phy.tx.recv() # type: GmiiFrame
packet = Ether(resp.get_payload())
tb.log.info(f"Packet Type: {packet.type:x}")
assert packet.type == 0x806, "Packet type is not ARP!"
arp_request = packet.payload
assert isinstance(arp_request, ARP)
tb.log.info(f"Arp OP: {arp_request.op}")
tb.log.info(f"Arp hwsrc: {arp_request.hwsrc}")
tb.log.info(f"Arp hwdst: {arp_request.hwdst}")
tb.log.info(f"Arp psrc: {arp_request.psrc}")
tb.log.info(f"Arp pdst: {arp_request.pdst}")
dut_mac = arp_request.hwsrc
dut_ip = arp_request.psrc
assert arp_request.op == 1, "ARP type is not request!"
assert arp_request.hwsrc == "02:00:00:aa:bb:cc", "ARP hwsrc does not match expected"
assert arp_request.hwdst == "00:00:00:00:00:00", "ARP hwdst does not match expected"
assert arp_request.psrc == dut_ip, "ARP psrc does not match expected"
assert arp_request.pdst == tb_ip, "ARP pdst does not match expected"
# hardcode the ARP response for now
arp_response = Ether(dst=dut_mac, src=tb_mac)
arp_response /= ARP(op="is-at", hwsrc=tb_mac, hwdst=dut_mac, psrc=tb_ip, pdst=dut_ip)
arp_response = arp_response.build()
await tb.mii_phy.rx.send(GmiiFrame.from_payload(arp_response))
###############################
# Start TCP handshake #
###############################
ip_packet = await read_tcp_from_dut()
t.send(ip_packet)
pkt = get_pkt_from_host()
tcp_synack = Ether(dst=dut_mac, src=tb_mac) / pkt
await tb.mii_phy.rx.send(GmiiFrame.from_payload(tcp_synack.build()))
ip_packet = await read_tcp_from_dut()
t.send(ip_packet)
con, addr = serversocket.accept()
tb.log.info(f"con_timeout: {con.timeout}")
###############################
# Close connection from DUT #
###############################
tb.log.info("Closing connection from the DUT side")
await tb.axil_master.write_dword(0x210, 5)
ip_packet = await read_tcp_from_dut()
tb.log.info("Sending packet to host")
t.send(ip_packet)
pkt = get_pkt_from_host()
tcp_synack = Ether(dst=dut_mac, src=tb_mac) / pkt
tb.log.info("Sending reply to DUT, this should be an ACK?")
await tb.mii_phy.rx.send(GmiiFrame.from_payload(tcp_synack.build()))
tb.log.info(tcp_synack.flags)
# Host will send an ack first, then a finack?
tb.log.info("Closing server socket")
con.close()
serversocket.close()
pkt = get_pkt_from_host()
tcp_synack = Ether(dst=dut_mac, src=tb_mac) / pkt
tb.log.info("Sending packet to DUT, this should be a FINACK?")
await tb.mii_phy.rx.send(GmiiFrame.from_payload(tcp_synack.build()))
pkt = get_pkt_from_host()
tcp_synack = Ether(dst=dut_mac, src=tb_mac) / pkt
ip_packet = await read_tcp_from_dut()
tb.log.info("Sending packet to host")
t.send(ip_packet)
await Timer(Decimal(CLK_PERIOD_NS * 20000), units='ns')

View File

@@ -0,0 +1,215 @@
import cocotb
from cocotb.clock import Clock
from cocotb.triggers import Timer
from cocotb.triggers import RisingEdge
from cocotbext.axi import AxiLiteBus, AxiLiteMaster, AxiLiteRam
from cocotbext.eth import MiiPhy, GmiiFrame
import struct
from scapy.layers.inet import Ether, IP, TCP
from scapy.layers.l2 import ARP
from scapy.utils import PcapWriter
import logging
from decimal import Decimal
CLK_PERIOD_NS = 10
MII_CLK_PERIOD_NS = 40
class TB:
def __init__(self, dut):
self.dut = dut
self.log = logging.getLogger("cocotb.tb")
self.log.setLevel(logging.DEBUG)
cocotb.start_soon(Clock(dut.clk, CLK_PERIOD_NS, units="ns").start())
cocotb.start_soon(Clock(dut.mii_rx_clk, MII_CLK_PERIOD_NS, units="ns").start())
cocotb.start_soon(Clock(dut.mii_tx_clk, MII_CLK_PERIOD_NS, units="ns").start())
self.axil_master = AxiLiteMaster(AxiLiteBus.from_prefix(dut, "s_regs_axil"), dut.clk, dut.rst)
self.axil_ram = AxiLiteRam(AxiLiteBus.from_prefix(dut, "m_dma_axil"), dut.clk, dut.rst, size=2**16)
self.mii_phy = MiiPhy(dut.mii_txd, dut.mii_tx_er, dut.mii_tx_en, dut.mii_tx_clk,
dut.mii_rxd, dut.mii_rx_er, dut.mii_rx_dv, dut.mii_rx_clk, None, speed=100e6)
async def cycle_reset(self):
self.dut.rst.setimmediatevalue(0)
await RisingEdge(self.dut.clk) # type: ignore
await RisingEdge(self.dut.clk) # type: ignore
self.dut.rst.value = 1
await RisingEdge(self.dut.clk) # type: ignore
await RisingEdge(self.dut.clk) # type: ignore
self.dut.rst.value = 0
await RisingEdge(self.dut.clk) # type: ignore
await RisingEdge(self.dut.clk) # type: ignore
def ip_to_hex(ip: str) -> int:
octets = [int(i) for i in ip.split(".")]
result = int.from_bytes(struct.pack("BBBB", octets[0], octets[1], octets[2], octets[3]))
return result
@cocotb.test()
async def test_simple(dut):
pktdump = PcapWriter("tcp.pcapng", append=False, sync=True)
tb = TB(dut)
await tb.cycle_reset()
dut_ip = "172.0.0.2"
tb_ip = "172.0.0.1"
dut_port = 0x1234
tb_port = 0x5678
tb_mac = "02:00:00:11:22:33"
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())
pktdump.write(packet)
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"
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()
pktdump.write(arp_response)
await tb.mii_phy.rx.send(GmiiFrame.from_payload(arp_response))
# 1. DUT sends syn with seq number
resp = await tb.mii_phy.tx.recv() # type: GmiiFrame
packet = Ether(resp.get_payload())
pktdump.write(packet)
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}")
dut_seq = tcp_packet.seq
tb_seq = 11111111
# 2. Send SYNACK with seq as our sequence number, and ACK as their sequence number plus 1
tcp_synack = Ether(dst=dut_mac, src=tb_mac)
tcp_synack /= IP(src=tb_ip, dst=dut_ip)
tcp_synack /= TCP(sport=tb_port, dport=dut_port, seq=tb_seq, ack=dut_seq+1, flags="SA")
tcp_synack = tcp_synack.build()
pktdump.write(tcp_synack)
await tb.mii_phy.rx.send(GmiiFrame.from_payload(tcp_synack))
# 3. Receieve ACK with our sequence number plus 1
resp = await tb.mii_phy.tx.recv() # type: GmiiFrame
packet = Ether(resp.get_payload())
pktdump.write(packet)
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}")
assert tcp_packet.ack == tb_seq + 1
# Try to send a packet from M2S
# Construct a descriptor in memry
tb.axil_ram.write_dword(0x00000000, 0x00001000)
tb.axil_ram.write_dword(0x00000004, 64)
tb.axil_ram.write_dword(0x00000008, 0)
tb.axil_ram.write_dword(0x0000000c, 0)
test_data = bytearray([x % 256 for x in range(256)])
tb.axil_ram.write(0x1000, test_data)
await tb.axil_master.write_dword(0x22c, 0)
await tb.axil_master.write_dword(0x220, 0x00000000)
await tb.axil_master.write_dword(0x224, 0x00000000)
resp = await tb.mii_phy.tx.recv() # type: GmiiFrame
packet = Ether(resp.get_payload())
pktdump.write(packet)
tb.log.info(f"Packet Type: {packet.type:x}")
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}")
pktdump.close()

View File

@@ -0,0 +1,24 @@
src/regs/tcp_stream_regs_pkg.sv
src/regs/tcp_stream_regs.sv
src/regs/tcp_top_regfile_pkg.sv
src/regs/tcp_top_regfile.sv
src/regs/mac_regs_pkg.sv
src/regs/mac_regs.sv
src/regs/ntw_top_regfile_pkg.sv
src/regs/ntw_top_regfile.sv
src/network_processor.sv
src/tcp_pkg.sv
src/tcp_tx_ctrl.sv
src/tcp_rx_ctrl.sv
src/tcp_packet_generator.sv
src/tcp_state_manager.sv
src/tcp_stream.sv
src/tcp.sv
src/eth_wrapper.sv
src/ip_arb_mux_wrapper.sv
src/ip_demux_wrapper.sv
src/tcp_dest_decap.sv
src/tcp_parser.sv
src/checksum_calc.sv
src/ip_pipeline_register_wrapper.sv
src/axil_reg_slice.sv

View File

@@ -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

View File

@@ -0,0 +1,36 @@
module checksum_calc (
input i_rst,
input i_clk,
input i_clear,
input i_enable,
input [31:0] i_data,
output [15:0] o_checksum
);
logic [31:0] sum;
logic [31:0] pre_sum;
logic [31:0] sum_next;
logic [15:0] sum_wrapped;
assign sum_wrapped = sum[15:0] + sum [31:16];
assign o_checksum = ~sum_wrapped;
always @(posedge i_clk) begin
if (i_rst || i_clear) begin
sum <= '0;
end else begin
if (i_enable) begin
sum <= sum_next;
end
end
end
always_comb begin
pre_sum = i_data[31:16] + i_data[15:0];
sum_next = sum + pre_sum;
end
endmodule

View File

@@ -0,0 +1,133 @@
module eth_wrapper #(
parameter MAC_DATA_WIDTH=8,
parameter MAC_KEEP_WIDTH = ((MAC_DATA_WIDTH+7)/8)
)(
input wire rst,
input wire clk_sys,
axis_intf.SLAVE tx_axis,
axis_intf.MASTER rx_axis,
/*
* MII interface
*/
input wire mii_rx_clk,
input wire [3:0] mii_rxd,
input wire mii_rx_dv,
input wire mii_rx_er,
input wire mii_tx_clk,
output wire [3:0] mii_txd,
output wire mii_tx_en,
output wire mii_tx_er,
/*
* CPUIF interface
*/
input wire s_cpuif_req,
input wire s_cpuif_req_is_wr,
input wire [4:0] s_cpuif_addr,
input wire [31:0] s_cpuif_wr_data,
input wire [31:0] s_cpuif_wr_biten,
output wire s_cpuif_req_stall_wr,
output wire s_cpuif_req_stall_rd,
output wire s_cpuif_rd_ack,
output wire s_cpuif_rd_err,
output wire [31:0] s_cpuif_rd_data,
output wire s_cpuif_wr_ack,
output wire s_cpuif_wr_err,
// MDIO Interface
input wire Mdi,
output wire Mdo,
output wire MdoEn,
output wire Mdc,
output wire phy_rstn
);
assign Mdo = '0;
assign MdoEn = '0;
assign Mdc = '0;
mac_regs_pkg::mac_regs__in_t hwif_in;
mac_regs_pkg::mac_regs__out_t hwif_out;
mac_regs u_mac_regs(
.clk(clk_sys),
.rst(rst),
.s_cpuif_req (s_cpuif_req),
.s_cpuif_req_is_wr (s_cpuif_req_is_wr),
.s_cpuif_addr (s_cpuif_addr),
.s_cpuif_wr_data (s_cpuif_wr_data),
.s_cpuif_wr_biten (s_cpuif_wr_biten),
.s_cpuif_req_stall_wr (s_cpuif_req_stall_wr),
.s_cpuif_req_stall_rd (s_cpuif_req_stall_rd),
.s_cpuif_rd_ack (s_cpuif_rd_ack),
.s_cpuif_rd_err (s_cpuif_rd_err),
.s_cpuif_rd_data (s_cpuif_rd_data),
.s_cpuif_wr_ack (s_cpuif_wr_ack),
.s_cpuif_wr_err (s_cpuif_wr_err),
.hwif_in (hwif_in),
.hwif_out (hwif_out)
);
assign phy_rstn = hwif_out.ctrl.phy_rstn.value;
eth_mac_mii_fifo #(
.TARGET("GENERIC"),
.AXIS_DATA_WIDTH(MAC_DATA_WIDTH),
.MIN_FRAME_LENGTH(64),
.TX_FIFO_DEPTH(4096),
.TX_FIFO_RAM_PIPELINE(1),
.TX_FRAME_FIFO(1),
.RX_FIFO_DEPTH(4096),
.RX_FIFO_RAM_PIPELINE(1),
.RX_FRAME_FIFO(1)
) u_mac (
.rst (rst),
.logic_clk (clk_sys),
.logic_rst (rst),
.tx_axis_tdata (tx_axis.tdata),
.tx_axis_tkeep (tx_axis.tkeep),
.tx_axis_tvalid (tx_axis.tvalid),
.tx_axis_tready (tx_axis.tready),
.tx_axis_tlast (tx_axis.tlast),
.tx_axis_tuser ('0),
.rx_axis_tdata (rx_axis.tdata),
.rx_axis_tkeep (rx_axis.tkeep),
.rx_axis_tvalid (rx_axis.tvalid),
.rx_axis_tready (rx_axis.tready),
.rx_axis_tlast (rx_axis.tlast),
.rx_axis_tuser (rx_axis.tuser),
.mii_rx_clk (mii_rx_clk),
.mii_rxd (mii_rxd),
.mii_rx_dv (mii_rx_dv),
.mii_rx_er (mii_rx_er),
.mii_tx_clk (mii_tx_clk),
.mii_txd (mii_txd),
.mii_tx_en (mii_tx_en),
.mii_tx_er (mii_tx_er),
.tx_error_underflow (hwif_in.stats.tx_error_underflow.hwset),
.tx_fifo_overflow (hwif_in.stats.tx_fifo_overflow.hwset),
.tx_fifo_bad_frame (hwif_in.stats.tx_fifo_bad_frame.hwset),
.tx_fifo_good_frame (hwif_in.stats.tx_fifo_good_frame.hwset),
.rx_error_bad_frame (hwif_in.stats.rx_error_bad_frame.hwset),
.rx_error_bad_fcs (hwif_in.stats.rx_error_bad_fcs.hwset),
.rx_fifo_overflow (hwif_in.stats.rx_fifo_overflow.hwset),
.rx_fifo_bad_frame (hwif_in.stats.rx_fifo_bad_frame.hwset),
.rx_fifo_good_frame (hwif_in.stats.rx_fifo_good_frame.hwset),
.cfg_ifg (hwif_out.ctrl.ifg.value),
.cfg_tx_enable (hwif_out.ctrl.tx_en.value), // this should be configurable w/ regfile
.cfg_rx_enable (hwif_out.ctrl.rx_en.value)
);
endmodule

View File

@@ -0,0 +1,154 @@
module ip_arb_mux_wrapper #(
parameter S_COUNT = 4,
parameter DATA_WIDTH = 8,
parameter KEEP_ENABLE = (DATA_WIDTH>8),
parameter KEEP_WIDTH = (DATA_WIDTH/8),
parameter ID_ENABLE = 0,
parameter ID_WIDTH = 8,
parameter DEST_ENABLE = 0,
parameter DEST_WIDTH = 8,
parameter USER_ENABLE = 1,
parameter USER_WIDTH = 1,
// select round robin arbitration
parameter ARB_TYPE_ROUND_ROBIN = 0,
// LSB priority selection
parameter ARB_LSB_HIGH_PRIORITY = 1
) (
input i_clk,
input i_rst,
ip_intf.SLAVE s_ip [S_COUNT],
ip_intf.MASTER m_ip
);
logic [S_COUNT-1:0] s_ip_hdr_valid;
logic [S_COUNT-1:0] s_ip_hdr_ready;
logic [S_COUNT*48-1:0] s_eth_dest_mac;
logic [S_COUNT*48-1:0] s_eth_src_mac;
logic [S_COUNT*16-1:0] s_eth_type;
logic [S_COUNT*4-1:0] s_ip_version;
logic [S_COUNT*4-1:0] s_ip_ihl;
logic [S_COUNT*6-1:0] s_ip_dscp;
logic [S_COUNT*2-1:0] s_ip_ecn;
logic [S_COUNT*16-1:0] s_ip_length;
logic [S_COUNT*16-1:0] s_ip_identification;
logic [S_COUNT*3-1:0] s_ip_flags;
logic [S_COUNT*13-1:0] s_ip_fragment_offset;
logic [S_COUNT*8-1:0] s_ip_ttl;
logic [S_COUNT*8-1:0] s_ip_protocol;
logic [S_COUNT*16-1:0] s_ip_header_checksum;
logic [S_COUNT*32-1:0] s_ip_source_ip;
logic [S_COUNT*32-1:0] s_ip_dest_ip;
logic [S_COUNT*DATA_WIDTH-1:0] s_ip_payload_axis_tdata;
logic [S_COUNT*KEEP_WIDTH-1:0] s_ip_payload_axis_tkeep;
logic [S_COUNT-1:0] s_ip_payload_axis_tvalid;
logic [S_COUNT-1:0] s_ip_payload_axis_tready;
logic [S_COUNT-1:0] s_ip_payload_axis_tlast;
logic [S_COUNT*ID_WIDTH-1:0] s_ip_payload_axis_tid;
logic [S_COUNT*DEST_WIDTH-1:0] s_ip_payload_axis_tdest;
logic [S_COUNT*USER_WIDTH-1:0] s_ip_payload_axis_tuser;
generate
for (genvar i = 0; i < S_COUNT; i++) begin
assign s_ip_hdr_valid[i] = s_ip[i].ip_hdr_valid;
assign s_ip[i].ip_hdr_ready = s_ip_hdr_ready[i];
assign s_eth_dest_mac[i*48+:48] = s_ip[i].eth_dest_mac;
assign s_eth_src_mac[i*48+:48] = s_ip[i].eth_src_mac;
assign s_eth_type[i*16+:16] = s_ip[i].eth_type;
assign s_ip_version[i*4+:4] = s_ip[i].ip_version;
assign s_ip_ihl[i*4+:4] = s_ip[i].ip_ihl;
assign s_ip_dscp[i*6+:6] = s_ip[i].ip_dscp;
assign s_ip_ecn[i*2+:2] = s_ip[i].ip_ecn;
assign s_ip_length[i*16+:16] = s_ip[i].ip_length;
assign s_ip_identification[i*16+:16] = s_ip[i].ip_identification;
assign s_ip_flags[i*3+:3] = s_ip[i].ip_flags;
assign s_ip_fragment_offset[i*13+:13] = s_ip[i].ip_fragment_offset;
assign s_ip_ttl[i*8+:8] = s_ip[i].ip_ttl;
assign s_ip_protocol[i*8+:8] = s_ip[i].ip_protocol;
assign s_ip_header_checksum[i*16+:16] = s_ip[i].ip_header_checksum;
assign s_ip_source_ip[i*32+:32] = s_ip[i].ip_source_ip;
assign s_ip_dest_ip[i*32+:32] = s_ip[i].ip_dest_ip;
assign s_ip_payload_axis_tdata[i*DATA_WIDTH+:DATA_WIDTH] = s_ip[i].ip_payload_axis_tdata;
assign s_ip_payload_axis_tkeep[i*KEEP_WIDTH+:KEEP_WIDTH] = s_ip[i].ip_payload_axis_tkeep;
assign s_ip_payload_axis_tvalid[i*KEEP_WIDTH+:KEEP_WIDTH] = s_ip[i].ip_payload_axis_tvalid;
assign s_ip[i].ip_payload_axis_tready = s_ip_payload_axis_tready[i];
assign s_ip_payload_axis_tlast[i] = s_ip[i].ip_payload_axis_tlast;
assign s_ip_payload_axis_tid[i*ID_WIDTH+:ID_WIDTH] = s_ip[i].ip_payload_axis_tid;
assign s_ip_payload_axis_tdest[i*DEST_WIDTH+:DEST_WIDTH] = s_ip[i].ip_payload_axis_tdest;
assign s_ip_payload_axis_tuser[i*USER_WIDTH+:USER_WIDTH] = s_ip[i].ip_payload_axis_tuser;
end
endgenerate
ip_arb_mux #(
.S_COUNT(S_COUNT),
.DATA_WIDTH(DATA_WIDTH),
.KEEP_ENABLE(KEEP_ENABLE),
.KEEP_WIDTH(KEEP_WIDTH),
.ID_ENABLE(ID_ENABLE),
.ID_WIDTH(ID_WIDTH),
.DEST_ENABLE(DEST_ENABLE),
.DEST_WIDTH(DEST_WIDTH),
.USER_ENABLE(USER_ENABLE),
.USER_WIDTH(USER_WIDTH),
.ARB_TYPE_ROUND_ROBIN(ARB_TYPE_ROUND_ROBIN),
.ARB_LSB_HIGH_PRIORITY(ARB_LSB_HIGH_PRIORITY)
) u_arb_mux (
.clk (i_clk),
.rst (i_rst),
.s_ip_hdr_valid (s_ip_hdr_valid ),
.s_ip_hdr_ready (s_ip_hdr_ready ),
.s_eth_dest_mac (s_eth_dest_mac ),
.s_eth_src_mac (s_eth_src_mac ),
.s_eth_type (s_eth_type ),
.s_ip_version (s_ip_version ),
.s_ip_ihl (s_ip_ihl ),
.s_ip_dscp (s_ip_dscp ),
.s_ip_ecn (s_ip_ecn ),
.s_ip_length (s_ip_length ),
.s_ip_identification (s_ip_identification ),
.s_ip_flags (s_ip_flags ),
.s_ip_fragment_offset (s_ip_fragment_offset ),
.s_ip_ttl (s_ip_ttl ),
.s_ip_protocol (s_ip_protocol ),
.s_ip_header_checksum (s_ip_header_checksum ),
.s_ip_source_ip (s_ip_source_ip ),
.s_ip_dest_ip (s_ip_dest_ip ),
.s_ip_payload_axis_tdata (s_ip_payload_axis_tdata ),
.s_ip_payload_axis_tkeep (s_ip_payload_axis_tkeep ),
.s_ip_payload_axis_tvalid (s_ip_payload_axis_tvalid ),
.s_ip_payload_axis_tready (s_ip_payload_axis_tready ),
.s_ip_payload_axis_tlast (s_ip_payload_axis_tlast ),
.s_ip_payload_axis_tid (s_ip_payload_axis_tid ),
.s_ip_payload_axis_tdest (s_ip_payload_axis_tdest ),
.s_ip_payload_axis_tuser (s_ip_payload_axis_tuser ),
.m_ip_hdr_valid (m_ip.ip_hdr_valid ),
.m_ip_hdr_ready (m_ip.ip_hdr_ready ),
.m_eth_dest_mac (m_ip.eth_dest_mac ),
.m_eth_src_mac (m_ip.eth_src_mac ),
.m_eth_type (m_ip.eth_type ),
.m_ip_version (m_ip.ip_version ),
.m_ip_ihl (m_ip.ip_ihl ),
.m_ip_dscp (m_ip.ip_dscp ),
.m_ip_ecn (m_ip.ip_ecn ),
.m_ip_length (m_ip.ip_length ),
.m_ip_identification (m_ip.ip_identification ),
.m_ip_flags (m_ip.ip_flags ),
.m_ip_fragment_offset (m_ip.ip_fragment_offset ),
.m_ip_ttl (m_ip.ip_ttl ),
.m_ip_protocol (m_ip.ip_protocol ),
.m_ip_header_checksum (m_ip.ip_header_checksum ),
.m_ip_source_ip (m_ip.ip_source_ip ),
.m_ip_dest_ip (m_ip.ip_dest_ip ),
.m_ip_payload_axis_tdata (m_ip.ip_payload_axis_tdata ),
.m_ip_payload_axis_tkeep (m_ip.ip_payload_axis_tkeep ),
.m_ip_payload_axis_tvalid (m_ip.ip_payload_axis_tvalid ),
.m_ip_payload_axis_tready (m_ip.ip_payload_axis_tready ),
.m_ip_payload_axis_tlast (m_ip.ip_payload_axis_tlast ),
.m_ip_payload_axis_tid (m_ip.ip_payload_axis_tid ),
.m_ip_payload_axis_tdest (m_ip.ip_payload_axis_tdest ),
.m_ip_payload_axis_tuser (m_ip.ip_payload_axis_tuser )
);
endmodule

View File

@@ -0,0 +1,158 @@
module ip_demux_wrapper #(
parameter M_COUNT = 4,
parameter DATA_WIDTH = 8,
parameter KEEP_ENABLE = (DATA_WIDTH>8),
parameter KEEP_WIDTH = (DATA_WIDTH/8),
parameter ID_ENABLE = 0,
parameter ID_WIDTH = 8,
parameter DEST_ENABLE = 0,
parameter DEST_WIDTH = 8,
parameter USER_ENABLE = 1,
parameter USER_WIDTH = 1
)
(
input wire clk,
input wire rst,
ip_intf.SLAVE s_ip,
ip_intf.MASTER m_ip [M_COUNT],
input wire enable,
input wire drop,
input wire [$clog2(M_COUNT)-1:0] select
);
logic [M_COUNT-1:0] m_ip_hdr_valid;
logic [M_COUNT-1:0] m_ip_hdr_ready;
logic [M_COUNT*48-1:0] m_eth_dest_mac;
logic [M_COUNT*48-1:0] m_eth_src_mac;
logic [M_COUNT*16-1:0] m_eth_type;
logic [M_COUNT*4-1:0] m_ip_version;
logic [M_COUNT*4-1:0] m_ip_ihl;
logic [M_COUNT*6-1:0] m_ip_dscp;
logic [M_COUNT*2-1:0] m_ip_ecn;
logic [M_COUNT*16-1:0] m_ip_length;
logic [M_COUNT*16-1:0] m_ip_identification;
logic [M_COUNT*3-1:0] m_ip_flags;
logic [M_COUNT*13-1:0] m_ip_fragment_offset;
logic [M_COUNT*8-1:0] m_ip_ttl;
logic [M_COUNT*8-1:0] m_ip_protocol;
logic [M_COUNT*16-1:0] m_ip_header_checksum;
logic [M_COUNT*32-1:0] m_ip_source_ip;
logic [M_COUNT*32-1:0] m_ip_dest_ip;
logic [M_COUNT*DATA_WIDTH-1:0] m_ip_payload_axis_tdata;
logic [M_COUNT*KEEP_WIDTH-1:0] m_ip_payload_axis_tkeep;
logic [M_COUNT-1:0] m_ip_payload_axis_tvalid;
logic [M_COUNT-1:0] m_ip_payload_axis_tready;
logic [M_COUNT-1:0] m_ip_payload_axis_tlast;
logic [M_COUNT*ID_WIDTH-1:0] m_ip_payload_axis_tid;
logic [M_COUNT*DEST_WIDTH-1:0] m_ip_payload_axis_tdest;
logic [M_COUNT*USER_WIDTH-1:0] m_ip_payload_axis_tuser;
generate
for (genvar i = 0; i < M_COUNT; i++) begin
assign m_ip[i].ip_hdr_valid = m_ip_hdr_valid[i];
assign m_ip_hdr_ready[i] = m_ip[i].ip_hdr_ready;
assign m_ip[i].eth_dest_mac = m_eth_dest_mac[i*48+:48];
assign m_ip[i].eth_src_mac = m_eth_src_mac[i*48+:48];
assign m_ip[i].eth_type = m_eth_type[i*16+:16];
assign m_ip[i].ip_version = m_ip_version[i*4+:4];
assign m_ip[i].ip_ihl = m_ip_ihl[i*4+:4];
assign m_ip[i].ip_dscp = m_ip_dscp[i*6+:6];
assign m_ip[i].ip_ecn = m_ip_ecn[i*2+:2];
assign m_ip[i].ip_length = m_ip_length[i*16+:16];
assign m_ip[i].ip_identification = m_ip_identification[i*16+:16];
assign m_ip[i].ip_flags = m_ip_flags[i*3+:3];
assign m_ip[i].ip_fragment_offset = m_ip_fragment_offset[i*13+:13];
assign m_ip[i].ip_ttl = m_ip_ttl[i*8+:8];
assign m_ip[i].ip_protocol = m_ip_protocol[i*8+:8];
assign m_ip[i].ip_header_checksum = m_ip_header_checksum[i*16+:16];
assign m_ip[i].ip_source_ip = m_ip_source_ip[i*32+:32];
assign m_ip[i].ip_dest_ip = m_ip_dest_ip[i*32+:32];
assign m_ip[i].ip_payload_axis_tdata = m_ip_payload_axis_tdata[i*DATA_WIDTH+:DATA_WIDTH];
assign m_ip[i].ip_payload_axis_tkeep = m_ip_payload_axis_tkeep[i*KEEP_WIDTH+:KEEP_WIDTH];
assign m_ip[i].ip_payload_axis_tvalid = m_ip_payload_axis_tvalid[i*KEEP_WIDTH+:KEEP_WIDTH];
assign m_ip_payload_axis_tready[i] = m_ip[i].ip_payload_axis_tready;
assign m_ip[i].ip_payload_axis_tlast = m_ip_payload_axis_tlast[i];
assign m_ip[i].ip_payload_axis_tid = m_ip_payload_axis_tid[i*ID_WIDTH+:ID_WIDTH];
assign m_ip[i].ip_payload_axis_tdest = m_ip_payload_axis_tdest[i*DEST_WIDTH+:DEST_WIDTH];
assign m_ip[i].ip_payload_axis_tuser = m_ip_payload_axis_tuser[i*USER_WIDTH+:USER_WIDTH];
end
endgenerate
ip_demux #(
.M_COUNT(M_COUNT),
.DATA_WIDTH(DATA_WIDTH),
.KEEP_ENABLE(KEEP_ENABLE),
.KEEP_WIDTH(KEEP_WIDTH),
.ID_ENABLE(ID_ENABLE),
.ID_WIDTH(ID_WIDTH),
.DEST_ENABLE(DEST_ENABLE),
.DEST_WIDTH(DEST_WIDTH),
.USER_ENABLE(USER_ENABLE),
.USER_WIDTH(USER_WIDTH)
) u_ip_demux (
.clk (clk),
.rst (rst),
.s_ip_hdr_valid (s_ip.ip_hdr_valid ),
.s_ip_hdr_ready (s_ip.ip_hdr_ready ),
.s_eth_dest_mac (s_ip.eth_dest_mac ),
.s_eth_src_mac (s_ip.eth_src_mac ),
.s_eth_type (s_ip.eth_type ),
.s_ip_version (s_ip.ip_version ),
.s_ip_ihl (s_ip.ip_ihl ),
.s_ip_dscp (s_ip.ip_dscp ),
.s_ip_ecn (s_ip.ip_ecn ),
.s_ip_length (s_ip.ip_length ),
.s_ip_identification (s_ip.ip_identification ),
.s_ip_flags (s_ip.ip_flags ),
.s_ip_fragment_offset (s_ip.ip_fragment_offset ),
.s_ip_ttl (s_ip.ip_ttl ),
.s_ip_protocol (s_ip.ip_protocol ),
.s_ip_header_checksum (s_ip.ip_header_checksum ),
.s_ip_source_ip (s_ip.ip_source_ip ),
.s_ip_dest_ip (s_ip.ip_dest_ip ),
.s_ip_payload_axis_tdata (s_ip.ip_payload_axis_tdata ),
.s_ip_payload_axis_tkeep (s_ip.ip_payload_axis_tkeep ),
.s_ip_payload_axis_tvalid (s_ip.ip_payload_axis_tvalid ),
.s_ip_payload_axis_tready (s_ip.ip_payload_axis_tready ),
.s_ip_payload_axis_tlast (s_ip.ip_payload_axis_tlast ),
.s_ip_payload_axis_tid (s_ip.ip_payload_axis_tid ),
.s_ip_payload_axis_tdest (s_ip.ip_payload_axis_tdest ),
.s_ip_payload_axis_tuser (s_ip.ip_payload_axis_tuser ),
.m_ip_hdr_valid (m_ip_hdr_valid ),
.m_ip_hdr_ready (m_ip_hdr_ready ),
.m_eth_dest_mac (m_eth_dest_mac ),
.m_eth_src_mac (m_eth_src_mac ),
.m_eth_type (m_eth_type ),
.m_ip_version (m_ip_version ),
.m_ip_ihl (m_ip_ihl ),
.m_ip_dscp (m_ip_dscp ),
.m_ip_ecn (m_ip_ecn ),
.m_ip_length (m_ip_length ),
.m_ip_identification (m_ip_identification ),
.m_ip_flags (m_ip_flags ),
.m_ip_fragment_offset (m_ip_fragment_offset ),
.m_ip_ttl (m_ip_ttl ),
.m_ip_protocol (m_ip_protocol ),
.m_ip_header_checksum (m_ip_header_checksum ),
.m_ip_source_ip (m_ip_source_ip ),
.m_ip_dest_ip (m_ip_dest_ip ),
.m_ip_payload_axis_tdata (m_ip_payload_axis_tdata ),
.m_ip_payload_axis_tkeep (m_ip_payload_axis_tkeep ),
.m_ip_payload_axis_tvalid (m_ip_payload_axis_tvalid ),
.m_ip_payload_axis_tready (m_ip_payload_axis_tready ),
.m_ip_payload_axis_tlast (m_ip_payload_axis_tlast ),
.m_ip_payload_axis_tid (m_ip_payload_axis_tid ),
.m_ip_payload_axis_tdest (m_ip_payload_axis_tdest ),
.m_ip_payload_axis_tuser (m_ip_payload_axis_tuser ),
.enable (enable),
.drop (drop),
.select (select)
);
endmodule

View File

@@ -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

View File

@@ -0,0 +1,343 @@
module network_processor #(
parameter NUM_TCP=8
)(
input i_clk,
input i_rst,
axil_intf.SLAVE s_reg_axil,
axil_intf.MASTER m_dma_axil,
//MII Interface
input wire mii_rx_clk,
input wire [3:0] mii_rxd,
input wire mii_rx_dv,
input wire mii_rx_er,
input wire mii_tx_clk,
output wire [3:0] mii_txd,
output wire mii_tx_en,
output wire mii_tx_er,
// MDIO Interface
input i_Mdi,
output o_Mdo,
output o_MdoEn,
output o_Mdc,
output phy_rstn
);
`define PROTO_ICMP 8'h1
`define PROTO_TCP 8'h6
`define PROTO_UDP 8'h11
localparam ICMP_IDX = 2;
localparam UDP_IDX = 1;
localparam TCP_IDX = 0;
localparam MAC_DATA_WIDTH = 8;
localparam AXIS_DATA_WIDTH = 8;
localparam AXIS_KEEP_WIDTH = ((AXIS_DATA_WIDTH+7)/8);
axil_intf reg_axil_post_reg();
axis_intf #(.DATA_WIDTH(MAC_DATA_WIDTH)) mac_tx_axis();
axis_intf #(.DATA_WIDTH(MAC_DATA_WIDTH)) mac_rx_axis();
eth_intf #(.DATA_WIDTH(MAC_DATA_WIDTH)) mac_tx_eth();
eth_intf #(.DATA_WIDTH(MAC_DATA_WIDTH)) mac_rx_eth();
ip_intf #(.DATA_WIDTH(MAC_DATA_WIDTH)) ntw_tx_ip();
ip_intf #(.DATA_WIDTH(MAC_DATA_WIDTH)) ntw_rx_ip();
ip_intf #(.DATA_WIDTH(MAC_DATA_WIDTH)) proto_rx_ip[3]();
ip_intf #(.DATA_WIDTH(MAC_DATA_WIDTH)) proto_tx_ip[3]();
ntw_top_regfile_pkg::ntw_top_regfile__in_t hwif_in;
ntw_top_regfile_pkg::ntw_top_regfile__out_t hwif_out;
axil_reg_slice u_reg_axil_reg_slice(
.clk(i_clk),
.rst(i_rst),
.s_axil(s_reg_axil),
.m_axil(reg_axil_post_reg)
);
ntw_top_regfile u_ntw_top_regfile (
.clk (i_clk),
.rst (i_rst),
.s_axil_awready (reg_axil_post_reg.awready),
.s_axil_awvalid (reg_axil_post_reg.awvalid),
.s_axil_awaddr (reg_axil_post_reg.awaddr),
.s_axil_awprot (reg_axil_post_reg.awprot),
.s_axil_wready (reg_axil_post_reg.wready),
.s_axil_wvalid (reg_axil_post_reg.wvalid),
.s_axil_wdata (reg_axil_post_reg.wdata),
.s_axil_wstrb (reg_axil_post_reg.wstrb),
.s_axil_bready (reg_axil_post_reg.bready),
.s_axil_bvalid (reg_axil_post_reg.bvalid),
.s_axil_bresp (reg_axil_post_reg.bresp),
.s_axil_arready (reg_axil_post_reg.arready),
.s_axil_arvalid (reg_axil_post_reg.arvalid),
.s_axil_araddr (reg_axil_post_reg.araddr),
.s_axil_arprot (reg_axil_post_reg.arprot),
.s_axil_rready (reg_axil_post_reg.rready),
.s_axil_rvalid (reg_axil_post_reg.rvalid),
.s_axil_rdata (reg_axil_post_reg.rdata),
.s_axil_rresp (reg_axil_post_reg.rresp),
.hwif_in (hwif_in),
.hwif_out (hwif_out)
);
// eth wrapper
eth_wrapper #(
.MAC_DATA_WIDTH(MAC_DATA_WIDTH)
) u_eth_wrapper (
.rst (i_rst),
.clk_sys (i_clk),
.s_cpuif_req (hwif_out.mac.req),
.s_cpuif_req_is_wr (hwif_out.mac.req_is_wr),
.s_cpuif_addr (hwif_out.mac.addr),
.s_cpuif_wr_data (hwif_out.mac.wr_data),
.s_cpuif_wr_biten (hwif_out.mac.wr_biten),
.s_cpuif_req_stall_wr (),
.s_cpuif_req_stall_rd (),
.s_cpuif_rd_ack (hwif_in.mac.rd_ack),
.s_cpuif_rd_err (),
.s_cpuif_rd_data (hwif_in.mac.rd_data),
.s_cpuif_wr_ack (hwif_in.mac.wr_ack),
.s_cpuif_wr_err (),
// MII
.mii_rx_clk (mii_rx_clk),
.mii_rxd (mii_rxd),
.mii_rx_dv (mii_rx_dv),
.mii_rx_er (mii_rx_er),
.mii_tx_clk (mii_tx_clk),
.mii_txd (mii_txd),
.mii_tx_en (mii_tx_en),
.mii_tx_er (mii_tx_er),
.tx_axis (mac_tx_axis),
.rx_axis (mac_rx_axis),
.Mdi (i_Mdi),
.Mdo (o_Mdo),
.MdoEn (o_MdoEn),
.Mdc (o_Mdc)
);
eth_axis_rx #(
.DATA_WIDTH(MAC_DATA_WIDTH)
) u_mac_eth_axis_rx (
.clk (i_clk),
.rst (i_rst),
.s_axis_tdata (mac_rx_axis.tdata),
.s_axis_tvalid (mac_rx_axis.tvalid),
.s_axis_tready (mac_rx_axis.tready),
.s_axis_tlast (mac_rx_axis.tlast),
.s_axis_tuser (mac_rx_axis.tuser),
.s_axis_tkeep (mac_rx_axis.tkeep),
.m_eth_hdr_valid (mac_rx_eth.eth_hdr_valid),
.m_eth_hdr_ready (mac_rx_eth.eth_hdr_ready),
.m_eth_dest_mac (mac_rx_eth.eth_dest_mac),
.m_eth_src_mac (mac_rx_eth.eth_src_mac),
.m_eth_type (mac_rx_eth.eth_type),
.m_eth_payload_axis_tdata (mac_rx_eth.eth_payload_axis_tdata),
.m_eth_payload_axis_tkeep (mac_rx_eth.eth_payload_axis_tkeep),
.m_eth_payload_axis_tvalid (mac_rx_eth.eth_payload_axis_tvalid),
.m_eth_payload_axis_tready (mac_rx_eth.eth_payload_axis_tready),
.m_eth_payload_axis_tlast (mac_rx_eth.eth_payload_axis_tlast),
.m_eth_payload_axis_tuser (mac_rx_eth.eth_payload_axis_tuser),
.busy (),
.error_header_early_termination () // We can add this to a register
);
eth_axis_tx #(
.DATA_WIDTH(MAC_DATA_WIDTH)
) u_mac_eth_axis_tx (
.clk (i_clk),
.rst (i_rst),
.s_eth_hdr_valid (mac_tx_eth.eth_hdr_valid),
.s_eth_hdr_ready (mac_tx_eth.eth_hdr_ready),
.s_eth_dest_mac (mac_tx_eth.eth_dest_mac),
.s_eth_src_mac (mac_tx_eth.eth_src_mac),
.s_eth_type (mac_tx_eth.eth_type),
.s_eth_payload_axis_tdata (mac_tx_eth.eth_payload_axis_tdata),
.s_eth_payload_axis_tkeep (mac_tx_eth.eth_payload_axis_tkeep),
.s_eth_payload_axis_tvalid (mac_tx_eth.eth_payload_axis_tvalid),
.s_eth_payload_axis_tready (mac_tx_eth.eth_payload_axis_tready),
.s_eth_payload_axis_tlast (mac_tx_eth.eth_payload_axis_tlast),
.s_eth_payload_axis_tuser (mac_tx_eth.eth_payload_axis_tuser),
.m_axis_tdata (mac_tx_axis.tdata),
.m_axis_tvalid (mac_tx_axis.tvalid),
.m_axis_tready (mac_tx_axis.tready),
.m_axis_tlast (mac_tx_axis.tlast),
.m_axis_tuser (mac_tx_axis.tuser),
.m_axis_tkeep (mac_tx_axis.tkeep),
.busy ()
);
// this is 8 bit only, we should assert that data width is 8 at this point.
ip_complete #(
.ARP_CACHE_ADDR_WIDTH(7), // memory usage is 81 bits per entry
.ARP_REQUEST_RETRY_COUNT(4),
.ARP_REQUEST_RETRY_INTERVAL(125000000*2), // these are defaults
.ARP_REQUEST_TIMEOUT(125000000*30)
) u_ip_complete (
.clk (i_clk),
.rst (i_rst),
.s_eth_hdr_valid (mac_rx_eth.eth_hdr_valid),
.s_eth_hdr_ready (mac_rx_eth.eth_hdr_ready),
.s_eth_dest_mac (mac_rx_eth.eth_dest_mac),
.s_eth_src_mac (mac_rx_eth.eth_src_mac),
.s_eth_type (mac_rx_eth.eth_type),
.s_eth_payload_axis_tdata (mac_rx_eth.eth_payload_axis_tdata),
.s_eth_payload_axis_tvalid (mac_rx_eth.eth_payload_axis_tvalid),
.s_eth_payload_axis_tready (mac_rx_eth.eth_payload_axis_tready),
.s_eth_payload_axis_tlast (mac_rx_eth.eth_payload_axis_tlast),
.s_eth_payload_axis_tuser (mac_rx_eth.eth_payload_axis_tuser),
.m_eth_hdr_valid (mac_tx_eth.eth_hdr_valid),
.m_eth_hdr_ready (mac_tx_eth.eth_hdr_ready),
.m_eth_dest_mac (mac_tx_eth.eth_dest_mac),
.m_eth_src_mac (mac_tx_eth.eth_src_mac),
.m_eth_type (mac_tx_eth.eth_type),
.m_eth_payload_axis_tdata (mac_tx_eth.eth_payload_axis_tdata),
.m_eth_payload_axis_tvalid (mac_tx_eth.eth_payload_axis_tvalid),
.m_eth_payload_axis_tready (mac_tx_eth.eth_payload_axis_tready),
.m_eth_payload_axis_tlast (mac_tx_eth.eth_payload_axis_tlast),
.m_eth_payload_axis_tuser (mac_tx_eth.eth_payload_axis_tuser),
.s_ip_hdr_valid (ntw_tx_ip.ip_hdr_valid),
.s_ip_hdr_ready (ntw_tx_ip.ip_hdr_ready),
.s_ip_dscp (ntw_tx_ip.ip_dscp),
.s_ip_ecn (ntw_tx_ip.ip_ecn),
.s_ip_length (ntw_tx_ip.ip_length),
.s_ip_ttl (ntw_tx_ip.ip_ttl),
.s_ip_protocol (ntw_tx_ip.ip_protocol),
.s_ip_source_ip (ntw_tx_ip.ip_source_ip),
.s_ip_dest_ip (ntw_tx_ip.ip_dest_ip),
.s_ip_payload_axis_tdata (ntw_tx_ip.ip_payload_axis_tdata),
.s_ip_payload_axis_tvalid (ntw_tx_ip.ip_payload_axis_tvalid),
.s_ip_payload_axis_tready (ntw_tx_ip.ip_payload_axis_tready),
.s_ip_payload_axis_tlast (ntw_tx_ip.ip_payload_axis_tlast),
.s_ip_payload_axis_tuser (ntw_tx_ip.ip_payload_axis_tuser),
.m_ip_hdr_valid (ntw_rx_ip.ip_hdr_valid),
.m_ip_hdr_ready (ntw_rx_ip.ip_hdr_ready),
.m_ip_eth_dest_mac (ntw_rx_ip.eth_dest_mac),
.m_ip_eth_src_mac (ntw_rx_ip.eth_src_mac),
.m_ip_eth_type (ntw_rx_ip.eth_type),
.m_ip_version (ntw_rx_ip.ip_version),
.m_ip_ihl (ntw_rx_ip.ip_ihl),
.m_ip_dscp (ntw_rx_ip.ip_dscp),
.m_ip_ecn (ntw_rx_ip.ip_ecn),
.m_ip_length (ntw_rx_ip.ip_length),
.m_ip_identification (ntw_rx_ip.ip_identification),
.m_ip_flags (ntw_rx_ip.ip_flags),
.m_ip_fragment_offset (ntw_rx_ip.ip_fragment_offset),
.m_ip_ttl (ntw_rx_ip.ip_ttl),
.m_ip_protocol (ntw_rx_ip.ip_protocol),
.m_ip_header_checksum (ntw_rx_ip.ip_header_checksum),
.m_ip_source_ip (ntw_rx_ip.ip_source_ip),
.m_ip_dest_ip (ntw_rx_ip.ip_dest_ip),
.m_ip_payload_axis_tdata (ntw_rx_ip.ip_payload_axis_tdata),
.m_ip_payload_axis_tvalid (ntw_rx_ip.ip_payload_axis_tvalid),
.m_ip_payload_axis_tready (ntw_rx_ip.ip_payload_axis_tready),
.m_ip_payload_axis_tlast (ntw_rx_ip.ip_payload_axis_tlast),
.m_ip_payload_axis_tuser (ntw_rx_ip.ip_payload_axis_tuser),
.rx_busy (), // should go to stats register
.tx_busy (), // should go to stats register
.rx_error_header_early_termination (), // should go to stats register
.rx_error_payload_early_termination (), // should go to stats register
.rx_error_invalid_header (), // should go to stats register
.rx_error_invalid_checksum (), // should go to stats register
.tx_error_payload_early_termination (), // should go to stats register
.tx_error_arp_failed (), // should go to stats register
.local_mac (48'h020000aabbcc), // should be a register
.local_ip (32'hAC000002), // should be a register
.gateway_ip (32'hAC000001), // should be a register
.subnet_mask (32'hffffff00), // should be a register
.clear_arp_cache ('0) // should come from sw
);
logic ip_demux_drop;
assign ip_demux_drop = !((ntw_rx_ip.ip_protocol == `PROTO_ICMP) || (ntw_rx_ip.ip_protocol == `PROTO_UDP) || (ntw_rx_ip.ip_protocol == `PROTO_TCP));
logic [1:0] ip_demux_sel;
assign ip_demux_sel = (ntw_rx_ip.ip_protocol == `PROTO_ICMP) ? 2'h2 : (ntw_rx_ip.ip_protocol == `PROTO_UDP) ? 2'h1 : 2'h0;
ip_demux_wrapper #(
.M_COUNT(3),
.DATA_WIDTH(MAC_DATA_WIDTH)
) u_ip_demux (
.clk (i_clk),
.rst (i_rst),
.s_ip (ntw_rx_ip),
.m_ip (proto_rx_ip),
.enable ('1),
.drop (ip_demux_drop),
.select (ip_demux_sel)
);
assign proto_rx_ip[ICMP_IDX].ip_hdr_ready = '1;
assign proto_rx_ip[ICMP_IDX].ip_payload_axis_tready = '1;
assign proto_rx_ip[UDP_IDX].ip_hdr_ready = '1;
assign proto_rx_ip[UDP_IDX].ip_payload_axis_tready = '1;
ip_arb_mux_wrapper #(
.S_COUNT(3),
.DATA_WIDTH(MAC_DATA_WIDTH)
) u_ip_arb_mux (
.i_clk (i_clk),
.i_rst (i_rst),
.s_ip (proto_tx_ip),
.m_ip (ntw_tx_ip)
);
tcp #(
.NUM_TCP(NUM_TCP)
) tcp (
.i_clk (i_clk),
.i_rst (i_rst),
.s_cpuif_req (hwif_out.tcp_top.req),
.s_cpuif_req_is_wr (hwif_out.tcp_top.req_is_wr),
.s_cpuif_addr (hwif_out.tcp_top.addr),
.s_cpuif_wr_data (hwif_out.tcp_top.wr_data),
.s_cpuif_wr_biten (hwif_out.tcp_top.wr_biten),
.s_cpuif_req_stall_wr (),
.s_cpuif_req_stall_rd (),
.s_cpuif_rd_ack (hwif_in.tcp_top.rd_ack),
.s_cpuif_rd_err (),
.s_cpuif_rd_data (hwif_in.tcp_top.rd_data),
.s_cpuif_wr_ack (hwif_in.tcp_top.wr_ack),
.s_cpuif_wr_err (),
.s_ip (proto_rx_ip[TCP_IDX]),
.m_ip (proto_tx_ip[TCP_IDX]),
.m_dma_axil (m_dma_axil)
);
endmodule

View File

@@ -0,0 +1,121 @@
addrmap mac_regs {
reg {
name = "Control";
desc = "Control bits for the MAC";
field {
name = "TX Enable";
desc = "Enable TX";
hw = r;
sw = rw;
} tx_en[0:0] = 0x0;
field {
name = "RX Enable";
desc = "Enable RX";
hw = r;
sw = rw;
} rx_en[1:1] = 0x0;
field {
name = "PHY Reset";
desc = "phy_rstn";
hw = r;
sw = rw;
} phy_rstn[2:2] = 0x1;
field {
name = "Interframe Gap";
desc = "Interframe gap in mii clock cycles";
hw = r;
sw = rw;
} ifg[15:8] = 0x0;
} ctrl @ 0x0;
reg {
name = "Error";
desc = "Latched Error from the MAC";
field {
name = "tx_error_underflow";
desc = "";
hw = r;
sw = r;
rclr;
hwset;
} tx_error_underflow[0:0] = 0x0;
field {
name = "tx_fifo_overflow";
desc = "";
hw = r;
sw = r;
rclr;
hwset;
} tx_fifo_overflow[1:1] = 0x0;
field {
name = "tx_fifo_bad_frame";
desc = "";
hw = r;
sw = r;
rclr;
hwset;
} tx_fifo_bad_frame[2:2] = 0x0;
field {
name = "tx_fifo_good_frame";
desc = "";
hw = r;
sw = r;
rclr;
hwset;
} tx_fifo_good_frame[3:3] = 0x0;
field {
name = "rx_error_bad_frame";
desc = "";
hw = r;
sw = r;
rclr;
hwset;
} rx_error_bad_frame[4:4] = 0x0;
field {
name = "rx_error_bad_fcs";
desc = "";
hw = r;
sw = r;
rclr;
hwset;
} rx_error_bad_fcs[5:5] = 0x0;
field {
name = "rx_fifo_overflow";
desc = "";
hw = r;
sw = r;
rclr;
hwset;
} rx_fifo_overflow[6:6] = 0x0;
field {
name = "rx_fifo_bad_frame";
desc = "";
hw = r;
sw = r;
rclr;
hwset;
} rx_fifo_bad_frame[7:7] = 0x0;
field {
name = "rx_fifo_good_frame";
desc = "";
hw = r;
sw = r;
rclr;
hwset;
} rx_fifo_good_frame[8:8] = 0x0;
} stats @ 0x4;
};

View File

@@ -0,0 +1,547 @@
// Generated by PeakRDL-regblock - A free and open-source SystemVerilog generator
// https://github.com/SystemRDL/PeakRDL-regblock
module mac_regs (
input wire clk,
input wire rst,
input wire s_cpuif_req,
input wire s_cpuif_req_is_wr,
input wire [2:0] s_cpuif_addr,
input wire [31:0] s_cpuif_wr_data,
input wire [31:0] s_cpuif_wr_biten,
output wire s_cpuif_req_stall_wr,
output wire s_cpuif_req_stall_rd,
output wire s_cpuif_rd_ack,
output wire s_cpuif_rd_err,
output wire [31:0] s_cpuif_rd_data,
output wire s_cpuif_wr_ack,
output wire s_cpuif_wr_err,
input mac_regs_pkg::mac_regs__in_t hwif_in,
output mac_regs_pkg::mac_regs__out_t hwif_out
);
//--------------------------------------------------------------------------
// CPU Bus interface logic
//--------------------------------------------------------------------------
logic cpuif_req;
logic cpuif_req_is_wr;
logic [2:0] cpuif_addr;
logic [31:0] cpuif_wr_data;
logic [31:0] cpuif_wr_biten;
logic cpuif_req_stall_wr;
logic cpuif_req_stall_rd;
logic cpuif_rd_ack;
logic cpuif_rd_err;
logic [31:0] cpuif_rd_data;
logic cpuif_wr_ack;
logic cpuif_wr_err;
assign cpuif_req = s_cpuif_req;
assign cpuif_req_is_wr = s_cpuif_req_is_wr;
assign cpuif_addr = s_cpuif_addr;
assign cpuif_wr_data = s_cpuif_wr_data;
assign cpuif_wr_biten = s_cpuif_wr_biten;
assign s_cpuif_req_stall_wr = cpuif_req_stall_wr;
assign s_cpuif_req_stall_rd = cpuif_req_stall_rd;
assign s_cpuif_rd_ack = cpuif_rd_ack;
assign s_cpuif_rd_err = cpuif_rd_err;
assign s_cpuif_rd_data = cpuif_rd_data;
assign s_cpuif_wr_ack = cpuif_wr_ack;
assign s_cpuif_wr_err = cpuif_wr_err;
logic cpuif_req_masked;
// Read & write latencies are balanced. Stalls not required
assign cpuif_req_stall_rd = '0;
assign cpuif_req_stall_wr = '0;
assign cpuif_req_masked = cpuif_req
& !(!cpuif_req_is_wr & cpuif_req_stall_rd)
& !(cpuif_req_is_wr & cpuif_req_stall_wr);
//--------------------------------------------------------------------------
// Address Decode
//--------------------------------------------------------------------------
typedef struct {
logic ctrl;
logic stats;
} decoded_reg_strb_t;
decoded_reg_strb_t decoded_reg_strb;
logic decoded_req;
logic decoded_req_is_wr;
logic [31:0] decoded_wr_data;
logic [31:0] decoded_wr_biten;
always_comb begin
decoded_reg_strb.ctrl = cpuif_req_masked & (cpuif_addr == 3'h0);
decoded_reg_strb.stats = cpuif_req_masked & (cpuif_addr == 3'h4);
end
// Pass down signals to next stage
assign decoded_req = cpuif_req_masked;
assign decoded_req_is_wr = cpuif_req_is_wr;
assign decoded_wr_data = cpuif_wr_data;
assign decoded_wr_biten = cpuif_wr_biten;
//--------------------------------------------------------------------------
// Field logic
//--------------------------------------------------------------------------
typedef struct {
struct {
struct {
logic next;
logic load_next;
} tx_en;
struct {
logic next;
logic load_next;
} rx_en;
struct {
logic next;
logic load_next;
} phy_rstn;
struct {
logic [7:0] next;
logic load_next;
} ifg;
} ctrl;
struct {
struct {
logic next;
logic load_next;
} tx_error_underflow;
struct {
logic next;
logic load_next;
} tx_fifo_overflow;
struct {
logic next;
logic load_next;
} tx_fifo_bad_frame;
struct {
logic next;
logic load_next;
} tx_fifo_good_frame;
struct {
logic next;
logic load_next;
} rx_error_bad_frame;
struct {
logic next;
logic load_next;
} rx_error_bad_fcs;
struct {
logic next;
logic load_next;
} rx_fifo_overflow;
struct {
logic next;
logic load_next;
} rx_fifo_bad_frame;
struct {
logic next;
logic load_next;
} rx_fifo_good_frame;
} stats;
} field_combo_t;
field_combo_t field_combo;
typedef struct {
struct {
struct {
logic value;
} tx_en;
struct {
logic value;
} rx_en;
struct {
logic value;
} phy_rstn;
struct {
logic [7:0] value;
} ifg;
} ctrl;
struct {
struct {
logic value;
} tx_error_underflow;
struct {
logic value;
} tx_fifo_overflow;
struct {
logic value;
} tx_fifo_bad_frame;
struct {
logic value;
} tx_fifo_good_frame;
struct {
logic value;
} rx_error_bad_frame;
struct {
logic value;
} rx_error_bad_fcs;
struct {
logic value;
} rx_fifo_overflow;
struct {
logic value;
} rx_fifo_bad_frame;
struct {
logic value;
} rx_fifo_good_frame;
} stats;
} field_storage_t;
field_storage_t field_storage;
// Field: mac_regs.ctrl.tx_en
always_comb begin
automatic logic [0:0] next_c;
automatic logic load_next_c;
next_c = field_storage.ctrl.tx_en.value;
load_next_c = '0;
if(decoded_reg_strb.ctrl && decoded_req_is_wr) begin // SW write
next_c = (field_storage.ctrl.tx_en.value & ~decoded_wr_biten[0:0]) | (decoded_wr_data[0:0] & decoded_wr_biten[0:0]);
load_next_c = '1;
end
field_combo.ctrl.tx_en.next = next_c;
field_combo.ctrl.tx_en.load_next = load_next_c;
end
always_ff @(posedge clk) begin
if(rst) begin
field_storage.ctrl.tx_en.value <= 1'h0;
end else if(field_combo.ctrl.tx_en.load_next) begin
field_storage.ctrl.tx_en.value <= field_combo.ctrl.tx_en.next;
end
end
assign hwif_out.ctrl.tx_en.value = field_storage.ctrl.tx_en.value;
// Field: mac_regs.ctrl.rx_en
always_comb begin
automatic logic [0:0] next_c;
automatic logic load_next_c;
next_c = field_storage.ctrl.rx_en.value;
load_next_c = '0;
if(decoded_reg_strb.ctrl && decoded_req_is_wr) begin // SW write
next_c = (field_storage.ctrl.rx_en.value & ~decoded_wr_biten[1:1]) | (decoded_wr_data[1:1] & decoded_wr_biten[1:1]);
load_next_c = '1;
end
field_combo.ctrl.rx_en.next = next_c;
field_combo.ctrl.rx_en.load_next = load_next_c;
end
always_ff @(posedge clk) begin
if(rst) begin
field_storage.ctrl.rx_en.value <= 1'h0;
end else if(field_combo.ctrl.rx_en.load_next) begin
field_storage.ctrl.rx_en.value <= field_combo.ctrl.rx_en.next;
end
end
assign hwif_out.ctrl.rx_en.value = field_storage.ctrl.rx_en.value;
// Field: mac_regs.ctrl.phy_rstn
always_comb begin
automatic logic [0:0] next_c;
automatic logic load_next_c;
next_c = field_storage.ctrl.phy_rstn.value;
load_next_c = '0;
if(decoded_reg_strb.ctrl && decoded_req_is_wr) begin // SW write
next_c = (field_storage.ctrl.phy_rstn.value & ~decoded_wr_biten[2:2]) | (decoded_wr_data[2:2] & decoded_wr_biten[2:2]);
load_next_c = '1;
end
field_combo.ctrl.phy_rstn.next = next_c;
field_combo.ctrl.phy_rstn.load_next = load_next_c;
end
always_ff @(posedge clk) begin
if(rst) begin
field_storage.ctrl.phy_rstn.value <= 1'h1;
end else if(field_combo.ctrl.phy_rstn.load_next) begin
field_storage.ctrl.phy_rstn.value <= field_combo.ctrl.phy_rstn.next;
end
end
assign hwif_out.ctrl.phy_rstn.value = field_storage.ctrl.phy_rstn.value;
// Field: mac_regs.ctrl.ifg
always_comb begin
automatic logic [7:0] next_c;
automatic logic load_next_c;
next_c = field_storage.ctrl.ifg.value;
load_next_c = '0;
if(decoded_reg_strb.ctrl && decoded_req_is_wr) begin // SW write
next_c = (field_storage.ctrl.ifg.value & ~decoded_wr_biten[15:8]) | (decoded_wr_data[15:8] & decoded_wr_biten[15:8]);
load_next_c = '1;
end
field_combo.ctrl.ifg.next = next_c;
field_combo.ctrl.ifg.load_next = load_next_c;
end
always_ff @(posedge clk) begin
if(rst) begin
field_storage.ctrl.ifg.value <= 8'h0;
end else if(field_combo.ctrl.ifg.load_next) begin
field_storage.ctrl.ifg.value <= field_combo.ctrl.ifg.next;
end
end
assign hwif_out.ctrl.ifg.value = field_storage.ctrl.ifg.value;
// Field: mac_regs.stats.tx_error_underflow
always_comb begin
automatic logic [0:0] next_c;
automatic logic load_next_c;
next_c = field_storage.stats.tx_error_underflow.value;
load_next_c = '0;
if(decoded_reg_strb.stats && !decoded_req_is_wr) begin // SW clear on read
next_c = '0;
load_next_c = '1;
end else if(hwif_in.stats.tx_error_underflow.hwset) begin // HW Set
next_c = '1;
load_next_c = '1;
end
field_combo.stats.tx_error_underflow.next = next_c;
field_combo.stats.tx_error_underflow.load_next = load_next_c;
end
always_ff @(posedge clk) begin
if(rst) begin
field_storage.stats.tx_error_underflow.value <= 1'h0;
end else if(field_combo.stats.tx_error_underflow.load_next) begin
field_storage.stats.tx_error_underflow.value <= field_combo.stats.tx_error_underflow.next;
end
end
assign hwif_out.stats.tx_error_underflow.value = field_storage.stats.tx_error_underflow.value;
// Field: mac_regs.stats.tx_fifo_overflow
always_comb begin
automatic logic [0:0] next_c;
automatic logic load_next_c;
next_c = field_storage.stats.tx_fifo_overflow.value;
load_next_c = '0;
if(decoded_reg_strb.stats && !decoded_req_is_wr) begin // SW clear on read
next_c = '0;
load_next_c = '1;
end else if(hwif_in.stats.tx_fifo_overflow.hwset) begin // HW Set
next_c = '1;
load_next_c = '1;
end
field_combo.stats.tx_fifo_overflow.next = next_c;
field_combo.stats.tx_fifo_overflow.load_next = load_next_c;
end
always_ff @(posedge clk) begin
if(rst) begin
field_storage.stats.tx_fifo_overflow.value <= 1'h0;
end else if(field_combo.stats.tx_fifo_overflow.load_next) begin
field_storage.stats.tx_fifo_overflow.value <= field_combo.stats.tx_fifo_overflow.next;
end
end
assign hwif_out.stats.tx_fifo_overflow.value = field_storage.stats.tx_fifo_overflow.value;
// Field: mac_regs.stats.tx_fifo_bad_frame
always_comb begin
automatic logic [0:0] next_c;
automatic logic load_next_c;
next_c = field_storage.stats.tx_fifo_bad_frame.value;
load_next_c = '0;
if(decoded_reg_strb.stats && !decoded_req_is_wr) begin // SW clear on read
next_c = '0;
load_next_c = '1;
end else if(hwif_in.stats.tx_fifo_bad_frame.hwset) begin // HW Set
next_c = '1;
load_next_c = '1;
end
field_combo.stats.tx_fifo_bad_frame.next = next_c;
field_combo.stats.tx_fifo_bad_frame.load_next = load_next_c;
end
always_ff @(posedge clk) begin
if(rst) begin
field_storage.stats.tx_fifo_bad_frame.value <= 1'h0;
end else if(field_combo.stats.tx_fifo_bad_frame.load_next) begin
field_storage.stats.tx_fifo_bad_frame.value <= field_combo.stats.tx_fifo_bad_frame.next;
end
end
assign hwif_out.stats.tx_fifo_bad_frame.value = field_storage.stats.tx_fifo_bad_frame.value;
// Field: mac_regs.stats.tx_fifo_good_frame
always_comb begin
automatic logic [0:0] next_c;
automatic logic load_next_c;
next_c = field_storage.stats.tx_fifo_good_frame.value;
load_next_c = '0;
if(decoded_reg_strb.stats && !decoded_req_is_wr) begin // SW clear on read
next_c = '0;
load_next_c = '1;
end else if(hwif_in.stats.tx_fifo_good_frame.hwset) begin // HW Set
next_c = '1;
load_next_c = '1;
end
field_combo.stats.tx_fifo_good_frame.next = next_c;
field_combo.stats.tx_fifo_good_frame.load_next = load_next_c;
end
always_ff @(posedge clk) begin
if(rst) begin
field_storage.stats.tx_fifo_good_frame.value <= 1'h0;
end else if(field_combo.stats.tx_fifo_good_frame.load_next) begin
field_storage.stats.tx_fifo_good_frame.value <= field_combo.stats.tx_fifo_good_frame.next;
end
end
assign hwif_out.stats.tx_fifo_good_frame.value = field_storage.stats.tx_fifo_good_frame.value;
// Field: mac_regs.stats.rx_error_bad_frame
always_comb begin
automatic logic [0:0] next_c;
automatic logic load_next_c;
next_c = field_storage.stats.rx_error_bad_frame.value;
load_next_c = '0;
if(decoded_reg_strb.stats && !decoded_req_is_wr) begin // SW clear on read
next_c = '0;
load_next_c = '1;
end else if(hwif_in.stats.rx_error_bad_frame.hwset) begin // HW Set
next_c = '1;
load_next_c = '1;
end
field_combo.stats.rx_error_bad_frame.next = next_c;
field_combo.stats.rx_error_bad_frame.load_next = load_next_c;
end
always_ff @(posedge clk) begin
if(rst) begin
field_storage.stats.rx_error_bad_frame.value <= 1'h0;
end else if(field_combo.stats.rx_error_bad_frame.load_next) begin
field_storage.stats.rx_error_bad_frame.value <= field_combo.stats.rx_error_bad_frame.next;
end
end
assign hwif_out.stats.rx_error_bad_frame.value = field_storage.stats.rx_error_bad_frame.value;
// Field: mac_regs.stats.rx_error_bad_fcs
always_comb begin
automatic logic [0:0] next_c;
automatic logic load_next_c;
next_c = field_storage.stats.rx_error_bad_fcs.value;
load_next_c = '0;
if(decoded_reg_strb.stats && !decoded_req_is_wr) begin // SW clear on read
next_c = '0;
load_next_c = '1;
end else if(hwif_in.stats.rx_error_bad_fcs.hwset) begin // HW Set
next_c = '1;
load_next_c = '1;
end
field_combo.stats.rx_error_bad_fcs.next = next_c;
field_combo.stats.rx_error_bad_fcs.load_next = load_next_c;
end
always_ff @(posedge clk) begin
if(rst) begin
field_storage.stats.rx_error_bad_fcs.value <= 1'h0;
end else if(field_combo.stats.rx_error_bad_fcs.load_next) begin
field_storage.stats.rx_error_bad_fcs.value <= field_combo.stats.rx_error_bad_fcs.next;
end
end
assign hwif_out.stats.rx_error_bad_fcs.value = field_storage.stats.rx_error_bad_fcs.value;
// Field: mac_regs.stats.rx_fifo_overflow
always_comb begin
automatic logic [0:0] next_c;
automatic logic load_next_c;
next_c = field_storage.stats.rx_fifo_overflow.value;
load_next_c = '0;
if(decoded_reg_strb.stats && !decoded_req_is_wr) begin // SW clear on read
next_c = '0;
load_next_c = '1;
end else if(hwif_in.stats.rx_fifo_overflow.hwset) begin // HW Set
next_c = '1;
load_next_c = '1;
end
field_combo.stats.rx_fifo_overflow.next = next_c;
field_combo.stats.rx_fifo_overflow.load_next = load_next_c;
end
always_ff @(posedge clk) begin
if(rst) begin
field_storage.stats.rx_fifo_overflow.value <= 1'h0;
end else if(field_combo.stats.rx_fifo_overflow.load_next) begin
field_storage.stats.rx_fifo_overflow.value <= field_combo.stats.rx_fifo_overflow.next;
end
end
assign hwif_out.stats.rx_fifo_overflow.value = field_storage.stats.rx_fifo_overflow.value;
// Field: mac_regs.stats.rx_fifo_bad_frame
always_comb begin
automatic logic [0:0] next_c;
automatic logic load_next_c;
next_c = field_storage.stats.rx_fifo_bad_frame.value;
load_next_c = '0;
if(decoded_reg_strb.stats && !decoded_req_is_wr) begin // SW clear on read
next_c = '0;
load_next_c = '1;
end else if(hwif_in.stats.rx_fifo_bad_frame.hwset) begin // HW Set
next_c = '1;
load_next_c = '1;
end
field_combo.stats.rx_fifo_bad_frame.next = next_c;
field_combo.stats.rx_fifo_bad_frame.load_next = load_next_c;
end
always_ff @(posedge clk) begin
if(rst) begin
field_storage.stats.rx_fifo_bad_frame.value <= 1'h0;
end else if(field_combo.stats.rx_fifo_bad_frame.load_next) begin
field_storage.stats.rx_fifo_bad_frame.value <= field_combo.stats.rx_fifo_bad_frame.next;
end
end
assign hwif_out.stats.rx_fifo_bad_frame.value = field_storage.stats.rx_fifo_bad_frame.value;
// Field: mac_regs.stats.rx_fifo_good_frame
always_comb begin
automatic logic [0:0] next_c;
automatic logic load_next_c;
next_c = field_storage.stats.rx_fifo_good_frame.value;
load_next_c = '0;
if(decoded_reg_strb.stats && !decoded_req_is_wr) begin // SW clear on read
next_c = '0;
load_next_c = '1;
end else if(hwif_in.stats.rx_fifo_good_frame.hwset) begin // HW Set
next_c = '1;
load_next_c = '1;
end
field_combo.stats.rx_fifo_good_frame.next = next_c;
field_combo.stats.rx_fifo_good_frame.load_next = load_next_c;
end
always_ff @(posedge clk) begin
if(rst) begin
field_storage.stats.rx_fifo_good_frame.value <= 1'h0;
end else if(field_combo.stats.rx_fifo_good_frame.load_next) begin
field_storage.stats.rx_fifo_good_frame.value <= field_combo.stats.rx_fifo_good_frame.next;
end
end
assign hwif_out.stats.rx_fifo_good_frame.value = field_storage.stats.rx_fifo_good_frame.value;
//--------------------------------------------------------------------------
// Write response
//--------------------------------------------------------------------------
assign cpuif_wr_ack = decoded_req & decoded_req_is_wr;
// Writes are always granted with no error response
assign cpuif_wr_err = '0;
//--------------------------------------------------------------------------
// Readback
//--------------------------------------------------------------------------
logic readback_err;
logic readback_done;
logic [31:0] readback_data;
// Assign readback values to a flattened array
logic [31:0] readback_array[2];
assign readback_array[0][0:0] = (decoded_reg_strb.ctrl && !decoded_req_is_wr) ? field_storage.ctrl.tx_en.value : '0;
assign readback_array[0][1:1] = (decoded_reg_strb.ctrl && !decoded_req_is_wr) ? field_storage.ctrl.rx_en.value : '0;
assign readback_array[0][2:2] = (decoded_reg_strb.ctrl && !decoded_req_is_wr) ? field_storage.ctrl.phy_rstn.value : '0;
assign readback_array[0][7:3] = '0;
assign readback_array[0][15:8] = (decoded_reg_strb.ctrl && !decoded_req_is_wr) ? field_storage.ctrl.ifg.value : '0;
assign readback_array[0][31:16] = '0;
assign readback_array[1][0:0] = (decoded_reg_strb.stats && !decoded_req_is_wr) ? field_storage.stats.tx_error_underflow.value : '0;
assign readback_array[1][1:1] = (decoded_reg_strb.stats && !decoded_req_is_wr) ? field_storage.stats.tx_fifo_overflow.value : '0;
assign readback_array[1][2:2] = (decoded_reg_strb.stats && !decoded_req_is_wr) ? field_storage.stats.tx_fifo_bad_frame.value : '0;
assign readback_array[1][3:3] = (decoded_reg_strb.stats && !decoded_req_is_wr) ? field_storage.stats.tx_fifo_good_frame.value : '0;
assign readback_array[1][4:4] = (decoded_reg_strb.stats && !decoded_req_is_wr) ? field_storage.stats.rx_error_bad_frame.value : '0;
assign readback_array[1][5:5] = (decoded_reg_strb.stats && !decoded_req_is_wr) ? field_storage.stats.rx_error_bad_fcs.value : '0;
assign readback_array[1][6:6] = (decoded_reg_strb.stats && !decoded_req_is_wr) ? field_storage.stats.rx_fifo_overflow.value : '0;
assign readback_array[1][7:7] = (decoded_reg_strb.stats && !decoded_req_is_wr) ? field_storage.stats.rx_fifo_bad_frame.value : '0;
assign readback_array[1][8:8] = (decoded_reg_strb.stats && !decoded_req_is_wr) ? field_storage.stats.rx_fifo_good_frame.value : '0;
assign readback_array[1][31:9] = '0;
// Reduce the array
always_comb begin
automatic logic [31:0] readback_data_var;
readback_done = decoded_req & ~decoded_req_is_wr;
readback_err = '0;
readback_data_var = '0;
for(int i=0; i<2; i++) readback_data_var |= readback_array[i];
readback_data = readback_data_var;
end
assign cpuif_rd_ack = readback_done;
assign cpuif_rd_data = readback_data;
assign cpuif_rd_err = readback_err;
endmodule

View File

@@ -0,0 +1,136 @@
// Generated by PeakRDL-regblock - A free and open-source SystemVerilog generator
// https://github.com/SystemRDL/PeakRDL-regblock
package mac_regs_pkg;
localparam MAC_REGS_DATA_WIDTH = 32;
localparam MAC_REGS_MIN_ADDR_WIDTH = 3;
typedef struct {
logic hwset;
} mac_regs__stats__tx_error_underflow__in_t;
typedef struct {
logic hwset;
} mac_regs__stats__tx_fifo_overflow__in_t;
typedef struct {
logic hwset;
} mac_regs__stats__tx_fifo_bad_frame__in_t;
typedef struct {
logic hwset;
} mac_regs__stats__tx_fifo_good_frame__in_t;
typedef struct {
logic hwset;
} mac_regs__stats__rx_error_bad_frame__in_t;
typedef struct {
logic hwset;
} mac_regs__stats__rx_error_bad_fcs__in_t;
typedef struct {
logic hwset;
} mac_regs__stats__rx_fifo_overflow__in_t;
typedef struct {
logic hwset;
} mac_regs__stats__rx_fifo_bad_frame__in_t;
typedef struct {
logic hwset;
} mac_regs__stats__rx_fifo_good_frame__in_t;
typedef struct {
mac_regs__stats__tx_error_underflow__in_t tx_error_underflow;
mac_regs__stats__tx_fifo_overflow__in_t tx_fifo_overflow;
mac_regs__stats__tx_fifo_bad_frame__in_t tx_fifo_bad_frame;
mac_regs__stats__tx_fifo_good_frame__in_t tx_fifo_good_frame;
mac_regs__stats__rx_error_bad_frame__in_t rx_error_bad_frame;
mac_regs__stats__rx_error_bad_fcs__in_t rx_error_bad_fcs;
mac_regs__stats__rx_fifo_overflow__in_t rx_fifo_overflow;
mac_regs__stats__rx_fifo_bad_frame__in_t rx_fifo_bad_frame;
mac_regs__stats__rx_fifo_good_frame__in_t rx_fifo_good_frame;
} mac_regs__stats__in_t;
typedef struct {
mac_regs__stats__in_t stats;
} mac_regs__in_t;
typedef struct {
logic value;
} mac_regs__ctrl__tx_en__out_t;
typedef struct {
logic value;
} mac_regs__ctrl__rx_en__out_t;
typedef struct {
logic value;
} mac_regs__ctrl__phy_rstn__out_t;
typedef struct {
logic [7:0] value;
} mac_regs__ctrl__ifg__out_t;
typedef struct {
mac_regs__ctrl__tx_en__out_t tx_en;
mac_regs__ctrl__rx_en__out_t rx_en;
mac_regs__ctrl__phy_rstn__out_t phy_rstn;
mac_regs__ctrl__ifg__out_t ifg;
} mac_regs__ctrl__out_t;
typedef struct {
logic value;
} mac_regs__stats__tx_error_underflow__out_t;
typedef struct {
logic value;
} mac_regs__stats__tx_fifo_overflow__out_t;
typedef struct {
logic value;
} mac_regs__stats__tx_fifo_bad_frame__out_t;
typedef struct {
logic value;
} mac_regs__stats__tx_fifo_good_frame__out_t;
typedef struct {
logic value;
} mac_regs__stats__rx_error_bad_frame__out_t;
typedef struct {
logic value;
} mac_regs__stats__rx_error_bad_fcs__out_t;
typedef struct {
logic value;
} mac_regs__stats__rx_fifo_overflow__out_t;
typedef struct {
logic value;
} mac_regs__stats__rx_fifo_bad_frame__out_t;
typedef struct {
logic value;
} mac_regs__stats__rx_fifo_good_frame__out_t;
typedef struct {
mac_regs__stats__tx_error_underflow__out_t tx_error_underflow;
mac_regs__stats__tx_fifo_overflow__out_t tx_fifo_overflow;
mac_regs__stats__tx_fifo_bad_frame__out_t tx_fifo_bad_frame;
mac_regs__stats__tx_fifo_good_frame__out_t tx_fifo_good_frame;
mac_regs__stats__rx_error_bad_frame__out_t rx_error_bad_frame;
mac_regs__stats__rx_error_bad_fcs__out_t rx_error_bad_fcs;
mac_regs__stats__rx_fifo_overflow__out_t rx_fifo_overflow;
mac_regs__stats__rx_fifo_bad_frame__out_t rx_fifo_bad_frame;
mac_regs__stats__rx_fifo_good_frame__out_t rx_fifo_good_frame;
} mac_regs__stats__out_t;
typedef struct {
mac_regs__ctrl__out_t ctrl;
mac_regs__stats__out_t stats;
} mac_regs__out_t;
endpackage

View File

@@ -0,0 +1,350 @@
// Generated by PeakRDL-regblock - A free and open-source SystemVerilog generator
// https://github.com/SystemRDL/PeakRDL-regblock
module ntw_top_regfile (
input wire clk,
input wire rst,
output logic s_axil_awready,
input wire s_axil_awvalid,
input wire [9:0] s_axil_awaddr,
input wire [2:0] s_axil_awprot,
output logic s_axil_wready,
input wire s_axil_wvalid,
input wire [31:0] s_axil_wdata,
input wire [3:0]s_axil_wstrb,
input wire s_axil_bready,
output logic s_axil_bvalid,
output logic [1:0] s_axil_bresp,
output logic s_axil_arready,
input wire s_axil_arvalid,
input wire [9:0] s_axil_araddr,
input wire [2:0] s_axil_arprot,
input wire s_axil_rready,
output logic s_axil_rvalid,
output logic [31:0] s_axil_rdata,
output logic [1:0] s_axil_rresp,
input ntw_top_regfile_pkg::ntw_top_regfile__in_t hwif_in,
output ntw_top_regfile_pkg::ntw_top_regfile__out_t hwif_out
);
//--------------------------------------------------------------------------
// CPU Bus interface logic
//--------------------------------------------------------------------------
logic cpuif_req;
logic cpuif_req_is_wr;
logic [9:0] cpuif_addr;
logic [31:0] cpuif_wr_data;
logic [31:0] cpuif_wr_biten;
logic cpuif_req_stall_wr;
logic cpuif_req_stall_rd;
logic cpuif_rd_ack;
logic cpuif_rd_err;
logic [31:0] cpuif_rd_data;
logic cpuif_wr_ack;
logic cpuif_wr_err;
// Max Outstanding Transactions: 2
logic [1:0] axil_n_in_flight;
logic axil_prev_was_rd;
logic axil_arvalid;
logic [9:0] axil_araddr;
logic axil_ar_accept;
logic axil_awvalid;
logic [9:0] axil_awaddr;
logic axil_wvalid;
logic [31:0] axil_wdata;
logic [3:0] axil_wstrb;
logic axil_aw_accept;
logic axil_resp_acked;
// Transaction request acceptance
always_ff @(posedge clk) begin
if(rst) begin
axil_prev_was_rd <= '0;
axil_arvalid <= '0;
axil_araddr <= '0;
axil_awvalid <= '0;
axil_awaddr <= '0;
axil_wvalid <= '0;
axil_wdata <= '0;
axil_wstrb <= '0;
axil_n_in_flight <= '0;
end else begin
// AR* acceptance register
if(axil_ar_accept) begin
axil_prev_was_rd <= '1;
axil_arvalid <= '0;
end
if(s_axil_arvalid && s_axil_arready) begin
axil_arvalid <= '1;
axil_araddr <= s_axil_araddr;
end
// AW* & W* acceptance registers
if(axil_aw_accept) begin
axil_prev_was_rd <= '0;
axil_awvalid <= '0;
axil_wvalid <= '0;
end
if(s_axil_awvalid && s_axil_awready) begin
axil_awvalid <= '1;
axil_awaddr <= s_axil_awaddr;
end
if(s_axil_wvalid && s_axil_wready) begin
axil_wvalid <= '1;
axil_wdata <= s_axil_wdata;
axil_wstrb <= s_axil_wstrb;
end
// Keep track of in-flight transactions
if((axil_ar_accept || axil_aw_accept) && !axil_resp_acked) begin
axil_n_in_flight <= axil_n_in_flight + 1'b1;
end else if(!(axil_ar_accept || axil_aw_accept) && axil_resp_acked) begin
axil_n_in_flight <= axil_n_in_flight - 1'b1;
end
end
end
always_comb begin
s_axil_arready = (!axil_arvalid || axil_ar_accept);
s_axil_awready = (!axil_awvalid || axil_aw_accept);
s_axil_wready = (!axil_wvalid || axil_aw_accept);
end
// Request dispatch
always_comb begin
cpuif_wr_data = axil_wdata;
for(int i=0; i<4; i++) begin
cpuif_wr_biten[i*8 +: 8] = {8{axil_wstrb[i]}};
end
cpuif_req = '0;
cpuif_req_is_wr = '0;
cpuif_addr = '0;
axil_ar_accept = '0;
axil_aw_accept = '0;
if(axil_n_in_flight < 2'd2) begin
// Can safely issue more transactions without overwhelming response buffer
if(axil_arvalid && !axil_prev_was_rd) begin
cpuif_req = '1;
cpuif_req_is_wr = '0;
cpuif_addr = {axil_araddr[9:2], 2'b0};
if(!cpuif_req_stall_rd) axil_ar_accept = '1;
end else if(axil_awvalid && axil_wvalid) begin
cpuif_req = '1;
cpuif_req_is_wr = '1;
cpuif_addr = {axil_awaddr[9:2], 2'b0};
if(!cpuif_req_stall_wr) axil_aw_accept = '1;
end else if(axil_arvalid) begin
cpuif_req = '1;
cpuif_req_is_wr = '0;
cpuif_addr = {axil_araddr[9:2], 2'b0};
if(!cpuif_req_stall_rd) axil_ar_accept = '1;
end
end
end
// AXI4-Lite Response Logic
struct {
logic is_wr;
logic err;
logic [31:0] rdata;
} axil_resp_buffer[2];
logic [1:0] axil_resp_wptr;
logic [1:0] axil_resp_rptr;
always_ff @(posedge clk) begin
if(rst) begin
for(int i=0; i<2; i++) begin
axil_resp_buffer[i].is_wr <= '0;
axil_resp_buffer[i].err <= '0;
axil_resp_buffer[i].rdata <= '0;
end
axil_resp_wptr <= '0;
axil_resp_rptr <= '0;
end else begin
// Store responses in buffer until AXI response channel accepts them
if(cpuif_rd_ack || cpuif_wr_ack) begin
if(cpuif_rd_ack) begin
axil_resp_buffer[axil_resp_wptr[0:0]].is_wr <= '0;
axil_resp_buffer[axil_resp_wptr[0:0]].err <= cpuif_rd_err;
axil_resp_buffer[axil_resp_wptr[0:0]].rdata <= cpuif_rd_data;
end else if(cpuif_wr_ack) begin
axil_resp_buffer[axil_resp_wptr[0:0]].is_wr <= '1;
axil_resp_buffer[axil_resp_wptr[0:0]].err <= cpuif_wr_err;
end
axil_resp_wptr <= axil_resp_wptr + 1'b1;
end
// Advance read pointer when acknowledged
if(axil_resp_acked) begin
axil_resp_rptr <= axil_resp_rptr + 1'b1;
end
end
end
always_comb begin
axil_resp_acked = '0;
s_axil_bvalid = '0;
s_axil_rvalid = '0;
if(axil_resp_rptr != axil_resp_wptr) begin
if(axil_resp_buffer[axil_resp_rptr[0:0]].is_wr) begin
s_axil_bvalid = '1;
if(s_axil_bready) axil_resp_acked = '1;
end else begin
s_axil_rvalid = '1;
if(s_axil_rready) axil_resp_acked = '1;
end
end
s_axil_rdata = axil_resp_buffer[axil_resp_rptr[0:0]].rdata;
if(axil_resp_buffer[axil_resp_rptr[0:0]].err) begin
s_axil_bresp = 2'b10;
s_axil_rresp = 2'b10;
end else begin
s_axil_bresp = 2'b00;
s_axil_rresp = 2'b00;
end
end
logic cpuif_req_masked;
logic external_req;
logic external_pending;
logic external_wr_ack;
logic external_rd_ack;
always_ff @(posedge clk) begin
if(rst) begin
external_pending <= '0;
end else begin
if(external_req & ~external_wr_ack & ~external_rd_ack) external_pending <= '1;
else if(external_wr_ack | external_rd_ack) external_pending <= '0;
assert(!external_wr_ack || (external_pending | external_req))
else $error("An external wr_ack strobe was asserted when no external request was active");
assert(!external_rd_ack || (external_pending | external_req))
else $error("An external rd_ack strobe was asserted when no external request was active");
end
end
// Read & write latencies are balanced. Stalls not required
// except if external
assign cpuif_req_stall_rd = external_pending;
assign cpuif_req_stall_wr = external_pending;
assign cpuif_req_masked = cpuif_req
& !(!cpuif_req_is_wr & cpuif_req_stall_rd)
& !(cpuif_req_is_wr & cpuif_req_stall_wr);
//--------------------------------------------------------------------------
// Address Decode
//--------------------------------------------------------------------------
typedef struct {
logic mac;
logic tcp_top;
} decoded_reg_strb_t;
decoded_reg_strb_t decoded_reg_strb;
logic decoded_strb_is_external;
logic [9:0] decoded_addr;
logic decoded_req;
logic decoded_req_is_wr;
logic [31:0] decoded_wr_data;
logic [31:0] decoded_wr_biten;
always_comb begin
automatic logic is_external;
is_external = '0;
decoded_reg_strb.mac = cpuif_req_masked & (cpuif_addr >= 10'h0) & (cpuif_addr <= 10'h0 + 10'h7);
is_external |= cpuif_req_masked & (cpuif_addr >= 10'h0) & (cpuif_addr <= 10'h0 + 10'h7);
decoded_reg_strb.tcp_top = cpuif_req_masked & (cpuif_addr >= 10'h200) & (cpuif_addr <= 10'h200 + 10'hff);
is_external |= cpuif_req_masked & (cpuif_addr >= 10'h200) & (cpuif_addr <= 10'h200 + 10'hff);
decoded_strb_is_external = is_external;
external_req = is_external;
end
// Pass down signals to next stage
assign decoded_addr = cpuif_addr;
assign decoded_req = cpuif_req_masked;
assign decoded_req_is_wr = cpuif_req_is_wr;
assign decoded_wr_data = cpuif_wr_data;
assign decoded_wr_biten = cpuif_wr_biten;
//--------------------------------------------------------------------------
// Field logic
//--------------------------------------------------------------------------
assign hwif_out.mac.req = decoded_reg_strb.mac;
assign hwif_out.mac.addr = decoded_addr[3:0];
assign hwif_out.mac.req_is_wr = decoded_req_is_wr;
assign hwif_out.mac.wr_data = decoded_wr_data;
assign hwif_out.mac.wr_biten = decoded_wr_biten;
assign hwif_out.tcp_top.req = decoded_reg_strb.tcp_top;
assign hwif_out.tcp_top.addr = decoded_addr[8:0];
assign hwif_out.tcp_top.req_is_wr = decoded_req_is_wr;
assign hwif_out.tcp_top.wr_data = decoded_wr_data;
assign hwif_out.tcp_top.wr_biten = decoded_wr_biten;
//--------------------------------------------------------------------------
// Write response
//--------------------------------------------------------------------------
always_comb begin
automatic logic wr_ack;
wr_ack = '0;
wr_ack |= hwif_in.mac.wr_ack;
wr_ack |= hwif_in.tcp_top.wr_ack;
external_wr_ack = wr_ack;
end
assign cpuif_wr_ack = external_wr_ack | (decoded_req & decoded_req_is_wr & ~decoded_strb_is_external);
// Writes are always granted with no error response
assign cpuif_wr_err = '0;
//--------------------------------------------------------------------------
// Readback
//--------------------------------------------------------------------------
logic readback_external_rd_ack_c;
always_comb begin
automatic logic rd_ack;
rd_ack = '0;
rd_ack |= hwif_in.mac.rd_ack;
rd_ack |= hwif_in.tcp_top.rd_ack;
readback_external_rd_ack_c = rd_ack;
end
logic readback_external_rd_ack;
assign readback_external_rd_ack = readback_external_rd_ack_c;
logic readback_err;
logic readback_done;
logic [31:0] readback_data;
// Assign readback values to a flattened array
logic [31:0] readback_array[2];
assign readback_array[0] = hwif_in.mac.rd_ack ? hwif_in.mac.rd_data : '0;
assign readback_array[1] = hwif_in.tcp_top.rd_ack ? hwif_in.tcp_top.rd_data : '0;
// Reduce the array
always_comb begin
automatic logic [31:0] readback_data_var;
readback_done = decoded_req & ~decoded_req_is_wr & ~decoded_strb_is_external;
readback_err = '0;
readback_data_var = '0;
for(int i=0; i<2; i++) readback_data_var |= readback_array[i];
readback_data = readback_data_var;
end
assign external_rd_ack = readback_external_rd_ack;
assign cpuif_rd_ack = readback_done | readback_external_rd_ack;
assign cpuif_rd_data = readback_data;
assign cpuif_rd_err = readback_err;
endmodule

View File

@@ -0,0 +1,46 @@
// Generated by PeakRDL-regblock - A free and open-source SystemVerilog generator
// https://github.com/SystemRDL/PeakRDL-regblock
package ntw_top_regfile_pkg;
localparam NTW_TOP_REGFILE_DATA_WIDTH = 32;
localparam NTW_TOP_REGFILE_MIN_ADDR_WIDTH = 10;
typedef struct {
logic rd_ack;
logic [31:0] rd_data;
logic wr_ack;
} mac_regs__external__in_t;
typedef struct {
logic rd_ack;
logic [31:0] rd_data;
logic wr_ack;
} tcp_top_regfile__external__in_t;
typedef struct {
mac_regs__external__in_t mac;
tcp_top_regfile__external__in_t tcp_top;
} ntw_top_regfile__in_t;
typedef struct {
logic req;
logic [2:0] addr;
logic req_is_wr;
logic [31:0] wr_data;
logic [31:0] wr_biten;
} mac_regs__external__out_t;
typedef struct {
logic req;
logic [7:0] addr;
logic req_is_wr;
logic [31:0] wr_data;
logic [31:0] wr_biten;
} tcp_top_regfile__external__out_t;
typedef struct {
mac_regs__external__out_t mac;
tcp_top_regfile__external__out_t tcp_top;
} ntw_top_regfile__out_t;
endpackage

View File

@@ -0,0 +1,4 @@
addrmap ntw_top_regfile {
external mac_regs mac @ 0x0;
external tcp_top_regfile tcp_top @ 0x200;
};

View File

@@ -0,0 +1,5 @@
peakrdl regblock -t tcp_top_regfile ../../../stream_dmas/src/regs/m2s_dma_regs.rdl tcp_stream_regs.rdl tcp_top_regs.rdl -o . --cpuif passthrough
peakrdl regblock -t tcp_stream_regs ../../../stream_dmas/src/regs/m2s_dma_regs.rdl tcp_stream_regs.rdl -o . --cpuif passthrough
peakrdl regblock -t mac_regs mac_regs.rdl -o . --cpuif passthrough
peakrdl regblock -t ntw_top_regfile mac_regs.rdl ../../../stream_dmas/src/regs/m2s_dma_regs.rdl tcp_stream_regs.rdl tcp_top_regs.rdl ntw_top_regs.rdl -o . --cpuif axi4-lite-flat
peakrdl html -t ntw_top_regfile mac_regs.rdl ../../../stream_dmas/src/regs/m2s_dma_regs.rdl tcp_stream_regs.rdl tcp_top_regs.rdl ntw_top_regs.rdl -o html

View File

@@ -0,0 +1,137 @@
addrmap tcp_stream_regs {
name = "TCP Stream Regs";
desc = "";
reg {
name = "SourcePort";
desc = "";
field {
name = "d";
desc = "";
hw = r;
sw = rw;
} d[31:0] = 0x0;
} source_port @ 0x0;
reg {
name = "SourceIP";
desc = "";
field {
name = "d";
desc = "";
hw = r;
sw = rw;
} d[31:0] = 0x0;
} source_ip @ 0x4;
reg {
name = "DestPort";
desc = "";
field {
name = "d";
desc = "";
hw = r;
sw = rw;
} d[31:0] = 0x0;
} dest_port @ 0x8;
reg {
name = "DestIP";
desc = "";
field {
name = "d";
desc = "";
hw = r;
sw = rw;
} d[31:0] = 0x0;
} dest_ip @ 0xc;
reg {
name = "Control";
desc = "";
field {
name = "Enable";
desc = "Enable the stream";
hw = r;
sw = rw;
} enable[0:0] = 0x0;
field {
name = "Open";
desc = "Open a new connection with the given parameters.
When written with 1, initiate a TCP handshake.";
hw = r;
sw = rw;
hwclr;
} open[1:1] = 0x0;
field {
name = "Close";
desc = "Closes the exisitng connection when written with 1";
hw = r;
sw = rw;
hwclr;
} close[2:2] = 0x0;
field {
name = "State";
desc = "Current state of the TCP connection";
hw = w;
sw = r;
} state[5:3] = 0x0;
} control @ 0x10;
// is addrmap right for this? How do we specify the address of it though?
// Maybe we have to do this separately and include it?
regfile stats {
name = "Statistics";
desc = "";
reg {
name = "TXValidPackets";
desc = "Number of packets transmitted";
field {
name = "d";
desc = "";
hw = r;
sw = w;
} d[31:0] = 0x0;
} tx_valid_packets @ 0x14;
reg {
name = "RXValidPackets";
desc = "Number of valid received packets";
field {
name = "d";
desc = "";
hw = r;
sw = w;
} d[31:0] = 0x0;
} rx_valid_packets @ 0x4;
reg {
name = "RXBadCRC";
desc = "RX packets with bad CRC";
field {
name = "d";
desc = "";
hw = r;
sw = w;
} d[31:0] = 0x0;
} rx_bad_crc @ 0x8;
};
external m2s_dma_regs m2s_dma_regs @ 0x20;
};

View File

@@ -0,0 +1,423 @@
// Generated by PeakRDL-regblock - A free and open-source SystemVerilog generator
// https://github.com/SystemRDL/PeakRDL-regblock
module tcp_stream_regs (
input wire clk,
input wire rst,
input wire s_cpuif_req,
input wire s_cpuif_req_is_wr,
input wire [5:0] s_cpuif_addr,
input wire [31:0] s_cpuif_wr_data,
input wire [31:0] s_cpuif_wr_biten,
output wire s_cpuif_req_stall_wr,
output wire s_cpuif_req_stall_rd,
output wire s_cpuif_rd_ack,
output wire s_cpuif_rd_err,
output wire [31:0] s_cpuif_rd_data,
output wire s_cpuif_wr_ack,
output wire s_cpuif_wr_err,
input tcp_stream_regs_pkg::tcp_stream_regs__in_t hwif_in,
output tcp_stream_regs_pkg::tcp_stream_regs__out_t hwif_out
);
//--------------------------------------------------------------------------
// CPU Bus interface logic
//--------------------------------------------------------------------------
logic cpuif_req;
logic cpuif_req_is_wr;
logic [5:0] cpuif_addr;
logic [31:0] cpuif_wr_data;
logic [31:0] cpuif_wr_biten;
logic cpuif_req_stall_wr;
logic cpuif_req_stall_rd;
logic cpuif_rd_ack;
logic cpuif_rd_err;
logic [31:0] cpuif_rd_data;
logic cpuif_wr_ack;
logic cpuif_wr_err;
assign cpuif_req = s_cpuif_req;
assign cpuif_req_is_wr = s_cpuif_req_is_wr;
assign cpuif_addr = s_cpuif_addr;
assign cpuif_wr_data = s_cpuif_wr_data;
assign cpuif_wr_biten = s_cpuif_wr_biten;
assign s_cpuif_req_stall_wr = cpuif_req_stall_wr;
assign s_cpuif_req_stall_rd = cpuif_req_stall_rd;
assign s_cpuif_rd_ack = cpuif_rd_ack;
assign s_cpuif_rd_err = cpuif_rd_err;
assign s_cpuif_rd_data = cpuif_rd_data;
assign s_cpuif_wr_ack = cpuif_wr_ack;
assign s_cpuif_wr_err = cpuif_wr_err;
logic cpuif_req_masked;
logic external_req;
logic external_pending;
logic external_wr_ack;
logic external_rd_ack;
always_ff @(posedge clk) begin
if(rst) begin
external_pending <= '0;
end else begin
if(external_req & ~external_wr_ack & ~external_rd_ack) external_pending <= '1;
else if(external_wr_ack | external_rd_ack) external_pending <= '0;
assert(!external_wr_ack || (external_pending | external_req))
else $error("An external wr_ack strobe was asserted when no external request was active");
assert(!external_rd_ack || (external_pending | external_req))
else $error("An external rd_ack strobe was asserted when no external request was active");
end
end
// Read & write latencies are balanced. Stalls not required
// except if external
assign cpuif_req_stall_rd = external_pending;
assign cpuif_req_stall_wr = external_pending;
assign cpuif_req_masked = cpuif_req
& !(!cpuif_req_is_wr & cpuif_req_stall_rd)
& !(cpuif_req_is_wr & cpuif_req_stall_wr);
//--------------------------------------------------------------------------
// Address Decode
//--------------------------------------------------------------------------
typedef struct {
logic source_port;
logic source_ip;
logic dest_port;
logic dest_ip;
logic control;
logic m2s_dma_regs;
} decoded_reg_strb_t;
decoded_reg_strb_t decoded_reg_strb;
logic decoded_strb_is_external;
logic [5:0] decoded_addr;
logic decoded_req;
logic decoded_req_is_wr;
logic [31:0] decoded_wr_data;
logic [31:0] decoded_wr_biten;
always_comb begin
automatic logic is_external;
is_external = '0;
decoded_reg_strb.source_port = cpuif_req_masked & (cpuif_addr == 6'h0);
decoded_reg_strb.source_ip = cpuif_req_masked & (cpuif_addr == 6'h4);
decoded_reg_strb.dest_port = cpuif_req_masked & (cpuif_addr == 6'h8);
decoded_reg_strb.dest_ip = cpuif_req_masked & (cpuif_addr == 6'hc);
decoded_reg_strb.control = cpuif_req_masked & (cpuif_addr == 6'h10);
decoded_reg_strb.m2s_dma_regs = cpuif_req_masked & (cpuif_addr >= 6'h20) & (cpuif_addr <= 6'h20 + 6'hf);
is_external |= cpuif_req_masked & (cpuif_addr >= 6'h20) & (cpuif_addr <= 6'h20 + 6'hf);
decoded_strb_is_external = is_external;
external_req = is_external;
end
// Pass down signals to next stage
assign decoded_addr = cpuif_addr;
assign decoded_req = cpuif_req_masked;
assign decoded_req_is_wr = cpuif_req_is_wr;
assign decoded_wr_data = cpuif_wr_data;
assign decoded_wr_biten = cpuif_wr_biten;
//--------------------------------------------------------------------------
// Field logic
//--------------------------------------------------------------------------
typedef struct {
struct {
struct {
logic [31:0] next;
logic load_next;
} d;
} source_port;
struct {
struct {
logic [31:0] next;
logic load_next;
} d;
} source_ip;
struct {
struct {
logic [31:0] next;
logic load_next;
} d;
} dest_port;
struct {
struct {
logic [31:0] next;
logic load_next;
} d;
} dest_ip;
struct {
struct {
logic next;
logic load_next;
} enable;
struct {
logic next;
logic load_next;
} open;
struct {
logic next;
logic load_next;
} close;
} control;
} field_combo_t;
field_combo_t field_combo;
typedef struct {
struct {
struct {
logic [31:0] value;
} d;
} source_port;
struct {
struct {
logic [31:0] value;
} d;
} source_ip;
struct {
struct {
logic [31:0] value;
} d;
} dest_port;
struct {
struct {
logic [31:0] value;
} d;
} dest_ip;
struct {
struct {
logic value;
} enable;
struct {
logic value;
} open;
struct {
logic value;
} close;
} control;
} field_storage_t;
field_storage_t field_storage;
// Field: tcp_stream_regs.source_port.d
always_comb begin
automatic logic [31:0] next_c;
automatic logic load_next_c;
next_c = field_storage.source_port.d.value;
load_next_c = '0;
if(decoded_reg_strb.source_port && decoded_req_is_wr) begin // SW write
next_c = (field_storage.source_port.d.value & ~decoded_wr_biten[31:0]) | (decoded_wr_data[31:0] & decoded_wr_biten[31:0]);
load_next_c = '1;
end
field_combo.source_port.d.next = next_c;
field_combo.source_port.d.load_next = load_next_c;
end
always_ff @(posedge clk) begin
if(rst) begin
field_storage.source_port.d.value <= 32'h0;
end else if(field_combo.source_port.d.load_next) begin
field_storage.source_port.d.value <= field_combo.source_port.d.next;
end
end
assign hwif_out.source_port.d.value = field_storage.source_port.d.value;
// Field: tcp_stream_regs.source_ip.d
always_comb begin
automatic logic [31:0] next_c;
automatic logic load_next_c;
next_c = field_storage.source_ip.d.value;
load_next_c = '0;
if(decoded_reg_strb.source_ip && decoded_req_is_wr) begin // SW write
next_c = (field_storage.source_ip.d.value & ~decoded_wr_biten[31:0]) | (decoded_wr_data[31:0] & decoded_wr_biten[31:0]);
load_next_c = '1;
end
field_combo.source_ip.d.next = next_c;
field_combo.source_ip.d.load_next = load_next_c;
end
always_ff @(posedge clk) begin
if(rst) begin
field_storage.source_ip.d.value <= 32'h0;
end else if(field_combo.source_ip.d.load_next) begin
field_storage.source_ip.d.value <= field_combo.source_ip.d.next;
end
end
assign hwif_out.source_ip.d.value = field_storage.source_ip.d.value;
// Field: tcp_stream_regs.dest_port.d
always_comb begin
automatic logic [31:0] next_c;
automatic logic load_next_c;
next_c = field_storage.dest_port.d.value;
load_next_c = '0;
if(decoded_reg_strb.dest_port && decoded_req_is_wr) begin // SW write
next_c = (field_storage.dest_port.d.value & ~decoded_wr_biten[31:0]) | (decoded_wr_data[31:0] & decoded_wr_biten[31:0]);
load_next_c = '1;
end
field_combo.dest_port.d.next = next_c;
field_combo.dest_port.d.load_next = load_next_c;
end
always_ff @(posedge clk) begin
if(rst) begin
field_storage.dest_port.d.value <= 32'h0;
end else if(field_combo.dest_port.d.load_next) begin
field_storage.dest_port.d.value <= field_combo.dest_port.d.next;
end
end
assign hwif_out.dest_port.d.value = field_storage.dest_port.d.value;
// Field: tcp_stream_regs.dest_ip.d
always_comb begin
automatic logic [31:0] next_c;
automatic logic load_next_c;
next_c = field_storage.dest_ip.d.value;
load_next_c = '0;
if(decoded_reg_strb.dest_ip && decoded_req_is_wr) begin // SW write
next_c = (field_storage.dest_ip.d.value & ~decoded_wr_biten[31:0]) | (decoded_wr_data[31:0] & decoded_wr_biten[31:0]);
load_next_c = '1;
end
field_combo.dest_ip.d.next = next_c;
field_combo.dest_ip.d.load_next = load_next_c;
end
always_ff @(posedge clk) begin
if(rst) begin
field_storage.dest_ip.d.value <= 32'h0;
end else if(field_combo.dest_ip.d.load_next) begin
field_storage.dest_ip.d.value <= field_combo.dest_ip.d.next;
end
end
assign hwif_out.dest_ip.d.value = field_storage.dest_ip.d.value;
// Field: tcp_stream_regs.control.enable
always_comb begin
automatic logic [0:0] next_c;
automatic logic load_next_c;
next_c = field_storage.control.enable.value;
load_next_c = '0;
if(decoded_reg_strb.control && decoded_req_is_wr) begin // SW write
next_c = (field_storage.control.enable.value & ~decoded_wr_biten[0:0]) | (decoded_wr_data[0:0] & decoded_wr_biten[0:0]);
load_next_c = '1;
end
field_combo.control.enable.next = next_c;
field_combo.control.enable.load_next = load_next_c;
end
always_ff @(posedge clk) begin
if(rst) begin
field_storage.control.enable.value <= 1'h0;
end else if(field_combo.control.enable.load_next) begin
field_storage.control.enable.value <= field_combo.control.enable.next;
end
end
assign hwif_out.control.enable.value = field_storage.control.enable.value;
// Field: tcp_stream_regs.control.open
always_comb begin
automatic logic [0:0] next_c;
automatic logic load_next_c;
next_c = field_storage.control.open.value;
load_next_c = '0;
if(decoded_reg_strb.control && decoded_req_is_wr) begin // SW write
next_c = (field_storage.control.open.value & ~decoded_wr_biten[1:1]) | (decoded_wr_data[1:1] & decoded_wr_biten[1:1]);
load_next_c = '1;
end else if(hwif_in.control.open.hwclr) begin // HW Clear
next_c = '0;
load_next_c = '1;
end
field_combo.control.open.next = next_c;
field_combo.control.open.load_next = load_next_c;
end
always_ff @(posedge clk) begin
if(rst) begin
field_storage.control.open.value <= 1'h0;
end else if(field_combo.control.open.load_next) begin
field_storage.control.open.value <= field_combo.control.open.next;
end
end
assign hwif_out.control.open.value = field_storage.control.open.value;
// Field: tcp_stream_regs.control.close
always_comb begin
automatic logic [0:0] next_c;
automatic logic load_next_c;
next_c = field_storage.control.close.value;
load_next_c = '0;
if(decoded_reg_strb.control && decoded_req_is_wr) begin // SW write
next_c = (field_storage.control.close.value & ~decoded_wr_biten[2:2]) | (decoded_wr_data[2:2] & decoded_wr_biten[2:2]);
load_next_c = '1;
end else if(hwif_in.control.close.hwclr) begin // HW Clear
next_c = '0;
load_next_c = '1;
end
field_combo.control.close.next = next_c;
field_combo.control.close.load_next = load_next_c;
end
always_ff @(posedge clk) begin
if(rst) begin
field_storage.control.close.value <= 1'h0;
end else if(field_combo.control.close.load_next) begin
field_storage.control.close.value <= field_combo.control.close.next;
end
end
assign hwif_out.control.close.value = field_storage.control.close.value;
assign hwif_out.m2s_dma_regs.req = decoded_reg_strb.m2s_dma_regs;
assign hwif_out.m2s_dma_regs.addr = decoded_addr[4:0];
assign hwif_out.m2s_dma_regs.req_is_wr = decoded_req_is_wr;
assign hwif_out.m2s_dma_regs.wr_data = decoded_wr_data;
assign hwif_out.m2s_dma_regs.wr_biten = decoded_wr_biten;
//--------------------------------------------------------------------------
// Write response
//--------------------------------------------------------------------------
always_comb begin
automatic logic wr_ack;
wr_ack = '0;
wr_ack |= hwif_in.m2s_dma_regs.wr_ack;
external_wr_ack = wr_ack;
end
assign cpuif_wr_ack = external_wr_ack | (decoded_req & decoded_req_is_wr & ~decoded_strb_is_external);
// Writes are always granted with no error response
assign cpuif_wr_err = '0;
//--------------------------------------------------------------------------
// Readback
//--------------------------------------------------------------------------
logic readback_external_rd_ack_c;
always_comb begin
automatic logic rd_ack;
rd_ack = '0;
rd_ack |= hwif_in.m2s_dma_regs.rd_ack;
readback_external_rd_ack_c = rd_ack;
end
logic readback_external_rd_ack;
assign readback_external_rd_ack = readback_external_rd_ack_c;
logic readback_err;
logic readback_done;
logic [31:0] readback_data;
// Assign readback values to a flattened array
logic [31:0] readback_array[6];
assign readback_array[0][31:0] = (decoded_reg_strb.source_port && !decoded_req_is_wr) ? field_storage.source_port.d.value : '0;
assign readback_array[1][31:0] = (decoded_reg_strb.source_ip && !decoded_req_is_wr) ? field_storage.source_ip.d.value : '0;
assign readback_array[2][31:0] = (decoded_reg_strb.dest_port && !decoded_req_is_wr) ? field_storage.dest_port.d.value : '0;
assign readback_array[3][31:0] = (decoded_reg_strb.dest_ip && !decoded_req_is_wr) ? field_storage.dest_ip.d.value : '0;
assign readback_array[4][0:0] = (decoded_reg_strb.control && !decoded_req_is_wr) ? field_storage.control.enable.value : '0;
assign readback_array[4][1:1] = (decoded_reg_strb.control && !decoded_req_is_wr) ? field_storage.control.open.value : '0;
assign readback_array[4][2:2] = (decoded_reg_strb.control && !decoded_req_is_wr) ? field_storage.control.close.value : '0;
assign readback_array[4][5:3] = (decoded_reg_strb.control && !decoded_req_is_wr) ? hwif_in.control.state.next : '0;
assign readback_array[4][31:6] = '0;
assign readback_array[5] = hwif_in.m2s_dma_regs.rd_ack ? hwif_in.m2s_dma_regs.rd_data : '0;
// Reduce the array
always_comb begin
automatic logic [31:0] readback_data_var;
readback_done = decoded_req & ~decoded_req_is_wr & ~decoded_strb_is_external;
readback_err = '0;
readback_data_var = '0;
for(int i=0; i<6; i++) readback_data_var |= readback_array[i];
readback_data = readback_data_var;
end
assign external_rd_ack = readback_external_rd_ack;
assign cpuif_rd_ack = readback_done | readback_external_rd_ack;
assign cpuif_rd_data = readback_data;
assign cpuif_rd_err = readback_err;
endmodule

View File

@@ -0,0 +1,104 @@
// Generated by PeakRDL-regblock - A free and open-source SystemVerilog generator
// https://github.com/SystemRDL/PeakRDL-regblock
package tcp_stream_regs_pkg;
localparam TCP_STREAM_REGS_DATA_WIDTH = 32;
localparam TCP_STREAM_REGS_MIN_ADDR_WIDTH = 6;
typedef struct {
logic hwclr;
} tcp_stream_regs__control__open__in_t;
typedef struct {
logic hwclr;
} tcp_stream_regs__control__close__in_t;
typedef struct {
logic [2:0] next;
} tcp_stream_regs__control__state__in_t;
typedef struct {
tcp_stream_regs__control__open__in_t open;
tcp_stream_regs__control__close__in_t close;
tcp_stream_regs__control__state__in_t state;
} tcp_stream_regs__control__in_t;
typedef struct {
logic rd_ack;
logic [31:0] rd_data;
logic wr_ack;
} m2s_dma_regs__external__in_t;
typedef struct {
tcp_stream_regs__control__in_t control;
m2s_dma_regs__external__in_t m2s_dma_regs;
} tcp_stream_regs__in_t;
typedef struct {
logic [31:0] value;
} tcp_stream_regs__source_port__d__out_t;
typedef struct {
tcp_stream_regs__source_port__d__out_t d;
} tcp_stream_regs__source_port__out_t;
typedef struct {
logic [31:0] value;
} tcp_stream_regs__source_ip__d__out_t;
typedef struct {
tcp_stream_regs__source_ip__d__out_t d;
} tcp_stream_regs__source_ip__out_t;
typedef struct {
logic [31:0] value;
} tcp_stream_regs__dest_port__d__out_t;
typedef struct {
tcp_stream_regs__dest_port__d__out_t d;
} tcp_stream_regs__dest_port__out_t;
typedef struct {
logic [31:0] value;
} tcp_stream_regs__dest_ip__d__out_t;
typedef struct {
tcp_stream_regs__dest_ip__d__out_t d;
} tcp_stream_regs__dest_ip__out_t;
typedef struct {
logic value;
} tcp_stream_regs__control__enable__out_t;
typedef struct {
logic value;
} tcp_stream_regs__control__open__out_t;
typedef struct {
logic value;
} tcp_stream_regs__control__close__out_t;
typedef struct {
tcp_stream_regs__control__enable__out_t enable;
tcp_stream_regs__control__open__out_t open;
tcp_stream_regs__control__close__out_t close;
} tcp_stream_regs__control__out_t;
typedef struct {
logic req;
logic [3:0] addr;
logic req_is_wr;
logic [31:0] wr_data;
logic [31:0] wr_biten;
} m2s_dma_regs__external__out_t;
typedef struct {
tcp_stream_regs__source_port__out_t source_port;
tcp_stream_regs__source_ip__out_t source_ip;
tcp_stream_regs__dest_port__out_t dest_port;
tcp_stream_regs__dest_ip__out_t dest_ip;
tcp_stream_regs__control__out_t control;
m2s_dma_regs__external__out_t m2s_dma_regs;
} tcp_stream_regs__out_t;
endpackage

View File

@@ -0,0 +1,188 @@
// Generated by PeakRDL-regblock - A free and open-source SystemVerilog generator
// https://github.com/SystemRDL/PeakRDL-regblock
module tcp_top_regfile (
input wire clk,
input wire rst,
input wire s_cpuif_req,
input wire s_cpuif_req_is_wr,
input wire [7:0] s_cpuif_addr,
input wire [31:0] s_cpuif_wr_data,
input wire [31:0] s_cpuif_wr_biten,
output wire s_cpuif_req_stall_wr,
output wire s_cpuif_req_stall_rd,
output wire s_cpuif_rd_ack,
output wire s_cpuif_rd_err,
output wire [31:0] s_cpuif_rd_data,
output wire s_cpuif_wr_ack,
output wire s_cpuif_wr_err,
input tcp_top_regfile_pkg::tcp_top_regfile__in_t hwif_in,
output tcp_top_regfile_pkg::tcp_top_regfile__out_t hwif_out
);
//--------------------------------------------------------------------------
// CPU Bus interface logic
//--------------------------------------------------------------------------
logic cpuif_req;
logic cpuif_req_is_wr;
logic [7:0] cpuif_addr;
logic [31:0] cpuif_wr_data;
logic [31:0] cpuif_wr_biten;
logic cpuif_req_stall_wr;
logic cpuif_req_stall_rd;
logic cpuif_rd_ack;
logic cpuif_rd_err;
logic [31:0] cpuif_rd_data;
logic cpuif_wr_ack;
logic cpuif_wr_err;
assign cpuif_req = s_cpuif_req;
assign cpuif_req_is_wr = s_cpuif_req_is_wr;
assign cpuif_addr = s_cpuif_addr;
assign cpuif_wr_data = s_cpuif_wr_data;
assign cpuif_wr_biten = s_cpuif_wr_biten;
assign s_cpuif_req_stall_wr = cpuif_req_stall_wr;
assign s_cpuif_req_stall_rd = cpuif_req_stall_rd;
assign s_cpuif_rd_ack = cpuif_rd_ack;
assign s_cpuif_rd_err = cpuif_rd_err;
assign s_cpuif_rd_data = cpuif_rd_data;
assign s_cpuif_wr_ack = cpuif_wr_ack;
assign s_cpuif_wr_err = cpuif_wr_err;
logic cpuif_req_masked;
logic external_req;
logic external_pending;
logic external_wr_ack;
logic external_rd_ack;
always_ff @(posedge clk) begin
if(rst) begin
external_pending <= '0;
end else begin
if(external_req & ~external_wr_ack & ~external_rd_ack) external_pending <= '1;
else if(external_wr_ack | external_rd_ack) external_pending <= '0;
assert(!external_wr_ack || (external_pending | external_req))
else $error("An external wr_ack strobe was asserted when no external request was active");
assert(!external_rd_ack || (external_pending | external_req))
else $error("An external rd_ack strobe was asserted when no external request was active");
end
end
// Read & write latencies are balanced. Stalls not required
// except if external
assign cpuif_req_stall_rd = external_pending;
assign cpuif_req_stall_wr = external_pending;
assign cpuif_req_masked = cpuif_req
& !(!cpuif_req_is_wr & cpuif_req_stall_rd)
& !(cpuif_req_is_wr & cpuif_req_stall_wr);
//--------------------------------------------------------------------------
// Address Decode
//--------------------------------------------------------------------------
typedef struct {
logic tcp_streams[4];
} decoded_reg_strb_t;
decoded_reg_strb_t decoded_reg_strb;
logic decoded_strb_is_external;
logic [7:0] decoded_addr;
logic decoded_req;
logic decoded_req_is_wr;
logic [31:0] decoded_wr_data;
logic [31:0] decoded_wr_biten;
always_comb begin
automatic logic is_external;
is_external = '0;
for(int i0=0; i0<4; i0++) begin
decoded_reg_strb.tcp_streams[i0] = cpuif_req_masked & (cpuif_addr >= 8'h0 + i0*8'h40) & (cpuif_addr <= 8'h0 + i0*8'h40 + 8'h2f);
is_external |= cpuif_req_masked & (cpuif_addr >= 8'h0 + i0*8'h40) & (cpuif_addr <= 8'h0 + i0*8'h40 + 8'h2f);
end
decoded_strb_is_external = is_external;
external_req = is_external;
end
// Pass down signals to next stage
assign decoded_addr = cpuif_addr;
assign decoded_req = cpuif_req_masked;
assign decoded_req_is_wr = cpuif_req_is_wr;
assign decoded_wr_data = cpuif_wr_data;
assign decoded_wr_biten = cpuif_wr_biten;
//--------------------------------------------------------------------------
// Field logic
//--------------------------------------------------------------------------
for(genvar i0=0; i0<4; i0++) begin
assign hwif_out.tcp_streams[i0].req = decoded_reg_strb.tcp_streams[i0];
assign hwif_out.tcp_streams[i0].addr = decoded_addr[5:0];
assign hwif_out.tcp_streams[i0].req_is_wr = decoded_req_is_wr;
assign hwif_out.tcp_streams[i0].wr_data = decoded_wr_data;
assign hwif_out.tcp_streams[i0].wr_biten = decoded_wr_biten;
end
//--------------------------------------------------------------------------
// Write response
//--------------------------------------------------------------------------
always_comb begin
automatic logic wr_ack;
wr_ack = '0;
for(int i0=0; i0<4; i0++) begin
wr_ack |= hwif_in.tcp_streams[i0].wr_ack;
end
external_wr_ack = wr_ack;
end
assign cpuif_wr_ack = external_wr_ack | (decoded_req & decoded_req_is_wr & ~decoded_strb_is_external);
// Writes are always granted with no error response
assign cpuif_wr_err = '0;
//--------------------------------------------------------------------------
// Readback
//--------------------------------------------------------------------------
logic readback_external_rd_ack_c;
always_comb begin
automatic logic rd_ack;
rd_ack = '0;
for(int i0=0; i0<4; i0++) begin
rd_ack |= hwif_in.tcp_streams[i0].rd_ack;
end
readback_external_rd_ack_c = rd_ack;
end
logic readback_external_rd_ack;
assign readback_external_rd_ack = readback_external_rd_ack_c;
logic readback_err;
logic readback_done;
logic [31:0] readback_data;
// Assign readback values to a flattened array
logic [31:0] readback_array[4];
for(genvar i0=0; i0<4; i0++) begin
assign readback_array[i0*1 + 0] = hwif_in.tcp_streams[i0].rd_ack ? hwif_in.tcp_streams[i0].rd_data : '0;
end
// Reduce the array
always_comb begin
automatic logic [31:0] readback_data_var;
readback_done = decoded_req & ~decoded_req_is_wr & ~decoded_strb_is_external;
readback_err = '0;
readback_data_var = '0;
for(int i=0; i<4; i++) readback_data_var |= readback_array[i];
readback_data = readback_data_var;
end
assign external_rd_ack = readback_external_rd_ack;
assign cpuif_rd_ack = readback_done | readback_external_rd_ack;
assign cpuif_rd_data = readback_data;
assign cpuif_rd_err = readback_err;
endmodule

View File

@@ -0,0 +1,30 @@
// Generated by PeakRDL-regblock - A free and open-source SystemVerilog generator
// https://github.com/SystemRDL/PeakRDL-regblock
package tcp_top_regfile_pkg;
localparam TCP_TOP_REGFILE_DATA_WIDTH = 32;
localparam TCP_TOP_REGFILE_MIN_ADDR_WIDTH = 8;
typedef struct {
logic rd_ack;
logic [31:0] rd_data;
logic wr_ack;
} tcp_stream_regs__external__in_t;
typedef struct {
tcp_stream_regs__external__in_t tcp_streams[4];
} tcp_top_regfile__in_t;
typedef struct {
logic req;
logic [5:0] addr;
logic req_is_wr;
logic [31:0] wr_data;
logic [31:0] wr_biten;
} tcp_stream_regs__external__out_t;
typedef struct {
tcp_stream_regs__external__out_t tcp_streams[4];
} tcp_top_regfile__out_t;
endpackage

View File

@@ -0,0 +1,3 @@
addrmap tcp_top_regfile{
external tcp_stream_regs tcp_streams[4] += 0x40;
};

View File

@@ -0,0 +1,276 @@
module tcp #(
parameter NUM_TCP=8,
parameter DATA_WIDTH=8
)(
input i_clk,
input i_rst,
input wire s_cpuif_req,
input wire s_cpuif_req_is_wr,
input wire [8:0] s_cpuif_addr,
input wire [31:0] s_cpuif_wr_data,
input wire [31:0] s_cpuif_wr_biten,
output wire s_cpuif_req_stall_wr,
output wire s_cpuif_req_stall_rd,
output wire s_cpuif_rd_ack,
output wire s_cpuif_rd_err,
output wire [31:0] s_cpuif_rd_data,
output wire s_cpuif_wr_ack,
output wire s_cpuif_wr_err,
/*
* IP input
*/
ip_intf.SLAVE s_ip,
/*
* IP output
*/
ip_intf.MASTER m_ip,
/*
* AXI DMA Interface
*/
axil_intf.MASTER m_dma_axil
);
tcp_top_regfile_pkg::tcp_top_regfile__in_t tcp_hwif_in;
tcp_top_regfile_pkg::tcp_top_regfile__out_t tcp_hwif_out;
tcp_top_regfile u_tcp_top_regfile (
.clk (i_clk),
.rst (i_rst),
.s_cpuif_req (s_cpuif_req),
.s_cpuif_req_is_wr (s_cpuif_req_is_wr),
.s_cpuif_addr (s_cpuif_addr),
.s_cpuif_wr_data (s_cpuif_wr_data),
.s_cpuif_wr_biten (s_cpuif_wr_biten),
.s_cpuif_req_stall_wr (),
.s_cpuif_req_stall_rd (),
.s_cpuif_rd_ack (s_cpuif_rd_ack),
.s_cpuif_rd_err (),
.s_cpuif_rd_data (s_cpuif_rd_data),
.s_cpuif_wr_ack (s_cpuif_wr_ack),
.s_cpuif_wr_err (),
.hwif_in (tcp_hwif_in),
.hwif_out (tcp_hwif_out)
);
localparam KEEP_WIDTH = ((DATA_WIDTH+7)/8);
localparam USER_WIDTH = 1;
localparam DEST_WIDTH = 8;
localparam ID_WIDTH = 8;
ip_intf #(.DATA_WIDTH(8)) tcp_stream_tx_ip [NUM_TCP]();
ip_intf #(.DATA_WIDTH(8)) tcp_delayed_rx_ip();
ip_intf #(.DATA_WIDTH(8)) tcp_stream_rx_ip [NUM_TCP]();
axil_intf m2s_stream_axil[NUM_TCP]();
axil_intf s2m_stream_axil[NUM_TCP]();
//m2s dma
wire [NUM_TCP-1:0] xbar_s_m2s_axi_arvalid;
wire [NUM_TCP-1:0] xbar_s_m2s_axi_arready;
wire [NUM_TCP*32-1:0] xbar_s_m2s_axi_araddr;
wire [NUM_TCP*3-1:0] xbar_s_m2s_axi_arprot;
wire [NUM_TCP-1:0] xbar_s_m2s_axi_rvalid;
wire [NUM_TCP-1:0] xbar_s_m2s_axi_rready;
wire [NUM_TCP*32-1:0] xbar_s_m2s_axi_rdata;
wire [NUM_TCP*2-1:0] xbar_s_m2s_axi_rresp;
wire [NUM_TCP-1:0] xbar_s_s2m_axi_arvalid;
wire [NUM_TCP-1:0] xbar_s_s2m_axi_arready;
wire [NUM_TCP*32-1:0] xbar_s_s2m_axi_araddr;
wire [NUM_TCP*3-1:0] xbar_s_s2m_axi_arprot;
wire [NUM_TCP-1:0] xbar_s_s2m_axi_rvalid;
wire [NUM_TCP-1:0] xbar_s_s2m_axi_rready;
wire [NUM_TCP*32-1:0] xbar_s_s2m_axi_rdata;
wire [NUM_TCP*2-1:0] xbar_s_s2m_axi_rresp;
axilxbar #(
.NM(NUM_TCP*2),
.NS(1),
.SLAVE_ADDR(
{32'h0, 32'hffffffff} // full address space
)
) u_m2s_xbar (
.S_AXI_ACLK (i_clk),
.S_AXI_ARESETN (~i_rst),
// No write channel
.S_AXI_AWVALID ('0),
.S_AXI_AWREADY (),
.S_AXI_AWADDR ('0),
.S_AXI_AWPROT ('0),
.S_AXI_WVALID ('0),
.S_AXI_WREADY (),
.S_AXI_WDATA ('0),
.S_AXI_WSTRB ('0),
.S_AXI_BVALID (),
.S_AXI_BREADY ('0),
.S_AXI_BRESP (),
.S_AXI_ARVALID ({xbar_s_m2s_axi_arvalid, xbar_s_s2m_axi_arvalid }),
.S_AXI_ARREADY ({xbar_s_m2s_axi_arready, xbar_s_s2m_axi_arready }),
.S_AXI_ARADDR ({xbar_s_m2s_axi_araddr, xbar_s_s2m_axi_araddr }),
.S_AXI_ARPROT ({xbar_s_m2s_axi_arprot, xbar_s_s2m_axi_arprot }),
.S_AXI_RVALID ({xbar_s_m2s_axi_rvalid, xbar_s_s2m_axi_rvalid }),
.S_AXI_RREADY ({xbar_s_m2s_axi_rready, xbar_s_s2m_axi_rready }),
.S_AXI_RDATA ({xbar_s_m2s_axi_rdata, xbar_s_s2m_axi_rdata }),
.S_AXI_RRESP ({xbar_s_m2s_axi_rresp, xbar_s_s2m_axi_rresp }),
.M_AXI_AWADDR (m_dma_axil.awaddr),
.M_AXI_AWPROT (m_dma_axil.awprot),
.M_AXI_AWVALID (m_dma_axil.awvalid),
.M_AXI_AWREADY (m_dma_axil.awready),
.M_AXI_WDATA (m_dma_axil.wdata),
.M_AXI_WSTRB (m_dma_axil.wstrb),
.M_AXI_WVALID (m_dma_axil.wvalid),
.M_AXI_WREADY (m_dma_axil.wready),
.M_AXI_BRESP (m_dma_axil.bresp),
.M_AXI_BVALID (m_dma_axil.bvalid),
.M_AXI_BREADY (m_dma_axil.bready),
.M_AXI_ARADDR (m_dma_axil.araddr),
.M_AXI_ARPROT (m_dma_axil.arprot),
.M_AXI_ARVALID (m_dma_axil.arvalid),
.M_AXI_ARREADY (m_dma_axil.arready),
.M_AXI_RDATA (m_dma_axil.rdata),
.M_AXI_RRESP (m_dma_axil.rresp),
.M_AXI_RVALID (m_dma_axil.rvalid),
.M_AXI_RREADY (m_dma_axil.rready)
);
generate
for (genvar i = 0; i < NUM_TCP; i++) begin
assign xbar_s_m2s_axi_arvalid[i] = m2s_stream_axil[i].arvalid;
assign m2s_stream_axil[i].arready = xbar_s_m2s_axi_arready[i];
assign xbar_s_m2s_axi_araddr[32*i+:32] = m2s_stream_axil[i].araddr;
assign xbar_s_m2s_axi_arprot[3*i+:3] = m2s_stream_axil[i].arprot;
assign m2s_stream_axil[i].rvalid = xbar_s_m2s_axi_rvalid[i];
assign xbar_s_m2s_axi_rready[i] = m2s_stream_axil[i].rready;
assign m2s_stream_axil[i].rdata = xbar_s_m2s_axi_rdata[32*i+:32];
assign m2s_stream_axil[i].rresp = xbar_s_m2s_axi_rresp[2*i+:2];
assign xbar_s_s2m_axi_arvalid[i] = s2m_stream_axil[i].arvalid;
assign s2m_stream_axil[i].arready = xbar_s_s2m_axi_arready[i];
assign xbar_s_s2m_axi_araddr[32*i+:32] = s2m_stream_axil[i].araddr;
assign xbar_s_s2m_axi_arprot[3*i+:3] = s2m_stream_axil[i].arprot;
assign s2m_stream_axil[i].rvalid = xbar_s_s2m_axi_rvalid[i];
assign xbar_s_s2m_axi_rready[i] = s2m_stream_axil[i].rready;
assign s2m_stream_axil[i].rdata = xbar_s_s2m_axi_rdata[32*i+:32];
assign s2m_stream_axil[i].rresp = xbar_s_s2m_axi_rresp[2*i+:2];
end
endgenerate
//s2m dma
// tx_stream arb mux (ip)
ip_arb_mux_wrapper #(
.S_COUNT(NUM_TCP),
.DATA_WIDTH(DATA_WIDTH)
) u_tx_stream_arb_mux (
.i_clk (i_clk),
.i_rst (i_rst),
.s_ip (tcp_stream_tx_ip),
.m_ip (m_ip)
);
// dest decap
logic [15:0] tcp_dest;
logic tcp_dest_valid;
tcp_dest_decap u_tcp_dest_decap(
.i_clk (i_clk),
.i_rst (i_rst),
.s_ip (s_ip),
.m_ip (tcp_delayed_rx_ip),
.o_tcp_dest (tcp_dest),
.o_tcp_dest_valid(tcp_dest_valid)
);
// rx_stream demux (ip)
logic [$clog2(NUM_TCP)-1:0] tcp_demux_sel;
logic [15:0] tcp_dests [NUM_TCP];
always_comb begin : TCP_DEST_SEL
tcp_demux_sel = '0;
for (int i = 0; i < NUM_TCP; i++) begin
if (tcp_dest == tcp_dests[i]) begin
tcp_demux_sel = i;
end
end
end
ip_demux_wrapper #(
.M_COUNT(NUM_TCP)
) u_ip_demux (
.clk (i_clk),
.rst (i_rst),
.s_ip (tcp_delayed_rx_ip),
.m_ip (tcp_stream_rx_ip),
.enable (tcp_dest_valid),
.drop ('0),
.select (tcp_demux_sel)
);
generate
for (genvar i = 0; i < NUM_TCP; i++) begin : TCP_STREAMS
logic req;
logic req_is_wr;
logic [5:0] addr;
logic [31:0] wr_data;
logic [31:0] wr_biten;
assign req = tcp_hwif_out.tcp_streams[i].req;
assign req_is_wr = tcp_hwif_out.tcp_streams[i].req_is_wr;
assign addr = tcp_hwif_out.tcp_streams[i].addr;
assign wr_data = tcp_hwif_out.tcp_streams[i].wr_data;
assign wr_biten = tcp_hwif_out.tcp_streams[i].wr_biten;
tcp_stream u_tcp_stream (
.clk (i_clk),
.rst (i_rst),
// This is the hacky decoder alex was telling me about
.s_cpuif_req (req),
.s_cpuif_req_is_wr (req_is_wr),
.s_cpuif_addr (addr),
.s_cpuif_wr_data (wr_data),
.s_cpuif_wr_biten (wr_biten),
.s_cpuif_req_stall_wr (),
.s_cpuif_req_stall_rd (),
.s_cpuif_rd_ack (tcp_hwif_in.tcp_streams[i].rd_ack),
.s_cpuif_rd_err (),
.s_cpuif_rd_data (tcp_hwif_in.tcp_streams[i].rd_data),
.s_cpuif_wr_ack (tcp_hwif_in.tcp_streams[i].wr_ack),
.s_cpuif_wr_err (),
.o_tcp_port (tcp_dests[i]),
.s_ip_rx (tcp_stream_rx_ip[i]),
.m_ip_tx (tcp_stream_tx_ip[i]),
.m_m2s_axil (m2s_stream_axil[i]),
.m_s2m_axil (s2m_stream_axil[i])
);
end
endgenerate
endmodule

View File

@@ -0,0 +1,148 @@
module tcp_dest_decap (
input i_clk,
input i_rst,
ip_intf.SLAVE s_ip,
ip_intf.MASTER m_ip,
output wire [15:0] o_tcp_dest,
output wire o_tcp_dest_valid
);
logic [15:0] tcp_dest, tcp_dest_next;
logic [31:0] pipe, pipe_next;
logic [3:0] pipe_valid, pipe_valid_next;
logic [3:0] pipe_last, pipe_last_next;
logic valid;
enum logic [1:0] {PORTS, PASSTHROUGH} state, state_next;
logic [1:0] counter, counter_next;
// We don't need the mac addresses or the ethertype.
assign m_ip.eth_src_mac = '0;
assign m_ip.eth_dest_mac = '0;
assign m_ip.eth_type = '0;
assign o_tcp_dest_valid = valid;
assign o_tcp_dest = tcp_dest;
skidbuffer #(
.DW(160)
) u_tcp_ip_hdr_skidbuffer (
.i_clk (i_clk),
.i_reset (i_rst),
.i_valid (s_ip.ip_hdr_valid),
.o_ready (s_ip.ip_hdr_ready),
.i_data ({
s_ip.ip_version,
s_ip.ip_ihl,
s_ip.ip_dscp,
s_ip.ip_ecn,
s_ip.ip_length,
s_ip.ip_identification,
s_ip.ip_flags,
s_ip.ip_fragment_offset,
s_ip.ip_ttl,
s_ip.ip_protocol,
s_ip.ip_header_checksum,
s_ip.ip_source_ip,
s_ip.ip_dest_ip
}),
.o_valid (m_ip.ip_hdr_valid),
.i_ready (m_ip.ip_hdr_ready),
.o_data ({
m_ip.ip_version,
m_ip.ip_ihl,
m_ip.ip_dscp,
m_ip.ip_ecn,
m_ip.ip_length,
m_ip.ip_identification,
m_ip.ip_flags,
m_ip.ip_fragment_offset,
m_ip.ip_ttl,
m_ip.ip_protocol,
m_ip.ip_header_checksum,
m_ip.ip_source_ip,
m_ip.ip_dest_ip
})
);
always_ff @(posedge i_clk) begin
if (i_rst) begin
tcp_dest <= '0;
pipe <= '0;
pipe_valid <= '0;
pipe_last <= '0;
state <= PORTS;
counter <= '0;
end else begin
tcp_dest <= tcp_dest_next;
pipe <= pipe_next;
pipe_valid <= pipe_valid_next;
pipe_last <= pipe_last_next;
state <= state_next;
counter <= counter_next;
end
end
always_comb begin
tcp_dest_next = tcp_dest;
state_next = state;
pipe_next = pipe;
pipe_valid_next = pipe_valid;
pipe_last_next = pipe_last;
counter_next = pipe;
s_ip.ip_payload_axis_tready = '0;
valid = '0;
m_ip.ip_payload_axis_tdata = '0;
m_ip.ip_payload_axis_tvalid = '0;
m_ip.ip_payload_axis_tlast = '0;
m_ip.ip_payload_axis_tuser = '0;
m_ip.ip_payload_axis_tid = '0;
m_ip.ip_payload_axis_tdest = '0;
case (state)
PORTS: begin
s_ip.ip_payload_axis_tready = 1;
valid = '0;
if (s_ip.ip_payload_axis_tvalid) begin
counter_next = counter + 1;
pipe_valid_next = {pipe_valid[2:0], 1'b1};
pipe_next = {pipe_next[23:0], s_ip.ip_payload_axis_tdata};
if (counter == 2'h3) begin
state_next = PASSTHROUGH;
tcp_dest_next = pipe_next[15:0];
end
end
end
PASSTHROUGH: begin
// match ready except if we have seen last, then just finish it out.
pipe_valid_next = {pipe_valid[2:0], s_ip.ip_payload_axis_tvalid};
pipe_last_next = {pipe_last[2:0], s_ip.ip_payload_axis_tlast};
pipe_next = {pipe_next[23:0], s_ip.ip_payload_axis_tdata};
s_ip.ip_payload_axis_tready = m_ip.ip_payload_axis_tready;
m_ip.ip_payload_axis_tvalid = pipe_valid[3];
m_ip.ip_payload_axis_tlast = pipe_last[3];
m_ip.ip_payload_axis_tdata = pipe[31:24];
valid = '1;
if (pipe_last[3] && pipe_valid[3]) begin
state_next = PORTS;
end
end
endcase
end
endmodule

View File

@@ -0,0 +1,262 @@
module tcp_packet_generator (
input wire i_clk,
input wire i_rst,
axis_intf.SLAVE s_axis_data,
input wire i_no_data,
input wire [15:0] i_ip_len,
input wire [31:0] i_seq_number,
input wire [31:0] i_ack_number,
input wire [15:0] i_source_port,
input wire [15:0] i_dest_port,
input wire [7:0] i_flags,
input wire [15:0] i_window_size,
input wire i_hdr_valid,
input wire [31:0] i_src_ip,
input wire [31:0] i_dst_ip,
output logic o_packet_done,
ip_intf.MASTER m_ip
);
axis_intf #(.DATA_WIDTH(8)) pre_checksum_data();
axis_intf #(.DATA_WIDTH(8)) post_checksum_data();
logic saf_ready;
assign pre_checksum_data.tdata = s_axis_data.tdata;
assign pre_checksum_data.tkeep = s_axis_data.tkeep;
assign pre_checksum_data.tvalid = s_axis_data.tvalid & saf_ready;
assign s_axis_data.tready = pre_checksum_data.tready & saf_ready;
assign pre_checksum_data.tlast = s_axis_data.tlast;
assign pre_checksum_data.tuser = s_axis_data.tuser;
axis_saf_fifo #(
.DATA_DEPTH_L2(11),
.CTRL_DEPTH_L2(2)
) u_checksum_fifo (
.sclk(i_clk),
.srst(i_rst),
.s_axis(pre_checksum_data),
.mclk(i_clk),
.mrst(i_rst),
.m_axis(post_checksum_data)
);
logic [31:0] counter, counter_next;
enum logic [1:0] {IDLE, DATA_CHECKSUM, HEADER, DATA} state, state_next;
logic [31:0] checksum_counter, checksum_counter_next;
logic [15:0] data_checksum;
assign data_checksum = '0;
logic checksum_enable;
logic checksum_clear;
logic [31:0] checksum_data;
logic [15:0] checksum_final;
logic [31:0] data_expand, data_expand_next;
logic data_checksum_enable;
logic data_checksum_clear;
logic [31:0] data_checksum_data;
logic [15:0] data_checksum_final;
logic [31:0] src_ip, dst_ip_next;
logic [31:0] dst_ip, src_ip_next;
checksum_calc u_header_checksum_calc(
.i_rst (i_rst),
.i_clk (i_clk),
.i_clear (checksum_clear),
.i_enable (checksum_enable),
.i_data (checksum_data),
.o_checksum (checksum_final)
);
always_ff @(posedge i_clk) begin
if (i_rst) begin
counter <= '0;
checksum_counter <= '0;
state <= IDLE;
data_expand <= '0;
src_ip <= '0;
dst_ip <= '0;
end else begin
counter <= counter_next;
checksum_counter <= checksum_counter_next;
state <= state_next;
data_expand <= data_expand_next;
src_ip <= src_ip_next;
dst_ip <= dst_ip_next;
end
end
always_comb begin
state_next = state;
m_ip.ip_hdr_valid = '0;
m_ip.ip_dscp = '0;
m_ip.ip_ecn = '0;
m_ip.ip_length = '0;
m_ip.ip_ttl = '0;
m_ip.ip_protocol = '0;
m_ip.ip_source_ip = '0;
m_ip.ip_dest_ip = '0;
m_ip.ip_payload_axis_tdata = '0;
m_ip.ip_payload_axis_tvalid = '0;
m_ip.ip_payload_axis_tlast = '0;
m_ip.ip_payload_axis_tuser = '0;
m_ip.ip_payload_axis_tid = '0;
m_ip.ip_payload_axis_tdest = '0;
post_checksum_data.tready = '0;
checksum_counter_next = checksum_counter;
checksum_data = '0;
counter_next = counter;
o_packet_done = '0;
checksum_clear = '0;
checksum_enable = '0;
saf_ready = '0;
data_expand_next = data_expand;
src_ip_next = src_ip;
dst_ip_next = dst_ip;
case (state)
IDLE: begin
counter_next = '0;
checksum_counter_next = '0;
checksum_clear = '1;
if (i_hdr_valid) begin
m_ip.ip_hdr_valid = '1;
m_ip.ip_dscp = '0;
m_ip.ip_ecn = '0;
m_ip.ip_length = i_ip_len;
m_ip.ip_ttl = '1;
m_ip.ip_protocol = 8'h6;
m_ip.ip_source_ip = i_src_ip;
m_ip.ip_dest_ip = i_dst_ip;
src_ip_next = i_src_ip;
dst_ip_next = i_dst_ip;
if (m_ip.ip_hdr_ready) begin
if (i_no_data) begin
state_next = HEADER;
end else begin
state_next = DATA_CHECKSUM;
end
end
end
end
DATA_CHECKSUM: begin
saf_ready = '1;
data_expand_next = {data_expand[23:0], pre_checksum_data.tdata};
// data_expand_next = {pre_checksum_data.tdata, data_expand[31:8]};
if (checksum_counter[1:0] == '1) begin
checksum_enable = '1;
checksum_data = data_expand_next;
end
if (s_axis_data.tready & s_axis_data.tvalid) begin
checksum_counter_next = checksum_counter + 1;
if (s_axis_data.tlast) begin
state_next = HEADER;
checksum_counter_next = '0;
end
end
end
HEADER: begin
m_ip.ip_payload_axis_tvalid = '1;
if (checksum_counter < 8) begin
checksum_counter_next = checksum_counter + 1;
checksum_enable = '1;
end
case (checksum_counter)
0: checksum_data = src_ip;
1: checksum_data = dst_ip;
2: checksum_data = {8'b0, 8'h6, (i_ip_len - 16'd20)}; // tcp length, not IP length
3: checksum_data = {i_source_port, i_dest_port};
4: checksum_data = i_seq_number;
5: checksum_data = i_ack_number;
6: checksum_data = {4'h5, 4'h0, i_flags, i_window_size};
7: checksum_data = '0; // checksum and urgent pointer
endcase
case (counter)
0: m_ip.ip_payload_axis_tdata = i_source_port[15:8];
1: m_ip.ip_payload_axis_tdata = i_source_port[7:0];
2: m_ip.ip_payload_axis_tdata = i_dest_port[15:8];
3: m_ip.ip_payload_axis_tdata = i_dest_port[7:0];
4: m_ip.ip_payload_axis_tdata = i_seq_number[31:24];
5: m_ip.ip_payload_axis_tdata = i_seq_number[23:16];
6: m_ip.ip_payload_axis_tdata = i_seq_number[15:8];
7: m_ip.ip_payload_axis_tdata = i_seq_number[7:0];
8: m_ip.ip_payload_axis_tdata = i_ack_number[31:24];
9: m_ip.ip_payload_axis_tdata = i_ack_number[23:16];
10: m_ip.ip_payload_axis_tdata = i_ack_number[15:8];
11: m_ip.ip_payload_axis_tdata = i_ack_number[7:0];
12: m_ip.ip_payload_axis_tdata = {4'h5, 4'h0};
13: m_ip.ip_payload_axis_tdata = i_flags;
14: m_ip.ip_payload_axis_tdata = i_window_size[15:8];
15: m_ip.ip_payload_axis_tdata = i_window_size[7:0];
16: m_ip.ip_payload_axis_tdata = checksum_final[15:8];
17: m_ip.ip_payload_axis_tdata = checksum_final[7:0];
18: m_ip.ip_payload_axis_tdata = '0;
19: begin
m_ip.ip_payload_axis_tdata = '0;
m_ip.ip_payload_axis_tlast = i_no_data; // kinda hacky
end
endcase
if (m_ip.ip_payload_axis_tready) begin
counter_next = counter + 1;
if (counter == 19) begin
state_next = DATA;
end
if (m_ip.ip_payload_axis_tlast) begin
state_next = IDLE;
o_packet_done = '1;
end
end
end
DATA: begin
state_next = DATA;
post_checksum_data.tready = m_ip.ip_payload_axis_tready;
m_ip.ip_payload_axis_tvalid = post_checksum_data.tvalid;
m_ip.ip_payload_axis_tdata = post_checksum_data.tdata;
m_ip.ip_payload_axis_tlast = post_checksum_data.tlast;
if (post_checksum_data.tlast && post_checksum_data.tvalid && post_checksum_data.tready) begin
state_next = IDLE;
o_packet_done = '1;
end
end
endcase
end
endmodule

View File

@@ -0,0 +1,123 @@
module tcp_parser(
input wire i_clk,
input wire i_rst,
ip_intf.SLAVE s_ip,
axis_intf.MASTER m_axis,
output wire [31:0] o_seq_number,
output wire [31:0] o_ack_number,
output wire [7:0] o_flags,
output wire [15:0] o_window_size,
output wire o_hdr_valid
);
enum logic {HEADER, PAYLOAD} state, state_next;
logic [4:0] counter, counter_next;
logic hdr_valid;
logic [31:0] sequence_num, sequence_num_next;
logic [31:0] ack_num, ack_num_next;
logic [3:0] data_offs, data_offs_next;
logic [7:0] flags, flags_next;
logic [15:0] window_size, window_size_next;
logic [15:0] checksum, checksum_next;
assign o_seq_number = sequence_num;
assign o_ack_number = ack_num;
assign o_flags = flags;
assign o_window_size = window_size;
assign o_hdr_valid = hdr_valid;
always_ff @(posedge i_clk) begin
if (i_rst) begin
state <= HEADER;
counter <= '0;
sequence_num <= '0;
ack_num <= '0;
data_offs <= '0;
flags <= '0;
window_size <= '0;
checksum <= '0;
end else begin
state <= state_next;
counter <= counter_next;
sequence_num <= sequence_num_next;
ack_num <= ack_num_next;
data_offs <= data_offs_next;
flags <= flags_next;
window_size <= window_size_next;
checksum <= checksum_next;
end
end
always_comb begin
sequence_num_next = sequence_num;
ack_num_next = ack_num;
data_offs_next = data_offs;
flags_next = flags;
window_size_next = window_size;
checksum_next = checksum;
hdr_valid = '0;
counter_next = counter;
state_next = state;
s_ip.ip_hdr_ready = '0;
s_ip.ip_payload_axis_tready = '0;
case (state)
HEADER: begin
s_ip.ip_hdr_ready = '1;
s_ip.ip_payload_axis_tready = '1;
if (s_ip.ip_payload_axis_tvalid) begin
counter_next = counter + 1;
case (counter)
4: sequence_num_next = {s_ip.ip_payload_axis_tdata, sequence_num[23:0]};
5: sequence_num_next = {sequence_num[31:24], s_ip.ip_payload_axis_tdata, sequence_num[15:0]};
6: sequence_num_next = {sequence_num[31:16], s_ip.ip_payload_axis_tdata, sequence_num[7:0]};
7: sequence_num_next = {sequence_num[31:8], s_ip.ip_payload_axis_tdata};
4: ack_num_next = {s_ip.ip_payload_axis_tdata, ack_num[23:0]};
5: ack_num_next = {ack_num[31:24], s_ip.ip_payload_axis_tdata, ack_num[15:0]};
6: ack_num_next = {ack_num[31:16], s_ip.ip_payload_axis_tdata, ack_num[8:0]};
7: ack_num_next = {ack_num[31:8], s_ip.ip_payload_axis_tdata};
12: data_offs_next = s_ip.ip_payload_axis_tdata[7:4];
13: flags_next = s_ip.ip_payload_axis_tdata;
14: window_size_next = {s_ip.ip_payload_axis_tdata, window_size[7:0]};
15: window_size_next = {window_size[15:8], s_ip.ip_payload_axis_tdata};
16: checksum_next = {s_ip.ip_payload_axis_tdata, checksum[7:0]};
17: checksum_next = {checksum[15:8], s_ip.ip_payload_axis_tdata};
19: begin
state_next = PAYLOAD;
hdr_valid = '1;
end
endcase
if (s_ip.ip_payload_axis_tlast) begin
counter_next = '0;
state_next = HEADER; // if we see last then we are done, its possible to have no data
end
end
end
PAYLOAD: begin
s_ip.ip_payload_axis_tready = '1;
if (s_ip.ip_payload_axis_tlast) begin
counter_next = '0;
state_next = HEADER;
end
end
endcase
end
endmodule

View File

@@ -0,0 +1,18 @@
package tcp_pkg;
typedef enum logic [2:0] {
TX_CTRL_NOP,
TX_CTRL_SEND_SYN,
TX_CTRL_SEND_ACK,
TX_CTRL_SEND_SYNACK,
TX_CTRL_SEND_FIN
} tx_ctrl_t;
typedef enum logic [2:0] {
RX_MSG_NOP,
RX_MSG_RECV_SYN,
RX_MSG_RECV_ACK,
RX_MSG_RECV_FIN,
RX_MSG_RECV_SYNACK
} rx_msg_t;
endpackage

View File

@@ -0,0 +1,68 @@
import tcp_pkg::*;
module tcp_rx_ctrl (
input logic i_clk,
input logic i_rst,
output tcp_pkg::rx_msg_t o_rx_msg,
output logic o_rx_msg_valid,
input logic i_rx_msg_ack,
input logic [31:0] i_seq_number,
input logic [31:0] i_ack_number,
input logic [15:0] i_source_port,
input logic [15:0] i_dest_port,
input logic [7:0] i_flags,
input logic [15:0] i_window_size,
input logic i_hdr_valid,
output logic [31:0] o_ack_number
);
tcp_pkg::rx_msg_t rx_msg_next;
logic rx_msg_valid_next;
logic [31:0] ack_num, ack_num_next;
assign o_ack_number = ack_num;
always_ff @(posedge i_clk) begin
if (i_rst) begin
ack_num <= '0;
o_rx_msg <= RX_MSG_NOP;
o_rx_msg_valid <= '0;
end else begin
ack_num <= ack_num_next;
o_rx_msg <= rx_msg_next;
o_rx_msg_valid <= rx_msg_valid_next;
end
end
always_comb begin
rx_msg_next = RX_MSG_NOP;
rx_msg_valid_next = '0;
ack_num_next = ack_num;
if (i_hdr_valid) begin
if (i_flags == 8'h12) begin
rx_msg_next = RX_MSG_RECV_SYNACK;
rx_msg_valid_next = '1;
ack_num_next = i_seq_number + 1;
end
if (i_flags == 8'h11) begin
rx_msg_next = RX_MSG_RECV_FIN;
rx_msg_valid_next = '1;
ack_num_next = i_seq_number + 1;
end
if (i_flags == 8'h10) begin
rx_msg_next = RX_MSG_RECV_ACK;
rx_msg_valid_next = '1;
end
end
end
endmodule

View File

@@ -0,0 +1,142 @@
import tcp_pkg::*;
module tcp_state_manager(
input wire i_clk,
input wire i_rst,
input wire i_enable,
input wire i_open,
output logic o_open_clr,
input wire i_close,
output logic o_close_clr,
output tcp_pkg::tx_ctrl_t o_tx_ctrl,
output logic o_tx_ctrl_valid,
input logic i_tx_ctrl_ack,
input tcp_pkg::rx_msg_t i_rx_msg,
input wire i_rx_msg_valid,
output logic o_rx_msg_ack
);
enum logic [3:0] {
IDLE,
SYN_RCVD, // In this design, this state should not be reached!
SYN_SENT_1,
SYN_SENT_2,
ESTABLISHED,
WAIT_CLOSE,
LAST_ACK,
TIME_WAIT,
FIN_WAIT_1,
FIN_WAIT_2
} tcp_state, tcp_state_next;
always_ff @(posedge i_clk) begin
if (i_rst) begin
tcp_state <= IDLE;
end else begin
if (~i_enable) begin
tcp_state <= IDLE;
end else begin
tcp_state <= tcp_state_next;
end
end
end
always_comb begin
tcp_state_next = tcp_state;
o_tx_ctrl_valid = '0;
o_open_clr = '0;
o_tx_ctrl = TX_CTRL_NOP;
o_tx_ctrl_valid = '0;
o_rx_msg_ack = '0;
case (tcp_state)
IDLE: begin
if (i_open) begin
o_tx_ctrl = TX_CTRL_SEND_SYN;
o_tx_ctrl_valid = '1;
if (i_tx_ctrl_ack) begin
tcp_state_next = SYN_SENT_1;
end
end
end
SYN_SENT_1: begin
if (i_rx_msg_valid && i_rx_msg== RX_MSG_RECV_SYNACK) begin
tcp_state_next = SYN_SENT_2;
end
end
SYN_SENT_2: begin
o_tx_ctrl = TX_CTRL_SEND_ACK;
o_tx_ctrl_valid = '1;
if (i_tx_ctrl_ack) begin
tcp_state_next = ESTABLISHED;
o_open_clr = '1;
end
end
ESTABLISHED: 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_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;
end
end
LAST_ACK: begin
if (i_rx_msg_valid && i_rx_msg == RX_MSG_RECV_ACK) begin
tcp_state_next = IDLE;
end
end
endcase
end
endmodule

View File

@@ -0,0 +1,264 @@
module tcp_stream #(
parameter DATA_WIDTH = 8,
parameter KEEP_WIDTH = ((DATA_WIDTH+7)/8),
parameter DEST_WIDTH = 8,
parameter USER_WIDTH = 1
)(
input wire clk,
input wire rst,
input wire s_cpuif_req,
input wire s_cpuif_req_is_wr,
input wire [5:0] s_cpuif_addr,
input wire [31:0] s_cpuif_wr_data,
input wire [31:0] s_cpuif_wr_biten,
output wire s_cpuif_req_stall_wr,
output wire s_cpuif_req_stall_rd,
output wire s_cpuif_rd_ack,
output wire s_cpuif_rd_err,
output wire [31:0] s_cpuif_rd_data,
output wire s_cpuif_wr_ack,
output wire s_cpuif_wr_err,
output logic [15:0] o_tcp_port,
ip_intf.SLAVE s_ip_rx,
ip_intf.MASTER m_ip_tx,
axil_intf.MASTER m_m2s_axil,
axil_intf.MASTER m_s2m_axil
);
axis_intf m2s_axis();
axis_intf m2s_axis_pre_reg();
axis_intf s2m_axis();
ip_intf m_ip_tx_pre_reg();
axis_intf m2s_post_saf_axis();
axis_intf s2m_pre_saf_axis();
axis_intf m_tx_ctrl_axis_data();
// regs
tcp_stream_regs_pkg::tcp_stream_regs__in_t hwif_in;
tcp_stream_regs_pkg::tcp_stream_regs__out_t hwif_out;
tcp_pkg::tx_ctrl_t tx_ctrl;
logic tx_ctrl_valid;
logic tx_ctrl_ack;
tcp_pkg::rx_msg_t rx_msg;
logic rx_msg_valid;
logic rx_msg_ack;
logic w_no_data;
logic [15:0] w_saf_pkt_len;
logic [15:0] w_tx_ip_len;
logic [31:0] w_tx_seq_number;
logic [31:0] w_tx_ack_number;
logic [7:0] w_tx_flags;
logic [15:0] w_tx_window_size;
logic w_tx_hdr_valid;
logic w_tx_packet_done;
logic [31:0] w_rx_seq_number;
logic [31:0] w_rx_ack_number;
logic [7:0] w_rx_flags;
logic [15:0] w_rx_window_size;
logic w_rx_hdr_valid;
assign o_tcp_port = hwif_out.source_port.d.value;
tcp_stream_regs u_tcp_stream_regs (
.clk (clk),
.rst (rst),
.s_cpuif_req (s_cpuif_req),
.s_cpuif_req_is_wr (s_cpuif_req_is_wr),
.s_cpuif_addr (s_cpuif_addr),
.s_cpuif_wr_data (s_cpuif_wr_data),
.s_cpuif_wr_biten (s_cpuif_wr_biten),
.s_cpuif_req_stall_wr (s_cpuif_req_stall_wr),
.s_cpuif_req_stall_rd (s_cpuif_req_stall_rd),
.s_cpuif_rd_ack (s_cpuif_rd_ack),
.s_cpuif_rd_err (s_cpuif_rd_err),
.s_cpuif_rd_data (s_cpuif_rd_data),
.s_cpuif_wr_ack (s_cpuif_wr_ack),
.s_cpuif_wr_err (s_cpuif_wr_err),
.hwif_in (hwif_in),
.hwif_out (hwif_out)
);
m2s_dma #(
.AXIS_DATA_WIDTH(DATA_WIDTH)
) u_m2s_dma (
.i_clk (clk),
.i_rst (rst),
.s_cpuif_req (hwif_out.m2s_dma_regs.req),
.s_cpuif_req_is_wr (hwif_out.m2s_dma_regs.req_is_wr),
.s_cpuif_addr (hwif_out.m2s_dma_regs.addr),
.s_cpuif_wr_data (hwif_out.m2s_dma_regs.wr_data),
.s_cpuif_wr_biten (hwif_out.m2s_dma_regs.wr_biten),
.s_cpuif_req_stall_wr (),
.s_cpuif_req_stall_rd (),
.s_cpuif_rd_ack (hwif_in.m2s_dma_regs.rd_ack),
.s_cpuif_rd_err (),
.s_cpuif_rd_data (hwif_in.m2s_dma_regs.rd_data),
.s_cpuif_wr_ack (hwif_in.m2s_dma_regs.wr_ack),
.s_cpuif_wr_err (),
.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)
);
// tcp state manager
tcp_state_manager u_tcp_state_manager (
.i_clk (clk),
.i_rst (rst),
.i_enable (hwif_out.control.enable.value),
.i_open (hwif_out.control.open.value),
.o_open_clr (hwif_in.control.open.hwclr),
.i_close (hwif_out.control.close.value),
.o_close_clr (hwif_in.control.close.hwclr),
.o_tx_ctrl (tx_ctrl),
.o_tx_ctrl_valid (tx_ctrl_valid),
.i_tx_ctrl_ack (tx_ctrl_ack),
.i_rx_msg (rx_msg),
.i_rx_msg_valid (rx_msg_valid),
.o_rx_msg_ack (rx_msg_ack)
);
// tx buffer
axis_saf_fifo #(
.DATA_DEPTH_L2(12),
.CTRL_DEPTH_L2(7),
.DATA_MEM("distributed"),
.CTRL_MEM("distributed")
) m2s_saf_fifo (
.sclk (clk),
.srst (rst),
.s_axis (m2s_axis),
.mclk (clk),
.mrst (rst),
.m_axis (m2s_post_saf_axis),
.o_len (w_saf_pkt_len),
.o_rx_pkt (),
.o_tx_pkt (),
.o_drop ()
);
// tx control
tcp_tx_ctrl u_tcp_tx_ctrl (
.i_clk (clk),
.i_rst (rst),
.i_tx_ctrl (tx_ctrl),
.i_tx_ctrl_valid (tx_ctrl_valid),
.o_tx_ctrl_ack (tx_ctrl_ack),
.o_no_data (w_no_data),
.o_ip_len (w_tx_ip_len),
.o_seq_number (w_tx_seq_number),
// .o_ack_number (w_tx_ack_number),
.o_flags (w_tx_flags),
.o_window_size (w_tx_window_size),
.o_hdr_valid (w_tx_hdr_valid),
.s_axis_len (w_saf_pkt_len),
.s_axis (m2s_post_saf_axis),
.m_axis (m_tx_ctrl_axis_data),
.i_packet_done (w_tx_packet_done)
);
// packet generator
tcp_packet_generator u_tcp_packet_generator (
.i_clk (clk),
.i_rst (rst),
.s_axis_data (m_tx_ctrl_axis_data),
.i_no_data (w_no_data),
.i_ip_len (w_tx_ip_len),
.i_seq_number (w_tx_seq_number),
.i_ack_number (w_tx_ack_number),
.i_source_port (hwif_out.source_port.d.value),
.i_dest_port (hwif_out.dest_port.d.value),
.i_flags (w_tx_flags),
.i_window_size (w_tx_window_size),
.i_hdr_valid (w_tx_hdr_valid),
.i_src_ip (hwif_out.source_ip.d.value),
.i_dst_ip (hwif_out.dest_ip.d.value),
.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)
);
// parser
tcp_parser u_tcp_parser (
.i_clk (clk),
.i_rst (rst),
.s_ip (s_ip_rx),
.m_axis (s2m_pre_saf_axis),
.o_seq_number (w_rx_seq_number),
.o_ack_number (w_rx_ack_number),
.o_flags (w_rx_flags),
.o_window_size (w_rx_window_size),
.o_hdr_valid (w_rx_hdr_valid)
);
// rx control
tcp_rx_ctrl u_tcp_rx_ctrl (
.i_clk (clk),
.i_rst (rst),
.o_rx_msg (rx_msg),
.o_rx_msg_valid (rx_msg_valid),
.i_rx_msg_ack (rx_msg_ack),
.i_seq_number (w_rx_seq_number),
.i_ack_number (w_rx_ack_number),
.i_flags (w_rx_flags),
.i_window_size (w_rx_window_size),
.i_hdr_valid (w_rx_hdr_valid),
.o_ack_number (w_tx_ack_number)
);
// rx buffer
endmodule

View File

@@ -0,0 +1,139 @@
import tcp_pkg::*;
module tcp_tx_ctrl(
input i_clk,
input i_rst,
input tcp_pkg::tx_ctrl_t i_tx_ctrl,
input logic i_tx_ctrl_valid,
output logic o_tx_ctrl_ack,
output logic o_no_data,
output logic [15:0] o_ip_len,
output logic [31:0] o_seq_number,
output logic [31:0] o_ack_number,
output logic [7:0] o_flags,
output logic [15:0] o_window_size,
output logic o_hdr_valid,
axis_intf.SLAVE s_axis,
input logic [15:0] s_axis_len,
axis_intf.MASTER m_axis,
input wire i_packet_done
);
axis_pipeline_register_wrapper u_m2s_reg (
.clk(i_clk),
.rst(i_rst),
.s_axis(s_axis),
.m_axis(m_axis)
);
localparam FLAG_FIN = (1 << 0);
localparam FLAG_SYN = (1 << 1);
localparam FLAG_RST = (1 << 2);
localparam FLAG_PSH = (1 << 3);
localparam FLAG_ACK = (1 << 4);
localparam FLAG_URG = (1 << 5);
localparam FLAG_ECE = (1 << 6);
localparam FLAG_CWR = (1 << 7);
logic [31:0] seq_num, seq_num_next;
assign o_seq_number = seq_num;
enum logic [2:0] {IDLE, SEND_SYN, SEND_ACK, SEND_FIN, SEND_DATA} state, state_next;
always_ff @(posedge i_clk) begin
if (i_rst) begin
state <= IDLE;
seq_num <= '0;
end else begin
state <= state_next;
seq_num <= seq_num_next;
end
end
always_comb begin
state_next = state;
o_no_data = '0;
o_tx_ctrl_ack = '0;
o_ack_number = '0;
o_flags = '0;
o_window_size = 16'h100;
o_hdr_valid = '0;
seq_num_next = seq_num;
o_ip_len = 16'd40; // default length of IP packet
case (state)
IDLE: begin
if (i_tx_ctrl_valid) begin
o_tx_ctrl_ack = '1;
case (i_tx_ctrl)
TX_CTRL_SEND_SYN: state_next = SEND_SYN;
TX_CTRL_SEND_ACK: state_next = SEND_ACK;
TX_CTRL_SEND_FIN: state_next = SEND_FIN;
endcase
end
if (s_axis.tvalid) begin
state_next = SEND_DATA;
end
end
SEND_SYN: begin
o_flags = FLAG_SYN;
o_no_data = '1;
o_hdr_valid = '1;
if (i_packet_done) begin
state_next = IDLE;
seq_num_next = seq_num + 1;
end
end
SEND_ACK: begin
o_flags = FLAG_ACK;
o_no_data = '1;
o_hdr_valid = '1;
if (i_packet_done) begin
state_next = IDLE;
seq_num_next = seq_num;
end
end
SEND_DATA: begin
o_flags = FLAG_ACK | FLAG_PSH;
o_no_data = '0;
o_ip_len = 16'd40 + s_axis_len; // default length of IP packet
o_hdr_valid = '1;
if (i_packet_done) begin
state_next = IDLE;
seq_num_next = seq_num + s_axis_len;
end
end
SEND_FIN: begin
o_flags = FLAG_ACK | FLAG_FIN;
o_no_data = '1;
o_ip_len = 16'd40; // default length of IP packet
o_hdr_valid = '1;
if (i_packet_done) begin
state_next = IDLE;
seq_num_next = seq_num + 1;
end
end
endcase
end
endmodule

View File

@@ -0,0 +1,22 @@
sd_controller_wrapper.sv
shadow_regs.sv
sdspi/rtl/sdckgen.v
sdspi/rtl/sddma_rxgears.v
sdspi/rtl/sddma.v
sdspi/rtl/sdrxframe.v
sdspi/rtl/sdtxframe.v
sdspi/rtl/sddma_s2mm.v
sdspi/rtl/sddma_s2mm_axi.v
# sdspi/rtl/afifo.v
sdspi/rtl/sddma_txgears.v
sdspi/rtl/sdskid.v
sdspi/rtl/sdfrontend.v
sdspi/rtl/spicmd.v
sdspi/rtl/sdaxil.v
sdspi/rtl/sddma_mm2s.v
sdspi/rtl/sddma_mm2s_axi.v
sdspi/rtl/sdio_top.v
sdspi/rtl/sdwb.v
sdspi/rtl/sdio.v
sdspi/rtl/sdcmd.v
sdspi/rtl/sdfifo.v

View File

@@ -1,118 +1,298 @@
<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="Wed Jul 31 2024 10:01:03 PM" location="/home/byron/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:family name="Trion" />
<efx:device name="T20F256" />
<efx:timing_model name="I4" />
<efx:family name="Trion"/>
<efx:device name="T20F256"/>
<efx:timing_model name="I4"/>
</efx:device_info>
<efx:design_info def_veri_version="sv_09" def_vhdl_version="vhdl_2008">
<efx:top_module name="super6502_fpga" />
<efx:design_file name="src/rtl/super_6502_fpga.sv" version="default" library="default" />
<efx:design_file name="src/sub/cpu_wrapper/cpu_wrapper.sv" version="default" library="default" />
<efx:design_file name="src/sub/rtl-common/src/rtl/axi4_lite_rom.sv" version="default" library="default" />
<efx:design_file name="src/sub/rtl-common/src/rtl/axi4_lite_ram.sv" version="default" library="default" />
<efx:design_file name="src/sub/rtl-common/src/rtl/ff_cdc.sv" version="default" library="default" />
<efx:design_file name="src/sub/rtl-common/src/rtl/axi4_lite_to_apb4.sv" version="default" library="default" />
<efx:design_file name="src/sub/rtl-common/src/rtl/async_fifo.sv" version="default" library="default" />
<efx:design_file name="src/sub/wb2axip/rtl/axilxbar.v" version="default" library="default" />
<efx:design_file name="src/sub/wb2axip/rtl/addrdecode.v" version="default" library="default" />
<efx:design_file name="src/sub/wb2axip/rtl/skidbuffer.v" version="default" library="default" />
<efx:design_file name="src/sub/sd_controller_wrapper/sd_controller_wrapper.sv" version="default" library="default" />
<efx:design_file name="src/sub/sd_controller_wrapper/shadow_regs.sv" version="default" library="default" />
<efx:design_file name="src/sub/sd_controller_wrapper/sdspi/rtl/sdckgen.v" version="default" library="default" />
<efx:design_file name="src/sub/sd_controller_wrapper/sdspi/rtl/sddma_rxgears.v" version="default" library="default" />
<efx:design_file name="src/sub/sd_controller_wrapper/sdspi/rtl/sddma.v" version="default" library="default" />
<efx:design_file name="src/sub/sd_controller_wrapper/sdspi/rtl/sdrxframe.v" version="default" library="default" />
<efx:design_file name="src/sub/sd_controller_wrapper/sdspi/rtl/sdtxframe.v" version="default" library="default" />
<efx:design_file name="src/sub/sd_controller_wrapper/sdspi/rtl/sddma_s2mm.v" version="default" library="default" />
<efx:design_file name="src/sub/sd_controller_wrapper/sdspi/rtl/sddma_s2mm_axi.v" version="default" library="default" />
<efx:design_file name="src/sub/sd_controller_wrapper/sdspi/rtl/afifo.v" version="default" library="default" />
<efx:design_file name="src/sub/sd_controller_wrapper/sdspi/rtl/sddma_txgears.v" version="default" library="default" />
<efx:design_file name="src/sub/sd_controller_wrapper/sdspi/rtl/sdskid.v" version="default" library="default" />
<efx:design_file name="src/sub/sd_controller_wrapper/sdspi/rtl/sdfrontend.v" version="default" library="default" />
<efx:design_file name="src/sub/sd_controller_wrapper/sdspi/rtl/spicmd.v" version="default" library="default" />
<efx:design_file name="src/sub/sd_controller_wrapper/sdspi/rtl/sdaxil.v" version="default" library="default" />
<efx:design_file name="src/sub/sd_controller_wrapper/sdspi/rtl/sddma_mm2s.v" version="default" library="default" />
<efx:design_file name="src/sub/sd_controller_wrapper/sdspi/rtl/sddma_mm2s_axi.v" version="default" library="default" />
<efx:design_file name="src/sub/sd_controller_wrapper/sdspi/rtl/sdio_top.v" version="default" library="default" />
<efx:design_file name="src/sub/sd_controller_wrapper/sdspi/rtl/sdwb.v" version="default" library="default" />
<efx:design_file name="src/sub/sd_controller_wrapper/sdspi/rtl/sdio.v" version="default" library="default" />
<efx:design_file name="src/sub/sd_controller_wrapper/sdspi/rtl/sdcmd.v" version="default" library="default" />
<efx:design_file name="src/sub/sd_controller_wrapper/sdspi/rtl/sdfifo.v" version="default" library="default" />
<efx:top_vhdl_arch name="" />
<efx:top_module name="super6502_fpga"/>
<efx:design_file name="src/rtl/super_6502_fpga.sv" version="default" library="default"/>
<efx:design_file name="src/sub/cpu_wrapper/cpu_wrapper.sv" version="default" library="default"/>
<efx:design_file name="src/sub/rtl-common/src/rtl/axi4_lite_rom.sv" version="default" library="default"/>
<efx:design_file name="src/sub/rtl-common/src/rtl/axi4_lite_ram.sv" version="default" library="default"/>
<efx:design_file name="src/sub/rtl-common/src/rtl/ff_cdc.sv" version="default" library="default"/>
<efx:design_file name="src/sub/rtl-common/src/rtl/axi4_lite_to_apb4.sv" version="default" library="default"/>
<efx:design_file name="src/sub/rtl-common/src/rtl/async_fifo.sv" version="default" library="default"/>
<efx:design_file name="src/sub/wb2axip/rtl/axilxbar.v" version="default" library="default"/>
<efx:design_file name="src/sub/wb2axip/rtl/addrdecode.v" version="default" library="default"/>
<efx:design_file name="src/sub/wb2axip/rtl/skidbuffer.v" version="default" library="default"/>
<efx:design_file name="src/sub/sd_controller_wrapper/sd_controller_wrapper.sv" version="default" library="default"/>
<efx:design_file name="src/sub/sd_controller_wrapper/shadow_regs.sv" version="default" library="default"/>
<efx:design_file name="src/sub/sd_controller_wrapper/sdspi/rtl/sdckgen.v" version="default" library="default"/>
<efx:design_file name="src/sub/sd_controller_wrapper/sdspi/rtl/sddma_rxgears.v" version="default" library="default"/>
<efx:design_file name="src/sub/sd_controller_wrapper/sdspi/rtl/sddma.v" version="default" library="default"/>
<efx:design_file name="src/sub/sd_controller_wrapper/sdspi/rtl/sdrxframe.v" version="default" library="default"/>
<efx:design_file name="src/sub/sd_controller_wrapper/sdspi/rtl/sdtxframe.v" version="default" library="default"/>
<efx:design_file name="src/sub/sd_controller_wrapper/sdspi/rtl/sddma_s2mm.v" version="default" library="default"/>
<efx:design_file name="src/sub/sd_controller_wrapper/sdspi/rtl/sddma_s2mm_axi.v" version="default" library="default"/>
<efx:design_file name="src/sub/sd_controller_wrapper/sdspi/rtl/afifo.v" version="default" library="default"/>
<efx:design_file name="src/sub/sd_controller_wrapper/sdspi/rtl/sddma_txgears.v" version="default" library="default"/>
<efx:design_file name="src/sub/sd_controller_wrapper/sdspi/rtl/sdskid.v" version="default" library="default"/>
<efx:design_file name="src/sub/sd_controller_wrapper/sdspi/rtl/sdfrontend.v" version="default" library="default"/>
<efx:design_file name="src/sub/sd_controller_wrapper/sdspi/rtl/spicmd.v" version="default" library="default"/>
<efx:design_file name="src/sub/sd_controller_wrapper/sdspi/rtl/sdaxil.v" version="default" library="default"/>
<efx:design_file name="src/sub/sd_controller_wrapper/sdspi/rtl/sddma_mm2s.v" version="default" library="default"/>
<efx:design_file name="src/sub/sd_controller_wrapper/sdspi/rtl/sddma_mm2s_axi.v" version="default" library="default"/>
<efx:design_file name="src/sub/sd_controller_wrapper/sdspi/rtl/sdio_top.v" version="default" library="default"/>
<efx:design_file name="src/sub/sd_controller_wrapper/sdspi/rtl/sdwb.v" version="default" library="default"/>
<efx:design_file name="src/sub/sd_controller_wrapper/sdspi/rtl/sdio.v" version="default" library="default"/>
<efx:design_file name="src/sub/sd_controller_wrapper/sdspi/rtl/sdcmd.v" version="default" library="default"/>
<efx:design_file name="src/sub/sd_controller_wrapper/sdspi/rtl/sdfifo.v" version="default" library="default"/>
<efx:design_file name="src/sub/network_processor/src/tcp_stream.sv" version="default" library="default"/>
<efx:design_file name="src/sub/network_processor/src/tcp_state_manager.sv" version="default" library="default"/>
<efx:design_file name="src/sub/network_processor/src/network_processor.sv" version="default" library="default"/>
<efx:design_file name="src/sub/network_processor/src/regs/tcp_stream_regs_pkg.sv" version="default" library="default"/>
<efx:design_file name="src/sub/network_processor/src/regs/tcp_top_regfile.sv" version="default" library="default"/>
<efx:design_file name="src/sub/network_processor/src/regs/tcp_stream_regs.sv" version="default" library="default"/>
<efx:design_file name="src/sub/network_processor/src/regs/tcp_top_regfile_pkg.sv" version="default" library="default"/>
<efx:design_file name="src/sub/network_processor/src/eth_wrapper.sv" version="default" library="default"/>
<efx:design_file name="src/sub/network_processor/src/tcp.sv" version="default" library="default"/>
<efx:design_file name="src/sub/network_processor/src/regs/mac_regs_pkg.sv" version="default" library="default"/>
<efx:design_file name="src/sub/network_processor/src/regs/ntw_top_regfile.sv" version="default" library="default"/>
<efx:design_file name="src/sub/network_processor/src/regs/mac_regs.sv" version="default" library="default"/>
<efx:design_file name="src/sub/network_processor/src/regs/ntw_top_regfile_pkg.sv" version="default" library="default"/>
<efx:design_file name="src/sub/verilog-ethernet/rtl/rgmii_phy_if.v" version="default" library="default"/>
<efx:design_file name="src/sub/verilog-ethernet/rtl/udp_ip_rx.v" version="default" library="default"/>
<efx:design_file name="src/sub/verilog-ethernet/rtl/eth_mux.v" version="default" library="default"/>
<efx:design_file name="src/sub/verilog-ethernet/rtl/ip_64.v" version="default" library="default"/>
<efx:design_file name="src/sub/verilog-ethernet/rtl/eth_duplicator.v" version="default" library="default"/>
<efx:design_file name="src/sub/verilog-ethernet/rtl/ptp_clock_cdc.v" version="default" library="default"/>
<efx:design_file name="src/sub/verilog-ethernet/rtl/eth_phy_10g.v" version="default" library="default"/>
<efx:design_file name="src/sub/verilog-ethernet/rtl/mac_ctrl_tx.v" version="default" library="default"/>
<efx:design_file name="src/sub/verilog-ethernet/rtl/eth_phy_10g_rx.v" version="default" library="default"/>
<efx:design_file name="src/sub/verilog-ethernet/rtl/udp_arb_mux.v" version="default" library="default"/>
<efx:design_file name="src/sub/verilog-ethernet/rtl/ptp_tag_insert.v" version="default" library="default"/>
<efx:design_file name="src/sub/verilog-ethernet/rtl/eth_mac_1g_rgmii.v" version="default" library="default"/>
<efx:design_file name="src/sub/verilog-ethernet/rtl/axis_gmii_tx.v" version="default" library="default"/>
<efx:design_file name="src/sub/verilog-ethernet/rtl/eth_axis_rx.v" version="default" library="default"/>
<efx:design_file name="src/sub/verilog-ethernet/rtl/eth_mac_10g_fifo.v" version="default" library="default"/>
<efx:design_file name="src/sub/verilog-ethernet/rtl/udp_checksum_gen.v" version="default" library="default"/>
<efx:design_file name="src/sub/verilog-ethernet/rtl/ssio_sdr_out.v" version="default" library="default"/>
<efx:design_file name="src/sub/verilog-ethernet/rtl/ip_complete.v" version="default" library="default"/>
<efx:design_file name="src/sub/verilog-ethernet/rtl/axis_baser_rx_64.v" version="default" library="default"/>
<efx:design_file name="src/sub/verilog-ethernet/rtl/ptp_td_phc.v" version="default" library="default"/>
<efx:design_file name="src/sub/verilog-ethernet/rtl/eth_phy_10g_rx_if.v" version="default" library="default"/>
<efx:design_file name="src/sub/verilog-ethernet/rtl/axis_baser_tx_64.v" version="default" library="default"/>
<efx:design_file name="src/sub/verilog-ethernet/rtl/udp_demux.v" version="default" library="default"/>
<efx:design_file name="src/sub/verilog-ethernet/rtl/eth_arb_mux.v" version="default" library="default"/>
<efx:design_file name="src/sub/verilog-ethernet/rtl/filter.v" version="default" library="default"/>
<efx:design_file name="src/sub/verilog-ethernet/rtl/eth_mac_1g.v" version="default" library="default"/>
<efx:design_file name="src/sub/verilog-ethernet/rtl/ip_eth_tx_64.v" version="default" library="default"/>
<efx:design_file name="src/sub/verilog-ethernet/rtl/icmp_ip_rx.v" version="default" library="default"/>
<efx:design_file name="src/sub/verilog-ethernet/rtl/modifier.v" version="default" library="default"/>
<efx:design_file name="src/sub/verilog-ethernet/rtl/mac_pause_ctrl_tx.v" version="default" library="default"/>
<efx:design_file name="src/sub/verilog-ethernet/rtl/lfsr.v" version="default" library="default"/>
<efx:design_file name="src/sub/verilog-ethernet/rtl/arp_eth_tx.v" version="default" library="default"/>
<efx:design_file name="src/sub/verilog-ethernet/rtl/eth_mac_1g_rgmii_fifo.v" version="default" library="default"/>
<efx:design_file name="src/sub/verilog-ethernet/rtl/eth_mac_1g_fifo.v" version="default" library="default"/>
<efx:design_file name="src/sub/verilog-ethernet/rtl/axis_xgmii_tx_64.v" version="default" library="default"/>
<efx:design_file name="src/sub/verilog-ethernet/rtl/udp.v" version="default" library="default"/>
<efx:design_file name="src/sub/verilog-ethernet/rtl/eth_mac_1g_gmii.v" version="default" library="default"/>
<efx:design_file name="src/sub/verilog-ethernet/rtl/ip_demux.v" version="default" library="default"/>
<efx:design_file name="src/sub/verilog-ethernet/rtl/eth_mac_phy_10g.v" version="default" library="default"/>
<efx:design_file name="src/sub/verilog-ethernet/rtl/udp_checksum_gen_64.v" version="default" library="default"/>
<efx:design_file name="src/sub/verilog-ethernet/rtl/mac_ctrl_rx.v" version="default" library="default"/>
<efx:design_file name="src/sub/verilog-ethernet/rtl/eth_mac_mii_fifo.v" version="default" library="default"/>
<efx:design_file name="src/sub/verilog-ethernet/rtl/icmp_ip_rx_64.v" version="default" library="default"/>
<efx:design_file name="src/sub/verilog-ethernet/rtl/ssio_sdr_in_diff.v" version="default" library="default"/>
<efx:design_file name="src/sub/verilog-ethernet/rtl/axis_eth_fcs_check.v" version="default" library="default"/>
<efx:design_file name="src/sub/verilog-ethernet/rtl/axis_xgmii_rx_32.v" version="default" library="default"/>
<efx:design_file name="src/sub/verilog-ethernet/rtl/eth_mac_10g.v" version="default" library="default"/>
<efx:design_file name="src/sub/verilog-ethernet/rtl/xgmii_baser_enc_64.v" version="default" library="default"/>
<efx:design_file name="src/sub/verilog-ethernet/rtl/ip_complete_64.v" version="default" library="default"/>
<efx:design_file name="src/sub/verilog-ethernet/rtl/udp_complete_64.v" version="default" library="default"/>
<efx:design_file name="src/sub/verilog-ethernet/rtl/eth_phy_10g_tx.v" version="default" library="default"/>
<efx:design_file name="src/sub/verilog-ethernet/rtl/arp_eth_rx.v" version="default" library="default"/>
<efx:design_file name="src/sub/verilog-ethernet/rtl/eth_mac_phy_10g_rx.v" version="default" library="default"/>
<efx:design_file name="src/sub/verilog-ethernet/rtl/icmp_ip_tx_64.v" version="default" library="default"/>
<efx:design_file name="src/sub/verilog-ethernet/rtl/axis_eth_fcs.v" version="default" library="default"/>
<efx:design_file name="src/sub/verilog-ethernet/rtl/ptp_clock.v" version="default" library="default"/>
<efx:design_file name="src/sub/verilog-ethernet/rtl/ip_arb_mux.v" version="default" library="default"/>
<efx:design_file name="src/sub/verilog-ethernet/rtl/axis_eth_fcs_insert_64.v" version="default" library="default"/>
<efx:design_file name="src/sub/verilog-ethernet/rtl/ptp_td_leaf.v" version="default" library="default"/>
<efx:design_file name="src/sub/verilog-ethernet/rtl/ssio_ddr_in_diff.v" version="default" library="default"/>
<efx:design_file name="src/sub/verilog-ethernet/rtl/eth_phy_10g_rx_ber_mon.v" version="default" library="default"/>
<efx:design_file name="src/sub/verilog-ethernet/rtl/eth_mac_phy_10g_tx.v" version="default" library="default"/>
<efx:design_file name="src/sub/verilog-ethernet/rtl/eth_mac_phy_10g_fifo.v" version="default" library="default"/>
<efx:design_file name="src/sub/verilog-ethernet/rtl/udp_64.v" version="default" library="default"/>
<efx:design_file name="src/sub/verilog-ethernet/rtl/axis_eth_fcs_check_64.v" version="default" library="default"/>
<efx:design_file name="src/sub/verilog-ethernet/rtl/mii_phy_if.v" version="default" library="default"/>
<efx:design_file name="src/sub/verilog-ethernet/rtl/ip_mux.v" version="default" library="default"/>
<efx:design_file name="src/sub/verilog-ethernet/rtl/ptp_td_rel2tod.v" version="default" library="default"/>
<efx:design_file name="src/sub/verilog-ethernet/rtl/xgmii_interleave.v" version="default" library="default"/>
<efx:design_file name="src/sub/verilog-ethernet/rtl/axis_gmii_rx.v" version="default" library="default"/>
<efx:design_file name="src/sub/verilog-ethernet/rtl/mac_pause_ctrl_rx.v" version="default" library="default"/>
<efx:design_file name="src/sub/verilog-ethernet/rtl/ptp_perout.v" version="default" library="default"/>
<efx:design_file name="src/sub/verilog-ethernet/rtl/udp_ip_rx_64.v" version="default" library="default"/>
<efx:design_file name="src/sub/verilog-ethernet/rtl/axis_eth_fcs_insert.v" version="default" library="default"/>
<efx:design_file name="src/sub/verilog-ethernet/rtl/oddr.v" version="default" library="default"/>
<efx:design_file name="src/sub/verilog-ethernet/rtl/ssio_sdr_in.v" version="default" library="default"/>
<efx:design_file name="src/sub/verilog-ethernet/rtl/ssio_ddr_out_diff.v" version="default" library="default"/>
<efx:design_file name="src/sub/verilog-ethernet/rtl/arp.v" version="default" library="default"/>
<efx:design_file name="src/sub/verilog-ethernet/rtl/udp_complete.v" version="default" library="default"/>
<efx:design_file name="src/sub/verilog-ethernet/rtl/axis_xgmii_rx_64.v" version="default" library="default"/>
<efx:design_file name="src/sub/verilog-ethernet/rtl/ip_eth_tx.v" version="default" library="default"/>
<efx:design_file name="src/sub/verilog-ethernet/rtl/ssio_sdr_out_diff.v" version="default" library="default"/>
<efx:design_file name="src/sub/verilog-ethernet/rtl/ip_eth_rx_64.v" version="default" library="default"/>
<efx:design_file name="src/sub/verilog-ethernet/rtl/eth_axis_tx.v" version="default" library="default"/>
<efx:design_file name="src/sub/verilog-ethernet/rtl/ip_eth_rx.v" version="default" library="default"/>
<efx:design_file name="src/sub/verilog-ethernet/rtl/eth_phy_10g_rx_watchdog.v" version="default" library="default"/>
<efx:design_file name="src/sub/verilog-ethernet/rtl/eth_mac_mii.v" version="default" library="default"/>
<efx:design_file name="src/sub/verilog-ethernet/rtl/xgmii_deinterleave.v" version="default" library="default"/>
<efx:design_file name="src/sub/verilog-ethernet/rtl/udp_ip_tx.v" version="default" library="default"/>
<efx:design_file name="src/sub/verilog-ethernet/rtl/xgmii_baser_dec_64.v" version="default" library="default"/>
<efx:design_file name="src/sub/verilog-ethernet/rtl/ptp_ts_extract.v" version="default" library="default"/>
<efx:design_file name="src/sub/verilog-ethernet/rtl/udp_ip_tx_64.v" version="default" library="default"/>
<efx:design_file name="src/sub/verilog-ethernet/rtl/axis_xgmii_tx_32.v" version="default" library="default"/>
<efx:design_file name="src/sub/verilog-ethernet/rtl/ip.v" version="default" library="default"/>
<efx:design_file name="src/sub/verilog-ethernet/rtl/gmii_phy_if.v" version="default" library="default"/>
<efx:design_file name="src/sub/verilog-ethernet/rtl/icmp_ip_tx.v" version="default" library="default"/>
<efx:design_file name="src/sub/verilog-ethernet/rtl/iddr.v" version="default" library="default"/>
<efx:design_file name="src/sub/verilog-ethernet/rtl/eth_mac_1g_gmii_fifo.v" version="default" library="default"/>
<efx:design_file name="src/sub/verilog-ethernet/rtl/eth_demux.v" version="default" library="default"/>
<efx:design_file name="src/sub/verilog-ethernet/rtl/ssio_ddr_in.v" version="default" library="default"/>
<efx:design_file name="src/sub/verilog-ethernet/rtl/ssio_ddr_out.v" version="default" library="default"/>
<efx:design_file name="src/sub/verilog-ethernet/rtl/eth_phy_10g_rx_frame_sync.v" version="default" library="default"/>
<efx:design_file name="src/sub/verilog-ethernet/rtl/arp_cache.v" version="default" library="default"/>
<efx:design_file name="src/sub/verilog-ethernet/rtl/eth_phy_10g_tx_if.v" version="default" library="default"/>
<efx:design_file name="src/sub/verilog-ethernet/rtl/udp_mux.v" version="default" library="default"/>
<efx:design_file name="src/sub/verilog-ethernet/lib/axis/rtl/axis_rate_limit.v" version="default" library="default"/>
<efx:design_file name="src/sub/verilog-ethernet/lib/axis/rtl/axis_crosspoint.v" version="default" library="default"/>
<efx:design_file name="src/sub/verilog-ethernet/lib/axis/rtl/axis_frame_length_adjust_fifo.v" version="default" library="default"/>
<efx:design_file name="src/sub/verilog-ethernet/lib/axis/rtl/axis_frame_join.v" version="default" library="default"/>
<efx:design_file name="src/sub/verilog-ethernet/lib/axis/rtl/axis_srl_fifo.v" version="default" library="default"/>
<efx:design_file name="src/sub/verilog-ethernet/lib/axis/rtl/axis_fifo.v" version="default" library="default"/>
<efx:design_file name="src/sub/verilog-ethernet/lib/axis/rtl/axis_ll_bridge.v" version="default" library="default"/>
<efx:design_file name="src/sub/verilog-ethernet/lib/axis/rtl/axis_pipeline_fifo.v" version="default" library="default"/>
<efx:design_file name="src/sub/verilog-ethernet/lib/axis/rtl/axis_switch.v" version="default" library="default"/>
<efx:design_file name="src/sub/verilog-ethernet/lib/axis/rtl/axis_demux.v" version="default" library="default"/>
<efx:design_file name="src/sub/verilog-ethernet/lib/axis/rtl/axis_async_fifo_adapter.v" version="default" library="default"/>
<efx:design_file name="src/sub/verilog-ethernet/lib/axis/rtl/axis_tap.v" version="default" library="default"/>
<efx:design_file name="src/sub/verilog-ethernet/lib/axis/rtl/axis_fifo_adapter.v" version="default" library="default"/>
<efx:design_file name="src/sub/verilog-ethernet/lib/axis/rtl/axis_arb_mux.v" version="default" library="default"/>
<efx:design_file name="src/sub/verilog-ethernet/lib/axis/rtl/ll_axis_bridge.v" version="default" library="default"/>
<efx:design_file name="src/sub/verilog-ethernet/lib/axis/rtl/axis_stat_counter.v" version="default" library="default"/>
<efx:design_file name="src/sub/verilog-ethernet/lib/axis/rtl/axis_ram_switch.v" version="default" library="default"/>
<efx:design_file name="src/sub/verilog-ethernet/lib/axis/rtl/axis_srl_register.v" version="default" library="default"/>
<efx:design_file name="src/sub/verilog-ethernet/lib/axis/rtl/axis_adapter.v" version="default" library="default"/>
<efx:design_file name="src/sub/verilog-ethernet/lib/axis/rtl/arbiter.v" version="default" library="default"/>
<efx:design_file name="src/sub/verilog-ethernet/lib/axis/rtl/axis_broadcast.v" version="default" library="default"/>
<efx:design_file name="src/sub/verilog-ethernet/lib/axis/rtl/axis_async_fifo.v" version="default" library="default"/>
<efx:design_file name="src/sub/verilog-ethernet/lib/axis/rtl/axis_register.v" version="default" library="default"/>
<efx:design_file name="src/sub/verilog-ethernet/lib/axis/rtl/axis_cobs_decode.v" version="default" library="default"/>
<efx:design_file name="src/sub/verilog-ethernet/lib/axis/rtl/axis_pipeline_register.v" version="default" library="default"/>
<efx:design_file name="src/sub/verilog-ethernet/lib/axis/rtl/axis_mux.v" version="default" library="default"/>
<efx:design_file name="src/sub/verilog-ethernet/lib/axis/rtl/axis_cobs_encode.v" version="default" library="default"/>
<efx:design_file name="src/sub/verilog-ethernet/lib/axis/rtl/axis_frame_length_adjust.v" version="default" library="default"/>
<efx:design_file name="src/sub/verilog-ethernet/lib/axis/rtl/axis_frame_len.v" version="default" library="default"/>
<efx:design_file name="src/sub/verilog-ethernet/lib/axis/rtl/sync_reset.v" version="default" library="default"/>
<efx:design_file name="src/sub/verilog-ethernet/lib/axis/rtl/priority_encoder.v" version="default" library="default"/>
<efx:design_file name="src/sub/stream_dmas/src/m2s_dma.sv" version="default" library="default"/>
<efx:design_file name="src/sub/stream_dmas/src/regs/m2s_dma_regs.sv" version="default" library="default"/>
<efx:design_file name="src/sub/stream_dmas/src/regs/m2s_dma_regs_pkg.sv" version="default" library="default"/>
<efx:design_file name="src/sub/network_processor/src/tcp_pkg.sv" version="default" library="default"/>
<efx:design_file name="src/sub/network_processor/src/tcp_parser.sv" version="default" library="default"/>
<efx:design_file name="src/sub/network_processor/src/ip_demux_wrapper.sv" version="default" library="default"/>
<efx:design_file name="src/sub/network_processor/src/tcp_rx_ctrl.sv" version="default" library="default"/>
<efx:design_file name="src/sub/network_processor/src/ip_arb_mux_wrapper.sv" version="default" library="default"/>
<efx:design_file name="src/sub/network_processor/src/s2m_dma.sv" version="default" library="default"/>
<efx:design_file name="src/sub/network_processor/src/tcp_dest_decap.sv" version="default" library="default"/>
<efx:design_file name="src/sub/network_processor/src/tcp_packet_generator.sv" version="default" library="default"/>
<efx:design_file name="src/sub/network_processor/src/tcp_tx_ctrl.sv" version="default" library="default"/>
<efx:design_file name="src/sub/network_processor/src/checksum_calc.sv" version="default" library="default"/>
<efx:design_file name="src/sub/interfaces/axil_intf.sv" version="default" library="default"/>
<efx:design_file name="src/sub/interfaces/axis_intf.sv" version="default" library="default"/>
<efx:design_file name="src/sub/interfaces/ip_intf.sv" version="default" library="default"/>
<efx:design_file name="src/sub/interfaces/eth_intf.sv" version="default" library="default"/>
<efx:design_file name="src/sub/my-fifos/src/axis_saf.sv" version="default" library="default"/>
<efx:design_file name="src/sub/my-fifos/src/dpram.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/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:design_info>
<efx:constraint_info>
<efx:sdc_file name="constraints/constraints.sdc" />
<efx:inter_file name="" />
<efx:sdc_file name="constraints/constraints.sdc"/>
<efx:inter_file name=""/>
</efx:constraint_info>
<efx:sim_info />
<efx:misc_info />
<efx:sim_info/>
<efx:misc_info/>
<efx:ip_info>
<efx:ip instance_name="sdram_controller" path="ip/sdram_controller/settings.json">
<efx:ip_src_file name="sdram_controller.v" />
<efx:ip_src_file name="sdram_controller.v"/>
</efx:ip>
</efx:ip_info>
<efx:synthesis tool_name="efx_map">
<efx:param name="work_dir" value="work_syn" value_type="e_string" />
<efx:param name="write_efx_verilog" value="on" value_type="e_bool" />
<efx:param name="allow-const-ram-index" value="0" value_type="e_option" />
<efx:param name="blackbox-error" value="1" value_type="e_option" />
<efx:param name="blast_const_operand_adders" value="1" value_type="e_option" />
<efx:param name="bram_output_regs_packing" value="1" value_type="e_option" />
<efx:param name="create-onehot-fsms" value="0" value_type="e_option" />
<efx:param name="fanout-limit" value="0" value_type="e_integer" />
<efx:param name="hdl-compile-unit" value="1" value_type="e_option" />
<efx:param name="infer-clk-enable" value="3" value_type="e_option" />
<efx:param name="infer-sync-set-reset" value="1" value_type="e_option" />
<efx:param name="max_ram" value="-1" value_type="e_integer" />
<efx:param name="max_mult" value="-1" value_type="e_integer" />
<efx:param name="min-sr-fanout" value="0" value_type="e_integer" />
<efx:param name="min-ce-fanout" value="0" value_type="e_integer" />
<efx:param name="mult-decomp-retime" value="0" value_type="e_option" />
<efx:param name="mode" value="speed" value_type="e_option" />
<efx:param name="operator-sharing" value="0" value_type="e_option" />
<efx:param name="optimize-adder-tree" value="0" value_type="e_option" />
<efx:param name="optimize-zero-init-rom" value="1" value_type="e_option" />
<efx:param name="retiming" value="1" value_type="e_option" />
<efx:param name="seq_opt" value="1" value_type="e_option" />
<efx:param name="seq-opt-sync-only" value="0" 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="include" value="ip/sdram_controller" value_type="e_string" />
<efx:defmacro name="SDIO_AXI" value="1" />
<efx:defmacro name="EFINIX" value="1" />
<efx:param name="work_dir" value="work_syn" value_type="e_string"/>
<efx:param name="write_efx_verilog" value="on" value_type="e_bool"/>
<efx:param name="allow-const-ram-index" value="0" value_type="e_option"/>
<efx:param name="blackbox-error" value="1" value_type="e_option"/>
<efx:param name="blast_const_operand_adders" value="1" value_type="e_option"/>
<efx:param name="bram_output_regs_packing" value="1" value_type="e_option"/>
<efx:param name="create-onehot-fsms" value="0" value_type="e_option"/>
<efx:param name="fanout-limit" value="0" value_type="e_integer"/>
<efx:param name="hdl-compile-unit" value="1" value_type="e_option"/>
<efx:param name="infer-clk-enable" value="3" value_type="e_option"/>
<efx:param name="infer-sync-set-reset" value="1" value_type="e_option"/>
<efx:param name="max_ram" value="-1" value_type="e_integer"/>
<efx:param name="max_mult" value="-1" value_type="e_integer"/>
<efx:param name="min-sr-fanout" value="0" value_type="e_integer"/>
<efx:param name="min-ce-fanout" value="0" value_type="e_integer"/>
<efx:param name="mult-decomp-retime" value="0" value_type="e_option"/>
<efx:param name="mode" value="speed" value_type="e_option"/>
<efx:param name="operator-sharing" value="0" value_type="e_option"/>
<efx:param name="optimize-adder-tree" value="0" value_type="e_option"/>
<efx:param name="optimize-zero-init-rom" value="1" value_type="e_option"/>
<efx:param name="retiming" value="1" value_type="e_option"/>
<efx:param name="seq_opt" value="1" value_type="e_option"/>
<efx:param name="seq-opt-sync-only" value="0" 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="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="EFINIX" value="1"/>
</efx:synthesis>
<efx:place_and_route tool_name="efx_pnr">
<efx:param name="work_dir" value="work_pnr" value_type="e_string" />
<efx:param name="verbose" value="off" value_type="e_bool" />
<efx:param name="load_delaym" value="on" value_type="e_bool" />
<efx:param name="optimization_level" value="TIMING_3" value_type="e_option" />
<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="max_threads" value="-1" value_type="e_integer" />
<efx:param name="work_dir" value="work_pnr" value_type="e_string"/>
<efx:param name="verbose" value="off" value_type="e_bool"/>
<efx:param name="load_delaym" value="on" value_type="e_bool"/>
<efx:param name="optimization_level" value="TIMING_3" value_type="e_option"/>
<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="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:bitstream_generation tool_name="efx_pgm">
<efx:param name="mode" value="active" value_type="e_option" />
<efx:param name="width" value="1" value_type="e_option" />
<efx:param name="enable_roms" value="smart" value_type="e_option" />
<efx:param name="spi_low_power_mode" value="on" value_type="e_bool" />
<efx:param name="io_weak_pullup" value="on" value_type="e_bool" />
<efx:param name="oscillator_clock_divider" value="DIV8" value_type="e_option" />
<efx:param name="bitstream_compression" value="off" value_type="e_bool" />
<efx:param name="enable_external_master_clock" value="off" value_type="e_bool" />
<efx:param name="active_capture_clk_edge" value="posedge" value_type="e_option" />
<efx:param name="jtag_usercode" value="0xFFFFFFFF" value_type="e_string" />
<efx:param name="release_tri_then_reset" value="on" value_type="e_bool" />
<efx:param name="four_byte_addressing" value="off" value_type="e_bool" />
<efx:param name="generate_bit" value="on" value_type="e_bool" />
<efx:param name="generate_bitbin" value="off" value_type="e_bool" />
<efx:param name="generate_hex" value="on" value_type="e_bool" />
<efx:param name="generate_hexbin" value="off" value_type="e_bool" />
<efx:param name="cold_boot" value="off" value_type="e_bool" />
<efx:param name="cascade" value="off" value_type="e_option" />
<efx:param name="mode" value="active" value_type="e_option"/>
<efx:param name="width" value="1" value_type="e_option"/>
<efx:param name="enable_roms" value="smart" value_type="e_option"/>
<efx:param name="spi_low_power_mode" value="on" value_type="e_bool"/>
<efx:param name="io_weak_pullup" value="on" value_type="e_bool"/>
<efx:param name="oscillator_clock_divider" value="DIV8" value_type="e_option"/>
<efx:param name="bitstream_compression" value="off" value_type="e_bool"/>
<efx:param name="enable_external_master_clock" value="off" value_type="e_bool"/>
<efx:param name="active_capture_clk_edge" value="posedge" value_type="e_option"/>
<efx:param name="jtag_usercode" value="0xFFFFFFFF" value_type="e_string"/>
<efx:param name="release_tri_then_reset" value="on" value_type="e_bool"/>
<efx:param name="four_byte_addressing" value="off" value_type="e_bool"/>
<efx:param name="generate_bit" value="on" value_type="e_bool"/>
<efx:param name="generate_bitbin" value="off" value_type="e_bool"/>
<efx:param name="generate_hex" value="on" value_type="e_bool"/>
<efx:param name="generate_hexbin" value="off" value_type="e_bool"/>
<efx:param name="cold_boot" value="off" value_type="e_bool"/>
<efx:param name="cascade" value="off" value_type="e_option"/>
</efx:bitstream_generation>
<efx:debugger>
<efx:param name="work_dir" value="work_dbg" value_type="e_string" />
<efx:param name="auto_instantiation" value="off" value_type="e_bool" />
<efx:param name="profile" value="debug_profile.wizard.json" value_type="e_string" />
<efx:param name="work_dir" value="work_dbg" value_type="e_string"/>
<efx:param name="auto_instantiation" value="off" value_type="e_bool"/>
<efx:param name="profile" value="debug_profile.wizard.json" value_type="e_string"/>
</efx:debugger>
</efx:project>
</efx:project>

View File

@@ -8,12 +8,11 @@ export KICAD7_SYMBOL_DIR=$REPO_TOP/hw/kicad_library/symbols
export KICAD7_3DMODEL_DIR=$REPO_TOP/hw/kicad_library/3dmodels
export KICAD7_FOOTPRINT_DIR=$REPO_TOP/hw/kicad_library/footprints
python3.11 -m venv .user_venv
. .user_venv/bin/activate
module load efinity/2023.1
module load iverilog/12.0
#module load efinity/2023.1
module load verilator
module load gtkwave/3.3_gtk3
# pip install -r requirements.txt
python3.12 -m venv .user_venv
. .user_venv/bin/activate
pip install -r requirements.txt

7
requirements.txt Normal file
View File

@@ -0,0 +1,7 @@
-i https://git.byronlathi.com/api/v4/projects/95/packages/pypi/simple
peakrdl==1.1.0
rtl-manifest>=0.2.0
cocotb
cocotbext-axi
cocotbext-eth
scapy

View File

@@ -1,7 +1,7 @@
MEMORY
{
RAM: start = $0000, size = $200;
ROM: start = $FF00, size = $100, file = %O;
ROM: start = $F000, size = $1000, file = %O;
}
SEGMENTS {

View 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=ntw_test
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

View 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
}

View File

@@ -0,0 +1,20 @@
.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 #$aa
sta $e200
@end: bra @end