diff options
| author | Jim Lawson <ucbjrl@berkeley.edu> | 2018-08-22 08:42:34 -0700 | 
|---|---|---|
| committer | GitHub <noreply@github.com> | 2018-08-22 08:42:34 -0700 | 
| commit | 2c0601eb6f2c5ed0d376ed880efda48a2aeeb9ef (patch) | |
| tree | 02b9412c9249cce3714972c8385d66f8093bfc17 /frontends/ast | |
| parent | 8b92ddb9d2635c30636b17ff3d24bc09a44b8551 (diff) | |
| parent | 408077769ff022f78f10ec1ffb60926361f8dc9f (diff) | |
| download | yosys-2c0601eb6f2c5ed0d376ed880efda48a2aeeb9ef.tar.gz yosys-2c0601eb6f2c5ed0d376ed880efda48a2aeeb9ef.tar.bz2 yosys-2c0601eb6f2c5ed0d376ed880efda48a2aeeb9ef.zip  | |
Merge pull request #1 from YosysHQ/master
merge with YosysHQ master
Diffstat (limited to 'frontends/ast')
| -rw-r--r-- | frontends/ast/ast.cc | 21 | ||||
| -rw-r--r-- | frontends/ast/ast.h | 10 | ||||
| -rw-r--r-- | frontends/ast/genrtlil.cc | 177 | ||||
| -rw-r--r-- | frontends/ast/simplify.cc | 286 | 
4 files changed, 268 insertions, 226 deletions
diff --git a/frontends/ast/ast.cc b/frontends/ast/ast.cc index 999202b47..7c72a50d9 100644 --- a/frontends/ast/ast.cc +++ b/frontends/ast/ast.cc @@ -171,8 +171,8 @@ bool AstNode::get_bool_attribute(RTLIL::IdString id)  	AstNode *attr = attributes.at(id);  	if (attr->type != AST_CONSTANT) -		log_error("Attribute `%s' with non-constant value at %s:%d!\n", -				id.c_str(), attr->filename.c_str(), attr->linenum); +		log_file_error(attr->filename, attr->linenum, "Attribute `%s' with non-constant value!\n", +			       id.c_str());  	return attr->integer != 0;  } @@ -191,8 +191,10 @@ AstNode::AstNode(AstNodeType type, AstNode *child1, AstNode *child2, AstNode *ch  	is_input = false;  	is_output = false;  	is_reg = false; +	is_logic = false;  	is_signed = false;  	is_string = false; +	was_checked = false;  	range_valid = false;  	range_swapped = false;  	port_id = 0; @@ -285,7 +287,9 @@ void AstNode::dumpAst(FILE *f, std::string indent) const  		fprintf(f, " input");  	if (is_output)  		fprintf(f, " output"); -	if (is_reg) +	if (is_logic) +		fprintf(f, " logic"); +	if (is_reg) // this is an AST dump, not Verilog - if we see "logic reg" that's fine.  		fprintf(f, " reg");  	if (is_signed)  		fprintf(f, " signed"); @@ -652,6 +656,8 @@ bool AstNode::operator==(const AstNode &other) const  		return false;  	if (is_output != other.is_output)  		return false; +	if (is_logic != other.is_logic) +		return false;  	if (is_reg != other.is_reg)  		return false;  	if (is_signed != other.is_signed) @@ -955,8 +961,8 @@ static AstModule* process_module(AstNode *ast, bool defer)  		for (auto &attr : ast->attributes) {  			if (attr.second->type != AST_CONSTANT) -				log_error("Attribute `%s' with non-constant value at %s:%d!\n", -						attr.first.c_str(), ast->filename.c_str(), ast->linenum); +				log_file_error(ast->filename, ast->linenum, "Attribute `%s' with non-constant value!\n", +					       attr.first.c_str());  			current_module->attributes[attr.first] = attr.second->asAttrConst();  		}  		for (size_t i = 0; i < ast->children.size(); i++) { @@ -1044,8 +1050,8 @@ void AST::process(RTLIL::Design *design, AstNode *ast, bool dump_ast1, bool dump  			if (design->has((*it)->str)) {  				RTLIL::Module *existing_mod = design->module((*it)->str);  				if (!nooverwrite && !overwrite && !existing_mod->get_bool_attribute("\\blackbox")) { -					log_error("Re-definition of module `%s' at %s:%d!\n", -							(*it)->str.c_str(), (*it)->filename.c_str(), (*it)->linenum); +					log_file_error((*it)->filename, (*it)->linenum, "Re-definition of module `%s'!\n", +						       (*it)->str.c_str());  				} else if (nooverwrite) {  					log("Ignoring re-definition of module `%s' at %s:%d.\n",  							(*it)->str.c_str(), (*it)->filename.c_str(), (*it)->linenum); @@ -1197,4 +1203,3 @@ void AST::use_internal_line_num()  }  YOSYS_NAMESPACE_END - diff --git a/frontends/ast/ast.h b/frontends/ast/ast.h index 756629aca..d94199643 100644 --- a/frontends/ast/ast.h +++ b/frontends/ast/ast.h @@ -1,4 +1,4 @@ -/* +/* -*- c++ -*-   *  yosys -- Yosys Open SYnthesis Suite   *   *  Copyright (C) 2012  Clifford Wolf <clifford@clifford.at> @@ -168,7 +168,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_signed, is_string, range_valid, range_swapped; +		bool is_input, is_output, is_reg, is_logic, is_signed, is_string, range_valid, range_swapped, was_checked;  		int port_id, range_left, range_right;  		uint32_t integer;  		double realvalue; @@ -282,9 +282,9 @@ namespace AST  	struct AstModule : RTLIL::Module {  		AstNode *ast;  		bool nolatches, nomeminit, nomem2reg, mem2reg, lib, noopt, icells, autowire; -		virtual ~AstModule(); -		virtual RTLIL::IdString derive(RTLIL::Design *design, dict<RTLIL::IdString, RTLIL::Const> parameters, bool mayfail); -		virtual RTLIL::Module *clone() const; +		~AstModule() YS_OVERRIDE; +		RTLIL::IdString derive(RTLIL::Design *design, dict<RTLIL::IdString, RTLIL::Const> parameters, bool mayfail) YS_OVERRIDE; +		RTLIL::Module *clone() const YS_OVERRIDE;  	};  	// this must be set by the language frontend before parsing the sources diff --git a/frontends/ast/genrtlil.cc b/frontends/ast/genrtlil.cc index d9f0039af..0f7e910f3 100644 --- a/frontends/ast/genrtlil.cc +++ b/frontends/ast/genrtlil.cc @@ -55,8 +55,8 @@ 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_error("Attribute `%s' with non-constant value at %s:%d!\n", -						attr.first.c_str(), that->filename.c_str(), that->linenum); +				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 +89,8 @@ 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_error("Attribute `%s' with non-constant value at %s:%d!\n", -						attr.first.c_str(), that->filename.c_str(), that->linenum); +				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 +117,8 @@ static RTLIL::SigSpec binop2rtlil(AstNode *that, std::string type, int result_wi  	for (auto &attr : that->attributes) {  		if (attr.second->type != AST_CONSTANT) -			log_error("Attribute `%s' with non-constant value at %s:%d!\n", -					attr.first.c_str(), that->filename.c_str(), that->linenum); +			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 +152,8 @@ static RTLIL::SigSpec mux2rtlil(AstNode *that, const RTLIL::SigSpec &cond, const  	for (auto &attr : that->attributes) {  		if (attr.second->type != AST_CONSTANT) -			log_error("Attribute `%s' with non-constant value at %s:%d!\n", -					attr.first.c_str(), that->filename.c_str(), that->linenum); +			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();  	} @@ -207,8 +207,8 @@ struct AST_INTERNAL::ProcessGenerator  		proc->name = stringf("$proc$%s:%d$%d", always->filename.c_str(), always->linenum, autoidx++);  		for (auto &attr : always->attributes) {  			if (attr.second->type != AST_CONSTANT) -				log_error("Attribute `%s' with non-constant value at %s:%d!\n", -						attr.first.c_str(), always->filename.c_str(), always->linenum); +				log_file_error(always->filename, always->linenum, "Attribute `%s' with non-constant value!\n", +						attr.first.c_str());  			proc->attributes[attr.first] = attr.second->asAttrConst();  		}  		current_module->processes[proc->name] = proc; @@ -238,7 +238,7 @@ struct AST_INTERNAL::ProcessGenerator  		if (found_anyedge_syncs) {  			if (found_global_syncs) -				log_error("Found non-synthesizable event list at %s:%d!\n", always->filename.c_str(), always->linenum); +				log_file_error(always->filename, always->linenum, "Found non-synthesizable event list!\n");  			log("Note: Assuming pure combinatorial block at %s:%d in\n", always->filename.c_str(), always->linenum);  			log("compliance with IEC 62142(E):2005 / IEEE Std. 1364.1(E):2002. Recommending\n");  			log("use of @* instead of @(...) for better match of synthesis and simulation.\n"); @@ -253,12 +253,12 @@ struct AST_INTERNAL::ProcessGenerator  					continue;  				found_clocked_sync = true;  				if (found_global_syncs || found_anyedge_syncs) -					log_error("Found non-synthesizable event list at %s:%d!\n", always->filename.c_str(), always->linenum); +					log_file_error(always->filename, always->linenum, "Found non-synthesizable event list!\n");  				RTLIL::SyncRule *syncrule = new RTLIL::SyncRule;  				syncrule->type = child->type == AST_POSEDGE ? RTLIL::STp : RTLIL::STn;  				syncrule->signal = child->children[0]->genRTLIL();  				if (GetSize(syncrule->signal) != 1) -					log_error("Found posedge/negedge event on a signal that is not 1 bit wide at %s:%d!\n", always->filename.c_str(), always->linenum); +					log_file_error(always->filename, always->linenum, "Found posedge/negedge event on a signal that is not 1 bit wide!\n");  				addChunkActions(syncrule->actions, subst_lvalue_from, subst_lvalue_to, true);  				proc->syncs.push_back(syncrule);  			} @@ -480,8 +480,8 @@ struct AST_INTERNAL::ProcessGenerator  				for (auto &attr : ast->attributes) {  					if (attr.second->type != AST_CONSTANT) -						log_error("Attribute `%s' with non-constant value at %s:%d!\n", -								attr.first.c_str(), ast->filename.c_str(), ast->linenum); +						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();  				} @@ -549,12 +549,12 @@ struct AST_INTERNAL::ProcessGenerator  			break;  		case AST_WIRE: -			log_error("Found wire declaration in block without label at at %s:%d!\n", ast->filename.c_str(), ast->linenum); +			log_file_error(ast->filename, ast->linenum, "Found wire declaration in block without label!\n");  			break;  		case AST_PARAMETER:  		case AST_LOCALPARAM: -			log_error("Found parameter declaration in block without label at at %s:%d!\n", ast->filename.c_str(), ast->linenum); +			log_file_error(ast->filename, ast->linenum, "Found parameter declaration in block without label!\n");  			break;  		case AST_NONE: @@ -602,7 +602,7 @@ void AstNode::detectSignWidthWorker(int &width_hint, bool &sign_hint, bool *foun  		if (id_ast == NULL && current_scope.count(str))  			id_ast = current_scope.at(str);  		if (!id_ast) -			log_error("Failed to resolve identifier %s for width detection at %s:%d!\n", str.c_str(), filename.c_str(), linenum); +			log_file_error(filename, linenum, "Failed to resolve identifier %s for width detection!\n", str.c_str());  		if (id_ast->type == AST_PARAMETER || id_ast->type == AST_LOCALPARAM) {  			if (id_ast->children.size() > 1 && id_ast->children[1]->range_valid) {  				this_width = id_ast->children[1]->range_left - id_ast->children[1]->range_right + 1; @@ -612,7 +612,7 @@ void AstNode::detectSignWidthWorker(int &width_hint, bool &sign_hint, bool *foun  			if (id_ast->children[0]->type == AST_CONSTANT)  				this_width = id_ast->children[0]->bits.size();  			else -				log_error("Failed to detect width for parameter %s at %s:%d!\n", str.c_str(), filename.c_str(), linenum); +				log_file_error(filename, linenum, "Failed to detect width for parameter %s!\n", str.c_str());  			if (children.size() != 0)  				range = children[0];  		} else if (id_ast->type == AST_WIRE || id_ast->type == AST_AUTOWIRE) { @@ -624,7 +624,7 @@ void AstNode::detectSignWidthWorker(int &width_hint, bool &sign_hint, bool *foun  					// log("---\n");  					// id_ast->dumpAst(NULL, "decl> ");  					// dumpAst(NULL, "ref> "); -					log_error("Failed to detect width of signal access `%s' at %s:%d!\n", str.c_str(), filename.c_str(), linenum); +					log_file_error(filename, linenum, "Failed to detect width of signal access `%s'!\n", str.c_str());  				}  			} else {  				this_width = id_ast->range_left - id_ast->range_right + 1; @@ -635,10 +635,10 @@ void AstNode::detectSignWidthWorker(int &width_hint, bool &sign_hint, bool *foun  			this_width = 32;  		} else if (id_ast->type == AST_MEMORY) {  			if (!id_ast->children[0]->range_valid) -				log_error("Failed to detect width of memory access `%s' at %s:%d!\n", str.c_str(), filename.c_str(), linenum); +				log_file_error(filename, linenum, "Failed to detect width of memory access `%s'!\n", str.c_str());  			this_width = id_ast->children[0]->range_left - id_ast->children[0]->range_right + 1;  		} else -			log_error("Failed to detect width for identifier %s at %s:%d!\n", str.c_str(), filename.c_str(), linenum); +			log_file_error(filename, linenum, "Failed to detect width for identifier %s!\n", str.c_str());  		if (range) {  			if (range->children.size() == 1)  				this_width = 1; @@ -648,8 +648,8 @@ 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_error("Unsupported expression on dynamic range select on signal `%s' at %s:%d!\n", -							str.c_str(), filename.c_str(), linenum); +					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; @@ -665,7 +665,7 @@ void AstNode::detectSignWidthWorker(int &width_hint, bool &sign_hint, bool *foun  	case AST_TO_BITS:  		while (children[0]->simplify(true, false, false, 1, -1, false, false) == true) { }  		if (children[0]->type != AST_CONSTANT) -			log_error("Left operand of tobits expression is not constant at %s:%d!\n", filename.c_str(), linenum); +			log_file_error(filename, linenum, "Left operand of tobits expression is not constant!\n");  		children[1]->detectSignWidthWorker(sub_width_hint, sign_hint);  		width_hint = max(width_hint, children[0]->bitsAsConst().as_int());  		break; @@ -693,7 +693,7 @@ void AstNode::detectSignWidthWorker(int &width_hint, bool &sign_hint, bool *foun  	case AST_REPLICATE:  		while (children[0]->simplify(true, false, false, 1, -1, false, true) == true) { }  		if (children[0]->type != AST_CONSTANT) -			log_error("Left operand of replicate expression is not constant at %s:%d!\n", filename.c_str(), linenum); +			log_file_error(filename, linenum, "Left operand of replicate expression is not constant!\n");  		children[1]->detectSignWidthWorker(sub_width_hint, sub_sign_hint);  		width_hint = max(width_hint, children[0]->bitsAsConst().as_int() * sub_width_hint);  		sign_hint = false; @@ -767,7 +767,7 @@ void AstNode::detectSignWidthWorker(int &width_hint, bool &sign_hint, bool *foun  		if (!id2ast->is_signed)  			sign_hint = false;  		if (!id2ast->children[0]->range_valid) -			log_error("Failed to detect width of memory access `%s' at %s:%d!\n", str.c_str(), filename.c_str(), linenum); +			log_file_error(filename, linenum, "Failed to detect width of memory access `%s'!\n", str.c_str());  		this_width = id2ast->children[0]->range_left - id2ast->children[0]->range_right + 1;  		width_hint = max(width_hint, this_width);  		break; @@ -777,8 +777,8 @@ void AstNode::detectSignWidthWorker(int &width_hint, bool &sign_hint, bool *foun  			if (GetSize(children) == 1) {  				while (children[0]->simplify(true, false, false, 1, -1, false, true) == true) { }  				if (children[0]->type != AST_CONSTANT) -					log_error("System function %s called with non-const argument at %s:%d!\n", -							RTLIL::unescape_id(str).c_str(), filename.c_str(), linenum); +					log_file_error(filename, linenum, "System function %s called with non-const argument!\n", +						       RTLIL::unescape_id(str).c_str());  				width_hint = max(width_hint, int(children[0]->asInt(true)));  			}  			break; @@ -799,8 +799,8 @@ void AstNode::detectSignWidthWorker(int &width_hint, bool &sign_hint, bool *foun  	default:  		for (auto f : log_files)  			current_ast->dumpAst(f, "verilog-ast> "); -		log_error("Don't know how to detect sign and width for %s node at %s:%d!\n", -				type2str(type).c_str(), filename.c_str(), linenum); +		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) @@ -863,11 +863,11 @@ 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_error("Re-definition of signal `%s' at %s:%d!\n", -						str.c_str(), filename.c_str(), linenum); +				log_file_error(filename, linenum, "Re-definition of signal `%s'!\n", +					       str.c_str());  			if (!range_valid) -				log_error("Signal `%s' with non-constant width at %s:%d!\n", -						str.c_str(), filename.c_str(), linenum); +				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 +881,8 @@ RTLIL::SigSpec AstNode::genRTLIL(int width_hint, bool sign_hint)  			for (auto &attr : attributes) {  				if (attr.second->type != AST_CONSTANT) -					log_error("Attribute `%s' with non-constant value at %s:%d!\n", -							attr.first.c_str(), filename.c_str(), linenum); +					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 +891,16 @@ 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_error("Re-definition of memory `%s' at %s:%d!\n", -						str.c_str(), filename.c_str(), linenum); +				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_error("Memory `%s' with non-constant width or size at %s:%d!\n", -						str.c_str(), filename.c_str(), linenum); +				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 +917,8 @@ RTLIL::SigSpec AstNode::genRTLIL(int width_hint, bool sign_hint)  			for (auto &attr : attributes) {  				if (attr.second->type != AST_CONSTANT) -					log_error("Attribute `%s' with non-constant value at %s:%d!\n", -							attr.first.c_str(), filename.c_str(), linenum); +					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 +937,8 @@ RTLIL::SigSpec AstNode::genRTLIL(int width_hint, bool sign_hint)  	case AST_REALVALUE:  		{  			RTLIL::SigSpec sig = realAsConst(width_hint); -			log_warning("converting real value %e to binary %s at %s:%d.\n", -					realvalue, log_signal(sig), filename.c_str(), linenum); +			log_file_warning(filename, linenum, "converting real value %e to binary %s.\n", +					 realvalue, log_signal(sig));  			return sig;  		} @@ -958,25 +958,25 @@ RTLIL::SigSpec AstNode::genRTLIL(int width_hint, bool sign_hint)  				wire->attributes["\\src"] = stringf("%s:%d", filename.c_str(), linenum);  				wire->name = str;  				if (flag_autowire) -					log_warning("Identifier `%s' is implicitly declared at %s:%d.\n", str.c_str(), filename.c_str(), linenum); +					log_file_warning(filename, linenum, "Identifier `%s' is implicitly declared.\n", str.c_str());  				else -					log_error("Identifier `%s' is implicitly declared at %s:%d and `default_nettype is set to none.\n", str.c_str(), filename.c_str(), linenum); +					log_file_error(filename, linenum, "Identifier `%s' is implicitly declared and `default_nettype is set to none.\n", str.c_str());  			}  			else if (id2ast->type == AST_PARAMETER || id2ast->type == AST_LOCALPARAM) {  				if (id2ast->children[0]->type != AST_CONSTANT) -					log_error("Parameter %s does not evaluate to constant value at %s:%d!\n", -							str.c_str(), filename.c_str(), linenum); +					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_error("Identifier `%s' doesn't map to any signal at %s:%d!\n", -						str.c_str(), filename.c_str(), linenum); +				log_file_error(filename, linenum, "Identifier `%s' doesn't map to any signal!\n", +						str.c_str());  			if (id2ast->type == AST_MEMORY) -				log_error("Identifier `%s' does map to an unexpanded memory at %s:%d!\n", -						str.c_str(), filename.c_str(), linenum); +				log_file_error(filename, linenum, "Identifier `%s' does map to an unexpanded memory!\n", +					       str.c_str());  			wire = current_module->wires_[str];  			chunk.wire = wire; @@ -994,8 +994,8 @@ 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_error("Unsupported expression on dynamic range select on signal `%s' at %s:%d!\n", -								str.c_str(), filename.c_str(), linenum); +						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()); @@ -1023,11 +1023,11 @@ RTLIL::SigSpec AstNode::genRTLIL(int width_hint, bool sign_hint)  						chunk.offset = (id2ast->range_left - id2ast->range_right + 1) - (chunk.offset + chunk.width);  					if (chunk.offset >= source_width || chunk.offset + chunk.width < 0) {  						if (chunk.width == 1) -							log_warning("Range select out of bounds on signal `%s' at %s:%d: Setting result bit to undef.\n", -									str.c_str(), filename.c_str(), linenum); +							log_file_warning(filename, linenum, "Range select out of bounds on signal `%s': Setting result bit to undef.\n", +									 str.c_str());  						else -							log_warning("Range select out of bounds on signal `%s' at %s:%d: Setting all %d result bits to undef.\n", -									str.c_str(), filename.c_str(), linenum, chunk.width); +							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);  						chunk = RTLIL::SigChunk(RTLIL::State::Sx, chunk.width);  					} else {  						if (chunk.width + chunk.offset > source_width) { @@ -1040,11 +1040,11 @@ RTLIL::SigSpec AstNode::genRTLIL(int width_hint, bool sign_hint)  							chunk.offset += add_undef_bits_lsb;  						}  						if (add_undef_bits_lsb) -							log_warning("Range select out of bounds on signal `%s' at %s:%d: Setting %d LSB bits to undef.\n", -									str.c_str(), filename.c_str(), linenum, 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);  						if (add_undef_bits_msb) -							log_warning("Range select out of bounds on signal `%s' at %s:%d: Setting %d MSB bits to undef.\n", -									str.c_str(), filename.c_str(), linenum, 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);  					}  				}  			} @@ -1083,7 +1083,7 @@ RTLIL::SigSpec AstNode::genRTLIL(int width_hint, bool sign_hint)  			RTLIL::SigSpec left = children[0]->genRTLIL();  			RTLIL::SigSpec right = children[1]->genRTLIL();  			if (!left.is_fully_const()) -				log_error("Left operand of replicate expression is not constant at %s:%d!\n", filename.c_str(), linenum); +				log_file_error(filename, linenum, "Left operand of replicate expression is not constant!\n");  			int count = left.as_int();  			RTLIL::SigSpec sig;  			for (int i = 0; i < count; i++) @@ -1322,7 +1322,7 @@ RTLIL::SigSpec AstNode::genRTLIL(int width_hint, bool sign_hint)  			int num_words = 1;  			if (type == AST_MEMINIT) {  				if (children[2]->type != AST_CONSTANT) -					log_error("Memory init with non-constant word count at %s:%d!\n", filename.c_str(), linenum); +					log_file_error(filename, linenum, "Memory init with non-constant word count!\n");  				num_words = int(children[2]->asInt(false));  				cell->parameters["\\WORDS"] = RTLIL::Const(num_words);  			} @@ -1379,8 +1379,8 @@ RTLIL::SigSpec AstNode::genRTLIL(int width_hint, bool sign_hint)  			for (auto &attr : attributes) {  				if (attr.second->type != AST_CONSTANT) -					log_error("Attribute `%s' with non-constant value at %s:%d!\n", -							attr.first.c_str(), filename.c_str(), linenum); +					log_file_error(filename, linenum, "Attribute `%s' with non-constant value!\n", +						       attr.first.c_str());  				cell->attributes[attr.first] = attr.second->asAttrConst();  			} @@ -1401,10 +1401,10 @@ RTLIL::SigSpec AstNode::genRTLIL(int width_hint, bool sign_hint)  						new_left.append(left[i]);  						new_right.append(right[i]);  					} -				log_warning("Ignoring assignment to constant bits at %s:%d:\n" -						"    old assignment: %s = %s\n    new assignment: %s = %s.\n", -						filename.c_str(), linenum, log_signal(left), log_signal(right), -						log_signal(new_left), log_signal(new_right)); +				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));  				left = new_left;  				right = new_right;  			} @@ -1418,8 +1418,7 @@ RTLIL::SigSpec AstNode::genRTLIL(int width_hint, bool sign_hint)  			int port_counter = 0, para_counter = 0;  			if (current_module->count_id(str) != 0) -				log_error("Re-definition of cell `%s' at %s:%d!\n", -						str.c_str(), filename.c_str(), linenum); +				log_file_error(filename, linenum, "Re-definition of cell `%s'!\n", str.c_str());  			RTLIL::Cell *cell = current_module->addCell(str, "");  			cell->attributes["\\src"] = stringf("%s:%d", filename.c_str(), linenum); @@ -1435,16 +1434,15 @@ RTLIL::SigSpec AstNode::genRTLIL(int width_hint, bool sign_hint)  				if (child->type == AST_PARASET) {  					IdString paraname = child->str.empty() ? stringf("$%d", ++para_counter) : child->str;  					if (child->children[0]->type == AST_REALVALUE) { -						log_warning("Replacing floating point parameter %s.%s = %f with string at %s:%d.\n", -							log_id(cell), log_id(paraname), child->children[0]->realvalue, -							filename.c_str(), linenum); +						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);  						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_error("Parameter %s.%s with non-constant value at %s:%d!\n", -								log_id(cell), log_id(paraname), filename.c_str(), linenum); +						log_file_error(filename, linenum, "Parameter %s.%s with non-constant value!\n", +							       log_id(cell), log_id(paraname));  					cell->parameters[paraname] = child->children[0]->asParaConst();  					continue;  				} @@ -1465,8 +1463,8 @@ RTLIL::SigSpec AstNode::genRTLIL(int width_hint, bool sign_hint)  			}  			for (auto &attr : attributes) {  				if (attr.second->type != AST_CONSTANT) -					log_error("Attribute `%s' with non-constant value at %s:%d!\n", -							attr.first.c_str(), filename.c_str(), linenum); +					log_file_error(filename, linenum, "Attribute `%s' with non-constant value!\n", +						       attr.first.c_str());  				cell->attributes[attr.first] = attr.second->asAttrConst();  			}  		} @@ -1493,19 +1491,19 @@ RTLIL::SigSpec AstNode::genRTLIL(int width_hint, bool sign_hint)  				int width = width_hint;  				if (GetSize(children) > 1) -					log_error("System function %s got %d arguments, expected 1 or 0 at %s:%d.\n", -							RTLIL::unescape_id(str).c_str(), GetSize(children), filename.c_str(), linenum); +					log_file_error(filename, linenum, "System function %s got %d arguments, expected 1 or 0.\n", +						       RTLIL::unescape_id(str).c_str(), GetSize(children));  				if (GetSize(children) == 1) {  					if (children[0]->type != AST_CONSTANT) -						log_error("System function %s called with non-const argument at %s:%d!\n", -								RTLIL::unescape_id(str).c_str(), filename.c_str(), linenum); +						log_file_error(filename, linenum, "System function %s called with non-const argument!\n", +							       RTLIL::unescape_id(str).c_str());  					width = children[0]->asInt(true);  				}  				if (width <= 0) -					log_error("Failed to detect width of %s at %s:%d!\n", -							RTLIL::unescape_id(str).c_str(), filename.c_str(), linenum); +					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); @@ -1514,7 +1512,7 @@ RTLIL::SigSpec AstNode::genRTLIL(int width_hint, bool sign_hint)  				if (attributes.count("\\reg")) {  					auto &attr = attributes.at("\\reg");  					if (attr->type != AST_CONSTANT) -						log_error("Attribute `reg' with non-constant value at %s:%d!\n", filename.c_str(), linenum); +						log_file_error(filename, linenum, "Attribute `reg' with non-constant value!\n");  					cell->attributes["\\reg"] =  attr->asAttrConst();  				} @@ -1532,8 +1530,8 @@ 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_error("Don't know how to generate RTLIL code for %s node at %s:%d!\n", -				type_name.c_str(), filename.c_str(), linenum); +		log_file_error(filename, linenum, "Don't know how to generate RTLIL code for %s node!\n", +			       type_name.c_str());  	}  	return RTLIL::SigSpec(); @@ -1563,4 +1561,3 @@ RTLIL::SigSpec AstNode::genWidthRTLIL(int width, const dict<RTLIL::SigBit, RTLIL  }  YOSYS_NAMESPACE_END - diff --git a/frontends/ast/simplify.cc b/frontends/ast/simplify.cc index a16fdfeeb..04c429f7f 100644 --- a/frontends/ast/simplify.cc +++ b/frontends/ast/simplify.cc @@ -177,13 +177,13 @@ bool AstNode::simplify(bool const_fold, bool at_zero, bool in_lvalue, int stage,  	// note that $display, $finish, and $stop are used for synthesis-time DRC so they're not in this list  	if ((type == AST_FCALL || type == AST_TCALL) && (str == "$strobe" || str == "$monitor" || str == "$time" ||  			str == "$dumpfile" || str == "$dumpvars" || str == "$dumpon" || str == "$dumpoff" || str == "$dumpall")) { -		log_warning("Ignoring call to system %s %s at %s:%d.\n", type == AST_FCALL ? "function" : "task", str.c_str(), filename.c_str(), linenum); +		log_file_warning(filename, linenum, "Ignoring call to system %s %s.\n", type == AST_FCALL ? "function" : "task", str.c_str());  		delete_children();  		str = std::string();  	}  	if ((type == AST_TCALL) && (str == "$display" || str == "$write") && (!current_always || current_always->type != AST_INITIAL)) { -		log_warning("System task `%s' outside initial block is unsupported at %s:%d.\n", str.c_str(), filename.c_str(), linenum); +		log_file_warning(filename, linenum, "System task `%s' outside initial block is unsupported.\n", str.c_str());  		delete_children();  		str = std::string();  	} @@ -195,14 +195,14 @@ bool AstNode::simplify(bool const_fold, bool at_zero, bool in_lvalue, int stage,  	{  		int nargs = GetSize(children);  		if (nargs < 1) -			log_error("System task `%s' got %d arguments, expected >= 1 at %s:%d.\n", -					str.c_str(), int(children.size()), filename.c_str(), linenum); +			log_file_error(filename, linenum, "System task `%s' got %d arguments, expected >= 1.\n", +				       str.c_str(), int(children.size()));  		// First argument is the format string  		AstNode *node_string = children[0];  		while (node_string->simplify(true, false, false, stage, width_hint, sign_hint, false)) { }  		if (node_string->type != AST_CONSTANT) -			log_error("Failed to evaluate system task `%s' with non-constant 1st argument at %s:%d.\n", str.c_str(), filename.c_str(), linenum); +			log_file_error(filename, linenum, "Failed to evaluate system task `%s' with non-constant 1st argument.\n", str.c_str());  		std::string sformat = node_string->bitsAsConst().decode_string();  		// Other arguments are placeholders. Process the string as we go through it @@ -215,7 +215,7 @@ bool AstNode::simplify(bool const_fold, bool at_zero, bool in_lvalue, int stage,  			{  				// If there's no next character, that's a problem  				if (i+1 >= sformat.length()) -					log_error("System task `%s' called with `%%' at end of string at %s:%d.\n", str.c_str(), filename.c_str(), linenum); +					log_file_error(filename, linenum, "System task `%s' called with `%%' at end of string.\n", str.c_str());  				char cformat = sformat[++i]; @@ -239,13 +239,13 @@ bool AstNode::simplify(bool const_fold, bool at_zero, bool in_lvalue, int stage,  					case 'x':  					case 'X':  						if (next_arg >= GetSize(children)) -							log_error("Missing argument for %%%c format specifier in system task `%s' at %s:%d.\n", -									cformat, str.c_str(), filename.c_str(), linenum); +							log_file_error(filename, linenum, "Missing argument for %%%c format specifier in system task `%s'.\n", +								       cformat, str.c_str());  						node_arg = children[next_arg++];  						while (node_arg->simplify(true, false, false, stage, width_hint, sign_hint, false)) { }  						if (node_arg->type != AST_CONSTANT) -							log_error("Failed to evaluate system task `%s' with non-constant argument at %s:%d.\n", str.c_str(), filename.c_str(), linenum); +							log_file_error(filename, linenum, "Failed to evaluate system task `%s' with non-constant argument.\n", str.c_str());  						break;  					case 'm': @@ -253,7 +253,7 @@ bool AstNode::simplify(bool const_fold, bool at_zero, bool in_lvalue, int stage,  						break;  					default: -						log_error("System task `%s' called with invalid/unsupported format specifier at %s:%d.\n", str.c_str(), filename.c_str(), linenum); +						log_file_error(filename, linenum, "System task `%s' called with invalid/unsupported format specifier.\n", str.c_str());  						break;  				} @@ -327,6 +327,8 @@ bool AstNode::simplify(bool const_fold, bool at_zero, bool in_lvalue, int stage,  			if (node->type == AST_WIRE) {  				if (this_wire_scope.count(node->str) > 0) {  					AstNode *first_node = this_wire_scope[node->str]; +					if (first_node->is_input && node->is_reg) +						goto wires_are_incompatible;  					if (!node->is_input && !node->is_output && node->is_reg && node->children.size() == 0)  						goto wires_are_compatible;  					if (first_node->children.size() == 0 && node->children.size() == 1 && node->children[0]->type == AST_RANGE) { @@ -361,6 +363,8 @@ bool AstNode::simplify(bool const_fold, bool at_zero, bool in_lvalue, int stage,  						first_node->is_output = true;  					if (node->is_reg)  						first_node->is_reg = true; +					if (node->is_logic) +						first_node->is_logic = true;  					if (node->is_signed)  						first_node->is_signed = true;  					for (auto &it : node->attributes) { @@ -374,7 +378,7 @@ bool AstNode::simplify(bool const_fold, bool at_zero, bool in_lvalue, int stage,  					continue;  				wires_are_incompatible:  					if (stage > 1) -						log_error("Incompatible re-declaration of wire %s at %s:%d.\n", node->str.c_str(), filename.c_str(), linenum); +						log_file_error(filename, linenum, "Incompatible re-declaration of wire %s.\n", node->str.c_str());  					continue;  				}  				this_wire_scope[node->str] = node; @@ -402,7 +406,7 @@ bool AstNode::simplify(bool const_fold, bool at_zero, bool in_lvalue, int stage,  	if (type == AST_ALWAYS || type == AST_INITIAL)  	{  		if (current_always != nullptr) -			log_error("Invalid nesting of always blocks and/or initializations at %s:%d.\n", filename.c_str(), linenum); +			log_file_error(filename, linenum, "Invalid nesting of always blocks and/or initializations.\n");  		current_always = this;  		current_always_clocked = false; @@ -440,6 +444,16 @@ bool AstNode::simplify(bool const_fold, bool at_zero, bool in_lvalue, int stage,  		children[1]->detectSignWidth(width_hint, sign_hint);  		width_hint = max(width_hint, backup_width_hint);  		child_0_is_self_determined = true; +		// test only once, before optimizations and memory mappings but after assignment LHS was mapped to an identifier +		if (children[0]->id2ast && !children[0]->was_checked) { +			if ((type == AST_ASSIGN_LE || type == AST_ASSIGN_EQ) && children[0]->id2ast->is_logic) +				children[0]->id2ast->is_reg = true; // if logic type is used in a block asignment +			if ((type == AST_ASSIGN_LE || type == AST_ASSIGN_EQ) && !children[0]->id2ast->is_reg) +				log_warning("wire '%s' is assigned in a block at %s:%d.\n", children[0]->str.c_str(), filename.c_str(), linenum); +			if (type == AST_ASSIGN && children[0]->id2ast->is_reg) +				log_warning("reg '%s' is assigned in a continuous assignment at %s:%d.\n", children[0]->str.c_str(), filename.c_str(), linenum); +			children[0]->was_checked = true; +		}  		break;  	case AST_PARAMETER: @@ -451,7 +465,7 @@ bool AstNode::simplify(bool const_fold, bool at_zero, bool in_lvalue, int stage,  			while (!children[1]->basic_prep && children[1]->simplify(false, false, false, stage, -1, false, true) == true)  				did_something = true;  			if (!children[1]->range_valid) -				log_error("Non-constant width range on parameter decl at %s:%d.\n", filename.c_str(), linenum); +				log_file_error(filename, linenum, "Non-constant width range on parameter decl.\n");  			width_hint = max(width_hint, children[1]->range_left - children[1]->range_right + 1);  		}  		break; @@ -695,7 +709,7 @@ bool AstNode::simplify(bool const_fold, bool at_zero, bool in_lvalue, int stage,  	if (type == AST_DEFPARAM && !children.empty())  	{  		if (children[0]->type != AST_IDENTIFIER) -			log_error("Module name in defparam at %s:%d contains non-constant expressions!\n", filename.c_str(), linenum); +			log_file_error(filename, linenum, "Module name in defparam contains non-constant expressions!\n");  		string modname, paramname = children[0]->str; @@ -712,13 +726,13 @@ bool AstNode::simplify(bool const_fold, bool at_zero, bool in_lvalue, int stage,  		}  		if (pos == std::string::npos) -			log_error("Can't find object for defparam `%s` at %s:%d!\n", RTLIL::unescape_id(paramname).c_str(), filename.c_str(), linenum); +			log_file_error(filename, linenum, "Can't find object for defparam `%s`!\n", RTLIL::unescape_id(paramname).c_str());  		paramname = "\\" + paramname.substr(pos+1);  		if (current_scope.at(modname)->type != AST_CELL) -			log_error("Defparam argument `%s . %s` does not match a cell at %s:%d!\n", -					RTLIL::unescape_id(modname).c_str(), RTLIL::unescape_id(paramname).c_str(), filename.c_str(), linenum); +			log_file_error(filename, linenum, "Defparam argument `%s . %s` does not match a cell!\n", +				       RTLIL::unescape_id(modname).c_str(), RTLIL::unescape_id(paramname).c_str());  		AstNode *paraset = new AstNode(AST_PARASET, children[1]->clone(), GetSize(children) > 2 ? children[2]->clone() : NULL);  		paraset->str = paramname; @@ -732,7 +746,7 @@ bool AstNode::simplify(bool const_fold, bool at_zero, bool in_lvalue, int stage,  	if (type == AST_PREFIX) {  		if (children[0]->type != AST_CONSTANT) {  			// dumpAst(NULL, ">   "); -			log_error("Index in generate block prefix syntax at %s:%d is not constant!\n", filename.c_str(), linenum); +			log_file_error(filename, linenum, "Index in generate block prefix syntax is not constant!\n");  		}  		if (children[1]->type == AST_PREFIX)  			children[1]->simplify(const_fold, at_zero, in_lvalue, stage, width_hint, sign_hint, in_param); @@ -748,9 +762,9 @@ bool AstNode::simplify(bool const_fold, bool at_zero, bool in_lvalue, int stage,  	// evaluate TO_BITS nodes  	if (type == AST_TO_BITS) {  		if (children[0]->type != AST_CONSTANT) -			log_error("Left operand of to_bits expression is not constant at %s:%d!\n", filename.c_str(), linenum); +			log_file_error(filename, linenum, "Left operand of to_bits expression is not constant!\n");  		if (children[1]->type != AST_CONSTANT) -			log_error("Right operand of to_bits expression is not constant at %s:%d!\n", filename.c_str(), linenum); +			log_file_error(filename, linenum, "Right operand of to_bits expression is not constant!\n");  		RTLIL::Const new_value = children[1]->bitsAsConst(children[0]->bitsAsConst().as_int(), children[1]->is_signed);  		newNode = mkconst_bits(new_value.bits, children[1]->is_signed);  		goto apply_newNode; @@ -814,7 +828,7 @@ bool AstNode::simplify(bool const_fold, bool at_zero, bool in_lvalue, int stage,  		multirange_dimensions.clear();  		for (auto range : children[1]->children) {  			if (!range->range_valid) -				log_error("Non-constant range on memory decl at %s:%d.\n", filename.c_str(), linenum); +				log_file_error(filename, linenum, "Non-constant range on memory decl.\n");  			multirange_dimensions.push_back(min(range->range_left, range->range_right));  			multirange_dimensions.push_back(max(range->range_left, range->range_right) - min(range->range_left, range->range_right) + 1);  			total_size *= multirange_dimensions.back(); @@ -832,7 +846,7 @@ bool AstNode::simplify(bool const_fold, bool at_zero, bool in_lvalue, int stage,  		for (int i = 0; 2*i < GetSize(id2ast->multirange_dimensions); i++)  		{  			if (GetSize(children[0]->children) < i) -				log_error("Insufficient number of array indices for %s at %s:%d.\n", log_id(str), filename.c_str(), linenum); +				log_file_error(filename, linenum, "Insufficient number of array indices for %s.\n", log_id(str));  			AstNode *new_index_expr = children[0]->children[i]->children.at(0)->clone(); @@ -861,12 +875,12 @@ bool AstNode::simplify(bool const_fold, bool at_zero, bool in_lvalue, int stage,  	if (type == AST_PARAMETER || type == AST_LOCALPARAM) {  		if (children.size() > 1 && children[1]->type == AST_RANGE) {  			if (!children[1]->range_valid) -				log_error("Non-constant width range on parameter decl at %s:%d.\n", filename.c_str(), linenum); +				log_file_error(filename, linenum, "Non-constant width range on parameter decl.\n");  			int width = std::abs(children[1]->range_left - children[1]->range_right) + 1;  			if (children[0]->type == AST_REALVALUE) {  				RTLIL::Const constvalue = children[0]->realAsConst(width); -				log_warning("converting real value %e to binary %s at %s:%d.\n", -						children[0]->realvalue, log_signal(constvalue), filename.c_str(), linenum); +				log_file_warning(filename, linenum, "converting real value %e to binary %s.\n", +						 children[0]->realvalue, log_signal(constvalue));  				delete children[0];  				children[0] = mkconst_bits(constvalue.bits, sign_hint);  				did_something = true; @@ -924,7 +938,7 @@ bool AstNode::simplify(bool const_fold, bool at_zero, bool in_lvalue, int stage,  	if (type == AST_IDENTIFIER && children.size() == 2 && children[0]->type == AST_RANGE && children[1]->type == AST_RANGE && !in_lvalue)  	{  		if (id2ast == NULL || id2ast->type != AST_MEMORY || children[0]->children.size() != 1) -			log_error("Invalid bit-select on memory access at %s:%d!\n", filename.c_str(), linenum); +			log_file_error(filename, linenum, "Invalid bit-select on memory access!\n");  		int mem_width, mem_size, addr_bits;  		id2ast->meminfo(mem_width, mem_size, addr_bits); @@ -949,6 +963,7 @@ bool AstNode::simplify(bool const_fold, bool at_zero, bool in_lvalue, int stage,  		AstNode *assign = new AstNode(AST_ASSIGN_EQ, new AstNode(AST_IDENTIFIER), data);  		assign->children[0]->str = wire_id; +		assign->children[0]->was_checked = true;  		if (current_block)  		{ @@ -973,10 +988,10 @@ bool AstNode::simplify(bool const_fold, bool at_zero, bool in_lvalue, int stage,  	}  	if (type == AST_WHILE) -		log_error("While loops are only allowed in constant functions at %s:%d!\n", filename.c_str(), linenum); +		log_file_error(filename, linenum, "While loops are only allowed in constant functions!\n");  	if (type == AST_REPEAT) -		log_error("Repeat loops are only allowed in constant functions at %s:%d!\n", filename.c_str(), linenum); +		log_file_error(filename, linenum, "Repeat loops are only allowed in constant functions!\n");  	// unroll for loops and generate-for blocks  	if ((type == AST_GENFOR || type == AST_FOR) && children.size() != 0) @@ -991,31 +1006,31 @@ bool AstNode::simplify(bool const_fold, bool at_zero, bool in_lvalue, int stage,  			body_ast = body_ast->children.at(0);  		if (init_ast->type != AST_ASSIGN_EQ) -			log_error("Unsupported 1st expression of generate for-loop at %s:%d!\n", filename.c_str(), linenum); +			log_file_error(filename, linenum, "Unsupported 1st expression of generate for-loop!\n");  		if (next_ast->type != AST_ASSIGN_EQ) -			log_error("Unsupported 3rd expression of generate for-loop at %s:%d!\n", filename.c_str(), linenum); +			log_file_error(filename, linenum, "Unsupported 3rd expression of generate for-loop!\n");  		if (type == AST_GENFOR) {  			if (init_ast->children[0]->id2ast == NULL || init_ast->children[0]->id2ast->type != AST_GENVAR) -				log_error("Left hand side of 1st expression of generate for-loop at %s:%d is not a gen var!\n", filename.c_str(), linenum); +				log_file_error(filename, linenum, "Left hand side of 1st expression of generate for-loop is not a gen var!\n");  			if (next_ast->children[0]->id2ast == NULL || next_ast->children[0]->id2ast->type != AST_GENVAR) -				log_error("Left hand side of 3rd expression of generate for-loop at %s:%d is not a gen var!\n", filename.c_str(), linenum); +				log_file_error(filename, linenum, "Left hand side of 3rd expression of generate for-loop is not a gen var!\n");  		} else {  			if (init_ast->children[0]->id2ast == NULL || init_ast->children[0]->id2ast->type != AST_WIRE) -				log_error("Left hand side of 1st expression of generate for-loop at %s:%d is not a register!\n", filename.c_str(), linenum); +				log_file_error(filename, linenum, "Left hand side of 1st expression of generate for-loop is not a register!\n");  			if (next_ast->children[0]->id2ast == NULL || next_ast->children[0]->id2ast->type != AST_WIRE) -				log_error("Left hand side of 3rd expression of generate for-loop at %s:%d is not a register!\n", filename.c_str(), linenum); +				log_file_error(filename, linenum, "Left hand side of 3rd expression of generate for-loop is not a register!\n");  		}  		if (init_ast->children[0]->id2ast != next_ast->children[0]->id2ast) -			log_error("Incompatible left-hand sides in 1st and 3rd expression of generate for-loop at %s:%d!\n", filename.c_str(), linenum); +			log_file_error(filename, linenum, "Incompatible left-hand sides in 1st and 3rd expression of generate for-loop!\n");  		// eval 1st expression  		AstNode *varbuf = init_ast->children[1]->clone();  		while (varbuf->simplify(true, false, false, stage, 32, true, false)) { }  		if (varbuf->type != AST_CONSTANT) -			log_error("Right hand side of 1st expression of generate for-loop at %s:%d is not constant!\n", filename.c_str(), linenum); +			log_file_error(filename, linenum, "Right hand side of 1st expression of generate for-loop is not constant!\n");  		varbuf = new AstNode(AST_LOCALPARAM, varbuf);  		varbuf->str = init_ast->children[0]->str; @@ -1037,7 +1052,7 @@ bool AstNode::simplify(bool const_fold, bool at_zero, bool in_lvalue, int stage,  			while (buf->simplify(true, false, false, stage, width_hint, sign_hint, false)) { }  			if (buf->type != AST_CONSTANT) -				log_error("2nd expression of generate for-loop at %s:%d is not constant!\n", filename.c_str(), linenum); +				log_file_error(filename, linenum, "2nd expression of generate for-loop is not constant!\n");  			if (buf->integer == 0) {  				delete buf; @@ -1078,7 +1093,7 @@ bool AstNode::simplify(bool const_fold, bool at_zero, bool in_lvalue, int stage,  			while (buf->simplify(true, false, false, stage, 32, true, false)) { }  			if (buf->type != AST_CONSTANT) -				log_error("Right hand side of 3rd expression of generate for-loop at %s:%d is not constant!\n", filename.c_str(), linenum); +				log_file_error(filename, linenum, "Right hand side of 3rd expression of generate for-loop is not constant!\n");  			delete varbuf->children[0];  			varbuf->children[0] = buf; @@ -1095,8 +1110,7 @@ bool AstNode::simplify(bool const_fold, bool at_zero, bool in_lvalue, int stage,  	{  		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) -				log_error("Local declaration in unnamed block at %s:%d is an unsupported SystemVerilog feature!\n", -						children[i]->filename.c_str(), children[i]->linenum); +				log_file_error(children[i]->filename, children[i]->linenum, "Local declaration in unnamed block is an unsupported SystemVerilog feature!\n");  	}  	// transform block with name @@ -1144,7 +1158,7 @@ bool AstNode::simplify(bool const_fold, bool at_zero, bool in_lvalue, int stage,  		if (buf->type != AST_CONSTANT) {  			// for (auto f : log_files)  			// 	dumpAst(f, "verilog-ast> "); -			log_error("Condition for generate if at %s:%d is not constant!\n", filename.c_str(), linenum); +			log_file_error(filename, linenum, "Condition for generate if is not constant!\n");  		}  		if (buf->asBool() != 0) {  			delete buf; @@ -1185,7 +1199,7 @@ bool AstNode::simplify(bool const_fold, bool at_zero, bool in_lvalue, int stage,  		if (buf->type != AST_CONSTANT) {  			// for (auto f : log_files)  			// 	dumpAst(f, "verilog-ast> "); -			log_error("Condition for generate case at %s:%d is not constant!\n", filename.c_str(), linenum); +			log_file_error(filename, linenum, "Condition for generate case is not constant!\n");  		}  		bool ref_signed = buf->is_signed; @@ -1219,7 +1233,7 @@ bool AstNode::simplify(bool const_fold, bool at_zero, bool in_lvalue, int stage,  				if (buf->type != AST_CONSTANT) {  					// for (auto f : log_files)  					// 	dumpAst(f, "verilog-ast> "); -					log_error("Expression in generate case at %s:%d is not constant!\n", filename.c_str(), linenum); +					log_file_error(filename, linenum, "Expression in generate case is not constant!\n");  				}  				bool is_selected = RTLIL::const_eq(ref_value, buf->bitsAsConst(), ref_signed && buf->is_signed, ref_signed && buf->is_signed, 1).as_bool(); @@ -1260,7 +1274,7 @@ bool AstNode::simplify(bool const_fold, bool at_zero, bool in_lvalue, int stage,  	if (type == AST_CELLARRAY)  	{  		if (!children.at(0)->range_valid) -			log_error("Non-constant array range on cell array at %s:%d.\n", filename.c_str(), linenum); +			log_file_error(filename, linenum, "Non-constant array range on cell array.\n");  		newNode = new AstNode(AST_GENBLOCK);  		int num = max(children.at(0)->range_left, children.at(0)->range_right) - min(children.at(0)->range_left, children.at(0)->range_right) + 1; @@ -1271,7 +1285,7 @@ bool AstNode::simplify(bool const_fold, bool at_zero, bool in_lvalue, int stage,  			newNode->children.push_back(new_cell);  			new_cell->str += stringf("[%d]", idx);  			if (new_cell->type == AST_PRIMITIVE) { -				log_error("Cell arrays of primitives are currently not supported at %s:%d.\n", filename.c_str(), linenum); +				log_file_error(filename, linenum, "Cell arrays of primitives are currently not supported.\n");  			} else {  				log_assert(new_cell->children.at(0)->type == AST_CELLTYPE);  				new_cell->children.at(0)->str = stringf("$array:%d:%d:%s", i, num, new_cell->children.at(0)->str.c_str()); @@ -1285,8 +1299,8 @@ bool AstNode::simplify(bool const_fold, bool at_zero, bool in_lvalue, int stage,  	if (type == AST_PRIMITIVE)  	{  		if (children.size() < 2) -			log_error("Insufficient number of arguments for primitive `%s' at %s:%d!\n", -					str.c_str(), filename.c_str(), linenum); +			log_file_error(filename, linenum, "Insufficient number of arguments for primitive `%s'!\n", +				       str.c_str());  		std::vector<AstNode*> children_list;  		for (auto child : children) { @@ -1301,8 +1315,8 @@ bool AstNode::simplify(bool const_fold, bool at_zero, bool in_lvalue, int stage,  		if (str == "bufif0" || str == "bufif1" || str == "notif0" || str == "notif1")  		{  			if (children_list.size() != 3) -				log_error("Invalid number of arguments for primitive `%s' at %s:%d!\n", -						str.c_str(), filename.c_str(), linenum); +				log_file_error(filename, linenum, "Invalid number of arguments for primitive `%s'!\n", +					       str.c_str());  			std::vector<RTLIL::State> z_const(1, RTLIL::State::Sz); @@ -1387,8 +1401,8 @@ bool AstNode::simplify(bool const_fold, bool at_zero, bool in_lvalue, int stage,  			while (left_at_zero_ast->simplify(true, true, false, stage, -1, false, false)) { }  			while (right_at_zero_ast->simplify(true, true, false, stage, -1, false, false)) { }  			if (left_at_zero_ast->type != AST_CONSTANT || right_at_zero_ast->type != AST_CONSTANT) -				log_error("Unsupported expression on dynamic range select on signal `%s' at %s:%d!\n", -						str.c_str(), filename.c_str(), linenum); +				log_file_error(filename, linenum, "Unsupported expression on dynamic range select on signal `%s'!\n", +					       str.c_str());  			result_width = abs(int(left_at_zero_ast->integer - right_at_zero_ast->integer)) + 1;  		}  		did_something = true; @@ -1415,16 +1429,19 @@ skip_dynamic_range_lvalue_expansion:;  		AstNode *wire_check = new AstNode(AST_WIRE);  		wire_check->str = id_check; +		wire_check->was_checked = true;  		current_ast_mod->children.push_back(wire_check);  		current_scope[wire_check->str] = wire_check;  		while (wire_check->simplify(true, false, false, 1, -1, false, false)) { }  		AstNode *wire_en = new AstNode(AST_WIRE);  		wire_en->str = id_en; +		wire_en->was_checked = true;  		current_ast_mod->children.push_back(wire_en);  		if (current_always_clocked) {  			current_ast_mod->children.push_back(new AstNode(AST_INITIAL, new AstNode(AST_BLOCK, new AstNode(AST_ASSIGN_LE, new AstNode(AST_IDENTIFIER), AstNode::mkconst_int(0, false, 1)))));  			current_ast_mod->children.back()->children[0]->children[0]->children[0]->str = id_en; +			current_ast_mod->children.back()->children[0]->children[0]->children[0]->was_checked = true;  		}  		current_scope[wire_en->str] = wire_en;  		while (wire_en->simplify(true, false, false, 1, -1, false, false)) { } @@ -1434,9 +1451,11 @@ skip_dynamic_range_lvalue_expansion:;  		AstNode *assign_check = new AstNode(AST_ASSIGN_LE, new AstNode(AST_IDENTIFIER), mkconst_bits(x_bit, false));  		assign_check->children[0]->str = id_check; +		assign_check->children[0]->was_checked = true;  		AstNode *assign_en = new AstNode(AST_ASSIGN_LE, new AstNode(AST_IDENTIFIER), mkconst_int(0, false, 1));  		assign_en->children[0]->str = id_en; +		assign_en->children[0]->was_checked = true;  		AstNode *default_signals = new AstNode(AST_BLOCK);  		default_signals->children.push_back(assign_check); @@ -1445,6 +1464,7 @@ skip_dynamic_range_lvalue_expansion:;  		assign_check = new AstNode(AST_ASSIGN_LE, new AstNode(AST_IDENTIFIER), new AstNode(AST_REDUCE_BOOL, children[0]->clone()));  		assign_check->children[0]->str = id_check; +		assign_check->children[0]->was_checked = true;  		if (current_always == nullptr || current_always->type != AST_INITIAL) {  			assign_en = new AstNode(AST_ASSIGN_LE, new AstNode(AST_IDENTIFIER), mkconst_int(1, false, 1)); @@ -1453,6 +1473,7 @@ skip_dynamic_range_lvalue_expansion:;  			assign_en->children[1]->str = "\\$initstate";  		}  		assign_en->children[0]->str = id_en; +		assign_en->children[0]->was_checked = true;  		newNode = new AstNode(AST_BLOCK);  		newNode->children.push_back(assign_check); @@ -1561,12 +1582,14 @@ skip_dynamic_range_lvalue_expansion:;  		AstNode *wire_addr = new AstNode(AST_WIRE, new AstNode(AST_RANGE, mkconst_int(addr_bits-1, true), mkconst_int(0, true)));  		wire_addr->str = id_addr; +		wire_addr->was_checked = true;  		current_ast_mod->children.push_back(wire_addr);  		current_scope[wire_addr->str] = wire_addr;  		while (wire_addr->simplify(true, false, false, 1, -1, false, false)) { }  		AstNode *wire_data = new AstNode(AST_WIRE, new AstNode(AST_RANGE, mkconst_int(mem_width-1, true), mkconst_int(0, true)));  		wire_data->str = id_data; +		wire_data->was_checked = true;  		wire_data->is_signed = mem_signed;  		current_ast_mod->children.push_back(wire_data);  		current_scope[wire_data->str] = wire_data; @@ -1576,6 +1599,7 @@ skip_dynamic_range_lvalue_expansion:;  		if (current_always->type != AST_INITIAL) {  			wire_en = new AstNode(AST_WIRE, new AstNode(AST_RANGE, mkconst_int(mem_width-1, true), mkconst_int(0, true)));  			wire_en->str = id_en; +			wire_en->was_checked = true;  			current_ast_mod->children.push_back(wire_en);  			current_scope[wire_en->str] = wire_en;  			while (wire_en->simplify(true, false, false, 1, -1, false, false)) { } @@ -1591,14 +1615,17 @@ skip_dynamic_range_lvalue_expansion:;  		AstNode *assign_addr = new AstNode(AST_ASSIGN_LE, new AstNode(AST_IDENTIFIER), mkconst_bits(x_bits_addr, false));  		assign_addr->children[0]->str = id_addr; +		assign_addr->children[0]->was_checked = true;  		AstNode *assign_data = new AstNode(AST_ASSIGN_LE, new AstNode(AST_IDENTIFIER), mkconst_bits(x_bits_data, false));  		assign_data->children[0]->str = id_data; +		assign_data->children[0]->was_checked = true;  		AstNode *assign_en = nullptr;  		if (current_always->type != AST_INITIAL) {  			assign_en = new AstNode(AST_ASSIGN_LE, new AstNode(AST_IDENTIFIER), mkconst_int(0, false, mem_width));  			assign_en->children[0]->str = id_en; +			assign_en->children[0]->was_checked = true;  		}  		AstNode *default_signals = new AstNode(AST_BLOCK); @@ -1610,6 +1637,7 @@ skip_dynamic_range_lvalue_expansion:;  		assign_addr = new AstNode(AST_ASSIGN_LE, new AstNode(AST_IDENTIFIER), children[0]->children[0]->children[0]->clone());  		assign_addr->children[0]->str = id_addr; +		assign_addr->children[0]->was_checked = true;  		if (children[0]->children.size() == 2)  		{ @@ -1624,12 +1652,14 @@ skip_dynamic_range_lvalue_expansion:;  				assign_data = new AstNode(AST_ASSIGN_LE, new AstNode(AST_IDENTIFIER),  						new AstNode(AST_CONCAT, mkconst_bits(padding_x, false), children[1]->clone()));  				assign_data->children[0]->str = id_data; +				assign_data->children[0]->was_checked = true;  				if (current_always->type != AST_INITIAL) {  					for (int i = 0; i < mem_width; i++)  						set_bits_en[i] = offset <= i && i < offset+width ? RTLIL::State::S1 : RTLIL::State::S0;  					assign_en = new AstNode(AST_ASSIGN_LE, new AstNode(AST_IDENTIFIER), mkconst_bits(set_bits_en, false));  					assign_en->children[0]->str = id_en; +					assign_en->children[0]->was_checked = true;  				}  			}  			else @@ -1645,12 +1675,13 @@ skip_dynamic_range_lvalue_expansion:;  				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_error("Unsupported expression on dynamic range select on signal `%s' at %s:%d!\n", str.c_str(), filename.c_str(), linenum); +					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;  				assign_data = new AstNode(AST_ASSIGN_LE, new AstNode(AST_IDENTIFIER),  						new AstNode(AST_SHIFT_LEFT, children[1]->clone(), offset_ast->clone()));  				assign_data->children[0]->str = id_data; +				assign_data->children[0]->was_checked = true;  				if (current_always->type != AST_INITIAL) {  					for (int i = 0; i < mem_width; i++) @@ -1658,6 +1689,7 @@ skip_dynamic_range_lvalue_expansion:;  					assign_en = new AstNode(AST_ASSIGN_LE, new AstNode(AST_IDENTIFIER),  							new AstNode(AST_SHIFT_LEFT, mkconst_bits(set_bits_en, false), offset_ast->clone()));  					assign_en->children[0]->str = id_en; +					assign_en->children[0]->was_checked = true;  				}  				delete left_at_zero_ast; @@ -1669,10 +1701,12 @@ skip_dynamic_range_lvalue_expansion:;  		{  			assign_data = new AstNode(AST_ASSIGN_LE, new AstNode(AST_IDENTIFIER), children[1]->clone());  			assign_data->children[0]->str = id_data; +			assign_data->children[0]->was_checked = true;  			if (current_always->type != AST_INITIAL) {  				assign_en = new AstNode(AST_ASSIGN_LE, new AstNode(AST_IDENTIFIER), mkconst_bits(set_bits_en, false));  				assign_en->children[0]->str = id_en; +				assign_en->children[0]->was_checked = true;  			}  		} @@ -1737,19 +1771,19 @@ skip_dynamic_range_lvalue_expansion:;  				int num_steps = 1;  				if (GetSize(children) != 1 && GetSize(children) != 2) -					log_error("System function %s got %d arguments, expected 1 or 2 at %s:%d.\n", -							RTLIL::unescape_id(str).c_str(), int(children.size()), filename.c_str(), linenum); +					log_file_error(filename, linenum, "System function %s got %d arguments, expected 1 or 2.\n", +						       RTLIL::unescape_id(str).c_str(), int(children.size()));  				if (!current_always_clocked) -					log_error("System function %s is only allowed in clocked blocks at %s:%d.\n", -							RTLIL::unescape_id(str).c_str(), filename.c_str(), linenum); +					log_file_error(filename, linenum, "System function %s is only allowed in clocked blocks.\n", +						       RTLIL::unescape_id(str).c_str());  				if (GetSize(children) == 2)  				{  					AstNode *buf = children[1]->clone();  					while (buf->simplify(true, false, false, stage, width_hint, sign_hint, false)) { }  					if (buf->type != AST_CONSTANT) -						log_error("Failed to evaluate system function `%s' with non-constant value at %s:%d.\n", str.c_str(), filename.c_str(), linenum); +						log_file_error(filename, linenum, "Failed to evaluate system function `%s' with non-constant value.\n", str.c_str());  					num_steps = buf->asInt(true);  					delete buf; @@ -1805,12 +1839,12 @@ skip_dynamic_range_lvalue_expansion:;  			if (str == "\\$stable" || str == "\\$rose" || str == "\\$fell")  			{  				if (GetSize(children) != 1) -					log_error("System function %s got %d arguments, expected 1 at %s:%d.\n", -							RTLIL::unescape_id(str).c_str(), int(children.size()), filename.c_str(), linenum); +					log_file_error(filename, linenum, "System function %s got %d arguments, expected 1.\n", +						       RTLIL::unescape_id(str).c_str(), int(children.size()));  				if (!current_always_clocked) -					log_error("System function %s is only allowed in clocked blocks at %s:%d.\n", -							RTLIL::unescape_id(str).c_str(), filename.c_str(), linenum); +					log_file_error(filename, linenum, "System function %s is only allowed in clocked blocks.\n", +						       RTLIL::unescape_id(str).c_str());  				AstNode *present = children.at(0)->clone();  				AstNode *past = clone(); @@ -1840,13 +1874,13 @@ skip_dynamic_range_lvalue_expansion:;  			if (str == "\\$clog2")  			{  				if (children.size() != 1) -					log_error("System function %s got %d arguments, expected 1 at %s:%d.\n", -							RTLIL::unescape_id(str).c_str(), int(children.size()), filename.c_str(), linenum); +					log_file_error(filename, linenum, "System function %s got %d arguments, expected 1.\n", +						       RTLIL::unescape_id(str).c_str(), int(children.size()));  				AstNode *buf = children[0]->clone();  				while (buf->simplify(true, false, false, stage, width_hint, sign_hint, false)) { }  				if (buf->type != AST_CONSTANT) -					log_error("Failed to evaluate system function `%s' with non-constant value at %s:%d.\n", str.c_str(), filename.c_str(), linenum); +					log_file_error(filename, linenum, "Failed to evaluate system function `%s' with non-constant value.\n", str.c_str());  				RTLIL::Const arg_value = buf->bitsAsConst();  				if (arg_value.as_bool()) @@ -1865,12 +1899,12 @@ skip_dynamic_range_lvalue_expansion:;  			if (str == "\\$size" || str == "\\$bits")  			{  				if (str == "\\$bits" && children.size() != 1) -					log_error("System function %s got %d arguments, expected 1 at %s:%d.\n", -							RTLIL::unescape_id(str).c_str(), int(children.size()), filename.c_str(), linenum); +					log_file_error(filename, linenum, "System function %s got %d arguments, expected 1.\n", +						       RTLIL::unescape_id(str).c_str(), int(children.size()));  				if (str == "\\$size" && children.size() != 1 && children.size() != 2) -					log_error("System function %s got %d arguments, expected 1 or 2 at %s:%d.\n", -							RTLIL::unescape_id(str).c_str(), int(children.size()), filename.c_str(), linenum); +					log_file_error(filename, linenum, "System function %s got %d arguments, expected 1 or 2.\n", +						       RTLIL::unescape_id(str).c_str(), int(children.size()));  				int dim = 1;  				if (str == "\\$size" && children.size() == 2) { @@ -1893,7 +1927,7 @@ skip_dynamic_range_lvalue_expansion:;  					if (id_ast == NULL && current_scope.count(buf->str))  						id_ast = current_scope.at(buf->str);  					if (!id_ast) -						log_error("Failed to resolve identifier %s for width detection at %s:%d!\n", buf->str.c_str(), filename.c_str(), linenum); +						log_file_error(filename, linenum, "Failed to resolve identifier %s for width detection!\n", buf->str.c_str());  					if (id_ast->type == AST_MEMORY) {  						// We got here only if the argument is a memory  						// Otherwise $size() and $bits() return the expression width @@ -1901,15 +1935,15 @@ skip_dynamic_range_lvalue_expansion:;  						if (str == "\\$bits") {  							if (mem_range->type == AST_RANGE) {  								if (!mem_range->range_valid) -									log_error("Failed to detect width of memory access `%s' at %s:%d!\n", buf->str.c_str(), filename.c_str(), linenum); +									log_file_error(filename, linenum, "Failed to detect width of memory access `%s'!\n", buf->str.c_str());  								mem_depth = mem_range->range_left - mem_range->range_right + 1;  							} else -								log_error("Unknown memory depth AST type in `%s' at %s:%d!\n", buf->str.c_str(), filename.c_str(), linenum); +								log_file_error(filename, linenum, "Unknown memory depth AST type in `%s'!\n", buf->str.c_str());  						} else {  							// $size()  							if (mem_range->type == AST_RANGE) {  								if (!mem_range->range_valid) -									log_error("Failed to detect width of memory access `%s' at %s:%d!\n", buf->str.c_str(), filename.c_str(), linenum); +									log_file_error(filename, linenum, "Failed to detect width of memory access `%s'!\n", buf->str.c_str());  								int dims;  								if (id_ast->multirange_dimensions.empty())  									dims = 1; @@ -1920,9 +1954,9 @@ skip_dynamic_range_lvalue_expansion:;  								else if (dim <= dims) {  									width_hint = id_ast->multirange_dimensions[2*dim-1];  								} else if ((dim > dims+1) || (dim < 0)) -									log_error("Dimension %d out of range in `%s', as it only has dimensions 1..%d at %s:%d!\n", dim, buf->str.c_str(), dims+1, filename.c_str(), linenum); +									log_file_error(filename, linenum, "Dimension %d out of range in `%s', as it only has dimensions 1..%d!\n", dim, buf->str.c_str(), dims+1);  							} else -								log_error("Unknown memory depth AST type in `%s' at %s:%d!\n", buf->str.c_str(), filename.c_str(), linenum); +								log_file_error(filename, linenum, "Unknown memory depth AST type in `%s'!\n", buf->str.c_str());  						}  					}  				} @@ -1943,19 +1977,19 @@ skip_dynamic_range_lvalue_expansion:;  				if (func_with_two_arguments) {  					if (children.size() != 2) -						log_error("System function %s got %d arguments, expected 2 at %s:%d.\n", -								RTLIL::unescape_id(str).c_str(), int(children.size()), filename.c_str(), linenum); +						log_file_error(filename, linenum, "System function %s got %d arguments, expected 2.\n", +							       RTLIL::unescape_id(str).c_str(), int(children.size()));  				} else {  					if (children.size() != 1) -						log_error("System function %s got %d arguments, expected 1 at %s:%d.\n", -								RTLIL::unescape_id(str).c_str(), int(children.size()), filename.c_str(), linenum); +						log_file_error(filename, linenum, "System function %s got %d arguments, expected 1.\n", +							       RTLIL::unescape_id(str).c_str(), int(children.size()));  				}  				if (children.size() >= 1) {  					while (children[0]->simplify(true, false, false, stage, width_hint, sign_hint, false)) { }  					if (!children[0]->isConst()) -						log_error("Failed to evaluate system function `%s' with non-constant argument at %s:%d.\n", -								RTLIL::unescape_id(str).c_str(), filename.c_str(), linenum); +						log_file_error(filename, linenum, "Failed to evaluate system function `%s' with non-constant argument.\n", +							       RTLIL::unescape_id(str).c_str());  					int child_width_hint = width_hint;  					bool child_sign_hint = sign_hint;  					children[0]->detectSignWidth(child_width_hint, child_sign_hint); @@ -1965,8 +1999,8 @@ skip_dynamic_range_lvalue_expansion:;  				if (children.size() >= 2) {  					while (children[1]->simplify(true, false, false, stage, width_hint, sign_hint, false)) { }  					if (!children[1]->isConst()) -						log_error("Failed to evaluate system function `%s' with non-constant argument at %s:%d.\n", -								RTLIL::unescape_id(str).c_str(), filename.c_str(), linenum); +						log_file_error(filename, linenum, "Failed to evaluate system function `%s' with non-constant argument.\n", +							       RTLIL::unescape_id(str).c_str());  					int child_width_hint = width_hint;  					bool child_sign_hint = sign_hint;  					children[1]->detectSignWidth(child_width_hint, child_sign_hint); @@ -2018,14 +2052,14 @@ skip_dynamic_range_lvalue_expansion:;  				for (int i = 2; i < GetSize(dpi_decl->children); i++)  				{  					if (i-2 >= GetSize(children)) -						log_error("Insufficient number of arguments in DPI function call at %s:%d.\n", filename.c_str(), linenum); +						log_file_error(filename, linenum, "Insufficient number of arguments in DPI function call.\n");  					argtypes.push_back(RTLIL::unescape_id(dpi_decl->children.at(i)->str));  					args.push_back(children.at(i-2)->clone());  					while (args.back()->simplify(true, false, false, stage, -1, false, true)) { }  					if (args.back()->type != AST_CONSTANT && args.back()->type != AST_REALVALUE) -						log_error("Failed to evaluate DPI function with non-constant argument at %s:%d.\n", filename.c_str(), linenum); +						log_file_error(filename, linenum, "Failed to evaluate DPI function with non-constant argument.\n");  				}  				newNode = dpi_call(rtype, fname, argtypes, args); @@ -2037,7 +2071,7 @@ skip_dynamic_range_lvalue_expansion:;  			}  			if (current_scope.count(str) == 0 || current_scope[str]->type != AST_FUNCTION) -				log_error("Can't resolve function name `%s' at %s:%d.\n", str.c_str(), filename.c_str(), linenum); +				log_file_error(filename, linenum, "Can't resolve function name `%s'.\n", str.c_str());  		}  		if (type == AST_TCALL) @@ -2045,26 +2079,26 @@ skip_dynamic_range_lvalue_expansion:;  			if (str == "$finish" || str == "$stop")  			{  				if (!current_always || current_always->type != AST_INITIAL) -					log_error("System task `%s' outside initial block is unsupported at %s:%d.\n", str.c_str(), filename.c_str(), linenum); +					log_file_error(filename, linenum, "System task `%s' outside initial block is unsupported.\n", str.c_str()); -				log_error("System task `%s' executed at %s:%d.\n", str.c_str(), filename.c_str(), linenum); +				log_file_error(filename, linenum, "System task `%s' executed.\n", str.c_str());  			}  			if (str == "\\$readmemh" || str == "\\$readmemb")  			{  				if (GetSize(children) < 2 || GetSize(children) > 4) -					log_error("System function %s got %d arguments, expected 2-4 at %s:%d.\n", -							RTLIL::unescape_id(str).c_str(), int(children.size()), filename.c_str(), linenum); +					log_file_error(filename, linenum, "System function %s got %d arguments, expected 2-4.\n", +						       RTLIL::unescape_id(str).c_str(), int(children.size()));  				AstNode *node_filename = children[0]->clone();  				while (node_filename->simplify(true, false, false, stage, width_hint, sign_hint, false)) { }  				if (node_filename->type != AST_CONSTANT) -					log_error("Failed to evaluate system function `%s' with non-constant 1st argument at %s:%d.\n", str.c_str(), filename.c_str(), linenum); +					log_file_error(filename, linenum, "Failed to evaluate system function `%s' with non-constant 1st argument.\n", str.c_str());  				AstNode *node_memory = children[1]->clone();  				while (node_memory->simplify(true, false, false, stage, width_hint, sign_hint, false)) { }  				if (node_memory->type != AST_IDENTIFIER || node_memory->id2ast == nullptr || node_memory->id2ast->type != AST_MEMORY) -					log_error("Failed to evaluate system function `%s' with non-memory 2nd argument at %s:%d.\n", str.c_str(), filename.c_str(), linenum); +					log_file_error(filename, linenum, "Failed to evaluate system function `%s' with non-memory 2nd argument.\n", str.c_str());  				int start_addr = -1, finish_addr = -1; @@ -2072,7 +2106,7 @@ skip_dynamic_range_lvalue_expansion:;  					AstNode *node_addr = children[2]->clone();  					while (node_addr->simplify(true, false, false, stage, width_hint, sign_hint, false)) { }  					if (node_addr->type != AST_CONSTANT) -						log_error("Failed to evaluate system function `%s' with non-constant 3rd argument at %s:%d.\n", str.c_str(), filename.c_str(), linenum); +						log_file_error(filename, linenum, "Failed to evaluate system function `%s' with non-constant 3rd argument.\n", str.c_str());  					start_addr = int(node_addr->asInt(false));  				} @@ -2080,7 +2114,7 @@ skip_dynamic_range_lvalue_expansion:;  					AstNode *node_addr = children[3]->clone();  					while (node_addr->simplify(true, false, false, stage, width_hint, sign_hint, false)) { }  					if (node_addr->type != AST_CONSTANT) -						log_error("Failed to evaluate system function `%s' with non-constant 4th argument at %s:%d.\n", str.c_str(), filename.c_str(), linenum); +						log_file_error(filename, linenum, "Failed to evaluate system function `%s' with non-constant 4th argument.\n", str.c_str());  					finish_addr = int(node_addr->asInt(false));  				} @@ -2106,7 +2140,7 @@ skip_dynamic_range_lvalue_expansion:;  			}  			if (current_scope.count(str) == 0 || current_scope[str]->type != AST_TASK) -				log_error("Can't resolve task name `%s' at %s:%d.\n", str.c_str(), filename.c_str(), linenum); +				log_file_error(filename, linenum, "Can't resolve task name `%s'.\n", str.c_str());  		}  		AstNode *decl = current_scope[str]; @@ -2134,9 +2168,9 @@ skip_dynamic_range_lvalue_expansion:;  			}  			if (in_param) -				log_error("Non-constant function call in constant expression at %s:%d.\n", filename.c_str(), linenum); +				log_file_error(filename, linenum, "Non-constant function call in constant expression.\n");  			if (require_const_eval) -				log_error("Function %s can only be called with constant arguments at %s:%d.\n", str.c_str(), filename.c_str(), linenum); +				log_file_error(filename, linenum, "Function %s can only be called with constant arguments.\n", str.c_str());  		}  		size_t arg_count = 0; @@ -2253,7 +2287,7 @@ skip_dynamic_range_lvalue_expansion:;  									goto tcall_incompatible_wires;  						} else {  					tcall_incompatible_wires: -							log_error("Incompatible re-declaration of wire %s at %s:%d.\n", child->str.c_str(), filename.c_str(), linenum); +							log_file_error(filename, linenum, "Incompatible re-declaration of wire %s.\n", child->str.c_str());  						}  					}  				} @@ -2641,7 +2675,7 @@ AstNode *AstNode::readmem(bool is_readmemh, std::string mem_filename, AstNode *m  	yosys_input_files.insert(mem_filename);  	if (f.fail()) -		log_error("Can not open file `%s` for %s at %s:%d.\n", mem_filename.c_str(), str.c_str(), filename.c_str(), linenum); +		log_file_error(filename, linenum, "Can not open file `%s` for %s.\n", mem_filename.c_str(), str.c_str());  	log_assert(GetSize(memory->children) == 2 && memory->children[1]->type == AST_RANGE && memory->children[1]->range_valid);  	int range_left =  memory->children[1]->range_left, range_right =  memory->children[1]->range_right; @@ -2687,7 +2721,7 @@ AstNode *AstNode::readmem(bool is_readmemh, std::string mem_filename, AstNode *m  				char *endptr;  				cursor = strtol(nptr, &endptr, 16);  				if (!*nptr || *endptr) -					log_error("Can not parse address `%s` for %s at %s:%d.\n", nptr, str.c_str(), filename.c_str(), linenum); +					log_file_error(filename, linenum, "Can not parse address `%s` for %s.\n", nptr, str.c_str());  				continue;  			} @@ -2943,7 +2977,7 @@ bool AstNode::mem2reg_check(pool<AstNode*> &mem2reg_set)  		return false;  	if (children.empty() || children[0]->type != AST_RANGE || GetSize(children[0]->children) != 1) -		log_error("Invalid array access at %s:%d.\n", filename.c_str(), linenum); +		log_file_error(filename, linenum, "Invalid array access.\n");  	return true;  } @@ -3008,6 +3042,7 @@ bool AstNode::mem2reg_as_needed_pass2(pool<AstNode*> &mem2reg_set, AstNode *mod,  		AstNode *wire_addr = new AstNode(AST_WIRE, new AstNode(AST_RANGE, mkconst_int(addr_bits-1, true), mkconst_int(0, true)));  		wire_addr->str = id_addr;  		wire_addr->is_reg = true; +		wire_addr->was_checked = true;  		wire_addr->attributes["\\nosync"] = AstNode::mkconst_int(1, false);  		mod->children.push_back(wire_addr);  		while (wire_addr->simplify(true, false, false, 1, -1, false, false)) { } @@ -3015,6 +3050,7 @@ bool AstNode::mem2reg_as_needed_pass2(pool<AstNode*> &mem2reg_set, AstNode *mod,  		AstNode *wire_data = new AstNode(AST_WIRE, new AstNode(AST_RANGE, mkconst_int(mem_width-1, true), mkconst_int(0, true)));  		wire_data->str = id_data;  		wire_data->is_reg = true; +		wire_data->was_checked = true;  		wire_data->is_signed = mem_signed;  		wire_data->attributes["\\nosync"] = AstNode::mkconst_int(1, false);  		mod->children.push_back(wire_data); @@ -3083,6 +3119,7 @@ bool AstNode::mem2reg_as_needed_pass2(pool<AstNode*> &mem2reg_set, AstNode *mod,  			AstNode *wire_addr = new AstNode(AST_WIRE, new AstNode(AST_RANGE, mkconst_int(addr_bits-1, true), mkconst_int(0, true)));  			wire_addr->str = id_addr;  			wire_addr->is_reg = true; +			wire_addr->was_checked = true;  			if (block)  				wire_addr->attributes["\\nosync"] = AstNode::mkconst_int(1, false);  			mod->children.push_back(wire_addr); @@ -3091,6 +3128,7 @@ bool AstNode::mem2reg_as_needed_pass2(pool<AstNode*> &mem2reg_set, AstNode *mod,  			AstNode *wire_data = new AstNode(AST_WIRE, new AstNode(AST_RANGE, mkconst_int(mem_width-1, true), mkconst_int(0, true)));  			wire_data->str = id_data;  			wire_data->is_reg = true; +			wire_data->was_checked = true;  			wire_data->is_signed = mem_signed;  			if (block)  				wire_data->attributes["\\nosync"] = AstNode::mkconst_int(1, false); @@ -3099,6 +3137,7 @@ bool AstNode::mem2reg_as_needed_pass2(pool<AstNode*> &mem2reg_set, AstNode *mod,  			AstNode *assign_addr = new AstNode(block ? AST_ASSIGN_EQ : AST_ASSIGN, new AstNode(AST_IDENTIFIER), children[0]->children[0]->clone());  			assign_addr->children[0]->str = id_addr; +			assign_addr->children[0]->was_checked = true;  			AstNode *case_node = new AstNode(AST_CASE, new AstNode(AST_IDENTIFIER));  			case_node->children[0]->str = id_addr; @@ -3109,6 +3148,7 @@ bool AstNode::mem2reg_as_needed_pass2(pool<AstNode*> &mem2reg_set, AstNode *mod,  				AstNode *cond_node = new AstNode(AST_COND, AstNode::mkconst_int(i, false, addr_bits), new AstNode(AST_BLOCK));  				AstNode *assign_reg = new AstNode(AST_ASSIGN_EQ, new AstNode(AST_IDENTIFIER), new AstNode(AST_IDENTIFIER));  				assign_reg->children[0]->str = id_data; +				assign_reg->children[0]->was_checked = true;  				assign_reg->children[1]->str = stringf("%s[%d]", str.c_str(), i);  				cond_node->children[1]->children.push_back(assign_reg);  				case_node->children.push_back(cond_node); @@ -3121,6 +3161,7 @@ bool AstNode::mem2reg_as_needed_pass2(pool<AstNode*> &mem2reg_set, AstNode *mod,  			AstNode *cond_node = new AstNode(AST_COND, new AstNode(AST_DEFAULT), new AstNode(AST_BLOCK));  			AstNode *assign_reg = new AstNode(AST_ASSIGN_EQ, new AstNode(AST_IDENTIFIER), AstNode::mkconst_bits(x_bits, false));  			assign_reg->children[0]->str = id_data; +			assign_reg->children[0]->was_checked = true;  			cond_node->children[1]->children.push_back(assign_reg);  			case_node->children.push_back(cond_node); @@ -3202,13 +3243,13 @@ void AstNode::replace_variables(std::map<std::string, AstNode::varinfo_t> &varia  		int offset = variables.at(str).offset, width = variables.at(str).val.bits.size();  		if (!children.empty()) {  			if (children.size() != 1 || children.at(0)->type != AST_RANGE) -				log_error("Memory access in constant function is not supported in %s:%d (called from %s:%d).\n", -						filename.c_str(), linenum, fcall->filename.c_str(), fcall->linenum); +				log_file_error(filename, linenum, "Memory access in constant function is not supported\n%s:%d: ...called from here.\n", +					       fcall->filename.c_str(), fcall->linenum);  			children.at(0)->replace_variables(variables, fcall);  			while (simplify(true, false, false, 1, -1, false, true)) { }  			if (!children.at(0)->range_valid) -				log_error("Non-constant range in %s:%d (called from %s:%d).\n", -						filename.c_str(), linenum, fcall->filename.c_str(), fcall->linenum); +				log_file_error(filename, linenum, "Non-constant range\n%s:%d: ... called from here.\n", +					       fcall->filename.c_str(), fcall->linenum);  			offset = min(children.at(0)->range_left, children.at(0)->range_right);  			width = min(std::abs(children.at(0)->range_left - children.at(0)->range_right) + 1, width);  		} @@ -3247,8 +3288,8 @@ AstNode *AstNode::eval_const_function(AstNode *fcall)  		{  			while (child->simplify(true, false, false, 1, -1, false, true)) { }  			if (!child->range_valid) -				log_error("Can't determine size of variable %s in %s:%d (called from %s:%d).\n", -						child->str.c_str(), child->filename.c_str(), child->linenum, fcall->filename.c_str(), fcall->linenum); +				log_file_error(child->filename, child->linenum, "Can't determine size of variable %s\n%s:%d: ... called from here.\n", +					       child->str.c_str(), fcall->filename.c_str(), fcall->linenum);  			variables[child->str].val = RTLIL::Const(RTLIL::State::Sx, abs(child->range_left - child->range_right)+1);  			variables[child->str].offset = min(child->range_left, child->range_right);  			variables[child->str].is_signed = child->is_signed; @@ -3291,24 +3332,24 @@ AstNode *AstNode::eval_const_function(AstNode *fcall)  				continue;  			if (stmt->children.at(1)->type != AST_CONSTANT) -				log_error("Non-constant expression in constant function at %s:%d (called from %s:%d). X\n", -						stmt->filename.c_str(), stmt->linenum, fcall->filename.c_str(), fcall->linenum); +				log_file_error(stmt->filename, stmt->linenum, "Non-constant expression in constant function\n%s:%d: ... called from here. X\n", +					       fcall->filename.c_str(), fcall->linenum);  			if (stmt->children.at(0)->type != AST_IDENTIFIER) -				log_error("Unsupported composite left hand side in constant function at %s:%d (called from %s:%d).\n", -						stmt->filename.c_str(), stmt->linenum, fcall->filename.c_str(), fcall->linenum); +				log_file_error(stmt->filename, stmt->linenum, "Unsupported composite left hand side in constant function\n%s:%d: ... called from here.\n", +					       fcall->filename.c_str(), fcall->linenum);  			if (!variables.count(stmt->children.at(0)->str)) -				log_error("Assignment to non-local variable in constant function at %s:%d (called from %s:%d).\n", -						stmt->filename.c_str(), stmt->linenum, fcall->filename.c_str(), fcall->linenum); +				log_file_error(stmt->filename, stmt->linenum, "Assignment to non-local variable in constant function\n%s:%d: ... called from here.\n", +					       fcall->filename.c_str(), fcall->linenum);  			if (stmt->children.at(0)->children.empty()) {  				variables[stmt->children.at(0)->str].val = stmt->children.at(1)->bitsAsConst(variables[stmt->children.at(0)->str].val.bits.size());  			} else {  				AstNode *range = stmt->children.at(0)->children.at(0);  				if (!range->range_valid) -					log_error("Non-constant range in %s:%d (called from %s:%d).\n", -							range->filename.c_str(), range->linenum, fcall->filename.c_str(), fcall->linenum); +					log_file_error(range->filename, range->linenum, "Non-constant range\n%s:%d: ... called from here.\n", +						       fcall->filename.c_str(), fcall->linenum);  				int offset = min(range->range_left, range->range_right);  				int width = std::abs(range->range_left - range->range_right) + 1;  				varinfo_t &v = variables[stmt->children.at(0)->str]; @@ -3339,8 +3380,8 @@ AstNode *AstNode::eval_const_function(AstNode *fcall)  			while (cond->simplify(true, false, false, 1, -1, false, true)) { }  			if (cond->type != AST_CONSTANT) -				log_error("Non-constant expression in constant function at %s:%d (called from %s:%d).\n", -						stmt->filename.c_str(), stmt->linenum, fcall->filename.c_str(), fcall->linenum); +				log_file_error(stmt->filename, stmt->linenum, "Non-constant expression in constant function\n%s:%d: ... called from here.\n", +					       fcall->filename.c_str(), fcall->linenum);  			if (cond->asBool()) {  				block->children.insert(block->children.begin(), stmt->children.at(1)->clone()); @@ -3360,8 +3401,8 @@ AstNode *AstNode::eval_const_function(AstNode *fcall)  			while (num->simplify(true, false, false, 1, -1, false, true)) { }  			if (num->type != AST_CONSTANT) -				log_error("Non-constant expression in constant function at %s:%d (called from %s:%d).\n", -						stmt->filename.c_str(), stmt->linenum, fcall->filename.c_str(), fcall->linenum); +				log_file_error(stmt->filename, stmt->linenum, "Non-constant expression in constant function\n%s:%d: ... called from here.\n", +					       fcall->filename.c_str(), fcall->linenum);  			block->children.erase(block->children.begin());  			for (int i = 0; i < num->bitsAsConst().as_int(); i++) @@ -3398,8 +3439,8 @@ AstNode *AstNode::eval_const_function(AstNode *fcall)  					while (cond->simplify(true, false, false, 1, -1, false, true)) { }  					if (cond->type != AST_CONSTANT) -						log_error("Non-constant expression in constant function at %s:%d (called from %s:%d).\n", -								stmt->filename.c_str(), stmt->linenum, fcall->filename.c_str(), fcall->linenum); +						log_file_error(stmt->filename, stmt->linenum, "Non-constant expression in constant function\n%s:%d: ... called from here.\n", +							       fcall->filename.c_str(), fcall->linenum);  					found_match = cond->asBool();  					delete cond; @@ -3428,8 +3469,8 @@ AstNode *AstNode::eval_const_function(AstNode *fcall)  			continue;  		} -		log_error("Unsupported language construct in constant function at %s:%d (called from %s:%d).\n", -				stmt->filename.c_str(), stmt->linenum, fcall->filename.c_str(), fcall->linenum); +		log_file_error(stmt->filename, stmt->linenum, "Unsupported language construct in constant function\n%s:%d: ... called from here.\n", +			       fcall->filename.c_str(), fcall->linenum);  		log_abort();  	} @@ -3446,4 +3487,3 @@ AstNode *AstNode::eval_const_function(AstNode *fcall)  }  YOSYS_NAMESPACE_END -  | 
