示例#1
0
    virtual void visit(AstRepeat* nodep, AstNUser*) {
	// So later optimizations don't need to deal with them,
	//    REPEAT(count,body) -> loop=count,WHILE(loop>0) { body, loop-- }
	// Note var can be signed or unsigned based on original number.
	AstNode* countp = nodep->countp()->unlinkFrBackWithNext();
   	string name = string("__Vrepeat")+cvtToStr(m_repeatNum++);
	// Spec says value is integral, if negative is ignored
	AstVar* varp = new AstVar(nodep->fileline(), AstVarType::BLOCKTEMP, name,
				  nodep->findSigned32DType());
	varp->usedLoopIdx(true);
	m_modp->addStmtp(varp);
	AstNode* initsp = new AstAssign(nodep->fileline(), new AstVarRef(nodep->fileline(), varp, true),
					countp);
	AstNode* decp = new AstAssign(nodep->fileline(), new AstVarRef(nodep->fileline(), varp, true),
				      new AstSub(nodep->fileline(), new AstVarRef(nodep->fileline(), varp, false),
						 new AstConst(nodep->fileline(), 1)));
	V3Number zero (nodep->fileline(), 32, 0);  zero.isSigned(true);
	AstNode* zerosp = new AstConst(nodep->fileline(), zero);
	AstNode* condp = new AstGtS(nodep->fileline(), new AstVarRef(nodep->fileline(), varp, false),
				    zerosp);
	AstNode* bodysp = nodep->bodysp(); if (bodysp) bodysp->unlinkFrBackWithNext();
	AstNode* newp = new AstWhile(nodep->fileline(),
				     condp,
				     bodysp,
				     decp);
	initsp = initsp->addNext(newp);
	newp = initsp;
	nodep->replaceWith(newp);
	nodep->deleteTree(); VL_DANGLING(nodep);
    }
示例#2
0
void AstPrinterVisitor::visitBlockNode(BlockNode* node) {
    if (!isMainScope(node->scope())) {
        _output << "{" << endl;
    }

    Scope::VarIterator varIt(node->scope());
    while(varIt.hasNext()) {
        AstVar* var = varIt.next();
        printVarType(var->type());
        _output << " " << var->name();
        printSemicolon();
    }

    Scope::FunctionIterator funcIt(node->scope());
    while(funcIt.hasNext()) {
        FunctionNode* func = funcIt.next()->node();
        func->visit(this);
    }

    for (uint32_t i = 0; i < node->nodes(); ++i) {
        node->nodeAt(i)->visit(this);
        if (!(node->nodeAt(i)->isIfNode()
              || node->nodeAt(i)->isWhileNode()
              || node->nodeAt(i)->isForNode()
              || node->nodeAt(i)->isReturnNode()
              || node->nodeAt(i)->isBlockNode())) {
            printSemicolon();
        }
    }
    if (!isMainScope(node->scope())) {
        _output << "}" << endl;
    }
}
示例#3
0
    virtual void visit(AstVarScope* nodep, AstNUser*) {
	nodep->iterateChildren(*this);
	// Avoid updating this if (), instead see varp->isTrace()
	if (!nodep->varp()->isTemp() && !nodep->varp()->isFuncLocal()) {
	    UINFO(5, "    vsc "<<nodep<<endl);
	    AstVar* varp = nodep->varp();
	    AstScope* scopep = nodep->scopep();
	    // Compute show name
	    // This code assumes SPTRACEVCDC_VERSION >= 1330;
	    // it uses spaces to separate hierarchy components.
	    m_traShowname = AstNode::vcdName(scopep->name() + " " + varp->name());
	    if (m_traShowname.substr(0,4) == "TOP ") m_traShowname.replace(0,4,"");
	    if (!m_initSubFuncp) nodep->v3fatalSrc("NULL");

	    m_traVscp = nodep;
	    m_traValuep = NULL;
	    if (varIgnoreTrace(varp)) {
		addIgnore(varIgnoreTrace(varp));
	    } else {
		++m_statSigs;
		if (nodep->valuep()) m_traValuep = nodep->valuep()->cloneTree(true);
		else m_traValuep = new AstVarRef(nodep->fileline(), nodep, false);
		{
		    // Recurse into data type of the signal; the visitors will call addTraceDecl()
		    varp->dtypeSkipRefp()->accept(*this);
		}
		// Cleanup
		if (m_traValuep) { m_traValuep->deleteTree(); m_traValuep=NULL; }
	    }
	    m_traVscp = NULL;
	    m_traValuep = NULL;
	    m_traShowname = "";
	}
    }
