diff --git a/elab_type.cc b/elab_type.cc index 338926ef1..413e6f61c 100644 --- a/elab_type.cc +++ b/elab_type.cc @@ -141,6 +141,7 @@ ivl_type_t vector_type_t::elaborate_type_raw(Design*des, NetScope*scope) const netvector_t*tmp = new netvector_t(packed, base_type); tmp->set_signed(signed_flag); tmp->set_isint(integer_flag); + tmp->set_implicit(implicit_flag); return tmp; } diff --git a/ivtest/ivltests/parameter_1bit.v b/ivtest/ivltests/parameter_1bit.v new file mode 100644 index 000000000..bf59e5b5c --- /dev/null +++ b/ivtest/ivltests/parameter_1bit.v @@ -0,0 +1,26 @@ +// Check that parameters with a implicit and 1-bit range type are handled correctly + +module test #( + // This should get truncated to 1'b1 + parameter [0:0] P = 2'b11 +); + + reg 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(P), 1); + `check(P + 1'b1, 1'b0); + `check(P, 1'b1); + + if (!failed) begin + $display("PASSED"); + end + end + +endmodule diff --git a/ivtest/ivltests/parameter_scalar.v b/ivtest/ivltests/parameter_scalar.v new file mode 100644 index 000000000..069193e60 --- /dev/null +++ b/ivtest/ivltests/parameter_scalar.v @@ -0,0 +1,26 @@ +// Check that parameters with a scalar type are handled correctly + +module test #( + // This should get truncated to 1'b1 + parameter bit P = 2'b11 +); + + 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(P), 1); + `check(P + 1'b1, 1'b0); + `check(P, 1'b1); + + if (!failed) begin + $display("PASSED"); + end + end + +endmodule diff --git a/ivtest/regress-sv.list b/ivtest/regress-sv.list index 65140e653..2aa6adcbe 100644 --- a/ivtest/regress-sv.list +++ b/ivtest/regress-sv.list @@ -374,6 +374,7 @@ parameter_no_default_fail2 CE ivltests parameter_no_default_toplvl normal,-g2005-sv ivltests parameter_override_invalid7 CE,-g2005-sv ivltests parameter_override_invalid8 CE,-g2005-sv ivltests +parameter_scalar normal,-g2005-sv ivltests parameter_type2 normal,-g2009 ivltests parpkg_test normal,-g2009 ivltests parpkg_test2 normal,-g2009 ivltests diff --git a/ivtest/regress-vlg.list b/ivtest/regress-vlg.list index 5f32b39d2..3bd41a707 100644 --- a/ivtest/regress-vlg.list +++ b/ivtest/regress-vlg.list @@ -712,6 +712,7 @@ param_test2 normal ivltests gold=param_test2.gold param_test3 normal ivltests gold=param_test3.gold # PR#293 param_test4 normal ivltests param_times normal ivltests # param has multiplication. +parameter_1bit normal ivltests parameter_type normal ivltests gold=parameter_type.gold parameter_in_generate1 CE ivltests parameter_no_default CE ivltests diff --git a/net_design.cc b/net_design.cc index 8112f2039..ac579bb51 100644 --- a/net_design.cc +++ b/net_design.cc @@ -515,8 +515,7 @@ void NetScope::evaluate_parameter_logic_(Design*des, param_ref_t cur) // case of a netvector_t with no dimensions, that exists only to carry // signed-ness, e.g.: // parameter signed foo = bar; - // (Scalars are handled differently, not by a netvector_t with no - // dimensions.) + // These will be marked as scalar, but also have the implict flag set. const netvector_t* param_vect = dynamic_cast (param_type); if (debug_elaborate) { @@ -536,8 +535,9 @@ void NetScope::evaluate_parameter_logic_(Design*des, param_ref_t cur) int lv_width = -2; if (param_type) { use_type = param_type->base_type(); - // Is this a netvector_t with no dimenions? - if (param_vect && param_vect->packed_dims().size()==0) + // Is this an implicit netvector_t with no dimenions? + if (param_vect && param_vect->get_implicit() && + param_vect->get_scalar()) lv_width = -2; else if (param_type->packed()) lv_width = param_type->packed_width(); diff --git a/netvector.cc b/netvector.cc index 86f3d1637..f43dd839e 100644 --- a/netvector.cc +++ b/netvector.cc @@ -50,13 +50,13 @@ const netvector_t* netvector_t::integer_type(bool is_signed) netvector_t netvector_t::scalar_logic (IVL_VT_LOGIC); netvector_t::netvector_t(ivl_variable_type_t type, long msb, long lsb, bool flag) -: type_(type), signed_(flag), isint_(false) +: type_(type), signed_(flag), isint_(false), implicit_(false) { packed_dims_.push_back(netrange_t(msb,lsb)); } netvector_t::netvector_t(ivl_variable_type_t type) -: type_(type), signed_(false), isint_(false) +: type_(type), signed_(false), isint_(false), implicit_(false) { } diff --git a/netvector.h b/netvector.h index c79672900..55a482ec8 100644 --- a/netvector.h +++ b/netvector.h @@ -56,6 +56,9 @@ class netvector_t : public ivl_type_s { inline bool get_scalar(void) const { return packed_dims_.empty(); } + void set_implicit(bool implicit) { implicit_ = implicit; } + bool get_implicit() const { return implicit_; } + ivl_variable_type_t base_type() const; const std::vector&packed_dims() const; @@ -89,6 +92,7 @@ class netvector_t : public ivl_type_s { ivl_variable_type_t type_; bool signed_ : 1; bool isint_ : 1; // original type of integer + bool implicit_ : 1; }; inline netvector_t::netvector_t(const std::vector&pd,