mirror of
				https://github.com/YosysHQ/yosys
				synced 2025-11-04 05:19:11 +00:00 
			
		
		
		
	Use "(id)" instead of "id" for types as temporary hack
Signed-off-by: Clifford Wolf <clifford@clifford.at>
This commit is contained in:
		
						commit
						e84cedfae4
					
				
					 17 changed files with 315 additions and 20 deletions
				
			
		| 
						 | 
				
			
			@ -164,6 +164,8 @@ std::string AST::type2str(AstNodeType type)
 | 
			
		|||
	X(AST_MODPORT)
 | 
			
		||||
	X(AST_MODPORTMEMBER)
 | 
			
		||||
	X(AST_PACKAGE)
 | 
			
		||||
	X(AST_WIRETYPE)
 | 
			
		||||
	X(AST_TYPEDEF)
 | 
			
		||||
#undef X
 | 
			
		||||
	default:
 | 
			
		||||
		log_abort();
 | 
			
		||||
| 
						 | 
				
			
			@ -206,6 +208,7 @@ AstNode::AstNode(AstNodeType type, AstNode *child1, AstNode *child2, AstNode *ch
 | 
			
		|||
	was_checked = false;
 | 
			
		||||
	range_valid = false;
 | 
			
		||||
	range_swapped = false;
 | 
			
		||||
	is_custom_type = false;
 | 
			
		||||
	port_id = 0;
 | 
			
		||||
	range_left = -1;
 | 
			
		||||
	range_right = 0;
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -148,7 +148,10 @@ namespace AST
 | 
			
		|||
		AST_INTERFACEPORTTYPE,
 | 
			
		||||
		AST_MODPORT,
 | 
			
		||||
		AST_MODPORTMEMBER,
 | 
			
		||||
		AST_PACKAGE
 | 
			
		||||
		AST_PACKAGE,
 | 
			
		||||
 | 
			
		||||
		AST_WIRETYPE,
 | 
			
		||||
		AST_TYPEDEF
 | 
			
		||||
	};
 | 
			
		||||
 | 
			
		||||
	// convert an node type to a string (e.g. for debug output)
 | 
			
		||||
| 
						 | 
				
			
			@ -174,7 +177,7 @@ namespace AST
 | 
			
		|||
		// node content - most of it is unused in most node types
 | 
			
		||||
		std::string str;
 | 
			
		||||
		std::vector<RTLIL::State> bits;
 | 
			
		||||
		bool is_input, is_output, is_reg, is_logic, is_signed, is_string, is_wand, is_wor, range_valid, range_swapped, was_checked, is_unsized;
 | 
			
		||||
		bool is_input, is_output, is_reg, is_logic, is_signed, is_string, is_wand, is_wor, range_valid, range_swapped, was_checked, is_unsized, is_custom_type;
 | 
			
		||||
		int port_id, range_left, range_right;
 | 
			
		||||
		uint32_t integer;
 | 
			
		||||
		double realvalue;
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -863,6 +863,7 @@ RTLIL::SigSpec AstNode::genRTLIL(int width_hint, bool sign_hint)
 | 
			
		|||
	case AST_PACKAGE:
 | 
			
		||||
	case AST_MODPORT:
 | 
			
		||||
	case AST_MODPORTMEMBER:
 | 
			
		||||
	case AST_TYPEDEF:
 | 
			
		||||
		break;
 | 
			
		||||
	case AST_INTERFACEPORT: {
 | 
			
		||||
		// If a port in a module with unknown type is found, mark it with the attribute 'is_interface'
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -318,7 +318,7 @@ bool AstNode::simplify(bool const_fold, bool at_zero, bool in_lvalue, int stage,
 | 
			
		|||
	}
 | 
			
		||||
 | 
			
		||||
	// activate const folding if this is anything that must be evaluated statically (ranges, parameters, attributes, etc.)
 | 
			
		||||
	if (type == AST_WIRE || type == AST_PARAMETER || type == AST_LOCALPARAM || type == AST_DEFPARAM || type == AST_PARASET || type == AST_RANGE || type == AST_PREFIX)
 | 
			
		||||
	if (type == AST_WIRE || type == AST_PARAMETER || type == AST_LOCALPARAM || type == AST_DEFPARAM || type == AST_PARASET || type == AST_RANGE || type == AST_PREFIX || type == AST_TYPEDEF)
 | 
			
		||||
		const_fold = true;
 | 
			
		||||
	if (type == AST_IDENTIFIER && current_scope.count(str) > 0 && (current_scope[str]->type == AST_PARAMETER || current_scope[str]->type == AST_LOCALPARAM))
 | 
			
		||||
		const_fold = true;
 | 
			
		||||
| 
						 | 
				
			
			@ -336,6 +336,7 @@ bool AstNode::simplify(bool const_fold, bool at_zero, bool in_lvalue, int stage,
 | 
			
		|||
		std::map<std::string, AstNode*> this_wire_scope;
 | 
			
		||||
		for (size_t i = 0; i < children.size(); i++) {
 | 
			
		||||
			AstNode *node = children[i];
 | 
			
		||||
 | 
			
		||||
			if (node->type == AST_WIRE) {
 | 
			
		||||
				if (node->children.size() == 1 && node->children[0]->type == AST_RANGE) {
 | 
			
		||||
					for (auto c : node->children[0]->children) {
 | 
			
		||||
| 
						 | 
				
			
			@ -405,14 +406,15 @@ bool AstNode::simplify(bool const_fold, bool at_zero, bool in_lvalue, int stage,
 | 
			
		|||
				this_wire_scope[node->str] = node;
 | 
			
		||||
			}
 | 
			
		||||
			if (node->type == AST_PARAMETER || node->type == AST_LOCALPARAM || node->type == AST_WIRE || node->type == AST_AUTOWIRE || node->type == AST_GENVAR ||
 | 
			
		||||
					node->type == AST_MEMORY || node->type == AST_FUNCTION || node->type == AST_TASK || node->type == AST_DPI_FUNCTION || node->type == AST_CELL) {
 | 
			
		||||
					node->type == AST_MEMORY || node->type == AST_FUNCTION || node->type == AST_TASK || node->type == AST_DPI_FUNCTION || node->type == AST_CELL ||
 | 
			
		||||
					node->type == AST_TYPEDEF) {
 | 
			
		||||
				backup_scope[node->str] = current_scope[node->str];
 | 
			
		||||
				current_scope[node->str] = node;
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
		for (size_t i = 0; i < children.size(); i++) {
 | 
			
		||||
			AstNode *node = children[i];
 | 
			
		||||
			if (node->type == AST_PARAMETER || node->type == AST_LOCALPARAM || node->type == AST_WIRE || node->type == AST_AUTOWIRE || node->type == AST_MEMORY)
 | 
			
		||||
			if (node->type == AST_PARAMETER || node->type == AST_LOCALPARAM || node->type == AST_WIRE || node->type == AST_AUTOWIRE || node->type == AST_MEMORY || node->type == AST_TYPEDEF)
 | 
			
		||||
				while (node->simplify(true, false, false, 1, -1, false, node->type == AST_PARAMETER || node->type == AST_LOCALPARAM))
 | 
			
		||||
					did_something = true;
 | 
			
		||||
		}
 | 
			
		||||
| 
						 | 
				
			
			@ -780,6 +782,99 @@ bool AstNode::simplify(bool const_fold, bool at_zero, bool in_lvalue, int stage,
 | 
			
		|||
		delete_children();
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	// resolve typedefs
 | 
			
		||||
	if (type == AST_TYPEDEF) {
 | 
			
		||||
		log_assert(children.size() == 1);
 | 
			
		||||
		log_assert(children[0]->type == AST_WIRE || children[0]->type == AST_MEMORY);
 | 
			
		||||
		while(children[0]->simplify(const_fold, at_zero, in_lvalue, stage, width_hint, sign_hint, in_param))
 | 
			
		||||
			did_something = true;
 | 
			
		||||
		log_assert(!children[0]->is_custom_type);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	// resolve types of wires
 | 
			
		||||
	if (type == AST_WIRE || type == AST_MEMORY) {
 | 
			
		||||
		if (is_custom_type) {
 | 
			
		||||
			log_assert(children.size() >= 1);
 | 
			
		||||
			log_assert(children[0]->type == AST_WIRETYPE);
 | 
			
		||||
			if (!current_scope.count(children[0]->str))
 | 
			
		||||
				log_file_error(filename, linenum, "Unknown identifier `%s' used as type name\n", children[0]->str.c_str());
 | 
			
		||||
			AstNode *resolved_type = current_scope.at(children[0]->str);
 | 
			
		||||
			if (resolved_type->type != AST_TYPEDEF)
 | 
			
		||||
				log_file_error(filename, linenum, "`%s' does not name a type\n", children[0]->str.c_str());
 | 
			
		||||
			log_assert(resolved_type->children.size() == 1);
 | 
			
		||||
			AstNode *templ = resolved_type->children[0];
 | 
			
		||||
			// Remove type reference
 | 
			
		||||
			delete children[0];
 | 
			
		||||
			children.erase(children.begin());
 | 
			
		||||
 | 
			
		||||
			// Ensure typedef itself is fully simplified
 | 
			
		||||
			while(templ->simplify(const_fold, at_zero, in_lvalue, stage, width_hint, sign_hint, in_param)) {};
 | 
			
		||||
 | 
			
		||||
			if (type == AST_WIRE)
 | 
			
		||||
				type = templ->type;
 | 
			
		||||
			is_reg = templ->is_reg;
 | 
			
		||||
			is_logic = templ->is_logic;
 | 
			
		||||
			is_signed = templ->is_signed;
 | 
			
		||||
			is_string = templ->is_string;
 | 
			
		||||
			is_custom_type = templ->is_custom_type;
 | 
			
		||||
 | 
			
		||||
			range_valid = templ->range_valid;
 | 
			
		||||
			range_swapped = templ->range_swapped;
 | 
			
		||||
			range_left = templ->range_left;
 | 
			
		||||
			range_right = templ->range_right;
 | 
			
		||||
 | 
			
		||||
			// Insert clones children from template at beginning
 | 
			
		||||
			for (int i  = 0; i < GetSize(templ->children); i++)
 | 
			
		||||
				children.insert(children.begin() + i, templ->children[i]->clone());
 | 
			
		||||
			
 | 
			
		||||
			if (type == AST_MEMORY && GetSize(children) == 1) {
 | 
			
		||||
				// Single-bit memories must have [0:0] range
 | 
			
		||||
				AstNode *rng = new AstNode(AST_RANGE);
 | 
			
		||||
				rng->children.push_back(AstNode::mkconst_int(0, true));
 | 
			
		||||
				rng->children.push_back(AstNode::mkconst_int(0, true));
 | 
			
		||||
				children.insert(children.begin(), rng);
 | 
			
		||||
			}
 | 
			
		||||
 | 
			
		||||
			did_something = true;
 | 
			
		||||
		}
 | 
			
		||||
		log_assert(!is_custom_type);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	// resolve types of parameters
 | 
			
		||||
	if (type == AST_LOCALPARAM || type == AST_PARAMETER) {
 | 
			
		||||
		if (is_custom_type) {
 | 
			
		||||
			log_assert(children.size() == 2);
 | 
			
		||||
			log_assert(children[1]->type == AST_WIRETYPE);
 | 
			
		||||
			if (!current_scope.count(children[1]->str))
 | 
			
		||||
				log_file_error(filename, linenum, "Unknown identifier `%s' used as type name\n", children[1]->str.c_str());
 | 
			
		||||
			AstNode *resolved_type = current_scope.at(children[1]->str);
 | 
			
		||||
			if (resolved_type->type != AST_TYPEDEF)
 | 
			
		||||
				log_file_error(filename, linenum, "`%s' does not name a type\n", children[1]->str.c_str());
 | 
			
		||||
			log_assert(resolved_type->children.size() == 1);
 | 
			
		||||
			AstNode *templ = resolved_type->children[0];
 | 
			
		||||
			delete children[1];
 | 
			
		||||
			children.pop_back();
 | 
			
		||||
 | 
			
		||||
			// Ensure typedef itself is fully simplified
 | 
			
		||||
			while(templ->simplify(const_fold, at_zero, in_lvalue, stage, width_hint, sign_hint, in_param)) {};
 | 
			
		||||
 | 
			
		||||
			if (templ->type == AST_MEMORY)
 | 
			
		||||
				log_file_error(filename, linenum, "unpacked array type `%s' cannot be used for a parameter\n", children[1]->str.c_str());
 | 
			
		||||
			is_signed = templ->is_signed;
 | 
			
		||||
			is_string = templ->is_string;
 | 
			
		||||
			is_custom_type = templ->is_custom_type;
 | 
			
		||||
 | 
			
		||||
			range_valid = templ->range_valid;
 | 
			
		||||
			range_swapped = templ->range_swapped;
 | 
			
		||||
			range_left = templ->range_left;
 | 
			
		||||
			range_right = templ->range_right;
 | 
			
		||||
			for (auto template_child : templ->children)
 | 
			
		||||
				children.push_back(template_child->clone());
 | 
			
		||||
			did_something = true;
 | 
			
		||||
		}
 | 
			
		||||
		log_assert(!is_custom_type);
 | 
			
		||||
	}	
 | 
			
		||||
 | 
			
		||||
	// resolve constant prefixes
 | 
			
		||||
	if (type == AST_PREFIX) {
 | 
			
		||||
		if (children[0]->type != AST_CONSTANT) {
 | 
			
		||||
| 
						 | 
				
			
			@ -1194,7 +1289,7 @@ bool AstNode::simplify(bool const_fold, bool at_zero, bool in_lvalue, int stage,
 | 
			
		|||
	if (type == AST_BLOCK && str.empty())
 | 
			
		||||
	{
 | 
			
		||||
		for (size_t i = 0; i < children.size(); i++)
 | 
			
		||||
			if (children[i]->type == AST_WIRE || children[i]->type == AST_MEMORY || children[i]->type == AST_PARAMETER || children[i]->type == AST_LOCALPARAM)
 | 
			
		||||
			if (children[i]->type == AST_WIRE || children[i]->type == AST_MEMORY || children[i]->type == AST_PARAMETER || children[i]->type == AST_LOCALPARAM || children[i]->type == AST_TYPEDEF)
 | 
			
		||||
				log_file_error(children[i]->filename, children[i]->linenum, "Local declaration in unnamed block is an unsupported SystemVerilog feature!\n");
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -1206,7 +1301,7 @@ bool AstNode::simplify(bool const_fold, bool at_zero, bool in_lvalue, int stage,
 | 
			
		|||
 | 
			
		||||
		std::vector<AstNode*> new_children;
 | 
			
		||||
		for (size_t i = 0; i < children.size(); i++)
 | 
			
		||||
			if (children[i]->type == AST_WIRE || children[i]->type == AST_MEMORY || children[i]->type == AST_PARAMETER || children[i]->type == AST_LOCALPARAM) {
 | 
			
		||||
			if (children[i]->type == AST_WIRE || children[i]->type == AST_MEMORY || children[i]->type == AST_PARAMETER || children[i]->type == AST_LOCALPARAM || children[i]->type == AST_TYPEDEF) {
 | 
			
		||||
				children[i]->simplify(false, false, false, stage, -1, false, false);
 | 
			
		||||
				current_ast_mod->children.push_back(children[i]);
 | 
			
		||||
				current_scope[children[i]->str] = children[i];
 | 
			
		||||
| 
						 | 
				
			
			@ -2906,7 +3001,7 @@ void AstNode::expand_genblock(std::string index_var, std::string prefix, std::ma
 | 
			
		|||
		}
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	if ((type == AST_IDENTIFIER || type == AST_FCALL || type == AST_TCALL) && name_map.count(str) > 0)
 | 
			
		||||
	if ((type == AST_IDENTIFIER || type == AST_FCALL || type == AST_TCALL || type == AST_WIRETYPE) && name_map.count(str) > 0)
 | 
			
		||||
		str = name_map[str];
 | 
			
		||||
 | 
			
		||||
	std::map<std::string, std::string> backup_name_map;
 | 
			
		||||
| 
						 | 
				
			
			@ -2914,7 +3009,7 @@ void AstNode::expand_genblock(std::string index_var, std::string prefix, std::ma
 | 
			
		|||
	for (size_t i = 0; i < children.size(); i++) {
 | 
			
		||||
		AstNode *child = children[i];
 | 
			
		||||
		if (child->type == AST_WIRE || child->type == AST_MEMORY || child->type == AST_PARAMETER || child->type == AST_LOCALPARAM ||
 | 
			
		||||
				child->type == AST_FUNCTION || child->type == AST_TASK || child->type == AST_CELL) {
 | 
			
		||||
				child->type == AST_FUNCTION || child->type == AST_TASK || child->type == AST_CELL || child->type == AST_TYPEDEF) {
 | 
			
		||||
			if (backup_name_map.size() == 0)
 | 
			
		||||
				backup_name_map = name_map;
 | 
			
		||||
			std::string new_name = prefix[0] == '\\' ? prefix.substr(1) : prefix;
 | 
			
		||||
| 
						 | 
				
			
			@ -2945,6 +3040,7 @@ void AstNode::expand_genblock(std::string index_var, std::string prefix, std::ma
 | 
			
		|||
			child->expand_genblock(index_var, prefix, name_map);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
	if (backup_name_map.size() > 0)
 | 
			
		||||
		name_map.swap(backup_name_map);
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			@ -2998,6 +3094,9 @@ void AstNode::mem2reg_as_needed_pass1(dict<AstNode*, pool<std::string>> &mem2reg
 | 
			
		|||
	uint32_t children_flags = 0;
 | 
			
		||||
	int lhs_children_counter = 0;
 | 
			
		||||
 | 
			
		||||
	if (type == AST_TYPEDEF)
 | 
			
		||||
		return; // don't touch content of typedefs
 | 
			
		||||
 | 
			
		||||
	if (type == AST_ASSIGN || type == AST_ASSIGN_LE || type == AST_ASSIGN_EQ)
 | 
			
		||||
	{
 | 
			
		||||
		// mark all memories that are used in a complex expression on the left side of an assignment
 | 
			
		||||
| 
						 | 
				
			
			@ -3155,6 +3254,9 @@ bool AstNode::mem2reg_as_needed_pass2(pool<AstNode*> &mem2reg_set, AstNode *mod,
 | 
			
		|||
	if (type == AST_FUNCTION || type == AST_TASK)
 | 
			
		||||
		return false;
 | 
			
		||||
 | 
			
		||||
	if (type == AST_TYPEDEF)
 | 
			
		||||
		return false;
 | 
			
		||||
 | 
			
		||||
	if (type == AST_MEMINIT && id2ast && mem2reg_set.count(id2ast))
 | 
			
		||||
	{
 | 
			
		||||
		log_assert(children[0]->type == AST_CONSTANT);
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -155,7 +155,7 @@ struct specify_rise_fall {
 | 
			
		|||
 | 
			
		||||
%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 opt_sva_label tok_prim_wrapper hierarchical_id
 | 
			
		||||
%type <string> opt_label opt_sva_label tok_prim_wrapper hierarchical_id hierarchical_type_id
 | 
			
		||||
%type <boolean> opt_signed opt_property unique_case_attr
 | 
			
		||||
%type <al> attr case_attr
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -206,6 +206,7 @@ design:
 | 
			
		|||
	task_func_decl design |
 | 
			
		||||
	param_decl design |
 | 
			
		||||
	localparam_decl design |
 | 
			
		||||
	typedef_decl design |
 | 
			
		||||
	package design |
 | 
			
		||||
	interface design |
 | 
			
		||||
	/* empty */;
 | 
			
		||||
| 
						 | 
				
			
			@ -290,6 +291,9 @@ hierarchical_id:
 | 
			
		|||
		$$ = $1;
 | 
			
		||||
	};
 | 
			
		||||
 | 
			
		||||
hierarchical_type_id:
 | 
			
		||||
	'(' hierarchical_id ')' { $$ = $2; };
 | 
			
		||||
 | 
			
		||||
module:
 | 
			
		||||
	attr TOK_MODULE TOK_ID {
 | 
			
		||||
		do_not_require_port_stubs = false;
 | 
			
		||||
| 
						 | 
				
			
			@ -324,13 +328,13 @@ single_module_para:
 | 
			
		|||
		astbuf1 = new AstNode(AST_PARAMETER);
 | 
			
		||||
		astbuf1->children.push_back(AstNode::mkconst_int(0, true));
 | 
			
		||||
		append_attr(astbuf1, $1);
 | 
			
		||||
	} param_signed param_integer param_range single_param_decl |
 | 
			
		||||
	} param_type single_param_decl |
 | 
			
		||||
	attr TOK_LOCALPARAM {
 | 
			
		||||
		if (astbuf1) delete astbuf1;
 | 
			
		||||
		astbuf1 = new AstNode(AST_LOCALPARAM);
 | 
			
		||||
		astbuf1->children.push_back(AstNode::mkconst_int(0, true));
 | 
			
		||||
		append_attr(astbuf1, $1);
 | 
			
		||||
	} param_signed param_integer param_range single_param_decl |
 | 
			
		||||
	} param_type single_param_decl |
 | 
			
		||||
	single_param_decl;
 | 
			
		||||
 | 
			
		||||
module_args_opt:
 | 
			
		||||
| 
						 | 
				
			
			@ -426,6 +430,7 @@ package_body:
 | 
			
		|||
	package_body package_body_stmt |;
 | 
			
		||||
 | 
			
		||||
package_body_stmt:
 | 
			
		||||
	typedef_decl |
 | 
			
		||||
	localparam_decl;
 | 
			
		||||
 | 
			
		||||
interface:
 | 
			
		||||
| 
						 | 
				
			
			@ -452,7 +457,7 @@ interface_body:
 | 
			
		|||
	interface_body interface_body_stmt |;
 | 
			
		||||
 | 
			
		||||
interface_body_stmt:
 | 
			
		||||
	param_decl | localparam_decl | defparam_decl | wire_decl | always_stmt | assign_stmt |
 | 
			
		||||
	param_decl | localparam_decl | typedef_decl | defparam_decl | wire_decl | always_stmt | assign_stmt |
 | 
			
		||||
	modport_stmt;
 | 
			
		||||
 | 
			
		||||
non_opt_delay:
 | 
			
		||||
| 
						 | 
				
			
			@ -475,8 +480,14 @@ wire_type:
 | 
			
		|||
	};
 | 
			
		||||
 | 
			
		||||
wire_type_token_list:
 | 
			
		||||
	wire_type_token | wire_type_token_list wire_type_token |
 | 
			
		||||
	wire_type_token_io ;
 | 
			
		||||
	wire_type_token |
 | 
			
		||||
	wire_type_token_list wire_type_token |
 | 
			
		||||
	wire_type_token_io |
 | 
			
		||||
	hierarchical_type_id {
 | 
			
		||||
		astbuf3->is_custom_type = true;
 | 
			
		||||
		astbuf3->children.push_back(new AstNode(AST_WIRETYPE));
 | 
			
		||||
		astbuf3->children.back()->str = *$1;
 | 
			
		||||
	};
 | 
			
		||||
 | 
			
		||||
wire_type_token_io:
 | 
			
		||||
	TOK_INPUT {
 | 
			
		||||
| 
						 | 
				
			
			@ -591,7 +602,7 @@ module_body:
 | 
			
		|||
	/* empty */;
 | 
			
		||||
 | 
			
		||||
module_body_stmt:
 | 
			
		||||
	task_func_decl | specify_block |param_decl | localparam_decl | defparam_decl | specparam_declaration | wire_decl | assign_stmt | cell_stmt |
 | 
			
		||||
	task_func_decl | specify_block | param_decl | localparam_decl | typedef_decl | defparam_decl | specparam_declaration | wire_decl | assign_stmt | cell_stmt |
 | 
			
		||||
	always_stmt | TOK_GENERATE module_gen_body TOK_ENDGENERATE | defattr | assert_property | checker_decl | ignored_specify_block;
 | 
			
		||||
 | 
			
		||||
checker_decl:
 | 
			
		||||
| 
						 | 
				
			
			@ -1149,12 +1160,20 @@ param_range:
 | 
			
		|||
		}
 | 
			
		||||
	};
 | 
			
		||||
 | 
			
		||||
param_type:
 | 
			
		||||
	param_signed param_integer param_real param_range |
 | 
			
		||||
	hierarchical_type_id {
 | 
			
		||||
		astbuf1->is_custom_type = true;
 | 
			
		||||
		astbuf1->children.push_back(new AstNode(AST_WIRETYPE));
 | 
			
		||||
		astbuf1->children.back()->str = *$1;
 | 
			
		||||
	};
 | 
			
		||||
 | 
			
		||||
param_decl:
 | 
			
		||||
	attr TOK_PARAMETER {
 | 
			
		||||
		astbuf1 = new AstNode(AST_PARAMETER);
 | 
			
		||||
		astbuf1->children.push_back(AstNode::mkconst_int(0, true));
 | 
			
		||||
		append_attr(astbuf1, $1);
 | 
			
		||||
	} param_signed param_integer param_real param_range param_decl_list ';' {
 | 
			
		||||
	} param_type param_decl_list ';' {
 | 
			
		||||
		delete astbuf1;
 | 
			
		||||
	};
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -1163,7 +1182,7 @@ localparam_decl:
 | 
			
		|||
		astbuf1 = new AstNode(AST_LOCALPARAM);
 | 
			
		||||
		astbuf1->children.push_back(AstNode::mkconst_int(0, true));
 | 
			
		||||
		append_attr(astbuf1, $1);
 | 
			
		||||
	} param_signed param_integer param_real param_range param_decl_list ';' {
 | 
			
		||||
	} param_type param_decl_list ';' {
 | 
			
		||||
		delete astbuf1;
 | 
			
		||||
	};
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -1327,7 +1346,7 @@ wire_name:
 | 
			
		|||
		if ($2 != NULL) {
 | 
			
		||||
			if (node->is_input || node->is_output)
 | 
			
		||||
				frontend_verilog_yyerror("input/output/inout ports cannot have unpacked dimensions.");
 | 
			
		||||
			if (!astbuf2) {
 | 
			
		||||
			if (!astbuf2 && !node->is_custom_type) {
 | 
			
		||||
				AstNode *rng = new AstNode(AST_RANGE);
 | 
			
		||||
				rng->children.push_back(AstNode::mkconst_int(0, true));
 | 
			
		||||
				rng->children.push_back(AstNode::mkconst_int(0, true));
 | 
			
		||||
| 
						 | 
				
			
			@ -1377,6 +1396,45 @@ assign_expr:
 | 
			
		|||
		ast_stack.back()->children.push_back(new AstNode(AST_ASSIGN, $1, $3));
 | 
			
		||||
	};
 | 
			
		||||
 | 
			
		||||
typedef_decl:
 | 
			
		||||
	TOK_TYPEDEF wire_type range TOK_ID range_or_multirange ';' {
 | 
			
		||||
		astbuf1 = $2;
 | 
			
		||||
		astbuf2 = $3;
 | 
			
		||||
		if (astbuf1->range_left >= 0 && astbuf1->range_right >= 0) {
 | 
			
		||||
			if (astbuf2) {
 | 
			
		||||
				frontend_verilog_yyerror("integer/genvar types cannot have packed dimensions.");
 | 
			
		||||
			} else {
 | 
			
		||||
				astbuf2 = new AstNode(AST_RANGE);
 | 
			
		||||
				astbuf2->children.push_back(AstNode::mkconst_int(astbuf1->range_left, true));
 | 
			
		||||
				astbuf2->children.push_back(AstNode::mkconst_int(astbuf1->range_right, true));
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
		if (astbuf2 && astbuf2->children.size() != 2)
 | 
			
		||||
			frontend_verilog_yyerror("wire/reg/logic packed dimension must be of the form: [<expr>:<expr>], [<expr>+:<expr>], or [<expr>-:<expr>]");
 | 
			
		||||
		if (astbuf2)
 | 
			
		||||
			astbuf1->children.push_back(astbuf2);
 | 
			
		||||
 | 
			
		||||
		if ($5 != NULL) {
 | 
			
		||||
			if (!astbuf2) {
 | 
			
		||||
				AstNode *rng = new AstNode(AST_RANGE);
 | 
			
		||||
				rng->children.push_back(AstNode::mkconst_int(0, true));
 | 
			
		||||
				rng->children.push_back(AstNode::mkconst_int(0, true));
 | 
			
		||||
				astbuf1->children.push_back(rng);
 | 
			
		||||
			}
 | 
			
		||||
			astbuf1->type = AST_MEMORY;
 | 
			
		||||
			auto *rangeNode = $5;
 | 
			
		||||
			if (rangeNode->type == AST_RANGE && rangeNode->children.size() == 1) {
 | 
			
		||||
				// SV array size [n], rewrite as [n-1:0]
 | 
			
		||||
				rangeNode->children[0] = new AstNode(AST_SUB, rangeNode->children[0], AstNode::mkconst_int(1, true));
 | 
			
		||||
				rangeNode->children.push_back(AstNode::mkconst_int(0, false));
 | 
			
		||||
			}
 | 
			
		||||
			astbuf1->children.push_back(rangeNode);
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		ast_stack.back()->children.push_back(new AstNode(AST_TYPEDEF, astbuf1));
 | 
			
		||||
		ast_stack.back()->children.back()->str = *$4;
 | 
			
		||||
	};
 | 
			
		||||
 | 
			
		||||
cell_stmt:
 | 
			
		||||
	attr TOK_ID {
 | 
			
		||||
		astbuf1 = new AstNode(AST_CELL);
 | 
			
		||||
| 
						 | 
				
			
			@ -1823,7 +1881,7 @@ simple_behavioral_stmt:
 | 
			
		|||
 | 
			
		||||
// this production creates the obligatory if-else shift/reduce conflict
 | 
			
		||||
behavioral_stmt:
 | 
			
		||||
	defattr | assert | wire_decl | param_decl | localparam_decl |
 | 
			
		||||
	defattr | assert | wire_decl | param_decl | localparam_decl | typedef_decl |
 | 
			
		||||
	non_opt_delay behavioral_stmt |
 | 
			
		||||
	simple_behavioral_stmt ';' | ';' |
 | 
			
		||||
	hierarchical_id attr {
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue