Support unique0; track internally with new attributes
This commit is contained in:
parent
3e4e8feb29
commit
e94fc1305b
|
|
@ -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
|
||||||
|
|
|
||||||
|
|
@ -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(),
|
||||||
|
|
|
||||||
|
|
@ -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 {
|
||||||
|
|
|
||||||
|
|
@ -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);
|
||||||
|
|
|
||||||
|
|
@ -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;
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -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); }
|
||||||
|
|
|
||||||
|
|
@ -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
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue