mirror of
				https://github.com/YosysHQ/yosys
				synced 2025-10-29 18:52:30 +00:00 
			
		
		
		
	Merge pull request #659 from rubund/sv_interfaces
Support for SystemVerilog interfaces and modports
This commit is contained in:
		
						commit
						f24bc1ed0a
					
				
					 11 changed files with 649 additions and 21 deletions
				
			
		|  | @ -153,6 +153,9 @@ YOSYS_NAMESPACE_END | |||
| "specparam"    { return TOK_SPECPARAM; } | ||||
| "package"      { SV_KEYWORD(TOK_PACKAGE); } | ||||
| "endpackage"   { SV_KEYWORD(TOK_ENDPACKAGE); } | ||||
| "interface"    { SV_KEYWORD(TOK_INTERFACE); } | ||||
| "endinterface" { SV_KEYWORD(TOK_ENDINTERFACE); } | ||||
| "modport"      { SV_KEYWORD(TOK_MODPORT); } | ||||
| "parameter"    { return TOK_PARAMETER; } | ||||
| "localparam"   { return TOK_LOCALPARAM; } | ||||
| "defparam"     { return TOK_DEFPARAM; } | ||||
|  | @ -298,6 +301,11 @@ supply1 { return TOK_SUPPLY1; } | |||
| 	return TOK_ID; | ||||
| } | ||||
| 
 | ||||
| [a-zA-Z_$][a-zA-Z0-9_$\.]* { | ||||
| 	frontend_verilog_yylval.string = new std::string(std::string("\\") + yytext); | ||||
|     return TOK_ID; | ||||
| } | ||||
| 
 | ||||
| "/*"[ \t]*(synopsys|synthesis)[ \t]*translate_off[ \t]*"*/" { | ||||
| 	static bool printed_warning = false; | ||||
| 	if (!printed_warning) { | ||||
|  |  | |||
|  | @ -61,6 +61,7 @@ namespace VERILOG_FRONTEND { | |||
| 	bool noassert_mode, noassume_mode, norestrict_mode; | ||||
| 	bool assume_asserts_mode, assert_assumes_mode; | ||||
| 	bool current_wire_rand, current_wire_const; | ||||
| 	bool current_modport_input, current_modport_output; | ||||
| 	std::istream *lexin; | ||||
| } | ||||
| YOSYS_NAMESPACE_END | ||||
|  | @ -106,6 +107,7 @@ static void free_attr(std::map<std::string, AstNode*> *al) | |||
| %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 | ||||
| %token TOK_INTERFACE TOK_ENDINTERFACE TOK_MODPORT | ||||
| %token TOK_INPUT TOK_OUTPUT TOK_INOUT TOK_WIRE TOK_REG TOK_LOGIC | ||||
| %token TOK_INTEGER TOK_SIGNED TOK_ASSIGN TOK_ALWAYS TOK_INITIAL | ||||
| %token TOK_BEGIN TOK_END TOK_IF TOK_ELSE TOK_FOR TOK_WHILE TOK_REPEAT | ||||
|  | @ -168,6 +170,7 @@ design: | |||
| 	param_decl design | | ||||
| 	localparam_decl design | | ||||
| 	package design | | ||||
| 	interface design | | ||||
| 	/* empty */; | ||||
| 
 | ||||
| attr: | ||||
|  | @ -320,6 +323,21 @@ module_arg: | |||
| 		} | ||||
| 		delete $1; | ||||
| 	} module_arg_opt_assignment | | ||||
| 	TOK_ID { | ||||
| 		astbuf1 = new AstNode(AST_INTERFACEPORT); | ||||
| 		astbuf1->children.push_back(new AstNode(AST_INTERFACEPORTTYPE)); | ||||
| 		astbuf1->children[0]->str = *$1; | ||||
| 		delete $1; | ||||
| 	} TOK_ID {  /* SV interfaces */ | ||||
| 		if (!sv_mode) | ||||
| 			frontend_verilog_yyerror("Interface found in port list (%s). This is not supported unless read_verilog is called with -sv!", $3->c_str()); | ||||
| 		astbuf2 = astbuf1->clone(); // really only needed if multiple instances of same type. | ||||
| 		astbuf2->str = *$3; | ||||
| 		delete $3; | ||||
| 		astbuf2->port_id = ++port_counter; | ||||
| 		ast_stack.back()->children.push_back(astbuf2); | ||||
| 		delete astbuf1; // really only needed if multiple instances of same type. | ||||
| 	} module_arg_opt_assignment | | ||||
| 	attr wire_type range TOK_ID { | ||||
| 		AstNode *node = $2; | ||||
| 		node->str = *$4; | ||||
|  | @ -357,6 +375,33 @@ package_body: | |||
| package_body_stmt: | ||||
| 	localparam_decl; | ||||
| 
 | ||||
| interface: | ||||
| 	TOK_INTERFACE TOK_ID { | ||||
| 		do_not_require_port_stubs = false; | ||||
| 		AstNode *intf = new AstNode(AST_INTERFACE); | ||||
| 		ast_stack.back()->children.push_back(intf); | ||||
| 		ast_stack.push_back(intf); | ||||
| 		current_ast_mod = intf; | ||||
| 		port_stubs.clear(); | ||||
| 		port_counter = 0; | ||||
| 		intf->str = *$2; | ||||
| 		delete $2; | ||||
| 	} module_para_opt module_args_opt ';' interface_body TOK_ENDINTERFACE { | ||||
| 		if (port_stubs.size() != 0) | ||||
| 			frontend_verilog_yyerror("Missing details for module port `%s'.", | ||||
| 				port_stubs.begin()->first.c_str()); | ||||
| 		ast_stack.pop_back(); | ||||
| 		log_assert(ast_stack.size() == 1); | ||||
| 		current_ast_mod = NULL; | ||||
| 	}; | ||||
| 
 | ||||
| interface_body: | ||||
| 	interface_body interface_body_stmt |; | ||||
| 
 | ||||
| interface_body_stmt: | ||||
| 	param_decl | localparam_decl | defparam_decl | wire_decl | always_stmt | assign_stmt | | ||||
| 	modport_stmt; | ||||
| 
 | ||||
| non_opt_delay: | ||||
| 	'#' TOK_ID { delete $2; } | | ||||
| 	'#' TOK_CONSTVAL { delete $2; } | | ||||
|  | @ -1280,6 +1325,41 @@ opt_property: | |||
| opt_stmt_label: | ||||
| 	TOK_ID ':' | /* empty */; | ||||
| 
 | ||||
| modport_stmt: | ||||
|     TOK_MODPORT TOK_ID { | ||||
|         AstNode *modport = new AstNode(AST_MODPORT); | ||||
|         ast_stack.back()->children.push_back(modport); | ||||
|         ast_stack.push_back(modport); | ||||
|         modport->str = *$2; | ||||
|         delete $2; | ||||
|     }  modport_args_opt { | ||||
|         ast_stack.pop_back(); | ||||
|         log_assert(ast_stack.size() == 2); | ||||
|     } ';' | ||||
| 
 | ||||
| modport_args_opt: | ||||
|     '(' ')' | '(' modport_args optional_comma ')'; | ||||
| 
 | ||||
| modport_args: | ||||
|     modport_arg | modport_args ',' modport_arg; | ||||
| 
 | ||||
| modport_arg: | ||||
|     modport_type_token modport_member | | ||||
|     modport_member | ||||
| 
 | ||||
| modport_member: | ||||
|     TOK_ID { | ||||
|         AstNode *modport_member = new AstNode(AST_MODPORTMEMBER); | ||||
|         ast_stack.back()->children.push_back(modport_member); | ||||
|         modport_member->str = *$1; | ||||
|         modport_member->is_input = current_modport_input; | ||||
|         modport_member->is_output = current_modport_output; | ||||
|         delete $1; | ||||
|     } | ||||
| 
 | ||||
| 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) | ||||
|  |  | |||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue