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-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
|
||||
|
|
|
|||
|
|
@ -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(),
|
||||
|
|
|
|||
|
|
@ -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 {
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
||||
|
|
|
|||
|
|
@ -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); }
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
Loading…
Reference in New Issue