From 4bf0d62cd1f33408897d39981dd44df3a7846755 Mon Sep 17 00:00:00 2001 From: Lars-Peter Clausen Date: Tue, 15 Mar 2022 08:24:33 +0100 Subject: [PATCH 1/2] Support type identifier base type for enum The base type for an enum type can be a type identifier for a typedef as long as it resolves to a vector or integer type with at most one packed dimension. This is described in section 6.19 ("Enumerations") of the LRM (1800-2017). E.g. ``` typedef bit [3:0] T; enum T { A } e; ``` Add support for this by allowing to specify a type identifier as the base type for an enum in the parser. During elaboration it is checked whether the type identifier resolves to a valid enum base type. Signed-off-by: Lars-Peter Clausen --- elab_scope.cc | 55 +++++++++++++++++++++++------------------ netenum.cc | 13 +++++----- netenum.h | 11 +++------ parse.y | 66 +++++++++++++++++++++----------------------------- pform_types.cc | 2 +- pform_types.h | 7 +++--- 6 files changed, 72 insertions(+), 82 deletions(-) diff --git a/elab_scope.cc b/elab_scope.cc index fe39506e9..826154eae 100644 --- a/elab_scope.cc +++ b/elab_scope.cc @@ -21,6 +21,8 @@ # include "config.h" # include "compiler.h" # include "netmisc.h" +# include "netvector.h" +# include "netparray.h" # include # include # include @@ -166,27 +168,31 @@ static void collect_scope_specparams(Design*des, NetScope*scope, static void elaborate_scope_enumeration(Design*des, NetScope*scope, enum_type_t*enum_type) { - std::vector ranges; - netrange_t range; + ivl_type_t base_type; bool rc_flag; - if (enum_type->range.get()) - evaluate_ranges(des, scope, enum_type, ranges, *enum_type->range); + base_type = enum_type->base_type->elaborate_type(des, scope); - if (!ranges.empty()) { - range = ranges.front(); - if (ranges.size() > 1) { - cerr << enum_type->get_fileline() << ": error: " - << "Enum type must not have more than 1 packed dimension." - << endl; - des->errors++; - } + const struct netvector_t *vec_type = dynamic_cast(base_type); + + if (!vec_type && !dynamic_cast(base_type)) { + cerr << enum_type->get_fileline() << ": error: " + << "Invalid enum base type `" << *base_type << "`." + << endl; + des->errors++; + } else if (base_type->slice_dimensions().size() > 1) { + cerr << enum_type->get_fileline() << ": error: " + << "Enum type must not have more than 1 packed dimension." + << endl; + des->errors++; } - netenum_t*use_enum = new netenum_t(enum_type->base_type, - enum_type->signed_flag, - enum_type->integer_flag, range, - enum_type->names->size()); + bool integer_flag = false; + if (vec_type) + integer_flag = vec_type->get_isint(); + + netenum_t*use_enum = new netenum_t(base_type, enum_type->names->size(), + integer_flag); use_enum->set_line(*enum_type); scope->add_enumeration_set(enum_type, use_enum); @@ -196,20 +202,21 @@ static void elaborate_scope_enumeration(Design*des, NetScope*scope, long raw_width = use_enum->packed_width(); assert(raw_width > 0); unsigned enum_width = (unsigned)raw_width; + bool is_signed = use_enum->get_signed(); // Define the default start value and the increment value to be the // correct type for this enumeration. verinum cur_value ((uint64_t)0, enum_width); - cur_value.has_sign(enum_type->signed_flag); + cur_value.has_sign(is_signed); verinum one_value ((uint64_t)1, enum_width); - one_value.has_sign(enum_type->signed_flag); + one_value.has_sign(is_signed); // Find the maximum allowed enumeration value. verinum max_value (0); - if (enum_type->signed_flag) { + if (is_signed) { max_value = pow(verinum(2), verinum(enum_width-1)) - one_value; } else { max_value = pow(verinum(2), verinum(enum_width)) - one_value; } - max_value.has_sign(enum_type->signed_flag); + max_value.has_sign(is_signed); // Variable to indicate when a defined value wraps. bool implicit_wrapped = false; // Process the enumeration definition. @@ -234,7 +241,7 @@ static void elaborate_scope_enumeration(Design*des, NetScope*scope, implicit_wrapped = false; // A 2-state value can not have a constant with X/Z bits. - if (enum_type->base_type==IVL_VT_BOOL && + if (use_enum->base_type() == IVL_VT_BOOL && ! cur_value.is_defined()) { cerr << use_enum->get_fileline() << ": error: Enumeration name " << cur->name @@ -259,7 +266,7 @@ static void elaborate_scope_enumeration(Design*des, NetScope*scope, // value does not have a defined width. if (((cur_value.len() != enum_width) || ! cur_value.has_len()) && - ! enum_type->signed_flag && cur_value.is_negative()) { + ! is_signed && cur_value.is_negative()) { cerr << use_enum->get_fileline() << ": error: Enumeration name " << cur->name << " has a negative value." << endl; @@ -282,7 +289,7 @@ static void elaborate_scope_enumeration(Design*des, NetScope*scope, if (cur_value[idx] != cur_value[check_width]) { // If this is an unsigned enumeration // then zero padding is okay. - if (! enum_type->signed_flag && + if (!is_signed && (idx == enum_width) && (cur_value[idx] == verinum::V0)) { check_width += 1; @@ -328,7 +335,7 @@ static void elaborate_scope_enumeration(Design*des, NetScope*scope, // At this point the value has the correct size and needs // to have the correct sign attribute set. cur_value.has_len(true); - cur_value.has_sign(enum_type->signed_flag); + cur_value.has_sign(is_signed); } else if (! cur_value.is_defined()) { cerr << use_enum->get_fileline() diff --git a/netenum.cc b/netenum.cc index 7ff455926..1cedf2e85 100644 --- a/netenum.cc +++ b/netenum.cc @@ -23,10 +23,9 @@ using namespace std; -netenum_t::netenum_t(ivl_variable_type_t btype, bool signed_flag, - bool integer_flag, const netrange_t &range, size_t name_count) -: base_type_(btype), signed_flag_(signed_flag), integer_flag_(integer_flag), - range_(range), names_(name_count), bits_(name_count) +netenum_t::netenum_t(ivl_type_t btype, size_t name_count, bool integer_flag) +: base_type_(btype), integer_flag_(integer_flag), names_(name_count), + bits_(name_count) { } @@ -36,7 +35,7 @@ netenum_t::~netenum_t() bool netenum_t::get_signed() const { - return signed_flag_; + return base_type_->get_signed(); } bool netenum_t::get_isint() const @@ -54,12 +53,12 @@ bool netenum_t::packed() const long netenum_t::packed_width() const { - return range_.width(); + return base_type_->packed_width(); } vector netenum_t::slice_dimensions() const { - return vector(1, range_); + return base_type_->slice_dimensions(); } bool netenum_t::insert_name(size_t name_idx, perm_string name, const verinum&val) diff --git a/netenum.h b/netenum.h index 94f7cd8cd..b2d64397a 100644 --- a/netenum.h +++ b/netenum.h @@ -32,9 +32,8 @@ class NetScope; class netenum_t : public LineInfo, public ivl_type_s { public: - explicit netenum_t(ivl_variable_type_t base_type, bool signed_flag, - bool isint_flag, const netrange_t &range, - size_t name_count); + explicit netenum_t(ivl_type_t base_type, size_t name_count, + bool integer_flag); ~netenum_t(); virtual ivl_variable_type_t base_type() const; @@ -71,10 +70,8 @@ class netenum_t : public LineInfo, public ivl_type_s { bool matches(const netenum_t*other) const; private: - ivl_variable_type_t base_type_; - bool signed_flag_; + ivl_type_t base_type_; bool integer_flag_; - netrange_t range_; std::map names_map_; std::vector names_; @@ -82,7 +79,7 @@ class netenum_t : public LineInfo, public ivl_type_s { }; inline ivl_variable_type_t netenum_t::base_type() const -{ return base_type_; } +{ return base_type_->base_type(); } inline size_t netenum_t::size() const { return names_.size(); } diff --git a/parse.y b/parse.y index dc4938e7d..004fb8001 100644 --- a/parse.y +++ b/parse.y @@ -439,8 +439,6 @@ static void current_function_set_statement(const YYLTYPE&loc, std::vector*statement_list; - enum_type_t*enum_type; - decl_assignment_t*decl_assignment; std::list*decl_assignments; @@ -620,7 +618,7 @@ static void current_function_set_statement(const YYLTYPE&loc, std::vector tf_port_item_expr_opt value_range_expression %type enum_name_list enum_name -%type enum_data_type enum_base_type +%type enum_data_type enum_base_type %type tf_item_declaration tf_item_list tf_item_list_opt %type tf_port_declaration tf_port_item tf_port_item_list tf_port_list tf_port_list_opt @@ -659,6 +657,7 @@ static void current_function_set_statement(const YYLTYPE&loc, std::vector simple_type_or_string let_formal_type %type packed_array_data_type %type ps_type_identifier +%type simple_packed_type %type class_identifier %type struct_union_member %type struct_union_member_list @@ -1222,17 +1221,12 @@ packed_array_data_type /* IEEE1800-2005: A.2.2.1 */ | ps_type_identifier ; -data_type /* IEEE1800-2005: A.2.2.1 */ +simple_packed_type /* Integer and vector types */ : integer_vector_type unsigned_signed_opt dimensions_opt { vector_type_t*tmp = new vector_type_t($1, $2, $3); FILE_NAME(tmp, @1); $$ = tmp; } - | non_integer_type - { real_type_t*tmp = new real_type_t($1); - FILE_NAME(tmp, @1); - $$ = tmp; - } | atom2_type signed_unsigned_opt { atom2_type_t*tmp = new atom2_type_t($1, $2); FILE_NAME(tmp, @1); @@ -1249,6 +1243,17 @@ data_type /* IEEE1800-2005: A.2.2.1 */ vector_type_t*tmp = new vector_type_t(IVL_VT_LOGIC, $2, pd); $$ = tmp; } + ; + +data_type /* IEEE1800-2005: A.2.2.1 */ + : simple_packed_type + { $$ = $1; + } + | non_integer_type + { real_type_t*tmp = new real_type_t($1); + FILE_NAME(tmp, @1); + $$ = tmp; + } | packed_array_data_type dimensions_opt { if ($2) { parray_type_t*tmp = new parray_type_t($1, $2); @@ -2736,43 +2741,26 @@ type_declaration can be any of the integral or vector types. */ enum_base_type /* IEEE 1800-2012 A.2.2.1 */ - : - { enum_type_t*enum_type = new enum_type_t; - enum_type->base_type = IVL_VT_BOOL; - enum_type->signed_flag = true; - enum_type->integer_flag = false; - enum_type->range.reset(make_range_from_width(32)); - $$ = enum_type; + : simple_packed_type + { $$ = $1; } - | atom2_type signed_unsigned_opt - { enum_type_t*enum_type = new enum_type_t; - enum_type->base_type = IVL_VT_BOOL; - enum_type->signed_flag = $2; - enum_type->integer_flag = false; - enum_type->range.reset(make_range_from_width($1)); - $$ = enum_type; + | ps_type_identifier dimensions_opt + { if ($2) { + $$ = new parray_type_t($1, $2); + FILE_NAME($$, @1); + } else { + $$ = $1; + } } - | K_integer signed_unsigned_opt - { enum_type_t*enum_type = new enum_type_t; - enum_type->base_type = IVL_VT_LOGIC; - enum_type->signed_flag = $2; - enum_type->integer_flag = true; - enum_type->range.reset(make_range_from_width(integer_width)); - $$ = enum_type; - } - | integer_vector_type unsigned_signed_opt dimensions_opt - { enum_type_t*enum_type = new enum_type_t; - enum_type->base_type = $1; - enum_type->signed_flag = $2; - enum_type->integer_flag = false; - enum_type->range.reset($3 ? $3 : make_range_from_width(1)); - $$ = enum_type; + | + { $$ = new atom2_type_t(32, true); + FILE_NAME($$, @0); } ; enum_data_type /* IEEE 1800-2012 A.2.2.1 */ : K_enum enum_base_type '{' enum_name_list '}' - { enum_type_t*enum_type = $2; + { enum_type_t*enum_type = new enum_type_t($2); FILE_NAME(enum_type, @1); enum_type->names.reset($4); pform_put_enum_type_in_scope(enum_type); diff --git a/pform_types.cc b/pform_types.cc index 21dc725ab..28dfe15fc 100644 --- a/pform_types.cc +++ b/pform_types.cc @@ -50,7 +50,7 @@ ivl_variable_type_t vector_type_t::figure_packed_base_type(void) const ivl_variable_type_t enum_type_t::figure_packed_base_type() const { - return base_type; + return base_type->figure_packed_base_type(); } ivl_variable_type_t atom2_type_t::figure_packed_base_type() const diff --git a/pform_types.h b/pform_types.h index 3bbd32286..b32f674bd 100644 --- a/pform_types.h +++ b/pform_types.h @@ -178,6 +178,8 @@ struct void_type_t : public data_type_t { * until it is elaborated in a scope. */ struct enum_type_t : public data_type_t { + explicit enum_type_t(data_type_t *btype) : base_type(btype) { } + // Return the elaborated version of the type. ivl_type_t elaborate_type_raw(Design*des, NetScope*scope) const; @@ -185,10 +187,7 @@ struct enum_type_t : public data_type_t { SymbolType symbol_type() const; - ivl_variable_type_t base_type; - bool signed_flag; - bool integer_flag; // True if "integer" was used - std::unique_ptr< std::list > range; + data_type_t *base_type; std::unique_ptr< std::list > names; }; From 315bc1908acdaaea989f0dbe32ef09202b1591ad Mon Sep 17 00:00:00 2001 From: Lars-Peter Clausen Date: Sat, 19 Mar 2022 19:11:00 +0100 Subject: [PATCH 2/2] Add regression tests for enum base type Check that the behavior for all sorts of base types for enums is correctly implemented. Both for valid as well as invalid base types. Signed-off-by: Lars-Peter Clausen --- ivtest/ivltests/enum_base_atom2.v | 31 ++++++++++++++++++++++++ ivtest/ivltests/enum_base_fail_array.v | 16 ++++++++++++ ivtest/ivltests/enum_base_fail_class.v | 17 +++++++++++++ ivtest/ivltests/enum_base_fail_darray.v | 16 ++++++++++++ ivtest/ivltests/enum_base_fail_enum.v | 18 ++++++++++++++ ivtest/ivltests/enum_base_fail_queue.v | 16 ++++++++++++ ivtest/ivltests/enum_base_fail_range1.v | 17 +++++++++++++ ivtest/ivltests/enum_base_fail_range2.v | 16 ++++++++++++ ivtest/ivltests/enum_base_fail_range3.v | 14 +++++++++++ ivtest/ivltests/enum_base_fail_real1.v | 14 +++++++++++ ivtest/ivltests/enum_base_fail_real2.v | 16 ++++++++++++ ivtest/ivltests/enum_base_fail_string1.v | 14 +++++++++++ ivtest/ivltests/enum_base_fail_string2.v | 16 ++++++++++++ ivtest/ivltests/enum_base_fail_struct.v | 18 ++++++++++++++ ivtest/ivltests/enum_base_integer.v | 18 ++++++++++++++ ivtest/ivltests/enum_base_none.v | 18 ++++++++++++++ ivtest/ivltests/enum_base_scalar.v | 26 ++++++++++++++++++++ ivtest/ivltests/enum_base_time.v | 18 ++++++++++++++ ivtest/ivltests/enum_base_typename1.v | 20 +++++++++++++++ ivtest/ivltests/enum_base_typename2.v | 20 +++++++++++++++ ivtest/regress-sv.list | 20 +++++++++++++++ ivtest/regress-vlog95.list | 2 ++ 22 files changed, 381 insertions(+) create mode 100644 ivtest/ivltests/enum_base_atom2.v create mode 100644 ivtest/ivltests/enum_base_fail_array.v create mode 100644 ivtest/ivltests/enum_base_fail_class.v create mode 100644 ivtest/ivltests/enum_base_fail_darray.v create mode 100644 ivtest/ivltests/enum_base_fail_enum.v create mode 100644 ivtest/ivltests/enum_base_fail_queue.v create mode 100644 ivtest/ivltests/enum_base_fail_range1.v create mode 100644 ivtest/ivltests/enum_base_fail_range2.v create mode 100644 ivtest/ivltests/enum_base_fail_range3.v create mode 100644 ivtest/ivltests/enum_base_fail_real1.v create mode 100644 ivtest/ivltests/enum_base_fail_real2.v create mode 100644 ivtest/ivltests/enum_base_fail_string1.v create mode 100644 ivtest/ivltests/enum_base_fail_string2.v create mode 100644 ivtest/ivltests/enum_base_fail_struct.v create mode 100644 ivtest/ivltests/enum_base_integer.v create mode 100644 ivtest/ivltests/enum_base_none.v create mode 100644 ivtest/ivltests/enum_base_scalar.v create mode 100644 ivtest/ivltests/enum_base_time.v create mode 100644 ivtest/ivltests/enum_base_typename1.v create mode 100644 ivtest/ivltests/enum_base_typename2.v diff --git a/ivtest/ivltests/enum_base_atom2.v b/ivtest/ivltests/enum_base_atom2.v new file mode 100644 index 000000000..467ed0d00 --- /dev/null +++ b/ivtest/ivltests/enum_base_atom2.v @@ -0,0 +1,31 @@ +// Check that it is possible to declare an enum type with an atom2 type as the +// base type. + +module test; + + enum byte { + A + } e1; + + enum shortint { + B + } e2; + + enum int { + C + } e3; + + enum longint { + D + } e4; + + initial begin + if ($bits(e1) == 8 && $bits(e2) == 16 && + $bits(e3) == 32 && $bits(e4) == 64) begin + $display("PASSED"); + end else begin + $display("FAILED"); + end + end + +endmodule diff --git a/ivtest/ivltests/enum_base_fail_array.v b/ivtest/ivltests/enum_base_fail_array.v new file mode 100644 index 000000000..6e11d34d9 --- /dev/null +++ b/ivtest/ivltests/enum_base_fail_array.v @@ -0,0 +1,16 @@ +// Check that using an array type as the base type for an enum results in an +// error. + +module test; + + typedef logic T[1:0]; + + enum T { + A + } e; + + initial begin + $display("FAILED"); + end + +endmodule diff --git a/ivtest/ivltests/enum_base_fail_class.v b/ivtest/ivltests/enum_base_fail_class.v new file mode 100644 index 000000000..cd36d254a --- /dev/null +++ b/ivtest/ivltests/enum_base_fail_class.v @@ -0,0 +1,17 @@ +// Check that using a class type as the base type for an enum results in an +// error. + +class C; +endclass + +module test; + + enum C { + A + } e; + + initial begin + $display("FAILED"); + end + +endmodule diff --git a/ivtest/ivltests/enum_base_fail_darray.v b/ivtest/ivltests/enum_base_fail_darray.v new file mode 100644 index 000000000..7eeb8718d --- /dev/null +++ b/ivtest/ivltests/enum_base_fail_darray.v @@ -0,0 +1,16 @@ +// Check that using a dynamic array type as the base type for an enum results in +// an error. + +module test; + + typedef logic T[]; + + enum T { + A + } e; + + initial begin + $display("FAILED"); + end + +endmodule diff --git a/ivtest/ivltests/enum_base_fail_enum.v b/ivtest/ivltests/enum_base_fail_enum.v new file mode 100644 index 000000000..32b84efd5 --- /dev/null +++ b/ivtest/ivltests/enum_base_fail_enum.v @@ -0,0 +1,18 @@ +// Check that using an enum type as the base type for an enum results in an +// error. + +module test; + + typedef enum { + X + } T; + + enum T { + A + } e; + + initial begin + $display("FAILED"); + end + +endmodule diff --git a/ivtest/ivltests/enum_base_fail_queue.v b/ivtest/ivltests/enum_base_fail_queue.v new file mode 100644 index 000000000..38a0921aa --- /dev/null +++ b/ivtest/ivltests/enum_base_fail_queue.v @@ -0,0 +1,16 @@ +// Check that using a queue type as the base type for an enum results in an +// error + +module test; + + typedef logic T[$]; + + enum T { + A + } e; + + initial begin + $display("FAILED"); + end + +endmodule diff --git a/ivtest/ivltests/enum_base_fail_range1.v b/ivtest/ivltests/enum_base_fail_range1.v new file mode 100644 index 000000000..a5bbf74a4 --- /dev/null +++ b/ivtest/ivltests/enum_base_fail_range1.v @@ -0,0 +1,17 @@ +// Check that using a type identifier that resolves to a type with a packed +// dimensions together with another packed dimensions as the base type for an +// enum results in an error. + +module test; + + typedef int T; + + enum T [1:0] { + A + } e; + + initial begin + $display("FAILED"); + end + +endmodule diff --git a/ivtest/ivltests/enum_base_fail_range2.v b/ivtest/ivltests/enum_base_fail_range2.v new file mode 100644 index 000000000..e82e640bd --- /dev/null +++ b/ivtest/ivltests/enum_base_fail_range2.v @@ -0,0 +1,16 @@ +// Check that using a type identifier that resolves to a type with multiple +// packed dimensions as the base type for an enum results in an error. + +module test; + + typedef bit [1:0][1:0] T; + + enum T { + A + } e; + + initial begin + $display("FAILED"); + end + +endmodule diff --git a/ivtest/ivltests/enum_base_fail_range3.v b/ivtest/ivltests/enum_base_fail_range3.v new file mode 100644 index 000000000..a7ccf5928 --- /dev/null +++ b/ivtest/ivltests/enum_base_fail_range3.v @@ -0,0 +1,14 @@ +// Check that specifying a vector type with multiple packed dimensions as the +// base type for an enum results in an error. + +module test; + + enum logic [1:0][1:0] { + A + } e; + + initial begin + $display("FAILED"); + end + +endmodule diff --git a/ivtest/ivltests/enum_base_fail_real1.v b/ivtest/ivltests/enum_base_fail_real1.v new file mode 100644 index 000000000..cfd5df8bf --- /dev/null +++ b/ivtest/ivltests/enum_base_fail_real1.v @@ -0,0 +1,14 @@ +// Check that using a real type as the base type for an enum results in an +// error. + +module test; + + enum real { + A + } e; + + initial begin + $display("FAILED"); + end + +endmodule diff --git a/ivtest/ivltests/enum_base_fail_real2.v b/ivtest/ivltests/enum_base_fail_real2.v new file mode 100644 index 000000000..c51748e21 --- /dev/null +++ b/ivtest/ivltests/enum_base_fail_real2.v @@ -0,0 +1,16 @@ +// Check that using a real type as the base type for an enum results in an +// error. + +module test; + + typedef real T; + + enum T { + A + } e; + + initial begin + $display("FAILED"); + end + +endmodule diff --git a/ivtest/ivltests/enum_base_fail_string1.v b/ivtest/ivltests/enum_base_fail_string1.v new file mode 100644 index 000000000..58b789a46 --- /dev/null +++ b/ivtest/ivltests/enum_base_fail_string1.v @@ -0,0 +1,14 @@ +// Check that using a string type as the base type for an enum results in an +// error. + +module test; + + enum string { + A + } e; + + initial begin + $display("FAILED"); + end + +endmodule diff --git a/ivtest/ivltests/enum_base_fail_string2.v b/ivtest/ivltests/enum_base_fail_string2.v new file mode 100644 index 000000000..638282f09 --- /dev/null +++ b/ivtest/ivltests/enum_base_fail_string2.v @@ -0,0 +1,16 @@ +// Check that using a string type as the base type for an enum results in an +// error. + +module test; + + typedef string T; + + enum T { + A + } e; + + initial begin + $display("FAILED"); + end + +endmodule diff --git a/ivtest/ivltests/enum_base_fail_struct.v b/ivtest/ivltests/enum_base_fail_struct.v new file mode 100644 index 000000000..556fb092c --- /dev/null +++ b/ivtest/ivltests/enum_base_fail_struct.v @@ -0,0 +1,18 @@ +// Check that using a struct type as the base type for an enum results in an +// error. + +module test; + + typedef struct packed { + int x; + } T; + + enum T { + A + } e; + + initial begin + $display("FAILED"); + end + +endmodule diff --git a/ivtest/ivltests/enum_base_integer.v b/ivtest/ivltests/enum_base_integer.v new file mode 100644 index 000000000..a419dddcc --- /dev/null +++ b/ivtest/ivltests/enum_base_integer.v @@ -0,0 +1,18 @@ +// Check that it is possible to declare an enum type with the integer type as +// the base type. + +module test; + + enum integer { + A + } E; + + initial begin + if ($bits(E) == $bits(integer)) begin + $display("PASSED"); + end else begin + $display("FAILED"); + end + end + +endmodule diff --git a/ivtest/ivltests/enum_base_none.v b/ivtest/ivltests/enum_base_none.v new file mode 100644 index 000000000..ab5d06ac0 --- /dev/null +++ b/ivtest/ivltests/enum_base_none.v @@ -0,0 +1,18 @@ +// Check that it is possible to declare an enum type without an explicit base +// type. In this case the base type should default to `int`. + +module test; + + enum { + A + } E; + + initial begin + if ($bits(E) == 32) begin + $display("PASSED"); + end else begin + $display("FAILED"); + end + end + +endmodule diff --git a/ivtest/ivltests/enum_base_scalar.v b/ivtest/ivltests/enum_base_scalar.v new file mode 100644 index 000000000..baf859934 --- /dev/null +++ b/ivtest/ivltests/enum_base_scalar.v @@ -0,0 +1,26 @@ +// Check that it is possible to declare an enum type with a scalar vector type +// as the base type. + +module test; + + enum reg { + A + } e1; + + enum logic { + B + } e2; + + enum bit { + C + } e3; + + initial begin + if ($bits(e1) == 1 && $bits(e2) == 1 && $bits(e3) == 1) begin + $display("PASSED"); + end else begin + $display("FAILED"); + end + end + +endmodule diff --git a/ivtest/ivltests/enum_base_time.v b/ivtest/ivltests/enum_base_time.v new file mode 100644 index 000000000..b8923ef23 --- /dev/null +++ b/ivtest/ivltests/enum_base_time.v @@ -0,0 +1,18 @@ +// Check that it is possible to declare an enum type with the time type as the +// base type. + +module test; + + enum time { + A + } E; + + initial begin + if ($bits(E) == 64) begin + $display("PASSED"); + end else begin + $display("FAILED"); + end + end + +endmodule diff --git a/ivtest/ivltests/enum_base_typename1.v b/ivtest/ivltests/enum_base_typename1.v new file mode 100644 index 000000000..98dbaca1b --- /dev/null +++ b/ivtest/ivltests/enum_base_typename1.v @@ -0,0 +1,20 @@ +// Check that it is possible to declare an enum type with a type identifier that +// resolves to an integer type as the base type. + +module test; + + typedef integer T; + + enum T { + A + } E; + + initial begin + if ($bits(E) == $bits(integer)) begin + $display("PASSED"); + end else begin + $display("FAILED"); + end + end + +endmodule diff --git a/ivtest/ivltests/enum_base_typename2.v b/ivtest/ivltests/enum_base_typename2.v new file mode 100644 index 000000000..efd1a2302 --- /dev/null +++ b/ivtest/ivltests/enum_base_typename2.v @@ -0,0 +1,20 @@ +// Check that it is possible to declare an enum type with a type identifier plus +// packed dimensions as the the base type. + +module test; + + typedef bit T; + + enum T [31:0] { + A + } E; + + initial begin + if ($bits(E) == 32) begin + $display("PASSED"); + end else begin + $display("FAILED"); + end + end + +endmodule diff --git a/ivtest/regress-sv.list b/ivtest/regress-sv.list index 70e7b90c5..291377749 100644 --- a/ivtest/regress-sv.list +++ b/ivtest/regress-sv.list @@ -231,7 +231,27 @@ clkgen_reg normal,-g2009 ivltests disable_fork_cmd normal,-g2009 ivltests display_bug normal,-g2009 ivltests gold=display_bug.gold edge normal,-g2009 ivltests +enum_base_atom2 normal,-g2005-sv ivltests +enum_base_fail_array CE,-g2005-sv ivltests +enum_base_fail_darray CE,-g2005-sv ivltests +enum_base_fail_darray CE,-g2005-sv ivltests +enum_base_fail_enum CE,-g2005-sv ivltests +enum_base_fail_queue CE,-g2005-sv ivltests +enum_base_fail_range1 CE,-g2005-sv ivltests +enum_base_fail_range2 CE,-g2005-sv ivltests +enum_base_fail_range3 CE,-g2005-sv ivltests +enum_base_fail_real1 CE,-g2005-sv ivltests +enum_base_fail_real2 CE,-g2005-sv ivltests +enum_base_fail_string1 CE,-g2005-sv ivltests +enum_base_fail_string2 CE,-g2005-sv ivltests +enum_base_fail_struct CE,-g2005-sv ivltests +enum_base_integer normal,-g2005-sv ivltests +enum_base_none normal,-g2005-sv ivltests enum_base_range normal,-g2005-sv ivltests +enum_base_scalar normal,-g2005-sv ivltests +enum_base_time normal,-g2005-sv ivltests +enum_base_typename1 normal,-g2005-sv ivltests +enum_base_typename2 normal,-g2005-sv ivltests enum_compatibility1 normal,-g2005-sv ivltests enum_compatibility2 normal,-g2005-sv ivltests enum_compatibility3 normal,-g2005-sv ivltests diff --git a/ivtest/regress-vlog95.list b/ivtest/regress-vlog95.list index cb68c4df5..8357e0afc 100644 --- a/ivtest/regress-vlog95.list +++ b/ivtest/regress-vlog95.list @@ -776,6 +776,8 @@ constfunc6_ams normal,-pallowsigned=1 ivltests constfunc7 normal,-pallowsigned=1 ivltests constfunc13 normal,-pallowsigned=1 ivltests constfunc14 normal,-pallowsigned=1 ivltests +enum_base_atom2 normal,-g2005-sv,-pallowsigned=1 ivltests +enum_base_none normal,-g2005-sv,-pallowsigned=1 ivltests enum_elem_ranges normal,-g2009,-pallowsigned=1 ivltests enum_value_expr normal,-g2009,-pallowsigned=1 ivltests enum_values normal,-g2009,-pallowsigned=1 ivltests