1212from ..hdl ._ir import IOBufferInstance , Design
1313from ..hdl ._xfrm import DomainLowerer
1414from ..lib .cdc import ResetSynchronizer
15+ from ..lib import io
1516from ..back import rtlil , verilog
1617from .res import *
1718from .run import *
@@ -138,8 +139,13 @@ def prepare(self, elaboratable, name="top", **kwargs):
138139 fragment ._propagate_domains (self .create_missing_domain , platform = self )
139140 fragment = DomainLowerer ()(fragment )
140141
142+ def missing_domain_error (name ):
143+ raise RuntimeError ("Missing domain in pin fragment" )
144+
141145 def add_pin_fragment (pin , pin_fragment ):
142146 pin_fragment = Fragment .get (pin_fragment , self )
147+ pin_fragment ._propagate_domains (missing_domain_error )
148+ pin_fragment = DomainLowerer ()(pin_fragment )
143149 fragment .add_subfragment (pin_fragment , name = f"pin_{ pin .name } " )
144150
145151 for pin , port , attrs , invert in self .iter_single_ended_pins ():
@@ -162,8 +168,7 @@ def add_pin_fragment(pin, pin_fragment):
162168 if pin .dir == "io" :
163169 add_pin_fragment (pin , self .get_diff_input_output (pin , port , attrs , invert ))
164170
165- ports = [(None , signal , None ) for signal in self .iter_ports ()]
166- fragment = Design (fragment , ports , hierarchy = (name ,))
171+ fragment = Design (fragment , [], hierarchy = (name ,))
167172 return self .toolchain_prepare (fragment , name , ** kwargs )
168173
169174 @abstractmethod
@@ -201,63 +206,87 @@ def _invert_if(invert, value):
201206 return value
202207
203208 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 )
206211
207212 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 )
209227 return m
210228
211229 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 )
214232
215233 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 )
217250 return m
218251
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
230253
231254 def get_input_output (self , pin , port , attrs , invert ):
232255 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 )
234257
235258 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 )
244284 return m
245285
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
261290
262291
263292class TemplatedPlatform (Platform ):
0 commit comments