Handle scalar typed parameters

Parameters without any type or range specification inherit the type from
the value that has been assigned to it. Similarly a parameter with just an
`signed` or `unsigned` keyword will inherit its range from the value
assigned to it.

In the current implementation any vector type parameter that does not have
a range specification inherits the type form the assigned value. That
includes parameters with an explicit scalar vector type. E.g.

```
parameter bit X = 10
```

Make sure that a parameter only uses the width from the assigned value if
the parameter does not have an explicit data type.

To support this we need to remember whether a `netvector_t` was declared as
an explicit or implicit data type. Currently this information is only
available on the unelaborated `vector_type_t`.

Signed-off-by: Lars-Peter Clausen <lars@metafoo.de>
This commit is contained in:
Lars-Peter Clausen 2022-03-26 10:45:00 +01:00
parent 0a86773c5e
commit 37f9cde49f
4 changed files with 11 additions and 6 deletions

View File

@ -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;
}

View File

@ -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<const netvector_t*> (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();

View File

@ -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)
{
}

View File

@ -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<netrange_t>&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<netrange_t>&pd,