aboutsummaryrefslogtreecommitdiffstats
path: root/common
diff options
context:
space:
mode:
Diffstat (limited to 'common')
-rw-r--r--common/archcheck.cc4
-rw-r--r--common/nextpnr.cc22
-rw-r--r--common/nextpnr.h26
-rw-r--r--common/place_common.cc7
-rw-r--r--common/placer1.cc8
-rw-r--r--common/placer_heap.cc4
-rw-r--r--common/timing_opt.cc9
7 files changed, 56 insertions, 24 deletions
diff --git a/common/archcheck.cc b/common/archcheck.cc
index f5760c88..412feca9 100644
--- a/common/archcheck.cc
+++ b/common/archcheck.cc
@@ -36,10 +36,10 @@ void archcheck_names(const Context *ctx)
log_info("Checking bel names..\n");
for (BelId bel : ctx->getBels()) {
- IdString name = ctx->getBelName(bel);
+ IdStringList name = ctx->getBelName(bel);
BelId bel2 = ctx->getBelByName(name);
if (bel != bel2) {
- log_error("bel != bel2, name = %s\n", name.c_str(ctx));
+ log_error("bel != bel2, name = %s\n", ctx->nameOfBel(bel));
}
}
diff --git a/common/nextpnr.cc b/common/nextpnr.cc
index 57baedf9..c9084a75 100644
--- a/common/nextpnr.cc
+++ b/common/nextpnr.cc
@@ -111,6 +111,14 @@ TimingConstrObjectId BaseCtx::timingWildcardObject()
return id;
}
+std::string &StrRingBuffer::next()
+{
+ std::string &s = buffer.at(index++);
+ if (index >= N)
+ index = 0;
+ return s;
+}
+
TimingConstrObjectId BaseCtx::timingClockDomainObject(NetInfo *clockDomain)
{
NPNR_ASSERT(clockDomain->clkconstr != nullptr);
@@ -283,7 +291,9 @@ void BaseCtx::removeConstraint(IdString constrName)
const char *BaseCtx::nameOfBel(BelId bel) const
{
const Context *ctx = getCtx();
- return ctx->getBelName(bel).c_str(ctx);
+ std::string &s = ctx->log_strs.next();
+ ctx->getBelName(bel).build_str(ctx, s);
+ return s.c_str();
}
const char *BaseCtx::nameOfWire(WireId wire) const
@@ -304,6 +314,12 @@ const char *BaseCtx::nameOfGroup(GroupId group) const
return ctx->getGroupName(group).c_str(ctx);
}
+BelId BaseCtx::getBelByNameStr(const std::string &str)
+{
+ Context *ctx = getCtx();
+ return ctx->getBelByName(IdStringList::parse(ctx, str));
+}
+
WireId Context::getNetinfoSourceWire(const NetInfo *net_info) const
{
if (net_info->driver.cell == nullptr)
@@ -655,7 +671,7 @@ void BaseCtx::archInfoToAttributes()
if (ci->attrs.find(id("BEL")) != ci->attrs.end()) {
ci->attrs.erase(ci->attrs.find(id("BEL")));
}
- ci->attrs[id("NEXTPNR_BEL")] = getCtx()->getBelName(ci->bel).str(this);
+ ci->attrs[id("NEXTPNR_BEL")] = getCtx()->getBelName(ci->bel).str(getCtx());
ci->attrs[id("BEL_STRENGTH")] = (int)ci->belStrength;
}
if (ci->constr_x != ci->UNCONSTR)
@@ -707,7 +723,7 @@ void BaseCtx::attributesToArchInfo()
if (str != ci->attrs.end())
strength = (PlaceStrength)str->second.as_int64();
- BelId b = getCtx()->getBelByName(id(val->second.as_string()));
+ BelId b = getCtx()->getBelByNameStr(val->second.as_string());
getCtx()->bindBel(b, ci, strength);
}
diff --git a/common/nextpnr.h b/common/nextpnr.h
index 66f31867..9523e418 100644
--- a/common/nextpnr.h
+++ b/common/nextpnr.h
@@ -148,14 +148,13 @@ NEXTPNR_NAMESPACE_BEGIN
// An small size optimised array that is statically allocated when the size is N or less; heap allocated otherwise
template <typename T, size_t N> class SSOArray
{
+ private:
union
{
T data_static[N];
T *data_heap;
};
size_t m_size;
-
- private:
inline bool is_heap() const { return (m_size > N); }
void alloc()
{
@@ -224,8 +223,8 @@ struct IdStringList
SSOArray<IdString, 4> ids;
IdStringList(){};
- explicit IdStringList(size_t n) : ids(n, IdString()){};
- explicit IdStringList(IdString id) : ids(1, id){};
+ IdStringList(size_t n) : ids(n, IdString()){};
+ IdStringList(IdString id) : ids(1, id){};
template <typename Tlist> IdStringList(const Tlist &list) : ids(list){};
static IdStringList parse(Context *ctx, const std::string &str);
@@ -238,6 +237,19 @@ struct IdStringList
const IdString &operator[](size_t idx) const { return ids[idx]; }
};
+// A ring buffer of strings, so we can return a simple const char * pointer for %s formatting - inspired by how logging
+// in Yosys works Let's just hope noone tries to log more than 100 things in one call....
+class StrRingBuffer
+{
+ private:
+ static const size_t N = 100;
+ std::array<std::string, N> buffer;
+ size_t index = 0;
+
+ public:
+ std::string &next();
+};
+
struct GraphicElement
{
enum type_t
@@ -760,6 +772,9 @@ struct BaseCtx
mutable std::unordered_map<std::string, int> *idstring_str_to_idx;
mutable std::vector<const std::string *> *idstring_idx_to_str;
+ // Temporary string backing store for logging
+ mutable StrRingBuffer log_strs;
+
// Project settings and config switches
std::unordered_map<IdString, Property> settings;
@@ -875,6 +890,9 @@ struct BaseCtx
const char *nameOfPip(PipId pip) const;
const char *nameOfGroup(GroupId group) const;
+ // Overrides of arch functions that take a string and handle IdStringList parsing
+ BelId getBelByNameStr(const std::string &str);
+
// --------------------------------------------------------------
bool allUiReload = true;
diff --git a/common/place_common.cc b/common/place_common.cc
index 3f89169a..6526c38e 100644
--- a/common/place_common.cc
+++ b/common/place_common.cc
@@ -158,8 +158,7 @@ bool place_single_cell(Context *ctx, CellInfo *cell, bool require_legality)
all_placed = true;
}
if (ctx->verbose)
- log_info(" placed single cell '%s' at '%s'\n", cell->name.c_str(ctx),
- ctx->getBelName(best_bel).c_str(ctx));
+ log_info(" placed single cell '%s' at '%s'\n", cell->name.c_str(ctx), ctx->nameOfBel(best_bel));
ctx->bindBel(best_bel, cell, STRENGTH_WEAK);
cell = ripup_target;
@@ -375,7 +374,7 @@ class ConstraintLegaliseWorker
if (confl_cell != nullptr) {
if (ctx->verbose)
log_info(" '%s' already placed at '%s'\n", ctx->nameOf(confl_cell),
- ctx->getBelName(confl_cell->bel).c_str(ctx));
+ ctx->nameOfBel(confl_cell->bel));
NPNR_ASSERT(confl_cell->belStrength < STRENGTH_STRONG);
ctx->unbindBel(target);
rippedCells.insert(confl_cell->name);
@@ -489,7 +488,7 @@ class ConstraintLegaliseWorker
for (auto cell : sorted(ctx->cells))
if (get_constraints_distance(ctx, cell.second) != 0)
log_error("constraint satisfaction check failed for cell '%s' at Bel '%s'\n", cell.first.c_str(ctx),
- ctx->getBelName(cell.second->bel).c_str(ctx));
+ ctx->nameOfBel(cell.second->bel));
return score;
}
};
diff --git a/common/placer1.cc b/common/placer1.cc
index 1c039090..c54c3cf2 100644
--- a/common/placer1.cc
+++ b/common/placer1.cc
@@ -154,7 +154,7 @@ class SAPlacer
auto loc = cell->attrs.find(ctx->id("BEL"));
if (loc != cell->attrs.end()) {
std::string loc_name = loc->second.as_string();
- BelId bel = ctx->getBelByName(ctx->id(loc_name));
+ BelId bel = ctx->getBelByNameStr(loc_name);
if (bel == BelId()) {
log_error("No Bel named \'%s\' located for "
"this chip (processing BEL attribute on \'%s\')\n",
@@ -409,18 +409,18 @@ class SAPlacer
if (ctx->force) {
log_warning("post-placement validity check failed for Bel '%s' "
"(%s)\n",
- ctx->getBelName(bel).c_str(ctx), cell_text.c_str());
+ ctx->nameOfBel(bel), cell_text.c_str());
} else {
log_error("post-placement validity check failed for Bel '%s' "
"(%s)\n",
- ctx->getBelName(bel).c_str(ctx), cell_text.c_str());
+ ctx->nameOfBel(bel), cell_text.c_str());
}
}
}
for (auto cell : sorted(ctx->cells))
if (get_constraints_distance(ctx, cell.second) != 0)
log_error("constraint satisfaction check failed for cell '%s' at Bel '%s'\n", cell.first.c_str(ctx),
- ctx->getBelName(cell.second->bel).c_str(ctx));
+ ctx->nameOfBel(cell.second->bel));
timing_analysis(ctx);
ctx->unlock();
return true;
diff --git a/common/placer_heap.cc b/common/placer_heap.cc
index d149a5b0..7882c8da 100644
--- a/common/placer_heap.cc
+++ b/common/placer_heap.cc
@@ -305,7 +305,7 @@ class HeAPPlacer
if (ctx->getBoundBelCell(cell.second->bel) != cell.second)
log_error("Found cell %s with mismatched binding\n", cell.first.c_str(ctx));
if (ctx->debug)
- log_info("AP soln: %s -> %s\n", cell.first.c_str(ctx), ctx->getBelName(cell.second->bel).c_str(ctx));
+ log_info("AP soln: %s -> %s\n", cell.first.c_str(ctx), ctx->nameOfBel(cell.second->bel));
}
ctx->unlock();
@@ -379,7 +379,7 @@ class HeAPPlacer
auto loc = cell->attrs.find(ctx->id("BEL"));
if (loc != cell->attrs.end()) {
std::string loc_name = loc->second.as_string();
- BelId bel = ctx->getBelByName(ctx->id(loc_name));
+ BelId bel = ctx->getBelByNameStr(loc_name);
if (bel == BelId()) {
log_error("No Bel named \'%s\' located for "
"this chip (processing BEL attribute on \'%s\')\n",
diff --git a/common/timing_opt.cc b/common/timing_opt.cc
index 025084b7..7ee7b805 100644
--- a/common/timing_opt.cc
+++ b/common/timing_opt.cc
@@ -427,7 +427,7 @@ class TimingOptimiser
if (pn->users.at(i).cell == port->cell && pn->users.at(i).port == port->port)
crit = net_crit.at(pn->name).criticality.at(i);
log_info(" %s.%s at %s crit %0.02f\n", port->cell->name.c_str(ctx), port->port.c_str(ctx),
- ctx->getBelName(port->cell->bel).c_str(ctx), crit);
+ ctx->nameOfBel(port->cell->bel), crit);
}
if (std::find(path_cells.begin(), path_cells.end(), port->cell->name) != path_cells.end())
continue;
@@ -472,10 +472,9 @@ class TimingOptimiser
if (ctx->debug) {
for (auto cell : path_cells) {
- log_info("Candidate neighbours for %s (%s):\n", cell.c_str(ctx),
- ctx->getBelName(ctx->cells[cell]->bel).c_str(ctx));
+ log_info("Candidate neighbours for %s (%s):\n", cell.c_str(ctx), ctx->nameOfBel(ctx->cells[cell]->bel));
for (auto neigh : cell_neighbour_bels.at(cell)) {
- log_info(" %s\n", ctx->getBelName(neigh).c_str(ctx));
+ log_info(" %s\n", ctx->nameOfBel(neigh));
}
}
}
@@ -597,7 +596,7 @@ class TimingOptimiser
CellInfo *cell = ctx->cells.at(rt_entry.first).get();
cell_swap_bel(cell, rt_entry.second);
if (ctx->debug)
- log_info(" %s at %s\n", rt_entry.first.c_str(ctx), ctx->getBelName(rt_entry.second).c_str(ctx));
+ log_info(" %s at %s\n", rt_entry.first.c_str(ctx), ctx->nameOfBel(rt_entry.second));
}
} else {