Internals: Refactoring prep for parameter type branch. No functional change intended.

This commit is contained in:
Wilson Snyder 2016-03-12 20:54:52 -05:00
parent b840334ad2
commit cef097b7b7
5 changed files with 128 additions and 78 deletions

View File

@ -1440,6 +1440,15 @@ private:
m_modp->addStmtp(varp); m_modp->addStmtp(varp);
return varp; return varp;
} }
void markAndCheckPinDup(AstNode* nodep, AstNode* refp, const char* whatp) {
if (refp->user5p() && refp->user5p()->castNode()!=nodep) {
nodep->v3error("Duplicate "<<whatp<<" connection: "<<nodep->prettyName()<<endl
<<refp->user5p()->castNode()->warnMore()
<<"... Location of original "<<whatp<<" connection");
} else {
refp->user5p(nodep);
}
}
// VISITs // VISITs
virtual void visit(AstNetlist* nodep, AstNUser* vup) { virtual void visit(AstNetlist* nodep, AstNUser* vup) {
@ -1513,27 +1522,26 @@ private:
if (!nodep->modVarp()) { if (!nodep->modVarp()) {
if (!m_pinSymp) nodep->v3fatalSrc("Pin not under cell?\n"); if (!m_pinSymp) nodep->v3fatalSrc("Pin not under cell?\n");
VSymEnt* foundp = m_pinSymp->findIdFlat(nodep->name()); VSymEnt* foundp = m_pinSymp->findIdFlat(nodep->name());
AstVar* refp = foundp ? foundp->nodep()->castVar() : NULL;
const char* whatp = nodep->param() ? "parameter pin" : "pin"; const char* whatp = nodep->param() ? "parameter pin" : "pin";
if (!refp) { if (!foundp) {
if (nodep->name() == "__paramNumber1" && m_cellp->modp()->castPrimitive()) { if (nodep->name() == "__paramNumber1" && m_cellp->modp()->castPrimitive()) {
// Primitive parameter is really a delay we can just ignore // Primitive parameter is really a delay we can just ignore
nodep->unlinkFrBack()->deleteTree(); VL_DANGLING(nodep); nodep->unlinkFrBack()->deleteTree(); VL_DANGLING(nodep);
return; return;
} }
nodep->v3error(ucfirst(whatp)<<" not found: "<<nodep->prettyName()); nodep->v3error(ucfirst(whatp)<<" not found: "<<nodep->prettyName());
} else if (!refp->isIO() && !refp->isParam() && !refp->isIfaceRef()) { }
nodep->v3error(ucfirst(whatp)<<" is not an in/out/inout/param/interface: "<<nodep->prettyName()); else if (AstVar* refp = foundp->nodep()->castVar()) {
} else { if (!refp->isIO() && !refp->isParam() && !refp->isIfaceRef()) {
nodep->modVarp(refp); nodep->v3error(ucfirst(whatp)<<" is not an in/out/inout/param/interface: "<<nodep->prettyName());
if (refp->user5p() && refp->user5p()->castNode()!=nodep) {
nodep->v3error("Duplicate "<<whatp<<" connection: "<<nodep->prettyName()<<endl
<<refp->user5p()->castNode()->warnMore()
<<"... Location of original "<<whatp<<" connection");
} else { } else {
refp->user5p(nodep); nodep->modVarp(refp);
markAndCheckPinDup(nodep, refp, whatp);
} }
} }
else {
nodep->v3error(ucfirst(whatp)<<" not found: "<<nodep->prettyName());
}
} }
// Early return() above when deleted // Early return() above when deleted
} }

View File

