3
0
Fork 0
mirror of https://github.com/YosysHQ/yosys synced 2025-06-22 05:43:40 +00:00

cxxrtl: preserve interior memory pointers across reset.

Before this commit, values, wires, and memories with an initializer
were value-initialized in emitted C++ code. After this commit, all
values, wires, and memories are default-initialized, and the default
constructor of generated modules calls the reset() method, which
assigns the members that have an initializer.
This commit is contained in:
Catherine 2021-12-11 15:38:43 +00:00
parent 7c9e498662
commit 55c9fb3b18
2 changed files with 67 additions and 95 deletions

View file

@ -738,24 +738,6 @@ struct memory {
return *this;
}
// 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
// first copied on the stack (probably overflowing it) and then again into `data`.
template<size_t Size>
struct init {
size_t offset;
value<Width> data[Size];
};
template<size_t... InitSize>
explicit memory(size_t depth, const init<InitSize> &...init) : depth(depth), data(new value<Width>[depth]) {
// This utterly reprehensible construct is the most reasonable way to apply a function to every element
// of a parameter pack, if the elements all have different types and so cannot be cast to an initializer list.
auto _ = {std::move(std::begin(init.data), std::end(init.data), &data[init.offset])...};
(void)_;
}
// An operator for direct memory reads. May be used at any time during the simulation.
const value<Width> &operator [](size_t index) const {
assert(index < depth);
@ -1051,9 +1033,9 @@ 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 {};
// Tag class to disambiguate the default constructor used by the toplevel module that calls reset(),
// and the constructor of interior modules that should not call it.
struct interior {};
struct module {
module() {}