diff --git a/himbaechel/arch.cc b/himbaechel/arch.cc index 4152e7ae..8a7fec1c 100644 --- a/himbaechel/arch.cc +++ b/himbaechel/arch.cc @@ -501,4 +501,71 @@ IdString Arch::get_tile_type(int tile) const return IdString(tile_data.type_name); } +std::vector Arch::getDecalGraphics(DecalId decal) const +{ + uint32_t flags = uarch->gfxAttributes(); + bool invert_y = flags & GfxFlags::FLAG_INVERT_Y; + std::vector ret; + if (flags & GfxFlags::FLAG_SHOW_BEL && decal.type == DecalId::TYPE_BEL) { + BelId bel(decal.tile, decal.index); + Loc loc = getBelLocation(bel); + if (invert_y) + loc.y = getGridDimY() - loc.y - 1; + GraphicElement::style_t style = decal.active ? GraphicElement::STYLE_ACTIVE : GraphicElement::STYLE_INACTIVE; + uarch->gfxTileBel(ret, loc.x, loc.y, loc.z, getGridDimX(), getGridDimY(), getBelType(bel), style); + } else if (flags & GfxFlags::FLAG_SHOW_WIRE && decal.type == DecalId::TYPE_WIRE) { + WireId wire(decal.tile, decal.index); + auto wire_type = getWireType(wire); + GraphicElement::style_t style = decal.active ? GraphicElement::STYLE_ACTIVE : GraphicElement::STYLE_INACTIVE; + Loc loc; + tile_xy(chip_info, wire.tile, loc.x, loc.y); + if (invert_y) + loc.y = getGridDimY() - loc.y - 1; + int32_t tilewire = chip_wire_info(chip_info, wire).flags; + uarch->gfxTileWire(ret, loc.x, loc.y, getGridDimX(), getGridDimY(), wire_type, tilewire, style); + } else if (flags & GfxFlags::FLAG_SHOW_PIP && decal.type == DecalId::TYPE_PIP) { + PipId pip(decal.tile, decal.index); + WireId src_wire = getPipSrcWire(pip); + WireId dst_wire = getPipDstWire(pip); + Loc loc = getPipLocation(pip); + if (invert_y) + loc.y = getGridDimY() - loc.y - 1; + int32_t src_id = chip_wire_info(chip_info, src_wire).flags; + int32_t dst_id = chip_wire_info(chip_info, dst_wire).flags; + GraphicElement::style_t style = decal.active ? GraphicElement::STYLE_ACTIVE : GraphicElement::STYLE_HIDDEN; + uarch->gfxTilePip(ret, loc.x, loc.y, getGridDimX(), getGridDimY(), src_wire, getWireType(src_wire), src_id, dst_wire, + getWireType(dst_wire), dst_id, style); + } + return ret; +} + +DecalXY Arch::getBelDecal(BelId bel) const +{ + DecalXY decalxy; + decalxy.decal = DecalId(bel.tile, bel.index, DecalId::TYPE_BEL); + decalxy.decal.active = getBoundBelCell(bel) != nullptr; + return decalxy; +} + +DecalXY Arch::getWireDecal(WireId wire) const +{ + DecalXY decalxy; + decalxy.decal = DecalId(wire.tile, wire.index, DecalId::TYPE_WIRE); + decalxy.decal.active = getBoundWireNet(wire) != nullptr; + return decalxy; +} + +DecalXY Arch::getPipDecal(PipId pip) const +{ + DecalXY decalxy; + decalxy.decal = DecalId(pip.tile, pip.index, DecalId::TYPE_PIP); + decalxy.decal.active = getBoundPipNet(pip) != nullptr; + return decalxy; +} + +DecalXY Arch::getGroupDecal(GroupId group) const +{ + return DecalXY(); +} + NEXTPNR_NAMESPACE_END diff --git a/himbaechel/arch.h b/himbaechel/arch.h index 80765da3..c1076d5a 100644 --- a/himbaechel/arch.h +++ b/himbaechel/arch.h @@ -698,6 +698,15 @@ struct Arch : BaseArch { return uarch->getClusterPlacement(cluster, root_bel, placement); } + + // ------------------------------------------------- + // Decal methods + std::vector getDecalGraphics(DecalId decal) const override; + DecalXY getBelDecal(BelId bel) const override; + DecalXY getWireDecal(WireId wire) const override; + DecalXY getPipDecal(PipId pip) const override; + DecalXY getGroupDecal(GroupId group) const override; + // ------------------------------------------------ bool pack() override; diff --git a/himbaechel/archdefs.h b/himbaechel/archdefs.h index d4b8d621..589dea99 100644 --- a/himbaechel/archdefs.h +++ b/himbaechel/archdefs.h @@ -85,7 +85,28 @@ struct PipId unsigned int hash() const { return mkhash(tile, index); } }; -typedef IdString DecalId; +struct DecalId +{ + int32_t tile = -1; + int32_t index = -1; + enum DecalType + { + TYPE_NONE, + TYPE_BEL, + TYPE_WIRE, + TYPE_PIP, + TYPE_GROUP + } type = TYPE_NONE; + bool active = false; + + 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; } + unsigned int hash() const { return mkhash(tile, mkhash(index, type)); } +}; + typedef IdString GroupId; typedef IdString BelBucketId; typedef IdString ClusterId; diff --git a/himbaechel/himbaechel_api.h b/himbaechel/himbaechel_api.h index e795e4d5..e0482672 100644 --- a/himbaechel/himbaechel_api.h +++ b/himbaechel/himbaechel_api.h @@ -55,6 +55,13 @@ struct Context; struct PlacerHeapCfg; +namespace GfxFlags { + static constexpr uint32_t FLAG_INVERT_Y = 0x0001; + static constexpr uint32_t FLAG_SHOW_BEL = 0x0002; + static constexpr uint32_t FLAG_SHOW_WIRE = 0x0004; + static constexpr uint32_t FLAG_SHOW_PIP = 0x0008; +} + struct HimbaechelAPI { // Architecture specific context initialization @@ -105,6 +112,20 @@ struct HimbaechelAPI virtual bool isClusterStrict(const CellInfo *cell) const; virtual bool getClusterPlacement(ClusterId cluster, BelId root_bel, std::vector> &placement) const; + + // Graphics + virtual uint32_t gfxAttributes() { return 0; } + + virtual void gfxTileBel(std::vector &g, int x, int y, int z, int w, int h, + IdString bel_type, GraphicElement::style_t style) {}; + + virtual void gfxTileWire(std::vector &g, int x, int y, int w, int h, IdString wire_type, + int32_t tilewire, GraphicElement::style_t style) {}; + + virtual void gfxTilePip(std::vector &g, int x, int y, int w, int h, WireId src, + IdString src_type, int32_t src_id, WireId dst, IdString dst_type, int32_t dst_id, + GraphicElement::style_t style) {}; + // --- Flow hooks --- virtual void pack() {}; // replaces the pack function // Called before and after main placement and routing