Update CV32E40P to be based on the OpenHW Group's repo
This commit is contained in:
parent
2613ae606a
commit
41564cc47b
|
@ -19,7 +19,7 @@ from litex.soc.cores.cpu import CPU, CPU_GCC_TRIPLE_RISCV32
|
|||
|
||||
# Variants -----------------------------------------------------------------------------------------
|
||||
|
||||
CPU_VARIANTS = ["standard", "full"]
|
||||
CPU_VARIANTS = ["standard", "standard+fpu"]
|
||||
|
||||
# GCC Flags ----------------------------------------------------------------------------------------
|
||||
|
||||
|
@ -32,7 +32,7 @@ GCC_FLAGS = {
|
|||
# | ||||/-- Double-Precision Floating-Point
|
||||
# i macfd
|
||||
"standard": "-march=rv32i2p0_mc -mabi=ilp32 ",
|
||||
"full": "-march=rv32i2p0_mfc -mabi=ilp32 ",
|
||||
"standard+fpu": "-march=rv32i2p0_mfc -mabi=ilp32 ",
|
||||
}
|
||||
|
||||
# OBI / APB / Trace Layouts ------------------------------------------------------------------------
|
||||
|
@ -59,18 +59,6 @@ apb_layout = [
|
|||
("pslverr", 1),
|
||||
]
|
||||
|
||||
trace_layout = [
|
||||
("ivalid", 1),
|
||||
("iexception", 1),
|
||||
("interrupt", 1),
|
||||
("cause", 5),
|
||||
("tval", 32),
|
||||
("priv", 3),
|
||||
("iaddr", 32),
|
||||
("instr", 32),
|
||||
("compressed", 1),
|
||||
]
|
||||
|
||||
# Helpers ------------------------------------------------------------------------------------------
|
||||
|
||||
def add_manifest_sources(platform, manifest):
|
||||
|
@ -182,102 +170,6 @@ class Wishbone2APB(LiteXModule):
|
|||
wb.dat_r.eq(apb.prdata),
|
||||
]
|
||||
|
||||
# Trace Collector ----------------------------------------------------------------------------------
|
||||
|
||||
class TraceCollector(LiteXModule):
|
||||
def __init__(self, trace_depth=16384):
|
||||
self.bus = bus = wishbone.Interface(data_width=32, address_width=32, addressing="word")
|
||||
self.sink = sink = stream.Endpoint([("data", 32)])
|
||||
|
||||
clear = Signal()
|
||||
enable = Signal()
|
||||
pointer = Signal(32)
|
||||
|
||||
self._enable = CSRStorage()
|
||||
self._clear = CSRStorage()
|
||||
self._pointer = CSRStatus(32)
|
||||
|
||||
mem = Memory(32, trace_depth)
|
||||
rd_port = mem.get_port()
|
||||
wr_port = mem.get_port(write_capable=True)
|
||||
|
||||
self.specials += rd_port, wr_port, mem
|
||||
|
||||
self.sync += [
|
||||
# wishbone
|
||||
bus.ack.eq(0),
|
||||
If(bus.cyc & bus.stb & ~bus.ack, bus.ack.eq(1)),
|
||||
# trace core
|
||||
If(clear, pointer.eq(0)).Else(
|
||||
If(sink.ready & sink.valid, pointer.eq(pointer+1)),
|
||||
),
|
||||
]
|
||||
|
||||
self.comb += [
|
||||
# wishbone
|
||||
rd_port.adr.eq(bus.adr),
|
||||
bus.dat_r.eq(rd_port.dat_r),
|
||||
# trace core
|
||||
wr_port.adr.eq(pointer),
|
||||
wr_port.dat_w.eq(sink.data),
|
||||
wr_port.we.eq(sink.ready & sink.valid),
|
||||
sink.ready.eq(enable & (pointer < trace_depth)),
|
||||
# csrs
|
||||
enable.eq(self._enable.storage),
|
||||
clear.eq(self._clear.storage),
|
||||
self._pointer.status.eq(pointer),
|
||||
]
|
||||
|
||||
# Trace Debugger -----------------------------------------------------------------------------------
|
||||
|
||||
class TraceDebugger(LiteXModule):
|
||||
def __init__(self):
|
||||
self.bus = wishbone.Interface(data_width=32, address_width=32, addressing="word")
|
||||
self.source = source = stream.Endpoint([("data", 32)])
|
||||
self.trace_if = trace_if = Record(trace_layout)
|
||||
|
||||
apb = Record(apb_layout)
|
||||
|
||||
self.bus_conv = Wishbone2APB(self.bus, apb)
|
||||
|
||||
self.trace_params = dict(
|
||||
# Clk / Rst.
|
||||
i_clk_i = ClockSignal("sys"),
|
||||
i_rst_ni = ~ResetSignal("sys"),
|
||||
i_test_mode_i = 0,
|
||||
|
||||
# CPU Interface.
|
||||
i_ivalid_i = trace_if.ivalid,
|
||||
i_iexception_i = trace_if.iexception,
|
||||
i_interrupt_i = trace_if.interrupt,
|
||||
i_cause_i = trace_if.cause,
|
||||
i_tval_i = trace_if.tval,
|
||||
i_priv_i = trace_if.priv,
|
||||
i_iaddr_i = trace_if.iaddr,
|
||||
i_instr_i = trace_if.instr,
|
||||
i_compressed_i = trace_if.compressed,
|
||||
|
||||
# APB Interface.
|
||||
i_paddr_i = apb.paddr,
|
||||
i_pwdata_i = apb.pwdata,
|
||||
i_pwrite_i = apb.pwrite,
|
||||
i_psel_i = apb.psel,
|
||||
i_penable_i = apb.penable,
|
||||
o_prdata_o = apb.prdata,
|
||||
o_pready_o = apb.pready,
|
||||
o_pslverr_o = apb.pslverr,
|
||||
|
||||
# Data Output.
|
||||
o_packet_word_o = source.data,
|
||||
o_packet_word_valid_o = source.valid,
|
||||
i_grant_i = source.ready,
|
||||
)
|
||||
self.specials += Instance("trace_debugger", **self.trace_params)
|
||||
|
||||
@staticmethod
|
||||
def add_sources(platform):
|
||||
add_manifest_sources(platform, "cv32e40p_trace_manifest.flist")
|
||||
|
||||
# Debug Module -------------------------------------------------------------------------------------
|
||||
|
||||
class DebugModule(LiteXModule):
|
||||
|
@ -350,10 +242,6 @@ class DebugModule(LiteXModule):
|
|||
|
||||
self.specials += Instance("dm_wrap", **self.dm_params)
|
||||
|
||||
@staticmethod
|
||||
def add_sources(platform):
|
||||
add_manifest_sources(platform, "cv32e40p_dm_manifest.flist")
|
||||
|
||||
# CV32E40P -----------------------------------------------------------------------------------------
|
||||
|
||||
class CV32E40P(CPU):
|
||||
|
@ -368,8 +256,7 @@ class CV32E40P(CPU):
|
|||
linker_output_format = "elf32-littleriscv"
|
||||
nop = "nop"
|
||||
io_regions = {0x80000000: 0x80000000} # Origin, Length.
|
||||
|
||||
has_fpu = ["full"]
|
||||
has_fpu = ["standard+fpu"]
|
||||
|
||||
# GCC Flags.
|
||||
@property
|
||||
|
@ -379,14 +266,15 @@ class CV32E40P(CPU):
|
|||
return flags
|
||||
|
||||
def __init__(self, platform, variant="standard"):
|
||||
self.platform = platform
|
||||
self.variant = variant
|
||||
self.reset = Signal()
|
||||
self.ibus = wishbone.Interface(data_width=32, address_width=32, addressing="word")
|
||||
self.dbus = wishbone.Interface(data_width=32, address_width=32, addressing="word")
|
||||
self.periph_buses = [self.ibus, self.dbus]
|
||||
self.memory_buses = []
|
||||
self.interrupt = Signal(15)
|
||||
self.platform = platform
|
||||
self.variant = variant
|
||||
self.reset = Signal()
|
||||
self.ibus = wishbone.Interface(data_width=32, address_width=32, addressing="word")
|
||||
self.dbus = wishbone.Interface(data_width=32, address_width=32, addressing="word")
|
||||
self.periph_buses = [self.ibus, self.dbus]
|
||||
self.memory_buses = []
|
||||
self.interrupt = Signal(16)
|
||||
self.interrupt_padding = Signal(16)
|
||||
|
||||
ibus = Record(obi_layout)
|
||||
dbus = Record(obi_layout)
|
||||
|
@ -406,11 +294,12 @@ class CV32E40P(CPU):
|
|||
i_rst_ni = ~ResetSignal("sys"),
|
||||
|
||||
# Controls.
|
||||
i_clock_en_i = 1,
|
||||
i_test_en_i = 0,
|
||||
i_fregfile_disable_i = 0,
|
||||
i_core_id_i = 0,
|
||||
i_cluster_id_i = 0,
|
||||
i_pulp_clock_en_i = 1,
|
||||
i_scan_cg_en_i = 0,
|
||||
i_mtvec_addr_i = 0,
|
||||
i_dm_halt_addr_i = 0,
|
||||
i_hart_id_i = 0,
|
||||
i_dm_exception_addr_i = 0,
|
||||
|
||||
# IBus.
|
||||
o_instr_req_o = ibus.req,
|
||||
|
@ -429,56 +318,32 @@ class CV32E40P(CPU):
|
|||
o_data_wdata_o = dbus.wdata,
|
||||
i_data_rdata_i = dbus.rdata,
|
||||
|
||||
# APU.
|
||||
i_apu_master_gnt_i = 0,
|
||||
i_apu_master_valid_i = 0,
|
||||
|
||||
# IRQ.
|
||||
i_irq_sec_i = 0,
|
||||
i_irq_software_i = 0,
|
||||
i_irq_external_i = 0,
|
||||
i_irq_fast_i = self.interrupt,
|
||||
i_irq_nmi_i = 0,
|
||||
i_irq_fastx_i = 0,
|
||||
i_irq_i = Cat(self.interrupt_padding, self.interrupt),
|
||||
|
||||
# Debug.
|
||||
i_debug_req_i = 0,
|
||||
i_debug_req_i = 0,
|
||||
|
||||
# CPU Control.
|
||||
i_fetch_enable_i = 1,
|
||||
i_fetch_enable_i = 1,
|
||||
)
|
||||
|
||||
# Add Verilog sources.
|
||||
add_manifest_sources(platform, 'cv32e40p_manifest.flist')
|
||||
|
||||
# Specific FPU variant parameters/files.
|
||||
if variant in self.has_fpu:
|
||||
# Specific FPU variant parameters/files.
|
||||
self.cpu_params.update(p_FPU=1)
|
||||
add_manifest_sources(platform, 'cv32e40p_fpu_manifest.flist')
|
||||
else:
|
||||
add_manifest_sources(platform, 'cv32e40p_manifest.flist')
|
||||
|
||||
def add_debug_module(self, dm):
|
||||
self.cpu_params.update(i_debug_req_i=dm.debug_req)
|
||||
self.cpu_params.update(i_rst_ni=~(ResetSignal("sys") | dm.ndmreset))
|
||||
|
||||
def add_trace_core(self, trace):
|
||||
trace_if = trace.trace_if
|
||||
|
||||
self.cpu_params.update(
|
||||
o_ivalid_o = trace_if.ivalid,
|
||||
o_iexception_o = trace_if.iexception,
|
||||
o_interrupt_o = trace_if.interrupt,
|
||||
o_cause_o = trace_if.cause,
|
||||
o_tval_o = trace_if.tval,
|
||||
o_priv_o = trace_if.priv,
|
||||
o_iaddr_o = trace_if.iaddr,
|
||||
o_instr_o = trace_if.instr,
|
||||
o_compressed_o = trace_if.compressed,
|
||||
)
|
||||
|
||||
def set_reset_address(self, reset_address):
|
||||
self.reset_address = reset_address
|
||||
self.cpu_params.update(i_boot_addr_i=Signal(32, reset=reset_address))
|
||||
|
||||
def do_finalize(self):
|
||||
assert hasattr(self, "reset_address")
|
||||
self.specials += Instance("riscv_core", **self.cpu_params)
|
||||
self.specials += Instance("cv32e40p_core", **self.cpu_params)
|
||||
|
|
|
@ -46,7 +46,7 @@ vector_table:
|
|||
j trap_entry # 28 firq12
|
||||
j trap_entry # 29 firq13
|
||||
j trap_entry # 30 firq14
|
||||
j trap_entry # 31 unused
|
||||
j trap_entry # 31 firq15
|
||||
|
||||
.global trap_entry
|
||||
trap_entry:
|
||||
|
@ -116,10 +116,8 @@ bss_loop:
|
|||
add a0,a0,4
|
||||
j bss_loop
|
||||
bss_done:
|
||||
|
||||
li a0, 0x7FFF0880 //7FFF0880 enable timer + external interrupt + fast interrupt sources (until mstatus.MIE is set, they will never trigger an interrupt)
|
||||
li a0, 0xFFFF0880 //FFFF0880 enable timer + external interrupt + fast interrupt sources (until mstatus.MIE is set, they will never trigger an interrupt)
|
||||
csrw mie,a0
|
||||
|
||||
j main
|
||||
infinit_loop:
|
||||
j infinit_loop
|
||||
|
|
|
@ -1,11 +1,14 @@
|
|||
#ifndef CSR_DEFS__H
|
||||
#define CSR_DEFS__H
|
||||
|
||||
/*Reference : https://docs.openhwgroup.org/projects/cv32e40p-user-manual/en/latest/control_status_registers.html */
|
||||
|
||||
#define CSR_MSTATUS_MIE 0x8
|
||||
|
||||
#define CSR_IRQ_MASK 0xBC0
|
||||
#define CSR_IRQ_PENDING 0xFC0
|
||||
|
||||
#define CSR_IRQ_MASK 0x304
|
||||
#define CSR_IRQ_PENDING 0x344
|
||||
#define FIRQ_OFFSET 16
|
||||
#define CSR_DCACHE_INFO 0xCC0
|
||||
|
||||
|
||||
#endif /* CSR_DEFS__H */
|
||||
|
|
|
@ -20,17 +20,21 @@ static inline void irq_setie(unsigned int ie)
|
|||
|
||||
static inline unsigned int irq_getmask(void)
|
||||
{
|
||||
return 0; // FIXME
|
||||
unsigned int mask;
|
||||
asm volatile ("csrr %0, %1" : "=r"(mask) : "i"(CSR_IRQ_MASK));
|
||||
return (mask >> FIRQ_OFFSET);
|
||||
}
|
||||
|
||||
static inline void irq_setmask(unsigned int mask)
|
||||
{
|
||||
// FIXME
|
||||
asm volatile ("csrw %0, %1" :: "i"(CSR_IRQ_MASK), "r"(mask << FIRQ_OFFSET));
|
||||
}
|
||||
|
||||
static inline unsigned int irq_pending(void)
|
||||
{
|
||||
return 0;// FIXME
|
||||
unsigned int pending;
|
||||
asm volatile ("csrr %0, %1" : "=r"(pending) : "i"(CSR_IRQ_PENDING));
|
||||
return (pending >> FIRQ_OFFSET);
|
||||
}
|
||||
|
||||
#ifdef __cplusplus
|
||||
|
|
|
@ -7,17 +7,8 @@
|
|||
extern "C" {
|
||||
#endif
|
||||
|
||||
__attribute__((unused)) static void flush_cpu_icache(void)
|
||||
{
|
||||
// FIXME
|
||||
asm volatile("nop");
|
||||
}
|
||||
|
||||
__attribute__((unused)) static void flush_cpu_dcache(void)
|
||||
{
|
||||
// FIXME
|
||||
asm volatile("nop");
|
||||
}
|
||||
__attribute__((unused)) static void flush_cpu_icache(void){}; /* No instruction cache */
|
||||
__attribute__((unused)) static void flush_cpu_dcache(void){}; /* No instruction cache */
|
||||
|
||||
void flush_l2_cache(void);
|
||||
|
||||
|
|
Loading…
Reference in New Issue