diff options
Diffstat (limited to 'frontends/ast')
| -rw-r--r-- | frontends/ast/ast.cc | 5 | ||||
| -rw-r--r-- | frontends/ast/simplify.cc | 53 | 
2 files changed, 48 insertions, 10 deletions
| diff --git a/frontends/ast/ast.cc b/frontends/ast/ast.cc index 4cf329f75..9ddd538b5 100644 --- a/frontends/ast/ast.cc +++ b/frontends/ast/ast.cc @@ -1158,6 +1158,7 @@ void AST::process(RTLIL::Design *design, AstNode *ast, bool dump_ast1, bool dump  		bool nolatches, bool nomeminit, bool nomem2reg, bool mem2reg, bool noblackbox, bool lib, bool nowb, bool noopt, bool icells, bool pwires, bool nooverwrite, bool overwrite, bool defer, bool autowire)  {  	current_ast = ast; +	current_ast_mod = nullptr;  	flag_dump_ast1 = dump_ast1;  	flag_dump_ast2 = dump_ast2;  	flag_no_dump_ptr = no_dump_ptr; @@ -1224,6 +1225,7 @@ void AST::process(RTLIL::Design *design, AstNode *ast, bool dump_ast1, bool dump  			}  			design->add(process_module(*it, defer)); +			current_ast_mod = nullptr;  		}  		else if ((*it)->type == AST_PACKAGE) {  			// process enum/other declarations @@ -1568,6 +1570,9 @@ std::string AstModule::derive_common(RTLIL::Design *design, const dict<RTLIL::Id  	rewritten.reserve(GetSize(parameters));  	AstNode *new_ast = ast->clone(); +	if (!new_ast->attributes.count(ID::hdlname)) +		new_ast->attributes[ID::hdlname] = AstNode::mkconst_str(stripped_name); +  	para_counter = 0;  	for (auto child : new_ast->children) {  		if (child->type != AST_PARAMETER) diff --git a/frontends/ast/simplify.cc b/frontends/ast/simplify.cc index 2ebe2edbc..837c14ad7 100644 --- a/frontends/ast/simplify.cc +++ b/frontends/ast/simplify.cc @@ -64,6 +64,21 @@ std::string AstNode::process_format_str(const std::string &sformat, int next_arg  				continue;  			} +			bool got_len = false; +			bool got_zlen = false; +			int len_value = 0; + +			while ('0' <= cformat && cformat <= '9') +			{ +				if (!got_len && cformat == '0') +					got_zlen = true; + +				got_len = true; +				len_value = 10*len_value + (cformat - '0'); + +				cformat = sformat[++i]; +			} +  			// Simplify the argument  			AstNode *node_arg = nullptr; @@ -74,6 +89,9 @@ std::string AstNode::process_format_str(const std::string &sformat, int next_arg  				case 'S':  				case 'd':  				case 'D': +					if (got_len) +						goto unsupported_format; +					/* fall through */  				case 'x':  				case 'X':  					if (next_arg >= GetSize(children)) @@ -88,9 +106,12 @@ std::string AstNode::process_format_str(const std::string &sformat, int next_arg  				case 'm':  				case 'M': +					if (got_len) +						goto unsupported_format;  					break;  				default: +				unsupported_format:  					log_file_error(filename, location.first_line, "System task `%s' called with invalid/unsupported format specifier.\n", str.c_str());  					break;  			} @@ -104,19 +125,28 @@ std::string AstNode::process_format_str(const std::string &sformat, int next_arg  				case 'd':  				case 'D': -					{ -						char tmp[128]; -						snprintf(tmp, sizeof(tmp), "%d", node_arg->bitsAsConst().as_int()); -						sout += tmp; -					} +					sout += stringf("%d", node_arg->bitsAsConst().as_int());  					break;  				case 'x':  				case 'X':  					{ -						char tmp[128]; -						snprintf(tmp, sizeof(tmp), "%x", node_arg->bitsAsConst().as_int()); -						sout += tmp; +						Const val = node_arg->bitsAsConst(); + +						while (GetSize(val) % 4 != 0) +							val.bits.push_back(State::S0); + +						int len = GetSize(val) / 4; +						for (int i = len; i < len_value; i++) +							sout += got_zlen ? '0' : ' '; + +						for (int i = len-1; i >= 0; i--) { +							Const digit = val.extract(4*i, 4); +							if (digit.is_fully_def()) +								sout += stringf(cformat == 'x' ? "%x" : "%X", digit.as_int()); +							else +								sout += cformat == 'x' ? "x" : "X"; +						}  					}  					break; @@ -1169,7 +1199,8 @@ bool AstNode::simplify(bool const_fold, bool at_zero, bool in_lvalue, int stage,  	// annotate identifiers using scope resolution and create auto-wires as needed  	if (type == AST_IDENTIFIER) {  		if (current_scope.count(str) == 0) { -			for (auto node : current_ast_mod->children) { +			AstNode *current_scope_ast = (current_ast_mod == nullptr) ? current_ast : current_ast_mod; +			for (auto node : current_scope_ast->children) {  				//log("looking at mod scope child %s\n", type2str(node->type).c_str());  				switch (node->type) {  				case AST_PARAMETER: @@ -1203,7 +1234,9 @@ bool AstNode::simplify(bool const_fold, bool at_zero, bool in_lvalue, int stage,  			}  		}  		if (current_scope.count(str) == 0) { -			if (flag_autowire || str == "\\$global_clock") { +			if (current_ast_mod == nullptr) { +				log_file_error(filename, location.first_line, "Identifier `%s' is implicitly declared outside of a module.\n", str.c_str()); +			} else if (flag_autowire || str == "\\$global_clock") {  				AstNode *auto_wire = new AstNode(AST_AUTOWIRE);  				auto_wire->str = str;  				current_ast_mod->children.push_back(auto_wire); | 
