Correctly handle separate port type declaration for atom2 types
When using non-ANSI style port declarations it is possible to declare the port direction and the data type for the port in separate statements. E.g. ``` input x; reg x; ``` When using packed array dimensions they must match for both declarations. E.g. ``` input [3:0] x; reg [3:0] x; ``` But this only applies to vector types, i.e. the packed dimension is explicitly declared. It does not apply to the atom2 types which have an implicit packed dimension. The current implementation requires that even for atom2 types the implicit dimension needs to be explicitly declared in the port direction. E.g. the following will result in a elaboration error complaining about a packed dimension mismatch. ``` module test; output x; byte x; endmodule ``` Currently atom2_type_t's are deconstructed into base type, range and signdness in the parser. That data is then passed to the signal elaboration, which will then construct a netvector_t from it. This makes it impossible to e.g. differentiate between `bit signed [31:0]` and `int` during elaboration. Instead of breaking the data type apart pass it as the data_type_t of the signal and use the elaborate_type() method in the signal elaboration to generate the netvector_t. Signed-off-by: Lars-Peter Clausen <lars@metafoo.de>
This commit is contained in:
parent
d480c4d7d0
commit
de9e3b791b
|
|
@ -941,7 +941,8 @@ ivl_type_t PWire::elaborate_type(Design*des, NetScope*scope,
|
|||
dynamic_cast<enum_type_t*>(set_data_type_) ||
|
||||
dynamic_cast<string_type_t*>(set_data_type_) ||
|
||||
dynamic_cast<class_type_t*>(set_data_type_) ||
|
||||
dynamic_cast<parray_type_t*>(set_data_type_)) {
|
||||
dynamic_cast<parray_type_t*>(set_data_type_) ||
|
||||
dynamic_cast<atom2_type_t*>(set_data_type_)) {
|
||||
ivl_type_t use_type = set_data_type_->elaborate_type(des, scope);
|
||||
ivl_assert(*this, packed_dimensions.empty());
|
||||
return use_type;
|
||||
|
|
|
|||
43
pform.cc
43
pform.cc
|
|
@ -2601,11 +2601,6 @@ void pform_module_define_port(const struct vlltype&li,
|
|||
data_type = vec_type->base_type;
|
||||
signed_flag = vec_type->signed_flag;
|
||||
prange = vec_type->pdims.get();
|
||||
} else if (atom2_type_t*atype = dynamic_cast<atom2_type_t*>(vtype)) {
|
||||
data_type = IVL_VT_BOOL;
|
||||
signed_flag = atype->signed_flag;
|
||||
prange = make_range_from_width(atype->type_code);
|
||||
|
||||
} else if (real_type_t*rtype = dynamic_cast<real_type_t*>(vtype)) {
|
||||
data_type = IVL_VT_REAL;
|
||||
signed_flag = true;
|
||||
|
|
@ -2959,11 +2954,8 @@ vector<pform_tf_port_t>*pform_make_task_ports(const struct vlltype&loc,
|
|||
vtype = uarray->base_type;
|
||||
}
|
||||
|
||||
if (atom2_type_t*atype = dynamic_cast<atom2_type_t*> (vtype)) {
|
||||
list<pform_range_t>*range_tmp = make_range_from_width(atype->type_code);
|
||||
ret = pform_make_task_ports(loc, pt, IVL_VT_BOOL,
|
||||
atype->signed_flag,
|
||||
range_tmp, ports);
|
||||
if (dynamic_cast<atom2_type_t*> (vtype)) {
|
||||
ret = do_make_task_ports(loc, pt, IVL_VT_BOOL, vtype, ports);
|
||||
}
|
||||
|
||||
if (vector_type_t*vec_type = dynamic_cast<vector_type_t*> (vtype)) {
|
||||
|
|
@ -3431,30 +3423,6 @@ void pform_set_port_type(const struct vlltype&li,
|
|||
delete attr;
|
||||
}
|
||||
|
||||
static void pform_set_integer_2atom(uint64_t width, bool signed_flag, perm_string name)
|
||||
{
|
||||
PWire*cur = pform_get_wire_in_scope(name);
|
||||
assert(cur);
|
||||
|
||||
cur->set_signed(signed_flag);
|
||||
|
||||
pform_range_t rng;
|
||||
rng.first = new PENumber(new verinum(width-1, integer_width));
|
||||
rng.second = new PENumber(new verinum((uint64_t)0, integer_width));
|
||||
list<pform_range_t>rlist;
|
||||
rlist.push_back(rng);
|
||||
cur->set_range(rlist, SR_NET);
|
||||
}
|
||||
|
||||
static void pform_set_integer_2atom(uint64_t width, bool signed_flag, list<perm_string>*names)
|
||||
{
|
||||
for (list<perm_string>::iterator cur = names->begin()
|
||||
; cur != names->end() ; ++ cur ) {
|
||||
perm_string txt = *cur;
|
||||
pform_set_integer_2atom(width, signed_flag, txt);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* This function detects the derived class for the given type and
|
||||
* dispatches the type to the proper subtype function.
|
||||
|
|
@ -3471,12 +3439,7 @@ void pform_set_data_type(const struct vlltype&li, data_type_t*data_type, list<pe
|
|||
if (uarray_type)
|
||||
data_type = uarray_type->base_type;
|
||||
|
||||
if (atom2_type_t*atom2_type = dynamic_cast<atom2_type_t*> (data_type)) {
|
||||
pform_set_integer_2atom(atom2_type->type_code, atom2_type->signed_flag, names);
|
||||
vt = IVL_VT_BOOL;
|
||||
}
|
||||
|
||||
else if (vector_type_t*vec_type = dynamic_cast<vector_type_t*> (data_type)) {
|
||||
if (vector_type_t*vec_type = dynamic_cast<vector_type_t*> (data_type)) {
|
||||
if (net_type==NetNet::REG && vec_type->integer_flag)
|
||||
net_type=NetNet::INTEGER;
|
||||
|
||||
|
|
|
|||
Loading…
Reference in New Issue