litex/misoclib/gensoc/__init__.py

223 lines
8.3 KiB
Python
Raw Normal View History

2013-11-24 04:30:02 -05:00
from operator import itemgetter
from math import ceil
from migen.fhdl.std import *
from migen.bank import csrgen
from migen.bus import wishbone, csr, lasmibus, dfi
from migen.bus import wishbone2lasmi, wishbone2csr
from misoclib import lm32, mor1kx, uart, identifier, timer, memtest
from misoclib.sdram import lasmicon
from misoclib.sdram import dfii
from misoclib.sdram.minicon import Minicon
2013-11-24 04:30:02 -05:00
def mem_decoder(address, start=26, end=29):
return lambda a: a[start:end] == ((address >> (start+2)) & (2**(end-start))-1)
2013-11-24 04:30:02 -05:00
class GenSoC(Module):
csr_map = {
"crg": 0, # user
"uart": 1, # provided by default
2013-11-24 04:30:02 -05:00
"identifier": 2, # provided
"timer0": 3, # provided
"buttons": 4, # user
"leds": 5, # user
}
interrupt_map = {
"uart": 0,
"timer0": 1,
}
mem_map = {
"rom": 0x00000000, # (shadow @0x80000000)
"sram": 0x10000000, # (shadow @0x90000000)
"csr": 0x60000000, # (shadow @0xe0000000)
}
def __init__(self, platform, clk_freq, cpu_reset_address, sram_size=4096, l2_size=0, with_uart=True, cpu_type="lm32",
csr_data_width=8, csr_address_width=14):
2013-11-24 04:30:02 -05:00
self.clk_freq = clk_freq
self.cpu_reset_address = cpu_reset_address
2013-11-24 04:30:02 -05:00
self.sram_size = sram_size
self.l2_size = l2_size
self.cpu_type = cpu_type
self.csr_data_width = csr_data_width
self.csr_address_width = csr_address_width
self.cpu_memory_regions = []
self.cpu_csr_regions = [] # list of (name, origin, busword, csr_list/Memory)
self._rom_registered = False
2013-11-24 04:30:02 -05:00
# Wishbone
if cpu_type == "lm32":
self.submodules.cpu = lm32.LM32(platform, cpu_reset_address)
elif cpu_type == "or1k":
self.submodules.cpu = mor1kx.MOR1KX(platform, cpu_reset_address)
else:
raise ValueError("Unsupported CPU type: "+cpu_type)
2013-11-24 04:30:02 -05:00
self.submodules.sram = wishbone.SRAM(sram_size)
self.submodules.wishbone2csr = wishbone2csr.WB2CSR(bus_csr=csr.Interface(csr_data_width, csr_address_width))
2013-11-24 04:30:02 -05:00
# rom 0x00000000 (shadow @0x80000000) from register_rom
2013-11-24 04:30:02 -05:00
# SRAM/debug 0x10000000 (shadow @0x90000000) provided
# CSR bridge 0x60000000 (shadow @0xe0000000) provided
self._wb_masters = [self.cpu.ibus, self.cpu.dbus]
self._wb_slaves = [
(mem_decoder(self.mem_map["sram"]), self.sram.bus),
(mem_decoder(self.mem_map["csr"]), self.wishbone2csr.wishbone)
2013-11-24 04:30:02 -05:00
]
self.add_cpu_memory_region("sram", self.mem_map["sram"], sram_size)
2013-11-24 04:30:02 -05:00
# CSR
if with_uart:
self.submodules.uart = uart.UART(platform.request("serial"), clk_freq, baud=115200)
2015-02-26 13:01:22 -05:00
platform_id = 0x554E if not hasattr(platform, "identifier") else platform.identifier
self.submodules.identifier = identifier.Identifier(platform_id, int(clk_freq),
2013-11-24 04:30:02 -05:00
log2_int(l2_size) if l2_size else 0)
2013-11-24 07:37:32 -05:00
self.submodules.timer0 = timer.Timer()
def register_rom(self, rom_wb_if, bios_size=0xa000):
if self._rom_registered:
raise FinalizeError
self._rom_registered = True
self.add_wb_slave(mem_decoder(self.mem_map["rom"]), rom_wb_if)
2013-11-25 04:22:14 -05:00
self.add_cpu_memory_region("rom", self.cpu_reset_address, bios_size)
2013-11-24 04:30:02 -05:00
def add_wb_master(self, wbm):
if self.finalized:
raise FinalizeError
self._wb_masters.append(wbm)
def add_wb_slave(self, address_decoder, interface):
if self.finalized:
raise FinalizeError
self._wb_slaves.append((address_decoder, interface))
def check_cpu_memory_region(self, name, origin):
for n, o, l in self.cpu_memory_regions:
if n == name or o == origin:
raise ValueError("Memory region conflict between {} and {}".format(n, name))
def add_cpu_memory_region(self, name, origin, length):
self.check_cpu_memory_region(name, origin)
self.cpu_memory_regions.append((name, origin, length))
def check_cpu_csr_region(self, name, origin):
for n, o, l, obj in self.cpu_csr_regions:
if n == name or o == origin:
raise ValueError("CSR region conflict between {} and {}".format(n, name))
def add_cpu_csr_region(self, name, origin, busword, obj):
self.check_cpu_csr_region(name, origin)
self.cpu_csr_regions.append((name, origin, busword, obj))
2013-11-24 04:30:02 -05:00
def do_finalize(self):
if not self._rom_registered:
raise FinalizeError("Need to call GenSoC.register_rom()")
2013-11-24 04:30:02 -05:00
# Wishbone
self.submodules.wishbonecon = wishbone.InterconnectShared(self._wb_masters,
self._wb_slaves, register=True)
# CSR
self.submodules.csrbankarray = csrgen.BankArray(self,
lambda name, memory: self.csr_map[name if memory is None else name + "_" + memory.name_override],
data_width=self.csr_data_width, address_width=self.csr_address_width)
2013-11-24 04:30:02 -05:00
self.submodules.csrcon = csr.Interconnect(self.wishbone2csr.csr, self.csrbankarray.get_buses())
for name, csrs, mapaddr, rmap in self.csrbankarray.banks:
self.add_cpu_csr_region(name, self.mem_map["csr"]+0x80000000+0x800*mapaddr, flen(rmap.bus.dat_w), csrs)
for name, memory, mapaddr, mmap in self.csrbankarray.srams:
self.add_cpu_csr_region(name, self.mem_map["csr"]+0x80000000+0x800*mapaddr, flen(rmap.bus.dat_w), memory)
2013-11-24 04:30:02 -05:00
# Interrupts
for k, v in sorted(self.interrupt_map.items(), key=itemgetter(1)):
if hasattr(self, k):
self.comb += self.cpu.interrupt[v].eq(getattr(self, k).ev.irq)
def ns(self, t, margin=True):
clk_period_ns = 1000000000/self.clk_freq
if margin:
t += clk_period_ns/2
return ceil(t/clk_period_ns)
def do_exit(self, vns):
pass
2013-11-25 04:22:14 -05:00
class IntegratedBIOS:
def __init__(self, bios_size=0x8000):
2013-11-25 04:25:05 -05:00
self.submodules.rom = wishbone.SRAM(bios_size, read_only=True)
2013-11-25 04:22:14 -05:00
self.register_rom(self.rom.bus, bios_size)
def init_bios_memory(self, data):
self.rom.mem.init = data
2013-11-24 04:30:02 -05:00
class SDRAMSoC(GenSoC):
csr_map = {
"dfii": 6,
"lasmicon": 7,
2014-11-27 10:05:36 -05:00
"memtest_w": 8,
"memtest_r": 9
2013-11-24 04:30:02 -05:00
}
csr_map.update(GenSoC.csr_map)
mem_map = {
"sdram": 0x40000000, # (shadow @0xc0000000)
}
mem_map.update(GenSoC.mem_map)
2014-10-31 18:36:06 -04:00
def __init__(self, platform, clk_freq, cpu_reset_address, with_memtest=False, sram_size=4096, l2_size=8192, with_uart=True, ramcon_type="lasmicon", **kwargs):
GenSoC.__init__(self, platform, clk_freq, cpu_reset_address, sram_size, l2_size, with_uart, **kwargs)
2013-11-24 04:30:02 -05:00
self.with_memtest = with_memtest
2014-10-31 18:36:06 -04:00
self.ramcon_type = ramcon_type
self._sdram_phy_registered = False
2013-11-24 04:30:02 -05:00
def register_sdram_phy(self, phy_dfi, phy_settings, sdram_geom, sdram_timing):
if self._sdram_phy_registered:
2013-11-24 04:30:02 -05:00
raise FinalizeError
self._sdram_phy_registered = True
2013-11-24 04:30:02 -05:00
# DFI
self.submodules.dfii = dfii.DFIInjector(sdram_geom.mux_a, sdram_geom.bank_a,
phy_settings.dfi_d, phy_settings.nphases)
self.submodules.dficon0 = dfi.Interconnect(self.dfii.master, phy_dfi)
# LASMICON
2014-10-31 18:36:06 -04:00
if self.ramcon_type == "lasmicon":
self.submodules.lasmicon = lasmicon.LASMIcon(phy_settings, sdram_geom, sdram_timing)
self.submodules.dficon1 = dfi.Interconnect(self.lasmicon.dfi, self.dfii.slave)
self.submodules.lasmixbar = lasmibus.Crossbar([self.lasmicon.lasmic], self.lasmicon.nrowbits)
if self.with_memtest:
self.submodules.memtest_w = memtest.MemtestWriter(self.lasmixbar.get_master())
self.submodules.memtest_r = memtest.MemtestReader(self.lasmixbar.get_master())
# Wishbone bridge
2014-10-31 18:36:06 -04:00
self.submodules.wishbone2lasmi = wishbone2lasmi.WB2LASMI(self.l2_size//4, self.lasmixbar.get_master())
self.add_wb_slave(mem_decoder(self.mem_map["sdram"]), self.wishbone2lasmi.wishbone)
self.add_cpu_memory_region("sdram", self.mem_map["sdram"],
2014-10-31 18:36:06 -04:00
2**self.lasmicon.lasmic.aw*self.lasmicon.lasmic.dw*self.lasmicon.lasmic.nbanks//8)
# MINICON
2014-10-31 18:36:06 -04:00
elif self.ramcon_type == "minicon":
self.submodules.minicon = sdramcon = Minicon(phy_settings, sdram_geom, sdram_timing)
self.submodules.dficon1 = dfi.Interconnect(sdramcon.dfi, self.dfii.slave)
sdram_width = flen(sdramcon.bus.dat_r)
if (sdram_width == 32):
self.add_wb_slave(mem_decoder(self.mem_map["sdram"]), sdramcon.bus)
2014-10-31 18:36:06 -04:00
elif (sdram_width < 32):
self.submodules.dc = wishbone.DownConverter(32, sdram_width)
2015-02-26 22:19:39 -05:00
self.submodules.intercon = wishbone.InterconnectPointToPoint(self.dc.wishbone_o, sdramcon.bus)
self.add_wb_slave(mem_decoder(self.mem_map["sdram"]), self.dc.wishbone_i)
2014-10-31 18:36:06 -04:00
else:
raise NotImplementedError("Unsupported SDRAM width of {} > 32".format(sdram_width))
# Wishbone bridge
self.add_cpu_memory_region("sdram", self.mem_map["sdram"],
2014-10-31 18:36:06 -04:00
2**(sdram_geom.bank_a+sdram_geom.row_a+sdram_geom.col_a)*sdram_width//8)
else:
raise ValueError("Unsupported SDRAM controller type: {}".format(self.ramcon_type))
2013-11-24 04:30:02 -05:00
def do_finalize(self):
if not self._sdram_phy_registered:
raise FinalizeError("Need to call SDRAMSoC.register_sdram_phy()")
GenSoC.do_finalize(self)