aboutsummaryrefslogtreecommitdiffstats
path: root/backends
diff options
context:
space:
mode:
authorwhitequark <whitequark@whitequark.org>2020-04-22 01:15:27 +0000
committerwhitequark <whitequark@whitequark.org>2020-04-22 01:15:27 +0000
commit1d5b6ac253a397d173b92549d420d898f80e577f (patch)
tree2b836f67a862bb3d625f98ac4630d218c2fbb0dd /backends
parent5f17e0ced552afb0a27bd244727ce58c24f45e95 (diff)
downloadyosys-1d5b6ac253a397d173b92549d420d898f80e577f.tar.gz
yosys-1d5b6ac253a397d173b92549d420d898f80e577f.tar.bz2
yosys-1d5b6ac253a397d173b92549d420d898f80e577f.zip
cxxrtl: add an unsupported knob for manipulating clock trees.
This is quite possibly the worst way to implement this, but it does work for a subset of well-behaved designs, and can be used to measure how much performance is lost simulating the inactive edge of a clock. It should be replaced with a clock tree analyzer generating safe code once it is clear how should such a thing look like.
Diffstat (limited to 'backends')
-rw-r--r--backends/cxxrtl/cxxrtl.cc18
1 files changed, 18 insertions, 0 deletions
diff --git a/backends/cxxrtl/cxxrtl.cc b/backends/cxxrtl/cxxrtl.cc
index 3cdc5ab6b..bb473cefb 100644
--- a/backends/cxxrtl/cxxrtl.cc
+++ b/backends/cxxrtl/cxxrtl.cc
@@ -1202,6 +1202,24 @@ struct CxxrtlWorker {
f << indent << mangle(cell) << access << mangle_wire_name(conn.first) << " = ";
dump_sigspec_rhs(conn.second);
f << ";\n";
+ if (getenv("CXXRTL_VOID_MY_WARRANTY")) {
+ // Until we have proper clock tree detection, this really awful hack that opportunistically
+ // propagates prev_* values for clocks can be used to estimate how much faster a design could
+ // be if only one clock edge was simulated by replacing:
+ // top.p_clk = value<1>{0u}; top.step();
+ // top.p_clk = value<1>{1u}; top.step();
+ // with:
+ // top.prev_p_clk = value<1>{0u}; top.p_clk = value<1>{1u}; top.step();
+ // Don't rely on this; it will be removed without warning.
+ RTLIL::Module *cell_module = cell->module->design->module(cell->type);
+ if (cell_module != nullptr && cell_module->wire(conn.first) && conn.second.is_wire()) {
+ RTLIL::Wire *cell_module_wire = cell_module->wire(conn.first);
+ if (edge_wires[conn.second.as_wire()] && edge_wires[cell_module_wire]) {
+ f << indent << mangle(cell) << access << "prev_" << mangle(cell_module_wire) << " = ";
+ f << "prev_" << mangle(conn.second.as_wire()) << ";\n";
+ }
+ }
+ }
} else if (cell->input(conn.first)) {
f << indent << mangle(cell) << access << mangle_wire_name(conn.first) << ".next = ";
dump_sigspec_rhs(conn.second);