Update CV32E40P to be based on the OpenHW Group's repo

This commit is contained in:
Nuntipat Narkthong 2024-05-13 16:03:23 -04:00
parent 2613ae606a
commit 41564cc47b
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 -----------------------------------------------------------------------------------------
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)

View File

@ -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

View File

@ -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 */

View File

@ -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

View File

@ -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);