aboutsummaryrefslogtreecommitdiffstats
path: root/common
diff options
context:
space:
mode:
authorD. Shah <dave@ds0.me>2021-01-29 13:30:56 +0000
committerD. Shah <dave@ds0.me>2021-02-02 17:00:32 +0000
commitd792bce0fb03529ee57b6f6ed5b0c234f503e452 (patch)
treedbc54e0d44ccd0ecfcb4a8c746e00ab2bdfa148b /common
parent9614d3722929f99520c6b83600641c14ef37188b (diff)
downloadnextpnr-d792bce0fb03529ee57b6f6ed5b0c234f503e452.tar.gz
nextpnr-d792bce0fb03529ee57b6f6ed5b0c234f503e452.tar.bz2
nextpnr-d792bce0fb03529ee57b6f6ed5b0c234f503e452.zip
ecp5: Implement IdStringList for all arch object names
This is a complete implementation of IdStringList for ECP5; excluding the GUI (which you will have to disable for it to build). Signed-off-by: D. Shah <dave@ds0.me>
Diffstat (limited to 'common')
-rw-r--r--common/archcheck.cc4
-rw-r--r--common/nextpnr.cc34
-rw-r--r--common/nextpnr.h25
3 files changed, 55 insertions, 8 deletions
diff --git a/common/archcheck.cc b/common/archcheck.cc
index 6efa3a1e..28b0c147 100644
--- a/common/archcheck.cc
+++ b/common/archcheck.cc
@@ -45,7 +45,7 @@ void archcheck_names(const Context *ctx)
log_info("Checking wire names..\n");
for (WireId wire : ctx->getWires()) {
- IdString name = ctx->getWireName(wire);
+ IdStringList name = ctx->getWireName(wire);
WireId wire2 = ctx->getWireByName(name);
if (wire != wire2) {
log_error("wire != wire2, name = %s\n", ctx->nameOfWire(wire));
@@ -64,7 +64,7 @@ void archcheck_names(const Context *ctx)
#ifndef ARCH_ECP5
log_info("Checking pip names..\n");
for (PipId pip : ctx->getPips()) {
- IdString name = ctx->getPipName(pip);
+ IdStringList name = ctx->getPipName(pip);
PipId pip2 = ctx->getPipByName(name);
if (pip != pip2) {
log_error("pip != pip2, name = %s\n", ctx->nameOfPip(pip));
diff --git a/common/nextpnr.cc b/common/nextpnr.cc
index c9084a75..f7f368f1 100644
--- a/common/nextpnr.cc
+++ b/common/nextpnr.cc
@@ -299,19 +299,25 @@ const char *BaseCtx::nameOfBel(BelId bel) const
const char *BaseCtx::nameOfWire(WireId wire) const
{
const Context *ctx = getCtx();
- return ctx->getWireName(wire).c_str(ctx);
+ std::string &s = ctx->log_strs.next();
+ ctx->getWireName(wire).build_str(ctx, s);
+ return s.c_str();
}
const char *BaseCtx::nameOfPip(PipId pip) const
{
const Context *ctx = getCtx();
- return ctx->getPipName(pip).c_str(ctx);
+ std::string &s = ctx->log_strs.next();
+ ctx->getPipName(pip).build_str(ctx, s);
+ return s.c_str();
}
const char *BaseCtx::nameOfGroup(GroupId group) const
{
const Context *ctx = getCtx();
- return ctx->getGroupName(group).c_str(ctx);
+ std::string &s = ctx->log_strs.next();
+ ctx->getGroupName(group).build_str(ctx, s);
+ return s.c_str();
}
BelId BaseCtx::getBelByNameStr(const std::string &str)
@@ -320,6 +326,24 @@ BelId BaseCtx::getBelByNameStr(const std::string &str)
return ctx->getBelByName(IdStringList::parse(ctx, str));
}
+WireId BaseCtx::getWireByNameStr(const std::string &str)
+{
+ Context *ctx = getCtx();
+ return ctx->getWireByName(IdStringList::parse(ctx, str));
+}
+
+PipId BaseCtx::getPipByNameStr(const std::string &str)
+{
+ Context *ctx = getCtx();
+ return ctx->getPipByName(IdStringList::parse(ctx, str));
+}
+
+GroupId BaseCtx::getGroupByNameStr(const std::string &str)
+{
+ Context *ctx = getCtx();
+ return ctx->getGroupByName(IdStringList::parse(ctx, str));
+}
+
WireId Context::getNetinfoSourceWire(const NetInfo *net_info) const
{
if (net_info->driver.cell == nullptr)
@@ -701,10 +725,10 @@ void BaseCtx::archInfoToAttributes()
for (auto &item : ni->wires) {
if (!first)
routing += ";";
- routing += getCtx()->getWireName(item.first).c_str(this);
+ routing += getCtx()->getWireName(item.first).str(getCtx());
routing += ";";
if (item.second.pip != PipId())
- routing += getCtx()->getPipName(item.second.pip).c_str(this);
+ routing += getCtx()->getPipName(item.second.pip).str(getCtx());
routing += ";" + std::to_string(item.second.strength);
first = false;
}
diff --git a/common/nextpnr.h b/common/nextpnr.h
index 9523e418..19d919e1 100644
--- a/common/nextpnr.h
+++ b/common/nextpnr.h
@@ -235,8 +235,28 @@ struct IdStringList
const IdString *begin() const { return ids.begin(); }
const IdString *end() const { return ids.end(); }
const IdString &operator[](size_t idx) const { return ids[idx]; }
+ bool operator==(const IdStringList &other) const { return ids == other.ids; }
+ bool operator!=(const IdStringList &other) const { return ids != other.ids; }
};
+NEXTPNR_NAMESPACE_END
+
+namespace std {
+template <> struct hash<NEXTPNR_NAMESPACE_PREFIX IdStringList>
+{
+ std::size_t operator()(const NEXTPNR_NAMESPACE_PREFIX IdStringList &obj) const noexcept
+ {
+ std::size_t seed = 0;
+ boost::hash_combine(seed, hash<size_t>()(obj.size()));
+ for (auto &id : obj)
+ boost::hash_combine(seed, hash<NEXTPNR_NAMESPACE_PREFIX IdString>()(id));
+ return seed;
+ }
+};
+} // namespace std
+
+NEXTPNR_NAMESPACE_BEGIN
+
// 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
@@ -890,8 +910,11 @@ 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
+ // Wrappers of arch functions that take a string and handle IdStringList parsing
BelId getBelByNameStr(const std::string &str);
+ WireId getWireByNameStr(const std::string &str);
+ PipId getPipByNameStr(const std::string &str);
+ GroupId getGroupByNameStr(const std::string &str);
// --------------------------------------------------------------