Create project
This commit is contained in:
2
.gitignore
vendored
Normal file
2
.gitignore
vendored
Normal file
@@ -0,0 +1,2 @@
|
||||
sim_build
|
||||
__pycache__
|
||||
6
.gitmodules
vendored
Normal file
6
.gitmodules
vendored
Normal file
@@ -0,0 +1,6 @@
|
||||
[submodule "sim/sub/taxi"]
|
||||
path = sim/sub/taxi
|
||||
url = git@git.byronlathi.com:bslathi19/taxi.git
|
||||
[submodule "sim/sub/verilog-6502"]
|
||||
path = sim/sub/verilog-6502
|
||||
url = git@git.byronlathi.com:third-party/verilog-6502.git
|
||||
10
init_env.sh
Normal file
10
init_env.sh
Normal file
@@ -0,0 +1,10 @@
|
||||
export REPO_TOP=$(git rev-parse --show-toplevel)
|
||||
|
||||
python3.13 -m venv .user_venv
|
||||
. .user_venv/bin/activate
|
||||
|
||||
pip install -r requirements.txt
|
||||
|
||||
export PYTHON3=$(which python)
|
||||
|
||||
module load verilator
|
||||
12
requirements.txt
Normal file
12
requirements.txt
Normal file
@@ -0,0 +1,12 @@
|
||||
peakrdl
|
||||
rtl-manifest
|
||||
cocotb
|
||||
cocotb-bus
|
||||
cocotbext-axi>=0.1.30
|
||||
cocotbext-eth>=0.1.24
|
||||
pytest
|
||||
fpga-sim>=0.5.4
|
||||
build_fpga
|
||||
git+https://github.com/arnavsacheti/PeakRDL-BusDecoder.git
|
||||
peakrdl-python-regmap>=0.0.5
|
||||
taxi-peakrdl-extensions
|
||||
27
sim/sources.list
Normal file
27
sim/sources.list
Normal file
@@ -0,0 +1,27 @@
|
||||
verilator.vlt
|
||||
verilog6502_wrapper_tb.sv
|
||||
|
||||
../src/regs/verilog6502_io_regs_pkg.sv
|
||||
../src/regs/verilog6502_io_regs.sv
|
||||
|
||||
../src/verilog6502_addr_decoder.sv
|
||||
../src/verilog6502_internal_memory.sv
|
||||
../src/verilog6502_apb_adapter.sv
|
||||
../src/verilog6502_external_memory.sv
|
||||
../src/verilog6502_wrapper.sv
|
||||
|
||||
|
||||
sub/verilog-6502/ALU.v
|
||||
sub/verilog-6502/cpu_65c02.v
|
||||
|
||||
sub/taxi/src/apb/rtl/taxi_apb_if.sv
|
||||
sub/taxi/src/axi/rtl/taxi_axi_if.sv
|
||||
sub/taxi/src/axi/rtl/taxi_axil_if.sv
|
||||
sub/taxi/src/axi/rtl/taxi_axi_ram_if_rd.sv
|
||||
sub/taxi/src/axi/rtl/taxi_axi_ram_if_wr.sv
|
||||
sub/taxi/src/axi/rtl/taxi_axi_ram_if_rdwr.sv
|
||||
sub/taxi/src/apb/rtl/taxi_apb_interconnect.sv
|
||||
sub/taxi/src/apb/rtl/taxi_apb_tie.sv
|
||||
sub/taxi/src/prim/rtl/taxi_arbiter.sv
|
||||
sub/taxi/src/prim/rtl/taxi_penc.sv
|
||||
sub/taxi/src/apb/rtl/taxi_apb_axil_adapter.sv
|
||||
1
sim/sub/taxi
Submodule
1
sim/sub/taxi
Submodule
Submodule sim/sub/taxi added at 1fe508a6bf
1
sim/sub/verilog-6502
Submodule
1
sim/sub/verilog-6502
Submodule
Submodule sim/sub/verilog-6502 added at 8f19e45b40
7
sim/verilator.vlt
Normal file
7
sim/verilator.vlt
Normal file
@@ -0,0 +1,7 @@
|
||||
`verilator_config
|
||||
|
||||
lint_off -file "**/ALU.v"
|
||||
lint_off -file "**/cpu_65c02.v"
|
||||
lint_off -rule MULTIDRIVEN -file "**/verilog6502_io_regs.sv"
|
||||
lint_off -rule UNOPTFLAT
|
||||
lint_off -rule TIMESCALEMOD
|
||||
9
sim/verilog6502_wrapper.yaml
Normal file
9
sim/verilog6502_wrapper.yaml
Normal file
@@ -0,0 +1,9 @@
|
||||
tests:
|
||||
- name: "verilog6502_wrapper"
|
||||
toplevel: "verilog6502_wrapper_tb"
|
||||
modules:
|
||||
- "verilog6502_wrapper_test"
|
||||
sources: "sources.list"
|
||||
waves: True
|
||||
defines:
|
||||
SIM: "hi"
|
||||
30
sim/verilog6502_wrapper_tb.sv
Normal file
30
sim/verilog6502_wrapper_tb.sv
Normal file
@@ -0,0 +1,30 @@
|
||||
module verilog6502_wrapper_tb();
|
||||
|
||||
`define SIM
|
||||
|
||||
taxi_apb_if s_apb();
|
||||
taxi_axil_if m_axil();
|
||||
taxi_axi_if s_axi();
|
||||
|
||||
logic clk;
|
||||
logic rst;
|
||||
|
||||
logic o_irq_ext;
|
||||
logic i_irq_ext;
|
||||
logic i_nmi_ext;
|
||||
|
||||
|
||||
verilog6502_wrapper u_dut(
|
||||
.clk(clk),
|
||||
.rst(rst),
|
||||
.s_apb(s_apb),
|
||||
.m_axil_rd(m_axil),
|
||||
.m_axil_wr(m_axil),
|
||||
.s_axi_rd(s_axi),
|
||||
.s_axi_wr(s_axi),
|
||||
.o_irq_ext(o_irq_ext),
|
||||
.i_irq_ext(i_irq_ext),
|
||||
.i_nmi_ext(i_nmi_ext)
|
||||
);
|
||||
|
||||
endmodule
|
||||
48
sim/verilog6502_wrapper_test.py
Normal file
48
sim/verilog6502_wrapper_test.py
Normal file
@@ -0,0 +1,48 @@
|
||||
import cocotb
|
||||
from cocotb.handle import Immediate
|
||||
|
||||
from cocotb.clock import Clock
|
||||
from cocotb.triggers import Timer, RisingEdge
|
||||
|
||||
from cocotbext.axi.apb import ApbMaster, ApbBus
|
||||
from cocotbext.axi import AxiMaster, AxiBus, AxiLiteBus, AxiLiteRam
|
||||
|
||||
|
||||
|
||||
CLK_PERIOD = 5
|
||||
|
||||
|
||||
@cocotb.test
|
||||
async def test_sanity(dut):
|
||||
print("Hello world")
|
||||
cocotb.start_soon(Clock(dut.clk, CLK_PERIOD, unit="ns").start())
|
||||
|
||||
s_apb = ApbMaster(ApbBus.from_prefix(dut.s_apb, ""), dut.clk, dut.rst)
|
||||
|
||||
s_axi = AxiMaster(AxiBus.from_prefix(dut.s_axi, ""), dut.clk, dut.rst)
|
||||
m_axil = AxiLiteRam(AxiLiteBus.from_prefix(dut.m_axil, ""), dut.clk, dut.rst, size=2**32)
|
||||
|
||||
m_axil.write(0, b"Hello, world!")
|
||||
|
||||
|
||||
dut.rst.value = Immediate(1)
|
||||
for _ in range(10):
|
||||
await RisingEdge(dut.clk)
|
||||
dut.rst.value = 0
|
||||
for _ in range(10):
|
||||
await RisingEdge(dut.clk)
|
||||
|
||||
# await s_axi.write(0x200, [0x58, 0xa9, 0x00, 0x1a, 0xcb, 0x4c, 0x03, 0x02])
|
||||
await s_axi.write(0x200, [0xAD, 0x00, 0xE0, 0xAD, 0x01, 0xE0, 0xAD, 0x02, 0xE0, 0xAD, 0x03, 0xE0, 0xAD, 0x04, 0xE0, 0xCB])
|
||||
|
||||
cocotb.start_soon(s_axi.read(0x200, 8))
|
||||
|
||||
await Timer(10, "us")
|
||||
|
||||
await s_apb.write_dword(0x0, 0)
|
||||
|
||||
await Timer(1, "us")
|
||||
|
||||
dut.i_nmi_ext.value = Immediate(1)
|
||||
|
||||
await Timer(1, "us")
|
||||
387
src/fpga6502.sv
Normal file
387
src/fpga6502.sv
Normal file
@@ -0,0 +1,387 @@
|
||||
module fpga6502 (
|
||||
output jtagCtrl_tdi,
|
||||
input jtagCtrl_tdo,
|
||||
output jtagCtrl_enable,
|
||||
output jtagCtrl_capture,
|
||||
output jtagCtrl_shift,
|
||||
output jtagCtrl_update,
|
||||
output jtagCtrl_reset,
|
||||
input ut_jtagCtrl_tdi,
|
||||
output ut_jtagCtrl_tdo,
|
||||
input ut_jtagCtrl_enable,
|
||||
input ut_jtagCtrl_capture,
|
||||
input ut_jtagCtrl_shift,
|
||||
input ut_jtagCtrl_update,
|
||||
input ut_jtagCtrl_reset,
|
||||
input io_cfuClk,
|
||||
input io_cfuReset,
|
||||
input cpu0_customInstruction_cmd_valid,
|
||||
output cpu0_customInstruction_cmd_ready,
|
||||
input [9:0] cpu0_customInstruction_function_id,
|
||||
input [31:0] cpu0_customInstruction_inputs_0,
|
||||
input [31:0] cpu0_customInstruction_inputs_1,
|
||||
output cpu0_customInstruction_rsp_valid,
|
||||
input cpu0_customInstruction_rsp_ready,
|
||||
output [31:0] cpu0_customInstruction_outputs_0,
|
||||
input cpu1_customInstruction_cmd_valid,
|
||||
output cpu1_customInstruction_cmd_ready,
|
||||
input [9:0] cpu1_customInstruction_function_id,
|
||||
input [31:0] cpu1_customInstruction_inputs_0,
|
||||
input [31:0] cpu1_customInstruction_inputs_1,
|
||||
output cpu1_customInstruction_rsp_valid,
|
||||
input cpu1_customInstruction_rsp_ready,
|
||||
output [31:0] cpu1_customInstruction_outputs_0,
|
||||
input cpu2_customInstruction_cmd_valid,
|
||||
output cpu2_customInstruction_cmd_ready,
|
||||
input [9:0] cpu2_customInstruction_function_id,
|
||||
input [31:0] cpu2_customInstruction_inputs_0,
|
||||
input [31:0] cpu2_customInstruction_inputs_1,
|
||||
output cpu2_customInstruction_rsp_valid,
|
||||
input cpu2_customInstruction_rsp_ready,
|
||||
output [31:0] cpu2_customInstruction_outputs_0,
|
||||
input cpu3_customInstruction_cmd_valid,
|
||||
output cpu3_customInstruction_cmd_ready,
|
||||
input [9:0] cpu3_customInstruction_function_id,
|
||||
input [31:0] cpu3_customInstruction_inputs_0,
|
||||
input [31:0] cpu3_customInstruction_inputs_1,
|
||||
output cpu3_customInstruction_rsp_valid,
|
||||
input cpu3_customInstruction_rsp_ready,
|
||||
output [31:0] cpu3_customInstruction_outputs_0,
|
||||
output io_ddrMasters_0_aw_valid,
|
||||
input io_ddrMasters_0_aw_ready,
|
||||
output [31:0] io_ddrMasters_0_aw_payload_addr,
|
||||
output [3:0] io_ddrMasters_0_aw_payload_id,
|
||||
output [3:0] io_ddrMasters_0_aw_payload_region,
|
||||
output [7:0] io_ddrMasters_0_aw_payload_len,
|
||||
output [2:0] io_ddrMasters_0_aw_payload_size,
|
||||
output [1:0] io_ddrMasters_0_aw_payload_burst,
|
||||
output io_ddrMasters_0_aw_payload_lock,
|
||||
output [3:0] io_ddrMasters_0_aw_payload_cache,
|
||||
output [3:0] io_ddrMasters_0_aw_payload_qos,
|
||||
output [2:0] io_ddrMasters_0_aw_payload_prot,
|
||||
output io_ddrMasters_0_aw_payload_allStrb,
|
||||
output io_ddrMasters_0_w_valid,
|
||||
input io_ddrMasters_0_w_ready,
|
||||
output [127:0] io_ddrMasters_0_w_payload_data,
|
||||
output [15:0] io_ddrMasters_0_w_payload_strb,
|
||||
output io_ddrMasters_0_w_payload_last,
|
||||
input io_ddrMasters_0_b_valid,
|
||||
output io_ddrMasters_0_b_ready,
|
||||
input [3:0] io_ddrMasters_0_b_payload_id,
|
||||
input [1:0] io_ddrMasters_0_b_payload_resp,
|
||||
output io_ddrMasters_0_ar_valid,
|
||||
input io_ddrMasters_0_ar_ready,
|
||||
output [31:0] io_ddrMasters_0_ar_payload_addr,
|
||||
output [3:0] io_ddrMasters_0_ar_payload_id,
|
||||
output [3:0] io_ddrMasters_0_ar_payload_region,
|
||||
output [7:0] io_ddrMasters_0_ar_payload_len,
|
||||
output [2:0] io_ddrMasters_0_ar_payload_size,
|
||||
output [1:0] io_ddrMasters_0_ar_payload_burst,
|
||||
output io_ddrMasters_0_ar_payload_lock,
|
||||
output [3:0] io_ddrMasters_0_ar_payload_cache,
|
||||
output [3:0] io_ddrMasters_0_ar_payload_qos,
|
||||
output [2:0] io_ddrMasters_0_ar_payload_prot,
|
||||
input io_ddrMasters_0_r_valid,
|
||||
output io_ddrMasters_0_r_ready,
|
||||
input [127:0] io_ddrMasters_0_r_payload_data,
|
||||
input [3:0] io_ddrMasters_0_r_payload_id,
|
||||
input [1:0] io_ddrMasters_0_r_payload_resp,
|
||||
input io_ddrMasters_0_r_payload_last,
|
||||
input io_ddrMasters_0_clk,
|
||||
input io_ddrMasters_0_reset,
|
||||
output io_ddrMasters_memCheck_pass,
|
||||
output userInterruptA,
|
||||
output userInterruptB,
|
||||
output userInterruptC,
|
||||
output userInterruptD,
|
||||
output userInterruptE,
|
||||
output userInterruptF,
|
||||
output userInterruptH,
|
||||
output userInterruptG,
|
||||
output userInterruptI,
|
||||
input [3:0] system_gpio_0_io_read,
|
||||
output [3:0] system_gpio_0_io_write,
|
||||
output [3:0] system_gpio_0_io_writeEnable,
|
||||
output system_uart_0_io_txd,
|
||||
input system_uart_0_io_rxd,
|
||||
output system_spi_0_io_sclk_write,
|
||||
output system_spi_0_io_data_0_writeEnable,
|
||||
input system_spi_0_io_data_0_read,
|
||||
output system_spi_0_io_data_0_write,
|
||||
output system_spi_0_io_data_1_writeEnable,
|
||||
input system_spi_0_io_data_1_read,
|
||||
output system_spi_0_io_data_1_write,
|
||||
output system_spi_0_io_data_2_writeEnable,
|
||||
input system_spi_0_io_data_2_read,
|
||||
output system_spi_0_io_data_2_write,
|
||||
output system_spi_0_io_data_3_writeEnable,
|
||||
input system_spi_0_io_data_3_read,
|
||||
output system_spi_0_io_data_3_write,
|
||||
output [3:0] system_spi_0_io_ss,
|
||||
output system_i2c_0_io_sda_writeEnable,
|
||||
output system_i2c_0_io_sda_write,
|
||||
input system_i2c_0_io_sda_read,
|
||||
output system_i2c_0_io_scl_writeEnable,
|
||||
output system_i2c_0_io_scl_write,
|
||||
input system_i2c_0_io_scl_read,
|
||||
input [31:0] axiA_awaddr,
|
||||
input [7:0] axiA_awlen,
|
||||
input [2:0] axiA_awsize,
|
||||
input [1:0] axiA_awburst,
|
||||
input axiA_awlock,
|
||||
input [3:0] axiA_awcache,
|
||||
input [2:0] axiA_awprot,
|
||||
input [3:0] axiA_awqos,
|
||||
input [3:0] axiA_awregion,
|
||||
input axiA_awvalid,
|
||||
output axiA_awready,
|
||||
input [31:0] axiA_wdata,
|
||||
input [3:0] axiA_wstrb,
|
||||
input axiA_wvalid,
|
||||
input axiA_wlast,
|
||||
output axiA_wready,
|
||||
output [1:0] axiA_bresp,
|
||||
output axiA_bvalid,
|
||||
input axiA_bready,
|
||||
input [31:0] axiA_araddr,
|
||||
input [7:0] axiA_arlen,
|
||||
input [2:0] axiA_arsize,
|
||||
input [1:0] axiA_arburst,
|
||||
input axiA_arlock,
|
||||
input [3:0] axiA_arcache,
|
||||
input [2:0] axiA_arprot,
|
||||
input [3:0] axiA_arqos,
|
||||
input [3:0] axiA_arregion,
|
||||
input axiA_arvalid,
|
||||
output axiA_arready,
|
||||
output [31:0] axiA_rdata,
|
||||
output [1:0] axiA_rresp,
|
||||
output axiA_rlast,
|
||||
output axiA_rvalid,
|
||||
input axiA_rready,
|
||||
output axiAInterrupt,
|
||||
input cfg_done,
|
||||
output cfg_start,
|
||||
output cfg_sel,
|
||||
output cfg_reset,
|
||||
input io_peripheralClk,
|
||||
input io_peripheralReset,
|
||||
output io_asyncReset,
|
||||
input io_gpio_sw_n,
|
||||
input pll_peripheral_locked,
|
||||
input pll_system_locked,
|
||||
input pll_tse_locked,
|
||||
// SDHC
|
||||
input sd_base_clk,
|
||||
output sd_clk_hi,
|
||||
output sd_clk_lo,
|
||||
input sd_cmd_i,
|
||||
output sd_cmd_o,
|
||||
output sd_cmd_oe,
|
||||
input [3:0] sd_dat_i,
|
||||
output [3:0] sd_dat_o,
|
||||
output [3:0] sd_dat_oe,
|
||||
input sd_cd_n,
|
||||
input sd_wp,
|
||||
// TSEMAC
|
||||
input io_tseClk,
|
||||
// MAC
|
||||
output [3:0] rgmii_txd_HI,
|
||||
output [3:0] rgmii_txd_LO,
|
||||
output rgmii_tx_ctl_HI,
|
||||
output rgmii_tx_ctl_LO,
|
||||
output rgmii_txc_HI,
|
||||
output rgmii_txc_LO,
|
||||
input [3:0] rgmii_rxd_HI,
|
||||
input [3:0] rgmii_rxd_LO,
|
||||
input rgmii_rx_ctl_HI,
|
||||
input rgmii_rx_ctl_LO,
|
||||
input mux_clk,
|
||||
output [1:0] mux_clk_sw,
|
||||
// PHY
|
||||
output phy_rst,
|
||||
input phy_mdi,
|
||||
output phy_mdo,
|
||||
output phy_mdo_en,
|
||||
output phy_mdc,
|
||||
input rgmii_rxc,
|
||||
input rgmii_rxc_slow
|
||||
);
|
||||
|
||||
|
||||
|
||||
top_soc u_top_soc (
|
||||
.jtagCtrl_tdi (jtagCtrl_tdi),
|
||||
.jtagCtrl_tdo (jtagCtrl_tdo),
|
||||
.jtagCtrl_enable (jtagCtrl_enable),
|
||||
.jtagCtrl_capture (jtagCtrl_capture),
|
||||
.jtagCtrl_shift (jtagCtrl_shift),
|
||||
.jtagCtrl_update (jtagCtrl_update),
|
||||
.jtagCtrl_reset (jtagCtrl_reset),
|
||||
.ut_jtagCtrl_tdi (ut_jtagCtrl_tdi),
|
||||
.ut_jtagCtrl_tdo (ut_jtagCtrl_tdo),
|
||||
.ut_jtagCtrl_enable (ut_jtagCtrl_enable),
|
||||
.ut_jtagCtrl_capture (ut_jtagCtrl_capture),
|
||||
.ut_jtagCtrl_shift (ut_jtagCtrl_shift),
|
||||
.ut_jtagCtrl_update (ut_jtagCtrl_update),
|
||||
.ut_jtagCtrl_reset (ut_jtagCtrl_reset),
|
||||
.io_cfuClk (io_cfuClk),
|
||||
.io_cfuReset (io_cfuReset),
|
||||
.io_ddrMasters_0_aw_valid (io_ddrMasters_0_aw_valid),
|
||||
.io_ddrMasters_0_aw_ready (io_ddrMasters_0_aw_ready),
|
||||
.io_ddrMasters_0_aw_payload_addr (io_ddrMasters_0_aw_payload_addr),
|
||||
.io_ddrMasters_0_aw_payload_id (io_ddrMasters_0_aw_payload_id),
|
||||
.io_ddrMasters_0_aw_payload_region (io_ddrMasters_0_aw_payload_region),
|
||||
.io_ddrMasters_0_aw_payload_len (io_ddrMasters_0_aw_payload_len),
|
||||
.io_ddrMasters_0_aw_payload_size (io_ddrMasters_0_aw_payload_size),
|
||||
.io_ddrMasters_0_aw_payload_burst (io_ddrMasters_0_aw_payload_burst),
|
||||
.io_ddrMasters_0_aw_payload_lock (io_ddrMasters_0_aw_payload_lock),
|
||||
.io_ddrMasters_0_aw_payload_cache (io_ddrMasters_0_aw_payload_cache),
|
||||
.io_ddrMasters_0_aw_payload_qos (io_ddrMasters_0_aw_payload_qos),
|
||||
.io_ddrMasters_0_aw_payload_prot (io_ddrMasters_0_aw_payload_prot),
|
||||
.io_ddrMasters_0_aw_payload_allStrb (io_ddrMasters_0_aw_payload_allStrb),
|
||||
.io_ddrMasters_0_w_valid (io_ddrMasters_0_w_valid),
|
||||
.io_ddrMasters_0_w_ready (io_ddrMasters_0_w_ready),
|
||||
.io_ddrMasters_0_w_payload_data (io_ddrMasters_0_w_payload_data),
|
||||
.io_ddrMasters_0_w_payload_strb (io_ddrMasters_0_w_payload_strb),
|
||||
.io_ddrMasters_0_w_payload_last (io_ddrMasters_0_w_payload_last),
|
||||
.io_ddrMasters_0_b_valid (io_ddrMasters_0_b_valid),
|
||||
.io_ddrMasters_0_b_ready (io_ddrMasters_0_b_ready),
|
||||
.io_ddrMasters_0_b_payload_id (io_ddrMasters_0_b_payload_id),
|
||||
.io_ddrMasters_0_b_payload_resp (io_ddrMasters_0_b_payload_resp),
|
||||
.io_ddrMasters_0_ar_valid (io_ddrMasters_0_ar_valid),
|
||||
.io_ddrMasters_0_ar_ready (io_ddrMasters_0_ar_ready),
|
||||
.io_ddrMasters_0_ar_payload_addr (io_ddrMasters_0_ar_payload_addr),
|
||||
.io_ddrMasters_0_ar_payload_id (io_ddrMasters_0_ar_payload_id),
|
||||
.io_ddrMasters_0_ar_payload_region (io_ddrMasters_0_ar_payload_region),
|
||||
.io_ddrMasters_0_ar_payload_len (io_ddrMasters_0_ar_payload_len),
|
||||
.io_ddrMasters_0_ar_payload_size (io_ddrMasters_0_ar_payload_size),
|
||||
.io_ddrMasters_0_ar_payload_burst (io_ddrMasters_0_ar_payload_burst),
|
||||
.io_ddrMasters_0_ar_payload_lock (io_ddrMasters_0_ar_payload_lock),
|
||||
.io_ddrMasters_0_ar_payload_cache (io_ddrMasters_0_ar_payload_cache),
|
||||
.io_ddrMasters_0_ar_payload_qos (io_ddrMasters_0_ar_payload_qos),
|
||||
.io_ddrMasters_0_ar_payload_prot (io_ddrMasters_0_ar_payload_prot),
|
||||
.io_ddrMasters_0_r_valid (io_ddrMasters_0_r_valid),
|
||||
.io_ddrMasters_0_r_ready (io_ddrMasters_0_r_ready),
|
||||
.io_ddrMasters_0_r_payload_data (io_ddrMasters_0_r_payload_data),
|
||||
.io_ddrMasters_0_r_payload_id (io_ddrMasters_0_r_payload_id),
|
||||
.io_ddrMasters_0_r_payload_resp (io_ddrMasters_0_r_payload_resp),
|
||||
.io_ddrMasters_0_r_payload_last (io_ddrMasters_0_r_payload_last),
|
||||
.io_ddrMasters_0_clk (io_ddrMasters_0_clk),
|
||||
.io_ddrMasters_0_reset (io_ddrMasters_0_reset),
|
||||
.io_ddrMasters_memCheck_pass (io_ddrMasters_memCheck_pass),
|
||||
.userInterruptA (userInterruptA),
|
||||
.userInterruptB (userInterruptB),
|
||||
.userInterruptC (userInterruptC),
|
||||
.userInterruptD (userInterruptD),
|
||||
.userInterruptE (userInterruptE),
|
||||
.userInterruptF (userInterruptF),
|
||||
.userInterruptH (userInterruptH),
|
||||
.userInterruptG (userInterruptG),
|
||||
.userInterruptI (userInterruptI),
|
||||
.system_gpio_0_io_read (system_gpio_0_io_read),
|
||||
.system_gpio_0_io_write (system_gpio_0_io_write),
|
||||
.system_gpio_0_io_writeEnable (system_gpio_0_io_writeEnable),
|
||||
.system_uart_0_io_txd (system_uart_0_io_txd),
|
||||
.system_uart_0_io_rxd (system_uart_0_io_rxd),
|
||||
.system_spi_0_io_sclk_write (system_spi_0_io_sclk_write),
|
||||
.system_spi_0_io_data_0_writeEnable (system_spi_0_io_data_0_writeEnable),
|
||||
.system_spi_0_io_data_0_read (system_spi_0_io_data_0_read),
|
||||
.system_spi_0_io_data_0_write (system_spi_0_io_data_0_write),
|
||||
.system_spi_0_io_data_1_writeEnable (system_spi_0_io_data_1_writeEnable),
|
||||
.system_spi_0_io_data_1_read (system_spi_0_io_data_1_read),
|
||||
.system_spi_0_io_data_1_write (system_spi_0_io_data_1_write),
|
||||
.system_spi_0_io_data_2_writeEnable (system_spi_0_io_data_2_writeEnable),
|
||||
.system_spi_0_io_data_2_read (system_spi_0_io_data_2_read),
|
||||
.system_spi_0_io_data_2_write (system_spi_0_io_data_2_write),
|
||||
.system_spi_0_io_data_3_writeEnable (system_spi_0_io_data_3_writeEnable),
|
||||
.system_spi_0_io_data_3_read (system_spi_0_io_data_3_read),
|
||||
.system_spi_0_io_data_3_write (system_spi_0_io_data_3_write),
|
||||
.system_spi_0_io_ss (system_spi_0_io_ss),
|
||||
.system_i2c_0_io_sda_writeEnable (system_i2c_0_io_sda_writeEnable),
|
||||
.system_i2c_0_io_sda_write (system_i2c_0_io_sda_write),
|
||||
.system_i2c_0_io_sda_read (system_i2c_0_io_sda_read),
|
||||
.system_i2c_0_io_scl_writeEnable (system_i2c_0_io_scl_writeEnable),
|
||||
.system_i2c_0_io_scl_write (system_i2c_0_io_scl_write),
|
||||
.system_i2c_0_io_scl_read (system_i2c_0_io_scl_read),
|
||||
.axiA_awaddr (axiA_awaddr),
|
||||
.axiA_awlen (axiA_awlen),
|
||||
.axiA_awsize (axiA_awsize),
|
||||
.axiA_awburst (axiA_awburst),
|
||||
.axiA_awlock (axiA_awlock),
|
||||
.axiA_awcache (axiA_awcache),
|
||||
.axiA_awprot (axiA_awprot),
|
||||
.axiA_awqos (axiA_awqos),
|
||||
.axiA_awregion (axiA_awregion),
|
||||
.axiA_awvalid (axiA_awvalid),
|
||||
.axiA_awready (axiA_awready),
|
||||
.axiA_wdata (axiA_wdata),
|
||||
.axiA_wstrb (axiA_wstrb),
|
||||
.axiA_wvalid (axiA_wvalid),
|
||||
.axiA_wlast (axiA_wlast),
|
||||
.axiA_wready (axiA_wready),
|
||||
.axiA_bresp (axiA_bresp),
|
||||
.axiA_bvalid (axiA_bvalid),
|
||||
.axiA_bready (axiA_bready),
|
||||
.axiA_araddr (axiA_araddr),
|
||||
.axiA_arlen (axiA_arlen),
|
||||
.axiA_arsize (axiA_arsize),
|
||||
.axiA_arburst (axiA_arburst),
|
||||
.axiA_arlock (axiA_arlock),
|
||||
.axiA_arcache (axiA_arcache),
|
||||
.axiA_arprot (axiA_arprot),
|
||||
.axiA_arqos (axiA_arqos),
|
||||
.axiA_arregion (axiA_arregion),
|
||||
.axiA_arvalid (axiA_arvalid),
|
||||
.axiA_arready (axiA_arready),
|
||||
.axiA_rdata (axiA_rdata),
|
||||
.axiA_rresp (axiA_rresp),
|
||||
.axiA_rlast (axiA_rlast),
|
||||
.axiA_rvalid (axiA_rvalid),
|
||||
.axiA_rready (axiA_rready),
|
||||
.axiAInterrupt (axiAInterrupt),
|
||||
.cfg_done (cfg_done),
|
||||
.cfg_start (cfg_start),
|
||||
.cfg_sel (cfg_sel),
|
||||
.cfg_reset (cfg_reset),
|
||||
.io_peripheralClk (io_peripheralClk),
|
||||
.io_peripheralReset (io_peripheralReset),
|
||||
.io_asyncReset (io_asyncReset),
|
||||
.io_gpio_sw_n (io_gpio_sw_n),
|
||||
.pll_peripheral_locked (pll_peripheral_locked),
|
||||
.pll_system_locked (pll_system_locked),
|
||||
.pll_tse_locked (pll_tse_locked),
|
||||
.sd_base_clk (sd_base_clk),
|
||||
.sd_clk_hi (sd_clk_hi),
|
||||
.sd_clk_lo (sd_clk_lo),
|
||||
.sd_cmd_i (sd_cmd_i),
|
||||
.sd_cmd_o (sd_cmd_o),
|
||||
.sd_cmd_oe (sd_cmd_oe),
|
||||
.sd_dat_i (sd_dat_i),
|
||||
.sd_dat_o (sd_dat_o),
|
||||
.sd_dat_oe (sd_dat_oe),
|
||||
.sd_cd_n (sd_cd_n),
|
||||
.sd_wp (sd_wp),
|
||||
.io_tseClk (io_tseClk),
|
||||
.rgmii_txd_HI (rgmii_txd_HI),
|
||||
.rgmii_txd_LO (rgmii_txd_LO),
|
||||
.rgmii_tx_ctl_HI (rgmii_tx_ctl_HI),
|
||||
.rgmii_tx_ctl_LO (rgmii_tx_ctl_LO),
|
||||
.rgmii_txc_HI (rgmii_txc_HI),
|
||||
.rgmii_txc_LO (rgmii_txc_LO),
|
||||
.rgmii_rxd_HI (rgmii_rxd_HI),
|
||||
.rgmii_rxd_LO (rgmii_rxd_LO),
|
||||
.rgmii_rx_ctl_HI (rgmii_rx_ctl_HI),
|
||||
.rgmii_rx_ctl_LO (rgmii_rx_ctl_LO),
|
||||
.mux_clk (mux_clk),
|
||||
.mux_clk_sw (mux_clk_sw),
|
||||
.phy_rst (phy_rst),
|
||||
.phy_mdi (phy_mdi),
|
||||
.phy_mdo (phy_mdo),
|
||||
.phy_mdo_en (phy_mdo_en),
|
||||
.phy_mdc (phy_mdc),
|
||||
.rgmii_rxc (rgmii_rxc),
|
||||
.rgmii_rxc_slow (rgmii_rxc_slow)
|
||||
);
|
||||
|
||||
endmodule
|
||||
1
src/regs/gen_regs.sh
Executable file
1
src/regs/gen_regs.sh
Executable file
@@ -0,0 +1 @@
|
||||
peakrdl regblock -o . --cpuif taxi-apb verilog6502_io_regs.rdl
|
||||
60
src/regs/verilog6502_io_regs.rdl
Normal file
60
src/regs/verilog6502_io_regs.rdl
Normal file
@@ -0,0 +1,60 @@
|
||||
addrmap verilog6502_io_regs {
|
||||
name = "";
|
||||
desc = "";
|
||||
|
||||
reg {
|
||||
name = "Core Control";
|
||||
desc = "";
|
||||
|
||||
field {
|
||||
name = "reset";
|
||||
desc = "";
|
||||
hw = r;
|
||||
sw = rw;
|
||||
} reset[0:0] = 0x1;
|
||||
|
||||
} core_ctrl @ 0x0;
|
||||
|
||||
reg {
|
||||
name = "AXI Base Address";
|
||||
desc = "";
|
||||
|
||||
field {
|
||||
name = "val";
|
||||
desc = "";
|
||||
hw = r;
|
||||
sw = rw;
|
||||
} val[31:0] = 0x0;
|
||||
|
||||
} axi_base_address @ 0x10;
|
||||
|
||||
reg {
|
||||
name = "nmi";
|
||||
|
||||
field {
|
||||
name = "nmi";
|
||||
desc = "";
|
||||
hw = r;
|
||||
sw = rw;
|
||||
} nmi[31:16] = 0x200;
|
||||
} nmi @ 0xff8;
|
||||
|
||||
reg {
|
||||
name = "reset_brq";
|
||||
desc = "";
|
||||
|
||||
field {
|
||||
name = "reset";
|
||||
desc = "";
|
||||
hw = r;
|
||||
sw = rw;
|
||||
} reset[15:0] = 0x200;
|
||||
|
||||
field {
|
||||
name = "brq";
|
||||
desc = "";
|
||||
hw = r;
|
||||
sw = rw;
|
||||
} brk[31:16] = 0x200;
|
||||
} reset_brq @ 0xffc;
|
||||
};
|
||||
340
src/regs/verilog6502_io_regs.sv
Normal file
340
src/regs/verilog6502_io_regs.sv
Normal file
@@ -0,0 +1,340 @@
|
||||
// Generated by PeakRDL-regblock - A free and open-source SystemVerilog generator
|
||||
// https://github.com/SystemRDL/PeakRDL-regblock
|
||||
|
||||
module verilog6502_io_regs (
|
||||
input wire clk,
|
||||
input wire rst,
|
||||
|
||||
taxi_apb_if.slv s_apb,
|
||||
|
||||
output verilog6502_io_regs_pkg::verilog6502_io_regs__out_t hwif_out
|
||||
);
|
||||
|
||||
//--------------------------------------------------------------------------
|
||||
// CPU Bus interface logic
|
||||
//--------------------------------------------------------------------------
|
||||
logic cpuif_req;
|
||||
logic cpuif_req_is_wr;
|
||||
logic [11: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;
|
||||
|
||||
`ifndef SYNTHESIS
|
||||
initial begin
|
||||
assert_bad_addr_width: assert($bits(s_apb.paddr) >= verilog6502_io_regs_pkg::VERILOG6502_IO_REGS_MIN_ADDR_WIDTH)
|
||||
else $error("Interface address width of %0d is too small. Shall be at least %0d bits", $bits(s_apb.paddr), verilog6502_io_regs_pkg::VERILOG6502_IO_REGS_MIN_ADDR_WIDTH);
|
||||
assert_bad_data_width: assert($bits(s_apb.pwdata) == verilog6502_io_regs_pkg::VERILOG6502_IO_REGS_DATA_WIDTH)
|
||||
else $error("Interface data width of %0d is incorrect. Shall be %0d bits", $bits(s_apb.pwdata), verilog6502_io_regs_pkg::VERILOG6502_IO_REGS_DATA_WIDTH);
|
||||
end
|
||||
`endif
|
||||
|
||||
// Request
|
||||
logic is_active;
|
||||
always_ff @(posedge clk) begin
|
||||
if(rst) begin
|
||||
is_active <= '0;
|
||||
cpuif_req <= '0;
|
||||
cpuif_req_is_wr <= '0;
|
||||
cpuif_addr <= '0;
|
||||
cpuif_wr_data <= '0;
|
||||
cpuif_wr_biten <= '0;
|
||||
end else begin
|
||||
if(~is_active) begin
|
||||
if(s_apb.psel) begin
|
||||
is_active <= '1;
|
||||
cpuif_req <= '1;
|
||||
cpuif_req_is_wr <= s_apb.pwrite;
|
||||
cpuif_addr <= {s_apb.paddr[11:2], 2'b0};
|
||||
cpuif_wr_data <= s_apb.pwdata;
|
||||
for(int i=0; i<4; i++) begin
|
||||
cpuif_wr_biten[i*8 +: 8] <= {8{s_apb.pstrb[i]}};
|
||||
end
|
||||
end
|
||||
end else begin
|
||||
cpuif_req <= '0;
|
||||
if(cpuif_rd_ack || cpuif_wr_ack) begin
|
||||
is_active <= '0;
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
// Response
|
||||
assign s_apb.pready = cpuif_rd_ack | cpuif_wr_ack;
|
||||
assign s_apb.prdata = cpuif_rd_data;
|
||||
assign s_apb.pslverr = cpuif_rd_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 core_ctrl;
|
||||
logic axi_base_address;
|
||||
logic nmi;
|
||||
logic reset_brq;
|
||||
} decoded_reg_strb_t;
|
||||
decoded_reg_strb_t decoded_reg_strb;
|
||||
logic decoded_err;
|
||||
logic [11: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_valid_addr;
|
||||
automatic logic is_valid_rw;
|
||||
is_valid_addr = '1; // No valid address check
|
||||
is_valid_rw = '1; // No valid RW check
|
||||
decoded_reg_strb.core_ctrl = cpuif_req_masked & (cpuif_addr == 12'h0);
|
||||
decoded_reg_strb.axi_base_address = cpuif_req_masked & (cpuif_addr == 12'h10);
|
||||
decoded_reg_strb.nmi = cpuif_req_masked & (cpuif_addr == 12'hff8);
|
||||
decoded_reg_strb.reset_brq = cpuif_req_masked & (cpuif_addr == 12'hffc);
|
||||
decoded_err = '0;
|
||||
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 next;
|
||||
logic load_next;
|
||||
} reset;
|
||||
} core_ctrl;
|
||||
struct {
|
||||
struct {
|
||||
logic [31:0] next;
|
||||
logic load_next;
|
||||
} val;
|
||||
} axi_base_address;
|
||||
struct {
|
||||
struct {
|
||||
logic [15:0] next;
|
||||
logic load_next;
|
||||
} nmi;
|
||||
} nmi;
|
||||
struct {
|
||||
struct {
|
||||
logic [15:0] next;
|
||||
logic load_next;
|
||||
} reset;
|
||||
struct {
|
||||
logic [15:0] next;
|
||||
logic load_next;
|
||||
} brk;
|
||||
} reset_brq;
|
||||
} field_combo_t;
|
||||
field_combo_t field_combo;
|
||||
|
||||
typedef struct {
|
||||
struct {
|
||||
struct {
|
||||
logic value;
|
||||
} reset;
|
||||
} core_ctrl;
|
||||
struct {
|
||||
struct {
|
||||
logic [31:0] value;
|
||||
} val;
|
||||
} axi_base_address;
|
||||
struct {
|
||||
struct {
|
||||
logic [15:0] value;
|
||||
} nmi;
|
||||
} nmi;
|
||||
struct {
|
||||
struct {
|
||||
logic [15:0] value;
|
||||
} reset;
|
||||
struct {
|
||||
logic [15:0] value;
|
||||
} brk;
|
||||
} reset_brq;
|
||||
} field_storage_t;
|
||||
field_storage_t field_storage;
|
||||
|
||||
// Field: verilog6502_io_regs.core_ctrl.reset
|
||||
always_comb begin
|
||||
automatic logic [0:0] next_c;
|
||||
automatic logic load_next_c;
|
||||
next_c = field_storage.core_ctrl.reset.value;
|
||||
load_next_c = '0;
|
||||
if(decoded_reg_strb.core_ctrl && decoded_req_is_wr) begin // SW write
|
||||
next_c = (field_storage.core_ctrl.reset.value & ~decoded_wr_biten[0:0]) | (decoded_wr_data[0:0] & decoded_wr_biten[0:0]);
|
||||
load_next_c = '1;
|
||||
end
|
||||
field_combo.core_ctrl.reset.next = next_c;
|
||||
field_combo.core_ctrl.reset.load_next = load_next_c;
|
||||
end
|
||||
always_ff @(posedge clk) begin
|
||||
if(rst) begin
|
||||
field_storage.core_ctrl.reset.value <= 1'h1;
|
||||
end else begin
|
||||
if(field_combo.core_ctrl.reset.load_next) begin
|
||||
field_storage.core_ctrl.reset.value <= field_combo.core_ctrl.reset.next;
|
||||
end
|
||||
end
|
||||
end
|
||||
assign hwif_out.core_ctrl.reset.value = field_storage.core_ctrl.reset.value;
|
||||
// Field: verilog6502_io_regs.axi_base_address.val
|
||||
always_comb begin
|
||||
automatic logic [31:0] next_c;
|
||||
automatic logic load_next_c;
|
||||
next_c = field_storage.axi_base_address.val.value;
|
||||
load_next_c = '0;
|
||||
if(decoded_reg_strb.axi_base_address && decoded_req_is_wr) begin // SW write
|
||||
next_c = (field_storage.axi_base_address.val.value & ~decoded_wr_biten[31:0]) | (decoded_wr_data[31:0] & decoded_wr_biten[31:0]);
|
||||
load_next_c = '1;
|
||||
end
|
||||
field_combo.axi_base_address.val.next = next_c;
|
||||
field_combo.axi_base_address.val.load_next = load_next_c;
|
||||
end
|
||||
always_ff @(posedge clk) begin
|
||||
if(rst) begin
|
||||
field_storage.axi_base_address.val.value <= 32'h0;
|
||||
end else begin
|
||||
if(field_combo.axi_base_address.val.load_next) begin
|
||||
field_storage.axi_base_address.val.value <= field_combo.axi_base_address.val.next;
|
||||
end
|
||||
end
|
||||
end
|
||||
assign hwif_out.axi_base_address.val.value = field_storage.axi_base_address.val.value;
|
||||
// Field: verilog6502_io_regs.nmi.nmi
|
||||
always_comb begin
|
||||
automatic logic [15:0] next_c;
|
||||
automatic logic load_next_c;
|
||||
next_c = field_storage.nmi.nmi.value;
|
||||
load_next_c = '0;
|
||||
if(decoded_reg_strb.nmi && decoded_req_is_wr) begin // SW write
|
||||
next_c = (field_storage.nmi.nmi.value & ~decoded_wr_biten[31:16]) | (decoded_wr_data[31:16] & decoded_wr_biten[31:16]);
|
||||
load_next_c = '1;
|
||||
end
|
||||
field_combo.nmi.nmi.next = next_c;
|
||||
field_combo.nmi.nmi.load_next = load_next_c;
|
||||
end
|
||||
always_ff @(posedge clk) begin
|
||||
if(rst) begin
|
||||
field_storage.nmi.nmi.value <= 16'h200;
|
||||
end else begin
|
||||
if(field_combo.nmi.nmi.load_next) begin
|
||||
field_storage.nmi.nmi.value <= field_combo.nmi.nmi.next;
|
||||
end
|
||||
end
|
||||
end
|
||||
assign hwif_out.nmi.nmi.value = field_storage.nmi.nmi.value;
|
||||
// Field: verilog6502_io_regs.reset_brq.reset
|
||||
always_comb begin
|
||||
automatic logic [15:0] next_c;
|
||||
automatic logic load_next_c;
|
||||
next_c = field_storage.reset_brq.reset.value;
|
||||
load_next_c = '0;
|
||||
if(decoded_reg_strb.reset_brq && decoded_req_is_wr) begin // SW write
|
||||
next_c = (field_storage.reset_brq.reset.value & ~decoded_wr_biten[15:0]) | (decoded_wr_data[15:0] & decoded_wr_biten[15:0]);
|
||||
load_next_c = '1;
|
||||
end
|
||||
field_combo.reset_brq.reset.next = next_c;
|
||||
field_combo.reset_brq.reset.load_next = load_next_c;
|
||||
end
|
||||
always_ff @(posedge clk) begin
|
||||
if(rst) begin
|
||||
field_storage.reset_brq.reset.value <= 16'h200;
|
||||
end else begin
|
||||
if(field_combo.reset_brq.reset.load_next) begin
|
||||
field_storage.reset_brq.reset.value <= field_combo.reset_brq.reset.next;
|
||||
end
|
||||
end
|
||||
end
|
||||
assign hwif_out.reset_brq.reset.value = field_storage.reset_brq.reset.value;
|
||||
// Field: verilog6502_io_regs.reset_brq.brk
|
||||
always_comb begin
|
||||
automatic logic [15:0] next_c;
|
||||
automatic logic load_next_c;
|
||||
next_c = field_storage.reset_brq.brk.value;
|
||||
load_next_c = '0;
|
||||
if(decoded_reg_strb.reset_brq && decoded_req_is_wr) begin // SW write
|
||||
next_c = (field_storage.reset_brq.brk.value & ~decoded_wr_biten[31:16]) | (decoded_wr_data[31:16] & decoded_wr_biten[31:16]);
|
||||
load_next_c = '1;
|
||||
end
|
||||
field_combo.reset_brq.brk.next = next_c;
|
||||
field_combo.reset_brq.brk.load_next = load_next_c;
|
||||
end
|
||||
always_ff @(posedge clk) begin
|
||||
if(rst) begin
|
||||
field_storage.reset_brq.brk.value <= 16'h200;
|
||||
end else begin
|
||||
if(field_combo.reset_brq.brk.load_next) begin
|
||||
field_storage.reset_brq.brk.value <= field_combo.reset_brq.brk.next;
|
||||
end
|
||||
end
|
||||
end
|
||||
assign hwif_out.reset_brq.brk.value = field_storage.reset_brq.brk.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 [11:0] rd_mux_addr;
|
||||
assign rd_mux_addr = decoded_addr;
|
||||
|
||||
logic readback_err;
|
||||
logic readback_done;
|
||||
logic [31:0] readback_data;
|
||||
always_comb begin
|
||||
automatic logic [31:0] readback_data_var;
|
||||
readback_data_var = '0;
|
||||
if(rd_mux_addr == 12'h0) begin
|
||||
readback_data_var[0] = field_storage.core_ctrl.reset.value;
|
||||
end
|
||||
if(rd_mux_addr == 12'h10) begin
|
||||
readback_data_var[31:0] = field_storage.axi_base_address.val.value;
|
||||
end
|
||||
if(rd_mux_addr == 12'hff8) begin
|
||||
readback_data_var[31:16] = field_storage.nmi.nmi.value;
|
||||
end
|
||||
if(rd_mux_addr == 12'hffc) begin
|
||||
readback_data_var[15:0] = field_storage.reset_brq.reset.value;
|
||||
readback_data_var[31:16] = field_storage.reset_brq.brk.value;
|
||||
end
|
||||
readback_data = readback_data_var;
|
||||
readback_done = decoded_req & ~decoded_req_is_wr;
|
||||
readback_err = '0;
|
||||
end
|
||||
|
||||
assign cpuif_rd_ack = readback_done;
|
||||
assign cpuif_rd_data = readback_data;
|
||||
assign cpuif_rd_err = readback_err;
|
||||
endmodule
|
||||
53
src/regs/verilog6502_io_regs_pkg.sv
Normal file
53
src/regs/verilog6502_io_regs_pkg.sv
Normal file
@@ -0,0 +1,53 @@
|
||||
// Generated by PeakRDL-regblock - A free and open-source SystemVerilog generator
|
||||
// https://github.com/SystemRDL/PeakRDL-regblock
|
||||
|
||||
package verilog6502_io_regs_pkg;
|
||||
|
||||
localparam VERILOG6502_IO_REGS_DATA_WIDTH = 32;
|
||||
localparam VERILOG6502_IO_REGS_MIN_ADDR_WIDTH = 12;
|
||||
localparam VERILOG6502_IO_REGS_SIZE = 'h1000;
|
||||
|
||||
typedef struct {
|
||||
logic value;
|
||||
} verilog6502_io_regs__core_ctrl__reset__out_t;
|
||||
|
||||
typedef struct {
|
||||
verilog6502_io_regs__core_ctrl__reset__out_t reset;
|
||||
} verilog6502_io_regs__core_ctrl__out_t;
|
||||
|
||||
typedef struct {
|
||||
logic [31:0] value;
|
||||
} verilog6502_io_regs__axi_base_address__val__out_t;
|
||||
|
||||
typedef struct {
|
||||
verilog6502_io_regs__axi_base_address__val__out_t val;
|
||||
} verilog6502_io_regs__axi_base_address__out_t;
|
||||
|
||||
typedef struct {
|
||||
logic [15:0] value;
|
||||
} verilog6502_io_regs__nmi__nmi__out_t;
|
||||
|
||||
typedef struct {
|
||||
verilog6502_io_regs__nmi__nmi__out_t nmi;
|
||||
} verilog6502_io_regs__nmi__out_t;
|
||||
|
||||
typedef struct {
|
||||
logic [15:0] value;
|
||||
} verilog6502_io_regs__reset_brq__reset__out_t;
|
||||
|
||||
typedef struct {
|
||||
logic [15:0] value;
|
||||
} verilog6502_io_regs__reset_brq__brk__out_t;
|
||||
|
||||
typedef struct {
|
||||
verilog6502_io_regs__reset_brq__reset__out_t reset;
|
||||
verilog6502_io_regs__reset_brq__brk__out_t brk;
|
||||
} verilog6502_io_regs__reset_brq__out_t;
|
||||
|
||||
typedef struct {
|
||||
verilog6502_io_regs__core_ctrl__out_t core_ctrl;
|
||||
verilog6502_io_regs__axi_base_address__out_t axi_base_address;
|
||||
verilog6502_io_regs__nmi__out_t nmi;
|
||||
verilog6502_io_regs__reset_brq__out_t reset_brq;
|
||||
} verilog6502_io_regs__out_t;
|
||||
endpackage
|
||||
124
src/verilog6502_addr_decoder.sv
Normal file
124
src/verilog6502_addr_decoder.sv
Normal file
@@ -0,0 +1,124 @@
|
||||
module verilog6502_addr_decoder(
|
||||
input i_clk,
|
||||
input i_rst,
|
||||
|
||||
input logic [15:0] i_cpu_addr,
|
||||
input logic [7:0] i_cpu_data,
|
||||
output logic [7:0] o_cpu_data,
|
||||
input logic i_cpu_we,
|
||||
input logic i_cpu_rdy,
|
||||
output logic o_cpu_rdy,
|
||||
|
||||
|
||||
output logic [15:0] o_mem_addr,
|
||||
output logic [7:0] o_mem_data,
|
||||
input logic [7:0] i_mem_data,
|
||||
output logic o_mem_rd,
|
||||
output logic o_mem_we,
|
||||
input logic i_mem_rdy,
|
||||
|
||||
output logic [15:0] o_external_addr,
|
||||
output logic [7:0] o_external_data,
|
||||
input logic [7:0] i_external_data,
|
||||
output logic o_external_rd,
|
||||
output logic o_external_we,
|
||||
input logic i_external_rdy,
|
||||
|
||||
output logic [15:0] o_io_addr,
|
||||
output logic [7:0] o_io_data,
|
||||
input logic [7:0] i_io_data,
|
||||
output logic o_io_rd,
|
||||
output logic o_io_we,
|
||||
input logic i_io_rdy
|
||||
);
|
||||
|
||||
enum logic [1:0] {NONE, MEM, EXT, IO} prev_addr, prev_addr_next;
|
||||
|
||||
always_ff @(posedge i_clk) begin
|
||||
if (i_rst) begin
|
||||
prev_addr <= NONE;
|
||||
end else begin
|
||||
prev_addr <= prev_addr_next;
|
||||
end
|
||||
end
|
||||
|
||||
always_comb begin
|
||||
prev_addr_next = prev_addr;
|
||||
|
||||
o_mem_addr = '0;
|
||||
o_mem_data = '0;
|
||||
o_mem_rd = '0;
|
||||
o_mem_we = '0;
|
||||
|
||||
o_external_addr = '0;
|
||||
o_external_data = '0;
|
||||
o_external_rd = '0;
|
||||
o_external_we = '0;
|
||||
|
||||
o_io_addr = '0;
|
||||
o_io_data = '0;
|
||||
o_io_rd = '0;
|
||||
o_io_we = '0;
|
||||
|
||||
case (prev_addr)
|
||||
NONE: begin
|
||||
o_cpu_rdy = '1;
|
||||
o_cpu_data = '0;
|
||||
end
|
||||
|
||||
MEM: begin
|
||||
o_cpu_rdy = i_mem_rdy;
|
||||
o_cpu_data = i_mem_data;
|
||||
end
|
||||
|
||||
EXT: begin
|
||||
o_cpu_rdy = i_external_rdy;
|
||||
o_cpu_data = i_external_data;
|
||||
end
|
||||
|
||||
IO: begin
|
||||
o_cpu_rdy = i_io_rdy;
|
||||
o_cpu_data = i_io_data;
|
||||
end
|
||||
|
||||
default: begin
|
||||
o_cpu_rdy = '1;
|
||||
o_cpu_data = '0;
|
||||
end
|
||||
endcase
|
||||
|
||||
if (o_cpu_rdy) begin
|
||||
if (i_cpu_addr < 16'hE000) begin
|
||||
o_mem_addr = i_cpu_addr;
|
||||
o_mem_data = i_cpu_data;
|
||||
o_mem_we = i_cpu_we & o_cpu_rdy;
|
||||
o_mem_rd = ~i_cpu_we & o_cpu_rdy;
|
||||
prev_addr_next = MEM;
|
||||
end else if (i_cpu_addr < 16'hF000) begin
|
||||
o_external_addr = {4'b0, i_cpu_addr[11:0]};
|
||||
o_external_data = i_cpu_data;
|
||||
o_external_we = i_cpu_we & o_cpu_rdy;
|
||||
o_external_rd = ~i_cpu_we & o_cpu_rdy;
|
||||
prev_addr_next = EXT;
|
||||
end else begin
|
||||
o_io_addr = {4'b0, i_cpu_addr[11:0]};
|
||||
o_io_data = i_cpu_data;
|
||||
o_io_we = i_cpu_we & o_cpu_rdy;
|
||||
o_io_rd = ~i_cpu_we & o_cpu_rdy;
|
||||
prev_addr_next = IO;
|
||||
end
|
||||
end
|
||||
|
||||
if (i_rst | ~i_cpu_rdy) begin
|
||||
prev_addr_next = NONE;
|
||||
o_mem_rd = 0;
|
||||
o_mem_we = 0;
|
||||
o_external_rd = 0;
|
||||
o_external_we = 0;
|
||||
o_io_rd = 0;
|
||||
o_io_we = 0;
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
endmodule
|
||||
116
src/verilog6502_apb_adapter.sv
Normal file
116
src/verilog6502_apb_adapter.sv
Normal file
@@ -0,0 +1,116 @@
|
||||
module verilog6502_apb_adapter(
|
||||
input i_clk,
|
||||
input i_rst,
|
||||
|
||||
input logic [15:0] i_addr,
|
||||
input logic [7:0] i_data,
|
||||
output logic [7:0] o_data,
|
||||
input logic i_rd,
|
||||
input logic i_we,
|
||||
output logic o_rdy,
|
||||
|
||||
taxi_apb_if.mst m_apb
|
||||
);
|
||||
|
||||
enum logic {IDLE, ENABLE} state, state_next;
|
||||
|
||||
logic [15:0] latched_addr, latched_addr_next;
|
||||
logic [15:0] second_addr, second_addr_next;
|
||||
logic second_we, second_rd, second_we_next, second_rd_next;
|
||||
logic [7:0] latched_data, latched_data_next;
|
||||
logic [7:0] second_data, second_data_next;
|
||||
logic latched_pwrite, latched_pwrite_next;
|
||||
|
||||
always_ff @(posedge i_clk) begin
|
||||
if (i_rst) begin
|
||||
state <= IDLE;
|
||||
latched_addr <= '0;
|
||||
second_addr <= '0;
|
||||
second_we <= '0;
|
||||
second_rd <= '0;
|
||||
latched_data <= '0;
|
||||
latched_pwrite <= '0;
|
||||
second_data <= '0;
|
||||
end else begin
|
||||
state <= state_next;
|
||||
latched_addr <= latched_addr_next;
|
||||
second_addr <= second_addr_next;
|
||||
second_we <= second_we_next;
|
||||
second_rd <= second_rd_next;
|
||||
latched_data <= latched_data_next;
|
||||
latched_pwrite <= latched_pwrite_next;
|
||||
second_data <= second_data_next;
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
always_comb begin
|
||||
|
||||
|
||||
case (state)
|
||||
IDLE: begin
|
||||
if (i_rd | i_we) begin
|
||||
m_apb.pprot = '0;
|
||||
m_apb.paddr = {16'b0, i_addr} & 32'hfffc; // 32 bit address
|
||||
m_apb.psel = '1;
|
||||
m_apb.pwrite = i_we;
|
||||
m_apb.pstrb = 4'h1 << i_addr[1:0]; // shift based on lower 2 bits
|
||||
m_apb.pwdata = {24'b0, i_data} << i_addr[1:0];
|
||||
o_rdy = '0;
|
||||
|
||||
m_apb.penable = '0;
|
||||
state_next = ENABLE;
|
||||
latched_addr_next = i_addr;
|
||||
latched_data_next = i_data;
|
||||
latched_pwrite_next = i_we;
|
||||
end else if (second_rd | second_we) begin
|
||||
m_apb.pprot = '0;
|
||||
m_apb.paddr = {16'b0, second_addr} & 32'hfffc; // 32 bit address
|
||||
m_apb.psel = '1;
|
||||
m_apb.pwrite = second_we;
|
||||
m_apb.pstrb = 4'h1 << second_addr[1:0]; // shift based on lower 2 bits
|
||||
m_apb.pwdata = {24'b0, second_data} << second_addr[1:0];
|
||||
o_rdy = '0;
|
||||
|
||||
m_apb.penable = '0;
|
||||
state_next = ENABLE;
|
||||
latched_addr_next = second_addr;
|
||||
latched_data_next = second_data;
|
||||
latched_pwrite_next = second_we;
|
||||
end else begin
|
||||
m_apb.pprot = '0;
|
||||
m_apb.paddr = '0;
|
||||
m_apb.psel = '0;
|
||||
m_apb.pwrite = '0;
|
||||
m_apb.pstrb = '0;
|
||||
m_apb.pwdata = '0;
|
||||
o_rdy = '0;
|
||||
end
|
||||
end
|
||||
|
||||
ENABLE: begin
|
||||
m_apb.penable = '1;
|
||||
|
||||
second_we_next = i_we;
|
||||
second_rd_next = i_rd;
|
||||
second_addr_next = i_addr;
|
||||
second_data_next = i_data;
|
||||
|
||||
m_apb.pprot = '0;
|
||||
m_apb.paddr = {16'b0, latched_addr} & 32'hfffc; // 32 bit address
|
||||
m_apb.psel = '1;
|
||||
m_apb.pwrite = latched_pwrite;
|
||||
m_apb.pstrb = 4'h1 << latched_addr[1:0]; // shift based on lower 2 bits
|
||||
m_apb.pwdata = {24'b0, latched_data} << latched_addr[1:0];
|
||||
|
||||
if (m_apb.pready) begin
|
||||
state_next = IDLE;
|
||||
o_data = m_apb.prdata[8 * latched_addr[1:0] +: 8];
|
||||
o_rdy = '1;
|
||||
end
|
||||
end
|
||||
|
||||
endcase
|
||||
end
|
||||
|
||||
endmodule
|
||||
61
src/verilog6502_external_memory.sv
Normal file
61
src/verilog6502_external_memory.sv
Normal file
@@ -0,0 +1,61 @@
|
||||
module verilog6502_external_memory (
|
||||
input i_clk,
|
||||
input i_rst,
|
||||
|
||||
input logic [15:0] i_addr,
|
||||
input logic [7:0] i_data,
|
||||
output logic [7:0] o_data,
|
||||
input logic i_rd,
|
||||
input logic i_we,
|
||||
output logic o_rdy,
|
||||
|
||||
input logic [31:0] i_axi_base_addr,
|
||||
|
||||
|
||||
taxi_axil_if.wr_mst m_axil_wr,
|
||||
taxi_axil_if.rd_mst m_axil_rd
|
||||
);
|
||||
|
||||
taxi_apb_if internal_apb();
|
||||
taxi_apb_if addr_shift_apb();
|
||||
|
||||
verilog6502_apb_adapter u_internal_apb_adapter (
|
||||
.i_clk (i_clk),
|
||||
.i_rst (i_rst),
|
||||
|
||||
.i_addr (i_addr),
|
||||
.i_data (i_data),
|
||||
.o_data (o_data),
|
||||
.i_rd (i_rd),
|
||||
.i_we (i_we),
|
||||
.o_rdy (o_rdy),
|
||||
|
||||
.m_apb (internal_apb)
|
||||
);
|
||||
|
||||
assign addr_shift_apb.paddr = {i_axi_base_addr[31:12], {internal_apb.paddr[11:0]}};
|
||||
assign addr_shift_apb.pprot = internal_apb.pprot;
|
||||
assign addr_shift_apb.psel = internal_apb.psel;
|
||||
assign addr_shift_apb.penable = internal_apb.penable;
|
||||
assign addr_shift_apb.pwrite = internal_apb.pwrite;
|
||||
assign addr_shift_apb.pwdata = internal_apb.pwdata;
|
||||
assign addr_shift_apb.pstrb = internal_apb.pstrb;
|
||||
assign internal_apb.pready = addr_shift_apb.pready;
|
||||
assign internal_apb.prdata = addr_shift_apb.prdata;
|
||||
assign internal_apb.pslverr = addr_shift_apb.pslverr;
|
||||
assign addr_shift_apb.pauser = '0;
|
||||
assign addr_shift_apb.pwuser = '0;
|
||||
assign internal_apb.pruser = '0;
|
||||
assign internal_apb.pbuser = '0;
|
||||
|
||||
taxi_apb_axil_adapter u_apb_axil_adapter (
|
||||
.clk (i_clk),
|
||||
.rst (i_rst),
|
||||
|
||||
.s_apb (addr_shift_apb),
|
||||
|
||||
.m_axil_wr (m_axil_wr),
|
||||
.m_axil_rd (m_axil_rd)
|
||||
);
|
||||
|
||||
endmodule
|
||||
226
src/verilog6502_internal_memory.sv
Normal file
226
src/verilog6502_internal_memory.sv
Normal file
@@ -0,0 +1,226 @@
|
||||
module verilog6502_internal_memory(
|
||||
input i_clk,
|
||||
input i_rst,
|
||||
|
||||
taxi_axi_if.rd_slv s_axi_rd,
|
||||
taxi_axi_if.wr_slv s_axi_wr,
|
||||
|
||||
input logic [15:0] i_addr,
|
||||
input logic [7:0] i_data,
|
||||
output logic [7:0] o_data,
|
||||
input logic i_rd,
|
||||
input logic i_we,
|
||||
output logic o_rdy
|
||||
);
|
||||
|
||||
localparam ID_W = 8;
|
||||
localparam ADDR_W = 32;
|
||||
localparam AUSER_W = 1;
|
||||
localparam RUSER_W = 1;
|
||||
localparam WUSER_W = 1;
|
||||
localparam DATA_W = 32;
|
||||
localparam STRB_W = 4;
|
||||
|
||||
logic [ID_W-1:0] ram_cmd_id;
|
||||
logic [ADDR_W-1:0] ram_cmd_addr;
|
||||
logic [DATA_W-1:0] ram_cmd_wr_data;
|
||||
logic [STRB_W-1:0] ram_cmd_wr_strb;
|
||||
logic ram_cmd_wr_en;
|
||||
logic ram_cmd_rd_en;
|
||||
logic ram_cmd_last;
|
||||
logic ram_cmd_ready;
|
||||
logic [DATA_W-1:0] ram_rd_resp_data;
|
||||
logic ram_rd_resp_last;
|
||||
logic ram_rd_resp_valid;
|
||||
logic ram_rd_resp_ready;
|
||||
|
||||
taxi_axi_ram_if_rdwr #(
|
||||
.DATA_W(DATA_W),
|
||||
.ADDR_W(ADDR_W),
|
||||
.STRB_W(STRB_W),
|
||||
.ID_W(ID_W),
|
||||
.AUSER_W(AUSER_W),
|
||||
.WUSER_W(WUSER_W),
|
||||
.RUSER_W(RUSER_W)
|
||||
) axi_ram_if_rdwr (
|
||||
.clk (i_clk),
|
||||
.rst (i_rst),
|
||||
|
||||
.s_axi_wr (s_axi_wr),
|
||||
.s_axi_rd (s_axi_rd),
|
||||
|
||||
.ram_cmd_id (ram_cmd_id),
|
||||
.ram_cmd_addr (ram_cmd_addr),
|
||||
.ram_cmd_lock (),
|
||||
.ram_cmd_cache (),
|
||||
.ram_cmd_prot (),
|
||||
.ram_cmd_qos (),
|
||||
.ram_cmd_region (),
|
||||
.ram_cmd_auser (),
|
||||
.ram_cmd_wr_data (ram_cmd_wr_data),
|
||||
.ram_cmd_wr_strb (ram_cmd_wr_strb),
|
||||
.ram_cmd_wr_user (),
|
||||
.ram_cmd_wr_en (ram_cmd_wr_en),
|
||||
.ram_cmd_rd_en (ram_cmd_rd_en),
|
||||
.ram_cmd_last (ram_cmd_last),
|
||||
.ram_cmd_ready (ram_cmd_ready),
|
||||
.ram_rd_resp_id (),
|
||||
.ram_rd_resp_data (ram_rd_resp_data),
|
||||
.ram_rd_resp_last (ram_rd_resp_last),
|
||||
.ram_rd_resp_user (),
|
||||
.ram_rd_resp_valid (ram_rd_resp_valid),
|
||||
.ram_rd_resp_ready (ram_rd_resp_ready)
|
||||
);
|
||||
|
||||
|
||||
logic [7:0] mem [4][14*1024];
|
||||
|
||||
|
||||
enum logic {CPU, EXT} sel, sel_next;
|
||||
|
||||
logic o_rdy_next;
|
||||
|
||||
logic [15:0] ram_addr;
|
||||
logic [31:0] ram_wdata;
|
||||
logic [3:0] ram_wstrb;
|
||||
logic ram_we;
|
||||
|
||||
logic ram_re;
|
||||
logic [31:0] ram_rdata;
|
||||
logic ram_rdata_valid;
|
||||
|
||||
logic [1:0] latched_byte_select;
|
||||
|
||||
logic [15:0] pending_addr;
|
||||
logic [7:0] pending_data;
|
||||
logic pending_rd;
|
||||
logic pending_we;
|
||||
|
||||
|
||||
always_ff @(posedge i_clk) begin
|
||||
if (i_rst) begin
|
||||
sel <= CPU;
|
||||
o_rdy <= '0;
|
||||
end else begin
|
||||
sel <= sel_next;
|
||||
o_rdy <= o_rdy_next;
|
||||
|
||||
ram_rdata_valid <= '0;
|
||||
ram_rd_resp_last <= '0;
|
||||
|
||||
if (ram_we) begin
|
||||
for (int i = 0; i < 4; i++) begin
|
||||
if (ram_wstrb[i]) begin
|
||||
mem[i][ram_addr[15:2]] <= ram_wdata[8*i +: 8];
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
if (ram_re) begin
|
||||
for (int i = 0; i < 4; i++) begin
|
||||
ram_rdata[8*i +: 8] <= mem[i][ram_addr[15:2]];
|
||||
end
|
||||
ram_rdata_valid <= '1;
|
||||
ram_rd_resp_last <= ram_cmd_last;
|
||||
|
||||
latched_byte_select <= ram_addr[1:0];
|
||||
end
|
||||
|
||||
if (sel == EXT) begin
|
||||
if (i_we) begin
|
||||
pending_we <= '1;
|
||||
pending_addr <= i_addr;
|
||||
pending_data <= i_data;
|
||||
end
|
||||
|
||||
if (i_rd) begin
|
||||
pending_rd <= '1;
|
||||
pending_addr <= i_addr;
|
||||
end
|
||||
end else begin
|
||||
pending_we <= '0;
|
||||
pending_rd <= '0;
|
||||
pending_addr <= '0;
|
||||
pending_data <= '0;
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
always_comb begin
|
||||
sel_next = sel;
|
||||
|
||||
ram_cmd_ready = '0;
|
||||
|
||||
ram_addr = '0;
|
||||
ram_we = '0;
|
||||
ram_wdata = '0;
|
||||
ram_we = '0;
|
||||
ram_re = '0;
|
||||
|
||||
ram_rd_resp_valid = '0;
|
||||
ram_rd_resp_data = '0;
|
||||
|
||||
o_rdy_next = '0;
|
||||
o_data = '0;
|
||||
|
||||
case (sel)
|
||||
CPU: begin
|
||||
// if there was no CPU op, then give external bus a chance
|
||||
if (~(i_rd | i_we | pending_rd | pending_we)) begin
|
||||
sel_next = EXT;
|
||||
end
|
||||
|
||||
if (i_we) begin
|
||||
ram_addr = i_addr;
|
||||
ram_wstrb = 4'b1 << i_addr[1:0];
|
||||
ram_wdata = {24'b0, i_data} << (i_addr[1:0] * 8);
|
||||
ram_we = '1;
|
||||
o_rdy_next = '1;
|
||||
end
|
||||
if (pending_we) begin
|
||||
ram_addr = pending_addr;
|
||||
ram_wstrb = 4'b1 << pending_addr[1:0];
|
||||
ram_wdata = {24'b0, pending_data} << (pending_addr[1:0] * 8);
|
||||
ram_we = '1;
|
||||
o_rdy_next = '1;
|
||||
end
|
||||
|
||||
if (i_rd) begin
|
||||
ram_addr = i_addr;
|
||||
ram_re = '1;
|
||||
o_rdy_next = '1;
|
||||
end
|
||||
if (pending_rd) begin
|
||||
ram_addr = pending_addr;
|
||||
ram_re = '1;
|
||||
o_rdy_next = '1;
|
||||
end
|
||||
|
||||
o_data = ram_rdata[8*latched_byte_select +: 8];
|
||||
|
||||
end
|
||||
|
||||
EXT: begin
|
||||
ram_cmd_ready = '1;
|
||||
|
||||
if (ram_cmd_wr_en) begin
|
||||
ram_addr = ram_cmd_addr[15:0];
|
||||
ram_wdata = ram_cmd_wr_data;
|
||||
ram_wstrb = ram_cmd_wr_strb;
|
||||
ram_we = '1;
|
||||
end else if (ram_cmd_rd_en) begin
|
||||
ram_addr = ram_cmd_addr[15:0];
|
||||
ram_re = '1;
|
||||
|
||||
end else begin
|
||||
sel_next = CPU;
|
||||
end
|
||||
|
||||
ram_rd_resp_valid = ram_rdata_valid;
|
||||
ram_rd_resp_data = ram_rdata;
|
||||
end
|
||||
endcase
|
||||
end
|
||||
|
||||
|
||||
endmodule
|
||||
205
src/verilog6502_wrapper.sv
Normal file
205
src/verilog6502_wrapper.sv
Normal file
@@ -0,0 +1,205 @@
|
||||
// Wrapper around verilog-6502
|
||||
|
||||
// memory map:
|
||||
// 0x0000-0x00FF Zero Page (Hard coded)
|
||||
// 0x0100-0x01FF Stack (Hard coded)
|
||||
// 0x0200-0xCFFF Internal Memory
|
||||
// 0xE000-0xEFFF External AXI
|
||||
// 0xF000-0xFFFF Processor IO
|
||||
|
||||
module verilog6502_wrapper(
|
||||
input clk,
|
||||
input rst,
|
||||
|
||||
taxi_apb_if.slv s_apb,
|
||||
|
||||
taxi_axil_if.wr_mst m_axil_wr,
|
||||
taxi_axil_if.rd_mst m_axil_rd,
|
||||
taxi_axi_if.rd_slv s_axi_rd,
|
||||
taxi_axi_if.wr_slv s_axi_wr,
|
||||
|
||||
output logic o_irq_ext,
|
||||
input logic i_irq_ext,
|
||||
input logic i_nmi_ext
|
||||
);
|
||||
|
||||
taxi_apb_if internal_apb();
|
||||
|
||||
taxi_apb_if s_apb_mux[2]();
|
||||
taxi_apb_if m_apb_mux[1]();
|
||||
taxi_apb_if m_apb();
|
||||
|
||||
taxi_apb_tie u_external_apb_tie(
|
||||
.s_apb(s_apb),
|
||||
.m_apb(s_apb_mux[0])
|
||||
);
|
||||
|
||||
taxi_apb_tie u_internal_apb_tie(
|
||||
.s_apb(internal_apb),
|
||||
.m_apb(s_apb_mux[1])
|
||||
);
|
||||
|
||||
taxi_apb_tie u_master_apb_tie(
|
||||
.s_apb(m_apb_mux[0]),
|
||||
.m_apb(m_apb)
|
||||
);
|
||||
|
||||
taxi_apb_interconnect #(
|
||||
.S_CNT(2),
|
||||
.M_CNT(1),
|
||||
.ADDR_W(32)
|
||||
) u_apb_interconnect (
|
||||
.clk (clk),
|
||||
.rst (rst),
|
||||
|
||||
.s_apb (s_apb_mux),
|
||||
.m_apb (m_apb_mux)
|
||||
);
|
||||
|
||||
|
||||
logic cpu_clk;
|
||||
logic cpu_reset;
|
||||
logic [15:0] cpu_addr;
|
||||
logic [7:0] cpu_data_in;
|
||||
logic [7:0] cpu_data_out;
|
||||
|
||||
logic cpu_we;
|
||||
logic cpu_irq;
|
||||
logic cpu_nmi;
|
||||
logic cpu_rdy;
|
||||
logic cpu_rdy_o;
|
||||
logic cpu_sync;
|
||||
|
||||
assign cpu_clk = clk;
|
||||
assign cpu_reset = hwif_out.core_ctrl.reset.value;
|
||||
|
||||
assign cpu_irq = i_irq_ext;
|
||||
assign cpu_nmi = i_nmi_ext;
|
||||
|
||||
logic [15:0] mem_addr;
|
||||
logic [7:0] mem_data_in;
|
||||
logic [7:0] mem_data_out;
|
||||
logic mem_rd;
|
||||
logic mem_we;
|
||||
logic mem_rdy;
|
||||
|
||||
logic [15:0] ext_addr;
|
||||
logic [7:0] ext_data_in;
|
||||
logic [7:0] ext_data_out;
|
||||
logic ext_rd;
|
||||
logic ext_we;
|
||||
logic ext_rdy;
|
||||
|
||||
logic [15:0] io_addr;
|
||||
logic [7:0] io_data_in;
|
||||
logic [7:0] io_data_out;
|
||||
logic io_rd;
|
||||
logic io_we;
|
||||
logic io_rdy;
|
||||
|
||||
verilog6502_io_regs_pkg::verilog6502_io_regs__out_t hwif_out;
|
||||
|
||||
cpu_65c02 u_cpu_6502(
|
||||
.clk (cpu_clk),
|
||||
.reset (cpu_reset),
|
||||
|
||||
.AB (cpu_addr),
|
||||
.DI (cpu_data_in),
|
||||
.DO (cpu_data_out),
|
||||
.WE (cpu_we),
|
||||
.IRQ (cpu_irq),
|
||||
.NMI (cpu_nmi),
|
||||
.RDY (cpu_rdy),
|
||||
.RDY_O (cpu_rdy_o),
|
||||
.SYNC (cpu_sync)
|
||||
);
|
||||
|
||||
verilog6502_addr_decoder u_addr_decoder(
|
||||
.i_clk (cpu_clk),
|
||||
.i_rst (cpu_reset),
|
||||
|
||||
.i_cpu_addr (cpu_addr),
|
||||
.i_cpu_data (cpu_data_out),
|
||||
.o_cpu_data (cpu_data_in),
|
||||
.i_cpu_we (cpu_we),
|
||||
.i_cpu_rdy (cpu_rdy_o),
|
||||
.o_cpu_rdy (cpu_rdy),
|
||||
|
||||
.o_mem_addr (mem_addr),
|
||||
.o_mem_data (mem_data_in),
|
||||
.i_mem_data (mem_data_out),
|
||||
.o_mem_rd (mem_rd),
|
||||
.o_mem_we (mem_we),
|
||||
.i_mem_rdy (mem_rdy),
|
||||
|
||||
.o_external_addr (ext_addr),
|
||||
.o_external_data (ext_data_in),
|
||||
.i_external_data (ext_data_out),
|
||||
.o_external_rd (ext_rd),
|
||||
.o_external_we (ext_we),
|
||||
.i_external_rdy (ext_rdy),
|
||||
|
||||
.o_io_addr (io_addr),
|
||||
.o_io_data (io_data_in),
|
||||
.i_io_data (io_data_out),
|
||||
.o_io_rd (io_rd),
|
||||
.o_io_we (io_we),
|
||||
.i_io_rdy (io_rdy)
|
||||
);
|
||||
|
||||
verilog6502_internal_memory u_internal_memory(
|
||||
.i_clk (cpu_clk),
|
||||
.i_rst (rst),
|
||||
|
||||
.s_axi_rd (s_axi_rd),
|
||||
.s_axi_wr (s_axi_wr),
|
||||
|
||||
.i_addr (mem_addr),
|
||||
.i_data (mem_data_in),
|
||||
.o_data (mem_data_out),
|
||||
.i_rd (mem_rd),
|
||||
.i_we (mem_we),
|
||||
.o_rdy (mem_rdy)
|
||||
);
|
||||
|
||||
verilog6502_external_memory u_external_memory (
|
||||
.i_clk (clk),
|
||||
.i_rst (rst),
|
||||
|
||||
.i_addr (ext_addr),
|
||||
.i_data (ext_data_in),
|
||||
.o_data (ext_data_out),
|
||||
.i_rd (ext_rd),
|
||||
.i_we (ext_we),
|
||||
.o_rdy (ext_rdy),
|
||||
|
||||
.i_axi_base_addr (hwif_out.axi_base_address.val.value),
|
||||
|
||||
.m_axil_rd (m_axil_rd),
|
||||
.m_axil_wr (m_axil_wr)
|
||||
);
|
||||
|
||||
verilog6502_apb_adapter u_io_apb_adapter(
|
||||
.i_clk (cpu_clk),
|
||||
.i_rst (rst),
|
||||
|
||||
.i_addr (io_addr),
|
||||
.i_data (io_data_in),
|
||||
.o_data (io_data_out),
|
||||
.i_rd (io_rd),
|
||||
.i_we (io_we),
|
||||
.o_rdy (io_rdy),
|
||||
|
||||
.m_apb (internal_apb)
|
||||
);
|
||||
|
||||
|
||||
verilog6502_io_regs u_io_regs (
|
||||
.clk (cpu_clk),
|
||||
.rst (rst),
|
||||
.s_apb (m_apb),
|
||||
|
||||
.hwif_out (hwif_out)
|
||||
);
|
||||
|
||||
endmodule
|
||||
Reference in New Issue
Block a user