Skip to content

Commit

Permalink
Add sub items to groups support
Browse files Browse the repository at this point in the history
  • Loading branch information
mmicko committed Nov 29, 2024
1 parent 3311b7b commit a5ef4b3
Show file tree
Hide file tree
Showing 3 changed files with 93 additions and 8 deletions.
63 changes: 55 additions & 8 deletions himbaechel/arch.h
Original file line number Diff line number Diff line change
Expand Up @@ -336,6 +336,48 @@ template <RelSlice<int32_t> TileWireDataPOD::*ptr> struct UpDownhillPipRange

// -----------------------------------------------------------------------

template <typename Tid, RelSlice<int32_t> 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<Tid, ptr> &other) const
{
return tile != other.tile || cursor != other.cursor;
}

bool operator==(const GroupObjIterator<Tid, ptr> &other) const
{
return tile == other.tile && cursor == other.cursor;
}

Tid operator*() const
{
return Tid(tile, (group.*ptr)[cursor]);
}
};

template <typename Tid, RelSlice<int32_t> GroupDataPOD::*ptr> struct GroupObjRange
{
using iterator = GroupObjIterator<Tid, ptr>;
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;
Expand Down Expand Up @@ -402,6 +444,11 @@ typedef TileObjRange<GroupId, GroupDataPOD, &TileTypePOD::groups> GroupRange;
typedef UpDownhillPipRange<&TileWireDataPOD::pips_uphill> UphillPipRange;
typedef UpDownhillPipRange<&TileWireDataPOD::pips_downhill> DownhillPipRange;

typedef GroupObjRange<BelId, &GroupDataPOD::group_bels> GroupBelRange;
typedef GroupObjRange<WireId, &GroupDataPOD::group_wires> GroupWireRange;
typedef GroupObjRange<PipId, &GroupDataPOD::group_pips> GroupPipRange;
typedef GroupObjRange<GroupId, &GroupDataPOD::group_groups> GroupGroupRange;

struct ArchRanges : BaseArchRanges
{
using ArchArgsT = ArchArgs;
Expand All @@ -419,10 +466,10 @@ struct ArchRanges : BaseArchRanges
using AllPipsRangeT = AllPipRange;
// Groups
using AllGroupsRangeT = GroupRange;
//using GroupBelsRangeT = const std::vector<BelId> &;
//using GroupWiresRangeT = const std::vector<WireId> &;
//using GroupPipsRangeT = const std::vector<PipId> &;
//using GroupGroupsRangeT = const std::vector<GroupId> &;
using GroupBelsRangeT = GroupBelRange;
using GroupWiresRangeT = GroupWireRange;
using GroupPipsRangeT = GroupPipRange;
using GroupGroupsRangeT = GroupGroupRange;
};

struct Arch : BaseArch<ArchRanges>
Expand Down Expand Up @@ -715,10 +762,10 @@ struct Arch : BaseArch<ArchRanges>
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<BelId> getGroupBels(GroupId group) const override;
//std::vector<WireId> getGroupWires(GroupId group) const override;
//std::vector<PipId> getGroupPips(GroupId group) const override;
//std::vector<GroupId> 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
Expand Down
4 changes: 4 additions & 0 deletions himbaechel/chipdb.h
Original file line number Diff line number Diff line change
Expand Up @@ -96,6 +96,10 @@ NPNR_PACKED_STRUCT(struct NodeShapePOD {
NPNR_PACKED_STRUCT(struct GroupDataPOD {
int32_t name;
int32_t group_type;
RelSlice<int32_t> group_bels;
RelSlice<int32_t> group_wires;
RelSlice<int32_t> group_pips;
RelSlice<int32_t> group_groups;

RelPtr<uint8_t> extra_data;
});
Expand Down
34 changes: 34 additions & 0 deletions himbaechel/himbaechel_dbgen/chip.py
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand All @@ -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:
Expand All @@ -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

Expand Down Expand Up @@ -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
Expand Down

0 comments on commit a5ef4b3

Please sign in to comment.