Add Groups API
Signed-off-by: Clifford Wolf <clifford@clifford.at>
This commit is contained in:
parent
1245eb6343
commit
a436035424
@ -271,6 +271,7 @@ struct BaseCtx
|
||||
std::unordered_set<BelId> belUiReload;
|
||||
std::unordered_set<WireId> wireUiReload;
|
||||
std::unordered_set<PipId> pipUiReload;
|
||||
std::unordered_set<GroupId> groupUiReload;
|
||||
|
||||
void refreshUi()
|
||||
{
|
||||
@ -296,6 +297,11 @@ struct BaseCtx
|
||||
{
|
||||
pipUiReload.insert(pip);
|
||||
}
|
||||
|
||||
void refreshUiGroup(GroupId group)
|
||||
{
|
||||
groupUiReload.insert(group);
|
||||
}
|
||||
};
|
||||
|
||||
NEXTPNR_NAMESPACE_END
|
||||
@ -368,6 +374,19 @@ struct Context : Arch
|
||||
return ret;
|
||||
}
|
||||
|
||||
NPNR_DEPRECATED std::vector<GraphicElement> getGroupGraphics(GroupId group) const {
|
||||
std::vector<GraphicElement> ret;
|
||||
DecalXY decalxy = getGroupDecal(group);
|
||||
ret = getDecalGraphics(decalxy.decal);
|
||||
for (auto &it : ret) {
|
||||
it.x1 += decalxy.x;
|
||||
it.x2 += decalxy.x;
|
||||
it.y1 += decalxy.y;
|
||||
it.y2 += decalxy.y;
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
// --------------------------------------------------------------
|
||||
|
||||
// provided by router1.cc
|
||||
|
@ -317,6 +317,8 @@ DecalXY Arch::getWireDecal(WireId wire) const { return {}; }
|
||||
|
||||
DecalXY Arch::getPipDecal(PipId pip) const { return {}; };
|
||||
|
||||
DecalXY Arch::getGroupDecal(PipId pip) const { return {}; };
|
||||
|
||||
// -----------------------------------------------------------------------
|
||||
|
||||
bool Arch::isValidBelForCell(CellInfo *cell, BelId bel) const { return true; }
|
||||
|
11
ecp5/arch.h
11
ecp5/arch.h
@ -711,6 +711,16 @@ struct Arch : BaseCtx
|
||||
|
||||
// -------------------------------------------------
|
||||
|
||||
GroupId getGroupByName(IdString name) const { return GroupId(); }
|
||||
IdString getGroupName(GroupId group) const { return IdString(); }
|
||||
std::vector<GroupId> getGroups() const { return std::vector<GroupId>(); }
|
||||
std::vector<BelId> getGroupBels(GroupId group) const { return std::vector<BelId>(); }
|
||||
std::vector<WireId> getGroupWires(GroupId group) const { return std::vector<WireId>(); }
|
||||
std::vector<PipId> getGroupPips(GroupId group) const { return std::vector<PipId>(); }
|
||||
std::vector<GroupId> getGroupGroups(GroupId group) const { return std::vector<GroupId>(); }
|
||||
|
||||
// -------------------------------------------------
|
||||
|
||||
void estimatePosition(BelId bel, int &x, int &y, bool &gb) const;
|
||||
delay_t estimateDelay(WireId src, WireId dst) const;
|
||||
delay_t getDelayEpsilon() const { return 20; }
|
||||
@ -731,6 +741,7 @@ struct Arch : BaseCtx
|
||||
DecalXY getBelDecal(BelId bel) const;
|
||||
DecalXY getWireDecal(WireId wire) const;
|
||||
DecalXY getPipDecal(PipId pip) const;
|
||||
DecalXY getGroupDecal(GroupId group) const;
|
||||
|
||||
// -------------------------------------------------
|
||||
|
||||
|
@ -105,11 +105,22 @@ struct PipId
|
||||
bool operator!=(const PipId &other) const { return index != other.index || location != other.location; }
|
||||
};
|
||||
|
||||
struct GroupId
|
||||
{
|
||||
int32_t index = -1;
|
||||
|
||||
bool operator==(const GroupId &other) const { return index == other.index; }
|
||||
bool operator!=(const GroupId &other) const { return index != other.index; }
|
||||
};
|
||||
|
||||
struct DecalId
|
||||
{
|
||||
char type = 0; // Bel/Wire/Pip/Frame (b/w/p/f)
|
||||
Location location;
|
||||
uint32_t z = 0;
|
||||
|
||||
bool operator==(const DecalId &other) const { return type == other.type && location == other.location && z == other.z; }
|
||||
bool operator!=(const DecalId &other) const { return type != other.type || location != other.location || z != other.z; }
|
||||
};
|
||||
|
||||
NEXTPNR_NAMESPACE_END
|
||||
@ -155,6 +166,14 @@ template <> struct hash<NEXTPNR_NAMESPACE_PREFIX PipId>
|
||||
}
|
||||
};
|
||||
|
||||
template <> struct hash<NEXTPNR_NAMESPACE_PREFIX GroupId>
|
||||
{
|
||||
std::size_t operator()(const NEXTPNR_NAMESPACE_PREFIX GroupId &group) const noexcept
|
||||
{
|
||||
return std::hash<int>()(group.index);
|
||||
}
|
||||
};
|
||||
|
||||
template <> struct hash<NEXTPNR_NAMESPACE_PREFIX DecalId>
|
||||
{
|
||||
std::size_t operator()(const NEXTPNR_NAMESPACE_PREFIX DecalId &decal) const noexcept
|
||||
|
@ -109,6 +109,26 @@ void Arch::addBelInout(IdString bel, IdString name, IdString wire)
|
||||
wires.at(wire).downhill_bel_pins.push_back(BelPin{bel, name});
|
||||
}
|
||||
|
||||
void Arch::addGroupBel(IdString group, IdString bel)
|
||||
{
|
||||
groups[group].bels.push_back(bel);
|
||||
}
|
||||
|
||||
void Arch::addGroupWire(IdString group, IdString wire)
|
||||
{
|
||||
groups[group].wires.push_back(wire);
|
||||
}
|
||||
|
||||
void Arch::addGroupPip(IdString group, IdString pip)
|
||||
{
|
||||
groups[group].pips.push_back(pip);
|
||||
}
|
||||
|
||||
void Arch::addGroupGroup(IdString group, IdString grp)
|
||||
{
|
||||
groups[group].groups.push_back(grp);
|
||||
}
|
||||
|
||||
void Arch::addDecalGraphic(DecalId decal, const GraphicElement &graphic)
|
||||
{
|
||||
decal_graphics[decal].push_back(graphic);
|
||||
@ -139,6 +159,12 @@ void Arch::setBelDecal(BelId bel, DecalXY decalxy)
|
||||
refreshUiBel(bel);
|
||||
}
|
||||
|
||||
void Arch::setGroupDecal(GroupId group, DecalXY decalxy)
|
||||
{
|
||||
groups[group].decalxy = decalxy;
|
||||
refreshUiGroup(group);
|
||||
}
|
||||
|
||||
// ---------------------------------------------------------------
|
||||
|
||||
Arch::Arch(ArchArgs) {}
|
||||
@ -300,6 +326,27 @@ const std::vector<PipId> &Arch::getWireAliases(WireId wire) const { return wires
|
||||
|
||||
// ---------------------------------------------------------------
|
||||
|
||||
GroupId Arch::getGroupByName(IdString name) const { return name; }
|
||||
|
||||
IdString Arch::getGroupName(GroupId group) const { return group; }
|
||||
|
||||
std::vector<GroupId> Arch::getGroups() const {
|
||||
std::vector<GroupId> ret;
|
||||
for (auto &it : groups)
|
||||
ret.push_back(it.first);
|
||||
return ret;
|
||||
}
|
||||
|
||||
const std::vector<BelId> &Arch::getGroupBels(GroupId group) const { return groups.at(group).bels; }
|
||||
|
||||
const std::vector<WireId> &Arch::getGroupWires(GroupId group) const { return groups.at(group).wires; }
|
||||
|
||||
const std::vector<PipId> &Arch::getGroupPips(GroupId group) const { return groups.at(group).pips; }
|
||||
|
||||
const std::vector<GroupId> &Arch::getGroupGroups(GroupId group) const { return groups.at(group).groups; }
|
||||
|
||||
// ---------------------------------------------------------------
|
||||
|
||||
void Arch::estimatePosition(BelId bel, int &x, int &y, bool &gb) const
|
||||
{
|
||||
x = bels.at(bel).grid_x;
|
||||
@ -330,7 +377,6 @@ bool Arch::route()
|
||||
|
||||
// ---------------------------------------------------------------
|
||||
|
||||
|
||||
const std::vector<GraphicElement> &Arch::getDecalGraphics(DecalId decal) const { return decal_graphics.at(decal); }
|
||||
|
||||
DecalXY Arch::getFrameDecal() const { return frame_decalxy; }
|
||||
@ -341,6 +387,8 @@ DecalXY Arch::getWireDecal(WireId wire) const { return wires.at(wire).decalxy; }
|
||||
|
||||
DecalXY Arch::getPipDecal(PipId pip) const { return pips.at(pip).decalxy; }
|
||||
|
||||
DecalXY Arch::getGroupDecal(GroupId group) const { return groups.at(group).decalxy; }
|
||||
|
||||
// ---------------------------------------------------------------
|
||||
|
||||
bool Arch::getCellDelay(const CellInfo *cell, IdString fromPort, IdString toPort, delay_t &delay) const
|
||||
|
@ -63,6 +63,16 @@ struct BelInfo
|
||||
bool gb;
|
||||
};
|
||||
|
||||
struct GroupInfo
|
||||
{
|
||||
IdString name;
|
||||
std::vector<BelId> bels;
|
||||
std::vector<WireId> wires;
|
||||
std::vector<PipId> pips;
|
||||
std::vector<GroupId> groups;
|
||||
DecalXY decalxy;
|
||||
};
|
||||
|
||||
struct Arch : BaseCtx
|
||||
{
|
||||
std::string chipName;
|
||||
@ -70,6 +80,7 @@ struct Arch : BaseCtx
|
||||
std::unordered_map<IdString, WireInfo> wires;
|
||||
std::unordered_map<IdString, PipInfo> pips;
|
||||
std::unordered_map<IdString, BelInfo> bels;
|
||||
std::unordered_map<GroupId, GroupInfo> groups;
|
||||
|
||||
std::vector<IdString> bel_ids, wire_ids, pip_ids;
|
||||
std::unordered_map<IdString, std::vector<IdString>> bel_ids_by_type;
|
||||
@ -88,11 +99,17 @@ struct Arch : BaseCtx
|
||||
void addBelOutput(IdString bel, IdString name, IdString wire);
|
||||
void addBelInout(IdString bel, IdString name, IdString wire);
|
||||
|
||||
void addGroupBel(IdString group, IdString bel);
|
||||
void addGroupWire(IdString group, IdString wire);
|
||||
void addGroupPip(IdString group, IdString pip);
|
||||
void addGroupGroup(IdString group, IdString grp);
|
||||
|
||||
void addDecalGraphic(DecalId decal, const GraphicElement &graphic);
|
||||
void setFrameDecal(DecalXY decalxy);
|
||||
void setWireDecal(WireId wire, DecalXY decalxy);
|
||||
void setPipDecal(PipId pip, DecalXY decalxy);
|
||||
void setBelDecal(BelId bel, DecalXY decalxy);
|
||||
void setGroupDecal(GroupId group, DecalXY decalxy);
|
||||
|
||||
// ---------------------------------------------------------------
|
||||
// Common Arch API. Every arch must provide the following methods.
|
||||
@ -151,6 +168,14 @@ struct Arch : BaseCtx
|
||||
const std::vector<PipId> &getPipsUphill(WireId wire) const;
|
||||
const std::vector<PipId> &getWireAliases(WireId wire) const;
|
||||
|
||||
GroupId getGroupByName(IdString name) const;
|
||||
IdString getGroupName(GroupId group) const;
|
||||
std::vector<GroupId> getGroups() const;
|
||||
const std::vector<BelId> &getGroupBels(GroupId group) const;
|
||||
const std::vector<WireId> &getGroupWires(GroupId group) const;
|
||||
const std::vector<PipId> &getGroupPips(GroupId group) const;
|
||||
const std::vector<GroupId> &getGroupGroups(GroupId group) const;
|
||||
|
||||
void estimatePosition(BelId bel, int &x, int &y, bool &gb) const;
|
||||
delay_t estimateDelay(WireId src, WireId dst) const;
|
||||
delay_t getDelayEpsilon() const { return 0.01; }
|
||||
@ -166,6 +191,7 @@ struct Arch : BaseCtx
|
||||
DecalXY getBelDecal(BelId bel) const;
|
||||
DecalXY getWireDecal(WireId wire) const;
|
||||
DecalXY getPipDecal(PipId pip) const;
|
||||
DecalXY getGroupDecal(GroupId group) const;
|
||||
|
||||
bool getCellDelay(const CellInfo *cell, IdString fromPort, IdString toPort, delay_t &delay) const;
|
||||
IdString getPortClock(const CellInfo *cell, IdString port) const;
|
||||
|
@ -49,6 +49,7 @@ typedef IdString PortPin;
|
||||
typedef IdString BelId;
|
||||
typedef IdString WireId;
|
||||
typedef IdString PipId;
|
||||
typedef IdString GroupId;
|
||||
typedef IdString DecalId;
|
||||
|
||||
NEXTPNR_NAMESPACE_END
|
||||
|
@ -383,6 +383,16 @@ void FPGAViewWidget::paintGL()
|
||||
lineShader_.draw(pips, matrix);
|
||||
}
|
||||
|
||||
// Draw Groups.
|
||||
auto groups = LineShaderData(0.0005f, QColor("#b000ba"));
|
||||
if (ctx_) {
|
||||
for (auto group : ctx_->getGroups()) {
|
||||
for (auto &el : ctx_->getGroupGraphics(group))
|
||||
drawElement(groups, el);
|
||||
}
|
||||
lineShader_.draw(groups, matrix);
|
||||
}
|
||||
|
||||
// Draw Frame Graphics.
|
||||
auto frames = LineShaderData(0.002f, QColor("#0066ba"));
|
||||
if (ctx_) {
|
||||
|
@ -369,6 +369,52 @@ std::string Arch::getBelPackagePin(BelId bel) const
|
||||
}
|
||||
return "";
|
||||
}
|
||||
|
||||
// -----------------------------------------------------------------------
|
||||
|
||||
GroupId Arch::getGroupByName(IdString name) const
|
||||
{
|
||||
for (auto g : getGroups())
|
||||
if (getGroupName(g) == name)
|
||||
return g;
|
||||
return GroupId();
|
||||
}
|
||||
|
||||
IdString Arch::getGroupName(GroupId group) const
|
||||
{
|
||||
return IdString();
|
||||
}
|
||||
|
||||
std::vector<GroupId> Arch::getGroups() const
|
||||
{
|
||||
std::vector<GroupId> ret;
|
||||
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;
|
||||
}
|
||||
|
||||
// -----------------------------------------------------------------------
|
||||
|
||||
void Arch::estimatePosition(BelId bel, int &x, int &y, bool &gb) const
|
||||
@ -417,15 +463,15 @@ bool Arch::route()
|
||||
DecalXY Arch::getFrameDecal() const
|
||||
{
|
||||
DecalXY decalxy;
|
||||
decalxy.decal.type = 'f';
|
||||
decalxy.decal.type = DecalId::TYPE_FRAME;
|
||||
return decalxy;
|
||||
}
|
||||
|
||||
DecalXY Arch::getBelDecal(BelId bel) const
|
||||
{
|
||||
DecalXY decalxy;
|
||||
decalxy.decal.type = 'b';
|
||||
decalxy.decal.z = bel.index;
|
||||
decalxy.decal.type = DecalId::TYPE_BEL;
|
||||
decalxy.decal.index = bel.index;
|
||||
return decalxy;
|
||||
}
|
||||
|
||||
@ -441,11 +487,17 @@ DecalXY Arch::getPipDecal(PipId pip) const
|
||||
return decalxy;
|
||||
};
|
||||
|
||||
DecalXY Arch::getGroupDecal(GroupId group) const
|
||||
{
|
||||
DecalXY decalxy;
|
||||
return decalxy;
|
||||
};
|
||||
|
||||
std::vector<GraphicElement> Arch::getDecalGraphics(DecalId decal) const
|
||||
{
|
||||
std::vector<GraphicElement> ret;
|
||||
|
||||
if (decal.type == 'f')
|
||||
if (decal.type == DecalId::TYPE_FRAME)
|
||||
{
|
||||
for (int x = 0; x <= chip_info->width; x++)
|
||||
for (int y = 0; y <= chip_info->height; y++) {
|
||||
@ -458,10 +510,10 @@ std::vector<GraphicElement> Arch::getDecalGraphics(DecalId decal) const
|
||||
}
|
||||
}
|
||||
|
||||
if (decal.type == 'b')
|
||||
if (decal.type == DecalId::TYPE_BEL)
|
||||
{
|
||||
BelId bel;
|
||||
bel.index = decal.z;
|
||||
bel.index = decal.index;
|
||||
|
||||
auto bel_type = getBelType(bel);
|
||||
|
||||
|
11
ice40/arch.h
11
ice40/arch.h
@ -634,6 +634,16 @@ struct Arch : BaseCtx
|
||||
|
||||
// -------------------------------------------------
|
||||
|
||||
GroupId getGroupByName(IdString name) const;
|
||||
IdString getGroupName(GroupId group) const;
|
||||
std::vector<GroupId> getGroups() const;
|
||||
std::vector<BelId> getGroupBels(GroupId group) const;
|
||||
std::vector<WireId> getGroupWires(GroupId group) const;
|
||||
std::vector<PipId> getGroupPips(GroupId group) const;
|
||||
std::vector<GroupId> getGroupGroups(GroupId group) const;
|
||||
|
||||
// -------------------------------------------------
|
||||
|
||||
void estimatePosition(BelId bel, int &x, int &y, bool &gb) const;
|
||||
delay_t estimateDelay(WireId src, WireId dst) const;
|
||||
delay_t getDelayEpsilon() const { return 20; }
|
||||
@ -654,6 +664,7 @@ struct Arch : BaseCtx
|
||||
DecalXY getBelDecal(BelId bel) const;
|
||||
DecalXY getWireDecal(WireId wire) const;
|
||||
DecalXY getPipDecal(PipId pip) const;
|
||||
DecalXY getGroupDecal(GroupId group) const;
|
||||
|
||||
// -------------------------------------------------
|
||||
|
||||
|
@ -109,11 +109,42 @@ struct PipId
|
||||
bool operator!=(const PipId &other) const { return index != other.index; }
|
||||
};
|
||||
|
||||
struct GroupId
|
||||
{
|
||||
enum : int8_t {
|
||||
TYPE_NONE,
|
||||
TYPE_FRAME,
|
||||
TYPE_MAIN_SW,
|
||||
TYPE_LOCAL_SW,
|
||||
TYPE_LC0_SW,
|
||||
TYPE_LC1_SW,
|
||||
TYPE_LC2_SW,
|
||||
TYPE_LC3_SW,
|
||||
TYPE_LC4_SW,
|
||||
TYPE_LC5_SW,
|
||||
TYPE_LC6_SW,
|
||||
TYPE_LC7_SW
|
||||
} type = TYPE_NONE;
|
||||
int8_t x = 0, y = 0;
|
||||
|
||||
bool operator==(const GroupId &other) const { return (type == other.type) && (x == other.x) && (y == other.y); }
|
||||
bool operator!=(const GroupId &other) const { return (type != other.type) || (x != other.x) || (y == other.y); }
|
||||
};
|
||||
|
||||
struct DecalId
|
||||
{
|
||||
char type = 0; // Bel/Wire/Pip/Frame (b/w/p/f)
|
||||
uint8_t x = 0, y = 0;
|
||||
uint32_t z = 0;
|
||||
enum : int8_t {
|
||||
TYPE_NONE,
|
||||
TYPE_FRAME,
|
||||
TYPE_BEL,
|
||||
TYPE_WIRE,
|
||||
TYPE_PIP,
|
||||
TYPE_GROUP
|
||||
} type = TYPE_NONE;
|
||||
int32_t index = -1;
|
||||
|
||||
bool operator==(const DecalId &other) const { return (type == other.type) && (index == other.index); }
|
||||
bool operator!=(const DecalId &other) const { return (type != other.type) || (index != other.index); }
|
||||
};
|
||||
|
||||
NEXTPNR_NAMESPACE_END
|
||||
@ -145,14 +176,23 @@ template <> struct hash<NEXTPNR_NAMESPACE_PREFIX PortPin> : hash<int>
|
||||
{
|
||||
};
|
||||
|
||||
template <> struct hash<NEXTPNR_NAMESPACE_PREFIX GroupId>
|
||||
{
|
||||
std::size_t operator()(const NEXTPNR_NAMESPACE_PREFIX GroupId &group) const noexcept {
|
||||
std::size_t seed = 0;
|
||||
boost::hash_combine(seed, hash<int>()(group.type));
|
||||
boost::hash_combine(seed, hash<int>()(group.x));
|
||||
boost::hash_combine(seed, hash<int>()(group.y));
|
||||
return seed;
|
||||
}
|
||||
};
|
||||
|
||||
template <> struct hash<NEXTPNR_NAMESPACE_PREFIX DecalId>
|
||||
{
|
||||
std::size_t operator()(const NEXTPNR_NAMESPACE_PREFIX DecalId &decal) const noexcept {
|
||||
std::size_t seed = 0;
|
||||
boost::hash_combine(seed, hash<int>()(decal.type));
|
||||
boost::hash_combine(seed, hash<int>()(decal.x));
|
||||
boost::hash_combine(seed, hash<int>()(decal.y));
|
||||
boost::hash_combine(seed, hash<int>()(decal.z));
|
||||
boost::hash_combine(seed, hash<int>()(decal.index));
|
||||
return seed;
|
||||
}
|
||||
};
|
||||
|
Loading…
Reference in New Issue
Block a user