From d810aac8676b9b4af0f4a1145bcfe9ac2a0b102e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Miodrag=20Milanovi=C4=87?= Date: Thu, 5 Dec 2024 13:59:33 +0100 Subject: [PATCH] Add GroupId related calls to Himbaechel API (#1399) * Add GroupId related calls to Himbaechel API * Example uarch using new API features * Update drawGroup to propagate only GroupId --- common/kernel/base_arch.h | 3 +- himbaechel/arch.cc | 39 ++- himbaechel/arch.h | 74 +++++ himbaechel/archdefs.h | 28 +- himbaechel/chipdb.h | 12 + himbaechel/himbaechel_api.cc | 5 +- himbaechel/himbaechel_api.h | 9 +- himbaechel/himbaechel_dbgen/chip.py | 71 ++++- himbaechel/himbaechel_gfxids.h | 2 +- himbaechel/uarch/example/constids.inc | 2 + himbaechel/uarch/example/example.cc | 289 ++++++++++--------- himbaechel/uarch/example/example_arch_gen.py | 2 + 12 files changed, 377 insertions(+), 159 deletions(-) diff --git a/common/kernel/base_arch.h b/common/kernel/base_arch.h index 2929bcba..96f1d804 100644 --- a/common/kernel/base_arch.h +++ b/common/kernel/base_arch.h @@ -443,7 +443,8 @@ template struct BaseArch : ArchAPI } // Routing methods - virtual void expandBoundingBox(BoundingBox &bb) const override { + virtual void expandBoundingBox(BoundingBox &bb) const override + { bb.x0 = std::max(bb.x0 - 1, 0); bb.y0 = std::max(bb.y0 - 1, 0); bb.x1 = std::min(bb.x1 + 1, this->getGridDimX()); diff --git a/himbaechel/arch.cc b/himbaechel/arch.cc index 9ae9225e..dccf285e 100644 --- a/himbaechel/arch.cc +++ b/himbaechel/arch.cc @@ -33,7 +33,7 @@ NEXTPNR_NAMESPACE_BEGIN -static constexpr int database_version = 5; +static constexpr int database_version = 6; static const ChipInfoPOD *get_chip_info(const RelPtr *ptr) { return ptr->get(); } @@ -307,6 +307,23 @@ 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 @@ -504,15 +521,21 @@ IdString Arch::get_tile_type(int tile) const std::vector Arch::getDecalGraphics(DecalId decal) const { std::vector 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, 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)); } else if (decal.type == DecalId::TYPE_WIRE) { WireId w(decal.tile, decal.index); - for (WireId wire: get_tile_wire_range(w)) { + for (WireId wire : get_tile_wire_range(w)) { auto wire_type = getWireType(wire); - GraphicElement::style_t style = decal.active ? GraphicElement::STYLE_ACTIVE : GraphicElement::STYLE_INACTIVE; + GraphicElement::style_t style = + decal.active ? GraphicElement::STYLE_ACTIVE : GraphicElement::STYLE_INACTIVE; Loc loc; tile_xy(chip_info, wire.tile, loc.x, loc.y); int32_t tilewire = chip_wire_info(chip_info, wire).tile_wire; @@ -526,7 +549,8 @@ std::vector Arch::getDecalGraphics(DecalId decal) const int32_t src_id = chip_wire_info(chip_info, src_wire).tile_wire; int32_t dst_id = chip_wire_info(chip_info, dst_wire).tile_wire; GraphicElement::style_t style = decal.active ? GraphicElement::STYLE_ACTIVE : GraphicElement::STYLE_HIDDEN; - uarch->drawPip(ret, style, loc, src_wire, getWireType(src_wire), src_id, dst_wire, getWireType(dst_wire), dst_id); + uarch->drawPip(ret, style, loc, src_wire, getWireType(src_wire), src_id, dst_wire, getWireType(dst_wire), + dst_id); } return ret; } @@ -557,7 +581,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 diff --git a/himbaechel/arch.h b/himbaechel/arch.h index ca965c86..29f5cb8d 100644 --- a/himbaechel/arch.h +++ b/himbaechel/arch.h @@ -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]; @@ -332,6 +336,41 @@ 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; @@ -393,10 +432,16 @@ struct ArchArgs typedef TileObjRange BelRange; typedef TileObjRange AllPipRange; +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; @@ -412,6 +457,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 @@ -699,6 +750,29 @@ struct Arch : BaseArch 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 getDecalGraphics(DecalId decal) const override; diff --git a/himbaechel/archdefs.h b/himbaechel/archdefs.h index 589dea99..13318bbe 100644 --- a/himbaechel/archdefs.h +++ b/himbaechel/archdefs.h @@ -102,12 +102,34 @@ struct DecalId DecalId() = default; DecalId(int32_t tile, int32_t index, DecalType type) : tile(tile), index(index), type(type) {}; - bool operator==(const DecalId &other) const { return tile == other.tile && index == other.index && type == other.type; } - bool operator!=(const DecalId &other) const { return tile != other.tile || index != other.index || type != other.type; } + bool operator==(const DecalId &other) const + { + return tile == other.tile && index == other.index && type == other.type; + } + bool operator!=(const DecalId &other) const + { + return tile != other.tile || index != other.index || type != other.type; + } 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; diff --git a/himbaechel/chipdb.h b/himbaechel/chipdb.h index 4f3241c7..099a1112 100644 --- a/himbaechel/chipdb.h +++ b/himbaechel/chipdb.h @@ -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 group_bels; + RelSlice group_wires; + RelSlice group_pips; + RelSlice group_groups; + + RelPtr extra_data; +}); + NPNR_PACKED_STRUCT(struct TileTypePOD { int32_t type_name; RelSlice bels; RelSlice wires; RelSlice pips; + RelSlice groups; RelPtr extra_data; }); diff --git a/himbaechel/himbaechel_api.cc b/himbaechel/himbaechel_api.cc index 23b24769..717d1879 100644 --- a/himbaechel/himbaechel_api.cc +++ b/himbaechel/himbaechel_api.cc @@ -85,10 +85,7 @@ bool HimbaechelAPI::getClusterPlacement(ClusterId cluster, BelId root_bel, return ctx->BaseArch::getClusterPlacement(cluster, root_bel, placement); } -void HimbaechelAPI::expandBoundingBox(BoundingBox &bb) const -{ - ctx->BaseArch::expandBoundingBox(bb); -} +void HimbaechelAPI::expandBoundingBox(BoundingBox &bb) const { ctx->BaseArch::expandBoundingBox(bb); } HimbaechelArch *HimbaechelArch::list_head; HimbaechelArch::HimbaechelArch(const std::string &name) : name(name) diff --git a/himbaechel/himbaechel_api.h b/himbaechel/himbaechel_api.h index fa757401..4f6f2101 100644 --- a/himbaechel/himbaechel_api.h +++ b/himbaechel/himbaechel_api.h @@ -109,10 +109,13 @@ struct HimbaechelAPI // Graphics virtual void drawBel(std::vector &g, GraphicElement::style_t style, IdString bel_type, Loc loc) {}; - virtual void drawWire(std::vector &g, GraphicElement::style_t style, Loc loc, IdString wire_type, int32_t tilewire, IdString tile_type) {}; + virtual void drawWire(std::vector &g, GraphicElement::style_t style, Loc loc, IdString wire_type, + int32_t tilewire, IdString tile_type) {}; - virtual void drawPip(std::vector &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 drawPip(std::vector &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 &g, GroupId group, Loc loc) {}; // Routing methods virtual void expandBoundingBox(BoundingBox &bb) const; diff --git a/himbaechel/himbaechel_dbgen/chip.py b/himbaechel/himbaechel_dbgen/chip.py index bedf0f28..6f7a3086 100644 --- a/himbaechel/himbaechel_dbgen/chip.py +++ b/himbaechel/himbaechel_dbgen/chip.py @@ -202,6 +202,47 @@ class PipData(BBAStruct): 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() @@ -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 @@ -253,6 +296,26 @@ class TileType(BBAStruct): 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 @@ -267,6 +330,8 @@ class TileType(BBAStruct): 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): @@ -277,6 +342,9 @@ class TileType(BBAStruct): 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) @@ -287,6 +355,7 @@ class TileType(BBAStruct): 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: @@ -839,7 +908,7 @@ class Chip: bba.label("chip_info") bba.u32(0x00ca7ca7) # magic - bba.u32(5) # version + bba.u32(6) # version bba.u32(self.width) bba.u32(self.height) diff --git a/himbaechel/himbaechel_gfxids.h b/himbaechel/himbaechel_gfxids.h index 8d954bb3..78bbabc3 100644 --- a/himbaechel/himbaechel_gfxids.h +++ b/himbaechel/himbaechel_gfxids.h @@ -44,7 +44,7 @@ enum GfxTileWireId , }; #endif -}; +}; // namespace HIMBAECHEL_UARCH NEXTPNR_NAMESPACE_END diff --git a/himbaechel/uarch/example/constids.inc b/himbaechel/uarch/example/constids.inc index eca9b108..4e16ad59 100644 --- a/himbaechel/uarch/example/constids.inc +++ b/himbaechel/uarch/example/constids.inc @@ -41,3 +41,5 @@ X(LOGIC) X(BRAM) X(IO) X(NULL) + +X(SWITCHBOX) diff --git a/himbaechel/uarch/example/example.cc b/himbaechel/uarch/example/example.cc index 42b76086..cfb2a0b9 100644 --- a/himbaechel/uarch/example/example.cc +++ b/himbaechel/uarch/example/example.cc @@ -139,166 +139,176 @@ struct ExampleImpl : HimbaechelAPI return true; } + void drawGroup(std::vector &g, GroupId group, Loc loc) override + { + IdString group_type = ctx->getGroupType(group); + if (group_type == id_SWITCHBOX) { + GraphicElement el; + el.type = GraphicElement::TYPE_BOX; + el.style = GraphicElement::STYLE_FRAME; + + el.x1 = loc.x + 0.1; + el.x2 = el.x1 + 0.4; + el.y1 = loc.y + 0.1; + el.y2 = el.y1 + 0.8; + g.push_back(el); + } + } void drawBel(std::vector &g, GraphicElement::style_t style, IdString bel_type, Loc loc) override { GraphicElement el; el.type = GraphicElement::TYPE_BOX; el.style = style; - switch (bel_type.index) - { - case id_LUT4.index : - el.x1 = loc.x + 0.15; - el.x2 = el.x1 + 0.25; - el.y1 = loc.y + 0.85 - (loc.z / 2) * 0.1; - el.y2 = el.y1 - 0.05; - g.push_back(el); - break; - case id_DFF.index : - el.x1 = loc.x + 0.55; - el.x2 = el.x1 + 0.25; - el.y1 = loc.y + 0.85 - (loc.z / 2) * 0.1; - el.y2 = el.y1 - 0.05; - g.push_back(el); - break; - case id_GND_DRV.index : - case id_VCC_DRV.index : - case id_IOB.index : - el.x1 = loc.x + 0.25; - el.x2 = el.x1 + 0.50; - el.y1 = loc.y + 0.80 - loc.z * 0.40; - el.y2 = el.y1 - 0.25; - g.push_back(el); - break; - case id_BRAM_512X16.index : - el.x1 = loc.x + 0.25; - el.x2 = el.x1 + 0.50; - el.y1 = loc.y + 0.80; - el.y2 = el.y1 - 0.60; - g.push_back(el); - break; + switch (bel_type.index) { + case id_LUT4.index: + el.x1 = loc.x + 0.55; + el.x2 = el.x1 + 0.15; + el.y1 = loc.y + 0.90 - (loc.z / 2) * 0.1; + el.y2 = el.y1 - 0.05; + g.push_back(el); + break; + case id_DFF.index: + el.x1 = loc.x + 0.75; + el.x2 = el.x1 + 0.15; + el.y1 = loc.y + 0.90 - (loc.z / 2) * 0.1; + el.y2 = el.y1 - 0.05; + g.push_back(el); + break; + case id_GND_DRV.index: + case id_VCC_DRV.index: + case id_IOB.index: + el.x1 = loc.x + 0.55; + el.x2 = el.x1 + 0.35; + el.y1 = loc.y + 0.90 - loc.z * 0.40; + el.y2 = el.y1 - 0.25; + g.push_back(el); + break; + case id_BRAM_512X16.index: + el.x1 = loc.x + 0.55; + el.x2 = el.x1 + 0.35; + el.y1 = loc.y + 0.90; + el.y2 = el.y1 - 0.60; + g.push_back(el); + break; } } - void drawWire(std::vector &g, GraphicElement::style_t style, Loc loc, IdString wire_type, int32_t tilewire, IdString tile_type) + void drawWire(std::vector &g, GraphicElement::style_t style, Loc loc, IdString wire_type, + int32_t tilewire, IdString tile_type) { GraphicElement el; el.type = GraphicElement::TYPE_LINE; el.style = style; int z; - switch(tile_type.index) - { - case id_LOGIC.index: - switch (wire_type.index) - { - case id_LUT_INPUT.index: - z = (tilewire - GFX_WIRE_L0_I0) / 4; - el.x1 = loc.x + 0.10; - el.x2 = el.x1 + 0.05; - el.y1 = loc.y + 0.85 - z * 0.1 - ((tilewire - GFX_WIRE_L0_I0) % 4 + 1) * 0.01; - el.y2 = el.y1; - g.push_back(el); - break; - case id_LUT_OUT.index: - z = tilewire - GFX_WIRE_L0_O; - el.x1 = loc.x + 0.40; - el.x2 = el.x1 + 0.05; - el.y1 = loc.y + 0.85 - z * 0.1 - 0.025; - el.y2 = el.y1; - g.push_back(el); - break; - case id_FF_DATA.index: - z = tilewire - GFX_WIRE_L0_D; - el.x1 = loc.x + 0.50; - el.x2 = el.x1 + 0.05; - el.y1 = loc.y + 0.85 - z * 0.1 - 0.025; - el.y2 = el.y1; - g.push_back(el); - break; - case id_FF_OUT.index: - z = tilewire - GFX_WIRE_L0_Q; - el.x1 = loc.x + 0.80; - el.x2 = el.x1 + 0.05; - el.y1 = loc.y + 0.85 - z * 0.1 - 0.025; - el.y2 = el.y1; - g.push_back(el); - break; - case id_TILE_CLK.index: - for(int i=0;i<8; i++) { - GraphicElement el; - el.type = GraphicElement::TYPE_LINE; - el.style = style; - el.x1 = loc.x + 0.6; - el.x2 = el.x1; - el.y1 = loc.y + 0.85 - i * 0.1 - 0.05; - el.y2 = el.y1 - 0.05; - g.push_back(el); - } - break; + switch (tile_type.index) { + case id_LOGIC.index: + switch (wire_type.index) { + case id_LUT_INPUT.index: + z = (tilewire - GFX_WIRE_L0_I0) / 4; + el.x1 = loc.x + 0.54; + el.x2 = el.x1 + 0.01; + el.y1 = loc.y + 0.90 - z * 0.1 - ((tilewire - GFX_WIRE_L0_I0) % 4 + 1) * 0.01; + el.y2 = el.y1; + g.push_back(el); + break; + case id_LUT_OUT.index: + z = tilewire - GFX_WIRE_L0_O; + el.x1 = loc.x + 0.70; + el.x2 = el.x1 + 0.01; + el.y1 = loc.y + 0.90 - z * 0.1 - 0.025; + el.y2 = el.y1; + g.push_back(el); + break; + case id_FF_DATA.index: + z = tilewire - GFX_WIRE_L0_D; + el.x1 = loc.x + 0.74; + el.x2 = el.x1 + 0.01; + el.y1 = loc.y + 0.90 - z * 0.1 - 0.025; + el.y2 = el.y1; + g.push_back(el); + break; + case id_FF_OUT.index: + z = tilewire - GFX_WIRE_L0_Q; + el.x1 = loc.x + 0.90; + el.x2 = el.x1 + 0.01; + el.y1 = loc.y + 0.90 - z * 0.1 - 0.025; + el.y2 = el.y1; + g.push_back(el); + break; + case id_TILE_CLK.index: + for (int i = 0; i < 8; i++) { + GraphicElement el; + el.type = GraphicElement::TYPE_LINE; + el.style = style; + el.x1 = loc.x + 0.6; + el.x2 = el.x1; + el.y1 = loc.y + 0.90 - i * 0.1 - 0.05; + el.y2 = el.y1 - 0.05; + g.push_back(el); } break; - case id_BRAM.index: - switch (wire_type.index) - { - case id_RAM_IN.index: - z = tilewire - GFX_WIRE_RAM_WA0; - el.x1 = loc.x + 0.20; - el.x2 = el.x1 + 0.05; - el.y1 = loc.y + 0.78 - z * 0.015; - el.y2 = el.y1; - g.push_back(el); - break; - case id_RAM_OUT.index: - z = tilewire - GFX_WIRE_RAM_DO0; - el.x1 = loc.x + 0.75; - el.x2 = el.x1 + 0.05; - el.y1 = loc.y + 0.78 - z * 0.015; - el.y2 = el.y1; - g.push_back(el); - break; - case id_TILE_CLK.index: - el.x1 = loc.x + 0.6; - el.x2 = el.x1; - el.y1 = loc.y + 0.20; - el.y2 = el.y1 - 0.05; - g.push_back(el); - break; - } + } + break; + case id_BRAM.index: + switch (wire_type.index) { + case id_RAM_IN.index: + z = tilewire - GFX_WIRE_RAM_WA0; + el.x1 = loc.x + 0.54; + el.x2 = el.x1 + 0.01; + el.y1 = loc.y + 0.90 - z * 0.015 - 0.025; + el.y2 = el.y1; + g.push_back(el); break; - case id_IO.index: - switch (wire_type.index) - { - case id_IO_I.index: - break; - case id_IO_O.index: - break; - case id_IO_T.index: - break; - case id_IO_PAD.index: - break; - case id_TILE_CLK.index: - break; - case id_GCLK.index: - break; - } + case id_RAM_OUT.index: + z = tilewire - GFX_WIRE_RAM_DO0; + el.x1 = loc.x + 0.90; + el.x2 = el.x1 + 0.01; + el.y1 = loc.y + 0.90 - z * 0.015 - 0.025; + el.y2 = el.y1; + g.push_back(el); break; - case id_NULL.index: - switch (wire_type.index) - { - case id_CLK_ROUTE.index: - break; - case id_GND.index: - break; - case id_VCC.index: - break; - case id_TILE_CLK.index: - break; - } + case id_TILE_CLK.index: + el.x1 = loc.x + 0.60; + el.x2 = el.x1; + el.y1 = loc.y + 0.30; + el.y2 = el.y1 - 0.025; + g.push_back(el); break; + } + break; + case id_IO.index: + switch (wire_type.index) { + case id_IO_I.index: + break; + case id_IO_O.index: + break; + case id_IO_T.index: + break; + case id_IO_PAD.index: + break; + case id_TILE_CLK.index: + break; + case id_GCLK.index: + break; + } + break; + case id_NULL.index: + switch (wire_type.index) { + case id_CLK_ROUTE.index: + break; + case id_GND.index: + break; + case id_VCC.index: + break; + case id_TILE_CLK.index: + break; + } + break; } } - void drawPip(std::vector &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) + void drawPip(std::vector &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) { GraphicElement el; el.type = GraphicElement::TYPE_ARROW; @@ -311,7 +321,6 @@ struct ExampleImpl : HimbaechelAPI el.x2 = loc.x + 0.50; el.y2 = el.y1; g.push_back(el); - } } }; diff --git a/himbaechel/uarch/example/example_arch_gen.py b/himbaechel/uarch/example/example_arch_gen.py index d36ae22e..ec7a1187 100644 --- a/himbaechel/uarch/example/example_arch_gen.py +++ b/himbaechel/uarch/example/example_arch_gen.py @@ -62,6 +62,8 @@ def create_switch_matrix(tt: TileType, inputs: list[str], outputs: list[str]): tt.create_wire(f"CLK_PREV", "CLK_ROUTE") tt.create_pip(f"CLK_PREV", f"CLK") + tt.create_group("SWITCHBOX", "SWITCHBOX") + def create_logic_tiletype(chip: Chip): tt = chip.create_tile_type("LOGIC") # setup wires