12
12
from ..hdl ._ir import IOBufferInstance , Design
13
13
from ..hdl ._xfrm import DomainLowerer
14
14
from ..lib .cdc import ResetSynchronizer
15
+ from ..lib import io
15
16
from ..back import rtlil , verilog
16
17
from .res import *
17
18
from .run import *
@@ -138,8 +139,13 @@ def prepare(self, elaboratable, name="top", **kwargs):
138
139
fragment ._propagate_domains (self .create_missing_domain , platform = self )
139
140
fragment = DomainLowerer ()(fragment )
140
141
142
+ def missing_domain_error (name ):
143
+ raise RuntimeError ("Missing domain in pin fragment" )
144
+
141
145
def add_pin_fragment (pin , pin_fragment ):
142
146
pin_fragment = Fragment .get (pin_fragment , self )
147
+ pin_fragment ._propagate_domains (missing_domain_error )
148
+ pin_fragment = DomainLowerer ()(pin_fragment )
143
149
fragment .add_subfragment (pin_fragment , name = f"pin_{ pin .name } " )
144
150
145
151
for pin , port , attrs , invert in self .iter_single_ended_pins ():
@@ -162,8 +168,7 @@ def add_pin_fragment(pin, pin_fragment):
162
168
if pin .dir == "io" :
163
169
add_pin_fragment (pin , self .get_diff_input_output (pin , port , attrs , invert ))
164
170
165
- ports = [(None , signal , None ) for signal in self .iter_ports ()]
166
- fragment = Design (fragment , ports , hierarchy = (name ,))
171
+ fragment = Design (fragment , [], hierarchy = (name ,))
167
172
return self .toolchain_prepare (fragment , name , ** kwargs )
168
173
169
174
@abstractmethod
@@ -201,63 +206,87 @@ def _invert_if(invert, value):
201
206
return value
202
207
203
208
def get_input (self , pin , port , attrs , invert ):
204
- self ._check_feature ("single-ended input" , pin , attrs ,
205
- valid_xdrs = (0 ,), valid_attrs = None )
209
+ self ._check_feature ("input" , pin , attrs ,
210
+ valid_xdrs = (0 , 1 , 2 ), valid_attrs = True )
206
211
207
212
m = Module ()
208
- m .d .comb += pin .i .eq (self ._invert_if (invert , port ))
213
+ if pin .xdr == 0 :
214
+ m .submodules .buf = buf = io .Buffer (io .Direction .Input , port )
215
+ m .d .comb += pin .i .eq (buf .i )
216
+ elif pin .xdr == 1 :
217
+ m .domains .input = cd_input = ClockDomain (reset_less = True )
218
+ m .submodules .buf = buf = io .FFBuffer (io .Direction .Input , port , i_domain = "input" )
219
+ m .d .comb += pin .i .eq (buf .i )
220
+ m .d .comb += cd_input .clk .eq (pin .i_clk )
221
+ elif pin .xdr == 2 :
222
+ m .domains .input = cd_input = ClockDomain (reset_less = True )
223
+ m .submodules .buf = buf = io .DDRBuffer (io .Direction .Input , port , i_domain = "input" )
224
+ m .d .comb += pin .i0 .eq (buf .i [0 ])
225
+ m .d .comb += pin .i1 .eq (buf .i [1 ])
226
+ m .d .comb += cd_input .clk .eq (pin .i_clk )
209
227
return m
210
228
211
229
def get_output (self , pin , port , attrs , invert ):
212
- self ._check_feature ("single-ended output" , pin , attrs ,
213
- valid_xdrs = (0 ,), valid_attrs = None )
230
+ self ._check_feature ("output" , pin , attrs ,
231
+ valid_xdrs = (0 , 1 , 2 ), valid_attrs = True )
214
232
215
233
m = Module ()
216
- m .d .comb += port .eq (self ._invert_if (invert , pin .o ))
234
+ if pin .xdr == 0 :
235
+ m .submodules .buf = buf = io .Buffer (io .Direction .Output , port )
236
+ m .d .comb += buf .o .eq (pin .o )
237
+ elif pin .xdr == 1 :
238
+ m .domains .output = cd_output = ClockDomain (reset_less = True )
239
+ m .submodules .buf = buf = io .FFBuffer (io .Direction .Output , port , o_domain = "output" )
240
+ m .d .comb += buf .o .eq (pin .o )
241
+ m .d .comb += cd_output .clk .eq (pin .o_clk )
242
+ elif pin .xdr == 2 :
243
+ m .domains .output = cd_output = ClockDomain (reset_less = True )
244
+ m .submodules .buf = buf = io .DDRBuffer (io .Direction .Output , port , o_domain = "output" )
245
+ m .d .comb += buf .o [0 ].eq (pin .o0 )
246
+ m .d .comb += buf .o [1 ].eq (pin .o1 )
247
+ m .d .comb += cd_output .clk .eq (pin .o_clk )
248
+ if pin .dir == "oe" :
249
+ m .d .comb += buf .oe .eq (pin .oe )
217
250
return m
218
251
219
- def get_tristate (self , pin , port , attrs , invert ):
220
- self ._check_feature ("single-ended tristate" , pin , attrs ,
221
- valid_xdrs = (0 ,), valid_attrs = None )
222
-
223
- m = Module ()
224
- m .submodules += IOBufferInstance (
225
- port = port ,
226
- o = self ._invert_if (invert , pin .o ),
227
- oe = pin .oe ,
228
- )
229
- return m
252
+ get_tristate = get_output
230
253
231
254
def get_input_output (self , pin , port , attrs , invert ):
232
255
self ._check_feature ("single-ended input/output" , pin , attrs ,
233
- valid_xdrs = (0 ,), valid_attrs = None )
256
+ valid_xdrs = (0 , 1 , 2 ), valid_attrs = True )
234
257
235
258
m = Module ()
236
- i = Signal .like (pin .i )
237
- m .submodules += IOBufferInstance (
238
- port = port ,
239
- i = i ,
240
- o = self ._invert_if (invert , pin .o ),
241
- oe = pin .oe ,
242
- )
243
- m .d .comb += pin .i .eq (self ._invert_if (invert , i ))
259
+ if pin .xdr == 0 :
260
+ m .submodules .buf = buf = io .Buffer (io .Direction .Bidir , port )
261
+ m .d .comb += pin .i .eq (buf .i )
262
+ m .d .comb += buf .o .eq (pin .o )
263
+ m .d .comb += buf .oe .eq (pin .oe )
264
+ elif pin .xdr == 1 :
265
+ m .domains .input = cd_input = ClockDomain (reset_less = True )
266
+ m .domains .output = cd_output = ClockDomain (reset_less = True )
267
+ m .submodules .buf = buf = io .FFBuffer (io .Direction .Bidir , port , i_domain = "input" , o_domain = "output" )
268
+ m .d .comb += pin .i .eq (buf .i )
269
+ m .d .comb += buf .o .eq (pin .o )
270
+ m .d .comb += buf .oe .eq (pin .oe )
271
+ m .d .comb += cd_input .clk .eq (pin .i_clk )
272
+ m .d .comb += cd_output .clk .eq (pin .o_clk )
273
+ elif pin .xdr == 2 :
274
+ m .domains .input = cd_input = ClockDomain (reset_less = True )
275
+ m .domains .output = cd_output = ClockDomain (reset_less = True )
276
+ m .submodules .buf = buf = io .DDRBuffer (io .Direction .Bidir , port , i_domain = "input" , o_domain = "output" )
277
+ m .d .comb += pin .i0 .eq (buf .i [0 ])
278
+ m .d .comb += pin .i1 .eq (buf .i [1 ])
279
+ m .d .comb += buf .o [0 ].eq (pin .o0 )
280
+ m .d .comb += buf .o [1 ].eq (pin .o1 )
281
+ m .d .comb += buf .oe .eq (pin .oe )
282
+ m .d .comb += cd_input .clk .eq (pin .i_clk )
283
+ m .d .comb += cd_output .clk .eq (pin .o_clk )
244
284
return m
245
285
246
- def get_diff_input (self , pin , port , attrs , invert ):
247
- self ._check_feature ("differential input" , pin , attrs ,
248
- valid_xdrs = (), valid_attrs = None )
249
-
250
- def get_diff_output (self , pin , port , attrs , invert ):
251
- self ._check_feature ("differential output" , pin , attrs ,
252
- valid_xdrs = (), valid_attrs = None )
253
-
254
- def get_diff_tristate (self , pin , port , attrs , invert ):
255
- self ._check_feature ("differential tristate" , pin , attrs ,
256
- valid_xdrs = (), valid_attrs = None )
257
-
258
- def get_diff_input_output (self , pin , port , attrs , invert ):
259
- self ._check_feature ("differential input/output" , pin , attrs ,
260
- valid_xdrs = (), valid_attrs = None )
286
+ get_diff_input = get_input
287
+ get_diff_output = get_output
288
+ get_diff_tristate = get_tristate
289
+ get_diff_input_output = get_input_output
261
290
262
291
263
292
class TemplatedPlatform (Platform ):
0 commit comments