Skip to content

Commit edf3f36

Browse files
committed
Assign io power pins
1 parent e79a06d commit edf3f36

File tree

3 files changed

+97
-62
lines changed

3 files changed

+97
-62
lines changed

chipflow_lib/platforms/_packages.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,11 @@
1-
from ._utils import QuadPackageDef, BareDiePackageDef, Package
1+
from ._utils import QuadPackageDef, BareDiePackageDef, GAPackageDef, Package
22
from ._openframe import OpenframePackageDef
33

44
# Add any new package types to both PACKAGE_DEFINITIONS and the PackageDef union
55
PACKAGE_DEFINITIONS = {
66
"pga144": QuadPackageDef(name="pga144", width=36, height=36),
77
"cf20": BareDiePackageDef(name="cf20", width=7, height=3),
8+
"bga144": GAPackageDef(name="bga144", width=36, height=36),
89
"openframe": OpenframePackageDef()
910
}
1011

chipflow_lib/platforms/_utils.py

Lines changed: 94 additions & 60 deletions
Original file line numberDiff line numberDiff line change
@@ -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:

chipflow_lib/platforms/silicon.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@
1414
from amaranth import Module, Signal, ClockDomain, ClockSignal, ResetSignal, unsigned
1515
from amaranth.lib import wiring, io, data
1616
from amaranth.lib.cdc import FFSynchronizer
17-
from amaranth.lib.wiring import Component, In, PureInterface
17+
from amaranth.lib.wiring import Component, In
1818
from amaranth.back import rtlil #type: ignore[reportAttributeAccessIssue]
1919
from amaranth.hdl import Fragment
2020
from amaranth.hdl._ir import PortDirection

0 commit comments

Comments
 (0)