Skip to content

Commit

Permalink
Add GroupId related calls to Himbaechel API
Browse files Browse the repository at this point in the history
  • Loading branch information
mmicko committed Nov 29, 2024
1 parent 2b8a235 commit 05e9943
Show file tree
Hide file tree
Showing 6 changed files with 197 additions and 3 deletions.
30 changes: 28 additions & 2 deletions himbaechel/arch.cc
Original file line number Diff line number Diff line change
Expand Up @@ -307,6 +307,24 @@ IdStringList Arch::getPipName(PipId pip) const

IdString Arch::getPipType(PipId pip) const { return IdString(); }

GroupId Arch::getGroupByName(IdStringList name) const
{
NPNR_ASSERT(name.size() == 2);
int tile = tile_name2idx.at(name[0]);
const auto &tdata = chip_tile_info(chip_info, tile);
for (int group = 0; group < tdata.groups.ssize(); group++) {
if (IdString(tdata.groups[group].name) == name[1])
return GroupId(tile, group);
}
return GroupId();

}

IdStringList Arch::getGroupName(GroupId group) const
{
return IdStringList::concat(tile_name.at(group.tile), IdString(chip_group_info(chip_info, group).name));
}

std::string Arch::getChipName() const { return chip_info->name.get(); }

IdString Arch::archArgsToId(ArchArgs args) const
Expand Down Expand Up @@ -504,7 +522,12 @@ IdString Arch::get_tile_type(int tile) const
std::vector<GraphicElement> Arch::getDecalGraphics(DecalId decal) const
{
std::vector<GraphicElement> ret;
if (decal.type == DecalId::TYPE_BEL) {
if (decal.type == DecalId::TYPE_GROUP) {
GroupId group(decal.tile, decal.index);
Loc loc;
tile_xy(chip_info, decal.tile, loc.x, loc.y);
uarch->drawGroup(ret, getGroupType(group), loc);
} else if (decal.type == DecalId::TYPE_BEL) {
BelId bel(decal.tile, decal.index);
GraphicElement::style_t style = decal.active ? GraphicElement::STYLE_ACTIVE : GraphicElement::STYLE_INACTIVE;
uarch->drawBel(ret, style, getBelType(bel), getBelLocation(bel));
Expand Down Expand Up @@ -557,7 +580,10 @@ DecalXY Arch::getPipDecal(PipId pip) const

DecalXY Arch::getGroupDecal(GroupId group) const
{
return DecalXY();
DecalXY decalxy;
decalxy.decal = DecalId(group.tile, group.index, DecalId::TYPE_GROUP);
decalxy.decal.active = true;
return decalxy;
}

NEXTPNR_NAMESPACE_END
69 changes: 69 additions & 0 deletions himbaechel/arch.h
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,10 @@ inline const PipDataPOD &chip_pip_info(const ChipInfoPOD *chip, PipId pip)
{
return chip_tile_info(chip, pip.tile).pips[pip.index];
}
inline const GroupDataPOD &chip_group_info(const ChipInfoPOD *chip, GroupId group)
{
return chip_tile_info(chip, group.tile).groups[group.index];
}
inline const TileRoutingShapePOD &chip_tile_shape(const ChipInfoPOD *chip, int tile)
{
return chip->tile_shapes[chip->tile_insts[tile].shape];
Expand Down Expand Up @@ -332,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 @@ -393,10 +439,16 @@ struct ArchArgs

typedef TileObjRange<BelId, BelDataPOD, &TileTypePOD::bels> BelRange;
typedef TileObjRange<PipId, PipDataPOD, &TileTypePOD::pips> AllPipRange;
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 @@ -412,6 +464,12 @@ struct ArchRanges : BaseArchRanges
using WireBelPinRangeT = BelPinRange;
// Pips
using AllPipsRangeT = AllPipRange;
// Groups
using AllGroupsRangeT = GroupRange;
using GroupBelsRangeT = GroupBelRange;
using GroupWiresRangeT = GroupWireRange;
using GroupPipsRangeT = GroupPipRange;
using GroupGroupsRangeT = GroupGroupRange;
};

struct Arch : BaseArch<ArchRanges>
Expand Down Expand Up @@ -699,6 +757,17 @@ struct Arch : BaseArch<ArchRanges>
return uarch->getClusterPlacement(cluster, root_bel, placement);
}

// -------------------------------------------------
// Group methods
GroupId getGroupByName(IdStringList name) const override;
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); }
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
std::vector<GraphicElement> getDecalGraphics(DecalId decal) const override;
Expand Down
18 changes: 17 additions & 1 deletion himbaechel/archdefs.h
Original file line number Diff line number Diff line change
Expand Up @@ -107,7 +107,23 @@ struct DecalId
unsigned int hash() const { return mkhash(tile, mkhash(index, type)); }
};

