diff options
Diffstat (limited to 'kernel')
-rw-r--r-- | kernel/calc.cc | 47 | ||||
-rw-r--r-- | kernel/celledges.cc | 2 | ||||
-rw-r--r-- | kernel/celledges.h | 4 | ||||
-rw-r--r-- | kernel/celltypes.h | 44 | ||||
-rw-r--r-- | kernel/constids.inc | 11 | ||||
-rw-r--r-- | kernel/hashlib.h | 12 | ||||
-rw-r--r-- | kernel/log.cc | 22 | ||||
-rw-r--r-- | kernel/log.h | 56 | ||||
-rw-r--r-- | kernel/macc.h | 2 | ||||
-rw-r--r-- | kernel/modtools.h | 8 | ||||
-rw-r--r-- | kernel/register.cc | 10 | ||||
-rw-r--r-- | kernel/register.h | 14 | ||||
-rw-r--r-- | kernel/rtlil.cc | 514 | ||||
-rw-r--r-- | kernel/rtlil.h | 103 | ||||
-rw-r--r-- | kernel/satgen.h | 42 | ||||
-rw-r--r-- | kernel/timinginfo.h | 19 | ||||
-rw-r--r-- | kernel/yosys.cc | 16 | ||||
-rw-r--r-- | kernel/yosys.h | 27 |
18 files changed, 778 insertions, 175 deletions
diff --git a/kernel/calc.cc b/kernel/calc.cc index 4a4840771..ae18809d3 100644 --- a/kernel/calc.cc +++ b/kernel/calc.cc @@ -489,6 +489,7 @@ RTLIL::Const RTLIL::const_mul(const RTLIL::Const &arg1, const RTLIL::Const &arg2 return big2const(y, result_len >= 0 ? result_len : max(arg1.bits.size(), arg2.bits.size()), min(undef_bit_pos, 0)); } +// truncating division RTLIL::Const RTLIL::const_div(const RTLIL::Const &arg1, const RTLIL::Const &arg2, bool signed1, bool signed2, int result_len) { int undef_bit_pos = -1; @@ -502,6 +503,7 @@ RTLIL::Const RTLIL::const_div(const RTLIL::Const &arg1, const RTLIL::Const &arg2 return big2const(result_neg ? -(a / b) : (a / b), result_len >= 0 ? result_len : max(arg1.bits.size(), arg2.bits.size()), min(undef_bit_pos, 0)); } +// truncating modulo RTLIL::Const RTLIL::const_mod(const RTLIL::Const &arg1, const RTLIL::Const &arg2, bool signed1, bool signed2, int result_len) { int undef_bit_pos = -1; @@ -515,6 +517,51 @@ RTLIL::Const RTLIL::const_mod(const RTLIL::Const &arg1, const RTLIL::Const &arg2 return big2const(result_neg ? -(a % b) : (a % b), result_len >= 0 ? result_len : max(arg1.bits.size(), arg2.bits.size()), min(undef_bit_pos, 0)); } +RTLIL::Const RTLIL::const_divfloor(const RTLIL::Const &arg1, const RTLIL::Const &arg2, bool signed1, bool signed2, int result_len) +{ + int undef_bit_pos = -1; + BigInteger a = const2big(arg1, signed1, undef_bit_pos); + BigInteger b = const2big(arg2, signed2, undef_bit_pos); + if (b.isZero()) + return RTLIL::Const(RTLIL::State::Sx, result_len); + + bool result_pos = (a.getSign() == BigInteger::negative) == (b.getSign() == BigInteger::negative); + a = a.getSign() == BigInteger::negative ? -a : a; + b = b.getSign() == BigInteger::negative ? -b : b; + BigInteger result; + + if (result_pos || a == 0) { + result = a / b; + } else { + // bigint division with negative numbers is wonky, make sure we only negate at the very end + result = -((a + b - 1) / b); + } + return big2const(result, result_len >= 0 ? result_len : max(arg1.bits.size(), arg2.bits.size()), min(undef_bit_pos, 0)); +} + +RTLIL::Const RTLIL::const_modfloor(const RTLIL::Const &arg1, const RTLIL::Const &arg2, bool signed1, bool signed2, int result_len) +{ + int undef_bit_pos = -1; + BigInteger a = const2big(arg1, signed1, undef_bit_pos); + BigInteger b = const2big(arg2, signed2, undef_bit_pos); + if (b.isZero()) + return RTLIL::Const(RTLIL::State::Sx, result_len); + + BigInteger::Sign a_sign = a.getSign(); + BigInteger::Sign b_sign = b.getSign(); + a = a_sign == BigInteger::negative ? -a : a; + b = b_sign == BigInteger::negative ? -b : b; + BigInteger truncated = a_sign == BigInteger::negative ? -(a % b) : (a % b); + BigInteger modulo; + + if (truncated == 0 || (a_sign == b_sign)) { + modulo = truncated; + } else { + modulo = b_sign == BigInteger::negative ? truncated - b : truncated + b; + } + return big2const(modulo, result_len >= 0 ? result_len : max(arg1.bits.size(), arg2.bits.size()), min(undef_bit_pos, 0)); +} + RTLIL::Const RTLIL::const_pow(const RTLIL::Const &arg1, const RTLIL::Const &arg2, bool signed1, bool signed2, int result_len) { int undef_bit_pos = -1; diff --git a/kernel/celledges.cc b/kernel/celledges.cc index 54e0168e2..314e7c77e 100644 --- a/kernel/celledges.cc +++ b/kernel/celledges.cc @@ -187,7 +187,7 @@ bool YOSYS_NAMESPACE_PREFIX AbstractCellEdgesDatabase::add_edges_from_cell(RTLIL return true; } - // FIXME: $mul $div $mod $slice $concat + // FIXME: $mul $div $mod $divfloor $modfloor $slice $concat // FIXME: $lut $sop $alu $lcu $macc $fa return false; diff --git a/kernel/celledges.h b/kernel/celledges.h index 2cc297cb2..d105e4009 100644 --- a/kernel/celledges.h +++ b/kernel/celledges.h @@ -38,7 +38,7 @@ struct FwdCellEdgesDatabase : AbstractCellEdgesDatabase dict<SigBit, pool<SigBit>> db; FwdCellEdgesDatabase(SigMap &sigmap) : sigmap(sigmap) { } - void add_edge(RTLIL::Cell *cell, RTLIL::IdString from_port, int from_bit, RTLIL::IdString to_port, int to_bit, int) YS_OVERRIDE { + void add_edge(RTLIL::Cell *cell, RTLIL::IdString from_port, int from_bit, RTLIL::IdString to_port, int to_bit, int) override { SigBit from_sigbit = sigmap(cell->getPort(from_port)[from_bit]); SigBit to_sigbit = sigmap(cell->getPort(to_port)[to_bit]); db[from_sigbit].insert(to_sigbit); @@ -51,7 +51,7 @@ struct RevCellEdgesDatabase : AbstractCellEdgesDatabase dict<SigBit, pool<SigBit>> db; RevCellEdgesDatabase(SigMap &sigmap) : sigmap(sigmap) { } - void add_edge(RTLIL::Cell *cell, RTLIL::IdString from_port, int from_bit, RTLIL::IdString to_port, int to_bit, int) YS_OVERRIDE { + void add_edge(RTLIL::Cell *cell, RTLIL::IdString from_port, int from_bit, RTLIL::IdString to_port, int to_bit, int) override { SigBit from_sigbit = sigmap(cell->getPort(from_port)[from_bit]); SigBit to_sigbit = sigmap(cell->getPort(to_port)[to_bit]); db[to_sigbit].insert(from_sigbit); diff --git a/kernel/celltypes.h b/kernel/celltypes.h index 450865ce9..12dea93b8 100644 --- a/kernel/celltypes.h +++ b/kernel/celltypes.h @@ -114,7 +114,7 @@ struct CellTypes ID($and), ID($or), ID($xor), ID($xnor), ID($shl), ID($shr), ID($sshl), ID($sshr), ID($shift), ID($shiftx), ID($lt), ID($le), ID($eq), ID($ne), ID($eqx), ID($nex), ID($ge), ID($gt), - ID($add), ID($sub), ID($mul), ID($div), ID($mod), ID($pow), + ID($add), ID($sub), ID($mul), ID($div), ID($mod), ID($divfloor), ID($modfloor), ID($pow), ID($logic_and), ID($logic_or), ID($concat), ID($macc) }; @@ -139,8 +139,14 @@ struct CellTypes setup_type(ID($dff), {ID::CLK, ID::D}, {ID::Q}); setup_type(ID($dffe), {ID::CLK, ID::EN, ID::D}, {ID::Q}); setup_type(ID($dffsr), {ID::CLK, ID::SET, ID::CLR, ID::D}, {ID::Q}); + setup_type(ID($dffsre), {ID::CLK, ID::SET, ID::CLR, ID::D, ID::E}, {ID::Q}); setup_type(ID($adff), {ID::CLK, ID::ARST, ID::D}, {ID::Q}); + setup_type(ID($adffe), {ID::CLK, ID::ARST, ID::D, ID::E}, {ID::Q}); + setup_type(ID($sdff), {ID::CLK, ID::SRST, ID::D}, {ID::Q}); + setup_type(ID($sdffe), {ID::CLK, ID::SRST, ID::D, ID::E}, {ID::Q}); + setup_type(ID($sdffce), {ID::CLK, ID::SRST, ID::D, ID::E}, {ID::Q}); setup_type(ID($dlatch), {ID::EN, ID::D}, {ID::Q}); + setup_type(ID($adlatch), {ID::EN, ID::D, ID::ARST}, {ID::Q}); setup_type(ID($dlatchsr), {ID::EN, ID::SET, ID::CLR, ID::D}, {ID::Q}); } @@ -210,14 +216,48 @@ struct CellTypes for (auto c1 : list_np) for (auto c2 : list_np) + for (auto c3 : list_01) + for (auto c4 : list_np) + setup_type(stringf("$_DFFE_%c%c%c%c_", c1, c2, c3, c4), {ID::C, ID::R, ID::D, ID::E}, {ID::Q}); + + for (auto c1 : list_np) + for (auto c2 : list_np) for (auto c3 : list_np) setup_type(stringf("$_DFFSR_%c%c%c_", c1, c2, c3), {ID::C, ID::S, ID::R, ID::D}, {ID::Q}); for (auto c1 : list_np) + for (auto c2 : list_np) + for (auto c3 : list_np) + for (auto c4 : list_np) + setup_type(stringf("$_DFFSRE_%c%c%c%c_", c1, c2, c3, c4), {ID::C, ID::S, ID::R, ID::D, ID::E}, {ID::Q}); + + for (auto c1 : list_np) + for (auto c2 : list_np) + for (auto c3 : list_01) + setup_type(stringf("$_SDFF_%c%c%c_", c1, c2, c3), {ID::C, ID::R, ID::D}, {ID::Q}); + + for (auto c1 : list_np) + for (auto c2 : list_np) + for (auto c3 : list_01) + for (auto c4 : list_np) + setup_type(stringf("$_SDFFE_%c%c%c%c_", c1, c2, c3, c4), {ID::C, ID::R, ID::D, ID::E}, {ID::Q}); + + for (auto c1 : list_np) + for (auto c2 : list_np) + for (auto c3 : list_01) + for (auto c4 : list_np) + setup_type(stringf("$_SDFFCE_%c%c%c%c_", c1, c2, c3, c4), {ID::C, ID::R, ID::D, ID::E}, {ID::Q}); + + for (auto c1 : list_np) setup_type(stringf("$_DLATCH_%c_", c1), {ID::E, ID::D}, {ID::Q}); for (auto c1 : list_np) for (auto c2 : list_np) + for (auto c3 : list_01) + setup_type(stringf("$_DLATCH_%c%c%c_", c1, c2, c3), {ID::E, ID::R, ID::D}, {ID::Q}); + + for (auto c1 : list_np) + for (auto c2 : list_np) for (auto c3 : list_np) setup_type(stringf("$_DLATCHSR_%c%c%c_", c1, c2, c3), {ID::E, ID::S, ID::R, ID::D}, {ID::Q}); } @@ -304,6 +344,8 @@ struct CellTypes HANDLE_CELL_TYPE(mul) HANDLE_CELL_TYPE(div) HANDLE_CELL_TYPE(mod) + HANDLE_CELL_TYPE(divfloor) + HANDLE_CELL_TYPE(modfloor) HANDLE_CELL_TYPE(pow) HANDLE_CELL_TYPE(pos) HANDLE_CELL_TYPE(neg) diff --git a/kernel/constids.inc b/kernel/constids.inc index 6b40a5908..69bc06d2c 100644 --- a/kernel/constids.inc +++ b/kernel/constids.inc @@ -2,13 +2,12 @@ X(A) X(abc9_box) X(abc9_box_id) X(abc9_box_seq) +X(abc9_bypass) X(abc9_carry) X(abc9_flop) -X(abc9_holes) -X(abc9_init) +X(abc9_keep) X(abc9_lut) X(abc9_mergeability) -X(abc9_scc) X(abc9_scc_id) X(abcgroup) X(ABITS) @@ -80,6 +79,8 @@ X(equiv_merged) X(equiv_region) X(extract_order) X(F) +X(force_downto) +X(force_upto) X(fsm_encoding) X(fsm_export) X(FULL) @@ -157,6 +158,9 @@ X(SRC_EN) X(SRC_PEN) X(SRC_POL) X(SRC_WIDTH) +X(SRST) +X(SRST_POLARITY) +X(SRST_VALUE) X(STATE_BITS) X(STATE_NUM) X(STATE_NUM_LOG2) @@ -170,6 +174,7 @@ X(techmap_autopurge) X(_TECHMAP_BITS_CONNMAP_) X(_TECHMAP_CELLTYPE_) X(techmap_celltype) +X(_TECHMAP_FAIL_) X(techmap_maccmap) X(_TECHMAP_REPLACE_) X(techmap_simplemap) diff --git a/kernel/hashlib.h b/kernel/hashlib.h index 592d6e577..a523afadd 100644 --- a/kernel/hashlib.h +++ b/kernel/hashlib.h @@ -207,6 +207,7 @@ class dict entry_t() { } entry_t(const std::pair<K, T> &udata, int next) : udata(udata), next(next) { } entry_t(std::pair<K, T> &&udata, int next) : udata(std::move(udata)), next(next) { } + bool operator<(const entry_t &other) const { return udata.first < other.udata.first; } }; std::vector<int> hashtable; @@ -362,6 +363,7 @@ public: public: const_iterator() { } const_iterator operator++() { index--; return *this; } + const_iterator operator+=(int amt) { index -= amt; return *this; } bool operator<(const const_iterator &other) const { return index > other.index; } bool operator==(const const_iterator &other) const { return index == other.index; } bool operator!=(const const_iterator &other) const { return index != other.index; } @@ -379,6 +381,7 @@ public: public: iterator() { } iterator operator++() { index--; return *this; } + iterator operator+=(int amt) { index -= amt; return *this; } bool operator<(const iterator &other) const { return index > other.index; } bool operator==(const iterator &other) const { return index == other.index; } bool operator!=(const iterator &other) const { return index != other.index; } @@ -615,6 +618,15 @@ public: return !operator==(other); } + unsigned int hash() const { + unsigned int h = mkhash_init; + for (auto &entry : entries) { + h ^= hash_ops<K>::hash(entry.udata.first); + h ^= hash_ops<T>::hash(entry.udata.second); + } + return h; + } + void reserve(size_t n) { entries.reserve(n); } size_t size() const { return entries.size(); } bool empty() const { return entries.empty(); } diff --git a/kernel/log.cc b/kernel/log.cc index a21ba480a..1c1d0182e 100644 --- a/kernel/log.cc +++ b/kernel/log.cc @@ -42,7 +42,7 @@ std::vector<FILE*> log_files; std::vector<std::ostream*> log_streams; std::map<std::string, std::set<std::string>> log_hdump; std::vector<YS_REGEX_TYPE> log_warn_regexes, log_nowarn_regexes, log_werror_regexes; -std::vector<std::pair<YS_REGEX_TYPE,LogExpectedItem>> log_expect_log, log_expect_warning, log_expect_error; +dict<std::string, LogExpectedItem> log_expect_log, log_expect_warning, log_expect_error; std::set<std::string> log_warnings, log_experimentals, log_experimentals_ignored; int log_warnings_count = 0; int log_warnings_count_noexpect = 0; @@ -181,7 +181,7 @@ void logv(const char *format, va_list ap) log_warning("Found log message matching -W regex:\n%s", str.c_str()); for (auto &item : log_expect_log) - if (YS_REGEX_NS::regex_search(linebuffer, item.first)) + if (YS_REGEX_NS::regex_search(linebuffer, item.second.pattern)) item.second.current_count++; linebuffer.clear(); @@ -256,7 +256,7 @@ static void logv_warning_with_prefix(const char *prefix, bool warning_match = false; for (auto &item : log_expect_warning) - if (YS_REGEX_NS::regex_search(message, item.first)) { + if (YS_REGEX_NS::regex_search(message, item.second.pattern)) { item.second.current_count++; warning_match = true; } @@ -319,7 +319,7 @@ void log_file_info(const std::string &filename, int lineno, va_end(ap); } -YS_ATTRIBUTE(noreturn) +[[noreturn]] static void logv_error_with_prefix(const char *prefix, const char *format, va_list ap) { @@ -349,7 +349,7 @@ static void logv_error_with_prefix(const char *prefix, log_error_atexit(); for (auto &item : log_expect_error) - if (YS_REGEX_NS::regex_search(log_last_error, item.first)) + if (YS_REGEX_NS::regex_search(log_last_error, item.second.pattern)) item.second.current_count++; if (check_expected_logs) @@ -672,31 +672,31 @@ void log_check_expected() for (auto &item : log_expect_warning) { if (item.second.current_count == 0) { log_warn_regexes.clear(); - log_error("Expected warning pattern '%s' not found !\n", item.second.pattern.c_str()); + log_error("Expected warning pattern '%s' not found !\n", item.first.c_str()); } if (item.second.current_count != item.second.expected_count) { log_warn_regexes.clear(); log_error("Expected warning pattern '%s' found %d time(s), instead of %d time(s) !\n", - item.second.pattern.c_str(), item.second.current_count, item.second.expected_count); + item.first.c_str(), item.second.current_count, item.second.expected_count); } } for (auto &item : log_expect_log) { if (item.second.current_count == 0) { log_warn_regexes.clear(); - log_error("Expected log pattern '%s' not found !\n", item.second.pattern.c_str()); + log_error("Expected log pattern '%s' not found !\n", item.first.c_str()); } if (item.second.current_count != item.second.expected_count) { log_warn_regexes.clear(); log_error("Expected log pattern '%s' found %d time(s), instead of %d time(s) !\n", - item.second.pattern.c_str(), item.second.current_count, item.second.expected_count); + item.first.c_str(), item.second.current_count, item.second.expected_count); } } for (auto &item : log_expect_error) if (item.second.current_count == item.second.expected_count) { log_warn_regexes.clear(); - log("Expected error pattern '%s' found !!!\n", item.second.pattern.c_str()); + log("Expected error pattern '%s' found !!!\n", item.first.c_str()); #ifdef EMSCRIPTEN throw 0; #elif defined(_MSC_VER) @@ -707,7 +707,7 @@ void log_check_expected() } else { display_error_log_msg = false; log_warn_regexes.clear(); - log_error("Expected error pattern '%s' not found !\n", item.second.pattern.c_str()); + log_error("Expected error pattern '%s' not found !\n", item.first.c_str()); } } diff --git a/kernel/log.h b/kernel/log.h index dee5d44d7..8981c4cde 100644 --- a/kernel/log.h +++ b/kernel/log.h @@ -55,7 +55,9 @@ #else # include <sys/time.h> # include <sys/resource.h> -# include <signal.h> +# if defined(__unix__) || (defined(__APPLE__) && defined(__MACH__)) +# include <signal.h> +# endif #endif #if defined(_MSC_VER) @@ -86,7 +88,7 @@ YOSYS_NAMESPACE_BEGIN # endif # if __has_builtin(__builtin_debugtrap) # define YS_DEBUGTRAP __builtin_debugtrap() -# elif defined(__unix__) +# elif defined(__unix__) || (defined(__APPLE__) && defined(__MACH__)) # define YS_DEBUGTRAP raise(SIGTRAP) # else # define YS_DEBUGTRAP do {} while(0) @@ -97,11 +99,11 @@ YOSYS_NAMESPACE_BEGIN // if a debugger is attached, and does nothing otherwise. #if defined(_WIN32) # define YS_DEBUGTRAP_IF_DEBUGGING do { if (IsDebuggerPresent()) DebugBreak(); } while(0) -#elif defined(__unix__) +# elif defined(__unix__) || (defined(__APPLE__) && defined(__MACH__)) // There is no reliable (or portable) *nix equivalent of IsDebuggerPresent(). However, // debuggers will stop when SIGTRAP is raised, even if the action is set to ignore. # define YS_DEBUGTRAP_IF_DEBUGGING do { \ - sighandler_t old = signal(SIGTRAP, SIG_IGN); raise(SIGTRAP); signal(SIGTRAP, old); \ + auto old = signal(SIGTRAP, SIG_IGN); raise(SIGTRAP); signal(SIGTRAP, old); \ } while(0) #else # define YS_DEBUGTRAP_IF_DEBUGGING do {} while(0) @@ -137,7 +139,7 @@ void logv(const char *format, va_list ap); void logv_header(RTLIL::Design *design, const char *format, va_list ap); void logv_warning(const char *format, va_list ap); void logv_warning_noprefix(const char *format, va_list ap); -YS_NORETURN void logv_error(const char *format, va_list ap) YS_ATTRIBUTE(noreturn); +[[noreturn]] void logv_error(const char *format, va_list ap); void log(const char *format, ...) YS_ATTRIBUTE(format(printf, 1, 2)); void log_header(RTLIL::Design *design, const char *format, ...) YS_ATTRIBUTE(format(printf, 2, 3)); @@ -149,17 +151,16 @@ void log_file_warning(const std::string &filename, int lineno, const char *forma void log_file_info(const std::string &filename, int lineno, const char *format, ...) YS_ATTRIBUTE(format(printf, 3, 4)); void log_warning_noprefix(const char *format, ...) YS_ATTRIBUTE(format(printf, 1, 2)); -YS_NORETURN void log_error(const char *format, ...) YS_ATTRIBUTE(format(printf, 1, 2), noreturn); -void log_file_error(const string &filename, int lineno, const char *format, ...) YS_ATTRIBUTE(format(printf, 3, 4), noreturn); -YS_NORETURN void log_cmd_error(const char *format, ...) YS_ATTRIBUTE(format(printf, 1, 2), noreturn); +[[noreturn]] void log_error(const char *format, ...) YS_ATTRIBUTE(format(printf, 1, 2)); +[[noreturn]] void log_file_error(const string &filename, int lineno, const char *format, ...) YS_ATTRIBUTE(format(printf, 3, 4)); +[[noreturn]] void log_cmd_error(const char *format, ...) YS_ATTRIBUTE(format(printf, 1, 2)); #ifndef NDEBUG static inline bool ys_debug(int n = 0) { if (log_force_debug) return true; log_debug_suppressed += n; return false; } -# define log_debug(...) do { if (ys_debug(1)) log(__VA_ARGS__); } while (0) #else static inline bool ys_debug(int = 0) { return false; } -# define log_debug(_fmt, ...) do { } while (0) #endif +# define log_debug(...) do { if (ys_debug(1)) log(__VA_ARGS__); } while (0) static inline void log_suppressed() { if (log_debug_suppressed && !log_make_debug) { @@ -202,19 +203,16 @@ void log_flush(); struct LogExpectedItem { - LogExpectedItem(std::string pattern, int expected) : - expected_count(expected), - current_count(0), - pattern(pattern) - { - } + LogExpectedItem(const YS_REGEX_TYPE &pat, int expected) : + pattern(pat), expected_count(expected), current_count(0) {} + LogExpectedItem() : expected_count(0), current_count(0) {} + YS_REGEX_TYPE pattern; int expected_count; int current_count; - std::string pattern; }; -extern std::vector<std::pair<YS_REGEX_TYPE,LogExpectedItem>> log_expect_log, log_expect_warning, log_expect_error; +extern dict<std::string, LogExpectedItem> log_expect_log, log_expect_warning, log_expect_error; void log_check_expected(); const char *log_signal(const RTLIL::SigSpec &sig, bool autoint = true); @@ -237,7 +235,7 @@ static inline void log_assert_worker(bool cond, const char *expr, const char *fi } # define log_assert(_assert_expr_) YOSYS_NAMESPACE_PREFIX log_assert_worker(_assert_expr_, #_assert_expr_, __FILE__, __LINE__) #else -# define log_assert(_assert_expr_) +# define log_assert(_assert_expr_) do { if (0) { (void)(_assert_expr_); } } while(0) #endif #define log_abort() YOSYS_NAMESPACE_PREFIX log_error("Abort in %s:%d.\n", __FILE__, __LINE__) @@ -309,19 +307,17 @@ struct PerformanceTimer static int64_t query() { # ifdef _WIN32 return 0; -# elif defined(_POSIX_TIMERS) && (_POSIX_TIMERS > 0) - struct timespec ts; - clock_gettime(CLOCK_PROCESS_CPUTIME_ID, &ts); - return int64_t(ts.tv_sec)*1000000000 + ts.tv_nsec; # elif defined(RUSAGE_SELF) struct rusage rusage; - int64_t t; - if (getrusage(RUSAGE_SELF, &rusage) == -1) { - log_cmd_error("getrusage failed!\n"); - log_abort(); + int64_t t = 0; + for (int who : {RUSAGE_SELF, RUSAGE_CHILDREN}) { + if (getrusage(who, &rusage) == -1) { + log_cmd_error("getrusage failed!\n"); + log_abort(); + } + t += 1000000000ULL * (int64_t) rusage.ru_utime.tv_sec + (int64_t) rusage.ru_utime.tv_usec * 1000ULL; + t += 1000000000ULL * (int64_t) rusage.ru_stime.tv_sec + (int64_t) rusage.ru_stime.tv_usec * 1000ULL; } - t = 1000000000ULL * (int64_t) rusage.ru_utime.tv_sec + (int64_t) rusage.ru_utime.tv_usec * 1000ULL; - t += 1000000000ULL * (int64_t) rusage.ru_stime.tv_sec + (int64_t) rusage.ru_stime.tv_usec * 1000ULL; return t; # else # error "Don't know how to measure per-process CPU time. Need alternative method (times()/clocks()/gettimeofday()?)." @@ -372,7 +368,7 @@ static inline void log_dump_val_worker(char *v) { log("%s", v); } static inline void log_dump_val_worker(const char *v) { log("%s", v); } static inline void log_dump_val_worker(std::string v) { log("%s", v.c_str()); } static inline void log_dump_val_worker(PerformanceTimer p) { log("%f seconds", p.sec()); } -static inline void log_dump_args_worker(const char *p YS_ATTRIBUTE(unused)) { log_assert(*p == 0); } +static inline void log_dump_args_worker(const char *p) { log_assert(*p == 0); } void log_dump_val_worker(RTLIL::IdString v); void log_dump_val_worker(RTLIL::SigSpec v); void log_dump_val_worker(RTLIL::State v); diff --git a/kernel/macc.h b/kernel/macc.h index e9f6f05e9..d216e6772 100644 --- a/kernel/macc.h +++ b/kernel/macc.h @@ -107,10 +107,8 @@ struct Macc std::vector<RTLIL::State> config_bits = cell->getParam(ID::CONFIG).bits; int config_cursor = 0; -#ifndef NDEBUG int config_width = cell->getParam(ID::CONFIG_WIDTH).as_int(); log_assert(GetSize(config_bits) >= config_width); -#endif int num_bits = 0; if (config_bits[config_cursor++] == State::S1) num_bits |= 1; diff --git a/kernel/modtools.h b/kernel/modtools.h index fbc5482ee..29c510059 100644 --- a/kernel/modtools.h +++ b/kernel/modtools.h @@ -158,7 +158,7 @@ struct ModIndex : public RTLIL::Monitor #endif } - void notify_connect(RTLIL::Cell *cell, const RTLIL::IdString &port, const RTLIL::SigSpec &old_sig, const RTLIL::SigSpec &sig) YS_OVERRIDE + void notify_connect(RTLIL::Cell *cell, const RTLIL::IdString &port, const RTLIL::SigSpec &old_sig, const RTLIL::SigSpec &sig) override { log_assert(module == cell->module); @@ -169,7 +169,7 @@ struct ModIndex : public RTLIL::Monitor port_add(cell, port, sig); } - void notify_connect(RTLIL::Module *mod YS_ATTRIBUTE(unused), const RTLIL::SigSig &sigsig) YS_OVERRIDE + void notify_connect(RTLIL::Module *mod, const RTLIL::SigSig &sigsig) override { log_assert(module == mod); @@ -214,13 +214,13 @@ struct ModIndex : public RTLIL::Monitor } } - void notify_connect(RTLIL::Module *mod YS_ATTRIBUTE(unused), const std::vector<RTLIL::SigSig>&) YS_OVERRIDE + void notify_connect(RTLIL::Module *mod, const std::vector<RTLIL::SigSig>&) override { log_assert(module == mod); auto_reload_module = true; } - void notify_blackout(RTLIL::Module *mod YS_ATTRIBUTE(unused)) YS_OVERRIDE + void notify_blackout(RTLIL::Module *mod) override { log_assert(module == mod); auto_reload_module = true; diff --git a/kernel/register.cc b/kernel/register.cc index 02974e534..34735a608 100644 --- a/kernel/register.cc +++ b/kernel/register.cc @@ -753,7 +753,7 @@ static struct CellHelpMessages { struct HelpPass : public Pass { HelpPass() : Pass("help", "display help messages") { } - void help() YS_OVERRIDE + void help() override { log("\n"); log(" help ................ list all commands\n"); @@ -822,7 +822,7 @@ struct HelpPass : public Pass { fclose(f); } - void execute(std::vector<std::string> args, RTLIL::Design*) YS_OVERRIDE + void execute(std::vector<std::string> args, RTLIL::Design*) override { if (args.size() == 1) { log("\n"); @@ -926,7 +926,7 @@ struct HelpPass : public Pass { struct EchoPass : public Pass { EchoPass() : Pass("echo", "turning echoing back of commands on and off") { } - void help() YS_OVERRIDE + void help() override { log("\n"); log(" echo on\n"); @@ -939,7 +939,7 @@ struct EchoPass : public Pass { log("Do not print all commands to log before executing them. (default)\n"); log("\n"); } - void execute(std::vector<std::string> args, RTLIL::Design*) YS_OVERRIDE + void execute(std::vector<std::string> args, RTLIL::Design*) override { if (args.size() > 2) cmd_error(args, 2, "Unexpected argument."); @@ -964,7 +964,7 @@ struct MinisatSatSolver : public SatSolver { MinisatSatSolver() : SatSolver("minisat") { yosys_satsolver = this; } - ezSAT *create() YS_OVERRIDE { + ezSAT *create() override { return new ezMiniSAT(); } } MinisatSatSolver; diff --git a/kernel/register.h b/kernel/register.h index 3d89386b7..5cd849082 100644 --- a/kernel/register.h +++ b/kernel/register.h @@ -97,9 +97,9 @@ struct Frontend : Pass std::string frontend_name; Frontend(std::string name, std::string short_help = "** document me **"); - void run_register() YS_OVERRIDE; - ~Frontend() YS_OVERRIDE; - void execute(std::vector<std::string> args, RTLIL::Design *design) YS_OVERRIDE YS_FINAL; + void run_register() override; + ~Frontend() override; + void execute(std::vector<std::string> args, RTLIL::Design *design) override final; virtual void execute(std::istream *&f, std::string filename, std::vector<std::string> args, RTLIL::Design *design) = 0; static std::vector<std::string> next_args; @@ -113,9 +113,9 @@ struct Backend : Pass { std::string backend_name; Backend(std::string name, std::string short_help = "** document me **"); - void run_register() YS_OVERRIDE; - ~Backend() YS_OVERRIDE; - void execute(std::vector<std::string> args, RTLIL::Design *design) YS_OVERRIDE YS_FINAL; + void run_register() override; + ~Backend() override; + void execute(std::vector<std::string> args, RTLIL::Design *design) override final; virtual void execute(std::ostream *&f, std::string filename, std::vector<std::string> args, RTLIL::Design *design) = 0; void extra_args(std::ostream *&f, std::string &filename, std::vector<std::string> args, size_t argidx, bool bin_output = false); @@ -125,7 +125,7 @@ struct Backend : Pass }; // implemented in passes/cmds/select.cc -extern void handle_extra_select_args(Pass *pass, std::vector<std::string> args, size_t argidx, size_t args_size, RTLIL::Design *design); +extern void handle_extra_select_args(Pass *pass, const std::vector<std::string> &args, size_t argidx, size_t args_size, RTLIL::Design *design); extern RTLIL::Selection eval_select_args(const vector<string> &args, RTLIL::Design *design); extern void eval_select_op(vector<RTLIL::Selection> &work, const string &op, RTLIL::Design *design); diff --git a/kernel/rtlil.cc b/kernel/rtlil.cc index 196e301b6..d7d226942 100644 --- a/kernel/rtlil.cc +++ b/kernel/rtlil.cc @@ -54,8 +54,14 @@ const pool<IdString> &RTLIL::builtin_ff_cell_types() { ID($dff), ID($dffe), ID($dffsr), + ID($dffsre), ID($adff), + ID($adffe), + ID($sdff), + ID($sdffe), + ID($sdffce), ID($dlatch), + ID($adlatch), ID($dlatchsr), ID($_DFFE_NN_), ID($_DFFE_NP_), @@ -69,16 +75,102 @@ const pool<IdString> &RTLIL::builtin_ff_cell_types() { ID($_DFFSR_PNP_), ID($_DFFSR_PPN_), ID($_DFFSR_PPP_), + ID($_DFFSRE_NNNN_), + ID($_DFFSRE_NNNP_), + ID($_DFFSRE_NNPN_), + ID($_DFFSRE_NNPP_), + ID($_DFFSRE_NPNN_), + ID($_DFFSRE_NPNP_), + ID($_DFFSRE_NPPN_), + ID($_DFFSRE_NPPP_), + ID($_DFFSRE_PNNN_), + ID($_DFFSRE_PNNP_), + ID($_DFFSRE_PNPN_), + ID($_DFFSRE_PNPP_), + ID($_DFFSRE_PPNN_), + ID($_DFFSRE_PPNP_), + ID($_DFFSRE_PPPN_), + ID($_DFFSRE_PPPP_), + ID($_DFF_N_), + ID($_DFF_P_), ID($_DFF_NN0_), ID($_DFF_NN1_), ID($_DFF_NP0_), ID($_DFF_NP1_), - ID($_DFF_N_), ID($_DFF_PN0_), ID($_DFF_PN1_), ID($_DFF_PP0_), ID($_DFF_PP1_), - ID($_DFF_P_), + ID($_DFFE_NN0N_), + ID($_DFFE_NN0P_), + ID($_DFFE_NN1N_), + ID($_DFFE_NN1P_), + ID($_DFFE_NP0N_), + ID($_DFFE_NP0P_), + ID($_DFFE_NP1N_), + ID($_DFFE_NP1P_), + ID($_DFFE_PN0N_), + ID($_DFFE_PN0P_), + ID($_DFFE_PN1N_), + ID($_DFFE_PN1P_), + ID($_DFFE_PP0N_), + ID($_DFFE_PP0P_), + ID($_DFFE_PP1N_), + ID($_DFFE_PP1P_), + ID($_SDFF_NN0_), + ID($_SDFF_NN1_), + ID($_SDFF_NP0_), + ID($_SDFF_NP1_), + ID($_SDFF_PN0_), + ID($_SDFF_PN1_), + ID($_SDFF_PP0_), + ID($_SDFF_PP1_), + ID($_SDFFE_NN0N_), + ID($_SDFFE_NN0P_), + ID($_SDFFE_NN1N_), + ID($_SDFFE_NN1P_), + ID($_SDFFE_NP0N_), + ID($_SDFFE_NP0P_), + ID($_SDFFE_NP1N_), + ID($_SDFFE_NP1P_), + ID($_SDFFE_PN0N_), + ID($_SDFFE_PN0P_), + ID($_SDFFE_PN1N_), + ID($_SDFFE_PN1P_), + ID($_SDFFE_PP0N_), + ID($_SDFFE_PP0P_), + ID($_SDFFE_PP1N_), + ID($_SDFFE_PP1P_), + ID($_SDFFCE_NN0N_), + ID($_SDFFCE_NN0P_), + ID($_SDFFCE_NN1N_), + ID($_SDFFCE_NN1P_), + ID($_SDFFCE_NP0N_), + ID($_SDFFCE_NP0P_), + ID($_SDFFCE_NP1N_), + ID($_SDFFCE_NP1P_), + ID($_SDFFCE_PN0N_), + ID($_SDFFCE_PN0P_), + ID($_SDFFCE_PN1N_), + ID($_SDFFCE_PN1P_), + ID($_SDFFCE_PP0N_), + ID($_SDFFCE_PP0P_), + ID($_SDFFCE_PP1N_), + ID($_SDFFCE_PP1P_), + ID($_SR_NN_), + ID($_SR_NP_), + ID($_SR_PN_), + ID($_SR_PP_), + ID($_DLATCH_N_), + ID($_DLATCH_P_), + ID($_DLATCH_NN0_), + ID($_DLATCH_NN1_), + ID($_DLATCH_NP0_), + ID($_DLATCH_NP1_), + ID($_DLATCH_PN0_), + ID($_DLATCH_PN1_), + ID($_DLATCH_PP0_), + ID($_DLATCH_PP1_), ID($_DLATCHSR_NNN_), ID($_DLATCHSR_NNP_), ID($_DLATCHSR_NPN_), @@ -87,8 +179,6 @@ const pool<IdString> &RTLIL::builtin_ff_cell_types() { ID($_DLATCHSR_PNP_), ID($_DLATCHSR_PPN_), ID($_DLATCHSR_PPP_), - ID($_DLATCH_N_), - ID($_DLATCH_P_), ID($_FF_), }; return res; @@ -319,7 +409,7 @@ void RTLIL::AttrObject::set_strpool_attribute(RTLIL::IdString id, const pool<str attrval += "|"; attrval += s; } - attributes[id] = RTLIL::Const(attrval); + set_string_attribute(id, attrval); } void RTLIL::AttrObject::add_strpool_attribute(RTLIL::IdString id, const pool<string> &data) @@ -334,11 +424,27 @@ pool<string> RTLIL::AttrObject::get_strpool_attribute(RTLIL::IdString id) const { pool<string> data; if (attributes.count(id) != 0) - for (auto s : split_tokens(attributes.at(id).decode_string(), "|")) + for (auto s : split_tokens(get_string_attribute(id), "|")) data.insert(s); return data; } +void RTLIL::AttrObject::set_hdlname_attribute(const vector<string> &hierarchy) +{ + string attrval; + for (const auto &ident : hierarchy) { + if (!attrval.empty()) + attrval += " "; + attrval += ident; + } + set_string_attribute(ID::hdlname, attrval); +} + +vector<string> RTLIL::AttrObject::get_hdlname_attribute() const +{ + return split_tokens(get_string_attribute(ID::hdlname), " "); +} + bool RTLIL::Selection::selected_module(RTLIL::IdString mod_name) const { if (full_selection) @@ -948,7 +1054,7 @@ namespace { return; } - if (cell->type.in(ID($add), ID($sub), ID($mul), ID($div), ID($mod), ID($pow))) { + if (cell->type.in(ID($add), ID($sub), ID($mul), ID($div), ID($mod), ID($divfloor), ID($modfloor), ID($pow))) { param_bool(ID::A_SIGNED); param_bool(ID::B_SIGNED); port(ID::A, param(ID::A_WIDTH)); @@ -1123,6 +1229,21 @@ namespace { return; } + if (cell->type == ID($dffsre)) { + param_bool(ID::CLK_POLARITY); + param_bool(ID::SET_POLARITY); + param_bool(ID::CLR_POLARITY); + param_bool(ID::EN_POLARITY); + port(ID::CLK, 1); + port(ID::EN, 1); + port(ID::SET, param(ID::WIDTH)); + port(ID::CLR, param(ID::WIDTH)); + port(ID::D, param(ID::WIDTH)); + port(ID::Q, param(ID::WIDTH)); + check_expected(); + return; + } + if (cell->type == ID($adff)) { param_bool(ID::CLK_POLARITY); param_bool(ID::ARST_POLARITY); @@ -1135,6 +1256,46 @@ namespace { return; } + if (cell->type == ID($sdff)) { + param_bool(ID::CLK_POLARITY); + param_bool(ID::SRST_POLARITY); + param_bits(ID::SRST_VALUE, param(ID::WIDTH)); + port(ID::CLK, 1); + port(ID::SRST, 1); + port(ID::D, param(ID::WIDTH)); + port(ID::Q, param(ID::WIDTH)); + check_expected(); + return; + } + + if (cell->type.in(ID($sdffe), ID($sdffce))) { + param_bool(ID::CLK_POLARITY); + param_bool(ID::EN_POLARITY); + param_bool(ID::SRST_POLARITY); + param_bits(ID::SRST_VALUE, param(ID::WIDTH)); + port(ID::CLK, 1); + port(ID::EN, 1); + port(ID::SRST, 1); + port(ID::D, param(ID::WIDTH)); + port(ID::Q, param(ID::WIDTH)); + check_expected(); + return; + } + + if (cell->type == ID($adffe)) { + param_bool(ID::CLK_POLARITY); + param_bool(ID::EN_POLARITY); + param_bool(ID::ARST_POLARITY); + param_bits(ID::ARST_VALUE, param(ID::WIDTH)); + port(ID::CLK, 1); + port(ID::EN, 1); + port(ID::ARST, 1); + port(ID::D, param(ID::WIDTH)); + port(ID::Q, param(ID::WIDTH)); + check_expected(); + return; + } + if (cell->type == ID($dlatch)) { param_bool(ID::EN_POLARITY); port(ID::EN, 1); @@ -1144,6 +1305,18 @@ namespace { return; } + if (cell->type == ID($adlatch)) { + param_bool(ID::EN_POLARITY); + param_bool(ID::ARST_POLARITY); + param_bits(ID::ARST_VALUE, param(ID::WIDTH)); + port(ID::EN, 1); + port(ID::ARST, 1); + port(ID::D, param(ID::WIDTH)); + port(ID::Q, param(ID::WIDTH)); + check_expected(); + return; + } + if (cell->type == ID($dlatchsr)) { param_bool(ID::EN_POLARITY); param_bool(ID::SET_POLARITY); @@ -1335,49 +1508,69 @@ namespace { if (cell->type == ID($_MUX8_)) { port(ID::A,1); port(ID::B,1); port(ID::C,1); port(ID::D,1); port(ID::E,1); port(ID::F,1); port(ID::G,1); port(ID::H,1); port(ID::S,1); port(ID::T,1); port(ID::U,1); port(ID::Y,1); check_expected(); return; } if (cell->type == ID($_MUX16_)) { port(ID::A,1); port(ID::B,1); port(ID::C,1); port(ID::D,1); port(ID::E,1); port(ID::F,1); port(ID::G,1); port(ID::H,1); port(ID::I,1); port(ID::J,1); port(ID::K,1); port(ID::L,1); port(ID::M,1); port(ID::N,1); port(ID::O,1); port(ID::P,1); port(ID::S,1); port(ID::T,1); port(ID::U,1); port(ID::V,1); port(ID::Y,1); check_expected(); return; } - if (cell->type == ID($_SR_NN_)) { port(ID::S,1); port(ID::R,1); port(ID::Q,1); check_expected(); return; } - if (cell->type == ID($_SR_NP_)) { port(ID::S,1); port(ID::R,1); port(ID::Q,1); check_expected(); return; } - if (cell->type == ID($_SR_PN_)) { port(ID::S,1); port(ID::R,1); port(ID::Q,1); check_expected(); return; } - if (cell->type == ID($_SR_PP_)) { port(ID::S,1); port(ID::R,1); port(ID::Q,1); check_expected(); return; } - - if (cell->type == ID($_FF_)) { port(ID::D,1); port(ID::Q,1); check_expected(); return; } - if (cell->type == ID($_DFF_N_)) { port(ID::D,1); port(ID::Q,1); port(ID::C,1); check_expected(); return; } - if (cell->type == ID($_DFF_P_)) { port(ID::D,1); port(ID::Q,1); port(ID::C,1); check_expected(); return; } - - if (cell->type == ID($_DFFE_NN_)) { port(ID::D,1); port(ID::Q,1); port(ID::C,1); port(ID::E,1); check_expected(); return; } - if (cell->type == ID($_DFFE_NP_)) { port(ID::D,1); port(ID::Q,1); port(ID::C,1); port(ID::E,1); check_expected(); return; } - if (cell->type == ID($_DFFE_PN_)) { port(ID::D,1); port(ID::Q,1); port(ID::C,1); port(ID::E,1); check_expected(); return; } - if (cell->type == ID($_DFFE_PP_)) { port(ID::D,1); port(ID::Q,1); port(ID::C,1); port(ID::E,1); check_expected(); return; } - - if (cell->type == ID($_DFF_NN0_)) { port(ID::D,1); port(ID::Q,1); port(ID::C,1); port(ID::R,1); check_expected(); return; } - if (cell->type == ID($_DFF_NN1_)) { port(ID::D,1); port(ID::Q,1); port(ID::C,1); port(ID::R,1); check_expected(); return; } - if (cell->type == ID($_DFF_NP0_)) { port(ID::D,1); port(ID::Q,1); port(ID::C,1); port(ID::R,1); check_expected(); return; } - if (cell->type == ID($_DFF_NP1_)) { port(ID::D,1); port(ID::Q,1); port(ID::C,1); port(ID::R,1); check_expected(); return; } - if (cell->type == ID($_DFF_PN0_)) { port(ID::D,1); port(ID::Q,1); port(ID::C,1); port(ID::R,1); check_expected(); return; } - if (cell->type == ID($_DFF_PN1_)) { port(ID::D,1); port(ID::Q,1); port(ID::C,1); port(ID::R,1); check_expected(); return; } - if (cell->type == ID($_DFF_PP0_)) { port(ID::D,1); port(ID::Q,1); port(ID::C,1); port(ID::R,1); check_expected(); return; } - if (cell->type == ID($_DFF_PP1_)) { port(ID::D,1); port(ID::Q,1); port(ID::C,1); port(ID::R,1); check_expected(); return; } - - if (cell->type == ID($_DFFSR_NNN_)) { port(ID::C,1); port(ID::S,1); port(ID::R,1); port(ID::D,1); port(ID::Q,1); check_expected(); return; } - if (cell->type == ID($_DFFSR_NNP_)) { port(ID::C,1); port(ID::S,1); port(ID::R,1); port(ID::D,1); port(ID::Q,1); check_expected(); return; } - if (cell->type == ID($_DFFSR_NPN_)) { port(ID::C,1); port(ID::S,1); port(ID::R,1); port(ID::D,1); port(ID::Q,1); check_expected(); return; } - if (cell->type == ID($_DFFSR_NPP_)) { port(ID::C,1); port(ID::S,1); port(ID::R,1); port(ID::D,1); port(ID::Q,1); check_expected(); return; } - if (cell->type == ID($_DFFSR_PNN_)) { port(ID::C,1); port(ID::S,1); port(ID::R,1); port(ID::D,1); port(ID::Q,1); check_expected(); return; } - if (cell->type == ID($_DFFSR_PNP_)) { port(ID::C,1); port(ID::S,1); port(ID::R,1); port(ID::D,1); port(ID::Q,1); check_expected(); return; } - if (cell->type == ID($_DFFSR_PPN_)) { port(ID::C,1); port(ID::S,1); port(ID::R,1); port(ID::D,1); port(ID::Q,1); check_expected(); return; } - if (cell->type == ID($_DFFSR_PPP_)) { port(ID::C,1); port(ID::S,1); port(ID::R,1); port(ID::D,1); port(ID::Q,1); check_expected(); return; } - - if (cell->type == ID($_DLATCH_N_)) { port(ID::E,1); port(ID::D,1); port(ID::Q,1); check_expected(); return; } - if (cell->type == ID($_DLATCH_P_)) { port(ID::E,1); port(ID::D,1); port(ID::Q,1); check_expected(); return; } - - if (cell->type == ID($_DLATCHSR_NNN_)) { port(ID::E,1); port(ID::S,1); port(ID::R,1); port(ID::D,1); port(ID::Q,1); check_expected(); return; } - if (cell->type == ID($_DLATCHSR_NNP_)) { port(ID::E,1); port(ID::S,1); port(ID::R,1); port(ID::D,1); port(ID::Q,1); check_expected(); return; } - if (cell->type == ID($_DLATCHSR_NPN_)) { port(ID::E,1); port(ID::S,1); port(ID::R,1); port(ID::D,1); port(ID::Q,1); check_expected(); return; } - if (cell->type == ID($_DLATCHSR_NPP_)) { port(ID::E,1); port(ID::S,1); port(ID::R,1); port(ID::D,1); port(ID::Q,1); check_expected(); return; } - if (cell->type == ID($_DLATCHSR_PNN_)) { port(ID::E,1); port(ID::S,1); port(ID::R,1); port(ID::D,1); port(ID::Q,1); check_expected(); return; } - if (cell->type == ID($_DLATCHSR_PNP_)) { port(ID::E,1); port(ID::S,1); port(ID::R,1); port(ID::D,1); port(ID::Q,1); check_expected(); return; } - if (cell->type == ID($_DLATCHSR_PPN_)) { port(ID::E,1); port(ID::S,1); port(ID::R,1); port(ID::D,1); port(ID::Q,1); check_expected(); return; } - if (cell->type == ID($_DLATCHSR_PPP_)) { port(ID::E,1); port(ID::S,1); port(ID::R,1); port(ID::D,1); port(ID::Q,1); check_expected(); return; } + if (cell->type.in(ID($_SR_NN_), ID($_SR_NP_), ID($_SR_PN_), ID($_SR_PP_))) + { port(ID::S,1); port(ID::R,1); port(ID::Q,1); check_expected(); return; } + + if (cell->type == ID($_FF_)) { port(ID::D,1); port(ID::Q,1); check_expected(); return; } + + if (cell->type.in(ID($_DFF_N_), ID($_DFF_P_))) + { port(ID::D,1); port(ID::Q,1); port(ID::C,1); check_expected(); return; } + + if (cell->type.in(ID($_DFFE_NN_), ID($_DFFE_NP_), ID($_DFFE_PN_), ID($_DFFE_PP_))) + { port(ID::D,1); port(ID::Q,1); port(ID::C,1); port(ID::E,1); check_expected(); return; } + + if (cell->type.in( + ID($_DFF_NN0_), ID($_DFF_NN1_), ID($_DFF_NP0_), ID($_DFF_NP1_), + ID($_DFF_PN0_), ID($_DFF_PN1_), ID($_DFF_PP0_), ID($_DFF_PP1_))) + { port(ID::D,1); port(ID::Q,1); port(ID::C,1); port(ID::R,1); check_expected(); return; } + + if (cell->type.in( + ID($_DFFE_NN0N_), ID($_DFFE_NN0P_), ID($_DFFE_NN1N_), ID($_DFFE_NN1P_), + ID($_DFFE_NP0N_), ID($_DFFE_NP0P_), ID($_DFFE_NP1N_), ID($_DFFE_NP1P_), + ID($_DFFE_PN0N_), ID($_DFFE_PN0P_), ID($_DFFE_PN1N_), ID($_DFFE_PN1P_), + ID($_DFFE_PP0N_), ID($_DFFE_PP0P_), ID($_DFFE_PP1N_), ID($_DFFE_PP1P_))) + { port(ID::D,1); port(ID::Q,1); port(ID::C,1); port(ID::R,1); port(ID::E,1); check_expected(); return; } + + if (cell->type.in( + ID($_DFFSR_NNN_), ID($_DFFSR_NNP_), ID($_DFFSR_NPN_), ID($_DFFSR_NPP_), + ID($_DFFSR_PNN_), ID($_DFFSR_PNP_), ID($_DFFSR_PPN_), ID($_DFFSR_PPP_))) + { port(ID::C,1); port(ID::S,1); port(ID::R,1); port(ID::D,1); port(ID::Q,1); check_expected(); return; } + + if (cell->type.in( + ID($_DFFSRE_NNNN_), ID($_DFFSRE_NNNP_), ID($_DFFSRE_NNPN_), ID($_DFFSRE_NNPP_), + ID($_DFFSRE_NPNN_), ID($_DFFSRE_NPNP_), ID($_DFFSRE_NPPN_), ID($_DFFSRE_NPPP_), + ID($_DFFSRE_PNNN_), ID($_DFFSRE_PNNP_), ID($_DFFSRE_PNPN_), ID($_DFFSRE_PNPP_), + ID($_DFFSRE_PPNN_), ID($_DFFSRE_PPNP_), ID($_DFFSRE_PPPN_), ID($_DFFSRE_PPPP_))) + { port(ID::C,1); port(ID::S,1); port(ID::R,1); port(ID::D,1); port(ID::E,1); port(ID::Q,1); check_expected(); return; } + + if (cell->type.in( + ID($_SDFF_NN0_), ID($_SDFF_NN1_), ID($_SDFF_NP0_), ID($_SDFF_NP1_), + ID($_SDFF_PN0_), ID($_SDFF_PN1_), ID($_SDFF_PP0_), ID($_SDFF_PP1_))) + { port(ID::D,1); port(ID::Q,1); port(ID::C,1); port(ID::R,1); check_expected(); return; } + + if (cell->type.in( + ID($_SDFFE_NN0N_), ID($_SDFFE_NN0P_), ID($_SDFFE_NN1N_), ID($_SDFFE_NN1P_), + ID($_SDFFE_NP0N_), ID($_SDFFE_NP0P_), ID($_SDFFE_NP1N_), ID($_SDFFE_NP1P_), + ID($_SDFFE_PN0N_), ID($_SDFFE_PN0P_), ID($_SDFFE_PN1N_), ID($_SDFFE_PN1P_), + ID($_SDFFE_PP0N_), ID($_SDFFE_PP0P_), ID($_SDFFE_PP1N_), ID($_SDFFE_PP1P_), + ID($_SDFFCE_NN0N_), ID($_SDFFCE_NN0P_), ID($_SDFFCE_NN1N_), ID($_SDFFCE_NN1P_), + ID($_SDFFCE_NP0N_), ID($_SDFFCE_NP0P_), ID($_SDFFCE_NP1N_), ID($_SDFFCE_NP1P_), + ID($_SDFFCE_PN0N_), ID($_SDFFCE_PN0P_), ID($_SDFFCE_PN1N_), ID($_SDFFCE_PN1P_), + ID($_SDFFCE_PP0N_), ID($_SDFFCE_PP0P_), ID($_SDFFCE_PP1N_), ID($_SDFFCE_PP1P_))) + { port(ID::D,1); port(ID::Q,1); port(ID::C,1); port(ID::R,1); port(ID::E,1); check_expected(); return; } + + if (cell->type.in(ID($_DLATCH_N_), ID($_DLATCH_P_))) + { port(ID::E,1); port(ID::D,1); port(ID::Q,1); check_expected(); return; } + + if (cell->type.in( + ID($_DLATCH_NN0_), ID($_DLATCH_NN1_), ID($_DLATCH_NP0_), ID($_DLATCH_NP1_), + ID($_DLATCH_PN0_), ID($_DLATCH_PN1_), ID($_DLATCH_PP0_), ID($_DLATCH_PP1_))) + { port(ID::E,1); port(ID::R,1); port(ID::D,1); port(ID::Q,1); check_expected(); return; } + + if (cell->type.in( + ID($_DLATCHSR_NNN_), ID($_DLATCHSR_NNP_), ID($_DLATCHSR_NPN_), ID($_DLATCHSR_NPP_), + ID($_DLATCHSR_PNN_), ID($_DLATCHSR_PNP_), ID($_DLATCHSR_PPN_), ID($_DLATCHSR_PPP_))) + { port(ID::E,1); port(ID::S,1); port(ID::R,1); port(ID::D,1); port(ID::Q,1); check_expected(); return; } error(__LINE__); } @@ -1520,13 +1713,13 @@ void RTLIL::Module::cloneInto(RTLIL::Module *new_mod) const new_mod->addWire(it.first, it.second); for (auto &it : memories) - new_mod->memories[it.first] = new RTLIL::Memory(*it.second); + new_mod->addMemory(it.first, it.second); for (auto &it : cells_) new_mod->addCell(it.first, it.second); for (auto &it : processes) - new_mod->processes[it.first] = it.second->clone(); + new_mod->addProcess(it.first, it.second); struct RewriteSigSpecWorker { @@ -1862,6 +2055,7 @@ RTLIL::Wire *RTLIL::Module::addWire(RTLIL::IdString name, const RTLIL::Wire *oth wire->port_input = other->port_input; wire->port_output = other->port_output; wire->upto = other->upto; + wire->is_signed = other->is_signed; wire->attributes = other->attributes; return wire; } @@ -1884,6 +2078,26 @@ RTLIL::Cell *RTLIL::Module::addCell(RTLIL::IdString name, const RTLIL::Cell *oth return cell; } +RTLIL::Memory *RTLIL::Module::addMemory(RTLIL::IdString name, const RTLIL::Memory *other) +{ + RTLIL::Memory *mem = new RTLIL::Memory; + mem->name = name; + mem->width = other->width; + mem->start_offset = other->start_offset; + mem->size = other->size; + mem->attributes = other->attributes; + memories[mem->name] = mem; + return mem; +} + +RTLIL::Process *RTLIL::Module::addProcess(RTLIL::IdString name, const RTLIL::Process *other) +{ + RTLIL::Process *proc = other->clone(); + proc->name = name; + processes[name] = proc; + return proc; +} + #define DEF_METHOD(_func, _y_size, _type) \ RTLIL::Cell* RTLIL::Module::add ## _func(RTLIL::IdString name, const RTLIL::SigSpec &sig_a, const RTLIL::SigSpec &sig_y, bool is_signed, const std::string &src) { \ RTLIL::Cell *cell = addCell(name, _type); \ @@ -1949,6 +2163,8 @@ DEF_METHOD(Sub, max(sig_a.size(), sig_b.size()), ID($sub)) DEF_METHOD(Mul, max(sig_a.size(), sig_b.size()), ID($mul)) DEF_METHOD(Div, max(sig_a.size(), sig_b.size()), ID($div)) DEF_METHOD(Mod, max(sig_a.size(), sig_b.size()), ID($mod)) +DEF_METHOD(DivFloor, max(sig_a.size(), sig_b.size()), ID($divfloor)) +DEF_METHOD(ModFloor, max(sig_a.size(), sig_b.size()), ID($modfloor)) DEF_METHOD(LogicAnd, 1, ID($logic_and)) DEF_METHOD(LogicOr, 1, ID($logic_or)) #undef DEF_METHOD @@ -2260,6 +2476,25 @@ RTLIL::Cell* RTLIL::Module::addDffsr(RTLIL::IdString name, const RTLIL::SigSpec return cell; } +RTLIL::Cell* RTLIL::Module::addDffsre(RTLIL::IdString name, const RTLIL::SigSpec &sig_clk, const RTLIL::SigSpec &sig_en, const RTLIL::SigSpec &sig_set, const RTLIL::SigSpec &sig_clr, + RTLIL::SigSpec sig_d, const RTLIL::SigSpec &sig_q, bool clk_polarity, bool en_polarity, bool set_polarity, bool clr_polarity, const std::string &src) +{ + RTLIL::Cell *cell = addCell(name, ID($dffsre)); + cell->parameters[ID::CLK_POLARITY] = clk_polarity; + cell->parameters[ID::EN_POLARITY] = en_polarity; + cell->parameters[ID::SET_POLARITY] = set_polarity; + cell->parameters[ID::CLR_POLARITY] = clr_polarity; + cell->parameters[ID::WIDTH] = sig_q.size(); + cell->setPort(ID::CLK, sig_clk); + cell->setPort(ID::EN, sig_en); + cell->setPort(ID::SET, sig_set); + cell->setPort(ID::CLR, sig_clr); + cell->setPort(ID::D, sig_d); + cell->setPort(ID::Q, sig_q); + cell->set_src_attribute(src); + return cell; +} + RTLIL::Cell* RTLIL::Module::addAdff(RTLIL::IdString name, const RTLIL::SigSpec &sig_clk, const RTLIL::SigSpec &sig_arst, const RTLIL::SigSpec &sig_d, const RTLIL::SigSpec &sig_q, RTLIL::Const arst_value, bool clk_polarity, bool arst_polarity, const std::string &src) { @@ -2276,6 +2511,76 @@ RTLIL::Cell* RTLIL::Module::addAdff(RTLIL::IdString name, const RTLIL::SigSpec & return cell; } +RTLIL::Cell* RTLIL::Module::addAdffe(RTLIL::IdString name, const RTLIL::SigSpec &sig_clk, const RTLIL::SigSpec &sig_en, const RTLIL::SigSpec &sig_arst, const RTLIL::SigSpec &sig_d, const RTLIL::SigSpec &sig_q, + RTLIL::Const arst_value, bool clk_polarity, bool en_polarity, bool arst_polarity, const std::string &src) +{ + RTLIL::Cell *cell = addCell(name, ID($adffe)); + cell->parameters[ID::CLK_POLARITY] = clk_polarity; + cell->parameters[ID::EN_POLARITY] = en_polarity; + cell->parameters[ID::ARST_POLARITY] = arst_polarity; + cell->parameters[ID::ARST_VALUE] = arst_value; + cell->parameters[ID::WIDTH] = sig_q.size(); + cell->setPort(ID::CLK, sig_clk); + cell->setPort(ID::EN, sig_en); + cell->setPort(ID::ARST, sig_arst); + cell->setPort(ID::D, sig_d); + cell->setPort(ID::Q, sig_q); + cell->set_src_attribute(src); + return cell; +} + +RTLIL::Cell* RTLIL::Module::addSdff(RTLIL::IdString name, const RTLIL::SigSpec &sig_clk, const RTLIL::SigSpec &sig_srst, const RTLIL::SigSpec &sig_d, const RTLIL::SigSpec &sig_q, + RTLIL::Const srst_value, bool clk_polarity, bool srst_polarity, const std::string &src) +{ + RTLIL::Cell *cell = addCell(name, ID($sdff)); + cell->parameters[ID::CLK_POLARITY] = clk_polarity; + cell->parameters[ID::SRST_POLARITY] = srst_polarity; + cell->parameters[ID::SRST_VALUE] = srst_value; + cell->parameters[ID::WIDTH] = sig_q.size(); + cell->setPort(ID::CLK, sig_clk); + cell->setPort(ID::SRST, sig_srst); + cell->setPort(ID::D, sig_d); + cell->setPort(ID::Q, sig_q); + cell->set_src_attribute(src); + return cell; +} + +RTLIL::Cell* RTLIL::Module::addSdffe(RTLIL::IdString name, const RTLIL::SigSpec &sig_clk, const RTLIL::SigSpec &sig_en, const RTLIL::SigSpec &sig_srst, const RTLIL::SigSpec &sig_d, const RTLIL::SigSpec &sig_q, + RTLIL::Const srst_value, bool clk_polarity, bool en_polarity, bool srst_polarity, const std::string &src) +{ + RTLIL::Cell *cell = addCell(name, ID($sdffe)); + cell->parameters[ID::CLK_POLARITY] = clk_polarity; + cell->parameters[ID::EN_POLARITY] = en_polarity; + cell->parameters[ID::SRST_POLARITY] = srst_polarity; + cell->parameters[ID::SRST_VALUE] = srst_value; + cell->parameters[ID::WIDTH] = sig_q.size(); + cell->setPort(ID::CLK, sig_clk); + cell->setPort(ID::EN, sig_en); + cell->setPort(ID::SRST, sig_srst); + cell->setPort(ID::D, sig_d); + cell->setPort(ID::Q, sig_q); + cell->set_src_attribute(src); + return cell; +} + +RTLIL::Cell* RTLIL::Module::addSdffce(RTLIL::IdString name, const RTLIL::SigSpec &sig_clk, const RTLIL::SigSpec &sig_en, const RTLIL::SigSpec &sig_srst, const RTLIL::SigSpec &sig_d, const RTLIL::SigSpec &sig_q, + RTLIL::Const srst_value, bool clk_polarity, bool en_polarity, bool srst_polarity, const std::string &src) +{ + RTLIL::Cell *cell = addCell(name, ID($sdffce)); + cell->parameters[ID::CLK_POLARITY] = clk_polarity; + cell->parameters[ID::EN_POLARITY] = en_polarity; + cell->parameters[ID::SRST_POLARITY] = srst_polarity; + cell->parameters[ID::SRST_VALUE] = srst_value; + cell->parameters[ID::WIDTH] = sig_q.size(); + cell->setPort(ID::CLK, sig_clk); + cell->setPort(ID::EN, sig_en); + cell->setPort(ID::SRST, sig_srst); + cell->setPort(ID::D, sig_d); + cell->setPort(ID::Q, sig_q); + cell->set_src_attribute(src); + return cell; +} + RTLIL::Cell* RTLIL::Module::addDlatch(RTLIL::IdString name, const RTLIL::SigSpec &sig_en, const RTLIL::SigSpec &sig_d, const RTLIL::SigSpec &sig_q, bool en_polarity, const std::string &src) { RTLIL::Cell *cell = addCell(name, ID($dlatch)); @@ -2288,6 +2593,22 @@ RTLIL::Cell* RTLIL::Module::addDlatch(RTLIL::IdString name, const RTLIL::SigSpec return cell; } +RTLIL::Cell* RTLIL::Module::addAdlatch(RTLIL::IdString name, const RTLIL::SigSpec &sig_en, const RTLIL::SigSpec &sig_arst, const RTLIL::SigSpec &sig_d, const RTLIL::SigSpec &sig_q, + RTLIL::Const arst_value, bool en_polarity, bool arst_polarity, const std::string &src) +{ + RTLIL::Cell *cell = addCell(name, ID($adlatch)); + cell->parameters[ID::EN_POLARITY] = en_polarity; + cell->parameters[ID::ARST_POLARITY] = arst_polarity; + cell->parameters[ID::ARST_VALUE] = arst_value; + cell->parameters[ID::WIDTH] = sig_q.size(); + cell->setPort(ID::EN, sig_en); + cell->setPort(ID::ARST, sig_arst); + cell->setPort(ID::D, sig_d); + cell->setPort(ID::Q, sig_q); + cell->set_src_attribute(src); + return cell; +} + RTLIL::Cell* RTLIL::Module::addDlatchsr(RTLIL::IdString name, const RTLIL::SigSpec &sig_en, const RTLIL::SigSpec &sig_set, const RTLIL::SigSpec &sig_clr, RTLIL::SigSpec sig_d, const RTLIL::SigSpec &sig_q, bool en_polarity, bool set_polarity, bool clr_polarity, const std::string &src) { @@ -2305,6 +2626,17 @@ RTLIL::Cell* RTLIL::Module::addDlatchsr(RTLIL::IdString name, const RTLIL::SigSp return cell; } +RTLIL::Cell* RTLIL::Module::addSrGate(RTLIL::IdString name, const RTLIL::SigSpec &sig_set, const RTLIL::SigSpec &sig_clr, + const RTLIL::SigSpec &sig_q, bool set_polarity, bool clr_polarity, const std::string &src) +{ + RTLIL::Cell *cell = addCell(name, stringf("$_SR_%c%c_", set_polarity ? 'P' : 'N', clr_polarity ? 'P' : 'N')); + cell->setPort(ID::S, sig_set); + cell->setPort(ID::R, sig_clr); + cell->setPort(ID::Q, sig_q); + cell->set_src_attribute(src); + return cell; +} + RTLIL::Cell* RTLIL::Module::addFfGate(RTLIL::IdString name, const RTLIL::SigSpec &sig_d, const RTLIL::SigSpec &sig_q, const std::string &src) { RTLIL::Cell *cell = addCell(name, ID($_FF_)); @@ -2348,6 +2680,20 @@ RTLIL::Cell* RTLIL::Module::addDffsrGate(RTLIL::IdString name, const RTLIL::SigS return cell; } +RTLIL::Cell* RTLIL::Module::addDffsreGate(RTLIL::IdString name, const RTLIL::SigSpec &sig_clk, const RTLIL::SigSpec &sig_en, const RTLIL::SigSpec &sig_set, const RTLIL::SigSpec &sig_clr, + RTLIL::SigSpec sig_d, const RTLIL::SigSpec &sig_q, bool clk_polarity, bool en_polarity, bool set_polarity, bool clr_polarity, const std::string &src) +{ + RTLIL::Cell *cell = addCell(name, stringf("$_DFFSRE_%c%c%c%c_", clk_polarity ? 'P' : 'N', set_polarity ? 'P' : 'N', clr_polarity ? 'P' : 'N', en_polarity ? 'P' : 'N')); + cell->setPort(ID::C, sig_clk); + cell->setPort(ID::S, sig_set); + cell->setPort(ID::R, sig_clr); + cell->setPort(ID::E, sig_en); + cell->setPort(ID::D, sig_d); + cell->setPort(ID::Q, sig_q); + cell->set_src_attribute(src); + return cell; +} + RTLIL::Cell* RTLIL::Module::addAdffGate(RTLIL::IdString name, const RTLIL::SigSpec &sig_clk, const RTLIL::SigSpec &sig_arst, const RTLIL::SigSpec &sig_d, const RTLIL::SigSpec &sig_q, bool arst_value, bool clk_polarity, bool arst_polarity, const std::string &src) { @@ -2360,6 +2706,57 @@ RTLIL::Cell* RTLIL::Module::addAdffGate(RTLIL::IdString name, const RTLIL::SigSp return cell; } +RTLIL::Cell* RTLIL::Module::addAdffeGate(RTLIL::IdString name, const RTLIL::SigSpec &sig_clk, const RTLIL::SigSpec &sig_en, const RTLIL::SigSpec &sig_arst, const RTLIL::SigSpec &sig_d, const RTLIL::SigSpec &sig_q, + bool arst_value, bool clk_polarity, bool en_polarity, bool arst_polarity, const std::string &src) +{ + RTLIL::Cell *cell = addCell(name, stringf("$_DFFE_%c%c%c%c_", clk_polarity ? 'P' : 'N', arst_polarity ? 'P' : 'N', arst_value ? '1' : '0', en_polarity ? 'P' : 'N')); + cell->setPort(ID::C, sig_clk); + cell->setPort(ID::R, sig_arst); + cell->setPort(ID::E, sig_en); + cell->setPort(ID::D, sig_d); + cell->setPort(ID::Q, sig_q); + cell->set_src_attribute(src); + return cell; +} + +RTLIL::Cell* RTLIL::Module::addSdffGate(RTLIL::IdString name, const RTLIL::SigSpec &sig_clk, const RTLIL::SigSpec &sig_srst, const RTLIL::SigSpec &sig_d, const RTLIL::SigSpec &sig_q, + bool srst_value, bool clk_polarity, bool srst_polarity, const std::string &src) +{ + RTLIL::Cell *cell = addCell(name, stringf("$_SDFF_%c%c%c_", clk_polarity ? 'P' : 'N', srst_polarity ? 'P' : 'N', srst_value ? '1' : '0')); + cell->setPort(ID::C, sig_clk); + cell->setPort(ID::R, sig_srst); + cell->setPort(ID::D, sig_d); + cell->setPort(ID::Q, sig_q); + cell->set_src_attribute(src); + return cell; +} + +RTLIL::Cell* RTLIL::Module::addSdffeGate(RTLIL::IdString name, const RTLIL::SigSpec &sig_clk, const RTLIL::SigSpec &sig_en, const RTLIL::SigSpec &sig_srst, const RTLIL::SigSpec &sig_d, const RTLIL::SigSpec &sig_q, + bool srst_value, bool clk_polarity, bool en_polarity, bool srst_polarity, const std::string &src) +{ + RTLIL::Cell *cell = addCell(name, stringf("$_SDFFE_%c%c%c%c_", clk_polarity ? 'P' : 'N', srst_polarity ? 'P' : 'N', srst_value ? '1' : '0', en_polarity ? 'P' : 'N')); + cell->setPort(ID::C, sig_clk); + cell->setPort(ID::R, sig_srst); + cell->setPort(ID::E, sig_en); + cell->setPort(ID::D, sig_d); + cell->setPort(ID::Q, sig_q); + cell->set_src_attribute(src); + return cell; +} + +RTLIL::Cell* RTLIL::Module::addSdffceGate(RTLIL::IdString name, const RTLIL::SigSpec &sig_clk, const RTLIL::SigSpec &sig_en, const RTLIL::SigSpec &sig_srst, const RTLIL::SigSpec &sig_d, const RTLIL::SigSpec &sig_q, + bool srst_value, bool clk_polarity, bool en_polarity, bool srst_polarity, const std::string &src) +{ + RTLIL::Cell *cell = addCell(name, stringf("$_SDFFCE_%c%c%c%c_", clk_polarity ? 'P' : 'N', srst_polarity ? 'P' : 'N', srst_value ? '1' : '0', en_polarity ? 'P' : 'N')); + cell->setPort(ID::C, sig_clk); + cell->setPort(ID::R, sig_srst); + cell->setPort(ID::E, sig_en); + cell->setPort(ID::D, sig_d); + cell->setPort(ID::Q, sig_q); + cell->set_src_attribute(src); + return cell; +} + RTLIL::Cell* RTLIL::Module::addDlatchGate(RTLIL::IdString name, const RTLIL::SigSpec &sig_en, const RTLIL::SigSpec &sig_d, const RTLIL::SigSpec &sig_q, bool en_polarity, const std::string &src) { RTLIL::Cell *cell = addCell(name, stringf("$_DLATCH_%c_", en_polarity ? 'P' : 'N')); @@ -2370,6 +2767,18 @@ RTLIL::Cell* RTLIL::Module::addDlatchGate(RTLIL::IdString name, const RTLIL::Sig return cell; } +RTLIL::Cell* RTLIL::Module::addAdlatchGate(RTLIL::IdString name, const RTLIL::SigSpec &sig_en, const RTLIL::SigSpec &sig_arst, const RTLIL::SigSpec &sig_d, const RTLIL::SigSpec &sig_q, + bool arst_value, bool en_polarity, bool arst_polarity, const std::string &src) +{ + RTLIL::Cell *cell = addCell(name, stringf("$_DLATCH_%c%c%c_", en_polarity ? 'P' : 'N', arst_polarity ? 'P' : 'N', arst_value ? '1' : '0')); + cell->setPort(ID::E, sig_en); + cell->setPort(ID::R, sig_arst); + cell->setPort(ID::D, sig_d); + cell->setPort(ID::Q, sig_q); + cell->set_src_attribute(src); + return cell; +} + RTLIL::Cell* RTLIL::Module::addDlatchsrGate(RTLIL::IdString name, const RTLIL::SigSpec &sig_en, const RTLIL::SigSpec &sig_set, const RTLIL::SigSpec &sig_clr, RTLIL::SigSpec sig_d, const RTLIL::SigSpec &sig_q, bool en_polarity, bool set_polarity, bool clr_polarity, const std::string &src) { @@ -2445,6 +2854,7 @@ RTLIL::Wire::Wire() port_input = false; port_output = false; upto = false; + is_signed = false; #ifdef WITH_PYTHON RTLIL::Wire::get_all_wires()->insert(std::pair<unsigned int, RTLIL::Wire*>(hashidx_, this)); diff --git a/kernel/rtlil.h b/kernel/rtlil.h index 11c45bbec..6c561cb85 100644 --- a/kernel/rtlil.h +++ b/kernel/rtlil.h @@ -150,9 +150,6 @@ namespace RTLIL if (!p[0]) return 0; - log_assert(p[0] == '$' || p[0] == '\\'); - log_assert(p[1] != 0); - auto it = global_id_index_.find((char*)p); if (it != global_id_index_.end()) { #ifndef YOSYS_NO_IDS_REFCNT @@ -165,6 +162,11 @@ namespace RTLIL return it->second; } + log_assert(p[0] == '$' || p[0] == '\\'); + log_assert(p[1] != 0); + for (const char *c = p; *c; c++) + log_assert((unsigned)*c > (unsigned)' '); + #ifndef YOSYS_NO_IDS_REFCNT if (global_free_idx_list_.empty()) { if (global_id_storage_.empty()) { @@ -296,8 +298,8 @@ namespace RTLIL // The methods below are just convenience functions for better compatibility with std::string. - bool operator==(const std::string &rhs) const { return str() == rhs; } - bool operator!=(const std::string &rhs) const { return str() != rhs; } + bool operator==(const std::string &rhs) const { return c_str() == rhs; } + bool operator!=(const std::string &rhs) const { return c_str() != rhs; } bool operator==(const char *rhs) const { return strcmp(c_str(), rhs) == 0; } bool operator!=(const char *rhs) const { return strcmp(c_str(), rhs) != 0; } @@ -466,6 +468,8 @@ namespace RTLIL RTLIL::Const const_sub (const RTLIL::Const &arg1, const RTLIL::Const &arg2, bool signed1, bool signed2, int result_len); RTLIL::Const const_mul (const RTLIL::Const &arg1, const RTLIL::Const &arg2, bool signed1, bool signed2, int result_len); RTLIL::Const const_div (const RTLIL::Const &arg1, const RTLIL::Const &arg2, bool signed1, bool signed2, int result_len); + RTLIL::Const const_divfloor (const RTLIL::Const &arg1, const RTLIL::Const &arg2, bool signed1, bool signed2, int result_len); + RTLIL::Const const_modfloor (const RTLIL::Const &arg1, const RTLIL::Const &arg2, bool signed1, bool signed2, int result_len); RTLIL::Const const_mod (const RTLIL::Const &arg1, const RTLIL::Const &arg2, bool signed1, bool signed2, int result_len); RTLIL::Const const_pow (const RTLIL::Const &arg1, const RTLIL::Const &arg2, bool signed1, bool signed2, int result_len); @@ -550,6 +554,29 @@ namespace RTLIL return *this; } + inline ObjIterator<T>& operator+=(int amt) { + log_assert(list_p != nullptr); + it += amt; + if (it == list_p->end()) { + (*refcount_p)--; + list_p = nullptr; + refcount_p = nullptr; + } + return *this; + } + + inline ObjIterator<T> operator+(int amt) { + log_assert(list_p != nullptr); + ObjIterator<T> new_obj(*this); + new_obj.it += amt; + if (new_obj.it == list_p->end()) { + (*(new_obj.refcount_p))--; + new_obj.list_p = nullptr; + new_obj.refcount_p = nullptr; + } + return new_obj; + } + inline const ObjIterator<T> operator++(int) { ObjIterator<T> result(*this); ++(*this); @@ -678,6 +705,9 @@ struct RTLIL::AttrObject std::string get_src_attribute() const { return get_string_attribute(ID::src); } + + void set_hdlname_attribute(const vector<string> &hierarchy); + vector<string> get_hdlname_attribute() const; }; struct RTLIL::SigChunk @@ -721,7 +751,7 @@ struct RTLIL::SigBit SigBit(const RTLIL::SigChunk &chunk); SigBit(const RTLIL::SigChunk &chunk, int index); SigBit(const RTLIL::SigSpec &sig); - SigBit(const RTLIL::SigBit &sigbit); + SigBit(const RTLIL::SigBit &sigbit) = default; RTLIL::SigBit &operator =(const RTLIL::SigBit &other) = default; bool operator <(const RTLIL::SigBit &other) const; @@ -1054,6 +1084,13 @@ struct RTLIL::Design return selected_member(module->name, member->name); } + template<typename T1> void select(T1 *module) { + if (selection_stack.size() > 0) { + RTLIL::Selection &sel = selection_stack.back(); + sel.select(module); + } + } + template<typename T1, typename T2> void select(T1 *module, T2 *member) { if (selection_stack.size() > 0) { RTLIL::Selection &sel = selection_stack.back(); @@ -1134,8 +1171,14 @@ public: return design->selected_member(name, member->name); } - RTLIL::Wire* wire(RTLIL::IdString id) { return wires_.count(id) ? wires_.at(id) : nullptr; } - RTLIL::Cell* cell(RTLIL::IdString id) { return cells_.count(id) ? cells_.at(id) : nullptr; } + RTLIL::Wire* wire(RTLIL::IdString id) { + auto it = wires_.find(id); + return it == wires_.end() ? nullptr : it->second; + } + RTLIL::Cell* cell(RTLIL::IdString id) { + auto it = cells_.find(id); + return it == cells_.end() ? nullptr : it->second; + } RTLIL::ObjRange<RTLIL::Wire*> wires() { return RTLIL::ObjRange<RTLIL::Wire*>(&wires_, &refcount_wires_); } RTLIL::ObjRange<RTLIL::Cell*> cells() { return RTLIL::ObjRange<RTLIL::Cell*>(&cells_, &refcount_cells_); } @@ -1160,6 +1203,10 @@ public: RTLIL::Cell *addCell(RTLIL::IdString name, RTLIL::IdString type); RTLIL::Cell *addCell(RTLIL::IdString name, const RTLIL::Cell *other); + RTLIL::Memory *addMemory(RTLIL::IdString name, const RTLIL::Memory *other); + + RTLIL::Process *addProcess(RTLIL::IdString name, const RTLIL::Process *other); + // The add* methods create a cell and return the created cell. All signals must exist in advance. RTLIL::Cell* addNot (RTLIL::IdString name, const RTLIL::SigSpec &sig_a, const RTLIL::SigSpec &sig_y, bool is_signed = false, const std::string &src = ""); @@ -1196,8 +1243,12 @@ public: RTLIL::Cell* addAdd (RTLIL::IdString name, const RTLIL::SigSpec &sig_a, const RTLIL::SigSpec &sig_b, const RTLIL::SigSpec &sig_y, bool is_signed = false, const std::string &src = ""); RTLIL::Cell* addSub (RTLIL::IdString name, const RTLIL::SigSpec &sig_a, const RTLIL::SigSpec &sig_b, const RTLIL::SigSpec &sig_y, bool is_signed = false, const std::string &src = ""); RTLIL::Cell* addMul (RTLIL::IdString name, const RTLIL::SigSpec &sig_a, const RTLIL::SigSpec &sig_b, const RTLIL::SigSpec &sig_y, bool is_signed = false, const std::string &src = ""); + // truncating division RTLIL::Cell* addDiv (RTLIL::IdString name, const RTLIL::SigSpec &sig_a, const RTLIL::SigSpec &sig_b, const RTLIL::SigSpec &sig_y, bool is_signed = false, const std::string &src = ""); + // truncating modulo RTLIL::Cell* addMod (RTLIL::IdString name, const RTLIL::SigSpec &sig_a, const RTLIL::SigSpec &sig_b, const RTLIL::SigSpec &sig_y, bool is_signed = false, const std::string &src = ""); + RTLIL::Cell* addDivFloor (RTLIL::IdString name, const RTLIL::SigSpec &sig_a, const RTLIL::SigSpec &sig_b, const RTLIL::SigSpec &sig_y, bool is_signed = false, const std::string &src = ""); + RTLIL::Cell* addModFloor (RTLIL::IdString name, const RTLIL::SigSpec &sig_a, const RTLIL::SigSpec &sig_b, const RTLIL::SigSpec &sig_y, bool is_signed = false, const std::string &src = ""); RTLIL::Cell* addPow (RTLIL::IdString name, const RTLIL::SigSpec &sig_a, const RTLIL::SigSpec &sig_b, const RTLIL::SigSpec &sig_y, bool a_signed = false, bool b_signed = false, const std::string &src = ""); RTLIL::Cell* addLogicNot (RTLIL::IdString name, const RTLIL::SigSpec &sig_a, const RTLIL::SigSpec &sig_y, bool is_signed = false, const std::string &src = ""); @@ -1222,13 +1273,16 @@ public: RTLIL::Cell* addFf (RTLIL::IdString name, const RTLIL::SigSpec &sig_d, const RTLIL::SigSpec &sig_q, const std::string &src = ""); RTLIL::Cell* addDff (RTLIL::IdString name, const RTLIL::SigSpec &sig_clk, const RTLIL::SigSpec &sig_d, const RTLIL::SigSpec &sig_q, bool clk_polarity = true, const std::string &src = ""); RTLIL::Cell* addDffe (RTLIL::IdString name, const RTLIL::SigSpec &sig_clk, const RTLIL::SigSpec &sig_en, const RTLIL::SigSpec &sig_d, const RTLIL::SigSpec &sig_q, bool clk_polarity = true, bool en_polarity = true, const std::string &src = ""); - RTLIL::Cell* addDffsr (RTLIL::IdString name, const RTLIL::SigSpec &sig_clk, const RTLIL::SigSpec &sig_set, const RTLIL::SigSpec &sig_clr, - RTLIL::SigSpec sig_d, const RTLIL::SigSpec &sig_q, bool clk_polarity = true, bool set_polarity = true, bool clr_polarity = true, const std::string &src = ""); - RTLIL::Cell* addAdff (RTLIL::IdString name, const RTLIL::SigSpec &sig_clk, const RTLIL::SigSpec &sig_arst, const RTLIL::SigSpec &sig_d, const RTLIL::SigSpec &sig_q, - RTLIL::Const arst_value, bool clk_polarity = true, bool arst_polarity = true, const std::string &src = ""); + RTLIL::Cell* addDffsr (RTLIL::IdString name, const RTLIL::SigSpec &sig_clk, const RTLIL::SigSpec &sig_set, const RTLIL::SigSpec &sig_clr, RTLIL::SigSpec sig_d, const RTLIL::SigSpec &sig_q, bool clk_polarity = true, bool set_polarity = true, bool clr_polarity = true, const std::string &src = ""); + RTLIL::Cell* addDffsre (RTLIL::IdString name, const RTLIL::SigSpec &sig_clk, const RTLIL::SigSpec &sig_en, const RTLIL::SigSpec &sig_set, const RTLIL::SigSpec &sig_clr, RTLIL::SigSpec sig_d, const RTLIL::SigSpec &sig_q, bool clk_polarity = true, bool en_polarity = true, bool set_polarity = true, bool clr_polarity = true, const std::string &src = ""); + RTLIL::Cell* addAdff (RTLIL::IdString name, const RTLIL::SigSpec &sig_clk, const RTLIL::SigSpec &sig_arst, const RTLIL::SigSpec &sig_d, const RTLIL::SigSpec &sig_q, RTLIL::Const arst_value, bool clk_polarity = true, bool arst_polarity = true, const std::string &src = ""); + RTLIL::Cell* addAdffe (RTLIL::IdString name, const RTLIL::SigSpec &sig_clk, const RTLIL::SigSpec &sig_en, const RTLIL::SigSpec &sig_arst, const RTLIL::SigSpec &sig_d, const RTLIL::SigSpec &sig_q, RTLIL::Const arst_value, bool clk_polarity = true, bool en_polarity = true, bool arst_polarity = true, const std::string &src = ""); + RTLIL::Cell* addSdff (RTLIL::IdString name, const RTLIL::SigSpec &sig_clk, const RTLIL::SigSpec &sig_srst, const RTLIL::SigSpec &sig_d, const RTLIL::SigSpec &sig_q, RTLIL::Const srst_value, bool clk_polarity = true, bool srst_polarity = true, const std::string &src = ""); + RTLIL::Cell* addSdffe (RTLIL::IdString name, const RTLIL::SigSpec &sig_clk, const RTLIL::SigSpec &sig_en, const RTLIL::SigSpec &sig_srst, const RTLIL::SigSpec &sig_d, const RTLIL::SigSpec &sig_q, RTLIL::Const srst_value, bool clk_polarity = true, bool en_polarity = true, bool srst_polarity = true, const std::string &src = ""); + RTLIL::Cell* addSdffce (RTLIL::IdString name, const RTLIL::SigSpec &sig_clk, const RTLIL::SigSpec &sig_en, const RTLIL::SigSpec &sig_srst, const RTLIL::SigSpec &sig_d, const RTLIL::SigSpec &sig_q, RTLIL::Const srst_value, bool clk_polarity = true, bool en_polarity = true, bool srst_polarity = true, const std::string &src = ""); RTLIL::Cell* addDlatch (RTLIL::IdString name, const RTLIL::SigSpec &sig_en, const RTLIL::SigSpec &sig_d, const RTLIL::SigSpec &sig_q, bool en_polarity = true, const std::string &src = ""); - RTLIL::Cell* addDlatchsr (RTLIL::IdString name, const RTLIL::SigSpec &sig_en, const RTLIL::SigSpec &sig_set, const RTLIL::SigSpec &sig_clr, - RTLIL::SigSpec sig_d, const RTLIL::SigSpec &sig_q, bool en_polarity = true, bool set_polarity = true, bool clr_polarity = true, const std::string &src = ""); + RTLIL::Cell* addAdlatch (RTLIL::IdString name, const RTLIL::SigSpec &sig_en, const RTLIL::SigSpec &sig_arst, const RTLIL::SigSpec &sig_d, const RTLIL::SigSpec &sig_q, RTLIL::Const arst_value, bool en_polarity = true, bool arst_polarity = true, const std::string &src = ""); + RTLIL::Cell* addDlatchsr (RTLIL::IdString name, const RTLIL::SigSpec &sig_en, const RTLIL::SigSpec &sig_set, const RTLIL::SigSpec &sig_clr, RTLIL::SigSpec sig_d, const RTLIL::SigSpec &sig_q, bool en_polarity = true, bool set_polarity = true, bool clr_polarity = true, const std::string &src = ""); RTLIL::Cell* addBufGate (RTLIL::IdString name, const RTLIL::SigBit &sig_a, const RTLIL::SigBit &sig_y, const std::string &src = ""); RTLIL::Cell* addNotGate (RTLIL::IdString name, const RTLIL::SigBit &sig_a, const RTLIL::SigBit &sig_y, const std::string &src = ""); @@ -1247,14 +1301,28 @@ public: RTLIL::Cell* addAoi4Gate (RTLIL::IdString name, const RTLIL::SigBit &sig_a, const RTLIL::SigBit &sig_b, const RTLIL::SigBit &sig_c, const RTLIL::SigBit &sig_d, const RTLIL::SigBit &sig_y, const std::string &src = ""); RTLIL::Cell* addOai4Gate (RTLIL::IdString name, const RTLIL::SigBit &sig_a, const RTLIL::SigBit &sig_b, const RTLIL::SigBit &sig_c, const RTLIL::SigBit &sig_d, const RTLIL::SigBit &sig_y, const std::string &src = ""); + RTLIL::Cell* addSrGate (RTLIL::IdString name, const RTLIL::SigSpec &sig_set, const RTLIL::SigSpec &sig_clr, + const RTLIL::SigSpec &sig_q, bool set_polarity = true, bool clr_polarity = true, const std::string &src = ""); RTLIL::Cell* addFfGate (RTLIL::IdString name, const RTLIL::SigSpec &sig_d, const RTLIL::SigSpec &sig_q, const std::string &src = ""); RTLIL::Cell* addDffGate (RTLIL::IdString name, const RTLIL::SigSpec &sig_clk, const RTLIL::SigSpec &sig_d, const RTLIL::SigSpec &sig_q, bool clk_polarity = true, const std::string &src = ""); RTLIL::Cell* addDffeGate (RTLIL::IdString name, const RTLIL::SigSpec &sig_clk, const RTLIL::SigSpec &sig_en, const RTLIL::SigSpec &sig_d, const RTLIL::SigSpec &sig_q, bool clk_polarity = true, bool en_polarity = true, const std::string &src = ""); RTLIL::Cell* addDffsrGate (RTLIL::IdString name, const RTLIL::SigSpec &sig_clk, const RTLIL::SigSpec &sig_set, const RTLIL::SigSpec &sig_clr, RTLIL::SigSpec sig_d, const RTLIL::SigSpec &sig_q, bool clk_polarity = true, bool set_polarity = true, bool clr_polarity = true, const std::string &src = ""); + RTLIL::Cell* addDffsreGate (RTLIL::IdString name, const RTLIL::SigSpec &sig_clk, const RTLIL::SigSpec &sig_en, const RTLIL::SigSpec &sig_set, const RTLIL::SigSpec &sig_clr, + RTLIL::SigSpec sig_d, const RTLIL::SigSpec &sig_q, bool clk_polarity = true, bool en_polarity = true, bool set_polarity = true, bool clr_polarity = true, const std::string &src = ""); RTLIL::Cell* addAdffGate (RTLIL::IdString name, const RTLIL::SigSpec &sig_clk, const RTLIL::SigSpec &sig_arst, const RTLIL::SigSpec &sig_d, const RTLIL::SigSpec &sig_q, bool arst_value = false, bool clk_polarity = true, bool arst_polarity = true, const std::string &src = ""); + RTLIL::Cell* addAdffeGate (RTLIL::IdString name, const RTLIL::SigSpec &sig_clk, const RTLIL::SigSpec &sig_en, const RTLIL::SigSpec &sig_arst, const RTLIL::SigSpec &sig_d, const RTLIL::SigSpec &sig_q, + bool arst_value = false, bool clk_polarity = true, bool en_polarity = true, bool arst_polarity = true, const std::string &src = ""); + RTLIL::Cell* addSdffGate (RTLIL::IdString name, const RTLIL::SigSpec &sig_clk, const RTLIL::SigSpec &sig_srst, const RTLIL::SigSpec &sig_d, const RTLIL::SigSpec &sig_q, + bool srst_value = false, bool clk_polarity = true, bool srst_polarity = true, const std::string &src = ""); + RTLIL::Cell* addSdffeGate (RTLIL::IdString name, const RTLIL::SigSpec &sig_clk, const RTLIL::SigSpec &sig_en, const RTLIL::SigSpec &sig_srst, const RTLIL::SigSpec &sig_d, const RTLIL::SigSpec &sig_q, + bool srst_value = false, bool clk_polarity = true, bool en_polarity = true, bool srst_polarity = true, const std::string &src = ""); + RTLIL::Cell* addSdffceGate (RTLIL::IdString name, const RTLIL::SigSpec &sig_clk, const RTLIL::SigSpec &sig_en, const RTLIL::SigSpec &sig_srst, const RTLIL::SigSpec &sig_d, const RTLIL::SigSpec &sig_q, + bool srst_value = false, bool clk_polarity = true, bool en_polarity = true, bool srst_polarity = true, const std::string &src = ""); RTLIL::Cell* addDlatchGate (RTLIL::IdString name, const RTLIL::SigSpec &sig_en, const RTLIL::SigSpec &sig_d, const RTLIL::SigSpec &sig_q, bool en_polarity = true, const std::string &src = ""); + RTLIL::Cell* addAdlatchGate(RTLIL::IdString name, const RTLIL::SigSpec &sig_en, const RTLIL::SigSpec &sig_arst, const RTLIL::SigSpec &sig_d, const RTLIL::SigSpec &sig_q, + bool arst_value = false, bool en_polarity = true, bool arst_polarity = true, const std::string &src = ""); RTLIL::Cell* addDlatchsrGate (RTLIL::IdString name, const RTLIL::SigSpec &sig_en, const RTLIL::SigSpec &sig_set, const RTLIL::SigSpec &sig_clr, RTLIL::SigSpec sig_d, const RTLIL::SigSpec &sig_q, bool en_polarity = true, bool set_polarity = true, bool clr_polarity = true, const std::string &src = ""); @@ -1295,8 +1363,12 @@ public: RTLIL::SigSpec Add (RTLIL::IdString name, const RTLIL::SigSpec &sig_a, const RTLIL::SigSpec &sig_b, bool is_signed = false, const std::string &src = ""); RTLIL::SigSpec Sub (RTLIL::IdString name, const RTLIL::SigSpec &sig_a, const RTLIL::SigSpec &sig_b, bool is_signed = false, const std::string &src = ""); RTLIL::SigSpec Mul (RTLIL::IdString name, const RTLIL::SigSpec &sig_a, const RTLIL::SigSpec &sig_b, bool is_signed = false, const std::string &src = ""); + // truncating division RTLIL::SigSpec Div (RTLIL::IdString name, const RTLIL::SigSpec &sig_a, const RTLIL::SigSpec &sig_b, bool is_signed = false, const std::string &src = ""); + // truncating modulo RTLIL::SigSpec Mod (RTLIL::IdString name, const RTLIL::SigSpec &sig_a, const RTLIL::SigSpec &sig_b, bool is_signed = false, const std::string &src = ""); + RTLIL::SigSpec DivFloor (RTLIL::IdString name, const RTLIL::SigSpec &sig_a, const RTLIL::SigSpec &sig_b, bool is_signed = false, const std::string &src = ""); + RTLIL::SigSpec ModFloor (RTLIL::IdString name, const RTLIL::SigSpec &sig_a, const RTLIL::SigSpec &sig_b, bool is_signed = false, const std::string &src = ""); RTLIL::SigSpec Pow (RTLIL::IdString name, const RTLIL::SigSpec &sig_a, const RTLIL::SigSpec &sig_b, bool a_signed = false, bool b_signed = false, const std::string &src = ""); RTLIL::SigSpec LogicNot (RTLIL::IdString name, const RTLIL::SigSpec &sig_a, bool is_signed = false, const std::string &src = ""); @@ -1353,7 +1425,7 @@ public: RTLIL::Module *module; RTLIL::IdString name; int width, start_offset, port_id; - bool port_input, port_output, upto; + bool port_input, port_output, upto, is_signed; #ifdef WITH_PYTHON static std::map<unsigned int, RTLIL::Wire*> *get_all_wires(void); @@ -1494,7 +1566,6 @@ inline RTLIL::SigBit::SigBit(RTLIL::Wire *wire) : wire(wire), offset(0) { log_as inline RTLIL::SigBit::SigBit(RTLIL::Wire *wire, int offset) : wire(wire), offset(offset) { log_assert(wire != nullptr); } inline RTLIL::SigBit::SigBit(const RTLIL::SigChunk &chunk) : wire(chunk.wire) { log_assert(chunk.width == 1); if (wire) offset = chunk.offset; else data = chunk.data[0]; } inline RTLIL::SigBit::SigBit(const RTLIL::SigChunk &chunk, int index) : wire(chunk.wire) { if (wire) offset = chunk.offset + index; else data = chunk.data[index]; } -inline RTLIL::SigBit::SigBit(const RTLIL::SigBit &sigbit) : wire(sigbit.wire), data(sigbit.data){ if (wire) offset = sigbit.offset; } inline bool RTLIL::SigBit::operator<(const RTLIL::SigBit &other) const { if (wire == other.wire) diff --git a/kernel/satgen.h b/kernel/satgen.h index 88b84b7e6..3929a8708 100644 --- a/kernel/satgen.h +++ b/kernel/satgen.h @@ -279,7 +279,7 @@ struct SatGen bool arith_undef_handled = false; bool is_arith_compare = cell->type.in(ID($lt), ID($le), ID($ge), ID($gt)); - if (model_undef && (cell->type.in(ID($add), ID($sub), ID($mul), ID($div), ID($mod)) || is_arith_compare)) + if (model_undef && (cell->type.in(ID($add), ID($sub), ID($mul), ID($div), ID($mod), ID($divfloor), ID($modfloor)) || is_arith_compare)) { std::vector<int> undef_a = importUndefSigSpec(cell->getPort(ID::A), timestep); std::vector<int> undef_b = importUndefSigSpec(cell->getPort(ID::B), timestep); @@ -293,7 +293,7 @@ struct SatGen int undef_any_b = ez->expression(ezSAT::OpOr, undef_b); int undef_y_bit = ez->OR(undef_any_a, undef_any_b); - if (cell->type.in(ID($div), ID($mod))) { + if (cell->type.in(ID($div), ID($mod), ID($divfloor), ID($modfloor))) { std::vector<int> b = importSigSpec(cell->getPort(ID::B), timestep); undef_y_bit = ez->OR(undef_y_bit, ez->NOT(ez->expression(ezSAT::OpOr, b))); } @@ -935,7 +935,7 @@ struct SatGen return true; } - if (cell->type.in(ID($div), ID($mod))) + if (cell->type.in(ID($div), ID($mod), ID($divfloor), ID($modfloor))) { std::vector<int> a = importDefSigSpec(cell->getPort(ID::A), timestep); std::vector<int> b = importDefSigSpec(cell->getPort(ID::B), timestep); @@ -970,23 +970,48 @@ struct SatGen } std::vector<int> y_tmp = ignore_div_by_zero ? yy : ez->vec_var(y.size()); + + // modulo calculation + std::vector<int> modulo_trunc; + int floored_eq_trunc; + if (cell->parameters[ID::A_SIGNED].as_bool() && cell->parameters[ID::B_SIGNED].as_bool()) { + modulo_trunc = ez->vec_ite(a.back(), ez->vec_neg(chain_buf), chain_buf); + // floor == trunc when sgn(a) == sgn(b) or trunc == 0 + floored_eq_trunc = ez->OR(ez->IFF(a.back(), b.back()), ez->NOT(ez->expression(ezSAT::OpOr, modulo_trunc))); + } else { + modulo_trunc = chain_buf; + floored_eq_trunc = ez->CONST_TRUE; + } + if (cell->type == ID($div)) { if (cell->parameters[ID::A_SIGNED].as_bool() && cell->parameters[ID::B_SIGNED].as_bool()) ez->assume(ez->vec_eq(y_tmp, ez->vec_ite(ez->XOR(a.back(), b.back()), ez->vec_neg(y_u), y_u))); else ez->assume(ez->vec_eq(y_tmp, y_u)); - } else { + } else if (cell->type == ID($mod)) { + ez->assume(ez->vec_eq(y_tmp, modulo_trunc)); + } else if (cell->type == ID($divfloor)) { if (cell->parameters[ID::A_SIGNED].as_bool() && cell->parameters[ID::B_SIGNED].as_bool()) - ez->assume(ez->vec_eq(y_tmp, ez->vec_ite(a.back(), ez->vec_neg(chain_buf), chain_buf))); + ez->assume(ez->vec_eq(y_tmp, ez->vec_ite( + ez->XOR(a.back(), b.back()), + ez->vec_neg(ez->vec_ite( + ez->vec_reduce_or(modulo_trunc), + ez->vec_add(y_u, ez->vec_const_unsigned(1, y_u.size())), + y_u + )), + y_u + ))); else - ez->assume(ez->vec_eq(y_tmp, chain_buf)); + ez->assume(ez->vec_eq(y_tmp, y_u)); + } else if (cell->type == ID($modfloor)) { + ez->assume(ez->vec_eq(y_tmp, ez->vec_ite(floored_eq_trunc, modulo_trunc, ez->vec_add(modulo_trunc, b)))); } if (ignore_div_by_zero) { ez->assume(ez->expression(ezSAT::OpOr, b)); } else { std::vector<int> div_zero_result; - if (cell->type == ID($div)) { + if (cell->type.in(ID($div), ID($divfloor))) { if (cell->parameters[ID::A_SIGNED].as_bool() && cell->parameters[ID::B_SIGNED].as_bool()) { std::vector<int> all_ones(y.size(), ez->CONST_TRUE); std::vector<int> only_first_one(y.size(), ez->CONST_FALSE); @@ -996,7 +1021,8 @@ struct SatGen div_zero_result.insert(div_zero_result.end(), cell->getPort(ID::A).size(), ez->CONST_TRUE); div_zero_result.insert(div_zero_result.end(), y.size() - div_zero_result.size(), ez->CONST_FALSE); } - } else { + } else if (cell->type.in(ID($mod), ID($modfloor))) { + // a mod 0 = a int copy_a_bits = min(cell->getPort(ID::A).size(), cell->getPort(ID::B).size()); div_zero_result.insert(div_zero_result.end(), a.begin(), a.begin() + copy_a_bits); if (cell->parameters[ID::A_SIGNED].as_bool() && cell->parameters[ID::B_SIGNED].as_bool()) diff --git a/kernel/timinginfo.h b/kernel/timinginfo.h index fb4e0930d..d818e580b 100644 --- a/kernel/timinginfo.h +++ b/kernel/timinginfo.h @@ -82,6 +82,9 @@ struct TimingInfo for (auto cell : module->cells()) { if (cell->type == ID($specify2)) { + auto en = cell->getPort(ID::EN); + if (en.is_fully_const() && !en.as_bool()) + continue; auto src = cell->getPort(ID::SRC); auto dst = cell->getPort(ID::DST); for (const auto &c : src.chunks()) @@ -128,11 +131,9 @@ struct TimingInfo int rise_max = cell->getParam(ID::T_RISE_MAX).as_int(); int fall_max = cell->getParam(ID::T_FALL_MAX).as_int(); int max = std::max(rise_max,fall_max); - if (max < 0) - log_warning("Module '%s' contains specify cell '%s' with T_{RISE,FALL}_MAX < 0 which is currently unsupported. Ignoring.\n", log_id(module), log_id(cell)); - if (max <= 0) { - log_debug("Module '%s' contains specify cell '%s' with T_{RISE,FALL}_MAX <= 0 which is currently unsupported. Ignoring.\n", log_id(module), log_id(cell)); - continue; + if (max < 0) { + log_warning("Module '%s' contains specify cell '%s' with T_{RISE,FALL}_MAX < 0 which is currently unsupported. Clamping to 0.\n", log_id(module), log_id(cell)); + max = 0; } for (const auto &d : dst) { auto &v = t.arrival[NameBit(d)]; @@ -152,11 +153,9 @@ struct TimingInfo if (!c.wire->port_input) log_error("Module '%s' contains specify cell '%s' where DST '%s' is not a module input.\n", log_id(module), log_id(cell), log_signal(dst)); int max = cell->getParam(ID::T_LIMIT_MAX).as_int(); - if (max < 0) - log_warning("Module '%s' contains specify cell '%s' with T_LIMIT_MAX < 0 which is currently unsupported. Ignoring.\n", log_id(module), log_id(cell)); - if (max <= 0) { - log_debug("Module '%s' contains specify cell '%s' with T_LIMIT_MAX <= 0 which is currently unsupported. Ignoring.\n", log_id(module), log_id(cell)); - continue; + if (max < 0) { + log_warning("Module '%s' contains specify cell '%s' with T_LIMIT_MAX < 0 which is currently unsupported. Clamping to 0.\n", log_id(module), log_id(cell)); + max = 0; } for (const auto &s : src) { auto &v = t.required[NameBit(s)]; diff --git a/kernel/yosys.cc b/kernel/yosys.cc index 2ec3dca0c..7e9f320e0 100644 --- a/kernel/yosys.cc +++ b/kernel/yosys.cc @@ -713,7 +713,7 @@ extern Tcl_Interp *yosys_get_tcl_interp() struct TclPass : public Pass { TclPass() : Pass("tcl", "execute a TCL script file") { } - void help() YS_OVERRIDE { + void help() override { // |---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---| log("\n"); log(" tcl <filename> [args]\n"); @@ -730,7 +730,7 @@ struct TclPass : public Pass { log("the standard $argc and $argv variables.\n"); log("\n"); } - void execute(std::vector<std::string> args, RTLIL::Design *) YS_OVERRIDE { + void execute(std::vector<std::string> args, RTLIL::Design *) override { if (args.size() < 2) log_cmd_error("Missing script file.\n"); @@ -1220,7 +1220,7 @@ void shell(RTLIL::Design *design) struct ShellPass : public Pass { ShellPass() : Pass("shell", "enter interactive command mode") { } - void help() YS_OVERRIDE { + void help() override { log("\n"); log(" shell\n"); log("\n"); @@ -1252,7 +1252,7 @@ struct ShellPass : public Pass { log("Press Ctrl-D or type 'exit' to leave the interactive shell.\n"); log("\n"); } - void execute(std::vector<std::string> args, RTLIL::Design *design) YS_OVERRIDE { + void execute(std::vector<std::string> args, RTLIL::Design *design) override { extra_args(args, 1, design, false); shell(design); } @@ -1261,7 +1261,7 @@ struct ShellPass : public Pass { #if defined(YOSYS_ENABLE_READLINE) || defined(YOSYS_ENABLE_EDITLINE) struct HistoryPass : public Pass { HistoryPass() : Pass("history", "show last interactive commands") { } - void help() YS_OVERRIDE { + void help() override { log("\n"); log(" history\n"); log("\n"); @@ -1270,7 +1270,7 @@ struct HistoryPass : public Pass { log("from executed scripts.\n"); log("\n"); } - void execute(std::vector<std::string> args, RTLIL::Design *design) YS_OVERRIDE { + void execute(std::vector<std::string> args, RTLIL::Design *design) override { extra_args(args, 1, design, false); #ifdef YOSYS_ENABLE_READLINE for(HIST_ENTRY **list = history_list(); *list != NULL; list++) @@ -1285,7 +1285,7 @@ struct HistoryPass : public Pass { struct ScriptCmdPass : public Pass { ScriptCmdPass() : Pass("script", "execute commands from file or wire") { } - void help() YS_OVERRIDE { + void help() override { // |---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---| log("\n"); log(" script <filename> [<from_label>:<to_label>]\n"); @@ -1308,7 +1308,7 @@ struct ScriptCmdPass : public Pass { log("'-module' mode can be exited by using the 'cd' command.\n"); log("\n"); } - void execute(std::vector<std::string> args, RTLIL::Design *design) YS_OVERRIDE + void execute(std::vector<std::string> args, RTLIL::Design *design) override { bool scriptwire = false; diff --git a/kernel/yosys.h b/kernel/yosys.h index c922faf26..f1646d6bc 100644 --- a/kernel/yosys.h +++ b/kernel/yosys.h @@ -117,11 +117,11 @@ extern Tcl_Obj *Tcl_ObjSetVar2(Tcl_Interp *interp, Tcl_Obj *part1Ptr, Tcl_Obj *p # define PATH_MAX MAX_PATH # define isatty _isatty # define fileno _fileno -# else -// mingw includes `wingdi.h` which defines a TRANSPARENT macro -// that conflicts with X(TRANSPARENT) entry in kernel/constids.inc -# undef TRANSPARENT # endif + +// mingw and msvc include `wingdi.h` which defines a TRANSPARENT macro +// that conflicts with X(TRANSPARENT) entry in kernel/constids.inc +# undef TRANSPARENT #endif #ifndef PATH_MAX @@ -136,23 +136,20 @@ extern Tcl_Obj *Tcl_ObjSetVar2(Tcl_Interp *interp, Tcl_Obj *part1Ptr, Tcl_Obj *p #define YOSYS_NAMESPACE_PREFIX Yosys:: #define USING_YOSYS_NAMESPACE using namespace Yosys; -#if __cplusplus >= 201103L -# define YS_OVERRIDE override -# define YS_FINAL final -#else -# define YS_OVERRIDE -# define YS_FINAL -#endif - #if defined(__GNUC__) || defined(__clang__) # define YS_ATTRIBUTE(...) __attribute__((__VA_ARGS__)) -# define YS_NORETURN #elif defined(_MSC_VER) # define YS_ATTRIBUTE(...) -# define YS_NORETURN __declspec(noreturn) #else # define YS_ATTRIBUTE(...) -# define YS_NORETURN +#endif + +#if __cplusplus >= 201703L +# define YS_MAYBE_UNUSED [[maybe_unused]]; +#elif defined(__GNUC__) || defined(__clang__) +# define YS_MAYBE_UNUSED __attribute__((__unused__)) +#else +# define YS_MAYBE_UNUSED #endif #if __cplusplus >= 201703L |