Merge pull request #577 from larsclausen/packed_array

Support signals of packed arrays of packed types
This commit is contained in:
Stephen Williams 2022-01-14 20:53:30 -08:00 committed by GitHub
commit 279b2665af
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
5 changed files with 32 additions and 75 deletions

View File

@ -873,37 +873,6 @@ void PWhile::elaborate_sig(Design*des, NetScope*scope) const
statement_->elaborate_sig(des, scope);
}
static ivl_type_s*elaborate_type(Design*des, NetScope*scope,
data_type_t*pform_type)
{
if (struct_type_t*struct_type = dynamic_cast<struct_type_t*>(pform_type)) {
ivl_type_s*use_type = struct_type->elaborate_type(des, scope);
return use_type;
}
cerr << pform_type->get_fileline() << ": sorry: I don't know how to elaborate "
<< typeid(*pform_type).name() << " here." << endl;
des->errors += 1;
return 0;
}
static netparray_t* elaborate_parray_type(Design*des, NetScope*scope, const LineInfo*li,
parray_type_t*data_type)
{
vector<netrange_t>packed_dimensions;
bool dimensions_ok = evaluate_ranges(des, scope, li, packed_dimensions, * data_type->dims);
ivl_assert(*data_type, dimensions_ok);
ivl_type_s*element_type = elaborate_type(des, scope, data_type->base_type);
netparray_t*res = new netparray_t(packed_dimensions, element_type);
//res->set_line(*data_type);
return res;
}
bool test_ranges_eeq(const vector<netrange_t>&lef, const vector<netrange_t>&rig)
{
if (lef.size() != rig.size())
@ -1307,7 +1276,8 @@ NetNet* PWire::elaborate_sig(Design*des, NetScope*scope) const
// The trick here is that the parray type has an
// arbitrary sub-type, and not just a scalar bit...
netparray_t*use_type = elaborate_parray_type(des, scope, this, parray_type);
ivl_type_t tmp_type = parray_type->elaborate_type(des, scope);
const netparray_t*use_type = dynamic_cast<const netparray_t*>(tmp_type);
// Should not be getting packed dimensions other than
// through the parray type declaration.
ivl_assert(*this, packed_dimensions.empty());

View File

@ -34,44 +34,6 @@
using namespace std;
/*
* Some types have a list of ranges that need to be elaborated. This
* function elaborates the ranges referenced by "dims" into the vector
* "ranges".
*/
static void elaborate_array_ranges(Design*des, NetScope*scope,
vector<netrange_t>&ranges,
const list<pform_range_t>*dims)
{
if (dims == 0)
return;
for (list<pform_range_t>::const_iterator cur = dims->begin()
; cur != dims->end() ; ++ cur) {
NetExpr*me = elab_and_eval(des, scope, cur->first, 0, true);
NetExpr*le = elab_and_eval(des, scope, cur->second, 0, true);
/* If elaboration failed for either expression, we
should have already reported the error, so just
skip the following evaluation to recover. */
long mnum = 0, lnum = 0;
if ( me && ! eval_as_long(mnum, me) ) {
assert(0);
des->errors += 1;
}
if ( le && ! eval_as_long(lnum, le) ) {
assert(0);
des->errors += 1;
}
ranges.push_back(netrange_t(mnum, lnum));
}
}
/*
* Elaborations of types may vary depending on the scope that it is
* done in, so keep a per-scope cache of the results.
@ -164,7 +126,8 @@ ivl_type_s* enum_type_t::elaborate_type_raw(Design*, NetScope*scope) const
ivl_type_s* vector_type_t::elaborate_type_raw(Design*des, NetScope*scope) const
{
vector<netrange_t> packed;
elaborate_array_ranges(des, scope, packed, pdims.get());
if (pdims.get())
evaluate_ranges(des, scope, this, packed, *pdims);
netvector_t*tmp = new netvector_t(packed, base_type);
tmp->set_signed(signed_flag);
@ -192,8 +155,21 @@ ivl_type_s* string_type_t::elaborate_type_raw(Design*, NetScope*) const
ivl_type_s* parray_type_t::elaborate_type_raw(Design*des, NetScope*scope) const
{
vector<netrange_t>packed;
elaborate_array_ranges(des, scope, packed, dims.get());
if (dims.get())
evaluate_ranges(des, scope, this, packed, *dims);
if (base_type->figure_packed_base_type() == IVL_VT_NO_TYPE) {
cerr << this->get_fileline() << " error: Packed array ";
if (!name.nil())
cerr << "`" << name << "` ";
cerr << "base-type `";
if (base_type->name.nil())
cerr << *base_type;
else
cerr << base_type->name;
cerr << "` is not packed." << endl;
des->errors++;
}
ivl_type_t etype = base_type->elaborate_type(des, scope);
return new netparray_t(packed, etype);

View File

@ -3549,9 +3549,6 @@ static void pform_set_integer_2atom(const struct vlltype&li, uint64_t width, boo
template <class T> static void pform_set2_data_type(const struct vlltype&li, T*data_type, perm_string name, NetNet::Type net_type, list<named_pexpr_t>*attr)
{
ivl_variable_type_t base_type = data_type->figure_packed_base_type();
if (base_type == IVL_VT_NO_TYPE) {
VLerror(li, "Compound type is not PACKED in this context.");
}
PWire*net = pform_get_make_wire_in_scope(li, name, net_type, NetNet::NOT_A_PORT, base_type);
assert(net);

View File

@ -48,6 +48,16 @@ ivl_variable_type_t vector_type_t::figure_packed_base_type(void) const
return base_type;
}
ivl_variable_type_t enum_type_t::figure_packed_base_type() const
{
return base_type;
}
ivl_variable_type_t atom2_type_t::figure_packed_base_type() const
{
return IVL_VT_BOOL;
}
atom2_type_t size_type (32, true);
PNamedItem::SymbolType enum_type_t::symbol_type() const

View File

@ -182,6 +182,8 @@ struct enum_type_t : public data_type_t {
// Return the elaborated version of the type.
virtual ivl_type_s*elaborate_type_raw(Design*des, NetScope*scope) const;
ivl_variable_type_t figure_packed_base_type() const;
SymbolType symbol_type() const;
ivl_variable_type_t base_type;
@ -217,6 +219,8 @@ struct atom2_type_t : public data_type_t {
virtual std::ostream& debug_dump(std::ostream&out) const;
ivl_type_s* elaborate_type_raw(Design*des, NetScope*scope) const;
ivl_variable_type_t figure_packed_base_type() const;
};
extern atom2_type_t size_type;