1 # This file is Copyright (c) 2015-2020 Florent Kermarrec <florent@enjoy-digital.fr>
2 # This file is Copyright (c) 2017 William D. Jones <thor0505@comcast.net>
3 # This file is Copyright (c) 2019 David Shah <dave@ds0.me>
6 from migen
.fhdl
.module
import Module
7 from migen
.fhdl
.specials
import Instance
, Tristate
8 from migen
.fhdl
.bitcontainer
import value_bits_sign
9 from migen
.genlib
.resetsync
import AsyncResetSynchronizer
11 from litex
.build
.io
import *
13 # ECP5 AsyncResetSynchronizer ----------------------------------------------------------------------
15 class LatticeECP5AsyncResetSynchronizerImpl(Module
):
16 def __init__(self
, cd
, async_reset
):
32 class LatticeECP5AsyncResetSynchronizer
:
35 return LatticeECP5AsyncResetSynchronizerImpl(dr
.cd
, dr
.async_reset
)
38 # ECP5 SDR Input -----------------------------------------------------------------------------------
40 class LatticeECP5SDRInputImpl(Module
):
41 def __init__(self
, i
, o
, clk
):
42 self
.specials
+= Instance("IFS1P3BX",
50 class LatticeECP5SDRInput
:
53 return LatticeECP5SDRInputImpl(dr
.i
, dr
.o
, dr
.clk
)
55 # ECP5 SDR Output ----------------------------------------------------------------------------------
57 class LatticeECP5SDROutputImpl(Module
):
58 def __init__(self
, i
, o
, clk
):
59 self
.specials
+= Instance("OFS1P3BX",
67 class LatticeECP5SDROutput
:
70 return LatticeECP5SDROutputImpl(dr
.i
, dr
.o
, dr
.clk
)
72 # ECP5 DDR Input -----------------------------------------------------------------------------------
74 class LatticeECP5DDRInputImpl(Module
):
75 def __init__(self
, i
, o1
, o2
, clk
):
76 self
.specials
+= Instance("IDDRX1F",
83 class LatticeECP5DDRInput
:
86 return LatticeECP5DDRInputImpl(dr
.i
, dr
.o1
, dr
.o2
, dr
.clk
)
88 # ECP5 DDR Output ----------------------------------------------------------------------------------
90 class LatticeECP5DDROutputImpl(Module
):
91 def __init__(self
, i1
, i2
, o
, clk
):
92 self
.specials
+= Instance("ODDRX1F",
99 class LatticeECP5DDROutput
:
102 return LatticeECP5DDROutputImpl(dr
.i1
, dr
.i2
, dr
.o
, dr
.clk
)
104 # ECP5 Special Overrides ---------------------------------------------------------------------------
106 lattice_ecp5_special_overrides
= {
107 AsyncResetSynchronizer
: LatticeECP5AsyncResetSynchronizer
,
108 SDRInput
: LatticeECP5SDRInput
,
109 SDROutput
: LatticeECP5SDROutput
,
110 DDRInput
: LatticeECP5DDRInput
,
111 DDROutput
: LatticeECP5DDROutput
,
114 # ECP5 Trellis Tristate ----------------------------------------------------------------------------
116 class LatticeECP5TrellisTristateImpl(Module
):
117 def __init__(self
, io
, o
, oe
, i
):
118 nbits
, sign
= value_bits_sign(io
)
119 for bit
in range(nbits
):
120 self
.specials
+= Instance("TRELLIS_IO",
122 i_B
= io
[bit
] if nbits
> 1 else io
,
123 i_I
= o
[bit
] if nbits
> 1 else o
,
124 o_O
= i
[bit
] if nbits
> 1 else i
,
128 class LatticeECP5TrellisTristate(Module
):
131 return LatticeECP5TrellisTristateImpl(dr
.target
, dr
.o
, dr
.oe
, dr
.i
)
133 # ECP5 Trellis Special Overrides -------------------------------------------------------------------
135 lattice_ecp5_trellis_special_overrides
= {
136 AsyncResetSynchronizer
: LatticeECP5AsyncResetSynchronizer
,
137 Tristate
: LatticeECP5TrellisTristate
,
138 SDRInput
: LatticeECP5SDRInput
,
139 SDROutput
: LatticeECP5SDROutput
,
140 DDRInput
: LatticeECP5DDRInput
,
141 DDROutput
: LatticeECP5DDROutput
144 # iCE40 AsyncResetSynchronizer ----------------------------------------------------------------------
146 class LatticeiCE40AsyncResetSynchronizerImpl(Module
):
147 def __init__(self
, cd
, async_reset
):
163 class LatticeiCE40AsyncResetSynchronizer
:
166 return LatticeiCE40AsyncResetSynchronizerImpl(dr
.cd
, dr
.async_reset
)
168 # iCE40 Tristate -----------------------------------------------------------------------------------
170 class LatticeiCE40TristateImpl(Module
):
171 def __init__(self
, io
, o
, oe
, i
):
172 nbits
, sign
= value_bits_sign(io
)
173 for bit
in range(nbits
):
174 self
.specials
+= Instance("SB_IO",
175 p_PIN_TYPE
= C(0b101001, 6), # PIN_OUTPUT_TRISTATE + PIN_INPUT
176 io_PACKAGE_PIN
= io
[bit
] if nbits
> 1 else io
,
177 i_OUTPUT_ENABLE
= oe
,
178 i_D_OUT_0
= o
[bit
] if nbits
> 1 else o
,
179 o_D_IN_0
= i
[bit
] if nbits
> 1 else i
,
182 class LatticeiCE40Tristate(Module
):
185 return LatticeiCE40TristateImpl(dr
.target
, dr
.o
, dr
.oe
, dr
.i
)
187 # iCE40 Differential Output ------------------------------------------------------------------------
189 class LatticeiCE40DifferentialOutputImpl(Module
):
190 def __init__(self
, i
, o_p
, o_n
):
193 p_PIN_TYPE
= C(0b011000, 6), # PIN_OUTPUT
194 p_IO_STANDARD
= "SB_LVCMOS",
195 io_PACKAGE_PIN
= o_p
,
199 p_PIN_TYPE
= C(0b011000, 6), # PIN_OUTPUT
200 p_IO_STANDARD
= "SB_LVCMOS",
201 io_PACKAGE_PIN
= o_n
,
206 class LatticeiCE40DifferentialOutput
:
209 return LatticeiCE40DifferentialOutputImpl(dr
.i
, dr
.o_p
, dr
.o_n
)
211 # iCE40 DDR Output ---------------------------------------------------------------------------------
213 class LatticeiCE40DDROutputImpl(Module
):
214 def __init__(self
, i1
, i2
, o
, clk
):
215 self
.specials
+= Instance("SB_IO",
216 p_PIN_TYPE
= C(0b010000, 6), # PIN_OUTPUT_DDR
217 p_IO_STANDARD
= "SB_LVCMOS",
227 class LatticeiCE40DDROutput
:
230 return LatticeiCE40DDROutputImpl(dr
.i1
, dr
.i2
, dr
.o
, dr
.clk
)
232 # iCE40 DDR Input ----------------------------------------------------------------------------------
234 class LatticeiCE40DDRInputImpl(Module
):
235 def __init__(self
, i
, o1
, o2
, clk
):
236 self
.specials
+= Instance("SB_IO",
237 p_PIN_TYPE
= C(0b000000, 6), # PIN_INPUT_DDR
238 p_IO_STANDARD
= "SB_LVCMOS",
247 class LatticeiCE40DDRInput
:
250 return LatticeiCE40DDRInputImpl(dr
.i
, dr
.o1
, dr
.o2
, dr
.clk
)
252 # iCE40 SDR Output ---------------------------------------------------------------------------------
254 class LatticeiCE40SDROutputImpl(Module
):
255 def __init__(self
, i
, o
, clk
):
256 self
.specials
+= Instance("SB_IO",
257 p_PIN_TYPE
= C(0b010100, 6), # PIN_OUTPUT_REGISTERED
258 p_IO_STANDARD
= "SB_LVCMOS",
266 class LatticeiCE40SDROutput
:
269 return LatticeiCE40SDROutputImpl(dr
.i
, dr
.o
, dr
.clk
)
271 # iCE40 SDR Input ----------------------------------------------------------------------------------
273 class LatticeiCE40SDRInput
:
276 return LatticeiCE40DDRInputImpl(dr
.i
, dr
.o
, Signal(), dr
.clk
)
278 # iCE40 SDR Tristate -------------------------------------------------------------------------------
280 class LatticeiCE40SDRTristateImpl(Module
):
281 def __init__(self
, io
, o
, oe
, i
, clk
):
282 self
.specials
+= Instance("SB_IO",
283 p_PIN_TYPE
= C(0b110100, 6), # PIN_OUTPUT_REGISTERED_ENABLE_REGISTERED + PIN_INPUT_REGISTERED
287 i_OUTPUT_ENABLE
= oe
,
292 class LatticeiCE40SDRTristate(Module
):
295 return LatticeiCE40SDRTristateImpl(dr
.io
, dr
.o
, dr
.oe
, dr
.i
, dr
.clk
)
297 # iCE40 Trellis Special Overrides ------------------------------------------------------------------
299 lattice_ice40_special_overrides
= {
300 AsyncResetSynchronizer
: LatticeiCE40AsyncResetSynchronizer
,
301 Tristate
: LatticeiCE40Tristate
,
302 DifferentialOutput
: LatticeiCE40DifferentialOutput
,
303 DDROutput
: LatticeiCE40DDROutput
,
304 DDRInput
: LatticeiCE40DDRInput
,
305 SDROutput
: LatticeiCE40SDROutput
,
306 SDRInput
: LatticeiCE40SDRInput
,
307 SDRTristate
: LatticeiCE40SDRTristate
,