diff --git a/PExpr.cc b/PExpr.cc index df07f982e..2bd2b78d6 100644 --- a/PExpr.cc +++ b/PExpr.cc @@ -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 " diff --git a/PWire.cc b/PWire.cc index 3591657b3..f44505850 100644 --- a/PWire.cc +++ b/PWire.cc @@ -18,6 +18,7 @@ */ # include "config.h" +# include "ivl_assert.h" # include "PWire.h" # include "PExpr.h" # include @@ -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&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; } } diff --git a/PWire.h b/PWire.h index dfc70970d..69b64296e 100644 --- a/PWire.h +++ b/PWire.h @@ -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&ranges, PWSRType type); void set_unpacked_idx(const std::list&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_; diff --git a/elab_sig.cc b/elab_sig.cc index 6f778f669..288bbb634 100644 --- a/elab_sig.cc +++ b/elab_sig.cc @@ -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: diff --git a/ivtest/gold/pr1723367.gold b/ivtest/gold/pr1723367.gold index 4b17f0295..0c42441aa 100644 --- a/ivtest/gold/pr1723367.gold +++ b/ivtest/gold/pr1723367.gold @@ -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 diff --git a/ivtest/gold/pr1841300.gold b/ivtest/gold/pr1841300.gold index e70fe4209..d231bad28 100644 --- a/ivtest/gold/pr1841300.gold +++ b/ivtest/gold/pr1841300.gold @@ -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' diff --git a/ivtest/gold/pr1960619.gold b/ivtest/gold/pr1960619.gold index 904cd9621..47341e829 100644 --- a/ivtest/gold/pr1960619.gold +++ b/ivtest/gold/pr1960619.gold @@ -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 diff --git a/ivtest/gold/pr2001162.gold b/ivtest/gold/pr2001162.gold index cc6c4a0e3..19361c8b1 100644 --- a/ivtest/gold/pr2001162.gold +++ b/ivtest/gold/pr2001162.gold @@ -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 diff --git a/ivtest/ivltests/br_ml20150606.v b/ivtest/ivltests/br_ml20150606.v deleted file mode 100644 index d04af02d6..000000000 --- a/ivtest/ivltests/br_ml20150606.v +++ /dev/null @@ -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 diff --git a/ivtest/ivltests/module_nonansi_atom2_fail.v b/ivtest/ivltests/module_nonansi_atom2_fail.v new file mode 100644 index 000000000..7077e0d36 --- /dev/null +++ b/ivtest/ivltests/module_nonansi_atom2_fail.v @@ -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 diff --git a/ivtest/ivltests/module_nonansi_enum_fail.v b/ivtest/ivltests/module_nonansi_enum_fail.v new file mode 100644 index 000000000..f8611c094 --- /dev/null +++ b/ivtest/ivltests/module_nonansi_enum_fail.v @@ -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 diff --git a/ivtest/ivltests/module_nonansi_fail1.v b/ivtest/ivltests/module_nonansi_fail1.v new file mode 100644 index 000000000..5f1cde8e1 --- /dev/null +++ b/ivtest/ivltests/module_nonansi_fail1.v @@ -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 diff --git a/ivtest/ivltests/module_nonansi_fail10.v b/ivtest/ivltests/module_nonansi_fail10.v new file mode 100644 index 000000000..3b714d28b --- /dev/null +++ b/ivtest/ivltests/module_nonansi_fail10.v @@ -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 diff --git a/ivtest/ivltests/module_nonansi_fail11.v b/ivtest/ivltests/module_nonansi_fail11.v new file mode 100644 index 000000000..77d3c44f1 --- /dev/null +++ b/ivtest/ivltests/module_nonansi_fail11.v @@ -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 diff --git a/ivtest/ivltests/module_nonansi_fail12.v b/ivtest/ivltests/module_nonansi_fail12.v new file mode 100644 index 000000000..ad5b2dafb --- /dev/null +++ b/ivtest/ivltests/module_nonansi_fail12.v @@ -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 diff --git a/ivtest/ivltests/module_nonansi_fail13.v b/ivtest/ivltests/module_nonansi_fail13.v new file mode 100644 index 000000000..4d2cd2733 --- /dev/null +++ b/ivtest/ivltests/module_nonansi_fail13.v @@ -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 diff --git a/ivtest/ivltests/module_nonansi_fail2.v b/ivtest/ivltests/module_nonansi_fail2.v new file mode 100644 index 000000000..2e84e422b --- /dev/null +++ b/ivtest/ivltests/module_nonansi_fail2.v @@ -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 diff --git a/ivtest/ivltests/module_nonansi_fail3.v b/ivtest/ivltests/module_nonansi_fail3.v new file mode 100644 index 000000000..21c078034 --- /dev/null +++ b/ivtest/ivltests/module_nonansi_fail3.v @@ -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 diff --git a/ivtest/ivltests/module_nonansi_fail4.v b/ivtest/ivltests/module_nonansi_fail4.v new file mode 100644 index 000000000..3303683f2 --- /dev/null +++ b/ivtest/ivltests/module_nonansi_fail4.v @@ -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 diff --git a/ivtest/ivltests/module_nonansi_fail5.v b/ivtest/ivltests/module_nonansi_fail5.v new file mode 100644 index 000000000..97c664cc0 --- /dev/null +++ b/ivtest/ivltests/module_nonansi_fail5.v @@ -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 diff --git a/ivtest/ivltests/module_nonansi_fail6.v b/ivtest/ivltests/module_nonansi_fail6.v new file mode 100644 index 000000000..9ce2c6fca --- /dev/null +++ b/ivtest/ivltests/module_nonansi_fail6.v @@ -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 diff --git a/ivtest/ivltests/module_nonansi_fail7.v b/ivtest/ivltests/module_nonansi_fail7.v new file mode 100644 index 000000000..21f50a184 --- /dev/null +++ b/ivtest/ivltests/module_nonansi_fail7.v @@ -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 diff --git a/ivtest/ivltests/module_nonansi_fail8.v b/ivtest/ivltests/module_nonansi_fail8.v new file mode 100644 index 000000000..7603854d0 --- /dev/null +++ b/ivtest/ivltests/module_nonansi_fail8.v @@ -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 diff --git a/ivtest/ivltests/module_nonansi_fail9.v b/ivtest/ivltests/module_nonansi_fail9.v new file mode 100644 index 000000000..6240fca3d --- /dev/null +++ b/ivtest/ivltests/module_nonansi_fail9.v @@ -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 diff --git a/ivtest/ivltests/module_nonansi_integer_fail.v b/ivtest/ivltests/module_nonansi_integer_fail.v new file mode 100644 index 000000000..c92dc5130 --- /dev/null +++ b/ivtest/ivltests/module_nonansi_integer_fail.v @@ -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 diff --git a/ivtest/ivltests/module_nonansi_parray_fail.v b/ivtest/ivltests/module_nonansi_parray_fail.v new file mode 100644 index 000000000..6ab45f9ba --- /dev/null +++ b/ivtest/ivltests/module_nonansi_parray_fail.v @@ -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 diff --git a/ivtest/ivltests/module_nonansi_real_fail.v b/ivtest/ivltests/module_nonansi_real_fail.v new file mode 100644 index 000000000..f8f05a018 --- /dev/null +++ b/ivtest/ivltests/module_nonansi_real_fail.v @@ -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 diff --git a/ivtest/ivltests/module_nonansi_struct_fail.v b/ivtest/ivltests/module_nonansi_struct_fail.v new file mode 100644 index 000000000..39f7be326 --- /dev/null +++ b/ivtest/ivltests/module_nonansi_struct_fail.v @@ -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 diff --git a/ivtest/ivltests/module_nonansi_time_fail.v b/ivtest/ivltests/module_nonansi_time_fail.v new file mode 100644 index 000000000..c06532a39 --- /dev/null +++ b/ivtest/ivltests/module_nonansi_time_fail.v @@ -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 diff --git a/ivtest/ivltests/module_nonansi_vec_fail1.v b/ivtest/ivltests/module_nonansi_vec_fail1.v new file mode 100644 index 000000000..ade4b9b07 --- /dev/null +++ b/ivtest/ivltests/module_nonansi_vec_fail1.v @@ -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 diff --git a/ivtest/ivltests/module_nonansi_vec_fail2.v b/ivtest/ivltests/module_nonansi_vec_fail2.v new file mode 100644 index 000000000..4c3e55da1 --- /dev/null +++ b/ivtest/ivltests/module_nonansi_vec_fail2.v @@ -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 diff --git a/ivtest/ivltests/module_nonansi_vec_fail3.v b/ivtest/ivltests/module_nonansi_vec_fail3.v new file mode 100644 index 000000000..e5bca214d --- /dev/null +++ b/ivtest/ivltests/module_nonansi_vec_fail3.v @@ -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 diff --git a/ivtest/ivltests/task_nonansi_atom2_fail.v b/ivtest/ivltests/task_nonansi_atom2_fail.v new file mode 100644 index 000000000..06d2a389e --- /dev/null +++ b/ivtest/ivltests/task_nonansi_atom2_fail.v @@ -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 diff --git a/ivtest/ivltests/task_nonansi_enum_fail.v b/ivtest/ivltests/task_nonansi_enum_fail.v new file mode 100644 index 000000000..c6cf38bcd --- /dev/null +++ b/ivtest/ivltests/task_nonansi_enum_fail.v @@ -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 diff --git a/ivtest/ivltests/task_nonansi_fail1.v b/ivtest/ivltests/task_nonansi_fail1.v new file mode 100644 index 000000000..f81ee6e92 --- /dev/null +++ b/ivtest/ivltests/task_nonansi_fail1.v @@ -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 diff --git a/ivtest/ivltests/task_nonansi_fail10.v b/ivtest/ivltests/task_nonansi_fail10.v new file mode 100644 index 000000000..10705a602 --- /dev/null +++ b/ivtest/ivltests/task_nonansi_fail10.v @@ -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 diff --git a/ivtest/ivltests/task_nonansi_fail11.v b/ivtest/ivltests/task_nonansi_fail11.v new file mode 100644 index 000000000..82d4b2285 --- /dev/null +++ b/ivtest/ivltests/task_nonansi_fail11.v @@ -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 diff --git a/ivtest/ivltests/task_nonansi_fail2.v b/ivtest/ivltests/task_nonansi_fail2.v new file mode 100644 index 000000000..9e4f07537 --- /dev/null +++ b/ivtest/ivltests/task_nonansi_fail2.v @@ -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 diff --git a/ivtest/ivltests/task_nonansi_fail3.v b/ivtest/ivltests/task_nonansi_fail3.v new file mode 100644 index 000000000..584b2dfd3 --- /dev/null +++ b/ivtest/ivltests/task_nonansi_fail3.v @@ -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 diff --git a/ivtest/ivltests/task_nonansi_fail4.v b/ivtest/ivltests/task_nonansi_fail4.v new file mode 100644 index 000000000..c5d3249c8 --- /dev/null +++ b/ivtest/ivltests/task_nonansi_fail4.v @@ -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 diff --git a/ivtest/ivltests/task_nonansi_fail5.v b/ivtest/ivltests/task_nonansi_fail5.v new file mode 100644 index 000000000..e1b3f2d8e --- /dev/null +++ b/ivtest/ivltests/task_nonansi_fail5.v @@ -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 diff --git a/ivtest/ivltests/task_nonansi_fail6.v b/ivtest/ivltests/task_nonansi_fail6.v new file mode 100644 index 000000000..7b0c09ada --- /dev/null +++ b/ivtest/ivltests/task_nonansi_fail6.v @@ -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 diff --git a/ivtest/ivltests/task_nonansi_fail7.v b/ivtest/ivltests/task_nonansi_fail7.v new file mode 100644 index 000000000..5d994273d --- /dev/null +++ b/ivtest/ivltests/task_nonansi_fail7.v @@ -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 diff --git a/ivtest/ivltests/task_nonansi_fail8.v b/ivtest/ivltests/task_nonansi_fail8.v new file mode 100644 index 000000000..6adf2e2cd --- /dev/null +++ b/ivtest/ivltests/task_nonansi_fail8.v @@ -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 diff --git a/ivtest/ivltests/task_nonansi_fail9.v b/ivtest/ivltests/task_nonansi_fail9.v new file mode 100644 index 000000000..17ad486d1 --- /dev/null +++ b/ivtest/ivltests/task_nonansi_fail9.v @@ -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 diff --git a/ivtest/ivltests/task_nonansi_integer_fail.v b/ivtest/ivltests/task_nonansi_integer_fail.v new file mode 100644 index 000000000..c19483926 --- /dev/null +++ b/ivtest/ivltests/task_nonansi_integer_fail.v @@ -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 diff --git a/ivtest/ivltests/task_nonansi_parray_fail.v b/ivtest/ivltests/task_nonansi_parray_fail.v new file mode 100644 index 000000000..f49af6b50 --- /dev/null +++ b/ivtest/ivltests/task_nonansi_parray_fail.v @@ -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 diff --git a/ivtest/ivltests/task_nonansi_real_fail.v b/ivtest/ivltests/task_nonansi_real_fail.v new file mode 100644 index 000000000..cf7dbdd72 --- /dev/null +++ b/ivtest/ivltests/task_nonansi_real_fail.v @@ -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 diff --git a/ivtest/ivltests/task_nonansi_struct_fail.v b/ivtest/ivltests/task_nonansi_struct_fail.v new file mode 100644 index 000000000..fff594b0a --- /dev/null +++ b/ivtest/ivltests/task_nonansi_struct_fail.v @@ -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 diff --git a/ivtest/ivltests/task_nonansi_time_fail.v b/ivtest/ivltests/task_nonansi_time_fail.v new file mode 100644 index 000000000..59bfcab18 --- /dev/null +++ b/ivtest/ivltests/task_nonansi_time_fail.v @@ -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 diff --git a/ivtest/ivltests/task_nonansi_vec_fail1.v b/ivtest/ivltests/task_nonansi_vec_fail1.v new file mode 100644 index 000000000..12340d05d --- /dev/null +++ b/ivtest/ivltests/task_nonansi_vec_fail1.v @@ -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 diff --git a/ivtest/ivltests/task_nonansi_vec_fail2.v b/ivtest/ivltests/task_nonansi_vec_fail2.v new file mode 100644 index 000000000..1be37e53a --- /dev/null +++ b/ivtest/ivltests/task_nonansi_vec_fail2.v @@ -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 diff --git a/ivtest/ivltests/task_nonansi_vec_fail3.v b/ivtest/ivltests/task_nonansi_vec_fail3.v new file mode 100644 index 000000000..f1210b2bc --- /dev/null +++ b/ivtest/ivltests/task_nonansi_vec_fail3.v @@ -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 diff --git a/ivtest/regress-sv.list b/ivtest/regress-sv.list index 1fa5ad77a..b69e4c0da 100644 --- a/ivtest/regress-sv.list +++ b/ivtest/regress-sv.list @@ -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 diff --git a/ivtest/regress-vlg.list b/ivtest/regress-vlg.list index 95d7c2ecf..2b8274d21 100644 --- a/ivtest/regress-vlg.list +++ b/ivtest/regress-vlg.list @@ -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 diff --git a/ivtest/regress-vlog95.list b/ivtest/regress-vlog95.list index 88f865357..0aeb61f90 100644 --- a/ivtest/regress-vlog95.list +++ b/ivtest/regress-vlog95.list @@ -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 diff --git a/pform.cc b/pform.cc index e5cd59427..496c69baf 100644 --- a/pform.cc +++ b/pform.cc @@ -2148,13 +2148,8 @@ static void pform_set_net_range(PWire *wire, PWSRType rt = SR_NET, std::list*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 *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_make_task_ports(const struct vlltype&loc, assert(pt != NetNet::PIMPLICIT && pt != NetNet::NOT_A_PORT); assert(ports); vector*res = new vector(0); + PWSRType rt = vtype != IVL_VT_NO_TYPE ? SR_BOTH : SR_PORT; + for (list::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_make_task_ports(const struct vlltype&loc, static vector*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*ports) { assert(pt != NetNet::PIMPLICIT && pt != NetNet::NOT_A_PORT); assert(ports); vector*res = new vector(0); + PWSRType rt = data_type ? SR_BOTH : SR_PORT; for (list::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*ports, NetNet::PortType pt, @@ -3306,7 +3249,8 @@ void pform_set_port_type(const struct vlltype&li, for (list::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: "