Skip to content
Browse files

Describe enum type to code generators

This gets the enumeration type through to the ivl_target API so
that code generators can do something with it. Generate stub
output with tgt-stub, and generate the proper vvp run time to
make simple enumerations work from end to end.
  • Loading branch information...
1 parent 0c72dfe commit de215f1f8dc152e1a9ea7b66977b648a49905165 @steveicarus steveicarus committed Nov 20, 2010
Showing with 377 additions and 25 deletions.
  1. +6 −1 compiler.h
  2. +5 −0 design_dump.cc
  3. +6 −0 dup_expr.cc
  4. +6 −4 elab_expr.cc
  5. +5 −3 elab_scope.cc
  6. +9 −0 emit.cc
  7. +20 −0 ivl_target.h
  8. +3 −0 main.cc
  9. +15 −0 net_expr.cc
  10. +5 −0 net_nex_input.cc
  11. +48 −5 netenum.cc
  12. +13 −4 netenum.h
  13. +23 −0 netlist.h
  14. +40 −0 t-dll-api.cc
  15. +11 −0 t-dll-expr.cc
  16. +12 −0 t-dll.cc
  17. +8 −0 t-dll.h
  18. +13 −0 target.cc
  19. +4 −0 target.h
  20. +1 −1 tgt-stub/Makefile.in
  21. +42 −0 tgt-stub/enumerate.c
  22. +9 −0 tgt-stub/expression.c
  23. +2 −0 tgt-stub/priv.h
  24. +3 −0 tgt-stub/stub.c
  25. +1 −1 tgt-vvp/Makefile.in
  26. +49 −0 tgt-vvp/draw_enum.c
  27. +5 −1 tgt-vvp/draw_vpi.c
  28. +5 −0 tgt-vvp/vvp_priv.h
  29. +8 −5 tgt-vvp/vvp_scope.c