示例#4
0
    AstVarScope* createVarSc(AstVarScope* oldvarscp, string name, int width/*0==fromoldvar*/) {
	// Because we've already scoped it, we may need to add both the AstVar and the AstVarScope
	if (!oldvarscp->scopep()) oldvarscp->v3fatalSrc("Var unscoped");
	AstVar* varp;
	AstNodeModule* addmodp = oldvarscp->scopep()->modp();
	// We need a new AstVar, but only one for all scopes, to match the new AstVarScope
	VarMap::iterator iter = m_modVarMap.find(make_pair(addmodp,name));
	if (iter != m_modVarMap.end()) {
	    // Created module's AstVar earlier under some other scope
	    varp = iter->second;
	} else {
	    if (width==0) {
		varp = new AstVar (oldvarscp->fileline(), AstVarType::BLOCKTEMP, name, oldvarscp->varp());
		varp->widthSignedFrom(oldvarscp);
	    } else { // Used for vset and dimensions, so can zero init
		varp = new AstVar (oldvarscp->fileline(), AstVarType::BLOCKTEMP, name, AstBitPacked(), width);
	    }
	    addmodp->addStmtp(varp);
	    m_modVarMap.insert(make_pair(make_pair(addmodp, name), varp));
	}

	AstVarScope* varscp = new AstVarScope (oldvarscp->fileline(), oldvarscp->scopep(), varp);
	oldvarscp->scopep()->addVarp(varscp);
	return varscp;
    }
示例#5
0
void ByteCodeVisitor::visitFunctionNode(mathvm::FunctionNode *node) {
    BytecodeFunction *dump = currentBytecodeFunction;
    if (currScope) {
        AstFunction *function = currScope->lookupFunction(node->name());
        if (!function) {
            error("undeclared function %s", node->name().c_str());
        }
        AstFunctionInfo *astFunctionInfo = (AstFunctionInfo *) function->info();
        currentBytecodeFunction = astFunctionInfo->function;
    } else {
        currentBytecodeFunction = dynamic_cast<BytecodeFunction *>(interpreterCode->functionById((uint16_t) 0));
    }
    std::vector<VarType> newStack;
    currStack = &newStack;

    Scope::VarIterator varIterator(node->body()->scope()->parent());
    while (varIterator.hasNext()) {
        AstVar *var = varIterator.next();
        pushStack(var->type());//ensure that variables on stack is ok
        store(var);
    }

    visitBlockNode(node->body());

    currentBytecodeFunction = dump;
    currScope = currScope->parent();//jump parameters scope
}
void ASTtoByteCodeTranslator::visitFunctionNode(FunctionNode* node) {
	uint16_t varId = 0;

	for(size_t i = 0; i < node->parametersNumber(); ++i) {
		AstVar *var = node->body()->scope()->lookupVariable(node->parameterName(node->parametersNumber() - i - 1));

		varMap[var] = varId;
		Bytecode *bytecode = funStack.top()->bytecode();
		switch (var->type()) {
		    case VT_INT:
		    	bytecode->addInsn(BC_STOREIVAR);
		        break;
		    case VT_DOUBLE:
		    	bytecode->addInsn(BC_STOREDVAR);
		        break;
		    case VT_STRING:
		    	bytecode->addInsn(BC_STORESVAR);
		        break;
		    default:
		    	bytecode->addInsn(BC_INVALID);
		        break;
		}
		bytecode->addUInt16(varId++);
	}
	node->body()->visit(this);
}
示例#7
0
    AstArraySel* insertImplicit(AstNode* nodep, unsigned start, unsigned count) {
	// Insert any implicit slices as explicit slices (ArraySel nodes).
	// Return a new pointer to replace nodep() in the ArraySel.
	UINFO(9,"  insertImplicit (start="<<start<<",c="<<count<<") "<<nodep<<endl);
	AstVarRef* refp = nodep->user1p()->castNode()->castVarRef();
	if (!refp) nodep->v3fatalSrc("No VarRef in user1 of node "<<nodep);
	AstVar* varp = refp->varp();
	AstNode* topp = nodep;
	for (unsigned i = start; i < start + count; ++i) {
	    AstNodeDType* dtypep = varp->dtypep()->dtypeDimensionp(i-1);
	    AstUnpackArrayDType* adtypep = dtypep->castUnpackArrayDType();
	    if (!adtypep) nodep->v3fatalSrc("insertImplicit tried to expand an array without an ArrayDType");
	    vlsint32_t msb = adtypep->msb();
	    vlsint32_t lsb = adtypep->lsb();
	    if (lsb > msb) {
		// Below code assumes big bit endian; just works out if we swap
		int x = msb; msb = lsb; lsb = x;
	    }
	    UINFO(9,"    ArraySel-child: "<<topp<<endl);
	    AstArraySel* newp = new AstArraySel(nodep->fileline(), topp,
						// "lsb-lsb": Arrays are zero-based so index 0 is always lsb
						new AstConst(nodep->fileline(), lsb-lsb));
	    if (!newp->dtypep()) {
		newp->v3fatalSrc("ArraySel dtyping failed when resolving slice");  // see ArraySel constructor
	    }
	    newp->user1p(refp);
	    newp->start(lsb);
	    newp->length(msb - lsb + 1);
	    topp = newp;
	}
	return topp->castArraySel();
    }
