diff options
author | Claire Wolf <clifford@clifford.at> | 2020-03-03 08:38:32 -0800 |
---|---|---|
committer | GitHub <noreply@github.com> | 2020-03-03 08:38:32 -0800 |
commit | b597f85b13b5369398350ef4ef43b7b2521eb140 (patch) | |
tree | 18ea3d52b5927ea1491162458e16cfcfd3280418 /frontends/ast | |
parent | 91892465e1af2bcb5ec348b86ba4e566b040cb12 (diff) | |
parent | f80fe8dc22ca2b3639b7b0bbff69458addb05432 (diff) | |
download | yosys-b597f85b13b5369398350ef4ef43b7b2521eb140.tar.gz yosys-b597f85b13b5369398350ef4ef43b7b2521eb140.tar.bz2 yosys-b597f85b13b5369398350ef4ef43b7b2521eb140.zip |
Merge pull request #1718 from boqwxp/precise_locations
Closes #1717. Add more precise Verilog source location information to AST and RTLIL nodes.
Diffstat (limited to 'frontends/ast')
-rw-r--r-- | frontends/ast/ast.cc | 46 | ||||
-rw-r--r-- | frontends/ast/ast.h | 9 | ||||
-rw-r--r-- | frontends/ast/genrtlil.cc | 203 | ||||
-rw-r--r-- | frontends/ast/simplify.cc | 262 |
4 files changed, 253 insertions, 267 deletions
diff --git a/frontends/ast/ast.cc b/frontends/ast/ast.cc index 3254012bd..650c7a937 100644 --- a/frontends/ast/ast.cc +++ b/frontends/ast/ast.cc @@ -182,7 +182,7 @@ bool AstNode::get_bool_attribute(RTLIL::IdString id) AstNode *attr = attributes.at(id); if (attr->type != AST_CONSTANT) - log_file_error(attr->filename, attr->linenum, "Attribute `%s' with non-constant value!\n", id.c_str()); + log_file_error(attr->filename, attr->location.first_line, "Attribute `%s' with non-constant value!\n", id.c_str()); return attr->integer != 0; } @@ -197,7 +197,6 @@ AstNode::AstNode(AstNodeType type, AstNode *child1, AstNode *child2, AstNode *ch this->type = type; filename = current_filename; - linenum = get_line_num(); is_input = false; is_output = false; is_reg = false; @@ -280,7 +279,8 @@ void AstNode::dumpAst(FILE *f, std::string indent) const } std::string type_name = type2str(type); - fprintf(f, "%s%s <%s:%d>", indent.c_str(), type_name.c_str(), filename.c_str(), linenum); + fprintf(f, "%s%s <%s:%d.%d-%d.%d>", indent.c_str(), type_name.c_str(), filename.c_str(), location.first_line, + location.first_column, location.last_line, location.last_column); if (!flag_no_dump_ptr) { if (id2ast) @@ -952,7 +952,8 @@ static AstModule* process_module(AstNode *ast, bool defer, AstNode *original_ast current_module = new AstModule; current_module->ast = NULL; current_module->name = ast->str; - current_module->attributes["\\src"] = stringf("%s:%d", ast->filename.c_str(), ast->linenum); + current_module->attributes["\\src"] = stringf("%s:%d.%d-%d.%d", ast->filename.c_str(), ast->location.first_line, + ast->location.first_column, ast->location.last_line, ast->location.last_column); current_module->set_bool_attribute("\\cells_not_processed"); current_ast_mod = ast; @@ -1029,14 +1030,14 @@ static AstModule* process_module(AstNode *ast, bool defer, AstNode *original_ast if (!blackbox_module && ast->attributes.count("\\blackbox")) { AstNode *n = ast->attributes.at("\\blackbox"); if (n->type != AST_CONSTANT) - log_file_error(ast->filename, ast->linenum, "Got blackbox attribute with non-constant value!\n"); + log_file_error(ast->filename, ast->location.first_line, "Got blackbox attribute with non-constant value!\n"); blackbox_module = n->asBool(); } if (blackbox_module && ast->attributes.count("\\whitebox")) { AstNode *n = ast->attributes.at("\\whitebox"); if (n->type != AST_CONSTANT) - log_file_error(ast->filename, ast->linenum, "Got whitebox attribute with non-constant value!\n"); + log_file_error(ast->filename, ast->location.first_line, "Got whitebox attribute with non-constant value!\n"); blackbox_module = !n->asBool(); } @@ -1044,7 +1045,7 @@ static AstModule* process_module(AstNode *ast, bool defer, AstNode *original_ast if (blackbox_module) { AstNode *n = ast->attributes.at("\\noblackbox"); if (n->type != AST_CONSTANT) - log_file_error(ast->filename, ast->linenum, "Got noblackbox attribute with non-constant value!\n"); + log_file_error(ast->filename, ast->location.first_line, "Got noblackbox attribute with non-constant value!\n"); blackbox_module = !n->asBool(); } delete ast->attributes.at("\\noblackbox"); @@ -1090,7 +1091,7 @@ static AstModule* process_module(AstNode *ast, bool defer, AstNode *original_ast for (auto &attr : ast->attributes) { if (attr.second->type != AST_CONSTANT) - log_file_error(ast->filename, ast->linenum, "Attribute `%s' with non-constant value!\n", attr.first.c_str()); + log_file_error(ast->filename, ast->location.first_line, "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++) { @@ -1203,15 +1204,15 @@ 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_blackbox_attribute()) { - log_file_error((*it)->filename, (*it)->linenum, "Re-definition of module `%s'!\n", (*it)->str.c_str()); + log_file_error((*it)->filename, (*it)->location.first_line, "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); + log("Ignoring re-definition of module `%s' at %s:%d.%d-%d.%d.\n", + (*it)->str.c_str(), (*it)->filename.c_str(), (*it)->location.first_line, (*it)->location.first_column, (*it)->location.last_line, (*it)->location.last_column); continue; } else { - log("Replacing existing%s module `%s' at %s:%d.\n", + log("Replacing existing%s module `%s' at %s:%d.%d-%d.%d.\n", existing_mod->get_bool_attribute("\\blackbox") ? " blackbox" : "", - (*it)->str.c_str(), (*it)->filename.c_str(), (*it)->linenum); + (*it)->str.c_str(), (*it)->filename.c_str(), (*it)->location.first_line, (*it)->location.first_column, (*it)->location.last_line, (*it)->location.last_column); design->remove(existing_mod); } } @@ -1633,25 +1634,6 @@ void AstModule::loadconfig() const flag_icells = icells; flag_pwires = pwires; flag_autowire = autowire; - use_internal_line_num(); -} - -// internal dummy line number callbacks -namespace { - int internal_line_num; - void internal_set_line_num(int n) { - internal_line_num = n; - } - int internal_get_line_num() { - return internal_line_num; - } -} - -// use internal dummy line number callbacks -void AST::use_internal_line_num() -{ - set_line_num = &internal_set_line_num; - get_line_num = &internal_get_line_num; } YOSYS_NAMESPACE_END diff --git a/frontends/ast/ast.h b/frontends/ast/ast.h index 59e6058a7..e27ab10c2 100644 --- a/frontends/ast/ast.h +++ b/frontends/ast/ast.h @@ -156,6 +156,13 @@ namespace AST AST_TYPEDEF }; + struct AstSrcLocType { + unsigned int first_line, last_line; + unsigned int first_column, last_column; + AstSrcLocType() : first_line(0), last_line(0), first_column(0), last_column(0) {} + AstSrcLocType(int _first_line, int _first_column, int _last_line, int _last_column) : first_line(_first_line), last_line(_last_line), first_column(_first_column), last_column(_last_column) {} + }; + // convert an node type to a string (e.g. for debug output) std::string type2str(AstNodeType type); @@ -199,7 +206,7 @@ namespace AST // it is automatically set by the constructor using AST::current_filename and // the AST::get_line_num() callback function. std::string filename; - int linenum; + AstSrcLocType location; // creating and deleting nodes AstNode(AstNodeType type = AST_NONE, AstNode *child1 = NULL, AstNode *child2 = NULL, AstNode *child3 = NULL); diff --git a/frontends/ast/genrtlil.cc b/frontends/ast/genrtlil.cc index 1dfcf3e0e..54d8a11fa 100644 --- a/frontends/ast/genrtlil.cc +++ b/frontends/ast/genrtlil.cc @@ -44,18 +44,18 @@ using namespace AST_INTERNAL; static RTLIL::SigSpec uniop2rtlil(AstNode *that, std::string type, int result_width, const RTLIL::SigSpec &arg, bool gen_attributes = true) { std::stringstream sstr; - sstr << type << "$" << that->filename << ":" << that->linenum << "$" << (autoidx++); + sstr << type << "$" << that->filename << ":" << that->location.first_line << "$" << (autoidx++); RTLIL::Cell *cell = current_module->addCell(sstr.str(), type); - cell->attributes["\\src"] = stringf("%s:%d", that->filename.c_str(), that->linenum); + cell->attributes["\\src"] = stringf("%s:%d", that->filename.c_str(), that->location.first_line); RTLIL::Wire *wire = current_module->addWire(cell->name.str() + "_Y", result_width); - wire->attributes["\\src"] = stringf("%s:%d", that->filename.c_str(), that->linenum); + wire->attributes["\\src"] = stringf("%s:%d", that->filename.c_str(), that->location.first_line); if (gen_attributes) for (auto &attr : that->attributes) { if (attr.second->type != AST_CONSTANT) - log_file_error(that->filename, that->linenum, "Attribute `%s' with non-constant value!\n", attr.first.c_str()); + log_file_error(that->filename, that->location.first_line, "Attribute `%s' with non-constant value!\n", attr.first.c_str()); cell->attributes[attr.first] = attr.second->asAttrConst(); } @@ -77,18 +77,18 @@ static void widthExtend(AstNode *that, RTLIL::SigSpec &sig, int width, bool is_s } std::stringstream sstr; - sstr << "$extend" << "$" << that->filename << ":" << that->linenum << "$" << (autoidx++); + sstr << "$extend" << "$" << that->filename << ":" << that->location.first_line << "$" << (autoidx++); RTLIL::Cell *cell = current_module->addCell(sstr.str(), "$pos"); - cell->attributes["\\src"] = stringf("%s:%d", that->filename.c_str(), that->linenum); + cell->attributes["\\src"] = stringf("%s:%d", that->filename.c_str(), that->location.first_line); RTLIL::Wire *wire = current_module->addWire(cell->name.str() + "_Y", width); - wire->attributes["\\src"] = stringf("%s:%d", that->filename.c_str(), that->linenum); + wire->attributes["\\src"] = stringf("%s:%d", that->filename.c_str(), that->location.first_line); if (that != NULL) for (auto &attr : that->attributes) { if (attr.second->type != AST_CONSTANT) - log_file_error(that->filename, that->linenum, "Attribute `%s' with non-constant value!\n", attr.first.c_str()); + log_file_error(that->filename, that->location.first_line, "Attribute `%s' with non-constant value!\n", attr.first.c_str()); cell->attributes[attr.first] = attr.second->asAttrConst(); } @@ -105,17 +105,17 @@ static void widthExtend(AstNode *that, RTLIL::SigSpec &sig, int width, bool is_s static RTLIL::SigSpec binop2rtlil(AstNode *that, std::string type, int result_width, const RTLIL::SigSpec &left, const RTLIL::SigSpec &right) { std::stringstream sstr; - sstr << type << "$" << that->filename << ":" << that->linenum << "$" << (autoidx++); + sstr << type << "$" << that->filename << ":" << that->location.first_line << "$" << (autoidx++); RTLIL::Cell *cell = current_module->addCell(sstr.str(), type); - cell->attributes["\\src"] = stringf("%s:%d", that->filename.c_str(), that->linenum); + cell->attributes["\\src"] = stringf("%s:%d", that->filename.c_str(), that->location.first_line); RTLIL::Wire *wire = current_module->addWire(cell->name.str() + "_Y", result_width); - wire->attributes["\\src"] = stringf("%s:%d", that->filename.c_str(), that->linenum); + wire->attributes["\\src"] = stringf("%s:%d", that->filename.c_str(), that->location.first_line); for (auto &attr : that->attributes) { if (attr.second->type != AST_CONSTANT) - log_file_error(that->filename, that->linenum, "Attribute `%s' with non-constant value!\n", attr.first.c_str()); + log_file_error(that->filename, that->location.first_line, "Attribute `%s' with non-constant value!\n", attr.first.c_str()); cell->attributes[attr.first] = attr.second->asAttrConst(); } @@ -139,17 +139,17 @@ static RTLIL::SigSpec mux2rtlil(AstNode *that, const RTLIL::SigSpec &cond, const log_assert(cond.size() == 1); std::stringstream sstr; - sstr << "$ternary$" << that->filename << ":" << that->linenum << "$" << (autoidx++); + sstr << "$ternary$" << that->filename << ":" << that->location.first_line << "$" << (autoidx++); RTLIL::Cell *cell = current_module->addCell(sstr.str(), "$mux"); - cell->attributes["\\src"] = stringf("%s:%d", that->filename.c_str(), that->linenum); + cell->attributes["\\src"] = stringf("%s:%d", that->filename.c_str(), that->location.first_line); RTLIL::Wire *wire = current_module->addWire(cell->name.str() + "_Y", left.size()); - wire->attributes["\\src"] = stringf("%s:%d", that->filename.c_str(), that->linenum); + wire->attributes["\\src"] = stringf("%s:%d", that->filename.c_str(), that->location.first_line); for (auto &attr : that->attributes) { if (attr.second->type != AST_CONSTANT) - log_file_error(that->filename, that->linenum, "Attribute `%s' with non-constant value!\n", attr.first.c_str()); + log_file_error(that->filename, that->location.first_line, "Attribute `%s' with non-constant value!\n", attr.first.c_str()); cell->attributes[attr.first] = attr.second->asAttrConst(); } @@ -199,11 +199,11 @@ struct AST_INTERNAL::ProcessGenerator { // generate process and simple root case proc = new RTLIL::Process; - proc->attributes["\\src"] = stringf("%s:%d", always->filename.c_str(), always->linenum); - proc->name = stringf("$proc$%s:%d$%d", always->filename.c_str(), always->linenum, autoidx++); + proc->attributes["\\src"] = stringf("%s:%d.%d-%d.%d", always->filename.c_str(), always->location.first_line, always->location.first_column, always->location.last_line, always->location.last_column); + proc->name = stringf("$proc$%s:%d$%d", always->filename.c_str(), always->location.first_line, autoidx++); for (auto &attr : always->attributes) { if (attr.second->type != AST_CONSTANT) - log_file_error(always->filename, always->linenum, "Attribute `%s' with non-constant value!\n", + log_file_error(always->filename, always->location.first_line, "Attribute `%s' with non-constant value!\n", attr.first.c_str()); proc->attributes[attr.first] = attr.second->asAttrConst(); } @@ -234,8 +234,8 @@ struct AST_INTERNAL::ProcessGenerator if (found_anyedge_syncs) { if (found_global_syncs) - 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_file_error(always->filename, always->location.first_line, "Found non-synthesizable event list!\n"); + log("Note: Assuming pure combinatorial block at %s:%d.%d-%d.%d in\n", always->filename.c_str(), always->location.first_line, always->location.first_column, always->location.last_line, always->location.last_column); 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"); } @@ -249,12 +249,12 @@ struct AST_INTERNAL::ProcessGenerator continue; found_clocked_sync = true; if (found_global_syncs || found_anyedge_syncs) - log_file_error(always->filename, always->linenum, "Found non-synthesizable event list!\n"); + log_file_error(always->filename, always->location.first_line, "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_file_error(always->filename, always->linenum, "Found posedge/negedge event on a signal that is not 1 bit wide!\n"); + log_file_error(always->filename, always->location.first_line, "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); } @@ -335,7 +335,7 @@ struct AST_INTERNAL::ProcessGenerator } while (current_module->wires_.count(wire_name) > 0); RTLIL::Wire *wire = current_module->addWire(wire_name, chunk.width); - wire->attributes["\\src"] = stringf("%s:%d", always->filename.c_str(), always->linenum); + wire->attributes["\\src"] = stringf("%s:%d.%d-%d.%d", always->filename.c_str(), always->location.first_line, always->location.first_column, always->location.last_line, always->location.last_column); chunk.wire = wire; chunk.offset = 0; @@ -470,13 +470,13 @@ struct AST_INTERNAL::ProcessGenerator case AST_CASE: { RTLIL::SwitchRule *sw = new RTLIL::SwitchRule; - sw->attributes["\\src"] = stringf("%s:%d", ast->filename.c_str(), ast->linenum); + sw->attributes["\\src"] = stringf("%s:%d.%d-%d.%d", ast->filename.c_str(), ast->location.first_line, ast->location.first_column, ast->location.last_line, ast->location.last_column); sw->signal = ast->children[0]->genWidthRTLIL(-1, &subst_rvalue_map.stdmap()); current_case->switches.push_back(sw); for (auto &attr : ast->attributes) { if (attr.second->type != AST_CONSTANT) - log_file_error(ast->filename, ast->linenum, "Attribute `%s' with non-constant value!\n", attr.first.c_str()); + log_file_error(ast->filename, ast->location.first_line, "Attribute `%s' with non-constant value!\n", attr.first.c_str()); sw->attributes[attr.first] = attr.second->asAttrConst(); } @@ -504,7 +504,7 @@ struct AST_INTERNAL::ProcessGenerator RTLIL::CaseRule *backup_case = current_case; current_case = new RTLIL::CaseRule; - current_case->attributes["\\src"] = stringf("%s:%d", child->filename.c_str(), child->linenum); + current_case->attributes["\\src"] = stringf("%s:%d.%d-%d.%d", child->filename.c_str(), child->location.first_line, child->location.first_column, child->location.last_line, child->location.last_column); last_generated_case = current_case; addChunkActions(current_case->actions, this_case_eq_ltemp, this_case_eq_rvalue); for (auto node : child->children) { @@ -554,16 +554,16 @@ struct AST_INTERNAL::ProcessGenerator break; case AST_WIRE: - log_file_error(ast->filename, ast->linenum, "Found reg declaration in block without label!\n"); + log_file_error(ast->filename, ast->location.first_line, "Found reg declaration in block without label!\n"); break; case AST_ASSIGN: - log_file_error(ast->filename, ast->linenum, "Found continous assignment in always/initial block!\n"); + log_file_error(ast->filename, ast->location.first_line, "Found continous assignment in always/initial block!\n"); break; case AST_PARAMETER: case AST_LOCALPARAM: - log_file_error(ast->filename, ast->linenum, "Found parameter declaration in block without label!\n"); + log_file_error(ast->filename, ast->location.first_line, "Found parameter declaration in block without label!\n"); break; case AST_NONE: @@ -614,7 +614,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_file_error(filename, linenum, "Failed to resolve identifier %s for width detection!\n", str.c_str()); + log_file_error(filename, location.first_line, "Failed to resolve identifier %s for width detection!\n", str.c_str()); if (id_ast->type == AST_PARAMETER || id_ast->type == AST_LOCALPARAM || id_ast->type == AST_ENUM_ITEM) { 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; @@ -624,7 +624,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_file_error(filename, linenum, "Failed to detect width for parameter %s!\n", str.c_str()); + log_file_error(filename, location.first_line, "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) { @@ -636,7 +636,7 @@ void AstNode::detectSignWidthWorker(int &width_hint, bool &sign_hint, bool *foun // log("---\n"); // id_ast->dumpAst(NULL, "decl> "); // dumpAst(NULL, "ref> "); - log_file_error(filename, linenum, "Failed to detect width of signal access `%s'!\n", str.c_str()); + log_file_error(filename, location.first_line, "Failed to detect width of signal access `%s'!\n", str.c_str()); } } else { this_width = id_ast->range_left - id_ast->range_right + 1; @@ -647,12 +647,12 @@ 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_file_error(filename, linenum, "Failed to detect width of memory access `%s'!\n", str.c_str()); + log_file_error(filename, location.first_line, "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; if (children.size() > 1) range = children[1]; } else - log_file_error(filename, linenum, "Failed to detect width for identifier %s!\n", str.c_str()); + log_file_error(filename, location.first_line, "Failed to detect width for identifier %s!\n", str.c_str()); if (range) { if (range->children.size() == 1) this_width = 1; @@ -662,7 +662,7 @@ void AstNode::detectSignWidthWorker(int &width_hint, bool &sign_hint, bool *foun while (left_at_zero_ast->simplify(true, true, false, 1, -1, false, false)) { } while (right_at_zero_ast->simplify(true, true, false, 1, -1, false, false)) { } if (left_at_zero_ast->type != AST_CONSTANT || right_at_zero_ast->type != AST_CONSTANT) - log_file_error(filename, linenum, "Unsupported expression on dynamic range select on signal `%s'!\n", str.c_str()); + log_file_error(filename, location.first_line, "Unsupported expression on dynamic range select on signal `%s'!\n", str.c_str()); this_width = abs(int(left_at_zero_ast->integer - right_at_zero_ast->integer)) + 1; delete left_at_zero_ast; delete right_at_zero_ast; @@ -678,7 +678,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_file_error(filename, linenum, "Left operand of tobits expression is not constant!\n"); + log_file_error(filename, location.first_line, "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; @@ -706,7 +706,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_file_error(filename, linenum, "Left operand of replicate expression is not constant!\n"); + log_file_error(filename, location.first_line, "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; @@ -780,7 +780,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_file_error(filename, linenum, "Failed to detect width of memory access `%s'!\n", str.c_str()); + log_file_error(filename, location.first_line, "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; @@ -790,7 +790,7 @@ 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_file_error(filename, linenum, "System function %s called with non-const argument!\n", + log_file_error(filename, location.first_line, "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))); } @@ -812,7 +812,7 @@ void AstNode::detectSignWidthWorker(int &width_hint, bool &sign_hint, bool *foun default: for (auto f : log_files) current_ast_mod->dumpAst(f, "verilog-ast> "); - log_file_error(filename, linenum, "Don't know how to detect sign and width for %s node!\n", type2str(type).c_str()); + log_file_error(filename, location.first_line, "Don't know how to detect sign and width for %s node!\n", type2str(type).c_str()); } if (*found_real) @@ -845,7 +845,6 @@ RTLIL::SigSpec AstNode::genRTLIL(int width_hint, bool sign_hint) std::string type_name; current_filename = filename; - set_line_num(linenum); switch (type) { @@ -874,7 +873,7 @@ RTLIL::SigSpec AstNode::genRTLIL(int width_hint, bool sign_hint) // This is used by the hierarchy pass to know when it can replace interface connection with the individual // signals. RTLIL::Wire *wire = current_module->addWire(str, 1); - wire->attributes["\\src"] = stringf("%s:%d", filename.c_str(), linenum); + wire->attributes["\\src"] = stringf("%s:%d.%d-%d.%d", filename.c_str(), location.first_line, location.first_column, location.last_line, location.last_column); wire->start_offset = 0; wire->port_id = port_id; wire->port_input = true; @@ -905,18 +904,18 @@ RTLIL::SigSpec AstNode::genRTLIL(int width_hint, bool sign_hint) if (flag_pwires) { if (GetSize(children) < 1 || children[0]->type != AST_CONSTANT) - log_file_error(filename, linenum, "Parameter `%s' with non-constant value!\n", str.c_str()); + log_file_error(filename, location.first_line, "Parameter `%s' with non-constant value!\n", str.c_str()); RTLIL::Const val = children[0]->bitsAsConst(); RTLIL::Wire *wire = current_module->addWire(str, GetSize(val)); current_module->connect(wire, val); - wire->attributes["\\src"] = stringf("%s:%d", filename.c_str(), linenum); + wire->attributes["\\src"] = stringf("%s:%d.%d-%d.%d", filename.c_str(), location.first_line, location.first_column, location.last_line, location.last_column); wire->attributes[type == AST_PARAMETER ? "\\parameter" : "\\localparam"] = 1; for (auto &attr : attributes) { if (attr.second->type != AST_CONSTANT) - log_file_error(filename, linenum, "Attribute `%s' with non-constant value!\n", attr.first.c_str()); + log_file_error(filename, location.first_line, "Attribute `%s' with non-constant value!\n", attr.first.c_str()); wire->attributes[attr.first] = attr.second->asAttrConst(); } } @@ -925,15 +924,15 @@ RTLIL::SigSpec AstNode::genRTLIL(int width_hint, bool sign_hint) // create an RTLIL::Wire for an AST_WIRE node case AST_WIRE: { if (current_module->wires_.count(str) != 0) - log_file_error(filename, linenum, "Re-definition of signal `%s'!\n", str.c_str()); + log_file_error(filename, location.first_line, "Re-definition of signal `%s'!\n", str.c_str()); if (!range_valid) - log_file_error(filename, linenum, "Signal `%s' with non-constant width!\n", str.c_str()); + log_file_error(filename, location.first_line, "Signal `%s' with non-constant width!\n", str.c_str()); if (!(range_left >= range_right || (range_left == -1 && range_right == 0))) - log_file_error(filename, linenum, "Signal `%s' with invalid width range %d!\n", str.c_str(), range_left - range_right + 1); + log_file_error(filename, location.first_line, "Signal `%s' with invalid width range %d!\n", str.c_str(), range_left - range_right + 1); RTLIL::Wire *wire = current_module->addWire(str, range_left - range_right + 1); - wire->attributes["\\src"] = stringf("%s:%d", filename.c_str(), linenum); + wire->attributes["\\src"] = stringf("%s:%d.%d-%d.%d", filename.c_str(), location.first_line, location.first_column, location.last_line, location.last_column); wire->start_offset = range_right; wire->port_id = port_id; wire->port_input = is_input; @@ -942,7 +941,7 @@ RTLIL::SigSpec AstNode::genRTLIL(int width_hint, bool sign_hint) for (auto &attr : attributes) { if (attr.second->type != AST_CONSTANT) - log_file_error(filename, linenum, "Attribute `%s' with non-constant value!\n", attr.first.c_str()); + log_file_error(filename, location.first_line, "Attribute `%s' with non-constant value!\n", attr.first.c_str()); wire->attributes[attr.first] = attr.second->asAttrConst(); } @@ -954,17 +953,17 @@ RTLIL::SigSpec AstNode::genRTLIL(int width_hint, bool sign_hint) // create an RTLIL::Memory for an AST_MEMORY node case AST_MEMORY: { if (current_module->memories.count(str) != 0) - log_file_error(filename, linenum, "Re-definition of memory `%s'!\n", str.c_str()); + log_file_error(filename, location.first_line, "Re-definition of memory `%s'!\n", str.c_str()); log_assert(children.size() >= 2); log_assert(children[0]->type == AST_RANGE); log_assert(children[1]->type == AST_RANGE); if (!children[0]->range_valid || !children[1]->range_valid) - log_file_error(filename, linenum, "Memory `%s' with non-constant width or size!\n", str.c_str()); + log_file_error(filename, location.first_line, "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); + memory->attributes["\\src"] = stringf("%s:%d.%d-%d.%d", filename.c_str(), location.first_line, location.first_column, location.last_line, location.last_column); memory->name = str; memory->width = children[0]->range_left - children[0]->range_right + 1; if (children[1]->range_right < children[1]->range_left) { @@ -978,7 +977,7 @@ RTLIL::SigSpec AstNode::genRTLIL(int width_hint, bool sign_hint) for (auto &attr : attributes) { if (attr.second->type != AST_CONSTANT) - log_file_error(filename, linenum, "Attribute `%s' with non-constant value!\n", attr.first.c_str()); + log_file_error(filename, location.first_line, "Attribute `%s' with non-constant value!\n", attr.first.c_str()); memory->attributes[attr.first] = attr.second->asAttrConst(); } } @@ -1001,7 +1000,7 @@ RTLIL::SigSpec AstNode::genRTLIL(int width_hint, bool sign_hint) } RTLIL::SigSpec sig = realAsConst(width_hint); - log_file_warning(filename, linenum, "converting real value %e to binary %s.\n", realvalue, log_signal(sig)); + log_file_warning(filename, location.first_line, "converting real value %e to binary %s.\n", realvalue, log_signal(sig)); return sig; } @@ -1019,16 +1018,16 @@ RTLIL::SigSpec AstNode::genRTLIL(int width_hint, bool sign_hint) if (id2ast && id2ast->type == AST_AUTOWIRE && current_module->wires_.count(str) == 0) { RTLIL::Wire *wire = current_module->addWire(str); - wire->attributes["\\src"] = stringf("%s:%d", filename.c_str(), linenum); + wire->attributes["\\src"] = stringf("%s:%d.%d-%d.%d", filename.c_str(), location.first_line, location.first_column, location.last_line, location.last_column); wire->name = str; if (flag_autowire) - log_file_warning(filename, linenum, "Identifier `%s' is implicitly declared.\n", str.c_str()); + log_file_warning(filename, location.first_line, "Identifier `%s' is implicitly declared.\n", str.c_str()); else - log_file_error(filename, linenum, "Identifier `%s' is implicitly declared and `default_nettype is set to none.\n", str.c_str()); + log_file_error(filename, location.first_line, "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 || id2ast->type == AST_ENUM_ITEM) { if (id2ast->children[0]->type != AST_CONSTANT) - log_file_error(filename, linenum, "Parameter %s does not evaluate to constant value!\n", str.c_str()); + log_file_error(filename, location.first_line, "Parameter %s does not evaluate to constant value!\n", str.c_str()); chunk = RTLIL::Const(id2ast->children[0]->bits); goto use_const_chunk; } @@ -1043,11 +1042,11 @@ RTLIL::SigSpec AstNode::genRTLIL(int width_hint, bool sign_hint) is_interface = true; } else { - log_file_error(filename, linenum, "Identifier `%s' doesn't map to any signal!\n", str.c_str()); + log_file_error(filename, location.first_line, "Identifier `%s' doesn't map to any signal!\n", str.c_str()); } if (id2ast->type == AST_MEMORY) - log_file_error(filename, linenum, "Identifier `%s' does map to an unexpanded memory!\n", str.c_str()); + log_file_error(filename, location.first_line, "Identifier `%s' does map to an unexpanded memory!\n", str.c_str()); // If identifier is an interface, create a RTLIL::SigSpec with a dummy wire with a attribute called 'is_interface' // This makes it possible for the hierarchy pass to see what are interface connections and then replace them @@ -1073,7 +1072,7 @@ RTLIL::SigSpec AstNode::genRTLIL(int width_hint, bool sign_hint) use_const_chunk: if (children.size() != 0) { if (children[0]->type != AST_RANGE) - log_file_error(filename, linenum, "Single range expected.\n"); + log_file_error(filename, location.first_line, "Single range expected.\n"); int source_width = id2ast->range_left - id2ast->range_right + 1; int source_offset = id2ast->range_right; if (!children[0]->range_valid) { @@ -1082,7 +1081,7 @@ RTLIL::SigSpec AstNode::genRTLIL(int width_hint, bool sign_hint) while (left_at_zero_ast->simplify(true, true, false, 1, -1, false, false)) { } while (right_at_zero_ast->simplify(true, true, false, 1, -1, false, false)) { } if (left_at_zero_ast->type != AST_CONSTANT || right_at_zero_ast->type != AST_CONSTANT) - log_file_error(filename, linenum, "Unsupported expression on dynamic range select on signal `%s'!\n", str.c_str()); + log_file_error(filename, location.first_line, "Unsupported expression on dynamic range select on signal `%s'!\n", str.c_str()); int width = abs(int(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()); @@ -1110,10 +1109,10 @@ 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_file_warning(filename, linenum, "Range select out of bounds on signal `%s': Setting result bit to undef.\n", + log_file_warning(filename, location.first_line, "Range select out of bounds on signal `%s': Setting result bit to undef.\n", str.c_str()); else - log_file_warning(filename, linenum, "Range select [%d:%d] out of bounds on signal `%s': Setting all %d result bits to undef.\n", + log_file_warning(filename, location.first_line, "Range select [%d:%d] out of bounds on signal `%s': Setting all %d result bits to undef.\n", children[0]->range_left, children[0]->range_right, str.c_str(), chunk.width); chunk = RTLIL::SigChunk(RTLIL::State::Sx, chunk.width); } else { @@ -1127,10 +1126,10 @@ RTLIL::SigSpec AstNode::genRTLIL(int width_hint, bool sign_hint) chunk.offset += add_undef_bits_lsb; } if (add_undef_bits_lsb) - log_file_warning(filename, linenum, "Range [%d:%d] select out of bounds on signal `%s': Setting %d LSB bits to undef.\n", + log_file_warning(filename, location.first_line, "Range [%d:%d] select out of bounds on signal `%s': Setting %d LSB bits to undef.\n", children[0]->range_left, children[0]->range_right, str.c_str(), add_undef_bits_lsb); if (add_undef_bits_msb) - log_file_warning(filename, linenum, "Range [%d:%d] select out of bounds on signal `%s': Setting %d MSB bits to undef.\n", + log_file_warning(filename, location.first_line, "Range [%d:%d] select out of bounds on signal `%s': Setting %d MSB bits to undef.\n", children[0]->range_left, children[0]->range_right, str.c_str(), add_undef_bits_msb); } } @@ -1170,7 +1169,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_file_error(filename, linenum, "Left operand of replicate expression is not constant!\n"); + log_file_error(filename, location.first_line, "Left operand of replicate expression is not constant!\n"); int count = left.as_int(); RTLIL::SigSpec sig; for (int i = 0; i < count; i++) @@ -1373,13 +1372,13 @@ RTLIL::SigSpec AstNode::genRTLIL(int width_hint, bool sign_hint) case AST_MEMRD: { std::stringstream sstr; - sstr << "$memrd$" << str << "$" << filename << ":" << linenum << "$" << (autoidx++); + sstr << "$memrd$" << str << "$" << filename << ":" << location.first_line << "$" << (autoidx++); RTLIL::Cell *cell = current_module->addCell(sstr.str(), "$memrd"); - cell->attributes["\\src"] = stringf("%s:%d", filename.c_str(), linenum); + cell->attributes["\\src"] = stringf("%s:%d", filename.c_str(), location.first_line); RTLIL::Wire *wire = current_module->addWire(cell->name.str() + "_DATA", current_module->memories[str]->width); - wire->attributes["\\src"] = stringf("%s:%d", filename.c_str(), linenum); + wire->attributes["\\src"] = stringf("%s:%d", filename.c_str(), location.first_line); int mem_width, mem_size, addr_bits; is_signed = id2ast->is_signed; @@ -1411,10 +1410,10 @@ RTLIL::SigSpec AstNode::genRTLIL(int width_hint, bool sign_hint) case AST_MEMINIT: { std::stringstream sstr; - sstr << (type == AST_MEMWR ? "$memwr$" : "$meminit$") << str << "$" << filename << ":" << linenum << "$" << (autoidx++); + sstr << (type == AST_MEMWR ? "$memwr$" : "$meminit$") << str << "$" << filename << ":" << location.first_line << "$" << (autoidx++); RTLIL::Cell *cell = current_module->addCell(sstr.str(), type == AST_MEMWR ? "$memwr" : "$meminit"); - cell->attributes["\\src"] = stringf("%s:%d", filename.c_str(), linenum); + cell->attributes["\\src"] = stringf("%s:%d.%d-%d.%d", filename.c_str(), location.first_line, location.first_column, location.last_line, location.last_column); int mem_width, mem_size, addr_bits; id2ast->meminfo(mem_width, mem_size, addr_bits); @@ -1422,7 +1421,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_file_error(filename, linenum, "Memory init with non-constant word count!\n"); + log_file_error(filename, location.first_line, "Memory init with non-constant word count!\n"); num_words = int(children[2]->asInt(false)); cell->parameters["\\WORDS"] = RTLIL::Const(num_words); } @@ -1474,18 +1473,18 @@ RTLIL::SigSpec AstNode::genRTLIL(int width_hint, bool sign_hint) IdString cellname; if (str.empty()) { std::stringstream sstr; - sstr << celltype << "$" << filename << ":" << linenum << "$" << (autoidx++); + sstr << celltype << "$" << filename << ":" << location.first_line << "$" << (autoidx++); cellname = sstr.str(); } else { cellname = str; } RTLIL::Cell *cell = current_module->addCell(cellname, celltype); - cell->attributes["\\src"] = stringf("%s:%d", filename.c_str(), linenum); + cell->attributes["\\src"] = stringf("%s:%d.%d-%d.%d", filename.c_str(), location.first_line, location.first_column, location.last_line, location.last_column); for (auto &attr : attributes) { if (attr.second->type != AST_CONSTANT) - log_file_error(filename, linenum, "Attribute `%s' with non-constant value!\n", attr.first.c_str()); + log_file_error(filename, location.first_line, "Attribute `%s' with non-constant value!\n", attr.first.c_str()); cell->attributes[attr.first] = attr.second->asAttrConst(); } @@ -1506,7 +1505,7 @@ RTLIL::SigSpec AstNode::genRTLIL(int width_hint, bool sign_hint) new_left.append(left[i]); new_right.append(right[i]); } - log_file_warning(filename, linenum, "Ignoring assignment to constant bits:\n" + log_file_warning(filename, location.first_line, "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)); @@ -1523,10 +1522,10 @@ 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_file_error(filename, linenum, "Re-definition of cell `%s'!\n", str.c_str()); + log_file_error(filename, location.first_line, "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); + cell->attributes["\\src"] = stringf("%s:%d.%d-%d.%d", filename.c_str(), location.first_line, location.first_column, location.last_line, location.last_column); // Set attribute 'module_not_derived' which will be cleared again after the hierarchy pass cell->set_bool_attribute("\\module_not_derived"); @@ -1542,7 +1541,7 @@ RTLIL::SigSpec AstNode::genRTLIL(int width_hint, bool sign_hint) int extra_const_flags = 0; IdString paraname = child->str.empty() ? stringf("$%d", ++para_counter) : child->str; if (child->children[0]->type == AST_REALVALUE) { - log_file_warning(filename, linenum, "Replacing floating point parameter %s.%s = %f with string.\n", + log_file_warning(filename, location.first_line, "Replacing floating point parameter %s.%s = %f with string.\n", log_id(cell), log_id(paraname), child->children[0]->realvalue); extra_const_flags = RTLIL::CONST_FLAG_REAL; auto strnode = AstNode::mkconst_str(stringf("%f", child->children[0]->realvalue)); @@ -1550,7 +1549,7 @@ RTLIL::SigSpec AstNode::genRTLIL(int width_hint, bool sign_hint) delete strnode; } if (child->children[0]->type != AST_CONSTANT) - log_file_error(filename, linenum, "Parameter %s.%s with non-constant value!\n", + log_file_error(filename, location.first_line, "Parameter %s.%s with non-constant value!\n", log_id(cell), log_id(paraname)); cell->parameters[paraname] = child->children[0]->asParaConst(); cell->parameters[paraname].flags |= extra_const_flags; @@ -1573,7 +1572,7 @@ RTLIL::SigSpec AstNode::genRTLIL(int width_hint, bool sign_hint) } for (auto &attr : attributes) { if (attr.second->type != AST_CONSTANT) - log_file_error(filename, linenum, "Attribute `%s' with non-constant value.\n", attr.first.c_str()); + log_file_error(filename, location.first_line, "Attribute `%s' with non-constant value.\n", attr.first.c_str()); cell->attributes[attr.first] = attr.second->asAttrConst(); } if (cell->type == "$specify2") { @@ -1581,7 +1580,7 @@ RTLIL::SigSpec AstNode::genRTLIL(int width_hint, bool sign_hint) int dst_width = GetSize(cell->getPort("\\DST")); bool full = cell->getParam("\\FULL").as_bool(); if (!full && src_width != dst_width) - log_file_error(filename, linenum, "Parallel specify SRC width does not match DST width.\n"); + log_file_error(filename, location.first_line, "Parallel specify SRC width does not match DST width.\n"); cell->setParam("\\SRC_WIDTH", Const(src_width)); cell->setParam("\\DST_WIDTH", Const(dst_width)); } @@ -1589,7 +1588,7 @@ RTLIL::SigSpec AstNode::genRTLIL(int width_hint, bool sign_hint) int dat_width = GetSize(cell->getPort("\\DAT")); int dst_width = GetSize(cell->getPort("\\DST")); if (dat_width != dst_width) - log_file_error(filename, linenum, "Specify DAT width does not match DST width.\n"); + log_file_error(filename, location.first_line, "Specify DAT width does not match DST width.\n"); int src_width = GetSize(cell->getPort("\\SRC")); cell->setParam("\\SRC_WIDTH", Const(src_width)); cell->setParam("\\DST_WIDTH", Const(dst_width)); @@ -1621,30 +1620,30 @@ RTLIL::SigSpec AstNode::genRTLIL(int width_hint, bool sign_hint) int sz = children.size(); if (str == "$info") { if (sz > 0) - log_file_info(filename, linenum, "%s.\n", children[0]->str.c_str()); + log_file_info(filename, location.first_line, "%s.\n", children[0]->str.c_str()); else - log_file_info(filename, linenum, "\n"); + log_file_info(filename, location.first_line, "\n"); } else if (str == "$warning") { if (sz > 0) - log_file_warning(filename, linenum, "%s.\n", children[0]->str.c_str()); + log_file_warning(filename, location.first_line, "%s.\n", children[0]->str.c_str()); else - log_file_warning(filename, linenum, "\n"); + log_file_warning(filename, location.first_line, "\n"); } else if (str == "$error") { if (sz > 0) - log_file_error(filename, linenum, "%s.\n", children[0]->str.c_str()); + log_file_error(filename, location.first_line, "%s.\n", children[0]->str.c_str()); else - log_file_error(filename, linenum, "\n"); + log_file_error(filename, location.first_line, "\n"); } else if (str == "$fatal") { // TODO: 1st parameter, if exists, is 0,1 or 2, and passed to $finish() // if no parameter is given, default value is 1 // dollar_finish(sz ? children[0] : 1); // perhaps create & use log_file_fatal() if (sz > 0) - log_file_error(filename, linenum, "FATAL: %s.\n", children[0]->str.c_str()); + log_file_error(filename, location.first_line, "FATAL: %s.\n", children[0]->str.c_str()); else - log_file_error(filename, linenum, "FATAL.\n"); + log_file_error(filename, location.first_line, "FATAL.\n"); } else { - log_file_error(filename, linenum, "Unknown elabortoon system task '%s'.\n", str.c_str()); + log_file_error(filename, location.first_line, "Unknown elabortoon system task '%s'.\n", str.c_str()); } } break; @@ -1655,32 +1654,32 @@ RTLIL::SigSpec AstNode::genRTLIL(int width_hint, bool sign_hint) int width = width_hint; if (GetSize(children) > 1) - log_file_error(filename, linenum, "System function %s got %d arguments, expected 1 or 0.\n", + log_file_error(filename, location.first_line, "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_file_error(filename, linenum, "System function %s called with non-const argument!\n", + log_file_error(filename, location.first_line, "System function %s called with non-const argument!\n", RTLIL::unescape_id(str).c_str()); width = children[0]->asInt(true); } if (width <= 0) - log_file_error(filename, linenum, "Failed to detect width of %s!\n", RTLIL::unescape_id(str).c_str()); + log_file_error(filename, location.first_line, "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); + cell->attributes["\\src"] = stringf("%s:%d.%d-%d.%d", filename.c_str(), location.first_line, location.first_column, location.last_line, location.last_column); cell->parameters["\\WIDTH"] = width; if (attributes.count("\\reg")) { auto &attr = attributes.at("\\reg"); if (attr->type != AST_CONSTANT) - log_file_error(filename, linenum, "Attribute `reg' with non-constant value!\n"); + log_file_error(filename, location.first_line, "Attribute `reg' with non-constant value!\n"); cell->attributes["\\reg"] = attr->asAttrConst(); } Wire *wire = current_module->addWire(myid + "_wire", width); - wire->attributes["\\src"] = stringf("%s:%d", filename.c_str(), linenum); + wire->attributes["\\src"] = stringf("%s:%d.%d-%d.%d", filename.c_str(), location.first_line, location.first_column, location.last_line, location.last_column); cell->setPort("\\Y", wire); is_signed = sign_hint; @@ -1693,7 +1692,7 @@ RTLIL::SigSpec AstNode::genRTLIL(int width_hint, bool sign_hint) for (auto f : log_files) current_ast_mod->dumpAst(f, "verilog-ast> "); type_name = type2str(type); - log_file_error(filename, linenum, "Don't know how to generate RTLIL code for %s node!\n", type_name.c_str()); + log_file_error(filename, location.first_line, "Don't know how to generate RTLIL code for %s node!\n", type_name.c_str()); } return RTLIL::SigSpec(); diff --git a/frontends/ast/simplify.cc b/frontends/ast/simplify.cc index 9a8150ebf..04c02d893 100644 --- a/frontends/ast/simplify.cc +++ b/frontends/ast/simplify.cc @@ -53,7 +53,7 @@ std::string AstNode::process_format_str(const std::string &sformat, int next_arg { // If there's no next character, that's a problem if (i+1 >= sformat.length()) - log_file_error(filename, linenum, "System task `%s' called with `%%' at end of string.\n", str.c_str()); + log_file_error(filename, location.first_line, "System task `%s' called with `%%' at end of string.\n", str.c_str()); char cformat = sformat[++i]; @@ -77,13 +77,13 @@ std::string AstNode::process_format_str(const std::string &sformat, int next_arg case 'x': case 'X': if (next_arg >= GetSize(children)) - log_file_error(filename, linenum, "Missing argument for %%%c format specifier in system task `%s'.\n", + log_file_error(filename, location.first_line, "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_file_error(filename, linenum, "Failed to evaluate system task `%s' with non-constant argument.\n", str.c_str()); + log_file_error(filename, location.first_line, "Failed to evaluate system task `%s' with non-constant argument.\n", str.c_str()); break; case 'm': @@ -91,7 +91,7 @@ std::string AstNode::process_format_str(const std::string &sformat, int next_arg break; default: - log_file_error(filename, linenum, "System task `%s' called with invalid/unsupported format specifier.\n", str.c_str()); + log_file_error(filename, location.first_line, "System task `%s' called with invalid/unsupported format specifier.\n", str.c_str()); break; } @@ -159,7 +159,7 @@ bool AstNode::simplify(bool const_fold, bool at_zero, bool in_lvalue, int stage, #if 0 log("-------------\n"); - log("AST simplify[%d] depth %d at %s:%d on %s %p:\n", stage, recursion_counter, filename.c_str(), linenum, type2str(type).c_str(), this); + log("AST simplify[%d] depth %d at %s:%d on %s %p:\n", stage, recursion_counter, filename.c_str(), location.first_line, type2str(type).c_str(), this); log("const_fold=%d, at_zero=%d, in_lvalue=%d, stage=%d, width_hint=%d, sign_hint=%d, in_param=%d\n", int(const_fold), int(at_zero), int(in_lvalue), int(stage), int(width_hint), int(sign_hint), int(in_param)); // dumpAst(NULL, "> "); @@ -251,7 +251,7 @@ bool AstNode::simplify(bool const_fold, bool at_zero, bool in_lvalue, int stage, if (it.first != ID(mem2reg)) reg->attributes.emplace(it.first, it.second->clone()); reg->filename = node->filename; - reg->linenum = node->linenum; + reg->location = node->location; children.push_back(reg); while (reg->simplify(true, false, false, 1, -1, false, false)) { } } @@ -273,7 +273,6 @@ bool AstNode::simplify(bool const_fold, bool at_zero, bool in_lvalue, int stage, } current_filename = filename; - set_line_num(linenum); // we do not look inside a task or function // (but as soon as a task or function is instantiated we process the generated AST as usual) @@ -286,13 +285,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_file_warning(filename, linenum, "Ignoring call to system %s %s.\n", type == AST_FCALL ? "function" : "task", str.c_str()); + log_file_warning(filename, location.first_line, "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_file_warning(filename, linenum, "System task `%s' outside initial block is unsupported.\n", str.c_str()); + log_file_warning(filename, location.first_line, "System task `%s' outside initial block is unsupported.\n", str.c_str()); delete_children(); str = std::string(); } @@ -304,14 +303,14 @@ bool AstNode::simplify(bool const_fold, bool at_zero, bool in_lvalue, int stage, { int nargs = GetSize(children); if (nargs < 1) - log_file_error(filename, linenum, "System task `%s' got %d arguments, expected >= 1.\n", + log_file_error(filename, location.first_line, "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_file_error(filename, linenum, "Failed to evaluate system task `%s' with non-constant 1st argument.\n", str.c_str()); + log_file_error(filename, location.first_line, "Failed to evaluate system task `%s' with non-constant 1st argument.\n", str.c_str()); std::string sformat = node_string->bitsAsConst().decode_string(); std::string sout = process_format_str(sformat, 1, stage, width_hint, sign_hint); // Finally, print the message (only include a \n for $display, not for $write) @@ -405,7 +404,7 @@ bool AstNode::simplify(bool const_fold, bool at_zero, bool in_lvalue, int stage, continue; wires_are_incompatible: if (stage > 1) - log_file_error(filename, linenum, "Incompatible re-declaration of wire %s.\n", node->str.c_str()); + log_file_error(filename, location.first_line, "Incompatible re-declaration of wire %s.\n", node->str.c_str()); continue; } this_wire_scope[node->str] = node; @@ -451,7 +450,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_file_error(filename, linenum, "Invalid nesting of always blocks and/or initializations.\n"); + log_file_error(filename, location.first_line, "Invalid nesting of always blocks and/or initializations.\n"); current_always = this; current_always_clocked = false; @@ -494,7 +493,7 @@ bool AstNode::simplify(bool const_fold, bool at_zero, bool in_lvalue, int stage, 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); + log_warning("wire '%s' is assigned in a block at %s:%d.%d-%d.%d.\n", children[0]->str.c_str(), filename.c_str(), location.first_line, location.first_column, location.last_line, location.last_column); if (type == AST_ASSIGN && children[0]->id2ast->is_reg) { bool is_rand_reg = false; if (children[1]->type == AST_FCALL) { @@ -508,7 +507,7 @@ bool AstNode::simplify(bool const_fold, bool at_zero, bool in_lvalue, int stage, is_rand_reg = true; } if (!is_rand_reg) - log_warning("reg '%s' is assigned in a continuous assignment at %s:%d.\n", children[0]->str.c_str(), filename.c_str(), linenum); + log_warning("reg '%s' is assigned in a continuous assignment at %s:%d.%d-%d.%d.\n", children[0]->str.c_str(), filename.c_str(), location.first_line, location.first_column, location.last_line, location.last_column); } children[0]->was_checked = true; } @@ -535,7 +534,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_file_error(filename, linenum, "Non-constant width range on parameter decl.\n"); + log_file_error(filename, location.first_line, "Non-constant width range on parameter decl.\n"); width_hint = max(width_hint, children[1]->range_left - children[1]->range_right + 1); } break; @@ -547,7 +546,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, in_param)) did_something = true; if (!children[1]->range_valid) - log_file_error(filename, linenum, "Non-constant width range on enum item decl.\n"); + log_file_error(filename, location.first_line, "Non-constant width range on enum item decl.\n"); width_hint = max(width_hint, children[1]->range_left - children[1]->range_right + 1); } break; @@ -786,7 +785,6 @@ bool AstNode::simplify(bool const_fold, bool at_zero, bool in_lvalue, int stage, } current_filename = filename; - set_line_num(linenum); if (type == AST_MODULE) current_scope.clear(); @@ -795,7 +793,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_file_error(filename, linenum, "Module name in defparam contains non-constant expressions!\n"); + log_file_error(filename, location.first_line, "Module name in defparam contains non-constant expressions!\n"); string modname, paramname = children[0]->str; @@ -812,12 +810,12 @@ bool AstNode::simplify(bool const_fold, bool at_zero, bool in_lvalue, int stage, } if (pos == std::string::npos) - log_file_error(filename, linenum, "Can't find object for defparam `%s`!\n", RTLIL::unescape_id(paramname).c_str()); + log_file_error(filename, location.first_line, "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_file_error(filename, linenum, "Defparam argument `%s . %s` does not match a cell!\n", + log_file_error(filename, location.first_line, "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); @@ -843,10 +841,10 @@ bool AstNode::simplify(bool const_fold, bool at_zero, bool in_lvalue, int stage, log_assert(children.size() >= 1); log_assert(children[0]->type == AST_WIRETYPE); if (!current_scope.count(children[0]->str)) - log_file_error(filename, linenum, "Unknown identifier `%s' used as type name\n", children[0]->str.c_str()); + log_file_error(filename, location.first_line, "Unknown identifier `%s' used as type name\n", children[0]->str.c_str()); AstNode *resolved_type = current_scope.at(children[0]->str); if (resolved_type->type != AST_TYPEDEF) - log_file_error(filename, linenum, "`%s' does not name a type\n", children[0]->str.c_str()); + log_file_error(filename, location.first_line, "`%s' does not name a type\n", children[0]->str.c_str()); log_assert(resolved_type->children.size() == 1); AstNode *templ = resolved_type->children[0]; // Remove type reference @@ -949,10 +947,10 @@ bool AstNode::simplify(bool const_fold, bool at_zero, bool in_lvalue, int stage, log_assert(children.size() == 2); log_assert(children[1]->type == AST_WIRETYPE); if (!current_scope.count(children[1]->str)) - log_file_error(filename, linenum, "Unknown identifier `%s' used as type name\n", children[1]->str.c_str()); + log_file_error(filename, location.first_line, "Unknown identifier `%s' used as type name\n", children[1]->str.c_str()); AstNode *resolved_type = current_scope.at(children[1]->str); if (resolved_type->type != AST_TYPEDEF) - log_file_error(filename, linenum, "`%s' does not name a type\n", children[1]->str.c_str()); + log_file_error(filename, location.first_line, "`%s' does not name a type\n", children[1]->str.c_str()); log_assert(resolved_type->children.size() == 1); AstNode *templ = resolved_type->children[0]; delete children[1]; @@ -962,7 +960,7 @@ bool AstNode::simplify(bool const_fold, bool at_zero, bool in_lvalue, int stage, while(templ->simplify(const_fold, at_zero, in_lvalue, stage, width_hint, sign_hint, in_param)) {}; if (templ->type == AST_MEMORY) - log_file_error(filename, linenum, "unpacked array type `%s' cannot be used for a parameter\n", children[1]->str.c_str()); + log_file_error(filename, location.first_line, "unpacked array type `%s' cannot be used for a parameter\n", children[1]->str.c_str()); is_signed = templ->is_signed; is_string = templ->is_string; is_custom_type = templ->is_custom_type; @@ -983,7 +981,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_file_error(filename, linenum, "Index in generate block prefix syntax is not constant!\n"); + log_file_error(filename, location.first_line, "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); @@ -999,9 +997,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_file_error(filename, linenum, "Left operand of to_bits expression is not constant!\n"); + log_file_error(filename, location.first_line, "Left operand of to_bits expression is not constant!\n"); if (children[1]->type != AST_CONSTANT) - log_file_error(filename, linenum, "Right operand of to_bits expression is not constant!\n"); + log_file_error(filename, location.first_line, "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; @@ -1065,7 +1063,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_file_error(filename, linenum, "Non-constant range on memory decl.\n"); + log_file_error(filename, location.first_line, "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(); @@ -1083,7 +1081,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_file_error(filename, linenum, "Insufficient number of array indices for %s.\n", log_id(str)); + log_file_error(filename, location.first_line, "Insufficient number of array indices for %s.\n", log_id(str)); AstNode *new_index_expr = children[0]->children[i]->children.at(0)->clone(); @@ -1112,11 +1110,11 @@ bool AstNode::simplify(bool const_fold, bool at_zero, bool in_lvalue, int stage, if (type == AST_PARAMETER || type == AST_LOCALPARAM || type == AST_ENUM_ITEM) { if (children.size() > 1 && children[1]->type == AST_RANGE) { if (!children[1]->range_valid) - log_file_error(filename, linenum, "Non-constant width range on parameter decl.\n"); + log_file_error(filename, location.first_line, "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_file_warning(filename, linenum, "converting real value %e to binary %s.\n", + log_file_warning(filename, location.first_line, "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); @@ -1190,7 +1188,7 @@ bool AstNode::simplify(bool const_fold, bool at_zero, bool in_lvalue, int stage, current_scope[str] = auto_wire; did_something = true; } else { - log_file_error(filename, linenum, "Identifier `%s' is implicitly declared and `default_nettype is set to none.\n", str.c_str()); + log_file_error(filename, location.first_line, "Identifier `%s' is implicitly declared and `default_nettype is set to none.\n", str.c_str()); } } if (id2ast != current_scope[str]) { @@ -1203,7 +1201,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_file_error(filename, linenum, "Invalid bit-select on memory access!\n"); + log_file_error(filename, location.first_line, "Invalid bit-select on memory access!\n"); int mem_width, mem_size, addr_bits; id2ast->meminfo(mem_width, mem_size, addr_bits); @@ -1215,7 +1213,7 @@ bool AstNode::simplify(bool const_fold, bool at_zero, bool in_lvalue, int stage, std::swap(data_range_left, data_range_right); std::stringstream sstr; - sstr << "$mem2bits$" << str << "$" << filename << ":" << linenum << "$" << (autoidx++); + sstr << "$mem2bits$" << str << "$" << filename << ":" << location.first_line << "$" << (autoidx++); std::string wire_id = sstr.str(); AstNode *wire = new AstNode(AST_WIRE, new AstNode(AST_RANGE, mkconst_int(data_range_left, true), mkconst_int(data_range_right, true))); @@ -1256,7 +1254,7 @@ bool AstNode::simplify(bool const_fold, bool at_zero, bool in_lvalue, int stage, } if (type == AST_WHILE) - log_file_error(filename, linenum, "While loops are only allowed in constant functions!\n"); + log_file_error(filename, location.first_line, "While loops are only allowed in constant functions!\n"); if (type == AST_REPEAT) { @@ -1267,7 +1265,7 @@ bool AstNode::simplify(bool const_fold, bool at_zero, bool in_lvalue, int stage, while (count->simplify(true, false, false, stage, 32, true, false)) { } if (count->type != AST_CONSTANT) - log_file_error(filename, linenum, "Repeat loops outside must have constant repeat counts!\n"); + log_file_error(filename, location.first_line, "Repeat loops outside must have constant repeat counts!\n"); // convert to a block with the body repeated n times type = AST_BLOCK; @@ -1293,24 +1291,24 @@ 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_file_error(filename, linenum, "Unsupported 1st expression of generate for-loop!\n"); + log_file_error(filename, location.first_line, "Unsupported 1st expression of generate for-loop!\n"); if (next_ast->type != AST_ASSIGN_EQ) - log_file_error(filename, linenum, "Unsupported 3rd expression of generate for-loop!\n"); + log_file_error(filename, location.first_line, "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_file_error(filename, linenum, "Left hand side of 1st expression of generate for-loop is not a gen var!\n"); + log_file_error(filename, location.first_line, "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_file_error(filename, linenum, "Left hand side of 3rd expression of generate for-loop is not a gen var!\n"); + log_file_error(filename, location.first_line, "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_file_error(filename, linenum, "Left hand side of 1st expression of generate for-loop is not a register!\n"); + log_file_error(filename, location.first_line, "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_file_error(filename, linenum, "Left hand side of 3rd expression of generate for-loop is not a register!\n"); + log_file_error(filename, location.first_line, "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_file_error(filename, linenum, "Incompatible left-hand sides in 1st and 3rd expression of generate for-loop!\n"); + log_file_error(filename, location.first_line, "Incompatible left-hand sides in 1st and 3rd expression of generate for-loop!\n"); // eval 1st expression AstNode *varbuf = init_ast->children[1]->clone(); @@ -1322,7 +1320,7 @@ bool AstNode::simplify(bool const_fold, bool at_zero, bool in_lvalue, int stage, } if (varbuf->type != AST_CONSTANT) - log_file_error(filename, linenum, "Right hand side of 1st expression of generate for-loop is not constant!\n"); + log_file_error(filename, location.first_line, "Right hand side of 1st expression of generate for-loop is not constant!\n"); auto resolved = current_scope.at(init_ast->children[0]->str); if (resolved->range_valid) { @@ -1363,7 +1361,7 @@ bool AstNode::simplify(bool const_fold, bool at_zero, bool in_lvalue, int stage, } if (buf->type != AST_CONSTANT) - log_file_error(filename, linenum, "2nd expression of generate for-loop is not constant!\n"); + log_file_error(filename, location.first_line, "2nd expression of generate for-loop is not constant!\n"); if (buf->integer == 0) { delete buf; @@ -1379,7 +1377,7 @@ bool AstNode::simplify(bool const_fold, bool at_zero, bool in_lvalue, int stage, buf = new AstNode(AST_GENBLOCK, body_ast->clone()); if (buf->str.empty()) { std::stringstream sstr; - sstr << "$genblock$" << filename << ":" << linenum << "$" << (autoidx++); + sstr << "$genblock$" << filename << ":" << location.first_line << "$" << (autoidx++); buf->str = sstr.str(); } std::map<std::string, std::string> name_map; @@ -1409,7 +1407,7 @@ bool AstNode::simplify(bool const_fold, bool at_zero, bool in_lvalue, int stage, } if (buf->type != AST_CONSTANT) - log_file_error(filename, linenum, "Right hand side of 3rd expression of generate for-loop is not constant (%s)!\n", type2str(buf->type).c_str()); + log_file_error(filename, location.first_line, "Right hand side of 3rd expression of generate for-loop is not constant (%s)!\n", type2str(buf->type).c_str()); delete varbuf->children[0]; varbuf->children[0] = buf; @@ -1433,7 +1431,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 || children[i]->type == AST_TYPEDEF) - log_file_error(children[i]->filename, children[i]->linenum, "Local declaration in unnamed block is an unsupported SystemVerilog feature!\n"); + log_file_error(children[i]->filename, children[i]->location.first_line, "Local declaration in unnamed block is an unsupported SystemVerilog feature!\n"); } // transform block with name @@ -1481,7 +1479,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_file_error(filename, linenum, "Condition for generate if is not constant!\n"); + log_file_error(filename, location.first_line, "Condition for generate if is not constant!\n"); } if (buf->asBool() != 0) { delete buf; @@ -1522,7 +1520,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_file_error(filename, linenum, "Condition for generate case is not constant!\n"); + log_file_error(filename, location.first_line, "Condition for generate case is not constant!\n"); } bool ref_signed = buf->is_signed; @@ -1556,7 +1554,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_file_error(filename, linenum, "Expression in generate case is not constant!\n"); + log_file_error(filename, location.first_line, "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(); @@ -1597,7 +1595,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_file_error(filename, linenum, "Non-constant array range on cell array.\n"); + log_file_error(filename, location.first_line, "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; @@ -1608,7 +1606,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_file_error(filename, linenum, "Cell arrays of primitives are currently not supported.\n"); + log_file_error(filename, location.first_line, "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()); @@ -1622,7 +1620,7 @@ bool AstNode::simplify(bool const_fold, bool at_zero, bool in_lvalue, int stage, if (type == AST_PRIMITIVE) { if (children.size() < 2) - log_file_error(filename, linenum, "Insufficient number of arguments for primitive `%s'!\n", str.c_str()); + log_file_error(filename, location.first_line, "Insufficient number of arguments for primitive `%s'!\n", str.c_str()); std::vector<AstNode*> children_list; for (auto child : children) { @@ -1637,7 +1635,7 @@ 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_file_error(filename, linenum, "Invalid number of arguments for primitive `%s'!\n", str.c_str()); + log_file_error(filename, location.first_line, "Invalid number of arguments for primitive `%s'!\n", str.c_str()); std::vector<RTLIL::State> z_const(1, RTLIL::State::Sz); @@ -1724,7 +1722,7 @@ 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_file_error(filename, linenum, "Unsupported expression on dynamic range select on signal `%s'!\n", str.c_str()); + log_file_error(filename, location.first_line, "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; @@ -1746,7 +1744,7 @@ skip_dynamic_range_lvalue_expansion:; if (stage > 1 && (type == AST_ASSERT || type == AST_ASSUME || type == AST_LIVE || type == AST_FAIR || type == AST_COVER) && current_block != NULL) { std::stringstream sstr; - sstr << "$formal$" << filename << ":" << linenum << "$" << (autoidx++); + sstr << "$formal$" << filename << ":" << location.first_line << "$" << (autoidx++); std::string id_check = sstr.str() + "_CHECK", id_en = sstr.str() + "_EN"; AstNode *wire_check = new AstNode(AST_WIRE); @@ -1854,7 +1852,7 @@ skip_dynamic_range_lvalue_expansion:; newNode = new AstNode(AST_BLOCK); AstNode *wire_tmp = new AstNode(AST_WIRE, new AstNode(AST_RANGE, mkconst_int(width_hint-1, true), mkconst_int(0, true))); - wire_tmp->str = stringf("$splitcmplxassign$%s:%d$%d", filename.c_str(), linenum, autoidx++); + wire_tmp->str = stringf("$splitcmplxassign$%s:%d$%d", filename.c_str(), location.first_line, autoidx++); current_ast_mod->children.push_back(wire_tmp); current_scope[wire_tmp->str] = wire_tmp; wire_tmp->attributes["\\nosync"] = AstNode::mkconst_int(1, false); @@ -1892,7 +1890,7 @@ skip_dynamic_range_lvalue_expansion:; (children[0]->children.size() == 1 || children[0]->children.size() == 2) && children[0]->children[0]->type == AST_RANGE) { std::stringstream sstr; - sstr << "$memwr$" << children[0]->str << "$" << filename << ":" << linenum << "$" << (autoidx++); + sstr << "$memwr$" << children[0]->str << "$" << filename << ":" << location.first_line << "$" << (autoidx++); std::string id_addr = sstr.str() + "_ADDR", id_data = sstr.str() + "_DATA", id_en = sstr.str() + "_EN"; int mem_width, mem_size, addr_bits; @@ -2003,7 +2001,7 @@ 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_file_error(filename, linenum, "Unsupported expression on dynamic range select on signal `%s'!\n", str.c_str()); + log_file_error(filename, location.first_line, "Unsupported expression on dynamic range select on signal `%s'!\n", str.c_str()); int width = abs(int(left_at_zero_ast->integer - right_at_zero_ast->integer)) + 1; assign_data = new AstNode(AST_ASSIGN_LE, new AstNode(AST_IDENTIFIER), @@ -2099,11 +2097,11 @@ skip_dynamic_range_lvalue_expansion:; int num_steps = 1; if (GetSize(children) != 1 && GetSize(children) != 2) - log_file_error(filename, linenum, "System function %s got %d arguments, expected 1 or 2.\n", + log_file_error(filename, location.first_line, "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_file_error(filename, linenum, "System function %s is only allowed in clocked blocks.\n", + log_file_error(filename, location.first_line, "System function %s is only allowed in clocked blocks.\n", RTLIL::unescape_id(str).c_str()); if (GetSize(children) == 2) @@ -2111,7 +2109,7 @@ skip_dynamic_range_lvalue_expansion:; AstNode *buf = children[1]->clone(); while (buf->simplify(true, false, false, stage, -1, false, false)) { } if (buf->type != AST_CONSTANT) - log_file_error(filename, linenum, "Failed to evaluate system function `%s' with non-constant value.\n", str.c_str()); + log_file_error(filename, location.first_line, "Failed to evaluate system function `%s' with non-constant value.\n", str.c_str()); num_steps = buf->asInt(true); delete buf; @@ -2138,7 +2136,7 @@ skip_dynamic_range_lvalue_expansion:; AstNode *reg = new AstNode(AST_WIRE, new AstNode(AST_RANGE, mkconst_int(width_hint-1, true), mkconst_int(0, true))); - reg->str = stringf("$past$%s:%d$%d$%d", filename.c_str(), linenum, myidx, i); + reg->str = stringf("$past$%s:%d$%d$%d", filename.c_str(), location.first_line, myidx, i); reg->is_reg = true; current_ast_mod->children.push_back(reg); @@ -2173,11 +2171,11 @@ skip_dynamic_range_lvalue_expansion:; if (str == "\\$stable" || str == "\\$rose" || str == "\\$fell" || str == "\\$changed") { if (GetSize(children) != 1) - log_file_error(filename, linenum, "System function %s got %d arguments, expected 1.\n", + log_file_error(filename, location.first_line, "System function %s got %d arguments, expected 1.\n", RTLIL::unescape_id(str).c_str(), int(children.size())); if (!current_always_clocked) - log_file_error(filename, linenum, "System function %s is only allowed in clocked blocks.\n", + log_file_error(filename, location.first_line, "System function %s is only allowed in clocked blocks.\n", RTLIL::unescape_id(str).c_str()); AstNode *present = children.at(0)->clone(); @@ -2215,13 +2213,13 @@ skip_dynamic_range_lvalue_expansion:; if (str == "\\$clog2") { if (children.size() != 1) - log_file_error(filename, linenum, "System function %s got %d arguments, expected 1.\n", + log_file_error(filename, location.first_line, "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_file_error(filename, linenum, "Failed to evaluate system function `%s' with non-constant value.\n", str.c_str()); + log_file_error(filename, location.first_line, "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()) @@ -2240,11 +2238,11 @@ skip_dynamic_range_lvalue_expansion:; if (str == "\\$size" || str == "\\$bits") { if (str == "\\$bits" && children.size() != 1) - log_file_error(filename, linenum, "System function %s got %d arguments, expected 1.\n", + log_file_error(filename, location.first_line, "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_file_error(filename, linenum, "System function %s got %d arguments, expected 1 or 2.\n", + log_file_error(filename, location.first_line, "System function %s got %d arguments, expected 1 or 2.\n", RTLIL::unescape_id(str).c_str(), int(children.size())); int dim = 1; @@ -2268,7 +2266,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_file_error(filename, linenum, "Failed to resolve identifier %s for width detection!\n", buf->str.c_str()); + log_file_error(filename, location.first_line, "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 @@ -2276,15 +2274,15 @@ skip_dynamic_range_lvalue_expansion:; if (str == "\\$bits") { if (mem_range->type == AST_RANGE) { if (!mem_range->range_valid) - log_file_error(filename, linenum, "Failed to detect width of memory access `%s'!\n", buf->str.c_str()); + log_file_error(filename, location.first_line, "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_file_error(filename, linenum, "Unknown memory depth AST type in `%s'!\n", buf->str.c_str()); + log_file_error(filename, location.first_line, "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_file_error(filename, linenum, "Failed to detect width of memory access `%s'!\n", buf->str.c_str()); + log_file_error(filename, location.first_line, "Failed to detect width of memory access `%s'!\n", buf->str.c_str()); int dims; if (id_ast->multirange_dimensions.empty()) dims = 1; @@ -2295,9 +2293,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_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); + log_file_error(filename, location.first_line, "Dimension %d out of range in `%s', as it only has dimensions 1..%d!\n", dim, buf->str.c_str(), dims+1); } else - log_file_error(filename, linenum, "Unknown memory depth AST type in `%s'!\n", buf->str.c_str()); + log_file_error(filename, location.first_line, "Unknown memory depth AST type in `%s'!\n", buf->str.c_str()); } } } @@ -2318,18 +2316,18 @@ skip_dynamic_range_lvalue_expansion:; if (func_with_two_arguments) { if (children.size() != 2) - log_file_error(filename, linenum, "System function %s got %d arguments, expected 2.\n", + log_file_error(filename, location.first_line, "System function %s got %d arguments, expected 2.\n", RTLIL::unescape_id(str).c_str(), int(children.size())); } else { if (children.size() != 1) - log_file_error(filename, linenum, "System function %s got %d arguments, expected 1.\n", + log_file_error(filename, location.first_line, "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_file_error(filename, linenum, "Failed to evaluate system function `%s' with non-constant argument.\n", + log_file_error(filename, location.first_line, "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; @@ -2340,7 +2338,7 @@ 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_file_error(filename, linenum, "Failed to evaluate system function `%s' with non-constant argument.\n", + log_file_error(filename, location.first_line, "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; @@ -2383,7 +2381,7 @@ skip_dynamic_range_lvalue_expansion:; 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_file_error(filename, linenum, "Failed to evaluate system function `%s' with non-constant 1st argument.\n", str.c_str()); + log_file_error(filename, location.first_line, "Failed to evaluate system function `%s' with non-constant 1st argument.\n", str.c_str()); std::string sformat = node_string->bitsAsConst().decode_string(); std::string sout = process_format_str(sformat, 1, stage, width_hint, sign_hint); newNode = AstNode::mkconst_str(sout); @@ -2404,14 +2402,14 @@ skip_dynamic_range_lvalue_expansion:; for (int i = 2; i < GetSize(dpi_decl->children); i++) { if (i-2 >= GetSize(children)) - log_file_error(filename, linenum, "Insufficient number of arguments in DPI function call.\n"); + log_file_error(filename, location.first_line, "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_file_error(filename, linenum, "Failed to evaluate DPI function with non-constant argument.\n"); + log_file_error(filename, location.first_line, "Failed to evaluate DPI function with non-constant argument.\n"); } newNode = dpi_call(rtype, fname, argtypes, args); @@ -2423,7 +2421,7 @@ skip_dynamic_range_lvalue_expansion:; } if (current_scope.count(str) == 0 || current_scope[str]->type != AST_FUNCTION) - log_file_error(filename, linenum, "Can't resolve function name `%s'.\n", str.c_str()); + log_file_error(filename, location.first_line, "Can't resolve function name `%s'.\n", str.c_str()); } if (type == AST_TCALL) @@ -2431,26 +2429,26 @@ skip_dynamic_range_lvalue_expansion:; if (str == "$finish" || str == "$stop") { if (!current_always || current_always->type != AST_INITIAL) - log_file_error(filename, linenum, "System task `%s' outside initial block is unsupported.\n", str.c_str()); + log_file_error(filename, location.first_line, "System task `%s' outside initial block is unsupported.\n", str.c_str()); - log_file_error(filename, linenum, "System task `%s' executed.\n", str.c_str()); + log_file_error(filename, location.first_line, "System task `%s' executed.\n", str.c_str()); } if (str == "\\$readmemh" || str == "\\$readmemb") { if (GetSize(children) < 2 || GetSize(children) > 4) - log_file_error(filename, linenum, "System function %s got %d arguments, expected 2-4.\n", + log_file_error(filename, location.first_line, "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_file_error(filename, linenum, "Failed to evaluate system function `%s' with non-constant 1st argument.\n", str.c_str()); + log_file_error(filename, location.first_line, "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_file_error(filename, linenum, "Failed to evaluate system function `%s' with non-memory 2nd argument.\n", str.c_str()); + log_file_error(filename, location.first_line, "Failed to evaluate system function `%s' with non-memory 2nd argument.\n", str.c_str()); int start_addr = -1, finish_addr = -1; @@ -2458,7 +2456,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_file_error(filename, linenum, "Failed to evaluate system function `%s' with non-constant 3rd argument.\n", str.c_str()); + log_file_error(filename, location.first_line, "Failed to evaluate system function `%s' with non-constant 3rd argument.\n", str.c_str()); start_addr = int(node_addr->asInt(false)); } @@ -2466,7 +2464,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_file_error(filename, linenum, "Failed to evaluate system function `%s' with non-constant 4th argument.\n", str.c_str()); + log_file_error(filename, location.first_line, "Failed to evaluate system function `%s' with non-constant 4th argument.\n", str.c_str()); finish_addr = int(node_addr->asInt(false)); } @@ -2494,13 +2492,13 @@ skip_dynamic_range_lvalue_expansion:; } if (current_scope.count(str) == 0 || current_scope[str]->type != AST_TASK) - log_file_error(filename, linenum, "Can't resolve task name `%s'.\n", str.c_str()); + log_file_error(filename, location.first_line, "Can't resolve task name `%s'.\n", str.c_str()); } AstNode *decl = current_scope[str]; std::stringstream sstr; - sstr << "$func$" << str << "$" << filename << ":" << linenum << "$" << (autoidx++) << "$"; + sstr << "$func$" << str << "$" << filename << ":" << location.first_line << "$" << (autoidx++) << "$"; std::string prefix = sstr.str(); bool recommend_const_eval = false; @@ -2522,9 +2520,9 @@ skip_dynamic_range_lvalue_expansion:; } if (in_param) - log_file_error(filename, linenum, "Non-constant function call in constant expression.\n"); + log_file_error(filename, location.first_line, "Non-constant function call in constant expression.\n"); if (require_const_eval) - log_file_error(filename, linenum, "Function %s can only be called with constant arguments.\n", str.c_str()); + log_file_error(filename, location.first_line, "Function %s can only be called with constant arguments.\n", str.c_str()); } size_t arg_count = 0; @@ -2646,7 +2644,7 @@ skip_dynamic_range_lvalue_expansion:; goto tcall_incompatible_wires; } else { tcall_incompatible_wires: - log_file_error(filename, linenum, "Incompatible re-declaration of wire %s.\n", child->str.c_str()); + log_file_error(filename, location.first_line, "Incompatible re-declaration of wire %s.\n", child->str.c_str()); } } } @@ -3000,7 +2998,7 @@ apply_newNode: // newNode->dumpAst(stderr, "+ "); log_assert(newNode != NULL); newNode->filename = filename; - newNode->linenum = linenum; + newNode->location = location; newNode->cloneInto(this); delete newNode; did_something = true; @@ -3049,7 +3047,7 @@ AstNode *AstNode::readmem(bool is_readmemh, std::string mem_filename, AstNode *m yosys_input_files.insert(mem_filename); } if (f.fail() || GetSize(mem_filename) == 0) - log_file_error(filename, linenum, "Can not open file `%s` for %s.\n", mem_filename.c_str(), str.c_str()); + log_file_error(filename, location.first_line, "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; @@ -3095,7 +3093,7 @@ AstNode *AstNode::readmem(bool is_readmemh, std::string mem_filename, AstNode *m char *endptr; cursor = strtol(nptr, &endptr, 16); if (!*nptr || *endptr) - log_file_error(filename, linenum, "Can not parse address `%s` for %s.\n", nptr, str.c_str()); + log_file_error(filename, location.first_line, "Can not parse address `%s` for %s.\n", nptr, str.c_str()); continue; } @@ -3270,7 +3268,7 @@ static void mark_memories_assign_lhs_complex(dict<AstNode*, pool<std::string>> & if (that->type == AST_IDENTIFIER && that->id2ast && that->id2ast->type == AST_MEMORY) { AstNode *mem = that->id2ast; if (!(mem2reg_candidates[mem] & AstNode::MEM2REG_FL_CMPLX_LHS)) - mem2reg_places[mem].insert(stringf("%s:%d", that->filename.c_str(), that->linenum)); + mem2reg_places[mem].insert(stringf("%s:%d", that->filename.c_str(), that->location.first_line)); mem2reg_candidates[mem] |= AstNode::MEM2REG_FL_CMPLX_LHS; } } @@ -3298,14 +3296,14 @@ void AstNode::mem2reg_as_needed_pass1(dict<AstNode*, pool<std::string>> &mem2reg // activate mem2reg if this is assigned in an async proc if (flags & AstNode::MEM2REG_FL_ASYNC) { if (!(mem2reg_candidates[mem] & AstNode::MEM2REG_FL_SET_ASYNC)) - mem2reg_places[mem].insert(stringf("%s:%d", filename.c_str(), linenum)); + mem2reg_places[mem].insert(stringf("%s:%d", filename.c_str(), location.first_line)); mem2reg_candidates[mem] |= AstNode::MEM2REG_FL_SET_ASYNC; } // remember if this is assigned blocking (=) if (type == AST_ASSIGN_EQ) { if (!(proc_flags[mem] & AstNode::MEM2REG_FL_EQ1)) - mem2reg_places[mem].insert(stringf("%s:%d", filename.c_str(), linenum)); + mem2reg_places[mem].insert(stringf("%s:%d", filename.c_str(), location.first_line)); proc_flags[mem] |= AstNode::MEM2REG_FL_EQ1; } @@ -3322,11 +3320,11 @@ void AstNode::mem2reg_as_needed_pass1(dict<AstNode*, pool<std::string>> &mem2reg // remember where this is if (flags & MEM2REG_FL_INIT) { if (!(mem2reg_candidates[mem] & AstNode::MEM2REG_FL_SET_INIT)) - mem2reg_places[mem].insert(stringf("%s:%d", filename.c_str(), linenum)); + mem2reg_places[mem].insert(stringf("%s:%d", filename.c_str(), location.first_line)); mem2reg_candidates[mem] |= AstNode::MEM2REG_FL_SET_INIT; } else { if (!(mem2reg_candidates[mem] & AstNode::MEM2REG_FL_SET_ELSE)) - mem2reg_places[mem].insert(stringf("%s:%d", filename.c_str(), linenum)); + mem2reg_places[mem].insert(stringf("%s:%d", filename.c_str(), location.first_line)); mem2reg_candidates[mem] |= AstNode::MEM2REG_FL_SET_ELSE; } } @@ -3340,7 +3338,7 @@ void AstNode::mem2reg_as_needed_pass1(dict<AstNode*, pool<std::string>> &mem2reg // flag if used after blocking assignment (in same proc) if ((proc_flags[mem] & AstNode::MEM2REG_FL_EQ1) && !(mem2reg_candidates[mem] & AstNode::MEM2REG_FL_EQ2)) { - mem2reg_places[mem].insert(stringf("%s:%d", filename.c_str(), linenum)); + mem2reg_places[mem].insert(stringf("%s:%d", filename.c_str(), location.first_line)); mem2reg_candidates[mem] |= AstNode::MEM2REG_FL_EQ2; } } @@ -3409,7 +3407,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_file_error(filename, linenum, "Invalid array access.\n"); + log_file_error(filename, location.first_line, "Invalid array access.\n"); return true; } @@ -3501,7 +3499,7 @@ bool AstNode::mem2reg_as_needed_pass2(pool<AstNode*> &mem2reg_set, AstNode *mod, children[0]->children[0]->children[0]->type != AST_CONSTANT) { std::stringstream sstr; - sstr << "$mem2reg_wr$" << children[0]->str << "$" << filename << ":" << linenum << "$" << (autoidx++); + sstr << "$mem2reg_wr$" << children[0]->str << "$" << filename << ":" << location.first_line << "$" << (autoidx++); std::string id_addr = sstr.str() + "_ADDR", id_data = sstr.str() + "_DATA"; int mem_width, mem_size, addr_bits; @@ -3580,7 +3578,7 @@ bool AstNode::mem2reg_as_needed_pass2(pool<AstNode*> &mem2reg_set, AstNode *mod, else { std::stringstream sstr; - sstr << "$mem2reg_rd$" << str << "$" << filename << ":" << linenum << "$" << (autoidx++); + sstr << "$mem2reg_rd$" << str << "$" << filename << ":" << location.first_line << "$" << (autoidx++); std::string id_addr = sstr.str() + "_ADDR", id_data = sstr.str() + "_DATA"; int mem_width, mem_size, addr_bits; @@ -3724,13 +3722,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_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); + log_file_error(filename, location.first_line, "Memory access in constant function is not supported\n%s:%d.%d-%d.%d: ...called from here.\n", + fcall->filename.c_str(), fcall->location.first_line, fcall->location.first_column, fcall->location.last_line, fcall->location.last_column); children.at(0)->replace_variables(variables, fcall); while (simplify(true, false, false, 1, -1, false, true)) { } if (!children.at(0)->range_valid) - log_file_error(filename, linenum, "Non-constant range\n%s:%d: ... called from here.\n", - fcall->filename.c_str(), fcall->linenum); + log_file_error(filename, location.first_line, "Non-constant range\n%s:%d.%d-%d.%d: ... called from here.\n", + fcall->filename.c_str(), fcall->location.first_line, fcall->location.first_column, fcall->location.last_line, fcall->location.last_column); 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); } @@ -3761,8 +3759,8 @@ AstNode *AstNode::eval_const_function(AstNode *fcall) { while (child->simplify(true, false, false, 1, -1, false, true)) { } if (!child->range_valid) - 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); + log_file_error(child->filename, child->location.first_line, "Can't determine size of variable %s\n%s:%d.%d-%d.%d: ... called from here.\n", + child->str.c_str(), fcall->filename.c_str(), fcall->location.first_line, fcall->location.first_column, fcall->location.last_line, fcall->location.last_column); 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; @@ -3801,24 +3799,24 @@ AstNode *AstNode::eval_const_function(AstNode *fcall) continue; if (stmt->children.at(1)->type != AST_CONSTANT) - 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); + log_file_error(stmt->filename, stmt->location.first_line, "Non-constant expression in constant function\n%s:%d.%d-%d.%d: ... called from here. X\n", + fcall->filename.c_str(), fcall->location.first_line, fcall->location.first_column, fcall->location.last_line, fcall->location.last_column); if (stmt->children.at(0)->type != AST_IDENTIFIER) - 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); + log_file_error(stmt->filename, stmt->location.first_line, "Unsupported composite left hand side in constant function\n%s:%d.%d-%d.%d: ... called from here.\n", + fcall->filename.c_str(), fcall->location.first_line, fcall->location.first_column, fcall->location.last_line, fcall->location.last_column); if (!variables.count(stmt->children.at(0)->str)) - 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); + log_file_error(stmt->filename, stmt->location.first_line, "Assignment to non-local variable in constant function\n%s:%d.%d-%d.%d: ... called from here.\n", + fcall->filename.c_str(), fcall->location.first_line, fcall->location.first_column, fcall->location.last_line, fcall->location.last_column); 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_file_error(range->filename, range->linenum, "Non-constant range\n%s:%d: ... called from here.\n", - fcall->filename.c_str(), fcall->linenum); + log_file_error(range->filename, range->location.first_line, "Non-constant range\n%s:%d.%d-%d.%d: ... called from here.\n", + fcall->filename.c_str(), fcall->location.first_line, fcall->location.first_column, fcall->location.last_line, fcall->location.last_column); 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]; @@ -3849,8 +3847,8 @@ AstNode *AstNode::eval_const_function(AstNode *fcall) while (cond->simplify(true, false, false, 1, -1, false, true)) { } if (cond->type != AST_CONSTANT) - 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); + log_file_error(stmt->filename, stmt->location.first_line, "Non-constant expression in constant function\n%s:%d.%d-%d.%d: ... called from here.\n", + fcall->filename.c_str(), fcall->location.first_line, fcall->location.first_column, fcall->location.last_line, fcall->location.last_column); if (cond->asBool()) { block->children.insert(block->children.begin(), stmt->children.at(1)->clone()); @@ -3870,8 +3868,8 @@ AstNode *AstNode::eval_const_function(AstNode *fcall) while (num->simplify(true, false, false, 1, -1, false, true)) { } if (num->type != AST_CONSTANT) - 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); + log_file_error(stmt->filename, stmt->location.first_line, "Non-constant expression in constant function\n%s:%d.%d-%d.%d: ... called from here.\n", + fcall->filename.c_str(), fcall->location.first_line, fcall->location.first_column, fcall->location.last_line, fcall->location.last_column); block->children.erase(block->children.begin()); for (int i = 0; i < num->bitsAsConst().as_int(); i++) @@ -3908,8 +3906,8 @@ AstNode *AstNode::eval_const_function(AstNode *fcall) while (cond->simplify(true, false, false, 1, -1, false, true)) { } if (cond->type != AST_CONSTANT) - 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); + log_file_error(stmt->filename, stmt->location.first_line, "Non-constant expression in constant function\n%s:%d.%d-%d.%d: ... called from here.\n", + fcall->filename.c_str(), fcall->location.first_line, fcall->location.first_column, fcall->location.last_line, fcall->location.last_column); found_match = cond->asBool(); delete cond; @@ -3938,8 +3936,8 @@ AstNode *AstNode::eval_const_function(AstNode *fcall) continue; } - 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_file_error(stmt->filename, stmt->location.first_line, "Unsupported language construct in constant function\n%s:%d.%d-%d.%d: ... called from here.\n", + fcall->filename.c_str(), fcall->location.first_line, fcall->location.first_column, fcall->location.last_line, fcall->location.last_column); log_abort(); } |