litex/misoclib/gensoc/__init__.py

203 lines
7.4 KiB
Python
Raw Normal View History

2013-11-24 07:37:32 -05:00
import os
2013-11-24 04:30:02 -05:00
from operator import itemgetter
from collections import defaultdict
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
class GenSoC(Module):
csr_base = 0xe0000000
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,
}
known_platform_id = defaultdict(lambda: 0x554E, {
2013-11-24 17:50:33 -05:00
"mixxeo": 0x4D58,
"m1": 0x4D31,
2014-08-06 11:53:51 -04:00
"papilio_pro": 0x5050,
"kc705": 0x4B37
2013-11-24 04:30:02 -05:00
})
def __init__(self, platform, clk_freq, cpu_reset_address, sram_size=4096, l2_size=0, with_uart=True, cpu_type="lm32"):
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.cpu_memory_regions = []
self._rom_registered = False
2013-11-24 04:30:02 -05:00
# Wishbone
if cpu_type == "lm32":
self.submodules.cpu = lm32.LM32(cpu_reset_address)
elif cpu_type == "or1k":
self.submodules.cpu = mor1kx.MOR1KX(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()
# 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 = [
(lambda a: a[26:29] == 1, self.sram.bus),
2014-11-30 09:05:51 -05:00
(lambda a: a[26:29] == 6, self.wishbone2csr.wishbone)
2013-11-24 04:30:02 -05:00
]
self.add_cpu_memory_region("sram", 0x10000000, 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)
2013-11-24 04:30:02 -05:00
self.submodules.identifier = identifier.Identifier(self.known_platform_id[platform.name], int(clk_freq),
log2_int(l2_size) if l2_size else 0)
2013-11-24 07:37:32 -05:00
self.submodules.timer0 = timer.Timer()
# add CPU Verilog sources
if cpu_type == "lm32":
2014-10-17 05:14:35 -04:00
platform.add_sources(os.path.join("verilog", "lm32", "submodule", "rtl"),
"lm32_cpu.v", "lm32_instruction_unit.v", "lm32_decoder.v",
"lm32_load_store_unit.v", "lm32_adder.v", "lm32_addsub.v", "lm32_logic_op.v",
"lm32_shifter.v", "lm32_multiplier.v", "lm32_mc_arithmetic.v",
"lm32_interrupt.v", "lm32_ram.v", "lm32_dp_ram.v", "lm32_icache.v",
"lm32_dcache.v", "lm32_debug.v", "lm32_itlb.v", "lm32_dtlb.v")
platform.add_verilog_include_path(os.path.join("verilog", "lm32"))
if cpu_type == "or1k":
platform.add_source_dir(os.path.join("verilog", "mor1kx", "submodule", "rtl", "verilog"))
def register_rom(self, rom_wb_if, bios_size=0xa000):
if self._rom_registered:
raise FinalizeError
self._rom_registered = True
self.add_wb_slave(lambda a: a[26:29] == 0, 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 add_cpu_memory_region(self, name, origin, length):
self.cpu_memory_regions.append((name, origin, length))
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])
self.submodules.csrcon = csr.Interconnect(self.wishbone2csr.csr, self.csrbankarray.get_buses())
# 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)
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)
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)
2014-10-31 18:36:06 -04:00
if self.ramcon_type == "lasmicon":
# LASMI
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: map SDRAM at 0x40000000 (shadow @0xc0000000)
self.submodules.wishbone2lasmi = wishbone2lasmi.WB2LASMI(self.l2_size//4, self.lasmixbar.get_master())
2014-11-30 09:05:51 -05:00
self.add_wb_slave(lambda a: a[26:29] == 4, self.wishbone2lasmi.wishbone)
2014-10-31 18:36:06 -04:00
self.add_cpu_memory_region("sdram", 0x40000000,
2**self.lasmicon.lasmic.aw*self.lasmicon.lasmic.dw*self.lasmicon.lasmic.nbanks//8)
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):
2014-11-30 09:05:51 -05:00
self.add_wb_slave(lambda a: a[26:29] == 4, sdramcon.bus)
2014-10-31 18:36:06 -04:00
elif (sdram_width < 32):
self.submodules.dc = dc = wishbone.DownConverter(32, sdram_width)
self.submodules.intercon = wishbone.InterconnectPointToPoint(dc.wishbone_o, sdramcon.bus)
2014-11-30 09:05:51 -05:00
self.add_wb_slave(lambda a: a[26:29] == 4, dc.wishbone_i)
2014-10-31 18:36:06 -04:00
else:
raise NotImplementedError("Unsupported SDRAM width of {} > 32".format(sdram_width))
# map SDRAM at 0x40000000 (shadow @0xc0000000)
self.add_cpu_memory_region("sdram", 0x40000000,
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)