From 9b2a40df06a9099a31f61c3e2f0d35b747e1c69d Mon Sep 17 00:00:00 2001 From: Byron Lathi Date: Sat, 17 Aug 2024 11:56:01 -0700 Subject: [PATCH] Add tcp regs and switch to verilator --- Makefile | 2 +- hw/super6502_fpga/.gitignore | 1 + hw/super6502_fpga/sources.list | 38 +- hw/super6502_fpga/src/rtl/super_6502_fpga.sv | 84 +++- hw/super6502_fpga/src/sim/Makefile | 13 +- hw/super6502_fpga/src/sim/hvl/sim_top.sv | 4 +- hw/super6502_fpga/src/sim/sources.list | 2 +- .../src/sim/sub/sim_sdram/generic_sdr.v | 26 +- .../src/sim/sub/sim_sdram/generic_sdr_stub.v | 106 +++++ .../src/sub/cpu_wrapper/sources.list | 1 + .../src/sub/network_processor/sources.list | 7 + .../src/network_processor.sv | 98 +++++ .../src/regs/run_precompile.sh | 10 + .../network_processor/src/regs/tcp_stream.rdl | 10 +- .../src/regs/tcp_stream_regs.sv | 375 ++++++++++++++++++ .../src/regs/tcp_stream_regs_pkg.sv | 96 +++++ .../src/regs/tcp_top_regfile.sv | 349 ++++++++++++++++ .../src/regs/tcp_top_regfile_pkg.sv | 30 ++ .../src/regs/tcp_top_regs.rdl | 3 + .../sub/network_processor/src/tcp_stream.sv | 39 ++ hw/super6502_fpga/src/sub/rtl-common | 2 +- .../src/sub/sd_controller_wrapper/sdspi | 2 +- .../sub/sd_controller_wrapper/sources.list | 22 + hw/super6502_fpga/src/sub/wb2axip | 2 +- init_env.sh | 2 + requirements.txt | 3 + sw/test_code/loop_test/link.ld | 2 +- sw/test_code/ntw_test/Makefile | 39 ++ sw/test_code/ntw_test/link.ld | 30 ++ sw/test_code/ntw_test/main.s | 20 + 30 files changed, 1340 insertions(+), 78 deletions(-) create mode 100644 hw/super6502_fpga/src/sim/sub/sim_sdram/generic_sdr_stub.v create mode 100644 hw/super6502_fpga/src/sub/cpu_wrapper/sources.list create mode 100644 hw/super6502_fpga/src/sub/network_processor/sources.list create mode 100644 hw/super6502_fpga/src/sub/network_processor/src/regs/run_precompile.sh create mode 100644 hw/super6502_fpga/src/sub/network_processor/src/regs/tcp_stream_regs.sv create mode 100644 hw/super6502_fpga/src/sub/network_processor/src/regs/tcp_stream_regs_pkg.sv create mode 100644 hw/super6502_fpga/src/sub/network_processor/src/regs/tcp_top_regfile.sv create mode 100644 hw/super6502_fpga/src/sub/network_processor/src/regs/tcp_top_regfile_pkg.sv create mode 100644 hw/super6502_fpga/src/sub/network_processor/src/regs/tcp_top_regs.rdl create mode 100644 hw/super6502_fpga/src/sub/sd_controller_wrapper/sources.list create mode 100644 requirements.txt create mode 100644 sw/test_code/ntw_test/Makefile create mode 100644 sw/test_code/ntw_test/link.ld create mode 100644 sw/test_code/ntw_test/main.s diff --git a/Makefile b/Makefile index aab0a02..0e22bb5 100644 --- a/Makefile +++ b/Makefile @@ -1,4 +1,4 @@ -ROM_TARGET=test_code/sd_controller_test +ROM_TARGET=test_code/ntw_test INIT_HEX=hw/super6502_fpga/init_hex.mem HEX=sw/$(ROM_TARGET)/$(notdir $(ROM_TARGET)).bin diff --git a/hw/super6502_fpga/.gitignore b/hw/super6502_fpga/.gitignore index 0af698c..7ec4812 100644 --- a/hw/super6502_fpga/.gitignore +++ b/hw/super6502_fpga/.gitignore @@ -1,3 +1,4 @@ outflow work_* .lock +obj_dir \ No newline at end of file diff --git a/hw/super6502_fpga/sources.list b/hw/super6502_fpga/sources.list index 4e453fe..f44069d 100644 --- a/hw/super6502_fpga/sources.list +++ b/hw/super6502_fpga/sources.list @@ -1,35 +1,7 @@ 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 \ No newline at end of file +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 \ No newline at end of file diff --git a/hw/super6502_fpga/src/rtl/super_6502_fpga.sv b/hw/super6502_fpga/src/rtl/super_6502_fpga.sv index 2e877f0..2a9d3f4 100644 --- a/hw/super6502_fpga/src/rtl/super_6502_fpga.sv +++ b/hw/super6502_fpga/src/rtl/super_6502_fpga.sv @@ -193,6 +193,24 @@ logic sd_controller_dma_RREADY; logic [DATA_WIDTH-1:0] sd_controller_dma_RDATA; logic [1:0] sd_controller_dma_RRESP; +logic ntw_AWVALID; +logic ntw_AWREADY; +logic [ADDR_WIDTH-1:0] ntw_AWADDR; +logic ntw_WVALID; +logic ntw_WREADY; +logic [DATA_WIDTH-1:0] ntw_WDATA; +logic [DATA_WIDTH/8-1:0] ntw_WSTRB; +logic ntw_BVALID; +logic ntw_BREADY; +logic [1:0] ntw_BRESP; +logic ntw_ARVALID; +logic ntw_ARREADY; +logic [ADDR_WIDTH-1:0] ntw_ARADDR; +logic ntw_RVALID; +logic ntw_RREADY; +logic [DATA_WIDTH-1:0] ntw_RDATA; +logic [1:0] ntw_RRESP; + cpu_wrapper u_cpu_wrapper_0( .i_clk_cpu (clk_cpu), @@ -240,12 +258,13 @@ cpu_wrapper u_cpu_wrapper_0( axilxbar #( .NM(2), - .NS(4), + .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), @@ -268,23 +287,23 @@ axilxbar #( .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 }) + .M_AXI_ARADDR ({ram_araddr, rom_araddr, sdram_ARADDR, sd_controller_ctrl_ARADDR, ntw_ARADDR }), + .M_AXI_ARVALID ({ram_arvalid, rom_arvalid, sdram_ARVALID, sd_controller_ctrl_ARVALID, ntw_ARVALID }), + .M_AXI_ARREADY ({ram_arready, rom_arready, sdram_ARREADY, sd_controller_ctrl_ARREADY, ntw_ARREADY }), + .M_AXI_RDATA ({ram_rdata, rom_rdata, sdram_RDATA, sd_controller_ctrl_RDATA, ntw_RDATA }), + .M_AXI_RRESP ({ram_rresp, rom_rresp, sdram_RRESP, sd_controller_ctrl_RRESP, ntw_RRESP }), + .M_AXI_RVALID ({ram_rvalid, rom_rvalid, sdram_RVALID, sd_controller_ctrl_RVALID, ntw_RVALID }), + .M_AXI_RREADY ({ram_rready, rom_rready, sdram_RREADY, sd_controller_ctrl_RREADY, ntw_RREADY }), + .M_AXI_AWADDR ({ram_awaddr, rom_awaddr, sdram_AWADDR, sd_controller_ctrl_AWADDR, ntw_AWADDR }), + .M_AXI_AWVALID ({ram_awvalid, rom_awvalid, sdram_AWVALID, sd_controller_ctrl_AWVALID, ntw_AWVALID }), + .M_AXI_AWREADY ({ram_awready, rom_awready, sdram_AWREADY, sd_controller_ctrl_AWREADY, ntw_AWREADY }), + .M_AXI_WDATA ({ram_wdata, rom_wdata, sdram_WDATA, sd_controller_ctrl_WDATA, ntw_WDATA }), + .M_AXI_WVALID ({ram_wvalid, rom_wvalid, sdram_WVALID, sd_controller_ctrl_WVALID, ntw_WVALID }), + .M_AXI_WREADY ({ram_wready, rom_wready, sdram_WREADY, sd_controller_ctrl_WREADY, ntw_WREADY }), + .M_AXI_WSTRB ({ram_wstrb, rom_wstrb, sdram_WSTRB, sd_controller_ctrl_WSTRB, ntw_WSTRB }), + .M_AXI_BRESP ({ram_bresp, rom_bresp, sdram_BRESP, sd_controller_ctrl_BRESP, ntw_BRESP }), + .M_AXI_BVALID ({ram_bvalid, rom_bvalid, sdram_BVALID, sd_controller_ctrl_BVALID, ntw_BVALID }), + .M_AXI_BREADY ({ram_bready, rom_bready, sdram_BREADY, sd_controller_ctrl_BREADY, ntw_BREADY }) ); @@ -484,4 +503,31 @@ sd_controller_wrapper #( .o_int (sd_irq) ); +network_processor #( + .NUM_TCP(8) +) u_network_processor ( + .i_clk (i_sysclk), + .i_rst (~master_resetn), + + .s_axil_awready (ntw_AWREADY), + .s_axil_awvalid (ntw_AWVALID), + .s_axil_awaddr (ntw_AWADDR), + .s_axil_awprot (ntw_AWPROT), + .s_axil_wready (ntw_WREADY), + .s_axil_wvalid (ntw_WVALID), + .s_axil_wdata (ntw_WDATA), + .s_axil_wstrb (ntw_WSTRB), + .s_axil_bready (ntw_BREADY), + .s_axil_bvalid (ntw_BVALID), + .s_axil_bresp (ntw_BRESP), + .s_axil_arready (ntw_ARREADY), + .s_axil_arvalid (ntw_ARVALID), + .s_axil_araddr (ntw_ARADDR), + .s_axil_arprot (ntw_ARPROT), + .s_axil_rready (ntw_RREADY), + .s_axil_rvalid (ntw_RVALID), + .s_axil_rdata (ntw_RDATA), + .s_axil_rresp (ntw_RRESP) +); + endmodule \ No newline at end of file diff --git a/hw/super6502_fpga/src/sim/Makefile b/hw/super6502_fpga/src/sim/Makefile index e1930d4..b820e43 100644 --- a/hw/super6502_fpga/src/sim/Makefile +++ b/hw/super6502_fpga/src/sim/Makefile @@ -1,7 +1,7 @@ FPGA_SRCS_LIST=../../sources.list SIM_SRCS_LIST=sources.list -SUPER6502_FPGA_SOURCES=$(foreach file, $(shell cat $(FPGA_SRCS_LIST)), ../../$(file)) +SUPER6502_FPGA_SOURCES=$(shell rtl-manifest $(FPGA_SRCS_LIST)) SIM_SOURCES=$(shell cat $(SIM_SRCS_LIST)) INCLUDE=include/sdram_controller_define.vh @@ -13,13 +13,19 @@ 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) $(SUPER6502_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 +40,4 @@ clean: rm -rf $(COPY_FILES) rm -rf $(TB_NAME) rm -rf sim_top.vcd + rm -rf obj_dir diff --git a/hw/super6502_fpga/src/sim/hvl/sim_top.sv b/hw/super6502_fpga/src/sim/hvl/sim_top.sv index 35db4bb..81c01d8 100644 --- a/hw/super6502_fpga/src/sim/hvl/sim_top.sv +++ b/hw/super6502_fpga/src/sim/hvl/sim_top.sv @@ -179,13 +179,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 diff --git a/hw/super6502_fpga/src/sim/sources.list b/hw/super6502_fpga/src/sim/sources.list index 6ea3783..f3b1f2e 100644 --- a/hw/super6502_fpga/src/sim/sources.list +++ b/hw/super6502_fpga/src/sim/sources.list @@ -1,7 +1,7 @@ hvl/sim_top.sv sub/verilog-6502/ALU.v sub/verilog-6502/cpu_65c02.v -sub/sim_sdram/generic_sdr.v +sub/sim_sdram/generic_sdr_stub.v ../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 diff --git a/hw/super6502_fpga/src/sim/sub/sim_sdram/generic_sdr.v b/hw/super6502_fpga/src/sim/sub/sim_sdram/generic_sdr.v index aaa53f7..de74693 100644 --- a/hw/super6502_fpga/src/sim/sub/sim_sdram/generic_sdr.v +++ b/hw/super6502_fpga/src/sim/sub/sim_sdram/generic_sdr.v @@ -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 diff --git a/hw/super6502_fpga/src/sim/sub/sim_sdram/generic_sdr_stub.v b/hw/super6502_fpga/src/sim/sub/sim_sdram/generic_sdr_stub.v new file mode 100644 index 0000000..be40625 --- /dev/null +++ b/hw/super6502_fpga/src/sim/sub/sim_sdram/generic_sdr_stub.v @@ -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 � 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 diff --git a/hw/super6502_fpga/src/sub/cpu_wrapper/sources.list b/hw/super6502_fpga/src/sub/cpu_wrapper/sources.list new file mode 100644 index 0000000..2de578c --- /dev/null +++ b/hw/super6502_fpga/src/sub/cpu_wrapper/sources.list @@ -0,0 +1 @@ +cpu_wrapper.sv \ No newline at end of file diff --git a/hw/super6502_fpga/src/sub/network_processor/sources.list b/hw/super6502_fpga/src/sub/network_processor/sources.list new file mode 100644 index 0000000..9571989 --- /dev/null +++ b/hw/super6502_fpga/src/sub/network_processor/sources.list @@ -0,0 +1,7 @@ +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/network_processor.sv +src/tcp_state_manager.sv +src/tcp_stream.sv \ No newline at end of file diff --git a/hw/super6502_fpga/src/sub/network_processor/src/network_processor.sv b/hw/super6502_fpga/src/sub/network_processor/src/network_processor.sv index e69de29..cec4160 100644 --- a/hw/super6502_fpga/src/sub/network_processor/src/network_processor.sv +++ b/hw/super6502_fpga/src/sub/network_processor/src/network_processor.sv @@ -0,0 +1,98 @@ +module network_processor #( + parameter NUM_TCP=8 +)( + input i_clk, + input i_rst, + + // our crossbar is all axi, so having this be apb means + // we have to convert it anyway + output logic s_axil_awready, + input wire s_axil_awvalid, + input wire [8: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 [8: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 +); + +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_axil_awready (s_axil_awready), + .s_axil_awvalid (s_axil_awvalid), + .s_axil_awaddr (s_axil_awaddr), + .s_axil_awprot (s_axil_awprot), + .s_axil_wready (s_axil_wready), + .s_axil_wvalid (s_axil_wvalid), + .s_axil_wdata (s_axil_wdata), + .s_axil_wstrb (s_axil_wstrb), + .s_axil_bready (s_axil_bready), + .s_axil_bvalid (s_axil_bvalid), + .s_axil_bresp (s_axil_bresp), + .s_axil_arready (s_axil_arready), + .s_axil_arvalid (s_axil_arvalid), + .s_axil_araddr (s_axil_araddr), + .s_axil_arprot (s_axil_arprot), + .s_axil_rready (s_axil_rready), + .s_axil_rvalid (s_axil_rvalid), + .s_axil_rdata (s_axil_rdata), + .s_axil_rresp (s_axil_rresp), + + .hwif_in (tcp_hwif_in), + .hwif_out (tcp_hwif_out) +); + +generate + + for (genvar i = 0; i < NUM_TCP; i++) begin + 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 () + ); + end +endgenerate + +endmodule \ No newline at end of file diff --git a/hw/super6502_fpga/src/sub/network_processor/src/regs/run_precompile.sh b/hw/super6502_fpga/src/sub/network_processor/src/regs/run_precompile.sh new file mode 100644 index 0000000..7df9a6a --- /dev/null +++ b/hw/super6502_fpga/src/sub/network_processor/src/regs/run_precompile.sh @@ -0,0 +1,10 @@ +peakrdl regblock tcp_stream.rdl tcp_top_regs.rdl -o . --cpuif axi4-lite-flat +peakrdl regblock -t tcp_stream_regs tcp_stream.rdl -o . --cpuif passthrough + +# sed -i -e 's/struct/struct packed/g' tcp_stream_regs.sv +# sed -i -e 's/struct/struct packed/g' tcp_stream_regs_pkg.sv +# sed -i -e 's/automatic/static/g' tcp_stream_regs.sv + +# sed -i -e 's/struct/struct packed/g' tcp_top_regfile.sv +# sed -i -e 's/struct/struct packed/g' tcp_top_regfile_pkg.sv +# sed -i -e 's/automatic/static/g' tcp_top_regfile.sv diff --git a/hw/super6502_fpga/src/sub/network_processor/src/regs/tcp_stream.rdl b/hw/super6502_fpga/src/sub/network_processor/src/regs/tcp_stream.rdl index bcb51ce..99a9474 100644 --- a/hw/super6502_fpga/src/sub/network_processor/src/regs/tcp_stream.rdl +++ b/hw/super6502_fpga/src/sub/network_processor/src/regs/tcp_stream.rdl @@ -1,4 +1,4 @@ -addrmap tcp_stream { +regfile tcp_stream { name = "TCP Stream Regs"; desc = ""; @@ -75,7 +75,7 @@ addrmap tcp_stream { desc = "Closes the exisitng connection when written with 1"; hw = r; sw = rw; - hwclr + hwclr; } close[2:2] = 0x0; field { @@ -89,7 +89,7 @@ addrmap tcp_stream { // is addrmap right for this? How do we specify the address of it though? // Maybe we have to do this separately and include it? - addrmap stats { + regfile stats { name = "Statistics"; desc = ""; @@ -132,4 +132,8 @@ addrmap tcp_stream { } rx_bad_crc @ 0x8; }; +}; + +addrmap tcp_stream_regs { + tcp_stream tcp_streams; }; \ No newline at end of file diff --git a/hw/super6502_fpga/src/sub/network_processor/src/regs/tcp_stream_regs.sv b/hw/super6502_fpga/src/sub/network_processor/src/regs/tcp_stream_regs.sv new file mode 100644 index 0000000..48704c0 --- /dev/null +++ b/hw/super6502_fpga/src/sub/network_processor/src/regs/tcp_stream_regs.sv @@ -0,0 +1,375 @@ +// 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 [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, + + 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 [4: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 { + struct { + logic source_port; + logic source_ip; + logic dest_port; + logic dest_ip; + logic control; + } tcp_streams; + } 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.tcp_streams.source_port = cpuif_req_masked & (cpuif_addr == 5'h0); + decoded_reg_strb.tcp_streams.source_ip = cpuif_req_masked & (cpuif_addr == 5'h4); + decoded_reg_strb.tcp_streams.dest_port = cpuif_req_masked & (cpuif_addr == 5'h8); + decoded_reg_strb.tcp_streams.dest_ip = cpuif_req_masked & (cpuif_addr == 5'hc); + decoded_reg_strb.tcp_streams.control = cpuif_req_masked & (cpuif_addr == 5'h10); + 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 { + 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; + } tcp_streams; + } field_combo_t; + field_combo_t field_combo; + + typedef struct { + 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; + } tcp_streams; + } field_storage_t; + field_storage_t field_storage; + + // Field: tcp_stream_regs.tcp_streams.source_port.d + always_comb begin + automatic logic [31:0] next_c; + automatic logic load_next_c; + next_c = field_storage.tcp_streams.source_port.d.value; + load_next_c = '0; + if(decoded_reg_strb.tcp_streams.source_port && decoded_req_is_wr) begin // SW write + next_c = (field_storage.tcp_streams.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.tcp_streams.source_port.d.next = next_c; + field_combo.tcp_streams.source_port.d.load_next = load_next_c; + end + always_ff @(posedge clk) begin + if(rst) begin + field_storage.tcp_streams.source_port.d.value <= 32'h0; + end else if(field_combo.tcp_streams.source_port.d.load_next) begin + field_storage.tcp_streams.source_port.d.value <= field_combo.tcp_streams.source_port.d.next; + end + end + assign hwif_out.tcp_streams.source_port.d.value = field_storage.tcp_streams.source_port.d.value; + // Field: tcp_stream_regs.tcp_streams.source_ip.d + always_comb begin + automatic logic [31:0] next_c; + automatic logic load_next_c; + next_c = field_storage.tcp_streams.source_ip.d.value; + load_next_c = '0; + if(decoded_reg_strb.tcp_streams.source_ip && decoded_req_is_wr) begin // SW write + next_c = (field_storage.tcp_streams.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.tcp_streams.source_ip.d.next = next_c; + field_combo.tcp_streams.source_ip.d.load_next = load_next_c; + end + always_ff @(posedge clk) begin + if(rst) begin + field_storage.tcp_streams.source_ip.d.value <= 32'h0; + end else if(field_combo.tcp_streams.source_ip.d.load_next) begin + field_storage.tcp_streams.source_ip.d.value <= field_combo.tcp_streams.source_ip.d.next; + end + end + assign hwif_out.tcp_streams.source_ip.d.value = field_storage.tcp_streams.source_ip.d.value; + // Field: tcp_stream_regs.tcp_streams.dest_port.d + always_comb begin + automatic logic [31:0] next_c; + automatic logic load_next_c; + next_c = field_storage.tcp_streams.dest_port.d.value; + load_next_c = '0; + if(decoded_reg_strb.tcp_streams.dest_port && decoded_req_is_wr) begin // SW write + next_c = (field_storage.tcp_streams.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.tcp_streams.dest_port.d.next = next_c; + field_combo.tcp_streams.dest_port.d.load_next = load_next_c; + end + always_ff @(posedge clk) begin + if(rst) begin + field_storage.tcp_streams.dest_port.d.value <= 32'h0; + end else if(field_combo.tcp_streams.dest_port.d.load_next) begin + field_storage.tcp_streams.dest_port.d.value <= field_combo.tcp_streams.dest_port.d.next; + end + end + assign hwif_out.tcp_streams.dest_port.d.value = field_storage.tcp_streams.dest_port.d.value; + // Field: tcp_stream_regs.tcp_streams.dest_ip.d + always_comb begin + automatic logic [31:0] next_c; + automatic logic load_next_c; + next_c = field_storage.tcp_streams.dest_ip.d.value; + load_next_c = '0; + if(decoded_reg_strb.tcp_streams.dest_ip && decoded_req_is_wr) begin // SW write + next_c = (field_storage.tcp_streams.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.tcp_streams.dest_ip.d.next = next_c; + field_combo.tcp_streams.dest_ip.d.load_next = load_next_c; + end + always_ff @(posedge clk) begin + if(rst) begin + field_storage.tcp_streams.dest_ip.d.value <= 32'h0; + end else if(field_combo.tcp_streams.dest_ip.d.load_next) begin + field_storage.tcp_streams.dest_ip.d.value <= field_combo.tcp_streams.dest_ip.d.next; + end + end + assign hwif_out.tcp_streams.dest_ip.d.value = field_storage.tcp_streams.dest_ip.d.value; + // Field: tcp_stream_regs.tcp_streams.control.enable + always_comb begin + automatic logic [0:0] next_c; + automatic logic load_next_c; + next_c = field_storage.tcp_streams.control.enable.value; + load_next_c = '0; + if(decoded_reg_strb.tcp_streams.control && decoded_req_is_wr) begin // SW write + next_c = (field_storage.tcp_streams.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.tcp_streams.control.enable.next = next_c; + field_combo.tcp_streams.control.enable.load_next = load_next_c; + end + always_ff @(posedge clk) begin + if(rst) begin + field_storage.tcp_streams.control.enable.value <= 1'h0; + end else if(field_combo.tcp_streams.control.enable.load_next) begin + field_storage.tcp_streams.control.enable.value <= field_combo.tcp_streams.control.enable.next; + end + end + assign hwif_out.tcp_streams.control.enable.value = field_storage.tcp_streams.control.enable.value; + // Field: tcp_stream_regs.tcp_streams.control.open + always_comb begin + automatic logic [0:0] next_c; + automatic logic load_next_c; + next_c = field_storage.tcp_streams.control.open.value; + load_next_c = '0; + if(decoded_reg_strb.tcp_streams.control && decoded_req_is_wr) begin // SW write + next_c = (field_storage.tcp_streams.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.tcp_streams.control.open.hwclr) begin // HW Clear + next_c = '0; + load_next_c = '1; + end + field_combo.tcp_streams.control.open.next = next_c; + field_combo.tcp_streams.control.open.load_next = load_next_c; + end + always_ff @(posedge clk) begin + if(rst) begin + field_storage.tcp_streams.control.open.value <= 1'h0; + end else if(field_combo.tcp_streams.control.open.load_next) begin + field_storage.tcp_streams.control.open.value <= field_combo.tcp_streams.control.open.next; + end + end + assign hwif_out.tcp_streams.control.open.value = field_storage.tcp_streams.control.open.value; + // Field: tcp_stream_regs.tcp_streams.control.close + always_comb begin + automatic logic [0:0] next_c; + automatic logic load_next_c; + next_c = field_storage.tcp_streams.control.close.value; + load_next_c = '0; + if(decoded_reg_strb.tcp_streams.control && decoded_req_is_wr) begin // SW write + next_c = (field_storage.tcp_streams.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.tcp_streams.control.close.hwclr) begin // HW Clear + next_c = '0; + load_next_c = '1; + end + field_combo.tcp_streams.control.close.next = next_c; + field_combo.tcp_streams.control.close.load_next = load_next_c; + end + always_ff @(posedge clk) begin + if(rst) begin + field_storage.tcp_streams.control.close.value <= 1'h0; + end else if(field_combo.tcp_streams.control.close.load_next) begin + field_storage.tcp_streams.control.close.value <= field_combo.tcp_streams.control.close.next; + end + end + assign hwif_out.tcp_streams.control.close.value = field_storage.tcp_streams.control.close.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[5]; + assign readback_array[0][31:0] = (decoded_reg_strb.tcp_streams.source_port && !decoded_req_is_wr) ? field_storage.tcp_streams.source_port.d.value : '0; + assign readback_array[1][31:0] = (decoded_reg_strb.tcp_streams.source_ip && !decoded_req_is_wr) ? field_storage.tcp_streams.source_ip.d.value : '0; + assign readback_array[2][31:0] = (decoded_reg_strb.tcp_streams.dest_port && !decoded_req_is_wr) ? field_storage.tcp_streams.dest_port.d.value : '0; + assign readback_array[3][31:0] = (decoded_reg_strb.tcp_streams.dest_ip && !decoded_req_is_wr) ? field_storage.tcp_streams.dest_ip.d.value : '0; + assign readback_array[4][0:0] = (decoded_reg_strb.tcp_streams.control && !decoded_req_is_wr) ? field_storage.tcp_streams.control.enable.value : '0; + assign readback_array[4][1:1] = (decoded_reg_strb.tcp_streams.control && !decoded_req_is_wr) ? field_storage.tcp_streams.control.open.value : '0; + assign readback_array[4][2:2] = (decoded_reg_strb.tcp_streams.control && !decoded_req_is_wr) ? field_storage.tcp_streams.control.close.value : '0; + assign readback_array[4][5:3] = (decoded_reg_strb.tcp_streams.control && !decoded_req_is_wr) ? hwif_in.tcp_streams.control.state.next : '0; + assign readback_array[4][31:6] = '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<5; 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 diff --git a/hw/super6502_fpga/src/sub/network_processor/src/regs/tcp_stream_regs_pkg.sv b/hw/super6502_fpga/src/sub/network_processor/src/regs/tcp_stream_regs_pkg.sv new file mode 100644 index 0000000..13b6a1a --- /dev/null +++ b/hw/super6502_fpga/src/sub/network_processor/src/regs/tcp_stream_regs_pkg.sv @@ -0,0 +1,96 @@ +// 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 = 5; + + typedef struct { + logic hwclr; + } tcp_stream__control__open__in_t; + + typedef struct { + logic hwclr; + } tcp_stream__control__close__in_t; + + typedef struct { + logic [2:0] next; + } tcp_stream__control__state__in_t; + + typedef struct { + tcp_stream__control__open__in_t open; + tcp_stream__control__close__in_t close; + tcp_stream__control__state__in_t state; + } tcp_stream__control__in_t; + + typedef struct { + tcp_stream__control__in_t control; + } tcp_stream__in_t; + + typedef struct { + tcp_stream__in_t tcp_streams; + } tcp_stream_regs__in_t; + + typedef struct { + logic [31:0] value; + } tcp_stream__source_port__d__out_t; + + typedef struct { + tcp_stream__source_port__d__out_t d; + } tcp_stream__source_port__out_t; + + typedef struct { + logic [31:0] value; + } tcp_stream__source_ip__d__out_t; + + typedef struct { + tcp_stream__source_ip__d__out_t d; + } tcp_stream__source_ip__out_t; + + typedef struct { + logic [31:0] value; + } tcp_stream__dest_port__d__out_t; + + typedef struct { + tcp_stream__dest_port__d__out_t d; + } tcp_stream__dest_port__out_t; + + typedef struct { + logic [31:0] value; + } tcp_stream__dest_ip__d__out_t; + + typedef struct { + tcp_stream__dest_ip__d__out_t d; + } tcp_stream__dest_ip__out_t; + + typedef struct { + logic value; + } tcp_stream__control__enable__out_t; + + typedef struct { + logic value; + } tcp_stream__control__open__out_t; + + typedef struct { + logic value; + } tcp_stream__control__close__out_t; + + typedef struct { + tcp_stream__control__enable__out_t enable; + tcp_stream__control__open__out_t open; + tcp_stream__control__close__out_t close; + } tcp_stream__control__out_t; + + typedef struct { + tcp_stream__source_port__out_t source_port; + tcp_stream__source_ip__out_t source_ip; + tcp_stream__dest_port__out_t dest_port; + tcp_stream__dest_ip__out_t dest_ip; + tcp_stream__control__out_t control; + } tcp_stream__out_t; + + typedef struct { + tcp_stream__out_t tcp_streams; + } tcp_stream_regs__out_t; +endpackage diff --git a/hw/super6502_fpga/src/sub/network_processor/src/regs/tcp_top_regfile.sv b/hw/super6502_fpga/src/sub/network_processor/src/regs/tcp_top_regfile.sv new file mode 100644 index 0000000..cbb4044 --- /dev/null +++ b/hw/super6502_fpga/src/sub/network_processor/src/regs/tcp_top_regfile.sv @@ -0,0 +1,349 @@ +// 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, + + output logic s_axil_awready, + input wire s_axil_awvalid, + input wire [8: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 [8: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 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 [8: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 [8:0] axil_araddr; + logic axil_ar_accept; + logic axil_awvalid; + logic [8: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[8: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[8: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[8: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 tcp_streams[8]; + } decoded_reg_strb_t; + decoded_reg_strb_t decoded_reg_strb; + logic decoded_strb_is_external; + + logic [8: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<8; i0++) begin + decoded_reg_strb.tcp_streams[i0] = cpuif_req_masked & (cpuif_addr >= 9'h0 + i0*9'h40) & (cpuif_addr <= 9'h0 + i0*9'h40 + 9'h13); + is_external |= cpuif_req_masked & (cpuif_addr >= 9'h0 + i0*9'h40) & (cpuif_addr <= 9'h0 + i0*9'h40 + 9'h13); + 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<8; i0++) begin + assign hwif_out.tcp_streams[i0].req = decoded_reg_strb.tcp_streams[i0]; + assign hwif_out.tcp_streams[i0].addr = decoded_addr[4: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<8; 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<8; 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[8]; + for(genvar i0=0; i0<8; 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<8; 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 diff --git a/hw/super6502_fpga/src/sub/network_processor/src/regs/tcp_top_regfile_pkg.sv b/hw/super6502_fpga/src/sub/network_processor/src/regs/tcp_top_regfile_pkg.sv new file mode 100644 index 0000000..6a22f62 --- /dev/null +++ b/hw/super6502_fpga/src/sub/network_processor/src/regs/tcp_top_regfile_pkg.sv @@ -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 = 9; + + typedef struct { + logic rd_ack; + logic [31:0] rd_data; + logic wr_ack; + } tcp_stream__external__in_t; + + typedef struct { + tcp_stream__external__in_t tcp_streams[8]; + } tcp_top_regfile__in_t; + + typedef struct { + logic req; + logic [4:0] addr; + logic req_is_wr; + logic [31:0] wr_data; + logic [31:0] wr_biten; + } tcp_stream__external__out_t; + + typedef struct { + tcp_stream__external__out_t tcp_streams[8]; + } tcp_top_regfile__out_t; +endpackage diff --git a/hw/super6502_fpga/src/sub/network_processor/src/regs/tcp_top_regs.rdl b/hw/super6502_fpga/src/sub/network_processor/src/regs/tcp_top_regs.rdl new file mode 100644 index 0000000..f2d4c61 --- /dev/null +++ b/hw/super6502_fpga/src/sub/network_processor/src/regs/tcp_top_regs.rdl @@ -0,0 +1,3 @@ +addrmap tcp_top_regfile{ + external tcp_stream tcp_streams[8] += 0x40; +}; \ No newline at end of file diff --git a/hw/super6502_fpga/src/sub/network_processor/src/tcp_stream.sv b/hw/super6502_fpga/src/sub/network_processor/src/tcp_stream.sv index b61fa4c..75430df 100644 --- a/hw/super6502_fpga/src/sub/network_processor/src/tcp_stream.sv +++ b/hw/super6502_fpga/src/sub/network_processor/src/tcp_stream.sv @@ -1,8 +1,47 @@ module tcp_stream( + input wire clk, + input wire rst, + + 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 ); // regs +tcp_stream_regs_pkg::tcp_stream_regs__in_t hwif_in; +tcp_stream_regs_pkg::tcp_stream_regs__out_t hwif_out; + + +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) +); // tcp state manager diff --git a/hw/super6502_fpga/src/sub/rtl-common b/hw/super6502_fpga/src/sub/rtl-common index 6bb56be..1f071c1 160000 --- a/hw/super6502_fpga/src/sub/rtl-common +++ b/hw/super6502_fpga/src/sub/rtl-common @@ -1 +1 @@ -Subproject commit 6bb56be03a32ea76c7477e2403b396ede5818c31 +Subproject commit 1f071c11d920882c4a82c25e84a3f34f169f28ad diff --git a/hw/super6502_fpga/src/sub/sd_controller_wrapper/sdspi b/hw/super6502_fpga/src/sub/sd_controller_wrapper/sdspi index 4738e69..eb8e8ba 160000 --- a/hw/super6502_fpga/src/sub/sd_controller_wrapper/sdspi +++ b/hw/super6502_fpga/src/sub/sd_controller_wrapper/sdspi @@ -1 +1 @@ -Subproject commit 4738e699cadfdc7eedc5a9406563dd15a1c1950b +Subproject commit eb8e8ba552ab1e336ac1478ed9d4e7962eab44c2 diff --git a/hw/super6502_fpga/src/sub/sd_controller_wrapper/sources.list b/hw/super6502_fpga/src/sub/sd_controller_wrapper/sources.list new file mode 100644 index 0000000..1fcbeef --- /dev/null +++ b/hw/super6502_fpga/src/sub/sd_controller_wrapper/sources.list @@ -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 \ No newline at end of file diff --git a/hw/super6502_fpga/src/sub/wb2axip b/hw/super6502_fpga/src/sub/wb2axip index bf09db6..29e1e37 160000 --- a/hw/super6502_fpga/src/sub/wb2axip +++ b/hw/super6502_fpga/src/sub/wb2axip @@ -1 +1 @@ -Subproject commit bf09db69cbeba4f8b52edeb6bd6dfe824bb741da +Subproject commit 29e1e3755f04becaaee878a8437b80444bb96df2 diff --git a/init_env.sh b/init_env.sh index 7302039..9de3039 100644 --- a/init_env.sh +++ b/init_env.sh @@ -12,6 +12,8 @@ export KICAD7_FOOTPRINT_DIR=$REPO_TOP/hw/kicad_library/footprints python3.11 -m venv .user_venv . .user_venv/bin/activate +pip install -r requirements.txt + module load efinity/2023.1 module load iverilog/12.0 module load gtkwave/3.3_gtk3 diff --git a/requirements.txt b/requirements.txt new file mode 100644 index 0000000..43a64b5 --- /dev/null +++ b/requirements.txt @@ -0,0 +1,3 @@ +-i https://git.byronlathi.com/api/v4/projects/95/packages/pypi/simple +peakrdl==1.1.0 +rtl-manifest>=0.2.0 \ No newline at end of file diff --git a/sw/test_code/loop_test/link.ld b/sw/test_code/loop_test/link.ld index 44fc445..bc63183 100644 --- a/sw/test_code/loop_test/link.ld +++ b/sw/test_code/loop_test/link.ld @@ -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 { diff --git a/sw/test_code/ntw_test/Makefile b/sw/test_code/ntw_test/Makefile new file mode 100644 index 0000000..dfda409 --- /dev/null +++ b/sw/test_code/ntw_test/Makefile @@ -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 + diff --git a/sw/test_code/ntw_test/link.ld b/sw/test_code/ntw_test/link.ld new file mode 100644 index 0000000..bc63183 --- /dev/null +++ b/sw/test_code/ntw_test/link.ld @@ -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 +} diff --git a/sw/test_code/ntw_test/main.s b/sw/test_code/ntw_test/main.s new file mode 100644 index 0000000..086625d --- /dev/null +++ b/sw/test_code/ntw_test/main.s @@ -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 \ No newline at end of file