@@ -78,31 +78,36 @@ def __init__(self,
7878
7979 if 'invert' in port_desc .iomodel :
8080 if isinstance (port_desc .iomodel ['invert' ], bool ):
81- self ._invert = [port_desc .iomodel ['invert' ]]* width
81+ self ._invert = [port_desc .iomodel ['invert' ]] * width
8282 else :
8383 self ._invert = port_desc .iomodel ['invert' ]
8484 else :
85- self ._invert = [False ]* width
85+ self ._invert = [False ] * width
8686
8787 self ._name = name
8888
8989 # Initialize signal attributes to None
9090 self ._i = None
91- self ._ie = None
9291 self ._o = None
9392 self ._oe = None
9493 self ._ie = None
9594
9695 # Create signals based on direction
9796 if self .direction in (io .Direction .Input , io .Direction .Bidir ):
9897 self ._i = Signal (width , name = f"{ self ._name } $i" )
99- self ._ie = Signal (width , name = f"{ self ._name } $inp_dis " , init = - 1 )
98+ self ._ie = Signal (width , name = f"{ self ._name } $ie " , init = - 1 )
10099 if self .direction in (io .Direction .Output , io .Direction .Bidir ):
101- self ._o = Signal (width , name = f"{ self ._name } $o" )
100+ init = 0
101+ if 'init' in port_desc .iomodel and port_desc .iomodel ['init' ]:
102+ init = port_desc .iomodel ['init' ]
103+ logger .debug (f"'init' found for self._name. Initialising outputs with { init } " )
104+
105+ self ._o = Signal (width , name = f"{ self ._name } $o" , init = init )
102106
103107 init_oe = - 1
104108 if 'init_oe' in port_desc .iomodel and port_desc .iomodel ['init_oe' ]:
105109 init_oe = port_desc .iomodel ['init_oe' ]
110+ logger .debug (f"'init_oe' found for self._name. Initialising oe with { init_oe } " )
106111
107112 # user side either gets single oe or multiple, depending on 'individual_oe'
108113 # cells side always gets <width> oes. Wired together in the wire method below
@@ -112,46 +117,47 @@ def __init__(self,
112117 else :
113118 self ._oes = Signal (width , name = f"{ self ._name } $oe" , init = init_oe )
114119 self ._oe = self ._oes
115-
116120 logger .debug (f"Created SiliconPlatformPort { self ._name } , with port description:\n { pformat (self ._port_desc )} " )
117121
118- def wire (self , m : Module , interface : PureInterface ):
119- assert self .direction == interface .signature .direction #type: ignore
120- if hasattr (interface , '_i' ):
121- m .d .comb += interface .i .eq (self .i ) # type: ignore
122- for d in ['_o' , '_oe' , '_ie' ]:
123- if hasattr (interface , d ):
124- m .d .comb += getattr (self , d ).eq (getattr (interface , d ))
125- # wire user side _oe to _oes if necessary
126- if self ._oe is not None and self ._oe .shape ().width == 1 and self ._oes .shape ().width > 1 :
127- m .d .comb += self ._oe .eq (self ._oes )
128-
129122 def instantiate_toplevel (self ):
130123 ports = []
131124 if self .direction in (io .Direction .Input , io .Direction .Bidir ):
132125 ports .append ((f"io${ self ._name } $i" , self ._i , PortDirection .Input ))
133126 ports .append ((f"io${ self ._name } $ie" , self ._ie , PortDirection .Output ))
134127 if self .direction in (io .Direction .Output , io .Direction .Bidir ):
135128 ports .append ((f"io${ self ._name } $o" , self ._o , PortDirection .Output ))
136- if self ._oe is not None and self ._oe . shape (). width == 1 and self ._oes . shape (). width > 1 :
129+ if self ._oe is not None and len ( self ._oe ) == 1 and len ( self ._oes ) > 1 :
137130 ports .append ((f"io${ self ._name } $oe" , self ._oes , PortDirection .Output ))
138131 else :
139132 ports .append ((f"io${ self ._name } $oe" , self ._oe , PortDirection .Output ))
140133 return ports
141134
142135 def wire_up (self , m , wire ):
136+ assert self .direction == wire .signature .direction #type: ignore
137+ # wire user side _oe to _oes if necessary
138+ if self ._oe is not None and len (self ._oe ) == 1 and len (self ._oes ) > 1 :
139+ self ._oes .eq (self ._oe .replicate (len (self ._oes )))
140+
143141 inv_mask = sum (inv << bit for bit , inv in enumerate (self .invert ))
144- if hasattr (wire , 'i' ):
145- m .d .comb += wire .i .eq (self .i ^ inv_mask )
146- if hasattr (wire , 'o' ):
147- m .d .comb += self .o .eq (wire .o ^ inv_mask )
148- if hasattr (wire , 'oe' ):
149- m .d .comb += self .oe .eq (wire .oe )
142+ if hasattr (wire , 'i' ) and wire .i is not None :
143+ assert self ._i is not None
144+ m .d .comb += wire .i .eq (self ._i ^ inv_mask )
145+ if hasattr (wire , 'o' ) and wire .o is not None :
146+ assert self ._o is not None
147+ m .d .comb += self ._o .eq (wire .o ^ inv_mask )
148+ if hasattr (wire , 'oe' ) and wire .oe is not None :
149+ assert self ._oe is not None
150+ m .d .comb += self ._oe .eq (wire .oe )
151+ elif self .direction in (io .Direction .Output , io .Direction .Bidir ):
152+ m .d .comb += self ._oes .eq (- 1 ) # set output enabled if the user hasn't connected
150153
151154 if hasattr (wire , 'ie' ):
152- m .d .comb += self .ie .eq (wire .ie )
153- elif hasattr (wire , 'oe' ):
154- m .d .comb += self .ie .eq (wire .oe )
155+ assert self ._ie is not None
156+ m .d .comb += self ._ie .eq (wire .ie )
157+ elif self .direction is io .Direction .Bidir :
158+ assert self ._oes is not None
159+ assert self ._ie is not None
160+ m .d .comb += self ._ie .eq (~ self ._oes )
155161
156162
157163 @property
@@ -238,7 +244,7 @@ class Sky130Port(SiliconPlatformPort):
238244 """
239245 Specialisation of `SiliconPlatformPort` for the `Skywater sky130_fd_io__gpiov2 IO cell <https://skywater-pdk.readthedocs.io/en/main/contents/libraries/sky130_fd_io/docs/user_guide.html>`_
240246
241- Includes wires and configuration for `Drive Modes <IODriveMode>`, `Input buffer trip point <IOTripPoint>`and buffer control~
247+ Includes wires and configuration for `Drive Modes <IODriveMode>`, `Input buffer trip point <IOTripPoint>`and buffer control
242248 """
243249
244250 _DriveMode_map = {
@@ -280,17 +286,6 @@ def __init__(self,
280286 # keep a list of signals we create
281287 self ._signals = []
282288
283- # Now create the signals for ``gpio_oeb`` (``oe_n``), ``gpio_inp_dis`` (``ie_n``)
284- self ._oe_n = None
285-
286- if self ._oe is not None :
287- self ._oe_n = Signal (self ._oe .shape ().width , name = f"{ self ._name } $oeb" )
288- self ._signals .append ((self ._oe_n , PortDirection .Output ))
289-
290- if self ._ie is not None :
291- self ._ie_n = Signal (self ._ie .shape ().width , name = f"{ self ._name } $inp_dis" )
292- self ._signals .append ((self ._ie_n , PortDirection .Output ))
293-
294289 # Port Configuration
295290 # Input voltage trip level
296291 if self .direction in (io .Direction .Input , io .Direction .Bidir ):
@@ -304,9 +299,9 @@ def __init__(self,
304299 else :
305300 ib_mode_init = vtrip_init = 0
306301
307- self ._ib_mode_sel = Signal (self . _i . shape (). width , name = f"{ self ._name } $ib_mode_sel" , init = ib_mode_init )
302+ self ._ib_mode_sel = Signal (width , name = f"{ self ._name } $ib_mode_sel" , init = ib_mode_init )
308303 self ._signals .append ((self ._ib_mode_sel , PortDirection .Output ))
309- self ._vtrip_sel = Signal (self . _i . shape (). width , name = f"{ self ._name } $vtrip_sel" , init = vtrip_init )
304+ self ._vtrip_sel = Signal (width , name = f"{ self ._name } $vtrip_sel" , init = vtrip_init )
310305 self ._signals .append ((self ._vtrip_sel , PortDirection .Output ))
311306
312307 # Drive mode
@@ -320,11 +315,11 @@ def __init__(self,
320315 dm_init = __class__ ._DriveMode_map [dm ]
321316 dm_init_bits = [ int (b ) for b in f"{ dm_init :b} " ]
322317 dms_shape = data .ArrayLayout (unsigned (3 ), width )
323- self ._dms = Signal (dms_shape , name = f"{ self ._name } $dms" , init = [dm_init ]* width )
318+ self ._dms = Signal (dms_shape , name = f"{ self ._name } $dms" , init = [dm_init ] * width )
324319 all_ones = (2 << (width - 1 ))- 1
325- self ._dm0 = Signal (width , name = f"{ self ._name } $dm0" , init = dm_init_bits [0 ]* all_ones )
326- self ._dm1 = Signal (width , name = f"{ self ._name } $dm1" , init = dm_init_bits [1 ]* all_ones )
327- self ._dm2 = Signal (width , name = f"{ self ._name } $dm2" , init = dm_init_bits [2 ]* all_ones )
320+ self ._dm0 = Signal (width , name = f"{ self ._name } $dm0" , init = dm_init_bits [0 ] * all_ones )
321+ self ._dm1 = Signal (width , name = f"{ self ._name } $dm1" , init = dm_init_bits [1 ] * all_ones )
322+ self ._dm2 = Signal (width , name = f"{ self ._name } $dm2" , init = dm_init_bits [2 ] * all_ones )
328323 self ._signals .append ((self ._dm0 , PortDirection .Output )) #type: ignore
329324 self ._signals .append ((self ._dm1 , PortDirection .Output )) #type: ignore
330325 self ._signals .append ((self ._dm2 , PortDirection .Output )) #type: ignore
@@ -347,14 +342,6 @@ def instantiate_toplevel(self):
347342
348343 def wire_up (self , m , wire ):
349344 super ().wire_up (m , wire )
350- # wire up oe_n = ~oe
351- if self ._oe is not None :
352- assert self ._oe_n is not None
353- m .d .comb += self ._oe_n .eq (~ self ._oe )
354-
355- if self ._ie is not None :
356- assert self ._ie_n is not None
357- m .d .comb += self ._ie_n .eq (~ self ._ie )
358345
359346 if hasattr (wire , 'drive_mode' ):
360347 m .d .comb += self .drive_mode .eq (wire .drive_mode )
0 commit comments