typedef IdString GroupId;
struct GroupId
{
int32_t tile = -1;
int32_t index = -1;

GroupId() = default;
GroupId(int32_t tile, int32_t index) : tile(tile), index(index) {};

bool operator==(const GroupId &other) const { return tile == other.tile && index == other.index; }
bool operator!=(const GroupId &other) const { return tile != other.tile || index != other.index; }
bool operator<(const GroupId &other) const
{
return tile < other.tile || (tile == other.tile && index < other.index);
}
unsigned int hash() const { return mkhash(tile, index); }
};

typedef IdString BelBucketId;
typedef IdString ClusterId;

Expand Down
12 changes: 12 additions & 0 deletions himbaechel/chipdb.h
Original file line number Diff line number Diff line change
Expand Up @@ -93,11 +93,23 @@ NPNR_PACKED_STRUCT(struct NodeShapePOD {
int32_t timing_idx;
});

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;
});

NPNR_PACKED_STRUCT(struct TileTypePOD {
int32_t type_name;
RelSlice<BelDataPOD> bels;
RelSlice<TileWireDataPOD> wires;
RelSlice<PipDataPOD> pips;
RelSlice<GroupDataPOD> groups;
RelPtr<uint8_t> extra_data;
});

Expand Down
2 changes: 2 additions & 0 deletions himbaechel/himbaechel_api.h
Original file line number Diff line number Diff line change
Expand Up @@ -114,6 +114,8 @@ struct HimbaechelAPI
virtual void drawPip(std::vector<GraphicElement> &g,GraphicElement::style_t style, Loc loc,
WireId src, IdString src_type, int32_t src_id, WireId dst, IdString dst_type, int32_t dst_id) {};

virtual void drawGroup(std::vector<GraphicElement> &g, IdString group_type, Loc loc) {};

// Routing methods
virtual void expandBoundingBox(BoundingBox &bb) const;
// --- Flow hooks ---
Expand Down
69 changes: 69 additions & 0 deletions himbaechel/himbaechel_dbgen/chip.py
Original file line number Diff line number Diff line change
Expand Up @@ -202,6 +202,47 @@ def serialise(self, context: str, bba: BBAWriter):
else:
bba.u32(0)
@dataclass
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)
bba.label(f"{context}_extra_data")
self.extra_data.serialise(f"{context}_extra_data", bba)
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:
bba.u32(0)

@dataclass
class TileType(BBAStruct):
strs: StringPool
gfx_wire_ids: dict()
Expand All @@ -210,8 +251,10 @@ class TileType(BBAStruct):
bels: list[BelData] = field(default_factory=list)
pips: list[PipData] = field(default_factory=list)
wires: list[TileWireData] = field(default_factory=list)
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 @@ -253,6 +296,26 @@ def create_pip(self, src: str, dst: str, timing_class: str=""):
self.wires[dst_idx].pips_uphill.append(pip.index)
self.pips.append(pip)
return pip
def create_group(self, name: str, type: str):
# Create a new group of a given name and type in the tile type
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 All @@ -267,6 +330,8 @@ def serialise_lists(self, context: str, bba: BBAWriter):
wire.serialise_lists(f"{context}_wire{i}", bba)
for i, pip in enumerate(self.pips):
pip.serialise_lists(f"{context}_pip{i}", bba)
for i, group in enumerate(self.groups):
group.serialise_lists(f"{context}_group{i}", bba)
# lists of members
bba.label(f"{context}_bels")
for i, bel in enumerate(self.bels):
Expand All @@ -277,6 +342,9 @@ def serialise_lists(self, context: str, bba: BBAWriter):
bba.label(f"{context}_pips")
for i, pip in enumerate(self.pips):
pip.serialise(f"{context}_pip{i}", bba)
bba.label(f"{context}_groups")
for i, group in enumerate(self.groups):
group.serialise(f"{context}_group{i}", bba)
# extra data (optional)
if self.extra_data is not None:
self.extra_data.serialise_lists(f"{context}_extra_data", bba)
Expand All @@ -287,6 +355,7 @@ def serialise(self, context: str, bba: BBAWriter):
bba.slice(f"{context}_bels", len(self.bels))
bba.slice(f"{context}_wires", len(self.wires))
bba.slice(f"{context}_pips", len(self.pips))
bba.slice(f"{context}_groups", len(self.groups))
if self.extra_data is not None:
bba.ref(f"{context}_extra_data")
else:
Expand Down

0 comments on commit 05e9943

Please sign in to comment.