@@ -173,7 +173,10 @@ class Port(pydantic.BaseModel):
173173 port_name : str
174174 iomodel : IOModel
175175 port_power_domain : Optional [PowerDomainName ] = None
176- power_pins : Optional [PowerPins ] = None
176+
177+ def model_post_init (self , __context ):
178+ logger .debug (f"Instantiating port { self .port_name } : { self } " )
179+ return super ().model_post_init (__context )
177180
178181 @property
179182 def width (self ):
@@ -250,29 +253,35 @@ def add_ports(self, component: str, interface: str, ports: Interface):
250253 self .ports [component ][interface ] = ports
251254
252255 def populate (self , interfaces : dict , lockfile : Optional ['LockFile' ] = None ):
253- for component , iface in interfaces .items ():
254- for k , v in iface ['interface' ]['members' ].items ():
255- logger .debug (f"Interface { component } .{ k } :" )
256+ for component , ann in interfaces .items ():
257+ for interface , v in ann ['interface' ]['members' ].items ():
258+ logger .debug (f"Interface { component } .{ interface } :" )
256259 logger .debug (pformat (v ))
257- width = count_member_pins (k , v )
258- logger .debug (f" { k } : total { width } pins" )
259- old_ports = lockfile .port_map .get_ports (component , k ) if lockfile else None
260+ width = count_member_pins (interface , v )
261+ logger .debug (f" { interface } : total { width } pins" )
262+ old_ports = lockfile .port_map .get_ports (component , interface ) if lockfile else None
260263
261264 if old_ports :
262- logger .debug (f" { iface } .{ k } found in pins.lock, reusing" )
265+ logger .debug (f" { component } .{ interface } found in pins.lock, reusing" )
263266 logger .debug (pformat (old_ports ))
264267 old_width = sum ([len (p .pins ) for p in old_ports .values () if p .pins is not None ])
265268 if old_width != width :
266269 raise ChipFlowError (
267- f"Interface { component } .{ k } has changed size. "
270+ f"Interface { component } .{ interface } has changed size. "
268271 f"Old size = { old_width } , new size = { width } "
269272 )
270- self .add_ports (component , k , old_ports )
273+ self .add_ports (component , interface , old_ports )
271274 else :
272- for n , p in v :
273- iomodel : IOModel = p
274- port = Port (type = 'io' , pins = None , port_name = n , iomodel = iomodel )
275- self .add_port (component , iface , n , port )
275+ print (f"i { interface } , v { v } " )
276+ for name , member in v ['members' ].items ():
277+ print (member )
278+ if member ['type' ] == 'interface' and 'annotations' in member \
279+ and IO_ANNOTATION_SCHEMA in member ['annotations' ]:
280+ iomodel : IOModel = member ['annotations' ][IO_ANNOTATION_SCHEMA ]
281+ port = Port (type = 'io' , pins = None , port_name = name , iomodel = iomodel )
282+ self .add_port (component , interface , name , port )
283+ else
284+
276285
277286 def allocate_power (self , config : 'Config' ):
278287 "Allocate power domains to top level ports"
@@ -348,8 +357,10 @@ def map_ports(c, i, *, port_power_domain, port_name=None, interface_power_domain
348357 else :
349358 raise ChipFlowError (f"Malformed [chipflow.power.map] section: { c } .{ i } .{ x } = { v } (unable to interpret '{ x } ')" )
350359 def allocate_pins (self , config : 'Config' , allocate : AllocateFunc , unallocated : Set [Pin ]) -> None :
360+ logger .debug ("Allocating pins" )
351361 for c ,v in self .ports .items ():
352362 for i ,v in v .items ():
363+ power_domains = set ()
353364 for n , port in v .items ():
354365 if not port .pins :
355366 pins = allocate (unallocated , port .width )
@@ -358,10 +369,23 @@ def allocate_pins(self, config: 'Config', allocate: AllocateFunc, unallocated: S
358369 logger .debug (f"allocated range: { pins } " )
359370 unallocated = unallocated - set (pins )
360371 port .pins = pins
361- if port .interface_power_domain :
362- powerpins = allocate (unallocated , 2 )
363- port .power_pins = PowerPins (powerpins [0 ], powerpins [1 ])
364-
372+ if port .interface_power_domain :
373+ power_domains .add (port .interface_power_domain )
374+ for pd in power_domains :
375+ if pd == '_core' : # core power handled specially
376+ continue
377+ logger .debug (f"Allocating power pins for { c } .{ i } , domain { pd } " )
378+ powerpins = allocate (unallocated , 2 )
379+
380+ power_port = '_power_vdd_' + pd
381+ if power_port not in self .ports [c ][i ]:
382+ self .ports [c ][i ][power_port ] = Port (type = 'vdd' , pins = [powerpins [0 ]], port_name = power_port ,
383+ iomodel = IOModel (width = 1 , direction = io .Direction .Input , interface_power_domain = pd ))
384+
385+ power_port = '_power_vss_' + pd
386+ if power_port not in self .ports [c ][i ]:
387+ self .ports [c ][i ][power_port ] = Port (type = 'vss' , pins = [powerpins [1 ]], port_name = power_port ,
388+ iomodel = IOModel (width = 1 , direction = io .Direction .Input , interface_power_domain = pd ))
365389
366390def construct_portmap (config : 'Config' , interfaces : dict , lockfile : Optional ['LockFile' ], core : Component , allocate : AllocateFunc , unallocated : Set [Pin ]) -> PortMap :
367391 portmap = PortMap ()
@@ -619,11 +643,8 @@ def count_member_pins(name: str, member: Dict[str, Any]) -> int:
619643 and IO_ANNOTATION_SCHEMA in member ['annotations' ]:
620644 ioport = member ['annotations' ][IO_ANNOTATION_SCHEMA ]
621645 width = ioport ['width' ]
622- if 'interface_power_domain' in ioport and ioport ['interface_power_domain' ]:
623- width += 2
624646 return width
625647 elif member ['type' ] == 'interface' :
626- logger .warning (f"Interface '{ name } ' has no IOSignature, pin allocation likely to be wrong" )
627648 width = 0
628649 for n , v in member ['members' ].items ():
629650 width += count_member_pins ('_' .join ([name , n ]), v )
0 commit comments