mirror of
				https://github.com/YosysHQ/yosys
				synced 2025-11-04 05:19:11 +00:00 
			
		
		
		
	Merge pull request #1811 from PeterCrozier/typedef_scope
Support module/package/interface/block scope for typedef names.
This commit is contained in:
		
						commit
						d5e2061687
					
				
					 6 changed files with 89 additions and 44 deletions
				
			
		| 
						 | 
					@ -541,8 +541,6 @@ from SystemVerilog:
 | 
				
			||||||
  SystemVerilog files being read into the same design afterwards.
 | 
					  SystemVerilog files being read into the same design afterwards.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
- typedefs are supported (including inside packages)
 | 
					- typedefs are supported (including inside packages)
 | 
				
			||||||
	- type identifiers must currently be enclosed in (parentheses) when declaring
 | 
					 | 
				
			||||||
	  signals of that type (this is syntactically incorrect SystemVerilog)
 | 
					 | 
				
			||||||
	- type casts are currently not supported
 | 
						- type casts are currently not supported
 | 
				
			||||||
 | 
					
 | 
				
			||||||
- enums are supported (including inside packages)
 | 
					- enums are supported (including inside packages)
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -52,7 +52,6 @@ static void add_package_types(std::map<std::string, AST::AstNode *> &user_types,
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	// prime the parser's user type lookup table with the package qualified names
 | 
						// prime the parser's user type lookup table with the package qualified names
 | 
				
			||||||
	// of typedefed names in the packages seen so far.
 | 
						// of typedefed names in the packages seen so far.
 | 
				
			||||||
	user_types.clear();
 | 
					 | 
				
			||||||
	for (const auto &pkg : package_list) {
 | 
						for (const auto &pkg : package_list) {
 | 
				
			||||||
		log_assert(pkg->type==AST::AST_PACKAGE);
 | 
							log_assert(pkg->type==AST::AST_PACKAGE);
 | 
				
			||||||
		for (const auto &node: pkg->children) {
 | 
							for (const auto &node: pkg->children) {
 | 
				
			||||||
| 
						 | 
					@ -62,6 +61,8 @@ static void add_package_types(std::map<std::string, AST::AstNode *> &user_types,
 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
						user_type_stack.clear();
 | 
				
			||||||
 | 
						user_type_stack.push_back(new UserTypeMap());
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
struct VerilogFrontend : public Frontend {
 | 
					struct VerilogFrontend : public Frontend {
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -45,8 +45,9 @@ namespace VERILOG_FRONTEND
 | 
				
			||||||
	// this function converts a Verilog constant to an AST_CONSTANT node
 | 
						// this function converts a Verilog constant to an AST_CONSTANT node
 | 
				
			||||||
	AST::AstNode *const2ast(std::string code, char case_type = 0, bool warn_z = false);
 | 
						AST::AstNode *const2ast(std::string code, char case_type = 0, bool warn_z = false);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	// names of locally typedef'ed types
 | 
						// names of locally typedef'ed types in a stack
 | 
				
			||||||
	extern std::map<std::string, AST::AstNode*> user_types;
 | 
						typedef std::map<std::string, AST::AstNode*> UserTypeMap;
 | 
				
			||||||
 | 
						extern std::vector<UserTypeMap *> user_type_stack;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	// names of package typedef'ed types
 | 
						// names of package typedef'ed types
 | 
				
			||||||
	extern std::map<std::string, AST::AstNode*> pkg_user_types;
 | 
						extern std::map<std::string, AST::AstNode*> pkg_user_types;
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -99,6 +99,18 @@ YYLTYPE old_location;
 | 
				
			||||||
#define YY_BUF_SIZE 65536
 | 
					#define YY_BUF_SIZE 65536
 | 
				
			||||||
 | 
					
 | 
				
			||||||
extern int frontend_verilog_yylex(YYSTYPE *yylval_param, YYLTYPE *yyloc_param);
 | 
					extern int frontend_verilog_yylex(YYSTYPE *yylval_param, YYLTYPE *yyloc_param);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static bool isUserType(std::string &s)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						// check current scope then outer scopes for a name
 | 
				
			||||||
 | 
						for (auto it = user_type_stack.rbegin(); it != user_type_stack.rend(); ++it) {
 | 
				
			||||||
 | 
							if ((*it)->count(s) > 0) {
 | 
				
			||||||
 | 
								return true;
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						return false;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
%}
 | 
					%}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
%option yylineno
 | 
					%option yylineno
 | 
				
			||||||
| 
						 | 
					@ -376,9 +388,9 @@ supply1 { return TOK_SUPPLY1; }
 | 
				
			||||||
	// package qualifier
 | 
						// package qualifier
 | 
				
			||||||
	auto s = std::string("\\") + yytext;
 | 
						auto s = std::string("\\") + yytext;
 | 
				
			||||||
	if (pkg_user_types.count(s) > 0) {
 | 
						if (pkg_user_types.count(s) > 0) {
 | 
				
			||||||
		// found it
 | 
							// package qualified typedefed name
 | 
				
			||||||
		yylval->string = new std::string(s);
 | 
							yylval->string = new std::string(s);
 | 
				
			||||||
		return TOK_USER_TYPE;
 | 
							return TOK_PKG_USER_TYPE;
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	else {
 | 
						else {
 | 
				
			||||||
		// backup before :: just return first part
 | 
							// backup before :: just return first part
 | 
				
			||||||
| 
						 | 
					@ -391,7 +403,8 @@ supply1 { return TOK_SUPPLY1; }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
[a-zA-Z_$][a-zA-Z0-9_$]* {
 | 
					[a-zA-Z_$][a-zA-Z0-9_$]* {
 | 
				
			||||||
	auto s = std::string("\\") + yytext;
 | 
						auto s = std::string("\\") + yytext;
 | 
				
			||||||
	if (user_types.count(s) > 0) {
 | 
						if (isUserType(s)) {
 | 
				
			||||||
 | 
							// previously typedefed name
 | 
				
			||||||
		yylval->string = new std::string(s);
 | 
							yylval->string = new std::string(s);
 | 
				
			||||||
		return TOK_USER_TYPE;
 | 
							return TOK_USER_TYPE;
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -54,7 +54,7 @@ namespace VERILOG_FRONTEND {
 | 
				
			||||||
	std::map<std::string, AstNode*> *attr_list, default_attr_list;
 | 
						std::map<std::string, AstNode*> *attr_list, default_attr_list;
 | 
				
			||||||
	std::stack<std::map<std::string, AstNode*> *> attr_list_stack;
 | 
						std::stack<std::map<std::string, AstNode*> *> attr_list_stack;
 | 
				
			||||||
	std::map<std::string, AstNode*> *albuf;
 | 
						std::map<std::string, AstNode*> *albuf;
 | 
				
			||||||
	std::map<std::string, AstNode*> user_types;
 | 
						std::vector<UserTypeMap*> user_type_stack;
 | 
				
			||||||
	std::map<std::string, AstNode*> pkg_user_types;
 | 
						std::map<std::string, AstNode*> pkg_user_types;
 | 
				
			||||||
	std::vector<AstNode*> ast_stack;
 | 
						std::vector<AstNode*> ast_stack;
 | 
				
			||||||
	struct AstNode *astbuf1, *astbuf2, *astbuf3;
 | 
						struct AstNode *astbuf1, *astbuf2, *astbuf3;
 | 
				
			||||||
| 
						 | 
					@ -130,14 +130,10 @@ struct specify_rise_fall {
 | 
				
			||||||
static void addTypedefNode(std::string *name, AstNode *node)
 | 
					static void addTypedefNode(std::string *name, AstNode *node)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	log_assert(node);
 | 
						log_assert(node);
 | 
				
			||||||
	// seems to be support for local scoped typedefs in simplify()
 | 
					 | 
				
			||||||
	// and tests redefine types.
 | 
					 | 
				
			||||||
	//if (user_types.count(*name) > 0) {
 | 
					 | 
				
			||||||
	//	frontend_verilog_yyerror("Type already defined.");
 | 
					 | 
				
			||||||
	//}
 | 
					 | 
				
			||||||
	auto *tnode = new AstNode(AST_TYPEDEF, node);
 | 
						auto *tnode = new AstNode(AST_TYPEDEF, node);
 | 
				
			||||||
	tnode->str = *name;
 | 
						tnode->str = *name;
 | 
				
			||||||
	user_types[*name] = tnode;
 | 
						auto user_types = user_type_stack.back();
 | 
				
			||||||
 | 
						(*user_types)[*name] = tnode;
 | 
				
			||||||
	if (current_ast_mod && current_ast_mod->type == AST_PACKAGE) {
 | 
						if (current_ast_mod && current_ast_mod->type == AST_PACKAGE) {
 | 
				
			||||||
		// typedef inside a package so we need the qualified name
 | 
							// typedef inside a package so we need the qualified name
 | 
				
			||||||
		auto qname = current_ast_mod->str + "::" + (*name).substr(1);
 | 
							auto qname = current_ast_mod->str + "::" + (*name).substr(1);
 | 
				
			||||||
| 
						 | 
					@ -147,6 +143,24 @@ static void addTypedefNode(std::string *name, AstNode *node)
 | 
				
			||||||
	ast_stack.back()->children.push_back(tnode);
 | 
						ast_stack.back()->children.push_back(tnode);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static void enterTypeScope()
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						auto user_types = new UserTypeMap();
 | 
				
			||||||
 | 
						user_type_stack.push_back(user_types);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static void exitTypeScope()
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						user_type_stack.pop_back();
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static bool isInLocalScope(const std::string *name)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						// tests if a name was declared in the current block scope
 | 
				
			||||||
 | 
						auto user_types = user_type_stack.back();
 | 
				
			||||||
 | 
						return (user_types->count(*name) > 0);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static AstNode *makeRange(int msb = 31, int lsb = 0, bool isSigned = true)
 | 
					static AstNode *makeRange(int msb = 31, int lsb = 0, bool isSigned = true)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	auto range = new AstNode(AST_RANGE);
 | 
						auto range = new AstNode(AST_RANGE);
 | 
				
			||||||
| 
						 | 
					@ -189,7 +203,7 @@ static void addRange(AstNode *parent, int msb = 31, int lsb = 0, bool isSigned =
 | 
				
			||||||
%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_SVA_LABEL TOK_SPECIFY_OPER TOK_MSG_TASKS
 | 
					%token <string> TOK_SVA_LABEL TOK_SPECIFY_OPER TOK_MSG_TASKS
 | 
				
			||||||
%token <string> TOK_BASE TOK_BASED_CONSTVAL TOK_UNBASED_UNSIZED_CONSTVAL
 | 
					%token <string> TOK_BASE TOK_BASED_CONSTVAL TOK_UNBASED_UNSIZED_CONSTVAL
 | 
				
			||||||
%token <string> TOK_USER_TYPE
 | 
					%token <string> TOK_USER_TYPE TOK_PKG_USER_TYPE
 | 
				
			||||||
%token TOK_ASSERT TOK_ASSUME TOK_RESTRICT TOK_COVER TOK_FINAL
 | 
					%token TOK_ASSERT TOK_ASSUME TOK_RESTRICT TOK_COVER TOK_FINAL
 | 
				
			||||||
%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
 | 
				
			||||||
| 
						 | 
					@ -355,11 +369,14 @@ hierarchical_id:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
hierarchical_type_id:
 | 
					hierarchical_type_id:
 | 
				
			||||||
	TOK_USER_TYPE
 | 
						TOK_USER_TYPE
 | 
				
			||||||
 | 
						| TOK_PKG_USER_TYPE				// package qualified type name
 | 
				
			||||||
	| '(' TOK_USER_TYPE ')'	{ $$ = $2; }		// non-standard grammar
 | 
						| '(' TOK_USER_TYPE ')'	{ $$ = $2; }		// non-standard grammar
 | 
				
			||||||
	;
 | 
						;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
module:
 | 
					module:
 | 
				
			||||||
	attr TOK_MODULE TOK_ID {
 | 
						attr TOK_MODULE {
 | 
				
			||||||
 | 
							enterTypeScope();
 | 
				
			||||||
 | 
						} TOK_ID {
 | 
				
			||||||
		do_not_require_port_stubs = false;
 | 
							do_not_require_port_stubs = false;
 | 
				
			||||||
		AstNode *mod = new AstNode(AST_MODULE);
 | 
							AstNode *mod = new AstNode(AST_MODULE);
 | 
				
			||||||
		ast_stack.back()->children.push_back(mod);
 | 
							ast_stack.back()->children.push_back(mod);
 | 
				
			||||||
| 
						 | 
					@ -367,9 +384,9 @@ module:
 | 
				
			||||||
		current_ast_mod = mod;
 | 
							current_ast_mod = mod;
 | 
				
			||||||
		port_stubs.clear();
 | 
							port_stubs.clear();
 | 
				
			||||||
		port_counter = 0;
 | 
							port_counter = 0;
 | 
				
			||||||
		mod->str = *$3;
 | 
							mod->str = *$4;
 | 
				
			||||||
		append_attr(mod, $1);
 | 
							append_attr(mod, $1);
 | 
				
			||||||
		delete $3;
 | 
							delete $4;
 | 
				
			||||||
	} module_para_opt module_args_opt ';' module_body TOK_ENDMODULE {
 | 
						} module_para_opt module_args_opt ';' module_body TOK_ENDMODULE {
 | 
				
			||||||
		if (port_stubs.size() != 0)
 | 
							if (port_stubs.size() != 0)
 | 
				
			||||||
			frontend_verilog_yyerror("Missing details for module port `%s'.",
 | 
								frontend_verilog_yyerror("Missing details for module port `%s'.",
 | 
				
			||||||
| 
						 | 
					@ -378,7 +395,7 @@ module:
 | 
				
			||||||
		ast_stack.pop_back();
 | 
							ast_stack.pop_back();
 | 
				
			||||||
		log_assert(ast_stack.size() == 1);
 | 
							log_assert(ast_stack.size() == 1);
 | 
				
			||||||
		current_ast_mod = NULL;
 | 
							current_ast_mod = NULL;
 | 
				
			||||||
		user_types.clear();
 | 
							exitTypeScope();
 | 
				
			||||||
	};
 | 
						};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
module_para_opt:
 | 
					module_para_opt:
 | 
				
			||||||
| 
						 | 
					@ -482,17 +499,19 @@ module_arg:
 | 
				
			||||||
	};
 | 
						};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
package:
 | 
					package:
 | 
				
			||||||
	attr TOK_PACKAGE TOK_ID {
 | 
						attr TOK_PACKAGE {
 | 
				
			||||||
 | 
							enterTypeScope();
 | 
				
			||||||
 | 
						} TOK_ID {
 | 
				
			||||||
		AstNode *mod = new AstNode(AST_PACKAGE);
 | 
							AstNode *mod = new AstNode(AST_PACKAGE);
 | 
				
			||||||
		ast_stack.back()->children.push_back(mod);
 | 
							ast_stack.back()->children.push_back(mod);
 | 
				
			||||||
		ast_stack.push_back(mod);
 | 
							ast_stack.push_back(mod);
 | 
				
			||||||
		current_ast_mod = mod;
 | 
							current_ast_mod = mod;
 | 
				
			||||||
		mod->str = *$3;
 | 
							mod->str = *$4;
 | 
				
			||||||
		append_attr(mod, $1);
 | 
							append_attr(mod, $1);
 | 
				
			||||||
	} ';' package_body TOK_ENDPACKAGE {
 | 
						} ';' package_body TOK_ENDPACKAGE {
 | 
				
			||||||
		ast_stack.pop_back();
 | 
							ast_stack.pop_back();
 | 
				
			||||||
		current_ast_mod = NULL;
 | 
							current_ast_mod = NULL;
 | 
				
			||||||
		user_types.clear();
 | 
							exitTypeScope();
 | 
				
			||||||
	};
 | 
						};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
package_body:
 | 
					package_body:
 | 
				
			||||||
| 
						 | 
					@ -505,7 +524,9 @@ package_body_stmt:
 | 
				
			||||||
	localparam_decl;
 | 
						localparam_decl;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
interface:
 | 
					interface:
 | 
				
			||||||
	TOK_INTERFACE TOK_ID {
 | 
						TOK_INTERFACE {
 | 
				
			||||||
 | 
							enterTypeScope();
 | 
				
			||||||
 | 
						} TOK_ID {
 | 
				
			||||||
		do_not_require_port_stubs = false;
 | 
							do_not_require_port_stubs = false;
 | 
				
			||||||
		AstNode *intf = new AstNode(AST_INTERFACE);
 | 
							AstNode *intf = new AstNode(AST_INTERFACE);
 | 
				
			||||||
		ast_stack.back()->children.push_back(intf);
 | 
							ast_stack.back()->children.push_back(intf);
 | 
				
			||||||
| 
						 | 
					@ -513,8 +534,8 @@ interface:
 | 
				
			||||||
		current_ast_mod = intf;
 | 
							current_ast_mod = intf;
 | 
				
			||||||
		port_stubs.clear();
 | 
							port_stubs.clear();
 | 
				
			||||||
		port_counter = 0;
 | 
							port_counter = 0;
 | 
				
			||||||
		intf->str = *$2;
 | 
							intf->str = *$3;
 | 
				
			||||||
		delete $2;
 | 
							delete $3;
 | 
				
			||||||
	} module_para_opt module_args_opt ';' interface_body TOK_ENDINTERFACE {
 | 
						} module_para_opt module_args_opt ';' interface_body TOK_ENDINTERFACE {
 | 
				
			||||||
		if (port_stubs.size() != 0)
 | 
							if (port_stubs.size() != 0)
 | 
				
			||||||
			frontend_verilog_yyerror("Missing details for module port `%s'.",
 | 
								frontend_verilog_yyerror("Missing details for module port `%s'.",
 | 
				
			||||||
| 
						 | 
					@ -522,7 +543,7 @@ interface:
 | 
				
			||||||
		ast_stack.pop_back();
 | 
							ast_stack.pop_back();
 | 
				
			||||||
		log_assert(ast_stack.size() == 1);
 | 
							log_assert(ast_stack.size() == 1);
 | 
				
			||||||
		current_ast_mod = NULL;
 | 
							current_ast_mod = NULL;
 | 
				
			||||||
		user_types.clear();
 | 
							exitTypeScope();
 | 
				
			||||||
	};
 | 
						};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
interface_body:
 | 
					interface_body:
 | 
				
			||||||
| 
						 | 
					@ -1621,7 +1642,7 @@ assign_expr:
 | 
				
			||||||
	};
 | 
						};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
type_name: TOK_ID		// first time seen
 | 
					type_name: TOK_ID		// first time seen
 | 
				
			||||||
	 | TOK_USER_TYPE	// redefinition
 | 
						 | TOK_USER_TYPE	{ if (isInLocalScope($1)) frontend_verilog_yyerror("Duplicate declaration of TYPEDEF '%s'", $1->c_str()+1); }
 | 
				
			||||||
	 ;
 | 
						 ;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
typedef_decl:
 | 
					typedef_decl:
 | 
				
			||||||
| 
						 | 
					@ -2210,20 +2231,21 @@ behavioral_stmt:
 | 
				
			||||||
	} opt_arg_list ';'{
 | 
						} opt_arg_list ';'{
 | 
				
			||||||
		ast_stack.pop_back();
 | 
							ast_stack.pop_back();
 | 
				
			||||||
	} |
 | 
						} |
 | 
				
			||||||
	attr TOK_BEGIN opt_label {
 | 
						attr TOK_BEGIN {
 | 
				
			||||||
 | 
							enterTypeScope();
 | 
				
			||||||
 | 
						} opt_label {
 | 
				
			||||||
		AstNode *node = new AstNode(AST_BLOCK);
 | 
							AstNode *node = new AstNode(AST_BLOCK);
 | 
				
			||||||
		ast_stack.back()->children.push_back(node);
 | 
							ast_stack.back()->children.push_back(node);
 | 
				
			||||||
		ast_stack.push_back(node);
 | 
							ast_stack.push_back(node);
 | 
				
			||||||
		append_attr(node, $1);
 | 
							append_attr(node, $1);
 | 
				
			||||||
		if ($3 != NULL)
 | 
							if ($4 != NULL)
 | 
				
			||||||
			node->str = *$3;
 | 
								node->str = *$4;
 | 
				
			||||||
	} behavioral_stmt_list TOK_END opt_label {
 | 
						} behavioral_stmt_list TOK_END opt_label {
 | 
				
			||||||
		if ($3 != NULL && $7 != NULL && *$3 != *$7)
 | 
							exitTypeScope();
 | 
				
			||||||
			frontend_verilog_yyerror("Begin label (%s) and end label (%s) don't match.", $3->c_str()+1, $7->c_str()+1);
 | 
							if ($4 != NULL && $8 != NULL && *$4 != *$8)
 | 
				
			||||||
		if ($3 != NULL)
 | 
								frontend_verilog_yyerror("Begin label (%s) and end label (%s) don't match.", $4->c_str()+1, $8->c_str()+1);
 | 
				
			||||||
			delete $3;
 | 
							delete $4;
 | 
				
			||||||
		if ($7 != NULL)
 | 
							delete $8;
 | 
				
			||||||
			delete $7;
 | 
					 | 
				
			||||||
		ast_stack.pop_back();
 | 
							ast_stack.pop_back();
 | 
				
			||||||
	} |
 | 
						} |
 | 
				
			||||||
	attr TOK_FOR '(' {
 | 
						attr TOK_FOR '(' {
 | 
				
			||||||
| 
						 | 
					@ -2301,6 +2323,8 @@ behavioral_stmt:
 | 
				
			||||||
		ast_stack.pop_back();
 | 
							ast_stack.pop_back();
 | 
				
			||||||
	};
 | 
						};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
unique_case_attr:
 | 
					unique_case_attr:
 | 
				
			||||||
	/* empty */ {
 | 
						/* empty */ {
 | 
				
			||||||
		$$ = false;
 | 
							$$ = false;
 | 
				
			||||||
| 
						 | 
					@ -2516,16 +2540,17 @@ gen_stmt:
 | 
				
			||||||
		case_type_stack.pop_back();
 | 
							case_type_stack.pop_back();
 | 
				
			||||||
		ast_stack.pop_back();
 | 
							ast_stack.pop_back();
 | 
				
			||||||
	} |
 | 
						} |
 | 
				
			||||||
	TOK_BEGIN opt_label {
 | 
						TOK_BEGIN {
 | 
				
			||||||
 | 
							enterTypeScope();
 | 
				
			||||||
 | 
						} opt_label {
 | 
				
			||||||
		AstNode *node = new AstNode(AST_GENBLOCK);
 | 
							AstNode *node = new AstNode(AST_GENBLOCK);
 | 
				
			||||||
		node->str = $2 ? *$2 : std::string();
 | 
							node->str = $3 ? *$3 : std::string();
 | 
				
			||||||
		ast_stack.back()->children.push_back(node);
 | 
							ast_stack.back()->children.push_back(node);
 | 
				
			||||||
		ast_stack.push_back(node);
 | 
							ast_stack.push_back(node);
 | 
				
			||||||
	} module_gen_body TOK_END opt_label {
 | 
						} module_gen_body TOK_END opt_label {
 | 
				
			||||||
		if ($2 != NULL)
 | 
							exitTypeScope();
 | 
				
			||||||
			delete $2;
 | 
							delete $3;
 | 
				
			||||||
		if ($6 != NULL)
 | 
							delete $7;
 | 
				
			||||||
			delete $6;
 | 
					 | 
				
			||||||
		ast_stack.pop_back();
 | 
							ast_stack.pop_back();
 | 
				
			||||||
	} |
 | 
						} |
 | 
				
			||||||
	TOK_MSG_TASKS {
 | 
						TOK_MSG_TASKS {
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -31,5 +31,12 @@ module top;
 | 
				
			||||||
	always @(*) assert(inner_i2 == 4'h2);
 | 
						always @(*) assert(inner_i2 == 4'h2);
 | 
				
			||||||
	always @(*) assert(inner_enum2 == 3'h4);
 | 
						always @(*) assert(inner_enum2 == 3'h4);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					 | 
				
			||||||
endmodule
 | 
					endmodule
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					typedef logic[7:0]  between_t;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					module other;
 | 
				
			||||||
 | 
						between_t a = 8'h42;
 | 
				
			||||||
 | 
						always @(*) assert(a == 8'h42);
 | 
				
			||||||
 | 
					endmodule
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue