|
5 | 5 | import pydantic |
6 | 6 |
|
7 | 7 | from collections import OrderedDict, deque |
8 | | -from collections.abc import MutableMapping |
| 8 | +from collections.abc import MutableMapping, Sequence |
9 | 9 | from enum import Enum, IntEnum, StrEnum, auto |
| 10 | +from math import ceil, floor |
10 | 11 | from pprint import pformat |
11 | 12 | from typing import Any, Dict, List, Set, Tuple, Optional, Union, Literal |
12 | 13 |
|
@@ -580,7 +581,7 @@ def bringup_pins(self) -> BringupPins: |
580 | 581 |
|
581 | 582 |
|
582 | 583 | def _allocate(self, available: PinSet, width: int) -> PinList: |
583 | | - avail_n = self.sortpins(available) |
| 584 | + avail_n = self._sortpins(available) |
584 | 585 | logger.debug(f"BareDiePackageDef.allocate {width} from {len(avail_n)} remaining") |
585 | 586 | ret = _find_contiguous_sequence(self._ordered_pins, avail_n, width) |
586 | 587 | logger.debug(f"BareDiePackageDef.returned {ret}") |
@@ -646,9 +647,6 @@ def _allocate(self, available: Set[str], width: int) -> List[str]: |
646 | 647 | assert len(ret) == width |
647 | 648 | return ret |
648 | 649 |
|
649 | | - def sortpins(self, pins: Union[List[str], Set[str]]) -> List[str]: |
650 | | - return sorted(list(pins), key=int) |
651 | | - |
652 | 650 | @property |
653 | 651 | def bringup_pins(self) -> BringupPins: |
654 | 652 | return BringupPins( |
@@ -774,83 +772,64 @@ class GAPackageDef(BasePackageDef): |
774 | 772 | additional_pins: Optional[Set[GAPin]] |
775 | 773 |
|
776 | 774 | def model_post_init(self, __context): |
| 775 | + def int_to_alpha(i: int): |
| 776 | + while i > 0: |
| 777 | + char = i % 26 |
| 778 | + i = i // 26 |
| 779 | + out = chr(ord('A')+char-1) + out |
| 780 | + return out |
| 781 | + |
| 782 | + def pins_for_range(h1, h2, w1, w2): |
| 783 | + return set([[(int_to_alpha(h),w) for h in range(h1, h2)] for w in range(w1, w2)]) |
| 784 | + |
777 | 785 | match self.layout_type: |
778 | 786 | case GALayout.FULL: |
779 | | - pins = ([(chr(h),w) for h in range(ord('a'), ord('a') + self.height + 10 )]) |
| 787 | + pins = pins_for_range(1, self.height, 1, self.width) |
| 788 | + |
780 | 789 | case GALayout.PERIMETER: |
781 | | - pins = set([str(i) for i in range(8, self.width * 2 + self.height * 2)] - ) |
782 | | - case GALayout.CHANNEL: |
| 790 | + pins = pins_for_range(1, self.height, 1, self.width) - \ |
| 791 | + pins_for_range(1 + self.channel_width, self.height-self.channel_width, 1 + self.channel_width, self.width - self.channel_width) |
| 792 | + |
783 | 793 | case GALayout.ISLAND: |
| 794 | + pins = pins_for_range(1, self.height, 1, self.width) - \ |
| 795 | + pins_for_range(1 + self.channel_width, self.height-self.channel_width, 1 + self.channel_width, self.width - self.channel_width) + \ |
| 796 | + pins_for_range(ceil(self.height/ 2 - self.island_width /2), floor(self.height/2 + self.island_width /2), |
| 797 | + ceil(self.width / 2 - self.island_width /2), floor(self.width /2 + self.island_width /2)) |
| 798 | + |
| 799 | + case GALayout.CHANNEL: |
| 800 | + pins = pins_for_range(1, self.channel_width + 1, 1, self.width) + \ |
| 801 | + pins_for_range(self.height - self.channel_width, self.height, 1, self.width) |
784 | 802 |
|
785 | | - pins =( |
786 | | - set([str(i) for i in range(8, self.width * 2 + self.height * 2)]) |
787 | | - - set(self.power.values()) |
788 | | - - set(self.power.clocks.values()) |
789 | | - - set(self.power.jtag.values()) |
790 | | - ) |
791 | 803 | self._ordered_pins = sorted(pins) |
792 | 804 | return super().model_post_init(__context) |
793 | 805 |
|
794 | 806 |
|
795 | | - def allocate(self, available: Set[str], width: int) -> List[str]: |
| 807 | + def _allocate(self, available: Set[str], width: int) -> List[str]: |
796 | 808 | avail_n = sorted(available) |
797 | 809 | logger.debug(f"GAPackageDef.allocate {width} from {len(avail_n)} remaining: {available}") |
798 | 810 | ret = _find_contiguous_sequence(self._ordered_pins, avail_n, width) |
799 | 811 | logger.debug(f"GAPackageDef.returned {ret}") |
800 | 812 | assert len(ret) == width |
801 | 813 | return ret |
802 | 814 |
|
803 | | - def sortpins(self, pins: Union[List[str], Set[str]]) -> List[str]: |
804 | | - return sorted(list(pins), key=int) |
805 | | - |
806 | 815 | @property |
807 | | - def power(self) -> List[Tuple[Pin, Pin]]: |
808 | | - """ |
809 | | - The set of power pins for a quad package. |
810 | | - Power pins are always a matched pair in the middle of a side, with the number |
811 | | - varying with the size of the package. |
812 | | - We don't move power pins from these locations to allow for easier bring up test. |
813 | | - """ |
814 | | - pins = [] |
815 | | - n = (self.width + self.height)//12 |
816 | | - # Left |
817 | | - pins.append((str(self.height//2), str(self.height//2 +1))) |
818 | | - # Bottom |
819 | | - start = self.height |
820 | | - if n > 2: |
821 | | - pins.append((str(start + self.width//2), str(start + self.width//2 +1))) |
822 | | - # Right |
823 | | - start = start + self.width |
824 | | - if n > 1: |
825 | | - pins.append((str(start + self.height//2), str(start + self.height//2 +1))) |
826 | | - # Top |
827 | | - start = start + self.height |
828 | | - if n > 3: |
829 | | - pins.append((str(start + self.width//2), str(start + self.width//2 +1))) |
830 | | - return pins |
831 | | - |
| 816 | + def bringup_pins(self) -> BringupPins: |
| 817 | + return BringupPins( |
| 818 | + core_power=[self._power], |
| 819 | + core_clock={0: str(2)}, |
| 820 | + core_reset={0: str(1)}, |
| 821 | + core_heartbeat={0: str(self.width * 2 + self.height * 2 - 1)}, |
| 822 | + core_jtag=self._jtag |
| 823 | + ) |
832 | 824 |
|
833 | 825 |
|
834 | 826 | @property |
835 | | - def resets(self) -> Dict[int, Pin]: |
836 | | - """ |
837 | | - Numbered set of reset pins for the package |
838 | | - Default implementation with one reset pin |
839 | | - near the beginning of the package |
840 | | - """ |
841 | | - return {0: str(1)} # Second pin |
| 827 | + def _power(self) -> List[PowerPins]: |
| 828 | + return [PowerPins(1,2)] |
842 | 829 |
|
843 | | - @property |
844 | | - def clocks(self) -> Dict[int, Pin]: |
845 | | - """ |
846 | | - Numbered set of clock pins for the package |
847 | | - Default implementation with one clock pin |
848 | | - near the beginning of the package |
849 | | - """ |
850 | | - return {0: str(2)} # Third pin |
851 | 830 |
|
852 | 831 | @property |
853 | | - def jtag(self) -> Dict[JTAGWire, Pin]: |
| 832 | + def _jtag(self) -> Dict[JTAGWire, Pin]: |
854 | 833 | """ |
855 | 834 | Map of JTAG pins for the package |
856 | 835 | """ |
|
0 commit comments