diff --git a/Changes b/Changes index 223ad8ec9..dcb0312cd 100644 --- a/Changes +++ b/Changes @@ -6,6 +6,8 @@ indicates the contributor was also the author of the fix; Thanks! * Verilator 3.887 devel +*** Add --no-decoration to remove output comments, msg2015. [Frederic Requin] + **** Add error on DPI functions > 32 bits, msg1995. [Elliot Mednick] **** Fix SystemC compiles with VPI, bug1081. [Arthur Kahlich] diff --git a/bin/verilator b/bin/verilator index 0ed247dde..c2432b01b 100755 --- a/bin/verilator +++ b/bin/verilator @@ -300,6 +300,7 @@ descriptions in the next sections for more information. --Mdir Name of output object directory --mod-prefix Name to prepend to lower classes --no-clk Prevent marking specified signal as clock + --no-decoration Disable comments and symbol decorations --no-pins64 Don't use vluint64_t's for 33-64 bit sigs --no-skip-identical Disable skipping identical output +notimingchecks Ignored @@ -843,6 +844,13 @@ the same as --prefix. Prevent the specified signal from being marked as clock. See C<--clk>. +=item --no-decoration + +When creating output Verilated code, minimize comments, whitespace, symbol +names and other decorative items, at the cost of greatly reduced +readability. This may assist C++ compile times. This will not typically +change the ultimate model's performance, but may in some cases. + =item --no-pins64 Backward compatible alias for "--pins-bv 33". diff --git a/src/V3EmitC.cpp b/src/V3EmitC.cpp index 67f7d453b..4124771b0 100644 --- a/src/V3EmitC.cpp +++ b/src/V3EmitC.cpp @@ -113,7 +113,7 @@ public: } if (AstEnumDType* adtypep = nodep->dtypep()->skipRefToEnump()->castEnumDType()) { if (adtypep->width()>64) { - puts("// enum "+nodep->name()+" // Ignored: Too wide for C++\n"); + putsDecoration("// enum "+nodep->name()+" // Ignored: Too wide for C++\n"); } else { puts("enum "+nodep->name()+" {\n"); for (AstEnumItem* itemp = adtypep->itemsp(); itemp; itemp=itemp->nextp()->castEnumItem()) { @@ -220,7 +220,7 @@ public: nodep->v3fatalSrc("Case statements should have been reduced out\n"); } virtual void visit(AstComment* nodep, AstNUser*) { - puts((string)"// "+nodep->name()+" at "+nodep->fileline()->ascii()+"\n"); + putsDecoration((string)"// "+nodep->name()+" at "+nodep->fileline()->ascii()+"\n"); nodep->iterateChildren(*this); } virtual void visit(AstCoverDecl* nodep, AstNUser*) { @@ -499,13 +499,13 @@ public: nodep->bodysp()->iterateAndNext(*this); } virtual void visit(AstUCStmt* nodep, AstNUser*) { - puts("// $c statement at "+nodep->fileline()->ascii()+"\n"); + putsDecoration("// $c statement at "+nodep->fileline()->ascii()+"\n"); nodep->bodysp()->iterateAndNext(*this); puts("\n"); } virtual void visit(AstUCFunc* nodep, AstNUser*) { puts("\n"); - puts("// $c function at "+nodep->fileline()->ascii()+"\n"); + putsDecoration("// $c function at "+nodep->fileline()->ascii()+"\n"); nodep->bodysp()->iterateAndNext(*this); puts("\n"); } @@ -844,7 +844,7 @@ class EmitCImp : EmitCStmts { if (nodep->symProlog()) puts(EmitCBaseVisitor::symTopAssign()+"\n"); - if (nodep->initsp()) puts("// Variables\n"); + if (nodep->initsp()) putsDecoration("// Variables\n"); ofp()->putAlign(V3OutFile::AL_AUTO, 4); for (AstNode* subnodep=nodep->argsp(); subnodep; subnodep = subnodep->nextp()) { if (AstVar* varp=subnodep->castVar()) { @@ -858,11 +858,11 @@ class EmitCImp : EmitCStmts { nodep->initsp()->iterateAndNext(*this); - if (nodep->stmtsp()) puts("// Body\n"); + if (nodep->stmtsp()) putsDecoration("// Body\n"); nodep->stmtsp()->iterateAndNext(*this); if (!m_blkChangeDetVec.empty()) emitChangeDet(); - if (nodep->finalsp()) puts("// Final\n"); + if (nodep->finalsp()) putsDecoration("// Final\n"); nodep->finalsp()->iterateAndNext(*this); // @@ -873,7 +873,7 @@ class EmitCImp : EmitCStmts { } void emitChangeDet() { - puts("// Change detection\n"); + putsDecoration("// Change detection\n"); puts("QData __req = false; // Logically a bool\n"); // But not because it results in faster code bool gotOne = false; for (vector::iterator it = m_blkChangeDetVec.begin(); @@ -1474,7 +1474,7 @@ void EmitCImp::emitVarReset(AstVar* varp) { void EmitCImp::emitCoverageDecl(AstNodeModule* modp) { if (v3Global.opt.coverage()) { ofp()->putsPrivate(true); - puts("// Coverage\n"); + putsDecoration("// Coverage\n"); puts("void __vlCoverInsert(uint32_t* countp, bool enable, const char* filenamep, int lineno, int column,\n"); puts( "const char* hierp, const char* pagep, const char* commentp);\n"); } @@ -1494,12 +1494,12 @@ void EmitCImp::emitCtorImp(AstNodeModule* modp) { emitCellCtors(modp); emitSensitives(); - puts("// Reset internal values\n"); + putsDecoration("// Reset internal values\n"); if (modp->isTop()) { if (v3Global.opt.inhibitSim()) puts("__Vm_inhibitSim = false;\n"); puts("\n"); } - puts("// Reset structure values\n"); + putsDecoration("// Reset structure values\n"); puts("_ctor_var_reset();\n"); emitTextSection(AstType::atSCCTOR); if (optSystemPerl()) puts("SP_AUTO_CTOR;\n"); @@ -1515,7 +1515,7 @@ void EmitCImp::emitConfigureImp(AstNodeModule* modp) { if (nodep->castCoverDecl()) { if (first) { first = false; - puts("// Coverage Declarations\n"); + putsDecoration("// Coverage Declarations\n"); } nodep->accept(*this); splitSizeInc(nodep); @@ -1681,7 +1681,7 @@ void EmitCImp::emitSensitives() { // Create sensitivity list for when to evaluate the model. // If C++ code, the user must call this routine themself. if (m_modp->isTop() && optSystemC()) { - puts("// Sensitivities on all clocks and combo inputs\n"); + putsDecoration("// Sensitivities on all clocks and combo inputs\n"); puts("SC_METHOD(eval);\n"); for (AstNode* nodep=m_modp->stmtsp(); nodep; nodep = nodep->nextp()) { if (AstVar* varp = nodep->castVar()) { @@ -1713,12 +1713,12 @@ void EmitCImp::emitWrapEval(AstNodeModule* modp) { puts("\nvoid "+modClassName(modp)+"::eval() {\n"); puts(EmitCBaseVisitor::symClassVar()+" = this->__VlSymsp; // Setup global symbol table\n"); puts(EmitCBaseVisitor::symTopAssign()+"\n"); - puts("// Initialize\n"); + putsDecoration("// Initialize\n"); puts("if (VL_UNLIKELY(!vlSymsp->__Vm_didInit)) _eval_initial_loop(vlSymsp);\n"); if (v3Global.opt.inhibitSim()) { puts("if (VL_UNLIKELY(__Vm_inhibitSim)) return;\n"); } - puts("// Evaluate till stable\n"); + putsDecoration("// Evaluate till stable\n"); puts("VL_DEBUG_IF(VL_PRINTF(\"\\n----TOP Evaluate "+modClassName(modp)+"::eval\\n\"); );\n"); puts("int __VclockLoop = 0;\n"); puts("QData __Vchange=1;\n"); @@ -1887,7 +1887,7 @@ void EmitCImp::emitInt(AstNodeModule* modp) { if (optSystemPerl()) { puts("/*AUTOSUBCELLS*/\n\n"); } else { - puts("// CELLS\n"); + putsDecoration("// CELLS\n"); if (modp->isTop()) puts("// Public to allow access to /*verilator_public*/ items;\n"); if (modp->isTop()) puts("// otherwise the application code can consider these internals.\n"); for (AstNode* nodep=modp->stmtsp(); nodep; nodep = nodep->nextp()) { @@ -1939,9 +1939,9 @@ void EmitCImp::emitInt(AstNodeModule* modp) { // These should be static const values, however microsloth VC++ doesn't // support them. They also cause problems with GDB under GCC2.95. if (varp->isWide()) { // Unsupported for output - puts("// enum WData "+varp->name()+" //wide"); + putsDecoration("// enum WData "+varp->name()+" //wide"); } else if (!varp->valuep()->castConst()) { // Unsupported for output - //puts("// enum ..... "+varp->name()+" //not simple value, see variable above instead"); + //putsDecoration("// enum ..... "+varp->name()+" //not simple value, see variable above instead"); } else { puts("enum "); puts(varp->isQuad()?"_QData":"_IData"); @@ -2222,7 +2222,7 @@ class EmitCTrace : EmitCStmts { puts("void "+topClassName()+"::traceInit(" +v3Global.opt.traceClassBase()+"* vcdp, void* userthis, uint32_t code) {\n"); - puts("// Callback from vcd->open()\n"); + putsDecoration("// Callback from vcd->open()\n"); puts(topClassName()+"* t=("+topClassName()+"*)userthis;\n"); puts(EmitCBaseVisitor::symClassVar()+" = t->__VlSymsp; // Setup global symbol table\n"); puts("if (!Verilated::calcUnusedSigs()) vl_fatal(__FILE__,__LINE__,__FILE__,\"Turning on wave traces requires Verilated::traceEverOn(true) call before time 0.\");\n"); @@ -2235,7 +2235,7 @@ class EmitCTrace : EmitCStmts { puts("void "+topClassName()+"::traceFull(" +v3Global.opt.traceClassBase()+"* vcdp, void* userthis, uint32_t code) {\n"); - puts("// Callback from vcd->dump()\n"); + putsDecoration("// Callback from vcd->dump()\n"); puts(topClassName()+"* t=("+topClassName()+"*)userthis;\n"); puts(EmitCBaseVisitor::symClassVar()+" = t->__VlSymsp; // Setup global symbol table\n"); puts("t->traceFullThis (vlSymsp, vcdp, code);\n"); @@ -2250,7 +2250,7 @@ class EmitCTrace : EmitCStmts { puts("void "+topClassName()+"::traceChg(" +v3Global.opt.traceClassBase()+"* vcdp, void* userthis, uint32_t code) {\n"); - puts("// Callback from vcd->dump()\n"); + putsDecoration("// Callback from vcd->dump()\n"); puts(topClassName()+"* t=("+topClassName()+"*)userthis;\n"); puts(EmitCBaseVisitor::symClassVar()+" = t->__VlSymsp; // Setup global symbol table\n"); puts("if (vlSymsp->getClearActivity()) {\n"); @@ -2404,16 +2404,16 @@ class EmitCTrace : EmitCStmts { } else if (nodep->funcType() == AstCFuncType::TRACE_CHANGE_SUB) { } else nodep->v3fatalSrc("Bad Case"); - if (nodep->initsp()) puts("// Variables\n"); + if (nodep->initsp()) putsDecoration("// Variables\n"); emitVarList(nodep->initsp(), EVL_ALL, ""); nodep->initsp()->iterateAndNext(*this); ofp()->putAlign(V3OutFile::AL_AUTO, 4); - puts("// Body\n"); + putsDecoration("// Body\n"); puts("{\n"); nodep->stmtsp()->iterateAndNext(*this); puts("}\n"); - if (nodep->finalsp()) puts("// Final\n"); + if (nodep->finalsp()) putsDecoration("// Final\n"); nodep->finalsp()->iterateAndNext(*this); puts("}\n"); } diff --git a/src/V3EmitCBase.h b/src/V3EmitCBase.h index 9c174ce53..b18cb063f 100644 --- a/src/V3EmitCBase.h +++ b/src/V3EmitCBase.h @@ -43,6 +43,7 @@ public: V3OutCFile* ofp() const { return m_ofp; } void puts(const string& str) { ofp()->puts(str); } void putbs(const string& str) { ofp()->putbs(str); } + void putsDecoration(const string& str) { if (v3Global.opt.decoration()) puts(str); } void putsQuoted(const string& str) { ofp()->putsQuoted(str); } bool optSystemC() { return v3Global.opt.systemC(); } bool optSystemPerl() { return v3Global.opt.systemPerl(); } diff --git a/src/V3Options.cpp b/src/V3Options.cpp index 04f9c6898..4f694bf17 100644 --- a/src/V3Options.cpp +++ b/src/V3Options.cpp @@ -689,6 +689,7 @@ void V3Options::parseOptsList(FileLine* fl, const string& optdir, int argc, char else if ( onoff (sw, "-debug-check", flag/*ref*/) ){ m_debugCheck = flag; } else if ( !strcmp (sw, "-debug-sigsegv") ) { throwSigsegv(); } // Undocumented, see also --debug-abort else if ( !strcmp (sw, "-debug-fatalsrc") ) { v3fatalSrc("--debug-fatal-src"); } // Undocumented, see also --debug-abort + else if ( onoff (sw, "-decoration", flag/*ref*/) ) { m_decoration = flag; } else if ( onoff (sw, "-dump-tree", flag/*ref*/) ) { m_dumpTree = flag ? 3 : 0; } // Also see --dump-treei else if ( onoff (sw, "-exe", flag/*ref*/) ) { m_exe = flag; } else if ( onoff (sw, "-ignc", flag/*ref*/) ) { m_ignc = flag; } @@ -1199,6 +1200,7 @@ V3Options::V3Options() { m_coverageUnderscore = false; m_coverageUser = false; m_debugCheck = false; + m_decoration = true; m_exe = false; m_ignc = false; m_inhibitSim = false; diff --git a/src/V3Options.h b/src/V3Options.h index d5040d564..6f18ba997 100644 --- a/src/V3Options.h +++ b/src/V3Options.h @@ -75,6 +75,7 @@ class V3Options { bool m_coverageUnderscore;// main switch: --coverage-underscore bool m_coverageUser; // main switch: --coverage-func bool m_debugCheck; // main switch: --debug-check + bool m_decoration; // main switch: --decoration bool m_exe; // main switch: --exe bool m_ignc; // main switch: --ignc bool m_inhibitSim; // main switch: --inhibit-sim @@ -226,6 +227,7 @@ class V3Options { bool coverageUnderscore() const { return m_coverageUnderscore; } bool coverageUser() const { return m_coverageUser; } bool debugCheck() const { return m_debugCheck; } + bool decoration() const { return m_decoration; } bool exe() const { return m_exe; } bool trace() const { return m_trace; } bool traceDups() const { return m_traceDups; } diff --git a/test_regress/t/t_trace_decoration.pl b/test_regress/t/t_trace_decoration.pl new file mode 100755 index 000000000..e8744e81d --- /dev/null +++ b/test_regress/t/t_trace_decoration.pl @@ -0,0 +1,21 @@ +#!/usr/bin/perl +if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } +# DESCRIPTION: Verilator: Verilog Test driver/expect definition +# +# Copyright 2003-2009 by Wilson Snyder. This program is free software; you can +# redistribute it and/or modify it under the terms of either the GNU +# Lesser General Public License Version 3 or the Perl Artistic License +# Version 2.0. + +compile ( + verilator_flags2 => ['--cc --trace --no-decoration'], + ); + +execute ( + check_finished=>1, + ); + +file_grep_not ("$Self->{obj_dir}/$Self->{VM_PREFIX}.h", qr!// Body!x); + +ok(1); +1; diff --git a/test_regress/t/t_trace_decoration.v b/test_regress/t/t_trace_decoration.v new file mode 100644 index 000000000..80f511d13 --- /dev/null +++ b/test_regress/t/t_trace_decoration.v @@ -0,0 +1,22 @@ +// DESCRIPTION: Verilator: Verilog Test module +// +// This file ONLY is placed into the Public Domain, for any use, +// without warranty, 2014 by Wilson Snyder. + +module t (clk); + input clk; + integer a_very_long_name_which_we_will_hash_eventually=0; + + always @ (posedge clk) begin + a_very_long_name_which_we_will_hash_eventually <= a_very_long_name_which_we_will_hash_eventually + 1; + if (a_very_long_name_which_we_will_hash_eventually == 5) begin + fin(); + end + end + + task fin; + $write("*-* All Finished *-*\n"); + $finish; + endtask + +endmodule