Created
April 23, 2020 15:42
-
-
Save enjoy-digital/641a52b6cbe5f29b989f587ec24e558e to your computer and use it in GitHub Desktop.
SweRV initial support
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
rom e9163d85ba2b0a1be46e9cef9c71f4a72710dc13 Mon Sep 17 00:00:00 2001 | |
From: Florent Kermarrec <florent@enjoy-digital.fr> | |
Date: Thu, 17 Oct 2019 10:08:54 +0200 | |
Subject: [PATCH] add initial SwerRV support | |
--- | |
.gitmodules | 3 + | |
litex/build/sim/core/Makefile | 3 +- | |
litex/soc/cores/cpu/__init__.py | 2 + | |
litex/soc/cores/cpu/swerv/__init__.py | 1 + | |
litex/soc/cores/cpu/swerv/core.py | 341 ++++++++++++++++++++ | |
litex/soc/integration/soc_core.py | 3 + | |
litex/soc/interconnect/axi.py | 1 + | |
litex/soc/software/bios/boot-helper-swerv.S | 4 + | |
litex/soc/software/bios/isr.c | 4 + | |
litex/soc/software/bios/sdram.c | 2 + | |
litex/soc/software/include/base/irq.h | 10 + | |
litex/soc/software/libbase/crt0-swerv.S | 63 ++++ | |
litex/soc/software/libbase/system.c | 6 + | |
13 files changed, 442 insertions(+), 1 deletion(-) | |
create mode 100644 litex/soc/cores/cpu/swerv/__init__.py | |
create mode 100644 litex/soc/cores/cpu/swerv/core.py | |
create mode 100644 litex/soc/software/bios/boot-helper-swerv.S | |
create mode 100644 litex/soc/software/libbase/crt0-swerv.S | |
diff --git a/.gitmodules b/.gitmodules | |
index 17eaf734..8c19280c 100644 | |
--- a/.gitmodules | |
+++ b/.gitmodules | |
@@ -22,3 +22,6 @@ | |
[submodule "litex/soc/cores/cpu/rocket/verilog"] | |
path = litex/soc/cores/cpu/rocket/verilog | |
url = https://github.com/enjoy-digital/rocket-litex-verilog | |
+[submodule "litex/soc/cores/cpu/swerv/verilog"] | |
+ path = litex/soc/cores/cpu/swerv/verilog | |
+ url = https://github.com/chipsalliance/Cores-SweRV | |
\ No newline at end of file | |
diff --git a/litex/build/sim/core/Makefile b/litex/build/sim/core/Makefile | |
index e34e456e..d280234c 100644 | |
--- a/litex/build/sim/core/Makefile | |
+++ b/litex/build/sim/core/Makefile | |
@@ -26,10 +26,11 @@ $(OBJS_SIM): %.o: $(SRC_DIR)/%.c | |
.PHONY: sim | |
sim: mkdir $(OBJS_SIM) | |
- verilator -Wno-fatal -O3 $(CC_SRCS) --top-module dut --exe \ | |
+ verilator '-UASSERT_ON' -Wno-fatal -O3 -CFLAGS "-std=c++11" $(CC_SRCS) --top-module dut --exe \ | |
-DPRINTF_COND=0 \ | |
$(SRCS_SIM_CPP) $(OBJS_SIM) \ | |
--top-module dut \ | |
+ --sv \ | |
$(if $(THREADS), --threads $(THREADS),) \ | |
-CFLAGS "$(CFLAGS) -I$(SRC_DIR)" \ | |
-LDFLAGS "$(LDFLAGS)" \ | |
diff --git a/litex/soc/cores/cpu/__init__.py b/litex/soc/cores/cpu/__init__.py | |
index 6aeb6ba5..371ae472 100644 | |
--- a/litex/soc/cores/cpu/__init__.py | |
+++ b/litex/soc/cores/cpu/__init__.py | |
@@ -32,6 +32,7 @@ from litex.soc.cores.cpu.picorv32 import PicoRV32 | |
from litex.soc.cores.cpu.vexriscv import VexRiscv | |
from litex.soc.cores.cpu.minerva import Minerva | |
from litex.soc.cores.cpu.rocket import RocketRV64 | |
+from litex.soc.cores.cpu.swerv import SweRV | |
CPUS = { | |
"lm32" : LM32, | |
@@ -40,6 +41,7 @@ CPUS = { | |
"vexriscv" : VexRiscv, | |
"minerva" : Minerva, | |
"rocket" : RocketRV64, | |
+ "swerv" : SweRV, | |
} | |
# CPU Variants/Extensions Definition --------------------------------------------------------------- | |
diff --git a/litex/soc/cores/cpu/swerv/__init__.py b/litex/soc/cores/cpu/swerv/__init__.py | |
new file mode 100644 | |
index 00000000..8d6f2d72 | |
--- /dev/null | |
+++ b/litex/soc/cores/cpu/swerv/__init__.py | |
@@ -0,0 +1 @@ | |
+from litex.soc.cores.cpu.swerv.core import SweRV | |
diff --git a/litex/soc/cores/cpu/swerv/core.py b/litex/soc/cores/cpu/swerv/core.py | |
new file mode 100644 | |
index 00000000..a791d2c1 | |
--- /dev/null | |
+++ b/litex/soc/cores/cpu/swerv/core.py | |
@@ -0,0 +1,341 @@ | |
+# This file is Copyright (c) 2019 Florent Kermarrec <florent@enjoy-digital.fr> | |
+ | |
+# License: BSD | |
+ | |
+import os | |
+ | |
+from migen import * | |
+ | |
+from litex.soc.interconnect import axi | |
+from litex.soc.interconnect import wishbone | |
+from litex.soc.cores.cpu import CPU | |
+ | |
+CPU_VARIANTS = ["standard"] | |
+ | |
+ | |
+class SweRV(CPU): | |
+ name = "swerv" | |
+ data_width = 32 | |
+ endianness = "little" | |
+ gcc_triple = ("riscv64-unknown-elf", "riscv32-unknown-elf", "riscv-none-embed") | |
+ linker_output_format = "elf32-littleriscv" | |
+ io_regions = {0x80000000: 0x80000000} # origin, length | |
+ | |
+ @property | |
+ def gcc_flags(self): | |
+ flags = "-march=rv32im " | |
+ flags += "-mabi=ilp32 " | |
+ flags += "-D__swerv__ " | |
+ return flags | |
+ | |
+ def __init__(self, platform, variant="standard"): | |
+ assert variant is "standard", "Unsupported variant %s" % variant | |
+ self.platform = platform | |
+ self.variant = variant | |
+ | |
+ self.reset = Signal() | |
+ self.ibus = wishbone.Interface() | |
+ self.dbus = wishbone.Interface() | |
+ self.buses = [self.ibus, self.dbus] | |
+ | |
+ self.lsu_axi = lsu_axi = axi.AXIInterface(data_width=32, address_width=32, id_width=4) | |
+ self.ifu_axi = ifu_axi = axi.AXIInterface(data_width=32, address_width=32, id_width=4) | |
+ self.sb_axi = sb_axi = axi.AXIInterface(data_width=32, address_width=32, id_width=4) | |
+ self.dma_axi = dma_axi = axi.AXIInterface(data_width=32, address_width=32, id_width=4) | |
+ | |
+ | |
+ # # # | |
+ | |
+ self.cpu_params = dict( | |
+ # Clk / Rst ---------------------------------------------------------------------------- | |
+ i_clk = ClockSignal("sys"), | |
+ i_rst_l = ~(ResetSignal("sys") | self.reset), | |
+ | |
+ # NMI ---------------------------------------------------------------------------------- | |
+ i_nmi_int = 0, | |
+ i_nmi_vec = 0x8880000, | |
+ | |
+ # JTAG --------------------------------------------------------------------------------- | |
+ i_jtag_id = 0, | |
+ i_jtag_tck = 0, | |
+ i_jtag_tms = 0, | |
+ i_jtag_tdi = 0, | |
+ i_jtag_trst_n = 0, | |
+ #o_jtag_tdo = , | |
+ | |
+ # Clock Enable ------------------------------------------------------------------------- | |
+ i_lsu_bus_clk_en = 1, | |
+ i_ifu_bus_clk_en = 1, | |
+ i_dbg_bus_clk_en = 1, | |
+ i_dma_bus_clk_en = 1, | |
+ | |
+ # IRQ ---------------------------------------------------------------------------------- | |
+ i_timer_int = 0, | |
+ i_extintsrc_req = 0, | |
+ | |
+ # DEBUG -------------------------------------------------------------------------------- | |
+ i_mpc_debug_halt_req = 0, | |
+ i_mpc_debug_run_req = 0, | |
+ i_mpc_reset_run_req = 1, | |
+ #o_mpc_debug_halt_ack = , | |
+ #o_mpc_debug_run_ack = , | |
+ #o_debug_brkpt_status = , | |
+ #o_o_debug_mode_status = , | |
+ | |
+ i_i_cpu_halt_req = 0, | |
+ #o_o_cpu_halt_ack = , | |
+ #o_o_cpu_halt_status = , | |
+ i_i_cpu_run_req = 0, | |
+ #o_o_cpu_run_ack = , | |
+ | |
+ i_scan_mode = 0, | |
+ i_mbist_mode = 0, | |
+ | |
+ # LSU AXI ------------------------------------------------------------------------------ | |
+ o_lsu_axi_awvalid = lsu_axi.aw.valid, | |
+ i_lsu_axi_awready = lsu_axi.aw.ready, | |
+ o_lsu_axi_awid = lsu_axi.aw.id, | |
+ o_lsu_axi_awaddr = lsu_axi.aw.addr, | |
+ o_lsu_axi_awregion = lsu_axi.aw.region, | |
+ o_lsu_axi_awlen = lsu_axi.aw.len, | |
+ o_lsu_axi_awsize = lsu_axi.aw.size, | |
+ o_lsu_axi_awburst = lsu_axi.aw.burst, | |
+ o_lsu_axi_awlock = lsu_axi.aw.lock, | |
+ o_lsu_axi_awcache = lsu_axi.aw.cache, | |
+ o_lsu_axi_awprot = lsu_axi.aw.prot, | |
+ o_lsu_axi_awqos = lsu_axi.aw.qos, | |
+ | |
+ o_lsu_axi_wvalid = lsu_axi.w.valid, | |
+ i_lsu_axi_wready = lsu_axi.w.ready, | |
+ o_lsu_axi_wdata = lsu_axi.w.data, | |
+ o_lsu_axi_wstrb = lsu_axi.w.strb, | |
+ o_lsu_axi_wlast = lsu_axi.w.last, | |
+ | |
+ i_lsu_axi_bvalid = lsu_axi.b.valid, | |
+ o_lsu_axi_bready = lsu_axi.b.ready, | |
+ i_lsu_axi_bresp = lsu_axi.b.resp, | |
+ i_lsu_axi_bid = lsu_axi.b.id, | |
+ | |
+ o_lsu_axi_arvalid = lsu_axi.ar.valid, | |
+ i_lsu_axi_arready = lsu_axi.ar.ready, | |
+ o_lsu_axi_arid = lsu_axi.ar.id, | |
+ o_lsu_axi_araddr = lsu_axi.ar.addr, | |
+ o_lsu_axi_arregion = lsu_axi.ar.region, | |
+ o_lsu_axi_arlen = lsu_axi.ar.len, | |
+ o_lsu_axi_arsize = lsu_axi.ar.size, | |
+ o_lsu_axi_arburst = lsu_axi.ar.burst, | |
+ o_lsu_axi_arlock = lsu_axi.ar.lock, | |
+ o_lsu_axi_arcache = lsu_axi.ar.cache, | |
+ o_lsu_axi_arprot = lsu_axi.ar.prot, | |
+ o_lsu_axi_arqos = lsu_axi.ar.qos, | |
+ | |
+ i_lsu_axi_rvalid = lsu_axi.r.valid, | |
+ o_lsu_axi_rready = lsu_axi.r.ready, | |
+ i_lsu_axi_rid = lsu_axi.r.id, | |
+ i_lsu_axi_rdata = lsu_axi.r.data, | |
+ i_lsu_axi_rresp = lsu_axi.r.resp, | |
+ i_lsu_axi_rlast = lsu_axi.r.last, | |
+ | |
+ # IFU AXI ------------------------------------------------------------------------------ | |
+ o_ifu_axi_awvalid = ifu_axi.aw.valid, | |
+ i_ifu_axi_awready = ifu_axi.aw.ready, | |
+ o_ifu_axi_awid = ifu_axi.aw.id, | |
+ o_ifu_axi_awaddr = ifu_axi.aw.addr, | |
+ o_ifu_axi_awregion = ifu_axi.aw.region, | |
+ o_ifu_axi_awlen = ifu_axi.aw.len, | |
+ o_ifu_axi_awsize = ifu_axi.aw.size, | |
+ o_ifu_axi_awburst = ifu_axi.aw.burst, | |
+ o_ifu_axi_awlock = ifu_axi.aw.lock, | |
+ o_ifu_axi_awcache = ifu_axi.aw.cache, | |
+ o_ifu_axi_awprot = ifu_axi.aw.prot, | |
+ o_ifu_axi_awqos = ifu_axi.aw.qos, | |
+ | |
+ o_ifu_axi_wvalid = ifu_axi.w.valid, | |
+ i_ifu_axi_wready = ifu_axi.w.ready, | |
+ o_ifu_axi_wdata = ifu_axi.w.data, | |
+ o_ifu_axi_wstrb = ifu_axi.w.strb, | |
+ o_ifu_axi_wlast = ifu_axi.w.last, | |
+ | |
+ i_ifu_axi_bvalid = ifu_axi.b.valid, | |
+ o_ifu_axi_bready = ifu_axi.b.ready, | |
+ i_ifu_axi_bresp = ifu_axi.b.resp, | |
+ i_ifu_axi_bid = ifu_axi.b.id, | |
+ | |
+ o_ifu_axi_arvalid = ifu_axi.ar.valid, | |
+ i_ifu_axi_arready = ifu_axi.ar.ready, | |
+ o_ifu_axi_arid = ifu_axi.ar.id, | |
+ o_ifu_axi_araddr = ifu_axi.ar.addr, | |
+ o_ifu_axi_arregion = ifu_axi.ar.region, | |
+ o_ifu_axi_arlen = ifu_axi.ar.len, | |
+ o_ifu_axi_arsize = ifu_axi.ar.size, | |
+ o_ifu_axi_arburst = ifu_axi.ar.burst, | |
+ o_ifu_axi_arlock = ifu_axi.ar.lock, | |
+ o_ifu_axi_arcache = ifu_axi.ar.cache, | |
+ o_ifu_axi_arprot = ifu_axi.ar.prot, | |
+ o_ifu_axi_arqos = ifu_axi.ar.qos, | |
+ | |
+ i_ifu_axi_rvalid = ifu_axi.r.valid, | |
+ o_ifu_axi_rready = ifu_axi.r.ready, | |
+ i_ifu_axi_rid = ifu_axi.r.id, | |
+ i_ifu_axi_rdata = ifu_axi.r.data, | |
+ i_ifu_axi_rresp = ifu_axi.r.resp, | |
+ i_ifu_axi_rlast = ifu_axi.r.last, | |
+ | |
+ # SB AXI ------------------------------------------------------------------------------- | |
+ o_sb_axi_awvalid = sb_axi.aw.valid, | |
+ i_sb_axi_awready = sb_axi.aw.ready, | |
+ o_sb_axi_awid = sb_axi.aw.id, | |
+ o_sb_axi_awaddr = sb_axi.aw.addr, | |
+ o_sb_axi_awregion = sb_axi.aw.region, | |
+ o_sb_axi_awlen = sb_axi.aw.len, | |
+ o_sb_axi_awsize = sb_axi.aw.size, | |
+ o_sb_axi_awburst = sb_axi.aw.burst, | |
+ o_sb_axi_awlock = sb_axi.aw.lock, | |
+ o_sb_axi_awcache = sb_axi.aw.cache, | |
+ o_sb_axi_awprot = sb_axi.aw.prot, | |
+ o_sb_axi_awqos = sb_axi.aw.qos, | |
+ | |
+ o_sb_axi_wvalid = sb_axi.w.valid, | |
+ i_sb_axi_wready = sb_axi.w.ready, | |
+ o_sb_axi_wdata = sb_axi.w.data, | |
+ o_sb_axi_wstrb = sb_axi.w.strb, | |
+ o_sb_axi_wlast = sb_axi.w.last, | |
+ | |
+ i_sb_axi_bvalid = sb_axi.b.valid, | |
+ o_sb_axi_bready = sb_axi.b.ready, | |
+ i_sb_axi_bresp = sb_axi.b.resp, | |
+ i_sb_axi_bid = sb_axi.b.id, | |
+ | |
+ o_sb_axi_arvalid = sb_axi.ar.valid, | |
+ i_sb_axi_arready = sb_axi.ar.ready, | |
+ o_sb_axi_arid = sb_axi.ar.id, | |
+ o_sb_axi_araddr = sb_axi.ar.addr, | |
+ o_sb_axi_arregion = sb_axi.ar.region, | |
+ o_sb_axi_arlen = sb_axi.ar.len, | |
+ o_sb_axi_arsize = sb_axi.ar.size, | |
+ o_sb_axi_arburst = sb_axi.ar.burst, | |
+ o_sb_axi_arlock = sb_axi.ar.lock, | |
+ o_sb_axi_arcache = sb_axi.ar.cache, | |
+ o_sb_axi_arprot = sb_axi.ar.prot, | |
+ o_sb_axi_arqos = sb_axi.ar.qos, | |
+ | |
+ i_sb_axi_rvalid = sb_axi.r.valid, | |
+ o_sb_axi_rready = sb_axi.r.ready, | |
+ i_sb_axi_rid = sb_axi.r.id, | |
+ i_sb_axi_rdata = sb_axi.r.data, | |
+ i_sb_axi_rresp = sb_axi.r.resp, | |
+ i_sb_axi_rlast = sb_axi.r.last, | |
+ | |
+ # DMA AXI ------------------------------------------------------------------------------ | |
+ i_dma_axi_awvalid = dma_axi.aw.valid, | |
+ o_dma_axi_awready = dma_axi.aw.ready, | |
+ i_dma_axi_awid = dma_axi.aw.id, | |
+ i_dma_axi_awaddr = dma_axi.aw.addr, | |
+ i_dma_axi_awsize = dma_axi.aw.size, | |
+ i_dma_axi_awprot = dma_axi.aw.prot, | |
+ i_dma_axi_awlen = dma_axi.aw.len, | |
+ i_dma_axi_awburst = dma_axi.aw.burst, | |
+ | |
+ i_dma_axi_wvalid = dma_axi.w.valid, | |
+ o_dma_axi_wready = dma_axi.w.ready, | |
+ i_dma_axi_wdata = dma_axi.w.data, | |
+ i_dma_axi_wstrb = dma_axi.w.strb, | |
+ i_dma_axi_wlast = dma_axi.w.last, | |
+ | |
+ o_dma_axi_bvalid = dma_axi.b.valid, | |
+ i_dma_axi_bready = dma_axi.b.ready, | |
+ o_dma_axi_bresp = dma_axi.b.resp, | |
+ o_dma_axi_bid = dma_axi.b.id, | |
+ | |
+ i_dma_axi_arvalid = dma_axi.ar.valid, | |
+ o_dma_axi_arready = dma_axi.ar.ready, | |
+ i_dma_axi_arid = dma_axi.ar.id, | |
+ i_dma_axi_araddr = dma_axi.ar.addr, | |
+ i_dma_axi_arsize = dma_axi.ar.size, | |
+ i_dma_axi_arprot = dma_axi.ar.prot, | |
+ i_dma_axi_arlen = dma_axi.ar.len, | |
+ i_dma_axi_arburst = dma_axi.ar.burst, | |
+ | |
+ o_dma_axi_rvalid = dma_axi.r.valid, | |
+ i_dma_axi_rready = dma_axi.r.ready, | |
+ o_dma_axi_rid = dma_axi.r.id, | |
+ o_dma_axi_rdata = dma_axi.r.data, | |
+ o_dma_axi_rresp = dma_axi.r.resp, | |
+ o_dma_axi_rlast = dma_axi.r.last, | |
+ ) | |
+ | |
+ # adapt axi interfaces to wishbone | |
+ lsu_a2w = ResetInserter()(axi.AXI2Wishbone(lsu_axi, self.ibus, base_address=0)) | |
+ ifu_a2w = ResetInserter()(axi.AXI2Wishbone(ifu_axi, self.dbus, base_address=0)) | |
+ self.comb += [ | |
+ lsu_a2w.reset.eq(ResetSignal() | self.reset), | |
+ ifu_a2w.reset.eq(ResetSignal() | self.reset), | |
+ ] | |
+ self.submodules += lsu_a2w, ifu_a2w | |
+ | |
+ # add verilog sources | |
+ self.add_sources(platform) | |
+ | |
+ def set_reset_address(self, reset_address): | |
+ assert not hasattr(self, "reset_address") | |
+ self.reset_address = reset_address | |
+ self.cpu_params.update(i_rst_vec=reset_address) | |
+ | |
+ @staticmethod | |
+ def add_sources(platform): | |
+ vdir = os.path.join(os.path.abspath(os.path.dirname(__file__)), "verilog") | |
+ platform.add_source(os.path.join(vdir, "configs", "snapshots", "default", "common_defines.vh")) | |
+ platform.add_source(os.path.join(vdir, "design/include", "build.h")) | |
+ platform.add_source(os.path.join(vdir, "design/include", "global.h")) | |
+ platform.add_source(os.path.join(vdir, "design/include", "swerv_types.sv")) | |
+ platform.add_source(os.path.join(vdir, "design/swerv_wrapper.sv")) | |
+ platform.add_source(os.path.join(vdir, "design/mem.sv")) | |
+ platform.add_source(os.path.join(vdir, "design/pic_ctrl.sv")) | |
+ platform.add_source(os.path.join(vdir, "design/swerv.sv")) | |
+ platform.add_source(os.path.join(vdir, "design/dma_ctrl.sv")) | |
+ platform.add_source(os.path.join(vdir, "design/ifu/ifu_aln_ctl.sv")) | |
+ platform.add_source(os.path.join(vdir, "design/ifu/ifu_compress_ctl.sv")) | |
+ platform.add_source(os.path.join(vdir, "design/ifu/ifu_ifc_ctl.sv")) | |
+ platform.add_source(os.path.join(vdir, "design/ifu/ifu_bp_ctl.sv")) | |
+ platform.add_source(os.path.join(vdir, "design/ifu/ifu_ic_mem.sv")) | |
+ platform.add_source(os.path.join(vdir, "design/ifu/ifu_mem_ctl.sv")) | |
+ platform.add_source(os.path.join(vdir, "design/ifu/ifu_iccm_mem.sv")) | |
+ platform.add_source(os.path.join(vdir, "design/ifu/ifu.sv")) | |
+ platform.add_source(os.path.join(vdir, "design/dec/dec_decode_ctl.sv")) | |
+ platform.add_source(os.path.join(vdir, "design/dec/dec_gpr_ctl.sv")) | |
+ platform.add_source(os.path.join(vdir, "design/dec/dec_ib_ctl.sv")) | |
+ platform.add_source(os.path.join(vdir, "design/dec/dec_tlu_ctl.sv")) | |
+ platform.add_source(os.path.join(vdir, "design/dec/dec_trigger.sv")) | |
+ platform.add_source(os.path.join(vdir, "design/dec/dec.sv")) | |
+ platform.add_source(os.path.join(vdir, "design/exu/exu_alu_ctl.sv")) | |
+ platform.add_source(os.path.join(vdir, "design/exu/exu_mul_ctl.sv")) | |
+ platform.add_source(os.path.join(vdir, "design/exu/exu_div_ctl.sv")) | |
+ platform.add_source(os.path.join(vdir, "design/exu/exu.sv")) | |
+ platform.add_source(os.path.join(vdir, "design/lsu/lsu.sv")) | |
+ platform.add_source(os.path.join(vdir, "design/lsu/lsu_clkdomain.sv")) | |
+ platform.add_source(os.path.join(vdir, "design/lsu/lsu_addrcheck.sv")) | |
+ platform.add_source(os.path.join(vdir, "design/lsu/lsu_lsc_ctl.sv")) | |
+ platform.add_source(os.path.join(vdir, "design/lsu/lsu_stbuf.sv")) | |
+ platform.add_source(os.path.join(vdir, "design/lsu/lsu_bus_buffer.sv")) | |
+ platform.add_source(os.path.join(vdir, "design/lsu/lsu_bus_intf.sv")) | |
+ platform.add_source(os.path.join(vdir, "design/lsu/lsu_ecc.sv")) | |
+ platform.add_source(os.path.join(vdir, "design/lsu/lsu_dccm_mem.sv")) | |
+ platform.add_source(os.path.join(vdir, "design/lsu/lsu_dccm_ctl.sv")) | |
+ platform.add_source(os.path.join(vdir, "design/lsu/lsu_trigger.sv")) | |
+ platform.add_source(os.path.join(vdir, "design/dbg/dbg.sv")) | |
+ platform.add_source(os.path.join(vdir, "design/dmi/dmi_wrapper.v")) | |
+ platform.add_source(os.path.join(vdir, "design/dmi/dmi_jtag_to_core_sync.v")) | |
+ platform.add_source(os.path.join(vdir, "design/dmi/rvjtag_tap.sv")) | |
+ platform.add_source(os.path.join(vdir, "design/lib/beh_lib.sv")) | |
+ platform.add_source(os.path.join(vdir, "design/lib/mem_lib.sv")) | |
+ platform.add_source(os.path.join(vdir, "design/lib/ahb_to_axi4.sv")) | |
+ platform.add_source(os.path.join(vdir, "design/lib/axi4_to_ahb.sv")) | |
+ platform.add_verilog_include_path(os.path.join(vdir, "design/include")) | |
+ platform.add_verilog_include_path(os.path.join(vdir, "design/lib")) | |
+ platform.add_verilog_include_path(os.path.join(vdir, "design/dmi")) | |
+ platform.add_verilog_include_path(os.path.join(vdir, "configs", "snapshots", "default")) | |
+ #platform.add_verilog_include_path(vdir) | |
+ | |
+ def do_finalize(self): | |
+ assert hasattr(self, "reset_address") | |
+ self.specials += Instance("swerv_wrapper", **self.cpu_params) | |
diff --git a/litex/soc/integration/soc_core.py b/litex/soc/integration/soc_core.py | |
index 7c8abecf..a4385213 100644 | |
--- a/litex/soc/integration/soc_core.py | |
+++ b/litex/soc/integration/soc_core.py | |
@@ -172,6 +172,9 @@ class SoCCore(Module): | |
# Add the CPU | |
self.add_cpu(cpu.CPUS[cpu_type](platform, self.cpu_variant)) | |
+ if cpu_type == "swerv": | |
+ self.add_constant("UART_POLLING") | |
+ | |
# Update Memory Map (if defined by CPU) | |
self.soc_mem_map.update(self.cpu.mem_map) | |
diff --git a/litex/soc/interconnect/axi.py b/litex/soc/interconnect/axi.py | |
index 5d362c7b..a45298f6 100644 | |
--- a/litex/soc/interconnect/axi.py | |
+++ b/litex/soc/interconnect/axi.py | |
@@ -25,6 +25,7 @@ def ax_description(address_width, id_width): | |
("burst", 2), # Burst type | |
("len", 8), # Number of data (-1) transfers (up to 256) | |
("size", 4), # Number of bytes (-1) of each data transfer (up to 1024 bits) | |
+ ("region", 4), # * | |
("lock", 2), # * | |
("prot", 3), # * | |
("cache", 4), # * | |
diff --git a/litex/soc/software/bios/boot-helper-swerv.S b/litex/soc/software/bios/boot-helper-swerv.S | |
new file mode 100644 | |
index 00000000..6dd74aae | |
--- /dev/null | |
+++ b/litex/soc/software/bios/boot-helper-swerv.S | |
@@ -0,0 +1,4 @@ | |
+.section .text, "ax", @progbits | |
+.global boot_helper | |
+boot_helper: | |
+ jr x13 | |
diff --git a/litex/soc/software/bios/isr.c b/litex/soc/software/bios/isr.c | |
index aa47cacc..4e8b4189 100644 | |
--- a/litex/soc/software/bios/isr.c | |
+++ b/litex/soc/software/bios/isr.c | |
@@ -30,9 +30,11 @@ void isr(void) | |
while ((claim = csr_readl(PLIC_CLAIM))) { | |
switch (claim - 1) { | |
+#ifndef UART_POLLING | |
case UART_INTERRUPT: | |
uart_isr(); | |
break; | |
+#endif | |
default: | |
printf("## PLIC: Unhandled claim: %d\n", claim); | |
printf("# plic_enabled: %08x\n", irq_getmask()); | |
@@ -56,7 +58,9 @@ void isr(void) | |
irqs = irq_pending() & irq_getmask(); | |
+#ifndef UART_POLLING | |
if(irqs & (1 << UART_INTERRUPT)) | |
uart_isr(); | |
+#endif | |
} | |
#endif | |
diff --git a/litex/soc/software/bios/sdram.c b/litex/soc/software/bios/sdram.c | |
index f0c12edf..774c11f5 100644 | |
--- a/litex/soc/software/bios/sdram.c | |
+++ b/litex/soc/software/bios/sdram.c | |
@@ -44,6 +44,8 @@ __attribute__((unused)) static void cdelay(int i) | |
__asm__ volatile("nop"); | |
#elif defined (__powerpc__) | |
__asm__ volatile("nop"); | |
+#elif defined (__swerv__) | |
+ __asm__ volatile("nop"); | |
#else | |
#error Unsupported architecture | |
#endif | |
diff --git a/litex/soc/software/include/base/irq.h b/litex/soc/software/include/base/irq.h | |
index 4bf6786c..3ee20f33 100644 | |
--- a/litex/soc/software/include/base/irq.h | |
+++ b/litex/soc/software/include/base/irq.h | |
@@ -56,6 +56,8 @@ static inline unsigned int irq_getie(void) | |
return (csrr(mstatus) & CSR_MSTATUS_MIE) != 0; | |
#elif defined (__rocket__) | |
return (csrr(mstatus) & CSR_MSTATUS_MIE) != 0; | |
+#elif defined (__swerv__) | |
+ return 0; /* FIXME */ | |
#else | |
#error Unsupported architecture | |
#endif | |
@@ -81,6 +83,8 @@ static inline void irq_setie(unsigned int ie) | |
if(ie) csrs(mstatus,CSR_MSTATUS_MIE); else csrc(mstatus,CSR_MSTATUS_MIE); | |
#elif defined (__rocket__) | |
if(ie) csrs(mstatus,CSR_MSTATUS_MIE); else csrc(mstatus,CSR_MSTATUS_MIE); | |
+#elif defined (__swerv__) | |
+ /* FIXME */ | |
#else | |
#error Unsupported architecture | |
#endif | |
@@ -108,6 +112,8 @@ static inline unsigned int irq_getmask(void) | |
return mask; | |
#elif defined (__rocket__) | |
return csr_readl(PLIC_ENABLED) >> 1; | |
+#elif defined (__swerv__) | |
+ return 0; /* FIXME */ | |
#else | |
#error Unsupported architecture | |
#endif | |
@@ -129,6 +135,8 @@ static inline void irq_setmask(unsigned int mask) | |
asm volatile ("csrw %0, %1" :: "i"(CSR_IRQ_MASK), "r"(mask)); | |
#elif defined (__rocket__) | |
csr_writel(mask << 1, PLIC_ENABLED); | |
+#elif defined (__swerv__) | |
+ /* FIXME */ | |
#else | |
#error Unsupported architecture | |
#endif | |
@@ -154,6 +162,8 @@ static inline unsigned int irq_pending(void) | |
return pending; | |
#elif defined (__rocket__) | |
return csr_readl(PLIC_PENDING) >> 1; | |
+#elif defined (__swerv__) | |
+ return 0;/* FIXME */ | |
#else | |
#error Unsupported architecture | |
#endif | |
diff --git a/litex/soc/software/libbase/crt0-swerv.S b/litex/soc/software/libbase/crt0-swerv.S | |
new file mode 100644 | |
index 00000000..6f6e9e6c | |
--- /dev/null | |
+++ b/litex/soc/software/libbase/crt0-swerv.S | |
@@ -0,0 +1,63 @@ | |
+#define MIE_MEIE 0x800 | |
+ | |
+ .global _start | |
+_start: | |
+ j reset_vector | |
+ | |
+reset_vector: | |
+ la sp, _fstack | |
+ la t0, trap_vector | |
+ csrw mtvec, t0 | |
+ | |
+ // initialize .bss | |
+ la t0, _fbss | |
+ la t1, _ebss | |
+1: beq t0, t1, 2f | |
+ sw zero, 0(t0) | |
+ addi t0, t0, 4 | |
+ j 1b | |
+2: | |
+ // enable external interrupts | |
+ li t0, MIE_MEIE | |
+ csrs mie, t0 | |
+ | |
+ call main | |
+1: j 1b | |
+ | |
+trap_vector: | |
+ addi sp, sp, -16*4 | |
+ sw ra, 0*4(sp) | |
+ sw t0, 1*4(sp) | |
+ sw t1, 2*4(sp) | |
+ sw t2, 3*4(sp) | |
+ sw a0, 4*4(sp) | |
+ sw a1, 5*4(sp) | |
+ sw a2, 6*4(sp) | |
+ sw a3, 7*4(sp) | |
+ sw a4, 8*4(sp) | |
+ sw a5, 9*4(sp) | |
+ sw a6, 10*4(sp) | |
+ sw a7, 11*4(sp) | |
+ sw t3, 12*4(sp) | |
+ sw t4, 13*4(sp) | |
+ sw t5, 14*4(sp) | |
+ sw t6, 15*4(sp) | |
+ call isr | |
+ lw ra, 0*4(sp) | |
+ lw t0, 1*4(sp) | |
+ lw t1, 2*4(sp) | |
+ lw t2, 3*4(sp) | |
+ lw a0, 4*4(sp) | |
+ lw a1, 5*4(sp) | |
+ lw a2, 6*4(sp) | |
+ lw a3, 7*4(sp) | |
+ lw a4, 8*4(sp) | |
+ lw a5, 9*4(sp) | |
+ lw a6, 10*4(sp) | |
+ lw a7, 11*4(sp) | |
+ lw t3, 12*4(sp) | |
+ lw t4, 13*4(sp) | |
+ lw t5, 14*4(sp) | |
+ lw t6, 15*4(sp) | |
+ addi sp, sp, 16*4 | |
+ mret | |
diff --git a/litex/soc/software/libbase/system.c b/litex/soc/software/libbase/system.c | |
index bb15aad0..d57b6b15 100644 | |
--- a/litex/soc/software/libbase/system.c | |
+++ b/litex/soc/software/libbase/system.c | |
@@ -56,6 +56,9 @@ void flush_cpu_icache(void) | |
#elif defined (__rocket__) | |
/* FIXME: do something useful here! */ | |
asm volatile("nop"); | |
+#elif defined (__swerv__) | |
+ /* FIXME: do something useful here! */ | |
+ asm volatile("nop"); | |
#else | |
#error Unsupported architecture | |
#endif | |
@@ -101,6 +104,9 @@ void flush_cpu_dcache(void) | |
#elif defined (__rocket__) | |
/* FIXME: do something useful here! */ | |
asm volatile("nop"); | |
+#elif defined (__swerv__) | |
+ /* no data cache */ | |
+ asm volatile("nop"); | |
#else | |
#error Unsupported architecture | |
#endif | |
-- | |
2.17.1 |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment