Support unique0; track internally with new attributes

This commit is contained in:
Wilson Snyder 2010-12-25 21:58:28 -05:00
parent 3e4e8feb29
commit e94fc1305b
7 changed files with 62 additions and 18 deletions

View File

@ -231,7 +231,7 @@ descriptions in the next sections for more information.
--bbox-sys Blackbox unknown $system calls --bbox-sys Blackbox unknown $system calls
--bbox-unsup Blackbox unsupported language features --bbox-unsup Blackbox unsupported language features
--bin <filename> Override Verilator binary --bin <filename> Override Verilator binary
-CFLAGS <flags> C++ Compiler flags for makefile -CFLAGS <flags> C++ Compiler flags for makefile
--cc Create C++ output --cc Create C++ output
--cdc Clock domain crossing analysis --cdc Clock domain crossing analysis
--compiler <compiler-name> Tune for specified C++ compiler --compiler <compiler-name> Tune for specified C++ compiler
@ -247,19 +247,19 @@ descriptions in the next sections for more information.
--debugi-<srcfile> <level> Enable debugging a source file at a level --debugi-<srcfile> <level> Enable debugging a source file at a level
+define+<var>+<value> Set preprocessor define +define+<var>+<value> Set preprocessor define
--dump-tree Enable dumping .tree files --dump-tree Enable dumping .tree files
-E Preprocess, but do not compile -E Preprocess, but do not compile
--error-limit <value> Abort after this number of errors --error-limit <value> Abort after this number of errors
--exe Link to create executable --exe Link to create executable
-F <file> Parse options from a file, relatively -F <file> Parse options from a file, relatively
-f <file> Parse options from a file -f <file> Parse options from a file
--gdbbt Run Verilator under GDB for backtrace --gdbbt Run Verilator under GDB for backtrace
--help Display this help. --help Display this help
-I<dir> Directory to search for includes -I<dir> Directory to search for includes
+incdir+<dir> Directory to search for includes +incdir+<dir> Directory to search for includes
--inhibit-sim Create function to turn off sim --inhibit-sim Create function to turn off sim
--inline-mult <value> Tune module inlining --inline-mult <value> Tune module inlining
-LDFLAGS <flags> Linker pre-object flags for makefile -LDFLAGS <flags> Linker pre-object flags for makefile
-LDLIBS <flags> Linker library flags for makefile -LDLIBS <flags> Linker library flags for makefile
--language <lang> Language standard to parse --language <lang> Language standard to parse
+libext+<ext>+[ext]... Extensions for finding modules +libext+<ext>+[ext]... Extensions for finding modules
--lint-only Lint, but do not make output --lint-only Lint, but do not make output
@ -273,12 +273,12 @@ descriptions in the next sections for more information.
-O0 Disable optimizations -O0 Disable optimizations
-O3 High performance optimizations -O3 High performance optimizations
-O<optimization-letter> Selectable optimizations -O<optimization-letter> Selectable optimizations
-o <executable> Name of final executable -o <executable> Name of final executable
--output-split <bytes> Split .cpp files into pieces --output-split <bytes> Split .cpp files into pieces
--output-split-cfuncs <statements> Split .ccp functions --output-split-cfuncs <statements> Split .ccp functions
--pins-bv <bits> Specify types for top level ports --pins-bv <bits> Specify types for top level ports
--pins-uint8 Specify types for top level ports --pins-uint8 Specify types for top level ports
--pipe-filter <command> Filter all input through a script --pipe-filter <command> Filter all input through a script
--prefix <topname> Name of top level class --prefix <topname> Name of top level class
--profile-cfuncs Name functions for profiling --profile-cfuncs Name functions for profiling
--private Debugging; see docs --private Debugging; see docs

View File

