Merge pull request #1951 from nuntipat/update-cv32e40p

Update CV32E40P to be based on the OpenHW Group's repo
This commit is contained in:
enjoy-digital 2024-05-14 12:11:50 +02:00 committed by GitHub
commit c810b89464
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
5 changed files with 42 additions and 181 deletions

View File

@ -19,7 +19,7 @@ from litex.soc.cores.cpu import CPU, CPU_GCC_TRIPLE_RISCV32
# Variants ----------------------------------------------------------------------------------------- # Variants -----------------------------------------------------------------------------------------
CPU_VARIANTS = ["standard", "full"] CPU_VARIANTS = ["standard", "standard+fpu"]
# GCC Flags ---------------------------------------------------------------------------------------- # GCC Flags ----------------------------------------------------------------------------------------
@ -32,7 +32,7 @@ GCC_FLAGS = {
# | ||||/-- Double-Precision Floating-Point # | ||||/-- Double-Precision Floating-Point
# i macfd # i macfd
"standard": "-march=rv32i2p0_mc -mabi=ilp32 ", "standard": "-march=rv32i2p0_mc -mabi=ilp32 ",
"full": "-march=rv32i2p0_mfc -mabi=ilp32 ", "standard+fpu": "-march=rv32i2p0_mfc -mabi=ilp32 ",
} }
# OBI / APB / Trace Layouts ------------------------------------------------------------------------ # OBI / APB / Trace Layouts ------------------------------------------------------------------------
@ -59,18 +59,6 @@ apb_layout = [
("pslverr", 1), ("pslverr", 1),
] ]
trace_layout = [
("ivalid", 1),
("iexception", 1),
("interrupt", 1),
("cause", 5),
("tval", 32),
("priv", 3),
("iaddr", 32),
("instr", 32),
("compressed", 1),
]
# Helpers ------------------------------------------------------------------------------------------ # Helpers ------------------------------------------------------------------------------------------
def add_manifest_sources(platform, manifest): def add_manifest_sources(platform, manifest):
@ -182,102 +170,6 @@ class Wishbone2APB(LiteXModule):
wb.dat_r.eq(apb.prdata), 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 ------------------------------------------------------------------------------------- # Debug Module -------------------------------------------------------------------------------------
class DebugModule(LiteXModule): class DebugModule(LiteXModule):
@ -350,10 +242,6 @@ class DebugModule(LiteXModule):
self.specials += Instance("dm_wrap", **self.dm_params) self.specials += Instance("dm_wrap", **self.dm_params)
@staticmethod
def add_sources(platform):
add_manifest_sources(platform, "cv32e40p_dm_manifest.flist")
# CV32E40P ----------------------------------------------------------------------------------------- # CV32E40P -----------------------------------------------------------------------------------------
class CV32E40P(CPU): class CV32E40P(CPU):
@ -368,8 +256,7 @@ class CV32E40P(CPU):
linker_output_format = "elf32-littleriscv" linker_output_format = "elf32-littleriscv"
nop = "nop" nop = "nop"
io_regions = {0x80000000: 0x80000000} # Origin, Length. io_regions = {0x80000000: 0x80000000} # Origin, Length.
has_fpu = ["standard+fpu"]
has_fpu = ["full"]
# GCC Flags. # GCC Flags.
@property @property
@ -379,14 +266,15 @@ class CV32E40P(CPU):
return flags return flags
def __init__(self, platform, variant="standard"): def __init__(self, platform, variant="standard"):
self.platform = platform self.platform = platform
self.variant = variant self.variant = variant
self.reset = Signal() self.reset = Signal()
self.ibus = wishbone.Interface(data_width=32, address_width=32, addressing="word") 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.dbus = wishbone.Interface(data_width=32, address_width=32, addressing="word")
self.periph_buses = [self.ibus, self.dbus] self.periph_buses = [self.ibus, self.dbus]
self.memory_buses = [] self.memory_buses = []
self.interrupt = Signal(15) self.interrupt = Signal(16)
self.interrupt_padding = Signal(16)
ibus = Record(obi_layout) ibus = Record(obi_layout)
dbus = Record(obi_layout) dbus = Record(obi_layout)
@ -406,11 +294,12 @@ class CV32E40P(CPU):
i_rst_ni = ~ResetSignal("sys"), i_rst_ni = ~ResetSignal("sys"),
# Controls. # Controls.
i_clock_en_i = 1, i_pulp_clock_en_i = 1,
i_test_en_i = 0, i_scan_cg_en_i = 0,
i_fregfile_disable_i = 0, i_mtvec_addr_i = 0,
i_core_id_i = 0, i_dm_halt_addr_i = 0,
i_cluster_id_i = 0, i_hart_id_i = 0,
i_dm_exception_addr_i = 0,
# IBus. # IBus.
o_instr_req_o = ibus.req, o_instr_req_o = ibus.req,
@ -429,56 +318,32 @@ class CV32E40P(CPU):
o_data_wdata_o = dbus.wdata, o_data_wdata_o = dbus.wdata,
i_data_rdata_i = dbus.rdata, i_data_rdata_i = dbus.rdata,
# APU.
i_apu_master_gnt_i = 0,
i_apu_master_valid_i = 0,
# IRQ. # IRQ.
i_irq_sec_i = 0, i_irq_i = Cat(self.interrupt_padding, self.interrupt),
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,
# Debug. # Debug.
i_debug_req_i = 0, i_debug_req_i = 0,
# CPU Control. # CPU Control.
i_fetch_enable_i = 1, i_fetch_enable_i = 1,
) )
# Add Verilog sources. # Add Verilog sources.
add_manifest_sources(platform, 'cv32e40p_manifest.flist')
# Specific FPU variant parameters/files.
if variant in self.has_fpu: if variant in self.has_fpu:
# Specific FPU variant parameters/files.
self.cpu_params.update(p_FPU=1) self.cpu_params.update(p_FPU=1)
add_manifest_sources(platform, 'cv32e40p_fpu_manifest.flist') add_manifest_sources(platform, 'cv32e40p_fpu_manifest.flist')
else:
add_manifest_sources(platform, 'cv32e40p_manifest.flist')
def add_debug_module(self, dm): def add_debug_module(self, dm):
self.cpu_params.update(i_debug_req_i=dm.debug_req) self.cpu_params.update(i_debug_req_i=dm.debug_req)
self.cpu_params.update(i_rst_ni=~(ResetSignal("sys") | dm.ndmreset)) 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): def set_reset_address(self, reset_address):
self.reset_address = reset_address self.reset_address = reset_address
self.cpu_params.update(i_boot_addr_i=Signal(32, reset=reset_address)) self.cpu_params.update(i_boot_addr_i=Signal(32, reset=reset_address))
def do_finalize(self): def do_finalize(self):
assert hasattr(self, "reset_address") assert hasattr(self, "reset_address")
self.specials += Instance("riscv_core", **self.cpu_params) self.specials += Instance("cv32e40p_core", **self.cpu_params)