@ -84,10 +84,10 @@ private:
typedef deque<pair<AstIfaceRefDType*,AstIfaceRefDType*> > IfaceRefRefs; // Note may have duplicate entries typedef deque<pair<AstIfaceRefDType*,AstIfaceRefDType*> > IfaceRefRefs; // Note may have duplicate entries
// STATE // STATE
typedef map<AstVar*,AstVar*> VarCloneMap; typedef map<AstNode*,AstNode*> CloneMap;
struct ModInfo { struct ModInfo {
AstNodeModule* m_modp; // Module with specified name AstNodeModule* m_modp; // Module with specified name
VarCloneMap m_cloneMap; // Map of old-varp -> new cloned varp CloneMap m_cloneMap; // Map of old-varp -> new cloned varp
explicit ModInfo(AstNodeModule* modp) { m_modp=modp; } explicit ModInfo(AstNodeModule* modp) { m_modp=modp; }
}; };
typedef map<string,ModInfo> ModNameMap; typedef map<string,ModInfo> ModNameMap;
@ -131,7 +131,7 @@ private:
} }
} }
} }
string paramSmallName(AstNodeModule* modp, AstVar* varp) { string paramSmallName(AstNodeModule* modp, AstNode* varp) {
if (varp->user4()<=1) { if (varp->user4()<=1) {
makeSmallNames(modp); makeSmallNames(modp);
} }
@ -145,7 +145,7 @@ private:
return st; return st;
} }
string paramValueNumber(AstNode* nodep) { string paramValueNumber(AstNode* nodep) {
// Given a compilcated object create a number to use for param module assignment // Given a complicated object create a number to use for param module assignment
// Ideally would be relatively stable if design changes (not use pointer value), // Ideally would be relatively stable if design changes (not use pointer value),
// and must return same value given same input node // and must return same value given same input node
// Return must presently be numeric so doesn't collide with 'small' alphanumeric parameter names // Return must presently be numeric so doesn't collide with 'small' alphanumeric parameter names
@ -166,14 +166,31 @@ private:
return (string)"z"+cvtToStr(num); return (string)"z"+cvtToStr(num);
} }
} }
void relinkPins(VarCloneMap* clonemapp, AstPin* startpinp) { void collectPins(CloneMap* clonemapp, AstNodeModule* modp) {
// Grab all I/O so we can remap our pins later
for (AstNode* stmtp=modp->stmtsp(); stmtp; stmtp = stmtp->nextp()) {
if (AstVar* varp = stmtp->castVar()) {
if (varp->isIO() || varp->isGParam() || varp->isIfaceRef()) {
// Cloning saved a pointer to the new node for us, so just follow that link.
AstVar* oldvarp = varp->clonep()->castVar();
//UINFO(8,"Clone list 0x"<<hex<<(uint32_t)oldvarp<<" -> 0x"<<(uint32_t)varp<<endl);
clonemapp->insert(make_pair(oldvarp, varp));
}
}
}
}
void relinkPins(CloneMap* clonemapp, AstPin* startpinp) {
for (AstPin* pinp = startpinp; pinp; pinp=pinp->nextp()->castPin()) { for (AstPin* pinp = startpinp; pinp; pinp=pinp->nextp()->castPin()) {
if (!pinp->modVarp()) pinp->v3fatalSrc("Not linked?\n"); if (pinp->modVarp()) {
// Find it in the clone structure // Find it in the clone structure
//UINFO(8,"Clone find 0x"<<hex<<(uint32_t)pinp->modVarp()<<endl); //UINFO(8,"Clone find 0x"<<hex<<(uint32_t)pinp->modVarp()<<endl);
VarCloneMap::iterator cloneiter = clonemapp->find(pinp->modVarp()); CloneMap::iterator cloneiter = clonemapp->find(pinp->modVarp());
UASSERT(cloneiter != clonemapp->end(), "Couldn't find pin in clone list"); UASSERT(cloneiter != clonemapp->end(), "Couldn't find pin in clone list");
pinp->modVarp(cloneiter->second); pinp->modVarp(cloneiter->second->castVar());
}
else {
pinp->v3fatalSrc("Not linked?\n");
}
} }
} }
void visitCell(AstCell* nodep); void visitCell(AstCell* nodep);
@ -458,31 +475,32 @@ void ParamVisitor::visitCell(AstCell* nodep) {
if (debug()>8) nodep->paramsp()->dumpTreeAndNext(cout,"-cellparams:\t"); if (debug()>8) nodep->paramsp()->dumpTreeAndNext(cout,"-cellparams:\t");
for (AstPin* pinp = nodep->paramsp(); pinp; pinp=pinp->nextp()->castPin()) { for (AstPin* pinp = nodep->paramsp(); pinp; pinp=pinp->nextp()->castPin()) {
if (!pinp->exprp()) continue; // No-connect if (!pinp->exprp()) continue; // No-connect
AstVar* modvarp = pinp->modVarp(); if (AstVar* modvarp = pinp->modVarp()) {
if (!modvarp) { if (!modvarp->isGParam()) {
pinp->v3error("Parameter not found in sub-module: Param "<<pinp->name()<<" of "<<nodep->prettyName()); pinp->v3error("Attempted parameter setting of non-parameter: Param "<<pinp->prettyName()<<" of "<<nodep->prettyName());
} else if (!modvarp->isGParam()) {
pinp->v3error("Attempted parameter setting of non-parameter: Param "<<pinp->name()<<" of "<<nodep->prettyName());
} else {
AstConst* constp = pinp->exprp()->castConst();
AstConst* origconstp = modvarp->valuep()->castConst();
if (!constp) {
//if (debug()) pinp->dumpTree(cout,"error:");
pinp->v3error("Can't convert defparam value to constant: Param "<<pinp->name()<<" of "<<nodep->prettyName());
pinp->exprp()->replaceWith(new AstConst(pinp->fileline(), V3Number(pinp->fileline(), modvarp->width(), 0)));
} else if (origconstp && constp->sameTree(origconstp)) {
// Setting parameter to its default value. Just ignore it.
// This prevents making additional modules, and makes coverage more
// obvious as it won't show up under a unique module page name.
} else if (constp->num().isDouble()
|| constp->num().isString()
|| constp->num().isFourState()) {
longname += "_" + paramSmallName(nodep->modp(),pinp->modVarp())+paramValueNumber(constp);
any_overrides = true;
} else { } else {
longname += "_" + paramSmallName(nodep->modp(),pinp->modVarp())+constp->num().ascii(false); AstConst* exprp = pinp->exprp()->castConst();
any_overrides = true; AstConst* origp = modvarp->valuep()->castConst();
if (!exprp) {
//if (debug()) pinp->dumpTree(cout,"error:");
pinp->v3error("Can't convert defparam value to constant: Param "<<pinp->name()<<" of "<<nodep->prettyName());
pinp->exprp()->replaceWith(new AstConst(pinp->fileline(), V3Number(pinp->fileline(), modvarp->width(), 0)));
} else if (origp && exprp->sameTree(origp)) {
// Setting parameter to its default value. Just ignore it.
// This prevents making additional modules, and makes coverage more
// obvious as it won't show up under a unique module page name.
} else if (exprp->num().isDouble()
|| exprp->num().isString()
|| exprp->num().isFourState()) {
longname += "_" + paramSmallName(nodep->modp(),modvarp)+paramValueNumber(exprp);
any_overrides = true;
} else {
longname += "_" + paramSmallName(nodep->modp(),modvarp)+exprp->num().ascii(false);
any_overrides = true;
}
} }
} else {
pinp->v3error("Parameter not found in sub-module: Param "<<pinp->prettyName()<<" of "<<nodep->prettyName());
} }
} }
IfaceRefRefs ifaceRefRefs; IfaceRefRefs ifaceRefRefs;
@ -573,22 +591,12 @@ void ParamVisitor::visitCell(AstCell* nodep) {
m_modNameMap.insert(make_pair(modp->name(), ModInfo(modp))); m_modNameMap.insert(make_pair(modp->name(), ModInfo(modp)));
iter = m_modNameMap.find(newname); iter = m_modNameMap.find(newname);
VarCloneMap* clonemapp = &(iter->second.m_cloneMap); CloneMap* clonemapp = &(iter->second.m_cloneMap);
UINFO(4," De-parameterize to new: "<<modp<<endl); UINFO(4," De-parameterize to new: "<<modp<<endl);
// Grab all I/O so we can remap our pins later // Grab all I/O so we can remap our pins later
// Note we allow multiple users of a parameterized model, thus we need to stash this info. // Note we allow multiple users of a parameterized model, thus we need to stash this info.
for (AstNode* stmtp=modp->stmtsp(); stmtp; stmtp = stmtp->nextp()) { collectPins(clonemapp, modp);
if (AstVar* varp = stmtp->castVar()) {
if (varp->isIO() || varp->isGParam() || varp->isIfaceRef()) {
// Cloning saved a pointer to the new node for us, so just follow that link.
AstVar* oldvarp = varp->clonep()->castVar();
//UINFO(8,"Clone list 0x"<<hex<<(uint32_t)oldvarp<<" -> 0x"<<(uint32_t)varp<<endl);
clonemapp->insert(make_pair(oldvarp, varp));
}
}
}
// Relink parameter vars to the new module // Relink parameter vars to the new module
relinkPins(clonemapp, nodep->paramsp()); relinkPins(clonemapp, nodep->paramsp());
@ -608,15 +616,17 @@ void ParamVisitor::visitCell(AstCell* nodep) {
// Assign parameters to the constants specified // Assign parameters to the constants specified
// DOES clone() so must be finished with module clonep() before here // DOES clone() so must be finished with module clonep() before here
for (AstPin* pinp = nodep->paramsp(); pinp; pinp=pinp->nextp()->castPin()) { for (AstPin* pinp = nodep->paramsp(); pinp; pinp=pinp->nextp()->castPin()) {
AstVar* modvarp = pinp->modVarp(); if (pinp->exprp()) {
if (modvarp && pinp->exprp()) { if (AstVar* modvarp = pinp->modVarp()) {
AstConst* constp = pinp->exprp()->castConst(); AstConst* constp = pinp->exprp()->castConst();
// Remove any existing parameter // Remove any existing parameter
if (modvarp->valuep()) modvarp->valuep()->unlinkFrBack()->deleteTree(); if (modvarp->valuep()) modvarp->valuep()->unlinkFrBack()->deleteTree();
// Set this parameter to value requested by cell // Set this parameter to value requested by cell
modvarp->valuep(constp->cloneTree(false)); modvarp->valuep(constp->cloneTree(false));
}
} }
} }
} else { } else {
UINFO(4," De-parameterize to old: "<<modp<<endl); UINFO(4," De-parameterize to old: "<<modp<<endl);
} }
@ -626,7 +636,7 @@ void ParamVisitor::visitCell(AstCell* nodep) {
nodep->modName(newname); nodep->modName(newname);
// We need to relink the pins to the new module // We need to relink the pins to the new module
VarCloneMap* clonemapp = &(iter->second.m_cloneMap); CloneMap* clonemapp = &(iter->second.m_cloneMap);
relinkPins(clonemapp, nodep->pinsp()); relinkPins(clonemapp, nodep->pinsp());
UINFO(8," Done with "<<modp<<endl); UINFO(8," Done with "<<modp<<endl);
} // if any_overrides } // if any_overrides

View File

@ -1157,7 +1157,7 @@ private:
// Note genvar's are also entered as integers // Note genvar's are also entered as integers
nodep->dtypeFrom(nodep->varp()); nodep->dtypeFrom(nodep->varp());
if (nodep->backp()->castNodeAssign() && nodep->lvalue()) { // On LHS if (nodep->backp()->castNodeAssign() && nodep->lvalue()) { // On LHS
if (!nodep->widthMin()) v3fatalSrc("LHS var should be size complete"); if (!nodep->widthMin()) nodep->v3fatalSrc("LHS var should be size complete");
} }
//if (debug()>=9) nodep->dumpTree(cout," VRout "); //if (debug()>=9) nodep->dumpTree(cout," VRout ");
if (nodep->lvalue() && nodep->varp()->isConst() if (nodep->lvalue() && nodep->varp()->isConst()

View File

@ -805,7 +805,7 @@ udpFront<modulep>:
parameter_value_assignmentE<pinp>: // IEEE: [ parameter_value_assignment ] parameter_value_assignmentE<pinp>: // IEEE: [ parameter_value_assignment ]
/* empty */ { $$ = NULL; } /* empty */ { $$ = NULL; }
| '#' '(' cellpinList ')' { $$ = $3; } | '#' '(' cellparamList ')' { $$ = $3; }
// // Parentheses are optional around a single parameter // // Parentheses are optional around a single parameter
| '#' yaINTNUM { $$ = new AstPin($1,1,"",new AstConst($1,*$2)); } | '#' yaINTNUM { $$ = new AstPin($1,1,"",new AstConst($1,*$2)); }
| '#' yaFLOATNUM { $$ = new AstPin($1,1,"",new AstConst($1,AstConst::Unsized32(),(int)(($2<0)?($2-0.5):($2+0.5)))); } | '#' yaFLOATNUM { $$ = new AstPin($1,1,"",new AstConst($1,AstConst::Unsized32(),(int)(($2<0)?($2-0.5):($2+0.5)))); }
@ -1123,6 +1123,7 @@ genvar_identifierDecl<varp>: // IEEE: genvar_identifier (for declaration)
local_parameter_declaration<nodep>: // IEEE: local_parameter_declaration local_parameter_declaration<nodep>: // IEEE: local_parameter_declaration
// // See notes in parameter_declaration // // See notes in parameter_declaration
// // Front must execute first so VARDTYPE is ready before list of vars
local_parameter_declarationFront list_of_param_assignments { $$ = $2; } local_parameter_declarationFront list_of_param_assignments { $$ = $2; }
; ;
@ -1131,30 +1132,33 @@ parameter_declaration<nodep>: // IEEE: parameter_declaration
// // Instead of list_of_type_assignments // // Instead of list_of_type_assignments
// // we use list_of_param_assignments because for port handling // // we use list_of_param_assignments because for port handling
// // it already must accept types, so simpler to have code only one place // // it already must accept types, so simpler to have code only one place
// // Front must execute first so VARDTYPE is ready before list of vars
parameter_declarationFront list_of_param_assignments { $$ = $2; } parameter_declarationFront list_of_param_assignments { $$ = $2; }
; ;
local_parameter_declarationFront: // IEEE: local_parameter_declaration w/o assignment local_parameter_declarationFront: // IEEE: local_parameter_declaration w/o assignment
// // Front must execute first so VARDTYPE is ready before list of vars
varLParamReset implicit_typeE { /*VARRESET-in-varLParam*/ VARDTYPE($2); } varLParamReset implicit_typeE { /*VARRESET-in-varLParam*/ VARDTYPE($2); }
| varLParamReset data_type { /*VARRESET-in-varLParam*/ VARDTYPE($2); } | varLParamReset data_type { /*VARRESET-in-varLParam*/ VARDTYPE($2); }
//UNSUP varLParamReset yTYPE { /*VARRESET-in-varLParam*/ VARDTYPE($2); } //UNSUP varLParamReset yTYPE { /*VARRESET-in-varLParam*/ VARDTYPE(new AstParseTypeDType($2)); }
; ;
parameter_declarationFront: // IEEE: parameter_declaration w/o assignment parameter_declarationFront: // IEEE: parameter_declaration w/o assignment
// // Front must execute first so VARDTYPE is ready before list of vars
varGParamReset implicit_typeE { /*VARRESET-in-varGParam*/ VARDTYPE($2); } varGParamReset implicit_typeE { /*VARRESET-in-varGParam*/ VARDTYPE($2); }
| varGParamReset data_type { /*VARRESET-in-varGParam*/ VARDTYPE($2); } | varGParamReset data_type { /*VARRESET-in-varGParam*/ VARDTYPE($2); }
//UNSUP varGParamReset yTYPE { /*VARRESET-in-varGParam*/ VARDTYPE($2); } //UNSUP varGParamReset yTYPE { /*VARRESET-in-varGParam*/ VARDTYPE(new AstParseTypeDType($2)); }
; ;
parameter_port_declarationFrontE: // IEEE: parameter_port_declaration w/o assignment parameter_port_declarationFrontE: // IEEE: parameter_port_declaration w/o assignment
// // IEEE: parameter_declaration (minus assignment) // // IEEE: parameter_declaration (minus assignment)
// // Front must execute first so VARDTYPE is ready before list of vars
varGParamReset implicit_typeE { /*VARRESET-in-varGParam*/ VARDTYPE($2); } varGParamReset implicit_typeE { /*VARRESET-in-varGParam*/ VARDTYPE($2); }
| varGParamReset data_type { /*VARRESET-in-varGParam*/ VARDTYPE($2); } | varGParamReset data_type { /*VARRESET-in-varGParam*/ VARDTYPE($2); }
//UNSUP varGParamReset yTYPE { /*VARRESET-in-varGParam*/ VARDTYPE(new AstParseTypeDType($2)); }
| implicit_typeE { /*VARRESET-in-varGParam*/ VARDTYPE($1); } | implicit_typeE { /*VARRESET-in-varGParam*/ VARDTYPE($1); }
| data_type { /*VARRESET-in-varGParam*/ VARDTYPE($1); } | data_type { /*VARRESET-in-varGParam*/ VARDTYPE($1); }
//UNSUP varGParamReset yTYPE { /*VARRESET-in-varGParam*/ VARDTYPE($2); } //UNSUP yTYPE { /*VARRESET-in-varGParam*/ VARDTYPE(new AstParseTypeDType($1)); }
//UNSUP data_type { VARDTYPE($1); }
//UNSUP yTYPE { VARDTYPE($1); }
; ;
net_declaration<nodep>: // IEEE: net_declaration - excluding implict net_declaration<nodep>: // IEEE: net_declaration - excluding implict
@ -1988,9 +1992,9 @@ packed_dimension<rangep>: // ==IEEE: packed_dimension
param_assignment<varp>: // ==IEEE: param_assignment param_assignment<varp>: // ==IEEE: param_assignment
// // IEEE: constant_param_expression // // IEEE: constant_param_expression
// // constant_param_expression: '$' is in expr // // constant_param_expression: '$' is in expr
// // note exptOrDataType being a data_type is only for yPARAMETER yTYPE
id/*new-parameter*/ variable_dimensionListE sigAttrListE '=' expr id/*new-parameter*/ variable_dimensionListE sigAttrListE '=' expr
/**/ { $$ = VARDONEA($<fl>1,*$1, $2, $3); $$->valuep($5); } /**/ { $$ = VARDONEA($<fl>1,*$1, $2, $3); $$->valuep($5); }
//UNSUP: exprOrDataType instead of expr
; ;
list_of_param_assignments<varp>: // ==IEEE: list_of_param_assignments list_of_param_assignments<varp>: // ==IEEE: list_of_param_assignments
@ -2067,16 +2071,25 @@ instRangeE<rangep>:
| '[' constExpr ':' constExpr ']' { $$ = new AstRange($1,$2,$4); } | '[' constExpr ':' constExpr ']' { $$ = new AstRange($1,$2,$4); }
; ;
cellparamList<pinp>:
{VARRESET_LIST(UNKNOWN);} cellparamItList { $$ = $2; VARRESET_NONLIST(UNKNOWN); }
;
cellpinList<pinp>: cellpinList<pinp>:
{VARRESET_LIST(UNKNOWN);} cellpinItList { $$ = $2; VARRESET_NONLIST(UNKNOWN); } {VARRESET_LIST(UNKNOWN);} cellpinItList { $$ = $2; VARRESET_NONLIST(UNKNOWN); }
; ;
cellpinItList<pinp>: // IEEE: list_of_port_connections + list_of_parameter_assignmente cellparamItList<pinp>: // IEEE: list_of_parameter_assignmente
cellparamItemE { $$ = $1; }
| cellparamItList ',' cellparamItemE { $$ = $1->addNextNull($3)->castPin(); }
;
cellpinItList<pinp>: // IEEE: list_of_port_connections
cellpinItemE { $$ = $1; } cellpinItemE { $$ = $1; }
| cellpinItList ',' cellpinItemE { $$ = $1->addNextNull($3)->castPin(); } | cellpinItList ',' cellpinItemE { $$ = $1->addNextNull($3)->castPin(); }
; ;
cellpinItemE<pinp>: // IEEE: named_port_connection + named_parameter_assignment + empty cellparamItemE<pinp>: // IEEE: named_parameter_assignment + empty
// Note empty can match either () or (,); V3LinkCells cleans up () // Note empty can match either () or (,); V3LinkCells cleans up ()
/* empty: ',,' is legal */ { $$ = new AstPin(CRELINE(),PINNUMINC(),"",NULL); } /* empty: ',,' is legal */ { $$ = new AstPin(CRELINE(),PINNUMINC(),"",NULL); }
| yP_DOTSTAR { $$ = new AstPin($1,PINNUMINC(),".*",NULL); } | yP_DOTSTAR { $$ = new AstPin($1,PINNUMINC(),".*",NULL); }
@ -2088,9 +2101,26 @@ cellpinItemE<pinp>: // IEEE: named_port_connection + named_parameter_assignment
//UNSUP '.' idAny '(' expr ':' expr ')' { } //UNSUP '.' idAny '(' expr ':' expr ')' { }
//UNSUP '.' idAny '(' expr ':' expr ':' expr ')' { } //UNSUP '.' idAny '(' expr ':' expr ':' expr ')' { }
// // For parameters // // For parameters
//UNSUP '.' idAny '(' data_type ')' { PINDONE($1,$2,$4); GRAMMARP->pinNumInc(); } | '.' idAny '(' data_type ')' { $$ = new AstPin($1,PINNUMINC(),*$2,$4); }
// // For parameters // // For parameters
//UNSUP data_type { PINDONE($1->fileline(),"",$1); GRAMMARP->pinNumInc(); } | data_type { $$ = new AstPin($1->fileline(),PINNUMINC(),"",$1); }
//
| expr { $$ = new AstPin($1->fileline(),PINNUMINC(),"",$1); }
//UNSUP expr ':' expr { }
//UNSUP expr ':' expr ':' expr { }
;
cellpinItemE<pinp>: // IEEE: named_port_connection + empty
// Note empty can match either () or (,); V3LinkCells cleans up ()
/* empty: ',,' is legal */ { $$ = new AstPin(CRELINE(),PINNUMINC(),"",NULL); }
| yP_DOTSTAR { $$ = new AstPin($1,PINNUMINC(),".*",NULL); }
| '.' idSVKwd { $$ = new AstPin($1,PINNUMINC(),*$2,new AstVarRef($1,*$2,false)); $$->svImplicit(true);}
| '.' idAny { $$ = new AstPin($1,PINNUMINC(),*$2,new AstVarRef($1,*$2,false)); $$->svImplicit(true);}
| '.' idAny '(' ')' { $$ = new AstPin($1,PINNUMINC(),*$2,NULL); }
// // mintypmax is expanded here, as it might be a UDP or gate primitive
| '.' idAny '(' expr ')' { $$ = new AstPin($1,PINNUMINC(),*$2,$4); }
//UNSUP '.' idAny '(' expr ':' expr ')' { }
//UNSUP '.' idAny '(' expr ':' expr ':' expr ')' { }
// //
| expr { $$ = new AstPin($1->fileline(),PINNUMINC(),"",$1); } | expr { $$ = new AstPin($1->fileline(),PINNUMINC(),"",$1); }
//UNSUP expr ':' expr { } //UNSUP expr ':' expr { }

View File

@ -55,10 +55,12 @@ module mod_typ #(
parameter type TYP = byte parameter type TYP = byte
)( )(
input logic clk, input logic clk,
output TYP cnt = 0, output TYP cnt,
output int siz output int siz
); );
initial cnt = 0;
always @ (posedge clk) always @ (posedge clk)
cnt <= cnt + 1; cnt <= cnt + 1;