Merge pull request #820 from larsclausen/array-compatibility
Add error checking for continuous unpacked array assignments
This commit is contained in:
commit
580d79eae3
14
elab_net.cc
14
elab_net.cc
|
|
@ -1107,8 +1107,20 @@ NetNet*PEIdent::elaborate_unpacked_net(Design*des, NetScope*scope) const
|
||||||
perm_string method_name;
|
perm_string method_name;
|
||||||
|
|
||||||
symbol_search(this, des, scope, path_, sig, par, eve);
|
symbol_search(this, des, scope, path_, sig, par, eve);
|
||||||
|
if (!sig) {
|
||||||
|
cerr << get_fileline() << ": error: Net " << path_
|
||||||
|
<< " is not defined in this context." << endl;
|
||||||
|
des->errors += 1;
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
ivl_assert(*this, sig);
|
const name_component_t&name_tail = path_.back();
|
||||||
|
if (name_tail.index.size() != 0) {
|
||||||
|
cerr << get_fileline() << ": sorry: Array slices are not yet "
|
||||||
|
<< "supported for continuous assignment." << endl;
|
||||||
|
des->errors += 1;
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
return sig;
|
return sig;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
107
elaborate.cc
107
elaborate.cc
|
|
@ -260,16 +260,64 @@ void PGAssign::elaborate(Design*des, NetScope*scope) const
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
NetNet *elaborate_unpacked_array(Design *des, NetScope *scope, const LineInfo &loc,
|
||||||
|
const NetNet *lval, PExpr *expr)
|
||||||
|
{
|
||||||
|
PEIdent* ident = dynamic_cast<PEIdent*> (expr);
|
||||||
|
if (!ident) {
|
||||||
|
des->errors++;
|
||||||
|
if (dynamic_cast<PEConcat*> (expr)) {
|
||||||
|
cout << loc.get_fileline() << ": sorry: Continuous assignment"
|
||||||
|
<< " of array concatenation is not yet supported."
|
||||||
|
<< endl;
|
||||||
|
} else if (dynamic_cast<PEAssignPattern*> (expr)) {
|
||||||
|
cout << loc.get_fileline() << ": sorry: Continuous assignment"
|
||||||
|
<< " of assignment pattern is not yet supported." << endl;
|
||||||
|
} else {
|
||||||
|
cout << loc.get_fileline() << ": error: Can not assign"
|
||||||
|
<< " non-array expression `" << *expr << "` to array."
|
||||||
|
<< endl;
|
||||||
|
}
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
NetNet *expr_net = ident->elaborate_unpacked_net(des, scope);
|
||||||
|
if (!expr_net)
|
||||||
|
return nullptr;
|
||||||
|
|
||||||
|
auto const &lval_dims = lval->unpacked_dims();
|
||||||
|
auto const &expr_dims = expr_net->unpacked_dims();
|
||||||
|
|
||||||
|
if (expr_dims.empty()) {
|
||||||
|
cerr << loc.get_fileline() << ": error: Can not assign"
|
||||||
|
<< " non-array identifier `" << *expr << "` to array."
|
||||||
|
<< endl;
|
||||||
|
des->errors++;
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!netrange_equivalent(lval_dims, expr_dims)) {
|
||||||
|
cerr << loc.get_fileline() << ": error: Unpacked dimensions"
|
||||||
|
<< " are not compatible in array assignment." << endl;
|
||||||
|
des->errors++;
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!lval->net_type()->type_equivalent(expr_net->net_type())) {
|
||||||
|
cerr << loc.get_fileline() << ": error: Element types are not"
|
||||||
|
<< " compatible in array assignment." << endl;
|
||||||
|
des->errors++;
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
return expr_net;
|
||||||
|
}
|
||||||
|
|
||||||
void PGAssign::elaborate_unpacked_array_(Design*des, NetScope*scope, NetNet*lval) const
|
void PGAssign::elaborate_unpacked_array_(Design*des, NetScope*scope, NetNet*lval) const
|
||||||
{
|
{
|
||||||
PEIdent*rval_pident = dynamic_cast<PEIdent*> (pin(1));
|
NetNet *rval_net = elaborate_unpacked_array(des, scope, *this, lval, pin(1));
|
||||||
ivl_assert(*this, rval_pident);
|
if (rval_net)
|
||||||
|
assign_unpacked_with_bufz(des, scope, lval, lval, rval_net);
|
||||||
NetNet*rval_net = rval_pident->elaborate_unpacked_net(des, scope);
|
|
||||||
|
|
||||||
ivl_assert(*this, rval_net->pin_count() == lval->pin_count());
|
|
||||||
|
|
||||||
assign_unpacked_with_bufz(des, scope, this, lval, rval_net);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void PGBuiltin::calculate_gate_and_lval_count_(unsigned&gate_count,
|
void PGBuiltin::calculate_gate_and_lval_count_(unsigned&gate_count,
|
||||||
|
|
@ -1147,6 +1195,29 @@ static void isolate_and_connect(Design*des, NetScope*scope, const PGModule*mod,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void elaborate_unpacked_port(Design *des, NetScope *scope, NetNet *port_net,
|
||||||
|
PExpr *expr, NetNet::PortType port_type,
|
||||||
|
Module *mod, unsigned int port_idx)
|
||||||
|
{
|
||||||
|
NetNet *expr_net = elaborate_unpacked_array(des, scope, *expr, port_net,
|
||||||
|
expr);
|
||||||
|
if (!expr_net) {
|
||||||
|
perm_string port_name = mod->get_port_name(port_idx);
|
||||||
|
cerr << expr->get_fileline() << ": : Port "
|
||||||
|
<< port_idx+1 << " (" << port_name << ") of "
|
||||||
|
<< mod->mod_name() << " is connected to "
|
||||||
|
<< *expr << endl;
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
ivl_assert(*port_net, expr_net->pin_count() == port_net->pin_count());
|
||||||
|
if (port_type == NetNet::POUTPUT)
|
||||||
|
assign_unpacked_with_bufz(des, scope, port_net, expr_net, port_net);
|
||||||
|
else
|
||||||
|
assign_unpacked_with_bufz(des, scope, port_net, port_net, expr_net);
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Instantiate a module by recursively elaborating it. Set the path of
|
* Instantiate a module by recursively elaborating it. Set the path of
|
||||||
* the recursive elaboration so that signal names get properly
|
* the recursive elaboration so that signal names get properly
|
||||||
|
|
@ -1481,13 +1552,8 @@ void PGModule::elaborate_mod_(Design*des, Module*rmod, NetScope*scope) const
|
||||||
// differently.
|
// differently.
|
||||||
if (prts.size() >= 1 && prts[0]->pin_count()>1) {
|
if (prts.size() >= 1 && prts[0]->pin_count()>1) {
|
||||||
ivl_assert(*this, prts.size()==1);
|
ivl_assert(*this, prts.size()==1);
|
||||||
|
elaborate_unpacked_port(des, scope, prts[0], pins[idx],
|
||||||
PEIdent*rval_pident = dynamic_cast<PEIdent*> (pins[idx]);
|
ptype, rmod, idx);
|
||||||
ivl_assert(*this, rval_pident);
|
|
||||||
|
|
||||||
NetNet*rval_net = rval_pident->elaborate_unpacked_net(des, scope);
|
|
||||||
ivl_assert(*this, rval_net->pin_count() == prts[0]->pin_count());
|
|
||||||
assign_unpacked_with_bufz(des, scope, this, prts[0], rval_net);
|
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -1650,15 +1716,8 @@ void PGModule::elaborate_mod_(Design*des, Module*rmod, NetScope*scope) const
|
||||||
// "r-value" expression, but since this is an
|
// "r-value" expression, but since this is an
|
||||||
// output port, we assign to it from the internal object.
|
// output port, we assign to it from the internal object.
|
||||||
if (prts[0]->pin_count() > 1) {
|
if (prts[0]->pin_count() > 1) {
|
||||||
ivl_assert(*this, prts.size()==1);
|
elaborate_unpacked_port(des, scope, prts[0], pins[idx],
|
||||||
|
ptype, rmod, idx);
|
||||||
PEIdent*rval_pident = dynamic_cast<PEIdent*>(pins[idx]);
|
|
||||||
ivl_assert(*this, rval_pident);
|
|
||||||
|
|
||||||
NetNet*rval_net = rval_pident->elaborate_unpacked_net(des, scope);
|
|
||||||
ivl_assert(*this, rval_net->pin_count() == prts[0]->pin_count());
|
|
||||||
|
|
||||||
assign_unpacked_with_bufz(des, scope, this, rval_net, prts[0]);
|
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,14 @@
|
||||||
|
// Check that continuous assignment of two compatible arrays is supported
|
||||||
|
|
||||||
|
module test;
|
||||||
|
|
||||||
|
wire [1:0] x[1:0];
|
||||||
|
wire [1:0] y[1:0];
|
||||||
|
|
||||||
|
assign x = y;
|
||||||
|
|
||||||
|
initial begin
|
||||||
|
$display("PASSED");
|
||||||
|
end
|
||||||
|
|
||||||
|
endmodule
|
||||||
|
|
@ -0,0 +1,16 @@
|
||||||
|
// Check that continuous assignment of two compatible arrays is supported, even
|
||||||
|
// if the upper and lower bounds of the arrays are not identical, as long as the
|
||||||
|
// size is the same.
|
||||||
|
|
||||||
|
module test;
|
||||||
|
|
||||||
|
wire [1:0] x[1:0];
|
||||||
|
wire [1:0] y[2:1];
|
||||||
|
|
||||||
|
assign x = y;
|
||||||
|
|
||||||
|
initial begin
|
||||||
|
$display("PASSED");
|
||||||
|
end
|
||||||
|
|
||||||
|
endmodule
|
||||||
|
|
@ -0,0 +1,15 @@
|
||||||
|
// Check that continuous assignment of two compatible arrays is supported, even
|
||||||
|
// if the element types are not identical, but just equivalent.
|
||||||
|
|
||||||
|
module test;
|
||||||
|
|
||||||
|
wire [1:0] x[1:0];
|
||||||
|
wire [2:1] y[1:0];
|
||||||
|
|
||||||
|
assign x = y;
|
||||||
|
|
||||||
|
initial begin
|
||||||
|
$display("PASSED");
|
||||||
|
end
|
||||||
|
|
||||||
|
endmodule
|
||||||
|
|
@ -0,0 +1,16 @@
|
||||||
|
// Check that continuous assignment of two compatible arrays is supported, even
|
||||||
|
// if the element types are not identical and one is a built-in integer and the
|
||||||
|
// other a equivalent packed type.
|
||||||
|
|
||||||
|
module test;
|
||||||
|
|
||||||
|
wire signed [31:0] x[1:0];
|
||||||
|
wire integer y[1:0];
|
||||||
|
|
||||||
|
assign x = y;
|
||||||
|
|
||||||
|
initial begin
|
||||||
|
$display("PASSED");
|
||||||
|
end
|
||||||
|
|
||||||
|
endmodule
|
||||||
|
|
@ -0,0 +1,16 @@
|
||||||
|
// Check that continuous assignment of two compatible arrays is supported, even
|
||||||
|
// if the element types have different number of dimensions, but have the same
|
||||||
|
// packed width.
|
||||||
|
|
||||||
|
module test;
|
||||||
|
|
||||||
|
wire [3:0] x[1:0];
|
||||||
|
wire [1:0][1:0] y[1:0];
|
||||||
|
|
||||||
|
assign x = y;
|
||||||
|
|
||||||
|
initial begin
|
||||||
|
$display("PASSED");
|
||||||
|
end
|
||||||
|
|
||||||
|
endmodule
|
||||||
|
|
@ -0,0 +1,15 @@
|
||||||
|
// Check that it is an error if the element type is not the same in a
|
||||||
|
// continuous array assignment.
|
||||||
|
|
||||||
|
module test;
|
||||||
|
|
||||||
|
wire [3:0] x[1:0];
|
||||||
|
reg [1:0] y[1:0];
|
||||||
|
|
||||||
|
assign x = y;
|
||||||
|
|
||||||
|
initial begin
|
||||||
|
$display("FAILED");
|
||||||
|
end
|
||||||
|
|
||||||
|
endmodule
|
||||||
|
|
@ -0,0 +1,18 @@
|
||||||
|
// Check that it is an error trying to continuously assign an unpacked array
|
||||||
|
// with an enum element type to another unpacked array with an element type that
|
||||||
|
// is not the same enum type, even if the two element types are the same size.
|
||||||
|
|
||||||
|
module test;
|
||||||
|
|
||||||
|
wire integer x[1:0];
|
||||||
|
enum integer {
|
||||||
|
A
|
||||||
|
} y[1:0];
|
||||||
|
|
||||||
|
assign x = y;
|
||||||
|
|
||||||
|
initial begin
|
||||||
|
$display("FAILED");
|
||||||
|
end
|
||||||
|
|
||||||
|
endmodule
|
||||||
|
|
@ -0,0 +1,18 @@
|
||||||
|
// Check that it is an error to continuously assign an unpacked array with an
|
||||||
|
// enum element type if the other unpacked array element type is not the same
|
||||||
|
// enum type, even if the two element types are the same size.
|
||||||
|
|
||||||
|
module test;
|
||||||
|
|
||||||
|
wire enum integer {
|
||||||
|
A
|
||||||
|
} x[1:0];
|
||||||
|
integer y[1:0];
|
||||||
|
|
||||||
|
assign x = y;
|
||||||
|
|
||||||
|
initial begin
|
||||||
|
$display("FAILED");
|
||||||
|
end
|
||||||
|
|
||||||
|
endmodule
|
||||||
|
|
@ -0,0 +1,15 @@
|
||||||
|
// Check that it is an error if the array size is not the same in a continuous
|
||||||
|
// unpacked array assignment.
|
||||||
|
|
||||||
|
module test;
|
||||||
|
|
||||||
|
wire [1:0] x[2:0];
|
||||||
|
reg [1:0] y[1:0];
|
||||||
|
|
||||||
|
assign x = y;
|
||||||
|
|
||||||
|
initial begin
|
||||||
|
$display("FAILED");
|
||||||
|
end
|
||||||
|
|
||||||
|
endmodule
|
||||||
|
|
@ -0,0 +1,16 @@
|
||||||
|
// Check that it is an error if the number of unpacked dimensions do not match
|
||||||
|
// in an continuous array assignment, even if the canonical size of the array is
|
||||||
|
// the same.
|
||||||
|
|
||||||
|
module test;
|
||||||
|
|
||||||
|
wire [1:0] x[1:0][1:0];
|
||||||
|
reg [1:0] y[3:0];
|
||||||
|
|
||||||
|
assign x = y;
|
||||||
|
|
||||||
|
initial begin
|
||||||
|
$display("FAILED");
|
||||||
|
end
|
||||||
|
|
||||||
|
endmodule
|
||||||
|
|
@ -0,0 +1,16 @@
|
||||||
|
// Check that it is an error if the element type is not the same in a
|
||||||
|
// continuous array assignment, even if the difference is just 2-state vs.
|
||||||
|
// 4-state.
|
||||||
|
|
||||||
|
module test;
|
||||||
|
|
||||||
|
wire [1:0] x[1:0];
|
||||||
|
bit [1:0] y[1:0];
|
||||||
|
|
||||||
|
assign x = y;
|
||||||
|
|
||||||
|
initial begin
|
||||||
|
$display("FAILED");
|
||||||
|
end
|
||||||
|
|
||||||
|
endmodule
|
||||||
|
|
@ -0,0 +1,16 @@
|
||||||
|
// Check that it is an error if the element type is not the same in a
|
||||||
|
// continuous array assignment, even if one of the types is a packed type and
|
||||||
|
// the other is a real type.
|
||||||
|
|
||||||
|
module test;
|
||||||
|
|
||||||
|
wire [1:0] x[1:0];
|
||||||
|
real [1:0] y[1:0];
|
||||||
|
|
||||||
|
assign x = y;
|
||||||
|
|
||||||
|
initial begin
|
||||||
|
$display("FAILED");
|
||||||
|
end
|
||||||
|
|
||||||
|
endmodule
|
||||||
|
|
@ -0,0 +1,14 @@
|
||||||
|
// Check that it is an error trying to continuously assign a scalar expression
|
||||||
|
// to a unpacked array.
|
||||||
|
|
||||||
|
module test;
|
||||||
|
|
||||||
|
wire [1:0] x[1:0];
|
||||||
|
|
||||||
|
assign x = 1'b1 + 1'b1;
|
||||||
|
|
||||||
|
initial begin
|
||||||
|
$display("FAILED");
|
||||||
|
end
|
||||||
|
|
||||||
|
endmodule
|
||||||
|
|
@ -0,0 +1,15 @@
|
||||||
|
// Check that it is an error trying to continuously assign a scalar variable to
|
||||||
|
// an unpacked array.
|
||||||
|
|
||||||
|
module test;
|
||||||
|
|
||||||
|
wire [1:0] x[1:0];
|
||||||
|
reg [1:0] y;
|
||||||
|
|
||||||
|
assign x = y;
|
||||||
|
|
||||||
|
initial begin
|
||||||
|
$display("FAILED");
|
||||||
|
end
|
||||||
|
|
||||||
|
endmodule
|
||||||
|
|
@ -0,0 +1,15 @@
|
||||||
|
// Check that it is an error trying to continuously assign a scalar net to an
|
||||||
|
// unpacked array.
|
||||||
|
|
||||||
|
module test;
|
||||||
|
|
||||||
|
wire a[1:0];
|
||||||
|
wire x;
|
||||||
|
|
||||||
|
assign a = x;
|
||||||
|
|
||||||
|
initial begin
|
||||||
|
$display("FAILED");
|
||||||
|
end
|
||||||
|
|
||||||
|
endmodule
|
||||||
|
|
@ -0,0 +1,15 @@
|
||||||
|
// Check that it is an error trying to continuously assign an element of an
|
||||||
|
// unpacked array to another unpacked array as a whole.
|
||||||
|
|
||||||
|
module test;
|
||||||
|
|
||||||
|
wire a[1:0];
|
||||||
|
wire x[1:0];
|
||||||
|
|
||||||
|
assign a = x[0];
|
||||||
|
|
||||||
|
initial begin
|
||||||
|
$display("FAILED");
|
||||||
|
end
|
||||||
|
|
||||||
|
endmodule
|
||||||
|
|
@ -501,6 +501,22 @@ sv_assign_pattern_func normal,-g2005-sv ivltests
|
||||||
sv_assign_pattern_op normal,-g2005-sv ivltests
|
sv_assign_pattern_op normal,-g2005-sv ivltests
|
||||||
sv_assign_pattern_part normal,-g2005-sv ivltests
|
sv_assign_pattern_part normal,-g2005-sv ivltests
|
||||||
sv_array_assign_pattern2 normal,-g2009 ivltests
|
sv_array_assign_pattern2 normal,-g2009 ivltests
|
||||||
|
sv_array_cassign1 normal,-g2005-sv ivltests
|
||||||
|
sv_array_cassign2 normal,-g2005-sv ivltests
|
||||||
|
sv_array_cassign3 normal,-g2005-sv ivltests
|
||||||
|
sv_array_cassign4 normal,-g2005-sv ivltests
|
||||||
|
sv_array_cassign5 normal,-g2005-sv ivltests
|
||||||
|
sv_array_cassign_fail1 CE,-g2005-sv ivltests
|
||||||
|
sv_array_cassign_fail2 CE,-g2005-sv ivltests
|
||||||
|
sv_array_cassign_fail3 CE,-g2005-sv ivltests
|
||||||
|
sv_array_cassign_fail4 CE,-g2005-sv ivltests
|
||||||
|
sv_array_cassign_fail5 CE,-g2005-sv ivltests
|
||||||
|
sv_array_cassign_fail6 CE,-g2005-sv ivltests
|
||||||
|
sv_array_cassign_fail7 CE,-g2005-sv ivltests
|
||||||
|
sv_array_cassign_fail8 CE,-g2005-sv ivltests
|
||||||
|
sv_array_cassign_fail9 CE,-g2005-sv ivltests
|
||||||
|
sv_array_cassign_fail10 CE,-g2005-sv ivltests
|
||||||
|
sv_array_cassign_fail11 CE,-g2005-sv ivltests
|
||||||
sv_array_query normal,-g2005-sv ivltests
|
sv_array_query normal,-g2005-sv ivltests
|
||||||
sv_cast_integer normal,-g2005-sv ivltests
|
sv_cast_integer normal,-g2005-sv ivltests
|
||||||
sv_cast_integer2 normal,-g2005-sv ivltests
|
sv_cast_integer2 normal,-g2005-sv ivltests
|
||||||
|
|
|
||||||
|
|
@ -257,6 +257,11 @@ scan-invalid CE ivltests
|
||||||
sel_rval_bit_ob CE ivltests
|
sel_rval_bit_ob CE ivltests
|
||||||
sel_rval_part_ob CE ivltests
|
sel_rval_part_ob CE ivltests
|
||||||
signed_net_display CE,-pallowsigned=1 ivltests
|
signed_net_display CE,-pallowsigned=1 ivltests
|
||||||
|
sv_array_cassign1 CE,-g2005-sv ivltests
|
||||||
|
sv_array_cassign2 CE,-g2005-sv ivltests
|
||||||
|
sv_array_cassign3 CE,-g2005-sv ivltests
|
||||||
|
sv_array_cassign4 CE,-g2005-sv ivltests
|
||||||
|
sv_array_cassign5 CE,-g2005-sv ivltests
|
||||||
sv_unpacked_port CE,-g2009 ivltests
|
sv_unpacked_port CE,-g2009 ivltests
|
||||||
sv_unpacked_port2 CE,-g2009,-pallowsigned=1 ivltests
|
sv_unpacked_port2 CE,-g2009,-pallowsigned=1 ivltests
|
||||||
sv_unpacked_wire CE,-g2009 ivltests
|
sv_unpacked_wire CE,-g2009 ivltests
|
||||||
|
|
|
||||||
12
netparray.cc
12
netparray.cc
|
|
@ -86,3 +86,15 @@ vector<netrange_t> netuarray_t::slice_dimensions() const
|
||||||
{
|
{
|
||||||
return static_dimensions();
|
return static_dimensions();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool netuarray_t::test_equivalence(ivl_type_t that) const
|
||||||
|
{
|
||||||
|
const netuarray_t *that_a = dynamic_cast<const netuarray_t *>(that);
|
||||||
|
if (!that_a)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
if (!netrange_equivalent(static_dimensions(), that_a->static_dimensions()))
|
||||||
|
return false;
|
||||||
|
|
||||||
|
return element_type()->type_equivalent(that_a->element_type());
|
||||||
|
}
|
||||||
|
|
|
||||||
|
|
@ -92,6 +92,9 @@ class netuarray_t : public netsarray_t {
|
||||||
public:
|
public:
|
||||||
// Virtual methods from the ivl_type_s type...
|
// Virtual methods from the ivl_type_s type...
|
||||||
std::vector<netrange_t> slice_dimensions() const;
|
std::vector<netrange_t> slice_dimensions() const;
|
||||||
|
|
||||||
|
private:
|
||||||
|
bool test_equivalence(ivl_type_t that) const;
|
||||||
};
|
};
|
||||||
|
|
||||||
inline netuarray_t::netuarray_t(const std::vector<netrange_t>&pd,
|
inline netuarray_t::netuarray_t(const std::vector<netrange_t>&pd,
|
||||||
|
|
|
||||||
14
nettypes.cc
14
nettypes.cc
|
|
@ -109,6 +109,20 @@ unsigned long netrange_width(const vector<netrange_t>&packed)
|
||||||
return wid;
|
return wid;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool netrange_equivalent(const std::vector<netrange_t> &a,
|
||||||
|
const std::vector<netrange_t> &b)
|
||||||
|
{
|
||||||
|
if (a.size() != b.size())
|
||||||
|
return false;
|
||||||
|
|
||||||
|
for (size_t i = 0; i < a.size(); i++) {
|
||||||
|
if (!a[i].equivalent(b[i]))
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Given a netrange_t list (which represent packed dimensions) and a
|
* Given a netrange_t list (which represent packed dimensions) and a
|
||||||
* prefix of calculated index values, calculate the canonical offset
|
* prefix of calculated index values, calculate the canonical offset
|
||||||
|
|
|
||||||
|
|
@ -137,6 +137,10 @@ class netrange_t {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool equivalent(const netrange_t &that) const {
|
||||||
|
return width() == that.width();
|
||||||
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
long msb_;
|
long msb_;
|
||||||
long lsb_;
|
long lsb_;
|
||||||
|
|
@ -146,6 +150,8 @@ extern std::ostream&operator << (std::ostream&out, const std::list<netrange_t>&r
|
||||||
extern std::ostream&operator << (std::ostream&out, const std::vector<netrange_t>&rlist);
|
extern std::ostream&operator << (std::ostream&out, const std::vector<netrange_t>&rlist);
|
||||||
|
|
||||||
extern unsigned long netrange_width(const std::vector<netrange_t>&dims);
|
extern unsigned long netrange_width(const std::vector<netrange_t>&dims);
|
||||||
|
extern bool netrange_equivalent(const std::vector<netrange_t> &a,
|
||||||
|
const std::vector<netrange_t> &b);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* There are a few cases where we need to know about the single-level
|
* There are a few cases where we need to know about the single-level
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue