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:
Stephen Williams 2012-11-11 17:42:31 -08:00
parent 55bebc8c39
commit 77d24cd095
35 changed files with 450 additions and 34 deletions

View File

@ -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 \

View File

@ -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;
};

View File

@ -389,6 +389,14 @@ PENew::~PENew()
delete size_;
}
PENewClass::PENewClass(void)
{
}
PENewClass::~PENewClass()
{
}
PENumber::PENumber(verinum*vp)
: value_(vp)
{

24
PExpr.h
View File

@ -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 {

View File

@ -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

View File

@ -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;

View File

@ -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_;

View File

@ -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_) << ">";

View File

@ -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);

View File

@ -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;

View File

@ -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.

View File

@ -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;

View File

@ -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());

View File

@ -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);

View File

@ -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;

View File

@ -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)

View File

@ -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;

View File

@ -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.

34
netclass.cc Normal file
View File

@ -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;
}

41
netclass.h Normal file
View File

@ -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

View File

@ -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
View File

@ -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;
}
;

View File

@ -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;
}

View File

@ -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

38
pform_class_type.cc Normal file
View File

@ -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);
}
}

View File

@ -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 ) {

View File

@ -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)

View File

@ -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,

View File

@ -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);

View File

@ -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*);

View File

@ -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);

View File

@ -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*);

View File

@ -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);

View File

@ -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;

View File

@ -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) {