From a5ef4b36df44a4eac49355d99fd9b41ba942fdcf Mon Sep 17 00:00:00 2001 From: Miodrag Milanovic Date: Fri, 29 Nov 2024 20:07:10 +0100 Subject: [PATCH] Add sub items to groups support --- himbaechel/arch.h | 63 +++++++++++++++++++++++++---- himbaechel/chipdb.h | 4 ++ himbaechel/himbaechel_dbgen/chip.py | 34 ++++++++++++++++ 3 files changed, 93 insertions(+), 8 deletions(-) diff --git a/himbaechel/arch.h b/himbaechel/arch.h index abc28155cb..8862df1f04 100644 --- a/himbaechel/arch.h +++ b/himbaechel/arch.h @@ -336,6 +336,48 @@ template TileWireDataPOD::*ptr> struct UpDownhillPipRange // ----------------------------------------------------------------------- +template GroupDataPOD::*ptr> struct GroupObjIterator +{ + const GroupDataPOD &group; + int tile = -1; + int cursor = -1; + + GroupObjIterator(const GroupDataPOD &group, int tile, int cursor) + : group(group), tile(tile), cursor(cursor) {}; + + void operator++() { cursor++; } + + bool operator!=(const GroupObjIterator &other) const + { + return tile != other.tile || cursor != other.cursor; + } + + bool operator==(const GroupObjIterator &other) const + { + return tile == other.tile && cursor == other.cursor; + } + + Tid operator*() const + { + return Tid(tile, (group.*ptr)[cursor]); + } +}; + +template GroupDataPOD::*ptr> struct GroupObjRange +{ + using iterator = GroupObjIterator; + GroupObjRange(const GroupDataPOD &group, int tile) + : b(group, tile, 0), e(group, tile, (group.*ptr).ssize()) + { + } + + iterator b, e; + iterator begin() const { return b; } + iterator end() const { return e; } +}; + +// ----------------------------------------------------------------------- + struct BelPinIterator { const ChipInfoPOD *chip; @@ -402,6 +444,11 @@ typedef TileObjRange GroupRange; typedef UpDownhillPipRange<&TileWireDataPOD::pips_uphill> UphillPipRange; typedef UpDownhillPipRange<&TileWireDataPOD::pips_downhill> DownhillPipRange; +typedef GroupObjRange GroupBelRange; +typedef GroupObjRange GroupWireRange; +typedef GroupObjRange GroupPipRange; +typedef GroupObjRange GroupGroupRange; + struct ArchRanges : BaseArchRanges { using ArchArgsT = ArchArgs; @@ -419,10 +466,10 @@ struct ArchRanges : BaseArchRanges using AllPipsRangeT = AllPipRange; // Groups using AllGroupsRangeT = GroupRange; - //using GroupBelsRangeT = const std::vector &; - //using GroupWiresRangeT = const std::vector &; - //using GroupPipsRangeT = const std::vector &; - //using GroupGroupsRangeT = const std::vector &; + using GroupBelsRangeT = GroupBelRange; + using GroupWiresRangeT = GroupWireRange; + using GroupPipsRangeT = GroupPipRange; + using GroupGroupsRangeT = GroupGroupRange; }; struct Arch : BaseArch @@ -715,10 +762,10 @@ struct Arch : BaseArch IdStringList getGroupName(GroupId group) const override; GroupRange getGroups() const override { return GroupRange(chip_info); } IdString getGroupType(GroupId group) const { return IdString(chip_group_info(chip_info, group).group_type); } - //std::vector getGroupBels(GroupId group) const override; - //std::vector getGroupWires(GroupId group) const override; - //std::vector getGroupPips(GroupId group) const override; - //std::vector getGroupGroups(GroupId group) const override; + GroupBelRange getGroupBels(GroupId group) const override { return GroupBelRange(chip_group_info(chip_info, group), group.tile); } + GroupWireRange getGroupWires(GroupId group) const override { return GroupWireRange(chip_group_info(chip_info, group), group.tile); } + GroupPipRange getGroupPips(GroupId group) const override { return GroupPipRange(chip_group_info(chip_info, group), group.tile); } + GroupGroupRange getGroupGroups(GroupId group) const override { return GroupGroupRange(chip_group_info(chip_info, group), group.tile); } // ------------------------------------------------- // Decal methods diff --git a/himbaechel/chipdb.h b/himbaechel/chipdb.h index 944f96fe2f..099a1112c7 100644 --- a/himbaechel/chipdb.h +++ b/himbaechel/chipdb.h @@ -96,6 +96,10 @@ NPNR_PACKED_STRUCT(struct NodeShapePOD { NPNR_PACKED_STRUCT(struct GroupDataPOD { int32_t name; int32_t group_type; + RelSlice group_bels; + RelSlice group_wires; + RelSlice group_pips; + RelSlice group_groups; RelPtr extra_data; }); diff --git a/himbaechel/himbaechel_dbgen/chip.py b/himbaechel/himbaechel_dbgen/chip.py index bf511eac58..b82c26174e 100644 --- a/himbaechel/himbaechel_dbgen/chip.py +++ b/himbaechel/himbaechel_dbgen/chip.py @@ -206,9 +206,25 @@ class GroupData(BBAStruct): index: int name: IdString group_type: IdString = field(default_factory=IdString) + group_bels: list[int] = field(default_factory=list) + group_wires: list[int] = field(default_factory=list) + group_pips: list[int] = field(default_factory=list) + group_groups: list[int] = field(default_factory=list) extra_data: object = None def serialise_lists(self, context: str, bba: BBAWriter): + bba.label(f"{context}_group_bels") + for idx in self.group_bels: + bba.u32(idx) + bba.label(f"{context}_group_wires") + for idx in self.group_wires: + bba.u32(idx) + bba.label(f"{context}_group_pips") + for idx in self.group_pips: + bba.u32(idx) + bba.label(f"{context}_group_groups") + for idx in self.group_groups: + bba.u32(idx) # extra data (optional) if self.extra_data is not None: self.extra_data.serialise_lists(f"{context}_extra_data", bba) @@ -217,6 +233,10 @@ def serialise_lists(self, context: str, bba: BBAWriter): def serialise(self, context: str, bba: BBAWriter): bba.u32(self.name.index) bba.u32(self.group_type.index) + bba.slice(f"{context}_group_bels", len(self.group_bels)) + bba.slice(f"{context}_group_wires", len(self.group_wires)) + bba.slice(f"{context}_group_pips", len(self.group_pips)) + bba.slice(f"{context}_group_groups", len(self.group_groups)) if self.extra_data is not None: bba.ref(f"{context}_extra_data") else: @@ -234,6 +254,7 @@ class TileType(BBAStruct): groups: list[GroupData] = field(default_factory=list) _wire2idx: dict[IdString, int] = field(default_factory=dict) + _group2idx: dict[IdString, int] = field(default_factory=dict) extra_data: object = None @@ -280,8 +301,21 @@ def create_group(self, name: str, type: str): group = GroupData(index=len(self.groups), name=self.strs.id(name), group_type=self.strs.id(type)) + self._group2idx[group.name] = group.index self.groups.append(group) return group + def add_bel_to_group(self, bel: BelData, group: str): + group_idx = self._group2idx[self.strs.id(group)] + self.groups[group_idx].group_bels.append(bel.index) + def add_wire_to_group(self, wire: TileWireData, group: str): + group_idx = self._group2idx[self.strs.id(group)] + self.groups[group_idx].group_wires.append(wire.index) + def add_pip_to_group(self, pip: PipData, group: str): + group_idx = self._group2idx[self.strs.id(group)] + self.groups[group_idx].group_pips.append(pip.index) + def add_group_to_group(self, sub_group: GroupData, group: str): + group_idx = self._group2idx[self.strs.id(group)] + self.groups[group_idx].group_groups.append(sub_group.index) def has_wire(self, wire: str): # Check if a wire has already been created return self.strs.id(wire) in self._wire2idx