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.

146 lines
5.2 KiB
Python

# A2O variants
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_32BE' : 'a2owb',
'WB_64LE' : 'a2owb',
'standard' : 'a2owb'
}
#wtf doesnt do anything, but you can somehow do it by using -Xassembler in gcc flags
GAS_FLAGS = {
'WB_32BE' : '-defsym BIOS_32=1',
'WB_64LE' : '-defsym BIOS_LE=1'
}
#wtf skip crc and ram memtest for now!
GCC_FLAGS = {
'WB_32BE' : '-mcpu=a2 -m32 -mbig-endian -fno-stack-protector -Xassembler -defsym -Xassembler BIOS_32=1 -DCONFIG_BIOS_NO_BOOT=1 -DCONFIG_BIOS_NO_CRC=1 -DCONFIG_MAIN_RAM_INIT=1',
'WB_64LE' : '-mcpu=a2 -m64 -mlittle-endian -mabi=elfv2 -fno-stack-protector -Xassembler -defsym -Xassembler BIOS_LE=1'
}
class A2O(CPU, AutoCSR):
name = 'a2o'
human_name = 'a2o'
variants = CPU_VARIANTS
# default 64LE
family = 'ppc64'
data_width = 64
endianness = 'little'
gcc_triple = ('powerpc64le-linux', 'powerpc64le-linux-gnu')
linker_output_format = 'elf64-powerpcle'
nop = 'nop'
io_regions = {0xF0000000: 0x10000000} # origin, length
@property
def mem_map(self):
return {}
# how do you make this be default but not overwrite any defines in soc.py?
return {
'rom': 0x00000000, # on-board
'sram': 0x00004000, # on-board
'main_ram': 0x00100000, # external 1M+
'csr': 0xF0000000,
}
@property
def gcc_flags(self):
flags = GCC_FLAGS[self.variant]
flags += ' -D__a2o__'
return flags
def __init__(self, platform, variant='WB'):
if variant == 'standard':
variant = 'WB_64LE'
if variant == 'WB_32BE':
self.family = 'ppc' # kills meson build unless update meson.build file
#self.family = 'powerpc'
self.data_width = 32
self.endianness = 'big'
self.gcc_triple = 'powerpc-linux-gnu'
self.linker_output_format = 'elf32-powerpc'
self.platform = platform
self.variant = variant
self.human_name = 'a2o_' + variant # CPU_VARIANTS.get(variant, 'a2o')
self.external_variant = None
self.reset = Signal()
self.interrupt = Signal(3)
self.interruptS = Signal()
self.dbus = dbus = wishbone.Interface()
self.periph_buses = [dbus]
self.memory_buses = []
self.enableDebug = False
self.enableJTAG = False
self.reset_address = 0x00000000
self.cpu_params = dict(
i_clk = ClockSignal('sys'),
#i_clk_2x = ClockSignal('sys2x'),
i_rst = ResetSignal() | self.reset,
# how do i connect these to csr?
#i_cfg_wr = csr_0[0], # wr command - will be 3+ bit cmd
#i_cfg_dat = csr_1, # wr data
#o_status = status, # should update csr continuously
i_cfg_wr = 0,
i_externalInterrupt = self.interrupt[0],
i_timerInterrupt = self.interrupt[1],
i_softwareInterrupt = self.interrupt[2],
i_externalInterruptS = self.interruptS,
#wtf i guess you get these names from the Inteface() def - but what about other sigs?
o_wb_cyc = dbus.cyc,
o_wb_stb = dbus.stb,
#wtf litex is declaring wire [29:0] a2o_dbus_adr and connecting directly here but a2owb;wb_adr is [0:31]
# o_wb_adr = Cat(dbus.adr,Signal(2)),
o_wb_adr = Cat(Signal(2),dbus.adr), # wb adr [31:2] = a2o adr[0:29]
o_wb_we = dbus.we,
o_wb_sel = dbus.sel,
o_wb_datw = dbus.dat_w,
i_wb_ack = dbus.ack,
i_wb_datr = dbus.dat_r
)
def set_reset_address(self, reset_address):
if reset_address != self.reset_address:
print(f'Reset address = {self.reset_address} and cannot be changed here!')
assert False
@staticmethod
def add_sources(platform, variant='WB_64LE'):
dir = os.path.dirname(os.path.realpath(__file__))
# unfortunately, vivado doesn't do the right thing and skip modules already analyzed, so overrides dirs don't work; rearrange override after
platform.add_source(os.path.join(dir, 'verilog/a2o_litex/')) # node, wrapper
platform.add_source(os.path.join(dir, 'verilog/trilib/')) # array, ff
platform.add_source(os.path.join(dir, 'verilog/trilib_clk1x/')) # 2r4w override
#platform.add_source(os.path.join(dir, 'verilog/unisims/')) # xil array
platform.add_source(os.path.join(dir, 'verilog/work/')) # core
def use_external_variant(self, variant_filename):
self.external_variant = True
self.platform.add_source(variant_filename)
def do_finalize(self):
if not self.external_variant:
self.add_sources(self.platform, self.variant)
self.specials += Instance('a2owb', **self.cpu_params)