build/lattice/common: add tristate support
authorFlorent Kermarrec <florent@enjoy-digital.fr>
Mon, 29 Oct 2018 18:22:04 +0000 (19:22 +0100)
committerFlorent Kermarrec <florent@enjoy-digital.fr>
Mon, 29 Oct 2018 18:22:04 +0000 (19:22 +0100)
litex/build/lattice/common.py

index 12379b279654c66457473d4d5d27b43cc27d51ba..0b5ef703101eb7dc6ff2912cc432a334a81dcf3e 100644 (file)
@@ -1,5 +1,6 @@
 from migen.fhdl.module import Module
-from migen.fhdl.specials import Instance
+from migen.fhdl.specials import Instance, Tristate
+from migen.fhdl.bitcontainer import value_bits_sign
 from migen.genlib.io import *
 from migen.genlib.resetsync import AsyncResetSynchronizer
 
@@ -34,9 +35,35 @@ class LatticeECPXDDROutput:
     def lower(dr):
         return LatticeECPXDDROutputImpl(dr.i1, dr.i2, dr.o, dr.clk)
 
+
 lattice_ecpx_special_overrides = {
     AsyncResetSynchronizer: LatticeECPXAsyncResetSynchronizer,
-    DDROutput: LatticeECPXDDROutput
+    DDROutput:              LatticeECPXDDROutput
+}
+
+
+class LatticeECPXPrjTrellisTristateImpl(Module):
+    def __init__(self, io, o, oe, i):
+        nbits, sign = value_bits_sign(io)
+        for bit in range(nbits):
+            self.specials += \
+                Instance("TRELLIS_IO",
+                    p_DIR="BIDIR",
+                    i_B=~io[bit],
+                    i_I=o[bit],
+                    o_O=i[bit]
+                )
+
+class LatticeECPXPrjTrellisTristate(Module):
+    @staticmethod
+    def lower(dr):
+        return LatticeECPXPrjTrellisTristateImpl(dr.target, dr.o, dr.oe, dr.i)
+
+
+lattice_ecpx_prjtrellis_special_overrides = {
+    AsyncResetSynchronizer: LatticeECPXAsyncResetSynchronizer,
+    Tristate:               LatticeECPXPrjTrellisTristate,
+    DDROutput:              LatticeECPXDDROutput
 }
 
 
@@ -57,6 +84,26 @@ class LatticeiCE40AsyncResetSynchronizer:
         return LatticeiCE40AsyncResetSynchronizerImpl(dr.cd, dr.async_reset)
 
 
+class LatticeiCE40TristateImpl(Module):
+    def __init__(self, io, o, oe, i):
+        nbits, sign = value_bits_sign(io)
+        for bit in range(nbits):
+            self.specials += \
+                Instance("SB_IO",
+                    p_PIN_TYPE=C(0b101001, 6),
+                    io_PACKAGE_PIN=io[bit],
+                    i_OUTPUT_ENABLE=oe,
+                    i_D_OUT_0=o[bit],
+                    o_D_IN_0=i[bit],
+                )
+
+
+class LatticeiCE40Tristate(Module):
+    @staticmethod
+    def lower(dr):
+        return LatticeiCE40TristateImpl(dr.target, dr.o, dr.oe, dr.i)
+
+
 class LatticeiCE40DifferentialOutputImpl(Module):
     def __init__(self, i, o_p, o_n):
         self.specials += Instance("SB_IO",
@@ -77,7 +124,9 @@ class LatticeiCE40DifferentialOutput:
     def lower(dr):
         return LatticeiCE40DifferentialOutputImpl(dr.i, dr.o_p, dr.o_n)
 
+
 lattice_ice40_special_overrides = {
     AsyncResetSynchronizer: LatticeiCE40AsyncResetSynchronizer,
+    Tristate:               LatticeiCE40Tristate,
     DifferentialOutput:     LatticeiCE40DifferentialOutput
 }