Skip to content

Commit

Permalink
Himbaechel GUI (YosysHQ#1295)
Browse files Browse the repository at this point in the history
* Extend Himbaechel API with gfx drawing methods

* Add bel drawing in example uarch

* changed API and added tile wire id in db

* extend API so we can distinguish CLK wires

* added bit more wires

* less horrid way of handling gfx ids

* loop wire range

* removed not needed brackets

* bump database version to 5

* Removed not used GfxFlags
  • Loading branch information
mmicko authored and KelvinChung2000 committed Nov 25, 2024
1 parent b5e692a commit b581139
Show file tree
Hide file tree
Showing 12 changed files with 506 additions and 5 deletions.
61 changes: 60 additions & 1 deletion himbaechel/arch.cc
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@

NEXTPNR_NAMESPACE_BEGIN

static constexpr int database_version = 4;
static constexpr int database_version = 5;

static const ChipInfoPOD *get_chip_info(const RelPtr<ChipInfoPOD> *ptr) { return ptr->get(); }

Expand Down Expand Up @@ -483,4 +483,63 @@ IdString Arch::get_tile_type(int tile) const
return IdString(tile_data.type_name);
}

std::vector<GraphicElement> Arch::getDecalGraphics(DecalId decal) const
{
std::vector<GraphicElement> ret;
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)) {
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);
int32_t tilewire = chip_wire_info(chip_info, wire).tile_wire;
uarch->drawWire(ret, style, loc, wire_type, tilewire, get_tile_type(wire.tile));
}
} else if (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);
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);
}
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
9 changes: 9 additions & 0 deletions himbaechel/arch.h
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down
23 changes: 22 additions & 1 deletion himbaechel/archdefs.h
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down
1 change: 1 addition & 0 deletions himbaechel/chipdb.h
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,7 @@ NPNR_PACKED_STRUCT(struct BelPinRefPOD {
NPNR_PACKED_STRUCT(struct TileWireDataPOD {
int32_t name;
int32_t wire_type;
int32_t tile_wire;
int32_t const_value;
int32_t flags; // 32 bits of arbitrary data
int32_t timing_idx; // used only when the wire is not part of a node, otherwise node idx applies
Expand Down
9 changes: 9 additions & 0 deletions himbaechel/himbaechel_api.h
Original file line number Diff line number Diff line change
Expand Up @@ -112,6 +112,15 @@ 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 void drawBel(std::vector<GraphicElement> &g, GraphicElement::style_t style, IdString bel_type, Loc loc) {};

virtual void drawWire(std::vector<GraphicElement> &g, GraphicElement::style_t style, Loc loc, IdString wire_type, int32_t tilewire, IdString tile_type) {};

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

// --- Flow hooks ---
virtual void pack() {}; // replaces the pack function
// Called before and after main placement and routing
Expand Down
25 changes: 23 additions & 2 deletions himbaechel/himbaechel_dbgen/chip.py
Original file line number Diff line number Diff line change
Expand Up @@ -144,6 +144,7 @@ class TileWireData:
index: int
name: IdString
wire_type: IdString
gfx_wire_id: int
const_value: IdString = field(default_factory=list)
flags: int = 0
timing_idx: int = -1
Expand All @@ -166,6 +167,7 @@ def serialise_lists(self, context: str, bba: BBAWriter):
def serialise(self, context: str, bba: BBAWriter):
bba.u32(self.name.index)
bba.u32(self.wire_type.index)
bba.u32(self.gfx_wire_id)
bba.u32(self.const_value.index)
bba.u32(self.flags)
bba.u32(self.timing_idx)
Expand Down Expand Up @@ -202,6 +204,7 @@ def serialise(self, context: str, bba: BBAWriter):
@dataclass
class TileType(BBAStruct):
strs: StringPool
gfx_wire_ids: dict()
tmg: "TimingPool"
type_name: IdString
bels: list[BelData] = field(default_factory=list)
Expand Down Expand Up @@ -229,9 +232,13 @@ def add_bel_pin(self, bel: BelData, pin: str, wire: str, dir: PinType):

def create_wire(self, name: str, type: str="", const_value: str=""):
# Create a new tile wire of a given name and type (optional) in the tile type
gfx_wire_id = 0
if name in self.gfx_wire_ids:
gfx_wire_id = self.gfx_wire_ids[name]
wire = TileWireData(index=len(self.wires),
name=self.strs.id(name),
wire_type=self.strs.id(type),
gfx_wire_id=gfx_wire_id,
const_value=self.strs.id(const_value))
self._wire2idx[wire.name] = wire.index
self.wires.append(wire)
Expand Down Expand Up @@ -700,8 +707,9 @@ def __init__(self, uarch: str, name: str, width: int, height: int):
self.packages = []
self.extra_data = None
self.timing = TimingPool(self.strs)
self.gfx_wire_ids = dict()
def create_tile_type(self, name: str):
tt = TileType(self.strs, self.timing, self.strs.id(name))
tt = TileType(self.strs, self.gfx_wire_ids, self.timing, self.strs.id(name))
self.tile_type_idx[name] = len(self.tile_types)
self.tile_types.append(tt)
return tt
Expand Down Expand Up @@ -831,7 +839,7 @@ def serialise(self, bba: BBAWriter):

bba.label("chip_info")
bba.u32(0x00ca7ca7) # magic
bba.u32(4) # version
bba.u32(5) # version
bba.u32(self.width)
bba.u32(self.height)

Expand Down Expand Up @@ -866,3 +874,16 @@ def write_bba(self, filename):
bba.ref('chip_info')
self.serialise(bba)
bba.pop()

def read_gfxids(self, filename):
idx = 1
with open(filename) as f:
for line in f:
l = line.strip()
if not l.startswith("X("):
continue
l = l[2:]
assert l.endswith(")"), l
l = l[:-1].strip()
self.gfx_wire_ids[l] = idx
idx += 1
53 changes: 53 additions & 0 deletions himbaechel/himbaechel_gfxids.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
/*
* nextpnr -- Next Generation Place and Route
*
* Copyright (C) 2018 gatecat <[email protected]>
*
* Permission to use, copy, modify, and/or distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
* copyright notice and this permission notice appear in all copies.
*
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*
*/

#ifndef HIMBAECHEL_GFXIDS_H
#define HIMBAECHEL_GFXIDS_H

/*
This enables use of 'gfxids' similar to a 'constids' in a HIMBAECHEL uarch.
To use:
- create a 'gfxids.inc' file in your uarch folder containing one ID per line; inside X( )
- set the HIMBAECHEL_UARCH macro to uarch namespace
- set the HIMBAECHEL_GFXIDS macro to the path to this file relative to the generic arch base
- include this file
*/

#include "nextpnr_namespaces.h"

NEXTPNR_NAMESPACE_BEGIN

namespace HIMBAECHEL_UARCH {
#ifndef Q_MOC_RUN
enum GfxTileWireId
{
GFX_WIRE_NONE
#define X(t) , GFX_WIRE_##t
#include HIMBAECHEL_GFXIDS
#undef X
,
};
#endif
};

NEXTPNR_NAMESPACE_END

using namespace NEXTPNR_NAMESPACE_PREFIX HIMBAECHEL_UARCH;

#endif
1 change: 1 addition & 0 deletions himbaechel/uarch/example/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ foreach(device ${HIMBAECHEL_EXAMPLE_DEVICES})
bbasm
${CMAKE_CURRENT_SOURCE_DIR}/example_arch_gen.py
${CMAKE_CURRENT_SOURCE_DIR}/constids.inc
${CMAKE_CURRENT_SOURCE_DIR}/gfxids.inc
VERBATIM)
list(APPEND chipdb_binaries ${device_bin})
endforeach()
Expand Down
26 changes: 25 additions & 1 deletion himbaechel/uarch/example/constids.inc
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,31 @@ X(IOB)
X(PAD)
X(INIT)

X(BRAM_512X16)

X(GND)
X(GND_DRV)
X(VCC)
X(VCC_DRV)
X(VCC_DRV)

X(LUT_INPUT)
X(FF_DATA)
X(LUT_OUT)
X(FF_OUT)
X(TILE_CLK)

X(RAM_IN)
X(RAM_OUT)

X(IO_I)
X(IO_O)
X(IO_T)
X(IO_PAD)
X(GCLK)

X(CLK_ROUTE)

X(LOGIC)
X(BRAM)
X(IO)
X(NULL)
Loading

0 comments on commit b581139

Please sign in to comment.