From 71fcf45d7372459a6c6a5adfefcc6cac9dff67ea Mon Sep 17 00:00:00 2001 From: Wilson Snyder Date: Sat, 27 Jan 2018 15:06:51 -0500 Subject: [PATCH] Fix gate optimization out of memory, add --gate-stmts, bug1260. --- Changes | 2 ++ bin/verilator | 6 ++++ src/V3Gate.cpp | 8 ++++- src/V3Options.cpp | 5 +++ src/V3Options.h | 2 ++ test_regress/t/t_gate_chained.pl | 56 ++++++++++++++++++++++++++++++++ 6 files changed, 78 insertions(+), 1 deletion(-) create mode 100755 test_regress/t/t_gate_chained.pl diff --git a/Changes b/Changes index 5de1979df..f3fa92615 100644 --- a/Changes +++ b/Changes @@ -4,6 +4,8 @@ The contributors that suggested a given feature are shown in []. Thanks! * Verilator 3.919 devel +**** Fix gate optimization out of memory, add --gate-stmts, bug1260. [Alex Solomatnikov] + **** Fix compile error on public real parameters by suppressing, bug1261. [Alex Solomatnikov] **** Fix input-only tristate comparisons, bug1267. [Alexis G] diff --git a/bin/verilator b/bin/verilator index 9d2ef0498..6071840c0 100755 --- a/bin/verilator +++ b/bin/verilator @@ -289,6 +289,7 @@ descriptions in the next sections for more information. --getenv Get environment variable with defaults --help Display this help -I Directory to search for includes + --gate-stmts Tune gate optimizer depth --if-depth Tune IFDEPTH warning +incdir+ Directory to search for includes --inhibit-sim Create function to turn off sim @@ -750,6 +751,11 @@ them properly, e.g. as -GSTR="\"My String\"" or -GSTR='"My String"'. =back +=item --gate-stmts I + +Rarely needed. Set the maximum number of statements that may be present in +an equation for the gate substitution optimization to inline that equation. + =item --gdb Run Verilator underneath an interactive GDB (or VERILATOR_GDB environment diff --git a/src/V3Gate.cpp b/src/V3Gate.cpp index 4117c9b34..944bf34ee 100644 --- a/src/V3Gate.cpp +++ b/src/V3Gate.cpp @@ -195,6 +195,7 @@ private: bool m_buffersOnly; // Set when we only allow simple buffering, no equations (for clocks) AstNodeVarRef* m_lhsVarRef; // VarRef on lhs of assignment (what we're replacing) bool m_dedupe; // Set when we use isGateDedupable instead of isGateOptimizable + int m_ops; // Operation count // METHODS void clearSimple(const char* because) { @@ -205,6 +206,7 @@ private: } // VISITORS virtual void visit(AstNodeVarRef* nodep) { + ++m_ops; nodep->iterateChildren(*this); // We only allow a LHS ref for the var being set, and a RHS ref for something else being read. if (nodep->varScopep()->varp()->isSc()) { @@ -254,6 +256,9 @@ private: virtual void visit(AstNode* nodep) { // *** Special iterator if (!m_isSimple) return; // Fastpath + if (++m_ops > v3Global.opt.gateStmts()) { + clearSimple("--gate-stmts exceeded"); + } if (!(m_dedupe ? nodep->isGateDedupable() : nodep->isGateOptimizable()) || !nodep->isPure() || nodep->isBrancher()) { @@ -270,6 +275,7 @@ public: m_buffersOnly = buffersOnly; m_lhsVarRef = NULL; m_dedupe = dedupe; + m_ops = 0; // Iterate nodep->accept(*this); // Check results @@ -327,7 +333,7 @@ private: // METHODS void iterateNewStmt(AstNode* nodep, const char* nonReducibleReason, const char* consumeReason) { if (m_scopep) { - UINFO(4," STMT "<new(">$filename"); + $fh->print("// Generated by t_gate_chained.pl\n"); + $fh->print("module t (clk,i,sel,o);\n"); + $fh->print(" input clk;\n"); + $fh->print(" input [63:0] i;\n"); + $fh->print(" input [15:0] sel;\n"); + $fh->print(" output [63:0] o;\n"); + $fh->print("\n"); + my $prev = "i"; + my $n = 9000; + for (my $i=1; $i<$n; ++$i) { + $fh->printf(" wire [63:0] ass%04x = (sel == 16'h%04x) ? 64'h0 : $prev;\n", $i, $i); + $prev = sprintf("ass%04x", $i); + } + + $fh->print("\n"); + $fh->print(" wire [63:0] o = $prev;\n"); + + $fh->print("\n"); + $fh->print(" always @ (posedge clk) begin\n"); + $fh->print(' $write("*-* All Finished *-*\n");',"\n"); + $fh->print(' $finish;',"\n"); + $fh->print(" end\n"); + $fh->print("endmodule\n"); +} + +top_filename("$Self->{obj_dir}/t_gate_chained.v"); + +gen($Self->{top_filename}); + +compile ( + verilator_flags2=>["--stats --x-assign fast --x-initial fast"], + ); + +execute ( + check_finished=>1, + ); + +# Must be <<9000 above to prove this worked +file_grep ($Self->{stats}, qr/Optimizations, Gate sigs deleted\s+(\d+)/i, 8575); + +ok(1); +1;