from litedram.phy.dfi import Interface as DFIInterface
from litex.soc.cores.spi import SPIMaster
from litex.soc.cores.pwm import PWM
-from litex.soc.cores.bitbang import I2CMaster
+#from litex.soc.cores.bitbang import I2CMaster
from litex.soc.cores import uart
from litex.tools.litex_sim import sdram_module_nphases, get_sdram_phy_settings
# GPIO Tristate -------------------------------------------------------
# doesn't work properly.
#from litex.soc.cores.gpio import GPIOTristate
-from litex.soc.interconnect.csr import CSRStorage, CSRStatus
+from litex.soc.interconnect.csr import CSRStorage, CSRStatus, CSRField
from migen.genlib.cdc import MultiReg
# Imports
from litex.build.io import SDROutput, SDRInput
+# I2C Master Bit-Banging --------------------------------------------------
+
+class I2CMaster(Module, AutoCSR):
+ """I2C Master Bit-Banging
+
+ Provides the minimal hardware to do software I2C Master bit banging.
+
+ On the same write CSRStorage (_w), software can control SCL (I2C_SCL),
+ SDA direction and value (I2C_OE, I2C_W). Software get back SDA value
+ with the read CSRStatus (_r).
+ """
+ pads_layout = [("scl", 1), ("sda", 1)]
+ def __init__(self, pads):
+ self.pads = pads
+ self._w = CSRStorage(fields=[
+ CSRField("scl", size=1, offset=0),
+ CSRField("oe", size=1, offset=1),
+ CSRField("sda", size=1, offset=2)],
+ name="w")
+ self._r = CSRStatus(fields=[
+ CSRField("sda", size=1, offset=0)],
+ name="r")
+
+ self.connect(pads)
+
+ def connect(self, pads):
+ _sda_w = Signal()
+ _sda_oe = Signal()
+ _sda_r = Signal()
+ self.comb += [
+ pads.scl.eq(self._w.fields.scl),
+ pads.sda_oe.eq( self._w.fields.oe),
+ pads.sda_o.eq( self._w.fields.sda),
+ self._r.fields.sda.eq(pads.sda_i),
+ ]
+
+
class GPIOTristateASIC(Module, AutoCSR):
def __init__(self, pads):
nbits = len(pads.oe) # hack
_o = getattr(pad, "%s_o" % name)
_oe = getattr(pad, "%s_oe" % name)
_i = getattr(pad, "%s_i" % name)
+ self.specials += SDROutput(clk=clk, i=oe, o=_oe)
for j in range(len(_o)):
self.specials += SDROutput(clk=clk, i=o[j], o=_o[j])
- self.specials += SDROutput(clk=clk, i=oe, o=_oe[j])
self.specials += SDRInput(clk=clk, i=_i[j], o=i[j])
# DQ/DM Data Path -------------------------------------------------
d = dfi.p0
+ wren = []
self.submodules.dq = SDRPad(pads, "dq", d.wrdata, d.wrdata_en, d.rddata)
if hasattr(pads, "dm"):
for i in range(len(pads.dm)):
- self.comb += pads.dm[i].eq(0) # FIXME
+ self.specials += SDROutput(i=d.wrdata_mask[i], o=pads.dm[i])
# DQ/DM Control Path ----------------------------------------------
rddata_en = Signal(cl + cmd_latency)
uart_name = "sim"
elif platform == 'ls180':
platform = LS180Platform()
- uart_name = "uart_litex"
+ uart_name = "uart"
#cpu_data_width = 32
cpu_data_width = 64
self.submodules.crg = CRG(platform.request("sys_clk"),
platform.request("sys_rst"))
+ # PLL/Clock Select
+ clksel_i = platform.request("sys_clksel_i")
+ pll48_o = platform.request("sys_pll_48_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
+
#ram_init = []
# SDRAM ----------------------------------------------------
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
self.add_constant("MEMTEST_ADDR_DEBUG", 1)
self.add_constant("MEMTEST_DATA_DEBUG", 1)
+ # SDRAM clock
+ sys_clk = ClockSignal()
+ 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.cpu.cpupads['serial']
+ 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.cpu.iopads['serial'] # 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.submodules.gpio = GPIOTristateASIC(gpio_core_pads)
self.add_csr("gpio")
- gpio_pads = platform.request("gpio_litex")
- gpio_io_pads = self.cpu.iopads['gpio'] # C4M JTAG pads
- self.comb += gpio_pads.i.eq(gpio_io_pads.i)
- self.comb += gpio_io_pads.o.eq(gpio_pads.o)
- self.comb += gpio_io_pads.oe.eq(gpio_pads.oe)
-
# 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.comb += self.cpu.jtag_tdi.eq(jtagpads.tdi)
self.comb += jtagpads.tdo.eq(self.cpu.jtag_tdo)
+ # NC - allows some iopads to be connected up
+ # sigh, just do something, anything, to stop yosys optimising these out
+ nc_pads = platform.request("nc")
+ num_nc = len(nc_pads)
+ self.nc = Signal(num_nc)
+ self.comb += self.nc.eq(nc_pads)
+ self.dummy = Signal(num_nc)
+ for i in range(num_nc):
+ 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("../")