Elaborate class_new and (null) expressions
This gets the types right for class_new and null expressions, and elaborate them down to the ivl_target.h API.
This commit is contained in:
parent
55bebc8c39
commit
77d24cd095
|
|
@ -107,13 +107,13 @@ O = main.o async.o design_dump.o discipline.o dup_expr.o elaborate.o \
|
|||
elab_scope.o elab_sig.o elab_sig_analog.o emit.o eval.o eval_attrib.o \
|
||||
eval_tree.o expr_synth.o functor.o lexor.o lexor_keyword.o link_const.o \
|
||||
load_module.o netlist.o netmisc.o nettypes.o net_analog.o net_assign.o \
|
||||
net_design.o netdarray.o \
|
||||
net_design.o netclass.o netdarray.o \
|
||||
netenum.o netparray.o netstruct.o netvector.o net_event.o net_expr.o net_func.o \
|
||||
net_func_eval.o net_link.o net_modulo.o \
|
||||
net_nex_input.o net_nex_output.o net_proc.o net_scope.o net_tran.o \
|
||||
net_udp.o pad_to_width.o parse.o parse_misc.o pform.o pform_analog.o \
|
||||
pform_disciplines.o pform_dump.o pform_package.o pform_pclass.o \
|
||||
pform_string_type.o pform_struct_type.o pform_types.o \
|
||||
pform_class_type.o pform_string_type.o pform_struct_type.o pform_types.o \
|
||||
symbol_search.o sync.o sys_funcs.o verinum.o verireal.o target.o \
|
||||
Attrib.o HName.o Module.o PClass.o PDelays.o PEvent.o PExpr.o PGate.o \
|
||||
PGenerate.o PPackage.o PScope.o PSpec.o PTask.o PUdp.o PFunction.o PWire.o \
|
||||
|
|
|
|||
3
PClass.h
3
PClass.h
|
|
@ -22,6 +22,7 @@
|
|||
# include "PScope.h"
|
||||
# include "LineInfo.h"
|
||||
# include "StringHeap.h"
|
||||
# include <iostream>
|
||||
|
||||
/*
|
||||
* SystemVerilog supports class declarations with their own lexical
|
||||
|
|
@ -35,6 +36,8 @@ class PClass : public PScopeExtra, public LineInfo {
|
|||
explicit PClass (perm_string name, LexicalScope*parent);
|
||||
~PClass();
|
||||
|
||||
void dump(std::ostream&out, unsigned indent) const;
|
||||
|
||||
public:
|
||||
class_type_t*type;
|
||||
};
|
||||
|
|
|
|||
8
PExpr.cc
8
PExpr.cc
|
|
@ -389,6 +389,14 @@ PENew::~PENew()
|
|||
delete size_;
|
||||
}
|
||||
|
||||
PENewClass::PENewClass(void)
|
||||
{
|
||||
}
|
||||
|
||||
PENewClass::~PENewClass()
|
||||
{
|
||||
}
|
||||
|
||||
PENumber::PENumber(verinum*vp)
|
||||
: value_(vp)
|
||||
{
|
||||
|
|
|
|||
24
PExpr.h
24
PExpr.h
|
|
@ -467,12 +467,36 @@ class PENew : public PExpr {
|
|||
PExpr*size_;
|
||||
};
|
||||
|
||||
class PENewClass : public PExpr {
|
||||
|
||||
public:
|
||||
explicit PENewClass ();
|
||||
~PENewClass();
|
||||
virtual void dump(ostream&) const;
|
||||
// Class objects don't have a useful width, but the expression
|
||||
// is IVL_VT_CLASS.
|
||||
virtual unsigned test_width(Design*des, NetScope*scope,
|
||||
width_mode_t&mode);
|
||||
// Note that class (new) expressions only appear in context
|
||||
// that uses this form of the elaborate_expr method. In fact,
|
||||
// the type argument is going to be a netclas_t object.
|
||||
virtual NetExpr*elaborate_expr(Design*des, NetScope*scope,
|
||||
ivl_type_t type, unsigned flags) const;
|
||||
|
||||
private:
|
||||
};
|
||||
|
||||
class PENull : public PExpr {
|
||||
public:
|
||||
explicit PENull();
|
||||
~PENull();
|
||||
|
||||
virtual void dump(ostream&) const;
|
||||
virtual unsigned test_width(Design*des, NetScope*scope,
|
||||
width_mode_t&mode);
|
||||
virtual NetExpr*elaborate_expr(Design*des, NetScope*,
|
||||
unsigned expr_wid,
|
||||
unsigned flags) const;
|
||||
};
|
||||
|
||||
class PENumber : public PExpr {
|
||||
|
|
|
|||
10
PScope.h
10
PScope.h
|
|
@ -30,6 +30,7 @@ class PExpr;
|
|||
class PFunction;
|
||||
class AProcess;
|
||||
class PProcess;
|
||||
class PClass;
|
||||
class PTask;
|
||||
class PWire;
|
||||
|
||||
|
|
@ -165,8 +166,13 @@ class PScopeExtra : public PScope {
|
|||
~PScopeExtra();
|
||||
|
||||
/* Task definitions within this module */
|
||||
map<perm_string,PTask*> tasks;
|
||||
map<perm_string,PFunction*> funcs;
|
||||
std::map<perm_string,PTask*> tasks;
|
||||
std::map<perm_string,PFunction*> funcs;
|
||||
/* class definitions within this module. */
|
||||
std::map<perm_string,PClass*> classes;
|
||||
|
||||
protected:
|
||||
void dump_classes_(ostream&out, unsigned indent) const;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
|
|
|||
2
PWire.cc
2
PWire.cc
|
|
@ -253,7 +253,7 @@ void PWire::set_unpacked_idx(const list<pform_range_t>&ranges)
|
|||
}
|
||||
}
|
||||
|
||||
void PWire::set_packed_type(data_type_t*type)
|
||||
void PWire::set_data_type(data_type_t*type)
|
||||
{
|
||||
assert(set_data_type_ == 0);
|
||||
set_data_type_ = type;
|
||||
|
|
|
|||
4
PWire.h
4
PWire.h
|
|
@ -81,7 +81,7 @@ class PWire : public LineInfo {
|
|||
|
||||
void set_unpacked_idx(const std::list<pform_range_t>&ranges);
|
||||
|
||||
void set_packed_type(data_type_t*type);
|
||||
void set_data_type(data_type_t*type);
|
||||
|
||||
void set_discipline(ivl_discipline_t);
|
||||
ivl_discipline_t get_discipline(void) const;
|
||||
|
|
@ -118,6 +118,8 @@ class PWire : public LineInfo {
|
|||
// me the size and address ranges of the memory.
|
||||
std::list<pform_range_t>unpacked_;
|
||||
|
||||
// This is the complex type of the wire. the data_type_ may
|
||||
// modify how this is interpreted.
|
||||
data_type_t*set_data_type_;
|
||||
|
||||
ivl_discipline_t discipline_;
|
||||
|
|
|
|||
|
|
@ -109,6 +109,9 @@ ostream& operator << (ostream&o, ivl_variable_type_t val)
|
|||
case IVL_VT_DARRAY:
|
||||
o << "darray";
|
||||
break;
|
||||
case IVL_VT_CLASS:
|
||||
o << "class";
|
||||
break;
|
||||
}
|
||||
return o;
|
||||
}
|
||||
|
|
@ -1506,6 +1509,11 @@ void NetENetenum::dump(ostream&o) const
|
|||
o << "<netenum=" << netenum_ << ">";
|
||||
}
|
||||
|
||||
void NetENull::dump(ostream&o) const
|
||||
{
|
||||
o << "<null>";
|
||||
}
|
||||
|
||||
void NetEScope::dump(ostream&o) const
|
||||
{
|
||||
o << "<scope=" << scope_path(scope_) << ">";
|
||||
|
|
|
|||
|
|
@ -177,6 +177,12 @@ NetENetenum* NetENetenum::dup_expr() const
|
|||
return 0;
|
||||
}
|
||||
|
||||
NetENull* NetENull::dup_expr() const
|
||||
{
|
||||
ivl_assert(*this, 0);
|
||||
return 0;
|
||||
}
|
||||
|
||||
NetEScope* NetEScope::dup_expr() const
|
||||
{
|
||||
ivl_assert(*this, 0);
|
||||
|
|
|
|||
50
elab_expr.cc
50
elab_expr.cc
|
|
@ -101,6 +101,12 @@ NetExpr* elaborate_rval_expr(Design*des, NetScope*scope,
|
|||
case IVL_VT_NO_TYPE:
|
||||
ivl_assert(*expr, 0);
|
||||
break;
|
||||
case IVL_VT_CLASS:
|
||||
cerr << expr->get_fileline() << ": sorry: "
|
||||
<< "I do not know how to elaborate r-value as IVL_VT_CLASS." << endl;
|
||||
des->errors += 1;
|
||||
return 0;
|
||||
break;
|
||||
}
|
||||
|
||||
return elab_and_eval(des, scope, expr, context_wid, need_const);
|
||||
|
|
@ -1074,7 +1080,7 @@ unsigned PECallFunction::test_width(Design*des, NetScope*scope,
|
|||
}
|
||||
|
||||
unsigned PECallFunction::test_width_method_(Design*des, NetScope*scope,
|
||||
width_mode_t&mode)
|
||||
width_mode_t&)
|
||||
{
|
||||
if (!gn_system_verilog())
|
||||
return 0;
|
||||
|
|
@ -2396,7 +2402,9 @@ unsigned PEIdent::test_width(Design*des, NetScope*scope, width_mode_t&mode)
|
|||
signed_flag_ = net->get_signed();
|
||||
if (debug_elaborate) {
|
||||
cerr << get_fileline() << ": PEIdent::test_width: "
|
||||
<< net->name() << " is a net, width=" << expr_width_ << endl;
|
||||
<< net->name() << " is a net, "
|
||||
<< "type=" << expr_type_
|
||||
<< ", width=" << expr_width_ << endl;
|
||||
}
|
||||
return expr_width_;
|
||||
}
|
||||
|
|
@ -4021,6 +4029,44 @@ NetExpr* PENew::elaborate_expr(Design*des, NetScope*scope,
|
|||
return tmp;
|
||||
}
|
||||
|
||||
unsigned PENewClass::test_width(Design*, NetScope*, width_mode_t&)
|
||||
{
|
||||
expr_type_ = IVL_VT_CLASS;
|
||||
expr_width_ = 1;
|
||||
min_width_ = 1;
|
||||
signed_flag_= false;
|
||||
return 1;
|
||||
}
|
||||
|
||||
NetExpr* PENewClass::elaborate_expr(Design*, NetScope*,
|
||||
ivl_type_t ntype, unsigned) const
|
||||
{
|
||||
NetESFunc*tmp = new NetESFunc("$ivl_class_method$new", ntype, 0);
|
||||
tmp->set_line(*this);
|
||||
return tmp;
|
||||
}
|
||||
|
||||
/*
|
||||
* A "null" expression represents class objects/handles. This brings
|
||||
* up a ton of special cases, but we handle it here bu setting the
|
||||
* expr_type_ and expr_width_ to fixed values.
|
||||
*/
|
||||
unsigned PENull::test_width(Design*, NetScope*, width_mode_t&)
|
||||
{
|
||||
expr_type_ = IVL_VT_CLASS;
|
||||
expr_width_ = 1;
|
||||
min_width_ = 1;
|
||||
signed_flag_ = false;
|
||||
return expr_width_;
|
||||
}
|
||||
|
||||
NetExpr* PENull::elaborate_expr(Design*, NetScope*, unsigned, unsigned) const
|
||||
{
|
||||
NetENull*tmp = new NetENull;
|
||||
tmp->set_line(*this);
|
||||
return tmp;
|
||||
}
|
||||
|
||||
unsigned PENumber::test_width(Design*, NetScope*, width_mode_t&mode)
|
||||
{
|
||||
expr_type_ = IVL_VT_LOGIC;
|
||||
|
|
|
|||
|
|
@ -33,8 +33,10 @@
|
|||
*/
|
||||
|
||||
# include "Module.h"
|
||||
# include "PEvent.h"
|
||||
# include "PClass.h"
|
||||
# include "PExpr.h"
|
||||
# include "PEvent.h"
|
||||
# include "PClass.h"
|
||||
# include "PGate.h"
|
||||
# include "PGenerate.h"
|
||||
# include "PTask.h"
|
||||
|
|
@ -42,6 +44,7 @@
|
|||
# include "Statement.h"
|
||||
# include "AStatement.h"
|
||||
# include "netlist.h"
|
||||
# include "netclass.h"
|
||||
# include "netenum.h"
|
||||
# include "util.h"
|
||||
# include <typeinfo>
|
||||
|
|
@ -286,6 +289,22 @@ static void elaborate_scope_enumerations(Design*des, NetScope*scope,
|
|||
}
|
||||
}
|
||||
|
||||
static void elaborate_scope_class(Design*des, NetScope*scope,
|
||||
PClass*pclass)
|
||||
{
|
||||
netclass_t*use_class = new netclass_t(pclass->type->name);
|
||||
scope->add_class(use_class);
|
||||
}
|
||||
|
||||
static void elaborate_scope_classes(Design*des, NetScope*scope,
|
||||
const map<perm_string,PClass*>&classes)
|
||||
{
|
||||
for (map<perm_string,PClass*>::const_iterator cur = classes.begin()
|
||||
; cur != classes.end() ; ++ cur) {
|
||||
elaborate_scope_class(des, scope, cur->second);
|
||||
}
|
||||
}
|
||||
|
||||
static void replace_scope_parameters_(NetScope*scope, const LineInfo&loc,
|
||||
const Module::replace_t&replacements)
|
||||
{
|
||||
|
|
@ -500,6 +519,8 @@ bool Module::elaborate_scope(Design*des, NetScope*scope,
|
|||
|
||||
elaborate_scope_enumerations(des, scope, enum_sets);
|
||||
|
||||
elaborate_scope_classes(des, scope, classes);
|
||||
|
||||
// Run through the defparams for this module and save the result
|
||||
// in a table for later final override.
|
||||
|
||||
|
|
|
|||
24
elab_sig.cc
24
elab_sig.cc
|
|
@ -34,6 +34,7 @@
|
|||
# include "compiler.h"
|
||||
# include "netlist.h"
|
||||
# include "netmisc.h"
|
||||
# include "netclass.h"
|
||||
# include "netenum.h"
|
||||
# include "netstruct.h"
|
||||
# include "netvector.h"
|
||||
|
|
@ -864,6 +865,13 @@ static bool evaluate_ranges(Design*des, NetScope*scope,
|
|||
return bad_msb | bad_lsb;
|
||||
}
|
||||
|
||||
static netclass_t* locate_class_type(Design*des, NetScope*scope,
|
||||
class_type_t*class_type)
|
||||
{
|
||||
netclass_t*use_class = scope->find_class(class_type->name);
|
||||
return use_class;
|
||||
}
|
||||
|
||||
static netstruct_t* elaborate_struct_type(Design*des, NetScope*scope,
|
||||
struct_type_t*struct_type)
|
||||
{
|
||||
|
|
@ -1196,9 +1204,19 @@ NetNet* PWire::elaborate_sig(Design*des, NetScope*scope) const
|
|||
|
||||
NetNet*sig = 0;
|
||||
|
||||
// If this is a struct type, then build the net with the
|
||||
// struct type.
|
||||
if (struct_type_t*struct_type = dynamic_cast<struct_type_t*>(set_data_type_)) {
|
||||
if (class_type_t*class_type = dynamic_cast<class_type_t*>(set_data_type_)) {
|
||||
// If this is a class variable, then the class type
|
||||
// should already have been elaborated. All we need to
|
||||
// do right now is locate the netclass_t object for the
|
||||
// class, and use that to build the net.
|
||||
netclass_t*use_type = locate_class_type(des, scope, class_type);
|
||||
// (No arrays of classes)
|
||||
list<netrange_t> use_unpacked;
|
||||
sig = new NetNet(scope, name_, wtype, use_unpacked, use_type);
|
||||
|
||||
} else if (struct_type_t*struct_type = dynamic_cast<struct_type_t*>(set_data_type_)) {
|
||||
// If this is a struct type, then build the net with the
|
||||
// struct type.
|
||||
netstruct_t*use_type = elaborate_struct_type(des, scope, struct_type);
|
||||
if (debug_elaborate) {
|
||||
cerr << get_fileline() << ": debug: Create signal " << wtype;
|
||||
|
|
|
|||
|
|
@ -2385,6 +2385,10 @@ NetProc* PAssign::elaborate(Design*des, NetScope*scope) const
|
|||
handle it with this code instead. */
|
||||
rv = elaborate_rval_(des, scope, lv->sig()->net_type());
|
||||
|
||||
} else if (lv->more==0 && dynamic_cast<const PENewClass*> (rval())) {
|
||||
|
||||
rv = elaborate_rval_(des, scope, lv->sig()->net_type());
|
||||
|
||||
} else {
|
||||
/* Elaborate the r-value expression, then try to evaluate it. */
|
||||
rv = elaborate_rval_(des, scope, count_lval_width(lv), lv->expr_type());
|
||||
|
|
|
|||
5
emit.cc
5
emit.cc
|
|
@ -551,6 +551,11 @@ void NetENetenum::expr_scan(struct expr_scan_t*tgt) const
|
|||
tgt->expr_netenum(this);
|
||||
}
|
||||
|
||||
void NetENull::expr_scan(struct expr_scan_t*tgt) const
|
||||
{
|
||||
tgt->expr_null(this);
|
||||
}
|
||||
|
||||
void NetEScope::expr_scan(struct expr_scan_t*tgt) const
|
||||
{
|
||||
tgt->expr_scope(this);
|
||||
|
|
|
|||
|
|
@ -224,6 +224,7 @@ typedef enum ivl_expr_type_e {
|
|||
IVL_EX_ENUMTYPE = 21,
|
||||
IVL_EX_EVENT = 17,
|
||||
IVL_EX_MEMORY = 4,
|
||||
IVL_EX_NULL = 22,
|
||||
IVL_EX_NUMBER = 5,
|
||||
IVL_EX_REALNUM = 16,
|
||||
IVL_EX_SCOPE = 6,
|
||||
|
|
@ -426,6 +427,7 @@ typedef enum ivl_variable_type_e {
|
|||
IVL_VT_LOGIC = 4,
|
||||
IVL_VT_STRING = 5,
|
||||
IVL_VT_DARRAY = 6, /* Array (esp. dynamic array) */
|
||||
IVL_VT_CLASS = 7, /* SystemVerilog class instances */
|
||||
IVL_VT_VECTOR = IVL_VT_LOGIC /* For compatibility */
|
||||
} ivl_variable_type_t;
|
||||
|
||||
|
|
|
|||
17
net_expr.cc
17
net_expr.cc
|
|
@ -20,6 +20,7 @@
|
|||
# include "config.h"
|
||||
# include "netlist.h"
|
||||
# include "netenum.h"
|
||||
# include "netclass.h"
|
||||
# include "netdarray.h"
|
||||
# include "compiler.h"
|
||||
# include "netmisc.h"
|
||||
|
|
@ -320,6 +321,14 @@ netenum_t* NetENetenum::netenum() const
|
|||
return netenum_;
|
||||
}
|
||||
|
||||
NetENull::NetENull()
|
||||
{
|
||||
}
|
||||
|
||||
NetENull::~NetENull()
|
||||
{
|
||||
}
|
||||
|
||||
NetESelect::NetESelect(NetExpr*exp, NetExpr*base, unsigned wid,
|
||||
ivl_select_type_t sel_type)
|
||||
: expr_(exp), base_(base), sel_type_(sel_type)
|
||||
|
|
@ -395,8 +404,12 @@ NetESFunc::NetESFunc(const char*n, ivl_type_t rtype, unsigned np)
|
|||
// FIXME: For now, assume that all uses of this constructor
|
||||
// are for the IVL_VT_DARRAY type. Eventually, the type_
|
||||
// member will go away.
|
||||
ivl_assert(*this, dynamic_cast<const netdarray_t*>(rtype));
|
||||
type_ = IVL_VT_DARRAY;
|
||||
if (dynamic_cast<const netdarray_t*>(rtype))
|
||||
type_ = IVL_VT_DARRAY;
|
||||
else if (dynamic_cast<const netclass_t*>(rtype))
|
||||
type_ = IVL_VT_CLASS;
|
||||
else
|
||||
ivl_assert(*this, 0);
|
||||
}
|
||||
|
||||
NetESFunc::NetESFunc(const char*n, netenum_t*enum_type, unsigned np)
|
||||
|
|
|
|||
|
|
@ -96,6 +96,11 @@ NexusSet* NetENetenum::nex_input(bool)
|
|||
return new NexusSet;
|
||||
}
|
||||
|
||||
NexusSet* NetENull::nex_input(bool)
|
||||
{
|
||||
return new NexusSet;
|
||||
}
|
||||
|
||||
NexusSet* NetEScope::nex_input(bool)
|
||||
{
|
||||
return new NexusSet;
|
||||
|
|
|
|||
15
net_scope.cc
15
net_scope.cc
|
|
@ -21,6 +21,7 @@
|
|||
# include "compiler.h"
|
||||
|
||||
# include "netlist.h"
|
||||
# include "netclass.h"
|
||||
# include "netenum.h"
|
||||
# include <cstring>
|
||||
# include <cstdlib>
|
||||
|
|
@ -551,6 +552,20 @@ netenum_t*NetScope::enumeration_for_name(perm_string name)
|
|||
return tmp->enumeration();
|
||||
}
|
||||
|
||||
void NetScope::add_class(netclass_t*net_class)
|
||||
{
|
||||
classes_[net_class->get_name()] = net_class;
|
||||
}
|
||||
|
||||
netclass_t*NetScope::find_class(perm_string name)
|
||||
{
|
||||
map<perm_string,netclass_t*>::const_iterator cur = classes_.find(name);
|
||||
if (cur == classes_.end())
|
||||
return 0;
|
||||
else
|
||||
return cur->second;
|
||||
}
|
||||
|
||||
/*
|
||||
* This method locates a child scope by name. The name is the simple
|
||||
* name of the child, no hierarchy is searched.
|
||||
|
|
|
|||
|
|
@ -0,0 +1,34 @@
|
|||
/*
|
||||
* Copyright (c) 2012 Stephen Williams (steve@icarus.com)
|
||||
*
|
||||
* This source code is free software; you can redistribute it
|
||||
* and/or modify it in source code form under the terms of the GNU
|
||||
* General Public License as published by the Free Software
|
||||
* Foundation; either version 2 of the License, or (at your option)
|
||||
* any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
*/
|
||||
|
||||
# include "netclass.h"
|
||||
|
||||
netclass_t::netclass_t(perm_string name)
|
||||
: name_(name)
|
||||
{
|
||||
}
|
||||
|
||||
netclass_t::~netclass_t()
|
||||
{
|
||||
}
|
||||
|
||||
ivl_variable_type_t netclass_t::base_type() const
|
||||
{
|
||||
return IVL_VT_CLASS;
|
||||
}
|
||||
|
|
@ -0,0 +1,41 @@
|
|||
#ifndef __netclass_H
|
||||
#define __netclass_H
|
||||
/*
|
||||
* Copyright (c) 2012 Stephen Williams (steve@icarus.com)
|
||||
*
|
||||
* This source code is free software; you can redistribute it
|
||||
* and/or modify it in source code form under the terms of the GNU
|
||||
* General Public License as published by the Free Software
|
||||
* Foundation; either version 2 of the License, or (at your option)
|
||||
* any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
*/
|
||||
|
||||
# include "LineInfo.h"
|
||||
# include "ivl_target.h"
|
||||
# include "nettypes.h"
|
||||
|
||||
class netclass_t : public ivl_type_s {
|
||||
public:
|
||||
netclass_t(perm_string class_name);
|
||||
~netclass_t();
|
||||
|
||||
// As an ivl_type_s object, the netclass is always an
|
||||
// ivl_VT_CLASS object.
|
||||
ivl_variable_type_t base_type() const;
|
||||
|
||||
inline perm_string get_name() const { return name_; }
|
||||
|
||||
private:
|
||||
perm_string name_;
|
||||
};
|
||||
|
||||
#endif
|
||||
23
netlist.h
23
netlist.h
|
|
@ -76,6 +76,7 @@ class NetEvTrig;
|
|||
class NetEvWait;
|
||||
class PExpr;
|
||||
class PFunction;
|
||||
class netclass_t;
|
||||
class netdarray_t;
|
||||
class netparray_t;
|
||||
class netenum_t;
|
||||
|
|
@ -835,6 +836,9 @@ class NetScope : public Attrib {
|
|||
|
||||
netenum_t* enumeration_for_name(perm_string name);
|
||||
|
||||
void add_class(netclass_t*class_type);
|
||||
netclass_t* find_class(perm_string name);
|
||||
|
||||
/* The parent and child() methods allow users of NetScope
|
||||
objects to locate nearby scopes. */
|
||||
NetScope* parent() { return up_; }
|
||||
|
|
@ -1083,6 +1087,8 @@ class NetScope : public Attrib {
|
|||
std::list<netenum_t*> enum_sets_;
|
||||
std::map<perm_string,NetEConstEnum*> enum_names_;
|
||||
|
||||
std::map<perm_string,netclass_t*> classes_;
|
||||
|
||||
NetScope*up_;
|
||||
map<hname_t,NetScope*> children_;
|
||||
|
||||
|
|
@ -3871,6 +3877,23 @@ class NetENetenum : public NetExpr {
|
|||
netenum_t*netenum_;
|
||||
};
|
||||
|
||||
/*
|
||||
* The NetENull node represents the SystemVerilog (null)
|
||||
* expression. This is always a null class handle.
|
||||
*/
|
||||
class NetENull : public NetExpr {
|
||||
|
||||
public:
|
||||
NetENull();
|
||||
~NetENull();
|
||||
|
||||
virtual void expr_scan(struct expr_scan_t*) const;
|
||||
virtual NetENull* dup_expr() const;
|
||||
virtual NexusSet* nex_input(bool rem_out = true);
|
||||
|
||||
virtual void dump(ostream&os) const;
|
||||
};
|
||||
|
||||
/*
|
||||
* This class is a special (and magical) expression node type that
|
||||
* represents scope names. These can only be found as parameters to
|
||||
|
|
|
|||
11
parse.y
11
parse.y
|
|
@ -658,7 +658,6 @@ class_declaration /* IEEE1800-2005: A.1.2 */
|
|||
class_items_opt K_endclass
|
||||
{ // Process a class.
|
||||
pform_end_class_declaration();
|
||||
yyerror(@2, "sorry: Class declarations not supported yet.");
|
||||
}
|
||||
class_declaration_endname_opt
|
||||
{ // Wrap up the class.
|
||||
|
|
@ -819,16 +818,18 @@ class_item_qualifier /* IEEE1800-2005 A.1.8 */
|
|||
|
||||
class_new /* IEEE1800-2005 A.2.4 */
|
||||
: K_new '(' ')'
|
||||
{ yyerror(@1, "sorry: class_new not implemented yet.");
|
||||
$$ = 0;
|
||||
{ PENewClass*tmp = new PENewClass;
|
||||
FILE_NAME(tmp, @1);
|
||||
$$ = tmp;
|
||||
}
|
||||
| K_new '(' expression_list_proper ')'
|
||||
{ yyerror(@1, "sorry: class_new not implemented yet.");
|
||||
$$ = 0;
|
||||
}
|
||||
| K_new
|
||||
{ yyerror(@1, "sorry: class_new not implemented yet.");
|
||||
$$ = 0;
|
||||
{ PENewClass*tmp = new PENewClass;
|
||||
FILE_NAME(tmp, @1);
|
||||
$$ = tmp;
|
||||
}
|
||||
;
|
||||
|
||||
|
|
|
|||
39
pform.cc
39
pform.cc
|
|
@ -284,11 +284,33 @@ void pform_pop_scope()
|
|||
lexical_scope = lexical_scope->parent_scope();
|
||||
}
|
||||
|
||||
static PScopeExtra* find_nearest_scopex(LexicalScope*scope)
|
||||
{
|
||||
PScopeExtra*scopex = dynamic_cast<PScopeExtra*> (scope);
|
||||
while (scope && !scopex) {
|
||||
scope = scope->parent_scope();
|
||||
scopex = dynamic_cast<PScopeExtra*> (scope);
|
||||
}
|
||||
return scopex;
|
||||
}
|
||||
|
||||
PClass* pform_push_class_scope(const struct vlltype&loc, perm_string name)
|
||||
{
|
||||
PClass*class_scope = new PClass(name, lexical_scope);
|
||||
FILE_NAME(class_scope, loc);
|
||||
|
||||
PScopeExtra*scopex = find_nearest_scopex(lexical_scope);
|
||||
|
||||
assert(!pform_cur_generate);
|
||||
|
||||
if (scopex->classes.find(name) != scopex->classes.end()) {
|
||||
cerr << class_scope->get_fileline() << ": error: duplicate "
|
||||
" definition for class '" << name << "' in '"
|
||||
<< scopex->pscope_name() << "'." << endl;
|
||||
error_count += 1;
|
||||
}
|
||||
scopex->classes[name] = class_scope;
|
||||
|
||||
lexical_scope = class_scope;
|
||||
return class_scope;
|
||||
}
|
||||
|
|
@ -309,12 +331,7 @@ PTask* pform_push_task_scope(const struct vlltype&loc, char*name, bool is_auto)
|
|||
PTask*task = new PTask(task_name, lexical_scope, is_auto);
|
||||
FILE_NAME(task, loc);
|
||||
|
||||
LexicalScope*scope = lexical_scope;
|
||||
PScopeExtra*scopex = dynamic_cast<PScopeExtra*> (scope);
|
||||
while (scope && !scopex) {
|
||||
scope = scope->parent_scope();
|
||||
scopex = dynamic_cast<PScopeExtra*> (scope);
|
||||
}
|
||||
PScopeExtra*scopex = find_nearest_scopex(lexical_scope);
|
||||
assert(scopex);
|
||||
|
||||
if (pform_cur_generate) {
|
||||
|
|
@ -2042,7 +2059,7 @@ void pform_module_define_port(const struct vlltype&li,
|
|||
cur->set_signed(signed_flag);
|
||||
|
||||
if (struct_type) {
|
||||
cur->set_packed_type(struct_type);
|
||||
cur->set_data_type(struct_type);
|
||||
|
||||
} else if (range == 0) {
|
||||
cur->set_range_scalar((type == NetNet::IMPLICIT) ? SR_PORT : SR_BOTH);
|
||||
|
|
@ -2830,7 +2847,7 @@ template <class T> static void pform_set2_data_type(const struct vlltype&li, T*d
|
|||
}
|
||||
|
||||
PWire*net = pform_get_make_wire_in_scope(name, net_type, NetNet::NOT_A_PORT, base_type);
|
||||
net->set_packed_type(data_type);
|
||||
net->set_data_type(data_type);
|
||||
pform_bind_attributes(net->attributes, attr, true);
|
||||
}
|
||||
|
||||
|
|
@ -2855,7 +2872,7 @@ static void pform_set_enum(const struct vlltype&li, enum_type_t*enum_type,
|
|||
assert(enum_type->range.get() != 0);
|
||||
assert(enum_type->range->size() == 1);
|
||||
//XXXXcur->set_range(*enum_type->range, SR_NET);
|
||||
cur->set_packed_type(enum_type);
|
||||
cur->set_data_type(enum_type);
|
||||
pform_bind_attributes(cur->attributes, attr, true);
|
||||
}
|
||||
|
||||
|
|
@ -2925,8 +2942,8 @@ void pform_set_data_type(const struct vlltype&li, data_type_t*data_type, list<pe
|
|||
return;
|
||||
}
|
||||
|
||||
if (/*class_type_t*class_type =*/ dynamic_cast<class_type_t*> (data_type)) {
|
||||
VLerror(li, "sorry: Class types not supported.");
|
||||
if (class_type_t*class_type = dynamic_cast<class_type_t*> (data_type)) {
|
||||
pform_set_class_type(class_type, names, net_type, attr);
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
|
|||
3
pform.h
3
pform.h
|
|
@ -311,6 +311,9 @@ extern void pform_set_struct_type(struct_type_t*struct_type, std::list<perm_stri
|
|||
|
||||
extern void pform_set_string_type(string_type_t*string_type, std::list<perm_string>*names, NetNet::Type net_type, std::list<named_pexpr_t>*attr);
|
||||
|
||||
extern void pform_set_class_type(class_type_t*class_type, std::list<perm_string>*names, NetNet::Type net_type, std::list<named_pexpr_t>*addr);
|
||||
|
||||
|
||||
/* pform_set_attrib and pform_set_type_attrib exist to support the
|
||||
$attribute syntax, which can only set string values to
|
||||
attributes. The functions keep the value strings that are
|
||||
|
|
|
|||
|
|
@ -0,0 +1,38 @@
|
|||
/*
|
||||
* Copyright (c) 2012 Picture Elements, Inc.
|
||||
* Stephen Williams (steve@icarus.com)
|
||||
*
|
||||
* This source code is free software; you can redistribute it
|
||||
* and/or modify it in source code form under the terms of the GNU
|
||||
* General Public License as published by the Free Software
|
||||
* Foundation; either version 2 of the License, or (at your option)
|
||||
* any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
*/
|
||||
|
||||
# include "pform.h"
|
||||
# include "parse_misc.h"
|
||||
# include "ivl_assert.h"
|
||||
|
||||
static void pform_set_class_type(class_type_t*class_type, perm_string name, NetNet::Type net_type, list<named_pexpr_t>*attr)
|
||||
{
|
||||
PWire*net = pform_get_make_wire_in_scope(name, net_type, NetNet::NOT_A_PORT, IVL_VT_CLASS);
|
||||
net->set_data_type(class_type);
|
||||
pform_bind_attributes(net->attributes, attr, true);
|
||||
}
|
||||
|
||||
void pform_set_class_type(class_type_t*class_type, list<perm_string>*names, NetNet::Type net_type, list<named_pexpr_t>*attr)
|
||||
{
|
||||
for (list<perm_string>::iterator cur = names->begin()
|
||||
; cur != names->end() ; ++ cur) {
|
||||
pform_set_class_type(class_type, *cur, net_type, attr);
|
||||
}
|
||||
}
|
||||
|
|
@ -26,6 +26,7 @@
|
|||
* module in question.
|
||||
*/
|
||||
# include "pform.h"
|
||||
# include "PClass.h"
|
||||
# include "PEvent.h"
|
||||
# include "PGenerate.h"
|
||||
# include "PSpec.h"
|
||||
|
|
@ -278,6 +279,11 @@ void PENew::dump(ostream&out) const
|
|||
out << "new [" << *size_ << "]";
|
||||
}
|
||||
|
||||
void PENewClass::dump(ostream&out) const
|
||||
{
|
||||
out << "class_new";
|
||||
}
|
||||
|
||||
void PENull::dump(ostream&out) const
|
||||
{
|
||||
out << "null";
|
||||
|
|
@ -1259,6 +1265,23 @@ void LexicalScope::dump_wires_(ostream&out, unsigned indent) const
|
|||
}
|
||||
}
|
||||
|
||||
void PScopeExtra::dump_classes_(ostream&out, unsigned indent) const
|
||||
{
|
||||
// Dump the task definitions.
|
||||
typedef map<perm_string,PClass*>::const_iterator class_iter_t;
|
||||
for (class_iter_t cur = classes.begin()
|
||||
; cur != classes.end() ; ++ cur ) {
|
||||
cur->second->dump(out, indent);
|
||||
}
|
||||
}
|
||||
|
||||
void PClass::dump(ostream&out, unsigned indent) const
|
||||
{
|
||||
out << setw(indent) << "" << "class " << type->name << ";" << endl;
|
||||
type->pform_dump(out, indent+2);
|
||||
out << setw(indent) << "" << "endclass" << endl;
|
||||
}
|
||||
|
||||
void Module::dump_specparams_(ostream&out, unsigned indent) const
|
||||
{
|
||||
typedef map<perm_string,param_expr_t>::const_iterator parm_iter_t;
|
||||
|
|
@ -1328,6 +1351,8 @@ void Module::dump(ostream&out) const
|
|||
|
||||
dump_enumerations_(out, 4);
|
||||
|
||||
dump_classes_(out, 4);
|
||||
|
||||
typedef map<perm_string,LineInfo*>::const_iterator genvar_iter_t;
|
||||
for (genvar_iter_t cur = genvars.begin()
|
||||
; cur != genvars.end() ; ++ cur ) {
|
||||
|
|
|
|||
|
|
@ -21,6 +21,9 @@
|
|||
# include "PClass.h"
|
||||
# include "parse_misc.h"
|
||||
|
||||
/*
|
||||
* The functions here help the parser put together class type declarations.
|
||||
*/
|
||||
static PClass*pform_cur_class = 0;
|
||||
|
||||
void pform_start_class_declaration(const struct vlltype&loc, class_type_t*type)
|
||||
|
|
@ -47,14 +50,15 @@ void pform_class_property(const struct vlltype&loc,
|
|||
return;
|
||||
}
|
||||
|
||||
// Add the non-static properties to the class type
|
||||
// object. Unwind the list of names to make a map of name to
|
||||
// type.
|
||||
for (list<decl_assignment_t*>::iterator cur = decls->begin()
|
||||
; cur != decls->end() ; ++cur) {
|
||||
|
||||
decl_assignment_t*curp = *cur;
|
||||
pform_cur_class->type->properties[curp->name] = data_type;
|
||||
}
|
||||
|
||||
VLerror(loc, "sorry: class properties not implemented yet.");
|
||||
}
|
||||
|
||||
void pform_end_class_declaration(void)
|
||||
|
|
|
|||
|
|
@ -56,7 +56,7 @@ static void pform_set_packed_struct(struct_type_t*struct_type, perm_string name,
|
|||
ivl_variable_type_t base_type = struct_type->figure_packed_base_type();
|
||||
|
||||
PWire*net = pform_get_make_wire_in_scope(name, net_type, NetNet::NOT_A_PORT, base_type);
|
||||
net->set_packed_type(struct_type);
|
||||
net->set_data_type(struct_type);
|
||||
pform_bind_attributes(net->attributes, attr, true);
|
||||
}
|
||||
|
||||
|
|
@ -89,7 +89,7 @@ static void pform_makewire(const struct vlltype&li,
|
|||
|
||||
PWire*cur = pform_get_make_wire_in_scope(name, NetNet::WIRE, ptype, base_type);
|
||||
FILE_NAME(cur, li);
|
||||
cur->set_packed_type(struct_type);
|
||||
cur->set_data_type(struct_type);
|
||||
}
|
||||
|
||||
void pform_makewire(const struct vlltype&li,
|
||||
|
|
|
|||
|
|
@ -316,6 +316,19 @@ void dll_target::expr_creal(const NetECReal*net)
|
|||
expr_->u_.real_.value = net->value().as_double();
|
||||
}
|
||||
|
||||
void dll_target::expr_null(const NetENull*net)
|
||||
{
|
||||
assert(expr_ == 0);
|
||||
expr_ = (ivl_expr_t)calloc(1, sizeof(struct ivl_expr_s));
|
||||
expr_->width_ = net->expr_width();
|
||||
expr_->signed_ = 0;
|
||||
expr_->sized_ = 1;
|
||||
expr_->type_ = IVL_EX_NULL;
|
||||
FILE_NAME(expr_, net);
|
||||
expr_->value_ = IVL_VT_CLASS;
|
||||
expr_->net_type= 0;
|
||||
}
|
||||
|
||||
void dll_target::expr_event(const NetEEvent*net)
|
||||
{
|
||||
assert(expr_ == 0);
|
||||
|
|
|
|||
1
t-dll.h
1
t-dll.h
|
|
@ -137,6 +137,7 @@ struct dll_target : public target_t, public expr_scan_t {
|
|||
void expr_concat(const NetEConcat*);
|
||||
void expr_const(const NetEConst*);
|
||||
void expr_creal(const NetECReal*);
|
||||
void expr_null(const NetENull*);
|
||||
void expr_param(const NetEConstParam*);
|
||||
void expr_rparam(const NetECRealParam*);
|
||||
void expr_event(const NetEEvent*);
|
||||
|
|
|
|||
|
|
@ -444,6 +444,12 @@ void expr_scan_t::expr_const(const NetEConst*)
|
|||
"unhandled expr_const." << endl;
|
||||
}
|
||||
|
||||
void expr_scan_t::expr_null(const NetENull*)
|
||||
{
|
||||
cerr << "expr_scan_t (" << typeid(*this).name() << "): "
|
||||
"unhandled expr_null." << endl;
|
||||
}
|
||||
|
||||
void expr_scan_t::expr_param(const NetEConstParam*that)
|
||||
{
|
||||
expr_const(that);
|
||||
|
|
|
|||
1
target.h
1
target.h
|
|
@ -150,6 +150,7 @@ struct expr_scan_t {
|
|||
virtual ~expr_scan_t();
|
||||
virtual void expr_access_func(const NetEAccess*);
|
||||
virtual void expr_const(const NetEConst*);
|
||||
virtual void expr_null(const NetENull*);
|
||||
virtual void expr_param(const NetEConstParam*);
|
||||
virtual void expr_rparam(const NetECRealParam*);
|
||||
virtual void expr_creal(const NetECReal*);
|
||||
|
|
|
|||
|
|
@ -165,6 +165,16 @@ static void show_memory_expression(ivl_expr_t net, unsigned ind)
|
|||
width);
|
||||
}
|
||||
|
||||
static void show_null_expression(ivl_expr_t net, unsigned ind)
|
||||
{
|
||||
fprintf(out, "%*s<null>\n", ind, "");
|
||||
if (ivl_expr_value(net) != IVL_VT_CLASS) {
|
||||
fprintf(out, "%sERROR: null expression must be IVL_VT_CLASS, got %s.\n",
|
||||
ind+3, "", vt_type_string(net));
|
||||
stub_errors += 1;
|
||||
}
|
||||
}
|
||||
|
||||
static void show_select_expression(ivl_expr_t net, unsigned ind)
|
||||
{
|
||||
unsigned width = ivl_expr_width(net);
|
||||
|
|
@ -351,6 +361,10 @@ void show_expression(ivl_expr_t net, unsigned ind)
|
|||
show_memory_expression(net, ind);
|
||||
break;
|
||||
|
||||
case IVL_EX_NULL:
|
||||
show_null_expression(net, ind);
|
||||
break;
|
||||
|
||||
case IVL_EX_NUMBER: {
|
||||
const char*bits = ivl_expr_bits(net);
|
||||
|
||||
|
|
|
|||
|
|
@ -172,6 +172,9 @@ const char*data_type_string(ivl_variable_type_t vtype)
|
|||
case IVL_VT_DARRAY:
|
||||
vt = "darray";
|
||||
break;
|
||||
case IVL_VT_CLASS:
|
||||
vt = "class";
|
||||
break;
|
||||
}
|
||||
|
||||
return vt;
|
||||
|
|
|
|||
|
|
@ -56,6 +56,9 @@ static void show_net_type(ivl_type_t net_type)
|
|||
case IVL_VT_DARRAY:
|
||||
show_net_type_darray(net_type);
|
||||
break;
|
||||
case IVL_VT_CLASS:
|
||||
fprintf(out, "class");
|
||||
break;
|
||||
case IVL_VT_VOID:
|
||||
fprintf(out, "void");
|
||||
break;
|
||||
|
|
@ -114,6 +117,9 @@ void show_type_of_signal(ivl_signal_t net)
|
|||
case IVL_VT_VOID:
|
||||
fprintf(out, "void");
|
||||
break;
|
||||
case IVL_VT_CLASS:
|
||||
fprintf(out, "class");
|
||||
break;
|
||||
}
|
||||
|
||||
for (dim = 0 ; dim < ivl_signal_packed_dimensions(net) ; dim += 1) {
|
||||
|
|
|
|||
Loading…
Reference in New Issue