mirror of
https://github.com/YosysHQ/yosys
synced 2025-06-06 14:13:23 +00:00
cxxrtl: implement debug information outlining.
Aggressive wire localization and inlining is necessary for CXXRTL to achieve high performance. However, that comes with a cost: reduced debug information coverage. Previously, as a workaround, the `-Og` option could have been used to guarantee complete coverage, at a cost of a significant performance penalty. This commit introduces debug information outlining. The main eval() function is compiled with the user-specified optimization settings. In tandem, an auxiliary debug_eval() function, compiled from the same netlist, can be used to reconstruct the values of localized/inlined signals on demand. To the extent that it is possible, debug_eval() reuses the results of computations performed by eval(), only filling in the missing values. Benchmarking a representative design (Minerva SoC SRAM) shows that: * Switching from `-O4`/`-Og` to `-O6` reduces runtime by ~40%. * Switching from `-g1` to `-g2`, both used with `-O6`, increases compile time by ~25%. * Although `-g2` increases the resident size of generated modules, this has no effect on runtime. Because the impact of `-g2` is minimal and the benefits of having unconditional 100% debug information coverage (and the performance improvement as well) are major, this commit removes `-Og` and changes the defaults to `-O6 -g2`. We'll have our cake and eat it too!
This commit is contained in:
parent
3b5a1314cd
commit
ece25a45d4
5 changed files with 278 additions and 71 deletions
|
@ -36,6 +36,7 @@
|
|||
#include <map>
|
||||
#include <algorithm>
|
||||
#include <memory>
|
||||
#include <functional>
|
||||
#include <sstream>
|
||||
|
||||
#include <backends/cxxrtl/cxxrtl_capi.h>
|
||||
|
@ -843,6 +844,9 @@ typedef std::map<std::string, metadata> metadata_map;
|
|||
// Tag class to disambiguate values/wires and their aliases.
|
||||
struct debug_alias {};
|
||||
|
||||
// Tag declaration to disambiguate values and debug outlines.
|
||||
using debug_outline = ::_cxxrtl_outline;
|
||||
|
||||
// This structure is intended for consumption via foreign function interfaces, like Python's ctypes.
|
||||
// Because of this it uses a C-style layout that is easy to parse rather than more idiomatic C++.
|
||||
//
|
||||
|
@ -851,10 +855,11 @@ struct debug_alias {};
|
|||
struct debug_item : ::cxxrtl_object {
|
||||
// Object types.
|
||||
enum : uint32_t {
|
||||
VALUE = CXXRTL_VALUE,
|
||||
WIRE = CXXRTL_WIRE,
|
||||
MEMORY = CXXRTL_MEMORY,
|
||||
ALIAS = CXXRTL_ALIAS,
|
||||
VALUE = CXXRTL_VALUE,
|
||||
WIRE = CXXRTL_WIRE,
|
||||
MEMORY = CXXRTL_MEMORY,
|
||||
ALIAS = CXXRTL_ALIAS,
|
||||
OUTLINE = CXXRTL_OUTLINE,
|
||||
};
|
||||
|
||||
// Object flags.
|
||||
|
@ -881,6 +886,7 @@ struct debug_item : ::cxxrtl_object {
|
|||
zero_at = 0;
|
||||
curr = item.data;
|
||||
next = item.data;
|
||||
outline = nullptr;
|
||||
}
|
||||
|
||||
template<size_t Bits>
|
||||
|
@ -895,6 +901,7 @@ struct debug_item : ::cxxrtl_object {
|
|||
zero_at = 0;
|
||||
curr = const_cast<chunk_t*>(item.data);
|
||||
next = nullptr;
|
||||
outline = nullptr;
|
||||
}
|
||||
|
||||
template<size_t Bits>
|
||||
|
@ -910,6 +917,7 @@ struct debug_item : ::cxxrtl_object {
|
|||
zero_at = 0;
|
||||
curr = item.curr.data;
|
||||
next = item.next.data;
|
||||
outline = nullptr;
|
||||
}
|
||||
|
||||
template<size_t Width>
|
||||
|
@ -924,6 +932,7 @@ struct debug_item : ::cxxrtl_object {
|
|||
zero_at = zero_offset;
|
||||
curr = item.data.empty() ? nullptr : item.data[0].data;
|
||||
next = nullptr;
|
||||
outline = nullptr;
|
||||
}
|
||||
|
||||
template<size_t Bits>
|
||||
|
@ -938,6 +947,7 @@ struct debug_item : ::cxxrtl_object {
|
|||
zero_at = 0;
|
||||
curr = const_cast<chunk_t*>(item.data);
|
||||
next = nullptr;
|
||||
outline = nullptr;
|
||||
}
|
||||
|
||||
template<size_t Bits>
|
||||
|
@ -953,6 +963,22 @@ struct debug_item : ::cxxrtl_object {
|
|||
zero_at = 0;
|
||||
curr = const_cast<chunk_t*>(item.curr.data);
|
||||
next = nullptr;
|
||||
outline = nullptr;
|
||||
}
|
||||
|
||||
template<size_t Bits>
|
||||
debug_item(debug_outline &group, const value<Bits> &item, size_t lsb_offset = 0) {
|
||||
static_assert(sizeof(item) == value<Bits>::chunks * sizeof(chunk_t),
|
||||
"value<Bits> is not compatible with C layout");
|
||||
type = OUTLINE;
|
||||
flags = DRIVEN_COMB;
|
||||
width = Bits;
|
||||
lsb_at = lsb_offset;
|
||||
depth = 1;
|
||||
zero_at = 0;
|
||||
curr = const_cast<chunk_t*>(item.data);
|
||||
next = nullptr;
|
||||
outline = &group;
|
||||
}
|
||||
};
|
||||
static_assert(std::is_standard_layout<debug_item>::value, "debug_item is not compatible with C layout");
|
||||
|
@ -1029,11 +1055,16 @@ struct module {
|
|||
|
||||
} // namespace cxxrtl
|
||||
|
||||
// Internal structure used to communicate with the implementation of the C interface.
|
||||
// Internal structures used to communicate with the implementation of the C interface.
|
||||
|
||||
typedef struct _cxxrtl_toplevel {
|
||||
std::unique_ptr<cxxrtl::module> module;
|
||||
} *cxxrtl_toplevel;
|
||||
|
||||
typedef struct _cxxrtl_outline {
|
||||
std::function<void()> eval;
|
||||
} *cxxrtl_outline;
|
||||
|
||||
// Definitions of internal Yosys cells. Other than the functions in this namespace, CXXRTL is fully generic
|
||||
// and indepenent of Yosys implementation details.
|
||||
//
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue