mirror of https://github.com/YosysHQ/yosys.git
Also add support for labels on sva module items, fixes #699
Signed-off-by: Clifford Wolf <clifford@clifford.at>
This commit is contained in:
parent
5dfc7becca
commit
e7a34d342e
|
@ -189,10 +189,57 @@ YOSYS_NAMESPACE_END
|
||||||
"always_ff" { SV_KEYWORD(TOK_ALWAYS); }
|
"always_ff" { SV_KEYWORD(TOK_ALWAYS); }
|
||||||
"always_latch" { SV_KEYWORD(TOK_ALWAYS); }
|
"always_latch" { SV_KEYWORD(TOK_ALWAYS); }
|
||||||
|
|
||||||
"assert" { if (formal_mode) return TOK_ASSERT; SV_KEYWORD(TOK_ASSERT); }
|
/* parse labels on assert, assume, cover, and restrict right here because it's insanley complex
|
||||||
"assume" { if (formal_mode) return TOK_ASSUME; SV_KEYWORD(TOK_ASSUME); }
|
to do it in the parser (because we force the parser too early to reduce when parsing cells..) */
|
||||||
"cover" { if (formal_mode) return TOK_COVER; SV_KEYWORD(TOK_COVER); }
|
([a-zA-Z_$][a-zA-Z0-9_$]*[ \t\r\n]*:[ \t\r\n]*)?(assert|assume|cover|restrict)/[^a-zA-Z0-9_$\.] {
|
||||||
"restrict" { if (formal_mode) return TOK_RESTRICT; SV_KEYWORD(TOK_RESTRICT); }
|
frontend_verilog_yylval.string = new std::string(yytext);
|
||||||
|
auto &str = *frontend_verilog_yylval.string;
|
||||||
|
std::string keyword;
|
||||||
|
int cursor = 0;
|
||||||
|
|
||||||
|
while (1) {
|
||||||
|
if (cursor == GetSize(str)) {
|
||||||
|
keyword = str;
|
||||||
|
delete frontend_verilog_yylval.string;
|
||||||
|
frontend_verilog_yylval.string = nullptr;
|
||||||
|
goto sva_without_label;
|
||||||
|
}
|
||||||
|
char c = str[cursor];
|
||||||
|
if (c != ' ' && c != '\t' && c != '\r' && c != '\n' && c != ':') {
|
||||||
|
cursor++;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
keyword = str.substr(cursor);
|
||||||
|
str = "\\" + str.substr(0, cursor);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
cursor = 0;
|
||||||
|
while (1) {
|
||||||
|
log_assert(cursor < GetSize(keyword));
|
||||||
|
char c = keyword[cursor];
|
||||||
|
if (c != ' ' && c != '\t' && c != '\r' && c != '\n' && c != ':') {
|
||||||
|
keyword = keyword.substr(cursor);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
cursor++;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (keyword == "assert") { return TOK_ASSERT; }
|
||||||
|
else if (keyword == "assume") { return TOK_ASSUME; }
|
||||||
|
else if (keyword == "cover") { return TOK_COVER; }
|
||||||
|
else if (keyword == "restrict") { return TOK_RESTRICT; }
|
||||||
|
else log_abort();
|
||||||
|
|
||||||
|
sva_without_label:
|
||||||
|
if (keyword == "assert") { if (formal_mode) return TOK_ASSERT; SV_KEYWORD(TOK_ASSERT); }
|
||||||
|
else if (keyword == "assume") { if (formal_mode) return TOK_ASSUME; SV_KEYWORD(TOK_ASSUME); }
|
||||||
|
else if (keyword == "cover") { if (formal_mode) return TOK_COVER; SV_KEYWORD(TOK_COVER); }
|
||||||
|
else if (keyword == "restrict") { if (formal_mode) return TOK_RESTRICT; SV_KEYWORD(TOK_RESTRICT); }
|
||||||
|
else log_abort();
|
||||||
|
}
|
||||||
|
|
||||||
"property" { if (formal_mode) return TOK_PROPERTY; SV_KEYWORD(TOK_PROPERTY); }
|
"property" { if (formal_mode) return TOK_PROPERTY; SV_KEYWORD(TOK_PROPERTY); }
|
||||||
"rand" { if (formal_mode) return TOK_RAND; SV_KEYWORD(TOK_RAND); }
|
"rand" { if (formal_mode) return TOK_RAND; SV_KEYWORD(TOK_RAND); }
|
||||||
"const" { if (formal_mode) return TOK_CONST; SV_KEYWORD(TOK_CONST); }
|
"const" { if (formal_mode) return TOK_CONST; SV_KEYWORD(TOK_CONST); }
|
||||||
|
|
|
@ -106,6 +106,7 @@ static void free_attr(std::map<std::string, AstNode*> *al)
|
||||||
}
|
}
|
||||||
|
|
||||||
%token <string> TOK_STRING TOK_ID TOK_CONSTVAL TOK_REALVAL TOK_PRIMITIVE
|
%token <string> TOK_STRING TOK_ID TOK_CONSTVAL TOK_REALVAL TOK_PRIMITIVE
|
||||||
|
%token <string> TOK_ASSERT TOK_ASSUME TOK_RESTRICT TOK_COVER
|
||||||
%token ATTR_BEGIN ATTR_END DEFATTR_BEGIN DEFATTR_END
|
%token ATTR_BEGIN ATTR_END DEFATTR_BEGIN DEFATTR_END
|
||||||
%token TOK_MODULE TOK_ENDMODULE TOK_PARAMETER TOK_LOCALPARAM TOK_DEFPARAM
|
%token TOK_MODULE TOK_ENDMODULE TOK_PARAMETER TOK_LOCALPARAM TOK_DEFPARAM
|
||||||
%token TOK_PACKAGE TOK_ENDPACKAGE TOK_PACKAGESEP
|
%token TOK_PACKAGE TOK_ENDPACKAGE TOK_PACKAGESEP
|
||||||
|
@ -119,14 +120,13 @@ static void free_attr(std::map<std::string, AstNode*> *al)
|
||||||
%token TOK_GENERATE TOK_ENDGENERATE TOK_GENVAR TOK_REAL
|
%token TOK_GENERATE TOK_ENDGENERATE TOK_GENVAR TOK_REAL
|
||||||
%token TOK_SYNOPSYS_FULL_CASE TOK_SYNOPSYS_PARALLEL_CASE
|
%token TOK_SYNOPSYS_FULL_CASE TOK_SYNOPSYS_PARALLEL_CASE
|
||||||
%token TOK_SUPPLY0 TOK_SUPPLY1 TOK_TO_SIGNED TOK_TO_UNSIGNED
|
%token TOK_SUPPLY0 TOK_SUPPLY1 TOK_TO_SIGNED TOK_TO_UNSIGNED
|
||||||
%token TOK_POS_INDEXED TOK_NEG_INDEXED TOK_ASSERT TOK_ASSUME
|
%token TOK_POS_INDEXED TOK_NEG_INDEXED TOK_PROPERTY TOK_ENUM TOK_TYPEDEF
|
||||||
%token TOK_RESTRICT TOK_COVER TOK_PROPERTY TOK_ENUM TOK_TYPEDEF
|
|
||||||
%token TOK_RAND TOK_CONST TOK_CHECKER TOK_ENDCHECKER TOK_EVENTUALLY
|
%token TOK_RAND TOK_CONST TOK_CHECKER TOK_ENDCHECKER TOK_EVENTUALLY
|
||||||
%token TOK_INCREMENT TOK_DECREMENT TOK_UNIQUE TOK_PRIORITY
|
%token TOK_INCREMENT TOK_DECREMENT TOK_UNIQUE TOK_PRIORITY
|
||||||
|
|
||||||
%type <ast> range range_or_multirange non_opt_range non_opt_multirange range_or_signed_int
|
%type <ast> range range_or_multirange non_opt_range non_opt_multirange range_or_signed_int
|
||||||
%type <ast> wire_type expr basic_expr concat_list rvalue lvalue lvalue_concat_list
|
%type <ast> wire_type expr basic_expr concat_list rvalue lvalue lvalue_concat_list
|
||||||
%type <string> opt_label opt_stmt_label tok_prim_wrapper hierarchical_id
|
%type <string> opt_label tok_prim_wrapper hierarchical_id
|
||||||
%type <boolean> opt_signed opt_property unique_case_attr
|
%type <boolean> opt_signed opt_property unique_case_attr
|
||||||
%type <al> attr case_attr
|
%type <al> attr case_attr
|
||||||
|
|
||||||
|
@ -1337,14 +1337,6 @@ opt_property:
|
||||||
$$ = false;
|
$$ = false;
|
||||||
};
|
};
|
||||||
|
|
||||||
opt_stmt_label:
|
|
||||||
TOK_ID ':' {
|
|
||||||
$$ = $1;
|
|
||||||
} |
|
|
||||||
/* empty */ {
|
|
||||||
$$ = NULL;
|
|
||||||
};
|
|
||||||
|
|
||||||
modport_stmt:
|
modport_stmt:
|
||||||
TOK_MODPORT TOK_ID {
|
TOK_MODPORT TOK_ID {
|
||||||
AstNode *modport = new AstNode(AST_MODPORT);
|
AstNode *modport = new AstNode(AST_MODPORT);
|
||||||
|
@ -1381,11 +1373,35 @@ modport_type_token:
|
||||||
TOK_INPUT {current_modport_input = 1; current_modport_output = 0;} | TOK_OUTPUT {current_modport_input = 0; current_modport_output = 1;}
|
TOK_INPUT {current_modport_input = 1; current_modport_output = 0;} | TOK_OUTPUT {current_modport_input = 0; current_modport_output = 1;}
|
||||||
|
|
||||||
assert:
|
assert:
|
||||||
opt_stmt_label TOK_ASSERT opt_property '(' expr ')' ';' {
|
TOK_ASSERT opt_property '(' expr ')' ';' {
|
||||||
|
if (noassert_mode) {
|
||||||
|
delete $4;
|
||||||
|
} else {
|
||||||
|
AstNode *node = new AstNode(assume_asserts_mode ? AST_ASSUME : AST_ASSERT, $4);
|
||||||
|
if ($1 != nullptr)
|
||||||
|
node->str = *$1;
|
||||||
|
ast_stack.back()->children.push_back(node);
|
||||||
|
}
|
||||||
|
if ($1 != nullptr)
|
||||||
|
delete $1;
|
||||||
|
} |
|
||||||
|
TOK_ASSUME opt_property '(' expr ')' ';' {
|
||||||
|
if (noassume_mode) {
|
||||||
|
delete $4;
|
||||||
|
} else {
|
||||||
|
AstNode *node = new AstNode(assert_assumes_mode ? AST_ASSERT : AST_ASSUME, $4);
|
||||||
|
if ($1 != nullptr)
|
||||||
|
node->str = *$1;
|
||||||
|
ast_stack.back()->children.push_back(node);
|
||||||
|
}
|
||||||
|
if ($1 != nullptr)
|
||||||
|
delete $1;
|
||||||
|
} |
|
||||||
|
TOK_ASSERT opt_property '(' TOK_EVENTUALLY expr ')' ';' {
|
||||||
if (noassert_mode) {
|
if (noassert_mode) {
|
||||||
delete $5;
|
delete $5;
|
||||||
} else {
|
} else {
|
||||||
AstNode *node = new AstNode(assume_asserts_mode ? AST_ASSUME : AST_ASSERT, $5);
|
AstNode *node = new AstNode(assume_asserts_mode ? AST_FAIR : AST_LIVE, $5);
|
||||||
if ($1 != nullptr)
|
if ($1 != nullptr)
|
||||||
node->str = *$1;
|
node->str = *$1;
|
||||||
ast_stack.back()->children.push_back(node);
|
ast_stack.back()->children.push_back(node);
|
||||||
|
@ -1393,11 +1409,11 @@ assert:
|
||||||
if ($1 != nullptr)
|
if ($1 != nullptr)
|
||||||
delete $1;
|
delete $1;
|
||||||
} |
|
} |
|
||||||
opt_stmt_label TOK_ASSUME opt_property '(' expr ')' ';' {
|
TOK_ASSUME opt_property '(' TOK_EVENTUALLY expr ')' ';' {
|
||||||
if (noassume_mode) {
|
if (noassume_mode) {
|
||||||
delete $5;
|
delete $5;
|
||||||
} else {
|
} else {
|
||||||
AstNode *node = new AstNode(assert_assumes_mode ? AST_ASSERT : AST_ASSUME, $5);
|
AstNode *node = new AstNode(assert_assumes_mode ? AST_LIVE : AST_FAIR, $5);
|
||||||
if ($1 != nullptr)
|
if ($1 != nullptr)
|
||||||
node->str = *$1;
|
node->str = *$1;
|
||||||
ast_stack.back()->children.push_back(node);
|
ast_stack.back()->children.push_back(node);
|
||||||
|
@ -1405,39 +1421,15 @@ assert:
|
||||||
if ($1 != nullptr)
|
if ($1 != nullptr)
|
||||||
delete $1;
|
delete $1;
|
||||||
} |
|
} |
|
||||||
opt_stmt_label TOK_ASSERT opt_property '(' TOK_EVENTUALLY expr ')' ';' {
|
TOK_COVER opt_property '(' expr ')' ';' {
|
||||||
if (noassert_mode) {
|
AstNode *node = new AstNode(AST_COVER, $4);
|
||||||
delete $6;
|
|
||||||
} else {
|
|
||||||
AstNode *node = new AstNode(assume_asserts_mode ? AST_FAIR : AST_LIVE, $6);
|
|
||||||
if ($1 != nullptr)
|
|
||||||
node->str = *$1;
|
|
||||||
ast_stack.back()->children.push_back(node);
|
|
||||||
}
|
|
||||||
if ($1 != nullptr)
|
|
||||||
delete $1;
|
|
||||||
} |
|
|
||||||
opt_stmt_label TOK_ASSUME opt_property '(' TOK_EVENTUALLY expr ')' ';' {
|
|
||||||
if (noassume_mode) {
|
|
||||||
delete $6;
|
|
||||||
} else {
|
|
||||||
AstNode *node = new AstNode(assert_assumes_mode ? AST_LIVE : AST_FAIR, $6);
|
|
||||||
if ($1 != nullptr)
|
|
||||||
node->str = *$1;
|
|
||||||
ast_stack.back()->children.push_back(node);
|
|
||||||
}
|
|
||||||
if ($1 != nullptr)
|
|
||||||
delete $1;
|
|
||||||
} |
|
|
||||||
opt_stmt_label TOK_COVER opt_property '(' expr ')' ';' {
|
|
||||||
AstNode *node = new AstNode(AST_COVER, $5);
|
|
||||||
if ($1 != nullptr) {
|
if ($1 != nullptr) {
|
||||||
node->str = *$1;
|
node->str = *$1;
|
||||||
delete $1;
|
delete $1;
|
||||||
}
|
}
|
||||||
ast_stack.back()->children.push_back(node);
|
ast_stack.back()->children.push_back(node);
|
||||||
} |
|
} |
|
||||||
opt_stmt_label TOK_COVER opt_property '(' ')' ';' {
|
TOK_COVER opt_property '(' ')' ';' {
|
||||||
AstNode *node = new AstNode(AST_COVER, AstNode::mkconst_int(1, false));
|
AstNode *node = new AstNode(AST_COVER, AstNode::mkconst_int(1, false));
|
||||||
if ($1 != nullptr) {
|
if ($1 != nullptr) {
|
||||||
node->str = *$1;
|
node->str = *$1;
|
||||||
|
@ -1445,7 +1437,7 @@ assert:
|
||||||
}
|
}
|
||||||
ast_stack.back()->children.push_back(node);
|
ast_stack.back()->children.push_back(node);
|
||||||
} |
|
} |
|
||||||
opt_stmt_label TOK_COVER ';' {
|
TOK_COVER ';' {
|
||||||
AstNode *node = new AstNode(AST_COVER, AstNode::mkconst_int(1, false));
|
AstNode *node = new AstNode(AST_COVER, AstNode::mkconst_int(1, false));
|
||||||
if ($1 != nullptr) {
|
if ($1 != nullptr) {
|
||||||
node->str = *$1;
|
node->str = *$1;
|
||||||
|
@ -1453,30 +1445,30 @@ assert:
|
||||||
}
|
}
|
||||||
ast_stack.back()->children.push_back(node);
|
ast_stack.back()->children.push_back(node);
|
||||||
} |
|
} |
|
||||||
opt_stmt_label TOK_RESTRICT opt_property '(' expr ')' ';' {
|
TOK_RESTRICT opt_property '(' expr ')' ';' {
|
||||||
if (norestrict_mode) {
|
if (norestrict_mode) {
|
||||||
delete $5;
|
delete $4;
|
||||||
} else {
|
} else {
|
||||||
AstNode *node = new AstNode(AST_ASSUME, $5);
|
AstNode *node = new AstNode(AST_ASSUME, $4);
|
||||||
if ($1 != nullptr)
|
if ($1 != nullptr)
|
||||||
node->str = *$1;
|
node->str = *$1;
|
||||||
ast_stack.back()->children.push_back(node);
|
ast_stack.back()->children.push_back(node);
|
||||||
}
|
}
|
||||||
if (!$3)
|
if (!$2)
|
||||||
log_file_warning(current_filename, get_line_num(), "SystemVerilog does not allow \"restrict\" without \"property\".\n");
|
log_file_warning(current_filename, get_line_num(), "SystemVerilog does not allow \"restrict\" without \"property\".\n");
|
||||||
if ($1 != nullptr)
|
if ($1 != nullptr)
|
||||||
delete $1;
|
delete $1;
|
||||||
} |
|
} |
|
||||||
opt_stmt_label TOK_RESTRICT opt_property '(' TOK_EVENTUALLY expr ')' ';' {
|
TOK_RESTRICT opt_property '(' TOK_EVENTUALLY expr ')' ';' {
|
||||||
if (norestrict_mode) {
|
if (norestrict_mode) {
|
||||||
delete $6;
|
delete $5;
|
||||||
} else {
|
} else {
|
||||||
AstNode *node = new AstNode(AST_FAIR, $6);
|
AstNode *node = new AstNode(AST_FAIR, $5);
|
||||||
if ($1 != nullptr)
|
if ($1 != nullptr)
|
||||||
node->str = *$1;
|
node->str = *$1;
|
||||||
ast_stack.back()->children.push_back(node);
|
ast_stack.back()->children.push_back(node);
|
||||||
}
|
}
|
||||||
if (!$3)
|
if (!$2)
|
||||||
log_file_warning(current_filename, get_line_num(), "SystemVerilog does not allow \"restrict\" without \"property\".\n");
|
log_file_warning(current_filename, get_line_num(), "SystemVerilog does not allow \"restrict\" without \"property\".\n");
|
||||||
if ($1 != nullptr)
|
if ($1 != nullptr)
|
||||||
delete $1;
|
delete $1;
|
||||||
|
@ -1485,30 +1477,60 @@ assert:
|
||||||
assert_property:
|
assert_property:
|
||||||
TOK_ASSERT TOK_PROPERTY '(' expr ')' ';' {
|
TOK_ASSERT TOK_PROPERTY '(' expr ')' ';' {
|
||||||
ast_stack.back()->children.push_back(new AstNode(assume_asserts_mode ? AST_ASSUME : AST_ASSERT, $4));
|
ast_stack.back()->children.push_back(new AstNode(assume_asserts_mode ? AST_ASSUME : AST_ASSERT, $4));
|
||||||
|
if ($1 != nullptr) {
|
||||||
|
ast_stack.back()->children.back()->str = *$1;
|
||||||
|
delete $1;
|
||||||
|
}
|
||||||
} |
|
} |
|
||||||
TOK_ASSUME TOK_PROPERTY '(' expr ')' ';' {
|
TOK_ASSUME TOK_PROPERTY '(' expr ')' ';' {
|
||||||
ast_stack.back()->children.push_back(new AstNode(AST_ASSUME, $4));
|
ast_stack.back()->children.push_back(new AstNode(AST_ASSUME, $4));
|
||||||
|
if ($1 != nullptr) {
|
||||||
|
ast_stack.back()->children.back()->str = *$1;
|
||||||
|
delete $1;
|
||||||
|
}
|
||||||
} |
|
} |
|
||||||
TOK_ASSERT TOK_PROPERTY '(' TOK_EVENTUALLY expr ')' ';' {
|
TOK_ASSERT TOK_PROPERTY '(' TOK_EVENTUALLY expr ')' ';' {
|
||||||
ast_stack.back()->children.push_back(new AstNode(assume_asserts_mode ? AST_FAIR : AST_LIVE, $5));
|
ast_stack.back()->children.push_back(new AstNode(assume_asserts_mode ? AST_FAIR : AST_LIVE, $5));
|
||||||
|
if ($1 != nullptr) {
|
||||||
|
ast_stack.back()->children.back()->str = *$1;
|
||||||
|
delete $1;
|
||||||
|
}
|
||||||
} |
|
} |
|
||||||
TOK_ASSUME TOK_PROPERTY '(' TOK_EVENTUALLY expr ')' ';' {
|
TOK_ASSUME TOK_PROPERTY '(' TOK_EVENTUALLY expr ')' ';' {
|
||||||
ast_stack.back()->children.push_back(new AstNode(AST_FAIR, $5));
|
ast_stack.back()->children.push_back(new AstNode(AST_FAIR, $5));
|
||||||
|
if ($1 != nullptr) {
|
||||||
|
ast_stack.back()->children.back()->str = *$1;
|
||||||
|
delete $1;
|
||||||
|
}
|
||||||
} |
|
} |
|
||||||
TOK_COVER TOK_PROPERTY '(' expr ')' ';' {
|
TOK_COVER TOK_PROPERTY '(' expr ')' ';' {
|
||||||
ast_stack.back()->children.push_back(new AstNode(AST_COVER, $4));
|
ast_stack.back()->children.push_back(new AstNode(AST_COVER, $4));
|
||||||
|
if ($1 != nullptr) {
|
||||||
|
ast_stack.back()->children.back()->str = *$1;
|
||||||
|
delete $1;
|
||||||
|
}
|
||||||
} |
|
} |
|
||||||
TOK_RESTRICT TOK_PROPERTY '(' expr ')' ';' {
|
TOK_RESTRICT TOK_PROPERTY '(' expr ')' ';' {
|
||||||
if (norestrict_mode)
|
if (norestrict_mode) {
|
||||||
delete $4;
|
delete $4;
|
||||||
else
|
} else {
|
||||||
ast_stack.back()->children.push_back(new AstNode(AST_ASSUME, $4));
|
ast_stack.back()->children.push_back(new AstNode(AST_ASSUME, $4));
|
||||||
|
if ($1 != nullptr) {
|
||||||
|
ast_stack.back()->children.back()->str = *$1;
|
||||||
|
delete $1;
|
||||||
|
}
|
||||||
|
}
|
||||||
} |
|
} |
|
||||||
TOK_RESTRICT TOK_PROPERTY '(' TOK_EVENTUALLY expr ')' ';' {
|
TOK_RESTRICT TOK_PROPERTY '(' TOK_EVENTUALLY expr ')' ';' {
|
||||||
if (norestrict_mode)
|
if (norestrict_mode) {
|
||||||
delete $5;
|
delete $5;
|
||||||
else
|
} else {
|
||||||
ast_stack.back()->children.push_back(new AstNode(AST_FAIR, $5));
|
ast_stack.back()->children.push_back(new AstNode(AST_FAIR, $5));
|
||||||
|
if ($1 != nullptr) {
|
||||||
|
ast_stack.back()->children.back()->str = *$1;
|
||||||
|
delete $1;
|
||||||
|
}
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
simple_behavioral_stmt:
|
simple_behavioral_stmt:
|
||||||
|
|
Loading…
Reference in New Issue