Add support for generate loops w/ wires and gates.
This commit is contained in:
parent
decfbff2b1
commit
f001d0001a
|
|
@ -16,7 +16,7 @@
|
|||
# 59 Temple Place - Suite 330
|
||||
# Boston, MA 02111-1307, USA
|
||||
#
|
||||
#ident "$Id: Makefile.in,v 1.174 2006/02/15 18:42:42 steve Exp $"
|
||||
#ident "$Id: Makefile.in,v 1.175 2006/04/10 00:37:42 steve Exp $"
|
||||
#
|
||||
#
|
||||
SHELL = /bin/sh
|
||||
|
|
@ -111,7 +111,7 @@ parse.o parse_misc.o pform.o pform_dump.o \
|
|||
set_width.o symbol_search.o sync.o sys_funcs.o \
|
||||
verinum.o verireal.o target.o targets.o \
|
||||
Attrib.o HName.o LineInfo.o Module.o PDelays.o PEvent.o \
|
||||
PExpr.o PGate.o \
|
||||
PExpr.o PGate.o PGenerate.o \
|
||||
PTask.o PUdp.o PFunction.o PWire.o Statement.o StringHeap.o \
|
||||
$(FF) $(TT)
|
||||
|
||||
|
|
|
|||
55
Module.h
55
Module.h
|
|
@ -19,7 +19,7 @@
|
|||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
||||
*/
|
||||
#ifdef HAVE_CVS_IDENT
|
||||
#ident "$Id: Module.h,v 1.39 2006/03/30 01:49:07 steve Exp $"
|
||||
#ident "$Id: Module.h,v 1.40 2006/04/10 00:37:42 steve Exp $"
|
||||
#endif
|
||||
|
||||
# include <list>
|
||||
|
|
@ -34,6 +34,7 @@ class PEvent;
|
|||
class PExpr;
|
||||
class PEIdent;
|
||||
class PGate;
|
||||
class PGenerate;
|
||||
class PTask;
|
||||
class PFunction;
|
||||
class PWire;
|
||||
|
|
@ -113,6 +114,14 @@ class Module : public LineInfo {
|
|||
set by the `timescale directive. */
|
||||
int time_unit, time_precision;
|
||||
|
||||
/* The module has a list of genvars that may be used in
|
||||
various generate schemes. */
|
||||
list<perm_string> genvars;
|
||||
|
||||
/* the module has a list of generate schemes that appear in
|
||||
the module definition. These are used at elaboration time. */
|
||||
list<PGenerate*> generate_schemes;
|
||||
|
||||
perm_string mod_name() const { return name_; }
|
||||
|
||||
void add_gate(PGate*gate);
|
||||
|
|
@ -164,51 +173,13 @@ class Module : public LineInfo {
|
|||
|
||||
/*
|
||||
* $Log: Module.h,v $
|
||||
* Revision 1.40 2006/04/10 00:37:42 steve
|
||||
* Add support for generate loops w/ wires and gates.
|
||||
*
|
||||
* Revision 1.39 2006/03/30 01:49:07 steve
|
||||
* Fix instance arrays indexed by overridden parameters.
|
||||
*
|
||||
* Revision 1.38 2005/07/11 16:56:50 steve
|
||||
* Remove NetVariable and ivl_variable_t structures.
|
||||
*
|
||||
* Revision 1.37 2004/06/13 04:56:53 steve
|
||||
* Add support for the default_nettype directive.
|
||||
*
|
||||
* Revision 1.36 2004/05/25 19:21:06 steve
|
||||
* More identifier lists use perm_strings.
|
||||
*
|
||||
* Revision 1.35 2004/02/20 18:53:33 steve
|
||||
* Addtrbute keys are perm_strings.
|
||||
*
|
||||
* Revision 1.34 2004/02/20 06:22:56 steve
|
||||
* parameter keys are per_strings.
|
||||
*
|
||||
* Revision 1.33 2004/02/18 17:11:54 steve
|
||||
* Use perm_strings for named langiage items.
|
||||
*
|
||||
* Revision 1.32 2003/06/20 00:53:19 steve
|
||||
* Module attributes from the parser
|
||||
* through to elaborated form.
|
||||
*
|
||||
* Revision 1.31 2003/06/13 19:10:45 steve
|
||||
* Properly manage real variables in subscopes.
|
||||
*
|
||||
* Revision 1.30 2003/03/06 04:37:12 steve
|
||||
* lex_strings.add module names earlier.
|
||||
*
|
||||
* Revision 1.29 2003/02/27 06:45:11 steve
|
||||
* specparams as far as pform.
|
||||
*
|
||||
* Revision 1.28 2003/01/26 21:15:58 steve
|
||||
* Rework expression parsing and elaboration to
|
||||
* accommodate real/realtime values and expressions.
|
||||
*
|
||||
* Revision 1.27 2002/08/19 02:39:16 steve
|
||||
* Support parameters with defined ranges.
|
||||
*
|
||||
* Revision 1.26 2002/08/12 01:34:58 steve
|
||||
* conditional ident string using autoconfig.
|
||||
*
|
||||
* Revision 1.25 2002/05/19 23:37:28 steve
|
||||
* Parse port_declaration_lists from the 2001 Standard.
|
||||
*/
|
||||
#endif
|
||||
|
|
|
|||
13
PGate.h
13
PGate.h
|
|
@ -19,7 +19,7 @@
|
|||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
||||
*/
|
||||
#ifdef HAVE_CVS_IDENT
|
||||
#ident "$Id: PGate.h,v 1.31 2006/01/03 05:22:14 steve Exp $"
|
||||
#ident "$Id: PGate.h,v 1.32 2006/04/10 00:37:42 steve Exp $"
|
||||
#endif
|
||||
|
||||
# include "svector.h"
|
||||
|
|
@ -94,7 +94,7 @@ class PGate : public LineInfo {
|
|||
|
||||
map<perm_string,PExpr*> attributes;
|
||||
|
||||
virtual void dump(ostream&out) const;
|
||||
virtual void dump(ostream&out, unsigned ind =4) const;
|
||||
virtual void elaborate(Design*des, NetScope*scope) const;
|
||||
virtual void elaborate_scope(Design*des, NetScope*sc) const;
|
||||
virtual bool elaborate_sig(Design*des, NetScope*scope) const;
|
||||
|
|
@ -128,7 +128,7 @@ class PGAssign : public PGate {
|
|||
explicit PGAssign(svector<PExpr*>*pins, svector<PExpr*>*dels);
|
||||
~PGAssign();
|
||||
|
||||
void dump(ostream&out) const;
|
||||
void dump(ostream&out, unsigned ind =4) const;
|
||||
virtual void elaborate(Design*des, NetScope*scope) const;
|
||||
|
||||
private:
|
||||
|
|
@ -165,7 +165,7 @@ class PGBuiltin : public PGate {
|
|||
Type type() const { return type_; }
|
||||
void set_range(PExpr*msb, PExpr*lsb);
|
||||
|
||||
virtual void dump(ostream&out) const;
|
||||
virtual void dump(ostream&out, unsigned ind =4) const;
|
||||
virtual void elaborate(Design*, NetScope*scope) const;
|
||||
|
||||
private:
|
||||
|
|
@ -208,7 +208,7 @@ class PGModule : public PGate {
|
|||
// method to pass the range to the pform.
|
||||
void set_range(PExpr*msb, PExpr*lsb);
|
||||
|
||||
virtual void dump(ostream&out) const;
|
||||
virtual void dump(ostream&out, unsigned ind =4) const;
|
||||
virtual void elaborate(Design*, NetScope*scope) const;
|
||||
virtual void elaborate_scope(Design*des, NetScope*sc) const;
|
||||
virtual bool elaborate_sig(Design*des, NetScope*scope) const;
|
||||
|
|
@ -239,6 +239,9 @@ class PGModule : public PGate {
|
|||
|
||||
/*
|
||||
* $Log: PGate.h,v $
|
||||
* Revision 1.32 2006/04/10 00:37:42 steve
|
||||
* Add support for generate loops w/ wires and gates.
|
||||
*
|
||||
* Revision 1.31 2006/01/03 05:22:14 steve
|
||||
* Handle complex net node delays.
|
||||
*
|
||||
|
|
|
|||
7
PWire.h
7
PWire.h
|
|
@ -19,7 +19,7 @@
|
|||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
||||
*/
|
||||
#ifdef HAVE_CVS_IDENT
|
||||
#ident "$Id: PWire.h,v 1.18 2005/07/07 16:22:49 steve Exp $"
|
||||
#ident "$Id: PWire.h,v 1.19 2006/04/10 00:37:42 steve Exp $"
|
||||
#endif
|
||||
|
||||
# include "netlist.h"
|
||||
|
|
@ -81,7 +81,7 @@ class PWire : public LineInfo {
|
|||
map<perm_string,PExpr*> attributes;
|
||||
|
||||
// Write myself to the specified stream.
|
||||
void dump(ostream&out) const;
|
||||
void dump(ostream&out, unsigned ind=4) const;
|
||||
|
||||
void elaborate_sig(Design*, NetScope*scope) const;
|
||||
|
||||
|
|
@ -110,6 +110,9 @@ class PWire : public LineInfo {
|
|||
|
||||
/*
|
||||
* $Log: PWire.h,v $
|
||||
* Revision 1.19 2006/04/10 00:37:42 steve
|
||||
* Add support for generate loops w/ wires and gates.
|
||||
*
|
||||
* Revision 1.18 2005/07/07 16:22:49 steve
|
||||
* Generalize signals to carry types.
|
||||
*
|
||||
|
|
|
|||
|
|
@ -17,7 +17,7 @@
|
|||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
||||
*/
|
||||
#ifdef HAVE_CVS_IDENT
|
||||
#ident "$Id: design_dump.cc,v 1.164 2006/02/02 02:43:57 steve Exp $"
|
||||
#ident "$Id: design_dump.cc,v 1.165 2006/04/10 00:37:42 steve Exp $"
|
||||
#endif
|
||||
|
||||
# include "config.h"
|
||||
|
|
@ -811,6 +811,9 @@ void NetScope::dump(ostream&o) const
|
|||
case TASK:
|
||||
o << " task";
|
||||
break;
|
||||
case GENBLOCK:
|
||||
o << " generate block";
|
||||
break;
|
||||
}
|
||||
o << endl;
|
||||
|
||||
|
|
@ -1170,6 +1173,9 @@ void Design::dump(ostream&o) const
|
|||
|
||||
/*
|
||||
* $Log: design_dump.cc,v $
|
||||
* Revision 1.165 2006/04/10 00:37:42 steve
|
||||
* Add support for generate loops w/ wires and gates.
|
||||
*
|
||||
* Revision 1.164 2006/02/02 02:43:57 steve
|
||||
* Allow part selects of memory words in l-values.
|
||||
*
|
||||
|
|
|
|||
112
elab_scope.cc
112
elab_scope.cc
|
|
@ -17,7 +17,7 @@
|
|||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
||||
*/
|
||||
#ifdef HAVE_CVS_IDENT
|
||||
#ident "$Id: elab_scope.cc,v 1.38 2006/03/30 01:49:07 steve Exp $"
|
||||
#ident "$Id: elab_scope.cc,v 1.39 2006/04/10 00:37:42 steve Exp $"
|
||||
#endif
|
||||
|
||||
# include "config.h"
|
||||
|
|
@ -37,6 +37,7 @@
|
|||
# include "PEvent.h"
|
||||
# include "PExpr.h"
|
||||
# include "PGate.h"
|
||||
# include "PGenerate.h"
|
||||
# include "PTask.h"
|
||||
# include "PWire.h"
|
||||
# include "Statement.h"
|
||||
|
|
@ -220,6 +221,17 @@ bool Module::elaborate_scope(Design*des, NetScope*scope,
|
|||
|
||||
delete[]attr;
|
||||
|
||||
// Generate schemes can create new scopes in the form of
|
||||
// generated code. Scan the generate schemes, and *generate*
|
||||
// new scopes, which is slightly different from simple
|
||||
// elaboration.
|
||||
|
||||
typedef list<PGenerate*>::const_iterator generate_it_t;
|
||||
for (generate_it_t cur = generate_schemes.begin()
|
||||
; cur != generate_schemes.end() ; cur ++ ) {
|
||||
(*cur) -> generate_scope(des, scope);
|
||||
}
|
||||
|
||||
|
||||
// Tasks introduce new scopes, so scan the tasks in this
|
||||
// module. Create a scope for the task and pass that to the
|
||||
|
|
@ -289,6 +301,101 @@ bool Module::elaborate_scope(Design*des, NetScope*scope,
|
|||
return des->errors == 0;
|
||||
}
|
||||
|
||||
bool PGenerate::generate_scope(Design*des, NetScope*container)
|
||||
{
|
||||
switch (scheme_type) {
|
||||
case GS_LOOP:
|
||||
return generate_scope_loop_(des, container);
|
||||
|
||||
default:
|
||||
cerr << get_line() << ": sorry: Generate of this sort"
|
||||
<< " is not supported yet!" << endl;
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* This is the elaborate scope method for a generate loop.
|
||||
*/
|
||||
bool PGenerate::generate_scope_loop_(Design*des, NetScope*container)
|
||||
{
|
||||
// We're going to need a genvar...
|
||||
int genvar;
|
||||
|
||||
// The initial value for the genvar does not need (nor can it
|
||||
// use) the genvar itself, so we can evaluate this expression
|
||||
// the same way any other paramter value is evaluated.
|
||||
NetExpr*init_ex = elab_and_eval(des, container, loop_init);
|
||||
NetEConst*init = dynamic_cast<NetEConst*> (init_ex);
|
||||
if (init == 0) {
|
||||
cerr << get_line() << ": error: Cannot evaluate genvar"
|
||||
<< " init expression: " << *loop_init << endl;
|
||||
des->errors += 1;
|
||||
return false;
|
||||
}
|
||||
|
||||
genvar = init->value().as_long();
|
||||
delete init_ex;
|
||||
|
||||
if (debug_elaborate)
|
||||
cerr << get_line() << ": debug: genvar init = " << genvar << endl;
|
||||
|
||||
container->genvar_tmp = loop_index;
|
||||
container->genvar_tmp_val = 0;
|
||||
verinum*test = loop_test->eval_const(des, container);
|
||||
assert(test);
|
||||
while (test->as_long()) {
|
||||
|
||||
// The actual name of the scope includes the genvar so
|
||||
// that each instance has a unique name in the
|
||||
// container. The format of using [] is part of the
|
||||
// Verilog standard.
|
||||
char name_buf[128];
|
||||
snprintf(name_buf, sizeof name_buf,
|
||||
"%s[%d]", scope_name.str(), genvar);
|
||||
perm_string use_name = lex_strings.make(name_buf);
|
||||
|
||||
if (debug_elaborate)
|
||||
cerr << get_line() << ": debug: "
|
||||
<< "Create generated scope " << use_name << endl;
|
||||
|
||||
NetScope*scope = new NetScope(container, use_name,
|
||||
NetScope::GENBLOCK);
|
||||
|
||||
// Set in the scope a localparam for the value of the
|
||||
// genvar within this instance of the generate
|
||||
// block. Code within this scope thus has access to the
|
||||
// genvar as a constant.
|
||||
{
|
||||
verinum genvar_verinum(genvar);
|
||||
genvar_verinum.has_sign(true);
|
||||
NetEConstParam*gp = new NetEConstParam(scope,
|
||||
loop_index,
|
||||
genvar_verinum);
|
||||
scope->set_localparam(loop_index, gp);
|
||||
}
|
||||
|
||||
scope_list_.push_back(scope);
|
||||
|
||||
// Calculate the step for the loop variable.
|
||||
verinum*step = loop_step->eval_const(des, container);
|
||||
assert(step);
|
||||
if (debug_elaborate)
|
||||
cerr << get_line() << ": debug: genvar step from "
|
||||
<< genvar << " to " << step->as_long() << endl;
|
||||
|
||||
genvar = step->as_long();
|
||||
container->genvar_tmp_val = genvar;
|
||||
delete step;
|
||||
delete test;
|
||||
test = loop_test->eval_const(des, container);
|
||||
}
|
||||
|
||||
container->genvar_tmp = perm_string();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void PGModule::elaborate_scope_mod_(Design*des, Module*mod, NetScope*sc) const
|
||||
{
|
||||
if (get_name() == "") {
|
||||
|
|
@ -635,6 +742,9 @@ void PWhile::elaborate_scope(Design*des, NetScope*scope) const
|
|||
|
||||
/*
|
||||
* $Log: elab_scope.cc,v $
|
||||
* Revision 1.39 2006/04/10 00:37:42 steve
|
||||
* Add support for generate loops w/ wires and gates.
|
||||
*
|
||||
* Revision 1.38 2006/03/30 01:49:07 steve
|
||||
* Fix instance arrays indexed by overridden parameters.
|
||||
*
|
||||
|
|
|
|||
54
elab_sig.cc
54
elab_sig.cc
|
|
@ -17,7 +17,7 @@
|
|||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
||||
*/
|
||||
#ifdef HAVE_CVS_IDENT
|
||||
#ident "$Id: elab_sig.cc,v 1.40 2005/07/11 16:56:50 steve Exp $"
|
||||
#ident "$Id: elab_sig.cc,v 1.41 2006/04/10 00:37:42 steve Exp $"
|
||||
#endif
|
||||
|
||||
# include "config.h"
|
||||
|
|
@ -27,6 +27,7 @@
|
|||
# include "Module.h"
|
||||
# include "PExpr.h"
|
||||
# include "PGate.h"
|
||||
# include "PGenerate.h"
|
||||
# include "PTask.h"
|
||||
# include "PWire.h"
|
||||
# include "compiler.h"
|
||||
|
|
@ -158,6 +159,16 @@ bool Module::elaborate_sig(Design*des, NetScope*scope) const
|
|||
des->errors += 1;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// Run through all the generate schemes to enaborate the
|
||||
// signals that they hold. Note that the generate schemes hold
|
||||
// the scopes that they instantiated, so we don't pass any
|
||||
// scope in.
|
||||
typedef list<PGenerate*>::const_iterator generate_it_t;
|
||||
for (generate_it_t cur = generate_schemes.begin()
|
||||
; cur != generate_schemes.end() ; cur ++ ) {
|
||||
(*cur) -> elaborate_sig(des);
|
||||
}
|
||||
|
||||
// Get all the gates of the module and elaborate them by
|
||||
|
|
@ -238,6 +249,44 @@ bool PGModule::elaborate_sig_mod_(Design*des, NetScope*scope,
|
|||
return flag;
|
||||
}
|
||||
|
||||
bool PGenerate::elaborate_sig(Design*des) const
|
||||
{
|
||||
bool flag = true;
|
||||
|
||||
typedef list<NetScope*>::const_iterator scope_list_it_t;
|
||||
for (scope_list_it_t cur = scope_list_.begin()
|
||||
; cur != scope_list_.end() ; cur ++ ) {
|
||||
|
||||
if (debug_elaborate)
|
||||
cerr << get_line() << ": debug: Elaborate nets in "
|
||||
<< "scope " << (*cur)->name() << endl;
|
||||
flag = elaborate_sig_(des, *cur) & flag;
|
||||
}
|
||||
|
||||
return flag;
|
||||
}
|
||||
|
||||
bool PGenerate::elaborate_sig_(Design*des, NetScope*scope) const
|
||||
{
|
||||
// Scan the declared PWires to elaborate the obvious signals
|
||||
// in the current scope.
|
||||
typedef map<hname_t,PWire*>::const_iterator wires_it_t;
|
||||
for (wires_it_t wt = wires.begin()
|
||||
; wt != wires.end() ; wt ++ ) {
|
||||
|
||||
PWire*cur = (*wt).second;
|
||||
|
||||
if (debug_elaborate)
|
||||
cerr << get_line() << ": debug: Elaborate PWire "
|
||||
<< cur->path() << " in scope " << scope->name() << endl;
|
||||
|
||||
cur->elaborate_sig(des, scope);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* A function definition exists within an elaborated module. This
|
||||
* matters when elaborating signals, as the ports of the function are
|
||||
|
|
@ -671,6 +720,9 @@ void PWire::elaborate_sig(Design*des, NetScope*scope) const
|
|||
|
||||
/*
|
||||
* $Log: elab_sig.cc,v $
|
||||
* Revision 1.41 2006/04/10 00:37:42 steve
|
||||
* Add support for generate loops w/ wires and gates.
|
||||
*
|
||||
* Revision 1.40 2005/07/11 16:56:50 steve
|
||||
* Remove NetVariable and ivl_variable_t structures.
|
||||
*
|
||||
|
|
|
|||
47
elaborate.cc
47
elaborate.cc
|
|
@ -17,7 +17,7 @@
|
|||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
||||
*/
|
||||
#ifdef HAVE_CVS_IDENT
|
||||
#ident "$Id: elaborate.cc,v 1.335 2006/03/30 01:49:07 steve Exp $"
|
||||
#ident "$Id: elaborate.cc,v 1.336 2006/04/10 00:37:42 steve Exp $"
|
||||
#endif
|
||||
|
||||
# include "config.h"
|
||||
|
|
@ -34,6 +34,7 @@
|
|||
# include <list>
|
||||
# include "pform.h"
|
||||
# include "PEvent.h"
|
||||
# include "PGenerate.h"
|
||||
# include "netlist.h"
|
||||
# include "netmisc.h"
|
||||
# include "util.h"
|
||||
|
|
@ -2846,6 +2847,12 @@ bool Module::elaborate(Design*des, NetScope*scope) const
|
|||
{
|
||||
bool result_flag = true;
|
||||
|
||||
// Elaborate within the generate blocks.
|
||||
typedef list<PGenerate*>::const_iterator generate_it_t;
|
||||
for (generate_it_t cur = generate_schemes.begin()
|
||||
; cur != generate_schemes.end() ; cur ++ ) {
|
||||
(*cur)->elaborate(des);
|
||||
}
|
||||
|
||||
// Elaborate functions.
|
||||
typedef map<perm_string,PFunction*>::const_iterator mfunc_it_t;
|
||||
|
|
@ -2966,6 +2973,35 @@ bool Module::elaborate(Design*des, NetScope*scope) const
|
|||
return result_flag;
|
||||
}
|
||||
|
||||
bool PGenerate::elaborate(Design*des) const
|
||||
{
|
||||
bool flag = true;
|
||||
|
||||
typedef list<NetScope*>::const_iterator scope_list_it_t;
|
||||
for (scope_list_it_t cur = scope_list_.begin()
|
||||
; cur != scope_list_.end() ; cur ++ ) {
|
||||
|
||||
if (debug_elaborate)
|
||||
cerr << get_line() << ": debug: Elaborate in "
|
||||
<< "scope " << (*cur)->name() << endl;
|
||||
|
||||
flag = elaborate_(des, *cur) & flag;
|
||||
}
|
||||
|
||||
return flag;
|
||||
}
|
||||
|
||||
bool PGenerate::elaborate_(Design*des, NetScope*scope) const
|
||||
{
|
||||
typedef list<PGate*>::const_iterator gates_it_t;
|
||||
for (gates_it_t cur = gates.begin() ; cur != gates.end() ; cur ++ ) {
|
||||
|
||||
(*cur)->elaborate(des, scope);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
struct root_elem {
|
||||
Module *mod;
|
||||
NetScope *scope;
|
||||
|
|
@ -2981,6 +3017,7 @@ Design* elaborate(list<perm_string>roots)
|
|||
// module and elaborate what I find.
|
||||
Design*des = new Design;
|
||||
|
||||
// Scan the root modules, and elaborate their scopes.
|
||||
for (list<perm_string>::const_iterator root = roots.begin()
|
||||
; root != roots.end()
|
||||
; root++) {
|
||||
|
|
@ -2996,6 +3033,7 @@ Design* elaborate(list<perm_string>roots)
|
|||
continue;
|
||||
}
|
||||
|
||||
// Get the module definition for this root instance.
|
||||
Module *rmod = (*mod).second;
|
||||
|
||||
// Make the root scope.
|
||||
|
|
@ -3006,7 +3044,9 @@ Design* elaborate(list<perm_string>roots)
|
|||
des->set_precision(rmod->time_precision);
|
||||
|
||||
Module::replace_t stub;
|
||||
// Recursively elaborate from this root scope down.
|
||||
|
||||
// Recursively elaborate from this root scope down. This
|
||||
// does a lot of the grunt work of creating sub-scopes, etc.
|
||||
if (! rmod->elaborate_scope(des, scope, stub)) {
|
||||
delete des;
|
||||
return 0;
|
||||
|
|
@ -3071,6 +3111,9 @@ Design* elaborate(list<perm_string>roots)
|
|||
|
||||
/*
|
||||
* $Log: elaborate.cc,v $
|
||||
* Revision 1.336 2006/04/10 00:37:42 steve
|
||||
* Add support for generate loops w/ wires and gates.
|
||||
*
|
||||
* Revision 1.335 2006/03/30 01:49:07 steve
|
||||
* Fix instance arrays indexed by overridden parameters.
|
||||
*
|
||||
|
|
|
|||
15
eval.cc
15
eval.cc
|
|
@ -17,7 +17,7 @@
|
|||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
||||
*/
|
||||
#ifdef HAVE_CVS_IDENT
|
||||
#ident "$Id: eval.cc,v 1.39 2005/12/07 04:04:23 steve Exp $"
|
||||
#ident "$Id: eval.cc,v 1.40 2006/04/10 00:37:42 steve Exp $"
|
||||
#endif
|
||||
|
||||
# include "config.h"
|
||||
|
|
@ -168,11 +168,19 @@ verinum* PEConcat::eval_const(const Design*des, NetScope*scope) const
|
|||
verinum* PEIdent::eval_const(const Design*des, NetScope*scope) const
|
||||
{
|
||||
assert(scope);
|
||||
//const NetExpr*expr = des->find_parameter(scope, path_);
|
||||
NetNet*net;
|
||||
NetMemory*mem;
|
||||
NetEvent*eve;
|
||||
const NetExpr*expr;
|
||||
|
||||
// Handle the special case that this ident is a genvar
|
||||
// variable name. In that case, the genvar meaning preempts
|
||||
// everything and we just return that value immediately.
|
||||
if (scope->genvar_tmp
|
||||
&& strcmp(path_.peek_tail_name(),scope->genvar_tmp) == 0) {
|
||||
return new verinum(scope->genvar_tmp_val);
|
||||
}
|
||||
|
||||
NetScope*found_in = symbol_search(des, scope, path_,
|
||||
net, mem, expr, eve);
|
||||
|
||||
|
|
@ -263,6 +271,9 @@ verinum* PEUnary::eval_const(const Design*des, NetScope*scope) const
|
|||
|
||||
/*
|
||||
* $Log: eval.cc,v $
|
||||
* Revision 1.40 2006/04/10 00:37:42 steve
|
||||
* Add support for generate loops w/ wires and gates.
|
||||
*
|
||||
* Revision 1.39 2005/12/07 04:04:23 steve
|
||||
* Allow constant concat expressions.
|
||||
*
|
||||
|
|
|
|||
|
|
@ -19,7 +19,7 @@
|
|||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
||||
*/
|
||||
#ifdef HAVE_CVS_IDENT
|
||||
#ident "$Id: ivl_target.h,v 1.165 2006/02/02 02:43:58 steve Exp $"
|
||||
#ident "$Id: ivl_target.h,v 1.166 2006/04/10 00:37:42 steve Exp $"
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
|
|
@ -266,7 +266,8 @@ typedef enum ivl_scope_type_e {
|
|||
IVL_SCT_FUNCTION= 1,
|
||||
IVL_SCT_TASK = 2,
|
||||
IVL_SCT_BEGIN = 3,
|
||||
IVL_SCT_FORK = 4
|
||||
IVL_SCT_FORK = 4,
|
||||
IVL_SCT_GENERATE= 5
|
||||
} ivl_scope_type_t;
|
||||
|
||||
/* Signals (ivl_signal_t) that are ports into the scope that contains
|
||||
|
|
@ -1707,6 +1708,9 @@ _END_DECL
|
|||
|
||||
/*
|
||||
* $Log: ivl_target.h,v $
|
||||
* Revision 1.166 2006/04/10 00:37:42 steve
|
||||
* Add support for generate loops w/ wires and gates.
|
||||
*
|
||||
* Revision 1.165 2006/02/02 02:43:58 steve
|
||||
* Allow part selects of memory words in l-values.
|
||||
*
|
||||
|
|
|
|||
|
|
@ -31,6 +31,7 @@ else, K_else
|
|||
end, K_end
|
||||
endcase, K_endcase
|
||||
endfunction, K_endfunction
|
||||
endgenerate, K_endgenerate
|
||||
endmodule, K_endmodule
|
||||
endprimitive, K_endprimitive
|
||||
endspecify, K_endspecify
|
||||
|
|
@ -42,6 +43,8 @@ force, K_force
|
|||
forever, K_forever
|
||||
fork, K_fork
|
||||
function, K_function
|
||||
generate, K_generate
|
||||
genvar, K_genvar
|
||||
highz0, K_highz0
|
||||
highz1, K_highz1
|
||||
if, K_if
|
||||
|
|
|
|||
13
netlist.h
13
netlist.h
|
|
@ -19,7 +19,7 @@
|
|||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
||||
*/
|
||||
#ifdef HAVE_CVS_IDENT
|
||||
#ident "$Id: netlist.h,v 1.356 2006/03/18 22:53:04 steve Exp $"
|
||||
#ident "$Id: netlist.h,v 1.357 2006/04/10 00:37:42 steve Exp $"
|
||||
#endif
|
||||
|
||||
/*
|
||||
|
|
@ -3137,7 +3137,7 @@ class NetESignal : public NetExpr {
|
|||
class NetScope : public Attrib {
|
||||
|
||||
public:
|
||||
enum TYPE { MODULE, TASK, FUNC, BEGIN_END, FORK_JOIN };
|
||||
enum TYPE { MODULE, TASK, FUNC, BEGIN_END, FORK_JOIN, GENBLOCK };
|
||||
|
||||
/* Create a new scope, and attach it to the given parent. The
|
||||
name is expected to have been permallocated. */
|
||||
|
|
@ -3281,6 +3281,12 @@ class NetScope : public Attrib {
|
|||
typedef svector<NetScope*> scope_vec_t;
|
||||
map<perm_string, scope_vec_t>instance_arrays;
|
||||
|
||||
/* Loop generate uses this as scratch space during
|
||||
elaboration. Expression evaluation can use this to match
|
||||
names. */
|
||||
perm_string genvar_tmp;
|
||||
long genvar_tmp_val;
|
||||
|
||||
private:
|
||||
TYPE type_;
|
||||
perm_string name_;
|
||||
|
|
@ -3458,6 +3464,9 @@ extern ostream& operator << (ostream&, NetNet::Type);
|
|||
|
||||
/*
|
||||
* $Log: netlist.h,v $
|
||||
* Revision 1.357 2006/04/10 00:37:42 steve
|
||||
* Add support for generate loops w/ wires and gates.
|
||||
*
|
||||
* Revision 1.356 2006/03/18 22:53:04 steve
|
||||
* Properly handle signedness in compare.
|
||||
*
|
||||
|
|
|
|||
43
parse.y
43
parse.y
|
|
@ -19,7 +19,7 @@
|
|||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
||||
*/
|
||||
#ifdef HAVE_CVS_IDENT
|
||||
#ident "$Id: parse.y,v 1.212 2006/03/30 05:22:34 steve Exp $"
|
||||
#ident "$Id: parse.y,v 1.213 2006/04/10 00:37:42 steve Exp $"
|
||||
#endif
|
||||
|
||||
# include "config.h"
|
||||
|
|
@ -137,9 +137,10 @@ const static struct str_pair_t str_strength = { PGate::STRONG, PGate::STRONG };
|
|||
%token K_LOR K_LAND K_NAND K_NOR K_NXOR K_TRIGGER
|
||||
%token K_always K_and K_assign K_begin K_bool K_buf K_bufif0 K_bufif1 K_case
|
||||
%token K_casex K_casez K_cmos K_deassign K_default K_defparam K_disable
|
||||
%token K_edge K_else K_end K_endcase K_endfunction K_endmodule
|
||||
%token K_edge K_else K_end K_endcase K_endfunction K_endgenerate K_endmodule
|
||||
%token K_endprimitive K_endspecify K_endtable K_endtask K_event K_for
|
||||
%token K_force K_forever K_fork K_function K_highz0 K_highz1 K_if
|
||||
%token K_force K_forever K_fork K_function K_generate K_genvar
|
||||
%token K_highz0 K_highz1 K_if
|
||||
%token K_initial K_inout K_input K_integer K_join K_large K_localparam
|
||||
%token K_logic K_macromodule
|
||||
%token K_medium K_module K_nand K_negedge K_nmos K_nor K_not K_notif0
|
||||
|
|
@ -1807,6 +1808,27 @@ module_item
|
|||
delete $3;
|
||||
}
|
||||
|
||||
/* A generate region can contain further module items. Actually, it
|
||||
is supposed to be limited to certain kinds of module items, but
|
||||
the semantic tests will check that for us. */
|
||||
|
||||
| K_generate module_item_list_opt K_endgenerate
|
||||
|
||||
| K_genvar list_of_identifiers ';'
|
||||
{ pform_genvars($2); }
|
||||
|
||||
| K_for '(' IDENTIFIER '=' expression ';'
|
||||
expression ';'
|
||||
IDENTIFIER '=' expression ')'
|
||||
{ pform_start_generate_for(@1, $3, $5, $7, $9, $11); }
|
||||
generate_block
|
||||
{ pform_endgenerate(); }
|
||||
|
||||
| K_if '(' expression ')' generate_block_opt K_else generate_block
|
||||
{ yyerror(@1, "sorry: Condition generate not supported yet.");
|
||||
}
|
||||
|
||||
|
||||
/* specify blocks are parsed but ignored. */
|
||||
|
||||
| K_specify K_endspecify
|
||||
|
|
@ -1873,6 +1895,21 @@ module_item_list_opt
|
|||
|
|
||||
;
|
||||
|
||||
/* A generate block is the thing within a generate scheme. It may be
|
||||
a single module item, an anonymous block of module items, or a
|
||||
named module item. In all cases, the meat is in the module items
|
||||
inside, and the processing is done by the module_item rules. We
|
||||
only need to take note here of the scope name, if any. */
|
||||
|
||||
generate_block
|
||||
: module_item
|
||||
| K_begin module_item_list_opt K_end
|
||||
| K_begin ':' IDENTIFIER module_item_list_opt K_end
|
||||
{ pform_generate_block_name($3); }
|
||||
;
|
||||
|
||||
generate_block_opt : generate_block | ;
|
||||
|
||||
|
||||
/* A net declaration assignment allows the programmer to combine the
|
||||
net declaration and the continuous assignment into a single
|
||||
|
|
|
|||
130
pform.cc
130
pform.cc
|
|
@ -17,7 +17,7 @@
|
|||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
||||
*/
|
||||
#ifdef HAVE_CVS_IDENT
|
||||
#ident "$Id: pform.cc,v 1.134 2006/03/30 05:22:34 steve Exp $"
|
||||
#ident "$Id: pform.cc,v 1.135 2006/04/10 00:37:42 steve Exp $"
|
||||
#endif
|
||||
|
||||
# include "config.h"
|
||||
|
|
@ -28,6 +28,7 @@
|
|||
# include "parse_api.h"
|
||||
# include "PEvent.h"
|
||||
# include "PUdp.h"
|
||||
# include "PGenerate.h"
|
||||
# include <list>
|
||||
# include <map>
|
||||
# include <assert.h>
|
||||
|
|
@ -44,7 +45,17 @@ string vl_file = "";
|
|||
|
||||
extern int VLparse();
|
||||
|
||||
/* This tracks the current module being processed. There can only be
|
||||
exactly one module currently being parsed, since verilog does not
|
||||
allow nested module definitions. */
|
||||
static Module*pform_cur_module = 0;
|
||||
/* increment this for generate schemes within a module, and set it
|
||||
to zero when a new module starts. */
|
||||
static unsigned scope_generate_counter = 1;
|
||||
|
||||
/* This tracks the current generate scheme being processed. This is
|
||||
always within a module. */
|
||||
static PGenerate*pform_cur_generate = 0;
|
||||
|
||||
static NetNet::Type pform_default_nettype = NetNet::WIRE;
|
||||
|
||||
|
|
@ -63,10 +74,13 @@ static unsigned pform_timescale_line = 0;
|
|||
* of scope. As I enter a scope, the push function is called, and as I
|
||||
* leave a scope the pop function is called. Entering tasks, functions
|
||||
* and named blocks causes scope to be pushed and popped. The module
|
||||
* name is not included it this scope stack.
|
||||
* name is not included in this scope stack.
|
||||
*
|
||||
* The hier_name function, therefore, returns the name path of a
|
||||
* function relative the current function.
|
||||
* The hier_name function, therefore, converts the name to the scope
|
||||
* of the module currently in progress.
|
||||
*
|
||||
* The scope stack does not include any scope created by a generate
|
||||
* scheme.
|
||||
*/
|
||||
|
||||
static hname_t scope_stack;
|
||||
|
|
@ -90,6 +104,18 @@ static hname_t hier_name(const char*tail)
|
|||
return name;
|
||||
}
|
||||
|
||||
static PWire*get_wire_in_module(const hname_t&name)
|
||||
{
|
||||
/* Note that if we are processing a generate, then the
|
||||
scope depth will be empty because generate schemes
|
||||
cannot be within sub-scopes. Only directly in
|
||||
modules. */
|
||||
if (pform_cur_generate)
|
||||
return pform_cur_generate->get_wire(name);
|
||||
|
||||
return pform_cur_module->get_wire(name);
|
||||
}
|
||||
|
||||
void pform_set_default_nettype(NetNet::Type type,
|
||||
const char*file, unsigned lineno)
|
||||
{
|
||||
|
|
@ -216,6 +242,10 @@ void pform_startmodule(const char*name, const char*file, unsigned lineno,
|
|||
pform_cur_module->set_file(file);
|
||||
pform_cur_module->set_lineno(lineno);
|
||||
|
||||
/* The generate scheme numbering starts with *1*, not
|
||||
zero. That's just the way it is, thanks to the standard. */
|
||||
scope_generate_counter = 1;
|
||||
|
||||
if (warn_timescale && pform_timescale_file
|
||||
&& (strcmp(pform_timescale_file,file) != 0)) {
|
||||
|
||||
|
|
@ -292,6 +322,58 @@ void pform_endmodule(const char*name)
|
|||
pform_cur_module = 0;
|
||||
}
|
||||
|
||||
void pform_genvars(list<perm_string>*names)
|
||||
{
|
||||
list<perm_string>::const_iterator cur;
|
||||
for (cur = names->begin(); cur != names->end() ; *cur++) {
|
||||
pform_cur_module->genvars.push_back( *cur );
|
||||
}
|
||||
|
||||
delete names;
|
||||
}
|
||||
|
||||
void pform_start_generate_for(const struct vlltype&li,
|
||||
char*ident1, PExpr*init,
|
||||
PExpr*test,
|
||||
char*ident2, PExpr*next)
|
||||
{
|
||||
PGenerate*gen = new PGenerate(scope_generate_counter++);
|
||||
|
||||
gen->set_file(li.text);
|
||||
gen->set_lineno(li.first_line);
|
||||
|
||||
// For now, assume that generates do not nest.
|
||||
assert(pform_cur_generate == 0);
|
||||
pform_cur_generate = gen;
|
||||
|
||||
pform_cur_generate->scheme_type = PGenerate::GS_LOOP;
|
||||
|
||||
pform_cur_generate->loop_index = lex_strings.make(ident1);
|
||||
pform_cur_generate->loop_init = init;
|
||||
pform_cur_generate->loop_test = test;
|
||||
pform_cur_generate->loop_step = next;
|
||||
|
||||
delete[]ident1;
|
||||
delete[]ident2;
|
||||
}
|
||||
|
||||
void pform_generate_block_name(char*name)
|
||||
{
|
||||
assert(pform_cur_generate != 0);
|
||||
assert(pform_cur_generate->scope_name == 0);
|
||||
pform_cur_generate->scope_name = lex_strings.make(name);
|
||||
delete[]name;
|
||||
}
|
||||
|
||||
void pform_endgenerate()
|
||||
{
|
||||
assert(pform_cur_generate != 0);
|
||||
assert(pform_cur_module);
|
||||
|
||||
pform_cur_module->generate_schemes.push_back(pform_cur_generate);
|
||||
pform_cur_generate = 0;
|
||||
}
|
||||
|
||||
bool pform_expression_is_constant(const PExpr*ex)
|
||||
{
|
||||
return ex->is_constant(pform_cur_module);
|
||||
|
|
@ -695,8 +777,7 @@ static void pform_set_net_range(const char* name,
|
|||
bool signed_flag,
|
||||
ivl_variable_type_t dt)
|
||||
{
|
||||
|
||||
PWire*cur = pform_cur_module->get_wire(hier_name(name));
|
||||
PWire*cur = get_wire_in_module(hier_name(name));
|
||||
if (cur == 0) {
|
||||
VLerror("error: name is not a valid net.");
|
||||
return;
|
||||
|
|
@ -796,6 +877,9 @@ void pform_makegate(PGBuiltin::Type type,
|
|||
cur->set_file(info.file);
|
||||
cur->set_lineno(info.lineno);
|
||||
|
||||
if (pform_cur_generate)
|
||||
pform_cur_generate->add_gate(cur);
|
||||
else
|
||||
pform_cur_module->add_gate(cur);
|
||||
}
|
||||
|
||||
|
|
@ -854,6 +938,9 @@ static void pform_make_modgate(perm_string type,
|
|||
cur->set_parameters(overrides->by_order);
|
||||
}
|
||||
|
||||
if (pform_cur_generate)
|
||||
pform_cur_generate->add_gate(cur);
|
||||
else
|
||||
pform_cur_module->add_gate(cur);
|
||||
}
|
||||
|
||||
|
|
@ -956,7 +1043,11 @@ static PGAssign* pform_make_pgassign(PExpr*lval, PExpr*rval,
|
|||
cur->strength0(str.str0);
|
||||
cur->strength1(str.str1);
|
||||
|
||||
if (pform_cur_generate)
|
||||
pform_cur_generate->add_gate(cur);
|
||||
else
|
||||
pform_cur_module->add_gate(cur);
|
||||
|
||||
return cur;
|
||||
}
|
||||
|
||||
|
|
@ -1089,13 +1180,22 @@ void pform_module_define_port(const struct vlltype&li,
|
|||
* do check to see if the name has already been declared, as this
|
||||
* function is called for every declaration.
|
||||
*/
|
||||
|
||||
/*
|
||||
* this is the basic form of pform_makwire. This takes a single simple
|
||||
* name, port type, net type, data type, and attributes, and creates
|
||||
* the variable/net. Other forms of pform_makewire ultimately call
|
||||
* this one to create the wire and stash it.
|
||||
*/
|
||||
void pform_makewire(const vlltype&li, const char*nm,
|
||||
NetNet::Type type, NetNet::PortType pt,
|
||||
ivl_variable_type_t dt,
|
||||
svector<named_pexpr_t*>*attr)
|
||||
{
|
||||
hname_t name = hier_name(nm);
|
||||
PWire*cur = pform_cur_module->get_wire(name);
|
||||
|
||||
PWire*cur = get_wire_in_module(name);
|
||||
|
||||
if (cur) {
|
||||
if ((cur->get_wire_type() != NetNet::IMPLICIT)
|
||||
&& (cur->get_wire_type() != NetNet::IMPLICIT_REG)) {
|
||||
|
|
@ -1130,9 +1230,17 @@ void pform_makewire(const vlltype&li, const char*nm,
|
|||
}
|
||||
}
|
||||
|
||||
if (pform_cur_generate)
|
||||
pform_cur_generate->add_wire(cur);
|
||||
else
|
||||
pform_cur_module->add_wire(cur);
|
||||
}
|
||||
|
||||
/*
|
||||
* This form takes a list of names and some type information, and
|
||||
* generates a bunch of variables/nets. We hse the basic
|
||||
* pform_makewire above.
|
||||
*/
|
||||
void pform_makewire(const vlltype&li,
|
||||
svector<PExpr*>*range,
|
||||
bool signed_flag,
|
||||
|
|
@ -1155,6 +1263,9 @@ void pform_makewire(const vlltype&li,
|
|||
delete range;
|
||||
}
|
||||
|
||||
/*
|
||||
* This form makes nets with delays and continuous assignments.
|
||||
*/
|
||||
void pform_makewire(const vlltype&li,
|
||||
svector<PExpr*>*range,
|
||||
bool signed_flag,
|
||||
|
|
@ -1174,7 +1285,7 @@ void pform_makewire(const vlltype&li,
|
|||
pform_set_net_range(first->name, range, signed_flag, dt);
|
||||
|
||||
hname_t name = hier_name(first->name);
|
||||
PWire*cur = pform_cur_module->get_wire(name);
|
||||
PWire*cur = get_wire_in_module(name);
|
||||
if (cur != 0) {
|
||||
PEIdent*lval = new PEIdent(hname_t(first->name));
|
||||
lval->set_file(li.text);
|
||||
|
|
@ -1596,6 +1707,9 @@ int pform_parse(const char*path, FILE*file)
|
|||
|
||||
/*
|
||||
* $Log: pform.cc,v $
|
||||
* Revision 1.135 2006/04/10 00:37:42 steve
|
||||
* Add support for generate loops w/ wires and gates.
|
||||
*
|
||||
* Revision 1.134 2006/03/30 05:22:34 steve
|
||||
* task/function ports can have types.
|
||||
*
|
||||
|
|
|
|||
21
pform.h
21
pform.h
|
|
@ -19,7 +19,7 @@
|
|||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
||||
*/
|
||||
#ifdef HAVE_CVS_IDENT
|
||||
#ident "$Id: pform.h,v 1.85 2006/03/30 05:22:34 steve Exp $"
|
||||
#ident "$Id: pform.h,v 1.86 2006/04/10 00:37:42 steve Exp $"
|
||||
#endif
|
||||
|
||||
# include "netlist.h"
|
||||
|
|
@ -167,6 +167,22 @@ extern void pform_pop_scope();
|
|||
extern verinum* pform_verinum_with_size(verinum*s, verinum*val,
|
||||
const char*file, unsigned loneno);
|
||||
|
||||
/*
|
||||
* This function takes the list of names as new genvars to declare in
|
||||
* the current module scope.
|
||||
*/
|
||||
extern void pform_genvars(list<perm_string>*names);
|
||||
|
||||
extern void pform_start_generate_for(const struct vlltype&li,
|
||||
char*ident1,
|
||||
PExpr*init,
|
||||
PExpr*test,
|
||||
char*ident2,
|
||||
PExpr*next);
|
||||
extern void pform_generate_block_name(char*name);
|
||||
extern void pform_endgenerate();
|
||||
|
||||
|
||||
/*
|
||||
* The makewire functions announce to the pform code new wires. These
|
||||
* go into a module that is currently opened.
|
||||
|
|
@ -307,6 +323,9 @@ extern void pform_dump(ostream&out, Module*mod);
|
|||
|
||||
/*
|
||||
* $Log: pform.h,v $
|
||||
* Revision 1.86 2006/04/10 00:37:42 steve
|
||||
* Add support for generate loops w/ wires and gates.
|
||||
*
|
||||
* Revision 1.85 2006/03/30 05:22:34 steve
|
||||
* task/function ports can have types.
|
||||
*
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright (c) 1998-2004 Stephen Williams (steve@icarus.com)
|
||||
* Copyright (c) 1998-2006 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
|
||||
|
|
@ -17,7 +17,7 @@
|
|||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
||||
*/
|
||||
#ifdef HAVE_CVS_IDENT
|
||||
#ident "$Id: pform_dump.cc,v 1.91 2005/10/04 04:09:26 steve Exp $"
|
||||
#ident "$Id: pform_dump.cc,v 1.92 2006/04/10 00:37:42 steve Exp $"
|
||||
#endif
|
||||
|
||||
# include "config.h"
|
||||
|
|
@ -30,6 +30,7 @@
|
|||
*/
|
||||
# include "pform.h"
|
||||
# include "PEvent.h"
|
||||
# include "PGenerate.h"
|
||||
# include <iostream>
|
||||
# include <iomanip>
|
||||
# include <typeinfo>
|
||||
|
|
@ -211,9 +212,9 @@ void PEBinary::dump(ostream&out) const
|
|||
}
|
||||
|
||||
|
||||
void PWire::dump(ostream&out) const
|
||||
void PWire::dump(ostream&out, unsigned ind) const
|
||||
{
|
||||
out << " " << type_;
|
||||
out << setw(ind) << "" << type_;
|
||||
|
||||
switch (port_type_) {
|
||||
case NetNet::PIMPLICIT:
|
||||
|
|
@ -303,9 +304,9 @@ void PGate::dump_delays(ostream&out) const
|
|||
delay_.dump_delays(out);
|
||||
}
|
||||
|
||||
void PGate::dump(ostream&out) const
|
||||
void PGate::dump(ostream&out, unsigned ind) const
|
||||
{
|
||||
out << " " << typeid(*this).name() << " ";
|
||||
out << setw(ind) << "" << typeid(*this).name() << " ";
|
||||
delay_.dump_delays(out);
|
||||
out << " " << get_name() << "(";
|
||||
dump_pins(out);
|
||||
|
|
@ -313,15 +314,17 @@ void PGate::dump(ostream&out) const
|
|||
|
||||
}
|
||||
|
||||
void PGAssign::dump(ostream&out) const
|
||||
void PGAssign::dump(ostream&out, unsigned ind) const
|
||||
{
|
||||
out << setw(ind) << "";
|
||||
out << "assign (" << strength0() << "0 " << strength1() << "1) ";
|
||||
dump_delays(out);
|
||||
out << " " << *pin(0) << " = " << *pin(1) << ";" << endl;
|
||||
}
|
||||
|
||||
void PGBuiltin::dump(ostream&out) const
|
||||
void PGBuiltin::dump(ostream&out, unsigned ind) const
|
||||
{
|
||||
out << setw(ind) << "";
|
||||
switch (type()) {
|
||||
case PGBuiltin::BUFIF0:
|
||||
out << "bufif0 ";
|
||||
|
|
@ -367,9 +370,9 @@ void PGBuiltin::dump(ostream&out) const
|
|||
out << ");" << endl;
|
||||
}
|
||||
|
||||
void PGModule::dump(ostream&out) const
|
||||
void PGModule::dump(ostream&out, unsigned ind) const
|
||||
{
|
||||
out << " " << type_ << " ";
|
||||
out << setw(ind) << "" << type_ << " ";
|
||||
|
||||
// If parameters are overridden by order, dump them.
|
||||
if (overrides_) {
|
||||
|
|
@ -731,6 +734,44 @@ void PProcess::dump(ostream&out, unsigned ind) const
|
|||
statement_->dump(out, ind+2);
|
||||
}
|
||||
|
||||
void PGenerate::dump(ostream&out) const
|
||||
{
|
||||
out << " generate(" << id_number << ")";
|
||||
|
||||
switch (scheme_type) {
|
||||
case GS_NONE:
|
||||
break;
|
||||
case GS_LOOP:
|
||||
out << " for ("
|
||||
<< loop_index
|
||||
<< "=" << *loop_init
|
||||
<< "; " << *loop_test
|
||||
<< "; " << loop_index
|
||||
<< "=" << *loop_step << ")";
|
||||
break;
|
||||
case GS_CONDIT:
|
||||
break;
|
||||
}
|
||||
|
||||
if (scope_name)
|
||||
out << " : " << scope_name;
|
||||
|
||||
out << endl;
|
||||
|
||||
for (map<hname_t,PWire*>::const_iterator idx = wires.begin()
|
||||
; idx != wires.end() ; idx++) {
|
||||
|
||||
(*idx).second->dump(out, 6);
|
||||
}
|
||||
|
||||
for (list<PGate*>::const_iterator idx = gates.begin()
|
||||
; idx != gates.end() ; idx++) {
|
||||
(*idx)->dump(out, 6);
|
||||
}
|
||||
|
||||
out << " endgenerate" << endl;
|
||||
}
|
||||
|
||||
void Module::dump(ostream&out) const
|
||||
{
|
||||
if (attributes.begin() != attributes.end()) {
|
||||
|
|
@ -796,6 +837,18 @@ void Module::dump(ostream&out) const
|
|||
out << "/* ERROR */;" << endl;
|
||||
}
|
||||
|
||||
typedef list<perm_string>::const_iterator genvar_iter_t;
|
||||
for (genvar_iter_t cur = genvars.begin()
|
||||
; cur != genvars.end() ; cur++) {
|
||||
out << " genvar " << (*cur) << ";" << endl;
|
||||
}
|
||||
|
||||
typedef list<PGenerate*>::const_iterator genscheme_iter_t;
|
||||
for (genscheme_iter_t cur = generate_schemes.begin()
|
||||
; cur != generate_schemes.end() ; cur++) {
|
||||
(*cur)->dump(out);
|
||||
}
|
||||
|
||||
typedef map<perm_string,PExpr*>::const_iterator specparm_iter_t;
|
||||
for (specparm_iter_t cur = specparams.begin()
|
||||
; cur != specparams.end() ; cur ++) {
|
||||
|
|
@ -914,6 +967,9 @@ void PUdp::dump(ostream&out) const
|
|||
|
||||
/*
|
||||
* $Log: pform_dump.cc,v $
|
||||
* Revision 1.92 2006/04/10 00:37:42 steve
|
||||
* Add support for generate loops w/ wires and gates.
|
||||
*
|
||||
* Revision 1.91 2005/10/04 04:09:26 steve
|
||||
* Add support for indexed select attached to parameters.
|
||||
*
|
||||
|
|
|
|||
9
t-dll.cc
9
t-dll.cc
|
|
@ -17,7 +17,7 @@
|
|||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
||||
*/
|
||||
#ifdef HAVE_CVS_IDENT
|
||||
#ident "$Id: t-dll.cc,v 1.155 2006/01/02 05:33:19 steve Exp $"
|
||||
#ident "$Id: t-dll.cc,v 1.156 2006/04/10 00:37:42 steve Exp $"
|
||||
#endif
|
||||
|
||||
# include "config.h"
|
||||
|
|
@ -2018,6 +2018,10 @@ void dll_target::scope(const NetScope*net)
|
|||
scope->type_ = IVL_SCT_FORK;
|
||||
scope->tname_ = scope->name_;
|
||||
break;
|
||||
case NetScope::GENBLOCK:
|
||||
scope->type_ = IVL_SCT_GENERATE;
|
||||
scope->tname_ = scope->name_;
|
||||
break;
|
||||
}
|
||||
|
||||
assert(scope->parent != 0);
|
||||
|
|
@ -2163,6 +2167,9 @@ extern const struct target tgt_dll = { "dll", &dll_target_obj };
|
|||
|
||||
/*
|
||||
* $Log: t-dll.cc,v $
|
||||
* Revision 1.156 2006/04/10 00:37:42 steve
|
||||
* Add support for generate loops w/ wires and gates.
|
||||
*
|
||||
* Revision 1.155 2006/01/02 05:33:19 steve
|
||||
* Node delays can be more general expressions in structural contexts.
|
||||
*
|
||||
|
|
|
|||
|
|
@ -17,7 +17,7 @@
|
|||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
||||
*/
|
||||
#ifdef HAVE_CVS_IDENT
|
||||
#ident "$Id: vvp_scope.c,v 1.142 2006/03/18 22:53:38 steve Exp $"
|
||||
#ident "$Id: vvp_scope.c,v 1.143 2006/04/10 00:37:42 steve Exp $"
|
||||
#endif
|
||||
|
||||
# include "vvp_priv.h"
|
||||
|
|
@ -2107,6 +2107,7 @@ int draw_scope(ivl_scope_t net, ivl_scope_t parent)
|
|||
case IVL_SCT_TASK: type = "task"; break;
|
||||
case IVL_SCT_BEGIN: type = "begin"; break;
|
||||
case IVL_SCT_FORK: type = "fork"; break;
|
||||
case IVL_SCT_GENERATE: type = "generate"; break;
|
||||
default: type = "?"; assert(0);
|
||||
}
|
||||
|
||||
|
|
@ -2204,6 +2205,9 @@ int draw_scope(ivl_scope_t net, ivl_scope_t parent)
|
|||
|
||||
/*
|
||||
* $Log: vvp_scope.c,v $
|
||||
* Revision 1.143 2006/04/10 00:37:42 steve
|
||||
* Add support for generate loops w/ wires and gates.
|
||||
*
|
||||
* Revision 1.142 2006/03/18 22:53:38 steve
|
||||
* Support more parameter syntax.
|
||||
*
|
||||
|
|
|
|||
|
|
@ -17,7 +17,7 @@
|
|||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
||||
*/
|
||||
#ifdef HAVE_CVS_IDENT
|
||||
#ident "$Id: vpi_scope.cc,v 1.35 2006/03/06 05:43:15 steve Exp $"
|
||||
#ident "$Id: vpi_scope.cc,v 1.36 2006/04/10 00:37:43 steve Exp $"
|
||||
#endif
|
||||
|
||||
# include "compile.h"
|
||||
|
|
@ -292,23 +292,21 @@ compile_scope_decl(char*label, char*type, char*name, char*tname, char*parent)
|
|||
struct __vpiScope*scope = new struct __vpiScope;
|
||||
count_vpi_scopes += 1;
|
||||
|
||||
switch(type[2]) {
|
||||
case 'd': /* type == moDule */
|
||||
if (strcmp(type,"module") == 0)
|
||||
scope->base.vpi_type = &vpip_scope_module_rt;
|
||||
break;
|
||||
case 'n': /* type == fuNction */
|
||||
else if (strcmp(type,"function") == 0)
|
||||
scope->base.vpi_type = &vpip_scope_function_rt;
|
||||
break;
|
||||
case 's': /* type == taSk */
|
||||
else if (strcmp(type,"task") == 0)
|
||||
scope->base.vpi_type = &vpip_scope_task_rt;
|
||||
break;
|
||||
case 'r': /* type == foRk */
|
||||
else if (strcmp(type,"fork") == 0)
|
||||
scope->base.vpi_type = &vpip_scope_fork_rt;
|
||||
break;
|
||||
case 'g': /* type == beGin */
|
||||
else if (strcmp(type,"begin") == 0)
|
||||
scope->base.vpi_type = &vpip_scope_begin_rt;
|
||||
break;
|
||||
default:
|
||||
else if (strcmp(type,"generate") == 0)
|
||||
// Generate blocks are not really modules, but this is a
|
||||
// hack that will work for now.
|
||||
scope->base.vpi_type = &vpip_scope_module_rt;
|
||||
else {
|
||||
scope->base.vpi_type = &vpip_scope_module_rt;
|
||||
assert(0);
|
||||
}
|
||||
|
|
@ -389,6 +387,9 @@ void vpip_attach_to_current_scope(vpiHandle obj)
|
|||
|
||||
/*
|
||||
* $Log: vpi_scope.cc,v $
|
||||
* Revision 1.36 2006/04/10 00:37:43 steve
|
||||
* Add support for generate loops w/ wires and gates.
|
||||
*
|
||||
* Revision 1.35 2006/03/06 05:43:15 steve
|
||||
* Cleanup vpi_const to use vec4 values.
|
||||
*
|
||||
|
|
|
|||
Loading…
Reference in New Issue