From a94f5ba200a737297f41c8ec4d805eabf1e1adcb Mon Sep 17 00:00:00 2001 From: Wilson Snyder Date: Thu, 7 Jan 2010 22:08:48 -0500 Subject: [PATCH] --bbox-unsup now ignores cmos and tran gate primitives --- bin/verilator | 5 +++-- src/V3AstNodes.h | 11 +++++++++ src/V3Link.cpp | 16 +++++++++++++ src/V3ParseImp.h | 1 + src/verilog.l | 24 ++++++++++---------- src/verilog.y | 41 ++++++++++++++++++++++++++++++++-- test_regress/t/t_gate_basic.v | 2 +- test_regress/t/t_gate_unsup.pl | 19 ++++++++++++++++ test_regress/t/t_gate_unsup.v | 33 +++++++++++++++++++++++++++ 9 files changed, 135 insertions(+), 17 deletions(-) create mode 100755 test_regress/t/t_gate_unsup.pl create mode 100644 test_regress/t/t_gate_unsup.v diff --git a/bin/verilator b/bin/verilator index 1b3368287..cec8685a1 100755 --- a/bin/verilator +++ b/bin/verilator @@ -296,8 +296,9 @@ calls. =item --bbox-unsup -Black box some unsupported language features, currently UDP tables. This -may allow linting when unsupported constructs are present. +Black box some unsupported language features, currently UDP tables and the +cmos and tran gate primitives. This may enable linting the rest of the +design even when unsupported constructs are present. =item --bin I diff --git a/src/V3AstNodes.h b/src/V3AstNodes.h index e626bbf42..651a1f0f4 100644 --- a/src/V3AstNodes.h +++ b/src/V3AstNodes.h @@ -689,6 +689,17 @@ public: string path() const { return m_path; } }; +struct AstImplicit : public AstNode { + // Create implicit wires and do nothing else, for gates that are ignored + // Parents: MODULE + AstImplicit(FileLine* fl, AstNode* exprsp) + : AstNode(fl) { + addNOp1p(exprsp); + } + ASTNODE_NODE_FUNCS(Implicit, IMPLICIT) + AstNode* exprsp() const { return op1p()->castNode(); } // op1 = Assign from +}; + struct AstScope : public AstNode { // A particular usage of a cell // Parents: MODULE diff --git a/src/V3Link.cpp b/src/V3Link.cpp index 84653efd1..6285d06b4 100644 --- a/src/V3Link.cpp +++ b/src/V3Link.cpp @@ -603,6 +603,22 @@ private: } nodep->iterateChildren(*this); } + virtual void visit(AstAssignAlias* nodep, AstNUser*) { + // tran gates need implicit creation + if (AstVarRef* forrefp = nodep->lhsp()->castVarRef()) { + createImplicitVar(forrefp, false); + } + if (AstVarRef* forrefp = nodep->rhsp()->castVarRef()) { + createImplicitVar(forrefp, false); + } + nodep->iterateChildren(*this); + } + virtual void visit(AstImplicit* nodep, AstNUser*) { + // Unsupported gates need implicit creation + pinImplicitExprRecurse(nodep); + // We're done with implicit gates + nodep->unlinkFrBack()->deleteTree(); + } virtual void visit(AstDefParam* nodep, AstNUser*) { nodep->iterateChildren(*this); diff --git a/src/V3ParseImp.h b/src/V3ParseImp.h index a930d9bba..cbcbf2129 100644 --- a/src/V3ParseImp.h +++ b/src/V3ParseImp.h @@ -76,6 +76,7 @@ struct V3ParseBisonYYSType { AstRange* rangep; AstSenTree* sentreep; AstVar* varp; + AstVarRef* varrefp; }; }; diff --git a/src/verilog.l b/src/verilog.l index de03de3c1..a859b0b06 100644 --- a/src/verilog.l +++ b/src/verilog.l @@ -203,6 +203,7 @@ escid \\[^ \t\f\r\n]+ "case" { FL; return yCASE; } "casex" { FL; return yCASEX; } "casez" { FL; return yCASEZ; } + "cmos" { FL; return yCMOS; } "default" { FL; return yDEFAULT; } "defparam" { FL; return yDEFPARAM; } "disable" { FL; return yDISABLE; } @@ -228,6 +229,7 @@ escid \\[^ \t\f\r\n]+ "module" { FL; return yMODULE; } "nand" { FL; return yNAND; } "negedge" { FL; return yNEGEDGE; } + "nmos" { FL; return yNMOS; } "nor" { FL; return yNOR; } "not" { FL; return yNOT; } "notif0" { FL; return yNOTIF0; } @@ -235,12 +237,19 @@ escid \\[^ \t\f\r\n]+ "or" { FL; return yOR; } "output" { FL; return yOUTPUT; } "parameter" { FL; return yPARAMETER; } + "pmos" { FL; return yPMOS; } "posedge" { FL; return yPOSEDGE; } "primitive" { FL; return yPRIMITIVE; } "pulldown" { FL; return yPULLDOWN; } "pullup" { FL; return yPULLUP; } + "rcmos" { FL; return yRCMOS; } "reg" { FL; return yREG; } "repeat" { FL; return yREPEAT; } + "rnmos" { FL; return yRNMOS; } + "rpmos" { FL; return yRPMOS; } + "rtran" { FL; return yRTRAN; } + "rtranif0" { FL; return yRTRANIF0; } + "rtranif1" { FL; return yRTRANIF1; } "scalared" { FL; return ySCALARED; } "specify" { FL; return ySPECIFY; } "specparam" { FL; return ySPECPARAM; } @@ -249,6 +258,9 @@ escid \\[^ \t\f\r\n]+ "table" { yy_push_state(TABLE); FL; return yTABLE; } "task" { FL; return yTASK; } "time" { FL; return yTIME; } + "tran" { FL; return yTRAN; } + "tranif0" { FL; return yTRANIF0; } + "tranif1" { FL; return yTRANIF1; } "tri" { FL; return yTRI; } "vectored" { FL; return yVECTORED; } "while" { FL; return yWHILE; } @@ -269,7 +281,6 @@ escid \\[^ \t\f\r\n]+ "$writeh" { FL; RETURN_BBOX_SYS_OR_MSG("Unsupported: Use $write with %%x format instead: %s",yytext); } "$writeo" { FL; RETURN_BBOX_SYS_OR_MSG("Unsupported: Use $write with %%o format instead: %s",yytext); } /* Generic unsupported warnings */ - "cmos" { yyerrorf("Unsupported: Verilog 1995 reserved word not implemented: %s",yytext); } "deassign" { yyerrorf("Unsupported: Verilog 1995 reserved word not implemented: %s",yytext); } "event" { yyerrorf("Unsupported: Verilog 1995 reserved word not implemented: %s",yytext); } "force" { yyerrorf("Unsupported: Verilog 1995 reserved word not implemented: %s",yytext); } @@ -279,25 +290,14 @@ escid \\[^ \t\f\r\n]+ "join" { yyerrorf("Unsupported: Verilog 1995 reserved word not implemented: %s",yytext); } "large" { yyerrorf("Unsupported: Verilog 1995 reserved word not implemented: %s",yytext); } "medium" { yyerrorf("Unsupported: Verilog 1995 reserved word not implemented: %s",yytext); } - "nmos" { yyerrorf("Unsupported: Verilog 1995 reserved word not implemented: %s",yytext); } - "pmos" { yyerrorf("Unsupported: Verilog 1995 reserved word not implemented: %s",yytext); } "pull0" { yyerrorf("Unsupported: Verilog 1995 reserved word not implemented: %s",yytext); } "pull1" { yyerrorf("Unsupported: Verilog 1995 reserved word not implemented: %s",yytext); } - "rcmos" { yyerrorf("Unsupported: Verilog 1995 reserved word not implemented: %s",yytext); } "real" { yyerrorf("Unsupported: Verilog 1995 reserved word not implemented: %s",yytext); } "realtime" { yyerrorf("Unsupported: Verilog 1995 reserved word not implemented: %s",yytext); } "release" { yyerrorf("Unsupported: Verilog 1995 reserved word not implemented: %s",yytext); } - "rnmos" { yyerrorf("Unsupported: Verilog 1995 reserved word not implemented: %s",yytext); } - "rpmos" { yyerrorf("Unsupported: Verilog 1995 reserved word not implemented: %s",yytext); } - "rtran" { yyerrorf("Unsupported: Verilog 1995 reserved word not implemented: %s",yytext); } - "rtranif0" { yyerrorf("Unsupported: Verilog 1995 reserved word not implemented: %s",yytext); } - "rtranif1" { yyerrorf("Unsupported: Verilog 1995 reserved word not implemented: %s",yytext); } "small" { yyerrorf("Unsupported: Verilog 1995 reserved word not implemented: %s",yytext); } "strong0" { yyerrorf("Unsupported: Verilog 1995 reserved word not implemented: %s",yytext); } "strong1" { yyerrorf("Unsupported: Verilog 1995 reserved word not implemented: %s",yytext); } - "tran" { yyerrorf("Unsupported: Verilog 1995 reserved word not implemented: %s",yytext); } - "tranif0" { yyerrorf("Unsupported: Verilog 1995 reserved word not implemented: %s",yytext); } - "tranif1" { yyerrorf("Unsupported: Verilog 1995 reserved word not implemented: %s",yytext); } "triand" { yyerrorf("Unsupported: Verilog 1995 reserved word not implemented: %s",yytext); } "trior" { yyerrorf("Unsupported: Verilog 1995 reserved word not implemented: %s",yytext); } "trireg" { yyerrorf("Unsupported: Verilog 1995 reserved word not implemented: %s",yytext); } diff --git a/src/verilog.y b/src/verilog.y index 3cff31871..a23fcb516 100644 --- a/src/verilog.y +++ b/src/verilog.y @@ -36,7 +36,7 @@ // Pick up new lexer #define yylex PARSEP->lexToBison -#define PSLUNSUP(what) NULL; yyerrorf("Unsupported: PSL language feature not implemented"); +#define GATEUNSUP(fl,tok) { if (!v3Global.opt.bboxUnsup()) { (fl)->v3error("Unsupported: Verilog 1995 gate primitive: "<<(tok)); } } extern void yyerror(const char* errmsg); extern void yyerrorf(const char* format, ...); @@ -264,6 +264,7 @@ class AstSenTree; %token yCASEZ "casez" %token yCHANDLE "chandle" %token yCLOCKING "clocking" +%token yCMOS "cmos" %token yCONTEXT "context" %token yCOVER "cover" %token yDEFAULT "default" @@ -307,6 +308,7 @@ class AstSenTree; %token yMODULE "module" %token yNAND "nand" %token yNEGEDGE "negedge" +%token yNMOS "nmos" %token yNOR "nor" %token yNOT "not" %token yNOTIF0 "notif0" @@ -315,6 +317,7 @@ class AstSenTree; %token yOUTPUT "output" %token yPACKAGE "package" %token yPARAMETER "parameter" +%token yPMOS "pmos" %token yPOSEDGE "posedge" %token yPRIMITIVE "primitive" %token yPRIORITY "priority" @@ -323,8 +326,14 @@ class AstSenTree; %token yPULLDOWN "pulldown" %token yPULLUP "pullup" %token yPURE "pure" +%token yRCMOS "rcmos" %token yREG "reg" %token yREPEAT "repeat" +%token yRNMOS "rnmos" +%token yRPMOS "rpmos" +%token yRTRAN "rtran" +%token yRTRANIF0 "rtranif0" +%token yRTRANIF1 "rtranif1" %token ySCALARED "scalared" %token ySHORTINT "shortint" %token ySIGNED "signed" @@ -339,6 +348,9 @@ class AstSenTree; %token yTIME "time" %token yTIMEPRECISION "timeprecision" %token yTIMEUNIT "timeunit" +%token yTRAN "tran" +%token yTRANIF0 "tranif0" +%token yTRANIF1 "tranif1" %token yTRI "tri" %token yTRUE "true" %token yTYPEDEF "typedef" @@ -2524,6 +2536,19 @@ gateDecl: | yXNOR delayE gateXnorList ';' { $$ = $3; } | yPULLUP delayE gatePullupList ';' { $$ = $3; } | yPULLDOWN delayE gatePulldownList ';' { $$ = $3; } + // + | yTRAN delayE gateUnsupList ';' { $$ = $3; GATEUNSUP($3,"tran"); } // Unsupported + | yNMOS delayE gateUnsupList ';' { $$ = $3; GATEUNSUP($3,"nmos"); } // Unsupported + | yPMOS delayE gateUnsupList ';' { $$ = $3; GATEUNSUP($3,"pmos"); } // Unsupported + | yRCMOS delayE gateUnsupList ';' { $$ = $3; GATEUNSUP($3,"rcmos"); } // Unsupported + | yCMOS delayE gateUnsupList ';' { $$ = $3; GATEUNSUP($3,"cmos"); } // Unsupported + | yRNMOS delayE gateUnsupList ';' { $$ = $3; GATEUNSUP($3,"rmos"); } // Unsupported + | yRPMOS delayE gateUnsupList ';' { $$ = $3; GATEUNSUP($3,"pmos"); } // Unsupported + | yRTRAN delayE gateUnsupList ';' { $$ = $3; GATEUNSUP($3,"rtran"); } // Unsupported + | yRTRANIF0 delayE gateUnsupList ';' { $$ = $3; GATEUNSUP($3,"rtranif0"); } // Unsupported + | yRTRANIF1 delayE gateUnsupList ';' { $$ = $3; GATEUNSUP($3,"rtranif1"); } // Unsupported + | yTRANIF0 delayE gateUnsupList ';' { $$ = $3; GATEUNSUP($3,"tranif0"); } // Unsupported + | yTRANIF1 delayE gateUnsupList ';' { $$ = $3; GATEUNSUP($3,"tranif1"); } // Unsupported ; gateBufList: @@ -2582,6 +2607,10 @@ gatePulldownList: gatePulldown { $$ = $1; } | gatePulldownList ',' gatePulldown { $$ = $1->addNext($3); } ; +gateUnsupList: + gateUnsup { $$ = $1; } + | gateUnsupList ',' gateUnsup { $$ = $1->addNext($3); } + ; gateBuf: gateIdE instRangeE '(' idClassSel ',' expr ')' { $$ = new AstAssignW ($3,$4,$6); } @@ -2625,6 +2654,10 @@ gatePullup: gatePulldown: gateIdE instRangeE '(' idClassSel ')' { $$ = new AstPull ($3, $4, false); } ; +gateUnsup: + gateIdE instRangeE '(' gateUnsupPinList ')' { $$ = new AstImplicit ($3,$4); } + ; + gateIdE: /*empty*/ {} | id {} @@ -2642,6 +2675,10 @@ gateXorPinList: expr { $$ = $1; } | gateXorPinList ',' expr { $$ = new AstXor($2,$1,$3); } ; +gateUnsupPinList: + expr { $$ = $1; } + | gateUnsupPinList ',' expr { $$ = $1->addNext($3); } + ; strengthSpecE: // IEEE: drive_strength + pullup_strength + pulldown_strength + charge_strength - plus empty /* empty */ { } @@ -2773,7 +2810,7 @@ idArrayed: // IEEE: id + select ; // VarRef without any dots or vectorizaion -varRefBase: +varRefBase: id { $$ = new AstVarRef(CRELINE(),*$1,false);} ; diff --git a/test_regress/t/t_gate_basic.v b/test_regress/t/t_gate_basic.v index 5417c4370..4d5e87c44 100644 --- a/test_regress/t/t_gate_basic.v +++ b/test_regress/t/t_gate_basic.v @@ -19,7 +19,7 @@ module t (/*AUTOARG*/ BF2 (bf[2], a[2]); // verilator lint_off IMPLICIT - not NT0 (nt0, a[0]); + not #(0.108) NT0 (nt0, a[0]); and #1 AN0 (an0, a[0], b[0]); nand #(2,3) ND0 (nd0, a[0], b[0], b[1]); or OR0 (or0, a[0], b[0]); diff --git a/test_regress/t/t_gate_unsup.pl b/test_regress/t/t_gate_unsup.pl new file mode 100755 index 000000000..cf12070f2 --- /dev/null +++ b/test_regress/t/t_gate_unsup.pl @@ -0,0 +1,19 @@ +#!/usr/bin/perl +if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } +# DESCRIPTION: Verilator: Verilog Test driver/expect definition +# +# Copyright 2003 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. + +compile ( + # Unsupported: UDP Tables + make_top_shell => 0, + make_main => 0, + verilator_flags2 => ["--lint-only --bbox-unsup"], + verilator_make_gcc => 0, + ); + +ok(1); +1; diff --git a/test_regress/t/t_gate_unsup.v b/test_regress/t/t_gate_unsup.v new file mode 100644 index 000000000..e48be1f9d --- /dev/null +++ b/test_regress/t/t_gate_unsup.v @@ -0,0 +1,33 @@ +// DESCRIPTION: Verilator: Verilog Test module +// +// This file ONLY is placed into the Public Domain, for any use, +// without warranty, 2004 by Wilson Snyder. + +module t (/*AUTOARG*/); + + wire d, en, nc, pc; + + // verilator lint_off IMPLICIT + cmos (cm0, d, nc, pc); + rcmos (rc0, d, nc, pc); + + nmos (nm0, d, en); + pmos (pm0, d, en); + rnmos (rn0, d, en); + rpmos (rp0, d, en); + + rtran (rt0, d); + tran (tr0, d); + + rtranif0 (r00, d, en); + rtranif1 (r10, d, en); + tranif0 (t00, d, en); + tranif1 (t10, d, en); + // verilator lint_on IMPLICIT + + initial begin + $write("*-* All Finished *-*\n"); + $finish; + end + +endmodule