@@ -664,8 +664,8 @@ def _allocate_bringup(self, config: 'Config') -> Component:
664664 vss = "vss"
665665 vdd = "vdd"
666666 if pp .name :
667- vss = f"vss { pp .name } "
668- vdd = f"vdd { pp .name } "
667+ vss = f"{ pp .name } vss "
668+ vdd = f"{ pp .name } vdd "
669669 powerpins [vss ].append (pp .power )
670670 powerpins [vdd ].append (pp .ground )
671671
@@ -769,12 +769,14 @@ def model_post_init(self, __context):
769769
770770 @property
771771 def bringup_pins (self ) -> BringupPins :
772- core_power = PowerPins (
773- (_Side .N , 1 ),
774- (_Side .N , 2 )
775- )
772+ #TODO, this makes no sense for anything that isn't tiny..
773+ core_power = [
774+ PowerPins ((_Side .N , 1 ), (_Side .N , 2 )),
775+ PowerPins ((_Side .W , 1 ), (_Side .W , 2 ), name = 'd' )
776+ ]
777+
776778 return BringupPins (
777- core_power = [ core_power ] ,
779+ core_power = core_power ,
778780 core_clock = (_Side .N , 3 ),
779781 core_reset = (_Side .N , 3 ),
780782 core_heartbeat = (_Side .E , 1 ),
@@ -849,27 +851,34 @@ def _power(self) -> List[PowerPins]:
849851 Power pins are always a matched pair in the middle of a side, with the number
850852 varying with the size of the package.
851853 We don't move power pins from these locations to allow for easier bring up test.
854+ returns two lists, core power pins and io power pins
852855 """
853- pins = []
856+ pins : List [PowerPins ] = []
857+ # heuristic for sensible number of power pins for a given size
854858 n = (self .width + self .height )// 12
855859 # Left
856860 p = self .height // 2 + self .height // 2
857- pins .append (PowerPins (p , p + 1 ))
861+ assert p > 3
862+ pins .append (PowerPins (p - 2 , p - 1 ))
863+ pins .append (PowerPins (p , p + 1 , name = 'd' ))
858864 # Bottom
859865 start = self .height
860866 if n > 2 :
861- p = start + self .width // 2 + self .width // 2
862- pins .append (PowerPins (p , p + 1 ))
867+ p = start + self .width // 2
868+ pins .append (PowerPins (p - 2 , p - 1 ))
869+ pins .append (PowerPins (p , p + 1 , name = 'd' ))
863870 # Right
864871 start = start + self .width
865872 if n > 1 :
866- p = start + self .height // 2 + self .height // 2
867- pins .append (PowerPins (p , p + 1 ))
873+ p = start + self .height // 2
874+ pins .append (PowerPins (p - 2 , p - 1 ))
875+ pins .append (PowerPins (p , p + 1 , name = 'd' ))
868876 # Top
869877 start = start + self .height
870878 if n > 3 :
871- p = start + self .width // 2 + self .width // 2
872- pins .append (PowerPins (p , p + 1 ))
879+ p = start + self .width // 2
880+ pins .append (PowerPins (p - 2 , p - 1 ))
881+ pins .append (PowerPins (p , p + 1 , name = 'd' ))
873882 return pins
874883
875884
@@ -961,75 +970,77 @@ class GAPackageDef(BasePackageDef):
961970 width :int
962971 height : int
963972 layout_type : GALayout = GALayout .FULL
964- channel_width : Optional [int ]
965- island_width : Optional [int ]
966- missing_pins : Optional [Set [GAPin ]]
967- additional_pins : Optional [Set [GAPin ]]
968-
969- def model_post_init (self , __context ):
970- def int_to_alpha (i : int ):
971- "Covert int to alpha representation, starting at 1"
972- valid_letters = "ABCDEFGHJKLMPRSTUVWXY"
973- out = ''
974- while i > 0 :
975- char = i % len (valid_letters )
976- i = i // len (valid_letters )
977- out = valid_letters [char - 1 ] + out
978- return out
979-
973+ channel_width : Optional [int ] = None
974+ island_width : Optional [int ] = None
975+ missing_pins : Optional [Set [GAPin ]] = None
976+ additional_pins : Optional [Set [GAPin ]] = None
977+
978+ @staticmethod
979+ def _int_to_alpha (i : int ):
980+ "Covert int to alpha representation, starting at 1"
981+ valid_letters = "ABCDEFGHJKLMPRSTUVWXY"
982+ out = ''
983+ while i > 0 :
984+ char = i % len (valid_letters )
985+ i = i // len (valid_letters )
986+ out = valid_letters [char - 1 ] + out
987+ return out
988+
989+ def _get_all_pins (self ) -> Tuple [Set [GAPin ], Set [GAPin ] | None ]:
980990 def pins_for_range (h1 : int , h2 : int , w1 : int , w2 : int ) -> Set [GAPin ]:
981- pins = [GAPin (int_to_alpha (h ),w ) for h in range (h1 , h2 ) for w in range (w1 , w2 )]
991+ pins = [GAPin (self . _int_to_alpha (h ),w ) for h in range (h1 , h2 ) for w in range (w1 , w2 )]
982992 return set (pins )
983993
984- def sort_by_quadrant (pins : Set [GAPin ]) -> List [Pin ]:
985- quadrants :List [Set [GAPin ]] = [set (), set (), set (), set ()]
986- midline_h = int_to_alpha (self .height // 2 )
987- midline_w = self .width // 2
988- for pin in pins :
989- if pin .h < midline_h and pin .w < midline_w :
990- quadrants [0 ].add (pin )
991- if pin .h >= midline_h and pin .w < midline_w :
992- quadrants [1 ].add (pin )
993- if pin .h < midline_h and pin .w >= midline_w :
994- quadrants [2 ].add (pin )
995- if pin .h >= midline_h and pin .w >= midline_w :
996- quadrants [3 ].add (pin )
997- ret = []
998- for q in range (0 ,3 ):
999- ret .append (sorted (quadrants [q ]))
1000- return ret
1001994
1002- self ._ordered_pins : List [Pin ] = []
1003995 match self .layout_type :
1004996 case GALayout .FULL :
1005997 pins = pins_for_range (1 , self .height , 1 , self .width )
1006- pins -= self .bringup_pins .to_set ()
1007- self ._ordered_pins = sort_by_quadrant (pins )
998+ return (pins , None )
1008999
10091000 case GALayout .PERIMETER :
10101001 assert self .channel_width is not None
10111002 pins = pins_for_range (1 , self .height , 1 , self .width ) - \
10121003 pins_for_range (1 + self .channel_width , self .height - self .channel_width , 1 + self .channel_width , self .width - self .channel_width )
1013- pins -= self .bringup_pins .to_set ()
1014- self ._ordered_pins = sort_by_quadrant (pins )
1004+ return (pins , None )
10151005
10161006 case GALayout .ISLAND :
10171007 assert self .channel_width is not None
10181008 assert self .island_width is not None
10191009 outer_pins = pins_for_range (1 , self .height , 1 , self .width ) - \
10201010 pins_for_range (1 + self .channel_width , self .height - self .channel_width , 1 + self .channel_width , self .width - self .channel_width )
1021- outer_pins -= self .bringup_pins .to_set ()
10221011 inner_pins = pins_for_range (ceil (self .height / 2 - self .island_width / 2 ), floor (self .height / 2 + self .island_width / 2 ),
10231012 ceil (self .width / 2 - self .island_width / 2 ), floor (self .width / 2 + self .island_width / 2 ))
1024- # TODO, allocate island as power
1025- self ._ordered_pins = sort_by_quadrant (outer_pins ) + sorted (inner_pins )
1013+ return (outer_pins , inner_pins )
10261014
10271015 case GALayout .CHANNEL :
10281016 assert self .channel_width is not None
10291017 pins = pins_for_range (1 , self .channel_width + 1 , 1 , self .width ) | \
10301018 pins_for_range (self .height - self .channel_width , self .height , 1 , self .width )
1031- pins -= self .bringup_pins .to_set ()
1032- self ._ordered_pins = sort_by_quadrant (pins )
1019+ return (pins , None )
1020+
1021+ def model_post_init (self , __context ):
1022+ def sort_by_quadrant (pins : Set [GAPin ]) -> List [GAPin ]:
1023+ quadrants :List [Set [GAPin ]] = [set (), set (), set (), set ()]
1024+ midline_h = self ._int_to_alpha (self .height // 2 )
1025+ midline_w = self .width // 2
1026+ for pin in pins :
1027+ if pin .h < midline_h and pin .w < midline_w :
1028+ quadrants [0 ].add (pin )
1029+ if pin .h >= midline_h and pin .w < midline_w :
1030+ quadrants [1 ].add (pin )
1031+ if pin .h < midline_h and pin .w >= midline_w :
1032+ quadrants [2 ].add (pin )
1033+ if pin .h >= midline_h and pin .w >= midline_w :
1034+ quadrants [3 ].add (pin )
1035+ ret = []
1036+ for q in range (0 ,3 ):
1037+ ret .append (sorted (quadrants [q ]))
1038+ return ret
1039+
1040+ self ._ordered_pins : List [GAPin ] = []
1041+ pins , _ = self ._get_all_pins ()
1042+ pins -= self .bringup_pins .to_set ()
1043+ self ._ordered_pins = sort_by_quadrant (pins )
10331044
10341045 return super ().model_post_init (__context )
10351046
@@ -1061,8 +1072,31 @@ def bringup_pins(self) -> BringupPins:
10611072
10621073 @property
10631074 def _power (self ) -> List [PowerPins ]:
1064- return [PowerPins (1 ,2 )]
1075+ #TODO build an internal padring mapping
1076+ # for now, just distribute evenly
1077+ power_pins = []
10651078
1079+ pins , inner = self ._get_all_pins ()
1080+ #allocate all of inner to core pins, alternating
1081+ try :
1082+ if inner :
1083+ it = iter (sorted (inner ))
1084+ for p in it :
1085+ power_pins .append (PowerPins (p , next (it )))
1086+ except StopIteration :
1087+ pass
1088+ # distribute the rest evenly
1089+ try :
1090+ it = iter (sorted (pins ))
1091+ for p in it :
1092+ for name in ('' ,'d' ):
1093+ power_pins .append (PowerPins (p , next (it )))
1094+ for i in range (0 ,15 ):
1095+ next (it )
1096+ except StopIteration :
1097+ pass
1098+
1099+ return power_pins
10661100
10671101 @property
10681102 def _jtag (self ) -> JTAGPins :
0 commit comments