Generalize user defined function return type handling.
I'm gonna need functions to return class objects, so generalize the output types of user defined functions.
This commit is contained in:
parent
c4257ecfc9
commit
20ee350601
|
|
@ -25,7 +25,7 @@ PFunction::PFunction(perm_string name, LexicalScope*parent, bool is_auto__)
|
||||||
: PTaskFunc(name, parent), statement_(0)
|
: PTaskFunc(name, parent), statement_(0)
|
||||||
{
|
{
|
||||||
is_auto_ = is_auto__;
|
is_auto_ = is_auto__;
|
||||||
return_type_.type = PTF_NONE;
|
return_type_ = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
PFunction::~PFunction()
|
PFunction::~PFunction()
|
||||||
|
|
@ -39,7 +39,7 @@ void PFunction::set_statement(Statement*s)
|
||||||
statement_ = s;
|
statement_ = s;
|
||||||
}
|
}
|
||||||
|
|
||||||
void PFunction::set_return(PTaskFuncArg t)
|
void PFunction::set_return(const data_type_t*t)
|
||||||
{
|
{
|
||||||
return_type_ = t;
|
return_type_ = t;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
22
PTask.h
22
PTask.h
|
|
@ -32,24 +32,6 @@ class PWire;
|
||||||
class Statement;
|
class Statement;
|
||||||
class PExpr;
|
class PExpr;
|
||||||
|
|
||||||
enum PTaskFuncEnum {
|
|
||||||
PTF_NONE,
|
|
||||||
PTF_REG,
|
|
||||||
PTF_REG_S,
|
|
||||||
PTF_INTEGER,
|
|
||||||
PTF_REAL,
|
|
||||||
PTF_REALTIME,
|
|
||||||
PTF_TIME,
|
|
||||||
PTF_ATOM2,
|
|
||||||
PTF_ATOM2_S,
|
|
||||||
PTF_STRING,
|
|
||||||
PTF_VOID
|
|
||||||
};
|
|
||||||
|
|
||||||
struct PTaskFuncArg {
|
|
||||||
PTaskFuncEnum type;
|
|
||||||
std::list<pform_range_t>*range;
|
|
||||||
};
|
|
||||||
|
|
||||||
class PTaskFunc : public PScope, public LineInfo {
|
class PTaskFunc : public PScope, public LineInfo {
|
||||||
|
|
||||||
|
|
@ -126,7 +108,7 @@ class PFunction : public PTaskFunc {
|
||||||
~PFunction();
|
~PFunction();
|
||||||
|
|
||||||
void set_statement(Statement *s);
|
void set_statement(Statement *s);
|
||||||
void set_return(PTaskFuncArg t);
|
void set_return(const data_type_t*t);
|
||||||
|
|
||||||
void elaborate_scope(Design*des, NetScope*scope) const;
|
void elaborate_scope(Design*des, NetScope*scope) const;
|
||||||
|
|
||||||
|
|
@ -141,7 +123,7 @@ class PFunction : public PTaskFunc {
|
||||||
void dump(ostream&, unsigned) const;
|
void dump(ostream&, unsigned) const;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
PTaskFuncArg return_type_;
|
const data_type_t* return_type_;
|
||||||
Statement *statement_;
|
Statement *statement_;
|
||||||
bool is_auto_;
|
bool is_auto_;
|
||||||
};
|
};
|
||||||
|
|
|
||||||
15
PWire.cc
15
PWire.cc
|
|
@ -120,6 +120,7 @@ bool PWire::set_data_type(ivl_variable_type_t dt)
|
||||||
|
|
||||||
assert(data_type_ == IVL_VT_NO_TYPE);
|
assert(data_type_ == IVL_VT_NO_TYPE);
|
||||||
data_type_ = dt;
|
data_type_ = dt;
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -140,7 +141,14 @@ bool PWire::get_signed() const
|
||||||
|
|
||||||
bool PWire::get_isint() const
|
bool PWire::get_isint() const
|
||||||
{
|
{
|
||||||
return isint_;
|
if (isint_)
|
||||||
|
return true;
|
||||||
|
|
||||||
|
if (vector_type_t*tmp = dynamic_cast<vector_type_t*>(set_data_type_)) {
|
||||||
|
return tmp->integer_flag;
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool PWire::get_scalar() const
|
bool PWire::get_scalar() const
|
||||||
|
|
@ -257,6 +265,11 @@ void PWire::set_data_type(data_type_t*type)
|
||||||
{
|
{
|
||||||
assert(set_data_type_ == 0);
|
assert(set_data_type_ == 0);
|
||||||
set_data_type_ = type;
|
set_data_type_ = type;
|
||||||
|
|
||||||
|
if (vector_type_t*tmp = dynamic_cast<vector_type_t*>(type)) {
|
||||||
|
if (tmp->integer_flag)
|
||||||
|
isint_ = true;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void PWire::set_discipline(ivl_discipline_t d)
|
void PWire::set_discipline(ivl_discipline_t d)
|
||||||
|
|
|
||||||
22
elab_expr.cc
22
elab_expr.cc
|
|
@ -1134,7 +1134,7 @@ unsigned PECallFunction::test_width_method_(Design*des, NetScope*scope,
|
||||||
<< endl;
|
<< endl;
|
||||||
}
|
}
|
||||||
|
|
||||||
netclass_t* class_type = net->class_type();
|
const netclass_t* class_type = net->class_type();
|
||||||
member_type = class_type->get_property(member_name);
|
member_type = class_type->get_property(member_name);
|
||||||
use_path = tmp_path;
|
use_path = tmp_path;
|
||||||
|
|
||||||
|
|
@ -1164,7 +1164,7 @@ unsigned PECallFunction::test_width_method_(Design*des, NetScope*scope,
|
||||||
return expr_width_;
|
return expr_width_;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (netclass_t*class_type = net->class_type()) {
|
if (const netclass_t*class_type = net->class_type()) {
|
||||||
cerr << get_fileline() << ": PECallFunction::test_width_method_: "
|
cerr << get_fileline() << ": PECallFunction::test_width_method_: "
|
||||||
<< "Try to find method " << method_name
|
<< "Try to find method " << method_name
|
||||||
<< " of class " << class_type->get_name() << endl;
|
<< " of class " << class_type->get_name() << endl;
|
||||||
|
|
@ -1425,7 +1425,7 @@ NetExpr* PECallFunction::elaborate_access_func_(Design*des, NetScope*scope,
|
||||||
*/
|
*/
|
||||||
static NetExpr* check_for_enum_methods(const LineInfo*li,
|
static NetExpr* check_for_enum_methods(const LineInfo*li,
|
||||||
Design*des, NetScope*scope,
|
Design*des, NetScope*scope,
|
||||||
netenum_t*netenum,
|
const netenum_t*netenum,
|
||||||
pform_name_t use_path,
|
pform_name_t use_path,
|
||||||
perm_string method_name,
|
perm_string method_name,
|
||||||
NetExpr*expr,
|
NetExpr*expr,
|
||||||
|
|
@ -1760,7 +1760,7 @@ static NetExpr* check_for_class_property(const LineInfo*li,
|
||||||
NetNet*net,
|
NetNet*net,
|
||||||
const name_component_t&comp)
|
const name_component_t&comp)
|
||||||
{
|
{
|
||||||
netclass_t*class_type = net->class_type();
|
const netclass_t*class_type = net->class_type();
|
||||||
const ivl_type_s*ptype = class_type->get_property(comp.name);
|
const ivl_type_s*ptype = class_type->get_property(comp.name);
|
||||||
|
|
||||||
if (ptype == 0) {
|
if (ptype == 0) {
|
||||||
|
|
@ -2055,7 +2055,7 @@ NetExpr* PECallFunction::elaborate_expr_method_(Design*des, NetScope*scope,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (netenum_t*netenum = net->enumeration()) {
|
if (const netenum_t*netenum = net->enumeration()) {
|
||||||
// We may need the net expression for the
|
// We may need the net expression for the
|
||||||
// enumeration variable so get it.
|
// enumeration variable so get it.
|
||||||
NetESignal*expr = new NetESignal(net);
|
NetESignal*expr = new NetESignal(net);
|
||||||
|
|
@ -2082,7 +2082,7 @@ NetExpr* PECallFunction::elaborate_expr_method_(Design*des, NetScope*scope,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (netclass_t*class_type = net->class_type()) {
|
if (const netclass_t*class_type = net->class_type()) {
|
||||||
NetScope*func = class_type->method_from_name(method_name);
|
NetScope*func = class_type->method_from_name(method_name);
|
||||||
if (func == 0) {
|
if (func == 0) {
|
||||||
return 0;
|
return 0;
|
||||||
|
|
@ -2595,7 +2595,7 @@ unsigned PEIdent::test_width(Design*des, NetScope*scope, width_mode_t&mode)
|
||||||
ivl_assert(*this, 0);
|
ivl_assert(*this, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (netdarray_t*darray = net? net->darray_type() : 0) {
|
if (const netdarray_t*darray = net? net->darray_type() : 0) {
|
||||||
if (use_sel == index_component_t::SEL_BIT) {
|
if (use_sel == index_component_t::SEL_BIT) {
|
||||||
expr_type_ = darray->element_base_type();
|
expr_type_ = darray->element_base_type();
|
||||||
expr_width_ = darray->element_width();
|
expr_width_ = darray->element_width();
|
||||||
|
|
@ -2637,7 +2637,7 @@ unsigned PEIdent::test_width(Design*des, NetScope*scope, width_mode_t&mode)
|
||||||
// The width of an enumeration literal is the width of the
|
// The width of an enumeration literal is the width of the
|
||||||
// enumeration base.
|
// enumeration base.
|
||||||
if (const NetEConstEnum*par_enum = dynamic_cast<const NetEConstEnum*> (par)) {
|
if (const NetEConstEnum*par_enum = dynamic_cast<const NetEConstEnum*> (par)) {
|
||||||
netenum_t*use_enum = par_enum->enumeration();
|
const netenum_t*use_enum = par_enum->enumeration();
|
||||||
ivl_assert(*this, use_enum != 0);
|
ivl_assert(*this, use_enum != 0);
|
||||||
|
|
||||||
expr_type_ = use_enum->base_type();
|
expr_type_ = use_enum->base_type();
|
||||||
|
|
@ -2714,7 +2714,7 @@ unsigned PEIdent::test_width(Design*des, NetScope*scope, width_mode_t&mode)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (netclass_t*class_type = net->class_type()) {
|
if (const netclass_t*class_type = net->class_type()) {
|
||||||
const ivl_type_s*ptype = class_type->get_property(method_name);
|
const ivl_type_s*ptype = class_type->get_property(method_name);
|
||||||
if (ptype) {
|
if (ptype) {
|
||||||
expr_type_ = ptype->base_type();
|
expr_type_ = ptype->base_type();
|
||||||
|
|
@ -3037,7 +3037,7 @@ NetExpr* PEIdent::elaborate_expr(Design*des, NetScope*scope,
|
||||||
if (net != 0) {
|
if (net != 0) {
|
||||||
// If this net is actually an enum, the method may
|
// If this net is actually an enum, the method may
|
||||||
// be an enumeration method.
|
// be an enumeration method.
|
||||||
if (netenum_t*netenum = net->enumeration()) {
|
if (const netenum_t*netenum = net->enumeration()) {
|
||||||
// We may need the net expression for the
|
// We may need the net expression for the
|
||||||
// enumeration variable so get it.
|
// enumeration variable so get it.
|
||||||
NetESignal*expr = new NetESignal(net);
|
NetESignal*expr = new NetESignal(net);
|
||||||
|
|
@ -4177,7 +4177,7 @@ NetExpr* PEIdent::elaborate_expr_net_bit_(Design*des, NetScope*scope,
|
||||||
|
|
||||||
NetExpr*mux = elab_and_eval(des, scope, index_tail.msb, -1, need_const);
|
NetExpr*mux = elab_and_eval(des, scope, index_tail.msb, -1, need_const);
|
||||||
|
|
||||||
if (netdarray_t*darray = net->sig()->darray_type()) {
|
if (const netdarray_t*darray = net->sig()->darray_type()) {
|
||||||
// Special case: This is a select of a dynamic
|
// Special case: This is a select of a dynamic
|
||||||
// array. Generate a NetESelect and attach it to
|
// array. Generate a NetESelect and attach it to
|
||||||
// the NetESignal. This should be interpreted as
|
// the NetESignal. This should be interpreted as
|
||||||
|
|
|
||||||
|
|
@ -790,12 +790,12 @@ bool PEIdent::elaborate_lval_net_class_member_(Design*des, NetScope*,
|
||||||
<< " of " << lv->sig()->name() << "." << endl;
|
<< " of " << lv->sig()->name() << "." << endl;
|
||||||
}
|
}
|
||||||
|
|
||||||
netclass_t*class_type = lv->sig()->class_type();
|
const netclass_t*class_type = lv->sig()->class_type();
|
||||||
ivl_assert(*this, class_type);
|
ivl_assert(*this, class_type);
|
||||||
|
|
||||||
/* Make sure the property is really present in the class. If
|
/* Make sure the property is really present in the class. If
|
||||||
not, then generate an error message and return an error. */
|
not, then generate an error message and return an error. */
|
||||||
const ivl_type_s*ptype = class_type->get_property(method_name);
|
ivl_type_t ptype = class_type->get_property(method_name);
|
||||||
if (ptype == 0) {
|
if (ptype == 0) {
|
||||||
cerr << get_fileline() << ": error: Class " << class_type->get_name()
|
cerr << get_fileline() << ": error: Class " << class_type->get_name()
|
||||||
<< " does not have a property " << method_name << "." << endl;
|
<< " does not have a property " << method_name << "." << endl;
|
||||||
|
|
|
||||||
|
|
@ -280,6 +280,8 @@ static void elaborate_scope_enumeration(Design*des, NetScope*scope,
|
||||||
if (cur_value.is_defined())
|
if (cur_value.is_defined())
|
||||||
cur_value = cur_value + one_value;
|
cur_value = cur_value + one_value;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
use_enum->insert_name_close();
|
||||||
}
|
}
|
||||||
|
|
||||||
static void elaborate_scope_enumerations(Design*des, NetScope*scope,
|
static void elaborate_scope_enumerations(Design*des, NetScope*scope,
|
||||||
|
|
|
||||||
153
elab_sig.cc
153
elab_sig.cc
|
|
@ -537,147 +537,20 @@ void PFunction::elaborate_sig(Design*des, NetScope*scope) const
|
||||||
|
|
||||||
elaborate_sig_wires_(des, scope);
|
elaborate_sig_wires_(des, scope);
|
||||||
|
|
||||||
NetNet*ret_sig = 0;
|
ivl_type_t ret_type;
|
||||||
netvector_t*ret_vec = 0;
|
|
||||||
|
|
||||||
/* Create the signals/variables of the return value and write
|
if (return_type_) {
|
||||||
them into the function scope. */
|
ret_type = return_type_->elaborate_type(des, scope);
|
||||||
switch (return_type_.type) {
|
} else {
|
||||||
|
netvector_t*tmp = new netvector_t(IVL_VT_LOGIC);
|
||||||
case PTF_REG:
|
tmp->set_scalar(true);
|
||||||
case PTF_REG_S:
|
ret_type = tmp;
|
||||||
if (return_type_.range) {
|
|
||||||
ivl_assert(*this, return_type_.range->size() == 1);
|
|
||||||
pform_range_t&return_range = return_type_.range->front();
|
|
||||||
|
|
||||||
NetExpr*me = elab_and_eval(des, scope,
|
|
||||||
return_range.first, -1,
|
|
||||||
true);
|
|
||||||
assert(me);
|
|
||||||
NetExpr*le = elab_and_eval(des, scope,
|
|
||||||
return_range.second, -1,
|
|
||||||
true);
|
|
||||||
assert(le);
|
|
||||||
|
|
||||||
long mnum = 0, lnum = 0;
|
|
||||||
if ( ! get_const_argument(me, mnum) ) {
|
|
||||||
cerr << me->get_fileline() << ": error: "
|
|
||||||
"Unable to evaluate constant expression "
|
|
||||||
<< *me << "." << endl;
|
|
||||||
des->errors += 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
if ( ! get_const_argument(le, lnum) ) {
|
|
||||||
cerr << le->get_fileline() << ": error: "
|
|
||||||
"Unable to evaluate constant expression "
|
|
||||||
<< *le << "." << endl;
|
|
||||||
des->errors += 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
vector<netrange_t> packed;
|
|
||||||
packed.push_back(netrange_t(mnum, lnum));
|
|
||||||
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_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->port_type(NetNet::POUTPUT);
|
|
||||||
break;
|
|
||||||
|
|
||||||
case PTF_INTEGER:
|
|
||||||
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->port_type(NetNet::POUTPUT);
|
|
||||||
break;
|
|
||||||
|
|
||||||
case PTF_TIME:
|
|
||||||
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->port_type(NetNet::POUTPUT);
|
|
||||||
break;
|
|
||||||
|
|
||||||
case PTF_REAL:
|
|
||||||
case PTF_REALTIME:
|
|
||||||
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->port_type(NetNet::POUTPUT);
|
|
||||||
break;
|
|
||||||
|
|
||||||
case PTF_ATOM2:
|
|
||||||
case PTF_ATOM2_S:
|
|
||||||
long use_wid;
|
|
||||||
{
|
|
||||||
ivl_assert(*this, return_type_.range->size() == 1);
|
|
||||||
pform_range_t&return_range = return_type_.range->front();
|
|
||||||
NetExpr*me = elab_and_eval(des, scope,
|
|
||||||
return_range.first, -1,
|
|
||||||
true);
|
|
||||||
ivl_assert(*this, me);
|
|
||||||
NetExpr*le = elab_and_eval(des, scope,
|
|
||||||
return_range.second, -1,
|
|
||||||
true);
|
|
||||||
ivl_assert(*this, le);
|
|
||||||
|
|
||||||
long mnum = 0, lnum = 0;
|
|
||||||
if ( ! get_const_argument(me, mnum) ) {
|
|
||||||
cerr << me->get_fileline() << ": error: "
|
|
||||||
"Unable to evaluate constant expression "
|
|
||||||
<< *me << "." << endl;
|
|
||||||
des->errors += 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
if ( ! get_const_argument(le, lnum) ) {
|
|
||||||
cerr << le->get_fileline() << ": error: "
|
|
||||||
"Unable to evaluate constant expression "
|
|
||||||
<< *le << "." << endl;
|
|
||||||
des->errors += 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
use_wid = mnum - lnum + 1;
|
|
||||||
}
|
|
||||||
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->port_type(NetNet::POUTPUT);
|
|
||||||
break;
|
|
||||||
|
|
||||||
case PTF_STRING:
|
|
||||||
cerr << get_fileline() << ": sorry: String functions are not supported yet" << endl;
|
|
||||||
break;
|
|
||||||
|
|
||||||
case PTF_VOID:
|
|
||||||
// Void functions have no return value, so there is no
|
|
||||||
// signal to create here.
|
|
||||||
break;
|
|
||||||
|
|
||||||
default:
|
|
||||||
/* If we do not have any ports or a return type this
|
|
||||||
* is probably a bad function definition. */
|
|
||||||
cerr << get_fileline() << ": error: Bad definition for "
|
|
||||||
<< "function " << scope->basename() << "?" << endl;
|
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
|
list<netrange_t> ret_unpacked;
|
||||||
|
NetNet*ret_sig = new NetNet(scope, fname, NetNet::REG, ret_unpacked, ret_type);
|
||||||
|
|
||||||
|
ret_sig->set_line(*this);
|
||||||
|
ret_sig->port_type(NetNet::POUTPUT);
|
||||||
|
|
||||||
vector<NetNet*>ports;
|
vector<NetNet*>ports;
|
||||||
elaborate_sig_ports_(des, scope, ports);
|
elaborate_sig_ports_(des, scope, ports);
|
||||||
|
|
@ -1290,7 +1163,7 @@ NetNet* PWire::elaborate_sig(Design*des, NetScope*scope) const
|
||||||
|
|
||||||
} else if (enum_type_t*enum_type = dynamic_cast<enum_type_t*>(set_data_type_)) {
|
} else if (enum_type_t*enum_type = dynamic_cast<enum_type_t*>(set_data_type_)) {
|
||||||
list<named_pexpr_t>::const_iterator sample_name = enum_type->names->begin();
|
list<named_pexpr_t>::const_iterator sample_name = enum_type->names->begin();
|
||||||
netenum_t*use_enum = scope->enumeration_for_name(sample_name->name);
|
const netenum_t*use_enum = scope->enumeration_for_name(sample_name->name);
|
||||||
|
|
||||||
if (debug_elaborate) {
|
if (debug_elaborate) {
|
||||||
cerr << get_fileline() << ": debug: Create signal " << wtype
|
cerr << get_fileline() << ": debug: Create signal " << wtype
|
||||||
|
|
|
||||||
37
elab_type.cc
37
elab_type.cc
|
|
@ -23,6 +23,7 @@
|
||||||
# include "netdarray.h"
|
# include "netdarray.h"
|
||||||
# include "netscalar.h"
|
# include "netscalar.h"
|
||||||
# include "netvector.h"
|
# include "netvector.h"
|
||||||
|
# include "netmisc.h"
|
||||||
# include <typeinfo>
|
# include <typeinfo>
|
||||||
# include "ivl_assert.h"
|
# include "ivl_assert.h"
|
||||||
|
|
||||||
|
|
@ -77,6 +78,42 @@ ivl_type_s* class_type_t::elaborate_type(Design*, NetScope*scope) const
|
||||||
return scope->find_class(name);
|
return scope->find_class(name);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ivl_type_s* vector_type_t::elaborate_type(Design*des, NetScope*scope) const
|
||||||
|
{
|
||||||
|
vector<netrange_t> packed;
|
||||||
|
|
||||||
|
if (pdims.get()) {
|
||||||
|
for (list<pform_range_t>::const_iterator cur = pdims->begin()
|
||||||
|
; cur != pdims->end() ; ++ cur) {
|
||||||
|
|
||||||
|
NetExpr*me = elab_and_eval(des, scope, cur->first, 0, true);
|
||||||
|
assert(me);
|
||||||
|
|
||||||
|
NetExpr*le = elab_and_eval(des, scope, cur->second, 0, true);
|
||||||
|
assert(le);
|
||||||
|
|
||||||
|
long mnum = 0, lnum = 0;
|
||||||
|
if ( ! eval_as_long(mnum, me) ) {
|
||||||
|
assert(0);
|
||||||
|
des->errors += 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( ! eval_as_long(lnum, le) ) {
|
||||||
|
assert(0);
|
||||||
|
des->errors += 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
packed.push_back(netrange_t(mnum, lnum));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
netvector_t*tmp = new netvector_t(packed, base_type);
|
||||||
|
tmp->set_signed(signed_flag);
|
||||||
|
tmp->set_isint(integer_flag);
|
||||||
|
|
||||||
|
return tmp;
|
||||||
|
}
|
||||||
|
|
||||||
ivl_type_s* real_type_t::elaborate_type(Design*, NetScope*) const
|
ivl_type_s* real_type_t::elaborate_type(Design*, NetScope*) const
|
||||||
{
|
{
|
||||||
switch (type_code) {
|
switch (type_code) {
|
||||||
|
|
|
||||||
|
|
@ -3314,7 +3314,7 @@ NetProc* PCallTask::elaborate_method_(Design*des, NetScope*scope) const
|
||||||
return sys;
|
return sys;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (netclass_t*class_type = net->class_type()) {
|
if (const netclass_t*class_type = net->class_type()) {
|
||||||
NetScope*task = class_type->method_from_name(method_name);
|
NetScope*task = class_type->method_from_name(method_name);
|
||||||
if (task == 0) {
|
if (task == 0) {
|
||||||
cerr << get_fileline() << ": internal error: "
|
cerr << get_fileline() << ": internal error: "
|
||||||
|
|
|
||||||
|
|
@ -165,7 +165,7 @@ typedef struct ivl_branch_s *ivl_branch_t;
|
||||||
typedef struct ivl_delaypath_s*ivl_delaypath_t;
|
typedef struct ivl_delaypath_s*ivl_delaypath_t;
|
||||||
typedef struct ivl_design_s *ivl_design_t;
|
typedef struct ivl_design_s *ivl_design_t;
|
||||||
typedef _CLASS ivl_discipline_s*ivl_discipline_t;
|
typedef _CLASS ivl_discipline_s*ivl_discipline_t;
|
||||||
typedef _CLASS netenum_t *ivl_enumtype_t;
|
typedef const _CLASS netenum_t*ivl_enumtype_t;
|
||||||
typedef struct ivl_event_s *ivl_event_t;
|
typedef struct ivl_event_s *ivl_event_t;
|
||||||
typedef struct ivl_expr_s *ivl_expr_t;
|
typedef struct ivl_expr_s *ivl_expr_t;
|
||||||
typedef struct ivl_island_s *ivl_island_t;
|
typedef struct ivl_island_s *ivl_island_t;
|
||||||
|
|
|
||||||
|
|
@ -102,7 +102,7 @@ unsigned NetAssign_::lwidth() const
|
||||||
return ptype->packed_width();
|
return ptype->packed_width();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (netdarray_t*darray = sig_->darray_type()) {
|
if (const netdarray_t*darray = sig_->darray_type()) {
|
||||||
if (word_ == 0)
|
if (word_ == 0)
|
||||||
return 1;
|
return 1;
|
||||||
else
|
else
|
||||||
|
|
@ -122,7 +122,7 @@ ivl_variable_type_t NetAssign_::expr_type() const
|
||||||
return tmp->base_type();
|
return tmp->base_type();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (netdarray_t*darray = sig_->darray_type()) {
|
if (const netdarray_t*darray = sig_->darray_type()) {
|
||||||
if (word_ == 0)
|
if (word_ == 0)
|
||||||
return IVL_VT_DARRAY;
|
return IVL_VT_DARRAY;
|
||||||
else
|
else
|
||||||
|
|
@ -153,9 +153,9 @@ const ivl_type_s* NetAssign_::net_type() const
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
netenum_t*NetAssign_::enumeration() const
|
const netenum_t*NetAssign_::enumeration() const
|
||||||
{
|
{
|
||||||
netenum_t*tmp = 0;
|
const netenum_t*tmp = 0;
|
||||||
|
|
||||||
// If the base signal is not an enumeration, return nil.
|
// If the base signal is not an enumeration, return nil.
|
||||||
if ( (tmp = sig_->enumeration()) == 0 )
|
if ( (tmp = sig_->enumeration()) == 0 )
|
||||||
|
|
|
||||||
14
net_expr.cc
14
net_expr.cc
|
|
@ -64,7 +64,7 @@ ivl_variable_type_t NetExpr::expr_type() const
|
||||||
return IVL_VT_LOGIC;
|
return IVL_VT_LOGIC;
|
||||||
}
|
}
|
||||||
|
|
||||||
netenum_t*NetExpr::enumeration() const
|
const netenum_t*NetExpr::enumeration() const
|
||||||
{
|
{
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
@ -246,7 +246,7 @@ void NetEConcat::set(unsigned idx, NetExpr*e)
|
||||||
expr_width( expr_width() + repeat_ * e->expr_width() );
|
expr_width( expr_width() + repeat_ * e->expr_width() );
|
||||||
}
|
}
|
||||||
|
|
||||||
NetEConstEnum::NetEConstEnum(NetScope*s, perm_string n, netenum_t*eset, const verinum&v)
|
NetEConstEnum::NetEConstEnum(NetScope*s, perm_string n, const netenum_t*eset, const verinum&v)
|
||||||
: NetEConst(v), scope_(s), enum_set_(eset), name_(n)
|
: NetEConst(v), scope_(s), enum_set_(eset), name_(n)
|
||||||
{
|
{
|
||||||
assert(has_width());
|
assert(has_width());
|
||||||
|
|
@ -256,7 +256,7 @@ NetEConstEnum::~NetEConstEnum()
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
netenum_t*NetEConstEnum::enumeration() const
|
const netenum_t*NetEConstEnum::enumeration() const
|
||||||
{
|
{
|
||||||
return enum_set_;
|
return enum_set_;
|
||||||
}
|
}
|
||||||
|
|
@ -307,7 +307,7 @@ const NetScope* NetECRealParam::scope() const
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
NetENetenum::NetENetenum(netenum_t*s)
|
NetENetenum::NetENetenum(const netenum_t*s)
|
||||||
: netenum_(s)
|
: netenum_(s)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
@ -316,7 +316,7 @@ NetENetenum::~NetENetenum()
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
netenum_t* NetENetenum::netenum() const
|
const netenum_t* NetENetenum::netenum() const
|
||||||
{
|
{
|
||||||
return netenum_;
|
return netenum_;
|
||||||
}
|
}
|
||||||
|
|
@ -456,7 +456,7 @@ NetESFunc::NetESFunc(const char*n, ivl_type_t rtype, unsigned np)
|
||||||
ivl_assert(*this, 0);
|
ivl_assert(*this, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
NetESFunc::NetESFunc(const char*n, netenum_t*enum_type, unsigned np)
|
NetESFunc::NetESFunc(const char*n, const netenum_t*enum_type, unsigned np)
|
||||||
: name_(0), type_(enum_type->base_type()), enum_type_(enum_type), parms_(np)
|
: name_(0), type_(enum_type->base_type()), enum_type_(enum_type), parms_(np)
|
||||||
{
|
{
|
||||||
name_ = lex_strings.add(n);
|
name_ = lex_strings.add(n);
|
||||||
|
|
@ -506,7 +506,7 @@ ivl_variable_type_t NetESFunc::expr_type() const
|
||||||
return type_;
|
return type_;
|
||||||
}
|
}
|
||||||
|
|
||||||
netenum_t* NetESFunc::enumeration() const
|
const netenum_t* NetESFunc::enumeration() const
|
||||||
{
|
{
|
||||||
return enum_type_;
|
return enum_type_;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -570,7 +570,7 @@ bool NetScope::add_enumeration_name(netenum_t*enum_set, perm_string name)
|
||||||
return cur.second;
|
return cur.second;
|
||||||
}
|
}
|
||||||
|
|
||||||
netenum_t*NetScope::enumeration_for_name(perm_string name)
|
const netenum_t*NetScope::enumeration_for_name(perm_string name)
|
||||||
{
|
{
|
||||||
NetEConstEnum*tmp = enum_names_[name];
|
NetEConstEnum*tmp = enum_names_[name];
|
||||||
assert(tmp != 0);
|
assert(tmp != 0);
|
||||||
|
|
|
||||||
|
|
@ -92,7 +92,7 @@ ivl_type_t netclass_t::get_prop_type(size_t idx) const
|
||||||
return property_table_[idx].type;
|
return property_table_[idx].type;
|
||||||
}
|
}
|
||||||
|
|
||||||
NetScope*netclass_t::method_from_name(perm_string name)
|
NetScope*netclass_t::method_from_name(perm_string name) const
|
||||||
{
|
{
|
||||||
NetScope*task = class_scope_->child( hname_t(name) );
|
NetScope*task = class_scope_->child( hname_t(name) );
|
||||||
if (task == 0) return 0;
|
if (task == 0) return 0;
|
||||||
|
|
|
||||||
|
|
@ -59,7 +59,7 @@ class netclass_t : public ivl_type_s {
|
||||||
int property_idx_from_name(perm_string pname) const;
|
int property_idx_from_name(perm_string pname) const;
|
||||||
|
|
||||||
// The task method scopes from the method name.
|
// The task method scopes from the method name.
|
||||||
NetScope*method_from_name(perm_string mname);
|
NetScope*method_from_name(perm_string mname) const;
|
||||||
|
|
||||||
void elaborate_sig(Design*des, PClass*pclass);
|
void elaborate_sig(Design*des, PClass*pclass);
|
||||||
void elaborate(Design*des, PClass*pclass);
|
void elaborate(Design*des, PClass*pclass);
|
||||||
|
|
|
||||||
53
netenum.cc
53
netenum.cc
|
|
@ -73,6 +73,32 @@ bool netenum_t::insert_name(size_t name_idx, perm_string name, const verinum&val
|
||||||
return res.second;
|
return res.second;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void netenum_t::insert_name_close(void)
|
||||||
|
{
|
||||||
|
for (size_t idx = 0 ; idx < names_.size() ; idx += 1) {
|
||||||
|
netenum_t::iterator cur = names_map_.find(names_[idx]);
|
||||||
|
|
||||||
|
vector<char>str (cur->second.len() + 1);
|
||||||
|
for (unsigned bit = 0 ; bit < cur->second.len() ; bit += 1) {
|
||||||
|
switch (cur->second.get(bit)) {
|
||||||
|
case verinum::V0:
|
||||||
|
str[bit] = '0';
|
||||||
|
break;
|
||||||
|
case verinum::V1:
|
||||||
|
str[bit] = '1';
|
||||||
|
break;
|
||||||
|
case verinum::Vx:
|
||||||
|
str[bit] = 'x';
|
||||||
|
break;
|
||||||
|
case verinum::Vz:
|
||||||
|
str[bit] = 'z';
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
bits_[idx] = bits_strings.make(&str[0]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
netenum_t::iterator netenum_t::find_name(perm_string name) const
|
netenum_t::iterator netenum_t::find_name(perm_string name) const
|
||||||
{
|
{
|
||||||
return names_map_.find(name);
|
return names_map_.find(name);
|
||||||
|
|
@ -115,32 +141,7 @@ perm_string netenum_t::name_at(size_t idx) const
|
||||||
return names_[idx];
|
return names_[idx];
|
||||||
}
|
}
|
||||||
|
|
||||||
perm_string netenum_t::bits_at(size_t idx)
|
perm_string netenum_t::bits_at(size_t idx) const
|
||||||
{
|
{
|
||||||
assert(idx < names_.size());
|
|
||||||
|
|
||||||
if (bits_[idx] == 0) {
|
|
||||||
netenum_t::iterator cur = names_map_.find(names_[idx]);
|
|
||||||
|
|
||||||
vector<char>str (cur->second.len() + 1);
|
|
||||||
for (unsigned bit = 0 ; bit < cur->second.len() ; bit += 1) {
|
|
||||||
switch (cur->second.get(bit)) {
|
|
||||||
case verinum::V0:
|
|
||||||
str[bit] = '0';
|
|
||||||
break;
|
|
||||||
case verinum::V1:
|
|
||||||
str[bit] = '1';
|
|
||||||
break;
|
|
||||||
case verinum::Vx:
|
|
||||||
str[bit] = 'x';
|
|
||||||
break;
|
|
||||||
case verinum::Vz:
|
|
||||||
str[bit] = 'z';
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
bits_[idx] = bits_strings.make(&str[0]);
|
|
||||||
}
|
|
||||||
|
|
||||||
return bits_[idx];
|
return bits_[idx];
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -49,6 +49,9 @@ class netenum_t : public LineInfo, public ivl_type_s {
|
||||||
// enumeration value.
|
// enumeration value.
|
||||||
bool insert_name(size_t idx, perm_string name, const verinum&val);
|
bool insert_name(size_t idx, perm_string name, const verinum&val);
|
||||||
|
|
||||||
|
// Indicate that there will be no more names to insert.
|
||||||
|
void insert_name_close(void);
|
||||||
|
|
||||||
typedef std::map<perm_string,verinum>::const_iterator iterator;
|
typedef std::map<perm_string,verinum>::const_iterator iterator;
|
||||||
iterator find_name(perm_string name) const;
|
iterator find_name(perm_string name) const;
|
||||||
iterator end_name() const;
|
iterator end_name() const;
|
||||||
|
|
@ -59,7 +62,7 @@ class netenum_t : public LineInfo, public ivl_type_s {
|
||||||
iterator last_name() const;
|
iterator last_name() const;
|
||||||
|
|
||||||
perm_string name_at(size_t idx) const;
|
perm_string name_at(size_t idx) const;
|
||||||
perm_string bits_at(size_t idx);
|
perm_string bits_at(size_t idx) const;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
ivl_variable_type_t base_type_;
|
ivl_variable_type_t base_type_;
|
||||||
|
|
|
||||||
22
netlist.cc
22
netlist.cc
|
|
@ -530,7 +530,7 @@ void NetNet::calculate_slice_widths_from_packed_dims_(void)
|
||||||
}
|
}
|
||||||
|
|
||||||
NetNet::NetNet(NetScope*s, perm_string n, Type t,
|
NetNet::NetNet(NetScope*s, perm_string n, Type t,
|
||||||
const list<netrange_t>&unpacked, ivl_type_s*use_net_type)
|
const list<netrange_t>&unpacked, ivl_type_t use_net_type)
|
||||||
: NetObj(s, n, calculate_count(unpacked)),
|
: NetObj(s, n, calculate_count(unpacked)),
|
||||||
type_(t), port_type_(NOT_A_PORT),
|
type_(t), port_type_(NOT_A_PORT),
|
||||||
local_flag_(false), net_type_(use_net_type),
|
local_flag_(false), net_type_(use_net_type),
|
||||||
|
|
@ -762,7 +762,7 @@ bool NetNet::get_signed() const
|
||||||
|
|
||||||
bool NetNet::get_isint() const
|
bool NetNet::get_isint() const
|
||||||
{
|
{
|
||||||
if (netvector_t*vec = dynamic_cast<netvector_t*> (net_type_))
|
if (const netvector_t*vec = dynamic_cast<const netvector_t*> (net_type_))
|
||||||
return vec->get_isint();
|
return vec->get_isint();
|
||||||
else
|
else
|
||||||
return false;
|
return false;
|
||||||
|
|
@ -770,20 +770,20 @@ bool NetNet::get_isint() const
|
||||||
|
|
||||||
bool NetNet::get_scalar() const
|
bool NetNet::get_scalar() const
|
||||||
{
|
{
|
||||||
if (netvector_t*vec = dynamic_cast<netvector_t*> (net_type_))
|
if (const netvector_t*vec = dynamic_cast<const netvector_t*> (net_type_))
|
||||||
return vec->get_scalar();
|
return vec->get_scalar();
|
||||||
else
|
else
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
netenum_t*NetNet::enumeration(void) const
|
const netenum_t*NetNet::enumeration(void) const
|
||||||
{
|
{
|
||||||
return dynamic_cast<netenum_t*> (net_type_);
|
return dynamic_cast<const netenum_t*> (net_type_);
|
||||||
}
|
}
|
||||||
|
|
||||||
const netstruct_t*NetNet::struct_type(void) const
|
const netstruct_t*NetNet::struct_type(void) const
|
||||||
{
|
{
|
||||||
const ivl_type_s*cur_type = net_type_;
|
ivl_type_t cur_type = net_type_;
|
||||||
while (cur_type) {
|
while (cur_type) {
|
||||||
if (const netdarray_t*da = dynamic_cast<const netdarray_t*> (cur_type)) {
|
if (const netdarray_t*da = dynamic_cast<const netdarray_t*> (cur_type)) {
|
||||||
cur_type = da->element_type();
|
cur_type = da->element_type();
|
||||||
|
|
@ -803,14 +803,14 @@ const netstruct_t*NetNet::struct_type(void) const
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
netdarray_t* NetNet::darray_type(void) const
|
const netdarray_t* NetNet::darray_type(void) const
|
||||||
{
|
{
|
||||||
return dynamic_cast<netdarray_t*> (net_type_);
|
return dynamic_cast<const netdarray_t*> (net_type_);
|
||||||
}
|
}
|
||||||
|
|
||||||
netclass_t* NetNet::class_type(void) const
|
const netclass_t* NetNet::class_type(void) const
|
||||||
{
|
{
|
||||||
return dynamic_cast<netclass_t*> (net_type_);
|
return dynamic_cast<const netclass_t*> (net_type_);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|
@ -2375,7 +2375,7 @@ perm_string NetESignal::name() const
|
||||||
return net_->name();
|
return net_->name();
|
||||||
}
|
}
|
||||||
|
|
||||||
netenum_t* NetESignal::enumeration() const
|
const netenum_t* NetESignal::enumeration() const
|
||||||
{
|
{
|
||||||
return enum_type_;
|
return enum_type_;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
38
netlist.h
38
netlist.h
|
|
@ -604,7 +604,7 @@ class NetNet : public NetObj, public PortType {
|
||||||
// now, the unpacked type is not burried into an ivl_type_s object.
|
// now, the unpacked type is not burried into an ivl_type_s object.
|
||||||
explicit NetNet(NetScope*s, perm_string n, Type t,
|
explicit NetNet(NetScope*s, perm_string n, Type t,
|
||||||
const std::list<netrange_t>&unpacked,
|
const std::list<netrange_t>&unpacked,
|
||||||
ivl_type_s*type =0);
|
ivl_type_t type =0);
|
||||||
|
|
||||||
// This form builds a NetNet from its record/enum/darray
|
// This form builds a NetNet from its record/enum/darray
|
||||||
// definition. They should probably be replaced with a single
|
// definition. They should probably be replaced with a single
|
||||||
|
|
@ -639,10 +639,10 @@ class NetNet : public NetObj, public PortType {
|
||||||
bool get_scalar() const;
|
bool get_scalar() const;
|
||||||
|
|
||||||
inline const ivl_type_s* net_type(void) const { return net_type_; }
|
inline const ivl_type_s* net_type(void) const { return net_type_; }
|
||||||
netenum_t*enumeration(void) const;
|
const netenum_t*enumeration(void) const;
|
||||||
const netstruct_t*struct_type(void) const;
|
const netstruct_t*struct_type(void) const;
|
||||||
netdarray_t*darray_type(void) const;
|
const netdarray_t*darray_type(void) const;
|
||||||
netclass_t*class_type(void) const;
|
const netclass_t*class_type(void) const;
|
||||||
|
|
||||||
/* Attach a discipline to the net. */
|
/* Attach a discipline to the net. */
|
||||||
ivl_discipline_t get_discipline() const;
|
ivl_discipline_t get_discipline() const;
|
||||||
|
|
@ -729,7 +729,7 @@ class NetNet : public NetObj, public PortType {
|
||||||
Type type_ : 5;
|
Type type_ : 5;
|
||||||
PortType port_type_ : 3;
|
PortType port_type_ : 3;
|
||||||
bool local_flag_: 1;
|
bool local_flag_: 1;
|
||||||
ivl_type_s*net_type_;
|
ivl_type_t net_type_;
|
||||||
ivl_discipline_t discipline_;
|
ivl_discipline_t discipline_;
|
||||||
|
|
||||||
std::vector<netrange_t> unpacked_dims_;
|
std::vector<netrange_t> unpacked_dims_;
|
||||||
|
|
@ -848,7 +848,7 @@ class NetScope : public Attrib {
|
||||||
void add_enumeration_set(netenum_t*enum_set);
|
void add_enumeration_set(netenum_t*enum_set);
|
||||||
bool add_enumeration_name(netenum_t*enum_set, perm_string enum_name);
|
bool add_enumeration_name(netenum_t*enum_set, perm_string enum_name);
|
||||||
|
|
||||||
netenum_t* enumeration_for_name(perm_string name);
|
const netenum_t* enumeration_for_name(perm_string name);
|
||||||
|
|
||||||
void add_class(netclass_t*class_type);
|
void add_class(netclass_t*class_type);
|
||||||
netclass_t* find_class(perm_string name);
|
netclass_t* find_class(perm_string name);
|
||||||
|
|
@ -1810,7 +1810,7 @@ class NetExpr : public LineInfo {
|
||||||
// Return the enumeration set that defines this expressions
|
// Return the enumeration set that defines this expressions
|
||||||
// enumeration type, or return nil if the expression is not
|
// enumeration type, or return nil if the expression is not
|
||||||
// part of the enumeration.
|
// part of the enumeration.
|
||||||
virtual netenum_t*enumeration() const;
|
virtual const netenum_t*enumeration() const;
|
||||||
|
|
||||||
// This method evaluates the expression and returns an
|
// This method evaluates the expression and returns an
|
||||||
// equivalent expression that is reduced as far as compile
|
// equivalent expression that is reduced as far as compile
|
||||||
|
|
@ -1903,12 +1903,12 @@ class NetEConstEnum : public NetEConst {
|
||||||
|
|
||||||
public:
|
public:
|
||||||
explicit NetEConstEnum(NetScope*scope, perm_string name,
|
explicit NetEConstEnum(NetScope*scope, perm_string name,
|
||||||
netenum_t*enum_set, const verinum&val);
|
const netenum_t*enum_set, const verinum&val);
|
||||||
~NetEConstEnum();
|
~NetEConstEnum();
|
||||||
|
|
||||||
perm_string name() const;
|
perm_string name() const;
|
||||||
const NetScope*scope() const;
|
const NetScope*scope() const;
|
||||||
netenum_t*enumeration() const;
|
const netenum_t*enumeration() const;
|
||||||
|
|
||||||
virtual void expr_scan(struct expr_scan_t*) const;
|
virtual void expr_scan(struct expr_scan_t*) const;
|
||||||
virtual void dump(ostream&) const;
|
virtual void dump(ostream&) const;
|
||||||
|
|
@ -1917,7 +1917,7 @@ class NetEConstEnum : public NetEConst {
|
||||||
|
|
||||||
private:
|
private:
|
||||||
NetScope*scope_;
|
NetScope*scope_;
|
||||||
netenum_t*enum_set_;
|
const netenum_t*enum_set_;
|
||||||
perm_string name_;
|
perm_string name_;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
@ -2496,7 +2496,7 @@ class NetAssign_ {
|
||||||
|
|
||||||
// Return the enumeration type of this l-value, or nil if it's
|
// Return the enumeration type of this l-value, or nil if it's
|
||||||
// not an enumeration.
|
// not an enumeration.
|
||||||
netenum_t*enumeration() const;
|
const netenum_t*enumeration() const;
|
||||||
|
|
||||||
// Get the name of the underlying object.
|
// Get the name of the underlying object.
|
||||||
perm_string name() const;
|
perm_string name() const;
|
||||||
|
|
@ -3916,10 +3916,10 @@ class NetEEvent : public NetExpr {
|
||||||
class NetENetenum : public NetExpr {
|
class NetENetenum : public NetExpr {
|
||||||
|
|
||||||
public:
|
public:
|
||||||
NetENetenum(netenum_t*);
|
NetENetenum(const netenum_t*);
|
||||||
~NetENetenum();
|
~NetENetenum();
|
||||||
|
|
||||||
netenum_t* netenum() const;
|
const netenum_t* netenum() const;
|
||||||
|
|
||||||
virtual void expr_scan(struct expr_scan_t*) const;
|
virtual void expr_scan(struct expr_scan_t*) const;
|
||||||
virtual NetENetenum* dup_expr() const;
|
virtual NetENetenum* dup_expr() const;
|
||||||
|
|
@ -3928,7 +3928,7 @@ class NetENetenum : public NetExpr {
|
||||||
virtual void dump(ostream&os) const;
|
virtual void dump(ostream&os) const;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
netenum_t*netenum_;
|
const netenum_t*netenum_;
|
||||||
};
|
};
|
||||||
|
|
||||||
class NetENew : public NetExpr {
|
class NetENew : public NetExpr {
|
||||||
|
|
@ -4032,7 +4032,7 @@ class NetESFunc : public NetExpr {
|
||||||
NetESFunc(const char*name, ivl_variable_type_t t,
|
NetESFunc(const char*name, ivl_variable_type_t t,
|
||||||
unsigned width, unsigned nprms);
|
unsigned width, unsigned nprms);
|
||||||
NetESFunc(const char*name, ivl_type_t rtype, unsigned nprms);
|
NetESFunc(const char*name, ivl_type_t rtype, unsigned nprms);
|
||||||
NetESFunc(const char*name, netenum_t*enum_type, unsigned nprms);
|
NetESFunc(const char*name, const netenum_t*enum_type, unsigned nprms);
|
||||||
~NetESFunc();
|
~NetESFunc();
|
||||||
|
|
||||||
const char* name() const;
|
const char* name() const;
|
||||||
|
|
@ -4048,7 +4048,7 @@ class NetESFunc : public NetExpr {
|
||||||
|
|
||||||
virtual ivl_variable_type_t expr_type() const;
|
virtual ivl_variable_type_t expr_type() const;
|
||||||
virtual NexusSet* nex_input(bool rem_out = true);
|
virtual NexusSet* nex_input(bool rem_out = true);
|
||||||
virtual netenum_t* enumeration() const;
|
virtual const netenum_t* enumeration() const;
|
||||||
virtual void dump(ostream&) const;
|
virtual void dump(ostream&) const;
|
||||||
|
|
||||||
virtual void expr_scan(struct expr_scan_t*) const;
|
virtual void expr_scan(struct expr_scan_t*) const;
|
||||||
|
|
@ -4073,7 +4073,7 @@ class NetESFunc : public NetExpr {
|
||||||
|
|
||||||
const char* name_;
|
const char* name_;
|
||||||
ivl_variable_type_t type_;
|
ivl_variable_type_t type_;
|
||||||
netenum_t*enum_type_;
|
const netenum_t*enum_type_;
|
||||||
std::vector<NetExpr*>parms_;
|
std::vector<NetExpr*>parms_;
|
||||||
|
|
||||||
ID built_in_id_() const;
|
ID built_in_id_() const;
|
||||||
|
|
@ -4252,7 +4252,7 @@ class NetESignal : public NetExpr {
|
||||||
virtual NetESignal* dup_expr() const;
|
virtual NetESignal* dup_expr() const;
|
||||||
NetNet* synthesize(Design*des, NetScope*scope, NetExpr*root);
|
NetNet* synthesize(Design*des, NetScope*scope, NetExpr*root);
|
||||||
NexusSet* nex_input(bool rem_out = true);
|
NexusSet* nex_input(bool rem_out = true);
|
||||||
netenum_t*enumeration() const;
|
const netenum_t*enumeration() const;
|
||||||
|
|
||||||
virtual NetExpr*evaluate_function(const LineInfo&loc,
|
virtual NetExpr*evaluate_function(const LineInfo&loc,
|
||||||
map<perm_string,LocalVar>&ctx) const;
|
map<perm_string,LocalVar>&ctx) const;
|
||||||
|
|
@ -4277,7 +4277,7 @@ class NetESignal : public NetExpr {
|
||||||
|
|
||||||
private:
|
private:
|
||||||
NetNet*net_;
|
NetNet*net_;
|
||||||
netenum_t*enum_type_;
|
const netenum_t*enum_type_;
|
||||||
// Expression to select a word from the net.
|
// Expression to select a word from the net.
|
||||||
NetExpr*word_;
|
NetExpr*word_;
|
||||||
};
|
};
|
||||||
|
|
|
||||||
144
parse.y
144
parse.y
|
|
@ -385,8 +385,6 @@ static void current_function_set_statement(const YYLTYPE&loc, vector<Statement*>
|
||||||
Statement*statement;
|
Statement*statement;
|
||||||
vector<Statement*>*statement_list;
|
vector<Statement*>*statement_list;
|
||||||
|
|
||||||
PTaskFuncArg function_type;
|
|
||||||
|
|
||||||
net_decl_assign_t*net_decl_assign;
|
net_decl_assign_t*net_decl_assign;
|
||||||
enum_type_t*enum_type;
|
enum_type_t*enum_type;
|
||||||
|
|
||||||
|
|
@ -596,7 +594,6 @@ static void current_function_set_statement(const YYLTYPE&loc, vector<Statement*>
|
||||||
%type <vartype> integer_vector_type
|
%type <vartype> integer_vector_type
|
||||||
%type <parmvalue> parameter_value_opt
|
%type <parmvalue> parameter_value_opt
|
||||||
|
|
||||||
%type <function_type> function_range_or_type_opt
|
|
||||||
%type <event_expr> event_expression_list
|
%type <event_expr> event_expression_list
|
||||||
%type <event_expr> event_expression
|
%type <event_expr> event_expression
|
||||||
%type <event_statement> event_control
|
%type <event_statement> event_control
|
||||||
|
|
@ -761,27 +758,36 @@ class_items /* IEEE1800-2005: A.1.2 */
|
||||||
class_item /* IEEE1800-2005: A.1.8 */
|
class_item /* IEEE1800-2005: A.1.8 */
|
||||||
|
|
||||||
/* IEEE1800 A.1.8: class_constructor_declaration */
|
/* IEEE1800 A.1.8: class_constructor_declaration */
|
||||||
: method_qualifier_opt K_function K_new '(' tf_port_list_opt ')' ';'
|
: method_qualifier_opt K_function K_new
|
||||||
|
{ assert(current_function==0);
|
||||||
|
current_function = pform_push_constructor_scope(@3);
|
||||||
|
}
|
||||||
|
'(' tf_port_list_opt ')' ';'
|
||||||
function_item_list_opt
|
function_item_list_opt
|
||||||
statement_or_null_list_opt
|
statement_or_null_list_opt
|
||||||
K_endfunction endnew_opt
|
K_endfunction endnew_opt
|
||||||
{ yyerror(@3, "sorry: Class constructors not supported yet.");
|
{ current_function->set_ports($6);
|
||||||
yyerrok;
|
pform_set_constructor_return(current_function);
|
||||||
|
pform_set_this_class(@3, current_function);
|
||||||
|
current_function_set_statement($10? @10 : @3, $10);
|
||||||
|
pform_pop_scope();
|
||||||
|
current_function = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* IEEE1800 A.1.8: class_constructor_declaration with a call to
|
/* IEEE1800 A.1.8: class_constructor_declaration with a call to
|
||||||
parent constructor. Note that the implicit_class_handle must
|
parent constructor. Note that the implicit_class_handle must
|
||||||
be K_super ("this.new" makes little sense) but that would
|
be K_super ("this.new" makes little sense) but that would
|
||||||
cause a conflict. */
|
cause a conflict. */
|
||||||
|
/* XXXX
|
||||||
| method_qualifier_opt K_function K_new '(' tf_port_list_opt ')' ';'
|
| method_qualifier_opt K_function K_new '(' tf_port_list_opt ')' ';'
|
||||||
function_item_list_opt
|
function_item_list_opt
|
||||||
attribute_list_opt implicit_class_handle '.' K_new '(' expression_list_with_nuls ')'
|
attribute_list_opt implicit_class_handle '.' K_new '(' expression_list_with_nuls ')'
|
||||||
statement_or_null_list_opt
|
statement_or_null_list_opt
|
||||||
K_endfunction endnew_opt
|
K_endfunction endnew_opt
|
||||||
{ yyerror(@3, "sorry: Class constructors not supported yet.");
|
{ yyerror(@3, "sorry: Class constructors with parent not supported yet.");
|
||||||
yyerrok;
|
yyerrok;
|
||||||
}
|
}
|
||||||
|
*/
|
||||||
/* Class properties... */
|
/* Class properties... */
|
||||||
|
|
||||||
| property_qualifier_opt data_type list_of_variable_decl_assignments ';'
|
| property_qualifier_opt data_type list_of_variable_decl_assignments ';'
|
||||||
|
|
@ -934,6 +940,19 @@ data_type /* IEEE1800-2005: A.2.2.1 */
|
||||||
FILE_NAME(tmp, @1);
|
FILE_NAME(tmp, @1);
|
||||||
$$ = tmp;
|
$$ = tmp;
|
||||||
}
|
}
|
||||||
|
| K_integer signed_unsigned_opt
|
||||||
|
{ list<pform_range_t>*pd = make_range_from_width(integer_width);
|
||||||
|
vector_type_t*tmp = new vector_type_t(IVL_VT_LOGIC, $2, pd);
|
||||||
|
tmp->reg_flag = true;
|
||||||
|
tmp->integer_flag = true;
|
||||||
|
$$ = tmp;
|
||||||
|
}
|
||||||
|
| K_time
|
||||||
|
{ list<pform_range_t>*pd = make_range_from_width(64);
|
||||||
|
vector_type_t*tmp = new vector_type_t(IVL_VT_LOGIC, true, pd);
|
||||||
|
tmp->reg_flag = true;
|
||||||
|
$$ = tmp;
|
||||||
|
}
|
||||||
| TYPE_IDENTIFIER range_opt
|
| TYPE_IDENTIFIER range_opt
|
||||||
{ if ($2) $$ = new parray_type_t($1, $2);
|
{ if ($2) $$ = new parray_type_t($1, $2);
|
||||||
else $$ = $1;
|
else $$ = $1;
|
||||||
|
|
@ -1045,7 +1064,7 @@ for_step /* IEEE1800-2005: A.6.8 */
|
||||||
definitions in the func_body to take on the scope of the function
|
definitions in the func_body to take on the scope of the function
|
||||||
instead of the module. */
|
instead of the module. */
|
||||||
function_declaration /* IEEE1800-2005: A.2.6 */
|
function_declaration /* IEEE1800-2005: A.2.6 */
|
||||||
: K_function K_automatic_opt function_range_or_type_opt IDENTIFIER ';'
|
: K_function K_automatic_opt data_type_or_implicit IDENTIFIER ';'
|
||||||
{ assert(current_function == 0);
|
{ assert(current_function == 0);
|
||||||
current_function = pform_push_function_scope(@1, $4, $2);
|
current_function = pform_push_function_scope(@1, $4, $2);
|
||||||
}
|
}
|
||||||
|
|
@ -1070,7 +1089,7 @@ function_declaration /* IEEE1800-2005: A.2.6 */
|
||||||
if ($11) delete[]$11;
|
if ($11) delete[]$11;
|
||||||
}
|
}
|
||||||
|
|
||||||
| K_function K_automatic_opt function_range_or_type_opt IDENTIFIER
|
| K_function K_automatic_opt data_type_or_implicit IDENTIFIER
|
||||||
{ assert(current_function == 0);
|
{ assert(current_function == 0);
|
||||||
current_function = pform_push_function_scope(@1, $4, $2);
|
current_function = pform_push_function_scope(@1, $4, $2);
|
||||||
}
|
}
|
||||||
|
|
@ -1102,7 +1121,7 @@ function_declaration /* IEEE1800-2005: A.2.6 */
|
||||||
|
|
||||||
/* Detect and recover from some errors. */
|
/* Detect and recover from some errors. */
|
||||||
|
|
||||||
| K_function K_automatic_opt function_range_or_type_opt IDENTIFIER error K_endfunction
|
| K_function K_automatic_opt data_type_or_implicit IDENTIFIER error K_endfunction
|
||||||
{ /* */
|
{ /* */
|
||||||
if (current_function) {
|
if (current_function) {
|
||||||
pform_pop_scope();
|
pform_pop_scope();
|
||||||
|
|
@ -1705,58 +1724,7 @@ tf_port_declaration /* IEEE1800-2005: A.2.7 */
|
||||||
|
|
||||||
tf_port_item /* IEEE1800-2005: A.2.7 */
|
tf_port_item /* IEEE1800-2005: A.2.7 */
|
||||||
|
|
||||||
/* Ports can be integer with a width of [31:0]. */
|
: port_direction_opt data_type_or_implicit IDENTIFIER range_opt tf_port_item_expr_opt
|
||||||
|
|
||||||
: port_direction_opt K_integer IDENTIFIER range_opt tf_port_item_expr_opt
|
|
||||||
{ list<pform_range_t>*range_stub = make_range_from_width(integer_width);
|
|
||||||
NetNet::PortType use_port_type = $1==NetNet::PIMPLICIT? NetNet::PINPUT : $1;
|
|
||||||
|
|
||||||
port_declaration_context.port_type = use_port_type;
|
|
||||||
port_declaration_context.var_type = IVL_VT_LOGIC;
|
|
||||||
port_declaration_context.sign_flag = true;
|
|
||||||
delete port_declaration_context.range;
|
|
||||||
port_declaration_context.range = copy_range(range_stub);
|
|
||||||
vector<PWire*>*tmp = pform_make_task_ports(@3, use_port_type,
|
|
||||||
IVL_VT_LOGIC, true,
|
|
||||||
range_stub,
|
|
||||||
list_from_identifier($3), true);
|
|
||||||
$$ = tmp;
|
|
||||||
if ($4) {
|
|
||||||
yyerror(@4, "sorry: Port variable dimensions not supported yet.");
|
|
||||||
delete $4;
|
|
||||||
}
|
|
||||||
if ($5) {
|
|
||||||
yyerror(@5, "sorry: Port default expressions not supported yet.");
|
|
||||||
delete $5;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Ports can be time with a width of [63:0] (unsigned). */
|
|
||||||
|
|
||||||
| port_direction_opt K_time IDENTIFIER range_opt tf_port_item_expr_opt
|
|
||||||
{ list<pform_range_t>*range_stub = make_range_from_width(64);
|
|
||||||
NetNet::PortType use_port_type = $1==NetNet::PIMPLICIT? NetNet::PINPUT : $1;
|
|
||||||
|
|
||||||
port_declaration_context.port_type = use_port_type;
|
|
||||||
port_declaration_context.var_type = IVL_VT_LOGIC;
|
|
||||||
port_declaration_context.sign_flag = false;
|
|
||||||
delete port_declaration_context.range;
|
|
||||||
port_declaration_context.range = copy_range(range_stub);
|
|
||||||
vector<PWire*>*tmp = pform_make_task_ports(@3, use_port_type, IVL_VT_LOGIC,
|
|
||||||
false, range_stub,
|
|
||||||
list_from_identifier($3));
|
|
||||||
$$ = tmp;
|
|
||||||
if ($4) {
|
|
||||||
yyerror(@4, "sorry: Port variable dimensions not supported yet.");
|
|
||||||
delete $4;
|
|
||||||
}
|
|
||||||
if ($5) {
|
|
||||||
yyerror(@5, "sorry: Port default expressions not supported yet.");
|
|
||||||
delete $5;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
| port_direction_opt data_type_or_implicit IDENTIFIER range_opt tf_port_item_expr_opt
|
|
||||||
{ vector<PWire*>*tmp;
|
{ vector<PWire*>*tmp;
|
||||||
NetNet::PortType use_port_type = $1==NetNet::PIMPLICIT? NetNet::PINPUT : $1;
|
NetNet::PortType use_port_type = $1==NetNet::PIMPLICIT? NetNet::PINPUT : $1;
|
||||||
list<perm_string>* ilist = list_from_identifier($3);
|
list<perm_string>* ilist = list_from_identifier($3);
|
||||||
|
|
@ -1987,22 +1955,10 @@ attribute
|
||||||
|
|
||||||
block_item_decl
|
block_item_decl
|
||||||
|
|
||||||
/* Integer atom declarations are simpler in that they do not have
|
|
||||||
all the trappings of a general variable declaration. All of that
|
|
||||||
is implicit in the "integer" of the declaration. */
|
|
||||||
|
|
||||||
: K_integer signed_unsigned_opt register_variable_list ';'
|
|
||||||
{ pform_set_reg_integer($3, attributes_in_context);
|
|
||||||
}
|
|
||||||
|
|
||||||
| K_time register_variable_list ';'
|
|
||||||
{ pform_set_reg_time($2, attributes_in_context);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* variable declarations. Note that data_type can be 0 if we are
|
/* variable declarations. Note that data_type can be 0 if we are
|
||||||
recovering from an error. */
|
recovering from an error. */
|
||||||
|
|
||||||
| data_type register_variable_list ';'
|
: data_type register_variable_list ';'
|
||||||
{ if ($1) pform_set_data_type(@1, $1, $2, NetNet::REG, attributes_in_context);
|
{ if ($1) pform_set_data_type(@1, $1, $2, NetNet::REG, attributes_in_context);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -5006,42 +4962,6 @@ dimensions
|
||||||
}
|
}
|
||||||
;
|
;
|
||||||
|
|
||||||
/* This is used to express the return type of a function. This is
|
|
||||||
not quite right, and should be replaced with a variant that uses
|
|
||||||
the data_type rule. This will get us by for now. */
|
|
||||||
function_range_or_type_opt
|
|
||||||
: unsigned_signed_opt range_opt
|
|
||||||
{ /* the default type is reg unsigned and no range */
|
|
||||||
$$.type = PTF_REG;
|
|
||||||
$$.range = $2;
|
|
||||||
if ($1)
|
|
||||||
$$.type = PTF_REG_S;
|
|
||||||
}
|
|
||||||
| K_reg unsigned_signed_opt range_opt
|
|
||||||
{ /* the default type is reg unsigned and no range */
|
|
||||||
$$.type = PTF_REG;
|
|
||||||
$$.range = $3;
|
|
||||||
if ($2)
|
|
||||||
$$.type = PTF_REG_S;
|
|
||||||
}
|
|
||||||
| bit_logic unsigned_signed_opt range_opt
|
|
||||||
{ /* the default type is bit/logic unsigned and no range */
|
|
||||||
$$.type = PTF_REG;
|
|
||||||
$$.range = $3;
|
|
||||||
if ($2)
|
|
||||||
$$.type = PTF_REG_S;
|
|
||||||
}
|
|
||||||
| K_integer { $$.range = 0; $$.type = PTF_INTEGER; }
|
|
||||||
| K_real { $$.range = 0; $$.type = PTF_REAL; }
|
|
||||||
| K_realtime { $$.range = 0; $$.type = PTF_REALTIME; }
|
|
||||||
| K_string { $$.range = 0; $$.type = PTF_STRING; }
|
|
||||||
| K_time { $$.range = 0; $$.type = PTF_TIME; }
|
|
||||||
| K_void { $$.range = 0; $$.type = PTF_VOID; }
|
|
||||||
| atom2_type { $$.range = make_range_from_width($1); $$.type = PTF_ATOM2_S; }
|
|
||||||
| atom2_type K_signed { $$.range = make_range_from_width($1); $$.type = PTF_ATOM2_S; }
|
|
||||||
| atom2_type K_unsigned { $$.range = make_range_from_width($1); $$.type = PTF_ATOM2; }
|
|
||||||
;
|
|
||||||
|
|
||||||
/* The register_variable rule is matched only when I am parsing
|
/* The register_variable rule is matched only when I am parsing
|
||||||
variables in a "reg" definition. I therefore know that I am
|
variables in a "reg" definition. I therefore know that I am
|
||||||
creating registers and I do not need to let the containing rule
|
creating registers and I do not need to let the containing rule
|
||||||
|
|
|
||||||
56
pform.cc
56
pform.cc
|
|
@ -368,7 +368,7 @@ PTask* pform_push_task_scope(const struct vlltype&loc, char*name, bool is_auto)
|
||||||
return task;
|
return task;
|
||||||
}
|
}
|
||||||
|
|
||||||
PFunction* pform_push_function_scope(const struct vlltype&loc, char*name,
|
PFunction* pform_push_function_scope(const struct vlltype&loc, const char*name,
|
||||||
bool is_auto)
|
bool is_auto)
|
||||||
{
|
{
|
||||||
perm_string func_name = lex_strings.make(name);
|
perm_string func_name = lex_strings.make(name);
|
||||||
|
|
@ -2932,57 +2932,6 @@ void pform_set_port_type(const struct vlltype&li,
|
||||||
delete range;
|
delete range;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void pform_set_reg_integer(perm_string name, list<named_pexpr_t>*attr)
|
|
||||||
{
|
|
||||||
PWire*cur = pform_get_make_wire_in_scope(name, NetNet::INTEGER, NetNet::NOT_A_PORT, IVL_VT_LOGIC);
|
|
||||||
assert(cur);
|
|
||||||
|
|
||||||
pform_range_t rng;
|
|
||||||
rng.first = new PENumber(new verinum(integer_width-1, integer_width));
|
|
||||||
rng.second = new PENumber(new verinum((uint64_t)0, integer_width));
|
|
||||||
list<pform_range_t>rlist;
|
|
||||||
rlist.push_back(rng);
|
|
||||||
cur->set_range(rlist, SR_NET);
|
|
||||||
cur->set_signed(true);
|
|
||||||
|
|
||||||
pform_bind_attributes(cur->attributes, attr, true);
|
|
||||||
}
|
|
||||||
|
|
||||||
void pform_set_reg_integer(list<perm_string>*names, list<named_pexpr_t>*attr)
|
|
||||||
{
|
|
||||||
for (list<perm_string>::iterator cur = names->begin()
|
|
||||||
; cur != names->end() ; ++ cur ) {
|
|
||||||
perm_string txt = *cur;
|
|
||||||
pform_set_reg_integer(txt, attr);
|
|
||||||
}
|
|
||||||
delete names;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void pform_set_reg_time(perm_string name, list<named_pexpr_t>*attr)
|
|
||||||
{
|
|
||||||
PWire*cur = pform_get_make_wire_in_scope(name, NetNet::REG, NetNet::NOT_A_PORT, IVL_VT_LOGIC);
|
|
||||||
assert(cur);
|
|
||||||
|
|
||||||
pform_range_t rng;
|
|
||||||
rng.first = new PENumber(new verinum(TIME_WIDTH-1, integer_width));
|
|
||||||
rng.second = new PENumber(new verinum((uint64_t)0, integer_width));
|
|
||||||
list<pform_range_t>rlist;
|
|
||||||
rlist.push_back(rng);
|
|
||||||
cur->set_range(rlist, SR_NET);
|
|
||||||
|
|
||||||
pform_bind_attributes(cur->attributes, attr, true);
|
|
||||||
}
|
|
||||||
|
|
||||||
void pform_set_reg_time(list<perm_string>*names, list<named_pexpr_t>*attr)
|
|
||||||
{
|
|
||||||
for (list<perm_string>::iterator cur = names->begin()
|
|
||||||
; cur != names->end() ; ++ cur ) {
|
|
||||||
perm_string txt = *cur;
|
|
||||||
pform_set_reg_time(txt, attr);
|
|
||||||
}
|
|
||||||
delete names;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void pform_set_integer_2atom(uint64_t width, bool signed_flag, perm_string name, NetNet::Type net_type, list<named_pexpr_t>*attr)
|
static void pform_set_integer_2atom(uint64_t width, bool signed_flag, perm_string name, NetNet::Type net_type, list<named_pexpr_t>*attr)
|
||||||
{
|
{
|
||||||
PWire*cur = pform_get_make_wire_in_scope(name, net_type, NetNet::NOT_A_PORT, IVL_VT_BOOL);
|
PWire*cur = pform_get_make_wire_in_scope(name, net_type, NetNet::NOT_A_PORT, IVL_VT_BOOL);
|
||||||
|
|
@ -3101,6 +3050,9 @@ void pform_set_data_type(const struct vlltype&li, data_type_t*data_type, list<pe
|
||||||
}
|
}
|
||||||
|
|
||||||
if (vector_type_t*vec_type = dynamic_cast<vector_type_t*> (data_type)) {
|
if (vector_type_t*vec_type = dynamic_cast<vector_type_t*> (data_type)) {
|
||||||
|
if (net_type==NetNet::REG && vec_type->integer_flag)
|
||||||
|
net_type=NetNet::INTEGER;
|
||||||
|
|
||||||
pform_set_net_range(names, vec_type->pdims.get(),
|
pform_set_net_range(names, vec_type->pdims.get(),
|
||||||
vec_type->signed_flag,
|
vec_type->signed_flag,
|
||||||
vec_type->base_type, net_type, attr);
|
vec_type->base_type, net_type, attr);
|
||||||
|
|
|
||||||
6
pform.h
6
pform.h
|
|
@ -187,6 +187,7 @@ extern void pform_class_property(const struct vlltype&loc,
|
||||||
data_type_t*data_type,
|
data_type_t*data_type,
|
||||||
std::list<decl_assignment_t*>*decls);
|
std::list<decl_assignment_t*>*decls);
|
||||||
extern void pform_set_this_class(const struct vlltype&loc, PTaskFunc*net);
|
extern void pform_set_this_class(const struct vlltype&loc, PTaskFunc*net);
|
||||||
|
extern void pform_set_constructor_return(PFunction*net);
|
||||||
|
|
||||||
extern void pform_end_class_declaration(void);
|
extern void pform_end_class_declaration(void);
|
||||||
|
|
||||||
|
|
@ -232,10 +233,11 @@ extern void pform_pop_scope();
|
||||||
extern LexicalScope* pform_peek_scope();
|
extern LexicalScope* pform_peek_scope();
|
||||||
|
|
||||||
extern PClass* pform_push_class_scope(const struct vlltype&loc, perm_string name);
|
extern PClass* pform_push_class_scope(const struct vlltype&loc, perm_string name);
|
||||||
|
extern PFunction*pform_push_constructor_scope(const struct vlltype&loc);
|
||||||
extern PPackage* pform_push_package_scope(const struct vlltype&loc, perm_string name);
|
extern PPackage* pform_push_package_scope(const struct vlltype&loc, perm_string name);
|
||||||
extern PTask*pform_push_task_scope(const struct vlltype&loc, char*name,
|
extern PTask*pform_push_task_scope(const struct vlltype&loc, char*name,
|
||||||
bool is_auto);
|
bool is_auto);
|
||||||
extern PFunction*pform_push_function_scope(const struct vlltype&loc, char*name,
|
extern PFunction*pform_push_function_scope(const struct vlltype&loc, const char*name,
|
||||||
bool is_auto);
|
bool is_auto);
|
||||||
extern PBlock*pform_push_block_scope(char*name, PBlock::BL_TYPE tt);
|
extern PBlock*pform_push_block_scope(char*name, PBlock::BL_TYPE tt);
|
||||||
|
|
||||||
|
|
@ -342,8 +344,6 @@ extern void pform_set_port_type(const struct vlltype&li,
|
||||||
|
|
||||||
extern void pform_set_reg_idx(perm_string name,
|
extern void pform_set_reg_idx(perm_string name,
|
||||||
std::list<pform_range_t>*indices);
|
std::list<pform_range_t>*indices);
|
||||||
extern void pform_set_reg_integer(list<perm_string>*names, list<named_pexpr_t>*attr);
|
|
||||||
extern void pform_set_reg_time(list<perm_string>*names, list<named_pexpr_t>*attr);
|
|
||||||
|
|
||||||
extern void pform_set_data_type(const struct vlltype&li, data_type_t*, list<perm_string>*names, NetNet::Type net_type, list<named_pexpr_t>*attr);
|
extern void pform_set_data_type(const struct vlltype&li, data_type_t*, list<perm_string>*names, NetNet::Type net_type, list<named_pexpr_t>*attr);
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -423,6 +423,13 @@ void PWire::dump(ostream&out, unsigned ind) const
|
||||||
out << " signed";
|
out << " signed";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (get_isint()) {
|
||||||
|
out << " integer";
|
||||||
|
}
|
||||||
|
if (set_data_type_) {
|
||||||
|
out << " set_data_type_=" << typeid(*set_data_type_).name();
|
||||||
|
}
|
||||||
|
|
||||||
if (discipline_) {
|
if (discipline_) {
|
||||||
out << " discipline<" << discipline_->name() << ">";
|
out << " discipline<" << discipline_->name() << ">";
|
||||||
}
|
}
|
||||||
|
|
@ -867,47 +874,12 @@ void PForStatement::dump(ostream&out, unsigned ind) const
|
||||||
void PFunction::dump(ostream&out, unsigned ind) const
|
void PFunction::dump(ostream&out, unsigned ind) const
|
||||||
{
|
{
|
||||||
out << setw(ind) << "" << "function ";
|
out << setw(ind) << "" << "function ";
|
||||||
if (is_auto_) cout << "automatic ";
|
if (is_auto_) out << "automatic...";
|
||||||
switch (return_type_.type) {
|
|
||||||
case PTF_NONE:
|
|
||||||
out << "?none? ";
|
|
||||||
break;
|
|
||||||
case PTF_REG:
|
|
||||||
out << "reg ";
|
|
||||||
break;
|
|
||||||
case PTF_REG_S:
|
|
||||||
out << "reg_s ";
|
|
||||||
break;
|
|
||||||
case PTF_INTEGER:
|
|
||||||
out << "integer ";
|
|
||||||
break;
|
|
||||||
case PTF_REAL:
|
|
||||||
out << "real ";
|
|
||||||
break;
|
|
||||||
case PTF_REALTIME:
|
|
||||||
out << "realtime ";
|
|
||||||
break;
|
|
||||||
case PTF_TIME:
|
|
||||||
out << "time ";
|
|
||||||
break;
|
|
||||||
case PTF_ATOM2:
|
|
||||||
out << "int unsigned ";
|
|
||||||
break;
|
|
||||||
case PTF_ATOM2_S:
|
|
||||||
out << "int signed ";
|
|
||||||
break;
|
|
||||||
case PTF_STRING:
|
|
||||||
out << "string ";
|
|
||||||
break;
|
|
||||||
case PTF_VOID:
|
|
||||||
out << "void ";
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (return_type_.range) {
|
if (return_type_)
|
||||||
out << "[";
|
return_type_->pform_dump(out, ind+8);
|
||||||
out << "] ";
|
else
|
||||||
}
|
out << setw(ind+8) << "" << "<implicit type>" << endl;
|
||||||
|
|
||||||
out << pscope_name() << ";" << endl;
|
out << pscope_name() << ";" << endl;
|
||||||
if (method_of())
|
if (method_of())
|
||||||
|
|
@ -944,7 +916,7 @@ void PRepeat::dump(ostream&out, unsigned ind) const
|
||||||
void PTask::dump(ostream&out, unsigned ind) const
|
void PTask::dump(ostream&out, unsigned ind) const
|
||||||
{
|
{
|
||||||
out << setw(ind) << "" << "task ";
|
out << setw(ind) << "" << "task ";
|
||||||
if (is_auto_) cout << "automatic ";
|
if (is_auto_) out << "automatic ";
|
||||||
out << pscope_name() << ";" << endl;
|
out << pscope_name() << ";" << endl;
|
||||||
if (method_of())
|
if (method_of())
|
||||||
out << setw(ind) << "" << "method of " << method_of()->name << ";" << endl;
|
out << setw(ind) << "" << "method of " << method_of()->name << ";" << endl;
|
||||||
|
|
|
||||||
|
|
@ -91,6 +91,22 @@ void pform_set_this_class(const struct vlltype&loc, PTaskFunc*net)
|
||||||
net->set_this(pform_cur_class->type, this_wire);
|
net->set_this(pform_cur_class->type, this_wire);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void pform_set_constructor_return(PFunction*net)
|
||||||
|
{
|
||||||
|
assert(pform_cur_class);
|
||||||
|
net->set_return(pform_cur_class->type);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* A constructor is basically a function with special implications.
|
||||||
|
*/
|
||||||
|
PFunction*pform_push_constructor_scope(const struct vlltype&loc)
|
||||||
|
{
|
||||||
|
assert(pform_cur_class);
|
||||||
|
PFunction*func = pform_push_function_scope(loc, "new", true);
|
||||||
|
return func;
|
||||||
|
}
|
||||||
|
|
||||||
void pform_end_class_declaration(void)
|
void pform_end_class_declaration(void)
|
||||||
{
|
{
|
||||||
assert(pform_cur_class);
|
assert(pform_cur_class);
|
||||||
|
|
|
||||||
|
|
@ -144,12 +144,14 @@ struct atom2_type_t : public data_type_t {
|
||||||
struct vector_type_t : public data_type_t {
|
struct vector_type_t : public data_type_t {
|
||||||
inline explicit vector_type_t(ivl_variable_type_t bt, bool sf,
|
inline explicit vector_type_t(ivl_variable_type_t bt, bool sf,
|
||||||
std::list<pform_range_t>*pd)
|
std::list<pform_range_t>*pd)
|
||||||
: base_type(bt), signed_flag(sf), reg_flag(false), implicit_flag(false), pdims(pd) { }
|
: base_type(bt), signed_flag(sf), reg_flag(false), integer_flag(false), implicit_flag(false), pdims(pd) { }
|
||||||
virtual ivl_variable_type_t figure_packed_base_type(void)const;
|
virtual ivl_variable_type_t figure_packed_base_type(void)const;
|
||||||
|
ivl_type_s* elaborate_type(Design*des, NetScope*scope) const;
|
||||||
|
|
||||||
ivl_variable_type_t base_type;
|
ivl_variable_type_t base_type;
|
||||||
bool signed_flag;
|
bool signed_flag;
|
||||||
bool reg_flag; // True if "reg" was used
|
bool reg_flag; // True if "reg" was used
|
||||||
|
bool integer_flag; // True if "integer" was used
|
||||||
bool implicit_flag; // True if this type is implicitly logic/reg
|
bool implicit_flag; // True if this type is implicitly logic/reg
|
||||||
std::auto_ptr< list<pform_range_t> > pdims;
|
std::auto_ptr< list<pform_range_t> > pdims;
|
||||||
};
|
};
|
||||||
|
|
|
||||||
|
|
@ -11,4 +11,4 @@
|
||||||
|
|
||||||
./ivl -v -Ctgt-stub/stub.conf -C./scripts/devel-stub.conf -Pa.pf -Na.net -fDLL=tgt-stub/stub.tgt foo.vl |& tee foo.log
|
./ivl -v -Ctgt-stub/stub.conf -C./scripts/devel-stub.conf -Pa.pf -Na.net -fDLL=tgt-stub/stub.tgt foo.vl |& tee foo.log
|
||||||
|
|
||||||
echo "*** ivl command completed, rc=$?"
|
echo "*** ivl command completed"
|
||||||
|
|
|
||||||
|
|
@ -1232,6 +1232,8 @@ static void show_signal(ivl_signal_t net)
|
||||||
switch (ivl_signal_type(net)) {
|
switch (ivl_signal_type(net)) {
|
||||||
case IVL_SIT_REG:
|
case IVL_SIT_REG:
|
||||||
type = "reg";
|
type = "reg";
|
||||||
|
if (ivl_signal_integer(net))
|
||||||
|
type = "integer";
|
||||||
break;
|
break;
|
||||||
case IVL_SIT_TRI:
|
case IVL_SIT_TRI:
|
||||||
type = "tri";
|
type = "tri";
|
||||||
|
|
@ -1351,6 +1353,11 @@ static void show_signal(ivl_signal_t net)
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (ivl_signal_integer(net) && ivl_signal_type(net)!=IVL_SIT_REG) {
|
||||||
|
fprintf(out, " ERROR: integers must be IVL_SIT_REG\n");
|
||||||
|
stub_errors += 1;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void test_expr_is_delay(ivl_expr_t expr)
|
void test_expr_is_delay(ivl_expr_t expr)
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue