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-unsup Blackbox unsupported language features
--bin <filename> Override Verilator binary
-CFLAGS <flags> C++ Compiler flags for makefile
-CFLAGS <flags> C++ Compiler flags for makefile
--cc Create C++ output
--cdc Clock domain crossing analysis
--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
+define+<var>+<value> Set preprocessor define
--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
--exe Link to create executable
-F <file> Parse options from a file, relatively
-f <file> Parse options from a file
--gdbbt Run Verilator under GDB for backtrace
--help Display this help.
--help Display this help
-I<dir> Directory to search for includes
+incdir+<dir> Directory to search for includes
--inhibit-sim Create function to turn off sim
--inline-mult <value> Tune module inlining
-LDFLAGS <flags> Linker pre-object flags for makefile
-LDLIBS <flags> Linker library flags for makefile
-LDFLAGS <flags> Linker pre-object flags for makefile
-LDLIBS <flags> Linker library flags for makefile
--language <lang> Language standard to parse
+libext+<ext>+[ext]... Extensions for finding modules
--lint-only Lint, but do not make output
@ -273,12 +273,12 @@ descriptions in the next sections for more information.
-O0 Disable optimizations
-O3 High performance 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-cfuncs <statements> Split .ccp functions
--pins-bv <bits> 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
--profile-cfuncs Name functions for profiling
--private Debugging; see docs

View File

@ -182,7 +182,7 @@ private:
for (AstCaseItem* itemp = nodep->itemsp(); itemp; itemp=itemp->nextp()->castCaseItem()) {
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
m_statAsFull++;
if (!has_default) {
@ -190,7 +190,7 @@ private:
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
// If there's a default, we allow none to match, else exactly one must match
m_statAsFull++;
@ -207,7 +207,8 @@ private:
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 AstOneHot (nodep->fileline(), propp))->castNode());
AstIf* ifp = new AstIf (nodep->fileline(),

View File

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

View File

@ -166,7 +166,13 @@ class EmitVBaseVisitor : public EmitCBaseVisitor {
nodep->iterateChildren(*this);
}
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(" (");
nodep->exprp()->iterateAndNext(*this);
puts(")\n");
@ -301,7 +307,13 @@ class EmitVBaseVisitor : public EmitCBaseVisitor {
putfs(nodep,"end\n");
}
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);
puts(") begin\n");
nodep->ifsp()->iterateAndNext(*this);

View File

@ -38,7 +38,7 @@ class V3Lexer;
//======================================================================
// 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;

View File

@ -493,6 +493,7 @@ word [a-zA-Z0-9_]+
<S09,PSL>{
/* Keywords */
"global" { FL; return yGLOBAL__LEX; }
"unique0" { FL; return yUNIQUE0; }
/* Generic unsupported warnings */
"accept_on" { 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); }
"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); }
"unique0" { 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); }
"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> yTYPEDEF "typedef"
%token<fl> yUNIQUE "unique"
%token<fl> yUNIQUE0 "unique0"
%token<fl> yUNSIGNED "unsigned"
%token<fl> yVAR "var"
%token<fl> yVECTORED "vectored"
@ -1819,16 +1820,23 @@ statement_item<nodep>: // IEEE: statement_item
//
// // IEEE: case_statement
| unique_priorityE caseStart caseAttrE case_itemListE yENDCASE { $$ = $2; if ($4) $2->addItemsp($4);
if ($1 == uniq_UNIQUE) $2->parallelPragma(true);
if ($1 == uniq_PRIORITY) $2->fullPragma(true); }
if ($1 == uniq_UNIQUE) $2->uniquePragma(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 yINSIDE case_insideListE yENDCASE { }
//
// // IEEE: conditional_statement
| 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
{ $$ = 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; }
// // IEEE: inc_or_dec_expression
@ -1961,6 +1969,7 @@ unique_priorityE<uniqstate>: // IEEE: unique_priority + empty
/*empty*/ { $$ = uniq_NONE; }
| yPRIORITY { $$ = uniq_PRIORITY; }
| yUNIQUE { $$ = uniq_UNIQUE; }
| yUNIQUE0 { $$ = uniq_UNIQUE0; }
;
caseStart<casep>: // IEEE: part of case_statement