示例#8
0
void Printer::printBlockContents(BlockNode* node) {
    // functions delcarations
    Scope::FunctionIterator funIt(node->scope());
    while (funIt.hasNext()) {
        funIt.next()->node()->visit(this);
        out << '\n';
    }

	// variables declarations
    Scope::VarIterator varIt(node->scope());
    while (varIt.hasNext()) {
        AstVar* var = varIt.next();
        out << typeToName(var->type()) 
        	<< " " << var->name() << ";\n";
    }

    // nodes
    for (size_t i = 0; i < node->nodes(); ++i) {
        AstNode* subNode = node->nodeAt(i);
        subNode->visit(this);
        if (!subNode->isIfNode() && 
        	!subNode->isWhileNode() && 
        	!subNode->isForNode()) {
            out << ';';
        }
        out << '\n';
    }
}
示例#9
0
 void printVars(Scope *scope)
 {
     Scope::VarIterator iter(scope);
     while (iter.hasNext()) {
         AstVar *astVar = iter.next();
         out << typeToName(astVar->type()) << " " << astVar->name() << ";" << endl;
     }
 }
void TypeInferenceVisitor::processFunction(AstFunction* function) {
	Scope* scope = function->scope();
	Scope::VarIterator vit(scope);
	while(vit.hasNext()) {
		AstVar* var = vit.next();
		_types[var] = var->type();
	}
	function->node()->visit(this);
}
示例#11
0
 void variableDeclaration(Scope* scope) {
   Scope::VarIterator iter(scope);
   while (iter.hasNext()) {
     AstVar* x = iter.next();
     indent();
     _output << typeToName(x->type()) << " "
             << x->name() << ";"
             << endl;
   }
 }
