From 4522709c06225bbc4dbff4aff8b448c02ab3ed12 Mon Sep 17 00:00:00 2001 From: Lars-Peter Clausen Date: Sat, 15 Oct 2022 12:27:59 +0200 Subject: [PATCH 1/7] Use C++11 for building the project There are C++11 constructs in Icarus at the moment and the plan is to retain C++11 compatibility until more modern versions are widely available in the default installation of systems. Pass `-std=c++11` to the compile to enforce building with C++11, this will make sure that neither an older nor a newer version is used. E.g. compilers on some platforms still default to an earlier version of C++11. Signed-off-by: Lars-Peter Clausen --- configure.ac | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/configure.ac b/configure.ac index 13585836c..7055f4f32 100644 --- a/configure.ac +++ b/configure.ac @@ -104,7 +104,7 @@ AS_IF( [test "x$with_m32" = xyes], []) CFLAGS="$CTARGETFLAGS $CFLAGS" -CXXFLAGS="$CTARGETFLAGS $CXXFLAGS" +CXXFLAGS="$CTARGETFLAGS $CXXFLAGS -std=c++11" LDFLAGS="$CTARGETFLAGS $LDFLAGS" # Check that we are using either the GNU compilers or the Sun compilers From 0a2cbcb4b73e6395c724c7f64528d37f50b8e822 Mon Sep 17 00:00:00 2001 From: Lars-Peter Clausen Date: Sat, 15 Oct 2022 11:05:22 +0200 Subject: [PATCH 2/7] Remove pre C++11 compatibility code for unique_ptr There is compatibility code that defines unique_ptr as auto_ptr if the C++ version is before C++11. But there are already other parts of the codebase that do require C++11 and the minimum required version to build the project is C++11. So remove the compat code as it is no longer needed. Signed-off-by: Lars-Peter Clausen --- net_func_eval.cc | 4 ---- pform_types.h | 8 -------- 2 files changed, 12 deletions(-) diff --git a/net_func_eval.cc b/net_func_eval.cc index 58b7d629d..278e17299 100644 --- a/net_func_eval.cc +++ b/net_func_eval.cc @@ -23,10 +23,6 @@ # include # include "ivl_assert.h" -#if __cplusplus < 201103L -#define unique_ptr auto_ptr -#endif - using namespace std; /* diff --git a/pform_types.h b/pform_types.h index 557b2a268..02a8a9e2a 100644 --- a/pform_types.h +++ b/pform_types.h @@ -33,10 +33,6 @@ # include # include -#if __cplusplus < 201103L -#define unique_ptr auto_ptr -#endif - /* * parse-form types. */ @@ -425,8 +421,4 @@ extern std::ostream& operator<< (std::ostream&out, const pform_name_t&); extern std::ostream& operator<< (std::ostream&out, const name_component_t&that); extern std::ostream& operator<< (std::ostream&out, const index_component_t&that); -#if __cplusplus < 201103L -#undef unique_ptr -#endif - #endif /* IVL_pform_types_H */ From 20d82bbdcb45b20417c05cf85112dcedf1f901b8 Mon Sep 17 00:00:00 2001 From: Lars-Peter Clausen Date: Tue, 22 Mar 2022 12:00:43 +0100 Subject: [PATCH 3/7] Simplify class end label parser rule The current class end label parser rule gets the data type from the TYPE_IDENTIFIER, casts that to a class_type_t and gets the name from that. This code was written when the TYPE_IDENTIFIER only provided the data type. But these days it provides both the data type and the name. Simplify the code to get the name directly from the TYPE_IDENTIIFER. Signed-off-by: Lars-Peter Clausen --- parse.y | 17 +++-------------- 1 file changed, 3 insertions(+), 14 deletions(-) diff --git a/parse.y b/parse.y index 816c81336..be48f8f94 100644 --- a/parse.y +++ b/parse.y @@ -824,20 +824,9 @@ class_identifier the class name is detected by the lexor as a TYPE_IDENTIFIER if it does indeed match a name. */ class_declaration_endlabel_opt - : ':' TYPE_IDENTIFIER - { class_type_t*tmp = dynamic_cast ($2.type); - if (tmp == 0) { - yyerror(@2, "error: class declaration endlabel \"%s\" is not a class name\n", $2.text); - $$ = 0; - } else { - $$ = strdupnew(tmp->name.str()); - } - delete[]$2.text; - } - | ':' IDENTIFIER - { $$ = $2; } - | - { $$ = 0; } + : ':' TYPE_IDENTIFIER { $$ = $2.text; } + | ':' IDENTIFIER { $$ = $2; } + | { $$ = 0; } ; /* This rule implements [ extends class_type ] in the From b7fce4a66e97802ef816d5a37240292fbf3e9f97 Mon Sep 17 00:00:00 2001 From: Lars-Peter Clausen Date: Thu, 24 Mar 2022 11:05:33 +0100 Subject: [PATCH 4/7] Improve handling of type identifier references Currently when referencing a typedef this gets replaced with the `data_type_t` that the typedef points to. This works for most cases, but there are some corner cases where it breaks down. E.g. it is possible to have a scoped type identifier which references a type defined in a package. For such type identifiers, only the data_type_t itself is remembered, but not the package scope. This will cause the type identifier to be elaborated in the wrong scope. Furthermore type identifiers of vector types used for module or task port might not be elaborated in the correct scope. Introduce a new `typeref_t` which has `data_type_t` as a base type and can be used as the data type for a signal. A new instance of a `typeref_t` is created when referencing a type identifier. The `typeref_t` remembers both the data type and the scope of the type identifier. When elaborating the `typeref_t` the elaboration is passed through to the referenced `data_type_t`. But special care is taken to lookup the right scope first. With the new approach also typedefs of typedefs are supported. This previously did not work because chained typedefs all reference the same `data_type_t`, but each typedef sets the `name` field of the `data_type_t`. So the second typedef overwrites the first typedef and a lookup of the scope of the first typedef by name will fail as it will return the scope of the second typedef. This refactoring also allows to define clear ownership of a data_type_t instance. This e.g. means that an array type owns its base type and the base type can be freed when the array type itself is freed. The same is true for signals and class properties, they now own their data type and the data type can be freed when the signal or property is freed. Signed-off-by: Lars-Peter Clausen --- PWire.cc | 9 ++++++--- PWire.h | 2 +- elab_scope.cc | 12 +----------- elab_sig.cc | 16 ++++++---------- elab_type.cc | 36 ++++++++++++++++++++++++++++++------ parse.y | 9 ++++++--- pform_dump.cc | 9 +++++++++ pform_pclass.cc | 2 +- pform_types.h | 36 ++++++++++++++++++++++++------------ 9 files changed, 84 insertions(+), 47 deletions(-) diff --git a/PWire.cc b/PWire.cc index d9a9899c6..dbe68afcb 100644 --- a/PWire.cc +++ b/PWire.cc @@ -33,7 +33,7 @@ PWire::PWire(perm_string n, : name_(n), type_(t), port_type_(pt), data_type_(dt), signed_(false), port_set_(false), net_set_(false), is_scalar_(false), - error_cnt_(0), set_data_type_(0), discipline_(0) + error_cnt_(0), discipline_(0) { switch (rt) { case SR_PORT: @@ -195,8 +195,11 @@ void PWire::set_unpacked_idx(const list&ranges) void PWire::set_data_type(data_type_t*type) { - assert(set_data_type_ == 0 || set_data_type_ == type); - set_data_type_ = type; + if (set_data_type_.get() == type) + return; + + assert(!set_data_type_.get()); + set_data_type_.reset(type); } void PWire::set_discipline(ivl_discipline_t d) diff --git a/PWire.h b/PWire.h index e9565a2d5..1f92fac9e 100644 --- a/PWire.h +++ b/PWire.h @@ -123,7 +123,7 @@ class PWire : public PNamedItem { // This is the complex type of the wire. the data_type_ may // modify how this is interpreted. - data_type_t*set_data_type_; + std::unique_ptr set_data_type_; ivl_discipline_t discipline_; diff --git a/elab_scope.cc b/elab_scope.cc index e798d0c91..a03d4df75 100644 --- a/elab_scope.cc +++ b/elab_scope.cc @@ -444,7 +444,7 @@ static void blend_class_constructors(PClass*pclass) // If we do not have an explicit constructor chain, but there // is a parent class, then create an implicit chain. - if (chain_new==0 && pclass->type->base_type!=0) { + if (chain_new==0 && pclass->type->base_type) { chain_new = new PChainConstructor(pclass->type->base_args); chain_new->set_line(*pclass); } @@ -512,16 +512,6 @@ static void elaborate_scope_class(Design*des, NetScope*scope, PClass*pclass) netclass_t*use_class = new netclass_t(use_type->name, use_base_class); - // If this is a package we need to remember the elaborated type so that - // scoped type references work. Since there is only one instance for each - // package this works. For classes defined in modules there might be - // multiple instances though. Each module instance will have its own class - // type instance, so the same does not work there. - if (scope->type() == NetScope::PACKAGE) { - ivl_assert(*pclass, use_type->save_elaborated_type == 0); - use_type->save_elaborated_type = use_class; - } - NetScope*class_scope = new NetScope(scope, hname_t(pclass->pscope_name()), NetScope::CLASS, scope->unit()); class_scope->set_line(pclass); diff --git a/elab_sig.cc b/elab_sig.cc index f4e26c5bd..924fdb945 100644 --- a/elab_sig.cc +++ b/elab_sig.cc @@ -939,10 +939,10 @@ bool test_ranges_eeq(const vector&lef, const vector&rig) ivl_type_t PWire::elaborate_type(Design*des, NetScope*scope, const std::vector&packed_dimensions) const { - if (set_data_type_ && !dynamic_cast(set_data_type_)) { - ivl_type_t use_type = set_data_type_->elaborate_type(des, scope); + vector_type_t *vec_type = dynamic_cast(set_data_type_.get()); + if (set_data_type_ && !vec_type) { ivl_assert(*this, packed_dimensions.empty()); - return use_type; + return set_data_type_->elaborate_type(des, scope); } // Fallback method. Create vector type. @@ -1003,10 +1003,6 @@ NetNet* PWire::elaborate_sig(Design*des, NetScope*scope) const unsigned wid = 1; vectorpacked_dimensions; - NetScope *type_scope = scope; - if (set_data_type_ && !set_data_type_->name.nil()) - type_scope = type_scope->find_typedef_scope(des, set_data_type_); - des->errors += error_cnt_; if (port_set_ || net_set_) { @@ -1046,7 +1042,7 @@ NetNet* PWire::elaborate_sig(Design*des, NetScope*scope) const cerr << get_fileline() << ": PWire::elaborate_sig: " << "Evaluate ranges for net " << basename() << endl; } - dimensions_ok &= evaluate_ranges(des, type_scope, this, nlist, net_); + dimensions_ok &= evaluate_ranges(des, scope, this, nlist, net_); } assert(net_set_ || net_.empty()); @@ -1147,10 +1143,10 @@ NetNet* PWire::elaborate_sig(Design*des, NetScope*scope) const wtype = NetNet::WIRE; } - ivl_type_t type = elaborate_type(des, type_scope, packed_dimensions); + ivl_type_t type = elaborate_type(des, scope, packed_dimensions); // Create the type for the unpacked dimensions. If the // unpacked_dimensions are empty this will just return the base type. - type = elaborate_array_type(des, type_scope, *this, type, unpacked_); + type = elaborate_array_type(des, scope, *this, type, unpacked_); list unpacked_dimensions; // If this is an unpacked array extract the base type and unpacked diff --git a/elab_type.cc b/elab_type.cc index a6be08f69..9c8280c61 100644 --- a/elab_type.cc +++ b/elab_type.cc @@ -18,6 +18,7 @@ */ # include "PExpr.h" +# include "PScope.h" # include "pform_types.h" # include "netlist.h" # include "netclass.h" @@ -40,10 +41,7 @@ using namespace std; */ ivl_type_t data_type_t::elaborate_type(Design*des, NetScope*scope) { - // User-defined types must be elaborated in the context - // where they were defined. - if (!name.nil()) - scope = scope->find_typedef_scope(des, this); + scope = find_scope(des, scope); ivl_assert(*this, scope); Definitions*use_definitions = scope; @@ -57,6 +55,11 @@ ivl_type_t data_type_t::elaborate_type(Design*des, NetScope*scope) return tmp; } +NetScope *data_type_t::find_scope(Design *, NetScope *scope) const +{ + return scope; +} + ivl_type_t data_type_t::elaborate_type_raw(Design*des, NetScope*) const { cerr << get_fileline() << ": internal error: " @@ -112,8 +115,6 @@ ivl_type_t atom_type_t::elaborate_type_raw(Design*des, NetScope*) const ivl_type_t class_type_t::elaborate_type_raw(Design*des, NetScope*scope) const { - if (save_elaborated_type) - return save_elaborated_type; return scope->find_class(des, name); } @@ -366,3 +367,26 @@ ivl_type_t uarray_type_t::elaborate_type_raw(Design*des, NetScope*scope) const return elaborate_array_type(des, scope, *this, btype, *dims.get()); } + +ivl_type_t typeref_t::elaborate_type_raw(Design*des, NetScope*s) const +{ + if (!s) { + // Try to recover + return new netvector_t(IVL_VT_LOGIC); + } + + return type->elaborate_type(des, s); +} + +NetScope *typeref_t::find_scope(Design *des, NetScope *s) const +{ + // If a scope has been specified use that as a starting point for the + // search + if (scope) + s = des->find_package(scope->pscope_name()); + + if (!type->name.nil()) + s = s->find_typedef_scope(des, type); + + return s; +} diff --git a/parse.y b/parse.y index be48f8f94..ffe782bb5 100644 --- a/parse.y +++ b/parse.y @@ -27,6 +27,7 @@ # include "pform.h" # include "Statement.h" # include "PSpec.h" +# include "PPackage.h" # include # include # include @@ -1167,12 +1168,14 @@ ps_type_identifier /* IEEE1800-2017: A.9.3 */ : TYPE_IDENTIFIER { pform_set_type_referenced(@1, $1.text); delete[]$1.text; - $$ = $1.type; + $$ = new typeref_t($1.type); + FILE_NAME($$, @1); } | package_scope TYPE_IDENTIFIER { lex_in_package_scope(0); - $$ = $2.type; - delete[]$2.text; + $$ = new typeref_t($2.type, $1); + FILE_NAME($$, @2); + delete[] $2.text; } ; diff --git a/pform_dump.cc b/pform_dump.cc index 4e1be9146..f6bc1c1b3 100644 --- a/pform_dump.cc +++ b/pform_dump.cc @@ -173,6 +173,15 @@ ostream& data_type_t::debug_dump(ostream&out) const return out; } +std::ostream& typeref_t::debug_dump(ostream&out) const +{ + if (scope) + out << scope->pscope_name() << "::"; + out << type->name; + + return out; +} + ostream& atom_type_t::debug_dump(ostream&out) const { if (signed_flag) diff --git a/pform_pclass.cc b/pform_pclass.cc index f922b9df9..7a7547b8f 100644 --- a/pform_pclass.cc +++ b/pform_pclass.cc @@ -50,7 +50,7 @@ void pform_start_class_declaration(const struct vlltype&loc, pform_cur_class = class_scope; assert(type->base_type == 0); - type->base_type = base_type; + type->base_type.reset(base_type); assert(type->base_args.empty()); if (base_exprs) { diff --git a/pform_types.h b/pform_types.h index 02a8a9e2a..2ef0585c6 100644 --- a/pform_types.h +++ b/pform_types.h @@ -41,6 +41,7 @@ class Design; class NetScope; class Definitions; class PExpr; +class PScope; class PWire; class Statement; class netclass_t; @@ -161,6 +162,8 @@ class data_type_t : public PNamedItem { virtual SymbolType symbol_type() const; + virtual NetScope *find_scope(Design* des, NetScope *scope) const; + perm_string name; private: @@ -171,6 +174,19 @@ class data_type_t : public PNamedItem { std::map cache_type_elaborate_; }; +struct typeref_t : public data_type_t { + explicit typeref_t(data_type_t *t, PScope *s = 0) : scope(s), type(t) {} + + ivl_type_t elaborate_type_raw(Design*des, NetScope*scope) const; + NetScope *find_scope(Design* des, NetScope *scope) const; + + std::ostream& debug_dump(std::ostream&out) const; + +private: + PScope *scope; + data_type_t *type; +}; + struct void_type_t : public data_type_t { virtual void pform_dump(std::ostream&out, unsigned indent) const; }; @@ -189,7 +205,7 @@ struct enum_type_t : public data_type_t { SymbolType symbol_type() const; - data_type_t *base_type; + std::unique_ptr base_type; std::unique_ptr< std::list > names; }; @@ -266,7 +282,7 @@ struct array_base_t : public data_type_t { inline explicit array_base_t(data_type_t*btype, std::list*pd) : base_type(btype), dims(pd) { } - data_type_t*base_type; + std::unique_ptr base_type; std::unique_ptr< std::list > dims; }; @@ -319,8 +335,7 @@ struct string_type_t : public data_type_t { struct class_type_t : public data_type_t { - inline explicit class_type_t(perm_string n) - : base_type(0), save_elaborated_type(0) { name = n; } + inline explicit class_type_t(perm_string n) { name = n; } void pform_dump(std::ostream&out, unsigned indent) const; void pform_dump_init(std::ostream&out, unsigned indent) const; @@ -329,15 +344,17 @@ struct class_type_t : public data_type_t { // class that we are extending. This is nil if there is no // hierarchy. If there are arguments to the base class, then // put them in the base_args vector. - data_type_t*base_type; + std::unique_ptr base_type; std::listbase_args; // This is a map of the properties. Map the name to the type. struct prop_info_t : public LineInfo { - inline prop_info_t() : qual(property_qualifier_t::make_none()), type(0) { } + inline prop_info_t() : qual(property_qualifier_t::make_none()) { } inline prop_info_t(property_qualifier_t q, data_type_t*t) : qual(q), type(t) { } + prop_info_t(prop_info_t&&) = default; + prop_info_t& operator=(prop_info_t&&) = default; property_qualifier_t qual; - data_type_t* type; + std::unique_ptr type; }; std::map properties; @@ -352,11 +369,6 @@ struct class_type_t : public data_type_t { std::vector initialize_static; ivl_type_t elaborate_type_raw(Design*, NetScope*) const; - // The save_elaborated_type member must be set to the pointer - // to the netclass_t object that is created to represent this - // type. The elaborate_type_raw() method uses this pointer, - // and it is used in some other situations as well. - netclass_t* save_elaborated_type; virtual SymbolType symbol_type() const; }; From 54afdc1e6b286159a9da0a4977029fe0f5dfcfe8 Mon Sep 17 00:00:00 2001 From: Lars-Peter Clausen Date: Sat, 1 Oct 2022 13:49:10 +0200 Subject: [PATCH 5/7] Add regression test for module port with vector typedef Check that for a module port with a vector type identifier the type is elaborated in the scope where it is declared rather than the scope of the module port. Signed-off-by: Lars-Peter Clausen --- ivtest/ivltests/module_port_typedef_vector.v | 29 ++++++++++++++++++++ ivtest/regress-sv.list | 1 + 2 files changed, 30 insertions(+) create mode 100644 ivtest/ivltests/module_port_typedef_vector.v diff --git a/ivtest/ivltests/module_port_typedef_vector.v b/ivtest/ivltests/module_port_typedef_vector.v new file mode 100644 index 000000000..ca5d4592a --- /dev/null +++ b/ivtest/ivltests/module_port_typedef_vector.v @@ -0,0 +1,29 @@ +// Check that a packed array type identifier used for a module port is +// elaborated in the correct scope. + +localparam A = 2; + +typedef logic [A-1:0] T; + +module test ( + input T x +); + + localparam A = 5; + + bit failed = 1'b0; + + `define check(expr, val) \ + if (expr !== val) begin \ + $display("FAILED: %s, expected %0d, got %0d", `"expr`", val, expr); \ + failed = 1'b1; \ + end + + initial begin + `check($bits(x), 2); + if (!failed) begin + $display("PASSED"); + end + end + +endmodule diff --git a/ivtest/regress-sv.list b/ivtest/regress-sv.list index e423c2a86..f57aba917 100644 --- a/ivtest/regress-sv.list +++ b/ivtest/regress-sv.list @@ -371,6 +371,7 @@ 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 module_port_typedef_array1 normal,-g2005-sv ivltests +module_port_typedef_vector normal,-g2005-sv ivltests named_begin normal,-g2009 ivltests named_begin_fail CE,-g2009 ivltests named_fork normal,-g2009 ivltests From 998d0c655d53111fcc8d7fcae8dd2242c1ecdc56 Mon Sep 17 00:00:00 2001 From: Lars-Peter Clausen Date: Sun, 17 Apr 2022 14:00:21 +0200 Subject: [PATCH 6/7] Add regression test for chained type definitions Check that chained type definitions declared in different scopes are handled correctly. Signed-off-by: Lars-Peter Clausen --- ivtest/ivltests/sv_typedef_chained.v | 51 ++++++++++++++++++++++++++++ ivtest/regress-sv.list | 1 + 2 files changed, 52 insertions(+) create mode 100644 ivtest/ivltests/sv_typedef_chained.v diff --git a/ivtest/ivltests/sv_typedef_chained.v b/ivtest/ivltests/sv_typedef_chained.v new file mode 100644 index 000000000..d62399cec --- /dev/null +++ b/ivtest/ivltests/sv_typedef_chained.v @@ -0,0 +1,51 @@ +// Check that chained type definitions declared in different scopes work +// correctly. + +package P1; + localparam A = 8; + typedef logic [A-1:0] T; +endpackage + +package P2; + localparam A = 4; + typedef P1::T T; +endpackage + +bit failed = 1'b0; + +`define check(expr, val) \ + if (expr !== val) begin \ + $display("FAILED: %s, expected %0d, got %0d", `"expr`", val, expr); \ + failed = 1'b1; \ + end + +module test; + localparam A = 2; + + typedef P2::T T; + + T x; + P1::T y; + P2::T z; + + initial begin + x = 8'hff; + y = 8'hff; + z = 8'hff; + + `check(x, 8'hff); + `check($bits(T), 8); + `check($bits(x), 8); + `check(y, 8'hff); + `check($bits(y), 8); + `check($bits(P1::T), 8); + `check(z, 8'hff); + `check($bits(z), 8); + `check($bits(P2::T), 8); + + if (!failed) begin + $display("PASSED"); + end + end + +endmodule diff --git a/ivtest/regress-sv.list b/ivtest/regress-sv.list index f57aba917..930cd8487 100644 --- a/ivtest/regress-sv.list +++ b/ivtest/regress-sv.list @@ -704,6 +704,7 @@ sv_typedef_array_base1 normal,-g2009 ivltests sv_typedef_array_base2 normal,-g2009 ivltests sv_typedef_array_base3 normal,-g2009 ivltests sv_typedef_array_base4 normal,-g2009 ivltests +sv_typedef_chained normal,-g2009 ivltests sv_typedef_darray_base1 normal,-g2009 ivltests sv_typedef_darray_base2 normal,-g2009 ivltests sv_typedef_darray_base3 normal,-g2009 ivltests From b9bc06951a4842c12f739440fb65c3191c3275cf Mon Sep 17 00:00:00 2001 From: Lars-Peter Clausen Date: Sat, 23 Apr 2022 22:22:39 +0200 Subject: [PATCH 7/7] Add regression tests for scoped type identifier references Check that it is possible to have scoped reference to a type identifier in a package. * As part of variable declarations * As an argument to a system function * As the type in a type cast Signed-off-by: Lars-Peter Clausen --- ivtest/ivltests/sv_ps_type_cast1.v | 26 ++++++++++++++++++ ivtest/ivltests/sv_ps_type_cast2.v | 28 +++++++++++++++++++ ivtest/ivltests/sv_ps_type_class1.v | 39 +++++++++++++++++++++++++++ ivtest/ivltests/sv_ps_type_enum1.v | 38 ++++++++++++++++++++++++++ ivtest/ivltests/sv_ps_type_expr1.v | 24 +++++++++++++++++ ivtest/ivltests/sv_ps_type_expr2.v | 26 ++++++++++++++++++ ivtest/ivltests/sv_ps_type_struct1.v | 40 ++++++++++++++++++++++++++++ ivtest/regress-sv.list | 7 +++++ ivtest/regress-vlog95.list | 1 + 9 files changed, 229 insertions(+) create mode 100644 ivtest/ivltests/sv_ps_type_cast1.v create mode 100644 ivtest/ivltests/sv_ps_type_cast2.v create mode 100644 ivtest/ivltests/sv_ps_type_class1.v create mode 100644 ivtest/ivltests/sv_ps_type_enum1.v create mode 100644 ivtest/ivltests/sv_ps_type_expr1.v create mode 100644 ivtest/ivltests/sv_ps_type_expr2.v create mode 100644 ivtest/ivltests/sv_ps_type_struct1.v diff --git a/ivtest/ivltests/sv_ps_type_cast1.v b/ivtest/ivltests/sv_ps_type_cast1.v new file mode 100644 index 000000000..305b05326 --- /dev/null +++ b/ivtest/ivltests/sv_ps_type_cast1.v @@ -0,0 +1,26 @@ +// Check that it is possible to reference a package scoped type identifier as +// the type in a type cast expression. + +bit failed = 1'b0; + +`define check(expr, val) \ + if (expr !== val) begin \ + $display("FAILED: %s, expected %0d, got %0d", `"expr`", val, expr); \ + failed = 1'b1; \ + end + +package P; + typedef integer T; +endpackage + +module test; + integer x; + initial begin + x = P::T'(-1024.123); + `check(x, -1024) + + if (!failed) begin + $display("PASSED"); + end + end +endmodule diff --git a/ivtest/ivltests/sv_ps_type_cast2.v b/ivtest/ivltests/sv_ps_type_cast2.v new file mode 100644 index 000000000..61ea62bb7 --- /dev/null +++ b/ivtest/ivltests/sv_ps_type_cast2.v @@ -0,0 +1,28 @@ +// Check that it is possible to reference a package scoped type identifier as +// the type in a type cast expression, even if there is a identifier of the same +// name in the local scope. + +bit failed = 1'b0; + +`define check(expr, val) \ + if (expr !== val) begin \ + $display("FAILED: %s, expected %0d, got %0d", `"expr`", val, expr); \ + failed = 1'b1; \ + end + +package P; + typedef integer T; +endpackage + +module test; + localparam T = 2; + integer x; + initial begin + x = P::T'(-1024.123); + `check(x, -1024) + + if (!failed) begin + $display("PASSED"); + end + end +endmodule diff --git a/ivtest/ivltests/sv_ps_type_class1.v b/ivtest/ivltests/sv_ps_type_class1.v new file mode 100644 index 000000000..4742a8c8e --- /dev/null +++ b/ivtest/ivltests/sv_ps_type_class1.v @@ -0,0 +1,39 @@ +// Check that class types declared in a package can be referenced using a scoped +// type identifier. + +bit failed = 1'b0; + +`define check(expr, val) \ + if (expr !== val) begin \ + $display("FAILED: %s, expected %0d, got %0d", `"expr`", val, expr); \ + failed = 1'b1; \ + end + +package P; + + localparam A = 8; + + class C; + logic [A-1:0] x; + + task t; + `check($bits(x), 8) + if (!failed) begin + $display("PASSED"); + end + endtask + endclass + +endpackage + +module test; + + localparam A = 4; + P::C c; + + initial begin + c = new; + c.t(); + end + +endmodule diff --git a/ivtest/ivltests/sv_ps_type_enum1.v b/ivtest/ivltests/sv_ps_type_enum1.v new file mode 100644 index 000000000..4745a218f --- /dev/null +++ b/ivtest/ivltests/sv_ps_type_enum1.v @@ -0,0 +1,38 @@ +// Check that enum types declared in a package can be referenced using a scoped +// type identifier. + +bit failed = 1'b0; + +`define check(expr, val) \ + if (expr !== val) begin \ + $display("FAILED: %s, expected %0d, got %0d", `"expr`", val, expr); \ + failed = 1'b1; \ + end + +package P; + + localparam X = 8; + + typedef enum logic [X-1:0] { + A, B = X + } T; + +endpackage + +module test; + localparam X = 4; + + typedef int T; + + P::T x = P::B; + + initial begin + `check(x, P::B) + `check(x, 8) + `check($bits(x), 8); + if (!failed) begin + $display("PASSED"); + end + end + +endmodule diff --git a/ivtest/ivltests/sv_ps_type_expr1.v b/ivtest/ivltests/sv_ps_type_expr1.v new file mode 100644 index 000000000..7ce97f2f7 --- /dev/null +++ b/ivtest/ivltests/sv_ps_type_expr1.v @@ -0,0 +1,24 @@ +// Check that it is possible to reference a package scoped type identifier in an +// expression. + +bit failed = 1'b0; + +`define check(expr, val) \ + if (expr !== val) begin \ + $display("FAILED: %s, expected %0d, got %0d", `"expr`", val, expr); \ + failed = 1'b1; \ + end + +package P; + typedef integer T; +endpackage + +module test; + initial begin + `check($bits(P::T), $bits(integer)) + + if (!failed) begin + $display("PASSED"); + end + end +endmodule diff --git a/ivtest/ivltests/sv_ps_type_expr2.v b/ivtest/ivltests/sv_ps_type_expr2.v new file mode 100644 index 000000000..30ca5b246 --- /dev/null +++ b/ivtest/ivltests/sv_ps_type_expr2.v @@ -0,0 +1,26 @@ +// Check that it is possible to reference a package scoped type identifier in an +// expression, even if there is a non type identifier of the same name in the +// current scope. + +bit failed = 1'b0; + +`define check(expr, val) \ + if (expr !== val) begin \ + $display("FAILED: %s, expected %0d, got %0d", `"expr`", val, expr); \ + failed = 1'b1; \ + end + +package P; + typedef integer T; +endpackage + +module test; + integer T; + initial begin + `check($bits(P::T), $bits(integer)) + + if (!failed) begin + $display("PASSED"); + end + end +endmodule diff --git a/ivtest/ivltests/sv_ps_type_struct1.v b/ivtest/ivltests/sv_ps_type_struct1.v new file mode 100644 index 000000000..3ec1b545d --- /dev/null +++ b/ivtest/ivltests/sv_ps_type_struct1.v @@ -0,0 +1,40 @@ +// Check that struct types declared in a package can be referenced using a +// scoped type identifier. + +bit failed = 1'b0; + +`define check(expr, val) \ + if (expr !== val) begin \ + $display("FAILED: %s, expected %0d, got %0d", `"expr`", val, expr); \ + failed = 1'b1; \ + end + +package P; + + localparam A = 8; + + typedef struct packed { + logic [A-1:0] x; + } T; + +endpackage + +typedef int T; + +module test; + localparam A = 4; + + typedef int T; + + P::T x; + + initial begin + x = 8'hff; + `check(x, 8'hff) + `check($bits(x), 8) + if (!failed) begin + $display("PASSED"); + end + end + +endmodule diff --git a/ivtest/regress-sv.list b/ivtest/regress-sv.list index 930cd8487..4c8042ba9 100644 --- a/ivtest/regress-sv.list +++ b/ivtest/regress-sv.list @@ -633,6 +633,13 @@ sv_ps_function2 normal,-g2009 ivltests sv_ps_function3 normal,-g2009 ivltests sv_ps_function4 normal,-g2009 ivltests sv_ps_type1 normal,-g2009 ivltests +sv_ps_type_cast1 normal,-g2009 ivltests +sv_ps_type_cast2 normal,-g2009 ivltests +sv_ps_type_class1 normal,-g2009 ivltests +sv_ps_type_enum1 normal,-g2009 ivltests +sv_ps_type_expr1 normal,-g2009 ivltests +sv_ps_type_expr2 normal,-g2009 ivltests +sv_ps_type_struct1 normal,-g2009 ivltests sv_ps_var1 normal,-g2009 ivltests sv_queue1 normal,-g2009 ivltests sv_queue2 normal,-g2009 ivltests diff --git a/ivtest/regress-vlog95.list b/ivtest/regress-vlog95.list index 97ad90d58..c4628ebd2 100644 --- a/ivtest/regress-vlog95.list +++ b/ivtest/regress-vlog95.list @@ -437,6 +437,7 @@ sv_port_default6 CE,-g2009,-pallowsigned=1 ivltests sv_port_default7 CE,-g2009,-pallowsigned=1 ivltests sv_port_default8 CE,-g2009,-pallowsigned=1 ivltests sv_port_default9 CE,-g2009 ivltests +sv_ps_type_class1 CE,-g2009 ivltests sv_root_class CE,-g2009 ivltests sv_typedef_scope3 CE,-g2009 ivltests sv_unit2b CE,-g2009 ivltests