An experimental small core based on VexRiscv, written in Scala
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

145 lines
5.0 KiB

11 months ago
import os
from migen import *
from litex import get_data_mod
from litex.soc.interconnect import wishbone
from litex.soc.interconnect.csr import *
from litex.soc.cores.cpu import CPU
dir = os.path.dirname(os.path.realpath(__file__))
# these select the top RTL file for each variant name
CPU_VARIANTS = {
'AXI': 'A2P_AXI',
'WB': 'A2P_WB',
'standard': 'A2P_WB' #wtf litex does this as default
}
GCC_FLAGS = {
'WB' : '-fomit-frame-pointer -Wall -fno-builtin -nostdinc -fno-stack-protector -fexceptions -Wstrict-prototypes -Wold-style-definition -Wmissing-prototypes'
}
class A2P(CPU, AutoCSR):
name = "a2p"
human_name = "a2p"
variants = CPU_VARIANTS
data_width = 32
endianness = "big"
gcc_triple = "powerpc-linux-gnu"
linker_output_format = "elf32-powerpc"
nop = "nop"
io_regions = {0x80000000: 0x80000000} # origin, length
@property
def mem_map(self):
return {
"rom": 0x00000000,
"sram": 0x00004000,
"main_ram": 0x40000000,
"csr": 0xf0000000,
}
@property
def gcc_flags(self):
flags = GCC_FLAGS[self.variant]
flags += " -D__a2p__"
return flags
def __init__(self, platform, variant='WB'):
if variant == 'standard':
variant = 'WB'
self.platform = platform
self.variant = variant
self.human_name = CPU_VARIANTS.get(variant, "A2P")
self.external_variant = None
self.reset = Signal()
self.interrupt = Signal(32)
self.interruptS = Signal()
self.ibus = ibus = wishbone.Interface()
self.dbus = dbus = wishbone.Interface()
self.periph_buses = [ibus, dbus]
self.memory_buses = []
self.enableDebug = False
self.enableJTAG = False
self.externalResetVector = 0
# # #
self.cpu_params = dict(
i_clk = ClockSignal(),
i_reset = ResetSignal() | self.reset,
i_externalInterrupt = self.interrupt[0],
i_externalInterruptS = self.interruptS,
i_timerInterrupt = 0,
i_softwareInterrupt = 0,
o_iBusWB_ADR = ibus.adr,
o_iBusWB_DAT_MOSI = ibus.dat_w,
o_iBusWB_SEL = ibus.sel,
o_iBusWB_CYC = ibus.cyc,
o_iBusWB_STB = ibus.stb,
o_iBusWB_WE = ibus.we,
o_iBusWB_CTI = ibus.cti,
o_iBusWB_BTE = ibus.bte,
i_iBusWB_DAT_MISO = ibus.dat_r,
i_iBusWB_ACK = ibus.ack,
i_iBusWB_ERR = ibus.err,
o_dBusWB_ADR = dbus.adr,
o_dBusWB_DAT_MOSI = dbus.dat_w,
o_dBusWB_SEL = dbus.sel,
o_dBusWB_CYC = dbus.cyc,
o_dBusWB_STB = dbus.stb,
o_dBusWB_WE = dbus.we,
o_dBusWB_CTI = dbus.cti,
o_dBusWB_BTE = dbus.bte,
i_dBusWB_DAT_MISO = dbus.dat_r,
i_dBusWB_ACK = dbus.ack,
i_dBusWB_ERR = dbus.err
)
self.cpu_params['i_externalResetVector'] = self.externalResetVector
# these need to connect to top nets
if self.enableDebug:
self.cpu_params['i_debugReset'] = 0
self.cpu_params['o_debug_resetOut'] = 0
self.cpu_params['i_debug_bus_cmd_valid'] = 0
self.cpu_params['i_debug_bus_cmd_ready'] = 0
self.cpu_params['i_debug_bus_cmd_payload_wr'] = 0
self.cpu_params['i_debug_bus_cmd_payload_address'] = 0
self.cpu_params['i_debug_bus_cmd_payload_data'] = 0
self.cpu_params['o_debug_bus_rsp_data'] = 0
if self.enableJTAG:
self.cpu_params['i_jtag_tms'] = 0
self.cpu_params['i_jtag_tck'] = 0
self.cpu_params['i_jtag_tdi'] = 0
self.cpu_params['o_jtag_tdo'] = 0
def set_reset_address(self, reset_address):
assert not hasattr(self, "reset_address")
self.reset_address = reset_address
self.cpu_params.update(i_externalResetVector=Signal(32, reset=reset_address))
@staticmethod
def add_sources(platform, variant="WB"):
cpu_filename = CPU_VARIANTS[variant] + ".v"
vdir = os.path.join(dir, 'verilog')
platform.add_source(os.path.join(vdir, cpu_filename))
def use_external_variant(self, variant_filename):
self.external_variant = True
self.platform.add_source(variant_filename)
def do_finalize(self):
assert hasattr(self, "reset_address")
if not self.external_variant:
self.add_sources(self.platform, self.variant)
self.specials += Instance("A2P_WB", **self.cpu_params)