from migen import (Signal, FSM, If, Display, Finish, NextValue, NextState,
Cat, Record, ClockSignal, wrap, ResetInserter)
+from litex.build.generic_platform import Pins, Subsignal
from litex.build.sim import SimPlatform
from litex.build.io import CRG
from litex.build.sim.config import SimConfig
from litex.tools.litex_sim import sdram_module_nphases, get_sdram_phy_settings
from litex.tools.litex_sim import Platform
-from libresoc.ls180 import LS180Platform, io
+from libresoc.ls180 import LS180Platform
from migen import Module
from litex.soc.interconnect.csr import AutoCSR
from litesdcard.frontend.dma import SDBlock2MemDMA, SDMem2BlockDMA
from litex.build.io import SDROutput, SDRInput
-from soc.debug.jtag import Pins, dummy_pinset # TODO move to suitable location
-from c4m.nmigen.jtag.tap import IOType
-from litex.build.generic_platform import ConstraintManager
-
-
-def make_pad(res, dirn, name, suffix, cpup, iop):
- cpud, iod = ('i', 'o') if dirn else ('o', 'i')
- res['%s_%s__core__%s' % (cpud, name, suffix)] = cpup
- res['%s_%s__pad__%s' % (iod, name, suffix)] = iop
-
-
-def make_jtag_ioconn(res, pin, cpupads, iopads):
- (fn, pin, iotype, pin_name, scan_idx) = pin
- #serial_tx__core__o, serial_rx__pad__i,
- print ("cpupads", cpupads)
- print ("iopads", iopads)
- print ("pin", fn, pin, iotype, pin_name)
- cpu = cpupads[fn]
- io = iopads[fn]
- sigs = []
-
- name = "%s_%s" % (fn, pin)
-
- if iotype in (IOType.In, IOType.Out):
- cpup = getattr(cpu, pin)
- iop = getattr(io, pin)
-
- if iotype == IOType.Out:
- # output from the pad is routed through C4M JTAG and so
- # is an *INPUT* into core. ls180soc connects this to "real" peripheral
- make_pad(res, True, name, "o", cpup, iop)
-
- elif iotype == IOType.In:
- # input to the pad is routed through C4M JTAG and so
- # is an *OUTPUT* into core. ls180soc connects this to "real" peripheral
- make_pad(res, False, name, "i", cpup, iop)
-
- elif iotype == IOType.InTriOut:
- if fn == 'gpio': # sigh decode GPIO special-case
- idx = int(pin[4:])
- cpup, iop = cpu.i[idx], io.i[idx]
- make_pad(res, False, name, "i", cpup, iop)
- cpup, iop = cpu.o[idx], io.o[idx]
- make_pad(res, True, name, "o", cpup, iop)
- cpup, iop = cpu.oe[idx], io.oe[idx]
- make_pad(res, True, name, "oe", cpup, iop)
-
- if iotype in (IOType.In, IOType.InTriOut):
- sigs.append(("i", 1))
- if iotype in (IOType.Out, IOType.TriOut, IOType.InTriOut):
- sigs.append(("o", 1))
- if iotype in (IOType.TriOut, IOType.InTriOut):
- sigs.append(("oe", 1))
-
# I2C Master Bit-Banging --------------------------------------------------
class GPIOTristateASIC(Module, AutoCSR):
- def __init__(self, pads):
+ def __init__(self, pads, prange=None):
nbits = len(pads.oe) # hack
self._oe = CSRStorage(nbits, description="GPIO Tristate(s) Control.")
self._in = CSRStatus(nbits, description="GPIO Input(s) Status.")
self.comb += _pads.oe.eq(self._oe.storage)
self.comb += _pads.o.eq(self._out.storage)
- for i in range(nbits):
+ if prange is None:
+ prange = range(nbits)
+ for i in prange:
self.specials += MultiReg(_pads.i[i], self._in.status[i])
# SDCard PHY IO -------------------------------------------------------
self.mem_map["main_ram"] = 0x90000000
self.mem_map["sram"] = 0x00000000
+ self.mem_map["sram1"] = 0x00001000
+ self.mem_map["sram2"] = 0x00002000
+ self.mem_map["sram3"] = 0x00003000
# SoCCore -------------------------------------------------------------
SoCCore.__init__(self, platform, clk_freq=sys_clk_freq,
cpu_type = "microwatt",
cpu_cls = LibreSoC if cpu == "libresoc" \
else Microwatt,
- #bus_data_width = 64,
+ bus_data_width = 64,
csr_address_width = 14, # limit to 0x8000
cpu_variant = variant,
csr_data_width = 8,
sdram_module = sdram_module,
sdram_data_width = sdram_data_width,
integrated_rom_size = 0, # if ram_fname else 0x10000,
+ #integrated_sram_size = 0x1000, - problem with yosys ABC
integrated_sram_size = 0x200,
#integrated_main_ram_init = ram_init,
integrated_main_ram_size = 0x00000000 if with_sdram \
)
self.platform.name = "ls180"
- # Create link pads --------------------------------------------------
-
- # urr yuk. have to expose iopads / pins from core to litex
- # then back again. cut _some_ of that out by connecting
- self.cpuresources = io()
- self.padresources = io()
- self.cpu_cm = ConstraintManager(self.cpuresources, [])
- self.pad_cm = ConstraintManager(self.cpuresources, [])
- self.cpupads = {'uart': self.cpu_cm.request('uart', 0),
- 'gpio': self.cpu_cm.request('gpio', 0)}
- self.iopads = {'uart': self.pad_cm.request('uart', 0),
- 'gpio': self.pad_cm.request('gpio', 0)}
-
- p = Pins(dummy_pinset())
- for pin in list(p):
- make_jtag_ioconn(self.cpu.cpu_params, pin, self.cpupads,
- self.iopads)
+ # add 3 more 4k integrated SRAMs
+ self.add_ram("sram1", self.mem_map["sram1"], 0x200)
+ self.add_ram("sram2", self.mem_map["sram2"], 0x200)
+ self.add_ram("sram3", self.mem_map["sram3"], 0x200)
# SDR SDRAM ----------------------------------------------
if False: # not self.integrated_main_ram_size:
# PLL/Clock Select
clksel_i = platform.request("sys_clksel_i")
- pll48_o = platform.request("sys_pll_48_o")
+ pll18_o = platform.request("sys_pll_18_o")
+ pll_lck_o = platform.request("sys_pll_lck_o")
self.comb += self.cpu.clk_sel.eq(clksel_i) # allow clock src select
- self.comb += pll48_o.eq(self.cpu.pll_48_o) # "test feed" from the PLL
+ self.comb += pll18_o.eq(self.cpu.pll_18_o) # "test feed" from the PLL
+ self.comb += pll_lck_o.eq(self.cpu.pll_lck_o) # PLL lock flag
#ram_init = []
clk_freq = sdram_clk_freq)
#sdrphy_cls = HalfRateGENSDRPHY
sdrphy_cls = GENSDRPHY
- self.submodules.sdrphy = sdrphy_cls(platform.request("sdram"))
+ sdram_pads = self.cpu.cpupads['sdr']
+ self.submodules.sdrphy = sdrphy_cls(sdram_pads)
#self.submodules.sdrphy = sdrphy_cls(sdram_module,
# phy_settings,
# init=ram_init
# SDRAM clock
sys_clk = ClockSignal()
- sdr_clk = platform.request("sdram_clock")
+ sdr_clk = self.cpu.cpupads['sdram_clock']
#self.specials += DDROutput(1, 0, , sdram_clk)
self.specials += SDROutput(clk=sys_clk, i=sys_clk, o=sdr_clk)
# UART
- uart_core_pads = self.cpupads['uart']
+ uart_core_pads = self.cpu.cpupads['uart']
self.submodules.uart_phy = uart.UARTPHY(
pads = uart_core_pads,
clk_freq = self.sys_clk_freq,
self.submodules.uart = ResetInserter()(uart.UART(self.uart_phy,
tx_fifo_depth = 16,
rx_fifo_depth = 16))
- # "real" pads connect to C4M JTAG iopad
- uart_pads = platform.request(uart_name) # "real" (actual) pin
- uart_io_pads = self.iopads['uart'] # C4M JTAG pads
- self.comb += uart_pads.tx.eq(uart_io_pads.tx)
- self.comb += uart_io_pads.rx.eq(uart_pads.rx)
self.csr.add("uart_phy", use_loc_if_exists=True)
self.csr.add("uart", use_loc_if_exists=True)
self.irq.add("uart", use_loc_if_exists=True)
# GPIOs (bi-directional)
- gpio_core_pads = self.cpupads['gpio']
- self.submodules.gpio = GPIOTristateASIC(gpio_core_pads)
+ gpio_core_pads = self.cpu.cpupads['gpio']
+ self.submodules.gpio = GPIOTristateASIC(gpio_core_pads, range(8))
self.add_csr("gpio")
- gpio_pads = platform.request("gpio") # "real" (actual) pins
- gpio_io_pads = self.iopads['gpio'] # C4M JTAG pads
- self.comb += gpio_io_pads.i.eq(gpio_pads.i)
- self.comb += gpio_pads.o.eq(gpio_io_pads.o)
- self.comb += gpio_pads.oe.eq(gpio_io_pads.oe)
+ self.submodules.gpio = GPIOTristateASIC(gpio_core_pads, range(8,16))
+ self.add_csr("gpio1")
# SPI Master
- self.submodules.spi_master = SPIMaster(
- pads = platform.request("spi_master"),
+ print ("cpupadkeys", self.cpu.cpupads.keys())
+ self.submodules.spimaster = SPIMaster(
+ pads = self.cpu.cpupads['mspi1'],
data_width = 8,
sys_clk_freq = sys_clk_freq,
spi_clk_freq = 8e6,
)
- self.add_csr("spi_master")
+ self.add_csr("spimaster")
+
+ # SPI SDCard (1 wide)
+ spi_clk_freq = 400e3
+ pads = self.cpu.cpupads['mspi0']
+ spisdcard = SPIMaster(pads, 8, self.sys_clk_freq, spi_clk_freq)
+ spisdcard.add_clk_divider()
+ setattr(self.submodules, 'spisdcard', spisdcard)
+ self.add_csr('spisdcard')
# EINTs - very simple, wire up top 3 bits to ls180 "eint" pins
- self.comb += self.cpu.interrupt[12:16].eq(platform.request("eint"))
+ eintpads = self.cpu.cpupads['eint']
+ print ("eintpads", eintpads)
+ self.comb += self.cpu.interrupt[12:16].eq(eintpads)
# JTAG
jtagpads = platform.request("jtag")
self.sync += self.dummy[i].eq(self.nc[i] | self.cpu.interrupt[0])
# PWM
+ pwmpads = self.cpu.cpupads['pwm']
for i in range(2):
name = "pwm%d" % i
- setattr(self.submodules, name, PWM(platform.request("pwm", i)))
+ setattr(self.submodules, name, PWM(pwmpads[i]))
self.add_csr(name)
# I2C Master
- self.submodules.i2c = I2CMaster(platform.request("i2c"))
+ i2c_core_pads = self.cpu.cpupads['mtwi']
+ self.submodules.i2c = I2CMaster(i2c_core_pads)
self.add_csr("i2c")
# SDCard -----------------------------------------------------
# Emulator / Pads
- sdcard_pads = self.platform.request("sdcard")
+ sdcard_pads = self.cpu.cpupads['sd0']
# Core
self.submodules.sdphy = SDPHY(sdcard_pads,
if not debug:
return
+ jtag_en = ('jtag' in variant) or variant == 'ls180'
+
# setup running of DMI FSM
dmi_addr = Signal(4)
dmi_din = Signal(64)
if args.platform == 'ls180':
soc = LibreSoCSim(cpu=args.cpu, debug=args.debug,
platform=args.platform)
- soc.add_spi_sdcard()
builder = Builder(soc, compile_gateware = True)
builder.build(run = True)
os.chdir("../")