View
7 compiler.h
@@ -200,7 +200,12 @@ extern map<perm_string,bool> library_file_map;
* much sense to use a StringHeapLex to hold them.
*/
extern StringHeapLex lex_strings;
-extern StringHeap misc_strings;
+
+/*
+ * The ivl_target.h API in a variety of places keeps strings of
+ * bits. Manage these as perm_string in a StringHeap.
+ */
+extern StringHeapLex bits_strings;
/*
* The filename_strings are perm_strings for file names. They are put
View
5 design_dump.cc
@@ -1452,6 +1452,11 @@ void NetEEvent::dump(ostream&o) const
o << "<event=" << event_->name() << ">";
}
+void NetENetenum::dump(ostream&o) const
+{
+ o << "<netenum=" << netenum_ << ">";
+}
+
void NetEScope::dump(ostream&o) const
{
o << "<scope=" << scope_path(scope_) << ">";
View
6 dup_expr.cc
@@ -79,6 +79,12 @@ NetEEvent* NetEEvent::dup_expr() const
return 0;
}
+NetENetenum* NetENetenum::dup_expr() const
+{
+ assert(0);
+ return 0;
+}
+
NetEScope* NetEScope::dup_expr() const
{
assert(0);
View
10 elab_expr.cc
@@ -2262,11 +2262,13 @@ NetExpr* PEIdent::elaborate_expr(Design*des, NetScope*scope,
sys_expr = new NetESFunc("$ivl_method$name", IVL_VT_STRING,0, 1);
sys_expr->parm(0, expr);
} else if (method_name == "next") {
- sys_expr = new NetESFunc("$ivl_method$next", netenum, 1);
- sys_expr->parm(0, expr);
+ sys_expr = new NetESFunc("$ivl_method$next", netenum, 2);
+ sys_expr->parm(0, new NetENetenum(netenum));
+ sys_expr->parm(1, expr);
} else if (method_name == "prev") {
- sys_expr = new NetESFunc("$ivl_method$prev", netenum, 1);
- sys_expr->parm(0, expr);
+ sys_expr = new NetESFunc("$ivl_method$prev", netenum, 2);
+ sys_expr->parm(0, new NetENetenum(netenum));
+ sys_expr->parm(1, expr);
} else {
cerr << get_fileline() << ": error: "
<< "Unknown method name `" << method_name << "'"
View
8 elab_scope.cc
@@ -222,14 +222,16 @@ static void elaborate_scope_enumeration(Design*des, NetScope*scope,
rc_flag = eval_as_long(lsb, lsb_ex);
assert(rc_flag);
- netenum_t*use_enum = new netenum_t(enum_type->base_type, enum_type->signed_flag, msb, lsb);
+ netenum_t*use_enum = new netenum_t(enum_type->base_type, enum_type->signed_flag,
+ msb, lsb, enum_type->names->size());
scope->add_enumeration_set(use_enum);
verinum cur_value (0);
verinum one_value (1);
+ size_t name_idx = 0;
for (list<named_pexpr_t>::const_iterator cur = enum_type->names->begin()
- ; cur != enum_type->names->end() ; ++ cur) {
+ ; cur != enum_type->names->end() ; ++ cur, name_idx += 1) {
if (cur->parm) {
@@ -262,7 +264,7 @@ static void elaborate_scope_enumeration(Design*des, NetScope*scope,
verinum tmp_val (cur_value, use_enum->base_width());
tmp_val.has_sign(enum_type->signed_flag);
- rc_flag = use_enum->insert_name(cur->name, tmp_val);
+ rc_flag = use_enum->insert_name(name_idx, cur->name, tmp_val);
rc_flag &= scope->add_enumeration_name(use_enum, cur->name);
if (! rc_flag) {
cerr << "<>:0: error: Duplicate enumeration name " << cur->name << endl;
View
9 emit.cc
@@ -385,6 +385,10 @@ void NetScope::emit_scope(struct target_t*tgt) const
for (NetEvent*cur = events_ ; cur ; cur = cur->snext_)
tgt->event(cur);
+ for (list<netenum_t*>::const_iterator cur = enum_sets_.begin()
+ ; cur != enum_sets_.end() ; ++cur)
+ tgt->enumeration(this, *cur);
+
for (map<hname_t,NetScope*>::const_iterator cur = children_.begin()
; cur != children_.end() ; cur ++)
cur->second->emit_scope(tgt);
@@ -547,6 +551,11 @@ void NetEEvent::expr_scan(struct expr_scan_t*tgt) const
tgt->expr_event(this);
}
+void NetENetenum::expr_scan(struct expr_scan_t*tgt) const
+{
+ tgt->expr_netenum(this);
+}
+
void NetEScope::expr_scan(struct expr_scan_t*tgt) const
{
tgt->expr_scope(this);
View
20 ivl_target.h
@@ -159,6 +159,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 struct ivl_discipline_s*ivl_discipline_t;
+typedef struct 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;
@@ -212,6 +213,7 @@ typedef enum ivl_expr_type_e {
IVL_EX_BINARY = 2,
IVL_EX_CONCAT = 3,
IVL_EX_DELAY = 20,
+ IVL_EX_ENUMTYPE = 21,
IVL_EX_EVENT = 17,
IVL_EX_MEMORY = 4,
IVL_EX_NUMBER = 5,
@@ -618,6 +620,16 @@ extern ivl_nature_t ivl_discipline_flow(ivl_discipline_t net);
extern const char* ivl_nature_name(ivl_nature_t net);
+/* ENUMERATIONS
+ *
+ * Enumerations are a collections of symbolic names and vector
+ * values. The enumeration has a base type, and a list of names and
+ * values.
+ */
+extern unsigned ivl_enum_names(ivl_enumtype_t net);
+extern const char*ivl_enum_name(ivl_enumtype_t net, unsigned idx);
+extern const char*ivl_enum_bits(ivl_enumtype_t net, unsigned idx);
+
/* EVENTS
*
* Events are a unification of named events and implicit events
@@ -774,6 +786,8 @@ extern ivl_scope_t ivl_expr_def(ivl_expr_t net);
extern uint64_t ivl_expr_delay_val(ivl_expr_t net);
/* IVL_EX_REALNUM */
extern double ivl_expr_dvalue(ivl_expr_t net);
+ /* IVL_EX_ENUMTYPE */
+extern ivl_enumtype_t ivl_expr_enumtype(ivl_expr_t net);
/* IVL_EX_SIGNAL, IVL_EX_SFUNC, IVL_EX_VARIABLE */
extern const char* ivl_expr_name(ivl_expr_t net);
/* IVL_EX_BACCESS */
@@ -1550,6 +1564,10 @@ extern unsigned ivl_parameter_lineno(ivl_parameter_t net);
* ivl_scope_def_lineno
* Returns the file and line where this scope is defined.
*
+ * ivl_scope_enumerate
+ * ivl_scope_enumerates
+ * Scopes have 0 or more enumeration types in them.
+ *
* ivl_scope_event
* ivl_scope_events
* Scopes have 0 or more event objects in them.
@@ -1637,6 +1655,8 @@ extern ivl_statement_t ivl_scope_def(ivl_scope_t net);
extern const char* ivl_scope_def_file(ivl_scope_t net);
extern unsigned ivl_scope_def_lineno(ivl_scope_t net);
+extern unsigned ivl_scope_enumerates(ivl_scope_t net);
+extern ivl_enumtype_t ivl_scope_enumerate(ivl_scope_t net, unsigned idx);
extern unsigned ivl_scope_events(ivl_scope_t net);
extern ivl_event_t ivl_scope_event(ivl_scope_t net, unsigned idx);
extern const char* ivl_scope_file(ivl_scope_t net);
View
3 main.cc
@@ -176,6 +176,8 @@ StringHeapLex lex_strings;
StringHeapLex filename_strings;
+StringHeapLex bits_strings;
+
/*
* In library searches, Windows file names are never case sensitive.
*/
@@ -748,6 +750,7 @@ static void EOC_cleanup(void)
flags.clear();
lex_strings.cleanup();
+ bits_strings.cleanup();
filename_strings.cleanup();
}
View
15 net_expr.cc
@@ -506,6 +506,21 @@ const NetScope* NetECRealParam::scope() const
}
+NetENetenum::NetENetenum(netenum_t*s)
+: netenum_(s)
+{
+}
+
+NetENetenum::~NetENetenum()
+{
+}
+
+netenum_t* NetENetenum::netenum() const
+{
+ return netenum_;
+}
+
+
NetEParam::NetEParam()
: des_(0), scope_(0)
{
View
5 net_nex_input.cc
@@ -100,6 +100,11 @@ NexusSet* NetEEvent::nex_input(bool rem_out)
return new NexusSet;
}
+NexusSet* NetENetenum::nex_input(bool rem_out)
+{
+ return new NexusSet;
+}
+
NexusSet* NetEScope::nex_input(bool rem_out)
{
return new NexusSet;
View
53 netenum.cc
@@ -18,26 +18,33 @@
*/
# include "netenum.h"
+# include "compiler.h"
# include <cassert>
-netenum_t::netenum_t(ivl_variable_type_t btype, bool signed_flag, long msb, long lsb)
-: base_type_(btype), signed_flag_(signed_flag), msb_(msb), lsb_(lsb)
+netenum_t::netenum_t(ivl_variable_type_t btype, bool signed_flag,
+ long msb, long lsb, size_t name_count)
+: base_type_(btype), signed_flag_(signed_flag), msb_(msb), lsb_(lsb),
+ names_(name_count), bits_(name_count)
{
}
netenum_t::~netenum_t()
{
}
-bool netenum_t::insert_name(perm_string name, const verinum&val)
+bool netenum_t::insert_name(size_t name_idx, perm_string name, const verinum&val)
{
std::pair<std::map<perm_string,verinum>::iterator, bool> res;
assert(val.has_len() && val.len() == (msb_-lsb_+1));
+ // Insert a map of the name to the value. This also gets a
+ // flag that returns true if the name is unique, or false
+ // otherwise.
res = names_map_.insert( make_pair(name,val) );
- // Only add the name to the list if it is not there already.
- if (res.second) names_.push_back(name);
+
+ assert(name_idx < names_.size() && names_[name_idx] == 0);
+ names_[name_idx] = name;
return res.second;
}
@@ -61,3 +68,39 @@ netenum_t::iterator netenum_t::last_name() const
{
return names_map_.find(names_.back());
}
+
+perm_string netenum_t::name_at(size_t idx) const
+{
+ assert(idx < names_.size());
+ return names_[idx];
+}
+
+perm_string netenum_t::bits_at(size_t idx)
+{
+ 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];
+}
View
17 netenum.h
@@ -22,14 +22,16 @@
# include "ivl_target.h"
# include "verinum.h"
# include "StringHeap.h"
-# include <list>
+# include <vector>
# include <map>
+class NetScope;
+
class netenum_t {
public:
explicit netenum_t(ivl_variable_type_t base_type, bool signed_flag,
- long msb, long lsb);
+ long msb, long lsb, size_t name_count);
~netenum_t();
ivl_variable_type_t base_type() const;
@@ -38,7 +40,10 @@ class netenum_t {
// The size() is the number of enumeration literals.
size_t size() const;
- bool insert_name(perm_string name, const verinum&val);
+ // Insert the name (and value) at the specific place in the
+ // enumeration. This must be done exactly once for each
+ // enumeration value.
+ bool insert_name(size_t idx, perm_string name, const verinum&val);
typedef std::map<perm_string,verinum>::const_iterator iterator;
iterator find_name(perm_string name) const;
@@ -48,13 +53,17 @@ class netenum_t {
iterator first_name() const;
iterator last_name() const;
+ perm_string name_at(size_t idx) const;
+ perm_string bits_at(size_t idx);
+
private:
ivl_variable_type_t base_type_;
bool signed_flag_;
long msb_, lsb_;
std::map<perm_string,verinum> names_map_;
- std::list<perm_string> names_;
+ std::vector<perm_string> names_;
+ std::vector<perm_string> bits_;
};
inline ivl_variable_type_t netenum_t::base_type() const
View
23 netlist.h
@@ -3717,6 +3717,29 @@ class NetEEvent : public NetExpr {
/*
* This class is a special (and magical) expression node type that
+ * represents enumeration types. These can only be found as parameters
+ * to NetSTask objects.
+ */
+class NetENetenum : public NetExpr {
+
+ public:
+ NetENetenum(netenum_t*);
+ ~NetENetenum();
+
+ netenum_t* netenum() const;
+
+ virtual void expr_scan(struct expr_scan_t*) const;
+ virtual NetENetenum* dup_expr() const;
+ virtual NexusSet* nex_input(bool rem_out = true);
+
+ virtual void dump(ostream&os) const;
+
+ private:
+ netenum_t*netenum_;
+};
+
+/*
+ * This class is a special (and magical) expression node type that
* represents scope names. These can only be found as parameters to
* NetSTask objects.
*/
View
40 t-dll-api.cc
@@ -21,6 +21,7 @@
# include "StringHeap.h"
# include "t-dll.h"
# include "discipline.h"
+# include "netenum.h"
# include "ivl_alloc.h"
# include <cstdlib>
# include <cstdio>
@@ -210,6 +211,26 @@ extern "C" unsigned ivl_const_width(ivl_net_const_t net)
return net->width_;
}
+extern "C" unsigned ivl_enum_names(ivl_enumtype_t net)
+{
+ assert(net);
+ return net->size();
+}
+
+extern "C" const char* ivl_enum_name(ivl_enumtype_t net, unsigned idx)
+{
+ assert(net);
+ assert(idx < net->size());
+ return net->name_at(idx);
+}
+
+extern "C" const char* ivl_enum_bits(ivl_enumtype_t net, unsigned idx)
+{
+ assert(net);
+ assert(idx < net->size());
+ return net->bits_at(idx);
+}
+
extern "C" const char* ivl_event_name(ivl_event_t net)
{
static char*name_buffer = 0;
@@ -323,6 +344,12 @@ extern "C" double ivl_expr_dvalue(ivl_expr_t net)
return net->u_.real_.value;
}
+extern "C" ivl_enumtype_t ivl_expr_enumtype(ivl_expr_t net)
+{
+ assert(net->type_ == IVL_EX_ENUMTYPE);
+ return net->u_.enumtype_.type;
+}
+
extern "C" const char* ivl_expr_name(ivl_expr_t net)
{
switch (net->type_) {
@@ -1671,6 +1698,19 @@ extern "C" unsigned ivl_scope_def_lineno(ivl_scope_t net)
return net->def_lineno;
}
+extern "C" unsigned ivl_scope_enumerates(ivl_scope_t net)
+{
+ assert(net);
+ return net->enumerations_.size();
+}
+
+extern "C" ivl_enumtype_t ivl_scope_enumerate(ivl_scope_t net, unsigned idx)
+{
+ assert(net);
+ assert(idx < net->enumerations_.size());
+ return net->enumerations_[idx];
+}
+
extern "C" unsigned ivl_scope_events(ivl_scope_t net)
{
assert(net);
View
11 t-dll-expr.cc
@@ -340,6 +340,17 @@ void dll_target::expr_scope(const NetEScope*net)
expr_->u_.scope_.scope = lookup_scope_(net->scope());
}
+void dll_target::expr_netenum(const NetENetenum*net)
+{
+ assert(expr_ == 0);
+
+ expr_ = (ivl_expr_t)calloc(1, sizeof(struct ivl_expr_s));
+
+ expr_->type_ = IVL_EX_ENUMTYPE;
+ expr_->value_= IVL_VT_VOID;
+ expr_->u_.enumtype_.type = net->netenum();
+}
+
void dll_target::expr_select(const NetESelect*net)
{
assert(expr_ == 0);
View
12 t-dll.cc
@@ -396,6 +396,11 @@ void scope_add_logic(ivl_scope_t scope, ivl_net_logic_t net)
}
+static void scope_add_enumeration(ivl_scope_t scope, ivl_enumtype_t net)
+{
+ scope->enumerations_.push_back(net);
+}
+
void scope_add_event(ivl_scope_t scope, ivl_event_t net)
{
if (scope->nevent_ == 0) {
@@ -786,6 +791,13 @@ bool dll_target::bufz(const NetBUFZ*net)
return true;
}
+bool dll_target::enumeration(const NetScope*in_scope, netenum_t*net)
+{
+ ivl_scope_t scop = find_scope(des_, in_scope);
+ scope_add_enumeration(scop, net);
+ return true;
+}
+
void dll_target::event(const NetEvent*net)
{
struct ivl_event_s *obj = new struct ivl_event_s;
View
8 t-dll.h
@@ -58,6 +58,7 @@ struct dll_target : public target_t, public expr_scan_t {
bool bufz(const NetBUFZ*);
bool branch(const NetBranch*);
+ bool enumeration(const NetScope*, netenum_t*);
void event(const NetEvent*);
void logic(const NetLogic*);
bool tran(const NetTran*);
@@ -139,6 +140,7 @@ struct dll_target : public target_t, public expr_scan_t {
void expr_rparam(const NetECRealParam*);
void expr_event(const NetEEvent*);
void expr_scope(const NetEScope*);
+ void expr_netenum(const NetENetenum*);
void expr_select(const NetESelect*);
void expr_sfunc(const NetESFunc*);
void expr_ternary(const NetETernary*);
@@ -252,6 +254,10 @@ struct ivl_expr_s {
} scope_;
struct {
+ ivl_enumtype_t type;
+ } enumtype_;
+
+ struct {
ivl_signal_t sig;
ivl_expr_t word;
} signal_;
@@ -599,6 +605,8 @@ struct ivl_scope_s {
unsigned def_lineno;
ivl_scope_type_t type_;
+ std::vector<ivl_enumtype_t> enumerations_;
+
unsigned nsigs_;
ivl_signal_t*sigs_;
View
13 target.cc
@@ -45,6 +45,13 @@ void target_t::event(const NetEvent*ev)
<< "): Unhandled event <" << ev->name() << ">." << endl;
}
+bool target_t::enumeration(const NetScope*, netenum_t*obj)
+{
+ cerr << "<>:0" << ": error: target (" << typeid(*this).name()
+ << "): Unhandled enumeration <" << obj << ">." << endl;
+ return false;
+}
+
bool target_t::signal_paths(const NetNet*)
{
return true;
@@ -460,6 +467,12 @@ void expr_scan_t::expr_event(const NetEEvent*)
"unhandled expr_event." << endl;
}
+void expr_scan_t::expr_netenum(const NetENetenum*)
+{
+ cerr << "expr_scan_t (" << typeid(*this).name() << "): "
+ "unhandled expr_netenum." << endl;
+}
+
void expr_scan_t::expr_scope(const NetEScope*)
{
cerr << "expr_scan_t (" << typeid(*this).name() << "): "
View
4 target.h
@@ -59,6 +59,9 @@ struct target_t {
/* Output an event object. Called for each named event in the scope. */
virtual void event(const NetEvent*);
+ /* Output an enumeration typespec. */
+ virtual bool enumeration(const NetScope*, netenum_t*);
+
/* Output a signal (called for each signal) */
virtual void signal(const NetNet*) =0;
virtual bool signal_paths(const NetNet*);
@@ -156,6 +159,7 @@ struct expr_scan_t {
virtual void expr_ufunc(const NetEUFunc*);
virtual void expr_unary(const NetEUnary*);
virtual void expr_binary(const NetEBinary*);
+ virtual void expr_netenum(const NetENetenum*);
};
View
2 tgt-stub/Makefile.in
@@ -45,7 +45,7 @@ CPPFLAGS = $(INCLUDE_PATH) @CPPFLAGS@ @DEFS@ @PICFLAG@
CFLAGS = @WARNING_FLAGS@ @CFLAGS@
LDFLAGS = @LDFLAGS@
-O = stub.o expression.o statement.o switches.o
+O = stub.o enumerate.o expression.o statement.o switches.o
all: dep stub.tgt
View
42 tgt-stub/enumerate.c
@@ -0,0 +1,42 @@
+/*
+ * Copyright (c) 2010 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
+ */
+
+# include "config.h"
+# include "priv.h"
+# include <string.h>
+
+void show_enumerate(ivl_enumtype_t net)
+{
+ unsigned idx;
+ fprintf(out, " enumeration %p {\n", net);
+
+ for (idx = 0 ; idx < ivl_enum_names(net) ; idx += 1) {
+ fprintf(out, " %s = <", ivl_enum_name(net, idx));
+
+ const char*bits = ivl_enum_bits(net, idx);
+ size_t bits_len = strlen(bits);
+ size_t bit;
+ for (bit = bits_len ; bit > 0 ; bit -= 1)
+ fputc(bits[bit-1], out);
+
+ fprintf(out, ">\n");
+ }
+
+ fprintf(out, " }\n");
+}
View
9 tgt-stub/expression.c
@@ -137,6 +137,11 @@ static void show_binary_expression(ivl_expr_t net, unsigned ind)
}
}
+static void show_enumtype_expression(ivl_expr_t net, unsigned ind)
+{
+ fprintf(out, "%*s<enumtype=%p>\n", ind, "", ivl_expr_enumtype(net));
+}
+
static void show_function_call(ivl_expr_t net, unsigned ind)
{
ivl_scope_t def = ivl_expr_def(net);
@@ -282,6 +287,10 @@ void show_expression(ivl_expr_t net, unsigned ind)
break;
+ case IVL_EX_ENUMTYPE:
+ show_enumtype_expression(net, ind);
+ break;
+
case IVL_EX_MEMORY:
show_memory_expression(net, ind);
break;
View
2 tgt-stub/priv.h
@@ -49,6 +49,8 @@ extern ivl_discipline_t discipline_of_nexus(ivl_nexus_t nex);
*/
extern void test_expr_is_delay(ivl_expr_t expr);
+extern void show_enumerate(ivl_enumtype_t net);
+
/*
* Show the details of the expression.
*/
View
3 tgt-stub/stub.c
@@ -1590,6 +1590,9 @@ static int show_scope(ivl_scope_t net, void*x)
for (idx = 0 ; idx < ivl_scope_params(net) ; idx += 1)
show_parameter(ivl_scope_param(net, idx));
+ for (idx = 0 ; idx < ivl_scope_enumerates(net) ; idx += 1)
+ show_enumerate(ivl_scope_enumerate(net, idx));
+
for (idx = 0 ; idx < ivl_scope_sigs(net) ; idx += 1)
show_signal(ivl_scope_sig(net, idx));
View
2 tgt-vvp/Makefile.in
@@ -48,7 +48,7 @@ CPPFLAGS = $(INCLUDE_PATH) @CPPFLAGS@ @DEFS@ @PICFLAG@
CFLAGS = @WARNING_FLAGS@ @CFLAGS@
LDFLAGS = @LDFLAGS@
-O = vvp.o draw_mux.o draw_net_input.o draw_switch.o draw_ufunc.o draw_vpi.o \
+O = vvp.o draw_enum.o draw_mux.o draw_net_input.o draw_switch.o draw_ufunc.o draw_vpi.o \
eval_bool.o eval_expr.o eval_real.o modpath.o vector.o vvp_process.o \
vvp_scope.o
View
49 tgt-vvp/draw_enum.c
@@ -0,0 +1,49 @@
+/*
+ * Copyright (c) 2010 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
+ */
+
+# include "vvp_priv.h"
+# include "ivl_alloc.h"
+# include <stdlib.h>
+# include <assert.h>
+
+void draw_enumeration_in_scope(ivl_enumtype_t enumtype)
+{
+ unsigned idx;
+
+ fprintf(vvp_out, "enum%p .enum\n", enumtype);
+
+ for (idx = 0 ; idx < ivl_enum_names(enumtype) ; idx += 1) {
+ const char*comma = idx+1 < ivl_enum_names(enumtype)? "," : "";
+
+ fprintf(vvp_out, " \"%s\"", ivl_enum_name(enumtype, idx));
+
+ long val = 0;
+ long mask = 1;
+ const char*bits = ivl_enum_bits(enumtype, idx);
+ const char*bit;
+ for (bit = bits, mask = 1 ; bit[0] != 0 ; bit += 1, mask <<= 1) {
+ if (*bit == '1')
+ val |= mask;
+ }
+
+ fprintf(vvp_out, " %ld%s\n", val, comma);
+ }
+
+ fprintf(vvp_out, " ;\n");
+}
View
6 tgt-vvp/draw_vpi.c
@@ -287,7 +287,7 @@ static void draw_vpi_taskfunc_args(const char*call_string,
assert((unsigned)(dp - buffer) <= sizeof buffer);
}
args[idx].text = strdup(buffer);
- continue;
+ continue;
}
case IVL_EX_STRING:
@@ -308,6 +308,10 @@ static void draw_vpi_taskfunc_args(const char*call_string,
}
break;
+ case IVL_EX_ENUMTYPE:
+ snprintf(buffer, sizeof buffer, "enum%p", ivl_expr_enumtype(expr));
+ args[idx].text = strdup(buffer);
+ continue;
case IVL_EX_EVENT:
snprintf(buffer, sizeof buffer, "E_%p", ivl_expr_event(expr));
args[idx].text = strdup(buffer);
View
5 tgt-vvp/vvp_priv.h
@@ -23,6 +23,11 @@
# include "ivl_target.h"
# include <stdio.h>
+#ifdef __MINGW32__ /* MinGW has inconsistent %p output. */
+#define snprintf _snprintf
+#endif
+
+
/*
* The target_design entry opens the output file that receives the
* compiled design, and sets the vvp_out to the descriptor.
View
13 tgt-vvp/vvp_scope.c
@@ -25,11 +25,6 @@
# include <inttypes.h>
# include <assert.h>
-#ifdef __MINGW32__ /* MinGW has inconsistent %p output. */
-#define snprintf _snprintf
-#endif
-
-
/*
* Escape non-symbol characters in ids, and quotes in strings.
*/
@@ -2026,6 +2021,14 @@ int draw_scope(ivl_scope_t net, ivl_scope_t parent)
}
}
+ /* Scan the scope for enumeration types, and write out
+ enumeration typespecs. */
+
+ for (idx = 0 ; idx < ivl_scope_enumerates(net) ; idx += 1) {
+ ivl_enumtype_t enumtype = ivl_scope_enumerate(net, idx);
+ draw_enumeration_in_scope(enumtype);
+ }
+
/* Scan the scope for logic devices. For each device, draw out
a functor that connects pin 0 to the output, and the
remaining pins to inputs. */

0 comments on commit de215f1

Please sign in to comment.
Something went wrong with that request. Please try again.