示例#12
0
    AstVar* createEnableVar(AstNode* outp, AstVarRef* outrefp, AstNode* enrhsp, int width, string suffix="") {
	// this function creates an  __en Var that corresponds to
	// the outp and outrefp and creates an assignw to enrhsp
        AstVar* enp = new AstVar (outrefp->varp()->fileline(),
				  AstVarType::MODULETEMP,
				  outrefp->name() + "__en" + suffix + cvtToStr(m_unique++),
				  AstLogicPacked(), width);
	enp->varType2Out();

	if (enp->width() != enrhsp->width()) {
	    if (enrhsp->width1()) { // it seems from my futzing that the linter guarantees this condition
		enrhsp = new AstReplicate(enrhsp->fileline(), enrhsp,
					  new AstConst(enrhsp->fileline(), V3Number(enrhsp->fileline(), 32, enp->width())));
		enrhsp->width(enp->width(), enp->width());  //minwidth==width
	    } else {
		enrhsp->v3error("Don't know how to deal with selection logic wider than 1 bit");
	    }
	}

	AstNode* newassp = new AstAssignW (enp->fileline(),
					   new AstVarRef (enp->fileline(), enp, true),
					   enrhsp);
	if (debug()>=9) enp->dumpTreeAndNext(cout,"-   cev-out: ");
	if (debug()>=9) newassp->dumpTreeAndNext(cout,"-   cev-out: ");
        m_modp->addStmtp(enp);
        m_modp->addStmtp(newassp);

	outrefp->user1p(enp); // put __en signal into varref for later usage
	outrefp->varp()->user1p(enp); // put __en signal into var as well in the event this is a single lhs driver and this needs passed up one level

	return enp;
    }
示例#13
0
    virtual void visit(AstPin* nodep, AstNUser*) {
	// Check to see if any output pins have __en pins and create the __en pins to match
	AstVarRef* refp = findVarRef(nodep);

	if (refp && refp->lvalue() && nodep->modVarp()->user1p()) {
	    AstVar* enchildp = (AstVar*)nodep->modVarp()->user1p();
	    UINFO(9, "       Pulling __en var" << enchildp << endl);
	    AstVar* enp = new AstVar(enchildp->fileline(),
				     AstVarType::OUTPUT,
				     enchildp->name()+cvtToStr(m_unique++),
				     enchildp);
	    enp->user2(enchildp->user2());
	    m_modp->addStmtp(enp);
	    AstPin* pinp = new AstPin(nodep->fileline(),
				      nodep->pinNum(),
				      enp->name(),
				      new AstVarRef(nodep->fileline(), enp, true));
	    AstVarRef *rp = findVarRef(pinp);
	    rp->replaceWith(new AstVarRef(nodep->fileline(), enp, true));
	    rp->deleteTree(); rp=NULL;
	    pinp->width(enp->width(),enp->width());  // minwidth==width
	    pinp->modVarp(enchildp);
	    m_cellp->addPinsp(pinp);
	    refp->user1p(enp);
	    refp->varp()->user1p(enp);
	}
	// Simplify interconnect in preperation for V3Inst
	// (This could be a separate visitor, but we're in the neighborhood)
	V3Inst::pinReconnectSimple(nodep, m_cellp, m_modp);
    }
