aboutsummaryrefslogtreecommitdiffstats
path: root/ecp5
diff options
context:
space:
mode:
authorDavid Shah <davey1576@gmail.com>2018-08-19 14:04:01 +0100
committerGitHub <noreply@github.com>2018-08-19 14:04:01 +0100
commit45bd0a8c723daad8718e38b0f563966e9da1ed34 (patch)
tree2c792de98ca1b93f469b71c6f91e377dc1e510c2 /ecp5
parent26be6f9761bba9dff646c6b1d071b149bd26f950 (diff)
parent0b35cb4e60c114b3d84ae39d0462a20085ef2bd4 (diff)
downloadnextpnr-45bd0a8c723daad8718e38b0f563966e9da1ed34.tar.gz
nextpnr-45bd0a8c723daad8718e38b0f563966e9da1ed34.tar.bz2
nextpnr-45bd0a8c723daad8718e38b0f563966e9da1ed34.zip
Merge pull request #54 from daveshah1/ecp5_speedup
ecp5: Improving placement speed
Diffstat (limited to 'ecp5')
-rw-r--r--ecp5/arch.cc4
-rw-r--r--ecp5/arch.h36
-rw-r--r--ecp5/arch_place.cc24
-rw-r--r--ecp5/archdefs.h4
-rw-r--r--ecp5/pack.cc24
5 files changed, 63 insertions, 29 deletions
diff --git a/ecp5/arch.cc b/ecp5/arch.cc
index acf1b42e..b2ce4acb 100644
--- a/ecp5/arch.cc
+++ b/ecp5/arch.cc
@@ -92,6 +92,8 @@ Arch::Arch(ArchArgs args) : args(args)
if (!package_info)
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.location = bel.location;
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;
}
diff --git a/ecp5/arch.h b/ecp5/arch.h
index f5336e55..712c6e0a 100644
--- a/ecp5/arch.h
+++ b/ecp5/arch.h
@@ -404,7 +404,7 @@ struct Arch : BaseCtx
mutable std::unordered_map<IdString, WireId> wire_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<PipId, NetInfo *> pip_to_net;
@@ -443,11 +443,18 @@ struct Arch : BaseCtx
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)
{
NPNR_ASSERT(bel != BelId());
- NPNR_ASSERT(bel_to_cell[bel] == nullptr);
- bel_to_cell[bel] = cell;
+ int idx = getBelFlatIndex(bel);
+ NPNR_ASSERT(bel_to_cell.at(idx) == nullptr);
+ bel_to_cell[idx] = cell;
cell->bel = bel;
cell->belStrength = strength;
refreshUiBel(bel);
@@ -456,10 +463,11 @@ struct Arch : BaseCtx
void unbindBel(BelId bel)
{
NPNR_ASSERT(bel != BelId());
- NPNR_ASSERT(bel_to_cell[bel] != nullptr);
- bel_to_cell[bel]->bel = BelId();
- bel_to_cell[bel]->belStrength = STRENGTH_NONE;
- bel_to_cell[bel] = nullptr;
+ int idx = getBelFlatIndex(bel);
+ NPNR_ASSERT(bel_to_cell.at(idx) != nullptr);
+ bel_to_cell[idx]->bel = BelId();
+ bel_to_cell[idx]->belStrength = STRENGTH_NONE;
+ bel_to_cell[idx] = nullptr;
refreshUiBel(bel);
}
@@ -480,25 +488,19 @@ struct Arch : BaseCtx
bool checkBelAvail(BelId bel) const
{
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
{
NPNR_ASSERT(bel != BelId());
- if (bel_to_cell.find(bel) == bel_to_cell.end())
- return nullptr;
- else
- return bel_to_cell.at(bel);
+ return bel_to_cell[getBelFlatIndex(bel)];
}
CellInfo *getConflictingBelCell(BelId bel) const
{
NPNR_ASSERT(bel != BelId());
- if (bel_to_cell.find(bel) == bel_to_cell.end())
- return nullptr;
- else
- return bel_to_cell.at(bel);
+ return bel_to_cell[getBelFlatIndex(bel)];
}
BelRange getBels() const
@@ -866,6 +868,8 @@ struct Arch : BaseCtx
// Helper function for above
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::string getTileByTypeAndLocation(int row, int col, std::string type) const
{
diff --git a/ecp5/arch_place.cc b/ecp5/arch_place.cc
index 83af6b5a..55fff73d 100644
--- a/ecp5/arch_place.cc
+++ b/ecp5/arch_place.cc
@@ -35,26 +35,26 @@ bool Arch::slicesCompatible(const std::vector<const CellInfo *> &cells) const
{
// TODO: allow different LSR/CLK and MUX/SRMODE settings once
// routing details are worked out
- NetInfo *clk_sig = nullptr, *lsr_sig = nullptr;
- std::string CLKMUX, LSRMUX, SRMODE;
+ IdString clk_sig, lsr_sig;
+ IdString CLKMUX, LSRMUX, SRMODE;
bool first = true;
for (auto cell : cells) {
if (first) {
- clk_sig = port_or_nullptr(cell, id_CLK);
- lsr_sig = port_or_nullptr(cell, id_LSR);
- CLKMUX = str_or_default(cell->params, id_CLKMUX, "CLK");
- LSRMUX = str_or_default(cell->params, id_LSRMUX, "LSR");
- SRMODE = str_or_default(cell->params, id_SRMODE, "CE_OVER_LSR");
+ clk_sig = cell->sliceInfo.clk_sig;
+ lsr_sig = cell->sliceInfo.lsr_sig;
+ CLKMUX = cell->sliceInfo.clkmux;
+ LSRMUX = cell->sliceInfo.lsrmux;
+ SRMODE = cell->sliceInfo.srmode;
} else {
- if (port_or_nullptr(cell, id_CLK) != clk_sig)
+ if (cell->sliceInfo.clk_sig != clk_sig)
return false;
- if (port_or_nullptr(cell, id_LSR) != lsr_sig)
+ if (cell->sliceInfo.lsr_sig != lsr_sig)
return false;
- if (str_or_default(cell->params, id_CLKMUX, "CLK") != CLKMUX)
+ if (cell->sliceInfo.clkmux != CLKMUX)
return false;
- if (str_or_default(cell->params, id_LSRMUX, "LSR") != LSRMUX)
+ if (cell->sliceInfo.lsrmux != LSRMUX)
return false;
- if (str_or_default(cell->params, id_SRMODE, "CE_OVER_LSR") != SRMODE)
+ if (cell->sliceInfo.srmode != SRMODE)
return false;
}
first = false;
diff --git a/ecp5/archdefs.h b/ecp5/archdefs.h
index 1493c691..c4e1413f 100644
--- a/ecp5/archdefs.h
+++ b/ecp5/archdefs.h
@@ -139,6 +139,10 @@ struct ArchNetInfo
};
struct ArchCellInfo
{
+ struct
+ {
+ IdString clk_sig, lsr_sig, clkmux, lsrmux, srmode;
+ } sliceInfo;
};
NEXTPNR_NAMESPACE_END
diff --git a/ecp5/pack.cc b/ecp5/pack.cc
index 786f543e..a2077204 100644
--- a/ecp5/pack.cc
+++ b/ecp5/pack.cc
@@ -536,10 +536,34 @@ bool Arch::pack()
log_break();
Ecp5Packer(ctx).pack();
log_info("Checksum: 0x%08x\n", ctx->checksum());
+ assignArchInfo();
return true;
} catch (log_execution_error_exception) {
+ assignArchInfo();
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