@ -182,7 +182,7 @@ private:
for (AstCaseItem* itemp = nodep->itemsp(); itemp; itemp=itemp->nextp()->castCaseItem()) { for (AstCaseItem* itemp = nodep->itemsp(); itemp; itemp=itemp->nextp()->castCaseItem()) {
if (itemp->isDefault()) has_default=true; if (itemp->isDefault()) has_default=true;
} }
if (nodep->fullPragma()) { if (nodep->fullPragma() || nodep->priorityPragma()) {
// Simply need to add a default if there isn't one already // Simply need to add a default if there isn't one already
m_statAsFull++; m_statAsFull++;
if (!has_default) { if (!has_default) {
@ -190,7 +190,7 @@ private:
newFireAssert(nodep, "synthesis full_case, but non-match found"))); newFireAssert(nodep, "synthesis full_case, but non-match found")));
} }
} }
if (nodep->parallelPragma()) { if (nodep->parallelPragma() || nodep->uniquePragma() || nodep->unique0Pragma()) {
// Need to check that one, and only one of the case items match at any moment // Need to check that one, and only one of the case items match at any moment
// If there's a default, we allow none to match, else exactly one must match // If there's a default, we allow none to match, else exactly one must match
m_statAsFull++; m_statAsFull++;
@ -207,7 +207,8 @@ private:
else propp = onep; else propp = onep;
} }
} }
AstNode* ohot = (has_default bool allow_none = has_default || nodep->unique0Pragma();
AstNode* ohot = (allow_none
? (new AstOneHot0(nodep->fileline(), propp))->castNode() ? (new AstOneHot0(nodep->fileline(), propp))->castNode()
: (new AstOneHot (nodep->fileline(), propp))->castNode()); : (new AstOneHot (nodep->fileline(), propp))->castNode());
AstIf* ifp = new AstIf (nodep->fileline(), AstIf* ifp = new AstIf (nodep->fileline(),

View File

@ -1538,11 +1538,15 @@ private:
AstCaseType m_casex; // 0=case, 1=casex, 2=casez AstCaseType m_casex; // 0=case, 1=casex, 2=casez
bool m_fullPragma; // Synthesis full_case bool m_fullPragma; // Synthesis full_case
bool m_parallelPragma; // Synthesis parallel_case bool m_parallelPragma; // Synthesis parallel_case
bool m_uniquePragma; // unique case
bool m_unique0Pragma; // unique0 case
bool m_priorityPragma; // priority case
public: public:
AstCase(FileLine* fileline, AstCaseType casex, AstNode* exprp, AstNode* casesp) AstCase(FileLine* fileline, AstCaseType casex, AstNode* exprp, AstNode* casesp)
: AstNodeCase(fileline, exprp, casesp) { : AstNodeCase(fileline, exprp, casesp) {
m_casex=casex; m_casex=casex;
m_fullPragma=false; m_parallelPragma=false; m_fullPragma=false; m_parallelPragma=false;
m_uniquePragma=false; m_unique0Pragma=false; m_priorityPragma=false;
} }
ASTNODE_NODE_FUNCS(Case, CASE) ASTNODE_NODE_FUNCS(Case, CASE)
virtual string verilogKwd() const { return casez()?"casez":casex()?"casex":"case"; } virtual string verilogKwd() const { return casez()?"casez":casex()?"casex":"case"; }
@ -1554,6 +1558,12 @@ public:
void fullPragma(bool flag) { m_fullPragma=flag; } void fullPragma(bool flag) { m_fullPragma=flag; }
bool parallelPragma() const { return m_parallelPragma; } bool parallelPragma() const { return m_parallelPragma; }
void parallelPragma(bool flag) { m_parallelPragma=flag; } void parallelPragma(bool flag) { m_parallelPragma=flag; }
bool uniquePragma() const { return m_uniquePragma; }
void uniquePragma(bool flag) { m_uniquePragma=flag; }
bool unique0Pragma() const { return m_unique0Pragma; }
void unique0Pragma(bool flag) { m_unique0Pragma=flag; }
bool priorityPragma() const { return m_priorityPragma; }
void priorityPragma(bool flag) { m_priorityPragma=flag; }
}; };
struct AstCaseItem : public AstNode { struct AstCaseItem : public AstNode {
@ -1952,10 +1962,22 @@ struct AstGenIf : public AstNodeIf {
}; };
struct AstIf : public AstNodeIf { struct AstIf : public AstNodeIf {
private:
bool m_uniquePragma; // unique case
bool m_unique0Pragma; // unique0 case
bool m_priorityPragma; // priority case
public:
AstIf(FileLine* fileline, AstNode* condp, AstNode* ifsp, AstNode* elsesp) AstIf(FileLine* fileline, AstNode* condp, AstNode* ifsp, AstNode* elsesp)
: AstNodeIf(fileline, condp, ifsp, elsesp) { : AstNodeIf(fileline, condp, ifsp, elsesp) {
m_uniquePragma=false; m_unique0Pragma=false; m_priorityPragma=false;
} }
ASTNODE_NODE_FUNCS(If, IF) ASTNODE_NODE_FUNCS(If, IF)
bool uniquePragma() const { return m_uniquePragma; }
void uniquePragma(bool flag) { m_uniquePragma=flag; }
bool unique0Pragma() const { return m_unique0Pragma; }
void unique0Pragma(bool flag) { m_unique0Pragma=flag; }
bool priorityPragma() const { return m_priorityPragma; }
void priorityPragma(bool flag) { m_priorityPragma=flag; }
}; };
struct AstJumpLabel : public AstNodeStmt { struct AstJumpLabel : public AstNodeStmt {

View File

@ -166,7 +166,13 @@ class EmitVBaseVisitor : public EmitCBaseVisitor {
nodep->iterateChildren(*this); nodep->iterateChildren(*this);
} }
virtual void visit(AstNodeCase* nodep, AstNUser*) { virtual void visit(AstNodeCase* nodep, AstNUser*) {
putfs(nodep,nodep->verilogKwd()); putfs(nodep,"");
if (AstCase* casep = nodep->castCase()) {
if (casep->priorityPragma()) puts("priority ");
if (casep->uniquePragma()) puts("unique ");
if (casep->unique0Pragma()) puts("unique0 ");
}
puts(nodep->verilogKwd());
puts(" ("); puts(" (");
nodep->exprp()->iterateAndNext(*this); nodep->exprp()->iterateAndNext(*this);
puts(")\n"); puts(")\n");
@ -301,7 +307,13 @@ class EmitVBaseVisitor : public EmitCBaseVisitor {
putfs(nodep,"end\n"); putfs(nodep,"end\n");
} }
virtual void visit(AstNodeIf* nodep, AstNUser*) { virtual void visit(AstNodeIf* nodep, AstNUser*) {
putfs(nodep,"if ("); putfs(nodep,"");
if (AstIf* ifp = nodep->castIf()) {
if (ifp->priorityPragma()) puts("priority ");
if (ifp->uniquePragma()) puts("unique ");
if (ifp->unique0Pragma()) puts("unique0 ");
}
puts("if (");
nodep->condp()->iterateAndNext(*this); nodep->condp()->iterateAndNext(*this);
puts(") begin\n"); puts(") begin\n");
nodep->ifsp()->iterateAndNext(*this); nodep->ifsp()->iterateAndNext(*this);

View File

@ -38,7 +38,7 @@ class V3Lexer;
//====================================================================== //======================================================================
// Types (between parser & lexer) // Types (between parser & lexer)
typedef enum { uniq_NONE, uniq_UNIQUE, uniq_PRIORITY } V3UniqState; typedef enum { uniq_NONE, uniq_UNIQUE, uniq_UNIQUE0, uniq_PRIORITY } V3UniqState;
typedef enum { iprop_NONE, iprop_CONTEXT, iprop_PURE } V3ImportProperty; typedef enum { iprop_NONE, iprop_CONTEXT, iprop_PURE } V3ImportProperty;

View File

@ -493,6 +493,7 @@ word [a-zA-Z0-9_]+
<S09,PSL>{ <S09,PSL>{
/* Keywords */ /* Keywords */
"global" { FL; return yGLOBAL__LEX; } "global" { FL; return yGLOBAL__LEX; }
"unique0" { FL; return yUNIQUE0; }
/* Generic unsupported warnings */ /* Generic unsupported warnings */
"accept_on" { yyerrorf("Unsupported: SystemVerilog 2009 reserved word not implemented: %s",yytext); } "accept_on" { yyerrorf("Unsupported: SystemVerilog 2009 reserved word not implemented: %s",yytext); }
"checker" { yyerrorf("Unsupported: SystemVerilog 2009 reserved word not implemented: %s",yytext); } "checker" { yyerrorf("Unsupported: SystemVerilog 2009 reserved word not implemented: %s",yytext); }
@ -511,7 +512,6 @@ word [a-zA-Z0-9_]+
"strong" { yyerrorf("Unsupported: SystemVerilog 2009 reserved word not implemented: %s",yytext); } "strong" { yyerrorf("Unsupported: SystemVerilog 2009 reserved word not implemented: %s",yytext); }
"sync_accept_on" { yyerrorf("Unsupported: SystemVerilog 2009 reserved word not implemented: %s",yytext); } "sync_accept_on" { yyerrorf("Unsupported: SystemVerilog 2009 reserved word not implemented: %s",yytext); }
"sync_reject_on" { yyerrorf("Unsupported: SystemVerilog 2009 reserved word not implemented: %s",yytext); } "sync_reject_on" { yyerrorf("Unsupported: SystemVerilog 2009 reserved word not implemented: %s",yytext); }
"unique0" { yyerrorf("Unsupported: SystemVerilog 2009 reserved word not implemented: %s",yytext); }
"until" { yyerrorf("Unsupported: SystemVerilog 2009 reserved word not implemented: %s",yytext); } "until" { yyerrorf("Unsupported: SystemVerilog 2009 reserved word not implemented: %s",yytext); }
"until_with" { yyerrorf("Unsupported: SystemVerilog 2009 reserved word not implemented: %s",yytext); } "until_with" { yyerrorf("Unsupported: SystemVerilog 2009 reserved word not implemented: %s",yytext); }
"untyped" { yyerrorf("Unsupported: SystemVerilog 2009 reserved word not implemented: %s",yytext); } "untyped" { yyerrorf("Unsupported: SystemVerilog 2009 reserved word not implemented: %s",yytext); }

View File

@ -369,6 +369,7 @@ class AstSenTree;
%token<fl> yTRUE "true" %token<fl> yTRUE "true"
%token<fl> yTYPEDEF "typedef" %token<fl> yTYPEDEF "typedef"
%token<fl> yUNIQUE "unique" %token<fl> yUNIQUE "unique"
%token<fl> yUNIQUE0 "unique0"
%token<fl> yUNSIGNED "unsigned" %token<fl> yUNSIGNED "unsigned"
%token<fl> yVAR "var" %token<fl> yVAR "var"
%token<fl> yVECTORED "vectored" %token<fl> yVECTORED "vectored"
@ -1819,16 +1820,23 @@ statement_item<nodep>: // IEEE: statement_item
// //
// // IEEE: case_statement // // IEEE: case_statement
| unique_priorityE caseStart caseAttrE case_itemListE yENDCASE { $$ = $2; if ($4) $2->addItemsp($4); | unique_priorityE caseStart caseAttrE case_itemListE yENDCASE { $$ = $2; if ($4) $2->addItemsp($4);
if ($1 == uniq_UNIQUE) $2->parallelPragma(true); if ($1 == uniq_UNIQUE) $2->uniquePragma(true);
if ($1 == uniq_PRIORITY) $2->fullPragma(true); } if ($1 == uniq_UNIQUE0) $2->unique0Pragma(true);
if ($1 == uniq_PRIORITY) $2->priorityPragma(true); }
//UNSUP caseStart caseAttrE yMATCHES case_patternListE yENDCASE { } //UNSUP caseStart caseAttrE yMATCHES case_patternListE yENDCASE { }
//UNSUP caseStart caseAttrE yINSIDE case_insideListE yENDCASE { } //UNSUP caseStart caseAttrE yINSIDE case_insideListE yENDCASE { }
// //
// // IEEE: conditional_statement // // IEEE: conditional_statement
| unique_priorityE yIF '(' expr ')' stmtBlock %prec prLOWER_THAN_ELSE | unique_priorityE yIF '(' expr ')' stmtBlock %prec prLOWER_THAN_ELSE
{ $$ = new AstIf($2,$4,$6,NULL); } { $$ = new AstIf($2,$4,$6,NULL);
if ($1 == uniq_UNIQUE) $$->castIf()->uniquePragma(true);
if ($1 == uniq_UNIQUE0) $$->castIf()->unique0Pragma(true);
if ($1 == uniq_PRIORITY) $$->castIf()->priorityPragma(true); }
| unique_priorityE yIF '(' expr ')' stmtBlock yELSE stmtBlock | unique_priorityE yIF '(' expr ')' stmtBlock yELSE stmtBlock
{ $$ = new AstIf($2,$4,$6,$8); } { $$ = new AstIf($2,$4,$6,$8);
if ($1 == uniq_UNIQUE) $$->castIf()->uniquePragma(true);
if ($1 == uniq_UNIQUE0) $$->castIf()->unique0Pragma(true);
if ($1 == uniq_PRIORITY) $$->castIf()->priorityPragma(true); }
// //
| finc_or_dec_expression ';' { $$ = $1; } | finc_or_dec_expression ';' { $$ = $1; }
// // IEEE: inc_or_dec_expression // // IEEE: inc_or_dec_expression
@ -1961,6 +1969,7 @@ unique_priorityE<uniqstate>: // IEEE: unique_priority + empty
/*empty*/ { $$ = uniq_NONE; } /*empty*/ { $$ = uniq_NONE; }
| yPRIORITY { $$ = uniq_PRIORITY; } | yPRIORITY { $$ = uniq_PRIORITY; }
| yUNIQUE { $$ = uniq_UNIQUE; } | yUNIQUE { $$ = uniq_UNIQUE; }
| yUNIQUE0 { $$ = uniq_UNIQUE0; }
; ;
caseStart<casep>: // IEEE: part of case_statement caseStart<casep>: // IEEE: part of case_statement