示例#14
0
void ASTAnalyzer::printScopeDeclarations (Scope* scope) {
    Scope::FunctionIterator fuctions(scope);
    while (fuctions.hasNext()) {
        fuctions.next()->node()->visit(this);
    }
    Scope::VarIterator vars(scope);
    while (vars.hasNext()) {
        AstVar* var = vars.next();
        output << typeToName(var->type()) << " " << var->name() << ";\n";
    }
}
ScopeHandler::ScopeHandler(uint16_t iniLocalId, Scope *scope, ScopeHandler *parent)
    : m_scope(scope)
    , m_parent(parent)
{
    Scope::VarIterator it = Scope::VarIterator(m_scope);
    while(it.hasNext()) {
        AstVar *var = it.next();
        m_varNameToId[var->name()] = iniLocalId;
        iniLocalId++;
    }
}
示例#16
0
// private:
// visitBlockNodeImpl
void BytecodeGenerator::visitVarDecls(BlockNode* node) {
    Bytecode* bc = _state.currentBcToFill();
    Scope::VarIterator varIt(node->scope());
    while(varIt.hasNext()) {
        AstVar* var = varIt.next();
        uint16_t varId = _state.currentCtxAddVar(var->name(), node->position());
        Instruction bcLoad0 = typedInsn(var->type(), BC_ILOAD0, BC_DLOAD0, BC_SLOAD0);
        bc->addInsn(bcLoad0);
        Instruction bcStore = typedInsn(var->type(), BC_STOREIVAR, BC_STOREDVAR, BC_STORESVAR);
        genBcInsnWithId(bc, bcStore, varId);
    }
}
示例#17
0
    void varsExpand() {
	// We didn'e have all m_scopes loaded when we encountered variables, so expand them now
	// It would be less code if each module inserted its own variables.
	// Someday.  For now public isn't common.
	for (vector<ScopeModPair>::iterator it = m_scopes.begin(); it != m_scopes.end(); ++it) {
	    AstScope* scopep = it->first;  AstNodeModule* smodp = it->second;
	    for (vector<ModVarPair>::iterator it = m_modVars.begin(); it != m_modVars.end(); ++it) {
		AstNodeModule* modp = it->first;
		AstVar* varp = it->second;
		if (modp == smodp) {
		    // Need to split the module + var name into the original-ish full scope and variable name under that scope.
		    // The module instance name is included later, when we know the scopes this module is under
		    string whole = scopep->name()+"__DOT__"+varp->name();
		    string scpName;
		    string varBase;
		    if (whole.substr(0,10) == "__DOT__TOP") whole.replace(0,10,"");
		    string::size_type pos = whole.rfind("__DOT__");
		    if (pos != string::npos) {
			scpName = whole.substr(0,pos);
			varBase = whole.substr(pos+strlen("__DOT__"));
		    } else {
			varBase = whole;
		    }
		    //UINFO(9,"For "<<scopep->name()<<" - "<<varp->name()<<"  Scp "<<scpName<<"  Var "<<varBase<<endl);
		    string varBasePretty = AstNode::prettyName(varBase);
		    string scpPretty = AstNode::prettyName(scpName);
		    string scpSym;
		    {
			string out = scpName;
			string::size_type pos;
			while ((pos=out.find("__PVT__")) != string::npos) {
			    out.replace(pos, 7, "");
			}
			if (out.substr(0,10) == "TOP__DOT__") out.replace(0,10,"");
			if (out.substr(0,4) == "TOP.") out.replace(0,4,"");
			while ((pos=out.find(".")) != string::npos) {
			    out.replace(pos, 1, "__");
			}
			while ((pos=out.find("__DOT__")) != string::npos) {
			    out.replace(pos, 7, "__");
			}
			scpSym = out;
		    }
		    //UINFO(9," scnameins sp "<<scpName<<" sp "<<scpPretty<<" ss "<<scpSym<<endl);
		    if (m_scopeNames.find(scpSym) == m_scopeNames.end()) {
			m_scopeNames.insert(make_pair(scpSym, ScopeNameData(scpSym, scpPretty)));
		    }
		    m_scopeVars.insert(make_pair(scpSym + " " + varp->name(),
						 ScopeVarData(scpSym, varBasePretty, varp, modp, scopep)));
		}
	    }
	}
    }
示例#18
0
    AstVarScope* getCreateLastClk(AstVarScope* vscp) {
	if (vscp->user1p()) return ((AstVarScope*)vscp->user1p());
	AstVar* varp = vscp->varp();
	if (!varp->width1()) varp->v3error("Unsupported: Clock edge on non-single bit signal: "<<varp->prettyName());
	string newvarname = ((string)"__Vclklast__"+vscp->scopep()->nameDotless()+"__"+varp->name());
        AstVar* newvarp = new AstVar(vscp->fileline(), AstVarType::MODULETEMP, newvarname, VFlagLogicPacked(), 1);
        newvarp->noReset(true);  // Reset by below assign
	m_modp->addStmtp(newvarp);
	AstVarScope* newvscp = new AstVarScope(vscp->fileline(), m_scopep, newvarp);
	vscp->user1p(newvscp);
	m_scopep->addVarp(newvscp);
        // Add init
        AstNode* fromp = new AstVarRef(newvarp->fileline(), vscp, false);
        if (v3Global.opt.xInitialEdge()) fromp = new AstNot(fromp->fileline(), fromp);
        AstNode* newinitp = new AstAssign(vscp->fileline(),
                                          new AstVarRef(newvarp->fileline(), newvscp, true),
                                          fromp);
        addToInitial(newinitp);
	// At bottom, assign them
	AstAssign* finalp
            = new AstAssign(vscp->fileline(),
                            new AstVarRef(vscp->fileline(), newvscp, true),
                            new AstVarRef(vscp->fileline(), vscp, false));
	m_evalFuncp->addFinalsp(finalp);
	//
	UINFO(4,"New Last: "<<newvscp<<endl);
	return newvscp;
    }
