diff options
Diffstat (limited to 'frontends/ast/genrtlil.cc')
| -rw-r--r-- | frontends/ast/genrtlil.cc | 158 | 
1 files changed, 97 insertions, 61 deletions
| diff --git a/frontends/ast/genrtlil.cc b/frontends/ast/genrtlil.cc index c9345ff08..9531dd356 100644 --- a/frontends/ast/genrtlil.cc +++ b/frontends/ast/genrtlil.cc @@ -55,8 +55,7 @@ static RTLIL::SigSpec uniop2rtlil(AstNode *that, std::string type, int result_wi  	if (gen_attributes)  		for (auto &attr : that->attributes) {  			if (attr.second->type != AST_CONSTANT) -				log_file_error(that->filename, that->linenum, "Attribute `%s' with non-constant value!\n", -					       attr.first.c_str()); +				log_file_error(that->filename, that->linenum, "Attribute `%s' with non-constant value!\n", attr.first.c_str());  			cell->attributes[attr.first] = attr.second->asAttrConst();  		} @@ -89,8 +88,7 @@ static void widthExtend(AstNode *that, RTLIL::SigSpec &sig, int width, bool is_s  	if (that != NULL)  		for (auto &attr : that->attributes) {  			if (attr.second->type != AST_CONSTANT) -				log_file_error(that->filename, that->linenum, "Attribute `%s' with non-constant value!\n", -					       attr.first.c_str()); +				log_file_error(that->filename, that->linenum, "Attribute `%s' with non-constant value!\n", attr.first.c_str());  			cell->attributes[attr.first] = attr.second->asAttrConst();  		} @@ -117,8 +115,7 @@ static RTLIL::SigSpec binop2rtlil(AstNode *that, std::string type, int result_wi  	for (auto &attr : that->attributes) {  		if (attr.second->type != AST_CONSTANT) -			log_file_error(that->filename, that->linenum, "Attribute `%s' with non-constant value!\n", -				       attr.first.c_str()); +			log_file_error(that->filename, that->linenum, "Attribute `%s' with non-constant value!\n", attr.first.c_str());  		cell->attributes[attr.first] = attr.second->asAttrConst();  	} @@ -152,8 +149,7 @@ static RTLIL::SigSpec mux2rtlil(AstNode *that, const RTLIL::SigSpec &cond, const  	for (auto &attr : that->attributes) {  		if (attr.second->type != AST_CONSTANT) -			log_file_error(that->filename, that->linenum, "Attribute `%s' with non-constant value!\n", -				       attr.first.c_str()); +			log_file_error(that->filename, that->linenum, "Attribute `%s' with non-constant value!\n", attr.first.c_str());  		cell->attributes[attr.first] = attr.second->asAttrConst();  	} @@ -480,8 +476,7 @@ struct AST_INTERNAL::ProcessGenerator  				for (auto &attr : ast->attributes) {  					if (attr.second->type != AST_CONSTANT) -						log_file_error(ast->filename, ast->linenum, "Attribute `%s' with non-constant value!\n", -							       attr.first.c_str()); +						log_file_error(ast->filename, ast->linenum, "Attribute `%s' with non-constant value!\n", attr.first.c_str());  					sw->attributes[attr.first] = attr.second->asAttrConst();  				} @@ -648,8 +643,7 @@ void AstNode::detectSignWidthWorker(int &width_hint, bool &sign_hint, bool *foun  				while (left_at_zero_ast->simplify(true, true, false, 1, -1, false, false)) { }  				while (right_at_zero_ast->simplify(true, true, false, 1, -1, false, false)) { }  				if (left_at_zero_ast->type != AST_CONSTANT || right_at_zero_ast->type != AST_CONSTANT) -					log_file_error(filename, linenum, "Unsupported expression on dynamic range select on signal `%s'!\n", -						       str.c_str()); +					log_file_error(filename, linenum, "Unsupported expression on dynamic range select on signal `%s'!\n", str.c_str());  				this_width = left_at_zero_ast->integer - right_at_zero_ast->integer + 1;  				delete left_at_zero_ast;  				delete right_at_zero_ast; @@ -778,7 +772,7 @@ void AstNode::detectSignWidthWorker(int &width_hint, bool &sign_hint, bool *foun  				while (children[0]->simplify(true, false, false, 1, -1, false, true) == true) { }  				if (children[0]->type != AST_CONSTANT)  					log_file_error(filename, linenum, "System function %s called with non-const argument!\n", -						       RTLIL::unescape_id(str).c_str()); +							RTLIL::unescape_id(str).c_str());  				width_hint = max(width_hint, int(children[0]->asInt(true)));  			}  			break; @@ -799,8 +793,7 @@ void AstNode::detectSignWidthWorker(int &width_hint, bool &sign_hint, bool *foun  	default:  		for (auto f : log_files)  			current_ast->dumpAst(f, "verilog-ast> "); -		log_file_error(filename, linenum, "Don't know how to detect sign and width for %s node!\n", -			       type2str(type).c_str()); +		log_file_error(filename, linenum, "Don't know how to detect sign and width for %s node!\n", type2str(type).c_str());  	}  	if (*found_real) @@ -853,6 +846,35 @@ RTLIL::SigSpec AstNode::genRTLIL(int width_hint, bool sign_hint)  	case AST_GENIF:  	case AST_GENCASE:  	case AST_PACKAGE: +	case AST_MODPORT: +	case AST_MODPORTMEMBER: +		break; +	case AST_INTERFACEPORT: { +		// If a port in a module with unknown type is found, mark it with the attribute 'is_interface' +		// This is used by the hierarchy pass to know when it can replace interface connection with the individual +		// signals. +		RTLIL::Wire *wire = current_module->addWire(str, 1); +		wire->attributes["\\src"] = stringf("%s:%d", filename.c_str(), linenum); +		wire->start_offset = 0; +		wire->port_id = port_id; +		wire->port_input = true; +		wire->port_output = true; +		wire->set_bool_attribute("\\is_interface"); +		if (children.size() > 0) { +			for(size_t i=0; i<children.size();i++) { +				if(children[i]->type == AST_INTERFACEPORTTYPE) { +					std::pair<std::string,std::string> res = AST::split_modport_from_type(children[i]->str); +					wire->attributes["\\interface_type"] = res.first; +					if (res.second != "") +						wire->attributes["\\interface_modport"] = res.second; +					break; +				} +			} +		} +		wire->upto = 0; +		} +		break; +	case AST_INTERFACEPORTTYPE:  		break;  	// remember the parameter, needed for example in techmap @@ -863,11 +885,9 @@ RTLIL::SigSpec AstNode::genRTLIL(int width_hint, bool sign_hint)  	// create an RTLIL::Wire for an AST_WIRE node  	case AST_WIRE: {  			if (current_module->wires_.count(str) != 0) -				log_file_error(filename, linenum, "Re-definition of signal `%s'!\n", -					       str.c_str()); +				log_file_error(filename, linenum, "Re-definition of signal `%s'!\n", str.c_str());  			if (!range_valid) -				log_file_error(filename, linenum, "Signal `%s' with non-constant width!\n", -					       str.c_str()); +				log_file_error(filename, linenum, "Signal `%s' with non-constant width!\n", str.c_str());  			log_assert(range_left >= range_right || (range_left == -1 && range_right == 0)); @@ -881,8 +901,7 @@ RTLIL::SigSpec AstNode::genRTLIL(int width_hint, bool sign_hint)  			for (auto &attr : attributes) {  				if (attr.second->type != AST_CONSTANT) -					log_file_error(filename, linenum, "Attribute `%s' with non-constant value!\n", -						       attr.first.c_str()); +					log_file_error(filename, linenum, "Attribute `%s' with non-constant value!\n", attr.first.c_str());  				wire->attributes[attr.first] = attr.second->asAttrConst();  			}  		} @@ -891,16 +910,14 @@ RTLIL::SigSpec AstNode::genRTLIL(int width_hint, bool sign_hint)  	// create an RTLIL::Memory for an AST_MEMORY node  	case AST_MEMORY: {  			if (current_module->memories.count(str) != 0) -				log_file_error(filename, linenum, "Re-definition of memory `%s'!\n", -					       str.c_str()); +				log_file_error(filename, linenum, "Re-definition of memory `%s'!\n", str.c_str());  			log_assert(children.size() >= 2);  			log_assert(children[0]->type == AST_RANGE);  			log_assert(children[1]->type == AST_RANGE);  			if (!children[0]->range_valid || !children[1]->range_valid) -				log_file_error(filename, linenum, "Memory `%s' with non-constant width or size!\n", -					       str.c_str()); +				log_file_error(filename, linenum, "Memory `%s' with non-constant width or size!\n", str.c_str());  			RTLIL::Memory *memory = new RTLIL::Memory;  			memory->attributes["\\src"] = stringf("%s:%d", filename.c_str(), linenum); @@ -917,8 +934,7 @@ RTLIL::SigSpec AstNode::genRTLIL(int width_hint, bool sign_hint)  			for (auto &attr : attributes) {  				if (attr.second->type != AST_CONSTANT) -					log_file_error(filename, linenum, "Attribute `%s' with non-constant value!\n", -						       attr.first.c_str()); +					log_file_error(filename, linenum, "Attribute `%s' with non-constant value!\n", attr.first.c_str());  				memory->attributes[attr.first] = attr.second->asAttrConst();  			}  		} @@ -937,8 +953,7 @@ RTLIL::SigSpec AstNode::genRTLIL(int width_hint, bool sign_hint)  	case AST_REALVALUE:  		{  			RTLIL::SigSpec sig = realAsConst(width_hint); -			log_file_warning(filename, linenum, "converting real value %e to binary %s.\n", -					 realvalue, log_signal(sig)); +			log_file_warning(filename, linenum, "converting real value %e to binary %s.\n", realvalue, log_signal(sig));  			return sig;  		} @@ -949,6 +964,7 @@ RTLIL::SigSpec AstNode::genRTLIL(int width_hint, bool sign_hint)  		{  			RTLIL::Wire *wire = NULL;  			RTLIL::SigChunk chunk; +			bool is_interface = false;  			int add_undef_bits_msb = 0;  			int add_undef_bits_lsb = 0; @@ -964,19 +980,42 @@ RTLIL::SigSpec AstNode::genRTLIL(int width_hint, bool sign_hint)  			}  			else if (id2ast->type == AST_PARAMETER || id2ast->type == AST_LOCALPARAM) {  				if (id2ast->children[0]->type != AST_CONSTANT) -					log_file_error(filename, linenum, "Parameter %s does not evaluate to constant value!\n", -						       str.c_str()); +					log_file_error(filename, linenum, "Parameter %s does not evaluate to constant value!\n", str.c_str());  				chunk = RTLIL::Const(id2ast->children[0]->bits);  				goto use_const_chunk;  			} -			else if (!id2ast || (id2ast->type != AST_WIRE && id2ast->type != AST_AUTOWIRE && -					id2ast->type != AST_MEMORY) || current_module->wires_.count(str) == 0) -				log_file_error(filename, linenum, "Identifier `%s' doesn't map to any signal!\n", -						str.c_str()); +			else if (id2ast && (id2ast->type == AST_WIRE || id2ast->type == AST_AUTOWIRE || id2ast->type == AST_MEMORY) && current_module->wires_.count(str) != 0) { +				RTLIL::Wire *current_wire = current_module->wire(str); +				if (current_wire->get_bool_attribute("\\is_interface")) +					is_interface = true; +				// Ignore +			} +			// If an identifier is found that is not already known, assume that it is an interface: +			else if (1) { // FIXME: Check if sv_mode first? +				is_interface = true; +			} +			else { +				log_file_error(filename, linenum, "Identifier `%s' doesn't map to any signal!\n", str.c_str()); +			}  			if (id2ast->type == AST_MEMORY) -				log_file_error(filename, linenum, "Identifier `%s' does map to an unexpanded memory!\n", -					       str.c_str()); +				log_file_error(filename, linenum, "Identifier `%s' does map to an unexpanded memory!\n", str.c_str()); + +			// If identifier is an interface, create a RTLIL::SigSpec with a dummy wire with a attribute called 'is_interface' +			// This makes it possible for the hierarchy pass to see what are interface connections and then replace them +			// with the individual signals: +			if (is_interface) { +				RTLIL::Wire *dummy_wire; +				std::string dummy_wire_name = "$dummywireforinterface" + str; +				if (current_module->wires_.count(dummy_wire_name)) +					dummy_wire = current_module->wires_[dummy_wire_name]; +				else { +					dummy_wire = current_module->addWire(dummy_wire_name); +					dummy_wire->set_bool_attribute("\\is_interface"); +				} +				RTLIL::SigSpec tmp = RTLIL::SigSpec(dummy_wire); +				return tmp; +			}  			wire = current_module->wires_[str];  			chunk.wire = wire; @@ -995,8 +1034,7 @@ RTLIL::SigSpec AstNode::genRTLIL(int width_hint, bool sign_hint)  					while (left_at_zero_ast->simplify(true, true, false, 1, -1, false, false)) { }  					while (right_at_zero_ast->simplify(true, true, false, 1, -1, false, false)) { }  					if (left_at_zero_ast->type != AST_CONSTANT || right_at_zero_ast->type != AST_CONSTANT) -						log_file_error(filename, linenum, "Unsupported expression on dynamic range select on signal `%s'!\n", -							       str.c_str()); +						log_file_error(filename, linenum, "Unsupported expression on dynamic range select on signal `%s'!\n", str.c_str());  					int width = left_at_zero_ast->integer - right_at_zero_ast->integer + 1;  					AstNode *fake_ast = new AstNode(AST_NONE, clone(), children[0]->children.size() >= 2 ?  							children[0]->children[1]->clone() : children[0]->children[0]->clone()); @@ -1025,10 +1063,10 @@ RTLIL::SigSpec AstNode::genRTLIL(int width_hint, bool sign_hint)  					if (chunk.offset >= source_width || chunk.offset + chunk.width < 0) {  						if (chunk.width == 1)  							log_file_warning(filename, linenum, "Range select out of bounds on signal `%s': Setting result bit to undef.\n", -									 str.c_str()); +									str.c_str());  						else -							log_file_warning(filename, linenum, "Range select out of bounds on signal `%s': Setting all %d result bits to undef.\n", -									str.c_str(), chunk.width); +							log_file_warning(filename, linenum, "Range select [%d:%d] out of bounds on signal `%s': Setting all %d result bits to undef.\n", +									children[0]->range_left, children[0]->range_right, str.c_str(), chunk.width);  						chunk = RTLIL::SigChunk(RTLIL::State::Sx, chunk.width);  					} else {  						if (chunk.width + chunk.offset > source_width) { @@ -1041,11 +1079,11 @@ RTLIL::SigSpec AstNode::genRTLIL(int width_hint, bool sign_hint)  							chunk.offset += add_undef_bits_lsb;  						}  						if (add_undef_bits_lsb) -							log_file_warning(filename, linenum, "Range select out of bounds on signal `%s': Setting %d LSB bits to undef.\n", -									 str.c_str(), add_undef_bits_lsb); +							log_file_warning(filename, linenum, "Range [%d:%d] select out of bounds on signal `%s': Setting %d LSB bits to undef.\n", +									children[0]->range_left, children[0]->range_right, str.c_str(), add_undef_bits_lsb);  						if (add_undef_bits_msb) -							log_file_warning(filename, linenum, "Range select out of bounds on signal `%s': Setting %d MSB bits to undef.\n", -									 str.c_str(), add_undef_bits_msb); +							log_file_warning(filename, linenum, "Range [%d:%d] select out of bounds on signal `%s': Setting %d MSB bits to undef.\n", +									children[0]->range_left, children[0]->range_right, str.c_str(), add_undef_bits_msb);  					}  				}  			} @@ -1380,8 +1418,7 @@ RTLIL::SigSpec AstNode::genRTLIL(int width_hint, bool sign_hint)  			for (auto &attr : attributes) {  				if (attr.second->type != AST_CONSTANT) -					log_file_error(filename, linenum, "Attribute `%s' with non-constant value!\n", -						       attr.first.c_str()); +					log_file_error(filename, linenum, "Attribute `%s' with non-constant value!\n", attr.first.c_str());  				cell->attributes[attr.first] = attr.second->asAttrConst();  			} @@ -1403,9 +1440,9 @@ RTLIL::SigSpec AstNode::genRTLIL(int width_hint, bool sign_hint)  						new_right.append(right[i]);  					}  				log_file_warning(filename, linenum, "Ignoring assignment to constant bits:\n" -						 "    old assignment: %s = %s\n    new assignment: %s = %s.\n", -						 log_signal(left), log_signal(right), -						 log_signal(new_left), log_signal(new_right)); +						"    old assignment: %s = %s\n    new assignment: %s = %s.\n", +						log_signal(left), log_signal(right), +						log_signal(new_left), log_signal(new_right));  				left = new_left;  				right = new_right;  			} @@ -1423,6 +1460,8 @@ RTLIL::SigSpec AstNode::genRTLIL(int width_hint, bool sign_hint)  			RTLIL::Cell *cell = current_module->addCell(str, "");  			cell->attributes["\\src"] = stringf("%s:%d", filename.c_str(), linenum); +			// Set attribute 'module_not_derived' which will be cleared again after the hierarchy pass +			cell->set_bool_attribute("\\module_not_derived");  			for (auto it = children.begin(); it != children.end(); it++) {  				AstNode *child = *it; @@ -1436,14 +1475,14 @@ RTLIL::SigSpec AstNode::genRTLIL(int width_hint, bool sign_hint)  					IdString paraname = child->str.empty() ? stringf("$%d", ++para_counter) : child->str;  					if (child->children[0]->type == AST_REALVALUE) {  						log_file_warning(filename, linenum, "Replacing floating point parameter %s.%s = %f with string.\n", -								 log_id(cell), log_id(paraname), child->children[0]->realvalue); +								log_id(cell), log_id(paraname), child->children[0]->realvalue);  						auto strnode = AstNode::mkconst_str(stringf("%f", child->children[0]->realvalue));  						strnode->cloneInto(child->children[0]);  						delete strnode;  					}  					if (child->children[0]->type != AST_CONSTANT)  						log_file_error(filename, linenum, "Parameter %s.%s with non-constant value!\n", -							       log_id(cell), log_id(paraname)); +								log_id(cell), log_id(paraname));  					cell->parameters[paraname] = child->children[0]->asParaConst();  					continue;  				} @@ -1464,8 +1503,7 @@ RTLIL::SigSpec AstNode::genRTLIL(int width_hint, bool sign_hint)  			}  			for (auto &attr : attributes) {  				if (attr.second->type != AST_CONSTANT) -					log_file_error(filename, linenum, "Attribute `%s' with non-constant value!\n", -						       attr.first.c_str()); +					log_file_error(filename, linenum, "Attribute `%s' with non-constant value!\n", attr.first.c_str());  				cell->attributes[attr.first] = attr.second->asAttrConst();  			}  		} @@ -1493,18 +1531,17 @@ RTLIL::SigSpec AstNode::genRTLIL(int width_hint, bool sign_hint)  				if (GetSize(children) > 1)  					log_file_error(filename, linenum, "System function %s got %d arguments, expected 1 or 0.\n", -						       RTLIL::unescape_id(str).c_str(), GetSize(children)); +							RTLIL::unescape_id(str).c_str(), GetSize(children));  				if (GetSize(children) == 1) {  					if (children[0]->type != AST_CONSTANT)  						log_file_error(filename, linenum, "System function %s called with non-const argument!\n", -							       RTLIL::unescape_id(str).c_str()); +								RTLIL::unescape_id(str).c_str());  					width = children[0]->asInt(true);  				}  				if (width <= 0) -					log_file_error(filename, linenum, "Failed to detect width of %s!\n", -						       RTLIL::unescape_id(str).c_str()); +					log_file_error(filename, linenum, "Failed to detect width of %s!\n", RTLIL::unescape_id(str).c_str());  				Cell *cell = current_module->addCell(myid, str.substr(1));  				cell->attributes["\\src"] = stringf("%s:%d", filename.c_str(), linenum); @@ -1531,8 +1568,7 @@ RTLIL::SigSpec AstNode::genRTLIL(int width_hint, bool sign_hint)  		for (auto f : log_files)  			current_ast->dumpAst(f, "verilog-ast> ");  		type_name = type2str(type); -		log_file_error(filename, linenum, "Don't know how to generate RTLIL code for %s node!\n", -			       type_name.c_str()); +		log_file_error(filename, linenum, "Don't know how to generate RTLIL code for %s node!\n", type_name.c_str());  	}  	return RTLIL::SigSpec(); | 
