aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorwhitequark <whitequark@whitequark.org>2020-12-02 19:41:00 +0000
committerwhitequark <whitequark@whitequark.org>2020-12-02 19:41:00 +0000
commitaa0a15a42cf7513697b3d93457a69ecf2d8b9e05 (patch)
tree12dcb30f7e147ac271f2bdf440297d4fb2c738c5
parent7b0cfd5c36af774ae255459d4ef0fa0934929902 (diff)
downloadyosys-aa0a15a42cf7513697b3d93457a69ecf2d8b9e05.tar.gz
yosys-aa0a15a42cf7513697b3d93457a69ecf2d8b9e05.tar.bz2
yosys-aa0a15a42cf7513697b3d93457a69ecf2d8b9e05.zip
cxxrtl: use CXXRTL_ASSERT for RTL contract violations instead of assert.
RTL contract violations and C++ contract violations are different: the former depend on the netlist and will never violate memory safety whereas the latter may. When loading a CXXRTL simulation into another process, RTL contract violations should generally not crash it, while C++ contract violations should.
-rw-r--r--backends/cxxrtl/cxxrtl.h14
-rw-r--r--backends/cxxrtl/cxxrtl_backend.cc4
2 files changed, 16 insertions, 2 deletions
diff --git a/backends/cxxrtl/cxxrtl.h b/backends/cxxrtl/cxxrtl.h
index 41089a153..7d3a8485c 100644
--- a/backends/cxxrtl/cxxrtl.h
+++ b/backends/cxxrtl/cxxrtl.h
@@ -53,6 +53,20 @@
#define CXXRTL_ALWAYS_INLINE inline
#endif
+// CXXRTL uses assert() to check for C++ contract violations (which may result in e.g. undefined behavior
+// of the simulation code itself), and CXXRTL_ASSERT to check for RTL contract violations (which may at
+// most result in undefined simulation results).
+//
+// Though by default, CXXRTL_ASSERT() expands to assert(), it may be overridden e.g. when integrating
+// the simulation into another process that should survive violating RTL contracts.
+#ifndef CXXRTL_ASSERT
+#ifndef CXXRTL_NDEBUG
+#define CXXRTL_ASSERT(x) assert(x)
+#else
+#define CXXRTL_ASSERT(x)
+#endif
+#endif
+
namespace cxxrtl {
// All arbitrary-width values in CXXRTL are backed by arrays of unsigned integers called chunks. The chunk size
diff --git a/backends/cxxrtl/cxxrtl_backend.cc b/backends/cxxrtl/cxxrtl_backend.cc
index a48ea5b23..23ea57b5a 100644
--- a/backends/cxxrtl/cxxrtl_backend.cc
+++ b/backends/cxxrtl/cxxrtl_backend.cc
@@ -1154,7 +1154,7 @@ struct CxxrtlWorker {
// larger program) will never crash the code that calls into it.
//
// If assertions are disabled, out of bounds reads are defined to return zero.
- f << indent << "assert(" << valid_index_temp << ".valid && \"out of bounds read\");\n";
+ f << indent << "CXXRTL_ASSERT(" << valid_index_temp << ".valid && \"out of bounds read\");\n";
f << indent << "if(" << valid_index_temp << ".valid) {\n";
inc_indent();
if (writable_memories[memory]) {
@@ -1211,7 +1211,7 @@ struct CxxrtlWorker {
// See above for rationale of having both the assert and the condition.
//
// If assertions are disabled, out of bounds writes are defined to do nothing.
- f << indent << "assert(" << valid_index_temp << ".valid && \"out of bounds write\");\n";
+ f << indent << "CXXRTL_ASSERT(" << valid_index_temp << ".valid && \"out of bounds write\");\n";
f << indent << "if (" << valid_index_temp << ".valid) {\n";
inc_indent();
f << indent << mangle(memory) << ".update(" << valid_index_temp << ".index, ";