Ignore gate delays in UDP cells
This commit is contained in:
parent
a94f5ba200
commit
2950f77dbc
|
|
@ -873,6 +873,7 @@ struct AstModule : public AstNodeModule {
|
||||||
AstModule(FileLine* fl, const string& name)
|
AstModule(FileLine* fl, const string& name)
|
||||||
: AstNodeModule (fl,name) {}
|
: AstNodeModule (fl,name) {}
|
||||||
ASTNODE_NODE_FUNCS(Module, MODULE)
|
ASTNODE_NODE_FUNCS(Module, MODULE)
|
||||||
|
virtual string verilogKwd() const { return "module"; }
|
||||||
};
|
};
|
||||||
|
|
||||||
struct AstPackage : public AstNodeModule {
|
struct AstPackage : public AstNodeModule {
|
||||||
|
|
@ -880,10 +881,19 @@ struct AstPackage : public AstNodeModule {
|
||||||
AstPackage(FileLine* fl, const string& name)
|
AstPackage(FileLine* fl, const string& name)
|
||||||
: AstNodeModule (fl,name) {}
|
: AstNodeModule (fl,name) {}
|
||||||
ASTNODE_NODE_FUNCS(Package, PACKAGE)
|
ASTNODE_NODE_FUNCS(Package, PACKAGE)
|
||||||
|
virtual string verilogKwd() const { return "package"; }
|
||||||
static string dollarUnitName() { return AstNode::encodeName("$unit"); }
|
static string dollarUnitName() { return AstNode::encodeName("$unit"); }
|
||||||
bool isDollarUnit() const { return name() == dollarUnitName(); }
|
bool isDollarUnit() const { return name() == dollarUnitName(); }
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct AstPrimitive : public AstNodeModule {
|
||||||
|
// A primitive declaration
|
||||||
|
AstPrimitive(FileLine* fl, const string& name)
|
||||||
|
: AstNodeModule (fl,name) {}
|
||||||
|
ASTNODE_NODE_FUNCS(Primitive, PRIMITIVE)
|
||||||
|
virtual string verilogKwd() const { return "primitive"; }
|
||||||
|
};
|
||||||
|
|
||||||
struct AstPackageImport : public AstNode {
|
struct AstPackageImport : public AstNode {
|
||||||
private:
|
private:
|
||||||
// A package import declaration
|
// A package import declaration
|
||||||
|
|
|
||||||
|
|
@ -66,10 +66,10 @@ class EmitVBaseVisitor : public EmitCBaseVisitor {
|
||||||
virtual void visit(AstNetlist* nodep, AstNUser*) {
|
virtual void visit(AstNetlist* nodep, AstNUser*) {
|
||||||
nodep->iterateChildren(*this);
|
nodep->iterateChildren(*this);
|
||||||
}
|
}
|
||||||
virtual void visit(AstModule* nodep, AstNUser*) {
|
virtual void visit(AstNodeModule* nodep, AstNUser*) {
|
||||||
putfs(nodep, "module "+modClassName(nodep)+";\n");
|
putfs(nodep, nodep->verilogKwd()+" "+modClassName(nodep)+";\n");
|
||||||
nodep->iterateChildren(*this);
|
nodep->iterateChildren(*this);
|
||||||
putqs(nodep, "endmodule\n");
|
putqs(nodep, "end"+nodep->verilogKwd()+"\n");
|
||||||
}
|
}
|
||||||
virtual void visit(AstNodeFTask* nodep, AstNUser*) {
|
virtual void visit(AstNodeFTask* nodep, AstNUser*) {
|
||||||
putfs(nodep, nodep->isFunction() ? "function":"task");
|
putfs(nodep, nodep->isFunction() ? "function":"task");
|
||||||
|
|
|
||||||
|
|
@ -67,6 +67,7 @@ private:
|
||||||
// STATE
|
// STATE
|
||||||
// Below state needs to be preserved between each module call.
|
// Below state needs to be preserved between each module call.
|
||||||
AstPackage* m_packagep; // Current package
|
AstPackage* m_packagep; // Current package
|
||||||
|
AstCell* m_cellp; // Current cell
|
||||||
AstNodeModule* m_modp; // Current module
|
AstNodeModule* m_modp; // Current module
|
||||||
AstNodeFTask* m_ftaskp; // Current function/task
|
AstNodeFTask* m_ftaskp; // Current function/task
|
||||||
IdState m_idState; // Id linking mode (find or resolve)
|
IdState m_idState; // Id linking mode (find or resolve)
|
||||||
|
|
@ -215,6 +216,7 @@ private:
|
||||||
virtual void visit(AstNodeModule* nodep, AstNUser*) {
|
virtual void visit(AstNodeModule* nodep, AstNUser*) {
|
||||||
// Module: Create sim table for entire module and iterate
|
// Module: Create sim table for entire module and iterate
|
||||||
UINFO(2,"Link Module: "<<nodep<<endl);
|
UINFO(2,"Link Module: "<<nodep<<endl);
|
||||||
|
AstCell* upperCellp = m_cellp;
|
||||||
V3SymTable* upperVarsp = m_curVarsp;
|
V3SymTable* upperVarsp = m_curVarsp;
|
||||||
{
|
{
|
||||||
m_modp = nodep;
|
m_modp = nodep;
|
||||||
|
|
@ -229,6 +231,7 @@ private:
|
||||||
UINFO(9, "New module scope "<<m_curVarsp<<endl);
|
UINFO(9, "New module scope "<<m_curVarsp<<endl);
|
||||||
}
|
}
|
||||||
// This state must be save/restored in the cell visitor function
|
// This state must be save/restored in the cell visitor function
|
||||||
|
m_cellp = NULL;
|
||||||
m_cellVarsp = NULL;
|
m_cellVarsp = NULL;
|
||||||
m_paramNum = 0;
|
m_paramNum = 0;
|
||||||
m_beginNum = 0;
|
m_beginNum = 0;
|
||||||
|
|
@ -239,6 +242,7 @@ private:
|
||||||
m_packagep = NULL;
|
m_packagep = NULL;
|
||||||
}
|
}
|
||||||
m_curVarsp = upperVarsp;
|
m_curVarsp = upperVarsp;
|
||||||
|
m_cellp = upperCellp;
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual void visit(AstGenerate* nodep, AstNUser*) {
|
virtual void visit(AstGenerate* nodep, AstNUser*) {
|
||||||
|
|
@ -507,6 +511,7 @@ private:
|
||||||
|
|
||||||
virtual void visit(AstCell* nodep, AstNUser*) {
|
virtual void visit(AstCell* nodep, AstNUser*) {
|
||||||
// Cell: Resolve its filename. If necessary, parse it.
|
// Cell: Resolve its filename. If necessary, parse it.
|
||||||
|
m_cellp = nodep;
|
||||||
if (m_idState==ID_FIND) {
|
if (m_idState==ID_FIND) {
|
||||||
// Add to list of all cells, for error checking and defparam's
|
// Add to list of all cells, for error checking and defparam's
|
||||||
findAndInsertAndCheck(nodep, nodep->name());
|
findAndInsertAndCheck(nodep, nodep->name());
|
||||||
|
|
@ -528,6 +533,7 @@ private:
|
||||||
nodep->iterateChildren(*this);
|
nodep->iterateChildren(*this);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
m_cellp = NULL;
|
||||||
// Parent module inherits child's publicity
|
// Parent module inherits child's publicity
|
||||||
// This is done bottom up in the LinkBotupVisitor stage
|
// This is done bottom up in the LinkBotupVisitor stage
|
||||||
}
|
}
|
||||||
|
|
@ -574,12 +580,17 @@ private:
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual void visit(AstPin* nodep, AstNUser*) {
|
virtual void visit(AstPin* nodep, AstNUser*) {
|
||||||
// Pin: Link to submodule's pin
|
// Pin: Link to submodule's port
|
||||||
// ONLY CALLED by AstCell during ID_RESOLVE and ID_PARAM state
|
// ONLY CALLED by AstCell during ID_RESOLVE and ID_PARAM state
|
||||||
if (m_idState==ID_RESOLVE && !nodep->modVarp()) {
|
if (m_idState==ID_RESOLVE && !nodep->modVarp()) {
|
||||||
if (!m_cellVarsp) nodep->v3fatalSrc("Pin not under cell?\n");
|
if (!m_cellVarsp) nodep->v3fatalSrc("Pin not under cell?\n");
|
||||||
AstVar* refp = m_cellVarsp->findIdFlat(nodep->name())->castVar();
|
AstVar* refp = m_cellVarsp->findIdFlat(nodep->name())->castVar();
|
||||||
if (!refp) {
|
if (!refp) {
|
||||||
|
if (nodep->name() == "__paramNumber1" && m_cellp->modp()->castPrimitive()) {
|
||||||
|
// Primitive parameter is really a delay we can just ignore
|
||||||
|
nodep->unlinkFrBack()->deleteTree(); nodep=NULL;
|
||||||
|
return;
|
||||||
|
}
|
||||||
nodep->v3error("Pin not found: "<<nodep->prettyName());
|
nodep->v3error("Pin not found: "<<nodep->prettyName());
|
||||||
} else if (!refp->isIO() && !refp->isParam()) {
|
} else if (!refp->isIO() && !refp->isParam()) {
|
||||||
nodep->v3error("Pin is not an in/out/inout/param: "<<nodep->prettyName());
|
nodep->v3error("Pin is not an in/out/inout/param: "<<nodep->prettyName());
|
||||||
|
|
@ -592,6 +603,7 @@ private:
|
||||||
if (m_idState==ID_PARAM && !nodep->svImplicit()) { // SV 19.11.3: .name pins don't allow implicit decls
|
if (m_idState==ID_PARAM && !nodep->svImplicit()) { // SV 19.11.3: .name pins don't allow implicit decls
|
||||||
pinImplicitExprRecurse(nodep->exprp());
|
pinImplicitExprRecurse(nodep->exprp());
|
||||||
}
|
}
|
||||||
|
// Early return() above when deleted
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual void visit(AstAssignW* nodep, AstNUser*) {
|
virtual void visit(AstAssignW* nodep, AstNUser*) {
|
||||||
|
|
@ -617,7 +629,7 @@ private:
|
||||||
// Unsupported gates need implicit creation
|
// Unsupported gates need implicit creation
|
||||||
pinImplicitExprRecurse(nodep);
|
pinImplicitExprRecurse(nodep);
|
||||||
// We're done with implicit gates
|
// We're done with implicit gates
|
||||||
nodep->unlinkFrBack()->deleteTree();
|
nodep->unlinkFrBack()->deleteTree(); nodep=NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual void visit(AstDefParam* nodep, AstNUser*) {
|
virtual void visit(AstDefParam* nodep, AstNUser*) {
|
||||||
|
|
@ -666,6 +678,7 @@ public:
|
||||||
LinkVisitor(AstNetlist* rootp) {
|
LinkVisitor(AstNetlist* rootp) {
|
||||||
m_curVarsp = NULL;
|
m_curVarsp = NULL;
|
||||||
m_cellVarsp = NULL;
|
m_cellVarsp = NULL;
|
||||||
|
m_cellp = NULL;
|
||||||
m_modp = NULL;
|
m_modp = NULL;
|
||||||
m_ftaskp = NULL;
|
m_ftaskp = NULL;
|
||||||
m_packagep = NULL;
|
m_packagep = NULL;
|
||||||
|
|
|
||||||
|
|
@ -694,7 +694,7 @@ modFront<modulep>:
|
||||||
|
|
||||||
udpFront<modulep>:
|
udpFront<modulep>:
|
||||||
yPRIMITIVE lifetimeE idAny
|
yPRIMITIVE lifetimeE idAny
|
||||||
{ $$ = new AstModule($1,*$3); $$->inLibrary(true);
|
{ $$ = new AstPrimitive($1,*$3); $$->inLibrary(true);
|
||||||
$$->modTrace(false);
|
$$->modTrace(false);
|
||||||
$$->addStmtp(new AstPragma($1,AstPragmaType::INLINE_MODULE));
|
$$->addStmtp(new AstPragma($1,AstPragmaType::INLINE_MODULE));
|
||||||
PARSEP->fileline()->tracingOn(false);
|
PARSEP->fileline()->tracingOn(false);
|
||||||
|
|
@ -708,6 +708,7 @@ parameter_value_assignmentE<pinp>: // IEEE: [ parameter_value_assignment ]
|
||||||
| '#' '(' cellpinList ')' { $$ = $3; }
|
| '#' '(' cellpinList ')' { $$ = $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)))); }
|
||||||
| '#' idClassSel { $$ = new AstPin($1,1,"",$2); }
|
| '#' idClassSel { $$ = new AstPin($1,1,"",$2); }
|
||||||
// // Not needed in Verilator:
|
// // Not needed in Verilator:
|
||||||
// // Side effect of combining *_instantiations
|
// // Side effect of combining *_instantiations
|
||||||
|
|
@ -1655,6 +1656,8 @@ cellpinItemE<pinp>: // IEEE: named_port_connection + named_parameter_assignment
|
||||||
//UNSUP data_type { PINDONE($1->fileline(),"",$1); GRAMMARP->pinNumInc(); }
|
//UNSUP data_type { PINDONE($1->fileline(),"",$1); GRAMMARP->pinNumInc(); }
|
||||||
//
|
//
|
||||||
| expr { $$ = new AstPin($1->fileline(),PINNUMINC(),"",$1); }
|
| expr { $$ = new AstPin($1->fileline(),PINNUMINC(),"",$1); }
|
||||||
|
// // Floatnum should only occur with UDPs, but since ports aren't floats, it's legal to round always
|
||||||
|
| yaFLOATNUM { $$ = new AstPin($<fl>1,PINNUMINC(),"",new AstConst($<fl>1,AstConst::Unsized32(),(int)(($1<0)?($1-0.5):($1+0.5)))); }
|
||||||
;
|
;
|
||||||
|
|
||||||
//************************************************
|
//************************************************
|
||||||
|
|
|
||||||
|
|
@ -31,9 +31,9 @@ module t (/*AUTOARG*/
|
||||||
|
|
||||||
//====== Mux
|
//====== Mux
|
||||||
wire [1:0] qm;
|
wire [1:0] qm;
|
||||||
// z a b sel
|
// delay z a b sel
|
||||||
udp_mux2 m0 (qm[0], in[0], in[2], in[4]);
|
udp_mux2 #(0.1) m0 (qm[0], in[0], in[2], in[4]);
|
||||||
udp_mux2 m1 (qm[1], in[1], in[3], in[4]);
|
udp_mux2 #0.1 m1 (qm[1], in[1], in[3], in[4]);
|
||||||
|
|
||||||
`define verilatorxx
|
`define verilatorxx
|
||||||
`ifdef verilatorxx
|
`ifdef verilatorxx
|
||||||
|
|
|
||||||
|
|
@ -13,7 +13,7 @@ compile (
|
||||||
# Unsupported: UDP Tables
|
# Unsupported: UDP Tables
|
||||||
make_top_shell => 0,
|
make_top_shell => 0,
|
||||||
make_main => 0,
|
make_main => 0,
|
||||||
v_flags2 => ["--lint-only --bbox-unsup"],
|
verilator_flags2 => ["--lint-only --bbox-unsup"],
|
||||||
verilator_make_gcc => 0,
|
verilator_make_gcc => 0,
|
||||||
);
|
);
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue