mirror of
				https://github.com/YosysHQ/yosys
				synced 2025-10-31 11:42:30 +00:00 
			
		
		
		
	Merge pull request #1803 from Grazfather/typedef
Support standard typedef grammar (Fixed)
This commit is contained in:
		
						commit
						b86905d952
					
				
					 12 changed files with 124 additions and 40 deletions
				
			
		|  | @ -1179,12 +1179,13 @@ void AST::process(RTLIL::Design *design, AstNode *ast, bool dump_ast1, bool dump | ||||||
| 			for (auto n : design->verilog_globals) | 			for (auto n : design->verilog_globals) | ||||||
| 				(*it)->children.push_back(n->clone()); | 				(*it)->children.push_back(n->clone()); | ||||||
| 
 | 
 | ||||||
| 			for (auto n : design->verilog_packages){ | 			// append nodes from previous packages using package-qualified names
 | ||||||
| 				for (auto o : n->children) { | 			for (auto &n : design->verilog_packages) { | ||||||
|  | 				for (auto &o : n->children) { | ||||||
| 					AstNode *cloned_node = o->clone(); | 					AstNode *cloned_node = o->clone(); | ||||||
| 					log("cloned node %s\n", type2str(cloned_node->type).c_str()); | 					// log("cloned node %s\n", type2str(cloned_node->type).c_str());
 | ||||||
| 					if (cloned_node->type == AST_ENUM){ | 					if (cloned_node->type == AST_ENUM) { | ||||||
| 						for (auto e : cloned_node->children){ | 						for (auto &e : cloned_node->children) { | ||||||
| 							log_assert(e->type == AST_ENUM_ITEM); | 							log_assert(e->type == AST_ENUM_ITEM); | ||||||
| 							e->str = n->str + std::string("::") + e->str.substr(1); | 							e->str = n->str + std::string("::") + e->str.substr(1); | ||||||
| 						} | 						} | ||||||
|  | @ -1220,6 +1221,8 @@ void AST::process(RTLIL::Design *design, AstNode *ast, bool dump_ast1, bool dump | ||||||
| 			design->add(process_module(*it, defer)); | 			design->add(process_module(*it, defer)); | ||||||
| 		} | 		} | ||||||
| 		else if ((*it)->type == AST_PACKAGE) { | 		else if ((*it)->type == AST_PACKAGE) { | ||||||
|  | 			// process enum/other declarations
 | ||||||
|  | 			(*it)->simplify(true, false, false, 1, -1, false, false); | ||||||
| 			design->verilog_packages.push_back((*it)->clone()); | 			design->verilog_packages.push_back((*it)->clone()); | ||||||
| 		} | 		} | ||||||
| 		else { | 		else { | ||||||
|  |  | ||||||
|  | @ -47,6 +47,22 @@ static void error_on_dpi_function(AST::AstNode *node) | ||||||
| 		error_on_dpi_function(child); | 		error_on_dpi_function(child); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | static void add_package_types(std::map<std::string, AST::AstNode *> &user_types, std::vector<AST::AstNode *> &package_list) | ||||||
|  | { | ||||||
|  | 	// prime the parser's user type lookup table with the package qualified names
 | ||||||
|  | 	// of typedefed names in the packages seen so far.
 | ||||||
|  | 	user_types.clear(); | ||||||
|  | 	for (const auto &pkg : package_list) { | ||||||
|  | 		log_assert(pkg->type==AST::AST_PACKAGE); | ||||||
|  | 		for (const auto &node: pkg->children) { | ||||||
|  | 			if (node->type == AST::AST_TYPEDEF) { | ||||||
|  | 				std::string s = pkg->str + "::" + node->str.substr(1); | ||||||
|  | 				user_types[s] = node; | ||||||
|  | 			} | ||||||
|  | 		} | ||||||
|  | 	} | ||||||
|  | } | ||||||
|  | 
 | ||||||
| struct VerilogFrontend : public Frontend { | struct VerilogFrontend : public Frontend { | ||||||
| 	VerilogFrontend() : Frontend("verilog", "read modules from Verilog file") { } | 	VerilogFrontend() : Frontend("verilog", "read modules from Verilog file") { } | ||||||
| 	void help() YS_OVERRIDE | 	void help() YS_OVERRIDE | ||||||
|  | @ -450,6 +466,9 @@ struct VerilogFrontend : public Frontend { | ||||||
| 			lexin = new std::istringstream(code_after_preproc); | 			lexin = new std::istringstream(code_after_preproc); | ||||||
| 		} | 		} | ||||||
| 
 | 
 | ||||||
|  | 		// make package typedefs available to parser
 | ||||||
|  | 		add_package_types(pkg_user_types, design->verilog_packages); | ||||||
|  | 
 | ||||||
| 		frontend_verilog_yyset_lineno(1); | 		frontend_verilog_yyset_lineno(1); | ||||||
| 		frontend_verilog_yyrestart(NULL); | 		frontend_verilog_yyrestart(NULL); | ||||||
| 		frontend_verilog_yyparse(); | 		frontend_verilog_yyparse(); | ||||||
|  | @ -468,6 +487,7 @@ struct VerilogFrontend : public Frontend { | ||||||
| 		AST::process(design, current_ast, flag_dump_ast1, flag_dump_ast2, flag_no_dump_ptr, flag_dump_vlog1, flag_dump_vlog2, flag_dump_rtlil, flag_nolatches, | 		AST::process(design, current_ast, flag_dump_ast1, flag_dump_ast2, flag_no_dump_ptr, flag_dump_vlog1, flag_dump_vlog2, flag_dump_rtlil, flag_nolatches, | ||||||
| 				flag_nomeminit, flag_nomem2reg, flag_mem2reg, flag_noblackbox, lib_mode, flag_nowb, flag_noopt, flag_icells, flag_pwires, flag_nooverwrite, flag_overwrite, flag_defer, default_nettype_wire); | 				flag_nomeminit, flag_nomem2reg, flag_mem2reg, flag_noblackbox, lib_mode, flag_nowb, flag_noopt, flag_icells, flag_pwires, flag_nooverwrite, flag_overwrite, flag_defer, default_nettype_wire); | ||||||
| 
 | 
 | ||||||
|  | 
 | ||||||
| 		if (!flag_nopp) | 		if (!flag_nopp) | ||||||
| 			delete lexin; | 			delete lexin; | ||||||
| 
 | 
 | ||||||
|  |  | ||||||
|  | @ -45,6 +45,12 @@ 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
 | ||||||
|  | 	extern std::map<std::string, AST::AstNode*> user_types; | ||||||
|  | 
 | ||||||
|  | 	// names of package typedef'ed types
 | ||||||
|  | 	extern std::map<std::string, AST::AstNode*> pkg_user_types; | ||||||
|  | 
 | ||||||
| 	// state of `default_nettype
 | 	// state of `default_nettype
 | ||||||
| 	extern bool default_nettype_wire; | 	extern bool default_nettype_wire; | ||||||
| 
 | 
 | ||||||
|  |  | ||||||
|  | @ -372,9 +372,33 @@ supply1 { return TOK_SUPPLY1; } | ||||||
| "$signed"   { return TOK_TO_SIGNED; } | "$signed"   { return TOK_TO_SIGNED; } | ||||||
| "$unsigned" { return TOK_TO_UNSIGNED; } | "$unsigned" { return TOK_TO_UNSIGNED; } | ||||||
| 
 | 
 | ||||||
| [a-zA-Z_$][a-zA-Z0-9_$]* { | [a-zA-Z_][a-zA-Z0-9_]*::[a-zA-Z_$][a-zA-Z0-9_$]* { | ||||||
|  | 	// package qualifier | ||||||
|  | 	auto s = std::string("\\") + yytext; | ||||||
|  | 	if (pkg_user_types.count(s) > 0) { | ||||||
|  | 		// found it | ||||||
|  | 		yylval->string = new std::string(s); | ||||||
|  | 		return TOK_USER_TYPE; | ||||||
|  | 	} | ||||||
|  | 	else { | ||||||
|  | 		// backup before :: just return first part | ||||||
|  | 		size_t len = strchr(yytext, ':') - yytext; | ||||||
|  | 		yyless(len); | ||||||
| 		yylval->string = new std::string(std::string("\\") + yytext); | 		yylval->string = new std::string(std::string("\\") + yytext); | ||||||
| 		return TOK_ID; | 		return TOK_ID; | ||||||
|  | 	} | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | [a-zA-Z_$][a-zA-Z0-9_$]* { | ||||||
|  | 	auto s = std::string("\\") + yytext; | ||||||
|  | 	if (user_types.count(s) > 0) { | ||||||
|  | 		yylval->string = new std::string(s); | ||||||
|  | 		return TOK_USER_TYPE; | ||||||
|  | 	} | ||||||
|  | 	else { | ||||||
|  | 		yylval->string = new std::string(std::string("\\") + yytext); | ||||||
|  | 		return TOK_ID; | ||||||
|  | 	} | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| [a-zA-Z_$][a-zA-Z0-9_$\.]* { | [a-zA-Z_$][a-zA-Z0-9_$\.]* { | ||||||
|  |  | ||||||
|  | @ -54,6 +54,8 @@ 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::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; | ||||||
| 	struct AstNode *current_function_or_task; | 	struct AstNode *current_function_or_task; | ||||||
|  | @ -125,6 +127,26 @@ struct specify_rise_fall { | ||||||
| 	specify_triple fall; | 	specify_triple fall; | ||||||
| }; | }; | ||||||
| 
 | 
 | ||||||
|  | static void addTypedefNode(std::string *name, AstNode *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); | ||||||
|  | 	tnode->str = *name; | ||||||
|  | 	user_types[*name] = tnode; | ||||||
|  | 	if (current_ast_mod && current_ast_mod->type == AST_PACKAGE) { | ||||||
|  | 		// typedef inside a package so we need the qualified name | ||||||
|  | 		auto qname = current_ast_mod->str + "::" + (*name).substr(1); | ||||||
|  | 		pkg_user_types[qname] = tnode; | ||||||
|  | 	} | ||||||
|  | 	delete name; | ||||||
|  | 	ast_stack.back()->children.push_back(tnode); | ||||||
|  | } | ||||||
|  | 
 | ||||||
| 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); | ||||||
|  | @ -167,6 +189,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 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 | ||||||
|  | @ -190,6 +213,7 @@ static void addRange(AstNode *parent, int msb = 31, int lsb = 0, bool isSigned = | ||||||
| %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_sva_label tok_prim_wrapper hierarchical_id hierarchical_type_id integral_number | %type <string> opt_label opt_sva_label tok_prim_wrapper hierarchical_id hierarchical_type_id integral_number | ||||||
|  | %type <string> type_name | ||||||
| %type <ast> opt_enum_init | %type <ast> opt_enum_init | ||||||
| %type <boolean> opt_signed opt_property unique_case_attr always_comb_or_latch always_or_always_ff | %type <boolean> opt_signed opt_property unique_case_attr always_comb_or_latch always_or_always_ff | ||||||
| %type <al> attr case_attr | %type <al> attr case_attr | ||||||
|  | @ -330,7 +354,9 @@ hierarchical_id: | ||||||
| 	}; | 	}; | ||||||
| 
 | 
 | ||||||
| hierarchical_type_id: | hierarchical_type_id: | ||||||
| 	'(' hierarchical_id ')' { $$ = $2; }; | 	TOK_USER_TYPE | ||||||
|  | 	| '(' TOK_USER_TYPE ')'	{ $$ = $2; }		// non-standard grammar | ||||||
|  | 	; | ||||||
| 
 | 
 | ||||||
| module: | module: | ||||||
| 	attr TOK_MODULE TOK_ID { | 	attr TOK_MODULE TOK_ID { | ||||||
|  | @ -352,6 +378,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(); | ||||||
| 	}; | 	}; | ||||||
| 
 | 
 | ||||||
| module_para_opt: | module_para_opt: | ||||||
|  | @ -465,6 +492,7 @@ package: | ||||||
| 	} ';' 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(); | ||||||
| 	}; | 	}; | ||||||
| 
 | 
 | ||||||
| package_body: | package_body: | ||||||
|  | @ -494,6 +522,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(); | ||||||
| 	}; | 	}; | ||||||
| 
 | 
 | ||||||
| interface_body: | interface_body: | ||||||
|  | @ -1591,8 +1620,12 @@ assign_expr: | ||||||
| 		ast_stack.back()->children.push_back(node); | 		ast_stack.back()->children.push_back(node); | ||||||
| 	}; | 	}; | ||||||
| 
 | 
 | ||||||
|  | type_name: TOK_ID		// first time seen | ||||||
|  | 	 | TOK_USER_TYPE	// redefinition | ||||||
|  | 	 ; | ||||||
|  | 
 | ||||||
| typedef_decl: | typedef_decl: | ||||||
| 	TOK_TYPEDEF wire_type range TOK_ID range_or_multirange ';' { | 	TOK_TYPEDEF wire_type range type_name range_or_multirange ';' { | ||||||
| 		astbuf1 = $2; | 		astbuf1 = $2; | ||||||
| 		astbuf2 = $3; | 		astbuf2 = $3; | ||||||
| 		if (astbuf1->range_left >= 0 && astbuf1->range_right >= 0) { | 		if (astbuf1->range_left >= 0 && astbuf1->range_right >= 0) { | ||||||
|  | @ -1625,13 +1658,10 @@ typedef_decl: | ||||||
| 			} | 			} | ||||||
| 			astbuf1->children.push_back(rangeNode); | 			astbuf1->children.push_back(rangeNode); | ||||||
| 		} | 		} | ||||||
| 
 | 		addTypedefNode($4, astbuf1); | ||||||
| 		ast_stack.back()->children.push_back(new AstNode(AST_TYPEDEF, astbuf1)); |  | ||||||
| 		ast_stack.back()->children.back()->str = *$4; |  | ||||||
| 	} | | 	} | | ||||||
| 	TOK_TYPEDEF enum_type TOK_ID ';' { | 	TOK_TYPEDEF enum_type type_name ';' { | ||||||
| 		ast_stack.back()->children.push_back(new AstNode(AST_TYPEDEF, astbuf1)); | 		addTypedefNode($3, astbuf1); | ||||||
| 		ast_stack.back()->children.back()->str = *$3; |  | ||||||
| 	} | 	} | ||||||
| 	; | 	; | ||||||
| 
 | 
 | ||||||
|  |  | ||||||
|  | @ -5,8 +5,9 @@ module enum_simple(input clk, input rst); | ||||||
| 	typedef enum logic [1:0] { | 	typedef enum logic [1:0] { | ||||||
| 		ts0, ts1, ts2, ts3 | 		ts0, ts1, ts2, ts3 | ||||||
| 	} states_t; | 	} states_t; | ||||||
| 	(states_t) state; | 	states_t state; | ||||||
| 	(states_t) enum_const = ts1; | 	(states_t) state1; | ||||||
|  | 	states_t enum_const = ts1; | ||||||
| 
 | 
 | ||||||
| 	always @(posedge clk) begin | 	always @(posedge clk) begin | ||||||
| 		if (rst) begin | 		if (rst) begin | ||||||
|  |  | ||||||
|  | @ -1,7 +1,7 @@ | ||||||
| module top(input [3:0] addr, wdata, input clk, wen, output reg [3:0] rdata); | module top(input [3:0] addr, wdata, input clk, wen, output reg [3:0] rdata); | ||||||
| 	typedef logic [3:0] ram16x4_t[0:15]; | 	typedef logic [3:0] ram16x4_t[0:15]; | ||||||
| 
 | 
 | ||||||
| 	(ram16x4_t) mem; | 	ram16x4_t mem; | ||||||
| 
 | 
 | ||||||
| 	always @(posedge clk) begin | 	always @(posedge clk) begin | ||||||
| 		if (wen) mem[addr] <= wdata; | 		if (wen) mem[addr] <= wdata; | ||||||
|  |  | ||||||
|  | @ -1,7 +1,7 @@ | ||||||
| module top(input [3:0] addr, wdata, input clk, wen, output reg [3:0] rdata); | module top(input [3:0] addr, wdata, input clk, wen, output reg [3:0] rdata); | ||||||
| 	typedef logic [3:0] nibble; | 	typedef logic [3:0] nibble; | ||||||
| 
 | 
 | ||||||
| 	(nibble) mem[0:15]; | 	nibble mem[0:15]; | ||||||
| 
 | 
 | ||||||
| 	always @(posedge clk) begin | 	always @(posedge clk) begin | ||||||
| 		if (wen) mem[addr] <= wdata; | 		if (wen) mem[addr] <= wdata; | ||||||
|  |  | ||||||
|  | @ -5,8 +5,8 @@ endpackage | ||||||
| 
 | 
 | ||||||
| module top; | module top; | ||||||
| 
 | 
 | ||||||
| 	(* keep *) (pkg::uint8_t) a = 8'hAA; | 	(* keep *) pkg::uint8_t a = 8'hAA; | ||||||
| 	(* keep *) (pkg::enum8_t) b_enum = pkg::bb; | 	(* keep *) pkg::enum8_t b_enum = pkg::bb; | ||||||
| 
 | 
 | ||||||
| 	always @* assert(a == 8'hAA); | 	always @* assert(a == 8'hAA); | ||||||
| 	always @* assert(b_enum == 8'hBB); | 	always @* assert(b_enum == 8'hBB); | ||||||
|  |  | ||||||
|  | @ -6,12 +6,12 @@ module top; | ||||||
| 	typedef logic [1:0] uint2_t; | 	typedef logic [1:0] uint2_t; | ||||||
| 	typedef logic signed [3:0] int4_t; | 	typedef logic signed [3:0] int4_t; | ||||||
| 	typedef logic signed [7:0] int8_t; | 	typedef logic signed [7:0] int8_t; | ||||||
| 	typedef (int8_t) char_t; | 	typedef int8_t char_t; | ||||||
| 
 | 
 | ||||||
| 	parameter (uint2_t) int2 = 2'b10; | 	parameter uint2_t int2 = 2'b10; | ||||||
| 	localparam (int4_t) int4 = -1; | 	localparam int4_t int4 = -1; | ||||||
| 	localparam (int8_t) int8 = int4; | 	localparam int8_t int8 = int4; | ||||||
| 	localparam (char_t) ch = int8; | 	localparam char_t ch = int8; | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
| 	`STATIC_ASSERT(int2 == 2'b10); | 	`STATIC_ASSERT(int2 == 2'b10); | ||||||
|  |  | ||||||
|  | @ -4,30 +4,30 @@ typedef enum logic {s0, s1} outer_enum_t; | ||||||
| 
 | 
 | ||||||
| module top; | module top; | ||||||
| 
 | 
 | ||||||
| 	(outer_uint4_t) u4_i = 8'hA5; | 	outer_uint4_t u4_i = 8'hA5; | ||||||
| 	(outer_enum_t) enum4_i = s0; | 	outer_enum_t enum4_i = s0; | ||||||
| 	always @(*) assert(u4_i == 4'h5); | 	always @(*) assert(u4_i == 4'h5); | ||||||
| 	always @(*) assert(enum4_i == 1'b0); | 	always @(*) assert(enum4_i == 1'b0); | ||||||
| 
 | 
 | ||||||
| 	typedef logic [3:0] inner_type; | 	typedef logic [3:0] inner_type; | ||||||
| 	typedef enum logic [2:0] {s2=2, s3, s4} inner_enum_t; | 	typedef enum logic [2:0] {s2=2, s3, s4} inner_enum_t; | ||||||
| 	(inner_type) inner_i1 = 8'h5A; | 	inner_type inner_i1 = 8'h5A; | ||||||
| 	(inner_enum_t) inner_enum1 = s3; | 	inner_enum_t inner_enum1 = s3; | ||||||
| 	always @(*) assert(inner_i1 == 4'hA); | 	always @(*) assert(inner_i1 == 4'hA); | ||||||
| 	always @(*) assert(inner_enum1 == 3'h3); | 	always @(*) assert(inner_enum1 == 3'h3); | ||||||
| 
 | 
 | ||||||
| 	if (1) begin: genblock | 	if (1) begin: genblock | ||||||
| 		typedef logic [7:0] inner_type; | 		typedef logic [7:0] inner_type; | ||||||
| 		parameter (inner_type) inner_const = 8'hA5; | 		parameter inner_type inner_const = 8'hA5; | ||||||
|  		typedef enum logic [2:0] {s5=5, s6, s7} inner_enum_t; |  		typedef enum logic [2:0] {s5=5, s6, s7} inner_enum_t; | ||||||
| 		(inner_type) inner_gb_i = inner_const; //8'hA5;
 | 		inner_type inner_gb_i = inner_const; //8'hA5;
 | ||||||
|  		(inner_enum_t) inner_gb_enum1 = s7; |  		inner_enum_t inner_gb_enum1 = s7; | ||||||
| 		always @(*) assert(inner_gb_i == 8'hA5); | 		always @(*) assert(inner_gb_i == 8'hA5); | ||||||
|  		always @(*) assert(inner_gb_enum1 == 3'h7); |  		always @(*) assert(inner_gb_enum1 == 3'h7); | ||||||
| 	end | 	end | ||||||
| 
 | 
 | ||||||
| 	(inner_type) inner_i2 = 8'h42; | 	inner_type inner_i2 = 8'h42; | ||||||
| 	(inner_enum_t) inner_enum2 = s4; | 	inner_enum_t inner_enum2 = s4; | ||||||
| 	always @(*) assert(inner_i2 == 4'h2); | 	always @(*) assert(inner_i2 == 4'h2); | ||||||
| 	always @(*) assert(inner_enum2 == 3'h4); | 	always @(*) assert(inner_enum2 == 3'h4); | ||||||
| 
 | 
 | ||||||
|  |  | ||||||
|  | @ -3,12 +3,12 @@ module top; | ||||||
| 	typedef logic [1:0] uint2_t; | 	typedef logic [1:0] uint2_t; | ||||||
| 	typedef logic signed [3:0] int4_t; | 	typedef logic signed [3:0] int4_t; | ||||||
| 	typedef logic signed [7:0] int8_t; | 	typedef logic signed [7:0] int8_t; | ||||||
| 	typedef (int8_t) char_t; | 	typedef int8_t char_t; | ||||||
| 
 | 
 | ||||||
| 	(* keep *) (uint2_t) int2 = 2'b10; | 	(* keep *) uint2_t int2 = 2'b10; | ||||||
| 	(* keep *) (int4_t) int4 = -1; | 	(* keep *) int4_t int4 = -1; | ||||||
| 	(* keep *) (int8_t) int8 = int4; | 	(* keep *) int8_t int8 = int4; | ||||||
| 	(* keep *) (char_t) ch = int8; | 	(* keep *) char_t ch = int8; | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
| 	always @* assert(int2 == 2'b10); | 	always @* assert(int2 == 2'b10); | ||||||
|  |  | ||||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue