mirror of
https://github.com/verilator/verilator.git
synced 2025-04-21 12:06:55 +00:00
Internals: Refactoring prep for parameter type branch. No functional change intended.
This commit is contained in:
parent
b840334ad2
commit
cef097b7b7
@ -1440,6 +1440,15 @@ private:
|
||||
m_modp->addStmtp(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
|
||||
virtual void visit(AstNetlist* nodep, AstNUser* vup) {
|
||||
@ -1513,27 +1522,26 @@ private:
|
||||
if (!nodep->modVarp()) {
|
||||
if (!m_pinSymp) nodep->v3fatalSrc("Pin not under cell?\n");
|
||||
VSymEnt* foundp = m_pinSymp->findIdFlat(nodep->name());
|
||||
AstVar* refp = foundp ? foundp->nodep()->castVar() : NULL;
|
||||
const char* whatp = nodep->param() ? "parameter pin" : "pin";
|
||||
if (!refp) {
|
||||
if (!foundp) {
|
||||
if (nodep->name() == "__paramNumber1" && m_cellp->modp()->castPrimitive()) {
|
||||
// Primitive parameter is really a delay we can just ignore
|
||||
nodep->unlinkFrBack()->deleteTree(); VL_DANGLING(nodep);
|
||||
return;
|
||||
}
|
||||
nodep->v3error(ucfirst(whatp)<<" not found: "<<nodep->prettyName());
|
||||
} else if (!refp->isIO() && !refp->isParam() && !refp->isIfaceRef()) {
|
||||
}
|
||||
else if (AstVar* refp = foundp->nodep()->castVar()) {
|
||||
if (!refp->isIO() && !refp->isParam() && !refp->isIfaceRef()) {
|
||||
nodep->v3error(ucfirst(whatp)<<" is not an in/out/inout/param/interface: "<<nodep->prettyName());
|
||||
} else {
|
||||
nodep->modVarp(refp);
|
||||
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);
|
||||
markAndCheckPinDup(nodep, refp, whatp);
|
||||
}
|
||||
}
|
||||
else {
|
||||
nodep->v3error(ucfirst(whatp)<<" not found: "<<nodep->prettyName());
|
||||
}
|
||||
}
|
||||
// Early return() above when deleted
|
||||
}
|
||||
|
@ -84,10 +84,10 @@ private:
|
||||
typedef deque<pair<AstIfaceRefDType*,AstIfaceRefDType*> > IfaceRefRefs; // Note may have duplicate entries
|
||||
|
||||
// STATE
|
||||
typedef map<AstVar*,AstVar*> VarCloneMap;
|
||||
typedef map<AstNode*,AstNode*> CloneMap;
|
||||
struct ModInfo {
|
||||
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; }
|
||||
};
|
||||
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) {
|
||||
makeSmallNames(modp);
|
||||
}
|
||||
@ -145,7 +145,7 @@ private:
|
||||
return st;
|
||||
}
|
||||
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),
|
||||
// and must return same value given same input node
|
||||
// Return must presently be numeric so doesn't collide with 'small' alphanumeric parameter names
|
||||
@ -166,14 +166,31 @@ private:
|
||||
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()) {
|
||||
if (!pinp->modVarp()) pinp->v3fatalSrc("Not linked?\n");
|
||||
if (pinp->modVarp()) {
|
||||
// Find it in the clone structure
|
||||
//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");
|
||||
pinp->modVarp(cloneiter->second);
|
||||
pinp->modVarp(cloneiter->second->castVar());
|
||||
}
|
||||
else {
|
||||
pinp->v3fatalSrc("Not linked?\n");
|
||||
}
|
||||
}
|
||||
}
|
||||
void visitCell(AstCell* nodep);
|
||||
@ -458,32 +475,33 @@ void ParamVisitor::visitCell(AstCell* nodep) {
|
||||
if (debug()>8) nodep->paramsp()->dumpTreeAndNext(cout,"-cellparams:\t");
|
||||
for (AstPin* pinp = nodep->paramsp(); pinp; pinp=pinp->nextp()->castPin()) {
|
||||
if (!pinp->exprp()) continue; // No-connect
|
||||
AstVar* modvarp = pinp->modVarp();
|
||||
if (!modvarp) {
|
||||
pinp->v3error("Parameter not found in sub-module: Param "<<pinp->name()<<" of "<<nodep->prettyName());
|
||||
} else if (!modvarp->isGParam()) {
|
||||
pinp->v3error("Attempted parameter setting of non-parameter: Param "<<pinp->name()<<" of "<<nodep->prettyName());
|
||||
if (AstVar* modvarp = pinp->modVarp()) {
|
||||
if (!modvarp->isGParam()) {
|
||||
pinp->v3error("Attempted parameter setting of non-parameter: Param "<<pinp->prettyName()<<" of "<<nodep->prettyName());
|
||||
} else {
|
||||
AstConst* constp = pinp->exprp()->castConst();
|
||||
AstConst* origconstp = modvarp->valuep()->castConst();
|
||||
if (!constp) {
|
||||
AstConst* exprp = pinp->exprp()->castConst();
|
||||
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 (origconstp && constp->sameTree(origconstp)) {
|
||||
} 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 (constp->num().isDouble()
|
||||
|| constp->num().isString()
|
||||
|| constp->num().isFourState()) {
|
||||
longname += "_" + paramSmallName(nodep->modp(),pinp->modVarp())+paramValueNumber(constp);
|
||||
} 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(),pinp->modVarp())+constp->num().ascii(false);
|
||||
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;
|
||||
for (AstPin* pinp = nodep->pinsp(); pinp; pinp=pinp->nextp()->castPin()) {
|
||||
@ -573,22 +591,12 @@ void ParamVisitor::visitCell(AstCell* nodep) {
|
||||
|
||||
m_modNameMap.insert(make_pair(modp->name(), ModInfo(modp)));
|
||||
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);
|
||||
|
||||
// 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.
|
||||
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));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
collectPins(clonemapp, modp);
|
||||
// Relink parameter vars to the new module
|
||||
relinkPins(clonemapp, nodep->paramsp());
|
||||
|
||||
@ -608,8 +616,8 @@ void ParamVisitor::visitCell(AstCell* nodep) {
|
||||
// Assign parameters to the constants specified
|
||||
// DOES clone() so must be finished with module clonep() before here
|
||||
for (AstPin* pinp = nodep->paramsp(); pinp; pinp=pinp->nextp()->castPin()) {
|
||||
AstVar* modvarp = pinp->modVarp();
|
||||
if (modvarp && pinp->exprp()) {
|
||||
if (pinp->exprp()) {
|
||||
if (AstVar* modvarp = pinp->modVarp()) {
|
||||
AstConst* constp = pinp->exprp()->castConst();
|
||||
// Remove any existing parameter
|
||||
if (modvarp->valuep()) modvarp->valuep()->unlinkFrBack()->deleteTree();
|
||||
@ -617,6 +625,8 @@ void ParamVisitor::visitCell(AstCell* nodep) {
|
||||
modvarp->valuep(constp->cloneTree(false));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
} else {
|
||||
UINFO(4," De-parameterize to old: "<<modp<<endl);
|
||||
}
|
||||
@ -626,7 +636,7 @@ void ParamVisitor::visitCell(AstCell* nodep) {
|
||||
nodep->modName(newname);
|
||||
|
||||
// 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());
|
||||
UINFO(8," Done with "<<modp<<endl);
|
||||
} // if any_overrides
|
||||
|
@ -1157,7 +1157,7 @@ private:
|
||||
// Note genvar's are also entered as integers
|
||||
nodep->dtypeFrom(nodep->varp());
|
||||
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 (nodep->lvalue() && nodep->varp()->isConst()
|
||||
|
@ -805,7 +805,7 @@ udpFront<modulep>:
|
||||
|
||||
parameter_value_assignmentE<pinp>: // IEEE: [ parameter_value_assignment ]
|
||||
/* empty */ { $$ = NULL; }
|
||||
| '#' '(' cellpinList ')' { $$ = $3; }
|
||||
| '#' '(' cellparamList ')' { $$ = $3; }
|
||||
// // Parentheses are optional around a single parameter
|
||||
| '#' 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)))); }
|
||||
@ -1123,6 +1123,7 @@ genvar_identifierDecl<varp>: // IEEE: genvar_identifier (for declaration)
|
||||
|
||||
local_parameter_declaration<nodep>: // IEEE: local_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; }
|
||||
;
|
||||
|
||||
@ -1131,30 +1132,33 @@ parameter_declaration<nodep>: // IEEE: parameter_declaration
|
||||
// // Instead of list_of_type_assignments
|
||||
// // we use list_of_param_assignments because for port handling
|
||||
// // 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; }
|
||||
;
|
||||
|
||||
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 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
|
||||
// // Front must execute first so VARDTYPE is ready before list of vars
|
||||
varGParamReset implicit_typeE { /*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
|
||||
// // 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 data_type { /*VARRESET-in-varGParam*/ VARDTYPE($2); }
|
||||
//UNSUP varGParamReset yTYPE { /*VARRESET-in-varGParam*/ VARDTYPE(new AstParseTypeDType($2)); }
|
||||
| implicit_typeE { /*VARRESET-in-varGParam*/ VARDTYPE($1); }
|
||||
| data_type { /*VARRESET-in-varGParam*/ VARDTYPE($1); }
|
||||
//UNSUP varGParamReset yTYPE { /*VARRESET-in-varGParam*/ VARDTYPE($2); }
|
||||
//UNSUP data_type { VARDTYPE($1); }
|
||||
//UNSUP yTYPE { VARDTYPE($1); }
|
||||
//UNSUP yTYPE { /*VARRESET-in-varGParam*/ VARDTYPE(new AstParseTypeDType($1)); }
|
||||
;
|
||||
|
||||
net_declaration<nodep>: // IEEE: net_declaration - excluding implict
|
||||
@ -1988,9 +1992,9 @@ packed_dimension<rangep>: // ==IEEE: packed_dimension
|
||||
param_assignment<varp>: // ==IEEE: param_assignment
|
||||
// // IEEE: constant_param_expression
|
||||
// // constant_param_expression: '$' is in expr
|
||||
// // note exptOrDataType being a data_type is only for yPARAMETER yTYPE
|
||||
id/*new-parameter*/ variable_dimensionListE sigAttrListE '=' expr
|
||||
/**/ { $$ = VARDONEA($<fl>1,*$1, $2, $3); $$->valuep($5); }
|
||||
//UNSUP: exprOrDataType instead of expr
|
||||
;
|
||||
|
||||
list_of_param_assignments<varp>: // ==IEEE: list_of_param_assignments
|
||||
@ -2067,16 +2071,25 @@ instRangeE<rangep>:
|
||||
| '[' constExpr ':' constExpr ']' { $$ = new AstRange($1,$2,$4); }
|
||||
;
|
||||
|
||||
cellparamList<pinp>:
|
||||
{VARRESET_LIST(UNKNOWN);} cellparamItList { $$ = $2; VARRESET_NONLIST(UNKNOWN); }
|
||||
;
|
||||
|
||||
cellpinList<pinp>:
|
||||
{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; }
|
||||
| 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 ()
|
||||
/* empty: ',,' is legal */ { $$ = new AstPin(CRELINE(),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 ':' expr ')' { }
|
||||
// // For parameters
|
||||
//UNSUP '.' idAny '(' data_type ')' { PINDONE($1,$2,$4); GRAMMARP->pinNumInc(); }
|
||||
| '.' idAny '(' data_type ')' { $$ = new AstPin($1,PINNUMINC(),*$2,$4); }
|
||||
// // 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); }
|
||||
//UNSUP expr ':' expr { }
|
||||
|
@ -55,10 +55,12 @@ module mod_typ #(
|
||||
parameter type TYP = byte
|
||||
)(
|
||||
input logic clk,
|
||||
output TYP cnt = 0,
|
||||
output TYP cnt,
|
||||
output int siz
|
||||
);
|
||||
|
||||
initial cnt = 0;
|
||||
|
||||
always @ (posedge clk)
|
||||
cnt <= cnt + 1;
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user