Merge branch 'x-mil4'
Conflicts: tgt-vvp/eval_real.c vvp/codes.h vvp/compile.cc vvp/opcodes.txt
This commit is contained in:
commit
559d965681
|
|
@ -108,8 +108,8 @@ 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 \
|
||||
load_module.o netlist.o netmisc.o nettypes.o net_analog.o net_assign.o \
|
||||
net_design.o netdarray.o \
|
||||
netenum.o netstruct.o net_event.o net_expr.o net_func.o net_func_eval.o \
|
||||
net_link.o net_modulo.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_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 \
|
||||
pform_disciplines.o pform_dump.o pform_package.o pform_pclass.o \
|
||||
|
|
|
|||
9
PExpr.h
9
PExpr.h
|
|
@ -121,6 +121,13 @@ class PExpr : public LineInfo {
|
|||
// to be propagated down to any context-dependant operands.
|
||||
void cast_signed(bool flag) { signed_flag_ = flag; }
|
||||
|
||||
// This is the more generic form of the elaborate_expr method
|
||||
// below. The plan is to replace the simpler elaborate_expr
|
||||
// method with this version, which can handle more advanced
|
||||
// types. But for now, this is only implemented in special cases.
|
||||
virtual NetExpr*elaborate_expr(Design*des, NetScope*scope,
|
||||
ivl_type_t type, unsigned flags) const;
|
||||
|
||||
// Procedural elaboration of the expression. The expr_width is
|
||||
// the required width of the expression.
|
||||
//
|
||||
|
|
@ -450,6 +457,8 @@ class PENew : public PExpr {
|
|||
virtual void dump(ostream&) const;
|
||||
virtual unsigned test_width(Design*des, NetScope*scope,
|
||||
width_mode_t&mode);
|
||||
virtual NetExpr*elaborate_expr(Design*des, NetScope*scope,
|
||||
ivl_type_t type, unsigned flags) const;
|
||||
virtual NetExpr*elaborate_expr(Design*des, NetScope*,
|
||||
unsigned expr_wid,
|
||||
unsigned flags) const;
|
||||
|
|
|
|||
|
|
@ -106,6 +106,7 @@ class PAssign_ : public Statement {
|
|||
NetAssign_* elaborate_lval(Design*, NetScope*scope) const;
|
||||
NetExpr* elaborate_rval_(Design*, NetScope*, unsigned lv_width,
|
||||
ivl_variable_type_t type) const;
|
||||
NetExpr* elaborate_rval_(Design*, NetScope*, ivl_type_t ntype) const;
|
||||
|
||||
NetExpr* elaborate_rval_obj_(Design*, NetScope*,
|
||||
ivl_variable_type_t type) const;
|
||||
|
|
|
|||
|
|
@ -29,6 +29,7 @@
|
|||
# include "compiler.h"
|
||||
# include "discipline.h"
|
||||
# include "netdarray.h"
|
||||
# include "netvector.h"
|
||||
# include "ivl_assert.h"
|
||||
# include "PExpr.h"
|
||||
|
||||
|
|
@ -140,6 +141,24 @@ ostream& operator << (ostream&o, ivl_switch_type_t val)
|
|||
return o;
|
||||
}
|
||||
|
||||
ostream& ivl_type_s::debug_dump(ostream&o) const
|
||||
{
|
||||
o << typeid(*this).name();
|
||||
return o;
|
||||
}
|
||||
|
||||
ostream& netdarray_t::debug_dump(ostream&o) const
|
||||
{
|
||||
o << "dynamic array of " << *element_type();
|
||||
return o;
|
||||
}
|
||||
|
||||
ostream& netvector_t::debug_dump(ostream&o) const
|
||||
{
|
||||
o << type_ << (signed_? " signed" : " unsigned") << packed_dims_;
|
||||
return o;
|
||||
}
|
||||
|
||||
static inline void dump_scope_path(ostream&o, const NetScope*scope)
|
||||
{
|
||||
const NetScope*parent = scope->parent();
|
||||
|
|
@ -230,14 +249,9 @@ void NetNet::dump_net(ostream&o, unsigned ind) const
|
|||
{
|
||||
o << setw(ind) << "" << type() << ": " << name()
|
||||
<< unpacked_dims_ << " unpacked dims=" << unpacked_dimensions();
|
||||
if (!packed_dims_.empty())
|
||||
o << " packed dims=" << packed_dims_;
|
||||
o << " pin_count=" << pin_count();
|
||||
if (local_flag_)
|
||||
o << " (local)";
|
||||
o << " " << data_type_;
|
||||
if (signed_)
|
||||
o << " signed";
|
||||
switch (port_type_) {
|
||||
case NetNet::NOT_A_PORT:
|
||||
break;
|
||||
|
|
@ -261,14 +275,7 @@ void NetNet::dump_net(ostream&o, unsigned ind) const
|
|||
if (ivl_discipline_t dis = get_discipline())
|
||||
o << " discipline=" << dis->name();
|
||||
|
||||
if (netdarray_t*darray = darray_type())
|
||||
o << " dynamic array of " << darray->data_type();
|
||||
|
||||
if (! packed_dims_.empty())
|
||||
o << " packed dims: " << packed_dims_;
|
||||
|
||||
if (net_type_)
|
||||
o << " net_type_=" << typeid(*net_type_).name();
|
||||
if (net_type_) o << " " << *net_type_;
|
||||
|
||||
o << " (eref=" << peek_eref() << ", lref=" << peek_lref() << ")";
|
||||
if (scope())
|
||||
|
|
@ -1098,7 +1105,7 @@ void NetFuncDef::dump(ostream&o, unsigned ind) const
|
|||
if (result_sig_) {
|
||||
o << setw(ind+2) << "" << "Return signal: ";
|
||||
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: ";
|
||||
if (port_count() == 0) o << "<none>";
|
||||
|
|
@ -1120,7 +1127,7 @@ void NetFuncDef::dump(ostream&o, unsigned ind) const
|
|||
break;
|
||||
}
|
||||
if (port(idx)->get_signed()) o << "+";
|
||||
o << port(idx)->name() << port(idx)->packed_dims() << endl;
|
||||
o << port(idx)->name() << endl;
|
||||
}
|
||||
if (statement_)
|
||||
statement_->dump(o, ind+2);
|
||||
|
|
@ -1520,7 +1527,14 @@ void NetESelect::dump(ostream&o) const
|
|||
else
|
||||
o << "(0)";
|
||||
|
||||
o << "+:" << expr_width() << "]>";
|
||||
o << "+:" << expr_width() << "]";
|
||||
if (ivl_type_t nt = net_type()) {
|
||||
o << " net_type=(" << *nt << ")";
|
||||
} else {
|
||||
o << " expr_type=" << expr_type();
|
||||
}
|
||||
|
||||
o << ">";
|
||||
}
|
||||
|
||||
void NetESFunc::dump(ostream&o) const
|
||||
|
|
@ -1539,7 +1553,8 @@ void NetESignal::dump(ostream&o) const
|
|||
o << "+";
|
||||
o << name();
|
||||
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
|
||||
|
|
|
|||
53
elab_expr.cc
53
elab_expr.cc
|
|
@ -27,6 +27,7 @@
|
|||
# include "pform.h"
|
||||
# include "netlist.h"
|
||||
# include "netenum.h"
|
||||
# include "netvector.h"
|
||||
# include "discipline.h"
|
||||
# include "netmisc.h"
|
||||
# include "netdarray.h"
|
||||
|
|
@ -130,6 +131,17 @@ unsigned PExpr::test_width(Design*des, NetScope*, width_mode_t&)
|
|||
return 1;
|
||||
}
|
||||
|
||||
NetExpr* PExpr::elaborate_expr(Design*des, NetScope*, ivl_type_t, unsigned) const
|
||||
{
|
||||
cerr << get_fileline() << ": internal error: I do not know how to"
|
||||
<< " elaborate (ivl_type_t) this expression. " << endl;
|
||||
cerr << get_fileline() << ": : Expression is: " << *this
|
||||
<< endl;
|
||||
des->errors += 1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
NetExpr* PExpr::elaborate_expr(Design*des, NetScope*, unsigned, unsigned) const
|
||||
{
|
||||
cerr << get_fileline() << ": internal error: I do not know how to"
|
||||
|
|
@ -1480,7 +1492,7 @@ static const netstruct_t::member_t*get_struct_member(const LineInfo*li,
|
|||
perm_string method_name,
|
||||
unsigned long&off)
|
||||
{
|
||||
netstruct_t*type = net->struct_type();
|
||||
const netstruct_t*type = net->struct_type();
|
||||
ivl_assert(*li, type);
|
||||
|
||||
if (! type->packed()) {
|
||||
|
|
@ -2354,8 +2366,8 @@ unsigned PEIdent::test_width(Design*des, NetScope*scope, width_mode_t&mode)
|
|||
|
||||
if (netdarray_t*darray = net? net->darray_type() : 0) {
|
||||
if (use_sel == index_component_t::SEL_BIT) {
|
||||
expr_type_ = darray->data_type();
|
||||
expr_width_ = darray->vector_width();
|
||||
expr_type_ = darray->element_base_type();
|
||||
expr_width_ = darray->element_width();
|
||||
min_width_ = expr_width_;
|
||||
signed_flag_ = net->get_signed();
|
||||
} else {
|
||||
|
|
@ -2382,6 +2394,10 @@ unsigned PEIdent::test_width(Design*des, NetScope*scope, width_mode_t&mode)
|
|||
expr_width_ = net->vector_width();
|
||||
min_width_ = expr_width_;
|
||||
signed_flag_ = net->get_signed();
|
||||
if (debug_elaborate) {
|
||||
cerr << get_fileline() << ": PEIdent::test_width: "
|
||||
<< net->name() << " is a net, width=" << expr_width_ << endl;
|
||||
}
|
||||
return expr_width_;
|
||||
}
|
||||
|
||||
|
|
@ -3550,7 +3566,7 @@ NetExpr* PEIdent::elaborate_expr_net_idx_up_(Design*des, NetScope*scope,
|
|||
long lsv = base_c->value().as_long();
|
||||
long offset = 0;
|
||||
// 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);
|
||||
|
||||
// We want the last range, which is where we work.
|
||||
|
|
@ -3744,7 +3760,7 @@ NetExpr* PEIdent::elaborate_expr_net_bit_(Design*des, NetScope*scope,
|
|||
cerr << get_fileline() << ": debug: "
|
||||
<< "Bit select of a dynamic array becomes NetESelect." << endl;
|
||||
}
|
||||
NetESelect*res = new NetESelect(net, mux, darray->vector_width());
|
||||
NetESelect*res = new NetESelect(net, mux, darray->element_width());
|
||||
res->set_line(*net);
|
||||
return res;
|
||||
}
|
||||
|
|
@ -3779,7 +3795,7 @@ NetExpr* PEIdent::elaborate_expr_net_bit_(Design*des, NetScope*scope,
|
|||
|
||||
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()) {
|
||||
// Special case: this is a slice of a multi-dimensional
|
||||
// packed array. For example:
|
||||
|
|
@ -3872,7 +3888,7 @@ NetExpr* PEIdent::elaborate_expr_net_bit_(Design*des, NetScope*scope,
|
|||
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()) {
|
||||
// Special case: this is a slice of a multi-dimensional
|
||||
// packed array. For example:
|
||||
|
|
@ -3965,7 +3981,7 @@ NetExpr* PEIdent::elaborate_expr_net(Design*des, NetScope*scope,
|
|||
return node;
|
||||
}
|
||||
|
||||
unsigned PENew::test_width(Design*des, NetScope*, width_mode_t&)
|
||||
unsigned PENew::test_width(Design*, NetScope*, width_mode_t&)
|
||||
{
|
||||
expr_type_ = IVL_VT_DARRAY;
|
||||
expr_width_ = 1;
|
||||
|
|
@ -3974,6 +3990,23 @@ unsigned PENew::test_width(Design*des, NetScope*, width_mode_t&)
|
|||
return 1;
|
||||
}
|
||||
|
||||
NetExpr* PENew::elaborate_expr(Design*des, NetScope*scope,
|
||||
ivl_type_t ntype, unsigned flags) const
|
||||
{
|
||||
// Elaborate the size expression.
|
||||
width_mode_t mode = LOSSLESS;
|
||||
unsigned use_wid = size_->test_width(des, scope, mode);
|
||||
NetExpr*size = size_->elaborate_expr(des, scope, use_wid, flags);
|
||||
|
||||
NetESFunc*tmp = new NetESFunc("$ivl_darray_method$new", ntype, 1);
|
||||
tmp->set_line(*this);
|
||||
tmp->parm(0, size);
|
||||
return tmp;
|
||||
}
|
||||
|
||||
/*
|
||||
* This method should never actually be called.
|
||||
*/
|
||||
NetExpr* PENew::elaborate_expr(Design*des, NetScope*scope,
|
||||
unsigned, unsigned flags) const
|
||||
{
|
||||
|
|
@ -4503,9 +4536,9 @@ NetNet* Design::find_discipline_reference(ivl_discipline_t dis, NetScope*scope)
|
|||
if (gnd) return gnd;
|
||||
|
||||
string name = string(dis->name()) + "$gnd";
|
||||
gnd = new NetNet(scope, lex_strings.make(name), NetNet::WIRE, 1);
|
||||
netvector_t*gnd_vec = new netvector_t(IVL_VT_REAL,0,0);
|
||||
gnd = new NetNet(scope, lex_strings.make(name), NetNet::WIRE, gnd_vec);
|
||||
gnd->set_discipline(dis);
|
||||
gnd->data_type(IVL_VT_REAL);
|
||||
discipline_references_[dis->name()] = gnd;
|
||||
|
||||
if (debug_elaborate)
|
||||
|
|
|
|||
|
|
@ -507,7 +507,7 @@ bool PEIdent::elaborate_lval_net_part_(Design*des,
|
|||
NetNet*reg = lv->sig();
|
||||
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
|
||||
// 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 offset = 0;
|
||||
// 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);
|
||||
|
||||
// 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();
|
||||
ivl_assert(*this, reg);
|
||||
|
||||
netstruct_t*struct_type = reg->struct_type();
|
||||
const netstruct_t*struct_type = reg->struct_type();
|
||||
ivl_assert(*this, struct_type);
|
||||
|
||||
if (debug_elaborate) {
|
||||
|
|
|
|||
30
elab_net.cc
30
elab_net.cc
|
|
@ -24,6 +24,7 @@
|
|||
# include "netlist.h"
|
||||
# include "netmisc.h"
|
||||
# include "netstruct.h"
|
||||
# include "netvector.h"
|
||||
# include "compiler.h"
|
||||
|
||||
# include <cstdlib>
|
||||
|
|
@ -98,12 +99,12 @@ NetNet* PEConcat::elaborate_lnet_common_(Design*des, NetScope*scope,
|
|||
concat operator from most significant to least significant,
|
||||
which is the order they are given in the concat list. */
|
||||
|
||||
netvector_t*tmp2_vec = new netvector_t(nets[0]->data_type(),width-1,0);
|
||||
NetNet*osig = new NetNet(scope, scope->local_symbol(),
|
||||
NetNet::IMPLICIT, width);
|
||||
NetNet::IMPLICIT, tmp2_vec);
|
||||
|
||||
/* Assume that the data types of the nets are all the same, so
|
||||
we can take the data type of any, the first will do. */
|
||||
osig->data_type(nets[0]->data_type());
|
||||
osig->local_flag(true);
|
||||
osig->set_line(*this);
|
||||
|
||||
|
|
@ -154,8 +155,6 @@ NetNet* PEConcat::elaborate_lnet_common_(Design*des, NetScope*scope,
|
|||
assert(width == 0);
|
||||
}
|
||||
|
||||
osig->data_type(nets[0]->data_type());
|
||||
osig->local_flag(true);
|
||||
return osig;
|
||||
}
|
||||
|
||||
|
|
@ -431,11 +430,18 @@ NetNet* PEIdent::elaborate_lnet_common_(Design*des, NetScope*scope,
|
|||
remove the member and store it into method_name, and retry
|
||||
the search with "a.b". */
|
||||
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;
|
||||
symbol_search(this, des, scope, path_prefix, sig, par, eve);
|
||||
|
||||
// Whoops, not a struct signal, so give up on this avenue.
|
||||
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();
|
||||
sig = 0;
|
||||
}
|
||||
|
|
@ -475,7 +481,7 @@ NetNet* PEIdent::elaborate_lnet_common_(Design*des, NetScope*scope,
|
|||
|
||||
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()) {
|
||||
|
||||
// Detect the variable is a structure and there was a
|
||||
|
|
@ -655,11 +661,12 @@ NetNet* PEIdent::elaborate_lnet_common_(Design*des, NetScope*scope,
|
|||
return 0;
|
||||
}
|
||||
|
||||
netvector_t*tmp2_vec = new netvector_t(sig->data_type(),
|
||||
sig->vector_width()-1,0);
|
||||
NetNet*tmp = new NetNet(scope, scope->local_symbol(),
|
||||
sig->type(), sig->vector_width());
|
||||
sig->type(), tmp2_vec);
|
||||
tmp->set_line(*this);
|
||||
tmp->local_flag(true);
|
||||
tmp->data_type( sig->data_type() );
|
||||
connect(sig->pin(widx), tmp->pin(0));
|
||||
sig = tmp;
|
||||
}
|
||||
|
|
@ -683,10 +690,11 @@ NetNet* PEIdent::elaborate_lnet_common_(Design*des, NetScope*scope,
|
|||
<< " wid=" << subnet_wid <<"]"
|
||||
<< endl;
|
||||
|
||||
netvector_t*tmp2_vec = new netvector_t(sig->data_type(),
|
||||
subnet_wid-1,0);
|
||||
NetNet*subsig = new NetNet(sig->scope(),
|
||||
sig->scope()->local_symbol(),
|
||||
NetNet::WIRE, subnet_wid);
|
||||
subsig->data_type( sig->data_type() );
|
||||
NetNet::WIRE, tmp2_vec);
|
||||
subsig->local_flag(true);
|
||||
subsig->set_line(*this);
|
||||
|
||||
|
|
@ -800,10 +808,10 @@ NetNet* PEIdent::elaborate_subport(Design*des, NetScope*scope) const
|
|||
unsigned swid = abs(midx - lidx) + 1;
|
||||
ivl_assert(*this, swid > 0 && swid < sig->vector_width());
|
||||
|
||||
netvector_t*tmp2_vec = new netvector_t(sig->data_type(),swid-1,0);
|
||||
NetNet*tmp = new NetNet(scope, scope->local_symbol(),
|
||||
NetNet::WIRE, swid);
|
||||
NetNet::WIRE, tmp2_vec);
|
||||
tmp->port_type(sig->port_type());
|
||||
tmp->data_type(sig->data_type());
|
||||
tmp->set_line(*this);
|
||||
tmp->local_flag(true);
|
||||
NetNode*ps = 0;
|
||||
|
|
|
|||
159
elab_sig.cc
159
elab_sig.cc
|
|
@ -36,6 +36,7 @@
|
|||
# include "netmisc.h"
|
||||
# include "netenum.h"
|
||||
# include "netstruct.h"
|
||||
# include "netvector.h"
|
||||
# include "netdarray.h"
|
||||
# include "netparray.h"
|
||||
# include "util.h"
|
||||
|
|
@ -485,6 +486,7 @@ void PFunction::elaborate_sig(Design*des, NetScope*scope) const
|
|||
}
|
||||
|
||||
NetNet*ret_sig = 0;
|
||||
netvector_t*ret_vec = 0;
|
||||
|
||||
/* Create the signals/variables of the return value and write
|
||||
them into the function scope. */
|
||||
|
|
@ -520,50 +522,51 @@ void PFunction::elaborate_sig(Design*des, NetScope*scope) const
|
|||
des->errors += 1;
|
||||
}
|
||||
|
||||
list<netrange_t> packed;
|
||||
vector<netrange_t> packed;
|
||||
packed.push_back(netrange_t(mnum, lnum));
|
||||
ret_sig = new NetNet(scope, fname, NetNet::REG, packed);
|
||||
ret_sig->set_scalar(false);
|
||||
ret_vec = new netvector_t(packed, IVL_VT_LOGIC);
|
||||
ret_vec->set_signed(return_type_.type == PTF_REG_S);
|
||||
ret_vec->set_scalar(false);
|
||||
ret_sig = new NetNet(scope, fname, NetNet::REG, ret_vec);
|
||||
|
||||
} else {
|
||||
ret_sig = new NetNet(scope, fname, NetNet::REG);
|
||||
ret_sig->set_scalar(true);
|
||||
ret_vec = new netvector_t(IVL_VT_LOGIC);
|
||||
ret_vec->set_signed(return_type_.type == PTF_REG_S);
|
||||
ret_vec->set_scalar(true);
|
||||
ret_sig = new NetNet(scope, fname, NetNet::REG, ret_vec);
|
||||
}
|
||||
ret_sig->set_line(*this);
|
||||
ret_sig->set_signed(return_type_.type == PTF_REG_S);
|
||||
ret_sig->port_type(NetNet::POUTPUT);
|
||||
ret_sig->data_type(IVL_VT_LOGIC);
|
||||
break;
|
||||
|
||||
case PTF_INTEGER:
|
||||
ret_sig = new NetNet(scope, fname, NetNet::REG, integer_width);
|
||||
ret_vec = new netvector_t(IVL_VT_LOGIC, integer_width-1,0);
|
||||
ret_vec->set_signed(true);
|
||||
ret_vec->set_isint(true);
|
||||
ret_vec->set_scalar(false);
|
||||
ret_sig = new NetNet(scope, fname, NetNet::REG, ret_vec);
|
||||
ret_sig->set_line(*this);
|
||||
ret_sig->set_signed(true);
|
||||
ret_sig->set_isint(true);
|
||||
ret_sig->set_scalar(false);
|
||||
ret_sig->port_type(NetNet::POUTPUT);
|
||||
ret_sig->data_type(IVL_VT_LOGIC);
|
||||
break;
|
||||
|
||||
case PTF_TIME:
|
||||
ret_sig = new NetNet(scope, fname, NetNet::REG, 64);
|
||||
ret_vec = new netvector_t(IVL_VT_LOGIC, 64-1,0);
|
||||
ret_vec->set_isint(false);
|
||||
ret_vec->set_scalar(false);
|
||||
ret_sig = new NetNet(scope, fname, NetNet::REG, ret_vec);
|
||||
ret_sig->set_line(*this);
|
||||
ret_sig->set_signed(false);
|
||||
ret_sig->set_isint(false);
|
||||
ret_sig->set_scalar(false);
|
||||
ret_sig->port_type(NetNet::POUTPUT);
|
||||
ret_sig->data_type(IVL_VT_LOGIC);
|
||||
break;
|
||||
|
||||
case PTF_REAL:
|
||||
case PTF_REALTIME:
|
||||
ret_sig = new NetNet(scope, fname, NetNet::REG, 1);
|
||||
ret_vec = new netvector_t(IVL_VT_REAL);
|
||||
ret_vec->set_signed(true);
|
||||
ret_vec->set_isint(false);
|
||||
ret_vec->set_scalar(true);
|
||||
ret_sig = new NetNet(scope, fname, NetNet::REG, ret_vec);
|
||||
ret_sig->set_line(*this);
|
||||
ret_sig->set_signed(true);
|
||||
ret_sig->set_isint(false);
|
||||
ret_sig->set_scalar(true);
|
||||
ret_sig->port_type(NetNet::POUTPUT);
|
||||
ret_sig->data_type(IVL_VT_REAL);
|
||||
break;
|
||||
|
||||
case PTF_ATOM2:
|
||||
|
|
@ -598,13 +601,13 @@ void PFunction::elaborate_sig(Design*des, NetScope*scope) const
|
|||
|
||||
use_wid = mnum - lnum + 1;
|
||||
}
|
||||
ret_sig = new NetNet(scope, fname, NetNet::REG, use_wid);
|
||||
ret_vec = new netvector_t(IVL_VT_BOOL, use_wid-1, 0);
|
||||
ret_vec->set_isint(true);
|
||||
ret_vec->set_scalar(false);
|
||||
ret_vec->set_signed(return_type_.type == PTF_ATOM2_S? true : false);
|
||||
ret_sig = new NetNet(scope, fname, NetNet::REG, ret_vec);
|
||||
ret_sig->set_line(*this);
|
||||
ret_sig->set_signed(return_type_.type == PTF_ATOM2_S? true : false);
|
||||
ret_sig->set_isint(true);
|
||||
ret_sig->set_scalar(false);
|
||||
ret_sig->port_type(NetNet::POUTPUT);
|
||||
ret_sig->data_type(IVL_VT_BOOL);
|
||||
break;
|
||||
|
||||
case PTF_STRING:
|
||||
|
|
@ -820,7 +823,7 @@ void PWhile::elaborate_sig(Design*des, NetScope*scope) const
|
|||
}
|
||||
|
||||
static bool evaluate_ranges(Design*des, NetScope*scope,
|
||||
list<netrange_t>&llist,
|
||||
vector<netrange_t>&llist,
|
||||
const list<pform_range_t>&rlist)
|
||||
{
|
||||
bool bad_msb = false, bad_lsb = false;
|
||||
|
|
@ -871,7 +874,7 @@ static netstruct_t* elaborate_struct_type(Design*des, NetScope*scope,
|
|||
for (list<struct_member_t*>::iterator cur = struct_type->members->begin()
|
||||
; cur != struct_type->members->end() ; ++ cur) {
|
||||
|
||||
list<netrange_t>packed_dimensions;
|
||||
vector<netrange_t>packed_dimensions;
|
||||
|
||||
struct_member_t*curp = *cur;
|
||||
if (curp->range.get() && ! curp->range->empty()) {
|
||||
|
|
@ -897,22 +900,8 @@ static netstruct_t* elaborate_struct_type(Design*des, NetScope*scope,
|
|||
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 nettype_base_t*elaborate_type(Design*des, NetScope*scope,
|
||||
data_type_t*pform_type)
|
||||
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)) {
|
||||
netstruct_t*use_type = elaborate_struct_type(des, scope, struct_type);
|
||||
|
|
@ -926,13 +915,29 @@ static nettype_base_t*elaborate_type(Design*des, NetScope*scope,
|
|||
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())
|
||||
return false;
|
||||
|
||||
list<netrange_t>::const_iterator lcur = lef.begin();
|
||||
list<netrange_t>::const_iterator rcur = rig.begin();
|
||||
vector<netrange_t>::const_iterator lcur = lef.begin();
|
||||
vector<netrange_t>::const_iterator rcur = rig.begin();
|
||||
while (lcur != lef.end()) {
|
||||
if (lcur->get_msb() != rcur->get_msb())
|
||||
return false;
|
||||
|
|
@ -967,7 +972,7 @@ NetNet* PWire::elaborate_sig(Design*des, NetScope*scope) const
|
|||
}
|
||||
|
||||
unsigned wid = 1;
|
||||
list<netrange_t>packed_dimensions;
|
||||
vector<netrange_t>packed_dimensions;
|
||||
|
||||
des->errors += error_cnt_;
|
||||
|
||||
|
|
@ -1008,7 +1013,7 @@ NetNet* PWire::elaborate_sig(Design*des, NetScope*scope) const
|
|||
|
||||
if (port_set_ || net_set_) {
|
||||
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 (port_set_ && !port_.empty()) {
|
||||
bad_range |= evaluate_ranges(des, scope, plist, port_);
|
||||
|
|
@ -1095,9 +1100,10 @@ NetNet* PWire::elaborate_sig(Design*des, NetScope*scope) const
|
|||
// dimensions, then turn this into a dynamic array and
|
||||
// put all the packed dimensions there.
|
||||
if (use_lidx==0 && use_ridx==0) {
|
||||
ivl_assert(*this, netarray==0);
|
||||
netarray = new netdarray_t(packed_dimensions, data_type_, wid);
|
||||
netvector_t*vec = new netvector_t(packed_dimensions, data_type_);
|
||||
packed_dimensions.clear();
|
||||
ivl_assert(*this, netarray==0);
|
||||
netarray = new netdarray_t(vec);
|
||||
continue;
|
||||
}
|
||||
|
||||
|
|
@ -1218,7 +1224,8 @@ NetNet* PWire::elaborate_sig(Design*des, NetScope*scope) const
|
|||
<< " 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) {
|
||||
|
|
@ -1252,14 +1259,7 @@ NetNet* PWire::elaborate_sig(Design*des, NetScope*scope) const
|
|||
<< " in scope " << scope_path(scope) << endl;
|
||||
}
|
||||
|
||||
nettype_base_t*base_type = elaborate_type(des, scope, parray_type->base_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);
|
||||
sig = new NetNet(scope, name_, wtype, unpacked_dimensions, use_type);
|
||||
|
||||
|
||||
} else {
|
||||
|
|
@ -1272,29 +1272,30 @@ NetNet* PWire::elaborate_sig(Design*des, NetScope*scope) const
|
|||
cerr << " in scope " << scope_path(scope) << endl;
|
||||
}
|
||||
|
||||
sig = new NetNet(scope, name_, wtype, packed_dimensions, unpacked_dimensions);
|
||||
ivl_variable_type_t use_data_type = data_type_;
|
||||
if (use_data_type == IVL_VT_NO_TYPE) {
|
||||
use_data_type = IVL_VT_LOGIC;
|
||||
if (debug_elaborate) {
|
||||
cerr << get_fileline() << ": debug: "
|
||||
<< "Signal " << name_
|
||||
<< " in scope " << scope_path(scope)
|
||||
<< " defaults to data type " << use_data_type << endl;
|
||||
}
|
||||
}
|
||||
|
||||
netvector_t*vec = new netvector_t(packed_dimensions, use_data_type);
|
||||
vec->set_signed(get_signed());
|
||||
vec->set_isint(get_isint());
|
||||
if (is_implicit_scalar) vec->set_scalar(true);
|
||||
else vec->set_scalar(get_scalar());
|
||||
packed_dimensions.clear();
|
||||
sig = new NetNet(scope, name_, wtype, unpacked_dimensions, vec);
|
||||
|
||||
}
|
||||
|
||||
if (wtype == NetNet::WIRE) sig->devirtualize_pins();
|
||||
|
||||
ivl_variable_type_t use_data_type = data_type_;
|
||||
if (use_data_type == IVL_VT_NO_TYPE) {
|
||||
use_data_type = IVL_VT_LOGIC;
|
||||
if (debug_elaborate) {
|
||||
cerr << get_fileline() << ": debug: "
|
||||
<< "Signal " << name_
|
||||
<< " in scope " << scope_path(scope)
|
||||
<< " defaults to data type " << use_data_type << endl;
|
||||
}
|
||||
}
|
||||
|
||||
sig->data_type(use_data_type);
|
||||
sig->set_line(*this);
|
||||
sig->port_type(port_type_);
|
||||
sig->set_signed(get_signed());
|
||||
sig->set_isint(get_isint());
|
||||
if (is_implicit_scalar) sig->set_scalar(true);
|
||||
else sig->set_scalar(get_scalar());
|
||||
|
||||
if (ivl_discipline_t dis = get_discipline()) {
|
||||
sig->set_discipline(dis);
|
||||
|
|
|
|||
81
elaborate.cc
81
elaborate.cc
|
|
@ -35,6 +35,7 @@
|
|||
# include "PGenerate.h"
|
||||
# include "PSpec.h"
|
||||
# include "netlist.h"
|
||||
# include "netvector.h"
|
||||
# include "netmisc.h"
|
||||
# include "util.h"
|
||||
# include "parse_api.h"
|
||||
|
|
@ -75,8 +76,7 @@ void PGAssign::elaborate(Design*des, NetScope*scope) const
|
|||
|
||||
if (debug_elaborate) {
|
||||
cerr << get_fileline() << ": debug: PGAssign: elaborated l-value"
|
||||
<< " width=" << lval->vector_width()
|
||||
<< ", type=" << lval->data_type() << endl;
|
||||
<< " width=" << lval->vector_width() << endl;
|
||||
}
|
||||
|
||||
NetExpr*rval_expr = elaborate_rval_expr(des, scope, lval->data_type(),
|
||||
|
|
@ -115,7 +115,6 @@ void PGAssign::elaborate(Design*des, NetScope*scope) const
|
|||
cerr << get_fileline() << ": debug: PGAssign: elaborated r-value"
|
||||
<< " width="<< rval->vector_width()
|
||||
<< ", type="<< rval->data_type()
|
||||
<< ", signed="<< rval->get_signed()
|
||||
<< ", expr=" << *rval_expr << endl;
|
||||
}
|
||||
|
||||
|
|
@ -164,11 +163,12 @@ void PGAssign::elaborate(Design*des, NetScope*scope) const
|
|||
NetPartSelect::VP);
|
||||
des->add_node(tmp);
|
||||
tmp->set_line(*this);
|
||||
netvector_t*osig_vec = new netvector_t(rval->data_type(),
|
||||
lval->vector_width()-1,0);
|
||||
NetNet*osig = new NetNet(scope, scope->local_symbol(),
|
||||
NetNet::TRI, lval->vector_width());
|
||||
NetNet::TRI, osig_vec);
|
||||
osig->set_line(*this);
|
||||
osig->local_flag(true);
|
||||
osig->data_type(rval->data_type());
|
||||
connect(osig->pin(0), tmp->pin(0));
|
||||
rval = osig;
|
||||
need_driver_flag = false;
|
||||
|
|
@ -190,10 +190,11 @@ void PGAssign::elaborate(Design*des, NetScope*scope) const
|
|||
|
||||
connect(rval->pin(0), driver->pin(1));
|
||||
|
||||
netvector_t*tmp_vec = new netvector_t(rval->data_type(),
|
||||
rval->vector_width()-1,0);
|
||||
NetNet*tmp = new NetNet(scope, scope->local_symbol(),
|
||||
NetNet::WIRE, rval->vector_width());
|
||||
NetNet::WIRE, tmp_vec);
|
||||
tmp->set_line(*this);
|
||||
tmp->data_type(rval->data_type());
|
||||
tmp->local_flag(true);
|
||||
|
||||
connect(driver->pin(0), tmp->pin(0));
|
||||
|
|
@ -868,10 +869,11 @@ void PGBuiltin::elaborate(Design*des, NetScope*scope) const
|
|||
des->add_node(rep);
|
||||
connect(rep->pin(1), sig->pin(0));
|
||||
|
||||
netvector_t*osig_vec = new netvector_t(IVL_VT_LOGIC,
|
||||
instance_width-1,0);
|
||||
sig = new NetNet(scope, scope->local_symbol(),
|
||||
NetNet::WIRE, instance_width);
|
||||
NetNet::WIRE, osig_vec);
|
||||
sig->set_line(*this);
|
||||
sig->data_type(IVL_VT_LOGIC);
|
||||
sig->local_flag(true);
|
||||
connect(rep->pin(0), sig->pin(0));
|
||||
|
||||
|
|
@ -948,12 +950,12 @@ void PGBuiltin::elaborate(Design*des, NetScope*scope) const
|
|||
unsigned dev = gdx*gate_count;
|
||||
connect(cur[dev+idx]->pin(0), cc->pin(gdx+1));
|
||||
|
||||
netvector_t*tmp2_vec = new netvector_t(IVL_VT_LOGIC);
|
||||
NetNet*tmp2 = new NetNet(scope,
|
||||
scope->local_symbol(),
|
||||
NetNet::WIRE, 1);
|
||||
NetNet::WIRE, tmp2_vec);
|
||||
tmp2->set_line(*this);
|
||||
tmp2->local_flag(true);
|
||||
tmp2->data_type(IVL_VT_LOGIC);
|
||||
connect(cc->pin(gdx+1), tmp2->pin(0));
|
||||
}
|
||||
|
||||
|
|
@ -965,11 +967,11 @@ void PGBuiltin::elaborate(Design*des, NetScope*scope) const
|
|||
tmp1->set_line(*this);
|
||||
des->add_node(tmp1);
|
||||
connect(tmp1->pin(1), sig->pin(0));
|
||||
netvector_t*tmp2_vec = new netvector_t(sig->data_type());
|
||||
NetNet*tmp2 = new NetNet(scope, scope->local_symbol(),
|
||||
NetNet::WIRE, 1);
|
||||
NetNet::WIRE, tmp2_vec);
|
||||
tmp2->set_line(*this);
|
||||
tmp2->local_flag(true);
|
||||
tmp2->data_type(sig->data_type());
|
||||
connect(tmp1->pin(0), tmp2->pin(0));
|
||||
unsigned use_idx = idx - gate_count + 1;
|
||||
unsigned dev = gdx*gate_count;
|
||||
|
|
@ -996,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::PIMPLICIT);
|
||||
|
||||
netvector_t*tmp_type = new netvector_t(IVL_VT_LOGIC, port_wid-1, 0);
|
||||
NetNet*tmp = new NetNet(scope, scope->local_symbol(),
|
||||
NetNet::WIRE, port_wid);
|
||||
NetNet::WIRE, tmp_type);
|
||||
tmp->local_flag(true);
|
||||
tmp->set_line(*this);
|
||||
|
||||
|
|
@ -1415,6 +1418,12 @@ void PGModule::elaborate_mod_(Design*des, Module*rmod, NetScope*scope) const
|
|||
<< "too complicated for elaboration." << endl;
|
||||
continue;
|
||||
}
|
||||
|
||||
if (debug_elaborate) {
|
||||
cerr << get_fileline() << ": debug: "
|
||||
<< "Elaborating INPUT port expression: " << *tmp_expr << endl;
|
||||
}
|
||||
|
||||
sig = tmp_expr->synthesize(des, scope, tmp_expr);
|
||||
if (sig == 0) {
|
||||
cerr << pins[idx]->get_fileline()
|
||||
|
|
@ -1432,11 +1441,12 @@ void PGModule::elaborate_mod_(Design*des, Module*rmod, NetScope*scope) const
|
|||
des->add_node(tmp);
|
||||
connect(tmp->pin(1), sig->pin(0));
|
||||
|
||||
netvector_t*tmp2_vec = new netvector_t(sig->data_type(),
|
||||
sig->vector_width()-1,0);
|
||||
NetNet*tmp2 = new NetNet(scope, scope->local_symbol(),
|
||||
NetNet::WIRE, sig->vector_width());
|
||||
NetNet::WIRE, tmp2_vec);
|
||||
tmp2->local_flag(true);
|
||||
tmp2->set_line(*this);
|
||||
tmp2->data_type(sig->data_type());
|
||||
connect(tmp->pin(0), tmp2->pin(0));
|
||||
sig = tmp2;
|
||||
}
|
||||
|
|
@ -2184,6 +2194,17 @@ NetAssign_* PAssign_::elaborate_lval(Design*des, NetScope*scope) const
|
|||
return lval_->elaborate_lval(des, scope, false);
|
||||
}
|
||||
|
||||
NetExpr* PAssign_::elaborate_rval_(Design*des, NetScope*scope,
|
||||
ivl_type_t net_type) const
|
||||
{
|
||||
ivl_assert(*this, rval_);
|
||||
|
||||
NetExpr*rv = rval_->elaborate_expr(des, scope, net_type, 0);
|
||||
|
||||
ivl_assert(*this, !is_constant_);
|
||||
return rv;
|
||||
}
|
||||
|
||||
NetExpr* PAssign_::elaborate_rval_(Design*des, NetScope*scope,
|
||||
unsigned lv_width,
|
||||
ivl_variable_type_t lv_type) const
|
||||
|
|
@ -2355,9 +2376,20 @@ NetProc* PAssign::elaborate(Design*des, NetScope*scope) const
|
|||
if (delay_ != 0)
|
||||
delay = elaborate_delay_expr(delay_, des, scope);
|
||||
|
||||
NetExpr*rv;
|
||||
if (lv->more==0 && dynamic_cast<const PENew*> (rval())) {
|
||||
/* Special case: The l-value is a single signal, and the
|
||||
r-value expression is a "new" expression. The l-value
|
||||
has a new form of type, and the PENew expression
|
||||
requires the extra information that it contains. So
|
||||
handle it with this code instead. */
|
||||
rv = elaborate_rval_(des, scope, lv->sig()->net_type());
|
||||
|
||||
} else {
|
||||
/* Elaborate the r-value expression, then try to evaluate it. */
|
||||
rv = elaborate_rval_(des, scope, count_lval_width(lv), lv->expr_type());
|
||||
}
|
||||
|
||||
/* Elaborate the r-value expression, then try to evaluate it. */
|
||||
NetExpr*rv = elaborate_rval_(des, scope, count_lval_width(lv), lv->expr_type());
|
||||
if (rv == 0) return 0;
|
||||
assert(rv);
|
||||
|
||||
|
|
@ -2382,11 +2414,11 @@ NetProc* PAssign::elaborate(Design*des, NetScope*scope) const
|
|||
if (delay || event_) {
|
||||
unsigned wid = count_lval_width(lv);
|
||||
|
||||
netvector_t*tmp2_vec = new netvector_t(rv->expr_type(),wid-1,0);
|
||||
NetNet*tmp = new NetNet(scope, scope->local_symbol(),
|
||||
NetNet::REG, wid);
|
||||
NetNet::REG, tmp2_vec);
|
||||
tmp->local_flag(true);
|
||||
tmp->set_line(*this);
|
||||
tmp->data_type(rv->expr_type());
|
||||
|
||||
NetESignal*sig = new NetESignal(tmp);
|
||||
|
||||
|
|
@ -2477,10 +2509,17 @@ NetProc* PAssign::elaborate(Design*des, NetScope*scope) const
|
|||
|
||||
if (lv->expr_type() == IVL_VT_BOOL && rv->expr_type() != IVL_VT_BOOL) {
|
||||
if (debug_elaborate)
|
||||
cerr << get_fileline() << ": debug: Cast expression to int2" << endl;
|
||||
cerr << get_fileline() << ": debug: "
|
||||
<< "Cast expression to int2" << endl;
|
||||
rv = cast_to_int2(rv);
|
||||
}
|
||||
|
||||
if (lv->expr_type() == IVL_VT_REAL && rv->expr_type() != IVL_VT_REAL) {
|
||||
if (debug_elaborate)
|
||||
cerr << get_fileline() << ": debug: "
|
||||
<< "Cast expression to real." << endl;
|
||||
rv = cast_to_real(rv);
|
||||
}
|
||||
if (lv->enumeration() && (lv->enumeration() != rv->enumeration())) {
|
||||
cerr << get_fileline() << ": error: "
|
||||
<< "Enumeration type mismatch in assignment." << endl;
|
||||
|
|
|
|||
|
|
@ -53,6 +53,9 @@ static bool get_real_arg_(const NetExpr*expr, verireal&val)
|
|||
break;
|
||||
}
|
||||
|
||||
case IVL_VT_DARRAY:
|
||||
return false;
|
||||
|
||||
default:
|
||||
assert(0);
|
||||
}
|
||||
|
|
|
|||
127
expr_synth.cc
127
expr_synth.cc
|
|
@ -24,6 +24,7 @@
|
|||
# include <iostream>
|
||||
|
||||
# include "netlist.h"
|
||||
# include "netvector.h"
|
||||
# include "netmisc.h"
|
||||
# include "ivl_assert.h"
|
||||
|
||||
|
|
@ -118,11 +119,11 @@ NetNet* NetEBAdd::synthesize(Design*des, NetScope*scope, NetExpr*root)
|
|||
}
|
||||
|
||||
perm_string path = lsig->scope()->local_symbol();
|
||||
NetNet*osig = new NetNet(lsig->scope(), path, NetNet::IMPLICIT, width);
|
||||
netvector_t*osig_vec = new netvector_t(expr_type(), width-1, 0);
|
||||
osig_vec->set_signed(has_sign());
|
||||
NetNet*osig = new NetNet(lsig->scope(), path, NetNet::IMPLICIT, osig_vec);
|
||||
osig->set_line(*this);
|
||||
osig->local_flag(true);
|
||||
osig->data_type(expr_type());
|
||||
osig->set_signed(has_sign());
|
||||
|
||||
perm_string oname = osig->scope()->local_symbol();
|
||||
NetAddSub *adder = new NetAddSub(lsig->scope(), oname, width);
|
||||
|
|
@ -173,11 +174,11 @@ NetNet* NetEBBits::synthesize(Design*des, NetScope*scope, NetExpr*root)
|
|||
rsig = pad_to_width(des, rsig, width, *this);
|
||||
|
||||
assert(lsig->vector_width() == rsig->vector_width());
|
||||
netvector_t*osig_vec = new netvector_t(expr_type(), width-1, 0);
|
||||
NetNet*osig = new NetNet(scope, scope->local_symbol(),
|
||||
NetNet::IMPLICIT, width);
|
||||
NetNet::IMPLICIT, osig_vec);
|
||||
osig->set_line(*this);
|
||||
osig->local_flag(true);
|
||||
osig->data_type(expr_type());
|
||||
|
||||
perm_string oname = scope->local_symbol();
|
||||
NetLogic*gate;
|
||||
|
|
@ -243,11 +244,11 @@ NetNet* NetEBComp::synthesize(Design*des, NetScope*scope, NetExpr*root)
|
|||
rsig = pad_to_width(des, rsig, width, *this);
|
||||
}
|
||||
|
||||
netvector_t*osig_vec = new netvector_t(IVL_VT_LOGIC);
|
||||
NetNet*osig = new NetNet(scope, scope->local_symbol(),
|
||||
NetNet::IMPLICIT, 1);
|
||||
NetNet::IMPLICIT, osig_vec);
|
||||
osig->set_line(*this);
|
||||
osig->local_flag(true);
|
||||
osig->data_type(IVL_VT_LOGIC);
|
||||
|
||||
// Test if the comparison is signed.
|
||||
//
|
||||
|
|
@ -390,11 +391,11 @@ NetNet* NetEBPow::synthesize(Design*des, NetScope*scope, NetExpr*root)
|
|||
connect(powr->pin_DataA(), lsig->pin(0));
|
||||
connect(powr->pin_DataB(), rsig->pin(0));
|
||||
|
||||
netvector_t*osig_vec = new netvector_t(expr_type(), width-1, 0);
|
||||
osig_vec->set_signed(has_sign());
|
||||
NetNet*osig = new NetNet(scope, scope->local_symbol(),
|
||||
NetNet::IMPLICIT, width);
|
||||
NetNet::IMPLICIT, osig_vec);
|
||||
osig->set_line(*this);
|
||||
osig->data_type(expr_type());
|
||||
osig->set_signed(has_sign());
|
||||
osig->local_flag(true);
|
||||
|
||||
connect(powr->pin_Result(), osig->pin(0));
|
||||
|
|
@ -427,11 +428,11 @@ NetNet* NetEBMult::synthesize(Design*des, NetScope*scope, NetExpr*root)
|
|||
connect(mult->pin_DataA(), lsig->pin(0));
|
||||
connect(mult->pin_DataB(), rsig->pin(0));
|
||||
|
||||
netvector_t*osig_vec = new netvector_t(expr_type(), width-1, 0);
|
||||
osig_vec->set_signed(has_sign());
|
||||
NetNet*osig = new NetNet(scope, scope->local_symbol(),
|
||||
NetNet::IMPLICIT, width);
|
||||
NetNet::IMPLICIT, osig_vec);
|
||||
osig->set_line(*this);
|
||||
osig->data_type(expr_type());
|
||||
osig->set_signed(has_sign());
|
||||
osig->local_flag(true);
|
||||
|
||||
connect(mult->pin_Result(), osig->pin(0));
|
||||
|
|
@ -452,11 +453,11 @@ NetNet* NetEBDiv::synthesize(Design*des, NetScope*scope, NetExpr*root)
|
|||
if (real_args) width = 1;
|
||||
else width = expr_width();
|
||||
|
||||
netvector_t*osig_vec = new netvector_t(lsig->data_type(), width-1, 0);
|
||||
osig_vec->set_signed(has_sign());
|
||||
NetNet*osig = new NetNet(scope, scope->local_symbol(),
|
||||
NetNet::IMPLICIT, width);
|
||||
NetNet::IMPLICIT, osig_vec);
|
||||
osig->set_line(*this);
|
||||
osig->data_type(lsig->data_type());
|
||||
osig->set_signed(has_sign());
|
||||
osig->local_flag(true);
|
||||
|
||||
switch (op()) {
|
||||
|
|
@ -530,10 +531,10 @@ NetNet* NetEBLogic::synthesize(Design*des, NetScope*scope, NetExpr*root)
|
|||
return 0;
|
||||
}
|
||||
|
||||
netvector_t*osig_tmp = new netvector_t(expr_type());
|
||||
NetNet*osig = new NetNet(scope, scope->local_symbol(),
|
||||
NetNet::IMPLICIT, 1);
|
||||
NetNet::IMPLICIT, osig_tmp);
|
||||
osig->set_line(*this);
|
||||
osig->data_type(expr_type());
|
||||
osig->local_flag(true);
|
||||
|
||||
NetLogic*olog;
|
||||
|
|
@ -597,10 +598,10 @@ NetNet* NetEBShift::synthesize(Design*des, NetScope*scope, NetExpr*root)
|
|||
if (shift == 0)
|
||||
return lsig;
|
||||
|
||||
netvector_t*osig_vec = new netvector_t(expr_type(), expr_width()-1,0);
|
||||
NetNet*osig = new NetNet(scope, scope->local_symbol(),
|
||||
NetNet::IMPLICIT, expr_width());
|
||||
NetNet::IMPLICIT, osig_vec);
|
||||
osig->set_line(*this);
|
||||
osig->data_type(expr_type());
|
||||
osig->local_flag(true);
|
||||
|
||||
// ushift is the amount of pad created by the shift.
|
||||
|
|
@ -618,10 +619,10 @@ NetNet* NetEBShift::synthesize(Design*des, NetScope*scope, NetExpr*root)
|
|||
psel->set_line(*this);
|
||||
des->add_node(psel);
|
||||
|
||||
netvector_t*psig_vec = new netvector_t(expr_type(), part_width-1, 0);
|
||||
NetNet*psig = new NetNet(scope, scope->local_symbol(),
|
||||
NetNet::IMPLICIT, part_width);
|
||||
NetNet::IMPLICIT, psig_vec);
|
||||
psig->set_line(*this);
|
||||
psig->data_type(expr_type());
|
||||
psig->local_flag(true);
|
||||
connect(psig->pin(0), psel->pin(0));
|
||||
|
||||
|
|
@ -646,10 +647,11 @@ NetNet* NetEBShift::synthesize(Design*des, NetScope*scope, NetExpr*root)
|
|||
znum);
|
||||
des->add_node(zcon);
|
||||
|
||||
netvector_t*zsig_vec = new netvector_t(osig->data_type(),
|
||||
znum.len()-1, 0);
|
||||
NetNet*zsig = new NetNet(scope, scope->local_symbol(),
|
||||
NetNet::WIRE, znum.len());
|
||||
NetNet::WIRE, zsig_vec);
|
||||
zsig->set_line(*this);
|
||||
zsig->data_type(osig->data_type());
|
||||
zsig->local_flag(true);
|
||||
connect(zcon->pin(0), zsig->pin(0));
|
||||
|
||||
|
|
@ -676,10 +678,10 @@ NetNet* NetEBShift::synthesize(Design*des, NetScope*scope, NetExpr*root)
|
|||
|
||||
if (rsig == 0) return 0;
|
||||
|
||||
netvector_t*osig_vec = new netvector_t(expr_type(), expr_width()-1, 0);
|
||||
NetNet*osig = new NetNet(scope, scope->local_symbol(),
|
||||
NetNet::IMPLICIT, expr_width());
|
||||
NetNet::IMPLICIT, osig_vec);
|
||||
osig->set_line(*this);
|
||||
osig->data_type(expr_type());
|
||||
osig->local_flag(true);
|
||||
|
||||
NetCLShift*dev = new NetCLShift(scope, scope->local_symbol(),
|
||||
|
|
@ -739,10 +741,10 @@ NetNet* NetEConcat::synthesize(Design*des, NetScope*scope, NetExpr*root)
|
|||
|
||||
/* Make a NetNet object to carry the output vector. */
|
||||
perm_string path = scope->local_symbol();
|
||||
NetNet*osig = new NetNet(scope, path, NetNet::IMPLICIT, expr_width());
|
||||
netvector_t*osig_vec = new netvector_t(data_type, expr_width()-1, 0);
|
||||
NetNet*osig = new NetNet(scope, path, NetNet::IMPLICIT, osig_vec);
|
||||
osig->set_line(*this);
|
||||
osig->local_flag(true);
|
||||
osig->data_type(data_type);
|
||||
|
||||
NetConcat*concat = new NetConcat(scope, scope->local_symbol(),
|
||||
osig->vector_width(),
|
||||
|
|
@ -785,11 +787,11 @@ NetNet* NetEConst::synthesize(Design*des, NetScope*scope, NetExpr*)
|
|||
return 0;
|
||||
}
|
||||
|
||||
NetNet*osig = new NetNet(scope, path, NetNet::IMPLICIT, width);
|
||||
netvector_t*osig_vec = new netvector_t(expr_type(), width-1, 0);
|
||||
osig_vec->set_signed(has_sign());
|
||||
NetNet*osig = new NetNet(scope, path, NetNet::IMPLICIT, osig_vec);
|
||||
osig->set_line(*this);
|
||||
osig->local_flag(true);
|
||||
osig->data_type(expr_type());
|
||||
osig->set_signed(has_sign());
|
||||
|
||||
NetConst*con = new NetConst(scope, scope->local_symbol(), value());
|
||||
con->set_line(*this);
|
||||
|
|
@ -806,11 +808,11 @@ NetNet* NetECReal::synthesize(Design*des, NetScope*scope, NetExpr*)
|
|||
{
|
||||
perm_string path = scope->local_symbol();
|
||||
|
||||
NetNet*osig = new NetNet(scope, path, NetNet::WIRE, 1);
|
||||
netvector_t*osig_vec = new netvector_t(IVL_VT_REAL);
|
||||
osig_vec->set_signed(has_sign());
|
||||
NetNet*osig = new NetNet(scope, path, NetNet::WIRE, osig_vec);
|
||||
osig->set_line(*this);
|
||||
osig->local_flag(true);
|
||||
osig->data_type(IVL_VT_REAL);
|
||||
osig->set_signed(has_sign());
|
||||
|
||||
NetLiteral*con = new NetLiteral(scope, scope->local_symbol(), value_);
|
||||
con->set_line(*this);
|
||||
|
|
@ -839,10 +841,10 @@ NetNet* NetEUBits::synthesize(Design*des, NetScope*scope, NetExpr*root)
|
|||
}
|
||||
|
||||
unsigned width = isig->vector_width();
|
||||
netvector_t*osig_vec = new netvector_t(expr_type(), width-1, 0);
|
||||
NetNet*osig = new NetNet(scope, scope->local_symbol(),
|
||||
NetNet::IMPLICIT, width);
|
||||
NetNet::IMPLICIT, osig_vec);
|
||||
osig->set_line(*this);
|
||||
osig->data_type(expr_type());
|
||||
osig->local_flag(true);
|
||||
|
||||
perm_string oname = scope->local_symbol();
|
||||
|
|
@ -882,11 +884,12 @@ NetNet* NetEUnary::synthesize(Design*des, NetScope*scope, NetExpr*root)
|
|||
if (expr_->has_sign() == false)
|
||||
return sub;
|
||||
|
||||
netvector_t*sig_vec = new netvector_t(sub->data_type(),
|
||||
sub->vector_width()-1, 0);
|
||||
NetNet*sig = new NetNet(scope, scope->local_symbol(),
|
||||
NetNet::WIRE, sub->vector_width());
|
||||
NetNet::WIRE, sig_vec);
|
||||
sig->set_line(*this);
|
||||
sig->local_flag(true);
|
||||
sig->data_type(sub->data_type());
|
||||
|
||||
NetAbs*tmp = new NetAbs(scope, scope->local_symbol(), sub->vector_width());
|
||||
tmp->set_line(*this);
|
||||
|
|
@ -956,10 +959,10 @@ NetNet* NetEUReduce::synthesize(Design*des, NetScope*scope, NetExpr*root)
|
|||
gate->set_line(*this);
|
||||
des->add_node(gate);
|
||||
|
||||
netvector_t*osig_vec = new netvector_t(expr_type());
|
||||
NetNet*osig = new NetNet(scope, scope->local_symbol(),
|
||||
NetNet::IMPLICIT, 1);
|
||||
NetNet::IMPLICIT, osig_vec);
|
||||
osig->set_line(*this);
|
||||
osig->data_type(expr_type());
|
||||
osig->local_flag(true);
|
||||
|
||||
connect(gate->pin(0), osig->pin(0));
|
||||
|
|
@ -1063,10 +1066,11 @@ NetNet* NetESelect::synthesize(Design *des, NetScope*scope, NetExpr*root)
|
|||
des->add_node(sel);
|
||||
|
||||
ivl_assert(*this, select_width > 0);
|
||||
netvector_t*tmp_vec = new netvector_t(sub->data_type(),
|
||||
select_width-1, 0);
|
||||
NetNet*tmp = new NetNet(scope, scope->local_symbol(),
|
||||
NetNet::WIRE, select_width);
|
||||
NetNet::WIRE, tmp_vec);
|
||||
tmp->set_line(*this);
|
||||
tmp->data_type(sub->data_type());
|
||||
tmp->local_flag(true);
|
||||
connect(sel->pin(0), tmp->pin(0));
|
||||
|
||||
|
|
@ -1090,10 +1094,10 @@ NetNet* NetESelect::synthesize(Design *des, NetScope*scope, NetExpr*root)
|
|||
connect(cat->pin(concat_count), above->pin(0));
|
||||
}
|
||||
|
||||
tmp_vec = new netvector_t(sub->data_type(), expr_width()-1, 0);
|
||||
tmp = new NetNet(scope, scope->local_symbol(),
|
||||
NetNet::WIRE, expr_width());
|
||||
NetNet::WIRE, tmp_vec);
|
||||
tmp->set_line(*this);
|
||||
tmp->data_type(sub->data_type());
|
||||
tmp->local_flag(true);
|
||||
connect(cat->pin(0), tmp->pin(0));
|
||||
}
|
||||
|
|
@ -1111,9 +1115,10 @@ NetNet* NetESelect::synthesize(Design *des, NetScope*scope, NetExpr*root)
|
|||
sel->set_line(*this);
|
||||
des->add_node(sel);
|
||||
|
||||
netvector_t*tmp_vec = new netvector_t(sub->data_type(),
|
||||
expr_width()-1, 0);
|
||||
NetNet*tmp = new NetNet(scope, scope->local_symbol(),
|
||||
NetNet::IMPLICIT, expr_width());
|
||||
tmp->data_type(sub->data_type());
|
||||
NetNet::IMPLICIT, tmp_vec);
|
||||
tmp->local_flag(true);
|
||||
tmp->set_line(*this);
|
||||
sub = tmp;
|
||||
|
|
@ -1134,10 +1139,11 @@ NetNet* NetESelect::synthesize(Design *des, NetScope*scope, NetExpr*root)
|
|||
// extension or 0 extension, depending on the has_sign() mode
|
||||
// of the expression.
|
||||
|
||||
netvector_t*net_vec = new netvector_t(expr_type(), expr_width()-1, 0);
|
||||
net_vec->set_signed(has_sign());
|
||||
NetNet*net = new NetNet(scope, scope->local_symbol(),
|
||||
NetNet::IMPLICIT, expr_width());
|
||||
NetNet::IMPLICIT, net_vec);
|
||||
net->set_line(*this);
|
||||
net->data_type(expr_type());
|
||||
net->local_flag(true);
|
||||
if (has_sign()) {
|
||||
NetSignExtend*pad = new NetSignExtend(scope,
|
||||
|
|
@ -1148,7 +1154,6 @@ NetNet* NetESelect::synthesize(Design *des, NetScope*scope, NetExpr*root)
|
|||
|
||||
connect(pad->pin(1), sub->pin(0));
|
||||
connect(pad->pin(0), net->pin(0));
|
||||
net->set_signed(true);
|
||||
|
||||
} else {
|
||||
|
||||
|
|
@ -1165,10 +1170,10 @@ NetNet* NetESelect::synthesize(Design *des, NetScope*scope, NetExpr*root)
|
|||
con->set_line(*this);
|
||||
des->add_node(con);
|
||||
|
||||
netvector_t*tmp_vec = new netvector_t(expr_type(), pad_width-1, 0);
|
||||
NetNet*tmp = new NetNet(scope, scope->local_symbol(),
|
||||
NetNet::IMPLICIT, pad_width);
|
||||
NetNet::IMPLICIT, tmp_vec);
|
||||
tmp->set_line(*this);
|
||||
tmp->data_type(expr_type());
|
||||
tmp->local_flag(true);
|
||||
connect(tmp->pin(0), con->pin(0));
|
||||
|
||||
|
|
@ -1220,9 +1225,9 @@ NetNet* NetETernary::synthesize(Design *des, NetScope*scope, NetExpr*root)
|
|||
ivl_assert(*this, csig->vector_width() == 1);
|
||||
|
||||
unsigned width=expr_width();
|
||||
NetNet*osig = new NetNet(csig->scope(), path, NetNet::IMPLICIT, width);
|
||||
netvector_t*osig_vec = new netvector_t(expr_type(), width-1, 0);
|
||||
NetNet*osig = new NetNet(csig->scope(), path, NetNet::IMPLICIT, osig_vec);
|
||||
osig->set_line(*this);
|
||||
osig->data_type(expr_type());
|
||||
osig->local_flag(true);
|
||||
|
||||
/* Make sure the types match. */
|
||||
|
|
@ -1265,11 +1270,12 @@ NetNet* NetESignal::synthesize(Design*des, NetScope*scope, NetExpr*root)
|
|||
if (word_ == 0)
|
||||
return net_;
|
||||
|
||||
netvector_t*tmp_vec = new netvector_t(net_->data_type(),
|
||||
net_->vector_width()-1, 0);
|
||||
NetNet*tmp = new NetNet(scope, scope->local_symbol(),
|
||||
NetNet::IMPLICIT, net_->vector_width());
|
||||
NetNet::IMPLICIT, tmp_vec);
|
||||
tmp->set_line(*this);
|
||||
tmp->local_flag(true);
|
||||
tmp->data_type(net_->data_type());
|
||||
|
||||
// For NetExpr objects, the word index is already converted to
|
||||
// a canonical (lsb==0) address. Just use the index directly.
|
||||
|
|
@ -1354,12 +1360,12 @@ NetNet* NetESFunc::synthesize(Design*des, NetScope*scope, NetExpr*root)
|
|||
net->set_line(*this);
|
||||
des->add_node(net);
|
||||
|
||||
netvector_t*osig_vec = new netvector_t(def->type, def->wid-1, 0);
|
||||
osig_vec->set_signed(def->type==IVL_VT_REAL? true : false);
|
||||
NetNet*osig = new NetNet(scope, scope->local_symbol(),
|
||||
NetNet::WIRE, def->wid);
|
||||
NetNet::WIRE, osig_vec);
|
||||
osig->set_line(*this);
|
||||
osig->local_flag(true);
|
||||
osig->set_signed(def->type==IVL_VT_REAL? true : false);
|
||||
osig->data_type(def->type);
|
||||
|
||||
connect(net->pin(0), osig->pin(0));
|
||||
|
||||
|
|
@ -1422,11 +1428,12 @@ NetNet* NetEUFunc::synthesize(Design*des, NetScope*scope, NetExpr*root)
|
|||
des->add_node(net);
|
||||
|
||||
/* Create an output signal and connect it to the function. */
|
||||
netvector_t*osig_vec = new netvector_t(result_sig_->expr_type(),
|
||||
result_sig_->vector_width()-1, 0);
|
||||
NetNet*osig = new NetNet(scope_, scope_->local_symbol(), NetNet::WIRE,
|
||||
result_sig_->vector_width());
|
||||
osig_vec);
|
||||
osig->set_line(*this);
|
||||
osig->local_flag(true);
|
||||
osig->data_type(result_sig_->expr_type());
|
||||
connect(net->pin(0), osig->pin(0));
|
||||
|
||||
/* Connect the pins to the arguments. */
|
||||
|
|
|
|||
62
ivl_target.h
62
ivl_target.h
|
|
@ -21,12 +21,19 @@
|
|||
|
||||
# include <inttypes.h>
|
||||
|
||||
/* Re the _CLASS define: clang++ wants this to be class to match the
|
||||
* definition, but clang (the C) compiler needs it to be a struct
|
||||
* since class is not defined in C. They are effecively both pointers
|
||||
* to an object so everything works out. */
|
||||
|
||||
#ifdef __cplusplus
|
||||
#define _BEGIN_DECL extern "C" {
|
||||
#define _END_DECL }
|
||||
#define _CLASS class
|
||||
#else
|
||||
#define _BEGIN_DECL
|
||||
#define _END_DECL
|
||||
#define _CLASS struct
|
||||
#endif
|
||||
|
||||
#ifndef __GNUC__
|
||||
|
|
@ -157,21 +164,8 @@ typedef struct ivl_array_s *ivl_array_t;
|
|||
typedef struct ivl_branch_s *ivl_branch_t;
|
||||
typedef struct ivl_delaypath_s*ivl_delaypath_t;
|
||||
typedef struct ivl_design_s *ivl_design_t;
|
||||
/* clang++ wants this to be class to match the definition, but clang
|
||||
* (the C) compiler needs it to be a struct since class is not defined
|
||||
* in C. They are effecively both pointers to an object so everything
|
||||
* works out. */
|
||||
#ifdef __cplusplus
|
||||
typedef class ivl_discipline_s*ivl_discipline_t;
|
||||
#else
|
||||
typedef struct ivl_discipline_s*ivl_discipline_t;
|
||||
#endif
|
||||
/* See the comments above. */
|
||||
#ifdef __cplusplus
|
||||
typedef class netenum_t *ivl_enumtype_t;
|
||||
#else
|
||||
typedef struct netenum_t *ivl_enumtype_t;
|
||||
#endif
|
||||
typedef _CLASS ivl_discipline_s*ivl_discipline_t;
|
||||
typedef _CLASS netenum_t *ivl_enumtype_t;
|
||||
typedef struct ivl_event_s *ivl_event_t;
|
||||
typedef struct ivl_expr_s *ivl_expr_t;
|
||||
typedef struct ivl_island_s *ivl_island_t;
|
||||
|
|
@ -180,12 +174,7 @@ typedef struct ivl_lval_s *ivl_lval_t;
|
|||
typedef struct ivl_net_const_s*ivl_net_const_t;
|
||||
typedef struct ivl_net_logic_s*ivl_net_logic_t;
|
||||
typedef struct ivl_udp_s *ivl_udp_t;
|
||||
/* See the comments above. */
|
||||
#ifdef __cplusplus
|
||||
typedef class ivl_nature_s *ivl_nature_t;
|
||||
#else
|
||||
typedef struct ivl_nature_s *ivl_nature_t;
|
||||
#endif
|
||||
typedef _CLASS ivl_nature_s *ivl_nature_t;
|
||||
typedef struct ivl_net_probe_s*ivl_net_probe_t;
|
||||
typedef struct ivl_nexus_s *ivl_nexus_t;
|
||||
typedef struct ivl_nexus_ptr_s*ivl_nexus_ptr_t;
|
||||
|
|
@ -193,10 +182,11 @@ typedef struct ivl_parameter_s*ivl_parameter_t;
|
|||
typedef struct ivl_process_s *ivl_process_t;
|
||||
typedef struct ivl_scope_s *ivl_scope_t;
|
||||
typedef struct ivl_signal_s *ivl_signal_t;
|
||||
typedef struct ivl_port_info_s *ivl_port_info_t;
|
||||
typedef struct ivl_port_info_s*ivl_port_info_t;
|
||||
typedef struct ivl_switch_s *ivl_switch_t;
|
||||
typedef struct ivl_memory_s *ivl_memory_t; //XXXX __attribute__((deprecated));
|
||||
typedef struct ivl_statement_s*ivl_statement_t;
|
||||
typedef const _CLASS ivl_type_s*ivl_type_t;
|
||||
|
||||
/*
|
||||
* These are types that are defined as enumerations. These have
|
||||
|
|
@ -774,6 +764,11 @@ extern unsigned ivl_event_lineno(ivl_event_t net);
|
|||
* Get the data type of the expression node. This uses the variable
|
||||
* type enum to express the type of the expression node.
|
||||
*
|
||||
* ivl_expr_net_type
|
||||
* This is used in some cases to carry more advanced type
|
||||
* descriptions. Over the long run, all type informatino will be
|
||||
* moved into the ivl_type_t type description method.
|
||||
*
|
||||
* ivl_expr_width
|
||||
* This method returns the bit width of the expression at this
|
||||
* node. It can be applied to any expression node, and returns the
|
||||
|
|
@ -851,6 +846,7 @@ extern unsigned ivl_event_lineno(ivl_event_t net);
|
|||
*/
|
||||
|
||||
extern ivl_expr_type_t ivl_expr_type(ivl_expr_t net);
|
||||
extern ivl_type_t ivl_expr_net_type(ivl_expr_t net);
|
||||
extern ivl_variable_type_t ivl_expr_value(ivl_expr_t net);
|
||||
extern const char*ivl_expr_file(ivl_expr_t net);
|
||||
extern unsigned ivl_expr_lineno(ivl_expr_t net);
|
||||
|
|
@ -1907,6 +1903,7 @@ extern unsigned ivl_signal_npath(ivl_signal_t net);
|
|||
extern ivl_delaypath_t ivl_signal_path(ivl_signal_t net, unsigned idx);
|
||||
extern ivl_signal_type_t ivl_signal_type(ivl_signal_t net);
|
||||
extern ivl_variable_type_t ivl_signal_data_type(ivl_signal_t net);
|
||||
extern ivl_type_t ivl_signal_net_type(ivl_signal_t net);
|
||||
extern const char* ivl_signal_name(ivl_signal_t net);
|
||||
extern const char* ivl_signal_basename(ivl_signal_t net);
|
||||
extern const char* ivl_signal_attr(ivl_signal_t net, const char*key);
|
||||
|
|
@ -1994,7 +1991,7 @@ extern unsigned ivl_stmt_lineno(ivl_statement_t net);
|
|||
* Statements that have event arguments (TRIGGER and WAIT) make
|
||||
* those event objects available through these methods.
|
||||
*
|
||||
* ivl_stmt_lval
|
||||
* ivl_stmt_lval
|
||||
* ivl_stmt_lvals
|
||||
* Return the number of l-values for an assignment statement, or
|
||||
* the specific l-value. If there is more than 1 l-value, then the
|
||||
|
|
@ -2195,6 +2192,25 @@ extern ivl_attribute_t ivl_switch_attr_val(ivl_switch_t net, unsigned idx);
|
|||
extern const char* ivl_switch_file(ivl_switch_t net);
|
||||
extern unsigned ivl_switch_lineno(ivl_switch_t net);
|
||||
|
||||
/* TYPES
|
||||
*
|
||||
* ivl_type_base
|
||||
* This returns the base type for the type. See the
|
||||
* ivl_variable_type_t definition for the various base types.
|
||||
*
|
||||
* ivl_type_element
|
||||
* Return the type of the element of an array. This is only valid
|
||||
* for array types.
|
||||
*
|
||||
* SEMANTIC NOTES
|
||||
*/
|
||||
extern ivl_variable_type_t ivl_type_base(ivl_type_t net);
|
||||
extern ivl_type_t ivl_type_element(ivl_type_t net);
|
||||
extern unsigned ivl_type_packed_dimensions(ivl_type_t net);
|
||||
extern int ivl_type_packed_lsb(ivl_type_t net, unsigned dim);
|
||||
extern int ivl_type_packed_msb(ivl_type_t net, unsigned dim);
|
||||
|
||||
|
||||
#if defined(__MINGW32__) || defined (__CYGWIN32__)
|
||||
# define DLLEXPORT __declspec(dllexport)
|
||||
#else
|
||||
|
|
|
|||
|
|
@ -89,7 +89,7 @@ unsigned NetAssign_::lwidth() const
|
|||
if (word_ == 0)
|
||||
return 1;
|
||||
else
|
||||
return darray->vector_width();
|
||||
return darray->element_width();
|
||||
}
|
||||
|
||||
return lwid_;
|
||||
|
|
@ -101,7 +101,7 @@ ivl_variable_type_t NetAssign_::expr_type() const
|
|||
if (word_ == 0)
|
||||
return IVL_VT_DARRAY;
|
||||
else
|
||||
return darray->data_type();
|
||||
return darray->element_base_type();
|
||||
}
|
||||
|
||||
return sig_->data_type();
|
||||
|
|
|
|||
69
net_expr.cc
69
net_expr.cc
|
|
@ -20,9 +20,40 @@
|
|||
# include "config.h"
|
||||
# include "netlist.h"
|
||||
# include "netenum.h"
|
||||
# include "netdarray.h"
|
||||
# include "compiler.h"
|
||||
# include "netmisc.h"
|
||||
# include <iostream>
|
||||
# include "ivl_assert.h"
|
||||
|
||||
NetExpr::NetExpr(unsigned w)
|
||||
: net_type_(0), width_(w), signed_flag_(false)
|
||||
{
|
||||
}
|
||||
|
||||
NetExpr::NetExpr(ivl_type_t t)
|
||||
: net_type_(t), width_(0), signed_flag_(false)
|
||||
{
|
||||
}
|
||||
|
||||
NetExpr::~NetExpr()
|
||||
{
|
||||
}
|
||||
|
||||
ivl_type_t NetExpr::net_type() const
|
||||
{
|
||||
return net_type_;
|
||||
}
|
||||
|
||||
void NetExpr::cast_signed(bool flag)
|
||||
{
|
||||
cast_signed_base_(flag);
|
||||
}
|
||||
|
||||
bool NetExpr::has_width() const
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
/*
|
||||
* the grand default data type is a logic vector.
|
||||
|
|
@ -317,6 +348,32 @@ ivl_select_type_t NetESelect::select_type() const
|
|||
return sel_type_;
|
||||
}
|
||||
|
||||
ivl_variable_type_t NetESelect::expr_type() const
|
||||
{
|
||||
ivl_variable_type_t type = expr_->expr_type();
|
||||
|
||||
// Special case: If the sub-expression is an IVL_VT_STRING,
|
||||
// then this node is representing a character select. The
|
||||
// width is the width of a byte, and the data type is BOOL.
|
||||
if (type == IVL_VT_STRING && expr_width()==8)
|
||||
return IVL_VT_BOOL;
|
||||
|
||||
if (type != IVL_VT_DARRAY)
|
||||
return type;
|
||||
|
||||
ivl_assert(*this, type == IVL_VT_DARRAY);
|
||||
|
||||
// Special case: If the expression is a DARRAY, then the
|
||||
// sub-expression must be a NetESignal and the type of the
|
||||
// NetESelect expression is the element type of the arrayed signal.
|
||||
NetESignal*sig = dynamic_cast<NetESignal*>(expr_);
|
||||
ivl_assert(*this, sig);
|
||||
const netarray_t*array_type = dynamic_cast<const netarray_t*> (sig->sig()->net_type());
|
||||
ivl_assert(*this, array_type);
|
||||
|
||||
return array_type->element_type()->base_type();
|
||||
}
|
||||
|
||||
bool NetESelect::has_width() const
|
||||
{
|
||||
return true;
|
||||
|
|
@ -330,6 +387,18 @@ NetESFunc::NetESFunc(const char*n, ivl_variable_type_t t,
|
|||
expr_width(width);
|
||||
}
|
||||
|
||||
NetESFunc::NetESFunc(const char*n, ivl_type_t rtype, unsigned np)
|
||||
: NetExpr(rtype), name_(0), type_(IVL_VT_NO_TYPE), enum_type_(0), parms_(np)
|
||||
{
|
||||
name_ = lex_strings.add(n);
|
||||
expr_width(rtype->packed_width());
|
||||
// FIXME: For now, assume that all uses of this constructor
|
||||
// are for the IVL_VT_DARRAY type. Eventually, the type_
|
||||
// member will go away.
|
||||
ivl_assert(*this, dynamic_cast<const netdarray_t*>(rtype));
|
||||
type_ = IVL_VT_DARRAY;
|
||||
}
|
||||
|
||||
NetESFunc::NetESFunc(const char*n, netenum_t*enum_type, unsigned np)
|
||||
: name_(0), type_(enum_type->base_type()), enum_type_(enum_type), parms_(np)
|
||||
{
|
||||
|
|
|
|||
10
netdarray.cc
10
netdarray.cc
|
|
@ -21,12 +21,16 @@
|
|||
|
||||
using namespace std;
|
||||
|
||||
netdarray_t::netdarray_t(const std::list<netrange_t>&packed,
|
||||
ivl_variable_type_t type, unsigned long wid)
|
||||
: packed_dims_(packed), type_(type), width_(wid)
|
||||
netdarray_t::netdarray_t(ivl_type_t vec)
|
||||
: netarray_t(vec)
|
||||
{
|
||||
}
|
||||
|
||||
netdarray_t::~netdarray_t()
|
||||
{
|
||||
}
|
||||
|
||||
ivl_variable_type_t netdarray_t::base_type(void) const
|
||||
{
|
||||
return IVL_VT_DARRAY;
|
||||
}
|
||||
|
|
|
|||
27
netdarray.h
27
netdarray.h
|
|
@ -21,23 +21,30 @@
|
|||
|
||||
# include "nettypes.h"
|
||||
# include "ivl_target.h"
|
||||
# include <list>
|
||||
|
||||
class netdarray_t : public nettype_base_t {
|
||||
class netdarray_t : public netarray_t {
|
||||
|
||||
public:
|
||||
explicit netdarray_t(const std::list<netrange_t>&packed,
|
||||
ivl_variable_type_t type,
|
||||
unsigned long wid);
|
||||
explicit netdarray_t(ivl_type_t vec);
|
||||
~netdarray_t();
|
||||
|
||||
inline ivl_variable_type_t data_type() const { return type_; }
|
||||
inline unsigned long vector_width(void) const { return width_; }
|
||||
// This is the "base_type()" virtual method of the
|
||||
// nettype_base_t. The ivl_target api expects this to return
|
||||
// IVL_VT_DARRAY for dynamic arrays?
|
||||
ivl_variable_type_t base_type() const;
|
||||
|
||||
// This is the base_type() of the element of the array. We
|
||||
// need this in some cases in order to get the base type of
|
||||
// the element, and not the IVL_VT_DARRAY of the array itself.
|
||||
inline ivl_variable_type_t element_base_type() const { return element_type()->base_type(); }
|
||||
|
||||
// This is a convenience function for getting the width of an
|
||||
// element. Strictly speaking it's not necessary.
|
||||
inline unsigned long element_width(void) const { return element_type()->packed_width(); }
|
||||
|
||||
std::ostream& debug_dump(std::ostream&) const;
|
||||
|
||||
private:
|
||||
std::list<netrange_t> packed_dims_;
|
||||
ivl_variable_type_t type_;
|
||||
unsigned long width_;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
|
|
|||
15
netenum.cc
15
netenum.cc
|
|
@ -21,6 +21,8 @@
|
|||
# include "compiler.h"
|
||||
# include <cassert>
|
||||
|
||||
using namespace std;
|
||||
|
||||
netenum_t::netenum_t(ivl_variable_type_t btype, bool signed_flag,
|
||||
long msb, long lsb, size_t name_count)
|
||||
: base_type_(btype), signed_flag_(signed_flag), msb_(msb), lsb_(lsb),
|
||||
|
|
@ -32,6 +34,11 @@ netenum_t::~netenum_t()
|
|||
{
|
||||
}
|
||||
|
||||
bool netenum_t::get_signed() const
|
||||
{
|
||||
return signed_flag_;
|
||||
}
|
||||
|
||||
long netenum_t::packed_width() const
|
||||
{
|
||||
if (msb_ >= lsb_)
|
||||
|
|
@ -40,6 +47,14 @@ long netenum_t::packed_width() const
|
|||
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)
|
||||
{
|
||||
std::pair<std::map<perm_string,verinum>::iterator, bool> res;
|
||||
|
|
|
|||
|
|
@ -29,7 +29,7 @@
|
|||
|
||||
class NetScope;
|
||||
|
||||
class netenum_t : public LineInfo, public nettype_base_t {
|
||||
class netenum_t : public LineInfo, public ivl_type_s {
|
||||
|
||||
public:
|
||||
explicit netenum_t(ivl_variable_type_t base_type, bool signed_flag,
|
||||
|
|
@ -38,7 +38,8 @@ class netenum_t : public LineInfo, public nettype_base_t {
|
|||
|
||||
ivl_variable_type_t base_type() const;
|
||||
long packed_width() const;
|
||||
bool has_sign() const;
|
||||
std::vector<netrange_t> slice_dimensions() const;
|
||||
bool get_signed() const;
|
||||
|
||||
// The size() is the number of enumeration literals.
|
||||
size_t size() const;
|
||||
|
|
@ -75,6 +76,4 @@ inline ivl_variable_type_t netenum_t::base_type() const
|
|||
|
||||
inline size_t netenum_t::size() const { return names_.size(); }
|
||||
|
||||
inline bool netenum_t::has_sign() const { return signed_flag_; }
|
||||
|
||||
#endif
|
||||
|
|
|
|||
239
netlist.cc
239
netlist.cc
|
|
@ -29,7 +29,9 @@
|
|||
# include "netmisc.h"
|
||||
# include "netdarray.h"
|
||||
# include "netenum.h"
|
||||
# include "netparray.h"
|
||||
# include "netstruct.h"
|
||||
# include "netvector.h"
|
||||
# include "ivl_assert.h"
|
||||
|
||||
|
||||
|
|
@ -463,44 +465,6 @@ PortType::Enum PortType::merged( Enum lhs, Enum rhs )
|
|||
return PINOUT;
|
||||
}
|
||||
|
||||
NetNet::NetNet(NetScope*s, perm_string n, Type t, unsigned npins)
|
||||
: NetObj(s, n, 1),
|
||||
type_(t), port_type_(NOT_A_PORT), data_type_(IVL_VT_NO_TYPE),
|
||||
signed_(false), isint_(false), is_scalar_(false), 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)
|
||||
{
|
||||
if (pins_are_virtual()) {
|
||||
|
|
@ -513,40 +477,6 @@ void NetNet::initialize_dir_(Link::DIR dir)
|
|||
}
|
||||
}
|
||||
|
||||
NetNet::NetNet(NetScope*s, perm_string n, Type t,
|
||||
const list<netrange_t>&packed)
|
||||
: NetObj(s, n, 1), type_(t),
|
||||
port_type_(NOT_A_PORT), data_type_(IVL_VT_NO_TYPE), signed_(false),
|
||||
isint_(false), is_scalar_(false), local_flag_(false),
|
||||
net_type_(0), discipline_(0),
|
||||
eref_count_(0), lref_count_(0)
|
||||
{
|
||||
packed_dims_ = packed;
|
||||
calculate_slice_widths_from_packed_dims_();
|
||||
assert(s);
|
||||
|
||||
Link::DIR dir = Link::PASSIVE;
|
||||
|
||||
switch (t) {
|
||||
case REG:
|
||||
case IMPLICIT_REG:
|
||||
dir = Link::OUTPUT;
|
||||
break;
|
||||
case SUPPLY0:
|
||||
dir = Link::OUTPUT;
|
||||
break;
|
||||
case SUPPLY1:
|
||||
dir = Link::OUTPUT;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
initialize_dir_(dir);
|
||||
|
||||
s->add_signal(this);
|
||||
}
|
||||
|
||||
static unsigned calculate_count(const list<netrange_t>&unpacked)
|
||||
{
|
||||
unsigned long sum = 1;
|
||||
|
|
@ -577,35 +507,35 @@ template <class T> static unsigned calculate_count(T*type)
|
|||
|
||||
void NetNet::calculate_slice_widths_from_packed_dims_(void)
|
||||
{
|
||||
if (packed_dims_.empty()) {
|
||||
slice_wids_.clear();
|
||||
ivl_assert(*this, net_type_);
|
||||
slice_dims_ = net_type_->slice_dimensions();
|
||||
|
||||
// Special case: There are no actual packed dimensions, so
|
||||
// build up a fake dimension of "1".
|
||||
if (slice_dims_.size() == 0) {
|
||||
slice_wids_.resize(1);
|
||||
slice_wids_[0] = net_type_->packed_width();
|
||||
return;
|
||||
}
|
||||
|
||||
slice_wids_.resize(packed_dims_.size());
|
||||
slice_wids_.resize(slice_dims_.size());
|
||||
|
||||
slice_wids_[0] = netrange_width(packed_dims_);
|
||||
list<netrange_t>::const_iterator cur = packed_dims_.begin();
|
||||
ivl_assert(*this, slice_wids_.size() >= 1);
|
||||
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) {
|
||||
slice_wids_[idx] = slice_wids_[idx-1] / cur->width();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
NetNet::NetNet(NetScope*s, perm_string n, Type t,
|
||||
const list<netrange_t>&packed,
|
||||
const list<netrange_t>&unpacked,
|
||||
nettype_base_t*net_type)
|
||||
const list<netrange_t>&unpacked, ivl_type_s*use_net_type)
|
||||
: NetObj(s, n, calculate_count(unpacked)),
|
||||
type_(t), port_type_(NOT_A_PORT),
|
||||
data_type_(IVL_VT_NO_TYPE), signed_(false), isint_(false),
|
||||
is_scalar_(false), local_flag_(false), net_type_(net_type),
|
||||
local_flag_(false), net_type_(use_net_type),
|
||||
discipline_(0), unpacked_dims_(unpacked.size()),
|
||||
eref_count_(0), lref_count_(0)
|
||||
{
|
||||
packed_dims_ = packed;
|
||||
if (net_type)
|
||||
packed_dims_.push_back(netrange_t(calculate_count(net_type)-1, 0));
|
||||
calculate_slice_widths_from_packed_dims_();
|
||||
size_t idx = 0;
|
||||
for (list<netrange_t>::const_iterator cur = unpacked.begin()
|
||||
|
|
@ -650,12 +580,11 @@ NetNet::NetNet(NetScope*s, perm_string n, Type t,
|
|||
NetNet::NetNet(NetScope*s, perm_string n, Type t, netstruct_t*ty)
|
||||
: NetObj(s, n, 1),
|
||||
type_(t), port_type_(NOT_A_PORT),
|
||||
data_type_(IVL_VT_NO_TYPE), signed_(false), isint_(false),
|
||||
is_scalar_(false), local_flag_(false), net_type_(ty),
|
||||
local_flag_(false), net_type_(ty),
|
||||
discipline_(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_();
|
||||
Link::DIR dir = Link::PASSIVE;
|
||||
|
||||
|
|
@ -682,8 +611,7 @@ NetNet::NetNet(NetScope*s, perm_string n, Type t, netstruct_t*ty)
|
|||
NetNet::NetNet(NetScope*s, perm_string n, Type t, netdarray_t*ty)
|
||||
: NetObj(s, n, 1),
|
||||
type_(t), port_type_(NOT_A_PORT),
|
||||
data_type_(IVL_VT_NO_TYPE), signed_(false), isint_(false),
|
||||
is_scalar_(false), local_flag_(false), net_type_(ty),
|
||||
local_flag_(false), net_type_(ty),
|
||||
discipline_(0),
|
||||
eref_count_(0), lref_count_(0)
|
||||
{
|
||||
|
|
@ -709,6 +637,36 @@ NetNet::NetNet(NetScope*s, perm_string n, Type t, netdarray_t*ty)
|
|||
s->add_signal(this);
|
||||
}
|
||||
|
||||
NetNet::NetNet(NetScope*s, perm_string n, Type t, netvector_t*ty)
|
||||
: NetObj(s, n, 1),
|
||||
type_(t), port_type_(NOT_A_PORT),
|
||||
local_flag_(false), net_type_(ty),
|
||||
discipline_(0),
|
||||
eref_count_(0), lref_count_(0)
|
||||
{
|
||||
calculate_slice_widths_from_packed_dims_();
|
||||
Link::DIR dir = Link::PASSIVE;
|
||||
|
||||
switch (t) {
|
||||
case REG:
|
||||
case IMPLICIT_REG:
|
||||
dir = Link::OUTPUT;
|
||||
break;
|
||||
case SUPPLY0:
|
||||
dir = Link::OUTPUT;
|
||||
break;
|
||||
case SUPPLY1:
|
||||
dir = Link::OUTPUT;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
initialize_dir_(dir);
|
||||
|
||||
s->add_signal(this);
|
||||
}
|
||||
|
||||
NetNet::~NetNet()
|
||||
{
|
||||
if (eref_count_ > 0) {
|
||||
|
|
@ -787,45 +745,34 @@ void NetNet::set_module_port_index(unsigned idx)
|
|||
|
||||
ivl_variable_type_t NetNet::data_type() const
|
||||
{
|
||||
return data_type_;
|
||||
}
|
||||
|
||||
void NetNet::data_type(ivl_variable_type_t t)
|
||||
{
|
||||
data_type_ = t;
|
||||
if (net_type_==0)
|
||||
return IVL_VT_LOGIC;
|
||||
else
|
||||
return net_type_->base_type();
|
||||
}
|
||||
|
||||
bool NetNet::get_signed() const
|
||||
{
|
||||
if (data_type_ == IVL_VT_REAL)
|
||||
return true;
|
||||
if (net_type_==0)
|
||||
return false;
|
||||
else
|
||||
return signed_;
|
||||
}
|
||||
|
||||
void NetNet::set_signed(bool flag)
|
||||
{
|
||||
signed_ = flag;
|
||||
return net_type_->get_signed();
|
||||
}
|
||||
|
||||
bool NetNet::get_isint() const
|
||||
{
|
||||
return isint_;
|
||||
}
|
||||
|
||||
void NetNet::set_isint(bool flag)
|
||||
{
|
||||
isint_ = flag;
|
||||
if (netvector_t*vec = dynamic_cast<netvector_t*> (net_type_))
|
||||
return vec->get_isint();
|
||||
else
|
||||
return false;
|
||||
}
|
||||
|
||||
bool NetNet::get_scalar() const
|
||||
{
|
||||
return is_scalar_;
|
||||
}
|
||||
|
||||
void NetNet::set_scalar(bool flag)
|
||||
{
|
||||
is_scalar_ = flag;
|
||||
if (netvector_t*vec = dynamic_cast<netvector_t*> (net_type_))
|
||||
return vec->get_scalar();
|
||||
else
|
||||
return false;
|
||||
}
|
||||
|
||||
netenum_t*NetNet::enumeration(void) const
|
||||
|
|
@ -833,9 +780,26 @@ netenum_t*NetNet::enumeration(void) const
|
|||
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
|
||||
|
|
@ -875,9 +839,9 @@ void NetNet::set_discipline(ivl_discipline_t dis)
|
|||
|
||||
bool NetNet::sb_is_valid(const list<long>&indices, long sb) const
|
||||
{
|
||||
ivl_assert(*this, indices.size()+1 == packed_dims_.size());
|
||||
assert(packed_dims_.size() == 1);
|
||||
const netrange_t&rng = packed_dims_.back();
|
||||
ivl_assert(*this, indices.size()+1 == packed_dims().size());
|
||||
assert(packed_dims().size() == 1);
|
||||
const netrange_t&rng = packed_dims().back();
|
||||
if (rng.get_msb() >= rng.get_lsb())
|
||||
return (sb <= rng.get_msb()) && (sb >= rng.get_lsb());
|
||||
else
|
||||
|
|
@ -886,9 +850,9 @@ bool NetNet::sb_is_valid(const list<long>&indices, long sb) const
|
|||
|
||||
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;
|
||||
|
||||
long acc_off;
|
||||
|
|
@ -924,8 +888,8 @@ long NetNet::sb_to_idx(const list<long>&indices, long sb) const
|
|||
|
||||
bool NetNet::sb_to_slice(const list<long>&indices, long sb, long&loff, unsigned long&lwid) const
|
||||
{
|
||||
ivl_assert(*this, indices.size() < packed_dims_.size());
|
||||
return prefix_to_slice(packed_dims_, indices, sb, loff, lwid);
|
||||
ivl_assert(*this, indices.size() < packed_dims().size());
|
||||
return prefix_to_slice(packed_dims(), indices, sb, loff, lwid);
|
||||
}
|
||||
|
||||
unsigned NetNet::unpacked_count() const
|
||||
|
|
@ -2265,25 +2229,6 @@ const NetScope* NetFree::scope() const
|
|||
return scope_;
|
||||
}
|
||||
|
||||
NetExpr::NetExpr(unsigned w)
|
||||
: width_(w), signed_flag_(false)
|
||||
{
|
||||
}
|
||||
|
||||
NetExpr::~NetExpr()
|
||||
{
|
||||
}
|
||||
|
||||
void NetExpr::cast_signed(bool flag)
|
||||
{
|
||||
cast_signed_base_(flag);
|
||||
}
|
||||
|
||||
bool NetExpr::has_width() const
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
/*
|
||||
* Create a bitwise operator node from the opcode and the left and
|
||||
* right expressions.
|
||||
|
|
@ -2480,14 +2425,14 @@ NetNet* NetESignal::sig()
|
|||
*/
|
||||
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);
|
||||
return packed.back().get_lsb();
|
||||
}
|
||||
|
||||
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);
|
||||
return packed.back().get_msb();
|
||||
}
|
||||
|
|
|
|||
59
netlist.h
59
netlist.h
|
|
@ -80,6 +80,7 @@ class netdarray_t;
|
|||
class netparray_t;
|
||||
class netenum_t;
|
||||
class netstruct_t;
|
||||
class netvector_t;
|
||||
|
||||
struct target;
|
||||
struct functor_t;
|
||||
|
|
@ -596,26 +597,18 @@ class NetNet : public NetObj, public PortType {
|
|||
typedef PortType::Enum PortType;
|
||||
|
||||
public:
|
||||
// The width in this case is a shorthand for ms=width-1 and
|
||||
// ls=0. Only one pin is created, the width is of the vector
|
||||
// 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.
|
||||
// This form is the more generic form of the constructor. For
|
||||
// now, the unpacked type is not burried into an ivl_type_s object.
|
||||
explicit NetNet(NetScope*s, perm_string n, Type t,
|
||||
const std::list<netrange_t>&packed);
|
||||
explicit NetNet(NetScope*s, perm_string n, Type t,
|
||||
const std::list<netrange_t>&packed,
|
||||
const std::list<netrange_t>&unpacked,
|
||||
nettype_base_t*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, netdarray_t*type);
|
||||
//explicit NetNet(NetScope*s, perm_string n, Type t, netparray_t*type);
|
||||
explicit NetNet(NetScope*s, perm_string n, Type t, netvector_t*type);
|
||||
|
||||
virtual ~NetNet();
|
||||
|
||||
|
|
@ -631,23 +624,20 @@ class NetNet : public NetObj, public PortType {
|
|||
void set_module_port_index(unsigned idx);
|
||||
|
||||
ivl_variable_type_t data_type() const;
|
||||
void data_type(ivl_variable_type_t t);
|
||||
|
||||
/* If a NetNet is signed, then its value is to be treated as
|
||||
signed. Otherwise, it is unsigned. */
|
||||
bool get_signed() const;
|
||||
void set_signed(bool);
|
||||
|
||||
/* Used to maintain original type of net since integers are
|
||||
implemented as 'reg signed [31:0]' in Icarus */
|
||||
bool get_isint() const;
|
||||
void set_isint(bool);
|
||||
|
||||
bool get_scalar() const;
|
||||
void set_scalar(bool);
|
||||
|
||||
inline const ivl_type_s* net_type(void) const { return net_type_; }
|
||||
netenum_t*enumeration(void) const;
|
||||
netstruct_t*struct_type(void) const;
|
||||
const netstruct_t*struct_type(void) const;
|
||||
netdarray_t*darray_type(void) const;
|
||||
|
||||
/* Attach a discipline to the net. */
|
||||
|
|
@ -657,8 +647,9 @@ class NetNet : public NetObj, public PortType {
|
|||
/* This method returns a reference to the packed dimensions
|
||||
for the vector. These are arranged as a list where the
|
||||
first range in the list (front) is the left-most range in
|
||||
the verilog declaration. */
|
||||
const std::list<netrange_t>& packed_dims() const { return packed_dims_; }
|
||||
the verilog declaration. These packed dims are compressed
|
||||
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_; }
|
||||
|
||||
|
|
@ -698,7 +689,7 @@ class NetNet : public NetObj, public PortType {
|
|||
|
||||
/* This methor returns 0 for scalars, but vectors and other
|
||||
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.
|
||||
unsigned unpacked_count() const;
|
||||
|
|
@ -733,15 +724,10 @@ class NetNet : public NetObj, public PortType {
|
|||
private:
|
||||
Type type_ : 5;
|
||||
PortType port_type_ : 3;
|
||||
ivl_variable_type_t data_type_ : 3;
|
||||
bool signed_ : 1;
|
||||
bool isint_ : 1; // original type of integer
|
||||
bool is_scalar_ : 1;
|
||||
bool local_flag_: 1;
|
||||
nettype_base_t*net_type_;
|
||||
ivl_type_s*net_type_;
|
||||
ivl_discipline_t discipline_;
|
||||
|
||||
std::list<netrange_t> packed_dims_;
|
||||
std::vector<netrange_t> unpacked_dims_;
|
||||
|
||||
// These are the widths of the various slice depths. There is
|
||||
|
|
@ -750,6 +736,7 @@ class NetNet : public NetObj, public PortType {
|
|||
//
|
||||
// For example: slice_wids_[0] is vector_width().
|
||||
void calculate_slice_widths_from_packed_dims_(void);
|
||||
std::vector<netrange_t> slice_dims_;
|
||||
std::vector<unsigned long> slice_wids_;
|
||||
|
||||
unsigned eref_count_;
|
||||
|
|
@ -764,7 +751,6 @@ class NetNet : public NetObj, public PortType {
|
|||
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
|
||||
|
|
@ -1753,11 +1739,18 @@ class NetTran : public NetNode, public IslandBranch {
|
|||
class NetExpr : public LineInfo {
|
||||
public:
|
||||
explicit NetExpr(unsigned w =0);
|
||||
explicit NetExpr(ivl_type_t t);
|
||||
virtual ~NetExpr() =0;
|
||||
|
||||
virtual void expr_scan(struct expr_scan_t*) const =0;
|
||||
virtual void dump(ostream&) const;
|
||||
|
||||
// This is the advanced description of the type. I think I
|
||||
// want to replace the other type description members with
|
||||
// this single method. The default for this method returns
|
||||
// nil.
|
||||
ivl_type_t net_type() const;
|
||||
|
||||
// Expressions have type.
|
||||
virtual ivl_variable_type_t expr_type() const;
|
||||
|
||||
|
|
@ -1826,6 +1819,7 @@ class NetExpr : public LineInfo {
|
|||
void cast_signed_base_(bool flag) { signed_flag_ = flag; }
|
||||
|
||||
private:
|
||||
ivl_type_t net_type_;
|
||||
unsigned width_;
|
||||
bool signed_flag_;
|
||||
|
||||
|
|
@ -3813,6 +3807,10 @@ class NetESelect : public NetExpr {
|
|||
const NetExpr*select() const;
|
||||
ivl_select_type_t select_type() const;
|
||||
|
||||
// The type of a NetESelect is the base type of the
|
||||
// sub-expression.
|
||||
virtual ivl_variable_type_t expr_type() const;
|
||||
|
||||
virtual NexusSet* nex_input(bool rem_out = true);
|
||||
virtual bool has_width() const;
|
||||
virtual void expr_scan(struct expr_scan_t*) const;
|
||||
|
|
@ -3906,6 +3904,7 @@ class NetESFunc : public NetExpr {
|
|||
public:
|
||||
NetESFunc(const char*name, ivl_variable_type_t t,
|
||||
unsigned width, unsigned nprms);
|
||||
NetESFunc(const char*name, ivl_type_t rtype, unsigned nprms);
|
||||
NetESFunc(const char*name, netenum_t*enum_type, unsigned nprms);
|
||||
~NetESFunc();
|
||||
|
||||
|
|
|
|||
49
netmisc.cc
49
netmisc.cc
|
|
@ -21,6 +21,7 @@
|
|||
|
||||
# include <cstdlib>
|
||||
# include "netlist.h"
|
||||
# include "netvector.h"
|
||||
# include "netmisc.h"
|
||||
# include "PExpr.h"
|
||||
# include "pform_types.h"
|
||||
|
|
@ -30,10 +31,11 @@
|
|||
|
||||
NetNet* sub_net_from(Design*des, NetScope*scope, long val, NetNet*sig)
|
||||
{
|
||||
netvector_t*zero_vec = new netvector_t(sig->data_type(),
|
||||
sig->vector_width()-1, 0);
|
||||
NetNet*zero_net = new NetNet(scope, scope->local_symbol(),
|
||||
NetNet::WIRE, sig->vector_width());
|
||||
NetNet::WIRE, zero_vec);
|
||||
zero_net->set_line(*sig);
|
||||
zero_net->data_type(sig->data_type());
|
||||
zero_net->local_flag(true);
|
||||
|
||||
if (sig->data_type() == IVL_VT_REAL) {
|
||||
|
|
@ -62,10 +64,11 @@ NetNet* sub_net_from(Design*des, NetScope*scope, long val, NetNet*sig)
|
|||
connect(zero_net->pin(0), adder->pin_DataA());
|
||||
connect(adder->pin_DataB(), sig->pin(0));
|
||||
|
||||
netvector_t*tmp_vec = new netvector_t(sig->data_type(),
|
||||
sig->vector_width()-1, 0);
|
||||
NetNet*tmp = new NetNet(scope, scope->local_symbol(),
|
||||
NetNet::WIRE, sig->vector_width());
|
||||
NetNet::WIRE, tmp_vec);
|
||||
tmp->set_line(*sig);
|
||||
tmp->data_type(sig->data_type());
|
||||
tmp->local_flag(true);
|
||||
|
||||
connect(adder->pin_Result(), tmp->pin(0));
|
||||
|
|
@ -78,9 +81,9 @@ NetNet* cast_to_int2(Design*des, NetScope*scope, NetNet*src, unsigned wid)
|
|||
if (src->data_type() == IVL_VT_BOOL)
|
||||
return src;
|
||||
|
||||
NetNet*tmp = new NetNet(scope, scope->local_symbol(), NetNet::WIRE, wid);
|
||||
netvector_t*tmp_vec = new netvector_t(IVL_VT_BOOL, wid-1, 0);
|
||||
NetNet*tmp = new NetNet(scope, scope->local_symbol(), NetNet::WIRE, tmp_vec);
|
||||
tmp->set_line(*src);
|
||||
tmp->data_type(IVL_VT_BOOL);
|
||||
tmp->local_flag(true);
|
||||
|
||||
NetCastInt2*cast = new NetCastInt2(scope, scope->local_symbol(), wid);
|
||||
|
|
@ -98,9 +101,9 @@ NetNet* cast_to_int4(Design*des, NetScope*scope, NetNet*src, unsigned wid)
|
|||
if (src->data_type() != IVL_VT_REAL)
|
||||
return src;
|
||||
|
||||
NetNet*tmp = new NetNet(scope, scope->local_symbol(), NetNet::WIRE, wid);
|
||||
netvector_t*tmp_vec = new netvector_t(IVL_VT_LOGIC, wid-1, 0);
|
||||
NetNet*tmp = new NetNet(scope, scope->local_symbol(), NetNet::WIRE, tmp_vec);
|
||||
tmp->set_line(*src);
|
||||
tmp->data_type(IVL_VT_LOGIC);
|
||||
tmp->local_flag(true);
|
||||
|
||||
NetCastInt4*cast = new NetCastInt4(scope, scope->local_symbol(), wid);
|
||||
|
|
@ -118,9 +121,9 @@ NetNet* cast_to_real(Design*des, NetScope*scope, NetNet*src)
|
|||
if (src->data_type() == IVL_VT_REAL)
|
||||
return src;
|
||||
|
||||
NetNet*tmp = new NetNet(scope, scope->local_symbol(), NetNet::WIRE);
|
||||
netvector_t*tmp_vec = new netvector_t(IVL_VT_REAL);
|
||||
NetNet*tmp = new NetNet(scope, scope->local_symbol(), NetNet::WIRE, tmp_vec);
|
||||
tmp->set_line(*src);
|
||||
tmp->data_type(IVL_VT_REAL);
|
||||
tmp->local_flag(true);
|
||||
|
||||
NetCastReal*cast = new NetCastReal(scope, scope->local_symbol(), src->get_signed());
|
||||
|
|
@ -149,6 +152,16 @@ NetExpr* cast_to_int2(NetExpr*expr)
|
|||
return cast;
|
||||
}
|
||||
|
||||
NetExpr* cast_to_real(NetExpr*expr)
|
||||
{
|
||||
if (expr->expr_type() == IVL_VT_REAL)
|
||||
return expr;
|
||||
|
||||
NetECast*cast = new NetECast('r', expr, 1, true);
|
||||
cast->set_line(*expr);
|
||||
return cast;
|
||||
}
|
||||
|
||||
/*
|
||||
* Add a signed constant to an existing expression. Generate a new
|
||||
* NetEBAdd node that has the input expression and an expression made
|
||||
|
|
@ -350,7 +363,7 @@ NetExpr *normalize_variable_base(NetExpr *base,
|
|||
NetExpr *normalize_variable_bit_base(const list<long>&indices, NetExpr*base,
|
||||
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());
|
||||
|
||||
// Get the canonical offset of the slice within which we are
|
||||
|
|
@ -366,7 +379,7 @@ NetExpr *normalize_variable_part_base(const list<long>&indices, NetExpr*base,
|
|||
const NetNet*reg,
|
||||
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());
|
||||
|
||||
// Get the canonical offset of the slice within which we are
|
||||
|
|
@ -381,10 +394,10 @@ NetExpr *normalize_variable_part_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 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());
|
||||
|
||||
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) {
|
||||
-- pcur;
|
||||
}
|
||||
|
|
@ -630,9 +643,9 @@ NetNet* make_const_x(Design*des, NetScope*scope, unsigned long wid)
|
|||
NetConst*res = new NetConst(scope, scope->local_symbol(), xxx);
|
||||
des->add_node(res);
|
||||
|
||||
NetNet*sig = new NetNet(scope, scope->local_symbol(), NetNet::WIRE, wid);
|
||||
netvector_t*sig_vec = new netvector_t(IVL_VT_LOGIC, wid-1, 0);
|
||||
NetNet*sig = new NetNet(scope, scope->local_symbol(), NetNet::WIRE, sig_vec);
|
||||
sig->local_flag(true);
|
||||
sig->data_type(IVL_VT_LOGIC);
|
||||
|
||||
connect(sig->pin(0), res->pin(0));
|
||||
return sig;
|
||||
|
|
@ -1179,8 +1192,8 @@ NetExpr*collapse_array_exprs(Design*des, NetScope*scope,
|
|||
return *exprs.begin();
|
||||
}
|
||||
|
||||
const std::list<netrange_t>&pdims = net->packed_dims();
|
||||
std::list<netrange_t>::const_iterator pcur = pdims.begin();
|
||||
const std::vector<netrange_t>&pdims = net->packed_dims();
|
||||
std::vector<netrange_t>::const_iterator pcur = pdims.begin();
|
||||
|
||||
list<NetExpr*>::iterator ecur = exprs.begin();
|
||||
NetExpr* base = 0;
|
||||
|
|
|
|||
|
|
@ -79,6 +79,7 @@ extern NetNet*cast_to_int2(Design*des, NetScope*scope, NetNet*src, unsigned wid)
|
|||
extern NetNet*cast_to_real(Design*des, NetScope*scope, NetNet*src);
|
||||
|
||||
extern NetExpr*cast_to_int2(NetExpr*expr);
|
||||
extern NetExpr*cast_to_real(NetExpr*expr);
|
||||
|
||||
/*
|
||||
* Take the input expression and return a variation that assures that
|
||||
|
|
|
|||
|
|
@ -0,0 +1,57 @@
|
|||
/*
|
||||
* 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;
|
||||
|
||||
netparray_t::~netparray_t()
|
||||
{
|
||||
}
|
||||
|
||||
/*
|
||||
* 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;
|
||||
}
|
||||
25
netparray.h
25
netparray.h
|
|
@ -20,33 +20,36 @@
|
|||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
||||
*/
|
||||
|
||||
# include "LineInfo.h"
|
||||
# include "nettypes.h"
|
||||
# include <vector>
|
||||
|
||||
/*
|
||||
* Packed arrays.
|
||||
*/
|
||||
class netparray_t : public nettype_base_t, public LineInfo {
|
||||
class netparray_t : public netarray_t {
|
||||
|
||||
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();
|
||||
|
||||
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;
|
||||
|
||||
public:
|
||||
inline const std::vector<netrange_t>& packed_dimensions() const
|
||||
{ return packed_dims_; }
|
||||
|
||||
private:
|
||||
std::list<netrange_t> packed_dims_;
|
||||
std::vector<netrange_t> packed_dims_;
|
||||
|
||||
};
|
||||
|
||||
inline netparray_t::netparray_t(const std::list<netrange_t>&packed)
|
||||
: packed_dims_(packed)
|
||||
{
|
||||
}
|
||||
|
||||
inline netparray_t::~netparray_t()
|
||||
inline netparray_t::netparray_t(const std::vector<netrange_t>&packed,
|
||||
ivl_type_t etype)
|
||||
: netarray_t(etype), packed_dims_(packed)
|
||||
{
|
||||
}
|
||||
|
||||
|
|
|
|||
20
netstruct.cc
20
netstruct.cc
|
|
@ -66,3 +66,23 @@ long netstruct_t::packed_width(void) const
|
|||
|
||||
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
|
||||
{
|
||||
if (! packed_)
|
||||
return IVL_VT_NO_TYPE;
|
||||
|
||||
for (size_t idx = 0 ; idx < members_.size() ; idx += 1) {
|
||||
if (members_[idx].data_type() != IVL_VT_BOOL)
|
||||
return members_[idx].data_type();
|
||||
}
|
||||
|
||||
return IVL_VT_BOOL;
|
||||
}
|
||||
|
|
|
|||
11
netstruct.h
11
netstruct.h
|
|
@ -20,17 +20,17 @@
|
|||
*/
|
||||
|
||||
# include "LineInfo.h"
|
||||
# include <vector>
|
||||
# include <vector>
|
||||
# include "ivl_target.h"
|
||||
# include "nettypes.h"
|
||||
|
||||
class netstruct_t : public LineInfo, public nettype_base_t {
|
||||
class netstruct_t : public LineInfo, public ivl_type_s {
|
||||
|
||||
public:
|
||||
struct member_t {
|
||||
perm_string name;
|
||||
ivl_variable_type_t type;
|
||||
list<netrange_t> packed_dims;
|
||||
std::vector<netrange_t> packed_dims;
|
||||
long width() const;
|
||||
ivl_variable_type_t data_type() const { return type; };
|
||||
// We need to keep the individual element sign information.
|
||||
|
|
@ -54,6 +54,11 @@ class netstruct_t : public LineInfo, public nettype_base_t {
|
|||
// Return the width (in bits) of the packed record, or -1 if
|
||||
// the record is not packed.
|
||||
long packed_width() const;
|
||||
std::vector<netrange_t> slice_dimensions() const;
|
||||
|
||||
// Return the base type of the packed record, or
|
||||
// IVL_VT_NO_TYPE if the record is not packed.
|
||||
ivl_variable_type_t base_type() const;
|
||||
|
||||
private:
|
||||
bool packed_;
|
||||
|
|
|
|||
38
nettypes.cc
38
nettypes.cc
|
|
@ -22,19 +22,43 @@
|
|||
|
||||
using namespace std;
|
||||
|
||||
nettype_base_t::~nettype_base_t()
|
||||
ivl_type_s::~ivl_type_s()
|
||||
{
|
||||
}
|
||||
|
||||
long nettype_base_t::packed_width(void) const
|
||||
long ivl_type_s::packed_width(void) const
|
||||
{
|
||||
return 0;
|
||||
return 1;
|
||||
}
|
||||
|
||||
unsigned long netrange_width(const list<netrange_t>&packed)
|
||||
vector<netrange_t> ivl_type_s::slice_dimensions() const
|
||||
{
|
||||
return vector<netrange_t>();
|
||||
}
|
||||
|
||||
ivl_variable_type_t ivl_type_s::base_type() const
|
||||
{
|
||||
return IVL_VT_NO_TYPE;
|
||||
}
|
||||
|
||||
bool ivl_type_s::get_signed() const
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
netarray_t::~netarray_t()
|
||||
{
|
||||
}
|
||||
|
||||
ivl_variable_type_t netarray_t::base_type() const
|
||||
{
|
||||
return element_type_->base_type();
|
||||
}
|
||||
|
||||
unsigned long netrange_width(const vector<netrange_t>&packed)
|
||||
{
|
||||
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) {
|
||||
unsigned use_wid = cur->width();
|
||||
wid *= use_wid;
|
||||
|
|
@ -49,14 +73,14 @@ unsigned long netrange_width(const list<netrange_t>&packed)
|
|||
* and width of the resulting slice. In this case, the "sb" argument
|
||||
* 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,
|
||||
long&loff, unsigned long&lwid)
|
||||
{
|
||||
assert(prefix.size() < dims.size());
|
||||
|
||||
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) {
|
||||
-- pcur;
|
||||
acc_wid *= pcur->width();
|
||||
|
|
|
|||
55
nettypes.h
55
nettypes.h
|
|
@ -19,20 +19,58 @@
|
|||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
*/
|
||||
|
||||
# include <list>
|
||||
# include <climits>
|
||||
# include <cassert>
|
||||
# include "ivl_target.h"
|
||||
# include <list>
|
||||
# include <vector>
|
||||
# include <climits>
|
||||
# include <ostream>
|
||||
# include <cassert>
|
||||
|
||||
class netrange_t;
|
||||
|
||||
/*
|
||||
* This is a fully abstract type that is a type that can be attached
|
||||
* to a NetNet object.
|
||||
*/
|
||||
class nettype_base_t {
|
||||
class ivl_type_s {
|
||||
public:
|
||||
virtual ~nettype_base_t() =0;
|
||||
virtual ~ivl_type_s() =0;
|
||||
virtual long packed_width(void) const;
|
||||
virtual std::vector<netrange_t> slice_dimensions() const;
|
||||
|
||||
// Some types have a base variable type.
|
||||
virtual ivl_variable_type_t base_type() const;
|
||||
virtual bool get_signed() const;
|
||||
|
||||
virtual std::ostream& debug_dump(std::ostream&) const;
|
||||
};
|
||||
|
||||
/*
|
||||
* There are a couple types of array types. This class represents the
|
||||
* common bits of array types.
|
||||
*/
|
||||
class netarray_t : public ivl_type_s {
|
||||
|
||||
public:
|
||||
inline explicit netarray_t(ivl_type_t etype) : element_type_(etype) { }
|
||||
~netarray_t();
|
||||
|
||||
public:
|
||||
// Some virtual methods have a common implementation for arrays.
|
||||
ivl_variable_type_t base_type() const;
|
||||
|
||||
public:
|
||||
inline ivl_type_t element_type() const { return element_type_; }
|
||||
|
||||
private:
|
||||
ivl_type_t element_type_;
|
||||
};
|
||||
|
||||
inline static std::ostream& operator << (std::ostream&out, const ivl_type_s&obj)
|
||||
{
|
||||
return obj.debug_dump(out);
|
||||
}
|
||||
|
||||
class netrange_t {
|
||||
|
||||
public:
|
||||
|
|
@ -65,14 +103,17 @@ class netrange_t {
|
|||
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
|
||||
* indices, and calculate the offset/width of the resulting slice into
|
||||
* 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,
|
||||
long&loff, unsigned long&lwid);
|
||||
|
||||
|
|
|
|||
|
|
@ -0,0 +1,52 @@
|
|||
/*
|
||||
* Copyright (c) 2012 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 "netvector.h"
|
||||
|
||||
using namespace std;
|
||||
|
||||
netvector_t::netvector_t(ivl_variable_type_t type, long msb, long lsb)
|
||||
: type_(type), signed_(false)
|
||||
{
|
||||
packed_dims_.push_back(netrange_t(msb,lsb));
|
||||
}
|
||||
|
||||
netvector_t::netvector_t(ivl_variable_type_t type)
|
||||
: type_(type), signed_(false)
|
||||
{
|
||||
}
|
||||
|
||||
netvector_t::~netvector_t()
|
||||
{
|
||||
}
|
||||
|
||||
ivl_variable_type_t netvector_t::base_type() const
|
||||
{
|
||||
return type_;
|
||||
}
|
||||
|
||||
long netvector_t::packed_width() const
|
||||
{
|
||||
return netrange_width(packed_dims_);
|
||||
}
|
||||
|
||||
vector<netrange_t> netvector_t::slice_dimensions() const
|
||||
{
|
||||
return packed_dims_;
|
||||
}
|
||||
|
|
@ -0,0 +1,91 @@
|
|||
#ifndef __netvector_H
|
||||
#define __netvector_H
|
||||
/*
|
||||
* Copyright (c) 2012 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 "nettypes.h"
|
||||
# include "ivl_target.h"
|
||||
# include <vector>
|
||||
|
||||
class netvector_t : public ivl_type_s {
|
||||
|
||||
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,
|
||||
ivl_variable_type_t type);
|
||||
|
||||
// special case: there is a single packed dimension and we
|
||||
// know it in the form [<msb>:<lsb>]. This step saves me
|
||||
// creating a netrange_t for this single item.
|
||||
explicit netvector_t(ivl_variable_type_t type, long msb, long lsb);
|
||||
|
||||
// Special case: scaler object--no packed dimenions at all.
|
||||
explicit netvector_t(ivl_variable_type_t type);
|
||||
|
||||
~netvector_t();
|
||||
|
||||
// Vectors can be interpreted as signed or unsigned when
|
||||
// handled as vectors.
|
||||
inline void set_signed(bool flag) { signed_ = flag; }
|
||||
inline bool get_signed(void) const { return signed_; }
|
||||
|
||||
inline void set_isint(bool flag) { isint_ = flag; }
|
||||
inline bool get_isint(void) const { return isint_; }
|
||||
|
||||
inline void set_scalar(bool flag) { is_scalar_ = flag; }
|
||||
inline bool get_scalar(void) const { return is_scalar_; }
|
||||
|
||||
ivl_variable_type_t base_type() const;
|
||||
const std::vector<netrange_t>&packed_dims() const;
|
||||
|
||||
long packed_width() const;
|
||||
std::vector<netrange_t> slice_dimensions() const;
|
||||
|
||||
std::ostream& debug_dump(std::ostream&) const;
|
||||
|
||||
private:
|
||||
std::vector<netrange_t> packed_dims_;
|
||||
ivl_variable_type_t type_;
|
||||
bool signed_ : 1;
|
||||
bool isint_ : 1; // original type of integer
|
||||
bool is_scalar_ : 1;
|
||||
};
|
||||
|
||||
inline netvector_t::netvector_t(const std::vector<netrange_t>&packed,
|
||||
ivl_variable_type_t type)
|
||||
: packed_dims_(packed), type_(type), signed_(false)
|
||||
{
|
||||
}
|
||||
|
||||
inline const std::vector<netrange_t>& netvector_t::packed_dims() const
|
||||
{
|
||||
return packed_dims_;
|
||||
}
|
||||
|
||||
inline static std::ostream& operator << (std::ostream&out, const netvector_t&obj)
|
||||
{
|
||||
return obj.debug_dump(out);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
|
@ -20,6 +20,7 @@
|
|||
# include "config.h"
|
||||
|
||||
# include "netlist.h"
|
||||
# include "netvector.h"
|
||||
# include "netmisc.h"
|
||||
|
||||
|
||||
|
|
@ -77,19 +78,20 @@ NetNet*pad_to_width(Design*des, NetNet*net, unsigned wid, const LineInfo&info)
|
|||
connect(cc->pin(2), con->pin(0));
|
||||
|
||||
// Make a NetNet for the NetConst to NetConcat link.
|
||||
netvector_t*tmp_vec = new netvector_t(net->data_type(),
|
||||
wid - net->vector_width() - 1, 0);
|
||||
NetNet*tmp = new NetNet(scope, scope->local_symbol(),
|
||||
NetNet::WIRE, wid - net->vector_width());
|
||||
NetNet::WIRE, tmp_vec);
|
||||
tmp->set_line(info);
|
||||
tmp->data_type( net->data_type() );
|
||||
tmp->local_flag(true);
|
||||
connect(cc->pin(2), tmp->pin(0));
|
||||
|
||||
// Create a NetNet of the output width and connect it to the
|
||||
// NetConcat node output pin.
|
||||
tmp_vec = new netvector_t(net->data_type(), wid-1, 0);
|
||||
tmp = new NetNet(scope, scope->local_symbol(),
|
||||
NetNet::WIRE, wid);
|
||||
NetNet::WIRE, tmp_vec);
|
||||
tmp->set_line(info);
|
||||
tmp->data_type( net->data_type() );
|
||||
tmp->local_flag(true);
|
||||
connect(cc->pin(0), tmp->pin(0));
|
||||
|
||||
|
|
@ -109,11 +111,11 @@ NetNet*pad_to_width_signed(Design*des, NetNet*net, unsigned wid,
|
|||
se->set_line(info);
|
||||
des->add_node(se);
|
||||
|
||||
NetNet*tmp = new NetNet(scope, scope->local_symbol(), NetNet::WIRE, wid);
|
||||
netvector_t*tmp_vec = new netvector_t(net->data_type(), wid-1, 0);
|
||||
tmp_vec->set_signed(true);
|
||||
NetNet*tmp = new NetNet(scope, scope->local_symbol(), NetNet::WIRE, tmp_vec);
|
||||
tmp->set_line(info);
|
||||
tmp->local_flag(true);
|
||||
tmp->data_type(net->data_type());
|
||||
tmp->set_signed(true);
|
||||
|
||||
connect(tmp->pin(0), se->pin(0));
|
||||
connect(se->pin(1), net->pin(0));
|
||||
|
|
@ -132,10 +134,10 @@ NetNet*crop_to_width(Design*des, NetNet*net, unsigned wid)
|
|||
ps->set_line(*net);
|
||||
des->add_node(ps);
|
||||
|
||||
netvector_t*tmp_vec = new netvector_t(net->data_type(), wid-1, 0);
|
||||
NetNet*tmp = new NetNet(scope, scope->local_symbol(),
|
||||
NetNet::WIRE, wid);
|
||||
NetNet::WIRE, tmp_vec);
|
||||
tmp->set_line(*net);
|
||||
tmp->data_type(net->data_type());
|
||||
tmp->local_flag(true);
|
||||
connect(ps->pin(0), tmp->pin(0));
|
||||
|
||||
|
|
|
|||
|
|
@ -153,6 +153,28 @@ void parray_type_t::pform_dump(ostream&out, unsigned indent) const
|
|||
base_type->pform_dump(out, indent+4);
|
||||
}
|
||||
|
||||
void struct_type_t::pform_dump(ostream&out, unsigned indent) const
|
||||
{
|
||||
out << setw(indent) << "" << "Struct " << (packed_flag?"packed":"unpacked")
|
||||
<< " with " << members->size() << " members" << endl;
|
||||
for (list<struct_member_t*>::iterator cur = members->begin()
|
||||
; cur != members->end() ; ++ cur) {
|
||||
struct_member_t*curp = *cur;
|
||||
curp->pform_dump(out, indent+4);
|
||||
}
|
||||
}
|
||||
|
||||
void struct_member_t::pform_dump(ostream&out, unsigned indent) const
|
||||
{
|
||||
out << setw(indent) << "" << type;
|
||||
for (list<decl_assignment_t*>::iterator cur = names->begin()
|
||||
; cur != names->end() ; ++cur) {
|
||||
decl_assignment_t*curp = *cur;
|
||||
out << " " << curp->name;
|
||||
}
|
||||
out << ";" << endl;
|
||||
}
|
||||
|
||||
static void dump_attributes_map(ostream&out,
|
||||
const map<perm_string,PExpr*>&attributes,
|
||||
int ind)
|
||||
|
|
|
|||
|
|
@ -97,10 +97,13 @@ struct struct_member_t : public LineInfo {
|
|||
ivl_variable_type_t type;
|
||||
std::auto_ptr< list<pform_range_t> > range;
|
||||
std::auto_ptr< list<decl_assignment_t*> > names;
|
||||
void pform_dump(std::ostream&out, unsigned indent) const;
|
||||
};
|
||||
|
||||
struct struct_type_t : public data_type_t {
|
||||
virtual ivl_variable_type_t figure_packed_base_type(void)const;
|
||||
virtual void pform_dump(std::ostream&out, unsigned indent) const;
|
||||
|
||||
bool packed_flag;
|
||||
std::auto_ptr< list<struct_member_t*> > members;
|
||||
};
|
||||
|
|
|
|||
|
|
@ -21,6 +21,7 @@
|
|||
|
||||
# include "functor.h"
|
||||
# include "netlist.h"
|
||||
# include "netvector.h"
|
||||
# include "netmisc.h"
|
||||
# include "compiler.h"
|
||||
# include <cassert>
|
||||
|
|
@ -221,10 +222,10 @@ bool NetCase::synth_async(Design*des, NetScope*scope,
|
|||
continue;
|
||||
}
|
||||
|
||||
netvector_t*isig_vec = new netvector_t(mux_data_type, mux_width-1, 0);
|
||||
isig = new NetNet(scope, scope->local_symbol(),
|
||||
NetNet::TRI, mux_width);
|
||||
NetNet::TRI, isig_vec);
|
||||
isig->local_flag(true);
|
||||
isig->data_type(mux_data_type);
|
||||
|
||||
connect(mux->pin_Data(idx), isig->pin(0));
|
||||
|
||||
|
|
|
|||
62
t-dll-api.cc
62
t-dll-api.cc
|
|
@ -21,7 +21,9 @@
|
|||
# include "StringHeap.h"
|
||||
# include "t-dll.h"
|
||||
# include "discipline.h"
|
||||
# include "netdarray.h"
|
||||
# include "netenum.h"
|
||||
# include "netvector.h"
|
||||
# include <cstdlib>
|
||||
# include <cstdio>
|
||||
# include <cstring>
|
||||
|
|
@ -265,7 +267,7 @@ extern "C" unsigned ivl_enum_width(ivl_enumtype_t net)
|
|||
extern "C" int ivl_enum_signed(ivl_enumtype_t net)
|
||||
{
|
||||
assert(net);
|
||||
return net->has_sign();
|
||||
return net->get_signed();
|
||||
}
|
||||
|
||||
extern "C" const char*ivl_enum_file(ivl_enumtype_t net)
|
||||
|
|
@ -411,6 +413,11 @@ extern "C" ivl_enumtype_t ivl_expr_enumtype(ivl_expr_t net)
|
|||
return net->u_.enumtype_.type;
|
||||
}
|
||||
|
||||
extern "C" ivl_type_t ivl_expr_net_type(ivl_expr_t net)
|
||||
{
|
||||
return net->net_type;
|
||||
}
|
||||
|
||||
extern "C" const char* ivl_expr_name(ivl_expr_t net)
|
||||
{
|
||||
switch (net->type_) {
|
||||
|
|
@ -1422,7 +1429,7 @@ extern "C" int ivl_lpm_signed(ivl_lpm_t net)
|
|||
case IVL_LPM_REPEAT:
|
||||
return 0;
|
||||
case IVL_LPM_ARRAY: // Array ports take the signedness of the array.
|
||||
return net->u_.array.sig->signed_;
|
||||
return net->u_.array.sig->net_type->get_signed()? 1 : 0;
|
||||
default:
|
||||
assert(0);
|
||||
return 0;
|
||||
|
|
@ -2231,7 +2238,7 @@ extern "C" ivl_scope_t ivl_signal_scope(ivl_signal_t net)
|
|||
|
||||
extern "C" unsigned ivl_signal_width(ivl_signal_t net)
|
||||
{
|
||||
return net->width_;
|
||||
return net->net_type->packed_width();
|
||||
}
|
||||
|
||||
extern "C" ivl_signal_port_t ivl_signal_port(ivl_signal_t net)
|
||||
|
|
@ -2251,7 +2258,7 @@ extern "C" int ivl_signal_local(ivl_signal_t net)
|
|||
|
||||
extern "C" int ivl_signal_signed(ivl_signal_t net)
|
||||
{
|
||||
return net->signed_;
|
||||
return net->net_type->get_signed()? 1 : 0;
|
||||
}
|
||||
|
||||
extern "C" unsigned ivl_signal_forced_net(ivl_signal_t net)
|
||||
|
|
@ -2273,12 +2280,20 @@ extern "C" unsigned ivl_signal_lineno(ivl_signal_t net)
|
|||
|
||||
extern "C" int ivl_signal_integer(ivl_signal_t net)
|
||||
{
|
||||
return net->isint_;
|
||||
if (const netvector_t*vec = dynamic_cast<const netvector_t*> (net->net_type))
|
||||
return vec->get_isint()? 1 : 0;
|
||||
else
|
||||
return 0;
|
||||
}
|
||||
|
||||
extern "C" ivl_variable_type_t ivl_signal_data_type(ivl_signal_t net)
|
||||
{
|
||||
return net->data_type;
|
||||
return net->net_type->base_type();
|
||||
}
|
||||
|
||||
extern "C" ivl_type_t ivl_signal_net_type(ivl_signal_t net)
|
||||
{
|
||||
return net->net_type;
|
||||
}
|
||||
|
||||
extern "C" unsigned ivl_signal_npath(ivl_signal_t net)
|
||||
|
|
@ -2773,3 +2788,38 @@ extern "C" unsigned ivl_switch_lineno(ivl_switch_t net)
|
|||
{
|
||||
return net->lineno;
|
||||
}
|
||||
|
||||
extern "C" ivl_variable_type_t ivl_type_base(ivl_type_t net)
|
||||
{
|
||||
if (net == 0) return IVL_VT_NO_TYPE;
|
||||
else return net->base_type();
|
||||
}
|
||||
|
||||
extern "C" ivl_type_t ivl_type_element(ivl_type_t net)
|
||||
{
|
||||
if (const netarray_t*da = dynamic_cast<const netarray_t*> (net))
|
||||
return da->element_type();
|
||||
|
||||
assert(0);
|
||||
return 0;
|
||||
}
|
||||
|
||||
extern "C" unsigned ivl_type_packed_dimensions(ivl_type_t net)
|
||||
{
|
||||
vector<netrange_t> slice = net->slice_dimensions();
|
||||
return slice.size();
|
||||
}
|
||||
|
||||
extern "C" int ivl_type_packed_lsb(ivl_type_t net, unsigned dim)
|
||||
{
|
||||
vector<netrange_t> slice = net->slice_dimensions();
|
||||
assert(dim < slice.size());
|
||||
return slice[dim].get_lsb();
|
||||
}
|
||||
|
||||
extern "C" int ivl_type_packed_msb(ivl_type_t net, unsigned dim)
|
||||
{
|
||||
vector<netrange_t> slice = net->slice_dimensions();
|
||||
assert(dim < slice.size());
|
||||
return slice[dim].get_msb();
|
||||
}
|
||||
|
|
|
|||
|
|
@ -56,6 +56,7 @@ void dll_target::sub_off_from_expr_(long off)
|
|||
ivl_expr_t tmpc = (ivl_expr_t)calloc(1, sizeof(struct ivl_expr_s));
|
||||
tmpc->type_ = IVL_EX_NUMBER;
|
||||
tmpc->value_ = IVL_VT_VECTOR;
|
||||
tmpc->net_type= 0;
|
||||
tmpc->width_ = expr_->width_;
|
||||
tmpc->signed_ = expr_->signed_;
|
||||
tmpc->sized_ = 1;
|
||||
|
|
@ -71,6 +72,7 @@ void dll_target::sub_off_from_expr_(long off)
|
|||
ivl_expr_t tmps = (ivl_expr_t)calloc(1, sizeof(struct ivl_expr_s));
|
||||
tmps->type_ = IVL_EX_BINARY;
|
||||
tmps->value_ = IVL_VT_VECTOR;
|
||||
tmps->net_type= 0;
|
||||
tmps->width_ = tmpc->width_;
|
||||
tmps->signed_ = tmpc->signed_;
|
||||
tmps->sized_ = 1;
|
||||
|
|
@ -90,6 +92,7 @@ void dll_target::mul_expr_by_const_(long val)
|
|||
ivl_expr_t tmpc = (ivl_expr_t)calloc(1, sizeof(struct ivl_expr_s));
|
||||
tmpc->type_ = IVL_EX_NUMBER;
|
||||
tmpc->value_ = IVL_VT_VECTOR;
|
||||
tmpc->net_type= 0;
|
||||
tmpc->width_ = expr_->width_;
|
||||
tmpc->signed_ = expr_->signed_;
|
||||
tmpc->sized_ = 1;
|
||||
|
|
@ -105,6 +108,7 @@ void dll_target::mul_expr_by_const_(long val)
|
|||
ivl_expr_t tmps = (ivl_expr_t)calloc(1, sizeof(struct ivl_expr_s));
|
||||
tmps->type_ = IVL_EX_BINARY;
|
||||
tmps->value_ = IVL_VT_VECTOR;
|
||||
tmpc->net_type= 0;
|
||||
tmps->width_ = tmpc->width_;
|
||||
tmps->signed_ = tmpc->signed_;
|
||||
tmps->sized_ = 1;
|
||||
|
|
@ -124,6 +128,7 @@ ivl_expr_t dll_target::expr_from_value_(const verinum&val)
|
|||
char*bits;
|
||||
expr->type_ = IVL_EX_NUMBER;
|
||||
expr->value_= IVL_VT_VECTOR;
|
||||
expr->net_type=0;
|
||||
expr->width_= val.len();
|
||||
expr->signed_ = val.has_sign()? 1 : 0;
|
||||
expr->sized_= 1;
|
||||
|
|
@ -158,6 +163,7 @@ void dll_target::expr_access_func(const NetEAccess*net)
|
|||
expr_ = (ivl_expr_t)calloc(1, sizeof(struct ivl_expr_s));
|
||||
expr_->type_ = IVL_EX_BACCESS;
|
||||
expr_->value_ = IVL_VT_REAL;
|
||||
expr_->net_type=0;
|
||||
expr_->width_ = 1;
|
||||
expr_->signed_= 1;
|
||||
expr_->sized_ = 1;
|
||||
|
|
@ -182,6 +188,7 @@ void dll_target::expr_binary(const NetEBinary*net)
|
|||
|
||||
expr_->type_ = IVL_EX_BINARY;
|
||||
expr_->value_= get_expr_type(net);
|
||||
expr_->net_type=0;
|
||||
expr_->width_= net->expr_width();
|
||||
expr_->signed_ = net->has_sign()? 1 : 0;
|
||||
expr_->sized_= 1;
|
||||
|
|
@ -201,6 +208,7 @@ void dll_target::expr_concat(const NetEConcat*net)
|
|||
|
||||
cur->type_ = IVL_EX_CONCAT;
|
||||
cur->value_ = net->expr_type();
|
||||
cur->net_type=0;
|
||||
cur->width_ = net->expr_width();
|
||||
cur->signed_ = net->has_sign() ? 1 : 0;
|
||||
cur->sized_ = 1;
|
||||
|
|
@ -226,6 +234,7 @@ void dll_target::expr_const(const NetEConst*net)
|
|||
|
||||
expr_ = (ivl_expr_t)calloc(1, sizeof(struct ivl_expr_s));
|
||||
expr_->value_= net->expr_type();
|
||||
expr_->net_type=0;
|
||||
FILE_NAME(expr_, net);
|
||||
|
||||
if (net->value().is_string()) {
|
||||
|
|
@ -303,6 +312,7 @@ void dll_target::expr_creal(const NetECReal*net)
|
|||
expr_->type_ = IVL_EX_REALNUM;
|
||||
FILE_NAME(expr_, net);
|
||||
expr_->value_= IVL_VT_REAL;
|
||||
expr_->net_type=0;
|
||||
expr_->u_.real_.value = net->value().as_double();
|
||||
}
|
||||
|
||||
|
|
@ -315,6 +325,7 @@ void dll_target::expr_event(const NetEEvent*net)
|
|||
expr_->type_ = IVL_EX_EVENT;
|
||||
FILE_NAME(expr_, net);
|
||||
expr_->value_= IVL_VT_VOID;
|
||||
expr_->net_type=0;
|
||||
|
||||
/* Locate the event by name. Save the ivl_event_t in the
|
||||
expression so that the generator can find it easily. */
|
||||
|
|
@ -339,6 +350,7 @@ void dll_target::expr_scope(const NetEScope*net)
|
|||
expr_->type_ = IVL_EX_SCOPE;
|
||||
FILE_NAME(expr_, net);
|
||||
expr_->value_= IVL_VT_VOID;
|
||||
expr_->net_type=0;
|
||||
expr_->u_.scope_.scope = lookup_scope_(net->scope());
|
||||
}
|
||||
|
||||
|
|
@ -351,6 +363,7 @@ void dll_target::expr_netenum(const NetENetenum*net)
|
|||
expr_->type_ = IVL_EX_ENUMTYPE;
|
||||
FILE_NAME(expr_, net);
|
||||
expr_->value_= IVL_VT_VOID;
|
||||
expr_->net_type=0;
|
||||
expr_->u_.enumtype_.type = net->netenum();
|
||||
}
|
||||
|
||||
|
|
@ -370,7 +383,8 @@ void dll_target::expr_select(const NetESelect*net)
|
|||
expr_ = (ivl_expr_t)calloc(1, sizeof(struct ivl_expr_s));
|
||||
|
||||
expr_->type_ = IVL_EX_SELECT;
|
||||
expr_->value_= IVL_VT_VECTOR;
|
||||
expr_->value_= net->expr_type();
|
||||
expr_->net_type=0;
|
||||
expr_->width_= net->expr_width();
|
||||
expr_->signed_ = net->has_sign()? 1 : 0;
|
||||
expr_->sized_= 1;
|
||||
|
|
@ -390,6 +404,7 @@ void dll_target::expr_sfunc(const NetESFunc*net)
|
|||
expr->type_ = IVL_EX_SFUNC;
|
||||
FILE_NAME(expr, net);
|
||||
expr->value_= net->expr_type();
|
||||
expr->net_type=net->net_type();
|
||||
expr->width_= net->expr_width();
|
||||
expr->signed_ = net->has_sign()? 1 : 0;
|
||||
expr->sized_= 1;
|
||||
|
|
@ -420,6 +435,7 @@ void dll_target::expr_ternary(const NetETernary*net)
|
|||
|
||||
expr->type_ = IVL_EX_TERNARY;
|
||||
expr->value_= net->expr_type();
|
||||
expr->net_type=0;
|
||||
expr->width_ = net->expr_width();
|
||||
expr->signed_ = net->has_sign()? 1 : 0;
|
||||
expr->sized_ = 1;
|
||||
|
|
@ -461,6 +477,7 @@ void dll_target::expr_signal(const NetESignal*net)
|
|||
|
||||
expr_->type_ = IVL_EX_SIGNAL;
|
||||
expr_->value_= net->expr_type();
|
||||
expr_->net_type=0;
|
||||
expr_->width_= net->expr_width();
|
||||
expr_->signed_ = net->has_sign()? 1 : 0;
|
||||
expr_->sized_= 1;
|
||||
|
|
@ -488,6 +505,7 @@ void dll_target::expr_ufunc(const NetEUFunc*net)
|
|||
|
||||
expr->type_ = IVL_EX_UFUNC;
|
||||
expr->value_= net->expr_type();
|
||||
expr->net_type=0;
|
||||
expr->width_= net->expr_width();
|
||||
expr->signed_ = net->has_sign()? 1 : 0;
|
||||
expr->sized_= 1;
|
||||
|
|
@ -523,6 +541,7 @@ void dll_target::expr_unary(const NetEUnary*net)
|
|||
expr_ = (ivl_expr_t)calloc(1, sizeof(struct ivl_expr_s));
|
||||
expr_->type_ = IVL_EX_UNARY;
|
||||
expr_->value_= net->expr_type();
|
||||
expr_->net_type=0;
|
||||
expr_->width_ = net->expr_width();
|
||||
expr_->signed_ = net->has_sign()? 1 : 0;
|
||||
expr_->sized_ = 1;
|
||||
|
|
|
|||
13
t-dll.cc
13
t-dll.cc
|
|
@ -2374,7 +2374,7 @@ void dll_target::signal(const NetNet*net)
|
|||
ivl_signal_t object. */
|
||||
|
||||
{ size_t idx = 0;
|
||||
list<netrange_t>::const_iterator cur;
|
||||
vector<netrange_t>::const_iterator cur;
|
||||
obj->packed_dims.resize(net->packed_dims().size());
|
||||
for (cur = net->packed_dims().begin(), idx = 0
|
||||
; cur != net->packed_dims().end() ; ++cur, idx += 1) {
|
||||
|
|
@ -2382,9 +2382,7 @@ void dll_target::signal(const NetNet*net)
|
|||
}
|
||||
}
|
||||
|
||||
obj->width_ = net->vector_width();
|
||||
obj->signed_= net->get_signed()? 1 : 0;
|
||||
obj->isint_ = false;
|
||||
obj->net_type = net->net_type();
|
||||
obj->local_ = net->local_flag()? 1 : 0;
|
||||
obj->forced_net_ = (net->type() != NetNet::REG) &&
|
||||
(net->peek_lref() > 0) ? 1 : 0;
|
||||
|
|
@ -2418,7 +2416,6 @@ void dll_target::signal(const NetNet*net)
|
|||
|
||||
case NetNet::REG:
|
||||
obj->type_ = IVL_SIT_REG;
|
||||
obj->isint_ = net->get_isint();
|
||||
break;
|
||||
|
||||
/* The SUPPLY0/1 net types are replaced with pulldown/up
|
||||
|
|
@ -2469,15 +2466,9 @@ void dll_target::signal(const NetNet*net)
|
|||
obj->npath = 0;
|
||||
obj->path = 0;
|
||||
|
||||
obj->data_type = net->data_type();
|
||||
obj->nattr = net->attr_cnt();
|
||||
obj->attr = fill_in_attributes(net);
|
||||
|
||||
/* If this is a dynamic array, then set the type to DARRAY. */
|
||||
if (net->darray_type()) {
|
||||
obj->data_type = IVL_VT_DARRAY;
|
||||
}
|
||||
|
||||
/* Get the nexus objects for all the pins of the signal. If
|
||||
the signal has only one pin, then write the single
|
||||
ivl_nexus_t object into n.pin_. Otherwise, make an array of
|
||||
|
|
|
|||
7
t-dll.h
7
t-dll.h
|
|
@ -218,6 +218,7 @@ struct ivl_event_s {
|
|||
struct ivl_expr_s {
|
||||
ivl_expr_type_t type_;
|
||||
ivl_variable_type_t value_;
|
||||
ivl_type_t net_type;
|
||||
perm_string file;
|
||||
unsigned lineno;
|
||||
|
||||
|
|
@ -677,14 +678,12 @@ struct ivl_signal_s {
|
|||
ivl_signal_type_t type_;
|
||||
ivl_signal_port_t port_;
|
||||
int module_port_index_;
|
||||
ivl_variable_type_t data_type;
|
||||
ivl_discipline_t discipline;
|
||||
perm_string file;
|
||||
unsigned lineno;
|
||||
|
||||
unsigned width_;
|
||||
unsigned signed_ : 1;
|
||||
unsigned isint_ : 1;
|
||||
// This is the type for the signal
|
||||
ivl_type_t net_type;
|
||||
unsigned local_ : 1;
|
||||
|
||||
unsigned forced_net_ : 1;
|
||||
|
|
|
|||
|
|
@ -44,7 +44,7 @@ CPPFLAGS = $(INCLUDE_PATH) @CPPFLAGS@ @DEFS@ @PICFLAG@
|
|||
CFLAGS = @WARNING_FLAGS@ @CFLAGS@
|
||||
LDFLAGS = @LDFLAGS@
|
||||
|
||||
O = stub.o enumerate.o expression.o statement.o switches.o
|
||||
O = stub.o enumerate.o expression.o statement.o switches.o types.o
|
||||
|
||||
all: dep stub.tgt
|
||||
|
||||
|
|
|
|||
|
|
@ -169,6 +169,7 @@ static void show_select_expression(ivl_expr_t net, unsigned ind)
|
|||
{
|
||||
unsigned width = ivl_expr_width(net);
|
||||
const char*sign = ivl_expr_signed(net)? "signed" : "unsigned";
|
||||
const char*vt = vt_type_string(net);
|
||||
ivl_expr_t oper1 = ivl_expr_oper1(net);
|
||||
ivl_expr_t oper2 = ivl_expr_oper2(net);
|
||||
|
||||
|
|
@ -177,17 +178,26 @@ static void show_select_expression(ivl_expr_t net, unsigned ind)
|
|||
substring and the code generator will handle it
|
||||
differently. */
|
||||
fprintf(out, "%*s<substring: width=%u bits, %u bytes>\n", ind, "", width, width/8);
|
||||
if (width%8 != 0)
|
||||
if (width%8 != 0) {
|
||||
fprintf(out, "%*sERROR: Width should be a multiple of 8 bits.\n", ind, "");
|
||||
stub_errors += 1;
|
||||
}
|
||||
assert(oper1);
|
||||
show_expression(oper1, ind+3);
|
||||
show_expression(oper2, ind+3);
|
||||
|
||||
if (oper2) {
|
||||
show_expression(oper2, ind+3);
|
||||
} else {
|
||||
fprintf(out, "%*sERROR: oper2 missing! Pad makes no sense for IVL_VT_STRING expressions.\n", ind+3, "");
|
||||
stub_errors += 1;
|
||||
}
|
||||
|
||||
} else if (oper2) {
|
||||
/* If oper2 is present, then it is the base of a part
|
||||
select. The width of the expression defines the range
|
||||
of the part select. */
|
||||
fprintf(out, "%*s<select: width=%u, %s>\n", ind, "",
|
||||
width, sign);
|
||||
fprintf(out, "%*s<select: width=%u, %s, type=%s>\n", ind, "",
|
||||
width, sign, vt);
|
||||
show_expression(oper1, ind+3);
|
||||
show_expression(oper2, ind+3);
|
||||
|
||||
|
|
@ -233,6 +243,14 @@ static void show_signal_expression(ivl_expr_t net, unsigned ind)
|
|||
fprintf(out, "%*sERROR: Missing word expression\n", ind+2, "");
|
||||
stub_errors += 1;
|
||||
}
|
||||
/* If this is not an array, then the expression with must
|
||||
match the signal width. We have IVL_EX_SELECT expressions
|
||||
for casting signal widths. */
|
||||
if (dimensions == 0 && ivl_signal_width(sig) != width) {
|
||||
fprintf(out, "%*sERROR: Expression width (%u) doesn't match ivl_signal_width(sig)=%u\n",
|
||||
ind+2, "", width, ivl_signal_width(sig));
|
||||
stub_errors += 1;
|
||||
}
|
||||
|
||||
if (word != 0) {
|
||||
fprintf(out, "%*sAddress-0 word address:\n", ind+2, "");
|
||||
|
|
@ -294,9 +312,10 @@ void show_unary_expression(ivl_expr_t net, unsigned ind)
|
|||
|
||||
void show_expression(ivl_expr_t net, unsigned ind)
|
||||
{
|
||||
assert(net);
|
||||
unsigned idx;
|
||||
const ivl_expr_type_t code = ivl_expr_type(net);
|
||||
ivl_parameter_t par = ivl_expr_parameter(net);
|
||||
const ivl_expr_type_t code = ivl_expr_type(net);
|
||||
unsigned width = ivl_expr_width(net);
|
||||
const char*sign = ivl_expr_signed(net)? "signed" : "unsigned";
|
||||
const char*sized = ivl_expr_sized(net)? "sized" : "unsized";
|
||||
|
|
|
|||
|
|
@ -61,6 +61,11 @@ extern void show_expression(ivl_expr_t net, unsigned ind);
|
|||
*/
|
||||
extern void show_statement(ivl_statement_t net, unsigned ind);
|
||||
|
||||
/*
|
||||
* Show the type of the signal, in one line.
|
||||
*/
|
||||
extern void show_type_of_signal(ivl_signal_t);
|
||||
|
||||
extern void show_switch(ivl_switch_t net);
|
||||
|
||||
/*
|
||||
|
|
|
|||
|
|
@ -31,7 +31,9 @@ static unsigned show_assign_lval_darray(ivl_lval_t lval, unsigned ind)
|
|||
assert(sig);
|
||||
|
||||
if (ivl_lval_idx(lval)) {
|
||||
fprintf(out, "%*sAddress-0 select of dynamic array:\n", ind+4, "");
|
||||
fprintf(out, "%*sAddress-0 select of ", ind+4, "");
|
||||
show_type_of_signal(sig);
|
||||
fprintf(out, ":\n");
|
||||
show_expression(ivl_lval_idx(lval), ind+6);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -1222,7 +1222,6 @@ static void show_signal(ivl_signal_t net)
|
|||
|
||||
const char*type = "?";
|
||||
const char*port = "";
|
||||
const char*data_type = "?";
|
||||
const char*sign = ivl_signal_signed(net)? "signed" : "unsigned";
|
||||
|
||||
switch (ivl_signal_type(net)) {
|
||||
|
|
@ -1263,32 +1262,6 @@ static void show_signal(ivl_signal_t net)
|
|||
break;
|
||||
}
|
||||
|
||||
data_type = "?data?";
|
||||
switch (ivl_signal_data_type(net)) {
|
||||
|
||||
case IVL_VT_NO_TYPE:
|
||||
data_type = "<no-type>";
|
||||
break;
|
||||
case IVL_VT_BOOL:
|
||||
data_type = "bool";
|
||||
break;
|
||||
case IVL_VT_LOGIC:
|
||||
data_type = "logic";
|
||||
break;
|
||||
case IVL_VT_REAL:
|
||||
data_type = "real";
|
||||
break;
|
||||
case IVL_VT_STRING:
|
||||
data_type = "string";
|
||||
break;
|
||||
case IVL_VT_DARRAY:
|
||||
data_type = "darray";
|
||||
break;
|
||||
case IVL_VT_VOID:
|
||||
data_type = "void";
|
||||
break;
|
||||
}
|
||||
|
||||
const char*discipline_txt = "NONE";
|
||||
if (ivl_signal_discipline(net)) {
|
||||
ivl_discipline_t dis = ivl_signal_discipline(net);
|
||||
|
|
@ -1298,13 +1271,9 @@ static void show_signal(ivl_signal_t net)
|
|||
for (idx = 0 ; idx < ivl_signal_array_count(net) ; idx += 1) {
|
||||
|
||||
ivl_nexus_t nex = ivl_signal_nex(net, idx);
|
||||
unsigned dim;
|
||||
|
||||
fprintf(out, " %s %s %s%s", type, sign, port, data_type);
|
||||
for (dim = 0 ; dim < ivl_signal_packed_dimensions(net) ; dim += 1) {
|
||||
fprintf(out, "[%d:%d]", ivl_signal_packed_msb(net,dim),
|
||||
ivl_signal_packed_lsb(net,dim));
|
||||
}
|
||||
fprintf(out, " %s %s %s", type, sign, port);
|
||||
show_type_of_signal(net);
|
||||
fprintf(out, " %s[word=%u, adr=%d] <width=%u%s> <discipline=%s> ",
|
||||
ivl_signal_basename(net),
|
||||
idx, ivl_signal_array_base(net)+idx,
|
||||
|
|
@ -1371,7 +1340,7 @@ static void show_signal(ivl_signal_t net)
|
|||
switch (ivl_signal_data_type(net)) {
|
||||
case IVL_VT_NO_TYPE:
|
||||
case IVL_VT_VOID:
|
||||
fprintf(out, " ERROR: Invalid type for signal: %s\n", data_type);
|
||||
fprintf(out, " ERROR: Invalid type for signal.\n");
|
||||
stub_errors += 1;
|
||||
break;
|
||||
default:
|
||||
|
|
|
|||
|
|
@ -0,0 +1,123 @@
|
|||
/*
|
||||
* Copyright (c) 2012 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 "config.h"
|
||||
# include "priv.h"
|
||||
# include <string.h>
|
||||
|
||||
static void show_net_type(ivl_type_t net_type);
|
||||
|
||||
static void show_net_type_darray(ivl_type_t net_type)
|
||||
{
|
||||
/* Dynamic arrays have a single element type. */
|
||||
ivl_type_t element_type = ivl_type_element(net_type);
|
||||
|
||||
fprintf(out, "darray of ");
|
||||
show_net_type(element_type);
|
||||
}
|
||||
|
||||
static void show_net_type(ivl_type_t net_type)
|
||||
{
|
||||
ivl_variable_type_t data_type = ivl_type_base(net_type);
|
||||
|
||||
switch (data_type) {
|
||||
case IVL_VT_NO_TYPE:
|
||||
fprintf(out, "<ERROR-no-type>");
|
||||
stub_errors += 1;
|
||||
break;
|
||||
case IVL_VT_BOOL:
|
||||
fprintf(out, "bool");
|
||||
break;
|
||||
case IVL_VT_LOGIC:
|
||||
fprintf(out, "logic");
|
||||
break;
|
||||
case IVL_VT_REAL:
|
||||
fprintf(out, "real");
|
||||
break;
|
||||
case IVL_VT_STRING:
|
||||
fprintf(out, "string");
|
||||
break;
|
||||
case IVL_VT_DARRAY:
|
||||
show_net_type_darray(net_type);
|
||||
break;
|
||||
case IVL_VT_VOID:
|
||||
fprintf(out, "void");
|
||||
break;
|
||||
}
|
||||
|
||||
unsigned packed_dimensions = ivl_type_packed_dimensions(net_type);
|
||||
unsigned idx;
|
||||
for (idx = 0 ; idx < packed_dimensions ; idx += 1) {
|
||||
fprintf(out, "[%d:%d]", ivl_type_packed_msb(net_type, idx),
|
||||
ivl_type_packed_lsb(net_type, idx));
|
||||
}
|
||||
}
|
||||
|
||||
void show_type_of_signal(ivl_signal_t net)
|
||||
{
|
||||
unsigned dim;
|
||||
|
||||
/* The data_type is the base type of the signal. This the the
|
||||
starting point for the type. In the long run I think I want
|
||||
to remove this in favor of the ivl_signal_net_type below. */
|
||||
ivl_variable_type_t data_type = ivl_signal_data_type(net);
|
||||
|
||||
/* This gets the more general type description. This is a
|
||||
newer form so doesn't yet handle all the cases. Newer
|
||||
types, such DARRAY types, REQUIRE this method to get at the
|
||||
type details. */
|
||||
ivl_type_t net_type = ivl_signal_net_type(net);
|
||||
|
||||
if (net_type) {
|
||||
show_net_type(net_type);
|
||||
return;
|
||||
}
|
||||
|
||||
switch (data_type) {
|
||||
case IVL_VT_NO_TYPE:
|
||||
fprintf(out, "<no-type>");
|
||||
break;
|
||||
case IVL_VT_BOOL:
|
||||
fprintf(out, "bool");
|
||||
break;
|
||||
case IVL_VT_LOGIC:
|
||||
fprintf(out, "logic");
|
||||
break;
|
||||
case IVL_VT_REAL:
|
||||
fprintf(out, "real");
|
||||
break;
|
||||
case IVL_VT_STRING:
|
||||
fprintf(out, "string");
|
||||
break;
|
||||
case IVL_VT_DARRAY:
|
||||
/* The DARRAY type MUST be described by an
|
||||
ivl_signal_net_type object. */
|
||||
fprintf(out, "ERROR-DARRAY");
|
||||
stub_errors += 1;
|
||||
break;
|
||||
case IVL_VT_VOID:
|
||||
fprintf(out, "void");
|
||||
break;
|
||||
}
|
||||
|
||||
for (dim = 0 ; dim < ivl_signal_packed_dimensions(net) ; dim += 1) {
|
||||
fprintf(out, "[%d:%d]", ivl_signal_packed_msb(net,dim),
|
||||
ivl_signal_packed_lsb(net,dim));
|
||||
}
|
||||
}
|
||||
|
|
@ -419,6 +419,9 @@ static void draw_vpi_taskfunc_args(const char*call_string,
|
|||
buffer[0] = 0;
|
||||
break;
|
||||
default:
|
||||
fprintf(vvp_out, "\nXXXX Unexpected argument: call_string=<%s>, arg=%d, type=%d\n",
|
||||
call_string, idx, ivl_expr_value(expr));
|
||||
fflush(vvp_out);
|
||||
assert(0);
|
||||
}
|
||||
args[idx].text = strdup(buffer);
|
||||
|
|
|
|||
|
|
@ -2471,6 +2471,17 @@ static struct vector_info draw_select_signal(ivl_expr_t expr,
|
|||
unsigned use_word = 0;
|
||||
unsigned use_wid, lab_x, lab_end;
|
||||
|
||||
/* Special case: the sub expression is a DARRAY variable, so
|
||||
do a dynamic array word load. */
|
||||
if (ivl_signal_data_type(sig) == IVL_VT_DARRAY) {
|
||||
res.base = allocate_vector(wid);
|
||||
res.wid = wid;
|
||||
draw_eval_expr_into_integer(bit_idx, 3);
|
||||
fprintf(vvp_out, " %%load/dar %u, v%p_0, %u;\n",
|
||||
res.base, sig, res.wid);
|
||||
return res;
|
||||
}
|
||||
|
||||
/* If this is an access to an array, try to get the index as a
|
||||
constant. If it is (and the array is not a reg array then
|
||||
this reduces to a signal access and we stay here. If it is
|
||||
|
|
|
|||
|
|
@ -28,8 +28,41 @@ static int eval_darray_new(ivl_expr_t ex)
|
|||
draw_eval_expr_into_integer(size_expr, size_reg);
|
||||
clr_word(size_reg);
|
||||
|
||||
// XXXX: Assume elements are 32bit integers.
|
||||
fprintf(vvp_out, " %%new/darray %u, \"sb32\";\n", size_reg);
|
||||
// The new function has a net_type that contains the details
|
||||
// of the type.
|
||||
ivl_type_t net_type = ivl_expr_net_type(ex);
|
||||
assert(net_type);
|
||||
|
||||
ivl_type_t element_type = ivl_type_element(net_type);
|
||||
assert(element_type);
|
||||
|
||||
switch (ivl_type_base(element_type)) {
|
||||
case IVL_VT_REAL:
|
||||
// REAL objects are not packable.
|
||||
assert(ivl_type_packed_dimensions(element_type) == 0);
|
||||
fprintf(vvp_out, " %%new/darray %u, \"r\";\n", size_reg);
|
||||
break;
|
||||
case IVL_VT_STRING:
|
||||
// STRING objects are not packable.
|
||||
assert(ivl_type_packed_dimensions(element_type) == 0);
|
||||
fprintf(vvp_out, " %%new/darray %u, \"S\";\n", size_reg);
|
||||
break;
|
||||
case IVL_VT_BOOL:
|
||||
// bool objects are vectorable, but for now only support
|
||||
// a single dimensions.
|
||||
assert(ivl_type_packed_dimensions(element_type) == 1);
|
||||
int msb = ivl_type_packed_msb(element_type, 0);
|
||||
int lsb = ivl_type_packed_lsb(element_type, 0);
|
||||
int wid = msb>=lsb? msb - lsb : lsb - msb;
|
||||
wid += 1;
|
||||
|
||||
fprintf(vvp_out, " %%new/darray %u, \"sb%d\";\n", size_reg, wid);
|
||||
break;
|
||||
|
||||
default:
|
||||
assert(0);
|
||||
break;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -256,6 +256,21 @@ static void draw_real_logic_expr(ivl_expr_t expr, int stuff_ok_flag)
|
|||
clr_vector(sv);
|
||||
}
|
||||
|
||||
static void draw_select_real(ivl_expr_t expr)
|
||||
{
|
||||
/* The sube references the expression to be selected from. */
|
||||
ivl_expr_t sube = ivl_expr_oper1(expr);
|
||||
/* This is the select expression */
|
||||
ivl_expr_t shift= ivl_expr_oper2(expr);
|
||||
|
||||
/* Assume the sub-expression is a signal */
|
||||
ivl_signal_t sig = ivl_expr_signal(sube);
|
||||
assert(ivl_signal_data_type(sig) == IVL_VT_DARRAY);
|
||||
|
||||
draw_eval_expr_into_integer(shift, 3);
|
||||
fprintf(vvp_out, " %%load/dar/r v%p_0;\n", sig);
|
||||
}
|
||||
|
||||
static void draw_sfunc_real(ivl_expr_t expr)
|
||||
{
|
||||
switch (ivl_expr_value(expr)) {
|
||||
|
|
@ -492,6 +507,10 @@ void draw_eval_real(ivl_expr_t expr)
|
|||
draw_realnum_real(expr);
|
||||
break;
|
||||
|
||||
case IVL_EX_SELECT:
|
||||
draw_select_real(expr);
|
||||
break;
|
||||
|
||||
case IVL_EX_SFUNC:
|
||||
draw_sfunc_real(expr);
|
||||
break;
|
||||
|
|
|
|||
|
|
@ -71,6 +71,21 @@ static void string_ex_signal(ivl_expr_t expr)
|
|||
fallback_eval(expr);
|
||||
}
|
||||
|
||||
static void string_ex_select(ivl_expr_t expr)
|
||||
{
|
||||
/* The sube references the expression to be selected from. */
|
||||
ivl_expr_t sube = ivl_expr_oper1(expr);
|
||||
/* This is the select expression */
|
||||
ivl_expr_t shift= ivl_expr_oper2(expr);
|
||||
|
||||
/* Assume the sub-expression is a signal */
|
||||
ivl_signal_t sig = ivl_expr_signal(sube);
|
||||
assert(ivl_signal_data_type(sig) == IVL_VT_DARRAY);
|
||||
|
||||
draw_eval_expr_into_integer(shift, 3);
|
||||
fprintf(vvp_out, " %%load/dar/str v%p_0;\n", sig);
|
||||
}
|
||||
|
||||
void draw_eval_string(ivl_expr_t expr)
|
||||
{
|
||||
|
||||
|
|
@ -87,6 +102,10 @@ void draw_eval_string(ivl_expr_t expr)
|
|||
string_ex_concat(expr);
|
||||
break;
|
||||
|
||||
case IVL_EX_SELECT:
|
||||
string_ex_select(expr);
|
||||
break;
|
||||
|
||||
default:
|
||||
fallback_eval(expr);
|
||||
break;
|
||||
|
|
|
|||
|
|
@ -767,6 +767,10 @@ static int show_stmt_assign_sig_darray(ivl_statement_t net)
|
|||
ivl_expr_t rval = ivl_stmt_rval(net);
|
||||
ivl_expr_t part = ivl_lval_part_off(lval);
|
||||
ivl_signal_t var= ivl_lval_sig(lval);
|
||||
ivl_type_t var_type= ivl_signal_net_type(var);
|
||||
assert(ivl_type_base(var_type) == IVL_VT_DARRAY);
|
||||
ivl_type_t element_type = ivl_type_element(var_type);
|
||||
|
||||
ivl_expr_t mux = ivl_lval_idx(lval);
|
||||
|
||||
assert(ivl_stmt_lvals(net) == 1);
|
||||
|
|
@ -774,7 +778,27 @@ static int show_stmt_assign_sig_darray(ivl_statement_t net)
|
|||
assert(ivl_lval_mux(lval) == 0);
|
||||
assert(part == 0);
|
||||
|
||||
if (mux) {
|
||||
if (mux && (ivl_type_base(element_type)==IVL_VT_REAL)) {
|
||||
draw_eval_real(rval);
|
||||
|
||||
/* The %set/dar expects the array index to be in index
|
||||
register 3. Calculate the index in place. */
|
||||
draw_eval_expr_into_integer(mux, 3);
|
||||
|
||||
fprintf(vvp_out, " %%store/dar/r v%p_0;\n", var);
|
||||
|
||||
} else if (mux && ivl_type_base(element_type)==IVL_VT_STRING) {
|
||||
|
||||
/* Evaluate the rval into the top of the string stack. */
|
||||
draw_eval_string(rval);
|
||||
|
||||
/* The %store/dar/s expects the array index to me in index
|
||||
register 3. Calculate the index in place. */
|
||||
draw_eval_expr_into_integer(mux, 3);
|
||||
|
||||
fprintf(vvp_out, " %%store/dar/str v%p_0;\n", var);
|
||||
|
||||
} else if (mux) {
|
||||
struct vector_info rvec = draw_eval_expr_wid(rval, ivl_lval_width(lval),
|
||||
STUFF_OK_XZ);
|
||||
/* The %set/dar expects the array index to be in index
|
||||
|
|
|
|||
|
|
@ -128,6 +128,8 @@ extern bool of_LOAD_AVP0_S(vthread_t thr, vvp_code_t code);
|
|||
extern bool of_LOAD_AVX_P(vthread_t thr, vvp_code_t code);
|
||||
extern bool of_LOAD_DAR(vthread_t thr, vvp_code_t code);
|
||||
extern bool of_LOAD_REAL(vthread_t thr, vvp_code_t code);
|
||||
extern bool of_LOAD_DAR_R(vthread_t thr, vvp_code_t code);
|
||||
extern bool of_LOAD_DAR_STR(vthread_t thr, vvp_code_t code);
|
||||
extern bool of_LOAD_STR(vthread_t thr, vvp_code_t code);
|
||||
extern bool of_LOAD_VEC(vthread_t thr, vvp_code_t code);
|
||||
extern bool of_LOAD_VP0(vthread_t thr, vvp_code_t code);
|
||||
|
|
@ -173,6 +175,8 @@ extern bool of_SET_X0_X(vthread_t thr, vvp_code_t code);
|
|||
extern bool of_SHIFTL_I0(vthread_t thr, vvp_code_t code);
|
||||
extern bool of_SHIFTR_I0(vthread_t thr, vvp_code_t code);
|
||||
extern bool of_SHIFTR_S_I0(vthread_t thr, vvp_code_t code);
|
||||
extern bool of_STORE_DAR_R(vthread_t thr, vvp_code_t code);
|
||||
extern bool of_STORE_DAR_STR(vthread_t thr, vvp_code_t code);
|
||||
extern bool of_STORE_OBJ(vthread_t thr, vvp_code_t code);
|
||||
extern bool of_STORE_REAL(vthread_t thr, vvp_code_t code);
|
||||
extern bool of_STORE_REALA(vthread_t thr, vvp_code_t code);
|
||||
|
|
|
|||
|
|
@ -171,13 +171,15 @@ static const struct opcode_table_s opcode_table[] = {
|
|||
{ "%join/detach",of_JOIN_DETACH,1,{OA_NUMBER,OA_NONE, OA_NONE} },
|
||||
{ "%load/ar",of_LOAD_AR,2, {OA_ARR_PTR, OA_BIT1, OA_NONE} },
|
||||
{ "%load/av",of_LOAD_AV,3, {OA_BIT1, OA_ARR_PTR, OA_BIT2} },
|
||||
{ "%load/avp0",of_LOAD_AVP0,3, {OA_BIT1, OA_ARR_PTR, OA_BIT2} },
|
||||
{ "%load/avp0/s",of_LOAD_AVP0_S,3,{OA_BIT1, OA_ARR_PTR, OA_BIT2} },
|
||||
{ "%load/avp0",of_LOAD_AVP0,3, {OA_BIT1, OA_ARR_PTR, OA_BIT2} },
|
||||
{ "%load/avp0/s",of_LOAD_AVP0_S,3,{OA_BIT1,OA_ARR_PTR, OA_BIT2} },
|
||||
{ "%load/avx.p",of_LOAD_AVX_P,3,{OA_BIT1, OA_ARR_PTR, OA_BIT2} },
|
||||
{ "%load/dar",of_LOAD_DAR,3,{OA_BIT1, OA_FUNC_PTR, OA_BIT2} },
|
||||
{ "%load/real", of_LOAD_REAL,1,{OA_VPI_PTR, OA_NONE, OA_NONE} },
|
||||
{ "%load/str", of_LOAD_STR, 1,{OA_FUNC_PTR,OA_NONE, OA_NONE} },
|
||||
{ "%load/v", of_LOAD_VEC,3, {OA_BIT1, OA_FUNC_PTR, OA_BIT2} },
|
||||
{ "%load/dar/r", of_LOAD_DAR_R, 1, {OA_FUNC_PTR, OA_NONE, OA_NONE}},
|
||||
{ "%load/dar/str",of_LOAD_DAR_STR, 1, {OA_FUNC_PTR, OA_NONE, OA_NONE} },
|
||||
{ "%load/real", of_LOAD_REAL,1,{OA_VPI_PTR, OA_NONE, OA_NONE} },
|
||||
{ "%load/str", of_LOAD_STR, 1,{OA_FUNC_PTR,OA_NONE, OA_NONE} },
|
||||
{ "%load/v", of_LOAD_VEC,3, {OA_BIT1, OA_FUNC_PTR, OA_BIT2} },
|
||||
{ "%load/vp0",of_LOAD_VP0,3,{OA_BIT1, OA_FUNC_PTR, OA_BIT2} },
|
||||
{ "%load/vp0/s",of_LOAD_VP0_S,3,{OA_BIT1, OA_FUNC_PTR, OA_BIT2} },
|
||||
{ "%load/x1p",of_LOAD_X1P,3,{OA_BIT1, OA_FUNC_PTR, OA_BIT2} },
|
||||
|
|
@ -220,6 +222,8 @@ static const struct opcode_table_s opcode_table[] = {
|
|||
{ "%shiftl/i0", of_SHIFTL_I0, 2, {OA_BIT1,OA_NUMBER, OA_NONE} },
|
||||
{ "%shiftr/i0", of_SHIFTR_I0, 2, {OA_BIT1,OA_NUMBER, OA_NONE} },
|
||||
{ "%shiftr/s/i0", of_SHIFTR_S_I0,2,{OA_BIT1,OA_NUMBER, OA_NONE} },
|
||||
{ "%store/dar/r", of_STORE_DAR_R, 1, {OA_FUNC_PTR, OA_NONE, OA_NONE} },
|
||||
{ "%store/dar/str",of_STORE_DAR_STR, 1, {OA_FUNC_PTR, OA_NONE, OA_NONE} },
|
||||
{ "%store/obj", of_STORE_OBJ, 1,{OA_FUNC_PTR,OA_NONE, OA_NONE} },
|
||||
{ "%store/real", of_STORE_REAL, 1,{OA_FUNC_PTR,OA_NONE, OA_NONE} },
|
||||
{ "%store/reala",of_STORE_REALA,2,{OA_ARR_PTR, OA_BIT1, OA_NONE} },
|
||||
|
|
|
|||
|
|
@ -612,12 +612,15 @@ out of range, then x is loaded. The index value is incremented by one
|
|||
if it is defined (bit 4 is not 1).
|
||||
|
||||
* %load/dar <bit>, <functor-label>, <wid>
|
||||
* %load/dar/r <functor-label>
|
||||
|
||||
This instruction loads an array word from a dynamic array. The
|
||||
<label> refers to the variable object, and the <bit>/<wid> are the
|
||||
location in local vector space where the extracted word goes. The
|
||||
index is implicitly extracted from index register 3.
|
||||
|
||||
The dar/r variant reads a real-value into a real-valued register.
|
||||
|
||||
(See also %set/dar)
|
||||
|
||||
* %load/real <vpi-label>
|
||||
|
|
@ -625,6 +628,16 @@ index is implicitly extracted from index register 3.
|
|||
The %load/real instruction reads a real value from the vpi-like object
|
||||
and pushes it to the top of the real value stack.
|
||||
|
||||
* %load/str <var-label>
|
||||
* %load/dar/str <var-label>
|
||||
|
||||
The %load/str instruction gets the string from the string variable and
|
||||
pushes in to the string stack. (See also %store/str)
|
||||
|
||||
The %load/dar/str is similar, but the variable is a dynamic array of
|
||||
strings, and there is an index value in index register 3.
|
||||
(See also %store/dar/str)
|
||||
|
||||
|
||||
* %load/v <bit>, <functor-label>, <wid>
|
||||
|
||||
|
|
@ -760,7 +773,10 @@ the array. See also %delete/obj
|
|||
|
||||
The supported types are:
|
||||
|
||||
"sb32" - signed bool 32bits
|
||||
"b<N>" - unsigned bool <N>-bits
|
||||
"sb<N>" - signed bool <N>-bits
|
||||
"r" - real
|
||||
"S" - SystemVerilog string
|
||||
|
||||
* %nor <dst>, <src>, <wid>
|
||||
|
||||
|
|
@ -961,9 +977,14 @@ The areal version is similar, but writes to a real array using the
|
|||
index in the index register <index>
|
||||
|
||||
* %store/str <var-label>
|
||||
* %store/dar/r <var-label>
|
||||
* %store/dar/str <var-label>
|
||||
|
||||
This pops the top of the string stack and writes it to the string
|
||||
varible.
|
||||
The %store/str instruction pops the top of the string stack and writes
|
||||
it to the string variable.
|
||||
|
||||
The %store/dar/str is similar, but the target is a dynamic array of
|
||||
string string. The index is taken from signed index register 3.
|
||||
|
||||
* %sub <bit-l>, <bit-r>, <wid>
|
||||
|
||||
|
|
|
|||
105
vvp/vthread.cc
105
vvp/vthread.cc
|
|
@ -3192,9 +3192,50 @@ bool of_LOAD_DAR(vthread_t thr, vvp_code_t cp)
|
|||
return true;
|
||||
}
|
||||
|
||||
/*
|
||||
* %load/dar/r <array-label>;
|
||||
*/
|
||||
bool of_LOAD_DAR_R(vthread_t thr, vvp_code_t cp)
|
||||
{
|
||||
unsigned adr = thr->words[3].w_int;
|
||||
vvp_net_t*net = cp->net;
|
||||
|
||||
assert(net);
|
||||
vvp_fun_signal_object*obj = dynamic_cast<vvp_fun_signal_object*> (net->fun);
|
||||
assert(obj);
|
||||
|
||||
vvp_darray*darray = dynamic_cast<vvp_darray*> (obj->get_object());
|
||||
assert(darray);
|
||||
|
||||
double word;
|
||||
darray->get_word(adr, word);
|
||||
|
||||
thr->push_real(word);
|
||||
return true;
|
||||
}
|
||||
|
||||
bool of_LOAD_DAR_STR(vthread_t thr, vvp_code_t cp)
|
||||
{
|
||||
unsigned adr = thr->words[3].w_int;
|
||||
vvp_net_t*net = cp->net;
|
||||
|
||||
assert(net);
|
||||
vvp_fun_signal_object*obj = dynamic_cast<vvp_fun_signal_object*> (net->fun);
|
||||
assert(obj);
|
||||
|
||||
vvp_darray*darray = dynamic_cast<vvp_darray*> (obj->get_object());
|
||||
assert(darray);
|
||||
|
||||
string word;
|
||||
darray->get_word(adr, word);
|
||||
thr->push_str(word);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/*
|
||||
* %load/vp0, %load/vp0/s, %load/avp0 and %load/avp0/s share this function.
|
||||
*/
|
||||
*/
|
||||
#if (SIZEOF_UNSIGNED_LONG >= 8)
|
||||
# define CPU_WORD_STRIDE CPU_WORD_BITS - 1 // avoid a warning
|
||||
#else
|
||||
|
|
@ -4019,8 +4060,26 @@ bool of_NEW_DARRAY(vthread_t thr, vvp_code_t cp)
|
|||
size_t size = thr->words[cp->bit_idx[0]].w_int;
|
||||
|
||||
vvp_object_t obj;
|
||||
if (strcmp(text,"sb32") == 0) {
|
||||
if (strcmp(text,"b8") == 0) {
|
||||
obj = new vvp_darray_atom<uint8_t>(size);
|
||||
} else if (strcmp(text,"b16") == 0) {
|
||||
obj = new vvp_darray_atom<uint16_t>(size);
|
||||
} else if (strcmp(text,"b32") == 0) {
|
||||
obj = new vvp_darray_atom<uint32_t>(size);
|
||||
} else if (strcmp(text,"b64") == 0) {
|
||||
obj = new vvp_darray_atom<uint64_t>(size);
|
||||
} else if (strcmp(text,"sb8") == 0) {
|
||||
obj = new vvp_darray_atom<int8_t>(size);
|
||||
} else if (strcmp(text,"sb16") == 0) {
|
||||
obj = new vvp_darray_atom<int16_t>(size);
|
||||
} else if (strcmp(text,"sb32") == 0) {
|
||||
obj = new vvp_darray_atom<int32_t>(size);
|
||||
} else if (strcmp(text,"sb64") == 0) {
|
||||
obj = new vvp_darray_atom<int64_t>(size);
|
||||
} else if (strcmp(text,"r") == 0) {
|
||||
obj = new vvp_darray_real(size);
|
||||
} else if (strcmp(text,"S") == 0) {
|
||||
obj = new vvp_darray_string(size);
|
||||
} else {
|
||||
obj = new vvp_darray (size);
|
||||
}
|
||||
|
|
@ -4821,6 +4880,48 @@ bool of_SHIFTR_S_I0(vthread_t thr, vvp_code_t cp)
|
|||
return true;
|
||||
}
|
||||
|
||||
bool of_STORE_DAR_R(vthread_t thr, vvp_code_t cp)
|
||||
{
|
||||
long adr = thr->words[3].w_int;
|
||||
|
||||
// Pop the real value to be store...
|
||||
double value = thr->pop_real();
|
||||
|
||||
vvp_net_t*net = cp->net;
|
||||
vvp_fun_signal_object*obj = dynamic_cast<vvp_fun_signal_object*> (net->fun);
|
||||
assert(obj);
|
||||
|
||||
vvp_darray*darray = dynamic_cast<vvp_darray*>(obj->get_object());
|
||||
assert(darray);
|
||||
|
||||
darray->set_word(adr, value);
|
||||
return true;
|
||||
}
|
||||
|
||||
/*
|
||||
* %store/dar/str <var>
|
||||
* In this case, <var> is the name of a dynamic array. Signed index
|
||||
* register 3 contains the index into the dynamic array.
|
||||
*/
|
||||
bool of_STORE_DAR_STR(vthread_t thr, vvp_code_t cp)
|
||||
{
|
||||
long adr = thr->words[3].w_int;
|
||||
|
||||
// Pop the string to be stored...
|
||||
string value = thr->pop_str();
|
||||
|
||||
vvp_net_t*net = cp->net;
|
||||
vvp_fun_signal_object*obj = dynamic_cast<vvp_fun_signal_object*> (net->fun);
|
||||
assert(obj);
|
||||
|
||||
vvp_darray*darray = dynamic_cast<vvp_darray*>(obj->get_object());
|
||||
assert(darray);
|
||||
|
||||
darray->set_word(adr, value);
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
bool of_STORE_OBJ(vthread_t thr, vvp_code_t cp)
|
||||
{
|
||||
/* set the value into port 0 of the destination. */
|
||||
|
|
|
|||
|
|
@ -1619,8 +1619,8 @@ ostream& operator<< (ostream&out, const vvp_vector4_t&that)
|
|||
return out;
|
||||
}
|
||||
|
||||
template <class INT>bool do_vector4_to_value(const vvp_vector4_t&vec, INT&val,
|
||||
bool is_signed, bool is_arithmetic)
|
||||
template <class INT>bool vector4_to_value(const vvp_vector4_t&vec, INT&val,
|
||||
bool is_signed, bool is_arithmetic)
|
||||
{
|
||||
long res = 0;
|
||||
INT msk = 1;
|
||||
|
|
@ -1654,22 +1654,27 @@ template <class INT>bool do_vector4_to_value(const vvp_vector4_t&vec, INT&val,
|
|||
return rc_flag;
|
||||
}
|
||||
|
||||
bool vector4_to_value(const vvp_vector4_t&vec, long&val,
|
||||
bool is_signed, bool is_arithmetic)
|
||||
{
|
||||
return do_vector4_to_value(vec, val, is_signed, is_arithmetic);
|
||||
}
|
||||
template bool vector4_to_value(const vvp_vector4_t&vec, int8_t&val,
|
||||
bool is_signed, bool is_arithmetic);
|
||||
template bool vector4_to_value(const vvp_vector4_t&vec, int16_t&val,
|
||||
bool is_signed, bool is_arithmetic);
|
||||
template bool vector4_to_value(const vvp_vector4_t&vec, int32_t&val,
|
||||
bool is_signed, bool is_arithmetic);
|
||||
template bool vector4_to_value(const vvp_vector4_t&vec, int64_t&val,
|
||||
bool is_signed, bool is_arithmetic);
|
||||
template bool vector4_to_value(const vvp_vector4_t&vec, uint8_t&val,
|
||||
bool is_signed, bool is_arithmetic);
|
||||
template bool vector4_to_value(const vvp_vector4_t&vec, uint16_t&val,
|
||||
bool is_signed, bool is_arithmetic);
|
||||
template bool vector4_to_value(const vvp_vector4_t&vec, uint32_t&val,
|
||||
bool is_signed, bool is_arithmetic);
|
||||
template bool vector4_to_value(const vvp_vector4_t&vec, uint64_t&val,
|
||||
bool is_signed, bool is_arithmetic);
|
||||
|
||||
bool vector4_to_value(const vvp_vector4_t&vec, int32_t&val,
|
||||
bool is_signed, bool is_arithmetic)
|
||||
template <class T> bool vector4_to_value(const vvp_vector4_t&vec, T&val)
|
||||
{
|
||||
return do_vector4_to_value(vec, val, is_signed, is_arithmetic);
|
||||
}
|
||||
|
||||
bool vector4_to_value(const vvp_vector4_t&vec, unsigned long&val)
|
||||
{
|
||||
unsigned long res = 0;
|
||||
unsigned long msk = 1;
|
||||
T res = 0;
|
||||
T msk = 1;
|
||||
|
||||
unsigned size = vec.size();
|
||||
if (size > 8*sizeof(val)) size = 8*sizeof(val);
|
||||
|
|
@ -1684,44 +1689,16 @@ bool vector4_to_value(const vvp_vector4_t&vec, unsigned long&val)
|
|||
return false;
|
||||
}
|
||||
|
||||
msk <<= 1UL;
|
||||
msk <<= static_cast<T>(1);
|
||||
}
|
||||
|
||||
val = res;
|
||||
return true;
|
||||
}
|
||||
|
||||
template bool vector4_to_value(const vvp_vector4_t&vec, unsigned long&val);
|
||||
#ifndef UL_AND_TIME64_SAME
|
||||
bool vector4_to_value(const vvp_vector4_t&vec, int64_t&val,
|
||||
bool is_signed, bool is_arithmetic)
|
||||
{
|
||||
return do_vector4_to_value(vec, val, is_signed, is_arithmetic);
|
||||
}
|
||||
|
||||
bool vector4_to_value(const vvp_vector4_t&vec, vvp_time64_t&val)
|
||||
{
|
||||
vvp_time64_t res = 0;
|
||||
vvp_time64_t msk = 1;
|
||||
|
||||
unsigned size = vec.size();
|
||||
if (size > 8*sizeof(val)) size = 8*sizeof(val);
|
||||
for (unsigned idx = 0 ; idx < size ; idx += 1) {
|
||||
switch (vec.value(idx)) {
|
||||
case BIT4_0:
|
||||
break;
|
||||
case BIT4_1:
|
||||
res |= msk;
|
||||
break;
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
|
||||
msk <<= 1UL;
|
||||
}
|
||||
|
||||
val = res;
|
||||
return true;
|
||||
}
|
||||
template bool vector4_to_value(const vvp_vector4_t&vec, vvp_time64_t&val);
|
||||
#endif
|
||||
|
||||
bool vector4_to_value(const vvp_vector4_t&vec, double&val, bool signed_flag)
|
||||
|
|
|
|||
|
|
@ -510,13 +510,12 @@ template <class T> extern T coerce_to_width(const T&that, unsigned width);
|
|||
* value will be "false", but the other bits will be transferred. This
|
||||
* is what you want if you are doing "vpi_get_value", for example.
|
||||
*/
|
||||
extern bool vector4_to_value(const vvp_vector4_t&a, long&val, bool is_signed, bool is_arithmetic =true);
|
||||
extern bool vector4_to_value(const vvp_vector4_t&a, unsigned long&val);
|
||||
extern bool vector4_to_value(const vvp_vector4_t&a, int32_t&val, bool is_signed, bool is_arithmetic =true);
|
||||
#ifndef UL_AND_TIME64_SAME
|
||||
extern bool vector4_to_value(const vvp_vector4_t&a, int64_t&val, bool is_signed, bool is_arithmetic =true);
|
||||
extern bool vector4_to_value(const vvp_vector4_t&a, vvp_time64_t&val);
|
||||
#endif
|
||||
template <class T> extern bool vector4_to_value(const vvp_vector4_t&a, T&val,
|
||||
bool is_signed,
|
||||
bool is_arithmetic =true);
|
||||
|
||||
template <class T> extern bool vector4_to_value(const vvp_vector4_t&a, T&val);
|
||||
|
||||
extern bool vector4_to_value(const vvp_vector4_t&a, double&val, bool is_signed);
|
||||
|
||||
extern bool vector2_to_value(const vvp_vector2_t&a, int32_t&val, bool is_signed);
|
||||
|
|
|
|||
|
|
@ -32,39 +32,112 @@ vvp_darray::~vvp_darray()
|
|||
{
|
||||
}
|
||||
|
||||
void vvp_darray::set_word(unsigned adr, const vvp_vector4_t&)
|
||||
void vvp_darray::set_word(unsigned, const vvp_vector4_t&)
|
||||
{
|
||||
cerr << "XXXX set_word not implemented for " << typeid(*this).name() << endl;
|
||||
cerr << "XXXX set_word(vvp_vector4_t) not implemented for " << typeid(*this).name() << endl;
|
||||
}
|
||||
|
||||
void vvp_darray::set_word(unsigned, double)
|
||||
{
|
||||
cerr << "XXXX set_word(double) not implemented for " << typeid(*this).name() << endl;
|
||||
}
|
||||
|
||||
void vvp_darray::set_word(unsigned, const string&)
|
||||
{
|
||||
cerr << "XXXX set_word(string) not implemented for " << typeid(*this).name() << endl;
|
||||
}
|
||||
|
||||
void vvp_darray::get_word(unsigned, vvp_vector4_t&)
|
||||
{
|
||||
cerr << "XXXX get_word not implemented for " << typeid(*this).name() << endl;
|
||||
cerr << "XXXX get_word(vvp_vector4_t) not implemented for " << typeid(*this).name() << endl;
|
||||
}
|
||||
|
||||
template <> vvp_darray_atom<int32_t>::~vvp_darray_atom()
|
||||
void vvp_darray::get_word(unsigned, double&)
|
||||
{
|
||||
cerr << "XXXX get_word(double) not implemented for " << typeid(*this).name() << endl;
|
||||
}
|
||||
|
||||
void vvp_darray::get_word(unsigned, string&)
|
||||
{
|
||||
cerr << "XXXX get_word(string) not implemented for " << typeid(*this).name() << endl;
|
||||
}
|
||||
|
||||
template <class TYPE> vvp_darray_atom<TYPE>::~vvp_darray_atom()
|
||||
{
|
||||
}
|
||||
|
||||
template <> void vvp_darray_atom<int32_t>::set_word(unsigned adr, const vvp_vector4_t&value)
|
||||
template <class TYPE> void vvp_darray_atom<TYPE>::set_word(unsigned adr, const vvp_vector4_t&value)
|
||||
{
|
||||
if (adr >= array_.size())
|
||||
return;
|
||||
vector4_to_value(value, array_[adr], true, false);
|
||||
TYPE tmp;
|
||||
vector4_to_value(value, tmp, true, false);
|
||||
array_[adr] = tmp;
|
||||
}
|
||||
|
||||
template <> void vvp_darray_atom<int32_t>::get_word(unsigned adr, vvp_vector4_t&value)
|
||||
template <class TYPE> void vvp_darray_atom<TYPE>::get_word(unsigned adr, vvp_vector4_t&value)
|
||||
{
|
||||
if (adr >= array_.size()) {
|
||||
value = vvp_vector4_t(32, BIT4_X);
|
||||
value = vvp_vector4_t(8*sizeof(TYPE), BIT4_X);
|
||||
return;
|
||||
}
|
||||
|
||||
uint32_t word = array_[adr];
|
||||
vvp_vector4_t tmp (32, BIT4_0);
|
||||
for (unsigned idx = 0 ; idx < 32 ; idx += 1) {
|
||||
TYPE word = array_[adr];
|
||||
vvp_vector4_t tmp (8*sizeof(TYPE), BIT4_0);
|
||||
for (unsigned idx = 0 ; idx < tmp.size() ; idx += 1) {
|
||||
if (word&1) tmp.set_bit(idx, BIT4_1);
|
||||
word >>= 1;
|
||||
}
|
||||
value = tmp;
|
||||
}
|
||||
|
||||
template class vvp_darray_atom<uint8_t>;
|
||||
template class vvp_darray_atom<uint16_t>;
|
||||
template class vvp_darray_atom<uint32_t>;
|
||||
template class vvp_darray_atom<uint64_t>;
|
||||
template class vvp_darray_atom<int8_t>;
|
||||
template class vvp_darray_atom<int16_t>;
|
||||
template class vvp_darray_atom<int32_t>;
|
||||
template class vvp_darray_atom<int64_t>;
|
||||
|
||||
vvp_darray_real::~vvp_darray_real()
|
||||
{
|
||||
}
|
||||
|
||||
void vvp_darray_real::set_word(unsigned adr, double value)
|
||||
{
|
||||
if (adr >= array_.size())
|
||||
return;
|
||||
array_[adr] = value;
|
||||
}
|
||||
|
||||
void vvp_darray_real::get_word(unsigned adr, double&value)
|
||||
{
|
||||
if (adr >= array_.size()) {
|
||||
value = 0.0;
|
||||
return;
|
||||
}
|
||||
|
||||
value = array_[adr];
|
||||
}
|
||||
|
||||
vvp_darray_string::~vvp_darray_string()
|
||||
{
|
||||
}
|
||||
|
||||
void vvp_darray_string::set_word(unsigned adr, const string&value)
|
||||
{
|
||||
if (adr >= array_.size())
|
||||
return;
|
||||
array_[adr] = value;
|
||||
}
|
||||
|
||||
void vvp_darray_string::get_word(unsigned adr, string&value)
|
||||
{
|
||||
if (adr >= array_.size()) {
|
||||
value = 0.0;
|
||||
return;
|
||||
}
|
||||
|
||||
value = array_[adr];
|
||||
}
|
||||
|
|
|
|||
|
|
@ -20,6 +20,7 @@
|
|||
*/
|
||||
|
||||
# include <stdlib.h>
|
||||
# include <string>
|
||||
# include <vector>
|
||||
|
||||
typedef class vvp_object*vvp_object_t;
|
||||
|
|
@ -40,9 +41,14 @@ class vvp_darray : public vvp_object {
|
|||
inline size_t get_size(void) const { return size_; }
|
||||
|
||||
virtual void set_word(unsigned adr, const vvp_vector4_t&value);
|
||||
|
||||
virtual void get_word(unsigned adr, vvp_vector4_t&value);
|
||||
|
||||
virtual void set_word(unsigned adr, double value);
|
||||
virtual void get_word(unsigned adr, double&value);
|
||||
|
||||
virtual void set_word(unsigned adr, const std::string&value);
|
||||
virtual void get_word(unsigned adr, std::string&value);
|
||||
|
||||
private:
|
||||
size_t size_;
|
||||
};
|
||||
|
|
@ -54,11 +60,36 @@ template <class TYPE> class vvp_darray_atom : public vvp_darray {
|
|||
~vvp_darray_atom();
|
||||
|
||||
void set_word(unsigned adr, const vvp_vector4_t&value);
|
||||
|
||||
void get_word(unsigned adr, vvp_vector4_t&value);
|
||||
|
||||
private:
|
||||
std::vector<TYPE> array_;
|
||||
};
|
||||
|
||||
class vvp_darray_real : public vvp_darray {
|
||||
|
||||
public:
|
||||
inline vvp_darray_real(size_t siz) : vvp_darray(siz), array_(siz) { }
|
||||
~vvp_darray_real();
|
||||
|
||||
void set_word(unsigned adr, double value);
|
||||
void get_word(unsigned adr, double&value);
|
||||
|
||||
private:
|
||||
std::vector<double> array_;
|
||||
};
|
||||
|
||||
class vvp_darray_string : public vvp_darray {
|
||||
|
||||
public:
|
||||
inline vvp_darray_string(size_t siz) : vvp_darray(siz), array_(siz) { }
|
||||
~vvp_darray_string();
|
||||
|
||||
void set_word(unsigned adr, const std::string&value);
|
||||
void get_word(unsigned adr, std::string&value);
|
||||
|
||||
private:
|
||||
std::vector<std::string> array_;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
|
|
|||
Loading…
Reference in New Issue