nope. put it back and connect to platform pads in LS180Platform
[soc.git] / src / soc / litex / florent / ls180soc.py
index 61f18b8a33edc99d671de3e34fa249e84a837097..50d2a95f9ff1bc781c112eb3ea0e78885c813693 100755 (executable)
@@ -6,7 +6,7 @@ from functools import reduce
 from operator import or_
 
 from migen import (Signal, FSM, If, Display, Finish, NextValue, NextState,
-                   Cat, Record, ClockSignal, wrap)
+                   Cat, Record, ClockSignal, wrap, ResetInserter)
 
 from litex.build.generic_platform import Pins, Subsignal
 from litex.build.sim import SimPlatform
@@ -26,7 +26,8 @@ from litedram.common import PHYPadsCombiner, PhySettings
 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
 
@@ -46,7 +47,7 @@ SoCCSRHandler.supported_address_width.append(12)
 # 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
@@ -60,6 +61,43 @@ from litesdcard.frontend.dma import SDBlock2MemDMA, SDMem2BlockDMA
 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
@@ -89,9 +127,9 @@ class SDRPad(Module):
         _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])
 
 
@@ -201,26 +239,30 @@ class GENSDRPHY(Module):
             pads.sel_group(pads_group)
 
             # Addresses and Commands --------------------------------------
-            self.specials += [SDROutput(i=dfi.p0.address[i], o=pads.a[i])
+            p0 = dfi.p0
+            self.specials += [SDROutput(i=p0.address[i], o=pads.a[i])
                                     for i in range(len(pads.a))]
-            self.specials += [SDROutput(i=dfi.p0.bank[i], o=pads.ba[i])
+            self.specials += [SDROutput(i=p0.bank[i], o=pads.ba[i])
                                     for i in range(len(pads.ba))]
-            self.specials += SDROutput(i=dfi.p0.cas_n, o=pads.cas_n)
-            self.specials += SDROutput(i=dfi.p0.ras_n, o=pads.ras_n)
-            self.specials += SDROutput(i=dfi.p0.we_n, o=pads.we_n)
+            self.specials += SDROutput(i=p0.cas_n, o=pads.cas_n)
+            self.specials += SDROutput(i=p0.ras_n, o=pads.ras_n)
+            self.specials += SDROutput(i=p0.we_n, o=pads.we_n)
             if hasattr(pads, "cke"):
-                self.specials += SDROutput(i=dfi.p0.cke, o=pads.cke)
+                for i in range(len(pads.cke)):
+                        self.specials += SDROutput(i=p0.cke[i], o=pads.cke[i])
             if hasattr(pads, "cs_n"):
-                self.specials += SDROutput(i=dfi.p0.cs_n, o=pads.cs_n)
+                for i in range(len(pads.cs_n)):
+                    self.specials += SDROutput(i=p0.cs_n[i], o=pads.cs_n[i])
 
         # 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)
@@ -247,7 +289,7 @@ class LibreSoCSim(SoCCore):
             uart_name = "sim"
         elif platform == 'ls180':
             platform     = LS180Platform()
-            uart_name = "serial"
+            uart_name = "uart"
 
         #cpu_data_width = 32
         cpu_data_width = 64
@@ -288,7 +330,8 @@ class LibreSoCSim(SoCCore):
             cpu_variant              = variant,
             csr_data_width            = 8,
             l2_size             = 0,
-            uart_name                = uart_name,
+            with_uart                = False,
+            uart_name                = None,
             with_sdram               = with_sdram,
             sdram_module          = sdram_module,
             sdram_data_width      = sdram_data_width,
@@ -320,6 +363,13 @@ class LibreSoCSim(SoCCore):
         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 ----------------------------------------------------
@@ -357,8 +407,29 @@ class LibreSoCSim(SoCCore):
             self.add_constant("MEMTEST_ADDR_DEBUG", 1)
             self.add_constant("MEMTEST_DATA_DEBUG", 1)
 
+            # SDRAM clock
+            sys_clk = ClockSignal()
+            sdr_clk = platform.request("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['uart']
+        self.submodules.uart_phy = uart.UARTPHY(
+                pads     = uart_core_pads,
+                clk_freq = self.sys_clk_freq,
+                baudrate = 115200)
+        self.submodules.uart = ResetInserter()(uart.UART(self.uart_phy,
+                tx_fifo_depth = 16,
+                rx_fifo_depth = 16))
+
+        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)
-        self.submodules.gpio = GPIOTristateASIC(platform.request("gpio"))
+        gpio_core_pads = self.cpu.cpupads['gpio']
+        self.submodules.gpio = GPIOTristateASIC(gpio_core_pads)
         self.add_csr("gpio")
 
         # SPI Master
@@ -380,6 +451,16 @@ class LibreSoCSim(SoCCore):
         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
         for i in range(2):
             name = "pwm%d" % i