Merge pull request #344 from YosysHQ/mmicko/ecp5_gui

ECP5 display improvement
This commit is contained in:
Miodrag Milanović 2019-12-28 15:46:02 +01:00 committed by GitHub
commit 247e18cf02
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
17 changed files with 5675 additions and 74 deletions

View File

@ -451,8 +451,6 @@ BelId Arch::getBelByLocation(Loc loc) const
delay_t Arch::estimateDelay(WireId src, WireId dst) const delay_t Arch::estimateDelay(WireId src, WireId dst) const
{ {
WireId cursor = dst;
int num_uh = locInfo(dst)->wire_data[dst.index].num_uphill; int num_uh = locInfo(dst)->wire_data[dst.index].num_uphill;
if (num_uh < 6) { if (num_uh < 6) {
for (auto uh : getPipsUphill(dst)) { for (auto uh : getPipsUphill(dst)) {
@ -613,34 +611,55 @@ std::vector<GraphicElement> Arch::getDecalGraphics(DecalId decal) const
{ {
std::vector<GraphicElement> ret; std::vector<GraphicElement> ret;
if (decal.type == DecalId::TYPE_BEL) { if (decal.type == DecalId::TYPE_GROUP) {
int type = decal.z;
int x = decal.location.x;
int y = decal.location.y;
if (type == GroupId::TYPE_SWITCHBOX) {
GraphicElement el;
el.type = GraphicElement::TYPE_BOX;
el.style = GraphicElement::STYLE_FRAME;
el.x1 = x + switchbox_x1;
el.x2 = x + switchbox_x2;
el.y1 = y + switchbox_y1;
el.y2 = y + switchbox_y2;
ret.push_back(el);
}
} else if (decal.type == DecalId::TYPE_WIRE) {
WireId wire;
wire.index = decal.z;
wire.location = decal.location;
auto wire_type = getWireType(wire);
int x = decal.location.x;
int y = decal.location.y;
GraphicElement::style_t style = decal.active ? GraphicElement::STYLE_ACTIVE : GraphicElement::STYLE_INACTIVE;
GfxTileWireId tilewire = GfxTileWireId(locInfo(wire)->wire_data[wire.index].tile_wire);
gfxTileWire(ret, x, y, chip_info->width, chip_info->height, wire_type, tilewire, style);
} else if (decal.type == DecalId::TYPE_PIP) {
PipId pip;
pip.index = decal.z;
pip.location = decal.location;
WireId src_wire = getPipSrcWire(pip);
WireId dst_wire = getPipDstWire(pip);
int x = decal.location.x;
int y = decal.location.y;
GfxTileWireId src_id = GfxTileWireId(locInfo(src_wire)->wire_data[src_wire.index].tile_wire);
GfxTileWireId dst_id = GfxTileWireId(locInfo(dst_wire)->wire_data[dst_wire.index].tile_wire);
GraphicElement::style_t style = decal.active ? GraphicElement::STYLE_ACTIVE : GraphicElement::STYLE_HIDDEN;
gfxTilePip(ret, x, y, chip_info->width, chip_info->height, src_wire, getWireType(src_wire), src_id, dst_wire,
getWireType(dst_wire), dst_id, style);
} else if (decal.type == DecalId::TYPE_BEL) {
BelId bel; BelId bel;
bel.index = decal.z; bel.index = decal.z;
bel.location = decal.location; bel.location = decal.location;
int z = locInfo(bel)->bel_data[bel.index].z;
auto bel_type = getBelType(bel); auto bel_type = getBelType(bel);
int x = decal.location.x;
if (bel_type == id_TRELLIS_SLICE) { int y = decal.location.y;
GraphicElement el; int z = locInfo(bel)->bel_data[bel.index].z;
el.type = GraphicElement::TYPE_BOX; GraphicElement::style_t style = decal.active ? GraphicElement::STYLE_ACTIVE : GraphicElement::STYLE_INACTIVE;
el.style = decal.active ? GraphicElement::STYLE_ACTIVE : GraphicElement::STYLE_INACTIVE; gfxTileBel(ret, x, y, z, chip_info->width, chip_info->height, bel_type, style);
el.x1 = bel.location.x + logic_cell_x1;
el.x2 = bel.location.x + logic_cell_x2;
el.y1 = bel.location.y + logic_cell_y1 + (z)*logic_cell_pitch;
el.y2 = bel.location.y + logic_cell_y2 + (z)*logic_cell_pitch;
ret.push_back(el);
}
if (bel_type == id_TRELLIS_IO) {
GraphicElement el;
el.type = GraphicElement::TYPE_BOX;
el.style = decal.active ? GraphicElement::STYLE_ACTIVE : GraphicElement::STYLE_INACTIVE;
el.x1 = bel.location.x + logic_cell_x1;
el.x2 = bel.location.x + logic_cell_x2;
el.y1 = bel.location.y + logic_cell_y1 + (2 * z) * logic_cell_pitch;
el.y2 = bel.location.y + logic_cell_y2 + (2 * z + 0.5f) * logic_cell_pitch;
ret.push_back(el);
}
} }
return ret; return ret;
@ -656,11 +675,35 @@ DecalXY Arch::getBelDecal(BelId bel) const
return decalxy; return decalxy;
} }
DecalXY Arch::getWireDecal(WireId wire) const { return {}; } DecalXY Arch::getWireDecal(WireId wire) const
{
DecalXY decalxy;
decalxy.decal.type = DecalId::TYPE_WIRE;
decalxy.decal.location = wire.location;
decalxy.decal.z = wire.index;
decalxy.decal.active = getBoundWireNet(wire) != nullptr;
return decalxy;
}
DecalXY Arch::getPipDecal(PipId pip) const { return {}; }; DecalXY Arch::getPipDecal(PipId pip) const
{
DecalXY decalxy;
decalxy.decal.type = DecalId::TYPE_PIP;
decalxy.decal.location = pip.location;
decalxy.decal.z = pip.index;
decalxy.decal.active = getBoundPipNet(pip) != nullptr;
return decalxy;
};
DecalXY Arch::getGroupDecal(GroupId pip) const { return {}; }; DecalXY Arch::getGroupDecal(GroupId group) const
{
DecalXY decalxy;
decalxy.decal.type = DecalId::TYPE_GROUP;
decalxy.decal.location = group.location;
decalxy.decal.z = group.type;
decalxy.decal.active = true;
return decalxy;
}
// ----------------------------------------------------------------------- // -----------------------------------------------------------------------
@ -1078,4 +1121,80 @@ const std::vector<std::string> Arch::availablePlacers = {"sa",
#endif #endif
}; };
// -----------------------------------------------------------------------
GroupId Arch::getGroupByName(IdString name) const
{
for (auto g : getGroups())
if (getGroupName(g) == name)
return g;
return GroupId();
}
IdString Arch::getGroupName(GroupId group) const
{
std::string suffix;
switch (group.type) {
case GroupId::TYPE_SWITCHBOX:
suffix = "switchbox";
break;
default:
return IdString();
}
return id("X" + std::to_string(group.location.x) + "/Y" + std::to_string(group.location.y) + "/" + suffix);
}
std::vector<GroupId> Arch::getGroups() const
{
std::vector<GroupId> ret;
for (int y = 1; y < chip_info->height - 1; y++) {
for (int x = 1; x < chip_info->width - 1; x++) {
GroupId group;
group.type = GroupId::TYPE_SWITCHBOX;
group.location.x = x;
group.location.y = y;
ret.push_back(group);
}
}
return ret;
}
std::vector<BelId> Arch::getGroupBels(GroupId group) const
{
std::vector<BelId> ret;
return ret;
}
std::vector<WireId> Arch::getGroupWires(GroupId group) const
{
std::vector<WireId> ret;
return ret;
}
std::vector<PipId> Arch::getGroupPips(GroupId group) const
{
std::vector<PipId> ret;
return ret;
}
std::vector<GroupId> Arch::getGroupGroups(GroupId group) const
{
std::vector<GroupId> ret;
return ret;
}
// -----------------------------------------------------------------------
std::vector<std::pair<IdString, std::string>> Arch::getWireAttrs(WireId wire) const
{
std::vector<std::pair<IdString, std::string>> ret;
auto &wi = locInfo(wire)->wire_data[wire.index];
ret.push_back(std::make_pair(id("TILE_WIRE_ID"), stringf("%d", wi.tile_wire)));
return ret;
}
NEXTPNR_NAMESPACE_END NEXTPNR_NAMESPACE_END

View File

@ -84,6 +84,8 @@ NPNR_PACKED_STRUCT(struct PipLocatorPOD {
NPNR_PACKED_STRUCT(struct WireInfoPOD { NPNR_PACKED_STRUCT(struct WireInfoPOD {
RelPtr<char> name; RelPtr<char> name;
int32_t type;
int32_t tile_wire;
int32_t num_uphill, num_downhill; int32_t num_uphill, num_downhill;
RelPtr<PipLocatorPOD> pips_uphill, pips_downhill; RelPtr<PipLocatorPOD> pips_uphill, pips_downhill;
@ -640,14 +642,16 @@ struct Arch : BaseCtx
return id(name.str()); return id(name.str());
} }
IdString getWireType(WireId wire) const { return IdString(); } IdString getWireType(WireId wire) const
std::vector<std::pair<IdString, std::string>> getWireAttrs(WireId) const
{ {
std::vector<std::pair<IdString, std::string>> ret; NPNR_ASSERT(wire != WireId());
return ret; IdString id;
id.index = locInfo(wire)->wire_data[wire.index].type;
return id;
} }
std::vector<std::pair<IdString, std::string>> getWireAttrs(WireId) const;
uint32_t getWireChecksum(WireId wire) const { return wire.index; } uint32_t getWireChecksum(WireId wire) const { return wire.index; }
void bindWire(WireId wire, NetInfo *net, PlaceStrength strength) void bindWire(WireId wire, NetInfo *net, PlaceStrength strength)
@ -657,6 +661,7 @@ struct Arch : BaseCtx
wire_to_net[wire] = net; wire_to_net[wire] = net;
net->wires[wire].pip = PipId(); net->wires[wire].pip = PipId();
net->wires[wire].strength = strength; net->wires[wire].strength = strength;
refreshUiWire(wire);
} }
void unbindWire(WireId wire) void unbindWire(WireId wire)
@ -676,6 +681,7 @@ struct Arch : BaseCtx
net_wires.erase(it); net_wires.erase(it);
wire_to_net[wire] = nullptr; wire_to_net[wire] = nullptr;
refreshUiWire(wire);
} }
bool checkWireAvail(WireId wire) const bool checkWireAvail(WireId wire) const
@ -931,13 +937,13 @@ struct Arch : BaseCtx
// ------------------------------------------------- // -------------------------------------------------
GroupId getGroupByName(IdString name) const { return GroupId(); } GroupId getGroupByName(IdString name) const;
IdString getGroupName(GroupId group) const { return IdString(); } IdString getGroupName(GroupId group) const;
std::vector<GroupId> getGroups() const { return std::vector<GroupId>(); } std::vector<GroupId> getGroups() const;
std::vector<BelId> getGroupBels(GroupId group) const { return std::vector<BelId>(); } std::vector<BelId> getGroupBels(GroupId group) const;
std::vector<WireId> getGroupWires(GroupId group) const { return std::vector<WireId>(); } std::vector<WireId> getGroupWires(GroupId group) const;
std::vector<PipId> getGroupPips(GroupId group) const { return std::vector<PipId>(); } std::vector<PipId> getGroupPips(GroupId group) const;
std::vector<GroupId> getGroupGroups(GroupId group) const { return std::vector<GroupId>(); } std::vector<GroupId> getGroupGroups(GroupId group) const;
// ------------------------------------------------- // -------------------------------------------------

View File

@ -128,10 +128,15 @@ struct PipId
struct GroupId struct GroupId
{ {
int32_t index = -1; enum : int8_t
{
TYPE_NONE,
TYPE_SWITCHBOX
} type = TYPE_NONE;
Location location;
bool operator==(const GroupId &other) const { return index == other.index; } bool operator==(const GroupId &other) const { return (type == other.type) && (location == other.location); }
bool operator!=(const GroupId &other) const { return index != other.index; } bool operator!=(const GroupId &other) const { return (type != other.type) || (location != other.location); }
}; };
struct DecalId struct DecalId
@ -139,8 +144,11 @@ struct DecalId
enum enum
{ {
TYPE_NONE, TYPE_NONE,
TYPE_BEL TYPE_BEL,
} type; TYPE_WIRE,
TYPE_PIP,
TYPE_GROUP
} type = TYPE_NONE;
Location location; Location location;
uint32_t z = 0; uint32_t z = 0;
bool active = false; bool active = false;
@ -222,7 +230,10 @@ template <> struct hash<NEXTPNR_NAMESPACE_PREFIX GroupId>
{ {
std::size_t operator()(const NEXTPNR_NAMESPACE_PREFIX GroupId &group) const noexcept std::size_t operator()(const NEXTPNR_NAMESPACE_PREFIX GroupId &group) const noexcept
{ {
return std::hash<int>()(group.index); std::size_t seed = 0;
boost::hash_combine(seed, hash<int>()(group.type));
boost::hash_combine(seed, hash<NEXTPNR_NAMESPACE_PREFIX Location>()(group.location));
return seed;
} }
}; };

View File

@ -1295,6 +1295,41 @@ X(ECLKBRIDGECS)
X(SEL) X(SEL)
X(ECSOUT) X(ECSOUT)
X(WIRE_TYPE_NONE)
X(WIRE_TYPE_SLICE)
X(WIRE_TYPE_DQS)
X(WIRE_TYPE_IOLOGIC)
X(WIRE_TYPE_SIOLOGIC)
X(WIRE_TYPE_PIO)
X(WIRE_TYPE_EBR)
X(WIRE_TYPE_MULT18)
X(WIRE_TYPE_ALU54)
X(WIRE_TYPE_DDRDLL)
X(WIRE_TYPE_CCLK)
X(WIRE_TYPE_EXTREF)
X(WIRE_TYPE_DCU)
X(WIRE_TYPE_PLL)
X(WIRE_TYPE_SED)
X(WIRE_TYPE_OSC)
X(WIRE_TYPE_JTAG)
X(WIRE_TYPE_GSR)
X(WIRE_TYPE_DTR)
X(WIRE_TYPE_PCSCLKDIV)
X(WIRE_TYPE_H00)
X(WIRE_TYPE_H01)
X(WIRE_TYPE_H02)
X(WIRE_TYPE_H06)
X(WIRE_TYPE_V00)
X(WIRE_TYPE_V01)
X(WIRE_TYPE_V02)
X(WIRE_TYPE_V06)
X(WIRE_TYPE_G_HPBX)
X(WIRE_TYPE_G_VPTX)
X(WIRE_TYPE_L_HPBX)
X(WIRE_TYPE_R_HPBX)
X(IOLOGIC_MODE_IDDRX1F) X(IOLOGIC_MODE_IDDRX1F)
X(IOLOGIC_MODE_IDDRX2F) X(IOLOGIC_MODE_IDDRX2F)
X(IOLOGIC_MODE_IREG) X(IOLOGIC_MODE_IREG)

View File

@ -41,14 +41,15 @@ if (NOT EXTERNAL_CHIPDB)
set(DEV_CC_DB ${CMAKE_CURRENT_BINARY_DIR}/ecp5/chipdbs/chipdb-${dev}.bin) set(DEV_CC_DB ${CMAKE_CURRENT_BINARY_DIR}/ecp5/chipdbs/chipdb-${dev}.bin)
set(DEV_CC_BBA_DB ${CMAKE_CURRENT_SOURCE_DIR}/ecp5/chipdbs/chipdb-${dev}.bba) set(DEV_CC_BBA_DB ${CMAKE_CURRENT_SOURCE_DIR}/ecp5/chipdbs/chipdb-${dev}.bba)
set(DEV_CONSTIDS_INC ${CMAKE_CURRENT_SOURCE_DIR}/ecp5/constids.inc) set(DEV_CONSTIDS_INC ${CMAKE_CURRENT_SOURCE_DIR}/ecp5/constids.inc)
set(DEV_GFXH ${CMAKE_CURRENT_SOURCE_DIR}/ecp5/gfx.h)
if (PREGENERATED_BBA_PATH) if (PREGENERATED_BBA_PATH)
add_custom_command(OUTPUT ${DEV_CC_DB} add_custom_command(OUTPUT ${DEV_CC_DB}
COMMAND bbasm ${BBASM_ENDIAN_FLAG} ${PREGENERATED_BBA_PATH}/chipdb-${dev}.bba ${DEV_CC_DB} COMMAND bbasm ${BBASM_ENDIAN_FLAG} ${PREGENERATED_BBA_PATH}/chipdb-${dev}.bba ${DEV_CC_DB}
) )
else() else()
add_custom_command(OUTPUT ${DEV_CC_BBA_DB} add_custom_command(OUTPUT ${DEV_CC_BBA_DB}
COMMAND ${ENV_CMD} ${PYTHON_EXECUTABLE} ${DB_PY} -p ${DEV_CONSTIDS_INC} ${dev} > ${DEV_CC_BBA_DB} COMMAND ${ENV_CMD} ${PYTHON_EXECUTABLE} ${DB_PY} -p ${DEV_CONSTIDS_INC} -g ${DEV_GFXH} ${dev} > ${DEV_CC_BBA_DB}
DEPENDS ${DB_PY} ${DEV_CONSTIDS_INC} ${PREV_DEV_CC_BBA_DB} DEPENDS ${DB_PY} ${DEV_CONSTIDS_INC} ${DEV_GFXH} ${PREV_DEV_CC_BBA_DB}
) )
add_custom_command(OUTPUT ${DEV_CC_DB} add_custom_command(OUTPUT ${DEV_CC_DB}
COMMAND bbasm ${BBASM_ENDIAN_FLAG} ${DEV_CC_BBA_DB} ${DEV_CC_DB} COMMAND bbasm ${BBASM_ENDIAN_FLAG} ${DEV_CC_BBA_DB} ${DEV_CC_DB}
@ -71,6 +72,7 @@ if (NOT EXTERNAL_CHIPDB)
set(DEV_CC_DB ${CMAKE_CURRENT_BINARY_DIR}/ecp5/chipdbs/chipdb-${dev}.cc) set(DEV_CC_DB ${CMAKE_CURRENT_BINARY_DIR}/ecp5/chipdbs/chipdb-${dev}.cc)
set(DEV_CC_BBA_DB ${CMAKE_CURRENT_SOURCE_DIR}/ecp5/chipdbs/chipdb-${dev}.bba) set(DEV_CC_BBA_DB ${CMAKE_CURRENT_SOURCE_DIR}/ecp5/chipdbs/chipdb-${dev}.bba)
set(DEV_CONSTIDS_INC ${CMAKE_CURRENT_SOURCE_DIR}/ecp5/constids.inc) set(DEV_CONSTIDS_INC ${CMAKE_CURRENT_SOURCE_DIR}/ecp5/constids.inc)
set(DEV_GFXH ${CMAKE_CURRENT_SOURCE_DIR}/ecp5/gfx.h)
if (PREGENERATED_BBA_PATH) if (PREGENERATED_BBA_PATH)
add_custom_command(OUTPUT ${DEV_CC_DB} add_custom_command(OUTPUT ${DEV_CC_DB}
COMMAND bbasm --c ${BBASM_ENDIAN_FLAG} ${PREGENERATED_BBA_PATH}/chipdb-${dev}.bba ${DEV_CC_DB}.new COMMAND bbasm --c ${BBASM_ENDIAN_FLAG} ${PREGENERATED_BBA_PATH}/chipdb-${dev}.bba ${DEV_CC_DB}.new
@ -78,9 +80,9 @@ if (NOT EXTERNAL_CHIPDB)
) )
else() else()
add_custom_command(OUTPUT ${DEV_CC_BBA_DB} add_custom_command(OUTPUT ${DEV_CC_BBA_DB}
COMMAND ${ENV_CMD} ${PYTHON_EXECUTABLE} ${DB_PY} -p ${DEV_CONSTIDS_INC} ${dev} > ${DEV_CC_BBA_DB}.new COMMAND ${ENV_CMD} ${PYTHON_EXECUTABLE} ${DB_PY} -p ${DEV_CONSTIDS_INC} -g ${DEV_GFXH} ${dev} > ${DEV_CC_BBA_DB}.new
COMMAND mv ${DEV_CC_BBA_DB}.new ${DEV_CC_BBA_DB} COMMAND mv ${DEV_CC_BBA_DB}.new ${DEV_CC_BBA_DB}
DEPENDS ${DB_PY} ${DEV_CONSTIDS_INC} ${PREV_DEV_CC_BBA_DB} DEPENDS ${DB_PY} ${DEV_CONSTIDS_INC} ${DEV_GFXH} ${PREV_DEV_CC_BBA_DB}
) )
add_custom_command(OUTPUT ${DEV_CC_DB} add_custom_command(OUTPUT ${DEV_CC_DB}
COMMAND bbasm --c ${BBASM_ENDIAN_FLAG} ${DEV_CC_BBA_DB} ${DEV_CC_DB}.new COMMAND bbasm --c ${BBASM_ENDIAN_FLAG} ${DEV_CC_BBA_DB} ${DEV_CC_DB}.new

1522
ecp5/gfx.cc Normal file

File diff suppressed because it is too large Load Diff

3688
ecp5/gfx.h

File diff suppressed because it is too large Load Diff

View File

@ -10,12 +10,146 @@ from os import path
location_types = dict() location_types = dict()
type_at_location = dict() type_at_location = dict()
tiletype_names = dict() tiletype_names = dict()
gfx_wire_ids = dict()
gfx_wire_names = list()
parser = argparse.ArgumentParser(description="import ECP5 routing and bels from Project Trellis") parser = argparse.ArgumentParser(description="import ECP5 routing and bels from Project Trellis")
parser.add_argument("device", type=str, help="target device") parser.add_argument("device", type=str, help="target device")
parser.add_argument("-p", "--constids", type=str, help="path to constids.inc") parser.add_argument("-p", "--constids", type=str, help="path to constids.inc")
parser.add_argument("-g", "--gfxh", type=str, help="path to gfx.h")
args = parser.parse_args() args = parser.parse_args()
with open(args.gfxh) as f:
state = 0
for line in f:
if state == 0 and line.startswith("enum GfxTileWireId"):
state = 1
elif state == 1 and line.startswith("};"):
state = 0
elif state == 1 and (line.startswith("{") or line.strip() == ""):
pass
elif state == 1:
idx = len(gfx_wire_ids)
name = line.strip().rstrip(",")
gfx_wire_ids[name] = idx
gfx_wire_names.append(name)
def gfx_wire_alias(old, new):
assert old in gfx_wire_ids
assert new not in gfx_wire_ids
gfx_wire_ids[new] = gfx_wire_ids[old]
def wire_type(name):
longname = name
name = name.split('/')
if name[0].startswith("X") and name[1].startswith("Y"):
name = name[2:]
if name[0].endswith("_SLICE"):
return "WIRE_TYPE_SLICE"
if name[0].endswith("_DQS"):
return "WIRE_TYPE_DQS"
if name[0].endswith("_IOLOGIC"):
return "WIRE_TYPE_IOLOGIC"
if name[0].endswith("_SIOLOGIC"):
return "WIRE_TYPE_SIOLOGIC"
if name[0].endswith("_PIO"):
return "WIRE_TYPE_PIO"
if name[0].endswith("_DDRDLL"):
return "WIRE_TYPE_DDRDLL"
if name[0].endswith("_CCLK"):
return "WIRE_TYPE_CCLK"
if name[0].endswith("_EXTREF"):
return "WIRE_TYPE_EXTREF"
if name[0].endswith("_DCU"):
return "WIRE_TYPE_DCU"
if name[0].endswith("_EBR"):
return "WIRE_TYPE_EBR"
if name[0].endswith("_MULT18"):
return "WIRE_TYPE_MULT18"
if name[0].endswith("_ALU54"):
return "WIRE_TYPE_ALU54"
if name[0].endswith("_PLL"):
return "WIRE_TYPE_PLL"
if name[0].endswith("_SED"):
return "WIRE_TYPE_SED"
if name[0].endswith("_OSC"):
return "WIRE_TYPE_OSC"
if name[0].endswith("_JTAG"):
return "WIRE_TYPE_JTAG"
if name[0].endswith("_GSR"):
return "WIRE_TYPE_GSR"
if name[0].endswith("_DTR"):
return "WIRE_TYPE_DTR"
if name[0].endswith("_PCSCLKDIV0"):
return "WIRE_TYPE_PCSCLKDIV"
if name[0].endswith("_PCSCLKDIV1"):
return "WIRE_TYPE_PCSCLKDIV"
if name[0].startswith("H00"):
return "WIRE_TYPE_H00"
if name[0].startswith("H01"):
return "WIRE_TYPE_H01"
if name[0].startswith("HFI"):
return "WIRE_TYPE_H01"
if name[0].startswith("HL7"):
return "WIRE_TYPE_H01"
if name[0].startswith("H02"):
return "WIRE_TYPE_H02"
if name[0].startswith("H06"):
return "WIRE_TYPE_H06"
if name[0].startswith("V00"):
return "WIRE_TYPE_V00"
if name[0].startswith("V01"):
return "WIRE_TYPE_V01"
if name[0].startswith("V02"):
return "WIRE_TYPE_V02"
if name[0].startswith("V06"):
return "WIRE_TYPE_V06"
if name[0].startswith("G_HPBX"):
return "WIRE_TYPE_G_HPBX"
if name[0].startswith("G_VPTX"):
return "WIRE_TYPE_G_VPTX"
if name[0].startswith("L_HPBX"):
return "WIRE_TYPE_L_HPBX"
if name[0].startswith("R_HPBX"):
return "WIRE_TYPE_R_HPBX"
return "WIRE_TYPE_NONE"
def is_global(loc): def is_global(loc):
return loc.x == -2 and loc.y == -2 return loc.x == -2 and loc.y == -2
@ -300,6 +434,11 @@ def write_database(dev_name, chip, ddrg, endianness):
for wire_idx in range(len(loctype.wires)): for wire_idx in range(len(loctype.wires)):
wire = loctype.wires[wire_idx] wire = loctype.wires[wire_idx]
bba.s(ddrg.to_str(wire.name), "name") bba.s(ddrg.to_str(wire.name), "name")
bba.u32(constids[wire_type(ddrg.to_str(wire.name))], "type")
if ("TILE_WIRE_" + ddrg.to_str(wire.name)) in gfx_wire_ids:
bba.u32(gfx_wire_ids["TILE_WIRE_" + ddrg.to_str(wire.name)], "tile_wire")
else:
bba.u32(0, "tile_wire")
bba.u32(len(wire.arcsUphill), "num_uphill") bba.u32(len(wire.arcsUphill), "num_uphill")
bba.u32(len(wire.arcsDownhill), "num_downhill") bba.u32(len(wire.arcsDownhill), "num_downhill")
bba.r("loc%d_wire%d_uppips" % (idx, wire_idx) if len(wire.arcsUphill) > 0 else None, "pips_uphill") bba.r("loc%d_wire%d_uppips" % (idx, wire_idx) if len(wire.arcsUphill) > 0 else None, "pips_uphill")

View File

@ -24,5 +24,9 @@
<file>resources/open_json.png</file> <file>resources/open_json.png</file>
<file>resources/save_json.png</file> <file>resources/save_json.png</file>
<file>resources/py.png</file> <file>resources/py.png</file>
<file>resources/bel.png</file>
<file>resources/wire.png</file>
<file>resources/pip.png</file>
<file>resources/group.png</file>
</qresource> </qresource>
</RCC> </RCC>

View File

@ -224,6 +224,38 @@ void BaseMainWindow::createMenusAndBars()
actionZoomOutbound->setIcon(QIcon(":/icons/resources/shape_square.png")); actionZoomOutbound->setIcon(QIcon(":/icons/resources/shape_square.png"));
connect(actionZoomOutbound, &QAction::triggered, fpgaView, &FPGAViewWidget::zoomOutbound); connect(actionZoomOutbound, &QAction::triggered, fpgaView, &FPGAViewWidget::zoomOutbound);
actionDisplayBel = new QAction("Enable/Disable Bels", this);
actionDisplayBel->setIcon(QIcon(":/icons/resources/bel.png"));
actionDisplayBel->setCheckable(true);
actionDisplayBel->setChecked(true);
connect(actionDisplayBel, &QAction::triggered, this, &BaseMainWindow::enableDisableDecals);
actionDisplayWire = new QAction("Enable/Disable Wires", this);
actionDisplayWire->setIcon(QIcon(":/icons/resources/wire.png"));
actionDisplayWire->setCheckable(true);
actionDisplayWire->setChecked(true);
connect(actionDisplayWire, &QAction::triggered, this, &BaseMainWindow::enableDisableDecals);
actionDisplayPip = new QAction("Enable/Disable Pips", this);
actionDisplayPip->setIcon(QIcon(":/icons/resources/pip.png"));
actionDisplayPip->setCheckable(true);
#ifdef ARCH_ECP5
actionDisplayPip->setChecked(false);
#else
actionDisplayPip->setChecked(true);
#endif
connect(actionDisplayPip, &QAction::triggered, this, &BaseMainWindow::enableDisableDecals);
actionDisplayGroups = new QAction("Enable/Disable Groups", this);
actionDisplayGroups->setIcon(QIcon(":/icons/resources/group.png"));
actionDisplayGroups->setCheckable(true);
actionDisplayGroups->setChecked(true);
connect(actionDisplayGroups, &QAction::triggered, this, &BaseMainWindow::enableDisableDecals);
// set initial state
fpgaView->enableDisableDecals(actionDisplayBel->isChecked(), actionDisplayWire->isChecked(),
actionDisplayPip->isChecked(), actionDisplayGroups->isChecked());
// Add main menu // Add main menu
menuBar = new QMenuBar(); menuBar = new QMenuBar();
menuBar->setGeometry(QRect(0, 0, 1024, 27)); menuBar->setGeometry(QRect(0, 0, 1024, 27));
@ -280,6 +312,11 @@ void BaseMainWindow::createMenusAndBars()
deviceViewToolBar->addAction(actionZoomOut); deviceViewToolBar->addAction(actionZoomOut);
deviceViewToolBar->addAction(actionZoomSelected); deviceViewToolBar->addAction(actionZoomSelected);
deviceViewToolBar->addAction(actionZoomOutbound); deviceViewToolBar->addAction(actionZoomOutbound);
deviceViewToolBar->addSeparator();
deviceViewToolBar->addAction(actionDisplayBel);
deviceViewToolBar->addAction(actionDisplayWire);
deviceViewToolBar->addAction(actionDisplayPip);
deviceViewToolBar->addAction(actionDisplayGroups);
// Add status bar with progress bar // Add status bar with progress bar
statusBar = new QStatusBar(); statusBar = new QStatusBar();
@ -292,6 +329,13 @@ void BaseMainWindow::createMenusAndBars()
setStatusBar(statusBar); setStatusBar(statusBar);
} }
void BaseMainWindow::enableDisableDecals()
{
fpgaView->enableDisableDecals(actionDisplayBel->isChecked(), actionDisplayWire->isChecked(),
actionDisplayPip->isChecked(), actionDisplayGroups->isChecked());
ctx->refreshUi();
}
void BaseMainWindow::open_json() void BaseMainWindow::open_json()
{ {
QString fileName = QFileDialog::getOpenFileName(this, QString("Open JSON"), QString(), QString("*.json")); QString fileName = QFileDialog::getOpenFileName(this, QString("Open JSON"), QString(), QString("*.json"));

View File

@ -56,6 +56,7 @@ class BaseMainWindow : public QMainWindow
protected: protected:
void createMenusAndBars(); void createMenusAndBars();
void disableActions(); void disableActions();
void enableDisableDecals();
virtual void onDisableActions(){}; virtual void onDisableActions(){};
virtual void onUpdateActions(){}; virtual void onUpdateActions(){};
@ -122,6 +123,11 @@ class BaseMainWindow : public QMainWindow
QAction *actionPlay; QAction *actionPlay;
QAction *actionPause; QAction *actionPause;
QAction *actionStop; QAction *actionStop;
QAction *actionDisplayBel;
QAction *actionDisplayWire;
QAction *actionDisplayPip;
QAction *actionDisplayGroups;
}; };
NEXTPNR_NAMESPACE_END NEXTPNR_NAMESPACE_END

View File

@ -66,6 +66,11 @@ FPGAViewWidget::FPGAViewWidget(QWidget *parent)
renderRunner_->start(); renderRunner_->start();
renderRunner_->startTimer(1000 / 2); // render lines 2 times per second renderRunner_->startTimer(1000 / 2); // render lines 2 times per second
setMouseTracking(true); setMouseTracking(true);
displayBel_ = false;
displayWire_ = false;
displayPip_ = false;
displayGroup_ = false;
} }
FPGAViewWidget::~FPGAViewWidget() {} FPGAViewWidget::~FPGAViewWidget() {}
@ -333,6 +338,14 @@ void FPGAViewWidget::paintGL()
void FPGAViewWidget::pokeRenderer(void) { renderRunner_->poke(); } void FPGAViewWidget::pokeRenderer(void) { renderRunner_->poke(); }
void FPGAViewWidget::enableDisableDecals(bool bels, bool wires, bool pips, bool groups)
{
displayBel_ = bels;
displayWire_ = wires;
displayPip_ = pips;
displayGroup_ = groups;
}
void FPGAViewWidget::renderLines(void) void FPGAViewWidget::renderLines(void)
{ {
if (ctx_ == nullptr) if (ctx_ == nullptr)
@ -379,17 +392,25 @@ void FPGAViewWidget::renderLines(void)
// Local copy of decals, taken as fast as possible to not block the P&R. // Local copy of decals, taken as fast as possible to not block the P&R.
if (decalsChanged) { if (decalsChanged) {
for (auto bel : ctx_->getBels()) { if (displayBel_) {
belDecals.push_back({ctx_->getBelDecal(bel), bel}); for (auto bel : ctx_->getBels()) {
belDecals.push_back({ctx_->getBelDecal(bel), bel});
}
} }
for (auto wire : ctx_->getWires()) { if (displayWire_) {
wireDecals.push_back({ctx_->getWireDecal(wire), wire}); for (auto wire : ctx_->getWires()) {
wireDecals.push_back({ctx_->getWireDecal(wire), wire});
}
} }
for (auto pip : ctx_->getPips()) { if (displayPip_) {
pipDecals.push_back({ctx_->getPipDecal(pip), pip}); for (auto pip : ctx_->getPips()) {
pipDecals.push_back({ctx_->getPipDecal(pip), pip});
}
} }
for (auto group : ctx_->getGroups()) { if (displayGroup_) {
groupDecals.push_back({ctx_->getGroupDecal(group), group}); for (auto group : ctx_->getGroups()) {
groupDecals.push_back({ctx_->getGroupDecal(group), group});
}
} }
} }
} }
@ -430,20 +451,28 @@ void FPGAViewWidget::renderLines(void)
data->bbGlobal.clear(); data->bbGlobal.clear();
// Draw Bels. // Draw Bels.
for (auto const &decal : belDecals) { if (displayBel_) {
renderArchDecal(data->gfxByStyle, data->bbGlobal, decal.first); for (auto const &decal : belDecals) {
renderArchDecal(data->gfxByStyle, data->bbGlobal, decal.first);
}
} }
// Draw Wires. // Draw Wires.
for (auto const &decal : wireDecals) { if (displayWire_) {
renderArchDecal(data->gfxByStyle, data->bbGlobal, decal.first); for (auto const &decal : wireDecals) {
renderArchDecal(data->gfxByStyle, data->bbGlobal, decal.first);
}
} }
// Draw Pips. // Draw Pips.
for (auto const &decal : pipDecals) { if (displayPip_) {
renderArchDecal(data->gfxByStyle, data->bbGlobal, decal.first); for (auto const &decal : pipDecals) {
renderArchDecal(data->gfxByStyle, data->bbGlobal, decal.first);
}
} }
// Draw Groups. // Draw Groups.
for (auto const &decal : groupDecals) { if (displayGroup_) {
renderArchDecal(data->gfxByStyle, data->bbGlobal, decal.first); for (auto const &decal : groupDecals) {
renderArchDecal(data->gfxByStyle, data->bbGlobal, decal.first);
}
} }
// Bounding box should be calculated by now. // Bounding box should be calculated by now.

View File

@ -119,6 +119,7 @@ class FPGAViewWidget : public QOpenGLWidget, protected QOpenGLFunctions
void zoomOut(); void zoomOut();
void zoomSelected(); void zoomSelected();
void zoomOutbound(); void zoomOutbound();
void enableDisableDecals(bool bels, bool wires, bool pips, bool groups);
Q_SIGNALS: Q_SIGNALS:
void clickedBel(BelId bel, bool add); void clickedBel(BelId bel, bool add);
@ -126,8 +127,8 @@ class FPGAViewWidget : public QOpenGLWidget, protected QOpenGLFunctions
void clickedPip(PipId pip, bool add); void clickedPip(PipId pip, bool add);
private: private:
const float zoomNear_ = 0.1f; // do not zoom closer than this const float zoomNear_ = 0.05f; // do not zoom closer than this
float zoomFar_ = 10.0f; // do not zoom further than this float zoomFar_ = 10.0f; // do not zoom further than this
const float zoomLvl1_ = 1.0f; const float zoomLvl1_ = 1.0f;
const float zoomLvl2_ = 5.0f; const float zoomLvl2_ = 5.0f;
@ -227,6 +228,11 @@ class FPGAViewWidget : public QOpenGLWidget, protected QOpenGLFunctions
QMatrix4x4 viewMove_; QMatrix4x4 viewMove_;
float zoom_; float zoom_;
bool displayBel_;
bool displayWire_;
bool displayPip_;
bool displayGroup_;
struct struct
{ {
QColor background; QColor background;

BIN
gui/resources/bel.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 516 B

BIN
gui/resources/group.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 529 B

BIN
gui/resources/pip.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 367 B

BIN
gui/resources/wire.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 365 B