1- import warnings
2-
31from .. import *
4- with warnings .catch_warnings ():
5- warnings .filterwarnings (action = "ignore" , category = DeprecationWarning )
6- from ..hdl .rec import *
7- from ..lib .wiring import In , Out , Signature , flipped , FlippedInterface
8-
9-
10- __all__ = ["pin_layout" , "Pin" ]
11-
12-
13- def _pin_signature (width , dir , xdr = 0 ):
14- if not isinstance (width , int ) or width < 0 :
15- raise TypeError ("Width must be a non-negative integer, not {!r}"
16- .format (width ))
17- if dir not in ("i" , "o" , "oe" , "io" ):
18- raise TypeError ("Direction must be one of \" i\" , \" o\" , \" io\" , or \" oe\" , not {!r}" ""
19- .format (dir ))
20- if not isinstance (xdr , int ) or xdr < 0 :
21- raise TypeError ("Gearing ratio must be a non-negative integer, not {!r}"
22- .format (xdr ))
23-
24- members = {}
25- if dir in ("i" , "io" ):
26- if xdr > 0 :
27- members ["i_clk" ] = In (1 )
28- if xdr > 2 :
29- members ["i_fclk" ] = In (1 )
30- if xdr in (0 , 1 ):
31- members ["i" ] = In (width )
32- else :
33- for n in range (xdr ):
34- members [f"i{ n } " ] = In (width )
35- if dir in ("o" , "oe" , "io" ):
36- if xdr > 0 :
37- members ["o_clk" ] = Out (1 )
38- if xdr > 2 :
39- members ["o_fclk" ] = Out (1 )
40- if xdr in (0 , 1 ):
41- members ["o" ] = Out (width )
42- else :
43- for n in range (xdr ):
44- members [f"o{ n } " ] = Out (width )
45- if dir in ("oe" , "io" ):
46- members ["oe" ] = Out (1 )
47- return Signature (members )
2+ from ..lib import wiring
3+ from ..lib .wiring import In , Out
484
495
50- def pin_layout (width , dir , xdr = 0 ):
51- """
52- Layout of the platform interface of a pin or several pins, which may be used inside
53- user-defined records.
54-
55- See :class:`Pin` for details.
56- """
57- fields = []
58- for name , member in _pin_signature (width , dir , xdr ).members .items ():
59- fields .append ((name , member .shape ))
60- return Layout (fields )
6+ __all__ = ["Pin" ]
617
628
63- class Pin (Record ):
9+ class Pin (wiring . PureInterface ):
6410 """
6511 An interface to an I/O buffer or a group of them that provides uniform access to input, output,
6612 or tristate buffers that may include a 1:n gearbox. (A 1:2 gearbox is typically called "DDR".)
6713
68- A :class:`Pin` is identical to a :class:`Record` that uses the corresponding :meth:`pin_layout`
69- except that it allows accessing the parameters like ``width`` as attributes. It is legal to use
70- a plain :class:`Record` anywhere a :class:`Pin` is used, provided that these attributes are
71- not necessary.
14+ This is an interface object using :class:`Pin.Signature` as its signature. The signature flows
15+ are defined from the point of view of a component that drives the I/O buffer.
7216
7317 Parameters
7418 ----------
@@ -87,8 +31,8 @@ class Pin(Record):
8731 are present instead, where ``N in range(0, N)``. For example, if ``xdr=2``, the I/O buffer
8832 is DDR; the signal ``i0`` reflects the value at the rising edge, and the signal ``i1``
8933 reflects the value at the falling edge.
90- name : str
91- Name of the underlying record .
34+ path : tuple of str
35+ As in :class:`PureInterface`, used to name the created signals .
9236
9337 Attributes
9438 ----------
@@ -119,23 +63,76 @@ class Pin(Record):
11963 cannot change direction more than once per cycle, so at most one output enable signal
12064 is present.
12165 """
122- def __init__ (self , width , dir , * , xdr = 0 , name = None , src_loc_at = 0 ):
123- self .width = width
124- self .dir = dir
125- self .xdr = xdr
12666
127- super ().__init__ (pin_layout (self .width , self .dir , self .xdr ),
128- name = name , src_loc_at = src_loc_at + 1 )
67+ class Signature (wiring .Signature ):
68+ """A signature for :class:`Pin`. The parameters are as defined on the ``Pin`` class,
69+ and are accessible as attributes.
70+ """
71+ def __init__ (self , width , dir , * , xdr = 0 ):
72+ if not isinstance (width , int ) or width < 0 :
73+ raise TypeError ("Width must be a non-negative integer, not {!r}"
74+ .format (width ))
75+ if dir not in ("i" , "o" , "oe" , "io" ):
76+ raise TypeError ("Direction must be one of \" i\" , \" o\" , \" io\" , or \" oe\" , not {!r}" ""
77+ .format (dir ))
78+ if not isinstance (xdr , int ) or xdr < 0 :
79+ raise TypeError ("Gearing ratio must be a non-negative integer, not {!r}"
80+ .format (xdr ))
81+
82+ self .width = width
83+ self .dir = dir
84+ self .xdr = xdr
85+
86+ members = {}
87+ if dir in ("i" , "io" ):
88+ if xdr > 0 :
89+ members ["i_clk" ] = Out (1 )
90+ if xdr > 2 :
91+ members ["i_fclk" ] = Out (1 )
92+ if xdr in (0 , 1 ):
93+ members ["i" ] = In (width )
94+ else :
95+ for n in range (xdr ):
96+ members [f"i{ n } " ] = In (width )
97+ if dir in ("o" , "oe" , "io" ):
98+ if xdr > 0 :
99+ members ["o_clk" ] = Out (1 )
100+ if xdr > 2 :
101+ members ["o_fclk" ] = Out (1 )
102+ if xdr in (0 , 1 ):
103+ members ["o" ] = Out (width )
104+ else :
105+ for n in range (xdr ):
106+ members [f"o{ n } " ] = Out (width )
107+ if dir in ("oe" , "io" ):
108+ members ["oe" ] = Out (1 )
109+ super ().__init__ (members )
110+
111+ def __eq__ (self , other ):
112+ return (type (self ) is type (other ) and
113+ self .width == other .width and
114+ self .dir == other .dir and
115+ self .xdr == other .xdr )
116+
117+ def create (self , * , path = None , src_loc_at = 0 ):
118+ return Pin (self .width , self .dir , xdr = self .xdr , path = path , src_loc_at = 1 + src_loc_at )
119+
120+ def __init__ (self , width , dir , * , xdr = 0 , name = None , path = None , src_loc_at = 0 ):
121+ if name is not None :
122+ if path is None :
123+ raise ValueError ("Cannot pass both name and path" )
124+ path = (name ,)
125+ signature = Pin .Signature (width , dir , xdr = xdr )
126+ super ().__init__ (signature , path = path , src_loc_at = src_loc_at + 1 )
129127
130128 @property
131- def signature (self ):
132- return _pin_signature (self .width , self .dir , self .xdr )
133-
134- def eq (self , other ):
135- first_field , _ , _ = next (iter (Pin (1 , dir = "o" ).layout ))
136- warnings .warn (f"`pin.eq(...)` is deprecated; use `pin.{ first_field } .eq(...)` here" ,
137- DeprecationWarning , stacklevel = 2 )
138- if isinstance (self , FlippedInterface ):
139- return Record .eq (flipped (self ), other )
140- else :
141- return Record .eq (self , other )
129+ def width (self ):
130+ return self .signature .width
131+
132+ @property
133+ def dir (self ):
134+ return self .signature .dir
135+
136+ @property
137+ def xdr (self ):
138+ return self .signature .xdr
0 commit comments