diff options
| author | Eddie Hung <eddieh@ece.ubc.ca> | 2019-03-14 08:59:19 -0700 | 
|---|---|---|
| committer | Eddie Hung <eddieh@ece.ubc.ca> | 2019-03-14 08:59:19 -0700 | 
| commit | f1a8e8a480a7a88835b02abafd27c03e90de7041 (patch) | |
| tree | 49679db03662de0b029d814354f01f972179e453 /frontends/verilog | |
| parent | 26ecbc1aee1dca1c186ab2b51835d74f67bc3e75 (diff) | |
| parent | f0b2d8e467998876ad2cc14232d30ff7892982a3 (diff) | |
| download | yosys-f1a8e8a480a7a88835b02abafd27c03e90de7041.tar.gz yosys-f1a8e8a480a7a88835b02abafd27c03e90de7041.tar.bz2 yosys-f1a8e8a480a7a88835b02abafd27c03e90de7041.zip  | |
Merge remote-tracking branch 'origin/master' into xc7srl
Diffstat (limited to 'frontends/verilog')
| -rw-r--r-- | frontends/verilog/verilog_lexer.l | 10 | ||||
| -rw-r--r-- | frontends/verilog/verilog_parser.y | 205 | 
2 files changed, 157 insertions, 58 deletions
diff --git a/frontends/verilog/verilog_lexer.l b/frontends/verilog/verilog_lexer.l index 1b1873e24..6ef38252a 100644 --- a/frontends/verilog/verilog_lexer.l +++ b/frontends/verilog/verilog_lexer.l @@ -189,6 +189,14 @@ YOSYS_NAMESPACE_END  "always_ff"    { SV_KEYWORD(TOK_ALWAYS); }  "always_latch" { SV_KEYWORD(TOK_ALWAYS); } + /* use special token for labels on assert, assume, cover, and restrict because it's insanley complex +    to fix parsing of cells otherwise. (the current cell parser forces a reduce very early to update some +    global state.. its a mess) */ +[a-zA-Z_$][a-zA-Z0-9_$]*/[ \t\r\n]*:[ \t\r\n]*(assert|assume|cover|restrict)[^a-zA-Z0-9_$\.] { +	frontend_verilog_yylval.string = new std::string(std::string("\\") + yytext); +	return TOK_SVA_LABEL; +} +  "assert"     { if (formal_mode) return TOK_ASSERT; SV_KEYWORD(TOK_ASSERT); }  "assume"     { if (formal_mode) return TOK_ASSUME; SV_KEYWORD(TOK_ASSUME); }  "cover"      { if (formal_mode) return TOK_COVER; SV_KEYWORD(TOK_COVER); } @@ -303,7 +311,7 @@ supply1 { return TOK_SUPPLY1; }  [a-zA-Z_$][a-zA-Z0-9_$\.]* {  	frontend_verilog_yylval.string = new std::string(std::string("\\") + yytext); -    return TOK_ID; +	return TOK_ID;  }  "/*"[ \t]*(synopsys|synthesis)[ \t]*translate_off[ \t]*"*/" { diff --git a/frontends/verilog/verilog_parser.y b/frontends/verilog/verilog_parser.y index a6718b020..52685f637 100644 --- a/frontends/verilog/verilog_parser.y +++ b/frontends/verilog/verilog_parser.y @@ -105,7 +105,8 @@ static void free_attr(std::map<std::string, AstNode*> *al)  	bool boolean;  } -%token <string> TOK_STRING TOK_ID TOK_CONSTVAL TOK_REALVAL TOK_PRIMITIVE +%token <string> TOK_STRING TOK_ID TOK_CONSTVAL TOK_REALVAL TOK_PRIMITIVE TOK_SVA_LABEL +%token TOK_ASSERT TOK_ASSUME TOK_RESTRICT TOK_COVER  %token ATTR_BEGIN ATTR_END DEFATTR_BEGIN DEFATTR_END  %token TOK_MODULE TOK_ENDMODULE TOK_PARAMETER TOK_LOCALPARAM TOK_DEFPARAM  %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_SYNOPSYS_FULL_CASE TOK_SYNOPSYS_PARALLEL_CASE  %token TOK_SUPPLY0 TOK_SUPPLY1 TOK_TO_SIGNED TOK_TO_UNSIGNED -%token TOK_POS_INDEXED TOK_NEG_INDEXED TOK_ASSERT TOK_ASSUME -%token TOK_RESTRICT TOK_COVER TOK_PROPERTY TOK_ENUM TOK_TYPEDEF +%token TOK_POS_INDEXED TOK_NEG_INDEXED TOK_PROPERTY TOK_ENUM TOK_TYPEDEF  %token TOK_RAND TOK_CONST TOK_CHECKER TOK_ENDCHECKER TOK_EVENTUALLY  %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> wire_type expr basic_expr concat_list rvalue lvalue lvalue_concat_list -%type <string> opt_label tok_prim_wrapper hierarchical_id +%type <string> opt_label opt_sva_label tok_prim_wrapper hierarchical_id  %type <boolean> opt_signed opt_property unique_case_attr  %type <al> attr case_attr @@ -1329,6 +1329,14 @@ opt_label:  		$$ = NULL;  	}; +opt_sva_label: +	TOK_SVA_LABEL ':' { +		$$ = $1; +	} | +	/* empty */ { +		$$ = NULL; +	}; +  opt_property:  	TOK_PROPERTY {  		$$ = true; @@ -1337,9 +1345,6 @@ opt_property:  		$$ = false;  	}; -opt_stmt_label: -	TOK_ID ':' | /* empty */; -  modport_stmt:      TOK_MODPORT TOK_ID {          AstNode *modport = new AstNode(AST_MODPORT); @@ -1376,83 +1381,164 @@ modport_type_token:      TOK_INPUT {current_modport_input = 1; current_modport_output = 0;} | TOK_OUTPUT {current_modport_input = 0; current_modport_output = 1;}  assert: -	opt_stmt_label TOK_ASSERT opt_property '(' expr ')' ';' { -		if (noassert_mode) +	opt_sva_label TOK_ASSERT opt_property '(' expr ')' ';' { +		if (noassert_mode) {  			delete $5; -		else -			ast_stack.back()->children.push_back(new AstNode(assume_asserts_mode ? AST_ASSUME : AST_ASSERT, $5)); +		} else { +			AstNode *node = new AstNode(assume_asserts_mode ? AST_ASSUME : AST_ASSERT, $5); +			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 '(' expr ')' ';' { -		if (noassume_mode) +	opt_sva_label TOK_ASSUME opt_property '(' expr ')' ';' { +		if (noassume_mode) {  			delete $5; -		else -			ast_stack.back()->children.push_back(new AstNode(assert_assumes_mode ? AST_ASSERT : AST_ASSUME, $5)); +		} else { +			AstNode *node = new AstNode(assert_assumes_mode ? AST_ASSERT : AST_ASSUME, $5); +			if ($1 != nullptr) +				node->str = *$1; +			ast_stack.back()->children.push_back(node); +		} +		if ($1 != nullptr) +			delete $1;  	} | -	opt_stmt_label TOK_ASSERT opt_property '(' TOK_EVENTUALLY expr ')' ';' { -		if (noassert_mode) +	opt_sva_label TOK_ASSERT opt_property '(' TOK_EVENTUALLY expr ')' ';' { +		if (noassert_mode) {  			delete $6; -		else -			ast_stack.back()->children.push_back(new AstNode(assume_asserts_mode ? AST_FAIR : AST_LIVE, $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) +	opt_sva_label TOK_ASSUME opt_property '(' TOK_EVENTUALLY expr ')' ';' { +		if (noassume_mode) {  			delete $6; -		else -			ast_stack.back()->children.push_back(new AstNode(assert_assumes_mode ? AST_LIVE : AST_FAIR, $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 ')' ';' { -		ast_stack.back()->children.push_back(new AstNode(AST_COVER, $5)); +	opt_sva_label TOK_COVER opt_property '(' expr ')' ';' { +		AstNode *node = new AstNode(AST_COVER, $5); +		if ($1 != nullptr) { +			node->str = *$1; +			delete $1; +		} +		ast_stack.back()->children.push_back(node);  	} | -	opt_stmt_label TOK_COVER opt_property '(' ')' ';' { -		ast_stack.back()->children.push_back(new AstNode(AST_COVER, AstNode::mkconst_int(1, false))); +	opt_sva_label TOK_COVER opt_property '(' ')' ';' { +		AstNode *node = new AstNode(AST_COVER, AstNode::mkconst_int(1, false)); +		if ($1 != nullptr) { +			node->str = *$1; +			delete $1; +		} +		ast_stack.back()->children.push_back(node);  	} | -	opt_stmt_label TOK_COVER ';' { -		ast_stack.back()->children.push_back(new AstNode(AST_COVER, AstNode::mkconst_int(1, false))); +	opt_sva_label TOK_COVER ';' { +		AstNode *node = new AstNode(AST_COVER, AstNode::mkconst_int(1, false)); +		if ($1 != nullptr) { +			node->str = *$1; +			delete $1; +		} +		ast_stack.back()->children.push_back(node);  	} | -	opt_stmt_label TOK_RESTRICT opt_property '(' expr ')' ';' { -		if (norestrict_mode) +	opt_sva_label TOK_RESTRICT opt_property '(' expr ')' ';' { +		if (norestrict_mode) {  			delete $5; -		else -			ast_stack.back()->children.push_back(new AstNode(AST_ASSUME, $5)); +		} else { +			AstNode *node = new AstNode(AST_ASSUME, $5); +			if ($1 != nullptr) +				node->str = *$1; +			ast_stack.back()->children.push_back(node); +		}  		if (!$3)  			log_file_warning(current_filename, get_line_num(), "SystemVerilog does not allow \"restrict\" without \"property\".\n"); +		if ($1 != nullptr) +			delete $1;  	} | -	opt_stmt_label TOK_RESTRICT opt_property '(' TOK_EVENTUALLY expr ')' ';' { -		if (norestrict_mode) +	opt_sva_label TOK_RESTRICT opt_property '(' TOK_EVENTUALLY expr ')' ';' { +		if (norestrict_mode) {  			delete $6; -		else -			ast_stack.back()->children.push_back(new AstNode(AST_FAIR, $6)); +		} else { +			AstNode *node = new AstNode(AST_FAIR, $6); +			if ($1 != nullptr) +				node->str = *$1; +			ast_stack.back()->children.push_back(node); +		}  		if (!$3)  			log_file_warning(current_filename, get_line_num(), "SystemVerilog does not allow \"restrict\" without \"property\".\n"); +		if ($1 != nullptr) +			delete $1;  	};  assert_property: -	TOK_ASSERT TOK_PROPERTY '(' expr ')' ';' { -		ast_stack.back()->children.push_back(new AstNode(assume_asserts_mode ? AST_ASSUME : AST_ASSERT, $4)); -	} | -	TOK_ASSUME TOK_PROPERTY '(' expr ')' ';' { -		ast_stack.back()->children.push_back(new AstNode(AST_ASSUME, $4)); +	opt_sva_label TOK_ASSERT TOK_PROPERTY '(' expr ')' ';' { +		ast_stack.back()->children.push_back(new AstNode(assume_asserts_mode ? AST_ASSUME : AST_ASSERT, $5)); +		if ($1 != nullptr) { +			ast_stack.back()->children.back()->str = *$1; +			delete $1; +		}  	} | -	TOK_ASSERT TOK_PROPERTY '(' TOK_EVENTUALLY expr ')' ';' { -		ast_stack.back()->children.push_back(new AstNode(assume_asserts_mode ? AST_FAIR : AST_LIVE, $5)); +	opt_sva_label TOK_ASSUME TOK_PROPERTY '(' expr ')' ';' { +		ast_stack.back()->children.push_back(new AstNode(AST_ASSUME, $5)); +		if ($1 != nullptr) { +			ast_stack.back()->children.back()->str = *$1; +			delete $1; +		}  	} | -	TOK_ASSUME TOK_PROPERTY '(' TOK_EVENTUALLY expr ')' ';' { -		ast_stack.back()->children.push_back(new AstNode(AST_FAIR, $5)); +	opt_sva_label TOK_ASSERT TOK_PROPERTY '(' TOK_EVENTUALLY expr ')' ';' { +		ast_stack.back()->children.push_back(new AstNode(assume_asserts_mode ? AST_FAIR : AST_LIVE, $6)); +		if ($1 != nullptr) { +			ast_stack.back()->children.back()->str = *$1; +			delete $1; +		}  	} | -	TOK_COVER TOK_PROPERTY '(' expr ')' ';' { -		ast_stack.back()->children.push_back(new AstNode(AST_COVER, $4)); +	opt_sva_label TOK_ASSUME TOK_PROPERTY '(' TOK_EVENTUALLY expr ')' ';' { +		ast_stack.back()->children.push_back(new AstNode(AST_FAIR, $6)); +		if ($1 != nullptr) { +			ast_stack.back()->children.back()->str = *$1; +			delete $1; +		}  	} | -	TOK_RESTRICT TOK_PROPERTY '(' expr ')' ';' { -		if (norestrict_mode) -			delete $4; -		else -			ast_stack.back()->children.push_back(new AstNode(AST_ASSUME, $4)); +	opt_sva_label TOK_COVER TOK_PROPERTY '(' expr ')' ';' { +		ast_stack.back()->children.push_back(new AstNode(AST_COVER, $5)); +		if ($1 != nullptr) { +			ast_stack.back()->children.back()->str = *$1; +			delete $1; +		}  	} | -	TOK_RESTRICT TOK_PROPERTY '(' TOK_EVENTUALLY expr ')' ';' { -		if (norestrict_mode) +	opt_sva_label TOK_RESTRICT TOK_PROPERTY '(' expr ')' ';' { +		if (norestrict_mode) {  			delete $5; -		else -			ast_stack.back()->children.push_back(new AstNode(AST_FAIR, $5)); +		} else { +			ast_stack.back()->children.push_back(new AstNode(AST_ASSUME, $5)); +			if ($1 != nullptr) { +				ast_stack.back()->children.back()->str = *$1; +				delete $1; +			} +		} +	} | +	opt_sva_label TOK_RESTRICT TOK_PROPERTY '(' TOK_EVENTUALLY expr ')' ';' { +		if (norestrict_mode) { +			delete $6; +		} else { +			ast_stack.back()->children.push_back(new AstNode(AST_FAIR, $6)); +			if ($1 != nullptr) { +				ast_stack.back()->children.back()->str = *$1; +				delete $1; +			} +		}  	};  simple_behavioral_stmt: @@ -1670,6 +1756,11 @@ case_expr_list:  	TOK_DEFAULT {  		ast_stack.back()->children.push_back(new AstNode(AST_DEFAULT));  	} | +	TOK_SVA_LABEL { +		ast_stack.back()->children.push_back(new AstNode(AST_IDENTIFIER)); +		ast_stack.back()->children.back()->str = *$1; +		delete $1; +	} |  	expr {  		ast_stack.back()->children.push_back($1);  	} |  | 
