diff options
author | Keith Rothman <537074+litghost@users.noreply.github.com> | 2021-03-12 13:09:44 -0800 |
---|---|---|
committer | Keith Rothman <537074+litghost@users.noreply.github.com> | 2021-03-15 09:05:23 -0700 |
commit | fe4608386eb163c70a75ed84beb07516af378b36 (patch) | |
tree | 05f1371ad44da5a69617f43cf68005cf271be5e1 /common/property.h | |
parent | 035b797ec230aa3d686d9013e0e15d79cd2982c3 (diff) | |
download | nextpnr-fe4608386eb163c70a75ed84beb07516af378b36.tar.gz nextpnr-fe4608386eb163c70a75ed84beb07516af378b36.tar.bz2 nextpnr-fe4608386eb163c70a75ed84beb07516af378b36.zip |
Split nextpnr.h to allow for linear inclusion.
"nextpnr.h" is no longer the god header. Important improvements:
- Functions in log.h can be used without including
BaseCtx/Arch/Context. This means that log_X functions can be called
without included "nextpnr.h"
- NPNR_ASSERT can be used without including "nextpnr.h" by including
"nextpnr_assertions.h". This allows NPNR_ASSERT to be used safely in
any header file.
- Types defined in "archdefs.h" are now available without including
BaseCtx/Arch/Context. This means that utility classes that will be
used inside of BaseCtx/Arch/Context can be defined safely in a
self-contained header.
Signed-off-by: Keith Rothman <537074+litghost@users.noreply.github.com>
Diffstat (limited to 'common/property.h')
-rw-r--r-- | common/property.h | 131 |
1 files changed, 131 insertions, 0 deletions
diff --git a/common/property.h b/common/property.h new file mode 100644 index 00000000..79fbf881 --- /dev/null +++ b/common/property.h @@ -0,0 +1,131 @@ +/* + * nextpnr -- Next Generation Place and Route + * + * Copyright (C) 2018 Clifford Wolf <clifford@symbioticeda.com> + * Copyright (C) 2018 Serge Bazanski <q3k@symbioticeda.com> + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + * + */ + +#ifndef PROPERTY_H +#define PROPERTY_H + +#include <algorithm> +#include <cstdint> +#include <string> +#include <vector> + +#include "nextpnr_assertions.h" +#include "nextpnr_namespaces.h" + +NEXTPNR_NAMESPACE_BEGIN + +struct Property +{ + enum State : char + { + S0 = '0', + S1 = '1', + Sx = 'x', + Sz = 'z' + }; + + Property(); + Property(int64_t intval, int width = 32); + Property(const std::string &strval); + Property(State bit); + Property &operator=(const Property &other) = default; + + bool is_string; + + // The string literal (for string values), or a string of [01xz] (for numeric values) + std::string str; + // The lower 64 bits (for numeric values), unused for string values + int64_t intval; + + void update_intval() + { + intval = 0; + for (int i = 0; i < int(str.size()); i++) { + NPNR_ASSERT(str[i] == S0 || str[i] == S1 || str[i] == Sx || str[i] == Sz); + if ((str[i] == S1) && i < 64) + intval |= (1ULL << i); + } + } + + int64_t as_int64() const + { + NPNR_ASSERT(!is_string); + return intval; + } + std::vector<bool> as_bits() const + { + std::vector<bool> result; + result.reserve(str.size()); + NPNR_ASSERT(!is_string); + for (auto c : str) + result.push_back(c == S1); + return result; + } + std::string as_string() const + { + NPNR_ASSERT(is_string); + return str; + } + const char *c_str() const + { + NPNR_ASSERT(is_string); + return str.c_str(); + } + size_t size() const { return is_string ? 8 * str.size() : str.size(); } + double as_double() const + { + NPNR_ASSERT(is_string); + return std::stod(str); + } + bool as_bool() const + { + if (int(str.size()) <= 64) + return intval != 0; + else + return std::any_of(str.begin(), str.end(), [](char c) { return c == S1; }); + } + bool is_fully_def() const + { + return !is_string && std::all_of(str.begin(), str.end(), [](char c) { return c == S0 || c == S1; }); + } + Property extract(int offset, int len, State padding = State::S0) const + { + Property ret; + ret.is_string = false; + ret.str.reserve(len); + for (int i = offset; i < offset + len; i++) + ret.str.push_back(i < int(str.size()) ? str[i] : char(padding)); + ret.update_intval(); + return ret; + } + // Convert to a string representation, escaping literal strings matching /^[01xz]* *$/ by adding a space at the end, + // to disambiguate from binary strings + std::string to_string() const; + // Convert a string of four-value binary [01xz], or a literal string escaped according to the above rule + // to a Property + static Property from_string(const std::string &s); +}; + +inline bool operator==(const Property &a, const Property &b) { return a.is_string == b.is_string && a.str == b.str; } +inline bool operator!=(const Property &a, const Property &b) { return a.is_string != b.is_string || a.str != b.str; } + +NEXTPNR_NAMESPACE_END + +#endif /* PROPERTY_H */ |