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)
|
||||
{
|
||||
is_auto_ = is_auto__;
|
||||
return_type_.type = PTF_NONE;
|
||||
return_type_ = 0;
|
||||
}
|
||||
|
||||
PFunction::~PFunction()
|
||||
|
|
@ -39,7 +39,7 @@ void PFunction::set_statement(Statement*s)
|
|||
statement_ = s;
|
||||
}
|
||||
|
||||
void PFunction::set_return(PTaskFuncArg t)
|
||||
void PFunction::set_return(const data_type_t*t)
|
||||
{
|
||||
return_type_ = t;
|
||||
}
|
||||
|
|
|
|||
22
PTask.h
22
PTask.h
|
|
@ -32,24 +32,6 @@ class PWire;
|
|||
class Statement;
|
||||
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 {
|
||||
|
||||
|
|
@ -126,7 +108,7 @@ class PFunction : public PTaskFunc {
|
|||
~PFunction();
|
||||
|
||||
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;
|
||||
|
||||
|
|
@ -141,7 +123,7 @@ class PFunction : public PTaskFunc {
|
|||
void dump(ostream&, unsigned) const;
|
||||
|
||||
private:
|
||||
PTaskFuncArg return_type_;
|
||||
const data_type_t* return_type_;
|
||||
Statement *statement_;
|
||||
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);
|
||||
data_type_ = dt;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
|
@ -140,7 +141,14 @@ bool PWire::get_signed() 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
|
||||
|
|
@ -257,6 +265,11 @@ void PWire::set_data_type(data_type_t*type)
|
|||
{
|
||||
assert(set_data_type_ == 0);
|
||||
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)
|
||||
|
|
|
|||
22
elab_expr.cc
22
elab_expr.cc
|
|
@ -1134,7 +1134,7 @@ unsigned PECallFunction::test_width_method_(Design*des, NetScope*scope,
|
|||
<< endl;
|
||||
}
|
||||
|
||||
netclass_t* class_type = net->class_type();
|
||||
const netclass_t* class_type = net->class_type();
|
||||
member_type = class_type->get_property(member_name);
|
||||
use_path = tmp_path;
|
||||
|
||||
|
|
@ -1164,7 +1164,7 @@ unsigned PECallFunction::test_width_method_(Design*des, NetScope*scope,
|
|||
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_: "
|
||||
<< "Try to find method " << method_name
|
||||
<< " 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,
|
||||
Design*des, NetScope*scope,
|
||||
netenum_t*netenum,
|
||||
const netenum_t*netenum,
|
||||
pform_name_t use_path,
|
||||
perm_string method_name,
|
||||
NetExpr*expr,
|
||||
|
|
@ -1760,7 +1760,7 @@ static NetExpr* check_for_class_property(const LineInfo*li,
|
|||
NetNet*net,
|
||||
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);
|
||||
|
||||
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
|
||||
// enumeration variable so get it.
|
||||
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);
|
||||
if (func == 0) {
|
||||
return 0;
|
||||
|
|
@ -2595,7 +2595,7 @@ unsigned PEIdent::test_width(Design*des, NetScope*scope, width_mode_t&mode)
|
|||
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) {
|
||||
expr_type_ = darray->element_base_type();
|
||||
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
|
||||
// enumeration base.
|
||||
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);
|
||||
|
||||
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);
|
||||
if (ptype) {
|
||||
expr_type_ = ptype->base_type();
|
||||
|
|
@ -3037,7 +3037,7 @@ NetExpr* PEIdent::elaborate_expr(Design*des, NetScope*scope,
|
|||
if (net != 0) {
|
||||
// If this net is actually an enum, the method may
|
||||
// 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
|
||||
// enumeration variable so get it.
|
||||
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);
|
||||
|
||||
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
|
||||
// array. Generate a NetESelect and attach it to
|
||||
// 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;
|
||||
}
|
||||
|
||||
netclass_t*class_type = lv->sig()->class_type();
|
||||
const netclass_t*class_type = lv->sig()->class_type();
|
||||
ivl_assert(*this, class_type);
|
||||
|
||||
/* Make sure the property is really present in the class. If
|
||||
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) {
|
||||
cerr << get_fileline() << ": error: Class " << class_type->get_name()
|
||||
<< " 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())
|
||||
cur_value = cur_value + one_value;
|
||||
}
|
||||
|
||||
use_enum->insert_name_close();
|
||||
}
|
||||
|
||||
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);
|
||||
|
||||
NetNet*ret_sig = 0;
|
||||
netvector_t*ret_vec = 0;
|
||||
ivl_type_t ret_type;
|
||||
|
||||
/* Create the signals/variables of the return value and write
|
||||
them into the function scope. */
|
||||
switch (return_type_.type) {
|
||||
|
||||
case PTF_REG:
|
||||
case PTF_REG_S:
|
||||
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;
|
||||
if (return_type_) {
|
||||
ret_type = return_type_->elaborate_type(des, scope);
|
||||
} else {
|
||||
netvector_t*tmp = new netvector_t(IVL_VT_LOGIC);
|
||||
tmp->set_scalar(true);
|
||||
ret_type = tmp;
|
||||
}
|
||||
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;
|
||||
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_)) {
|
||||
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) {
|
||||
cerr << get_fileline() << ": debug: Create signal " << wtype
|
||||
|
|
|
|||
37
elab_type.cc
37
elab_type.cc
|
|
@ -23,6 +23,7 @@
|
|||
# include "netdarray.h"
|
||||
# include "netscalar.h"
|
||||
# include "netvector.h"
|
||||
# include "netmisc.h"
|
||||
# include <typeinfo>
|
||||
# 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);
|
||||
}
|
||||
|
||||
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
|
||||
{
|
||||
switch (type_code) {
|
||||
|
|
|
|||
|
|
@ -3314,7 +3314,7 @@ NetProc* PCallTask::elaborate_method_(Design*des, NetScope*scope) const
|
|||
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);
|
||||
if (task == 0) {
|
||||
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_design_s *ivl_design_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_expr_s *ivl_expr_t;
|
||||
typedef struct ivl_island_s *ivl_island_t;
|
||||
|
|
|
|||
|
|
@ -102,7 +102,7 @@ unsigned NetAssign_::lwidth() const
|
|||
return ptype->packed_width();
|
||||
}
|
||||
|
||||
if (netdarray_t*darray = sig_->darray_type()) {
|
||||
if (const netdarray_t*darray = sig_->darray_type()) {
|
||||
if (word_ == 0)
|
||||
return 1;
|
||||
else
|
||||
|
|
@ -122,7 +122,7 @@ ivl_variable_type_t NetAssign_::expr_type() const
|
|||
return tmp->base_type();
|
||||
}
|
||||
|
||||
if (netdarray_t*darray = sig_->darray_type()) {
|
||||
if (const netdarray_t*darray = sig_->darray_type()) {
|
||||
if (word_ == 0)
|
||||
return IVL_VT_DARRAY;
|
||||
else
|
||||
|
|
@ -153,9 +153,9 @@ const ivl_type_s* NetAssign_::net_type() const
|
|||
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 ( (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;
|
||||
}
|
||||
|
||||
netenum_t*NetExpr::enumeration() const
|
||||
const netenum_t*NetExpr::enumeration() const
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
|
@ -246,7 +246,7 @@ void NetEConcat::set(unsigned idx, NetExpr*e)
|
|||
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)
|
||||
{
|
||||
assert(has_width());
|
||||
|
|
@ -256,7 +256,7 @@ NetEConstEnum::~NetEConstEnum()
|
|||
{
|
||||
}
|
||||
|
||||
netenum_t*NetEConstEnum::enumeration() const
|
||||
const netenum_t*NetEConstEnum::enumeration() const
|
||||
{
|
||||
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)
|
||||
{
|
||||
}
|
||||
|
|
@ -316,7 +316,7 @@ NetENetenum::~NetENetenum()
|
|||
{
|
||||
}
|
||||
|
||||
netenum_t* NetENetenum::netenum() const
|
||||
const netenum_t* NetENetenum::netenum() const
|
||||
{
|
||||
return netenum_;
|
||||
}
|
||||
|
|
@ -456,7 +456,7 @@ NetESFunc::NetESFunc(const char*n, ivl_type_t rtype, unsigned np)
|
|||
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_ = lex_strings.add(n);
|
||||
|
|
@ -506,7 +506,7 @@ ivl_variable_type_t NetESFunc::expr_type() const
|
|||
return type_;
|
||||
}
|
||||
|
||||
netenum_t* NetESFunc::enumeration() const
|
||||
const netenum_t* NetESFunc::enumeration() const
|
||||
{
|
||||
return enum_type_;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -570,7 +570,7 @@ bool NetScope::add_enumeration_name(netenum_t*enum_set, perm_string name)
|
|||
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];
|
||||
assert(tmp != 0);
|
||||
|
|
|
|||
|
|
@ -92,7 +92,7 @@ ivl_type_t netclass_t::get_prop_type(size_t idx) const
|
|||
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) );
|
||||
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;
|
||||
|
||||
// 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(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;
|
||||
}
|
||||
|
||||
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
|
||||
{
|
||||
return names_map_.find(name);
|
||||
|
|
@ -115,32 +141,7 @@ perm_string netenum_t::name_at(size_t idx) const
|
|||
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];
|
||||
}
|
||||
|
|
|
|||
|
|
@ -49,6 +49,9 @@ class netenum_t : public LineInfo, public ivl_type_s {
|
|||
// enumeration value.
|
||||
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;
|
||||
iterator find_name(perm_string name) const;
|
||||
iterator end_name() const;
|
||||
|
|
@ -59,7 +62,7 @@ class netenum_t : public LineInfo, public ivl_type_s {
|
|||
iterator last_name() 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:
|
||||
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,
|
||||
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)),
|
||||
type_(t), port_type_(NOT_A_PORT),
|
||||
local_flag_(false), net_type_(use_net_type),
|
||||
|
|
@ -762,7 +762,7 @@ bool NetNet::get_signed() 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();
|
||||
else
|
||||
return false;
|
||||
|
|
@ -770,20 +770,20 @@ bool NetNet::get_isint() 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();
|
||||
else
|
||||
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 ivl_type_s*cur_type = net_type_;
|
||||
ivl_type_t cur_type = net_type_;
|
||||
while (cur_type) {
|
||||
if (const netdarray_t*da = dynamic_cast<const netdarray_t*> (cur_type)) {
|
||||
cur_type = da->element_type();
|
||||
|
|
@ -803,14 +803,14 @@ const netstruct_t*NetNet::struct_type(void) const
|
|||
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();
|
||||
}
|
||||
|
||||
netenum_t* NetESignal::enumeration() const
|
||||
const netenum_t* NetESignal::enumeration() const
|
||||
{
|
||||
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.
|
||||
explicit NetNet(NetScope*s, perm_string n, Type t,
|
||||
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
|
||||
// definition. They should probably be replaced with a single
|
||||
|
|
@ -639,10 +639,10 @@ class NetNet : public NetObj, public PortType {
|
|||
bool get_scalar() const;
|
||||
|
||||
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;
|
||||
netdarray_t*darray_type(void) const;
|
||||
netclass_t*class_type(void) const;
|
||||
const netdarray_t*darray_type(void) const;
|
||||
const netclass_t*class_type(void) const;
|
||||
|
||||
/* Attach a discipline to the net. */
|
||||
ivl_discipline_t get_discipline() const;
|
||||
|
|
@ -729,7 +729,7 @@ class NetNet : public NetObj, public PortType {
|
|||
Type type_ : 5;
|
||||
PortType port_type_ : 3;
|
||||
bool local_flag_: 1;
|
||||
ivl_type_s*net_type_;
|
||||
ivl_type_t net_type_;
|
||||
ivl_discipline_t discipline_;
|
||||
|
||||
std::vector<netrange_t> unpacked_dims_;
|
||||
|
|
@ -848,7 +848,7 @@ class NetScope : public Attrib {
|
|||
void add_enumeration_set(netenum_t*enum_set);
|
||||
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);
|
||||
netclass_t* find_class(perm_string name);
|
||||
|
|
@ -1810,7 +1810,7 @@ class NetExpr : public LineInfo {
|
|||
// Return the enumeration set that defines this expressions
|
||||
// enumeration type, or return nil if the expression is not
|
||||
// part of the enumeration.
|
||||
virtual netenum_t*enumeration() const;
|
||||
virtual const netenum_t*enumeration() const;
|
||||
|
||||
// This method evaluates the expression and returns an
|
||||
// equivalent expression that is reduced as far as compile
|
||||
|
|
@ -1903,12 +1903,12 @@ class NetEConstEnum : public NetEConst {
|
|||
|
||||
public:
|
||||
explicit NetEConstEnum(NetScope*scope, perm_string name,
|
||||
netenum_t*enum_set, const verinum&val);
|
||||
const netenum_t*enum_set, const verinum&val);
|
||||
~NetEConstEnum();
|
||||
|
||||
perm_string name() 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 dump(ostream&) const;
|
||||
|
|
@ -1917,7 +1917,7 @@ class NetEConstEnum : public NetEConst {
|
|||
|
||||
private:
|
||||
NetScope*scope_;
|
||||
netenum_t*enum_set_;
|
||||
const netenum_t*enum_set_;
|
||||
perm_string name_;
|
||||
};
|
||||
|
||||
|
|
@ -2496,7 +2496,7 @@ class NetAssign_ {
|
|||
|
||||
// Return the enumeration type of this l-value, or nil if it's
|
||||
// not an enumeration.
|
||||
netenum_t*enumeration() const;
|
||||
const netenum_t*enumeration() const;
|
||||
|
||||
// Get the name of the underlying object.
|
||||
perm_string name() const;
|
||||
|
|
@ -3916,10 +3916,10 @@ class NetEEvent : public NetExpr {
|
|||
class NetENetenum : public NetExpr {
|
||||
|
||||
public:
|
||||
NetENetenum(netenum_t*);
|
||||
NetENetenum(const netenum_t*);
|
||||
~NetENetenum();
|
||||
|
||||
netenum_t* netenum() const;
|
||||
const netenum_t* netenum() const;
|
||||
|
||||
virtual void expr_scan(struct expr_scan_t*) const;
|
||||
virtual NetENetenum* dup_expr() const;
|
||||
|
|
@ -3928,7 +3928,7 @@ class NetENetenum : public NetExpr {
|
|||
virtual void dump(ostream&os) const;
|
||||
|
||||
private:
|
||||
netenum_t*netenum_;
|
||||
const netenum_t*netenum_;
|
||||
};
|
||||
|
||||
class NetENew : public NetExpr {
|
||||
|
|
@ -4032,7 +4032,7 @@ class NetESFunc : public NetExpr {
|
|||
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(const char*name, const netenum_t*enum_type, unsigned nprms);
|
||||
~NetESFunc();
|
||||
|
||||
const char* name() const;
|
||||
|
|
@ -4048,7 +4048,7 @@ class NetESFunc : public NetExpr {
|
|||
|
||||
virtual ivl_variable_type_t expr_type() const;
|
||||
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 expr_scan(struct expr_scan_t*) const;
|
||||
|
|
@ -4073,7 +4073,7 @@ class NetESFunc : public NetExpr {
|
|||
|
||||
const char* name_;
|
||||
ivl_variable_type_t type_;
|
||||
netenum_t*enum_type_;
|
||||
const netenum_t*enum_type_;
|
||||
std::vector<NetExpr*>parms_;
|
||||
|
||||
ID built_in_id_() const;
|
||||
|
|
@ -4252,7 +4252,7 @@ class NetESignal : public NetExpr {
|
|||
virtual NetESignal* dup_expr() const;
|
||||
NetNet* synthesize(Design*des, NetScope*scope, NetExpr*root);
|
||||
NexusSet* nex_input(bool rem_out = true);
|
||||
netenum_t*enumeration() const;
|
||||
const netenum_t*enumeration() const;
|
||||
|
||||
virtual NetExpr*evaluate_function(const LineInfo&loc,
|
||||
map<perm_string,LocalVar>&ctx) const;
|
||||
|
|
@ -4277,7 +4277,7 @@ class NetESignal : public NetExpr {
|
|||
|
||||
private:
|
||||
NetNet*net_;
|
||||
netenum_t*enum_type_;
|
||||
const netenum_t*enum_type_;
|
||||
// Expression to select a word from the net.
|
||||
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;
|
||||
vector<Statement*>*statement_list;
|
||||
|
||||
PTaskFuncArg function_type;
|
||||
|
||||
net_decl_assign_t*net_decl_assign;
|
||||
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 <parmvalue> parameter_value_opt
|
||||
|
||||
%type <function_type> function_range_or_type_opt
|
||||
%type <event_expr> event_expression_list
|
||||
%type <event_expr> event_expression
|
||||
%type <event_statement> event_control
|
||||
|
|
@ -761,27 +758,36 @@ class_items /* IEEE1800-2005: A.1.2 */
|
|||
class_item /* IEEE1800-2005: A.1.8 */
|
||||
|
||||
/* 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
|
||||
statement_or_null_list_opt
|
||||
K_endfunction endnew_opt
|
||||
{ yyerror(@3, "sorry: Class constructors not supported yet.");
|
||||
yyerrok;
|
||||
{ current_function->set_ports($6);
|
||||
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
|
||||
parent constructor. Note that the implicit_class_handle must
|
||||
be K_super ("this.new" makes little sense) but that would
|
||||
cause a conflict. */
|
||||
/* XXXX
|
||||
| method_qualifier_opt K_function K_new '(' tf_port_list_opt ')' ';'
|
||||
function_item_list_opt
|
||||
attribute_list_opt implicit_class_handle '.' K_new '(' expression_list_with_nuls ')'
|
||||
statement_or_null_list_opt
|
||||
K_endfunction endnew_opt
|
||||
{ yyerror(@3, "sorry: Class constructors not supported yet.");
|
||||
{ yyerror(@3, "sorry: Class constructors with parent not supported yet.");
|
||||
yyerrok;
|
||||
}
|
||||
|
||||
*/
|
||||
/* Class properties... */
|
||||
|
||||
| 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);
|
||||
$$ = 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
|
||||
{ if ($2) $$ = new parray_type_t($1, $2);
|
||||
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
|
||||
instead of the module. */
|
||||
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);
|
||||
current_function = pform_push_function_scope(@1, $4, $2);
|
||||
}
|
||||
|
|
@ -1070,7 +1089,7 @@ function_declaration /* IEEE1800-2005: A.2.6 */
|
|||
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);
|
||||
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. */
|
||||
|
||||
| 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) {
|
||||
pform_pop_scope();
|
||||
|
|
@ -1705,58 +1724,7 @@ tf_port_declaration /* 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 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
|
||||
: port_direction_opt data_type_or_implicit IDENTIFIER range_opt tf_port_item_expr_opt
|
||||
{ vector<PWire*>*tmp;
|
||||
NetNet::PortType use_port_type = $1==NetNet::PIMPLICIT? NetNet::PINPUT : $1;
|
||||
list<perm_string>* ilist = list_from_identifier($3);
|
||||
|
|
@ -1987,22 +1955,10 @@ attribute
|
|||
|
||||
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
|
||||
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);
|
||||
}
|
||||
|
||||
|
|
@ -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
|
||||
variables in a "reg" definition. I therefore know that I am
|
||||
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;
|
||||
}
|
||||
|
||||
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)
|
||||
{
|
||||
perm_string func_name = lex_strings.make(name);
|
||||
|
|
@ -2932,57 +2932,6 @@ void pform_set_port_type(const struct vlltype&li,
|
|||
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)
|
||||
{
|
||||
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 (net_type==NetNet::REG && vec_type->integer_flag)
|
||||
net_type=NetNet::INTEGER;
|
||||
|
||||
pform_set_net_range(names, vec_type->pdims.get(),
|
||||
vec_type->signed_flag,
|
||||
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,
|
||||
std::list<decl_assignment_t*>*decls);
|
||||
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);
|
||||
|
||||
|
|
@ -232,10 +233,11 @@ extern void pform_pop_scope();
|
|||
extern LexicalScope* pform_peek_scope();
|
||||
|
||||
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 PTask*pform_push_task_scope(const struct vlltype&loc, char*name,
|
||||
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);
|
||||
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,
|
||||
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);
|
||||
|
||||
|
|
|
|||
|
|
@ -423,6 +423,13 @@ void PWire::dump(ostream&out, unsigned ind) const
|
|||
out << " signed";
|
||||
}
|
||||
|
||||
if (get_isint()) {
|
||||
out << " integer";
|
||||
}
|
||||
if (set_data_type_) {
|
||||
out << " set_data_type_=" << typeid(*set_data_type_).name();
|
||||
}
|
||||
|
||||
if (discipline_) {
|
||||
out << " discipline<" << discipline_->name() << ">";
|
||||
}
|
||||
|
|
@ -867,47 +874,12 @@ void PForStatement::dump(ostream&out, unsigned ind) const
|
|||
void PFunction::dump(ostream&out, unsigned ind) const
|
||||
{
|
||||
out << setw(ind) << "" << "function ";
|
||||
if (is_auto_) cout << "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 (is_auto_) out << "automatic...";
|
||||
|
||||
if (return_type_.range) {
|
||||
out << "[";
|
||||
out << "] ";
|
||||
}
|
||||
if (return_type_)
|
||||
return_type_->pform_dump(out, ind+8);
|
||||
else
|
||||
out << setw(ind+8) << "" << "<implicit type>" << endl;
|
||||
|
||||
out << pscope_name() << ";" << endl;
|
||||
if (method_of())
|
||||
|
|
@ -944,7 +916,7 @@ void PRepeat::dump(ostream&out, unsigned ind) const
|
|||
void PTask::dump(ostream&out, unsigned ind) const
|
||||
{
|
||||
out << setw(ind) << "" << "task ";
|
||||
if (is_auto_) cout << "automatic ";
|
||||
if (is_auto_) out << "automatic ";
|
||||
out << pscope_name() << ";" << endl;
|
||||
if (method_of())
|
||||
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);
|
||||
}
|
||||
|
||||
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)
|
||||
{
|
||||
assert(pform_cur_class);
|
||||
|
|
|
|||
|
|
@ -144,12 +144,14 @@ struct atom2_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,
|
||||
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;
|
||||
ivl_type_s* elaborate_type(Design*des, NetScope*scope) const;
|
||||
|
||||
ivl_variable_type_t base_type;
|
||||
bool signed_flag;
|
||||
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
|
||||
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
|
||||
|
||||
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)) {
|
||||
case IVL_SIT_REG:
|
||||
type = "reg";
|
||||
if (ivl_signal_integer(net))
|
||||
type = "integer";
|
||||
break;
|
||||
case IVL_SIT_TRI:
|
||||
type = "tri";
|
||||
|
|
@ -1351,6 +1353,11 @@ static void show_signal(ivl_signal_t net)
|
|||
default:
|
||||
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)
|
||||
|
|
|
|||
Loading…
Reference in New Issue