mirror of
https://github.com/YosysHQ/yosys
synced 2025-04-07 01:54:10 +00:00
genrtlil: improve name conflict error messaging
This commit is contained in:
parent
dcd9f0af23
commit
bbff844acd
|
@ -1002,6 +1002,29 @@ void AstNode::detectSignWidth(int &width_hint, bool &sign_hint, bool *found_real
|
||||||
detectSignWidthWorker(width_hint, sign_hint, found_real);
|
detectSignWidthWorker(width_hint, sign_hint, found_real);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void check_unique_id(RTLIL::Module *module, RTLIL::IdString id,
|
||||||
|
const AstNode *node, const char *to_add_kind)
|
||||||
|
{
|
||||||
|
auto already_exists = [&](const RTLIL::AttrObject *existing, const char *existing_kind) {
|
||||||
|
std::string src = existing->get_string_attribute(ID::src);
|
||||||
|
std::string location_str = "earlier";
|
||||||
|
if (!src.empty())
|
||||||
|
location_str = "at " + src;
|
||||||
|
log_file_error(node->filename, node->location.first_line,
|
||||||
|
"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());
|
||||||
|
};
|
||||||
|
|
||||||
|
if (const RTLIL::Wire *wire = module->wire(id))
|
||||||
|
already_exists(wire, "signal");
|
||||||
|
if (const RTLIL::Cell *cell = module->cell(id))
|
||||||
|
already_exists(cell, "cell");
|
||||||
|
if (module->processes.count(id))
|
||||||
|
already_exists(module->processes.at(id), "process");
|
||||||
|
if (module->memories.count(id))
|
||||||
|
already_exists(module->memories.at(id), "memory");
|
||||||
|
}
|
||||||
|
|
||||||
// create RTLIL from an AST node
|
// create RTLIL from an AST node
|
||||||
// all generated cells, wires and processes are added to the module pointed to by 'current_module'
|
// all generated cells, wires and processes are added to the module pointed to by 'current_module'
|
||||||
// when the AST node is an expression (AST_ADD, AST_BIT_XOR, etc.), the result signal is returned.
|
// when the AST node is an expression (AST_ADD, AST_BIT_XOR, etc.), the result signal is returned.
|
||||||
|
@ -1047,7 +1070,9 @@ RTLIL::SigSpec AstNode::genRTLIL(int width_hint, bool sign_hint)
|
||||||
// If a port in a module with unknown type is found, mark it with the attribute 'is_interface'
|
// If a port in a module with unknown type is found, mark it with the attribute 'is_interface'
|
||||||
// This is used by the hierarchy pass to know when it can replace interface connection with the individual
|
// This is used by the hierarchy pass to know when it can replace interface connection with the individual
|
||||||
// signals.
|
// signals.
|
||||||
RTLIL::Wire *wire = current_module->addWire(str, 1);
|
RTLIL::IdString id = str;
|
||||||
|
check_unique_id(current_module, id, this, "interface port");
|
||||||
|
RTLIL::Wire *wire = current_module->addWire(id, 1);
|
||||||
set_src_attr(wire, this);
|
set_src_attr(wire, this);
|
||||||
wire->start_offset = 0;
|
wire->start_offset = 0;
|
||||||
wire->port_id = port_id;
|
wire->port_id = port_id;
|
||||||
|
@ -1085,7 +1110,9 @@ RTLIL::SigSpec AstNode::genRTLIL(int width_hint, bool sign_hint)
|
||||||
log_file_error(filename, location.first_line, "Parameter `%s' with non-constant value!\n", str.c_str());
|
log_file_error(filename, location.first_line, "Parameter `%s' with non-constant value!\n", str.c_str());
|
||||||
|
|
||||||
RTLIL::Const val = children[0]->bitsAsConst();
|
RTLIL::Const val = children[0]->bitsAsConst();
|
||||||
RTLIL::Wire *wire = current_module->addWire(str, GetSize(val));
|
RTLIL::IdString id = str;
|
||||||
|
check_unique_id(current_module, id, this, "pwire");
|
||||||
|
RTLIL::Wire *wire = current_module->addWire(id, GetSize(val));
|
||||||
current_module->connect(wire, val);
|
current_module->connect(wire, val);
|
||||||
wire->is_signed = children[0]->is_signed;
|
wire->is_signed = children[0]->is_signed;
|
||||||
|
|
||||||
|
@ -1102,15 +1129,15 @@ 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 (current_module->wires_.count(str) != 0)
|
|
||||||
log_file_error(filename, location.first_line, "Re-definition of signal `%s'!\n", str.c_str());
|
|
||||||
if (!range_valid)
|
if (!range_valid)
|
||||||
log_file_error(filename, location.first_line, "Signal `%s' with non-constant width!\n", str.c_str());
|
log_file_error(filename, location.first_line, "Signal `%s' with non-constant width!\n", str.c_str());
|
||||||
|
|
||||||
if (!(range_left + 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);
|
log_file_error(filename, location.first_line, "Signal `%s' with invalid width range %d!\n", str.c_str(), range_left - range_right + 1);
|
||||||
|
|
||||||
RTLIL::Wire *wire = current_module->addWire(str, range_left - range_right + 1);
|
RTLIL::IdString id = str;
|
||||||
|
check_unique_id(current_module, id, this, "signal");
|
||||||
|
RTLIL::Wire *wire = current_module->addWire(id, range_left - range_right + 1);
|
||||||
set_src_attr(wire, this);
|
set_src_attr(wire, this);
|
||||||
wire->start_offset = range_right;
|
wire->start_offset = range_right;
|
||||||
wire->port_id = port_id;
|
wire->port_id = port_id;
|
||||||
|
@ -1132,9 +1159,6 @@ RTLIL::SigSpec AstNode::genRTLIL(int width_hint, bool sign_hint)
|
||||||
|
|
||||||
// create an RTLIL::Memory for an AST_MEMORY node
|
// create an RTLIL::Memory for an AST_MEMORY node
|
||||||
case AST_MEMORY: {
|
case AST_MEMORY: {
|
||||||
if (current_module->memories.count(str) != 0)
|
|
||||||
log_file_error(filename, location.first_line, "Re-definition of memory `%s'!\n", str.c_str());
|
|
||||||
|
|
||||||
log_assert(children.size() >= 2);
|
log_assert(children.size() >= 2);
|
||||||
log_assert(children[0]->type == AST_RANGE);
|
log_assert(children[0]->type == AST_RANGE);
|
||||||
log_assert(children[1]->type == AST_RANGE);
|
log_assert(children[1]->type == AST_RANGE);
|
||||||
|
@ -1153,6 +1177,7 @@ RTLIL::SigSpec AstNode::genRTLIL(int width_hint, bool sign_hint)
|
||||||
memory->start_offset = children[1]->range_left;
|
memory->start_offset = children[1]->range_left;
|
||||||
memory->size = children[1]->range_right - children[1]->range_left + 1;
|
memory->size = children[1]->range_right - children[1]->range_left + 1;
|
||||||
}
|
}
|
||||||
|
check_unique_id(current_module, memory->name, this, "memory");
|
||||||
current_module->memories[memory->name] = memory;
|
current_module->memories[memory->name] = memory;
|
||||||
|
|
||||||
for (auto &attr : attributes) {
|
for (auto &attr : attributes) {
|
||||||
|
@ -1684,6 +1709,7 @@ RTLIL::SigSpec AstNode::genRTLIL(int width_hint, bool sign_hint)
|
||||||
else
|
else
|
||||||
cellname = str;
|
cellname = str;
|
||||||
|
|
||||||
|
check_unique_id(current_module, cellname, this, "procedural assertion");
|
||||||
RTLIL::Cell *cell = current_module->addCell(cellname, celltype);
|
RTLIL::Cell *cell = current_module->addCell(cellname, celltype);
|
||||||
set_src_attr(cell, this);
|
set_src_attr(cell, this);
|
||||||
|
|
||||||
|
@ -1726,10 +1752,9 @@ RTLIL::SigSpec AstNode::genRTLIL(int width_hint, bool sign_hint)
|
||||||
{
|
{
|
||||||
int port_counter = 0, para_counter = 0;
|
int port_counter = 0, para_counter = 0;
|
||||||
|
|
||||||
if (current_module->count_id(str) != 0)
|
RTLIL::IdString id = str;
|
||||||
log_file_error(filename, location.first_line, "Re-definition of cell `%s'!\n", str.c_str());
|
check_unique_id(current_module, id, this, "cell");
|
||||||
|
RTLIL::Cell *cell = current_module->addCell(id, "");
|
||||||
RTLIL::Cell *cell = current_module->addCell(str, "");
|
|
||||||
set_src_attr(cell, this);
|
set_src_attr(cell, this);
|
||||||
// Set attribute 'module_not_derived' which will be cleared again after the hierarchy pass
|
// Set attribute 'module_not_derived' which will be cleared again after the hierarchy pass
|
||||||
cell->set_bool_attribute(ID::module_not_derived);
|
cell->set_bool_attribute(ID::module_not_derived);
|
||||||
|
|
8
tests/verilog/conflict_assert.ys
Normal file
8
tests/verilog/conflict_assert.ys
Normal file
|
@ -0,0 +1,8 @@
|
||||||
|
logger -expect error "Cannot add procedural assertion `\\x' because a signal with the same name was already created" 1
|
||||||
|
read_verilog -sv <<EOT
|
||||||
|
module top;
|
||||||
|
wire x, y;
|
||||||
|
always @*
|
||||||
|
x: assert(y == 1);
|
||||||
|
endmodule
|
||||||
|
EOT
|
9
tests/verilog/conflict_cell_memory.ys
Normal file
9
tests/verilog/conflict_cell_memory.ys
Normal file
|
@ -0,0 +1,9 @@
|
||||||
|
logger -expect error "Cannot add cell `\\x' because a memory with the same name was already created" 1
|
||||||
|
read_verilog <<EOT
|
||||||
|
module mod;
|
||||||
|
endmodule
|
||||||
|
module top;
|
||||||
|
reg [2:0] x [0:0];
|
||||||
|
mod x();
|
||||||
|
endmodule
|
||||||
|
EOT
|
17
tests/verilog/conflict_interface_port.ys
Normal file
17
tests/verilog/conflict_interface_port.ys
Normal file
|
@ -0,0 +1,17 @@
|
||||||
|
logger -expect error "Cannot add interface port `\\i' because a signal with the same name was already created" 1
|
||||||
|
read_verilog -sv <<EOT
|
||||||
|
interface intf;
|
||||||
|
logic x;
|
||||||
|
assign x = 1;
|
||||||
|
modport m(input x);
|
||||||
|
endinterface
|
||||||
|
module mod(intf.m i);
|
||||||
|
wire x;
|
||||||
|
assign x = i.x;
|
||||||
|
wire i;
|
||||||
|
endmodule
|
||||||
|
module top;
|
||||||
|
intf i();
|
||||||
|
mod m(i);
|
||||||
|
endmodule
|
||||||
|
EOT
|
7
tests/verilog/conflict_memory_wire.ys
Normal file
7
tests/verilog/conflict_memory_wire.ys
Normal file
|
@ -0,0 +1,7 @@
|
||||||
|
logger -expect error "Cannot add memory `\\x' because a signal with the same name was already created" 1
|
||||||
|
read_verilog <<EOT
|
||||||
|
module top;
|
||||||
|
reg [2:0] x;
|
||||||
|
reg [2:0] x [0:0];
|
||||||
|
endmodule
|
||||||
|
EOT
|
8
tests/verilog/conflict_pwire.ys
Normal file
8
tests/verilog/conflict_pwire.ys
Normal file
|
@ -0,0 +1,8 @@
|
||||||
|
logger -expect error "Cannot add pwire `\\x' because a signal with the same name was already created" 1
|
||||||
|
read_verilog -pwires <<EOT
|
||||||
|
module top;
|
||||||
|
wire x;
|
||||||
|
assign x = 1;
|
||||||
|
localparam x = 2;
|
||||||
|
endmodule
|
||||||
|
EOT
|
7
tests/verilog/conflict_wire_memory.ys
Normal file
7
tests/verilog/conflict_wire_memory.ys
Normal file
|
@ -0,0 +1,7 @@
|
||||||
|
logger -expect error "Cannot add signal `\\x' because a memory with the same name was already created" 1
|
||||||
|
read_verilog <<EOT
|
||||||
|
module top;
|
||||||
|
reg [2:0] x [0:0];
|
||||||
|
reg [2:0] x;
|
||||||
|
endmodule
|
||||||
|
EOT
|
Loading…
Reference in a new issue