示例#19
0
    virtual void visit(AstAlwaysPublic* nodep, AstNUser*) {
	// AlwaysPublic was attached under a var, but it's a statement that should be
	// at the same level as the var
	cleanFileline(nodep);
	nodep->iterateChildren(*this);
	if (m_varp) {
	    nodep->unlinkFrBack();
	    m_varp->addNext(nodep);
	    // lvalue is true, because we know we have a verilator public_flat_rw
	    // but someday we may be more general
	    bool lvalue = m_varp->isSigUserRWPublic();
	    nodep->addStmtp(new AstVarRef(nodep->fileline(), m_varp, lvalue));
	}
    }
示例#20
0
        void visitScope(Scope * scope) {
            Scope::VarIterator varIter(scope);
            while (varIter.hasNext()) {
                addIndent();
                AstVar * var = varIter.next();
                out<< typeToName(var->type())<< " "<< var->name()<< ";"<< endl;

            }
            Scope::FunctionIterator funcIter(scope);
            while (funcIter.hasNext()) {

                funcIter.next()->node()->visit(this);
            }
        }
示例#21
0
    virtual void visit(AstAttrOf* nodep, AstNUser*) {
	cleanFileline(nodep);
	nodep->iterateChildren(*this);
	if (nodep->attrType() == AstAttrType::VAR_CLOCK) {
	    if (!m_varp) nodep->v3fatalSrc("Attribute not attached to variable");
	    m_varp->attrScClocked(true);
	    nodep->unlinkFrBack()->deleteTree(); nodep=NULL;
	}
	else if (nodep->attrType() == AstAttrType::VAR_CLOCK_ENABLE) {
	    if (!m_varp) nodep->v3fatalSrc("Attribute not attached to variable");
	    m_varp->attrClockEn(true);
	    nodep->unlinkFrBack()->deleteTree(); nodep=NULL;
	}
	else if (nodep->attrType() == AstAttrType::VAR_PUBLIC) {
	    if (!m_varp) nodep->v3fatalSrc("Attribute not attached to variable");
	    m_varp->sigUserRWPublic(true); m_varp->sigModPublic(true);
	    nodep->unlinkFrBack()->deleteTree(); nodep=NULL;
	}
	else if (nodep->attrType() == AstAttrType::VAR_PUBLIC_FLAT) {
	    if (!m_varp) nodep->v3fatalSrc("Attribute not attached to variable");
	    m_varp->sigUserRWPublic(true);
	    nodep->unlinkFrBack()->deleteTree(); nodep=NULL;
	}
	else if (nodep->attrType() == AstAttrType::VAR_PUBLIC_FLAT_RD) {
	    if (!m_varp) nodep->v3fatalSrc("Attribute not attached to variable");
	    m_varp->sigUserRdPublic(true);
	    nodep->unlinkFrBack()->deleteTree(); nodep=NULL;
	}
	else if (nodep->attrType() == AstAttrType::VAR_PUBLIC_FLAT_RW) {
	    if (!m_varp) nodep->v3fatalSrc("Attribute not attached to variable");
	    m_varp->sigUserRWPublic(true);
	    nodep->unlinkFrBack()->deleteTree(); nodep=NULL;
	}
	else if (nodep->attrType() == AstAttrType::VAR_ISOLATE_ASSIGNMENTS) {
	    if (!m_varp) nodep->v3fatalSrc("Attribute not attached to variable");
	    m_varp->attrIsolateAssign(true);
	    nodep->unlinkFrBack()->deleteTree(); nodep=NULL;
	}
	else if (nodep->attrType() == AstAttrType::VAR_SFORMAT) {
	    if (!m_varp) nodep->v3fatalSrc("Attribute not attached to variable");
	    m_varp->attrSFormat(true);
	    nodep->unlinkFrBack()->deleteTree(); nodep=NULL;
	}
	else if (nodep->attrType() == AstAttrType::VAR_SC_BV) {
	    if (!m_varp) nodep->v3fatalSrc("Attribute not attached to variable");
	    m_varp->attrScBv(true);
	    nodep->unlinkFrBack()->deleteTree(); nodep=NULL;
	}
    }