View File

@ -46,7 +46,7 @@ vector_table:
j trap_entry # 28 firq12 j trap_entry # 28 firq12
j trap_entry # 29 firq13 j trap_entry # 29 firq13
j trap_entry # 30 firq14 j trap_entry # 30 firq14
j trap_entry # 31 unused j trap_entry # 31 firq15
.global trap_entry .global trap_entry
trap_entry: trap_entry:
@ -116,10 +116,8 @@ bss_loop:
add a0,a0,4 add a0,a0,4
j bss_loop j bss_loop
bss_done: bss_done:
li a0, 0xFFFF0880 //FFFF0880 enable timer + external interrupt + fast interrupt sources (until mstatus.MIE is set, they will never trigger an interrupt)
li a0, 0x7FFF0880 //7FFF0880 enable timer + external interrupt + fast interrupt sources (until mstatus.MIE is set, they will never trigger an interrupt)
csrw mie,a0 csrw mie,a0
j main j main
infinit_loop: infinit_loop:
j infinit_loop j infinit_loop

View File

@ -1,11 +1,14 @@
#ifndef CSR_DEFS__H #ifndef CSR_DEFS__H
#define 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_MSTATUS_MIE 0x8
#define CSR_IRQ_MASK 0xBC0 #define CSR_IRQ_MASK 0x304
#define CSR_IRQ_PENDING 0xFC0 #define CSR_IRQ_PENDING 0x344
#define FIRQ_OFFSET 16
#define CSR_DCACHE_INFO 0xCC0 #define CSR_DCACHE_INFO 0xCC0
#endif /* CSR_DEFS__H */ #endif /* CSR_DEFS__H */

View File

@ -20,17 +20,21 @@ static inline void irq_setie(unsigned int ie)
static inline unsigned int irq_getmask(void) 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) 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) 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 #ifdef __cplusplus

View File

@ -7,17 +7,8 @@
extern "C" { extern "C" {
#endif #endif
__attribute__((unused)) static void flush_cpu_icache(void) __attribute__((unused)) static void flush_cpu_icache(void){}; /* No instruction cache */
{ __attribute__((unused)) static void flush_cpu_dcache(void){}; /* No instruction cache */
// FIXME
asm volatile("nop");
}
__attribute__((unused)) static void flush_cpu_dcache(void)
{
// FIXME
asm volatile("nop");
}
void flush_l2_cache(void); void flush_l2_cache(void);