Permalink
Browse files

Parse support for dynamic arrays.

This includes limited support for dynamic arrays down to the code
generator, and some stubs in the vvp code generator and vvp run time.
  • Loading branch information...
steveicarus committed Jul 14, 2012
1 parent a337a93 commit 14f229de308148bffef6b3770bfe26221ac8a10a
Showing with 902 additions and 141 deletions.
  1. +1 −1 Makefile.in
  2. +10 −0 PExpr.cc
  3. +19 −1 PExpr.h
  4. +1 −0 PWire.h
  5. +21 −3 design_dump.cc
  6. +120 −3 elab_expr.cc
  7. +2 −2 elab_lval.cc
  8. +51 −17 elab_sig.cc
  9. +1 −0 ivl_target.h
  10. +32 −0 netdarray.cc
  11. +40 −0 netdarray.h
  12. +2 −1 netenum.h
  13. +60 −24 netlist.cc
  14. +7 −6 netlist.h
  15. +17 −15 netmisc.cc
  16. +1 −1 netstruct.h
  17. +13 −13 nettypes.cc
  18. +32 −9 nettypes.h
  19. +5 −5 parse.y
  20. +5 −0 pform_dump.cc
  21. +1 −0 sv_vpi_user.h
  22. +6 −6 t-dll-api.cc
  23. +9 −22 t-dll.cc
  24. +1 −2 t-dll.h
  25. +1 −1 tgt-stub/expression.c
  26. +21 −6 tgt-stub/stub.c
  27. +5 −0 tgt-vvp/vvp_scope.c
  28. +2 −1 vpi/Makefile.in
  29. +91 −0 vpi/sys_darray.c
  30. +2 −0 vpi/sys_table.c
  31. +6 −0 vpi_user.h
  32. +1 −1 vvp/Makefile.in
  33. +1 −0 vvp/compile.h
  34. +1 −0 vvp/lexor.lex
  35. +4 −1 vvp/parse.y
  36. +87 −0 vvp/vpi_darray.cc
  37. +2 −0 vvp/vpi_priv.h
  38. +7 −0 vvp/vvp_net.cc
  39. +23 −0 vvp/vvp_net.h
  40. +74 −0 vvp/vvp_net_sig.cc
  41. +57 −0 vvp/vvp_net_sig.h
  42. +24 −0 vvp/vvp_object.h
  43. +36 −0 vvp/words.cc
