diff options
author | D. Shah <dave@ds0.me> | 2021-01-29 13:30:56 +0000 |
---|---|---|
committer | D. Shah <dave@ds0.me> | 2021-02-02 17:00:32 +0000 |
commit | d792bce0fb03529ee57b6f6ed5b0c234f503e452 (patch) | |
tree | dbc54e0d44ccd0ecfcb4a8c746e00ab2bdfa148b /common | |
parent | 9614d3722929f99520c6b83600641c14ef37188b (diff) | |
download | nextpnr-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.cc | 4 | ||||
-rw-r--r-- | common/nextpnr.cc | 34 | ||||
-rw-r--r-- | common/nextpnr.h | 25 |
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); // -------------------------------------------------------------- |