# 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)