from mibuild.tools import write_to_file
-from misoclib import cpuif
+from misoclib.gensoc import cpuif
from misoclib.s6ddrphy import initsequence
import top, jtag
def build(platform_name, build_bitstream, build_header, csr_csv_filename, *soc_args, **soc_kwargs):
platform_module = importlib.import_module("mibuild.platforms."+platform_name)
platform = platform_module.Platform()
- soc = top.SoC(platform, platform_name, *soc_args, **soc_kwargs)
+ soc = top.SoC(platform, *soc_args, **soc_kwargs)
platform.add_platform_command("""
INST "mxcrg/wr_bufpll" LOC = "BUFPLL_X0Y2";
+++ /dev/null
-from migen.bank.description import CSRStatus
-
-def _get_rw_functions(reg_name, reg_base, size, read_only):
- r = ""
-
- r += "#define CSR_"+reg_name.upper()+"_ADDR "+hex(reg_base)+"\n"
- r += "#define CSR_"+reg_name.upper()+"_SIZE "+str(size)+"\n"
-
- if size > 8:
- raise NotImplementedError("Register too large")
- elif size > 4:
- ctype = "unsigned long long int"
- elif size > 2:
- ctype = "unsigned int"
- elif size > 1:
- ctype = "unsigned short int"
- else:
- ctype = "unsigned char"
-
- r += "static inline "+ctype+" "+reg_name+"_read(void) {\n"
- if size > 1:
- r += "\t"+ctype+" r = MMPTR("+hex(reg_base)+");\n"
- for byte in range(1, size):
- r += "\tr <<= 8;\n\tr |= MMPTR("+hex(reg_base+4*byte)+");\n"
- r += "\treturn r;\n}\n"
- else:
- r += "\treturn MMPTR("+hex(reg_base)+");\n}\n"
-
- if not read_only:
- r += "static inline void "+reg_name+"_write("+ctype+" value) {\n"
- for byte in range(size):
- shift = (size-byte-1)*8
- if shift:
- value_shifted = "value >> "+str(shift)
- else:
- value_shifted = "value"
- r += "\tMMPTR("+hex(reg_base+4*byte)+") = "+value_shifted+";\n"
- r += "}\n"
- return r
-
-def get_csr_header(csr_base, bank_array, interrupt_map):
- r = "#ifndef __HW_CSR_H\n#define __HW_CSR_H\n#include <hw/common.h>\n"
- for name, csrs, mapaddr, rmap in bank_array.banks:
- r += "\n/* "+name+" */\n"
- reg_base = csr_base + 0x800*mapaddr
- r += "#define "+name.upper()+"_BASE "+hex(reg_base)+"\n"
- for csr in csrs:
- nr = (csr.size + 7)//8
- r += _get_rw_functions(name + "_" + csr.name, reg_base, nr, isinstance(csr, CSRStatus))
- reg_base += 4*nr
- try:
- interrupt_nr = interrupt_map[name]
- except KeyError:
- pass
- else:
- r += "#define "+name.upper()+"_INTERRUPT "+str(interrupt_nr)+"\n"
- for name, memory, mapaddr, mmap in bank_array.srams:
- mem_base = csr_base + 0x800*mapaddr
- fullname = name + "_" + memory.name_override
- r += "#define "+fullname.upper()+"_BASE "+hex(mem_base)+"\n"
- r += "\n#endif\n"
- return r
-
-def get_csr_csv(csr_base, bank_array):
- r = ""
- for name, csrs, mapaddr, rmap in bank_array.banks:
- reg_base = csr_base + 0x800*mapaddr
- for csr in csrs:
- nr = (csr.size + 7)//8
- r += "{}_{},0x{:08x},{},{}\n".format(name, csr.name, reg_base, nr, "ro" if isinstance(csr, CSRStatus) else "rw")
- reg_base += 4*nr
- return r
--- /dev/null
+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, uart, dfii, lasmicon, identifier, timer, memtest
+
+class GenSoC(Module):
+ csr_base = 0xe0000000
+ csr_map = {
+ "crg": 0, # user
+ "uart": 1, # provided
+ "identifier": 2, # provided
+ "timer0": 3, # provided
+ "buttons": 4, # user
+ "leds": 5, # user
+ }
+ interrupt_map = {
+ "uart": 0,
+ "timer0": 1,
+ }
+ known_platform_id = defaultdict(lambda: 0x554E, {
+ "mixxeo": 0x4D58,
+ "m1": 0x4D31
+ })
+
+ def __init__(self, platform, clk_freq, sram_size, l2_size=0):
+ self.clk_freq = clk_freq
+ self.sram_size = sram_size
+ self.l2_size = l2_size
+
+ # Wishbone
+ self.submodules.cpu = lm32.LM32()
+ self.submodules.sram = wishbone.SRAM(sram_size)
+ self.submodules.wishbone2csr = wishbone2csr.WB2CSR()
+
+ # rom 0x00000000 (shadow @0x80000000) user
+ # 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),
+ (lambda a: a[27:29] == 3, self.wishbone2csr.wishbone)
+ ]
+
+ # CSR
+ self.submodules.uart = uart.UART(platform.request("serial"), clk_freq, baud=115200)
+ self.submodules.identifier = identifier.Identifier(self.known_platform_id[platform.name], int(clk_freq),
+ log2_int(l2_size) if l2_size else 0)
+ self.submodules.timer0 = timer.Timer()
+
+ 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 do_finalize(self):
+ # 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)
+
+class SDRAMSoC(GenSoC):
+ csr_map = {
+ "dfii": 6,
+ "lasmicon": 7,
+ "memtest_w": 8,
+ "memtest_r": 9
+ }
+ csr_map.update(GenSoC.csr_map)
+
+ def __init__(self, platform, clk_freq, sram_size, l2_size, with_memtest):
+ GenSoC.__init__(self, platform, clk_freq, sram_size, l2_size)
+ self.with_memtest = with_memtest
+ self._sdram_modules_created = False
+
+ def create_sdram_modules(self, phy_dfi, phy_settings, sdram_geom, sdram_timing):
+ if self._sdram_modules_created:
+ raise FinalizeError
+ self._sdram_modules_created = True
+
+ # 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)
+
+ # 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())
+ self.add_wb_slave(lambda a: a[27:29] == 2, self.wishbone2lasmi.wishbone)
+
+ def do_finalize(self):
+ if not self._sdram_modules_created:
+ raise FinalizeError("Need to call SDRAMSoC.create_sdram_modules()")
+ GenSoC.do_finalize(self)
--- /dev/null
+from migen.bank.description import CSRStatus
+
+def _get_rw_functions(reg_name, reg_base, size, read_only):
+ r = ""
+
+ r += "#define CSR_"+reg_name.upper()+"_ADDR "+hex(reg_base)+"\n"
+ r += "#define CSR_"+reg_name.upper()+"_SIZE "+str(size)+"\n"
+
+ if size > 8:
+ raise NotImplementedError("Register too large")
+ elif size > 4:
+ ctype = "unsigned long long int"
+ elif size > 2:
+ ctype = "unsigned int"
+ elif size > 1:
+ ctype = "unsigned short int"
+ else:
+ ctype = "unsigned char"
+
+ r += "static inline "+ctype+" "+reg_name+"_read(void) {\n"
+ if size > 1:
+ r += "\t"+ctype+" r = MMPTR("+hex(reg_base)+");\n"
+ for byte in range(1, size):
+ r += "\tr <<= 8;\n\tr |= MMPTR("+hex(reg_base+4*byte)+");\n"
+ r += "\treturn r;\n}\n"
+ else:
+ r += "\treturn MMPTR("+hex(reg_base)+");\n}\n"
+
+ if not read_only:
+ r += "static inline void "+reg_name+"_write("+ctype+" value) {\n"
+ for byte in range(size):
+ shift = (size-byte-1)*8
+ if shift:
+ value_shifted = "value >> "+str(shift)
+ else:
+ value_shifted = "value"
+ r += "\tMMPTR("+hex(reg_base+4*byte)+") = "+value_shifted+";\n"
+ r += "}\n"
+ return r
+
+def get_csr_header(csr_base, bank_array, interrupt_map):
+ r = "#ifndef __HW_CSR_H\n#define __HW_CSR_H\n#include <hw/common.h>\n"
+ for name, csrs, mapaddr, rmap in bank_array.banks:
+ r += "\n/* "+name+" */\n"
+ reg_base = csr_base + 0x800*mapaddr
+ r += "#define "+name.upper()+"_BASE "+hex(reg_base)+"\n"
+ for csr in csrs:
+ nr = (csr.size + 7)//8
+ r += _get_rw_functions(name + "_" + csr.name, reg_base, nr, isinstance(csr, CSRStatus))
+ reg_base += 4*nr
+ try:
+ interrupt_nr = interrupt_map[name]
+ except KeyError:
+ pass
+ else:
+ r += "#define "+name.upper()+"_INTERRUPT "+str(interrupt_nr)+"\n"
+ for name, memory, mapaddr, mmap in bank_array.srams:
+ mem_base = csr_base + 0x800*mapaddr
+ fullname = name + "_" + memory.name_override
+ r += "#define "+fullname.upper()+"_BASE "+hex(mem_base)+"\n"
+ r += "\n#endif\n"
+ return r
+
+def get_csr_csv(csr_base, bank_array):
+ r = ""
+ for name, csrs, mapaddr, rmap in bank_array.banks:
+ reg_base = csr_base + 0x800*mapaddr
+ for csr in csrs:
+ nr = (csr.size + 7)//8
+ r += "{}_{},0x{:08x},{},{}\n".format(name, csr.name, reg_base, nr, "ro" if isinstance(csr, CSRStatus) else "rw")
+ reg_base += 4*nr
+ return r
from fractions import Fraction
-from math import ceil
-from operator import itemgetter
-from collections import defaultdict
from migen.fhdl.std import *
-from migen.bus import wishbone, csr, lasmibus, dfi
-from migen.bus import wishbone2lasmi, wishbone2csr
-from migen.bank import csrgen
from mibuild.generic_platform import ConstraintError
-from misoclib import mxcrg, lm32, norflash, uart, s6ddrphy, dfii, lasmicon, \
- identifier, timer, minimac3, framebuffer, dvisampler, gpio, memtest
+from misoclib import lasmicon, mxcrg, norflash, s6ddrphy, minimac3, framebuffer, dvisampler, gpio
+from misoclib.gensoc import SDRAMSoC
-clk_freq = (83 + Fraction(1, 3))*1000000
-sram_size = 4096 # in bytes
-l2_size = 8192 # in bytes
-
-clk_period_ns = 1000000000/clk_freq
-def ns(t, margin=True):
- if margin:
- t += clk_period_ns/2
- return ceil(t/clk_period_ns)
-
-sdram_geom = lasmicon.GeomSettings(
- bank_a=2,
- row_a=13,
- col_a=10
-)
-sdram_timing = lasmicon.TimingSettings(
- tRP=ns(15),
- tRCD=ns(15),
- tWR=ns(15),
- tWTR=2,
- tREFI=ns(7800, False),
- tRFC=ns(70),
-
- req_queue_size=8,
- read_time=32,
- write_time=16
-)
-
-class MXClockPads:
+class _MXClockPads:
def __init__(self, platform):
self.clk50 = platform.request("clk50")
self.trigger_reset = 0
self.eth_rx_clk = eth_clocks.rx
self.eth_tx_clk = eth_clocks.tx
-class SoC(Module):
- csr_base = 0xe0000000
+class MiniSoC(SDRAMSoC):
csr_map = {
- "crg": 0,
- "uart": 1,
- "dfii": 2,
- "identifier": 3,
- "timer0": 4,
- "minimac": 5,
- "fb": 6,
- "lasmicon": 7,
- "dvisampler0": 8,
- "dvisampler0_edid_mem": 9,
- "dvisampler1": 10,
- "dvisampler1_edid_mem": 11,
- "pots": 12,
- "buttons": 13,
- "leds": 14,
- "memtest_w": 15,
- "memtest_r": 16
+ "minimac": 10,
+ "fb": 11,
+ "dvisampler0": 12,
+ "dvisampler0_edid_mem": 13,
+ "dvisampler1": 14,
+ "dvisampler1_edid_mem": 15,
}
+ csr_map.update(SDRAMSoC.csr_map)
+
interrupt_map = {
- "uart": 0,
- "timer0": 1,
"minimac": 2,
"dvisampler0": 3,
"dvisampler1": 4,
}
- known_platform_id = defaultdict(lambda: 0x554E, {
- "mixxeo": 0x4D58,
- "m1": 0x4D31
- })
+ interrupt_map.update(SDRAMSoC.interrupt_map)
- def __init__(self, platform, platform_name, with_memtest):
- #
- # DFI
- #
- self.submodules.ddrphy = s6ddrphy.S6DDRPHY(platform.request("ddram"), memtype="DDR", nphases=2, cl=3, rd_bitslip=0, wr_bitslip=3, dqs_ddr_alignment="C1")
- self.submodules.dfii = dfii.DFIInjector(sdram_geom.mux_a, sdram_geom.bank_a,
- self.ddrphy.phy_settings.dfi_d, self.ddrphy.phy_settings.nphases)
- self.submodules.dficon0 = dfi.Interconnect(self.dfii.master, self.ddrphy.dfi)
+ def __init__(self, platform, with_memtest):
+ SDRAMSoC.__init__(self, platform,
+ clk_freq=(83 + Fraction(1, 3))*1000000,
+ sram_size=4096,
+ l2_size=8192,
+ with_memtest=with_memtest)
- #
- # LASMI
- #
- self.submodules.lasmicon = lasmicon.LASMIcon(self.ddrphy.phy_settings, sdram_geom, sdram_timing)
- self.submodules.dficon1 = dfi.Interconnect(self.lasmicon.dfi, self.dfii.slave)
+ sdram_geom = lasmicon.GeomSettings(
+ bank_a=2,
+ row_a=13,
+ col_a=10
+ )
+ sdram_timing = lasmicon.TimingSettings(
+ tRP=self.ns(15),
+ tRCD=self.ns(15),
+ tWR=self.ns(15),
+ tWTR=2,
+ tREFI=self.ns(7800, False),
+ tRFC=self.ns(70),
- self.submodules.lasmixbar = lasmibus.Crossbar([self.lasmicon.lasmic], self.lasmicon.nrowbits)
- lasmim_wb = self.lasmixbar.get_master()
- if platform_name == "mixxeo":
- lasmim_fb0, lasmim_fb1, lasmim_dvi0, lasmim_dvi1 = (self.lasmixbar.get_master() for i in range(4))
- if platform_name == "m1":
- lasmim_fb = self.lasmixbar.get_master()
- if with_memtest:
- lasmim_mtw, lasmim_mtr = self.lasmixbar.get_master(), self.lasmixbar.get_master()
+ req_queue_size=8,
+ read_time=32,
+ write_time=16
+ )
+ self.submodules.ddrphy = s6ddrphy.S6DDRPHY(platform.request("ddram"), memtype="DDR",
+ nphases=2, cl=3, rd_bitslip=0, wr_bitslip=3, dqs_ddr_alignment="C1")
+ self.create_sdram_modules(self.ddrphy.dfi, self.ddrphy.phy_settings, sdram_geom, sdram_timing)
- #
- # WISHBONE
- #
- self.submodules.cpu = lm32.LM32()
+ # Wishbone
self.submodules.norflash = norflash.NorFlash(platform.request("norflash"), 12)
- self.submodules.sram = wishbone.SRAM(sram_size)
self.submodules.minimac = minimac3.MiniMAC(platform.request("eth"))
- self.submodules.wishbone2lasmi = wishbone2lasmi.WB2LASMI(l2_size//4, lasmim_wb)
- self.submodules.wishbone2csr = wishbone2csr.WB2CSR()
-
- # norflash 0x00000000 (shadow @0x80000000)
- # SRAM/debug 0x10000000 (shadow @0x90000000)
- # USB 0x20000000 (shadow @0xa0000000)
- # Ethernet 0x30000000 (shadow @0xb0000000)
- # SDRAM 0x40000000 (shadow @0xc0000000)
- # CSR bridge 0x60000000 (shadow @0xe0000000)
- self.submodules.wishbonecon = wishbone.InterconnectShared(
- [
- self.cpu.ibus,
- self.cpu.dbus
- ], [
- (lambda a: a[26:29] == 0, self.norflash.bus),
- (lambda a: a[26:29] == 1, self.sram.bus),
- (lambda a: a[26:29] == 3, self.minimac.membus),
- (lambda a: a[27:29] == 2, self.wishbone2lasmi.wishbone),
- (lambda a: a[27:29] == 3, self.wishbone2csr.wishbone)
- ],
- register=True)
+ self.add_wb_slave(lambda a: a[26:29] == 0, self.norflash.bus)
+ self.add_wb_slave(lambda a: a[26:29] == 3, self.minimac.membus)
- #
# CSR
- #
- self.submodules.crg = mxcrg.MXCRG(MXClockPads(platform), clk_freq)
- self.submodules.uart = uart.UART(platform.request("serial"), clk_freq, baud=115200)
- self.submodules.identifier = identifier.Identifier(self.known_platform_id[platform_name], int(clk_freq),
- log2_int(l2_size))
- self.submodules.timer0 = timer.Timer()
- if platform_name == "mixxeo":
+ self.submodules.crg = mxcrg.MXCRG(_MXClockPads(platform), self.clk_freq)
+ if platform.name == "mixxeo":
self.submodules.leds = gpio.GPIOOut(platform.request("user_led"))
- self.submodules.fb = framebuffer.MixFramebuffer(platform.request("vga_out"), platform.request("dvi_out"),
- lasmim_fb0, lasmim_fb1)
- self.submodules.dvisampler0 = dvisampler.DVISampler(platform.request("dvi_in", 0), lasmim_dvi0)
- self.submodules.dvisampler1 = dvisampler.DVISampler(platform.request("dvi_in", 1), lasmim_dvi1)
- if platform_name == "m1":
+ if platform.name == "m1":
self.submodules.buttons = gpio.GPIOIn(Cat(platform.request("user_btn", 0), platform.request("user_btn", 2)))
self.submodules.leds = gpio.GPIOOut(Cat(*[platform.request("user_led", i) for i in range(2)]))
- self.submodules.fb = framebuffer.Framebuffer(platform.request("vga"), None, lasmim_fb)
- if with_memtest:
- self.submodules.memtest_w = memtest.MemtestWriter(lasmim_mtw)
- self.submodules.memtest_r = memtest.MemtestReader(lasmim_mtr)
- 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)
-
- #
- # Clocking
- #
+ # Clock glue
self.comb += [
self.ddrphy.clk4x_wr_strb.eq(self.crg.clk4x_wr_strb),
self.ddrphy.clk4x_rd_strb.eq(self.crg.clk4x_rd_strb)
]
+
+def _get_vga_dvi(platform):
+ try:
+ pads_vga = platform.request("vga_out")
+ except ConstraintError:
+ pads_vga = None
+ try:
+ pads_dvi = platform.request("dvi_out")
+ except ConstraintError:
+ pads_dvi = None
+ return pads_vga, pads_dvi
+
+class FramebufferSoC(MiniSoC):
+ def __init__(self, platform, with_memtest):
+ MiniSoC.__init__(self, platform, with_memtest)
+ pads_vga, pads_dvi = _get_vga_dvi(platform)
+ self.submodules.fb = framebuffer.Framebuffer(pads_vga, pads_dvi, self.lasmixbar.get_master())
+
+class VideomixerSoC(MiniSoC):
+ def __init__(self, platform, with_memtest):
+ MiniSoC.__init__(self, platform, with_memtest)
+ pads_vga, pads_dvi = _get_vga_dvi(platform)
+ self.submodules.fb = framebuffer.MixFramebuffer(pads_vga, pads_dvi,
+ self.lasmixbar.get_master(), self.lasmixbar.get_master())
+ self.submodules.dvisampler0 = dvisampler.DVISampler(platform.request("dvi_in", 0), self.lasmixbar.get_master())
+ self.submodules.dvisampler1 = dvisampler.DVISampler(platform.request("dvi_in", 1), self.lasmixbar.get_master())
+
+SoC = VideomixerSoC