示例#22
0
    virtual void visit(AstVar* nodep, AstNUser*) {
	if (m_state == CONVERT_VARS) {
	    if (nodep->isTristate() && !m_ftaskp) {
		// create the input var and leave the original as the output var
		AstVar* varinp = nodep->cloneTree(false)->castVar();
		varinp->name(varinp->name() + "__in");
		varinp->varType2In();

		nodep->combineType(AstVarType::OUTPUT);
		nodep->varType2Out();
		m_modp->addStmtp(varinp);
		nodep->user1p(varinp);
	    }
	}
    }
示例#23
0
void Ast2SrcVisitor::initScope(Scope* scope) {
    std::string indent(_indent, ' ');

    Scope::VarIterator varIt(scope);
    while (varIt.hasNext()) {
        AstVar* var = varIt.next();
        _out << indent << mathvm::typeToName(var->type()) << " "<< var->name() << ";" << std::endl;
    }

    Scope::FunctionIterator funcIt(scope);
    while (funcIt.hasNext()) {
        funcIt.next()->node()->visit(this);
        _out << std::endl;
    }
}
示例#24
0
void PrettyPrinter::printScope(Scope *scope)
{
	std::string indentation(m_indent, ' ');
	//why constructor doesn't get const pointer?
	Scope::VarIterator ivar(scope);
	//Java-style iterators in C++?
	while (ivar.hasNext())
	{
		AstVar *var = ivar.next();
		m_out << indentation << typeToName(var->type()) << " "
		      << var->name() << ";" << std::endl;
	}
	
	Scope::FunctionIterator ifun(scope);
	while (ifun.hasNext()) ifun.next()->node()->visit(this);
}
示例#25
0
 string bitNames(BitNamesWhich which) {
     string bits="";
     bool prev = false;
     int msb = 0;
     // bit==-1 loops below; we do one extra iteration so end with prev=false
     for (int bit=(m_flags.size()/FLAGS_PER_BIT)-1; bit >= -1; --bit) {
         if (bit>=0
                 && ((which == BN_UNUSED && !usedFlag(bit) && drivenFlag(bit))
                     || (which == BN_UNDRIVEN && usedFlag(bit) && !drivenFlag(bit))
                     || (which == BN_BOTH && !usedFlag(bit) && !drivenFlag(bit)))) {
             if (!prev) {
                 prev=true;
                 msb = bit;
             }
         } else if (prev) {
             AstBasicDType* bdtypep = m_varp->basicp();
             int lsb = bit+1;
             if (bits != "") bits += ",";
             if (lsb==msb) {
                 bits += cvtToStr(lsb+bdtypep->lsb());
             } else {
                 if (bdtypep->littleEndian()) {
                     bits += cvtToStr(lsb+bdtypep->lsb())+":"+cvtToStr(msb+bdtypep->lsb());
                 } else {
                     bits += cvtToStr(msb+bdtypep->lsb())+":"+cvtToStr(lsb+bdtypep->lsb());
                 }
             }
             prev = false;
         }
     }
     return "["+bits+"]";
 }
示例#26
0
 void drivenBit (int bit, int width) {
     UINFO(9, "set d["<<(bit+width-1)<<":"<<bit<<"] "<<m_varp->name()<<endl);
     for (int i=0; i<width; i++) {
         if (bitNumOk(bit+i)) {
             m_flags[(bit+i)*FLAGS_PER_BIT + FLAG_DRIVEN] = true;
         }
     }
 }