View
@@ -108,7 +108,7 @@ 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 \
+ net_design.o netdarray.o \
netenum.o netstruct.o net_event.o net_expr.o net_func.o net_func_eval.o \
net_link.o net_modulo.o \
net_nex_input.o net_nex_output.o net_proc.o net_scope.o net_tran.o \
View
@@ -371,6 +371,16 @@ bool PEIdent::has_aa_term(Design*des, NetScope*scope) const
return false;
}
+PENew::PENew(PExpr*size_expr)
+: size_(size_expr)
+{
+}
+
+PENew::~PENew()
+{
+ delete size_;
+}
+
PENumber::PENumber(verinum*vp)
: value_(vp)
{
View
20 PExpr.h
@@ -439,6 +439,18 @@ class PEIdent : public PExpr {
long&midx, long&lidx) const;
};
+class PENew : public PExpr {
+
+ public:
+ explicit PENew (PExpr*s);
+ ~PENew();
+
+ virtual void dump(ostream&) const;
+
+ private:
+ PExpr*size_;
+};
+
class PENumber : public PExpr {
public:
@@ -720,9 +732,13 @@ class PECallFunction : public PExpr {
NetExpr* cast_to_width_(NetExpr*expr, unsigned wid) const;
+ NetExpr*elaborate_expr_method_(Design*des, NetScope*scope,
+ unsigned expr_wid) const;
+#if 0
+ NetExpr*elaborate_expr_string_method_(Design*des, NetScope*scope) const;
NetExpr*elaborate_expr_enum_method_(Design*des, NetScope*scope,
unsigned expr_wid) const;
- NetExpr*elaborate_expr_string_method_(Design*des, NetScope*scope) const;
+#endif
NetExpr* elaborate_sfunc_(Design*des, NetScope*scope,
unsigned expr_wid,
@@ -731,6 +747,8 @@ class PECallFunction : public PExpr {
unsigned expr_wid) const;
unsigned test_width_sfunc_(Design*des, NetScope*scope,
width_mode_t&mode);
+ unsigned test_width_method_(Design*des, NetScope*scope,
+ width_mode_t&mode);
};
/*
View
@@ -33,6 +33,7 @@ class ostream;
class PExpr;
class Design;
+class netdarray_t;
/*
* The different type of PWire::set_range() calls.
View
@@ -28,6 +28,7 @@
# include "netlist.h"
# include "compiler.h"
# include "discipline.h"
+# include "netdarray.h"
# include "ivl_assert.h"
# include "PExpr.h"
@@ -104,6 +105,9 @@ ostream& operator << (ostream&o, ivl_variable_type_t val)
case IVL_VT_STRING:
o << "string";
break;
+ case IVL_VT_DARRAY:
+ o << "darray";
+ break;
}
return o;
}
@@ -193,11 +197,21 @@ void NetDelaySrc::dump(ostream&o, unsigned ind) const
dump_node_pins(o, ind+4);
}
+static inline ostream&operator<<(ostream&out, const netrange_t&that)
+{
+ if (that.defined())
+ out << "[" << that.get_msb() << ":" << that.get_lsb() << "]";
+ else
+ out << "[]";
+
+ return out;
+}
+
ostream&operator<<(ostream&out, const list<netrange_t>&rlist)
{
for (list<netrange_t>::const_iterator cur = rlist.begin()
; cur != rlist.end() ; ++cur) {
- out << "[" << cur->msb << ":" << cur->lsb << "]";
+ out << *cur;
}
return out;
}
@@ -206,7 +220,7 @@ ostream&operator<<(ostream&out, const vector<netrange_t>&rlist)
{
for (vector<netrange_t>::const_iterator cur = rlist.begin()
; cur != rlist.end() ; ++cur) {
- out << "[" << cur->msb << ":" << cur->lsb << "]";
+ out << *cur;
}
return out;
}
@@ -244,7 +258,11 @@ void NetNet::dump_net(ostream&o, unsigned ind) const
if (ivl_discipline_t dis = get_discipline())
o << " discipline=" << dis->name();
- o << " packed dims: " << packed_dims_;
+ if (netdarray_t*darray = darray_type())
+ o << " dynamic array of " << darray->data_type();
+
+ if (!packed_dims_.empty())
+ o << " packed dims: " << packed_dims_;
o << " (eref=" << peek_eref() << ", lref=" << peek_lref() << ")";
if (scope())
View
@@ -96,6 +96,7 @@ NetExpr* elaborate_rval_expr(Design*des, NetScope*scope,
break;
case IVL_VT_VOID:
case IVL_VT_NO_TYPE:
+ case IVL_VT_DARRAY:
ivl_assert(*expr, 0);
break;
}
@@ -1021,6 +1022,15 @@ unsigned PECallFunction::test_width(Design*des, NetScope*scope,
return expr_width_;
}
+ if (test_width_method_(des, scope, mode)) {
+ if (debug_elaborate)
+ cerr << get_fileline() << ": debug: test_width "
+ << "of method returns width " << expr_width_
+ << ", type=" << expr_type_
+ << "." << endl;
+ return expr_width_;
+ }
+
if (debug_elaborate)
cerr << get_fileline() << ": debug: test_width "
<< "cannot find definition of " << path_
@@ -1050,6 +1060,46 @@ unsigned PECallFunction::test_width(Design*des, NetScope*scope,
return 0;
}
+unsigned PECallFunction::test_width_method_(Design*des, NetScope*scope,
+ width_mode_t&mode)
+{
+ if (!gn_system_verilog())
+ return 0;
+
+ // This is only useful if the path is at least 2 elements. For
+ // example, foo.bar() is a method, bar() is not.
+ if (path_.size() < 2)
+ return 0;
+
+ pform_name_t use_path = path_;
+ perm_string method_name = peek_tail_name(use_path);
+ use_path.pop_back();
+
+ NetNet *net;
+ const NetExpr *par;
+ NetEvent *eve;
+ const NetExpr *ex1, *ex2;
+
+ symbol_search(this, des, scope, use_path,
+ net, par, eve, ex1, ex2);
+
+ if (net == 0)
+ return 0;
+
+ netdarray_t*darray = net->darray_type();
+
+ // function int size()
+ if (darray && method_name == "size") {
+ expr_type_ = IVL_VT_BOOL;
+ expr_width_ = 32;
+ min_width_ = expr_width_;
+ signed_flag_= true;
+ return expr_width_;
+ }
+
+ return 0;
+}
+
NetExpr*PECallFunction::cast_to_width_(NetExpr*expr, unsigned wid) const
{
/* If the expression is a const, then replace it with a new
@@ -1582,6 +1632,13 @@ NetExpr* PECallFunction::elaborate_expr(Design*des, NetScope*scope,
return elaborate_access_func_(des, scope, access_nature,
expr_wid);
+ // Maybe this is a method attached to a signal? If this
+ // is SystemVerilog then try that possibility.
+ if (gn_system_verilog()) {
+ NetExpr*tmp = elaborate_expr_method_(des, scope, expr_wid);
+ if (tmp) return tmp;
+ }
+#if 0
// Maybe this is a method attached to an enumeration name? If
// this is system verilog, then test to see if the name is
// really a method attached to an object.
@@ -1597,7 +1654,7 @@ NetExpr* PECallFunction::elaborate_expr(Design*des, NetScope*scope,
NetExpr*tmp = elaborate_expr_string_method_(des, scope);
if (tmp) return tmp;
}
-
+#endif
// Nothing was found so report this as an error.
cerr << get_fileline() << ": error: No function named `" << path_
<< "' found in this context (" << scope_path(scope) << ")."
@@ -1736,6 +1793,64 @@ NetExpr* PECallFunction::elaborate_expr(Design*des, NetScope*scope,
return 0;
}
+NetExpr* PECallFunction::elaborate_expr_method_(Design*des, NetScope*scope,
+ unsigned expr_wid) const
+{
+ pform_name_t use_path = path_;
+ perm_string method_name = peek_tail_name(use_path);
+ use_path.pop_back();
+
+ NetNet *net;
+ const NetExpr *par;
+ NetEvent *eve;
+ const NetExpr *ex1, *ex2;
+
+ symbol_search(this, des, scope, use_path,
+ net, par, eve, ex1, ex2);
+
+ if (net == 0)
+ return 0;
+
+ if (net->data_type() == IVL_VT_STRING) {
+
+ if (method_name == "len") {
+ NetESFunc*sys_expr = new NetESFunc("$ivl_string_method$len",
+ IVL_VT_BOOL, 32, 1);
+ sys_expr->parm(0, new NetESignal(net));
+ return sys_expr;
+ }
+ }
+
+ if (netenum_t*netenum = net->enumeration()) {
+ // We may need the net expression for the
+ // enumeration variable so get it.
+ NetESignal*expr = new NetESignal(net);
+ expr->set_line(*this);
+ // This expression cannot be a select!
+ assert(use_path.back().index.empty());
+
+ PExpr*tmp = parms_.size() ? parms_[0] : 0;
+ return check_for_enum_methods(this, des, scope,
+ netenum, use_path,
+ method_name, expr,
+ expr_wid, tmp,
+ parms_.size());
+ }
+
+ if (net->darray_type()) {
+
+ if (method_name == "size") {
+ NetESFunc*sys_expr = new NetESFunc("$ivl_darray_method$size",
+ IVL_VT_BOOL, 32, 1);
+ sys_expr->parm(0, new NetESignal(net));
+ sys_expr->set_line(*this);
+ return sys_expr;
+ }
+ }
+
+ return 0;
+}
+#if 0
NetExpr* PECallFunction::elaborate_expr_enum_method_(Design*des, NetScope*scope,
unsigned expr_wid) const
{
@@ -1775,7 +1890,8 @@ NetExpr* PECallFunction::elaborate_expr_enum_method_(Design*des, NetScope*scope,
return 0;
}
-
+#endif
+#if 0
NetExpr* PECallFunction::elaborate_expr_string_method_(Design*des, NetScope*scope) const
{
pform_name_t use_path = path_;
@@ -1808,6 +1924,7 @@ NetExpr* PECallFunction::elaborate_expr_string_method_(Design*des, NetScope*scop
return 0;
}
+#endif
unsigned PECastSize::test_width(Design*des, NetScope*scope, width_mode_t&)
{
@@ -3455,7 +3572,7 @@ NetExpr* PEIdent::elaborate_expr_net_idx_up_(Design*des, NetScope*scope,
// We want the last range, which is where we work.
const netrange_t&rng = packed.back();
- if (rng.msb < rng.lsb) {
+ if (rng.get_msb() < rng.get_lsb()) {
offset = -wid + 1;
}
View
@@ -574,9 +574,9 @@ bool PEIdent::elaborate_lval_net_idx_(Design*des,
// We want the last range, which is where we work.
const netrange_t&rng = packed.back();
- if (((rng.msb < rng.lsb) &&
+ if (((rng.get_msb() < rng.get_lsb()) &&
use_sel == index_component_t::SEL_IDX_UP) ||
- ((rng.msb > rng.lsb) &&
+ ((rng.get_msb() > rng.get_lsb()) &&
use_sel == index_component_t::SEL_IDX_DO)) {
offset = -wid + 1;
}
Oops, something went wrong.

0 comments on commit 14f229d

Please sign in to comment.