mirror of https://github.com/YosysHQ/yosys.git
ast: Move to a new helper method to print input errors
It's a repeating pattern to print an error message tied to an AST node. Start using an 'input_error' helper for that. Among other things this is beneficial in shortening the print lines, which tend to be long.
This commit is contained in:
parent
1ac1b2eed5
commit
77d4b5230e
|
@ -192,7 +192,7 @@ bool AstNode::get_bool_attribute(RTLIL::IdString id)
|
||||||
|
|
||||||
AstNode *attr = attributes.at(id);
|
AstNode *attr = attributes.at(id);
|
||||||
if (attr->type != AST_CONSTANT)
|
if (attr->type != AST_CONSTANT)
|
||||||
log_file_error(attr->filename, attr->location.first_line, "Attribute `%s' with non-constant value!\n", id.c_str());
|
attr->input_error("Attribute `%s' with non-constant value!\n", id.c_str());
|
||||||
|
|
||||||
return attr->integer != 0;
|
return attr->integer != 0;
|
||||||
}
|
}
|
||||||
|
@ -1039,7 +1039,7 @@ static RTLIL::Module *process_module(RTLIL::Design *design, AstNode *ast, bool d
|
||||||
{
|
{
|
||||||
for (const AstNode *node : ast->children)
|
for (const AstNode *node : ast->children)
|
||||||
if (node->type == AST_PARAMETER && param_has_no_default(node))
|
if (node->type == AST_PARAMETER && param_has_no_default(node))
|
||||||
log_file_error(node->filename, node->location.first_line, "Parameter `%s' has no default value and has not been overridden!\n", node->str.c_str());
|
node->input_error("Parameter `%s' has no default value and has not been overridden!\n", node->str.c_str());
|
||||||
|
|
||||||
bool blackbox_module = flag_lib;
|
bool blackbox_module = flag_lib;
|
||||||
|
|
||||||
|
@ -1099,14 +1099,14 @@ static RTLIL::Module *process_module(RTLIL::Design *design, AstNode *ast, bool d
|
||||||
if (!blackbox_module && ast->attributes.count(ID::blackbox)) {
|
if (!blackbox_module && ast->attributes.count(ID::blackbox)) {
|
||||||
AstNode *n = ast->attributes.at(ID::blackbox);
|
AstNode *n = ast->attributes.at(ID::blackbox);
|
||||||
if (n->type != AST_CONSTANT)
|
if (n->type != AST_CONSTANT)
|
||||||
log_file_error(ast->filename, ast->location.first_line, "Got blackbox attribute with non-constant value!\n");
|
ast->input_error("Got blackbox attribute with non-constant value!\n");
|
||||||
blackbox_module = n->asBool();
|
blackbox_module = n->asBool();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (blackbox_module && ast->attributes.count(ID::whitebox)) {
|
if (blackbox_module && ast->attributes.count(ID::whitebox)) {
|
||||||
AstNode *n = ast->attributes.at(ID::whitebox);
|
AstNode *n = ast->attributes.at(ID::whitebox);
|
||||||
if (n->type != AST_CONSTANT)
|
if (n->type != AST_CONSTANT)
|
||||||
log_file_error(ast->filename, ast->location.first_line, "Got whitebox attribute with non-constant value!\n");
|
ast->input_error("Got whitebox attribute with non-constant value!\n");
|
||||||
blackbox_module = !n->asBool();
|
blackbox_module = !n->asBool();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1114,7 +1114,7 @@ static RTLIL::Module *process_module(RTLIL::Design *design, AstNode *ast, bool d
|
||||||
if (blackbox_module) {
|
if (blackbox_module) {
|
||||||
AstNode *n = ast->attributes.at(ID::noblackbox);
|
AstNode *n = ast->attributes.at(ID::noblackbox);
|
||||||
if (n->type != AST_CONSTANT)
|
if (n->type != AST_CONSTANT)
|
||||||
log_file_error(ast->filename, ast->location.first_line, "Got noblackbox attribute with non-constant value!\n");
|
ast->input_error("Got noblackbox attribute with non-constant value!\n");
|
||||||
blackbox_module = !n->asBool();
|
blackbox_module = !n->asBool();
|
||||||
}
|
}
|
||||||
delete ast->attributes.at(ID::noblackbox);
|
delete ast->attributes.at(ID::noblackbox);
|
||||||
|
@ -1158,7 +1158,7 @@ static RTLIL::Module *process_module(RTLIL::Design *design, AstNode *ast, bool d
|
||||||
|
|
||||||
for (auto &attr : ast->attributes) {
|
for (auto &attr : ast->attributes) {
|
||||||
if (attr.second->type != AST_CONSTANT)
|
if (attr.second->type != AST_CONSTANT)
|
||||||
log_file_error(ast->filename, ast->location.first_line, "Attribute `%s' with non-constant value!\n", attr.first.c_str());
|
ast->input_error("Attribute `%s' with non-constant value!\n", attr.first.c_str());
|
||||||
module->attributes[attr.first] = attr.second->asAttrConst();
|
module->attributes[attr.first] = attr.second->asAttrConst();
|
||||||
}
|
}
|
||||||
for (size_t i = 0; i < ast->children.size(); i++) {
|
for (size_t i = 0; i < ast->children.size(); i++) {
|
||||||
|
@ -1841,4 +1841,11 @@ void AstModule::loadconfig() const
|
||||||
flag_autowire = autowire;
|
flag_autowire = autowire;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void AstNode::input_error(const char *format, ...) const
|
||||||
|
{
|
||||||
|
va_list ap;
|
||||||
|
va_start(ap, format);
|
||||||
|
logv_file_error(filename, location.first_line, format, ap);
|
||||||
|
}
|
||||||
|
|
||||||
YOSYS_NAMESPACE_END
|
YOSYS_NAMESPACE_END
|
||||||
|
|
|
@ -335,6 +335,9 @@ namespace AST
|
||||||
|
|
||||||
// Helper for looking up identifiers which are prefixed with the current module name
|
// Helper for looking up identifiers which are prefixed with the current module name
|
||||||
std::string try_pop_module_prefix() const;
|
std::string try_pop_module_prefix() const;
|
||||||
|
|
||||||
|
// helper to print errors from simplify/genrtlil code
|
||||||
|
[[noreturn]] void input_error(const char *format, ...) const YS_ATTRIBUTE(format(printf, 2, 3));
|
||||||
};
|
};
|
||||||
|
|
||||||
// process an AST tree (ast must point to an AST_DESIGN node) and generate RTLIL code
|
// process an AST tree (ast must point to an AST_DESIGN node) and generate RTLIL code
|
||||||
|
|
|
@ -56,7 +56,7 @@ static RTLIL::SigSpec uniop2rtlil(AstNode *that, IdString type, int result_width
|
||||||
if (gen_attributes)
|
if (gen_attributes)
|
||||||
for (auto &attr : that->attributes) {
|
for (auto &attr : that->attributes) {
|
||||||
if (attr.second->type != AST_CONSTANT)
|
if (attr.second->type != AST_CONSTANT)
|
||||||
log_file_error(that->filename, that->location.first_line, "Attribute `%s' with non-constant value!\n", attr.first.c_str());
|
that->input_error("Attribute `%s' with non-constant value!\n", attr.first.c_str());
|
||||||
cell->attributes[attr.first] = attr.second->asAttrConst();
|
cell->attributes[attr.first] = attr.second->asAttrConst();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -88,7 +88,7 @@ static void widthExtend(AstNode *that, RTLIL::SigSpec &sig, int width, bool is_s
|
||||||
if (that != NULL)
|
if (that != NULL)
|
||||||
for (auto &attr : that->attributes) {
|
for (auto &attr : that->attributes) {
|
||||||
if (attr.second->type != AST_CONSTANT)
|
if (attr.second->type != AST_CONSTANT)
|
||||||
log_file_error(that->filename, that->location.first_line, "Attribute `%s' with non-constant value!\n", attr.first.c_str());
|
that->input_error("Attribute `%s' with non-constant value!\n", attr.first.c_str());
|
||||||
cell->attributes[attr.first] = attr.second->asAttrConst();
|
cell->attributes[attr.first] = attr.second->asAttrConst();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -114,7 +114,7 @@ static RTLIL::SigSpec binop2rtlil(AstNode *that, IdString type, int result_width
|
||||||
|
|
||||||
for (auto &attr : that->attributes) {
|
for (auto &attr : that->attributes) {
|
||||||
if (attr.second->type != AST_CONSTANT)
|
if (attr.second->type != AST_CONSTANT)
|
||||||
log_file_error(that->filename, that->location.first_line, "Attribute `%s' with non-constant value!\n", attr.first.c_str());
|
that->input_error("Attribute `%s' with non-constant value!\n", attr.first.c_str());
|
||||||
cell->attributes[attr.first] = attr.second->asAttrConst();
|
cell->attributes[attr.first] = attr.second->asAttrConst();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -149,7 +149,7 @@ static RTLIL::SigSpec mux2rtlil(AstNode *that, const RTLIL::SigSpec &cond, const
|
||||||
|
|
||||||
for (auto &attr : that->attributes) {
|
for (auto &attr : that->attributes) {
|
||||||
if (attr.second->type != AST_CONSTANT)
|
if (attr.second->type != AST_CONSTANT)
|
||||||
log_file_error(that->filename, that->location.first_line, "Attribute `%s' with non-constant value!\n", attr.first.c_str());
|
that->input_error("Attribute `%s' with non-constant value!\n", attr.first.c_str());
|
||||||
cell->attributes[attr.first] = attr.second->asAttrConst();
|
cell->attributes[attr.first] = attr.second->asAttrConst();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -325,8 +325,7 @@ struct AST_INTERNAL::ProcessGenerator
|
||||||
set_src_attr(proc, always);
|
set_src_attr(proc, always);
|
||||||
for (auto &attr : always->attributes) {
|
for (auto &attr : always->attributes) {
|
||||||
if (attr.second->type != AST_CONSTANT)
|
if (attr.second->type != AST_CONSTANT)
|
||||||
log_file_error(always->filename, always->location.first_line, "Attribute `%s' with non-constant value!\n",
|
always->input_error("Attribute `%s' with non-constant value!\n", attr.first.c_str());
|
||||||
attr.first.c_str());
|
|
||||||
proc->attributes[attr.first] = attr.second->asAttrConst();
|
proc->attributes[attr.first] = attr.second->asAttrConst();
|
||||||
}
|
}
|
||||||
current_case = &proc->root_case;
|
current_case = &proc->root_case;
|
||||||
|
@ -355,7 +354,7 @@ struct AST_INTERNAL::ProcessGenerator
|
||||||
|
|
||||||
if (found_anyedge_syncs) {
|
if (found_anyedge_syncs) {
|
||||||
if (found_global_syncs)
|
if (found_global_syncs)
|
||||||
log_file_error(always->filename, always->location.first_line, "Found non-synthesizable event list!\n");
|
always->input_error("Found non-synthesizable event list!\n");
|
||||||
log("Note: Assuming pure combinatorial block at %s in\n", always->loc_string().c_str());
|
log("Note: Assuming pure combinatorial block at %s in\n", always->loc_string().c_str());
|
||||||
log("compliance with IEC 62142(E):2005 / IEEE Std. 1364.1(E):2002. Recommending\n");
|
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");
|
log("use of @* instead of @(...) for better match of synthesis and simulation.\n");
|
||||||
|
@ -370,12 +369,12 @@ struct AST_INTERNAL::ProcessGenerator
|
||||||
continue;
|
continue;
|
||||||
found_clocked_sync = true;
|
found_clocked_sync = true;
|
||||||
if (found_global_syncs || found_anyedge_syncs)
|
if (found_global_syncs || found_anyedge_syncs)
|
||||||
log_file_error(always->filename, always->location.first_line, "Found non-synthesizable event list!\n");
|
always->input_error("Found non-synthesizable event list!\n");
|
||||||
RTLIL::SyncRule *syncrule = new RTLIL::SyncRule;
|
RTLIL::SyncRule *syncrule = new RTLIL::SyncRule;
|
||||||
syncrule->type = child->type == AST_POSEDGE ? RTLIL::STp : RTLIL::STn;
|
syncrule->type = child->type == AST_POSEDGE ? RTLIL::STp : RTLIL::STn;
|
||||||
syncrule->signal = child->children[0]->genRTLIL();
|
syncrule->signal = child->children[0]->genRTLIL();
|
||||||
if (GetSize(syncrule->signal) != 1)
|
if (GetSize(syncrule->signal) != 1)
|
||||||
log_file_error(always->filename, always->location.first_line, "Found posedge/negedge event on a signal that is not 1 bit wide!\n");
|
always->input_error("Found posedge/negedge event on a signal that is not 1 bit wide!\n");
|
||||||
addChunkActions(syncrule->actions, subst_lvalue_from, subst_lvalue_to, true);
|
addChunkActions(syncrule->actions, subst_lvalue_from, subst_lvalue_to, true);
|
||||||
proc->syncs.push_back(syncrule);
|
proc->syncs.push_back(syncrule);
|
||||||
}
|
}
|
||||||
|
@ -604,7 +603,7 @@ struct AST_INTERNAL::ProcessGenerator
|
||||||
|
|
||||||
for (auto &attr : ast->attributes) {
|
for (auto &attr : ast->attributes) {
|
||||||
if (attr.second->type != AST_CONSTANT)
|
if (attr.second->type != AST_CONSTANT)
|
||||||
log_file_error(ast->filename, ast->location.first_line, "Attribute `%s' with non-constant value!\n", attr.first.c_str());
|
ast->input_error("Attribute `%s' with non-constant value!\n", attr.first.c_str());
|
||||||
sw->attributes[attr.first] = attr.second->asAttrConst();
|
sw->attributes[attr.first] = attr.second->asAttrConst();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -682,16 +681,16 @@ struct AST_INTERNAL::ProcessGenerator
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case AST_WIRE:
|
case AST_WIRE:
|
||||||
log_file_error(ast->filename, ast->location.first_line, "Found reg declaration in block without label!\n");
|
ast->input_error("Found reg declaration in block without label!\n");
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case AST_ASSIGN:
|
case AST_ASSIGN:
|
||||||
log_file_error(ast->filename, ast->location.first_line, "Found continous assignment in always/initial block!\n");
|
ast->input_error("Found continous assignment in always/initial block!\n");
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case AST_PARAMETER:
|
case AST_PARAMETER:
|
||||||
case AST_LOCALPARAM:
|
case AST_LOCALPARAM:
|
||||||
log_file_error(ast->filename, ast->location.first_line, "Found parameter declaration in block without label!\n");
|
ast->input_error("Found parameter declaration in block without label!\n");
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case AST_NONE:
|
case AST_NONE:
|
||||||
|
@ -840,7 +839,7 @@ void AstNode::detectSignWidthWorker(int &width_hint, bool &sign_hint, bool *foun
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (!id_ast)
|
if (!id_ast)
|
||||||
log_file_error(filename, location.first_line, "Failed to resolve identifier %s for width detection!\n", str.c_str());
|
input_error("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->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) {
|
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;
|
this_width = id_ast->children[1]->range_left - id_ast->children[1]->range_right + 1;
|
||||||
|
@ -850,7 +849,7 @@ void AstNode::detectSignWidthWorker(int &width_hint, bool &sign_hint, bool *foun
|
||||||
if (id_ast->children[0]->type == AST_CONSTANT)
|
if (id_ast->children[0]->type == AST_CONSTANT)
|
||||||
this_width = id_ast->children[0]->bits.size();
|
this_width = id_ast->children[0]->bits.size();
|
||||||
else
|
else
|
||||||
log_file_error(filename, location.first_line, "Failed to detect width for parameter %s!\n", str.c_str());
|
input_error("Failed to detect width for parameter %s!\n", str.c_str());
|
||||||
}
|
}
|
||||||
if (children.size() != 0)
|
if (children.size() != 0)
|
||||||
range = children[0];
|
range = children[0];
|
||||||
|
@ -863,7 +862,7 @@ void AstNode::detectSignWidthWorker(int &width_hint, bool &sign_hint, bool *foun
|
||||||
// log("---\n");
|
// log("---\n");
|
||||||
// id_ast->dumpAst(NULL, "decl> ");
|
// id_ast->dumpAst(NULL, "decl> ");
|
||||||
// dumpAst(NULL, "ref> ");
|
// dumpAst(NULL, "ref> ");
|
||||||
log_file_error(filename, location.first_line, "Failed to detect width of signal access `%s'!\n", str.c_str());
|
input_error("Failed to detect width of signal access `%s'!\n", str.c_str());
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
this_width = id_ast->range_left - id_ast->range_right + 1;
|
this_width = id_ast->range_left - id_ast->range_right + 1;
|
||||||
|
@ -874,7 +873,7 @@ void AstNode::detectSignWidthWorker(int &width_hint, bool &sign_hint, bool *foun
|
||||||
this_width = 32;
|
this_width = 32;
|
||||||
} else if (id_ast->type == AST_MEMORY) {
|
} else if (id_ast->type == AST_MEMORY) {
|
||||||
if (!id_ast->children[0]->range_valid)
|
if (!id_ast->children[0]->range_valid)
|
||||||
log_file_error(filename, location.first_line, "Failed to detect width of memory access `%s'!\n", str.c_str());
|
input_error("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;
|
this_width = id_ast->children[0]->range_left - id_ast->children[0]->range_right + 1;
|
||||||
if (children.size() > 1)
|
if (children.size() > 1)
|
||||||
range = children[1];
|
range = children[1];
|
||||||
|
@ -883,7 +882,7 @@ void AstNode::detectSignWidthWorker(int &width_hint, bool &sign_hint, bool *foun
|
||||||
this_width = tmp_range->range_left - tmp_range->range_right + 1;
|
this_width = tmp_range->range_left - tmp_range->range_right + 1;
|
||||||
delete tmp_range;
|
delete tmp_range;
|
||||||
} else
|
} else
|
||||||
log_file_error(filename, location.first_line, "Failed to detect width for identifier %s!\n", str.c_str());
|
input_error("Failed to detect width for identifier %s!\n", str.c_str());
|
||||||
if (range) {
|
if (range) {
|
||||||
if (range->children.size() == 1)
|
if (range->children.size() == 1)
|
||||||
this_width = 1;
|
this_width = 1;
|
||||||
|
@ -893,7 +892,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 (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)) { }
|
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)
|
if (left_at_zero_ast->type != AST_CONSTANT || right_at_zero_ast->type != AST_CONSTANT)
|
||||||
log_file_error(filename, location.first_line, "Unsupported expression on dynamic range select on signal `%s'!\n", str.c_str());
|
input_error("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;
|
this_width = abs(int(left_at_zero_ast->integer - right_at_zero_ast->integer)) + 1;
|
||||||
delete left_at_zero_ast;
|
delete left_at_zero_ast;
|
||||||
delete right_at_zero_ast;
|
delete right_at_zero_ast;
|
||||||
|
@ -909,7 +908,7 @@ void AstNode::detectSignWidthWorker(int &width_hint, bool &sign_hint, bool *foun
|
||||||
case AST_TO_BITS:
|
case AST_TO_BITS:
|
||||||
while (children[0]->simplify(true, false, false, 1, -1, false, false) == true) { }
|
while (children[0]->simplify(true, false, false, 1, -1, false, false) == true) { }
|
||||||
if (children[0]->type != AST_CONSTANT)
|
if (children[0]->type != AST_CONSTANT)
|
||||||
log_file_error(filename, location.first_line, "Left operand of tobits expression is not constant!\n");
|
input_error("Left operand of tobits expression is not constant!\n");
|
||||||
children[1]->detectSignWidthWorker(sub_width_hint, sign_hint);
|
children[1]->detectSignWidthWorker(sub_width_hint, sign_hint);
|
||||||
width_hint = max(width_hint, children[0]->bitsAsConst().as_int());
|
width_hint = max(width_hint, children[0]->bitsAsConst().as_int());
|
||||||
break;
|
break;
|
||||||
|
@ -931,12 +930,12 @@ void AstNode::detectSignWidthWorker(int &width_hint, bool &sign_hint, bool *foun
|
||||||
case AST_CAST_SIZE:
|
case AST_CAST_SIZE:
|
||||||
while (children.at(0)->simplify(true, false, false, 1, -1, false, false)) { }
|
while (children.at(0)->simplify(true, false, false, 1, -1, false, false)) { }
|
||||||
if (children.at(0)->type != AST_CONSTANT)
|
if (children.at(0)->type != AST_CONSTANT)
|
||||||
log_file_error(filename, location.first_line, "Static cast with non constant expression!\n");
|
input_error("Static cast with non constant expression!\n");
|
||||||
children.at(1)->detectSignWidthWorker(width_hint, sign_hint);
|
children.at(1)->detectSignWidthWorker(width_hint, sign_hint);
|
||||||
this_width = children.at(0)->bitsAsConst().as_int();
|
this_width = children.at(0)->bitsAsConst().as_int();
|
||||||
width_hint = max(width_hint, this_width);
|
width_hint = max(width_hint, this_width);
|
||||||
if (width_hint <= 0)
|
if (width_hint <= 0)
|
||||||
log_file_error(filename, location.first_line, "Static cast with zero or negative size!\n");
|
input_error("Static cast with zero or negative size!\n");
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case AST_CONCAT:
|
case AST_CONCAT:
|
||||||
|
@ -953,7 +952,7 @@ void AstNode::detectSignWidthWorker(int &width_hint, bool &sign_hint, bool *foun
|
||||||
case AST_REPLICATE:
|
case AST_REPLICATE:
|
||||||
while (children[0]->simplify(true, false, false, 1, -1, false, true) == true) { }
|
while (children[0]->simplify(true, false, false, 1, -1, false, true) == true) { }
|
||||||
if (children[0]->type != AST_CONSTANT)
|
if (children[0]->type != AST_CONSTANT)
|
||||||
log_file_error(filename, location.first_line, "Left operand of replicate expression is not constant!\n");
|
input_error("Left operand of replicate expression is not constant!\n");
|
||||||
children[1]->detectSignWidthWorker(sub_width_hint, sub_sign_hint);
|
children[1]->detectSignWidthWorker(sub_width_hint, sub_sign_hint);
|
||||||
width_hint = max(width_hint, children[0]->bitsAsConst().as_int() * sub_width_hint);
|
width_hint = max(width_hint, children[0]->bitsAsConst().as_int() * sub_width_hint);
|
||||||
sign_hint = false;
|
sign_hint = false;
|
||||||
|
@ -1029,7 +1028,7 @@ void AstNode::detectSignWidthWorker(int &width_hint, bool &sign_hint, bool *foun
|
||||||
if (!id2ast->is_signed)
|
if (!id2ast->is_signed)
|
||||||
sign_hint = false;
|
sign_hint = false;
|
||||||
if (!id2ast->children[0]->range_valid)
|
if (!id2ast->children[0]->range_valid)
|
||||||
log_file_error(filename, location.first_line, "Failed to detect width of memory access `%s'!\n", str.c_str());
|
input_error("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;
|
this_width = id2ast->children[0]->range_left - id2ast->children[0]->range_right + 1;
|
||||||
width_hint = max(width_hint, this_width);
|
width_hint = max(width_hint, this_width);
|
||||||
break;
|
break;
|
||||||
|
@ -1073,7 +1072,7 @@ void AstNode::detectSignWidthWorker(int &width_hint, bool &sign_hint, bool *foun
|
||||||
if (GetSize(children) == 1) {
|
if (GetSize(children) == 1) {
|
||||||
while (children[0]->simplify(true, false, false, 1, -1, false, true) == true) { }
|
while (children[0]->simplify(true, false, false, 1, -1, false, true) == true) { }
|
||||||
if (children[0]->type != AST_CONSTANT)
|
if (children[0]->type != AST_CONSTANT)
|
||||||
log_file_error(filename, location.first_line, "System function %s called with non-const argument!\n",
|
input_error("System function %s called with non-const argument!\n",
|
||||||
RTLIL::unescape_id(str).c_str());
|
RTLIL::unescape_id(str).c_str());
|
||||||
width_hint = max(width_hint, int(children[0]->asInt(true)));
|
width_hint = max(width_hint, int(children[0]->asInt(true)));
|
||||||
}
|
}
|
||||||
|
@ -1101,7 +1100,7 @@ void AstNode::detectSignWidthWorker(int &width_hint, bool &sign_hint, bool *foun
|
||||||
// item expressions.
|
// item expressions.
|
||||||
const AstNode *func = current_scope.at(str);
|
const AstNode *func = current_scope.at(str);
|
||||||
if (func->type != AST_FUNCTION)
|
if (func->type != AST_FUNCTION)
|
||||||
log_file_error(filename, location.first_line, "Function call to %s resolved to something that isn't a function!\n", RTLIL::unescape_id(str).c_str());
|
input_error("Function call to %s resolved to something that isn't a function!\n", RTLIL::unescape_id(str).c_str());
|
||||||
const AstNode *wire = nullptr;
|
const AstNode *wire = nullptr;
|
||||||
for (const AstNode *child : func->children)
|
for (const AstNode *child : func->children)
|
||||||
if (child->str == func->str) {
|
if (child->str == func->str) {
|
||||||
|
@ -1121,7 +1120,7 @@ void AstNode::detectSignWidthWorker(int &width_hint, bool &sign_hint, bool *foun
|
||||||
while (left->simplify(true, false, false, 1, -1, false, true)) { }
|
while (left->simplify(true, false, false, 1, -1, false, true)) { }
|
||||||
while (right->simplify(true, false, false, 1, -1, false, true)) { }
|
while (right->simplify(true, false, false, 1, -1, false, true)) { }
|
||||||
if (left->type != AST_CONSTANT || right->type != AST_CONSTANT)
|
if (left->type != AST_CONSTANT || right->type != AST_CONSTANT)
|
||||||
log_file_error(filename, location.first_line, "Function %s has non-constant width!",
|
input_error("Function %s has non-constant width!",
|
||||||
RTLIL::unescape_id(str).c_str());
|
RTLIL::unescape_id(str).c_str());
|
||||||
result_width = abs(int(left->asInt(true) - right->asInt(true)));
|
result_width = abs(int(left->asInt(true) - right->asInt(true)));
|
||||||
delete left;
|
delete left;
|
||||||
|
@ -1137,7 +1136,7 @@ void AstNode::detectSignWidthWorker(int &width_hint, bool &sign_hint, bool *foun
|
||||||
AstNode *current_scope_ast = current_ast_mod == nullptr ? current_ast : current_ast_mod;
|
AstNode *current_scope_ast = current_ast_mod == nullptr ? current_ast : current_ast_mod;
|
||||||
for (auto f : log_files)
|
for (auto f : log_files)
|
||||||
current_scope_ast->dumpAst(f, "verilog-ast> ");
|
current_scope_ast->dumpAst(f, "verilog-ast> ");
|
||||||
log_file_error(filename, location.first_line, "Don't know how to detect sign and width for %s node!\n", type2str(type).c_str());
|
input_error("Don't know how to detect sign and width for %s node!\n", type2str(type).c_str());
|
||||||
}
|
}
|
||||||
|
|
||||||
if (*found_real)
|
if (*found_real)
|
||||||
|
@ -1155,9 +1154,8 @@ void AstNode::detectSignWidth(int &width_hint, bool &sign_hint, bool *found_real
|
||||||
|
|
||||||
constexpr int kWidthLimit = 1 << 24;
|
constexpr int kWidthLimit = 1 << 24;
|
||||||
if (width_hint >= kWidthLimit)
|
if (width_hint >= kWidthLimit)
|
||||||
log_file_error(filename, location.first_line,
|
input_error("Expression width %d exceeds implementation limit of %d!\n",
|
||||||
"Expression width %d exceeds implementation limit of %d!\n",
|
width_hint, kWidthLimit);
|
||||||
width_hint, kWidthLimit);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void check_unique_id(RTLIL::Module *module, RTLIL::IdString id,
|
static void check_unique_id(RTLIL::Module *module, RTLIL::IdString id,
|
||||||
|
@ -1168,9 +1166,8 @@ static void check_unique_id(RTLIL::Module *module, RTLIL::IdString id,
|
||||||
std::string location_str = "earlier";
|
std::string location_str = "earlier";
|
||||||
if (!src.empty())
|
if (!src.empty())
|
||||||
location_str = "at " + src;
|
location_str = "at " + src;
|
||||||
log_file_error(node->filename, node->location.first_line,
|
node->input_error("Cannot add %s `%s' because a %s with the same name was already created %s!\n",
|
||||||
"Cannot add %s `%s' because a %s with the same name was already created %s!\n",
|
to_add_kind, id.c_str(), existing_kind, location_str.c_str());
|
||||||
to_add_kind, id.c_str(), existing_kind, location_str.c_str());
|
|
||||||
};
|
};
|
||||||
|
|
||||||
if (const RTLIL::Wire *wire = module->wire(id))
|
if (const RTLIL::Wire *wire = module->wire(id))
|
||||||
|
@ -1265,7 +1262,7 @@ RTLIL::SigSpec AstNode::genRTLIL(int width_hint, bool sign_hint)
|
||||||
if (flag_pwires)
|
if (flag_pwires)
|
||||||
{
|
{
|
||||||
if (GetSize(children) < 1 || children[0]->type != AST_CONSTANT)
|
if (GetSize(children) < 1 || children[0]->type != AST_CONSTANT)
|
||||||
log_file_error(filename, location.first_line, "Parameter `%s' with non-constant value!\n", str.c_str());
|
input_error("Parameter `%s' with non-constant value!\n", str.c_str());
|
||||||
|
|
||||||
RTLIL::Const val = children[0]->bitsAsConst();
|
RTLIL::Const val = children[0]->bitsAsConst();
|
||||||
RTLIL::IdString id = str;
|
RTLIL::IdString id = str;
|
||||||
|
@ -1279,7 +1276,7 @@ RTLIL::SigSpec AstNode::genRTLIL(int width_hint, bool sign_hint)
|
||||||
|
|
||||||
for (auto &attr : attributes) {
|
for (auto &attr : attributes) {
|
||||||
if (attr.second->type != AST_CONSTANT)
|
if (attr.second->type != AST_CONSTANT)
|
||||||
log_file_error(filename, location.first_line, "Attribute `%s' with non-constant value!\n", attr.first.c_str());
|
input_error("Attribute `%s' with non-constant value!\n", attr.first.c_str());
|
||||||
wire->attributes[attr.first] = attr.second->asAttrConst();
|
wire->attributes[attr.first] = attr.second->asAttrConst();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1288,10 +1285,10 @@ RTLIL::SigSpec AstNode::genRTLIL(int width_hint, bool sign_hint)
|
||||||
// create an RTLIL::Wire for an AST_WIRE node
|
// create an RTLIL::Wire for an AST_WIRE node
|
||||||
case AST_WIRE: {
|
case AST_WIRE: {
|
||||||
if (!range_valid)
|
if (!range_valid)
|
||||||
log_file_error(filename, location.first_line, "Signal `%s' with non-constant width!\n", str.c_str());
|
input_error("Signal `%s' with non-constant width!\n", str.c_str());
|
||||||
|
|
||||||
if (!(range_left + 1 >= range_right))
|
if (!(range_left + 1 >= range_right))
|
||||||
log_file_error(filename, location.first_line, "Signal `%s' with invalid width range %d!\n", str.c_str(), range_left - range_right + 1);
|
input_error("Signal `%s' with invalid width range %d!\n", str.c_str(), range_left - range_right + 1);
|
||||||
|
|
||||||
RTLIL::IdString id = str;
|
RTLIL::IdString id = str;
|
||||||
check_unique_id(current_module, id, this, "signal");
|
check_unique_id(current_module, id, this, "signal");
|
||||||
|
@ -1306,7 +1303,7 @@ RTLIL::SigSpec AstNode::genRTLIL(int width_hint, bool sign_hint)
|
||||||
|
|
||||||
for (auto &attr : attributes) {
|
for (auto &attr : attributes) {
|
||||||
if (attr.second->type != AST_CONSTANT)
|
if (attr.second->type != AST_CONSTANT)
|
||||||
log_file_error(filename, location.first_line, "Attribute `%s' with non-constant value!\n", attr.first.c_str());
|
input_error("Attribute `%s' with non-constant value!\n", attr.first.c_str());
|
||||||
wire->attributes[attr.first] = attr.second->asAttrConst();
|
wire->attributes[attr.first] = attr.second->asAttrConst();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1322,7 +1319,7 @@ RTLIL::SigSpec AstNode::genRTLIL(int width_hint, bool sign_hint)
|
||||||
log_assert(children[1]->type == AST_RANGE);
|
log_assert(children[1]->type == AST_RANGE);
|
||||||
|
|
||||||
if (!children[0]->range_valid || !children[1]->range_valid)
|
if (!children[0]->range_valid || !children[1]->range_valid)
|
||||||
log_file_error(filename, location.first_line, "Memory `%s' with non-constant width or size!\n", str.c_str());
|
input_error("Memory `%s' with non-constant width or size!\n", str.c_str());
|
||||||
|
|
||||||
RTLIL::Memory *memory = new RTLIL::Memory;
|
RTLIL::Memory *memory = new RTLIL::Memory;
|
||||||
set_src_attr(memory, this);
|
set_src_attr(memory, this);
|
||||||
|
@ -1340,7 +1337,7 @@ RTLIL::SigSpec AstNode::genRTLIL(int width_hint, bool sign_hint)
|
||||||
|
|
||||||
for (auto &attr : attributes) {
|
for (auto &attr : attributes) {
|
||||||
if (attr.second->type != AST_CONSTANT)
|
if (attr.second->type != AST_CONSTANT)
|
||||||
log_file_error(filename, location.first_line, "Attribute `%s' with non-constant value!\n", attr.first.c_str());
|
input_error("Attribute `%s' with non-constant value!\n", attr.first.c_str());
|
||||||
memory->attributes[attr.first] = attr.second->asAttrConst();
|
memory->attributes[attr.first] = attr.second->asAttrConst();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1397,11 +1394,11 @@ RTLIL::SigSpec AstNode::genRTLIL(int width_hint, bool sign_hint)
|
||||||
} else if (flag_autowire)
|
} else if (flag_autowire)
|
||||||
log_file_warning(filename, location.first_line, "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
|
else
|
||||||
log_file_error(filename, location.first_line, "Identifier `%s' is implicitly declared and `default_nettype is set to none.\n", str.c_str());
|
input_error("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) {
|
else if (id2ast->type == AST_PARAMETER || id2ast->type == AST_LOCALPARAM || id2ast->type == AST_ENUM_ITEM) {
|
||||||
if (id2ast->children[0]->type != AST_CONSTANT)
|
if (id2ast->children[0]->type != AST_CONSTANT)
|
||||||
log_file_error(filename, location.first_line, "Parameter %s does not evaluate to constant value!\n", str.c_str());
|
input_error("Parameter %s does not evaluate to constant value!\n", str.c_str());
|
||||||
chunk = RTLIL::Const(id2ast->children[0]->bits);
|
chunk = RTLIL::Const(id2ast->children[0]->bits);
|
||||||
goto use_const_chunk;
|
goto use_const_chunk;
|
||||||
}
|
}
|
||||||
|
@ -1416,11 +1413,11 @@ RTLIL::SigSpec AstNode::genRTLIL(int width_hint, bool sign_hint)
|
||||||
is_interface = true;
|
is_interface = true;
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
log_file_error(filename, location.first_line, "Identifier `%s' doesn't map to any signal!\n", str.c_str());
|
input_error("Identifier `%s' doesn't map to any signal!\n", str.c_str());
|
||||||
}
|
}
|
||||||
|
|
||||||
if (id2ast->type == AST_MEMORY)
|
if (id2ast->type == AST_MEMORY)
|
||||||
log_file_error(filename, location.first_line, "Identifier `%s' does map to an unexpanded memory!\n", str.c_str());
|
input_error("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'
|
// 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
|
// This makes it possible for the hierarchy pass to see what are interface connections and then replace them
|
||||||
|
@ -1449,7 +1446,7 @@ RTLIL::SigSpec AstNode::genRTLIL(int width_hint, bool sign_hint)
|
||||||
use_const_chunk:
|
use_const_chunk:
|
||||||
if (children.size() != 0) {
|
if (children.size() != 0) {
|
||||||
if (children[0]->type != AST_RANGE)
|
if (children[0]->type != AST_RANGE)
|
||||||
log_file_error(filename, location.first_line, "Single range expected.\n");
|
input_error("Single range expected.\n");
|
||||||
int source_width = id2ast->range_left - id2ast->range_right + 1;
|
int source_width = id2ast->range_left - id2ast->range_right + 1;
|
||||||
int source_offset = id2ast->range_right;
|
int source_offset = id2ast->range_right;
|
||||||
int chunk_left = source_width - 1;
|
int chunk_left = source_width - 1;
|
||||||
|
@ -1468,7 +1465,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 (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)) { }
|
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)
|
if (left_at_zero_ast->type != AST_CONSTANT || right_at_zero_ast->type != AST_CONSTANT)
|
||||||
log_file_error(filename, location.first_line, "Unsupported expression on dynamic range select on signal `%s'!\n", str.c_str());
|
input_error("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;
|
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 ?
|
AstNode *fake_ast = new AstNode(AST_NONE, clone(), children[0]->children.size() >= 2 ?
|
||||||
children[0]->children[1]->clone() : children[0]->children[0]->clone());
|
children[0]->children[1]->clone() : children[0]->children[0]->clone());
|
||||||
|
@ -1553,10 +1550,10 @@ RTLIL::SigSpec AstNode::genRTLIL(int width_hint, bool sign_hint)
|
||||||
case AST_CAST_SIZE: {
|
case AST_CAST_SIZE: {
|
||||||
RTLIL::SigSpec size = children[0]->genRTLIL();
|
RTLIL::SigSpec size = children[0]->genRTLIL();
|
||||||
if (!size.is_fully_const())
|
if (!size.is_fully_const())
|
||||||
log_file_error(filename, location.first_line, "Static cast with non constant expression!\n");
|
input_error("Static cast with non constant expression!\n");
|
||||||
int width = size.as_int();
|
int width = size.as_int();
|
||||||
if (width <= 0)
|
if (width <= 0)
|
||||||
log_file_error(filename, location.first_line, "Static cast with zero or negative size!\n");
|
input_error("Static cast with zero or negative size!\n");
|
||||||
// determine the *signedness* of the expression
|
// determine the *signedness* of the expression
|
||||||
int sub_width_hint = -1;
|
int sub_width_hint = -1;
|
||||||
bool sub_sign_hint = true;
|
bool sub_sign_hint = true;
|
||||||
|
@ -1585,7 +1582,7 @@ RTLIL::SigSpec AstNode::genRTLIL(int width_hint, bool sign_hint)
|
||||||
RTLIL::SigSpec left = children[0]->genRTLIL();
|
RTLIL::SigSpec left = children[0]->genRTLIL();
|
||||||
RTLIL::SigSpec right = children[1]->genRTLIL();
|
RTLIL::SigSpec right = children[1]->genRTLIL();
|
||||||
if (!left.is_fully_const())
|
if (!left.is_fully_const())
|
||||||
log_file_error(filename, location.first_line, "Left operand of replicate expression is not constant!\n");
|
input_error("Left operand of replicate expression is not constant!\n");
|
||||||
int count = left.as_int();
|
int count = left.as_int();
|
||||||
RTLIL::SigSpec sig;
|
RTLIL::SigSpec sig;
|
||||||
for (int i = 0; i < count; i++)
|
for (int i = 0; i < count; i++)
|
||||||
|
@ -1845,7 +1842,7 @@ RTLIL::SigSpec AstNode::genRTLIL(int width_hint, bool sign_hint)
|
||||||
id2ast->meminfo(mem_width, mem_size, addr_bits);
|
id2ast->meminfo(mem_width, mem_size, addr_bits);
|
||||||
|
|
||||||
if (children[3]->type != AST_CONSTANT)
|
if (children[3]->type != AST_CONSTANT)
|
||||||
log_file_error(filename, location.first_line, "Memory init with non-constant word count!\n");
|
input_error("Memory init with non-constant word count!\n");
|
||||||
int num_words = int(children[3]->asInt(false));
|
int num_words = int(children[3]->asInt(false));
|
||||||
cell->parameters[ID::WORDS] = RTLIL::Const(num_words);
|
cell->parameters[ID::WORDS] = RTLIL::Const(num_words);
|
||||||
|
|
||||||
|
@ -1899,7 +1896,7 @@ RTLIL::SigSpec AstNode::genRTLIL(int width_hint, bool sign_hint)
|
||||||
|
|
||||||
for (auto &attr : attributes) {
|
for (auto &attr : attributes) {
|
||||||
if (attr.second->type != AST_CONSTANT)
|
if (attr.second->type != AST_CONSTANT)
|
||||||
log_file_error(filename, location.first_line, "Attribute `%s' with non-constant value!\n", attr.first.c_str());
|
input_error("Attribute `%s' with non-constant value!\n", attr.first.c_str());
|
||||||
cell->attributes[attr.first] = attr.second->asAttrConst();
|
cell->attributes[attr.first] = attr.second->asAttrConst();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1958,7 +1955,7 @@ RTLIL::SigSpec AstNode::genRTLIL(int width_hint, bool sign_hint)
|
||||||
log_file_warning(filename, location.first_line, "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), value->realvalue);
|
log_id(cell), log_id(paraname), value->realvalue);
|
||||||
else if (value->type != AST_CONSTANT)
|
else if (value->type != AST_CONSTANT)
|
||||||
log_file_error(filename, location.first_line, "Parameter %s.%s with non-constant value!\n",
|
input_error("Parameter %s.%s with non-constant value!\n",
|
||||||
log_id(cell), log_id(paraname));
|
log_id(cell), log_id(paraname));
|
||||||
cell->parameters[paraname] = value->asParaConst();
|
cell->parameters[paraname] = value->asParaConst();
|
||||||
continue;
|
continue;
|
||||||
|
@ -2006,7 +2003,7 @@ RTLIL::SigSpec AstNode::genRTLIL(int width_hint, bool sign_hint)
|
||||||
}
|
}
|
||||||
for (auto &attr : attributes) {
|
for (auto &attr : attributes) {
|
||||||
if (attr.second->type != AST_CONSTANT)
|
if (attr.second->type != AST_CONSTANT)
|
||||||
log_file_error(filename, location.first_line, "Attribute `%s' with non-constant value.\n", attr.first.c_str());
|
input_error("Attribute `%s' with non-constant value.\n", attr.first.c_str());
|
||||||
cell->attributes[attr.first] = attr.second->asAttrConst();
|
cell->attributes[attr.first] = attr.second->asAttrConst();
|
||||||
}
|
}
|
||||||
if (cell->type == ID($specify2)) {
|
if (cell->type == ID($specify2)) {
|
||||||
|
@ -2014,7 +2011,7 @@ RTLIL::SigSpec AstNode::genRTLIL(int width_hint, bool sign_hint)
|
||||||
int dst_width = GetSize(cell->getPort(ID::DST));
|
int dst_width = GetSize(cell->getPort(ID::DST));
|
||||||
bool full = cell->getParam(ID::FULL).as_bool();
|
bool full = cell->getParam(ID::FULL).as_bool();
|
||||||
if (!full && src_width != dst_width)
|
if (!full && src_width != dst_width)
|
||||||
log_file_error(filename, location.first_line, "Parallel specify SRC width does not match DST width.\n");
|
input_error("Parallel specify SRC width does not match DST width.\n");
|
||||||
cell->setParam(ID::SRC_WIDTH, Const(src_width));
|
cell->setParam(ID::SRC_WIDTH, Const(src_width));
|
||||||
cell->setParam(ID::DST_WIDTH, Const(dst_width));
|
cell->setParam(ID::DST_WIDTH, Const(dst_width));
|
||||||
}
|
}
|
||||||
|
@ -2022,7 +2019,7 @@ RTLIL::SigSpec AstNode::genRTLIL(int width_hint, bool sign_hint)
|
||||||
int dat_width = GetSize(cell->getPort(ID::DAT));
|
int dat_width = GetSize(cell->getPort(ID::DAT));
|
||||||
int dst_width = GetSize(cell->getPort(ID::DST));
|
int dst_width = GetSize(cell->getPort(ID::DST));
|
||||||
if (dat_width != dst_width)
|
if (dat_width != dst_width)
|
||||||
log_file_error(filename, location.first_line, "Specify DAT width does not match DST width.\n");
|
input_error("Specify DAT width does not match DST width.\n");
|
||||||
int src_width = GetSize(cell->getPort(ID::SRC));
|
int src_width = GetSize(cell->getPort(ID::SRC));
|
||||||
cell->setParam(ID::SRC_WIDTH, Const(src_width));
|
cell->setParam(ID::SRC_WIDTH, Const(src_width));
|
||||||
cell->setParam(ID::DST_WIDTH, Const(dst_width));
|
cell->setParam(ID::DST_WIDTH, Const(dst_width));
|
||||||
|
@ -2064,20 +2061,20 @@ RTLIL::SigSpec AstNode::genRTLIL(int width_hint, bool sign_hint)
|
||||||
log_file_warning(filename, location.first_line, "\n");
|
log_file_warning(filename, location.first_line, "\n");
|
||||||
} else if (str == "$error") {
|
} else if (str == "$error") {
|
||||||
if (sz > 0)
|
if (sz > 0)
|
||||||
log_file_error(filename, location.first_line, "%s.\n", children[0]->str.c_str());
|
input_error("%s.\n", children[0]->str.c_str());
|
||||||
else
|
else
|
||||||
log_file_error(filename, location.first_line, "\n");
|
input_error("\n");
|
||||||
} else if (str == "$fatal") {
|
} else if (str == "$fatal") {
|
||||||
// TODO: 1st parameter, if exists, is 0,1 or 2, and passed to $finish()
|
// TODO: 1st parameter, if exists, is 0,1 or 2, and passed to $finish()
|
||||||
// if no parameter is given, default value is 1
|
// if no parameter is given, default value is 1
|
||||||
// dollar_finish(sz ? children[0] : 1);
|
// dollar_finish(sz ? children[0] : 1);
|
||||||
// perhaps create & use log_file_fatal()
|
// perhaps create & use log_file_fatal()
|
||||||
if (sz > 0)
|
if (sz > 0)
|
||||||
log_file_error(filename, location.first_line, "FATAL: %s.\n", children[0]->str.c_str());
|
input_error("FATAL: %s.\n", children[0]->str.c_str());
|
||||||
else
|
else
|
||||||
log_file_error(filename, location.first_line, "FATAL.\n");
|
input_error("FATAL.\n");
|
||||||
} else {
|
} else {
|
||||||
log_file_error(filename, location.first_line, "Unknown elabortoon system task '%s'.\n", str.c_str());
|
input_error("Unknown elabortoon system task '%s'.\n", str.c_str());
|
||||||
}
|
}
|
||||||
} break;
|
} break;
|
||||||
|
|
||||||
|
@ -2095,18 +2092,18 @@ RTLIL::SigSpec AstNode::genRTLIL(int width_hint, bool sign_hint)
|
||||||
int width = width_hint;
|
int width = width_hint;
|
||||||
|
|
||||||
if (GetSize(children) > 1)
|
if (GetSize(children) > 1)
|
||||||
log_file_error(filename, location.first_line, "System function %s got %d arguments, expected 1 or 0.\n",
|
input_error("System function %s got %d arguments, expected 1 or 0.\n",
|
||||||
RTLIL::unescape_id(str).c_str(), GetSize(children));
|
RTLIL::unescape_id(str).c_str(), GetSize(children));
|
||||||
|
|
||||||
if (GetSize(children) == 1) {
|
if (GetSize(children) == 1) {
|
||||||
if (children[0]->type != AST_CONSTANT)
|
if (children[0]->type != AST_CONSTANT)
|
||||||
log_file_error(filename, location.first_line, "System function %s called with non-const argument!\n",
|
input_error("System function %s called with non-const argument!\n",
|
||||||
RTLIL::unescape_id(str).c_str());
|
RTLIL::unescape_id(str).c_str());
|
||||||
width = children[0]->asInt(true);
|
width = children[0]->asInt(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (width <= 0)
|
if (width <= 0)
|
||||||
log_file_error(filename, location.first_line, "Failed to detect width of %s!\n", RTLIL::unescape_id(str).c_str());
|
input_error("Failed to detect width of %s!\n", RTLIL::unescape_id(str).c_str());
|
||||||
|
|
||||||
Cell *cell = current_module->addCell(myid, str.substr(1));
|
Cell *cell = current_module->addCell(myid, str.substr(1));
|
||||||
set_src_attr(cell, this);
|
set_src_attr(cell, this);
|
||||||
|
@ -2115,7 +2112,7 @@ RTLIL::SigSpec AstNode::genRTLIL(int width_hint, bool sign_hint)
|
||||||
if (attributes.count(ID::reg)) {
|
if (attributes.count(ID::reg)) {
|
||||||
auto &attr = attributes.at(ID::reg);
|
auto &attr = attributes.at(ID::reg);
|
||||||
if (attr->type != AST_CONSTANT)
|
if (attr->type != AST_CONSTANT)
|
||||||
log_file_error(filename, location.first_line, "Attribute `reg' with non-constant value!\n");
|
input_error("Attribute `reg' with non-constant value!\n");
|
||||||
cell->attributes[ID::reg] = attr->asAttrConst();
|
cell->attributes[ID::reg] = attr->asAttrConst();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2133,7 +2130,7 @@ RTLIL::SigSpec AstNode::genRTLIL(int width_hint, bool sign_hint)
|
||||||
default:
|
default:
|
||||||
for (auto f : log_files)
|
for (auto f : log_files)
|
||||||
current_ast_mod->dumpAst(f, "verilog-ast> ");
|
current_ast_mod->dumpAst(f, "verilog-ast> ");
|
||||||
log_file_error(filename, location.first_line, "Don't know how to generate RTLIL code for %s node!\n", type2str(type).c_str());
|
input_error("Don't know how to generate RTLIL code for %s node!\n", type2str(type).c_str());
|
||||||
}
|
}
|
||||||
|
|
||||||
return RTLIL::SigSpec();
|
return RTLIL::SigSpec();
|
||||||
|
|
|
@ -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 there's no next character, that's a problem
|
||||||
if (i+1 >= sformat.length())
|
if (i+1 >= sformat.length())
|
||||||
log_file_error(filename, location.first_line, "System task `%s' called with `%%' at end of string.\n", str.c_str());
|
input_error("System task `%s' called with `%%' at end of string.\n", str.c_str());
|
||||||
|
|
||||||
char cformat = sformat[++i];
|
char cformat = sformat[++i];
|
||||||
|
|
||||||
|
@ -95,13 +95,13 @@ std::string AstNode::process_format_str(const std::string &sformat, int next_arg
|
||||||
case 'x':
|
case 'x':
|
||||||
case 'X':
|
case 'X':
|
||||||
if (next_arg >= GetSize(children))
|
if (next_arg >= GetSize(children))
|
||||||
log_file_error(filename, location.first_line, "Missing argument for %%%c format specifier in system task `%s'.\n",
|
input_error("Missing argument for %%%c format specifier in system task `%s'.\n",
|
||||||
cformat, str.c_str());
|
cformat, str.c_str());
|
||||||
|
|
||||||
node_arg = children[next_arg++];
|
node_arg = children[next_arg++];
|
||||||
while (node_arg->simplify(true, false, false, stage, width_hint, sign_hint, false)) { }
|
while (node_arg->simplify(true, false, false, stage, width_hint, sign_hint, false)) { }
|
||||||
if (node_arg->type != AST_CONSTANT)
|
if (node_arg->type != AST_CONSTANT)
|
||||||
log_file_error(filename, location.first_line, "Failed to evaluate system task `%s' with non-constant argument.\n", str.c_str());
|
input_error("Failed to evaluate system task `%s' with non-constant argument.\n", str.c_str());
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 'm':
|
case 'm':
|
||||||
|
@ -118,7 +118,7 @@ std::string AstNode::process_format_str(const std::string &sformat, int next_arg
|
||||||
|
|
||||||
default:
|
default:
|
||||||
unsupported_format:
|
unsupported_format:
|
||||||
log_file_error(filename, location.first_line, "System task `%s' called with invalid/unsupported format specifier.\n", str.c_str());
|
input_error("System task `%s' called with invalid/unsupported format specifier.\n", str.c_str());
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -266,7 +266,7 @@ static int range_width(AstNode *node, AstNode *rnode)
|
||||||
{
|
{
|
||||||
log_assert(rnode->type==AST_RANGE);
|
log_assert(rnode->type==AST_RANGE);
|
||||||
if (!rnode->range_valid) {
|
if (!rnode->range_valid) {
|
||||||
log_file_error(node->filename, node->location.first_line, "Size must be constant in packed struct/union member %s\n", node->str.c_str());
|
node->input_error("Size must be constant in packed struct/union member %s\n", node->str.c_str());
|
||||||
|
|
||||||
}
|
}
|
||||||
// note: range swapping has already been checked for
|
// note: range swapping has already been checked for
|
||||||
|
@ -275,7 +275,7 @@ static int range_width(AstNode *node, AstNode *rnode)
|
||||||
|
|
||||||
[[noreturn]] static void struct_array_packing_error(AstNode *node)
|
[[noreturn]] static void struct_array_packing_error(AstNode *node)
|
||||||
{
|
{
|
||||||
log_file_error(node->filename, node->location.first_line, "Unpacked array in packed struct/union member %s\n", node->str.c_str());
|
node->input_error("Unpacked array in packed struct/union member %s\n", node->str.c_str());
|
||||||
}
|
}
|
||||||
|
|
||||||
static void save_struct_range_dimensions(AstNode *node, AstNode *rnode)
|
static void save_struct_range_dimensions(AstNode *node, AstNode *rnode)
|
||||||
|
@ -394,10 +394,8 @@ static int size_packed_struct(AstNode *snode, int base_offset)
|
||||||
packed_width = width;
|
packed_width = width;
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
if (packed_width != width) {
|
if (packed_width != width)
|
||||||
|
node->input_error("member %s of a packed union has %d bits, expecting %d\n", node->str.c_str(), width, packed_width);
|
||||||
log_file_error(node->filename, node->location.first_line, "member %s of a packed union has %d bits, expecting %d\n", node->str.c_str(), width, packed_width);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
|
@ -409,7 +407,7 @@ static int size_packed_struct(AstNode *snode, int base_offset)
|
||||||
|
|
||||||
[[noreturn]] static void struct_op_error(AstNode *node)
|
[[noreturn]] static void struct_op_error(AstNode *node)
|
||||||
{
|
{
|
||||||
log_file_error(node->filename, node->location.first_line, "Unsupported operation for struct/union member %s\n", node->str.c_str()+1);
|
node->input_error("Unsupported operation for struct/union member %s\n", node->str.c_str()+1);
|
||||||
}
|
}
|
||||||
|
|
||||||
static AstNode *node_int(int ival)
|
static AstNode *node_int(int ival)
|
||||||
|
@ -1034,14 +1032,14 @@ bool AstNode::simplify(bool const_fold, bool at_zero, bool in_lvalue, int stage,
|
||||||
{
|
{
|
||||||
int nargs = GetSize(children);
|
int nargs = GetSize(children);
|
||||||
if (nargs < 1)
|
if (nargs < 1)
|
||||||
log_file_error(filename, location.first_line, "System task `%s' got %d arguments, expected >= 1.\n",
|
input_error("System task `%s' got %d arguments, expected >= 1.\n",
|
||||||
str.c_str(), int(children.size()));
|
str.c_str(), int(children.size()));
|
||||||
|
|
||||||
// First argument is the format string
|
// First argument is the format string
|
||||||
AstNode *node_string = children[0];
|
AstNode *node_string = children[0];
|
||||||
while (node_string->simplify(true, false, false, stage, width_hint, sign_hint, false)) { }
|
while (node_string->simplify(true, false, false, stage, width_hint, sign_hint, false)) { }
|
||||||
if (node_string->type != AST_CONSTANT)
|
if (node_string->type != AST_CONSTANT)
|
||||||
log_file_error(filename, location.first_line, "Failed to evaluate system task `%s' with non-constant 1st argument.\n", str.c_str());
|
input_error("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 sformat = node_string->bitsAsConst().decode_string();
|
||||||
std::string sout = process_format_str(sformat, 1, stage, width_hint, sign_hint);
|
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)
|
// Finally, print the message (only include a \n for $display, not for $write)
|
||||||
|
@ -1138,7 +1136,7 @@ bool AstNode::simplify(bool const_fold, bool at_zero, bool in_lvalue, int stage,
|
||||||
continue;
|
continue;
|
||||||
wires_are_incompatible:
|
wires_are_incompatible:
|
||||||
if (stage > 1)
|
if (stage > 1)
|
||||||
log_file_error(filename, location.first_line, "Incompatible re-declaration of wire %s.\n", node->str.c_str());
|
input_error("Incompatible re-declaration of wire %s.\n", node->str.c_str());
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
this_wire_scope[node->str] = node;
|
this_wire_scope[node->str] = node;
|
||||||
|
@ -1157,7 +1155,7 @@ bool AstNode::simplify(bool const_fold, bool at_zero, bool in_lvalue, int stage,
|
||||||
if (current_scope.count(enode->str) == 0)
|
if (current_scope.count(enode->str) == 0)
|
||||||
current_scope[enode->str] = enode;
|
current_scope[enode->str] = enode;
|
||||||
else
|
else
|
||||||
log_file_error(filename, location.first_line, "enum item %s already exists\n", enode->str.c_str());
|
input_error("enum item %s already exists\n", enode->str.c_str());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1197,7 +1195,7 @@ bool AstNode::simplify(bool const_fold, bool at_zero, bool in_lvalue, int stage,
|
||||||
if (current_scope.count(enode->str) == 0)
|
if (current_scope.count(enode->str) == 0)
|
||||||
current_scope[enode->str] = enode;
|
current_scope[enode->str] = enode;
|
||||||
else
|
else
|
||||||
log_file_error(filename, location.first_line, "enum item %s already exists in package\n", enode->str.c_str());
|
input_error("enum item %s already exists in package\n", enode->str.c_str());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1213,7 +1211,7 @@ bool AstNode::simplify(bool const_fold, bool at_zero, bool in_lvalue, int stage,
|
||||||
if (type == AST_ALWAYS || type == AST_INITIAL)
|
if (type == AST_ALWAYS || type == AST_INITIAL)
|
||||||
{
|
{
|
||||||
if (current_always != nullptr)
|
if (current_always != nullptr)
|
||||||
log_file_error(filename, location.first_line, "Invalid nesting of always blocks and/or initializations.\n");
|
input_error("Invalid nesting of always blocks and/or initializations.\n");
|
||||||
|
|
||||||
current_always = this;
|
current_always = this;
|
||||||
current_always_clocked = false;
|
current_always_clocked = false;
|
||||||
|
@ -1279,16 +1277,14 @@ bool AstNode::simplify(bool const_fold, bool at_zero, bool in_lvalue, int stage,
|
||||||
port_name = child->str;
|
port_name = child->str;
|
||||||
else {
|
else {
|
||||||
if (port_counter >= module->ports.size())
|
if (port_counter >= module->ports.size())
|
||||||
log_file_error(filename, location.first_line,
|
input_error("Cell instance has more ports than the module!\n");
|
||||||
"Cell instance has more ports than the module!\n");
|
|
||||||
port_name = module->ports[port_counter++];
|
port_name = module->ports[port_counter++];
|
||||||
}
|
}
|
||||||
|
|
||||||
// find the port's wire in the underlying module
|
// find the port's wire in the underlying module
|
||||||
const RTLIL::Wire *ref = module->wire(port_name);
|
const RTLIL::Wire *ref = module->wire(port_name);
|
||||||
if (ref == nullptr)
|
if (ref == nullptr)
|
||||||
log_file_error(filename, location.first_line,
|
input_error("Cell instance refers to port %s which does not exist in module %s!.\n",
|
||||||
"Cell instance refers to port %s which does not exist in module %s!.\n",
|
|
||||||
log_id(port_name), log_id(module->name));
|
log_id(port_name), log_id(module->name));
|
||||||
|
|
||||||
// select the argument, if present
|
// select the argument, if present
|
||||||
|
@ -1494,7 +1490,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)
|
while (!children[1]->basic_prep && children[1]->simplify(false, false, false, stage, -1, false, true) == true)
|
||||||
did_something = true;
|
did_something = true;
|
||||||
if (!children[1]->range_valid)
|
if (!children[1]->range_valid)
|
||||||
log_file_error(filename, location.first_line, "Non-constant width range on parameter decl.\n");
|
input_error("Non-constant width range on parameter decl.\n");
|
||||||
width_hint = max(width_hint, children[1]->range_left - children[1]->range_right + 1);
|
width_hint = max(width_hint, children[1]->range_left - children[1]->range_right + 1);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
@ -1506,7 +1502,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))
|
while (!children[1]->basic_prep && children[1]->simplify(false, false, false, stage, -1, false, in_param))
|
||||||
did_something = true;
|
did_something = true;
|
||||||
if (!children[1]->range_valid)
|
if (!children[1]->range_valid)
|
||||||
log_file_error(filename, location.first_line, "Non-constant width range on enum item decl.\n");
|
input_error("Non-constant width range on enum item decl.\n");
|
||||||
width_hint = max(width_hint, children[1]->range_left - children[1]->range_right + 1);
|
width_hint = max(width_hint, children[1]->range_left - children[1]->range_right + 1);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
@ -1812,7 +1808,7 @@ bool AstNode::simplify(bool const_fold, bool at_zero, bool in_lvalue, int stage,
|
||||||
if (type == AST_DEFPARAM && !children.empty())
|
if (type == AST_DEFPARAM && !children.empty())
|
||||||
{
|
{
|
||||||
if (children[0]->type != AST_IDENTIFIER)
|
if (children[0]->type != AST_IDENTIFIER)
|
||||||
log_file_error(filename, location.first_line, "Module name in defparam contains non-constant expressions!\n");
|
input_error("Module name in defparam contains non-constant expressions!\n");
|
||||||
|
|
||||||
string modname, paramname = children[0]->str;
|
string modname, paramname = children[0]->str;
|
||||||
|
|
||||||
|
@ -1829,12 +1825,12 @@ bool AstNode::simplify(bool const_fold, bool at_zero, bool in_lvalue, int stage,
|
||||||
}
|
}
|
||||||
|
|
||||||
if (pos == std::string::npos)
|
if (pos == std::string::npos)
|
||||||
log_file_error(filename, location.first_line, "Can't find object for defparam `%s`!\n", RTLIL::unescape_id(paramname).c_str());
|
input_error("Can't find object for defparam `%s`!\n", RTLIL::unescape_id(paramname).c_str());
|
||||||
|
|
||||||
paramname = "\\" + paramname.substr(pos+1);
|
paramname = "\\" + paramname.substr(pos+1);
|
||||||
|
|
||||||
if (current_scope.at(modname)->type != AST_CELL)
|
if (current_scope.at(modname)->type != AST_CELL)
|
||||||
log_file_error(filename, location.first_line, "Defparam argument `%s . %s` does not match a cell!\n",
|
input_error("Defparam argument `%s . %s` does not match a cell!\n",
|
||||||
RTLIL::unescape_id(modname).c_str(), RTLIL::unescape_id(paramname).c_str());
|
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);
|
AstNode *paraset = new AstNode(AST_PARASET, children[1]->clone(), GetSize(children) > 2 ? children[2]->clone() : NULL);
|
||||||
|
@ -1863,11 +1859,11 @@ bool AstNode::simplify(bool const_fold, bool at_zero, bool in_lvalue, int stage,
|
||||||
log_assert(children[0]->type == AST_WIRETYPE);
|
log_assert(children[0]->type == AST_WIRETYPE);
|
||||||
auto type_name = children[0]->str;
|
auto type_name = children[0]->str;
|
||||||
if (!current_scope.count(type_name)) {
|
if (!current_scope.count(type_name)) {
|
||||||
log_file_error(filename, location.first_line, "Unknown identifier `%s' used as type name\n", type_name.c_str());
|
input_error("Unknown identifier `%s' used as type name\n", type_name.c_str());
|
||||||
}
|
}
|
||||||
AstNode *resolved_type_node = current_scope.at(type_name);
|
AstNode *resolved_type_node = current_scope.at(type_name);
|
||||||
if (resolved_type_node->type != AST_TYPEDEF)
|
if (resolved_type_node->type != AST_TYPEDEF)
|
||||||
log_file_error(filename, location.first_line, "`%s' does not name a type\n", type_name.c_str());
|
input_error("`%s' does not name a type\n", type_name.c_str());
|
||||||
log_assert(resolved_type_node->children.size() == 1);
|
log_assert(resolved_type_node->children.size() == 1);
|
||||||
AstNode *template_node = resolved_type_node->children[0];
|
AstNode *template_node = resolved_type_node->children[0];
|
||||||
|
|
||||||
|
@ -1928,11 +1924,11 @@ bool AstNode::simplify(bool const_fold, bool at_zero, bool in_lvalue, int stage,
|
||||||
log_assert(children[1]->type == AST_WIRETYPE);
|
log_assert(children[1]->type == AST_WIRETYPE);
|
||||||
auto type_name = children[1]->str;
|
auto type_name = children[1]->str;
|
||||||
if (!current_scope.count(type_name)) {
|
if (!current_scope.count(type_name)) {
|
||||||
log_file_error(filename, location.first_line, "Unknown identifier `%s' used as type name\n", type_name.c_str());
|
input_error("Unknown identifier `%s' used as type name\n", type_name.c_str());
|
||||||
}
|
}
|
||||||
AstNode *resolved_type_node = current_scope.at(type_name);
|
AstNode *resolved_type_node = current_scope.at(type_name);
|
||||||
if (resolved_type_node->type != AST_TYPEDEF)
|
if (resolved_type_node->type != AST_TYPEDEF)
|
||||||
log_file_error(filename, location.first_line, "`%s' does not name a type\n", type_name.c_str());
|
input_error("`%s' does not name a type\n", type_name.c_str());
|
||||||
log_assert(resolved_type_node->children.size() == 1);
|
log_assert(resolved_type_node->children.size() == 1);
|
||||||
AstNode *template_node = resolved_type_node->children[0];
|
AstNode *template_node = resolved_type_node->children[0];
|
||||||
|
|
||||||
|
@ -1955,7 +1951,7 @@ bool AstNode::simplify(bool const_fold, bool at_zero, bool in_lvalue, int stage,
|
||||||
children.pop_back();
|
children.pop_back();
|
||||||
|
|
||||||
if (template_node->type == AST_MEMORY)
|
if (template_node->type == AST_MEMORY)
|
||||||
log_file_error(filename, location.first_line, "unpacked array type `%s' cannot be used for a parameter\n", children[1]->str.c_str());
|
input_error("unpacked array type `%s' cannot be used for a parameter\n", children[1]->str.c_str());
|
||||||
is_signed = template_node->is_signed;
|
is_signed = template_node->is_signed;
|
||||||
is_string = template_node->is_string;
|
is_string = template_node->is_string;
|
||||||
is_custom_type = template_node->is_custom_type;
|
is_custom_type = template_node->is_custom_type;
|
||||||
|
@ -1976,7 +1972,7 @@ bool AstNode::simplify(bool const_fold, bool at_zero, bool in_lvalue, int stage,
|
||||||
if (type == AST_PREFIX) {
|
if (type == AST_PREFIX) {
|
||||||
if (children[0]->type != AST_CONSTANT) {
|
if (children[0]->type != AST_CONSTANT) {
|
||||||
// dumpAst(NULL, "> ");
|
// dumpAst(NULL, "> ");
|
||||||
log_file_error(filename, location.first_line, "Index in generate block prefix syntax is not constant!\n");
|
input_error("Index in generate block prefix syntax is not constant!\n");
|
||||||
}
|
}
|
||||||
if (children[1]->type == AST_PREFIX)
|
if (children[1]->type == AST_PREFIX)
|
||||||
children[1]->simplify(const_fold, at_zero, in_lvalue, stage, width_hint, sign_hint, in_param);
|
children[1]->simplify(const_fold, at_zero, in_lvalue, stage, width_hint, sign_hint, in_param);
|
||||||
|
@ -1992,9 +1988,9 @@ bool AstNode::simplify(bool const_fold, bool at_zero, bool in_lvalue, int stage,
|
||||||
// evaluate TO_BITS nodes
|
// evaluate TO_BITS nodes
|
||||||
if (type == AST_TO_BITS) {
|
if (type == AST_TO_BITS) {
|
||||||
if (children[0]->type != AST_CONSTANT)
|
if (children[0]->type != AST_CONSTANT)
|
||||||
log_file_error(filename, location.first_line, "Left operand of to_bits expression is not constant!\n");
|
input_error("Left operand of to_bits expression is not constant!\n");
|
||||||
if (children[1]->type != AST_CONSTANT)
|
if (children[1]->type != AST_CONSTANT)
|
||||||
log_file_error(filename, location.first_line, "Right operand of to_bits expression is not constant!\n");
|
input_error("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);
|
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);
|
newNode = mkconst_bits(new_value.bits, children[1]->is_signed);
|
||||||
goto apply_newNode;
|
goto apply_newNode;
|
||||||
|
@ -2044,17 +2040,17 @@ bool AstNode::simplify(bool const_fold, bool at_zero, bool in_lvalue, int stage,
|
||||||
if (attributes.count(ID::force_upto)) {
|
if (attributes.count(ID::force_upto)) {
|
||||||
AstNode *val = attributes[ID::force_upto];
|
AstNode *val = attributes[ID::force_upto];
|
||||||
if (val->type != AST_CONSTANT)
|
if (val->type != AST_CONSTANT)
|
||||||
log_file_error(filename, location.first_line, "Attribute `force_upto' with non-constant value!\n");
|
input_error("Attribute `force_upto' with non-constant value!\n");
|
||||||
force_upto = val->asAttrConst().as_bool();
|
force_upto = val->asAttrConst().as_bool();
|
||||||
}
|
}
|
||||||
if (attributes.count(ID::force_downto)) {
|
if (attributes.count(ID::force_downto)) {
|
||||||
AstNode *val = attributes[ID::force_downto];
|
AstNode *val = attributes[ID::force_downto];
|
||||||
if (val->type != AST_CONSTANT)
|
if (val->type != AST_CONSTANT)
|
||||||
log_file_error(filename, location.first_line, "Attribute `force_downto' with non-constant value!\n");
|
input_error("Attribute `force_downto' with non-constant value!\n");
|
||||||
force_downto = val->asAttrConst().as_bool();
|
force_downto = val->asAttrConst().as_bool();
|
||||||
}
|
}
|
||||||
if (force_upto && force_downto)
|
if (force_upto && force_downto)
|
||||||
log_file_error(filename, location.first_line, "Attributes `force_downto' and `force_upto' cannot be both set!\n");
|
input_error("Attributes `force_downto' and `force_upto' cannot be both set!\n");
|
||||||
if ((force_upto && !range_swapped) || (force_downto && range_swapped)) {
|
if ((force_upto && !range_swapped) || (force_downto && range_swapped)) {
|
||||||
std::swap(range_left, range_right);
|
std::swap(range_left, range_right);
|
||||||
range_swapped = force_upto;
|
range_swapped = force_upto;
|
||||||
|
@ -2078,7 +2074,7 @@ bool AstNode::simplify(bool const_fold, bool at_zero, bool in_lvalue, int stage,
|
||||||
multirange_swapped.clear();
|
multirange_swapped.clear();
|
||||||
for (auto range : children[1]->children) {
|
for (auto range : children[1]->children) {
|
||||||
if (!range->range_valid)
|
if (!range->range_valid)
|
||||||
log_file_error(filename, location.first_line, "Non-constant range on memory decl.\n");
|
input_error("Non-constant range on memory decl.\n");
|
||||||
multirange_dimensions.push_back(min(range->range_left, range->range_right));
|
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);
|
multirange_dimensions.push_back(max(range->range_left, range->range_right) - min(range->range_left, range->range_right) + 1);
|
||||||
multirange_swapped.push_back(range->range_swapped);
|
multirange_swapped.push_back(range->range_swapped);
|
||||||
|
@ -2098,7 +2094,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++)
|
for (int i = 0; 2*i < GetSize(id2ast->multirange_dimensions); i++)
|
||||||
{
|
{
|
||||||
if (GetSize(children[0]->children) <= i)
|
if (GetSize(children[0]->children) <= i)
|
||||||
log_file_error(filename, location.first_line, "Insufficient number of array indices for %s.\n", log_id(str));
|
input_error("Insufficient number of array indices for %s.\n", log_id(str));
|
||||||
|
|
||||||
AstNode *new_index_expr = children[0]->children[i]->children.at(0)->clone();
|
AstNode *new_index_expr = children[0]->children[i]->children.at(0)->clone();
|
||||||
|
|
||||||
|
@ -2127,7 +2123,7 @@ 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 (type == AST_PARAMETER || type == AST_LOCALPARAM || type == AST_ENUM_ITEM) {
|
||||||
if (children.size() > 1 && children[1]->type == AST_RANGE) {
|
if (children.size() > 1 && children[1]->type == AST_RANGE) {
|
||||||
if (!children[1]->range_valid)
|
if (!children[1]->range_valid)
|
||||||
log_file_error(filename, location.first_line, "Non-constant width range on parameter decl.\n");
|
input_error("Non-constant width range on parameter decl.\n");
|
||||||
int width = std::abs(children[1]->range_left - children[1]->range_right) + 1;
|
int width = std::abs(children[1]->range_left - children[1]->range_right) + 1;
|
||||||
if (children[0]->type == AST_REALVALUE) {
|
if (children[0]->type == AST_REALVALUE) {
|
||||||
RTLIL::Const constvalue = children[0]->realAsConst(width);
|
RTLIL::Const constvalue = children[0]->realAsConst(width);
|
||||||
|
@ -2228,7 +2224,7 @@ bool AstNode::simplify(bool const_fold, bool at_zero, bool in_lvalue, int stage,
|
||||||
}
|
}
|
||||||
if (current_scope.count(str) == 0) {
|
if (current_scope.count(str) == 0) {
|
||||||
if (current_ast_mod == nullptr) {
|
if (current_ast_mod == nullptr) {
|
||||||
log_file_error(filename, location.first_line, "Identifier `%s' is implicitly declared outside of a module.\n", str.c_str());
|
input_error("Identifier `%s' is implicitly declared outside of a module.\n", str.c_str());
|
||||||
} else if (flag_autowire || str == "\\$global_clock") {
|
} else if (flag_autowire || str == "\\$global_clock") {
|
||||||
AstNode *auto_wire = new AstNode(AST_AUTOWIRE);
|
AstNode *auto_wire = new AstNode(AST_AUTOWIRE);
|
||||||
auto_wire->str = str;
|
auto_wire->str = str;
|
||||||
|
@ -2236,7 +2232,7 @@ bool AstNode::simplify(bool const_fold, bool at_zero, bool in_lvalue, int stage,
|
||||||
current_scope[str] = auto_wire;
|
current_scope[str] = auto_wire;
|
||||||
did_something = true;
|
did_something = true;
|
||||||
} else {
|
} else {
|
||||||
log_file_error(filename, location.first_line, "Identifier `%s' is implicitly declared and `default_nettype is set to none.\n", str.c_str());
|
input_error("Identifier `%s' is implicitly declared and `default_nettype is set to none.\n", str.c_str());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (id2ast != current_scope[str]) {
|
if (id2ast != current_scope[str]) {
|
||||||
|
@ -2249,7 +2245,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 && stage == 2)
|
if (type == AST_IDENTIFIER && children.size() == 2 && children[0]->type == AST_RANGE && children[1]->type == AST_RANGE && !in_lvalue && stage == 2)
|
||||||
{
|
{
|
||||||
if (id2ast == NULL || id2ast->type != AST_MEMORY || children[0]->children.size() != 1)
|
if (id2ast == NULL || id2ast->type != AST_MEMORY || children[0]->children.size() != 1)
|
||||||
log_file_error(filename, location.first_line, "Invalid bit-select on memory access!\n");
|
input_error("Invalid bit-select on memory access!\n");
|
||||||
|
|
||||||
int mem_width, mem_size, addr_bits;
|
int mem_width, mem_size, addr_bits;
|
||||||
id2ast->meminfo(mem_width, mem_size, addr_bits);
|
id2ast->meminfo(mem_width, mem_size, addr_bits);
|
||||||
|
@ -2303,7 +2299,7 @@ bool AstNode::simplify(bool const_fold, bool at_zero, bool in_lvalue, int stage,
|
||||||
}
|
}
|
||||||
|
|
||||||
if (type == AST_WHILE)
|
if (type == AST_WHILE)
|
||||||
log_file_error(filename, location.first_line, "While loops are only allowed in constant functions!\n");
|
input_error("While loops are only allowed in constant functions!\n");
|
||||||
|
|
||||||
if (type == AST_REPEAT)
|
if (type == AST_REPEAT)
|
||||||
{
|
{
|
||||||
|
@ -2314,7 +2310,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)) { }
|
while (count->simplify(true, false, false, stage, 32, true, false)) { }
|
||||||
|
|
||||||
if (count->type != AST_CONSTANT)
|
if (count->type != AST_CONSTANT)
|
||||||
log_file_error(filename, location.first_line, "Repeat loops outside must have constant repeat counts!\n");
|
input_error("Repeat loops outside must have constant repeat counts!\n");
|
||||||
|
|
||||||
// convert to a block with the body repeated n times
|
// convert to a block with the body repeated n times
|
||||||
type = AST_BLOCK;
|
type = AST_BLOCK;
|
||||||
|
@ -2349,17 +2345,17 @@ bool AstNode::simplify(bool const_fold, bool at_zero, bool in_lvalue, int stage,
|
||||||
}
|
}
|
||||||
|
|
||||||
if (init_ast->type != AST_ASSIGN_EQ)
|
if (init_ast->type != AST_ASSIGN_EQ)
|
||||||
log_file_error(filename, location.first_line, "Unsupported 1st expression of %s for-loop!\n", loop_type_str);
|
input_error("Unsupported 1st expression of %s for-loop!\n", loop_type_str);
|
||||||
if (next_ast->type != AST_ASSIGN_EQ)
|
if (next_ast->type != AST_ASSIGN_EQ)
|
||||||
log_file_error(filename, location.first_line, "Unsupported 3rd expression of %s for-loop!\n", loop_type_str);
|
input_error("Unsupported 3rd expression of %s for-loop!\n", loop_type_str);
|
||||||
|
|
||||||
if (init_ast->children[0]->id2ast == NULL || init_ast->children[0]->id2ast->type != var_type)
|
if (init_ast->children[0]->id2ast == NULL || init_ast->children[0]->id2ast->type != var_type)
|
||||||
log_file_error(filename, location.first_line, "Left hand side of 1st expression of %s for-loop is not a %s!\n", loop_type_str, var_type_str);
|
input_error("Left hand side of 1st expression of %s for-loop is not a %s!\n", loop_type_str, var_type_str);
|
||||||
if (next_ast->children[0]->id2ast == NULL || next_ast->children[0]->id2ast->type != var_type)
|
if (next_ast->children[0]->id2ast == NULL || next_ast->children[0]->id2ast->type != var_type)
|
||||||
log_file_error(filename, location.first_line, "Left hand side of 3rd expression of %s for-loop is not a %s!\n", loop_type_str, var_type_str);
|
input_error("Left hand side of 3rd expression of %s for-loop is not a %s!\n", loop_type_str, var_type_str);
|
||||||
|
|
||||||
if (init_ast->children[0]->id2ast != next_ast->children[0]->id2ast)
|
if (init_ast->children[0]->id2ast != next_ast->children[0]->id2ast)
|
||||||
log_file_error(filename, location.first_line, "Incompatible left-hand sides in 1st and 3rd expression of %s for-loop!\n", loop_type_str);
|
input_error("Incompatible left-hand sides in 1st and 3rd expression of %s for-loop!\n", loop_type_str);
|
||||||
|
|
||||||
// eval 1st expression
|
// eval 1st expression
|
||||||
AstNode *varbuf = init_ast->children[1]->clone();
|
AstNode *varbuf = init_ast->children[1]->clone();
|
||||||
|
@ -2371,7 +2367,7 @@ bool AstNode::simplify(bool const_fold, bool at_zero, bool in_lvalue, int stage,
|
||||||
}
|
}
|
||||||
|
|
||||||
if (varbuf->type != AST_CONSTANT)
|
if (varbuf->type != AST_CONSTANT)
|
||||||
log_file_error(filename, location.first_line, "Right hand side of 1st expression of %s for-loop is not constant!\n", loop_type_str);
|
input_error("Right hand side of 1st expression of %s for-loop is not constant!\n", loop_type_str);
|
||||||
|
|
||||||
auto resolved = current_scope.at(init_ast->children[0]->str);
|
auto resolved = current_scope.at(init_ast->children[0]->str);
|
||||||
if (resolved->range_valid) {
|
if (resolved->range_valid) {
|
||||||
|
@ -2412,7 +2408,7 @@ bool AstNode::simplify(bool const_fold, bool at_zero, bool in_lvalue, int stage,
|
||||||
}
|
}
|
||||||
|
|
||||||
if (buf->type != AST_CONSTANT)
|
if (buf->type != AST_CONSTANT)
|
||||||
log_file_error(filename, location.first_line, "2nd expression of %s for-loop is not constant!\n", loop_type_str);
|
input_error("2nd expression of %s for-loop is not constant!\n", loop_type_str);
|
||||||
|
|
||||||
if (buf->integer == 0) {
|
if (buf->integer == 0) {
|
||||||
delete buf;
|
delete buf;
|
||||||
|
@ -2463,7 +2459,7 @@ bool AstNode::simplify(bool const_fold, bool at_zero, bool in_lvalue, int stage,
|
||||||
}
|
}
|
||||||
|
|
||||||
if (buf->type != AST_CONSTANT)
|
if (buf->type != AST_CONSTANT)
|
||||||
log_file_error(filename, location.first_line, "Right hand side of 3rd expression of %s for-loop is not constant (%s)!\n", loop_type_str, type2str(buf->type).c_str());
|
input_error("Right hand side of 3rd expression of %s for-loop is not constant (%s)!\n", loop_type_str, type2str(buf->type).c_str());
|
||||||
|
|
||||||
delete varbuf->children[0];
|
delete varbuf->children[0];
|
||||||
varbuf->children[0] = buf;
|
varbuf->children[0] = buf;
|
||||||
|
@ -2489,7 +2485,7 @@ bool AstNode::simplify(bool const_fold, bool at_zero, bool in_lvalue, int stage,
|
||||||
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)
|
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_assert(!VERILOG_FRONTEND::sv_mode);
|
log_assert(!VERILOG_FRONTEND::sv_mode);
|
||||||
log_file_error(children[i]->filename, children[i]->location.first_line, "Local declaration in unnamed block is only supported in SystemVerilog mode!\n");
|
children[i]->input_error("Local declaration in unnamed block is only supported in SystemVerilog mode!\n");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2546,7 +2542,7 @@ bool AstNode::simplify(bool const_fold, bool at_zero, bool in_lvalue, int stage,
|
||||||
if (buf->type != AST_CONSTANT) {
|
if (buf->type != AST_CONSTANT) {
|
||||||
// for (auto f : log_files)
|
// for (auto f : log_files)
|
||||||
// dumpAst(f, "verilog-ast> ");
|
// dumpAst(f, "verilog-ast> ");
|
||||||
log_file_error(filename, location.first_line, "Condition for generate if is not constant!\n");
|
input_error("Condition for generate if is not constant!\n");
|
||||||
}
|
}
|
||||||
if (buf->asBool() != 0) {
|
if (buf->asBool() != 0) {
|
||||||
delete buf;
|
delete buf;
|
||||||
|
@ -2586,7 +2582,7 @@ bool AstNode::simplify(bool const_fold, bool at_zero, bool in_lvalue, int stage,
|
||||||
if (buf->type != AST_CONSTANT) {
|
if (buf->type != AST_CONSTANT) {
|
||||||
// for (auto f : log_files)
|
// for (auto f : log_files)
|
||||||
// dumpAst(f, "verilog-ast> ");
|
// dumpAst(f, "verilog-ast> ");
|
||||||
log_file_error(filename, location.first_line, "Condition for generate case is not constant!\n");
|
input_error("Condition for generate case is not constant!\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
bool ref_signed = buf->is_signed;
|
bool ref_signed = buf->is_signed;
|
||||||
|
@ -2620,7 +2616,7 @@ bool AstNode::simplify(bool const_fold, bool at_zero, bool in_lvalue, int stage,
|
||||||
if (buf->type != AST_CONSTANT) {
|
if (buf->type != AST_CONSTANT) {
|
||||||
// for (auto f : log_files)
|
// for (auto f : log_files)
|
||||||
// dumpAst(f, "verilog-ast> ");
|
// dumpAst(f, "verilog-ast> ");
|
||||||
log_file_error(filename, location.first_line, "Expression in generate case is not constant!\n");
|
input_error("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();
|
bool is_selected = RTLIL::const_eq(ref_value, buf->bitsAsConst(), ref_signed && buf->is_signed, ref_signed && buf->is_signed, 1).as_bool();
|
||||||
|
@ -2660,7 +2656,7 @@ bool AstNode::simplify(bool const_fold, bool at_zero, bool in_lvalue, int stage,
|
||||||
if (type == AST_CELLARRAY)
|
if (type == AST_CELLARRAY)
|
||||||
{
|
{
|
||||||
if (!children.at(0)->range_valid)
|
if (!children.at(0)->range_valid)
|
||||||
log_file_error(filename, location.first_line, "Non-constant array range on cell array.\n");
|
input_error("Non-constant array range on cell array.\n");
|
||||||
|
|
||||||
newNode = new AstNode(AST_GENBLOCK);
|
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;
|
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;
|
||||||
|
@ -2671,7 +2667,7 @@ bool AstNode::simplify(bool const_fold, bool at_zero, bool in_lvalue, int stage,
|
||||||
newNode->children.push_back(new_cell);
|
newNode->children.push_back(new_cell);
|
||||||
new_cell->str += stringf("[%d]", idx);
|
new_cell->str += stringf("[%d]", idx);
|
||||||
if (new_cell->type == AST_PRIMITIVE) {
|
if (new_cell->type == AST_PRIMITIVE) {
|
||||||
log_file_error(filename, location.first_line, "Cell arrays of primitives are currently not supported.\n");
|
input_error("Cell arrays of primitives are currently not supported.\n");
|
||||||
} else {
|
} else {
|
||||||
log_assert(new_cell->children.at(0)->type == AST_CELLTYPE);
|
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());
|
new_cell->children.at(0)->str = stringf("$array:%d:%d:%s", i, num, new_cell->children.at(0)->str.c_str());
|
||||||
|
@ -2685,7 +2681,7 @@ bool AstNode::simplify(bool const_fold, bool at_zero, bool in_lvalue, int stage,
|
||||||
if (type == AST_PRIMITIVE)
|
if (type == AST_PRIMITIVE)
|
||||||
{
|
{
|
||||||
if (children.size() < 2)
|
if (children.size() < 2)
|
||||||
log_file_error(filename, location.first_line, "Insufficient number of arguments for primitive `%s'!\n", str.c_str());
|
input_error("Insufficient number of arguments for primitive `%s'!\n", str.c_str());
|
||||||
|
|
||||||
std::vector<AstNode*> children_list;
|
std::vector<AstNode*> children_list;
|
||||||
for (auto child : children) {
|
for (auto child : children) {
|
||||||
|
@ -2700,7 +2696,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 (str == "bufif0" || str == "bufif1" || str == "notif0" || str == "notif1")
|
||||||
{
|
{
|
||||||
if (children_list.size() != 3)
|
if (children_list.size() != 3)
|
||||||
log_file_error(filename, location.first_line, "Invalid number of arguments for primitive `%s'!\n", str.c_str());
|
input_error("Invalid number of arguments for primitive `%s'!\n", str.c_str());
|
||||||
|
|
||||||
std::vector<RTLIL::State> z_const(1, RTLIL::State::Sz);
|
std::vector<RTLIL::State> z_const(1, RTLIL::State::Sz);
|
||||||
|
|
||||||
|
@ -2816,7 +2812,7 @@ bool AstNode::simplify(bool const_fold, bool at_zero, bool in_lvalue, int stage,
|
||||||
AstNode *range = children[0]->children[0];
|
AstNode *range = children[0]->children[0];
|
||||||
|
|
||||||
if (!try_determine_range_width(range, result_width))
|
if (!try_determine_range_width(range, result_width))
|
||||||
log_file_error(filename, location.first_line, "Unsupported expression on dynamic range select on signal `%s'!\n", str.c_str());
|
input_error("Unsupported expression on dynamic range select on signal `%s'!\n", str.c_str());
|
||||||
|
|
||||||
if (range->children.size() >= 2)
|
if (range->children.size() >= 2)
|
||||||
shift_expr = range->children[1]->clone();
|
shift_expr = range->children[1]->clone();
|
||||||
|
@ -2829,7 +2825,7 @@ bool AstNode::simplify(bool const_fold, bool at_zero, bool in_lvalue, int stage,
|
||||||
AstNode *node = children[0]->id2ast->attributes.at(ID::nowrshmsk);
|
AstNode *node = children[0]->id2ast->attributes.at(ID::nowrshmsk);
|
||||||
while (node->simplify(true, false, false, stage, -1, false, false)) { }
|
while (node->simplify(true, false, false, stage, -1, false, false)) { }
|
||||||
if (node->type != AST_CONSTANT)
|
if (node->type != AST_CONSTANT)
|
||||||
log_file_error(filename, location.first_line, "Non-constant value for `nowrshmsk' attribute on `%s'!\n", children[0]->id2ast->str.c_str());
|
input_error("Non-constant value for `nowrshmsk' attribute on `%s'!\n", children[0]->id2ast->str.c_str());
|
||||||
if (node->asAttrConst().as_bool())
|
if (node->asAttrConst().as_bool())
|
||||||
use_case_method = true;
|
use_case_method = true;
|
||||||
}
|
}
|
||||||
|
@ -3229,7 +3225,7 @@ skip_dynamic_range_lvalue_expansion:;
|
||||||
int width;
|
int width;
|
||||||
|
|
||||||
if (!try_determine_range_width(the_range, width))
|
if (!try_determine_range_width(the_range, width))
|
||||||
log_file_error(filename, location.first_line, "Unsupported expression on dynamic range select on signal `%s'!\n", str.c_str());
|
input_error("Unsupported expression on dynamic range select on signal `%s'!\n", str.c_str());
|
||||||
|
|
||||||
if (the_range->children.size() >= 2)
|
if (the_range->children.size() >= 2)
|
||||||
offset_ast = the_range->children[1]->clone();
|
offset_ast = the_range->children[1]->clone();
|
||||||
|
@ -3337,11 +3333,11 @@ skip_dynamic_range_lvalue_expansion:;
|
||||||
int num_steps = 1;
|
int num_steps = 1;
|
||||||
|
|
||||||
if (GetSize(children) != 1 && GetSize(children) != 2)
|
if (GetSize(children) != 1 && GetSize(children) != 2)
|
||||||
log_file_error(filename, location.first_line, "System function %s got %d arguments, expected 1 or 2.\n",
|
input_error("System function %s got %d arguments, expected 1 or 2.\n",
|
||||||
RTLIL::unescape_id(str).c_str(), int(children.size()));
|
RTLIL::unescape_id(str).c_str(), int(children.size()));
|
||||||
|
|
||||||
if (!current_always_clocked)
|
if (!current_always_clocked)
|
||||||
log_file_error(filename, location.first_line, "System function %s is only allowed in clocked blocks.\n",
|
input_error("System function %s is only allowed in clocked blocks.\n",
|
||||||
RTLIL::unescape_id(str).c_str());
|
RTLIL::unescape_id(str).c_str());
|
||||||
|
|
||||||
if (GetSize(children) == 2)
|
if (GetSize(children) == 2)
|
||||||
|
@ -3349,7 +3345,7 @@ skip_dynamic_range_lvalue_expansion:;
|
||||||
AstNode *buf = children[1]->clone();
|
AstNode *buf = children[1]->clone();
|
||||||
while (buf->simplify(true, false, false, stage, -1, false, false)) { }
|
while (buf->simplify(true, false, false, stage, -1, false, false)) { }
|
||||||
if (buf->type != AST_CONSTANT)
|
if (buf->type != AST_CONSTANT)
|
||||||
log_file_error(filename, location.first_line, "Failed to evaluate system function `%s' with non-constant value.\n", str.c_str());
|
input_error("Failed to evaluate system function `%s' with non-constant value.\n", str.c_str());
|
||||||
|
|
||||||
num_steps = buf->asInt(true);
|
num_steps = buf->asInt(true);
|
||||||
delete buf;
|
delete buf;
|
||||||
|
@ -3412,11 +3408,11 @@ skip_dynamic_range_lvalue_expansion:;
|
||||||
if (str == "\\$stable" || str == "\\$rose" || str == "\\$fell" || str == "\\$changed")
|
if (str == "\\$stable" || str == "\\$rose" || str == "\\$fell" || str == "\\$changed")
|
||||||
{
|
{
|
||||||
if (GetSize(children) != 1)
|
if (GetSize(children) != 1)
|
||||||
log_file_error(filename, location.first_line, "System function %s got %d arguments, expected 1.\n",
|
input_error("System function %s got %d arguments, expected 1.\n",
|
||||||
RTLIL::unescape_id(str).c_str(), int(children.size()));
|
RTLIL::unescape_id(str).c_str(), int(children.size()));
|
||||||
|
|
||||||
if (!current_always_clocked)
|
if (!current_always_clocked)
|
||||||
log_file_error(filename, location.first_line, "System function %s is only allowed in clocked blocks.\n",
|
input_error("System function %s is only allowed in clocked blocks.\n",
|
||||||
RTLIL::unescape_id(str).c_str());
|
RTLIL::unescape_id(str).c_str());
|
||||||
|
|
||||||
AstNode *present = children.at(0)->clone();
|
AstNode *present = children.at(0)->clone();
|
||||||
|
@ -3454,13 +3450,13 @@ skip_dynamic_range_lvalue_expansion:;
|
||||||
if (str == "\\$clog2")
|
if (str == "\\$clog2")
|
||||||
{
|
{
|
||||||
if (children.size() != 1)
|
if (children.size() != 1)
|
||||||
log_file_error(filename, location.first_line, "System function %s got %d arguments, expected 1.\n",
|
input_error("System function %s got %d arguments, expected 1.\n",
|
||||||
RTLIL::unescape_id(str).c_str(), int(children.size()));
|
RTLIL::unescape_id(str).c_str(), int(children.size()));
|
||||||
|
|
||||||
AstNode *buf = children[0]->clone();
|
AstNode *buf = children[0]->clone();
|
||||||
while (buf->simplify(true, false, false, stage, width_hint, sign_hint, false)) { }
|
while (buf->simplify(true, false, false, stage, width_hint, sign_hint, false)) { }
|
||||||
if (buf->type != AST_CONSTANT)
|
if (buf->type != AST_CONSTANT)
|
||||||
log_file_error(filename, location.first_line, "Failed to evaluate system function `%s' with non-constant value.\n", str.c_str());
|
input_error("Failed to evaluate system function `%s' with non-constant value.\n", str.c_str());
|
||||||
|
|
||||||
RTLIL::Const arg_value = buf->bitsAsConst();
|
RTLIL::Const arg_value = buf->bitsAsConst();
|
||||||
if (arg_value.as_bool())
|
if (arg_value.as_bool())
|
||||||
|
@ -3481,11 +3477,11 @@ skip_dynamic_range_lvalue_expansion:;
|
||||||
int dim = 1;
|
int dim = 1;
|
||||||
if (str == "\\$bits") {
|
if (str == "\\$bits") {
|
||||||
if (children.size() != 1)
|
if (children.size() != 1)
|
||||||
log_file_error(filename, location.first_line, "System function %s got %d arguments, expected 1.\n",
|
input_error("System function %s got %d arguments, expected 1.\n",
|
||||||
RTLIL::unescape_id(str).c_str(), int(children.size()));
|
RTLIL::unescape_id(str).c_str(), int(children.size()));
|
||||||
} else {
|
} else {
|
||||||
if (children.size() != 1 && children.size() != 2)
|
if (children.size() != 1 && children.size() != 2)
|
||||||
log_file_error(filename, location.first_line, "System function %s got %d arguments, expected 1 or 2.\n",
|
input_error("System function %s got %d arguments, expected 1 or 2.\n",
|
||||||
RTLIL::unescape_id(str).c_str(), int(children.size()));
|
RTLIL::unescape_id(str).c_str(), int(children.size()));
|
||||||
if (children.size() == 2) {
|
if (children.size() == 2) {
|
||||||
AstNode *buf = children[1]->clone();
|
AstNode *buf = children[1]->clone();
|
||||||
|
@ -3509,7 +3505,7 @@ skip_dynamic_range_lvalue_expansion:;
|
||||||
if (id_ast == NULL && current_scope.count(buf->str))
|
if (id_ast == NULL && current_scope.count(buf->str))
|
||||||
id_ast = current_scope.at(buf->str);
|
id_ast = current_scope.at(buf->str);
|
||||||
if (!id_ast)
|
if (!id_ast)
|
||||||
log_file_error(filename, location.first_line, "Failed to resolve identifier %s for width detection!\n", buf->str.c_str());
|
input_error("Failed to resolve identifier %s for width detection!\n", buf->str.c_str());
|
||||||
|
|
||||||
// Check for item in packed struct / union
|
// Check for item in packed struct / union
|
||||||
AST::AstNode *item_node = get_struct_member(buf);
|
AST::AstNode *item_node = get_struct_member(buf);
|
||||||
|
@ -3518,13 +3514,13 @@ skip_dynamic_range_lvalue_expansion:;
|
||||||
dim += buf->integer;
|
dim += buf->integer;
|
||||||
if (item_node->multirange_dimensions.empty()) {
|
if (item_node->multirange_dimensions.empty()) {
|
||||||
if (dim != 1)
|
if (dim != 1)
|
||||||
log_file_error(filename, location.first_line, "Dimension %d out of range in `%s', as it only has one dimension!\n", dim, item_node->str.c_str());
|
input_error("Dimension %d out of range in `%s', as it only has one dimension!\n", dim, item_node->str.c_str());
|
||||||
left = high = item_node->range_left;
|
left = high = item_node->range_left;
|
||||||
right = low = item_node->range_right;
|
right = low = item_node->range_right;
|
||||||
} else {
|
} else {
|
||||||
int dims = GetSize(item_node->multirange_dimensions)/2;
|
int dims = GetSize(item_node->multirange_dimensions)/2;
|
||||||
if (dim < 1 || dim > dims)
|
if (dim < 1 || dim > dims)
|
||||||
log_file_error(filename, location.first_line, "Dimension %d out of range in `%s', as it only has dimensions 1..%d!\n", dim, item_node->str.c_str(), dims);
|
input_error("Dimension %d out of range in `%s', as it only has dimensions 1..%d!\n", dim, item_node->str.c_str(), dims);
|
||||||
right = low = get_struct_range_offset(item_node, dim - 1);
|
right = low = get_struct_range_offset(item_node, dim - 1);
|
||||||
left = high = low + get_struct_range_width(item_node, dim - 1) - 1;
|
left = high = low + get_struct_range_width(item_node, dim - 1) - 1;
|
||||||
if (item_node->multirange_swapped[dim - 1]) {
|
if (item_node->multirange_swapped[dim - 1]) {
|
||||||
|
@ -3568,17 +3564,17 @@ skip_dynamic_range_lvalue_expansion:;
|
||||||
if (str == "\\$bits") {
|
if (str == "\\$bits") {
|
||||||
if (mem_range->type == AST_RANGE) {
|
if (mem_range->type == AST_RANGE) {
|
||||||
if (!mem_range->range_valid)
|
if (!mem_range->range_valid)
|
||||||
log_file_error(filename, location.first_line, "Failed to detect width of memory access `%s'!\n", buf->str.c_str());
|
input_error("Failed to detect width of memory access `%s'!\n", buf->str.c_str());
|
||||||
mem_depth = mem_range->range_left - mem_range->range_right + 1;
|
mem_depth = mem_range->range_left - mem_range->range_right + 1;
|
||||||
} else
|
} else
|
||||||
log_file_error(filename, location.first_line, "Unknown memory depth AST type in `%s'!\n", buf->str.c_str());
|
input_error("Unknown memory depth AST type in `%s'!\n", buf->str.c_str());
|
||||||
} else {
|
} else {
|
||||||
// $size(), $left(), $right(), $high(), $low()
|
// $size(), $left(), $right(), $high(), $low()
|
||||||
int dims = 1;
|
int dims = 1;
|
||||||
if (mem_range->type == AST_RANGE) {
|
if (mem_range->type == AST_RANGE) {
|
||||||
if (id_ast->multirange_dimensions.empty()) {
|
if (id_ast->multirange_dimensions.empty()) {
|
||||||
if (!mem_range->range_valid)
|
if (!mem_range->range_valid)
|
||||||
log_file_error(filename, location.first_line, "Failed to detect width of memory access `%s'!\n", buf->str.c_str());
|
input_error("Failed to detect width of memory access `%s'!\n", buf->str.c_str());
|
||||||
if (dim == 1) {
|
if (dim == 1) {
|
||||||
left = mem_range->range_right;
|
left = mem_range->range_right;
|
||||||
right = mem_range->range_left;
|
right = mem_range->range_left;
|
||||||
|
@ -3599,10 +3595,10 @@ skip_dynamic_range_lvalue_expansion:;
|
||||||
left = high;
|
left = high;
|
||||||
}
|
}
|
||||||
} else if ((dim > dims+1) || (dim < 0))
|
} else if ((dim > dims+1) || (dim < 0))
|
||||||
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);
|
input_error("Dimension %d out of range in `%s', as it only has dimensions 1..%d!\n", dim, buf->str.c_str(), dims+1);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
log_file_error(filename, location.first_line, "Unknown memory depth AST type in `%s'!\n", buf->str.c_str());
|
input_error("Unknown memory depth AST type in `%s'!\n", buf->str.c_str());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -3639,18 +3635,18 @@ skip_dynamic_range_lvalue_expansion:;
|
||||||
|
|
||||||
if (func_with_two_arguments) {
|
if (func_with_two_arguments) {
|
||||||
if (children.size() != 2)
|
if (children.size() != 2)
|
||||||
log_file_error(filename, location.first_line, "System function %s got %d arguments, expected 2.\n",
|
input_error("System function %s got %d arguments, expected 2.\n",
|
||||||
RTLIL::unescape_id(str).c_str(), int(children.size()));
|
RTLIL::unescape_id(str).c_str(), int(children.size()));
|
||||||
} else {
|
} else {
|
||||||
if (children.size() != 1)
|
if (children.size() != 1)
|
||||||
log_file_error(filename, location.first_line, "System function %s got %d arguments, expected 1.\n",
|
input_error("System function %s got %d arguments, expected 1.\n",
|
||||||
RTLIL::unescape_id(str).c_str(), int(children.size()));
|
RTLIL::unescape_id(str).c_str(), int(children.size()));
|
||||||
}
|
}
|
||||||
|
|
||||||
if (children.size() >= 1) {
|
if (children.size() >= 1) {
|
||||||
while (children[0]->simplify(true, false, false, stage, width_hint, sign_hint, false)) { }
|
while (children[0]->simplify(true, false, false, stage, width_hint, sign_hint, false)) { }
|
||||||
if (!children[0]->isConst())
|
if (!children[0]->isConst())
|
||||||
log_file_error(filename, location.first_line, "Failed to evaluate system function `%s' with non-constant argument.\n",
|
input_error("Failed to evaluate system function `%s' with non-constant argument.\n",
|
||||||
RTLIL::unescape_id(str).c_str());
|
RTLIL::unescape_id(str).c_str());
|
||||||
int child_width_hint = width_hint;
|
int child_width_hint = width_hint;
|
||||||
bool child_sign_hint = sign_hint;
|
bool child_sign_hint = sign_hint;
|
||||||
|
@ -3661,7 +3657,7 @@ skip_dynamic_range_lvalue_expansion:;
|
||||||
if (children.size() >= 2) {
|
if (children.size() >= 2) {
|
||||||
while (children[1]->simplify(true, false, false, stage, width_hint, sign_hint, false)) { }
|
while (children[1]->simplify(true, false, false, stage, width_hint, sign_hint, false)) { }
|
||||||
if (!children[1]->isConst())
|
if (!children[1]->isConst())
|
||||||
log_file_error(filename, location.first_line, "Failed to evaluate system function `%s' with non-constant argument.\n",
|
input_error("Failed to evaluate system function `%s' with non-constant argument.\n",
|
||||||
RTLIL::unescape_id(str).c_str());
|
RTLIL::unescape_id(str).c_str());
|
||||||
int child_width_hint = width_hint;
|
int child_width_hint = width_hint;
|
||||||
bool child_sign_hint = sign_hint;
|
bool child_sign_hint = sign_hint;
|
||||||
|
@ -3704,7 +3700,7 @@ skip_dynamic_range_lvalue_expansion:;
|
||||||
AstNode *node_string = children[0];
|
AstNode *node_string = children[0];
|
||||||
while (node_string->simplify(true, false, false, stage, width_hint, sign_hint, false)) { }
|
while (node_string->simplify(true, false, false, stage, width_hint, sign_hint, false)) { }
|
||||||
if (node_string->type != AST_CONSTANT)
|
if (node_string->type != AST_CONSTANT)
|
||||||
log_file_error(filename, location.first_line, "Failed to evaluate system function `%s' with non-constant 1st argument.\n", str.c_str());
|
input_error("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 sformat = node_string->bitsAsConst().decode_string();
|
||||||
std::string sout = process_format_str(sformat, 1, stage, width_hint, sign_hint);
|
std::string sout = process_format_str(sformat, 1, stage, width_hint, sign_hint);
|
||||||
newNode = AstNode::mkconst_str(sout);
|
newNode = AstNode::mkconst_str(sout);
|
||||||
|
@ -3713,7 +3709,7 @@ skip_dynamic_range_lvalue_expansion:;
|
||||||
|
|
||||||
if (str == "\\$countbits") {
|
if (str == "\\$countbits") {
|
||||||
if (children.size() < 2)
|
if (children.size() < 2)
|
||||||
log_file_error(filename, location.first_line, "System function %s got %d arguments, expected at least 2.\n",
|
input_error("System function %s got %d arguments, expected at least 2.\n",
|
||||||
RTLIL::unescape_id(str).c_str(), int(children.size()));
|
RTLIL::unescape_id(str).c_str(), int(children.size()));
|
||||||
|
|
||||||
std::vector<RTLIL::State> control_bits;
|
std::vector<RTLIL::State> control_bits;
|
||||||
|
@ -3723,9 +3719,9 @@ skip_dynamic_range_lvalue_expansion:;
|
||||||
AstNode *node = children[i];
|
AstNode *node = children[i];
|
||||||
while (node->simplify(true, false, false, stage, -1, false, false)) { }
|
while (node->simplify(true, false, false, stage, -1, false, false)) { }
|
||||||
if (node->type != AST_CONSTANT)
|
if (node->type != AST_CONSTANT)
|
||||||
log_file_error(filename, location.first_line, "Failed to evaluate system function `%s' with non-constant control bit argument.\n", str.c_str());
|
input_error("Failed to evaluate system function `%s' with non-constant control bit argument.\n", str.c_str());
|
||||||
if (node->bits.size() != 1)
|
if (node->bits.size() != 1)
|
||||||
log_file_error(filename, location.first_line, "Failed to evaluate system function `%s' with control bit width != 1.\n", str.c_str());
|
input_error("Failed to evaluate system function `%s' with control bit width != 1.\n", str.c_str());
|
||||||
control_bits.push_back(node->bits[0]);
|
control_bits.push_back(node->bits[0]);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -3772,7 +3768,7 @@ skip_dynamic_range_lvalue_expansion:;
|
||||||
|
|
||||||
if (str == "\\$countones" || str == "\\$isunknown" || str == "\\$onehot" || str == "\\$onehot0") {
|
if (str == "\\$countones" || str == "\\$isunknown" || str == "\\$onehot" || str == "\\$onehot0") {
|
||||||
if (children.size() != 1)
|
if (children.size() != 1)
|
||||||
log_file_error(filename, location.first_line, "System function %s got %d arguments, expected 1.\n",
|
input_error("System function %s got %d arguments, expected 1.\n",
|
||||||
RTLIL::unescape_id(str).c_str(), int(children.size()));
|
RTLIL::unescape_id(str).c_str(), int(children.size()));
|
||||||
|
|
||||||
AstNode *countbits = clone();
|
AstNode *countbits = clone();
|
||||||
|
@ -3812,14 +3808,14 @@ skip_dynamic_range_lvalue_expansion:;
|
||||||
for (int i = 2; i < GetSize(dpi_decl->children); i++)
|
for (int i = 2; i < GetSize(dpi_decl->children); i++)
|
||||||
{
|
{
|
||||||
if (i-2 >= GetSize(children))
|
if (i-2 >= GetSize(children))
|
||||||
log_file_error(filename, location.first_line, "Insufficient number of arguments in DPI function call.\n");
|
input_error("Insufficient number of arguments in DPI function call.\n");
|
||||||
|
|
||||||
argtypes.push_back(RTLIL::unescape_id(dpi_decl->children.at(i)->str));
|
argtypes.push_back(RTLIL::unescape_id(dpi_decl->children.at(i)->str));
|
||||||
args.push_back(children.at(i-2)->clone());
|
args.push_back(children.at(i-2)->clone());
|
||||||
while (args.back()->simplify(true, false, false, stage, -1, false, true)) { }
|
while (args.back()->simplify(true, false, false, stage, -1, false, true)) { }
|
||||||
|
|
||||||
if (args.back()->type != AST_CONSTANT && args.back()->type != AST_REALVALUE)
|
if (args.back()->type != AST_CONSTANT && args.back()->type != AST_REALVALUE)
|
||||||
log_file_error(filename, location.first_line, "Failed to evaluate DPI function with non-constant argument.\n");
|
input_error("Failed to evaluate DPI function with non-constant argument.\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
newNode = dpi_call(rtype, fname, argtypes, args);
|
newNode = dpi_call(rtype, fname, argtypes, args);
|
||||||
|
@ -3833,7 +3829,7 @@ skip_dynamic_range_lvalue_expansion:;
|
||||||
if (current_scope.count(str) == 0)
|
if (current_scope.count(str) == 0)
|
||||||
str = try_pop_module_prefix();
|
str = try_pop_module_prefix();
|
||||||
if (current_scope.count(str) == 0 || current_scope[str]->type != AST_FUNCTION)
|
if (current_scope.count(str) == 0 || current_scope[str]->type != AST_FUNCTION)
|
||||||
log_file_error(filename, location.first_line, "Can't resolve function name `%s'.\n", str.c_str());
|
input_error("Can't resolve function name `%s'.\n", str.c_str());
|
||||||
}
|
}
|
||||||
|
|
||||||
if (type == AST_TCALL)
|
if (type == AST_TCALL)
|
||||||
|
@ -3841,26 +3837,26 @@ skip_dynamic_range_lvalue_expansion:;
|
||||||
if (str == "$finish" || str == "$stop")
|
if (str == "$finish" || str == "$stop")
|
||||||
{
|
{
|
||||||
if (!current_always || current_always->type != AST_INITIAL)
|
if (!current_always || current_always->type != AST_INITIAL)
|
||||||
log_file_error(filename, location.first_line, "System task `%s' outside initial block is unsupported.\n", str.c_str());
|
input_error("System task `%s' outside initial block is unsupported.\n", str.c_str());
|
||||||
|
|
||||||
log_file_error(filename, location.first_line, "System task `%s' executed.\n", str.c_str());
|
input_error("System task `%s' executed.\n", str.c_str());
|
||||||
}
|
}
|
||||||
|
|
||||||
if (str == "\\$readmemh" || str == "\\$readmemb")
|
if (str == "\\$readmemh" || str == "\\$readmemb")
|
||||||
{
|
{
|
||||||
if (GetSize(children) < 2 || GetSize(children) > 4)
|
if (GetSize(children) < 2 || GetSize(children) > 4)
|
||||||
log_file_error(filename, location.first_line, "System function %s got %d arguments, expected 2-4.\n",
|
input_error("System function %s got %d arguments, expected 2-4.\n",
|
||||||
RTLIL::unescape_id(str).c_str(), int(children.size()));
|
RTLIL::unescape_id(str).c_str(), int(children.size()));
|
||||||
|
|
||||||
AstNode *node_filename = children[0]->clone();
|
AstNode *node_filename = children[0]->clone();
|
||||||
while (node_filename->simplify(true, false, false, stage, width_hint, sign_hint, false)) { }
|
while (node_filename->simplify(true, false, false, stage, width_hint, sign_hint, false)) { }
|
||||||
if (node_filename->type != AST_CONSTANT)
|
if (node_filename->type != AST_CONSTANT)
|
||||||
log_file_error(filename, location.first_line, "Failed to evaluate system function `%s' with non-constant 1st argument.\n", str.c_str());
|
input_error("Failed to evaluate system function `%s' with non-constant 1st argument.\n", str.c_str());
|
||||||
|
|
||||||
AstNode *node_memory = children[1]->clone();
|
AstNode *node_memory = children[1]->clone();
|
||||||
while (node_memory->simplify(true, false, false, stage, width_hint, sign_hint, false)) { }
|
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)
|
if (node_memory->type != AST_IDENTIFIER || node_memory->id2ast == nullptr || node_memory->id2ast->type != AST_MEMORY)
|
||||||
log_file_error(filename, location.first_line, "Failed to evaluate system function `%s' with non-memory 2nd argument.\n", str.c_str());
|
input_error("Failed to evaluate system function `%s' with non-memory 2nd argument.\n", str.c_str());
|
||||||
|
|
||||||
int start_addr = -1, finish_addr = -1;
|
int start_addr = -1, finish_addr = -1;
|
||||||
|
|
||||||
|
@ -3868,7 +3864,7 @@ skip_dynamic_range_lvalue_expansion:;
|
||||||
AstNode *node_addr = children[2]->clone();
|
AstNode *node_addr = children[2]->clone();
|
||||||
while (node_addr->simplify(true, false, false, stage, width_hint, sign_hint, false)) { }
|
while (node_addr->simplify(true, false, false, stage, width_hint, sign_hint, false)) { }
|
||||||
if (node_addr->type != AST_CONSTANT)
|
if (node_addr->type != AST_CONSTANT)
|
||||||
log_file_error(filename, location.first_line, "Failed to evaluate system function `%s' with non-constant 3rd argument.\n", str.c_str());
|
input_error("Failed to evaluate system function `%s' with non-constant 3rd argument.\n", str.c_str());
|
||||||
start_addr = int(node_addr->asInt(false));
|
start_addr = int(node_addr->asInt(false));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -3876,7 +3872,7 @@ skip_dynamic_range_lvalue_expansion:;
|
||||||
AstNode *node_addr = children[3]->clone();
|
AstNode *node_addr = children[3]->clone();
|
||||||
while (node_addr->simplify(true, false, false, stage, width_hint, sign_hint, false)) { }
|
while (node_addr->simplify(true, false, false, stage, width_hint, sign_hint, false)) { }
|
||||||
if (node_addr->type != AST_CONSTANT)
|
if (node_addr->type != AST_CONSTANT)
|
||||||
log_file_error(filename, location.first_line, "Failed to evaluate system function `%s' with non-constant 4th argument.\n", str.c_str());
|
input_error("Failed to evaluate system function `%s' with non-constant 4th argument.\n", str.c_str());
|
||||||
finish_addr = int(node_addr->asInt(false));
|
finish_addr = int(node_addr->asInt(false));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -3906,7 +3902,7 @@ skip_dynamic_range_lvalue_expansion:;
|
||||||
if (current_scope.count(str) == 0)
|
if (current_scope.count(str) == 0)
|
||||||
str = try_pop_module_prefix();
|
str = try_pop_module_prefix();
|
||||||
if (current_scope.count(str) == 0 || current_scope[str]->type != AST_TASK)
|
if (current_scope.count(str) == 0 || current_scope[str]->type != AST_TASK)
|
||||||
log_file_error(filename, location.first_line, "Can't resolve task name `%s'.\n", str.c_str());
|
input_error("Can't resolve task name `%s'.\n", str.c_str());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -3943,9 +3939,9 @@ skip_dynamic_range_lvalue_expansion:;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (in_param)
|
if (in_param)
|
||||||
log_file_error(filename, location.first_line, "Non-constant function call in constant expression.\n");
|
input_error("Non-constant function call in constant expression.\n");
|
||||||
if (require_const_eval)
|
if (require_const_eval)
|
||||||
log_file_error(filename, location.first_line, "Function %s can only be called with constant arguments.\n", str.c_str());
|
input_error("Function %s can only be called with constant arguments.\n", str.c_str());
|
||||||
}
|
}
|
||||||
|
|
||||||
size_t arg_count = 0;
|
size_t arg_count = 0;
|
||||||
|
@ -4066,7 +4062,7 @@ skip_dynamic_range_lvalue_expansion:;
|
||||||
goto tcall_incompatible_wires;
|
goto tcall_incompatible_wires;
|
||||||
} else {
|
} else {
|
||||||
tcall_incompatible_wires:
|
tcall_incompatible_wires:
|
||||||
log_file_error(filename, location.first_line, "Incompatible re-declaration of wire %s.\n", child->str.c_str());
|
input_error("Incompatible re-declaration of wire %s.\n", child->str.c_str());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -4498,7 +4494,7 @@ AstNode *AstNode::readmem(bool is_readmemh, std::string mem_filename, AstNode *m
|
||||||
yosys_input_files.insert(mem_filename);
|
yosys_input_files.insert(mem_filename);
|
||||||
}
|
}
|
||||||
if (f.fail() || GetSize(mem_filename) == 0)
|
if (f.fail() || GetSize(mem_filename) == 0)
|
||||||
log_file_error(filename, location.first_line, "Can not open file `%s` for %s.\n", mem_filename.c_str(), str.c_str());
|
input_error("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);
|
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;
|
int range_left = memory->children[1]->range_left, range_right = memory->children[1]->range_right;
|
||||||
|
@ -4544,7 +4540,7 @@ AstNode *AstNode::readmem(bool is_readmemh, std::string mem_filename, AstNode *m
|
||||||
char *endptr;
|
char *endptr;
|
||||||
cursor = strtol(nptr, &endptr, 16);
|
cursor = strtol(nptr, &endptr, 16);
|
||||||
if (!*nptr || *endptr)
|
if (!*nptr || *endptr)
|
||||||
log_file_error(filename, location.first_line, "Can not parse address `%s` for %s.\n", nptr, str.c_str());
|
input_error("Can not parse address `%s` for %s.\n", nptr, str.c_str());
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -4905,7 +4901,7 @@ bool AstNode::mem2reg_check(pool<AstNode*> &mem2reg_set)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
if (children.empty() || children[0]->type != AST_RANGE || GetSize(children[0]->children) != 1)
|
if (children.empty() || children[0]->type != AST_RANGE || GetSize(children[0]->children) != 1)
|
||||||
log_file_error(filename, location.first_line, "Invalid array access.\n");
|
input_error("Invalid array access.\n");
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
@ -5339,7 +5335,7 @@ bool AstNode::replace_variables(std::map<std::string, AstNode::varinfo_t> &varia
|
||||||
if (children.size() != 1 || children.at(0)->type != AST_RANGE) {
|
if (children.size() != 1 || children.at(0)->type != AST_RANGE) {
|
||||||
if (!must_succeed)
|
if (!must_succeed)
|
||||||
return false;
|
return false;
|
||||||
log_file_error(filename, location.first_line, "Memory access in constant function is not supported\n%s: ...called from here.\n",
|
input_error("Memory access in constant function is not supported\n%s: ...called from here.\n",
|
||||||
fcall->loc_string().c_str());
|
fcall->loc_string().c_str());
|
||||||
}
|
}
|
||||||
if (!children.at(0)->replace_variables(variables, fcall, must_succeed))
|
if (!children.at(0)->replace_variables(variables, fcall, must_succeed))
|
||||||
|
@ -5348,7 +5344,7 @@ bool AstNode::replace_variables(std::map<std::string, AstNode::varinfo_t> &varia
|
||||||
if (!children.at(0)->range_valid) {
|
if (!children.at(0)->range_valid) {
|
||||||
if (!must_succeed)
|
if (!must_succeed)
|
||||||
return false;
|
return false;
|
||||||
log_file_error(filename, location.first_line, "Non-constant range\n%s: ... called from here.\n",
|
input_error("Non-constant range\n%s: ... called from here.\n",
|
||||||
fcall->loc_string().c_str());
|
fcall->loc_string().c_str());
|
||||||
}
|
}
|
||||||
offset = min(children.at(0)->range_left, children.at(0)->range_right);
|
offset = min(children.at(0)->range_left, children.at(0)->range_right);
|
||||||
|
@ -5403,7 +5399,7 @@ AstNode *AstNode::eval_const_function(AstNode *fcall, bool must_succeed)
|
||||||
if (!stmt->range_valid) {
|
if (!stmt->range_valid) {
|
||||||
if (!must_succeed)
|
if (!must_succeed)
|
||||||
goto finished;
|
goto finished;
|
||||||
log_file_error(stmt->filename, stmt->location.first_line, "Can't determine size of variable %s\n%s: ... called from here.\n",
|
stmt->input_error("Can't determine size of variable %s\n%s: ... called from here.\n",
|
||||||
stmt->str.c_str(), fcall->loc_string().c_str());
|
stmt->str.c_str(), fcall->loc_string().c_str());
|
||||||
}
|
}
|
||||||
AstNode::varinfo_t &variable = variables[stmt->str];
|
AstNode::varinfo_t &variable = variables[stmt->str];
|
||||||
|
@ -5411,7 +5407,7 @@ AstNode *AstNode::eval_const_function(AstNode *fcall, bool must_succeed)
|
||||||
// if this variable has already been declared as an input, check the
|
// if this variable has already been declared as an input, check the
|
||||||
// sizes match if it already had an explicit size
|
// sizes match if it already had an explicit size
|
||||||
if (variable.arg && variable.explicitly_sized && variable.val.size() != width) {
|
if (variable.arg && variable.explicitly_sized && variable.val.size() != width) {
|
||||||
log_file_error(filename, location.first_line, "Incompatible re-declaration of constant function wire %s.\n", stmt->str.c_str());
|
input_error("Incompatible re-declaration of constant function wire %s.\n", stmt->str.c_str());
|
||||||
}
|
}
|
||||||
variable.val = RTLIL::Const(RTLIL::State::Sx, width);
|
variable.val = RTLIL::Const(RTLIL::State::Sx, width);
|
||||||
variable.offset = stmt->range_swapped ? stmt->range_left : stmt->range_right;
|
variable.offset = stmt->range_swapped ? stmt->range_left : stmt->range_right;
|
||||||
|
@ -5468,21 +5464,21 @@ AstNode *AstNode::eval_const_function(AstNode *fcall, bool must_succeed)
|
||||||
if (stmt->children.at(1)->type != AST_CONSTANT) {
|
if (stmt->children.at(1)->type != AST_CONSTANT) {
|
||||||
if (!must_succeed)
|
if (!must_succeed)
|
||||||
goto finished;
|
goto finished;
|
||||||
log_file_error(stmt->filename, stmt->location.first_line, "Non-constant expression in constant function\n%s: ... called from here. X\n",
|
stmt->input_error("Non-constant expression in constant function\n%s: ... called from here. X\n",
|
||||||
fcall->loc_string().c_str());
|
fcall->loc_string().c_str());
|
||||||
}
|
}
|
||||||
|
|
||||||
if (stmt->children.at(0)->type != AST_IDENTIFIER) {
|
if (stmt->children.at(0)->type != AST_IDENTIFIER) {
|
||||||
if (!must_succeed)
|
if (!must_succeed)
|
||||||
goto finished;
|
goto finished;
|
||||||
log_file_error(stmt->filename, stmt->location.first_line, "Unsupported composite left hand side in constant function\n%s: ... called from here.\n",
|
stmt->input_error("Unsupported composite left hand side in constant function\n%s: ... called from here.\n",
|
||||||
fcall->loc_string().c_str());
|
fcall->loc_string().c_str());
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!variables.count(stmt->children.at(0)->str)) {
|
if (!variables.count(stmt->children.at(0)->str)) {
|
||||||
if (!must_succeed)
|
if (!must_succeed)
|
||||||
goto finished;
|
goto finished;
|
||||||
log_file_error(stmt->filename, stmt->location.first_line, "Assignment to non-local variable in constant function\n%s: ... called from here.\n",
|
stmt->input_error("Assignment to non-local variable in constant function\n%s: ... called from here.\n",
|
||||||
fcall->loc_string().c_str());
|
fcall->loc_string().c_str());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -5493,8 +5489,7 @@ AstNode *AstNode::eval_const_function(AstNode *fcall, bool must_succeed)
|
||||||
if (!range->range_valid) {
|
if (!range->range_valid) {
|
||||||
if (!must_succeed)
|
if (!must_succeed)
|
||||||
goto finished;
|
goto finished;
|
||||||
log_file_error(range->filename, range->location.first_line, "Non-constant range\n%s: ... called from here.\n",
|
range->input_error("Non-constant range\n%s: ... called from here.\n", fcall->loc_string().c_str());
|
||||||
fcall->loc_string().c_str());
|
|
||||||
}
|
}
|
||||||
int offset = min(range->range_left, range->range_right);
|
int offset = min(range->range_left, range->range_right);
|
||||||
int width = std::abs(range->range_left - range->range_right) + 1;
|
int width = std::abs(range->range_left - range->range_right) + 1;
|
||||||
|
@ -5533,7 +5528,7 @@ AstNode *AstNode::eval_const_function(AstNode *fcall, bool must_succeed)
|
||||||
if (cond->type != AST_CONSTANT) {
|
if (cond->type != AST_CONSTANT) {
|
||||||
if (!must_succeed)
|
if (!must_succeed)
|
||||||
goto finished;
|
goto finished;
|
||||||
log_file_error(stmt->filename, stmt->location.first_line, "Non-constant expression in constant function\n%s: ... called from here.\n",
|
stmt->input_error("Non-constant expression in constant function\n%s: ... called from here.\n",
|
||||||
fcall->loc_string().c_str());
|
fcall->loc_string().c_str());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -5558,7 +5553,7 @@ AstNode *AstNode::eval_const_function(AstNode *fcall, bool must_succeed)
|
||||||
if (num->type != AST_CONSTANT) {
|
if (num->type != AST_CONSTANT) {
|
||||||
if (!must_succeed)
|
if (!must_succeed)
|
||||||
goto finished;
|
goto finished;
|
||||||
log_file_error(stmt->filename, stmt->location.first_line, "Non-constant expression in constant function\n%s: ... called from here.\n",
|
stmt->input_error("Non-constant expression in constant function\n%s: ... called from here.\n",
|
||||||
fcall->loc_string().c_str());
|
fcall->loc_string().c_str());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -5601,7 +5596,7 @@ AstNode *AstNode::eval_const_function(AstNode *fcall, bool must_succeed)
|
||||||
if (cond->type != AST_CONSTANT) {
|
if (cond->type != AST_CONSTANT) {
|
||||||
if (!must_succeed)
|
if (!must_succeed)
|
||||||
goto finished;
|
goto finished;
|
||||||
log_file_error(stmt->filename, stmt->location.first_line, "Non-constant expression in constant function\n%s: ... called from here.\n",
|
stmt->input_error("Non-constant expression in constant function\n%s: ... called from here.\n",
|
||||||
fcall->loc_string().c_str());
|
fcall->loc_string().c_str());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -5637,7 +5632,7 @@ AstNode *AstNode::eval_const_function(AstNode *fcall, bool must_succeed)
|
||||||
|
|
||||||
if (!must_succeed)
|
if (!must_succeed)
|
||||||
goto finished;
|
goto finished;
|
||||||
log_file_error(stmt->filename, stmt->location.first_line, "Unsupported language construct in constant function\n%s: ... called from here.\n",
|
stmt->input_error("Unsupported language construct in constant function\n%s: ... called from here.\n",
|
||||||
fcall->loc_string().c_str());
|
fcall->loc_string().c_str());
|
||||||
log_abort();
|
log_abort();
|
||||||
}
|
}
|
||||||
|
|
|
@ -378,14 +378,20 @@ void logv_error(const char *format, va_list ap)
|
||||||
logv_error_with_prefix("ERROR: ", format, ap);
|
logv_error_with_prefix("ERROR: ", format, ap);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void logv_file_error(const string &filename, int lineno,
|
||||||
|
const char *format, va_list ap)
|
||||||
|
{
|
||||||
|
std::string prefix = stringf("%s:%d: ERROR: ",
|
||||||
|
filename.c_str(), lineno);
|
||||||
|
logv_error_with_prefix(prefix.c_str(), format, ap);
|
||||||
|
}
|
||||||
|
|
||||||
void log_file_error(const string &filename, int lineno,
|
void log_file_error(const string &filename, int lineno,
|
||||||
const char *format, ...)
|
const char *format, ...)
|
||||||
{
|
{
|
||||||
va_list ap;
|
va_list ap;
|
||||||
va_start(ap, format);
|
va_start(ap, format);
|
||||||
std::string prefix = stringf("%s:%d: ERROR: ",
|
logv_file_error(filename, lineno, format, ap);
|
||||||
filename.c_str(), lineno);
|
|
||||||
logv_error_with_prefix(prefix.c_str(), format, ap);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void log(const char *format, ...)
|
void log(const char *format, ...)
|
||||||
|
|
|
@ -124,6 +124,7 @@ void logv_header(RTLIL::Design *design, const char *format, va_list ap);
|
||||||
void logv_warning(const char *format, va_list ap);
|
void logv_warning(const char *format, va_list ap);
|
||||||
void logv_warning_noprefix(const char *format, va_list ap);
|
void logv_warning_noprefix(const char *format, va_list ap);
|
||||||
[[noreturn]] void logv_error(const char *format, va_list ap);
|
[[noreturn]] void logv_error(const char *format, va_list ap);
|
||||||
|
[[noreturn]] void logv_file_error(const string &filename, int lineno, const char *format, va_list ap);
|
||||||
|
|
||||||
void log(const char *format, ...) YS_ATTRIBUTE(format(printf, 1, 2));
|
void log(const char *format, ...) YS_ATTRIBUTE(format(printf, 1, 2));
|
||||||
void log_header(RTLIL::Design *design, const char *format, ...) YS_ATTRIBUTE(format(printf, 2, 3));
|
void log_header(RTLIL::Design *design, const char *format, ...) YS_ATTRIBUTE(format(printf, 2, 3));
|
||||||
|
|
Loading…
Reference in New Issue