示例#27
0
void AstPrinter::printScopeDeclarations(Scope* scope) {
    Scope::VarIterator varIterator(scope);
    while(varIterator.hasNext()) {
        AstVar *var = varIterator.next();
        print(typeToName(var->type()));
        print(" ");
        print(var->name());
        print(";\n");
    }
    
    Scope::FunctionIterator funcIterator(scope);
    while(funcIterator.hasNext()) {
        AstFunction *func = funcIterator.next();
		printFunction(func);
    }
    print("\n");
}
示例#28
0
    // VISITORS
    virtual void visit(AstArraySel* nodep, AstNUser*) {
	if (!nodep->backp()->castArraySel()) {
	    // This is the top of an ArraySel, setup for iteration
	    m_refp = nodep->user1p()->castNode()->castVarRef();
	    m_vecIdx += 1;
	    if (m_vecIdx == (int)m_selBits.size()) {
		m_selBits.push_back(vector<unsigned>());
		AstVar* varp = m_refp->varp();
		pair<uint32_t,uint32_t> arrDim = varp->dtypep()->dimensions(false);
		uint32_t dimensions = arrDim.second;
		// for 3-dimensions we want m_selBits[m_vecIdx]=[0,0,0]
		for (uint32_t i = 0; i < dimensions; ++i) {
		    m_selBits[m_vecIdx].push_back(0);
		}
	    }
	}
	nodep->iterateChildren(*this);
	if (nodep->fromp()->castVarRef()) {
	    m_depth = 0;
	} else {
	    ++m_depth;
	}
	// Check if m_selBits has overflowed
	if (m_selBits[m_vecIdx][m_depth] >= nodep->length()) {
	    m_selBits[m_vecIdx][m_depth] = 0;
	    if (m_depth + 1 < m_selBits[m_vecIdx].size())
		m_selBits[m_vecIdx][m_depth+1] += 1;
	}
	// Reassign the bitp()
	if (nodep->length() > 1) {
	    if (AstConst* bitp = nodep->bitp()->castConst()) {
		AstUnpackArrayDType* adtypep = nodep->fromp()->dtypep()->skipRefp()->castUnpackArrayDType();
		if (!adtypep) nodep->v3fatalSrc("slice select tried to expand an array without an ArrayDType");
		unsigned idx = nodep->start() + m_selBits[m_vecIdx][m_depth] - adtypep->lsb();
		AstNode* constp = new AstConst(bitp->fileline(), V3Number(bitp->fileline(), bitp->castConst()->num().width(), idx));
		bitp->replaceWith(constp);
	    } else {
		nodep->v3error("Unsupported: Only constants supported in slices");
	    }
	}
	if (!nodep->backp()->castArraySel()) {
	    // Top ArraySel, increment m_selBits
	    m_selBits[m_vecIdx][0] += 1;
	}
	nodep->length(1);
    }
示例#29
0
    void printScope(Scope * scope) {
        Scope::VarIterator varIt(scope); 

        while(varIt.hasNext()) {
            AstVar* var = varIt.next();

            os << indent();
            os << typeToName(var->type()) << " " << var->name() << ";" << endl;
        }

        Scope::FunctionIterator funcIt(scope);
        while(funcIt.hasNext()) {
            AstFunction* func = funcIt.next();
            
            os << indent();
            func->node()->visit(this);
        }
    }
示例#30
0
    void createDeepTemp(AstNode* nodep, bool noSubst) {
	if (debug()>8) nodep->dumpTree(cout,"deepin:");

	AstNRelinker linker;
	nodep->unlinkFrBack(&linker);

	AstVar* varp = getBlockTemp(nodep);
	if (noSubst) varp->noSubst(true); // Do not remove varrefs to this in V3Const
	// Replace node tree with reference to var
	AstVarRef* newp = new AstVarRef (nodep->fileline(), varp, false);
	linker.relink(newp);
	// Put assignment before the referencing statement
	AstAssign* assp = new AstAssign (nodep->fileline(),
					 new AstVarRef(nodep->fileline(), varp, true),
					 nodep);
	insertBeforeStmt(assp);
	if (debug()>8) assp->dumpTree(cout,"deepou:");
	nodep->user1(true);  // Don't add another assignment
    }