Extend Himbaechel API with gfx drawing methods

This commit is contained in:
Miodrag Milanovic 2024-02-29 09:57:32 +01:00
parent 9c2d96f86e
commit 8bb97c711e
4 changed files with 119 additions and 1 deletions

View File

@ -501,4 +501,71 @@ IdString Arch::get_tile_type(int tile) const
return IdString(tile_data.type_name);
}
std::vector<GraphicElement> Arch::getDecalGraphics(DecalId decal) const
{
uint32_t flags = uarch->gfxAttributes();
bool invert_y = flags & GfxFlags::FLAG_INVERT_Y;
std::vector<GraphicElement> 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

View File

@ -698,6 +698,15 @@ struct Arch : BaseArch<ArchRanges>
{
return uarch->getClusterPlacement(cluster, root_bel, placement);
}
// -------------------------------------------------
// Decal methods
std::vector<GraphicElement> 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;

View File

@ -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;

View File

@ -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<std::pair<CellInfo *, BelId>> &placement) const;
// Graphics
virtual uint32_t gfxAttributes() { return 0; }
virtual void gfxTileBel(std::vector<GraphicElement> &g, int x, int y, int z, int w, int h,
IdString bel_type, GraphicElement::style_t style) {};
virtual void gfxTileWire(std::vector<GraphicElement> &g, int x, int y, int w, int h, IdString wire_type,
int32_t tilewire, GraphicElement::style_t style) {};
virtual void gfxTilePip(std::vector<GraphicElement> &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