Some rework to allow for nested packed types.
This also simplifies the NetNet set of contructors and generalizes the types that are supported, especially packed types.
This commit is contained in:
parent
4e76912331
commit
914ebeca4a
|
|
@ -108,7 +108,7 @@ O = main.o async.o design_dump.o discipline.o dup_expr.o elaborate.o \
|
||||||
eval_tree.o expr_synth.o functor.o lexor.o lexor_keyword.o link_const.o \
|
eval_tree.o expr_synth.o functor.o lexor.o lexor_keyword.o link_const.o \
|
||||||
load_module.o netlist.o netmisc.o nettypes.o net_analog.o net_assign.o \
|
load_module.o netlist.o netmisc.o nettypes.o net_analog.o net_assign.o \
|
||||||
net_design.o netdarray.o \
|
net_design.o netdarray.o \
|
||||||
netenum.o netstruct.o netvector.o net_event.o net_expr.o net_func.o \
|
netenum.o netparray.o netstruct.o netvector.o net_event.o net_expr.o net_func.o \
|
||||||
net_func_eval.o net_link.o net_modulo.o \
|
net_func_eval.o net_link.o net_modulo.o \
|
||||||
net_nex_input.o net_nex_output.o net_proc.o net_scope.o net_tran.o \
|
net_nex_input.o net_nex_output.o net_proc.o net_scope.o net_tran.o \
|
||||||
net_udp.o pad_to_width.o parse.o parse_misc.o pform.o pform_analog.o \
|
net_udp.o pad_to_width.o parse.o parse_misc.o pform.o pform_analog.o \
|
||||||
|
|
|
||||||
|
|
@ -249,8 +249,6 @@ void NetNet::dump_net(ostream&o, unsigned ind) const
|
||||||
{
|
{
|
||||||
o << setw(ind) << "" << type() << ": " << name()
|
o << setw(ind) << "" << type() << ": " << name()
|
||||||
<< unpacked_dims_ << " unpacked dims=" << unpacked_dimensions();
|
<< unpacked_dims_ << " unpacked dims=" << unpacked_dimensions();
|
||||||
if (!packed_dims_.empty())
|
|
||||||
o << " packed dims=" << packed_dims_;
|
|
||||||
o << " pin_count=" << pin_count();
|
o << " pin_count=" << pin_count();
|
||||||
if (local_flag_)
|
if (local_flag_)
|
||||||
o << " (local)";
|
o << " (local)";
|
||||||
|
|
@ -1107,7 +1105,7 @@ void NetFuncDef::dump(ostream&o, unsigned ind) const
|
||||||
if (result_sig_) {
|
if (result_sig_) {
|
||||||
o << setw(ind+2) << "" << "Return signal: ";
|
o << setw(ind+2) << "" << "Return signal: ";
|
||||||
if (result_sig_->get_signed()) o << "+";
|
if (result_sig_->get_signed()) o << "+";
|
||||||
o << result_sig_->name() << result_sig_->packed_dims() << endl;
|
o << result_sig_->name() << endl;
|
||||||
}
|
}
|
||||||
o << setw(ind+2) << "" << "Arguments: ";
|
o << setw(ind+2) << "" << "Arguments: ";
|
||||||
if (port_count() == 0) o << "<none>";
|
if (port_count() == 0) o << "<none>";
|
||||||
|
|
@ -1129,7 +1127,7 @@ void NetFuncDef::dump(ostream&o, unsigned ind) const
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
if (port(idx)->get_signed()) o << "+";
|
if (port(idx)->get_signed()) o << "+";
|
||||||
o << port(idx)->name() << port(idx)->packed_dims() << endl;
|
o << port(idx)->name() << endl;
|
||||||
}
|
}
|
||||||
if (statement_)
|
if (statement_)
|
||||||
statement_->dump(o, ind+2);
|
statement_->dump(o, ind+2);
|
||||||
|
|
@ -1548,7 +1546,8 @@ void NetESignal::dump(ostream&o) const
|
||||||
o << "+";
|
o << "+";
|
||||||
o << name();
|
o << name();
|
||||||
if (word_) o << "[word=" << *word_ << "]";
|
if (word_) o << "[word=" << *word_ << "]";
|
||||||
o << sig()->packed_dims();
|
vector<netrange_t>tmp = net_->net_type()->slice_dimensions();
|
||||||
|
o << tmp;
|
||||||
}
|
}
|
||||||
|
|
||||||
void NetETernary::dump(ostream&o) const
|
void NetETernary::dump(ostream&o) const
|
||||||
|
|
|
||||||
|
|
@ -1481,7 +1481,7 @@ static const netstruct_t::member_t*get_struct_member(const LineInfo*li,
|
||||||
perm_string method_name,
|
perm_string method_name,
|
||||||
unsigned long&off)
|
unsigned long&off)
|
||||||
{
|
{
|
||||||
netstruct_t*type = net->struct_type();
|
const netstruct_t*type = net->struct_type();
|
||||||
ivl_assert(*li, type);
|
ivl_assert(*li, type);
|
||||||
|
|
||||||
if (! type->packed()) {
|
if (! type->packed()) {
|
||||||
|
|
@ -3555,7 +3555,7 @@ NetExpr* PEIdent::elaborate_expr_net_idx_up_(Design*des, NetScope*scope,
|
||||||
long lsv = base_c->value().as_long();
|
long lsv = base_c->value().as_long();
|
||||||
long offset = 0;
|
long offset = 0;
|
||||||
// Get the signal range.
|
// Get the signal range.
|
||||||
const list<netrange_t>&packed = net->sig()->packed_dims();
|
const vector<netrange_t>&packed = net->sig()->packed_dims();
|
||||||
ivl_assert(*this, packed.size() == prefix_indices.size()+1);
|
ivl_assert(*this, packed.size() == prefix_indices.size()+1);
|
||||||
|
|
||||||
// We want the last range, which is where we work.
|
// We want the last range, which is where we work.
|
||||||
|
|
@ -3784,7 +3784,7 @@ NetExpr* PEIdent::elaborate_expr_net_bit_(Design*des, NetScope*scope,
|
||||||
|
|
||||||
long msv = msc->value().as_long();
|
long msv = msc->value().as_long();
|
||||||
|
|
||||||
const list<netrange_t>& sig_packed = net->sig()->packed_dims();
|
const vector<netrange_t>& sig_packed = net->sig()->packed_dims();
|
||||||
if (prefix_indices.size()+2 <= sig_packed.size()) {
|
if (prefix_indices.size()+2 <= sig_packed.size()) {
|
||||||
// Special case: this is a slice of a multi-dimensional
|
// Special case: this is a slice of a multi-dimensional
|
||||||
// packed array. For example:
|
// packed array. For example:
|
||||||
|
|
@ -3877,7 +3877,7 @@ NetExpr* PEIdent::elaborate_expr_net_bit_(Design*des, NetScope*scope,
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
const list<netrange_t>& sig_packed = net->sig()->packed_dims();
|
const vector<netrange_t>& sig_packed = net->sig()->packed_dims();
|
||||||
if (prefix_indices.size()+2 <= sig_packed.size()) {
|
if (prefix_indices.size()+2 <= sig_packed.size()) {
|
||||||
// Special case: this is a slice of a multi-dimensional
|
// Special case: this is a slice of a multi-dimensional
|
||||||
// packed array. For example:
|
// packed array. For example:
|
||||||
|
|
|
||||||
|
|
@ -507,7 +507,7 @@ bool PEIdent::elaborate_lval_net_part_(Design*des,
|
||||||
NetNet*reg = lv->sig();
|
NetNet*reg = lv->sig();
|
||||||
ivl_assert(*this, reg);
|
ivl_assert(*this, reg);
|
||||||
|
|
||||||
const list<netrange_t>&packed = reg->packed_dims();
|
const vector<netrange_t>&packed = reg->packed_dims();
|
||||||
|
|
||||||
// Part selects cannot select slices. So there must be enough
|
// Part selects cannot select slices. So there must be enough
|
||||||
// prefix_indices to get all the way to the final dimension.
|
// prefix_indices to get all the way to the final dimension.
|
||||||
|
|
@ -596,7 +596,7 @@ bool PEIdent::elaborate_lval_net_idx_(Design*des,
|
||||||
long lsv = base_c->value().as_long();
|
long lsv = base_c->value().as_long();
|
||||||
long offset = 0;
|
long offset = 0;
|
||||||
// Get the signal range.
|
// Get the signal range.
|
||||||
const list<netrange_t>&packed = reg->packed_dims();
|
const vector<netrange_t>&packed = reg->packed_dims();
|
||||||
ivl_assert(*this, packed.size() == prefix_indices.size()+1);
|
ivl_assert(*this, packed.size() == prefix_indices.size()+1);
|
||||||
|
|
||||||
// We want the last range, which is where we work.
|
// We want the last range, which is where we work.
|
||||||
|
|
@ -680,7 +680,7 @@ bool PEIdent::elaborate_lval_net_packed_member_(Design*des, NetScope*scope,
|
||||||
NetNet*reg = lv->sig();
|
NetNet*reg = lv->sig();
|
||||||
ivl_assert(*this, reg);
|
ivl_assert(*this, reg);
|
||||||
|
|
||||||
netstruct_t*struct_type = reg->struct_type();
|
const netstruct_t*struct_type = reg->struct_type();
|
||||||
ivl_assert(*this, struct_type);
|
ivl_assert(*this, struct_type);
|
||||||
|
|
||||||
if (debug_elaborate) {
|
if (debug_elaborate) {
|
||||||
|
|
|
||||||
|
|
@ -430,11 +430,18 @@ NetNet* PEIdent::elaborate_lnet_common_(Design*des, NetScope*scope,
|
||||||
remove the member and store it into method_name, and retry
|
remove the member and store it into method_name, and retry
|
||||||
the search with "a.b". */
|
the search with "a.b". */
|
||||||
if (sig == 0 && path_.size() >= 2) {
|
if (sig == 0 && path_.size() >= 2) {
|
||||||
|
if (debug_elaborate) {
|
||||||
|
cerr << get_fileline() << ": PEIdent::elaborate_lnet_common_: "
|
||||||
|
"Symbol not found, try again with path_prefix=" << path_prefix
|
||||||
|
<< " and method_name=" << path_tail.name << endl;
|
||||||
|
}
|
||||||
method_name = path_tail.name;
|
method_name = path_tail.name;
|
||||||
symbol_search(this, des, scope, path_prefix, sig, par, eve);
|
symbol_search(this, des, scope, path_prefix, sig, par, eve);
|
||||||
|
|
||||||
// Whoops, not a struct signal, so give up on this avenue.
|
// Whoops, not a struct signal, so give up on this avenue.
|
||||||
if (sig && sig->struct_type() == 0) {
|
if (sig && sig->struct_type() == 0) {
|
||||||
|
cerr << get_fileline() << ": XXXXX: sig=" << sig->name()
|
||||||
|
<< " is found, but not a struct with member " << method_name << endl;
|
||||||
method_name = perm_string();
|
method_name = perm_string();
|
||||||
sig = 0;
|
sig = 0;
|
||||||
}
|
}
|
||||||
|
|
@ -474,7 +481,7 @@ NetNet* PEIdent::elaborate_lnet_common_(Design*des, NetScope*scope,
|
||||||
|
|
||||||
list<long> unpacked_indices_const;
|
list<long> unpacked_indices_const;
|
||||||
|
|
||||||
netstruct_t*struct_type = 0;
|
const netstruct_t*struct_type = 0;
|
||||||
if ((struct_type = sig->struct_type()) && !method_name.nil()) {
|
if ((struct_type = sig->struct_type()) && !method_name.nil()) {
|
||||||
|
|
||||||
// Detect the variable is a structure and there was a
|
// Detect the variable is a structure and there was a
|
||||||
|
|
|
||||||
60
elab_sig.cc
60
elab_sig.cc
|
|
@ -522,7 +522,7 @@ void PFunction::elaborate_sig(Design*des, NetScope*scope) const
|
||||||
des->errors += 1;
|
des->errors += 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
list<netrange_t> packed;
|
vector<netrange_t> packed;
|
||||||
packed.push_back(netrange_t(mnum, lnum));
|
packed.push_back(netrange_t(mnum, lnum));
|
||||||
ret_vec = new netvector_t(packed, IVL_VT_LOGIC);
|
ret_vec = new netvector_t(packed, IVL_VT_LOGIC);
|
||||||
ret_vec->set_signed(return_type_.type == PTF_REG_S);
|
ret_vec->set_signed(return_type_.type == PTF_REG_S);
|
||||||
|
|
@ -823,7 +823,7 @@ void PWhile::elaborate_sig(Design*des, NetScope*scope) const
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool evaluate_ranges(Design*des, NetScope*scope,
|
static bool evaluate_ranges(Design*des, NetScope*scope,
|
||||||
list<netrange_t>&llist,
|
vector<netrange_t>&llist,
|
||||||
const list<pform_range_t>&rlist)
|
const list<pform_range_t>&rlist)
|
||||||
{
|
{
|
||||||
bool bad_msb = false, bad_lsb = false;
|
bool bad_msb = false, bad_lsb = false;
|
||||||
|
|
@ -874,7 +874,7 @@ static netstruct_t* elaborate_struct_type(Design*des, NetScope*scope,
|
||||||
for (list<struct_member_t*>::iterator cur = struct_type->members->begin()
|
for (list<struct_member_t*>::iterator cur = struct_type->members->begin()
|
||||||
; cur != struct_type->members->end() ; ++ cur) {
|
; cur != struct_type->members->end() ; ++ cur) {
|
||||||
|
|
||||||
list<netrange_t>packed_dimensions;
|
vector<netrange_t>packed_dimensions;
|
||||||
|
|
||||||
struct_member_t*curp = *cur;
|
struct_member_t*curp = *cur;
|
||||||
if (curp->range.get() && ! curp->range->empty()) {
|
if (curp->range.get() && ! curp->range->empty()) {
|
||||||
|
|
@ -900,20 +900,6 @@ static netstruct_t* elaborate_struct_type(Design*des, NetScope*scope,
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
static netparray_t* elaborate_parray_type(Design*des, NetScope*scope,
|
|
||||||
parray_type_t*data_type)
|
|
||||||
{
|
|
||||||
|
|
||||||
list<netrange_t>packed_dimensions;
|
|
||||||
bool bad_range = evaluate_ranges(des, scope, packed_dimensions, * data_type->packed_dims);
|
|
||||||
ivl_assert(*data_type, !bad_range);
|
|
||||||
|
|
||||||
netparray_t*res = new netparray_t(packed_dimensions);
|
|
||||||
//res->set_line(*data_type);
|
|
||||||
|
|
||||||
return res;
|
|
||||||
}
|
|
||||||
|
|
||||||
static ivl_type_s*elaborate_type(Design*des, NetScope*scope,
|
static ivl_type_s*elaborate_type(Design*des, NetScope*scope,
|
||||||
data_type_t*pform_type)
|
data_type_t*pform_type)
|
||||||
{
|
{
|
||||||
|
|
@ -929,13 +915,29 @@ static ivl_type_s*elaborate_type(Design*des, NetScope*scope,
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool test_ranges_eeq(const list<netrange_t>&lef, const list<netrange_t>&rig)
|
static netparray_t* elaborate_parray_type(Design*des, NetScope*scope,
|
||||||
|
parray_type_t*data_type)
|
||||||
|
{
|
||||||
|
|
||||||
|
vector<netrange_t>packed_dimensions;
|
||||||
|
bool bad_range = evaluate_ranges(des, scope, packed_dimensions, * data_type->packed_dims);
|
||||||
|
ivl_assert(*data_type, !bad_range);
|
||||||
|
|
||||||
|
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())
|
if (lef.size() != rig.size())
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
list<netrange_t>::const_iterator lcur = lef.begin();
|
vector<netrange_t>::const_iterator lcur = lef.begin();
|
||||||
list<netrange_t>::const_iterator rcur = rig.begin();
|
vector<netrange_t>::const_iterator rcur = rig.begin();
|
||||||
while (lcur != lef.end()) {
|
while (lcur != lef.end()) {
|
||||||
if (lcur->get_msb() != rcur->get_msb())
|
if (lcur->get_msb() != rcur->get_msb())
|
||||||
return false;
|
return false;
|
||||||
|
|
@ -970,7 +972,7 @@ NetNet* PWire::elaborate_sig(Design*des, NetScope*scope) const
|
||||||
}
|
}
|
||||||
|
|
||||||
unsigned wid = 1;
|
unsigned wid = 1;
|
||||||
list<netrange_t>packed_dimensions;
|
vector<netrange_t>packed_dimensions;
|
||||||
|
|
||||||
des->errors += error_cnt_;
|
des->errors += error_cnt_;
|
||||||
|
|
||||||
|
|
@ -1011,7 +1013,7 @@ NetNet* PWire::elaborate_sig(Design*des, NetScope*scope) const
|
||||||
|
|
||||||
if (port_set_ || net_set_) {
|
if (port_set_ || net_set_) {
|
||||||
bool bad_range = false;
|
bool bad_range = false;
|
||||||
list<netrange_t> plist, nlist;
|
vector<netrange_t> plist, nlist;
|
||||||
/* If they exist get the port definition MSB and LSB */
|
/* If they exist get the port definition MSB and LSB */
|
||||||
if (port_set_ && !port_.empty()) {
|
if (port_set_ && !port_.empty()) {
|
||||||
bad_range |= evaluate_ranges(des, scope, plist, port_);
|
bad_range |= evaluate_ranges(des, scope, plist, port_);
|
||||||
|
|
@ -1222,7 +1224,8 @@ NetNet* PWire::elaborate_sig(Design*des, NetScope*scope) const
|
||||||
<< " and packed_width=" << use_enum->packed_width() << endl;
|
<< " and packed_width=" << use_enum->packed_width() << endl;
|
||||||
}
|
}
|
||||||
|
|
||||||
sig = new NetNet(scope, name_, wtype, packed_dimensions, unpacked_dimensions, use_enum);
|
ivl_assert(*this, packed_dimensions.empty());
|
||||||
|
sig = new NetNet(scope, name_, wtype, unpacked_dimensions, use_enum);
|
||||||
|
|
||||||
|
|
||||||
} else if (netarray) {
|
} else if (netarray) {
|
||||||
|
|
@ -1256,14 +1259,7 @@ NetNet* PWire::elaborate_sig(Design*des, NetScope*scope) const
|
||||||
<< " in scope " << scope_path(scope) << endl;
|
<< " in scope " << scope_path(scope) << endl;
|
||||||
}
|
}
|
||||||
|
|
||||||
ivl_type_s*base_type = elaborate_type(des, scope, parray_type->base_type);
|
sig = new NetNet(scope, name_, wtype, unpacked_dimensions, use_type);
|
||||||
#if 0
|
|
||||||
cerr << get_fileline() << ": sorry: Packed array of "
|
|
||||||
<< typeid(*parray_type->base_type).name()
|
|
||||||
<< " not supported." << endl;
|
|
||||||
des->errors += 1;
|
|
||||||
#endif
|
|
||||||
sig = new NetNet(scope, name_, wtype, use_type->packed_dimensions(), unpacked_dimensions, base_type);
|
|
||||||
|
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
|
|
@ -1293,7 +1289,7 @@ NetNet* PWire::elaborate_sig(Design*des, NetScope*scope) const
|
||||||
if (is_implicit_scalar) vec->set_scalar(true);
|
if (is_implicit_scalar) vec->set_scalar(true);
|
||||||
else vec->set_scalar(get_scalar());
|
else vec->set_scalar(get_scalar());
|
||||||
packed_dimensions.clear();
|
packed_dimensions.clear();
|
||||||
sig = new NetNet(scope, name_, wtype, packed_dimensions, unpacked_dimensions, vec);
|
sig = new NetNet(scope, name_, wtype, unpacked_dimensions, vec);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -998,8 +998,9 @@ NetNet*PGModule::resize_net_to_port_(Design*des, NetScope*scope,
|
||||||
ivl_assert(*this, dir != NetNet::NOT_A_PORT);
|
ivl_assert(*this, dir != NetNet::NOT_A_PORT);
|
||||||
ivl_assert(*this, dir != NetNet::PIMPLICIT);
|
ivl_assert(*this, dir != NetNet::PIMPLICIT);
|
||||||
|
|
||||||
|
netvector_t*tmp_type = new netvector_t(IVL_VT_LOGIC, port_wid-1, 0);
|
||||||
NetNet*tmp = new NetNet(scope, scope->local_symbol(),
|
NetNet*tmp = new NetNet(scope, scope->local_symbol(),
|
||||||
NetNet::WIRE, port_wid);
|
NetNet::WIRE, tmp_type);
|
||||||
tmp->local_flag(true);
|
tmp->local_flag(true);
|
||||||
tmp->set_line(*this);
|
tmp->set_line(*this);
|
||||||
|
|
||||||
|
|
@ -1417,6 +1418,12 @@ void PGModule::elaborate_mod_(Design*des, Module*rmod, NetScope*scope) const
|
||||||
<< "too complicated for elaboration." << endl;
|
<< "too complicated for elaboration." << endl;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (debug_elaborate) {
|
||||||
|
cerr << get_fileline() << ": debug: "
|
||||||
|
<< "Elaborating INPUT port expression: " << *tmp_expr << endl;
|
||||||
|
}
|
||||||
|
|
||||||
sig = tmp_expr->synthesize(des, scope, tmp_expr);
|
sig = tmp_expr->synthesize(des, scope, tmp_expr);
|
||||||
if (sig == 0) {
|
if (sig == 0) {
|
||||||
cerr << pins[idx]->get_fileline()
|
cerr << pins[idx]->get_fileline()
|
||||||
|
|
|
||||||
10
netenum.cc
10
netenum.cc
|
|
@ -21,6 +21,8 @@
|
||||||
# include "compiler.h"
|
# include "compiler.h"
|
||||||
# include <cassert>
|
# include <cassert>
|
||||||
|
|
||||||
|
using namespace std;
|
||||||
|
|
||||||
netenum_t::netenum_t(ivl_variable_type_t btype, bool signed_flag,
|
netenum_t::netenum_t(ivl_variable_type_t btype, bool signed_flag,
|
||||||
long msb, long lsb, size_t name_count)
|
long msb, long lsb, size_t name_count)
|
||||||
: base_type_(btype), signed_flag_(signed_flag), msb_(msb), lsb_(lsb),
|
: base_type_(btype), signed_flag_(signed_flag), msb_(msb), lsb_(lsb),
|
||||||
|
|
@ -45,6 +47,14 @@ long netenum_t::packed_width() const
|
||||||
return lsb_ - msb_ + 1;
|
return lsb_ - msb_ + 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
vector<netrange_t> netenum_t::slice_dimensions() const
|
||||||
|
{
|
||||||
|
vector<netrange_t> tmp (1);
|
||||||
|
tmp[0] = netrange_t(msb_, lsb_);
|
||||||
|
return tmp;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
bool netenum_t::insert_name(size_t name_idx, perm_string name, const verinum&val)
|
bool netenum_t::insert_name(size_t name_idx, perm_string name, const verinum&val)
|
||||||
{
|
{
|
||||||
std::pair<std::map<perm_string,verinum>::iterator, bool> res;
|
std::pair<std::map<perm_string,verinum>::iterator, bool> res;
|
||||||
|
|
|
||||||
|
|
@ -38,6 +38,7 @@ class netenum_t : public LineInfo, public ivl_type_s {
|
||||||
|
|
||||||
ivl_variable_type_t base_type() const;
|
ivl_variable_type_t base_type() const;
|
||||||
long packed_width() const;
|
long packed_width() const;
|
||||||
|
std::vector<netrange_t> slice_dimensions() const;
|
||||||
bool get_signed() const;
|
bool get_signed() const;
|
||||||
|
|
||||||
// The size() is the number of enumeration literals.
|
// The size() is the number of enumeration literals.
|
||||||
|
|
|
||||||
114
netlist.cc
114
netlist.cc
|
|
@ -29,6 +29,7 @@
|
||||||
# include "netmisc.h"
|
# include "netmisc.h"
|
||||||
# include "netdarray.h"
|
# include "netdarray.h"
|
||||||
# include "netenum.h"
|
# include "netenum.h"
|
||||||
|
# include "netparray.h"
|
||||||
# include "netstruct.h"
|
# include "netstruct.h"
|
||||||
# include "netvector.h"
|
# include "netvector.h"
|
||||||
# include "ivl_assert.h"
|
# include "ivl_assert.h"
|
||||||
|
|
@ -464,44 +465,6 @@ PortType::Enum PortType::merged( Enum lhs, Enum rhs )
|
||||||
return PINOUT;
|
return PINOUT;
|
||||||
}
|
}
|
||||||
|
|
||||||
NetNet::NetNet(NetScope*s, perm_string n, Type t, unsigned npins)
|
|
||||||
: NetObj(s, n, 1),
|
|
||||||
type_(t), port_type_(NOT_A_PORT),
|
|
||||||
local_flag_(false),
|
|
||||||
net_type_(0), discipline_(0),
|
|
||||||
eref_count_(0), lref_count_(0),
|
|
||||||
port_index_(-1)
|
|
||||||
{
|
|
||||||
assert(s);
|
|
||||||
assert(npins>0);
|
|
||||||
|
|
||||||
// Synthesize a single range to describe this canonical vector.
|
|
||||||
packed_dims_.push_back(netrange_t(npins-1, 0));
|
|
||||||
calculate_slice_widths_from_packed_dims_();
|
|
||||||
|
|
||||||
Link::DIR dir = Link::PASSIVE;
|
|
||||||
|
|
||||||
switch (t) {
|
|
||||||
case REG:
|
|
||||||
case INTEGER:
|
|
||||||
case IMPLICIT_REG:
|
|
||||||
dir = Link::OUTPUT;
|
|
||||||
break;
|
|
||||||
case SUPPLY0:
|
|
||||||
dir = Link::OUTPUT;
|
|
||||||
break;
|
|
||||||
case SUPPLY1:
|
|
||||||
dir = Link::OUTPUT;
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
pin(0).set_dir(dir);
|
|
||||||
|
|
||||||
s->add_signal(this);
|
|
||||||
}
|
|
||||||
|
|
||||||
void NetNet::initialize_dir_(Link::DIR dir)
|
void NetNet::initialize_dir_(Link::DIR dir)
|
||||||
{
|
{
|
||||||
if (pins_are_virtual()) {
|
if (pins_are_virtual()) {
|
||||||
|
|
@ -544,47 +507,35 @@ template <class T> static unsigned calculate_count(T*type)
|
||||||
|
|
||||||
void NetNet::calculate_slice_widths_from_packed_dims_(void)
|
void NetNet::calculate_slice_widths_from_packed_dims_(void)
|
||||||
{
|
{
|
||||||
netvector_t*vec = dynamic_cast<netvector_t*> (net_type_);
|
ivl_assert(*this, net_type_);
|
||||||
ivl_assert(*this, vec==0 || packed_dims_.empty());
|
slice_dims_ = net_type_->slice_dimensions();
|
||||||
|
|
||||||
const std::list<netrange_t>&use_packed = vec? vec->packed_dims() : packed_dims_;
|
// Special case: There are no actual packed dimensions, so
|
||||||
if (use_packed.empty()) {
|
// build up a fake dimension of "1".
|
||||||
slice_wids_.clear();
|
if (slice_dims_.size() == 0) {
|
||||||
|
slice_wids_.resize(1);
|
||||||
|
slice_wids_[0] = net_type_->packed_width();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
slice_wids_.resize(use_packed.size());
|
slice_wids_.resize(slice_dims_.size());
|
||||||
|
|
||||||
slice_wids_[0] = netrange_width(use_packed);
|
ivl_assert(*this, slice_wids_.size() >= 1);
|
||||||
list<netrange_t>::const_iterator cur = use_packed.begin();
|
slice_wids_[0] = netrange_width(slice_dims_);
|
||||||
|
vector<netrange_t>::const_iterator cur = slice_dims_.begin();
|
||||||
for (size_t idx = 1 ; idx < slice_wids_.size() ; idx += 1) {
|
for (size_t idx = 1 ; idx < slice_wids_.size() ; idx += 1) {
|
||||||
slice_wids_[idx] = slice_wids_[idx-1] / cur->width();
|
slice_wids_[idx] = slice_wids_[idx-1] / cur->width();
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
NetNet::NetNet(NetScope*s, perm_string n, Type t,
|
NetNet::NetNet(NetScope*s, perm_string n, Type t,
|
||||||
const list<netrange_t>&packed,
|
const list<netrange_t>&unpacked, ivl_type_s*use_net_type)
|
||||||
const list<netrange_t>&unpacked,
|
|
||||||
ivl_type_s*use_net_type)
|
|
||||||
: NetObj(s, n, calculate_count(unpacked)),
|
: NetObj(s, n, calculate_count(unpacked)),
|
||||||
type_(t), port_type_(NOT_A_PORT),
|
type_(t), port_type_(NOT_A_PORT),
|
||||||
local_flag_(false), net_type_(use_net_type),
|
local_flag_(false), net_type_(use_net_type),
|
||||||
discipline_(0), unpacked_dims_(unpacked.size()),
|
discipline_(0), unpacked_dims_(unpacked.size()),
|
||||||
eref_count_(0), lref_count_(0)
|
eref_count_(0), lref_count_(0)
|
||||||
{
|
{
|
||||||
packed_dims_ = packed;
|
|
||||||
// Special case: This is an enum, so it is its own packed vector.
|
|
||||||
if (netenum_t*et = dynamic_cast<netenum_t*>(use_net_type)) {
|
|
||||||
ivl_assert(*this, packed_dims_.empty());
|
|
||||||
packed_dims_.push_back(netrange_t(calculate_count(et)-1, 0));
|
|
||||||
}
|
|
||||||
// Special case: netstruct types are like another packed
|
|
||||||
// dimension.
|
|
||||||
if (netstruct_t*st = dynamic_cast<netstruct_t*>(use_net_type)) {
|
|
||||||
packed_dims_.push_back(netrange_t(calculate_count(st)-1, 0));
|
|
||||||
}
|
|
||||||
|
|
||||||
calculate_slice_widths_from_packed_dims_();
|
calculate_slice_widths_from_packed_dims_();
|
||||||
size_t idx = 0;
|
size_t idx = 0;
|
||||||
for (list<netrange_t>::const_iterator cur = unpacked.begin()
|
for (list<netrange_t>::const_iterator cur = unpacked.begin()
|
||||||
|
|
@ -633,7 +584,7 @@ NetNet::NetNet(NetScope*s, perm_string n, Type t, netstruct_t*ty)
|
||||||
discipline_(0),
|
discipline_(0),
|
||||||
eref_count_(0), lref_count_(0)
|
eref_count_(0), lref_count_(0)
|
||||||
{
|
{
|
||||||
packed_dims_.push_back(netrange_t(calculate_count(ty)-1, 0));
|
//XXXX packed_dims_.push_back(netrange_t(calculate_count(ty)-1, 0));
|
||||||
calculate_slice_widths_from_packed_dims_();
|
calculate_slice_widths_from_packed_dims_();
|
||||||
Link::DIR dir = Link::PASSIVE;
|
Link::DIR dir = Link::PASSIVE;
|
||||||
|
|
||||||
|
|
@ -792,16 +743,6 @@ void NetNet::set_module_port_index(unsigned idx)
|
||||||
assert( port_index_ >= 0 );
|
assert( port_index_ >= 0 );
|
||||||
}
|
}
|
||||||
|
|
||||||
const std::list<netrange_t>& NetNet::packed_dims() const
|
|
||||||
{
|
|
||||||
if (netvector_t*vec = dynamic_cast<netvector_t*> (net_type_)) {
|
|
||||||
ivl_assert(*this, packed_dims_.empty());
|
|
||||||
return vec->packed_dims();
|
|
||||||
}
|
|
||||||
|
|
||||||
return packed_dims_;
|
|
||||||
}
|
|
||||||
|
|
||||||
ivl_variable_type_t NetNet::data_type() const
|
ivl_variable_type_t NetNet::data_type() const
|
||||||
{
|
{
|
||||||
if (net_type_==0)
|
if (net_type_==0)
|
||||||
|
|
@ -839,9 +780,26 @@ netenum_t*NetNet::enumeration(void) const
|
||||||
return dynamic_cast<netenum_t*> (net_type_);
|
return dynamic_cast<netenum_t*> (net_type_);
|
||||||
}
|
}
|
||||||
|
|
||||||
netstruct_t*NetNet::struct_type(void) const
|
const netstruct_t*NetNet::struct_type(void) const
|
||||||
{
|
{
|
||||||
return dynamic_cast<netstruct_t*> (net_type_);
|
const ivl_type_s*cur_type = net_type_;
|
||||||
|
while (cur_type) {
|
||||||
|
if (const netdarray_t*da = dynamic_cast<const netdarray_t*> (cur_type)) {
|
||||||
|
cur_type = da->element_type();
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if (const netparray_t*da = dynamic_cast<const netparray_t*> (cur_type)) {
|
||||||
|
cur_type = da->element_type();
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if (const netstruct_t*st = dynamic_cast<const netstruct_t*> (cur_type))
|
||||||
|
return st;
|
||||||
|
else
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
assert(0);
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
netdarray_t* NetNet::darray_type(void) const
|
netdarray_t* NetNet::darray_type(void) const
|
||||||
|
|
@ -894,7 +852,7 @@ long NetNet::sb_to_idx(const list<long>&indices, long sb) const
|
||||||
{
|
{
|
||||||
ivl_assert(*this, indices.size()+1 == packed_dims().size());
|
ivl_assert(*this, indices.size()+1 == packed_dims().size());
|
||||||
|
|
||||||
list<netrange_t>::const_iterator pcur = packed_dims().end();
|
vector<netrange_t>::const_iterator pcur = packed_dims().end();
|
||||||
-- pcur;
|
-- pcur;
|
||||||
|
|
||||||
long acc_off;
|
long acc_off;
|
||||||
|
|
@ -2486,14 +2444,14 @@ NetNet* NetESignal::sig()
|
||||||
*/
|
*/
|
||||||
long NetESignal::lsi() const
|
long NetESignal::lsi() const
|
||||||
{
|
{
|
||||||
const list<netrange_t>&packed = net_->packed_dims();
|
const vector<netrange_t>&packed = net_->packed_dims();
|
||||||
ivl_assert(*this, packed.size() == 1);
|
ivl_assert(*this, packed.size() == 1);
|
||||||
return packed.back().get_lsb();
|
return packed.back().get_lsb();
|
||||||
}
|
}
|
||||||
|
|
||||||
long NetESignal::msi() const
|
long NetESignal::msi() const
|
||||||
{
|
{
|
||||||
const list<netrange_t>&packed = net_->packed_dims();
|
const vector<netrange_t>&packed = net_->packed_dims();
|
||||||
ivl_assert(*this, packed.size() == 1);
|
ivl_assert(*this, packed.size() == 1);
|
||||||
return packed.back().get_msb();
|
return packed.back().get_msb();
|
||||||
}
|
}
|
||||||
|
|
|
||||||
28
netlist.h
28
netlist.h
|
|
@ -597,21 +597,15 @@ class NetNet : public NetObj, public PortType {
|
||||||
typedef PortType::Enum PortType;
|
typedef PortType::Enum PortType;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
// The width in this case is a shorthand for ms=width-1 and
|
// This form is the more generic form of the constructor. For
|
||||||
// ls=0. Only one pin is created, the width is of the vector
|
// now, the unpacked type is not burried into an ivl_type_s object.
|
||||||
// that passed through.
|
|
||||||
explicit NetNet(NetScope*s, perm_string n, Type t, unsigned width =1);
|
|
||||||
|
|
||||||
// This form supports an array of vectors. The [ms:ls] define
|
|
||||||
// the base vector, and the [s0:e0] define the array
|
|
||||||
// dimensions. If s0==e0, then this is not an array after
|
|
||||||
// all.
|
|
||||||
explicit NetNet(NetScope*s, perm_string n, Type t,
|
explicit NetNet(NetScope*s, perm_string n, Type t,
|
||||||
const std::list<netrange_t>&packed,
|
|
||||||
const std::list<netrange_t>&unpacked,
|
const std::list<netrange_t>&unpacked,
|
||||||
ivl_type_s*type =0);
|
ivl_type_s*type =0);
|
||||||
|
|
||||||
// This form builds a NetNet from its record/enum definition.
|
// This form builds a NetNet from its record/enum/darray
|
||||||
|
// definition. They should probably be replaced with a single
|
||||||
|
// version that takes an ivl_type_s* base.
|
||||||
explicit NetNet(NetScope*s, perm_string n, Type t, netstruct_t*type);
|
explicit NetNet(NetScope*s, perm_string n, Type t, netstruct_t*type);
|
||||||
explicit NetNet(NetScope*s, perm_string n, Type t, netdarray_t*type);
|
explicit NetNet(NetScope*s, perm_string n, Type t, netdarray_t*type);
|
||||||
explicit NetNet(NetScope*s, perm_string n, Type t, netvector_t*type);
|
explicit NetNet(NetScope*s, perm_string n, Type t, netvector_t*type);
|
||||||
|
|
@ -643,7 +637,7 @@ class NetNet : public NetObj, public PortType {
|
||||||
|
|
||||||
inline const ivl_type_s* net_type(void) const { return net_type_; }
|
inline const ivl_type_s* net_type(void) const { return net_type_; }
|
||||||
netenum_t*enumeration(void) const;
|
netenum_t*enumeration(void) const;
|
||||||
netstruct_t*struct_type(void) const;
|
const netstruct_t*struct_type(void) const;
|
||||||
netdarray_t*darray_type(void) const;
|
netdarray_t*darray_type(void) const;
|
||||||
|
|
||||||
/* Attach a discipline to the net. */
|
/* Attach a discipline to the net. */
|
||||||
|
|
@ -653,8 +647,9 @@ class NetNet : public NetObj, public PortType {
|
||||||
/* This method returns a reference to the packed dimensions
|
/* This method returns a reference to the packed dimensions
|
||||||
for the vector. These are arranged as a list where the
|
for the vector. These are arranged as a list where the
|
||||||
first range in the list (front) is the left-most range in
|
first range in the list (front) is the left-most range in
|
||||||
the verilog declaration. */
|
the verilog declaration. These packed dims are compressed
|
||||||
const std::list<netrange_t>& packed_dims() const;
|
to represent the dimensions of all the subtypes. */
|
||||||
|
const std::vector<netrange_t>& packed_dims() const { return slice_dims_; }
|
||||||
|
|
||||||
const std::vector<netrange_t>& unpacked_dims() const { return unpacked_dims_; }
|
const std::vector<netrange_t>& unpacked_dims() const { return unpacked_dims_; }
|
||||||
|
|
||||||
|
|
@ -694,7 +689,7 @@ class NetNet : public NetObj, public PortType {
|
||||||
|
|
||||||
/* This methor returns 0 for scalars, but vectors and other
|
/* This methor returns 0 for scalars, but vectors and other
|
||||||
PACKED arrays have packed dimensions. */
|
PACKED arrays have packed dimensions. */
|
||||||
inline size_t packed_dimensions() const { return packed_dims_.size(); }
|
inline size_t packed_dimensions() const { return slice_dims_.size(); }
|
||||||
|
|
||||||
// This is the number of array elements.
|
// This is the number of array elements.
|
||||||
unsigned unpacked_count() const;
|
unsigned unpacked_count() const;
|
||||||
|
|
@ -733,7 +728,6 @@ class NetNet : public NetObj, public PortType {
|
||||||
ivl_type_s*net_type_;
|
ivl_type_s*net_type_;
|
||||||
ivl_discipline_t discipline_;
|
ivl_discipline_t discipline_;
|
||||||
|
|
||||||
std::list<netrange_t> packed_dims_;
|
|
||||||
std::vector<netrange_t> unpacked_dims_;
|
std::vector<netrange_t> unpacked_dims_;
|
||||||
|
|
||||||
// These are the widths of the various slice depths. There is
|
// These are the widths of the various slice depths. There is
|
||||||
|
|
@ -742,6 +736,7 @@ class NetNet : public NetObj, public PortType {
|
||||||
//
|
//
|
||||||
// For example: slice_wids_[0] is vector_width().
|
// For example: slice_wids_[0] is vector_width().
|
||||||
void calculate_slice_widths_from_packed_dims_(void);
|
void calculate_slice_widths_from_packed_dims_(void);
|
||||||
|
std::vector<netrange_t> slice_dims_;
|
||||||
std::vector<unsigned long> slice_wids_;
|
std::vector<unsigned long> slice_wids_;
|
||||||
|
|
||||||
unsigned eref_count_;
|
unsigned eref_count_;
|
||||||
|
|
@ -756,7 +751,6 @@ class NetNet : public NetObj, public PortType {
|
||||||
int port_index_;
|
int port_index_;
|
||||||
};
|
};
|
||||||
|
|
||||||
extern std::ostream&operator << (std::ostream&out, const std::list<netrange_t>&rlist);
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* This object type is used to contain a logical scope within a
|
* This object type is used to contain a logical scope within a
|
||||||
|
|
|
||||||
12
netmisc.cc
12
netmisc.cc
|
|
@ -353,7 +353,7 @@ NetExpr *normalize_variable_base(NetExpr *base,
|
||||||
NetExpr *normalize_variable_bit_base(const list<long>&indices, NetExpr*base,
|
NetExpr *normalize_variable_bit_base(const list<long>&indices, NetExpr*base,
|
||||||
const NetNet*reg)
|
const NetNet*reg)
|
||||||
{
|
{
|
||||||
const list<netrange_t>&packed_dims = reg->packed_dims();
|
const vector<netrange_t>&packed_dims = reg->packed_dims();
|
||||||
ivl_assert(*base, indices.size()+1 == packed_dims.size());
|
ivl_assert(*base, indices.size()+1 == packed_dims.size());
|
||||||
|
|
||||||
// Get the canonical offset of the slice within which we are
|
// Get the canonical offset of the slice within which we are
|
||||||
|
|
@ -369,7 +369,7 @@ NetExpr *normalize_variable_part_base(const list<long>&indices, NetExpr*base,
|
||||||
const NetNet*reg,
|
const NetNet*reg,
|
||||||
unsigned long wid, bool is_up)
|
unsigned long wid, bool is_up)
|
||||||
{
|
{
|
||||||
const list<netrange_t>&packed_dims = reg->packed_dims();
|
const vector<netrange_t>&packed_dims = reg->packed_dims();
|
||||||
ivl_assert(*base, indices.size()+1 == packed_dims.size());
|
ivl_assert(*base, indices.size()+1 == packed_dims.size());
|
||||||
|
|
||||||
// Get the canonical offset of the slice within which we are
|
// Get the canonical offset of the slice within which we are
|
||||||
|
|
@ -384,10 +384,10 @@ NetExpr *normalize_variable_part_base(const list<long>&indices, NetExpr*base,
|
||||||
NetExpr *normalize_variable_slice_base(const list<long>&indices, NetExpr*base,
|
NetExpr *normalize_variable_slice_base(const list<long>&indices, NetExpr*base,
|
||||||
const NetNet*reg, unsigned long&lwid)
|
const NetNet*reg, unsigned long&lwid)
|
||||||
{
|
{
|
||||||
const list<netrange_t>&packed_dims = reg->packed_dims();
|
const vector<netrange_t>&packed_dims = reg->packed_dims();
|
||||||
ivl_assert(*base, indices.size() < packed_dims.size());
|
ivl_assert(*base, indices.size() < packed_dims.size());
|
||||||
|
|
||||||
list<netrange_t>::const_iterator pcur = packed_dims.end();
|
vector<netrange_t>::const_iterator pcur = packed_dims.end();
|
||||||
for (size_t idx = indices.size() ; idx < packed_dims.size(); idx += 1) {
|
for (size_t idx = indices.size() ; idx < packed_dims.size(); idx += 1) {
|
||||||
-- pcur;
|
-- pcur;
|
||||||
}
|
}
|
||||||
|
|
@ -1182,8 +1182,8 @@ NetExpr*collapse_array_exprs(Design*des, NetScope*scope,
|
||||||
return *exprs.begin();
|
return *exprs.begin();
|
||||||
}
|
}
|
||||||
|
|
||||||
const std::list<netrange_t>&pdims = net->packed_dims();
|
const std::vector<netrange_t>&pdims = net->packed_dims();
|
||||||
std::list<netrange_t>::const_iterator pcur = pdims.begin();
|
std::vector<netrange_t>::const_iterator pcur = pdims.begin();
|
||||||
|
|
||||||
list<NetExpr*>::iterator ecur = exprs.begin();
|
list<NetExpr*>::iterator ecur = exprs.begin();
|
||||||
NetExpr* base = 0;
|
NetExpr* base = 0;
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,58 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2012 Picture Elements, Inc.
|
||||||
|
* Stephen Williams (steve@icarus.com)
|
||||||
|
*
|
||||||
|
* This source code is free software; you can redistribute it
|
||||||
|
* and/or modify it in source code form under the terms of the GNU
|
||||||
|
* General Public License as published by the Free Software
|
||||||
|
* Foundation; either version 2 of the License, or (at your option)
|
||||||
|
* any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program; if not, write to the Free Software
|
||||||
|
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||||
|
*/
|
||||||
|
|
||||||
|
# include "netparray.h"
|
||||||
|
|
||||||
|
using namespace std;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* The packed width of a packed array is the packed width of the
|
||||||
|
* element times the dimension width of the array itself.
|
||||||
|
*/
|
||||||
|
long netparray_t::packed_width(void) const
|
||||||
|
{
|
||||||
|
long cur_width = element_type_->packed_width();
|
||||||
|
|
||||||
|
for (vector<netrange_t>::const_iterator cur = packed_dims_.begin()
|
||||||
|
; cur != packed_dims_.end() ; ++cur) {
|
||||||
|
cur_width *= cur->width();
|
||||||
|
}
|
||||||
|
|
||||||
|
return cur_width;
|
||||||
|
}
|
||||||
|
|
||||||
|
vector<netrange_t> netparray_t::slice_dimensions() const
|
||||||
|
{
|
||||||
|
vector<netrange_t> elem_dims = element_type_->slice_dimensions();
|
||||||
|
|
||||||
|
vector<netrange_t> res (packed_dims_.size() + elem_dims.size());
|
||||||
|
|
||||||
|
for (size_t idx = 0 ; idx < packed_dims_.size() ; idx += 1)
|
||||||
|
res[idx] = packed_dims_[0];
|
||||||
|
for (size_t idx = 0 ; idx < elem_dims.size() ; idx += 1)
|
||||||
|
res[idx+packed_dims_.size()] = elem_dims[idx];
|
||||||
|
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
|
ivl_variable_type_t netparray_t::base_type() const
|
||||||
|
{
|
||||||
|
return element_type_->base_type();
|
||||||
|
}
|
||||||
25
netparray.h
25
netparray.h
|
|
@ -20,29 +20,40 @@
|
||||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
||||||
*/
|
*/
|
||||||
|
|
||||||
# include "LineInfo.h"
|
|
||||||
# include "nettypes.h"
|
# include "nettypes.h"
|
||||||
# include <vector>
|
# include <vector>
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Packed arrays.
|
* Packed arrays.
|
||||||
*/
|
*/
|
||||||
class netparray_t : public ivl_type_s, public LineInfo {
|
class netparray_t : public ivl_type_s {
|
||||||
|
|
||||||
public:
|
public:
|
||||||
explicit netparray_t(const std::list<netrange_t>&packed);
|
explicit netparray_t(const std::vector<netrange_t>&packed,
|
||||||
|
ivl_type_t etype);
|
||||||
~netparray_t();
|
~netparray_t();
|
||||||
|
|
||||||
inline const std::list<netrange_t>& packed_dimensions() const
|
public:
|
||||||
|
// Virtual methods from the ivl_type_s type...
|
||||||
|
long packed_width(void) const;
|
||||||
|
std::vector<netrange_t> slice_dimensions() const;
|
||||||
|
ivl_variable_type_t base_type() const;
|
||||||
|
|
||||||
|
public:
|
||||||
|
inline const ivl_type_s* element_type() const { return element_type_; }
|
||||||
|
|
||||||
|
inline const std::vector<netrange_t>& packed_dimensions() const
|
||||||
{ return packed_dims_; }
|
{ return packed_dims_; }
|
||||||
|
|
||||||
private:
|
private:
|
||||||
std::list<netrange_t> packed_dims_;
|
std::vector<netrange_t> packed_dims_;
|
||||||
|
ivl_type_t element_type_;
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
inline netparray_t::netparray_t(const std::list<netrange_t>&packed)
|
inline netparray_t::netparray_t(const std::vector<netrange_t>&packed,
|
||||||
: packed_dims_(packed)
|
ivl_type_t etype)
|
||||||
|
: packed_dims_(packed), element_type_(etype)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -67,6 +67,13 @@ long netstruct_t::packed_width(void) const
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
vector<netrange_t> netstruct_t::slice_dimensions() const
|
||||||
|
{
|
||||||
|
vector<netrange_t> tmp;
|
||||||
|
tmp .push_back(netrange_t(packed_width()-1, 0));
|
||||||
|
return tmp;
|
||||||
|
}
|
||||||
|
|
||||||
ivl_variable_type_t netstruct_t::base_type() const
|
ivl_variable_type_t netstruct_t::base_type() const
|
||||||
{
|
{
|
||||||
if (! packed_)
|
if (! packed_)
|
||||||
|
|
|
||||||
|
|
@ -20,7 +20,7 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
# include "LineInfo.h"
|
# include "LineInfo.h"
|
||||||
# include <vector>
|
# include <vector>
|
||||||
# include "ivl_target.h"
|
# include "ivl_target.h"
|
||||||
# include "nettypes.h"
|
# include "nettypes.h"
|
||||||
|
|
||||||
|
|
@ -30,7 +30,7 @@ class netstruct_t : public LineInfo, public ivl_type_s {
|
||||||
struct member_t {
|
struct member_t {
|
||||||
perm_string name;
|
perm_string name;
|
||||||
ivl_variable_type_t type;
|
ivl_variable_type_t type;
|
||||||
list<netrange_t> packed_dims;
|
std::vector<netrange_t> packed_dims;
|
||||||
long width() const;
|
long width() const;
|
||||||
ivl_variable_type_t data_type() const { return type; };
|
ivl_variable_type_t data_type() const { return type; };
|
||||||
// We need to keep the individual element sign information.
|
// We need to keep the individual element sign information.
|
||||||
|
|
@ -54,6 +54,7 @@ class netstruct_t : public LineInfo, public ivl_type_s {
|
||||||
// Return the width (in bits) of the packed record, or -1 if
|
// Return the width (in bits) of the packed record, or -1 if
|
||||||
// the record is not packed.
|
// the record is not packed.
|
||||||
long packed_width() const;
|
long packed_width() const;
|
||||||
|
std::vector<netrange_t> slice_dimensions() const;
|
||||||
|
|
||||||
// Return the base type of the packed record, or
|
// Return the base type of the packed record, or
|
||||||
// IVL_VT_NO_TYPE if the record is not packed.
|
// IVL_VT_NO_TYPE if the record is not packed.
|
||||||
|
|
|
||||||
13
nettypes.cc
13
nettypes.cc
|
|
@ -31,6 +31,11 @@ long ivl_type_s::packed_width(void) const
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
vector<netrange_t> ivl_type_s::slice_dimensions() const
|
||||||
|
{
|
||||||
|
return vector<netrange_t>();
|
||||||
|
}
|
||||||
|
|
||||||
ivl_variable_type_t ivl_type_s::base_type() const
|
ivl_variable_type_t ivl_type_s::base_type() const
|
||||||
{
|
{
|
||||||
return IVL_VT_NO_TYPE;
|
return IVL_VT_NO_TYPE;
|
||||||
|
|
@ -41,10 +46,10 @@ bool ivl_type_s::get_signed() const
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
unsigned long netrange_width(const list<netrange_t>&packed)
|
unsigned long netrange_width(const vector<netrange_t>&packed)
|
||||||
{
|
{
|
||||||
unsigned wid = 1;
|
unsigned wid = 1;
|
||||||
for (list<netrange_t>::const_iterator cur = packed.begin()
|
for (vector<netrange_t>::const_iterator cur = packed.begin()
|
||||||
; cur != packed.end() ; ++cur) {
|
; cur != packed.end() ; ++cur) {
|
||||||
unsigned use_wid = cur->width();
|
unsigned use_wid = cur->width();
|
||||||
wid *= use_wid;
|
wid *= use_wid;
|
||||||
|
|
@ -59,14 +64,14 @@ unsigned long netrange_width(const list<netrange_t>&packed)
|
||||||
* and width of the resulting slice. In this case, the "sb" argument
|
* and width of the resulting slice. In this case, the "sb" argument
|
||||||
* is an extra index of the prefix.
|
* is an extra index of the prefix.
|
||||||
*/
|
*/
|
||||||
bool prefix_to_slice(const std::list<netrange_t>&dims,
|
bool prefix_to_slice(const std::vector<netrange_t>&dims,
|
||||||
const std::list<long>&prefix, long sb,
|
const std::list<long>&prefix, long sb,
|
||||||
long&loff, unsigned long&lwid)
|
long&loff, unsigned long&lwid)
|
||||||
{
|
{
|
||||||
assert(prefix.size() < dims.size());
|
assert(prefix.size() < dims.size());
|
||||||
|
|
||||||
size_t acc_wid = 1;
|
size_t acc_wid = 1;
|
||||||
list<netrange_t>::const_iterator pcur = dims.end();
|
vector<netrange_t>::const_iterator pcur = dims.end();
|
||||||
for (size_t idx = prefix.size()+1 ; idx < dims.size() ; idx += 1) {
|
for (size_t idx = prefix.size()+1 ; idx < dims.size() ; idx += 1) {
|
||||||
-- pcur;
|
-- pcur;
|
||||||
acc_wid *= pcur->width();
|
acc_wid *= pcur->width();
|
||||||
|
|
|
||||||
19
nettypes.h
19
nettypes.h
|
|
@ -20,10 +20,13 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
# include "ivl_target.h"
|
# include "ivl_target.h"
|
||||||
# include <list>
|
# include <list>
|
||||||
# include <climits>
|
# include <vector>
|
||||||
# include <ostream>
|
# include <climits>
|
||||||
# include <cassert>
|
# include <ostream>
|
||||||
|
# include <cassert>
|
||||||
|
|
||||||
|
class netrange_t;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* This is a fully abstract type that is a type that can be attached
|
* This is a fully abstract type that is a type that can be attached
|
||||||
|
|
@ -33,6 +36,7 @@ class ivl_type_s {
|
||||||
public:
|
public:
|
||||||
virtual ~ivl_type_s() =0;
|
virtual ~ivl_type_s() =0;
|
||||||
virtual long packed_width(void) const;
|
virtual long packed_width(void) const;
|
||||||
|
virtual std::vector<netrange_t> slice_dimensions() const;
|
||||||
|
|
||||||
// Some types have a base variable type.
|
// Some types have a base variable type.
|
||||||
virtual ivl_variable_type_t base_type() const;
|
virtual ivl_variable_type_t base_type() const;
|
||||||
|
|
@ -78,14 +82,17 @@ class netrange_t {
|
||||||
long lsb_;
|
long lsb_;
|
||||||
};
|
};
|
||||||
|
|
||||||
extern unsigned long netrange_width(const std::list<netrange_t>&dims);
|
extern std::ostream&operator << (std::ostream&out, const std::list<netrange_t>&rlist);
|
||||||
|
extern std::ostream&operator << (std::ostream&out, const std::vector<netrange_t>&rlist);
|
||||||
|
|
||||||
|
extern unsigned long netrange_width(const std::vector<netrange_t>&dims);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Take as input a list of packed dimensions and a list of prefix
|
* Take as input a list of packed dimensions and a list of prefix
|
||||||
* indices, and calculate the offset/width of the resulting slice into
|
* indices, and calculate the offset/width of the resulting slice into
|
||||||
* the packed array.
|
* the packed array.
|
||||||
*/
|
*/
|
||||||
extern bool prefix_to_slice(const std::list<netrange_t>&dims,
|
extern bool prefix_to_slice(const std::vector<netrange_t>&dims,
|
||||||
const std::list<long>&prefix, long sb,
|
const std::list<long>&prefix, long sb,
|
||||||
long&loff, unsigned long&lwid);
|
long&loff, unsigned long&lwid);
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -19,6 +19,8 @@
|
||||||
|
|
||||||
# include "netvector.h"
|
# include "netvector.h"
|
||||||
|
|
||||||
|
using namespace std;
|
||||||
|
|
||||||
netvector_t::netvector_t(ivl_variable_type_t type, long msb, long lsb)
|
netvector_t::netvector_t(ivl_variable_type_t type, long msb, long lsb)
|
||||||
: type_(type), signed_(false)
|
: type_(type), signed_(false)
|
||||||
{
|
{
|
||||||
|
|
@ -43,3 +45,8 @@ long netvector_t::packed_width() const
|
||||||
{
|
{
|
||||||
return netrange_width(packed_dims_);
|
return netrange_width(packed_dims_);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
vector<netrange_t> netvector_t::slice_dimensions() const
|
||||||
|
{
|
||||||
|
return packed_dims_;
|
||||||
|
}
|
||||||
|
|
|
||||||
15
netvector.h
15
netvector.h
|
|
@ -26,6 +26,12 @@
|
||||||
class netvector_t : public ivl_type_s {
|
class netvector_t : public ivl_type_s {
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
explicit netvector_t(const std::vector<netrange_t>&packed,
|
||||||
|
ivl_variable_type_t type);
|
||||||
|
|
||||||
|
// This is a variant of the vector form. Some code processes
|
||||||
|
// the list of packed ranges as a list, but we will store them
|
||||||
|
// as a vector in this constructor.
|
||||||
explicit netvector_t(const std::list<netrange_t>&packed,
|
explicit netvector_t(const std::list<netrange_t>&packed,
|
||||||
ivl_variable_type_t type);
|
ivl_variable_type_t type);
|
||||||
|
|
||||||
|
|
@ -51,27 +57,28 @@ class netvector_t : public ivl_type_s {
|
||||||
inline bool get_scalar(void) const { return is_scalar_; }
|
inline bool get_scalar(void) const { return is_scalar_; }
|
||||||
|
|
||||||
ivl_variable_type_t base_type() const;
|
ivl_variable_type_t base_type() const;
|
||||||
const std::list<netrange_t>&packed_dims() const;
|
const std::vector<netrange_t>&packed_dims() const;
|
||||||
|
|
||||||
long packed_width() const;
|
long packed_width() const;
|
||||||
|
std::vector<netrange_t> slice_dimensions() const;
|
||||||
|
|
||||||
std::ostream& debug_dump(std::ostream&) const;
|
std::ostream& debug_dump(std::ostream&) const;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
std::list<netrange_t> packed_dims_;
|
std::vector<netrange_t> packed_dims_;
|
||||||
ivl_variable_type_t type_;
|
ivl_variable_type_t type_;
|
||||||
bool signed_ : 1;
|
bool signed_ : 1;
|
||||||
bool isint_ : 1; // original type of integer
|
bool isint_ : 1; // original type of integer
|
||||||
bool is_scalar_ : 1;
|
bool is_scalar_ : 1;
|
||||||
};
|
};
|
||||||
|
|
||||||
inline netvector_t::netvector_t(const std::list<netrange_t>&packed,
|
inline netvector_t::netvector_t(const std::vector<netrange_t>&packed,
|
||||||
ivl_variable_type_t type)
|
ivl_variable_type_t type)
|
||||||
: packed_dims_(packed), type_(type), signed_(false)
|
: packed_dims_(packed), type_(type), signed_(false)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
inline const std::list<netrange_t>& netvector_t::packed_dims() const
|
inline const std::vector<netrange_t>& netvector_t::packed_dims() const
|
||||||
{
|
{
|
||||||
return packed_dims_;
|
return packed_dims_;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
2
t-dll.cc
2
t-dll.cc
|
|
@ -2374,7 +2374,7 @@ void dll_target::signal(const NetNet*net)
|
||||||
ivl_signal_t object. */
|
ivl_signal_t object. */
|
||||||
|
|
||||||
{ size_t idx = 0;
|
{ size_t idx = 0;
|
||||||
list<netrange_t>::const_iterator cur;
|
vector<netrange_t>::const_iterator cur;
|
||||||
obj->packed_dims.resize(net->packed_dims().size());
|
obj->packed_dims.resize(net->packed_dims().size());
|
||||||
for (cur = net->packed_dims().begin(), idx = 0
|
for (cur = net->packed_dims().begin(), idx = 0
|
||||||
; cur != net->packed_dims().end() ; ++cur, idx += 1) {
|
; cur != net->packed_dims().end() ; ++cur, idx += 1) {
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue