@@ -96,60 +96,67 @@ def __init__(self,
9696 self ._i = Signal (width , name = f"{ self ._name } $i" )
9797 self ._ie = Signal (width , name = f"{ self ._name } $ie" , init = - 1 )
9898 if self .direction in (io .Direction .Output , io .Direction .Bidir ):
99- self ._o = Signal (width , name = f"{ self ._name } $o" )
99+ init = 0
100+ if 'init' in port_desc .iomodel and port_desc .iomodel ['init' ]:
101+ init = port_desc .iomodel ['init' ]
102+ logger .debug (f"'init' found for self._name. Initialising outputs with { init } " )
103+
104+ self ._o = Signal (width , name = f"{ self ._name } $o" , init = init )
100105
101106 init_oe = - 1
102107 if 'init_oe' in port_desc .iomodel and port_desc .iomodel ['init_oe' ]:
103108 init_oe = port_desc .iomodel ['init_oe' ]
109+ logger .debug (f"'init_oe' found for self._name. Initialising oe with { init_oe } " )
104110
105111 # user side either gets single oe or multiple, depending on 'individual_oe'
106112 # cells side always gets <width> oes. Wired together in the wire method below
107113 if "individual_oe" not in self .iomodel or not self .iomodel ["individual_oe" ]:
108114 self ._oe = Signal (1 , name = f"{ self ._name } $oe" , init = init_oe )
109- self ._oes = Signal (width , name = f"{ self ._name } $oe" )
115+ self ._oes = Signal (width , name = f"{ self ._name } $oe" )
110116 else :
111117 self ._oes = Signal (width , name = f"{ self ._name } $oe" , init = init_oe )
112118 self ._oe = self ._oes
113-
114119 logger .debug (f"Created SiliconPlatformPort { self ._name } , with port description:\n { pformat (self ._port_desc )} " )
115120
116- def wire (self , m : Module , interface : PureInterface ):
117- assert self .direction == interface .signature .direction #type: ignore
118- if hasattr (interface , '_i' ):
119- m .d .comb += interface .i .eq (self .i ) # type: ignore
120- for d in ['_o' , '_oe' , '_ie' ]:
121- if hasattr (interface , d ):
122- m .d .comb += getattr (self , d ).eq (getattr (interface , d ))
123- # wire user side _oe to _oes if necessary
124- if self ._oe is not None and self ._oe .shape ().width == 1 and self ._oes .shape ().width > 1 :
125- m .d .comb += self ._oe .eq (self ._oes )
126-
127121 def instantiate_toplevel (self ):
128122 ports = []
129123 if self .direction in (io .Direction .Input , io .Direction .Bidir ):
130124 ports .append ((f"io${ self ._name } $i" , self ._i , PortDirection .Input ))
131125 ports .append ((f"io${ self ._name } $ie" , self ._ie , PortDirection .Output ))
132126 if self .direction in (io .Direction .Output , io .Direction .Bidir ):
133127 ports .append ((f"io${ self ._name } $o" , self ._o , PortDirection .Output ))
134- if self ._oe is not None and self ._oe . shape (). width == 1 and self ._oes . shape (). width > 1 :
128+ if self ._oe is not None and len ( self ._oe ) == 1 and len ( self ._oes ) > 1 :
135129 ports .append ((f"io${ self ._name } $oe" , self ._oes , PortDirection .Output ))
136130 else :
137131 ports .append ((f"io${ self ._name } $oe" , self ._oe , PortDirection .Output ))
138132 return ports
139133
140134 def wire_up (self , m , wire ):
135+ assert self .direction == wire .signature .direction #type: ignore
136+ # wire user side _oe to _oes if necessary
137+ if self ._oe is not None and len (self ._oe ) == 1 and len (self ._oes ) > 1 :
138+ self ._oes .eq (self ._oe .replicate (len (self ._oes )))
139+
141140 inv_mask = sum (inv << bit for bit , inv in enumerate (self .invert ))
142- if hasattr (wire , 'i' ):
143- m .d .comb += wire .i .eq (self .i ^ inv_mask )
144- if hasattr (wire , 'o' ):
145- m .d .comb += self .o .eq (wire .o ^ inv_mask )
146- if hasattr (wire , 'oe' ):
147- m .d .comb += self .oe .eq (wire .oe )
141+ if hasattr (wire , 'i' ) and wire .i is not None :
142+ assert self ._i is not None
143+ m .d .comb += wire .i .eq (self ._i ^ inv_mask )
144+ if hasattr (wire , 'o' ) and wire .o is not None :
145+ assert self ._o is not None
146+ m .d .comb += self ._o .eq (wire .o ^ inv_mask )
147+ if hasattr (wire , 'oe' ) and wire .oe is not None :
148+ assert self ._oe is not None
149+ m .d .comb += self ._oe .eq (wire .oe )
150+ elif self .direction in (io .Direction .Output , io .Direction .Bidir ):
151+ m .d .comb += self ._oes .eq (- 1 ) # set output enabled if the user hasn't connected
148152
149153 if hasattr (wire , 'ie' ):
150- m .d .comb += self .ie .eq (wire .ie )
151- elif hasattr (wire , 'oe' ):
152- m .d .comb += self .ie .eq (~ wire .oe )
154+ assert self ._ie is not None
155+ m .d .comb += self ._ie .eq (wire .ie )
156+ elif self .direction is io .Direction .Bidir :
157+ assert self ._oes is not None
158+ assert self ._ie is not None
159+ m .d .comb += self ._ie .eq (~ self ._oes )
153160
154161
155162 @property
@@ -240,7 +247,7 @@ class Sky130Port(SiliconPlatformPort):
240247 """
241248 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>`_
242249
243- Includes wires and configuration for `Drive Modes <IODriveMode>`, `Input buffer trip point <IOTripPoint>`and buffer control~
250+ Includes wires and configuration for `Drive Modes <IODriveMode>`, `Input buffer trip point <IOTripPoint>`and buffer control
244251 """
245252
246253 _DriveMode_map = {
@@ -308,8 +315,8 @@ def __init__(self,
308315 dm = Sky130DriveMode .STRONG_UP_STRONG_DOWN
309316 dm_init = __class__ ._DriveMode_map [dm ]
310317 dm_init_bits = [ int (b ) for b in f"{ dm_init :b} " ]
311- dms_shape = data .ArrayLayout (unsigned (3 ), self .width )
312- self ._dms = Signal (dms_shape , name = f"{ self ._name } $dms" , init = [dm_init ]* self .width )
318+ dms_layout = data .ArrayLayout (unsigned (3 ), self .width )
319+ self ._dms = Signal (dms_layout , name = f"{ self ._name } $dms" , init = [dm_init ]* self .width )
313320 all_ones = (2 << (self .width - 1 ))- 1
314321 self ._dm0 = Signal (self .width , name = f"{ self ._name } $dm0" , init = dm_init_bits [0 ]* all_ones )
315322 self ._dm1 = Signal (self .width , name = f"{ self ._name } $dm1" , init = dm_init_bits [1 ]* all_ones )
0 commit comments