aboutsummaryrefslogtreecommitdiffstats
path: root/kernel
diff options
context:
space:
mode:
Diffstat (limited to 'kernel')
-rw-r--r--kernel/calc.cc47
-rw-r--r--kernel/celledges.cc2
-rw-r--r--kernel/celledges.h4
-rw-r--r--kernel/celltypes.h44
-rw-r--r--kernel/constids.inc11
-rw-r--r--kernel/hashlib.h12
-rw-r--r--kernel/log.cc22
-rw-r--r--kernel/log.h56
-rw-r--r--kernel/macc.h2
-rw-r--r--kernel/modtools.h8
-rw-r--r--kernel/register.cc10
-rw-r--r--kernel/register.h14
-rw-r--r--kernel/rtlil.cc514
-rw-r--r--kernel/rtlil.h103
-rw-r--r--kernel/satgen.h42
-rw-r--r--kernel/timinginfo.h19
-rw-r--r--kernel/yosys.cc16
-rw-r--r--kernel/yosys.h27
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