Merge pull request #597 from antmicro/jboc/litex-buildenv-add-adapter-fix
[litex.git] / litex / build / lattice / common.py
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>
4 # License: BSD
5
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
10
11 from litex.build.io import *
12
13 # ECP5 AsyncResetSynchronizer ----------------------------------------------------------------------
14
15 class LatticeECP5AsyncResetSynchronizerImpl(Module):
16 def __init__(self, cd, async_reset):
17 rst1 = Signal()
18 self.specials += [
19 Instance("FD1S3BX",
20 i_D = 0,
21 i_PD = async_reset,
22 i_CK = cd.clk,
23 o_Q = rst1),
24 Instance("FD1S3BX",
25 i_D = rst1,
26 i_PD = async_reset,
27 i_CK = cd.clk,
28 o_Q = cd.rst)
29 ]
30
31
32 class LatticeECP5AsyncResetSynchronizer:
33 @staticmethod
34 def lower(dr):
35 return LatticeECP5AsyncResetSynchronizerImpl(dr.cd, dr.async_reset)
36
37
38 # ECP5 SDR Input -----------------------------------------------------------------------------------
39
40 class LatticeECP5SDRInputImpl(Module):
41 def __init__(self, i, o, clk):
42 self.specials += Instance("IFS1P3BX",
43 i_SCLK = clk,
44 i_PD = 0,
45 i_SP = 1,
46 i_D = i,
47 o_Q = o,
48 )
49
50 class LatticeECP5SDRInput:
51 @staticmethod
52 def lower(dr):
53 return LatticeECP5SDRInputImpl(dr.i, dr.o, dr.clk)
54
55 # ECP5 SDR Output ----------------------------------------------------------------------------------
56
57 class LatticeECP5SDROutputImpl(Module):
58 def __init__(self, i, o, clk):
59 self.specials += Instance("OFS1P3BX",
60 i_SCLK = clk,
61 i_PD = 0,
62 i_SP = 1,
63 i_D = i,
64 o_Q = o,
65 )
66
67 class LatticeECP5SDROutput:
68 @staticmethod
69 def lower(dr):
70 return LatticeECP5SDROutputImpl(dr.i, dr.o, dr.clk)
71
72 # ECP5 DDR Input -----------------------------------------------------------------------------------
73
74 class LatticeECP5DDRInputImpl(Module):
75 def __init__(self, i, o1, o2, clk):
76 self.specials += Instance("IDDRX1F",
77 i_SCLK = clk,
78 i_D = i,
79 o_Q0 = o1,
80 o_Q1 = o2,
81 )
82
83 class LatticeECP5DDRInput:
84 @staticmethod
85 def lower(dr):
86 return LatticeECP5DDRInputImpl(dr.i, dr.o1, dr.o2, dr.clk)
87
88 # ECP5 DDR Output ----------------------------------------------------------------------------------
89
90 class LatticeECP5DDROutputImpl(Module):
91 def __init__(self, i1, i2, o, clk):
92 self.specials += Instance("ODDRX1F",
93 i_SCLK = clk,
94 i_D0 = i1,
95 i_D1 = i2,
96 o_Q = o,
97 )
98
99 class LatticeECP5DDROutput:
100 @staticmethod
101 def lower(dr):
102 return LatticeECP5DDROutputImpl(dr.i1, dr.i2, dr.o, dr.clk)
103
104 # ECP5 Special Overrides ---------------------------------------------------------------------------
105
106 lattice_ecp5_special_overrides = {
107 AsyncResetSynchronizer: LatticeECP5AsyncResetSynchronizer,
108 SDRInput: LatticeECP5SDRInput,
109 SDROutput: LatticeECP5SDROutput,
110 DDRInput: LatticeECP5DDRInput,
111 DDROutput: LatticeECP5DDROutput,
112 }
113
114 # ECP5 Trellis Tristate ----------------------------------------------------------------------------
115
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",
121 p_DIR = "BIDIR",
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,
125 i_T = ~oe
126 )
127
128 class LatticeECP5TrellisTristate(Module):
129 @staticmethod
130 def lower(dr):
131 return LatticeECP5TrellisTristateImpl(dr.target, dr.o, dr.oe, dr.i)
132
133 # ECP5 Trellis Special Overrides -------------------------------------------------------------------
134
135 lattice_ecp5_trellis_special_overrides = {
136 AsyncResetSynchronizer: LatticeECP5AsyncResetSynchronizer,
137 Tristate: LatticeECP5TrellisTristate,
138 SDRInput: LatticeECP5SDRInput,
139 SDROutput: LatticeECP5SDROutput,
140 DDRInput: LatticeECP5DDRInput,
141 DDROutput: LatticeECP5DDROutput
142 }
143
144 # iCE40 AsyncResetSynchronizer ----------------------------------------------------------------------
145
146 class LatticeiCE40AsyncResetSynchronizerImpl(Module):
147 def __init__(self, cd, async_reset):
148 rst1 = Signal()
149 self.specials += [
150 Instance("SB_DFFS",
151 i_D = 0,
152 i_S = async_reset,
153 i_C = cd.clk,
154 o_Q = rst1),
155 Instance("SB_DFFS",
156 i_D = rst1,
157 i_S = async_reset,
158 i_C = cd.clk,
159 o_Q = cd.rst)
160 ]
161
162
163 class LatticeiCE40AsyncResetSynchronizer:
164 @staticmethod
165 def lower(dr):
166 return LatticeiCE40AsyncResetSynchronizerImpl(dr.cd, dr.async_reset)
167
168 # iCE40 Tristate -----------------------------------------------------------------------------------
169
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,
180 )
181
182 class LatticeiCE40Tristate(Module):
183 @staticmethod
184 def lower(dr):
185 return LatticeiCE40TristateImpl(dr.target, dr.o, dr.oe, dr.i)
186
187 # iCE40 Differential Output ------------------------------------------------------------------------
188
189 class LatticeiCE40DifferentialOutputImpl(Module):
190 def __init__(self, i, o_p, o_n):
191 self.specials += [
192 Instance("SB_IO",
193 p_PIN_TYPE = C(0b011000, 6), # PIN_OUTPUT
194 p_IO_STANDARD = "SB_LVCMOS",
195 io_PACKAGE_PIN = o_p,
196 i_D_OUT_0 = i
197 ),
198 Instance("SB_IO",
199 p_PIN_TYPE = C(0b011000, 6), # PIN_OUTPUT
200 p_IO_STANDARD = "SB_LVCMOS",
201 io_PACKAGE_PIN = o_n,
202 i_D_OUT_0 = ~i
203 )
204 ]
205
206 class LatticeiCE40DifferentialOutput:
207 @staticmethod
208 def lower(dr):
209 return LatticeiCE40DifferentialOutputImpl(dr.i, dr.o_p, dr.o_n)
210
211 # iCE40 DDR Output ---------------------------------------------------------------------------------
212
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",
218 io_PACKAGE_PIN = o,
219 i_CLOCK_ENABLE = 1,
220 i_OUTPUT_CLK = clk,
221 i_OUTPUT_ENABLE = 1,
222 i_D_OUT_0 = i1,
223 i_D_OUT_1 = i2
224 )
225
226
227 class LatticeiCE40DDROutput:
228 @staticmethod
229 def lower(dr):
230 return LatticeiCE40DDROutputImpl(dr.i1, dr.i2, dr.o, dr.clk)
231
232 # iCE40 DDR Input ----------------------------------------------------------------------------------
233
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",
239 io_PACKAGE_PIN = i,
240 i_CLOCK_ENABLE = 1,
241 i_INPUT_CLK = clk,
242 o_D_IN_0 = o1,
243 o_D_IN_1 = o2
244 )
245
246
247 class LatticeiCE40DDRInput:
248 @staticmethod
249 def lower(dr):
250 return LatticeiCE40DDRInputImpl(dr.i, dr.o1, dr.o2, dr.clk)
251
252 # iCE40 SDR Output ---------------------------------------------------------------------------------
253
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",
259 io_PACKAGE_PIN = o,
260 i_CLOCK_ENABLE = 1,
261 i_OUTPUT_CLK = clk,
262 i_OUTPUT_ENABLE = 1,
263 i_D_OUT_0 = i
264 )
265
266 class LatticeiCE40SDROutput:
267 @staticmethod
268 def lower(dr):
269 return LatticeiCE40SDROutputImpl(dr.i, dr.o, dr.clk)
270
271 # iCE40 SDR Input ----------------------------------------------------------------------------------
272
273 class LatticeiCE40SDRInput:
274 @staticmethod
275 def lower(dr):
276 return LatticeiCE40DDRInputImpl(dr.i, dr.o, Signal(), dr.clk)
277
278 # iCE40 SDR Tristate -------------------------------------------------------------------------------
279
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
284 io_PACKAGE_PIN = io,
285 i_INPUT_CLK = clk,
286 i_OUTPUT_CLK = clk,
287 i_OUTPUT_ENABLE = oe,
288 i_D_OUT_0 = o,
289 o_D_IN_0 = i,
290 )
291
292 class LatticeiCE40SDRTristate(Module):
293 @staticmethod
294 def lower(dr):
295 return LatticeiCE40SDRTristateImpl(dr.io, dr.o, dr.oe, dr.i, dr.clk)
296
297 # iCE40 Trellis Special Overrides ------------------------------------------------------------------
298
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,
308 }