build/lattice: cleanup/simplify
[litex.git] / litex / build / lattice / common.py
1 # This file is Copyright (c) 2015-2019 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.io import *
10 from migen.genlib.resetsync import AsyncResetSynchronizer
11
12 # ECPX AsyncResetSynchronizer ----------------------------------------------------------------------
13
14 class LatticeECPXAsyncResetSynchronizerImpl(Module):
15 def __init__(self, cd, async_reset):
16 rst1 = Signal()
17 self.specials += [
18 Instance("FD1S3BX",
19 i_D = 0,
20 i_PD = async_reset,
21 i_CK = cd.clk,
22 o_Q = rst1),
23 Instance("FD1S3BX",
24 i_D = rst1,
25 i_PD = async_reset,
26 i_CK = cd.clk,
27 o_Q = cd.rst)
28 ]
29
30
31 class LatticeECPXAsyncResetSynchronizer:
32 @staticmethod
33 def lower(dr):
34 return LatticeECPXAsyncResetSynchronizerImpl(dr.cd, dr.async_reset)
35
36 # ECPX Differential Output -------------------------------------------------------------------------
37
38 class LatticeECPXDDROutputImpl(Module):
39 def __init__(self, i1, i2, o, clk):
40 self.specials += [
41 Instance("ODDRXD1",
42 synthesis_directive="ODDRAPPS=\"SCLK_ALIGNED\"",
43 i_SCLK = clk,
44 i_DA = i1,
45 i_DB = i2,
46 o_Q = o)
47 ]
48
49
50 class LatticeECPXDDROutput:
51 @staticmethod
52 def lower(dr):
53 return LatticeECPXDDROutputImpl(dr.i1, dr.i2, dr.o, dr.clk)
54
55 # ECPX Special Overrides ---------------------------------------------------------------------------
56
57 lattice_ecpx_special_overrides = {
58 AsyncResetSynchronizer: LatticeECPXAsyncResetSynchronizer,
59 DDROutput: LatticeECPXDDROutput
60 }
61
62 # ECPX Trellis Tristate ----------------------------------------------------------------------------
63
64 class LatticeECPXTrellisTristateImpl(Module):
65 def __init__(self, io, o, oe, i):
66 nbits, sign = value_bits_sign(io)
67 if nbits == 1:
68 self.specials += [
69 Instance("TRELLIS_IO",
70 p_DIR = "BIDIR",
71 i_B = io,
72 i_I = o,
73 o_O = i,
74 i_T = ~oe
75 )
76 ]
77 else:
78 for bit in range(nbits):
79 self.specials += [
80 Instance("TRELLIS_IO",
81 p_DIR="BIDIR",
82 i_B = io[bit],
83 i_I = o[bit],
84 o_O = i[bit],
85 i_T = ~oe
86 )
87 ]
88
89
90 class LatticeECPXTrellisTristate(Module):
91 @staticmethod
92 def lower(dr):
93 return LatticeECPXTrellisTristateImpl(dr.target, dr.o, dr.oe, dr.i)
94
95 # ECPX Trellis Special Overrides -------------------------------------------------------------------
96
97 lattice_ecpx_trellis_special_overrides = {
98 AsyncResetSynchronizer: LatticeECPXAsyncResetSynchronizer,
99 Tristate: LatticeECPXTrellisTristate,
100 DDROutput: LatticeECPXDDROutput
101 }
102
103 # iCE40 AsyncResetSynchronizer ----------------------------------------------------------------------
104
105 class LatticeiCE40AsyncResetSynchronizerImpl(Module):
106 def __init__(self, cd, async_reset):
107 rst1 = Signal()
108 self.specials += [
109 Instance("SB_DFFS", i_D=0, i_S=async_reset,
110 i_C=cd.clk, o_Q=rst1),
111 Instance("SB_DFFS", i_D=rst1, i_S=async_reset,
112 i_C=cd.clk, o_Q=cd.rst)
113 ]
114
115
116 class LatticeiCE40AsyncResetSynchronizer:
117 @staticmethod
118 def lower(dr):
119 return LatticeiCE40AsyncResetSynchronizerImpl(dr.cd, dr.async_reset)
120
121 # iCE40 Trellis Tristate ---------------------------------------------------------------------------
122
123 class LatticeiCE40TristateImpl(Module):
124 def __init__(self, io, o, oe, i):
125 nbits, sign = value_bits_sign(io)
126 if nbits == 1:
127 self.specials += [
128 Instance("SB_IO",
129 p_PIN_TYPE = C(0b101001, 6),
130 io_PACKAGE_PIN = io,
131 i_OUTPUT_ENABLE = oe,
132 i_D_OUT_0 = o,
133 o_D_IN_0 = i
134 )
135 ]
136 else:
137 for bit in range(nbits):
138 self.specials += [
139 Instance("SB_IO",
140 p_PIN_TYPE = C(0b101001, 6),
141 io_PACKAGE_PIN = io[bit],
142 i_OUTPUT_ENABLE = oe,
143 i_D_OUT_0 = o[bit],
144 o_D_IN_0 = i[bit]
145 )
146 ]
147
148
149 class LatticeiCE40Tristate(Module):
150 @staticmethod
151 def lower(dr):
152 return LatticeiCE40TristateImpl(dr.target, dr.o, dr.oe, dr.i)
153
154 # iCE40 Differential Output ------------------------------------------------------------------------
155
156 class LatticeiCE40DifferentialOutputImpl(Module):
157 def __init__(self, i, o_p, o_n):
158 self.specials += [
159 Instance("SB_IO",
160 p_PIN_TYPE = C(0b011000, 6),
161 p_IO_STANDARD = "SB_LVCMOS",
162 io_PACKAGE_PIN = o_p,
163 i_D_OUT_0 = i
164 )
165 ]
166
167 self.specials += [
168 Instance("SB_IO",
169 p_PIN_TYPE = C(0b011000, 6),
170 p_IO_STANDARD = "SB_LVCMOS",
171 io_PACKAGE_PIN = o_n,
172 i_D_OUT_0 = ~i
173 )
174 ]
175
176
177 class LatticeiCE40DifferentialOutput:
178 @staticmethod
179 def lower(dr):
180 return LatticeiCE40DifferentialOutputImpl(dr.i, dr.o_p, dr.o_n)
181
182
183 # iCE40 DDR Output ---------------------------------------------------------------------------------
184
185 class LatticeiCE40DDROutputImpl(Module):
186 def __init__(self, i1, i2, o, clk):
187 self.specials += [
188 Instance("SB_IO",
189 p_PIN_TYPE = C(0b010000, 6),
190 p_IO_STANDARD = "SB_LVCMOS",
191 io_PACKAGE_PIN = o,
192 i_CLOCK_ENABLE = 1,
193 i_OUTPUT_CLK = clk,
194 i_OUTPUT_ENABLE = 1,
195 i_D_OUT_0 = i1,
196 i_D_OUT_1 = i2
197 )
198 ]
199
200
201 class LatticeiCE40DDROutput:
202 @staticmethod
203 def lower(dr):
204 return LatticeiCE40DDROutputImpl(dr.i1, dr.i2, dr.o, dr.clk)
205
206 # iCE40 Trellis Special Overrides ------------------------------------------------------------------
207
208 lattice_ice40_special_overrides = {
209 AsyncResetSynchronizer: LatticeiCE40AsyncResetSynchronizer,
210 Tristate: LatticeiCE40Tristate,
211 DifferentialOutput: LatticeiCE40DifferentialOutput,
212 DDROutput: LatticeiCE40DDROutput
213 }