Merge pull request #767 from larsclausen/invalid-port-decl

Prevent invalid port redeclaration
This commit is contained in:
Stephen Williams 2022-09-14 22:54:27 -07:00 committed by GitHub
commit 62b1f44104
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
57 changed files with 800 additions and 284 deletions

View File

@ -436,7 +436,6 @@ void PEIdent::declare_implicit_nets(LexicalScope*scope, NetNet::Type type)
PWire*net = new PWire(name, type, NetNet::NOT_A_PORT, IVL_VT_LOGIC);
net->set_file(get_file());
net->set_lineno(get_lineno());
net->set_range_scalar(SR_NET);
scope->wires[name] = net;
if (warn_implicit) {
cerr << get_fileline() << ": warning: implicit "

122
PWire.cc
View File

@ -18,6 +18,7 @@
*/
# include "config.h"
# include "ivl_assert.h"
# include "PWire.h"
# include "PExpr.h"
# include <cassert>
@ -27,13 +28,26 @@ using namespace std;
PWire::PWire(perm_string n,
NetNet::Type t,
NetNet::PortType pt,
ivl_variable_type_t dt)
ivl_variable_type_t dt,
PWSRType rt)
: name_(n), type_(t), port_type_(pt), data_type_(dt),
signed_(false),
port_set_(false), net_set_(false), is_scalar_(false),
error_cnt_(0), uarray_type_(0), set_data_type_(0),
discipline_(0)
{
switch (rt) {
case SR_PORT:
port_set_ = true;
break;
case SR_NET:
net_set_ = true;
break;
case SR_BOTH:
port_set_ = true;
net_set_ = true;
break;
}
}
NetNet::Type PWire::get_wire_type() const
@ -132,47 +146,23 @@ bool PWire::get_signed() const
return signed_;
}
void PWire::set_range_scalar(PWSRType type)
void PWire::set_port(NetNet::PortType pt)
{
is_scalar_ = true;
switch (type) {
case SR_PORT:
if (port_set_) {
cerr << get_fileline() << ": error: Port ``" << name_
<< "'' has already been declared a port." << endl;
error_cnt_ += 1;
} else {
port_set_ = true;
}
return;
ivl_assert(*this, !port_set_);
port_set_ = true;
case SR_NET:
if (net_set_) {
cerr << get_fileline() << ": error: Net ``" << name_
<< "'' has already been declared." << endl;
error_cnt_ += 1;
} else {
net_set_ = true;
}
return;
bool rc = set_port_type(pt);
ivl_assert(*this, rc);
}
case SR_BOTH:
if (port_set_ || net_set_) {
if (port_set_) {
cerr << get_fileline() << ": error: Port ``" << name_
<< "'' has already been declared a port." << endl;
error_cnt_ += 1;
}
if (net_set_) {
cerr << get_fileline() << ": error: Net ``" << name_
<< "'' has already been declared." << endl;
error_cnt_ += 1;
}
} else {
port_set_ = true;
net_set_ = true;
}
return;
void PWire::set_net(NetNet::Type t)
{
ivl_assert(*this, !net_set_);
net_set_ = true;
if (t != NetNet::IMPLICIT) {
bool rc = set_wire_type(t);
ivl_assert(*this, rc);
}
}
@ -180,49 +170,21 @@ void PWire::set_range(const list<pform_range_t>&rlist, PWSRType type)
{
switch (type) {
case SR_PORT:
if (port_set_) {
cerr << get_fileline() << ": error: Port ``" << name_
<< "'' has already been declared a port." << endl;
error_cnt_ += 1;
} else {
port_ = rlist;
port_set_ = true;
is_scalar_ = false;
}
return;
if (!port_.empty())
return;
port_ = rlist;
break;
case SR_NET:
if (net_set_) {
cerr << get_fileline() << ": error: Net ``" << name_
<< "'' has already been declared." << endl;
error_cnt_ += 1;
} else {
net_ = rlist;
net_set_ = true;
is_scalar_ = false;
}
return;
if (!net_.empty())
return;
net_ = rlist;
break;
case SR_BOTH:
if (port_set_ || net_set_) {
if (port_set_) {
cerr << get_fileline() << ": error: Port ``" << name_
<< "'' has already been declared a port." << endl;
error_cnt_ += 1;
}
if (net_set_) {
cerr << get_fileline() << ": error: Net ``" << name_
<< "'' has already been declared." << endl;
error_cnt_ += 1;
}
} else {
port_ = rlist;
port_set_ = true;
net_ = rlist;
net_set_ = true;
is_scalar_ = false;
}
return;
if (!port_.empty() || !net_.empty())
return;
port_ = rlist;
net_ = rlist;
break;
}
}

View File

@ -57,7 +57,8 @@ class PWire : public PNamedItem {
PWire(perm_string name,
NetNet::Type t,
NetNet::PortType pt,
ivl_variable_type_t dt);
ivl_variable_type_t dt,
PWSRType rt = SR_NET);
// Return a hierarchical name.
perm_string basename() const;
@ -74,7 +75,6 @@ class PWire : public PNamedItem {
bool set_data_type(ivl_variable_type_t dt);
ivl_variable_type_t get_data_type() const;
void set_range_scalar(PWSRType type);
void set_range(const std::list<pform_range_t>&ranges, PWSRType type);
void set_unpacked_idx(const std::list<pform_range_t>&ranges);
@ -94,6 +94,11 @@ class PWire : public PNamedItem {
SymbolType symbol_type() const;
bool is_net() const { return net_set_; };
bool is_port() const { return port_set_; };
void set_net(NetNet::Type t);
void set_port(NetNet::PortType pt);
private:
perm_string name_;
NetNet::Type type_;

View File

@ -1040,8 +1040,6 @@ NetNet* PWire::elaborate_sig(Design*des, NetScope*scope) const
<< "Evaluate ranges for port " << basename() << endl;
}
dimensions_ok &= evaluate_ranges(des, scope, this, plist, port_);
nlist = plist;
/* An implicit port can have a range so note that here. */
}
assert(port_set_ || port_.empty());
@ -1062,9 +1060,10 @@ NetNet* PWire::elaborate_sig(Design*des, NetScope*scope) const
<< ". Now check for consistency." << endl;
}
/* We have a port size error */
if (port_set_ && net_set_ && !test_ranges_eeq(plist, nlist)) {
/* We have a port size error. Skip this if the dimensions could not
* be evaluated since it will likely print nonsensical errors. */
if (port_set_ && net_set_ && !test_ranges_eeq(plist, nlist) &&
dimensions_ok) {
/* Scalar port with a vector net/etc. definition */
if (port_.empty()) {
if (!gn_io_range_error_flag) {
@ -1103,7 +1102,7 @@ NetNet* PWire::elaborate_sig(Design*des, NetScope*scope) const
}
}
packed_dimensions = nlist;
packed_dimensions = net_set_ ? nlist : plist;
wid = netrange_width(packed_dimensions);
if (wid > warn_dimension_size) {
cerr << get_fileline() << ": warning: Vector size "
@ -1116,17 +1115,6 @@ NetNet* PWire::elaborate_sig(Design*des, NetScope*scope) const
attrib_list_t*attrib_list = evaluate_attributes(attributes, nattrib,
des, scope);
if (data_type_ == IVL_VT_REAL && !packed_dimensions.empty()) {
cerr << get_fileline() << ": error: real ";
if (wtype == NetNet::REG) cerr << "variable";
else cerr << "net";
cerr << " '" << name_
<< "' cannot be declared as a vector, found a range "
<< packed_dimensions << "." << endl;
des->errors += 1;
return 0;
}
/* If the net type is supply0 or supply1, replace it
with a simple wire with a pulldown/pullup with supply
strength. In other words, transform:

View File

@ -1,23 +1,23 @@
./ivltests/pr1723367.v:131: warning: Scalar port ``a'' has a vectored net declaration [7:0].
./ivltests/pr1723367.v:138: warning: Scalar port ``a'' has a vectored net declaration [7:0].
./ivltests/pr1723367.v:132: warning: Scalar port ``a'' has a vectored net declaration [7:0].
./ivltests/pr1723367.v:140: warning: Scalar port ``a'' has a vectored net declaration [7:0].
./ivltests/pr1723367.v:141: warning: Scalar port ``b'' has a vectored net declaration [15:0].
./ivltests/pr1723367.v:148: warning: Scalar port ``a'' has a vectored net declaration [7:0].
./ivltests/pr1723367.v:156: warning: Scalar port ``a'' has a vectored net declaration [7:0].
./ivltests/pr1723367.v:167: warning: Scalar port ``a'' has a vectored net declaration [7:0].
./ivltests/pr1723367.v:174: warning: Scalar port ``a'' has a vectored net declaration [7:0].
./ivltests/pr1723367.v:149: warning: Scalar port ``a'' has a vectored net declaration [7:0].
./ivltests/pr1723367.v:157: warning: Scalar port ``a'' has a vectored net declaration [7:0].
./ivltests/pr1723367.v:168: warning: Scalar port ``a'' has a vectored net declaration [7:0].
./ivltests/pr1723367.v:176: warning: Scalar port ``a'' has a vectored net declaration [7:0].
./ivltests/pr1723367.v:177: warning: Scalar port ``b'' has a vectored net declaration [15:0].
./ivltests/pr1723367.v:184: warning: Scalar port ``a'' has a vectored net declaration [7:0].
./ivltests/pr1723367.v:192: warning: Scalar port ``a'' has a vectored net declaration [7:0].
./ivltests/pr1723367.v:203: warning: Scalar port ``a'' has a vectored net declaration [7:0].
./ivltests/pr1723367.v:212: warning: Scalar port ``a'' has a vectored net declaration [7:0].
./ivltests/pr1723367.v:185: warning: Scalar port ``a'' has a vectored net declaration [7:0].
./ivltests/pr1723367.v:193: warning: Scalar port ``a'' has a vectored net declaration [7:0].
./ivltests/pr1723367.v:204: warning: Scalar port ``a'' has a vectored net declaration [7:0].
./ivltests/pr1723367.v:214: warning: Scalar port ``a'' has a vectored net declaration [7:0].
./ivltests/pr1723367.v:215: warning: Scalar port ``b'' has a vectored net declaration [31:0].
./ivltests/pr1723367.v:246: warning: Scalar port ``a'' has a vectored net declaration [15:0].
./ivltests/pr1723367.v:253: warning: Scalar port ``a'' has a vectored net declaration [7:0].
./ivltests/pr1723367.v:247: warning: Scalar port ``a'' has a vectored net declaration [15:0].
./ivltests/pr1723367.v:255: warning: Scalar port ``a'' has a vectored net declaration [7:0].
./ivltests/pr1723367.v:256: warning: Scalar port ``b'' has a vectored net declaration [31:0].
./ivltests/pr1723367.v:282: warning: Scalar port ``a'' has a vectored net declaration [15:0].
./ivltests/pr1723367.v:289: warning: Scalar port ``a'' has a vectored net declaration [7:0].
./ivltests/pr1723367.v:283: warning: Scalar port ``a'' has a vectored net declaration [15:0].
./ivltests/pr1723367.v:291: warning: Scalar port ``a'' has a vectored net declaration [7:0].
./ivltests/pr1723367.v:292: warning: Scalar port ``b'' has a vectored net declaration [15:0].
./ivltests/pr1723367.v:307: warning: Scalar port ``a'' has a vectored net declaration [15:0].
./ivltests/pr1723367.v:308: warning: Scalar port ``a'' has a vectored net declaration [15:0].
sum[ 1] = 0101010101100000
sum[ 2] = 0101010101100000
sum[ 3] = 0101010101100000

View File

@ -1 +1,2 @@
./ivltests/pr1841300.v:15: warning: Scalar port ``l'' has a vectored net declaration [4:0].
a is '14'; b is 'fffffff4'; c is 'fffffff4'

View File

@ -1 +1,8 @@
./ivltests/pr1960619.v:26: warning: Scalar port ``l'' has a vectored net declaration [7:0].
./ivltests/pr1960619.v:26: warning: Scalar port ``r'' has a vectored net declaration [7:0].
./ivltests/pr1960619.v:14: warning: Scalar port ``l'' has a vectored net declaration [4:0].
./ivltests/pr1960619.v:32: warning: Scalar port ``l'' has a vectored net declaration [31:0].
./ivltests/pr1960619.v:47: warning: Scalar port ``l'' has a vectored net declaration [31:0].
./ivltests/pr1960619.v:20: warning: Scalar port ``l'' has a vectored net declaration [7:0].
./ivltests/pr1960619.v:20: warning: Scalar port ``r'' has a vectored net declaration [7:0].
a is 14; b is fffffff4; c is 14; d is fffffff4

View File

@ -1,3 +1,5 @@
./ivltests/pr2001162.v:36: warning: Scalar port ``l'' has a vectored net declaration [31:0].
./ivltests/pr2001162.v:36: warning: Scalar port ``r'' has a vectored net declaration [31:0].
test2 increment; reading counter as 0
test1 increment; reading counter as 1
test2 increment; reading counter as 2

View File

@ -1,26 +0,0 @@
module dut(input [3:0] DataI, output [3:0] DataO);
wire [3:0] DataI;
reg [3:0] DataO;
always @* DataO = DataI;
endmodule
module top();
reg [3:0] DataI;
wire [3:0] DataO;
dut dut(DataI, DataO);
initial begin
DataI = 5;
#1;
if (DataO === 5)
$display("PASSED");
else
$display("FAILED");
end
endmodule

View File

@ -0,0 +1,14 @@
// Check that it is an error to declare a non-ANSI module port with implicit
// packed dimensions if it is later redeclared as an atom2 typed variable. Even
// if the size of the packed dimensions matches that of the size of the atom2
// type.
module test(x);
output [15:0] x;
shortint x;
initial begin
$display("FAILED");
end
endmodule

View File

@ -0,0 +1,17 @@
// Check that it is an error to declare a non-ANSI module port with implicit
// packed dimensions if it is later redeclared as a enum typed variable. Even if
// the size of the packed dimensions matches that of the size of the enum type.
typedef enum integer {
A, B
} T;
module test(x);
output [31:0] x;
T x;
initial begin
$display("FAILED");
end
endmodule

View File

@ -0,0 +1,7 @@
// Check that declaring multiple non-ANSI module ports with the same name is an
// error. Even if they both have an implicit type.
module test(x);
input x;
input x;
endmodule

View File

@ -0,0 +1,7 @@
// Check that declaring a non-ANSI module port with an explicit type for a
// signal that was previously declared as a real variable is an error.
module test(x);
real x;
output integer x;
endmodule

View File

@ -0,0 +1,9 @@
// Check that declaring multiple non-ANSI module ports with an implicit type and
// the same name is an error. Even if the signal was previously declared as a
// net.
module test(x);
wire x;
input x;
input x;
endmodule

View File

@ -0,0 +1,10 @@
// Check that declaring multiple non-ANSI module ports with an implicit type and
// the same name is an error. Even if the signal was previously declared as a
// integer typed net.
module test(x);
wire integer x;
input x;
input x;
endmodule

View File

@ -0,0 +1,8 @@
// Check that declaring multiple non-ANSI module output ports with an explicit
// type is an error. Even if the types are the same.
module test(x);
output integer x;
output integer x;
endmodule

View File

@ -0,0 +1,8 @@
// Check that declaring a net multiple times for a signal that was previously
// declared as a non-ANSI module port is an error.
module test(x);
input x;
wire x;
wire x;
endmodule

View File

@ -0,0 +1,8 @@
// Check that declaring a variable multiple times for a signal that was
// previously declared as a non-ANSI module port is an error.
module test(x);
output x;
reg x;
reg x;
endmodule

View File

@ -0,0 +1,8 @@
// Check that declaring both a net and a variable for a signal that was
// previously declared as a non-ANSI module port is an error.
module test(x);
input x;
wire x;
reg x;
endmodule

View File

@ -0,0 +1,8 @@
// Check that declaring an integer typed non-ANSI module port for signal that
// was previously declared as a net is an error. Even if the types for both
// declarations are the same.
module test(x);
wire integer x;
input integer x;
endmodule

View File

@ -0,0 +1,8 @@
// Check that declaring an integer typed net for a signal that was previously
// declared as a non-ANSI module port is an error. Even if the types for both
// declarations are the same.
module test(x);
input integer x;
wire integer x;
endmodule

View File

@ -0,0 +1,8 @@
// Check that declaring a real typed variable for a signal that was previously
// declared as a non-ANSI module port is an error. Even if the types for both
// declarations are the same.
module test(x);
output real x;
real x;
endmodule

View File

@ -0,0 +1,8 @@
// Check that declaring a real typed non-ANSI module port for a signal that was
// previously declared as a variable is an error. Even if the types for both
// declarations are the same.
module test(x);
real x;
output real x;
endmodule

View File

@ -0,0 +1,7 @@
// Check that declaring an integer typed variable for a signal that was previously
// declared as a real typed non-ANSI module port is an error.
module test(x);
output real x;
integer x;
endmodule

View File

@ -0,0 +1,14 @@
// Check that it is an error to declare a non-ANSI module port with implicit
// packed dimensions if it is later redeclared as an integer typed variable.
// Even if the size of the packed dimensions matches that of the size of the
// integer type.
module test(x);
output [31:0] x;
integer x;
initial begin
$display("FAILED");
end
endmodule

View File

@ -0,0 +1,17 @@
// Check that it is an error to declare a non-ANSI module port with implicit
// packed dimensions if it is later redeclared as a packed array typed variable.
// Even if the size of the packed dimensions matches that of the size of the
// packed array.
typedef reg [7:0] T1;
typedef T1 [3:0] T2;
module test(x);
output [31:0] x;
T2 x;
initial begin
$display("FAILED");
end
endmodule

View File

@ -0,0 +1,12 @@
// Check that it is an error to declare a non-ANSI module port with implicit
// packed dimensions if it is later redeclared as a real typed variable.
module test(x);
output [3:0] x;
real x;
initial begin
$display("FAILED");
end
endmodule

View File

@ -0,0 +1,19 @@
// Check that it is an error to declare a non-ANSI module port with implicit
// packed dimensions if it is later redeclared as a packed struct typed
// variable. Even if the size of the packed dimensions matches that of the size
// of the struct.
typedef struct packed {
reg [31:0] x;
reg [7:0] y;
} T;
module test(x);
output [47:0] x;
T x;
initial begin
$display("FAILED");
end
endmodule

View File

@ -0,0 +1,13 @@
// Check that it is an error to declare a non-ANSI module port with implicit
// packed dimensions if it is later redeclared as a time typed variable. Even if
// the size of the packed dimensions matches that of the size of the time type.
module test(x);
output [63:0] x;
time x;
initial begin
$display("FAILED");
end
endmodule

View File

@ -0,0 +1,13 @@
// Check that it is an error to declare a non-ANSI module port with implicit
// packed dimensions if it is later redeclared as a vector typed variable and
// the size of the packed dimensions do not match.
module test(x);
output [3:0] x;
reg [7:0] x;
initial begin
$display("FAILED");
end
endmodule

View File

@ -0,0 +1,13 @@
// Check that it is an error to declare a non-ANSI module port without implicit
// packed dimensions if it is later redeclared as a vector typed variable and
// the vector type is not a scalar.
module test(x);
output x;
reg [7:0] x;
initial begin
$display("FAILED");
end
endmodule

View File

@ -0,0 +1,13 @@
// Check that it is an error to declare a non-ANSI module port with implicit
// packed dimensions if it is later redeclared as a vector typed variable and
// the vector type is a scalar.
module test(x);
output [7:0] x;
reg x;
initial begin
$display("FAILED");
end
endmodule

View File

@ -0,0 +1,16 @@
// Check that it is an error to declare a non-ANSI task port with implicit
// packed dimensions if it is later redeclared as an atom2 typed variable. Even
// if the size of the packed dimensions matches that of the size of the atom2
// type.
module test;
task t;
input [15:0] x;
shortint x;
$display("FAILED");
endtask
initial t(10);
endmodule

View File

@ -0,0 +1,19 @@
// Check that it is an error to declare a non-ANSI task port with implicit
// packed dimensions if it is later redeclared as a enum typed variable. Even if
// the size of the packed dimensions matches that of the size of the enum type.
typedef enum integer {
A, B
} T;
module test;
task t;
input [31:0] x;
T x;
$display("FAILED");
endtask
initial t(10);
endmodule

View File

@ -0,0 +1,15 @@
// Check that declaring multiple task non-ANSI ports with the same name is an
// error. Even if they both have an implicit type.
module test;
task t;
input x;
input x;
$display("FAILED");
endtask
reg y;
initial t(y, y);
endmodule

View File

@ -0,0 +1,17 @@
// Check that declaring two non-ANSI task ports with an implicit type and the
// same name is an error. Even if the signal was previously declared as an
// variable.
module test;
task t;
integer x;
input x;
input x;
$display("FAILED");
endtask
integer y;
initial t(y, y);
endmodule

View File

@ -0,0 +1,15 @@
// Check that declaring two non-ANSI output task ports with an explicit type is
// an error. Even if the types are the same.
module test;
task t;
input integer x;
input integer x;
$display("FAILED");
endtask
integer y;
initial t(y, y);
endmodule

View File

@ -0,0 +1,16 @@
// Check that declaring a variable multiple times for a signal that was
// previously declared as a non-ANSI task input port is an error.
module test;
task t;
input x;
reg x;
reg x;
$display("FAILED");
endtask
reg y;
initial t(y);
endmodule

View File

@ -0,0 +1,16 @@
// Check that declaring a variable multiple times for a signal that was
// previously declared as a non-ANSI task output port is an error.
module test;
task t;
output x;
reg x;
reg x;
$display("FAILED");
endtask
reg y;
initial t(y);
endmodule

View File

@ -0,0 +1,16 @@
// Check that declaring an integer typed non-ANSI task port for signal that was
// previously declared as a variable is an error. Even if the types for both
// declarations are the same.
module test;
task t;
integer x;
input integer x;
$display("FAILED");
endtask
integer y;
initial t(y);
endmodule

View File

@ -0,0 +1,15 @@
// Check that declaring an integer typed variabe for a signal that was
// previously declared as a non-ANSI task port is an error. Even if the types
// for both declarations are the same.
module test;
task t;
input integer x;
integer x;
$display("FAILED");
endtask
initial t();
endmodule

View File

@ -0,0 +1,16 @@
// Check that declaring a real typed variable for a signal that was previously
// declared as a non-ANSI task port is an error. Even if the types for both
// declarations are the same.
module test;
task t;
output real x;
real x;
$display("FAILED");
endtask
real y;
initial t(y);
endmodule

View File

@ -0,0 +1,16 @@
// Check that declaring a real typed non-ANSI task port for signal that was
// previously declared as a variable is an error. Even if the types for both
// declarations are the same.
module test;
task t;
real x;
output real x;
$display("FAILED");
endtask
real y;
initial t(y);
endmodule

View File

@ -0,0 +1,14 @@
// Check that declaring an integer typed variable for a signal that was previously
// declared as a real typed non-ANSI task port is an error.
module test;
task t;
output real x;
integer x;
$display("FAILED");
endtask
initial t();
endmodule

View File

@ -0,0 +1,15 @@
// Check that declaring a non-ANSI task port with an explicit type for a signal
// that was previously declared real variable is an error.
module test;
task t;
real x;
output integer x;
$display("FAILED");
endtask
real y;
initial t(y);
endmodule

View File

@ -0,0 +1,16 @@
// Check that it is an error to declare a non-ANSI task port with implicit
// packed dimensions if it is later redeclared as an integer typed variable.
// Even if the size of the packed dimensions matches that of the size of the
// integer type.
module test;
task t;
input [31:0] x;
integer x;
$display("FAILED");
endtask
initial t(10);
endmodule

View File

@ -0,0 +1,19 @@
// Check that it is an error to declare a non-ANSI task port with implicit
// packed dimensions if it is later redeclared as a packed array typed variable.
// Even if the size of the packed dimensions matches that of the size of the
// packed array.
typedef reg [7:0] T1;
typedef T1 [3:0] T2;
module test;
task t;
input [31:0] x;
T2 x;
$display("FAILED");
endtask
initial t(10);
endmodule

View File

@ -0,0 +1,14 @@
// Check that it is an error to declare a non-ANSI task port with implicit
// packed dimensions if it is later redeclared as a real typed variable.
module test;
task t;
input [3:0] x;
real x;
$display("FAILED");
endtask
initial t(10);
endmodule

View File

@ -0,0 +1,21 @@
// Check that it is an error to declare a non-ANSI task port with implicit
// packed dimensions if it is later redeclared as a packed struct typed
// variable. Even if the size of the packed dimensions matches that of the size
// of the struct.
typedef struct packed {
reg [31:0] x;
reg [7:0] y;
} T;
module test;
task t;
input [47:0] x;
T x;
$display("FAILED");
endtask
initial t(10);
endmodule

View File

@ -0,0 +1,15 @@
// Check that it is an error to declare a non-ANSI task port with implicit
// packed dimensions if it is later redeclared as a time typed variable. Even if
// the size of the packed dimensions matches that of the size of the time type.
module test;
task t;
input [63:0] x;
time x;
$display("FAILED");
endtask
initial t(10);
endmodule

View File

@ -0,0 +1,17 @@
// Check that it is an error to declare a non-ANSI task port with implicit
// packed dimensions if it is later redeclared as a vector typed variable and
// the size of the packed dimensions do not match.
module test;
task t;
input [7:0] x;
reg [3:0] x;
$display("FAILED");
endtask
initial begin
t(10);
end
endmodule

View File

@ -0,0 +1,17 @@
// Check that it is an error to declare a non-ANSI task port without implicit
// packed dimensions if it is later redeclared as a vector typed variable and
// the vector type is not a scalar.
module test;
task t;
input [7:0] x;
reg x;
$display("FAILED");
endtask
initial begin
t(10);
end
endmodule

View File

@ -0,0 +1,17 @@
// Check that it is an error to declare a non-ANSI task port with implicit
// packed dimensions if it is later redeclared as a vector typed variable and
// the vector type is a scalar.
module test;
task t;
input x;
reg [3:0] x;
$display("FAILED");
endtask
initial begin
t(10);
end
endmodule

View File

@ -351,16 +351,21 @@ localparam_type2 normal,-g2009 ivltests
logical_short_circuit normal,-g2012 ivltests
logp2 normal,-g2005-sv ivltests
mod_inst_pkg normal,-g2009 ivltests
module_nonansi_atom2_fail CE,-g2005-sv ivltests
module_nonansi_enum1 normal,-g2005-sv ivltests
module_nonansi_enum2 normal,-g2005-sv ivltests
module_nonansi_enum_fail CE,-g2005-sv ivltests
module_nonansi_int1 normal,-g2005-sv ivltests
module_nonansi_int2 normal,-g2005-sv ivltests
module_nonansi_parray1 normal,-g2005-sv ivltests
module_nonansi_parray2 normal,-g2005-sv ivltests
module_nonansi_parray_fail CE,-g2005-sv ivltests
module_nonansi_real1 normal,-g2005-sv ivltests
module_nonansi_real2 normal,-g2005-sv ivltests
module_nonansi_real_fail CE,-g2005-sv ivltests
module_nonansi_struct1 normal,-g2005-sv ivltests
module_nonansi_struct2 normal,-g2005-sv ivltests
module_nonansi_struct_fail CE,-g2005-sv ivltests
module_output_port_sv_var1 normal,-g2005-sv ivltests
module_output_port_sv_var2 normal,-g2005-sv ivltests
named_begin normal,-g2009 ivltests
@ -724,14 +729,18 @@ task_init_assign normal,-g2009 ivltests
task_init_var1 normal,-g2009 ivltests
task_init_var2 normal,-g2009 ivltests
task_init_var3 normal,-g2009 ivltests
task_nonansi_atom2_fail CE,-g2005-sv ivltests
task_nonansi_enum1 normal,-g2005-sv ivltests
task_nonansi_enum2 normal,-g2005-sv ivltests
task_nonansi_enum_fail CE,-g2005-sv ivltests
task_nonansi_int1 normal,-g2005-sv ivltests
task_nonansi_int2 normal,-g2005-sv ivltests
task_nonansi_parray1 normal,-g2005-sv ivltests
task_nonansi_parray2 normal,-g2005-sv ivltests
task_nonansi_parray_fail CE,-g2005-sv ivltests
task_nonansi_struct1 normal,-g2005-sv ivltests
task_nonansi_struct2 normal,-g2005-sv ivltests
task_nonansi_struct_fail CE,-g2005-sv ivltests
task_port_types1 normal,-g2009 ivltests
task_port_types2 normal,-g2009 ivltests
task_scope2 normal,-g2009 ivltests

View File

@ -351,7 +351,6 @@ br_gh674 normal ivltests
br_gh732 normal ivltests gold=br_gh732.gold
br_ml20150315 normal ivltests gold=br_ml_20150315.gold
br_ml20150321 CE ivltests
br_ml20150606 normal ivltests
br_mw20171108 normal ivltests
br_ml20190806a normal ivltests
br_ml20190806b normal ivltests
@ -655,12 +654,30 @@ module_inout_port_list_def CE ivltests # inout ports do not support default va
module_inout_port_type CE ivltests
module_input_port_list_def CE ivltests # input ports only support default values in SV
module_input_port_type CE ivltests
module_nonansi_fail1 CE ivltests
module_nonansi_fail2 CE ivltests
module_nonansi_fail3 CE ivltests
module_nonansi_fail4 CE ivltests
module_nonansi_fail5 CE ivltests
module_nonansi_fail6 CE ivltests
module_nonansi_fail7 CE ivltests
module_nonansi_fail8 CE ivltests
module_nonansi_fail9 CE ivltests
module_nonansi_fail10 CE ivltests
module_nonansi_fail11 CE ivltests
module_nonansi_fail12 CE ivltests
module_nonansi_fail13 CE ivltests
module_nonansi_integer1 normal ivltests
module_nonansi_integer2 normal ivltests
module_nonansi_integer_fail CE ivltests
module_nonansi_time1 normal ivltests
module_nonansi_time2 normal ivltests
module_nonansi_time_fail CE ivltests
module_nonansi_vec1 normal ivltests
module_nonansi_vec2 normal ivltests
module_nonansi_vec_fail1 CE ivltests
module_nonansi_vec_fail2 CE ivltests
module_nonansi_vec_fail3 CE ivltests
module_output_port_list_def normal ivltests
module_output_port_var1 normal ivltests
module_output_port_var2 normal ivltests
@ -1049,7 +1066,7 @@ pr1832097a normal ivltests
pr1832097b normal ivltests
pr1833024 CE ivltests gold=pr1833024.gold
pr1833754 CE ivltests
pr1841300 normal ivltests gold=pr1841300.gold
pr1841300 normal,-gno-io-range-error ivltests gold=pr1841300.gold
pr1845683 normal ivltests gold=pr1845683.gold
pr1851310 normal ivltests gold=pr1851310.gold
pr1855504 normal ivltests gold=pr1855504.gold
@ -1117,7 +1134,7 @@ pr1960548 normal ivltests gold=pr1960548.gold
pr1960558 normal ivltests gold=pr1960558.gold
pr1960575 normal ivltests gold=pr1960575.gold
pr1960596 normal ivltests gold=pr1960596.gold
pr1960619 normal ivltests gold=pr1960619.gold
pr1960619 normal,-gno-io-range-error ivltests gold=pr1960619.gold
pr1960625 normal ivltests
pr1960633 normal ivltests
pr1963240 normal ivltests gold=pr1963240.gold
@ -1140,7 +1157,7 @@ pr1990269 normal ivltests
pr1992244 normal ivltests
pr1992729 normal ivltests
pr1993479 normal ivltests gold=pr1993479.gold
pr2001162 normal ivltests gold=pr2001162.gold
pr2001162 normal,-gno-io-range-error ivltests gold=pr2001162.gold
pr2011429 normal ivltests
pr2013758 normal ivltests
pr2014673 normal ivltests
@ -1635,14 +1652,31 @@ task_inpad normal ivltests # Validates input of task should pad w/ 0
task_iotypes normal ivltests # task ports with types.
task_iotypes2 normal ivltests # task ports with types.
task_mem normal ivltests
task_nonansi_fail1 CE ivltests
task_nonansi_fail2 CE ivltests
task_nonansi_fail3 CE ivltests
task_nonansi_fail4 CE ivltests
task_nonansi_fail5 CE ivltests
task_nonansi_fail6 CE ivltests
task_nonansi_fail7 CE ivltests
task_nonansi_fail8 CE ivltests
task_nonansi_fail9 CE ivltests
task_nonansi_fail10 CE ivltests
task_nonansi_fail11 CE ivltests
task_nonansi_integer1 normal ivltests
task_nonansi_integer2 normal ivltests
task_nonansi_integer_fail CE ivltests
task_nonansi_real1 normal ivltests
task_nonansi_real2 normal ivltests
task_nonansi_real_fail CE ivltests
task_nonansi_time1 normal ivltests
task_nonansi_time2 normal ivltests
task_nonansi_time_fail CE ivltests
task_nonansi_vec1 normal ivltests
task_nonansi_vec2 normal ivltests
task_nonansi_vec_fail1 CE ivltests
task_nonansi_vec_fail2 CE ivltests
task_nonansi_vec_fail3 CE ivltests
task_noop normal ivltests # Task with no contents.
task_noop2 CO ivltests # Task *really* with no contents.
task_omemw2 normal ivltests

View File

@ -1011,10 +1011,10 @@ pr1793749b normal,-pallowsigned=1 ivltests gold=pr1793749b.gold
pr1795005a normal,-pallowsigned=1 ivltests gold=pr1795005a.gold
pr1795005b normal,-pallowsigned=1 ivltests gold=pr1795005b.gold
pr1823732 normal,-pallowsigned=1 ivltests gold=pr1823732.gold
pr1841300 normal,-pallowsigned=1 ivltests gold=pr1841300.gold
pr1841300 normal,-pallowsigned=1,-gno-io-range-error ivltests gold=pr1841300.gold
pr1845683 normal,-pallowsigned=1 ivltests gold=pr1845683.gold
pr1960558 normal,-pallowsigned=1 ivltests gold=pr1960558.gold
pr1960619 normal,-pallowsigned=1 ivltests gold=pr1960619.gold
pr1960619 normal,-pallowsigned=1,-gno-io-range-error ivltests gold=pr1960619.gold
pr1963240 normal,-pallowsigned=1 ivltests gold=pr1963240.gold
pr1990164 normal,-pallowsigned=1 ivltests
pr2136787 normal,-pallowsigned=1 ivltests gold=pr2136787.gold

218
pform.cc
View File

@ -2148,13 +2148,8 @@ static void pform_set_net_range(PWire *wire,
PWSRType rt = SR_NET,
std::list<named_pexpr_t>*attr = 0)
{
if (range == 0) {
/* This is the special case that we really mean a
scalar. Set a fake range. */
wire->set_range_scalar(rt);
} else {
if (range)
wire->set_range(*range, rt);
}
wire->set_signed(signed_flag);
pform_bind_attributes(wire->attributes, attr, true);
@ -2515,6 +2510,68 @@ void pform_make_var_init(const struct vlltype&li,
lexical_scope->var_inits.push_back(ass);
}
/*
* This function makes a single signal (a wire, a reg, etc) as
* requested by the parser. The name is unscoped, so I attach the
* current scope to it (with the scoped_name function) and I try to
* resolve it with an existing PWire in the scope.
*
* The wire might already exist because of an implicit declaration in
* a module port, i.e.:
*
* module foo (bar...
*
* reg bar;
*
* The output (or other port direction indicator) may or may not have
* been seen already, so I do not do any checking with it yet. But I
* do check to see if the name has already been declared, as this
* function is called for every declaration.
*/
static PWire* pform_get_or_make_wire(const struct vlltype&li, perm_string name,
NetNet::Type type, NetNet::PortType ptype,
ivl_variable_type_t dtype, PWSRType rt)
{
PWire *cur = 0;
// If this is not a full declaration check if there is already a signal
// with the same name that can be extended.
if (rt != SR_BOTH)
cur = pform_get_wire_in_scope(name);
// If the wire already exists but isn't yet fully defined,
// carry on adding details.
if (rt == SR_NET && cur && !cur->is_net()) {
// At the moment there can only be one location for the PWire, if
// there is both a port and signal declaration use the location of
// the signal.
FILE_NAME(cur, li);
cur->set_net(type);
return cur;
}
if (rt == SR_PORT && cur && !cur->is_port()) {
cur->set_port(ptype);
return cur;
}
// If the wire already exists and is fully defined, this
// must be a redeclaration. Start again with a new wire.
// The error will be reported when we add the new wire
// to the scope. Do not delete the old wire - it will
// remain in the local symbol map.
cur = new PWire(name, type, ptype, dtype, rt);
FILE_NAME(cur, li);
pform_put_wire_in_scope(name, cur);
return cur;
}
/*
* This function is used by the parser when I have port definition of
* the form like this:
@ -2536,16 +2593,6 @@ void pform_module_define_port(const struct vlltype&li,
ivl_variable_type_t data_type = IVL_VT_NO_TYPE;
bool signed_flag = false;
PWire*cur = pform_get_wire_in_scope(name);
if (cur) {
ostringstream msg;
msg << name << " definition conflicts with "
<< "definition at " << cur->get_fileline()
<< ".";
VLerror(msg.str().c_str());
return;
}
pform_check_net_data_type(li, type, vtype);
// Packed ranges
@ -2583,27 +2630,22 @@ void pform_module_define_port(const struct vlltype&li,
if (data_type == IVL_VT_NO_TYPE)
data_type = IVL_VT_LOGIC;
cur = new PWire(name, type, port_kind, data_type);
FILE_NAME(cur, li);
PWire *cur = pform_get_or_make_wire(li, name, type, port_kind, data_type,
SR_BOTH);
cur->set_signed(signed_flag);
if (vtype)
cur->set_data_type(vtype);
if (prange == 0) {
cur->set_range_scalar((type == NetNet::IMPLICIT) ? SR_PORT : SR_BOTH);
} else {
cur->set_range(*prange, (type == NetNet::IMPLICIT) ? SR_PORT : SR_BOTH);
}
if (prange)
cur->set_range(*prange, SR_BOTH);
if (urange) {
cur->set_unpacked_idx(*urange);
}
pform_bind_attributes(cur->attributes, attr, keep_attr);
pform_put_wire_in_scope(name, cur);
}
void pform_module_define_port(const struct vlltype&li,
@ -2633,66 +2675,6 @@ void pform_module_define_port(const struct vlltype&li,
delete attr;
}
/*
* This function makes a single signal (a wire, a reg, etc) as
* requested by the parser. The name is unscoped, so I attach the
* current scope to it (with the scoped_name function) and I try to
* resolve it with an existing PWire in the scope.
*
* The wire might already exist because of an implicit declaration in
* a module port, i.e.:
*
* module foo (bar...
*
* reg bar;
*
* The output (or other port direction indicator) may or may not have
* been seen already, so I do not do any checking with it yet. But I
* do check to see if the name has already been declared, as this
* function is called for every declaration.
*/
static PWire* pform_get_or_make_wire(const vlltype&li, perm_string name,
NetNet::Type type, NetNet::PortType ptype,
ivl_variable_type_t dtype)
{
PWire*cur = pform_get_wire_in_scope(name);
// If the wire already exists but isn't yet fully defined,
// carry on adding details.
if (cur && (cur->get_data_type() == IVL_VT_NO_TYPE ||
cur->get_wire_type() == NetNet::IMPLICIT) ) {
// If this is not implicit ("implicit" meaning we don't
// know what the type is yet) then set the type now.
if (type != NetNet::IMPLICIT) {
bool rc = cur->set_wire_type(type);
if (rc == false) {
ostringstream msg;
msg << name << " " << type
<< " definition conflicts with " << cur->get_wire_type()
<< " definition at " << cur->get_fileline()
<< ".";
VLerror(msg.str().c_str());
}
FILE_NAME(cur, li);
}
return cur;
}
// If the wire already exists and is fully defined, this
// must be a redeclaration. Start again with a new wire.
// The error will be reported when we add the new wire
// to the scope. Do not delete the old wire - it will
// remain in the local symbol map.
cur = new PWire(name, type, ptype, dtype);
FILE_NAME(cur, li);
pform_put_wire_in_scope(name, cur);
return cur;
}
/*
* this is the basic form of pform_makewire. This takes a single simple
* name, port type, net type, data type, and attributes, and creates
@ -2703,7 +2685,7 @@ PWire *pform_makewire(const vlltype&li, perm_string name, NetNet::Type type,
ivl_variable_type_t dt, std::list<pform_range_t> *indices)
{
PWire*cur = pform_get_or_make_wire(li, name, type, NetNet::NOT_A_PORT,
dt);
dt, SR_NET);
assert(cur);
bool flag;
@ -2717,7 +2699,6 @@ PWire *pform_makewire(const vlltype&li, perm_string name, NetNet::Type type,
<< " to " << dt << "." << endl;
}
ivl_assert(*cur, flag);
cur->set_range_scalar(SR_NET);
cur->set_signed(true);
break;
default:
@ -2821,27 +2802,21 @@ static vector<pform_tf_port_t>*pform_make_task_ports(const struct vlltype&loc,
assert(pt != NetNet::PIMPLICIT && pt != NetNet::NOT_A_PORT);
assert(ports);
vector<pform_tf_port_t>*res = new vector<pform_tf_port_t>(0);
PWSRType rt = vtype != IVL_VT_NO_TYPE ? SR_BOTH : SR_PORT;
for (list<pform_port_t>::iterator cur = ports->begin()
; cur != ports->end() ; ++ cur ) {
perm_string &name = cur->name;
/* Look for a preexisting wire. If it exists, set the
port direction. If not, create it. */
PWire*curw = pform_get_wire_in_scope(name);
if (curw) {
curw->set_port_type(pt);
} else {
curw = new PWire(name, NetNet::IMPLICIT_REG, pt, vtype);
FILE_NAME(curw, loc);
pform_put_wire_in_scope(name, curw);
}
PWire*curw = pform_get_or_make_wire(loc, name, NetNet::IMPLICIT_REG,
pt, vtype, rt);
curw->set_signed(signed_flag);
/* If there is a range involved, it needs to be set. */
if (range) {
curw->set_range(*range, SR_PORT);
}
if (range)
curw->set_range(*range, rt);
if (cur->udims) {
if (pform_requires_sv(loc, "Task/function port with unpacked dimensions"))
@ -2857,27 +2832,23 @@ static vector<pform_tf_port_t>*pform_make_task_ports(const struct vlltype&loc,
static vector<pform_tf_port_t>*do_make_task_ports(const struct vlltype&loc,
NetNet::PortType pt,
ivl_variable_type_t var_type,
ivl_variable_type_t vtype,
data_type_t*data_type,
list<pform_port_t>*ports)
{
assert(pt != NetNet::PIMPLICIT && pt != NetNet::NOT_A_PORT);
assert(ports);
vector<pform_tf_port_t>*res = new vector<pform_tf_port_t>(0);
PWSRType rt = data_type ? SR_BOTH : SR_PORT;
for (list<pform_port_t>::iterator cur = ports->begin()
; cur != ports->end() ; ++cur) {
perm_string &name = cur->name;
PWire*curw = pform_get_wire_in_scope(name);
if (curw) {
curw->set_port_type(pt);
} else {
curw = new PWire(name, NetNet::IMPLICIT_REG, pt, var_type);
FILE_NAME(curw, loc);
PWire*curw = pform_get_or_make_wire(loc, name, NetNet::IMPLICIT_REG,
pt, vtype, rt);
if (data_type)
curw->set_data_type(data_type);
pform_put_wire_in_scope(name, curw);
}
if (cur->udims) {
if (pform_requires_sv(loc, "Task/function port with unpacked dimensions"))
@ -3256,34 +3227,6 @@ extern void pform_module_specify_path(PSpecPath*obj)
}
static PWire *pform_set_port_type(const struct vlltype&li,
perm_string name, NetNet::PortType pt)
{
PWire*cur = pform_get_wire_in_scope(name);
if (cur == 0) {
cur = new PWire(name, NetNet::IMPLICIT, NetNet::PIMPLICIT, IVL_VT_NO_TYPE);
FILE_NAME(cur, li);
pform_put_wire_in_scope(name, cur);
}
switch (cur->get_port_type()) {
case NetNet::NOT_A_PORT:
case NetNet::PIMPLICIT:
if (! cur->set_port_type(pt))
VLerror("error setting port direction.");
break;
default:
cerr << li << ": error: "
<< "port " << name << " already has a port declaration."
<< endl;
error_count += 1;
break;
}
return cur;
}
void pform_set_port_type(const struct vlltype&li,
list<pform_port_t>*ports,
NetNet::PortType pt,
@ -3306,7 +3249,8 @@ void pform_set_port_type(const struct vlltype&li,
for (list<pform_port_t>::iterator cur = ports->begin()
; cur != ports->end() ; ++ cur ) {
PWire *wire = pform_set_port_type(li, cur->name, pt);
PWire *wire = pform_get_or_make_wire(li, cur->name, NetNet::IMPLICIT, pt,
IVL_VT_NO_TYPE, SR_PORT);
pform_set_net_range(wire, range, signed_flag, SR_PORT, attr);
if (cur->udims) {
cerr << li << ": warning: "