3
0
Fork 0
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:
whitequark 2020-12-13 07:03:16 +00:00
parent 3b5a1314cd
commit ece25a45d4
5 changed files with 278 additions and 71 deletions

View file

@ -128,6 +128,18 @@ enum cxxrtl_type {
// pointer is always NULL.
CXXRTL_ALIAS = 3,
// Outlines correspond to netlist nodes that were optimized in a way that makes them inaccessible
// outside of a module's `eval()` function. At the highest debug information level, every inlined
// node has a corresponding outline object.
//
// Outlines can be inspected via the `curr` pointer and can never be modified; the `next` pointer
// is always NULL. Unlike all other objects, the bits of an outline object are meaningful only
// after a call to `cxxrtl_outline_eval` and until any subsequent modification to the netlist.
// Observing this requirement is the responsibility of the caller; it is not enforced.
//
// Outlines always correspond to combinatorial netlist nodes that are not ports.
CXXRTL_OUTLINE = 4,
// More object types may be added in the future, but the existing ones will never change.
};
@ -171,8 +183,8 @@ enum cxxrtl_flag {
// Node has bits that are driven by a combinatorial cell or another node.
//
// This flag can be set on objects of type `CXXRTL_VALUE` and `CXXRTL_WIRE`. It may be combined
// with `CXXRTL_DRIVEN_SYNC` and `CXXRTL_UNDRIVEN`, as well as other flags.
// This flag can be set on objects of type `CXXRTL_VALUE`, `CXXRTL_WIRE`, and `CXXRTL_OUTLINE`.
// It may be combined with `CXXRTL_DRIVEN_SYNC` and `CXXRTL_UNDRIVEN`, as well as other flags.
//
// This flag is set on objects that have bits connected to the output of a combinatorial cell,
// or directly to another node. For designs without combinatorial loops, writing to such bits
@ -193,8 +205,8 @@ enum cxxrtl_flag {
// Description of a simulated object.
//
// The `data` array can be accessed directly to inspect and, if applicable, modify the bits
// stored in the object.
// The `curr` and `next` arrays can be accessed directly to inspect and, if applicable, modify
// the bits stored in the object.
struct cxxrtl_object {
// Type of the object.
//
@ -231,6 +243,12 @@ struct cxxrtl_object {
uint32_t *curr;
uint32_t *next;
// Opaque reference to an outline. Only meaningful for outline objects.
//
// See the documentation of `cxxrtl_outline` for details. When creating a `cxxrtl_object`, set
// this field to NULL.
struct _cxxrtl_outline *outline;
// More description fields may be added in the future, but the existing ones will never change.
};
@ -272,6 +290,20 @@ void cxxrtl_enum(cxxrtl_handle handle, void *data,
void (*callback)(void *data, const char *name,
struct cxxrtl_object *object, size_t parts));
// Opaque reference to an outline.
//
// An outline is a group of outline objects that are evaluated simultaneously. The identity of
// an outline can be compared to determine whether any two objects belong to the same outline.
typedef struct _cxxrtl_outline *cxxrtl_outline;
// Evaluate an outline.
//
// After evaluating an outline, the bits of every outline object contained in it are consistent
// with the current state of the netlist. In general, any further modification to the netlist
// causes every outline object to become stale, after which the corresponding outline must be
// re-evaluated, otherwise the bits read from that object are meaningless.
void cxxrtl_outline_eval(cxxrtl_outline outline);
#ifdef __cplusplus
}
#endif