diff options
Diffstat (limited to 'backends/cxxrtl/cxxrtl.h')
-rw-r--r-- | backends/cxxrtl/cxxrtl.h | 29 |
1 files changed, 26 insertions, 3 deletions
diff --git a/backends/cxxrtl/cxxrtl.h b/backends/cxxrtl/cxxrtl.h index 7d3a8485c..eb7d7eaeb 100644 --- a/backends/cxxrtl/cxxrtl.h +++ b/backends/cxxrtl/cxxrtl.h @@ -110,9 +110,11 @@ struct value : public expr_base<value<Bits>> { explicit constexpr value(Init ...init) : data{init...} {} value(const value<Bits> &) = default; - value(value<Bits> &&) = default; value<Bits> &operator=(const value<Bits> &) = default; + value(value<Bits> &&) = default; + value<Bits> &operator=(value<Bits> &&) = default; + // A (no-op) helper that forces the cast to value<>. CXXRTL_ALWAYS_INLINE const value<Bits> &val() const { @@ -661,10 +663,16 @@ struct wire { template<typename... Init> explicit constexpr wire(Init ...init) : curr{init...}, next{init...} {} + // Copying and copy-assigning values is natural. If, however, a value is replaced with a wire, + // e.g. because a module is built with a different optimization level, then existing code could + // unintentionally copy a wire instead, which would create a subtle but serious bug. To make sure + // this doesn't happen, prohibit copying and copy-assigning wires. wire(const wire<Bits> &) = delete; - wire(wire<Bits> &&) = default; wire<Bits> &operator=(const wire<Bits> &) = delete; + wire(wire<Bits> &&) = default; + wire<Bits> &operator=(wire<Bits> &&) = default; + template<class IntegerT> CXXRTL_ALWAYS_INLINE IntegerT get() const { @@ -706,6 +714,9 @@ struct memory { memory(const memory<Width> &) = delete; memory<Width> &operator=(const memory<Width> &) = delete; + memory(memory<Width> &&) = default; + memory<Width> &operator=(memory<Width> &&) = default; + // The only way to get the compiler to put the initializer in .rodata and do not copy it on stack is to stuff it // into a plain array. You'd think an std::initializer_list would work here, but it doesn't, because you can't // construct an initializer_list in a constexpr (or something) and so if you try to do that the whole thing is @@ -829,7 +840,7 @@ struct metadata { typedef std::map<std::string, metadata> metadata_map; -// Helper class to disambiguate values/wires and their aliases. +// Tag class to disambiguate values/wires and their aliases. struct debug_alias {}; // This structure is intended for consumption via foreign function interfaces, like Python's ctypes. @@ -979,13 +990,25 @@ struct debug_items { } }; +// Tag class to disambiguate module move constructor and module constructor that takes black boxes +// out of another instance of the module. +struct adopt {}; + struct module { module() {} virtual ~module() {} + // Modules with black boxes cannot be copied. Although not all designs include black boxes, + // delete the copy constructor and copy assignment operator to make sure that any downstream + // code that manipulates modules doesn't accidentally depend on their availability. module(const module &) = delete; module &operator=(const module &) = delete; + module(module &&) = default; + module &operator=(module &&) = default; + + virtual void reset() = 0; + virtual bool eval() = 0; virtual bool commit() = 0; |