//************************************************************************* // DESCRIPTION: Verilator: Emit C++ for tree // // Code available from: http://www.veripool.org/verilator // // AUTHORS: Wilson Snyder with Paul Wasson, Duane Gabli // //************************************************************************* // // Copyright 2003-2011 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. // // Verilator is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // //************************************************************************* #include "config_build.h" #include "verilatedos.h" #include #include #include #include #include #include #include "V3Global.h" #include "V3EmitC.h" #include "V3EmitCBase.h" #include "V3Stats.h" #define EMITCINLINES_NUM_CONSTW 10 // Number of VL_CONST_W_*X's in verilated.h (IE VL_CONST_W_9X is last) //###################################################################### class EmitCInlines : EmitCBaseVisitor { // STATE vector m_wordWidths; // What sizes are used? // METHODS void emitInt(); // VISITORS virtual void visit(AstVar* nodep, AstNUser*) { // All wide constants load into variables, so we can just hunt for them nodep->iterateChildren(*this); if (nodep->widthWords() >= EMITCINLINES_NUM_CONSTW ) { if (int(m_wordWidths.size()) <= nodep->widthWords()) { m_wordWidths.resize(nodep->widthWords()+5); } ++ m_wordWidths.at(nodep->widthWords()); v3Global.needHInlines(true); } } virtual void visit(AstBasicDType* nodep, AstNUser*) { if (nodep->keyword() == AstBasicDTypeKwd::STRING) { v3Global.needHeavy(true); // #include via verilated_heavy.h when we create symbol file } } // NOPs virtual void visit(AstNodeStmt*, AstNUser*) {} // Default virtual void visit(AstNode* nodep, AstNUser*) { nodep->iterateChildren(*this); } //--------------------------------------- // ACCESSORS public: EmitCInlines(AstNetlist* nodep) { nodep->accept(*this); if (v3Global.needHInlines()) { emitInt(); } } }; void EmitCInlines::emitInt() { string filename = v3Global.opt.makeDir()+"/"+topClassName()+"__Inlines.h"; newCFile(filename, false/*slow*/, false/*source*/); V3OutCFile hf (filename); m_ofp = &hf; ofp()->putsHeader(); puts("#ifndef _"+topClassName()+"__Inlines_H_\n"); puts("#define _"+topClassName()+"__Inlines_H_\n"); puts("\n"); puts("#include \"verilated.h\"\n"); puts("\n//======================\n\n"); for (unsigned words=0; words=0; --i) { puts(",IData d"+cvtToStr(i)); if (i && (i % 8 == 0)) puts("\n\t"); } puts(") {\n"); puts(" "); for (int i=words-1; i>=0; --i) { puts(" o["+cvtToStr(i)+"]=d"+cvtToStr(i)+";"); if (i && (i % 8 == 0)) puts("\n "); } puts("\n"); puts(" for(int i="+cvtToStr(words)+";i