You cannot select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
151 lines
5.2 KiB
Python
151 lines
5.2 KiB
Python
#
|
|
|
|
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 = {
|
|
'WB': 'A2P',
|
|
'standard': 'A2P' #wtf litex does this as default
|
|
}
|
|
|
|
GCC_FLAGS = {
|
|
'WB' : '-m32 -mbig-endian -mno-multiple -msoft-float -fno-stack-protector -Xassembler -defsym -Xassembler BIOS_32=1'
|
|
}
|
|
|
|
class A2P(CPU, AutoCSR):
|
|
name = 'a2p'
|
|
human_name = 'a2p'
|
|
variants = CPU_VARIANTS
|
|
|
|
family = 'powerpc'
|
|
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__'
|
|
flags += ' -DCONFIG_BIOS_NO_BOOT=1 -DCONFIG_BIOS_NO_CRC=1 -DCONFIG_MAIN_RAM_INIT=1' #wtf skip crc and ram memtest for now!
|
|
return flags
|
|
|
|
def __init__(self, platform, variant='WB'):
|
|
|
|
if variant == 'standard':
|
|
variant = 'WB'
|
|
|
|
self.platform = platform
|
|
self.variant = variant
|
|
self.human_name = '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,
|
|
|
|
#wtf i guess you get these names from the Inteface() def - but what about other sigs?
|
|
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 = get_data_mod('cpu', 'a2p').data_location
|
|
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', **self.cpu_params)
|