Merge pull request #54 from daveshah1/ecp5_speedup
ecp5: Improving placement speed
This commit is contained in:
commit
45bd0a8c72
@ -92,6 +92,8 @@ Arch::Arch(ArchArgs args) : args(args)
|
|||||||
|
|
||||||
if (!package_info)
|
if (!package_info)
|
||||||
log_error("Unsupported package '%s' for '%s'.\n", args.package.c_str(), getChipName().c_str());
|
log_error("Unsupported package '%s' for '%s'.\n", args.package.c_str(), getChipName().c_str());
|
||||||
|
|
||||||
|
bel_to_cell.resize(chip_info->height * chip_info->width * max_loc_bels, nullptr);
|
||||||
}
|
}
|
||||||
|
|
||||||
// -----------------------------------------------------------------------
|
// -----------------------------------------------------------------------
|
||||||
@ -432,7 +434,7 @@ DecalXY Arch::getBelDecal(BelId bel) const
|
|||||||
decalxy.decal.type = DecalId::TYPE_BEL;
|
decalxy.decal.type = DecalId::TYPE_BEL;
|
||||||
decalxy.decal.location = bel.location;
|
decalxy.decal.location = bel.location;
|
||||||
decalxy.decal.z = bel.index;
|
decalxy.decal.z = bel.index;
|
||||||
decalxy.decal.active = bel_to_cell.count(bel) && (bel_to_cell.at(bel) != nullptr);
|
decalxy.decal.active = (bel_to_cell.at(getBelFlatIndex(bel)) != nullptr);
|
||||||
return decalxy;
|
return decalxy;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
36
ecp5/arch.h
36
ecp5/arch.h
@ -404,7 +404,7 @@ struct Arch : BaseCtx
|
|||||||
mutable std::unordered_map<IdString, WireId> wire_by_name;
|
mutable std::unordered_map<IdString, WireId> wire_by_name;
|
||||||
mutable std::unordered_map<IdString, PipId> pip_by_name;
|
mutable std::unordered_map<IdString, PipId> pip_by_name;
|
||||||
|
|
||||||
std::unordered_map<BelId, CellInfo *> bel_to_cell;
|
std::vector<CellInfo *> bel_to_cell;
|
||||||
std::unordered_map<WireId, NetInfo *> wire_to_net;
|
std::unordered_map<WireId, NetInfo *> wire_to_net;
|
||||||
std::unordered_map<PipId, NetInfo *> pip_to_net;
|
std::unordered_map<PipId, NetInfo *> pip_to_net;
|
||||||
|
|
||||||
@ -443,11 +443,18 @@ struct Arch : BaseCtx
|
|||||||
|
|
||||||
uint32_t getBelChecksum(BelId bel) const { return bel.index; }
|
uint32_t getBelChecksum(BelId bel) const { return bel.index; }
|
||||||
|
|
||||||
|
const int max_loc_bels = 20;
|
||||||
|
int getBelFlatIndex(BelId bel) const
|
||||||
|
{
|
||||||
|
return (bel.location.y * chip_info->width + bel.location.x) * max_loc_bels + bel.index;
|
||||||
|
}
|
||||||
|
|
||||||
void bindBel(BelId bel, CellInfo *cell, PlaceStrength strength)
|
void bindBel(BelId bel, CellInfo *cell, PlaceStrength strength)
|
||||||
{
|
{
|
||||||
NPNR_ASSERT(bel != BelId());
|
NPNR_ASSERT(bel != BelId());
|
||||||
NPNR_ASSERT(bel_to_cell[bel] == nullptr);
|
int idx = getBelFlatIndex(bel);
|
||||||
bel_to_cell[bel] = cell;
|
NPNR_ASSERT(bel_to_cell.at(idx) == nullptr);
|
||||||
|
bel_to_cell[idx] = cell;
|
||||||
cell->bel = bel;
|
cell->bel = bel;
|
||||||
cell->belStrength = strength;
|
cell->belStrength = strength;
|
||||||
refreshUiBel(bel);
|
refreshUiBel(bel);
|
||||||
@ -456,10 +463,11 @@ struct Arch : BaseCtx
|
|||||||
void unbindBel(BelId bel)
|
void unbindBel(BelId bel)
|
||||||
{
|
{
|
||||||
NPNR_ASSERT(bel != BelId());
|
NPNR_ASSERT(bel != BelId());
|
||||||
NPNR_ASSERT(bel_to_cell[bel] != nullptr);
|
int idx = getBelFlatIndex(bel);
|
||||||
bel_to_cell[bel]->bel = BelId();
|
NPNR_ASSERT(bel_to_cell.at(idx) != nullptr);
|
||||||
bel_to_cell[bel]->belStrength = STRENGTH_NONE;
|
bel_to_cell[idx]->bel = BelId();
|
||||||
bel_to_cell[bel] = nullptr;
|
bel_to_cell[idx]->belStrength = STRENGTH_NONE;
|
||||||
|
bel_to_cell[idx] = nullptr;
|
||||||
refreshUiBel(bel);
|
refreshUiBel(bel);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -480,25 +488,19 @@ struct Arch : BaseCtx
|
|||||||
bool checkBelAvail(BelId bel) const
|
bool checkBelAvail(BelId bel) const
|
||||||
{
|
{
|
||||||
NPNR_ASSERT(bel != BelId());
|
NPNR_ASSERT(bel != BelId());
|
||||||
return bel_to_cell.find(bel) == bel_to_cell.end() || bel_to_cell.at(bel) == nullptr;
|
return bel_to_cell[getBelFlatIndex(bel)] == nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
CellInfo *getBoundBelCell(BelId bel) const
|
CellInfo *getBoundBelCell(BelId bel) const
|
||||||
{
|
{
|
||||||
NPNR_ASSERT(bel != BelId());
|
NPNR_ASSERT(bel != BelId());
|
||||||
if (bel_to_cell.find(bel) == bel_to_cell.end())
|
return bel_to_cell[getBelFlatIndex(bel)];
|
||||||
return nullptr;
|
|
||||||
else
|
|
||||||
return bel_to_cell.at(bel);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
CellInfo *getConflictingBelCell(BelId bel) const
|
CellInfo *getConflictingBelCell(BelId bel) const
|
||||||
{
|
{
|
||||||
NPNR_ASSERT(bel != BelId());
|
NPNR_ASSERT(bel != BelId());
|
||||||
if (bel_to_cell.find(bel) == bel_to_cell.end())
|
return bel_to_cell[getBelFlatIndex(bel)];
|
||||||
return nullptr;
|
|
||||||
else
|
|
||||||
return bel_to_cell.at(bel);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
BelRange getBels() const
|
BelRange getBels() const
|
||||||
@ -866,6 +868,8 @@ struct Arch : BaseCtx
|
|||||||
// Helper function for above
|
// Helper function for above
|
||||||
bool slicesCompatible(const std::vector<const CellInfo *> &cells) const;
|
bool slicesCompatible(const std::vector<const CellInfo *> &cells) const;
|
||||||
|
|
||||||
|
void assignArchInfo();
|
||||||
|
|
||||||
std::vector<std::pair<std::string, std::string>> getTilesAtLocation(int row, int col);
|
std::vector<std::pair<std::string, std::string>> getTilesAtLocation(int row, int col);
|
||||||
std::string getTileByTypeAndLocation(int row, int col, std::string type) const
|
std::string getTileByTypeAndLocation(int row, int col, std::string type) const
|
||||||
{
|
{
|
||||||
|
@ -35,26 +35,26 @@ bool Arch::slicesCompatible(const std::vector<const CellInfo *> &cells) const
|
|||||||
{
|
{
|
||||||
// TODO: allow different LSR/CLK and MUX/SRMODE settings once
|
// TODO: allow different LSR/CLK and MUX/SRMODE settings once
|
||||||
// routing details are worked out
|
// routing details are worked out
|
||||||
NetInfo *clk_sig = nullptr, *lsr_sig = nullptr;
|
IdString clk_sig, lsr_sig;
|
||||||
std::string CLKMUX, LSRMUX, SRMODE;
|
IdString CLKMUX, LSRMUX, SRMODE;
|
||||||
bool first = true;
|
bool first = true;
|
||||||
for (auto cell : cells) {
|
for (auto cell : cells) {
|
||||||
if (first) {
|
if (first) {
|
||||||
clk_sig = port_or_nullptr(cell, id_CLK);
|
clk_sig = cell->sliceInfo.clk_sig;
|
||||||
lsr_sig = port_or_nullptr(cell, id_LSR);
|
lsr_sig = cell->sliceInfo.lsr_sig;
|
||||||
CLKMUX = str_or_default(cell->params, id_CLKMUX, "CLK");
|
CLKMUX = cell->sliceInfo.clkmux;
|
||||||
LSRMUX = str_or_default(cell->params, id_LSRMUX, "LSR");
|
LSRMUX = cell->sliceInfo.lsrmux;
|
||||||
SRMODE = str_or_default(cell->params, id_SRMODE, "CE_OVER_LSR");
|
SRMODE = cell->sliceInfo.srmode;
|
||||||
} else {
|
} else {
|
||||||
if (port_or_nullptr(cell, id_CLK) != clk_sig)
|
if (cell->sliceInfo.clk_sig != clk_sig)
|
||||||
return false;
|
return false;
|
||||||
if (port_or_nullptr(cell, id_LSR) != lsr_sig)
|
if (cell->sliceInfo.lsr_sig != lsr_sig)
|
||||||
return false;
|
return false;
|
||||||
if (str_or_default(cell->params, id_CLKMUX, "CLK") != CLKMUX)
|
if (cell->sliceInfo.clkmux != CLKMUX)
|
||||||
return false;
|
return false;
|
||||||
if (str_or_default(cell->params, id_LSRMUX, "LSR") != LSRMUX)
|
if (cell->sliceInfo.lsrmux != LSRMUX)
|
||||||
return false;
|
return false;
|
||||||
if (str_or_default(cell->params, id_SRMODE, "CE_OVER_LSR") != SRMODE)
|
if (cell->sliceInfo.srmode != SRMODE)
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
first = false;
|
first = false;
|
||||||
|
@ -139,6 +139,10 @@ struct ArchNetInfo
|
|||||||
};
|
};
|
||||||
struct ArchCellInfo
|
struct ArchCellInfo
|
||||||
{
|
{
|
||||||
|
struct
|
||||||
|
{
|
||||||
|
IdString clk_sig, lsr_sig, clkmux, lsrmux, srmode;
|
||||||
|
} sliceInfo;
|
||||||
};
|
};
|
||||||
|
|
||||||
NEXTPNR_NAMESPACE_END
|
NEXTPNR_NAMESPACE_END
|
||||||
|
24
ecp5/pack.cc
24
ecp5/pack.cc
@ -536,10 +536,34 @@ bool Arch::pack()
|
|||||||
log_break();
|
log_break();
|
||||||
Ecp5Packer(ctx).pack();
|
Ecp5Packer(ctx).pack();
|
||||||
log_info("Checksum: 0x%08x\n", ctx->checksum());
|
log_info("Checksum: 0x%08x\n", ctx->checksum());
|
||||||
|
assignArchInfo();
|
||||||
return true;
|
return true;
|
||||||
} catch (log_execution_error_exception) {
|
} catch (log_execution_error_exception) {
|
||||||
|
assignArchInfo();
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Arch::assignArchInfo()
|
||||||
|
{
|
||||||
|
for (auto cell : sorted(cells)) {
|
||||||
|
CellInfo *ci = cell.second;
|
||||||
|
if (ci->type == id_TRELLIS_SLICE) {
|
||||||
|
if (ci->ports.count(id_CLK) && ci->ports[id_CLK].net != nullptr)
|
||||||
|
ci->sliceInfo.clk_sig = ci->ports[id_CLK].net->name;
|
||||||
|
else
|
||||||
|
ci->sliceInfo.clk_sig = IdString();
|
||||||
|
|
||||||
|
if (ci->ports.count(id_LSR) && ci->ports[id_LSR].net != nullptr)
|
||||||
|
ci->sliceInfo.lsr_sig = ci->ports[id_LSR].net->name;
|
||||||
|
else
|
||||||
|
ci->sliceInfo.lsr_sig = IdString();
|
||||||
|
|
||||||
|
ci->sliceInfo.clkmux = id(str_or_default(ci->params, id_CLKMUX, "CLK"));
|
||||||
|
ci->sliceInfo.lsrmux = id(str_or_default(ci->params, id_LSRMUX, "LSR"));
|
||||||
|
ci->sliceInfo.srmode = id(str_or_default(ci->params, id_SRMODE, "LSR_OVER_CE"));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
NEXTPNR_NAMESPACE_END
|
NEXTPNR_NAMESPACE_END
|
||||||
|
Loading…
Reference in New Issue
Block a user