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
|
# 59 Temple Place - Suite 330
|
||||||
# Boston, MA 02111-1307, USA
|
# 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
|
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 \
|
set_width.o symbol_search.o sync.o sys_funcs.o \
|
||||||
verinum.o verireal.o target.o targets.o \
|
verinum.o verireal.o target.o targets.o \
|
||||||
Attrib.o HName.o LineInfo.o Module.o PDelays.o PEvent.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 \
|
PTask.o PUdp.o PFunction.o PWire.o Statement.o StringHeap.o \
|
||||||
$(FF) $(TT)
|
$(FF) $(TT)
|
||||||
|
|
||||||
|
|
|
||||||
55
Module.h
55
Module.h
|
|
@ -19,7 +19,7 @@
|
||||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
||||||
*/
|
*/
|
||||||
#ifdef HAVE_CVS_IDENT
|
#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
|
#endif
|
||||||
|
|
||||||
# include <list>
|
# include <list>
|
||||||
|
|
@ -34,6 +34,7 @@ class PEvent;
|
||||||
class PExpr;
|
class PExpr;
|
||||||
class PEIdent;
|
class PEIdent;
|
||||||
class PGate;
|
class PGate;
|
||||||
|
class PGenerate;
|
||||||
class PTask;
|
class PTask;
|
||||||
class PFunction;
|
class PFunction;
|
||||||
class PWire;
|
class PWire;
|
||||||
|
|
@ -113,6 +114,14 @@ class Module : public LineInfo {
|
||||||
set by the `timescale directive. */
|
set by the `timescale directive. */
|
||||||
int time_unit, time_precision;
|
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_; }
|
perm_string mod_name() const { return name_; }
|
||||||
|
|
||||||
void add_gate(PGate*gate);
|
void add_gate(PGate*gate);
|
||||||
|
|
@ -164,51 +173,13 @@ class Module : public LineInfo {
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* $Log: Module.h,v $
|
* $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
|
* Revision 1.39 2006/03/30 01:49:07 steve
|
||||||
* Fix instance arrays indexed by overridden parameters.
|
* Fix instance arrays indexed by overridden parameters.
|
||||||
*
|
*
|
||||||
* Revision 1.38 2005/07/11 16:56:50 steve
|
* Revision 1.38 2005/07/11 16:56:50 steve
|
||||||
* Remove NetVariable and ivl_variable_t structures.
|
* 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
|
#endif
|
||||||
|
|
|
||||||
13
PGate.h
13
PGate.h
|
|
@ -19,7 +19,7 @@
|
||||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
||||||
*/
|
*/
|
||||||
#ifdef HAVE_CVS_IDENT
|
#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
|
#endif
|
||||||
|
|
||||||
# include "svector.h"
|
# include "svector.h"
|
||||||
|
|
@ -94,7 +94,7 @@ class PGate : public LineInfo {
|
||||||
|
|
||||||
map<perm_string,PExpr*> attributes;
|
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(Design*des, NetScope*scope) const;
|
||||||
virtual void elaborate_scope(Design*des, NetScope*sc) const;
|
virtual void elaborate_scope(Design*des, NetScope*sc) const;
|
||||||
virtual bool elaborate_sig(Design*des, NetScope*scope) 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);
|
explicit PGAssign(svector<PExpr*>*pins, svector<PExpr*>*dels);
|
||||||
~PGAssign();
|
~PGAssign();
|
||||||
|
|
||||||
void dump(ostream&out) const;
|
void dump(ostream&out, unsigned ind =4) const;
|
||||||
virtual void elaborate(Design*des, NetScope*scope) const;
|
virtual void elaborate(Design*des, NetScope*scope) const;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
@ -165,7 +165,7 @@ class PGBuiltin : public PGate {
|
||||||
Type type() const { return type_; }
|
Type type() const { return type_; }
|
||||||
void set_range(PExpr*msb, PExpr*lsb);
|
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(Design*, NetScope*scope) const;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
@ -208,7 +208,7 @@ class PGModule : public PGate {
|
||||||
// method to pass the range to the pform.
|
// method to pass the range to the pform.
|
||||||
void set_range(PExpr*msb, PExpr*lsb);
|
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(Design*, NetScope*scope) const;
|
||||||
virtual void elaborate_scope(Design*des, NetScope*sc) const;
|
virtual void elaborate_scope(Design*des, NetScope*sc) const;
|
||||||
virtual bool elaborate_sig(Design*des, NetScope*scope) const;
|
virtual bool elaborate_sig(Design*des, NetScope*scope) const;
|
||||||
|
|
@ -239,6 +239,9 @@ class PGModule : public PGate {
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* $Log: PGate.h,v $
|
* $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
|
* Revision 1.31 2006/01/03 05:22:14 steve
|
||||||
* Handle complex net node delays.
|
* 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
|
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
||||||
*/
|
*/
|
||||||
#ifdef HAVE_CVS_IDENT
|
#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
|
#endif
|
||||||
|
|
||||||
# include "netlist.h"
|
# include "netlist.h"
|
||||||
|
|
@ -81,7 +81,7 @@ class PWire : public LineInfo {
|
||||||
map<perm_string,PExpr*> attributes;
|
map<perm_string,PExpr*> attributes;
|
||||||
|
|
||||||
// Write myself to the specified stream.
|
// 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;
|
void elaborate_sig(Design*, NetScope*scope) const;
|
||||||
|
|
||||||
|
|
@ -110,6 +110,9 @@ class PWire : public LineInfo {
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* $Log: PWire.h,v $
|
* $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
|
* Revision 1.18 2005/07/07 16:22:49 steve
|
||||||
* Generalize signals to carry types.
|
* Generalize signals to carry types.
|
||||||
*
|
*
|
||||||
|
|
|
||||||
|
|
@ -17,7 +17,7 @@
|
||||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
||||||
*/
|
*/
|
||||||
#ifdef HAVE_CVS_IDENT
|
#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
|
#endif
|
||||||
|
|
||||||
# include "config.h"
|
# include "config.h"
|
||||||
|
|
@ -811,6 +811,9 @@ void NetScope::dump(ostream&o) const
|
||||||
case TASK:
|
case TASK:
|
||||||
o << " task";
|
o << " task";
|
||||||
break;
|
break;
|
||||||
|
case GENBLOCK:
|
||||||
|
o << " generate block";
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
o << endl;
|
o << endl;
|
||||||
|
|
||||||
|
|
@ -1170,6 +1173,9 @@ void Design::dump(ostream&o) const
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* $Log: design_dump.cc,v $
|
* $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
|
* Revision 1.164 2006/02/02 02:43:57 steve
|
||||||
* Allow part selects of memory words in l-values.
|
* 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
|
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
||||||
*/
|
*/
|
||||||
#ifdef HAVE_CVS_IDENT
|
#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
|
#endif
|
||||||
|
|
||||||
# include "config.h"
|
# include "config.h"
|
||||||
|
|
@ -37,6 +37,7 @@
|
||||||
# include "PEvent.h"
|
# include "PEvent.h"
|
||||||
# include "PExpr.h"
|
# include "PExpr.h"
|
||||||
# include "PGate.h"
|
# include "PGate.h"
|
||||||
|
# include "PGenerate.h"
|
||||||
# include "PTask.h"
|
# include "PTask.h"
|
||||||
# include "PWire.h"
|
# include "PWire.h"
|
||||||
# include "Statement.h"
|
# include "Statement.h"
|
||||||
|
|
@ -220,6 +221,17 @@ bool Module::elaborate_scope(Design*des, NetScope*scope,
|
||||||
|
|
||||||
delete[]attr;
|
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
|
// Tasks introduce new scopes, so scan the tasks in this
|
||||||
// module. Create a scope for the task and pass that to the
|
// 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;
|
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
|
void PGModule::elaborate_scope_mod_(Design*des, Module*mod, NetScope*sc) const
|
||||||
{
|
{
|
||||||
if (get_name() == "") {
|
if (get_name() == "") {
|
||||||
|
|
@ -635,6 +742,9 @@ void PWhile::elaborate_scope(Design*des, NetScope*scope) const
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* $Log: elab_scope.cc,v $
|
* $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
|
* Revision 1.38 2006/03/30 01:49:07 steve
|
||||||
* Fix instance arrays indexed by overridden parameters.
|
* 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
|
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
||||||
*/
|
*/
|
||||||
#ifdef HAVE_CVS_IDENT
|
#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
|
#endif
|
||||||
|
|
||||||
# include "config.h"
|
# include "config.h"
|
||||||
|
|
@ -27,6 +27,7 @@
|
||||||
# include "Module.h"
|
# include "Module.h"
|
||||||
# include "PExpr.h"
|
# include "PExpr.h"
|
||||||
# include "PGate.h"
|
# include "PGate.h"
|
||||||
|
# include "PGenerate.h"
|
||||||
# include "PTask.h"
|
# include "PTask.h"
|
||||||
# include "PWire.h"
|
# include "PWire.h"
|
||||||
# include "compiler.h"
|
# include "compiler.h"
|
||||||
|
|
@ -158,6 +159,16 @@ bool Module::elaborate_sig(Design*des, NetScope*scope) const
|
||||||
des->errors += 1;
|
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
|
// 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;
|
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
|
* A function definition exists within an elaborated module. This
|
||||||
* matters when elaborating signals, as the ports of the function are
|
* 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 $
|
* $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
|
* Revision 1.40 2005/07/11 16:56:50 steve
|
||||||
* Remove NetVariable and ivl_variable_t structures.
|
* 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
|
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
||||||
*/
|
*/
|
||||||
#ifdef HAVE_CVS_IDENT
|
#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
|
#endif
|
||||||
|
|
||||||
# include "config.h"
|
# include "config.h"
|
||||||
|
|
@ -34,6 +34,7 @@
|
||||||
# include <list>
|
# include <list>
|
||||||
# include "pform.h"
|
# include "pform.h"
|
||||||
# include "PEvent.h"
|
# include "PEvent.h"
|
||||||
|
# include "PGenerate.h"
|
||||||
# include "netlist.h"
|
# include "netlist.h"
|
||||||
# include "netmisc.h"
|
# include "netmisc.h"
|
||||||
# include "util.h"
|
# include "util.h"
|
||||||
|
|
@ -2846,6 +2847,12 @@ bool Module::elaborate(Design*des, NetScope*scope) const
|
||||||
{
|
{
|
||||||
bool result_flag = true;
|
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.
|
// Elaborate functions.
|
||||||
typedef map<perm_string,PFunction*>::const_iterator mfunc_it_t;
|
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;
|
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 {
|
struct root_elem {
|
||||||
Module *mod;
|
Module *mod;
|
||||||
NetScope *scope;
|
NetScope *scope;
|
||||||
|
|
@ -2981,6 +3017,7 @@ Design* elaborate(list<perm_string>roots)
|
||||||
// module and elaborate what I find.
|
// module and elaborate what I find.
|
||||||
Design*des = new Design;
|
Design*des = new Design;
|
||||||
|
|
||||||
|
// Scan the root modules, and elaborate their scopes.
|
||||||
for (list<perm_string>::const_iterator root = roots.begin()
|
for (list<perm_string>::const_iterator root = roots.begin()
|
||||||
; root != roots.end()
|
; root != roots.end()
|
||||||
; root++) {
|
; root++) {
|
||||||
|
|
@ -2996,6 +3033,7 @@ Design* elaborate(list<perm_string>roots)
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Get the module definition for this root instance.
|
||||||
Module *rmod = (*mod).second;
|
Module *rmod = (*mod).second;
|
||||||
|
|
||||||
// Make the root scope.
|
// Make the root scope.
|
||||||
|
|
@ -3006,7 +3044,9 @@ Design* elaborate(list<perm_string>roots)
|
||||||
des->set_precision(rmod->time_precision);
|
des->set_precision(rmod->time_precision);
|
||||||
|
|
||||||
Module::replace_t stub;
|
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)) {
|
if (! rmod->elaborate_scope(des, scope, stub)) {
|
||||||
delete des;
|
delete des;
|
||||||
return 0;
|
return 0;
|
||||||
|
|
@ -3071,6 +3111,9 @@ Design* elaborate(list<perm_string>roots)
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* $Log: elaborate.cc,v $
|
* $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
|
* Revision 1.335 2006/03/30 01:49:07 steve
|
||||||
* Fix instance arrays indexed by overridden parameters.
|
* 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
|
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
||||||
*/
|
*/
|
||||||
#ifdef HAVE_CVS_IDENT
|
#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
|
#endif
|
||||||
|
|
||||||
# include "config.h"
|
# 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
|
verinum* PEIdent::eval_const(const Design*des, NetScope*scope) const
|
||||||
{
|
{
|
||||||
assert(scope);
|
assert(scope);
|
||||||
//const NetExpr*expr = des->find_parameter(scope, path_);
|
|
||||||
NetNet*net;
|
NetNet*net;
|
||||||
NetMemory*mem;
|
NetMemory*mem;
|
||||||
NetEvent*eve;
|
NetEvent*eve;
|
||||||
const NetExpr*expr;
|
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_,
|
NetScope*found_in = symbol_search(des, scope, path_,
|
||||||
net, mem, expr, eve);
|
net, mem, expr, eve);
|
||||||
|
|
||||||
|
|
@ -263,6 +271,9 @@ verinum* PEUnary::eval_const(const Design*des, NetScope*scope) const
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* $Log: eval.cc,v $
|
* $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
|
* Revision 1.39 2005/12/07 04:04:23 steve
|
||||||
* Allow constant concat expressions.
|
* Allow constant concat expressions.
|
||||||
*
|
*
|
||||||
|
|
|
||||||
|
|
@ -19,7 +19,7 @@
|
||||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
||||||
*/
|
*/
|
||||||
#ifdef HAVE_CVS_IDENT
|
#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
|
#endif
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
|
|
@ -266,7 +266,8 @@ typedef enum ivl_scope_type_e {
|
||||||
IVL_SCT_FUNCTION= 1,
|
IVL_SCT_FUNCTION= 1,
|
||||||
IVL_SCT_TASK = 2,
|
IVL_SCT_TASK = 2,
|
||||||
IVL_SCT_BEGIN = 3,
|
IVL_SCT_BEGIN = 3,
|
||||||
IVL_SCT_FORK = 4
|
IVL_SCT_FORK = 4,
|
||||||
|
IVL_SCT_GENERATE= 5
|
||||||
} ivl_scope_type_t;
|
} ivl_scope_type_t;
|
||||||
|
|
||||||
/* Signals (ivl_signal_t) that are ports into the scope that contains
|
/* Signals (ivl_signal_t) that are ports into the scope that contains
|
||||||
|
|
@ -1707,6 +1708,9 @@ _END_DECL
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* $Log: ivl_target.h,v $
|
* $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
|
* Revision 1.165 2006/02/02 02:43:58 steve
|
||||||
* Allow part selects of memory words in l-values.
|
* Allow part selects of memory words in l-values.
|
||||||
*
|
*
|
||||||
|
|
|
||||||
|
|
@ -31,6 +31,7 @@ else, K_else
|
||||||
end, K_end
|
end, K_end
|
||||||
endcase, K_endcase
|
endcase, K_endcase
|
||||||
endfunction, K_endfunction
|
endfunction, K_endfunction
|
||||||
|
endgenerate, K_endgenerate
|
||||||
endmodule, K_endmodule
|
endmodule, K_endmodule
|
||||||
endprimitive, K_endprimitive
|
endprimitive, K_endprimitive
|
||||||
endspecify, K_endspecify
|
endspecify, K_endspecify
|
||||||
|
|
@ -42,6 +43,8 @@ force, K_force
|
||||||
forever, K_forever
|
forever, K_forever
|
||||||
fork, K_fork
|
fork, K_fork
|
||||||
function, K_function
|
function, K_function
|
||||||
|
generate, K_generate
|
||||||
|
genvar, K_genvar
|
||||||
highz0, K_highz0
|
highz0, K_highz0
|
||||||
highz1, K_highz1
|
highz1, K_highz1
|
||||||
if, K_if
|
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
|
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
||||||
*/
|
*/
|
||||||
#ifdef HAVE_CVS_IDENT
|
#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
|
#endif
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|
@ -3137,7 +3137,7 @@ class NetESignal : public NetExpr {
|
||||||
class NetScope : public Attrib {
|
class NetScope : public Attrib {
|
||||||
|
|
||||||
public:
|
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
|
/* Create a new scope, and attach it to the given parent. The
|
||||||
name is expected to have been permallocated. */
|
name is expected to have been permallocated. */
|
||||||
|
|
@ -3281,6 +3281,12 @@ class NetScope : public Attrib {
|
||||||
typedef svector<NetScope*> scope_vec_t;
|
typedef svector<NetScope*> scope_vec_t;
|
||||||
map<perm_string, scope_vec_t>instance_arrays;
|
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:
|
private:
|
||||||
TYPE type_;
|
TYPE type_;
|
||||||
perm_string name_;
|
perm_string name_;
|
||||||
|
|
@ -3458,6 +3464,9 @@ extern ostream& operator << (ostream&, NetNet::Type);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* $Log: netlist.h,v $
|
* $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
|
* Revision 1.356 2006/03/18 22:53:04 steve
|
||||||
* Properly handle signedness in compare.
|
* 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
|
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
||||||
*/
|
*/
|
||||||
#ifdef HAVE_CVS_IDENT
|
#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
|
#endif
|
||||||
|
|
||||||
# include "config.h"
|
# 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_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_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_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_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_initial K_inout K_input K_integer K_join K_large K_localparam
|
||||||
%token K_logic K_macromodule
|
%token K_logic K_macromodule
|
||||||
%token K_medium K_module K_nand K_negedge K_nmos K_nor K_not K_notif0
|
%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;
|
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. */
|
/* specify blocks are parsed but ignored. */
|
||||||
|
|
||||||
| K_specify K_endspecify
|
| 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
|
/* A net declaration assignment allows the programmer to combine the
|
||||||
net declaration and the continuous assignment into a single
|
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
|
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
||||||
*/
|
*/
|
||||||
#ifdef HAVE_CVS_IDENT
|
#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
|
#endif
|
||||||
|
|
||||||
# include "config.h"
|
# include "config.h"
|
||||||
|
|
@ -28,6 +28,7 @@
|
||||||
# include "parse_api.h"
|
# include "parse_api.h"
|
||||||
# include "PEvent.h"
|
# include "PEvent.h"
|
||||||
# include "PUdp.h"
|
# include "PUdp.h"
|
||||||
|
# include "PGenerate.h"
|
||||||
# include <list>
|
# include <list>
|
||||||
# include <map>
|
# include <map>
|
||||||
# include <assert.h>
|
# include <assert.h>
|
||||||
|
|
@ -44,7 +45,17 @@ string vl_file = "";
|
||||||
|
|
||||||
extern int VLparse();
|
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;
|
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;
|
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
|
* 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
|
* leave a scope the pop function is called. Entering tasks, functions
|
||||||
* and named blocks causes scope to be pushed and popped. The module
|
* 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
|
* The hier_name function, therefore, converts the name to the scope
|
||||||
* function relative the current function.
|
* of the module currently in progress.
|
||||||
|
*
|
||||||
|
* The scope stack does not include any scope created by a generate
|
||||||
|
* scheme.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
static hname_t scope_stack;
|
static hname_t scope_stack;
|
||||||
|
|
@ -90,6 +104,18 @@ static hname_t hier_name(const char*tail)
|
||||||
return name;
|
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,
|
void pform_set_default_nettype(NetNet::Type type,
|
||||||
const char*file, unsigned lineno)
|
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_file(file);
|
||||||
pform_cur_module->set_lineno(lineno);
|
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
|
if (warn_timescale && pform_timescale_file
|
||||||
&& (strcmp(pform_timescale_file,file) != 0)) {
|
&& (strcmp(pform_timescale_file,file) != 0)) {
|
||||||
|
|
||||||
|
|
@ -292,6 +322,58 @@ void pform_endmodule(const char*name)
|
||||||
pform_cur_module = 0;
|
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)
|
bool pform_expression_is_constant(const PExpr*ex)
|
||||||
{
|
{
|
||||||
return ex->is_constant(pform_cur_module);
|
return ex->is_constant(pform_cur_module);
|
||||||
|
|
@ -695,8 +777,7 @@ static void pform_set_net_range(const char* name,
|
||||||
bool signed_flag,
|
bool signed_flag,
|
||||||
ivl_variable_type_t dt)
|
ivl_variable_type_t dt)
|
||||||
{
|
{
|
||||||
|
PWire*cur = get_wire_in_module(hier_name(name));
|
||||||
PWire*cur = pform_cur_module->get_wire(hier_name(name));
|
|
||||||
if (cur == 0) {
|
if (cur == 0) {
|
||||||
VLerror("error: name is not a valid net.");
|
VLerror("error: name is not a valid net.");
|
||||||
return;
|
return;
|
||||||
|
|
@ -796,6 +877,9 @@ void pform_makegate(PGBuiltin::Type type,
|
||||||
cur->set_file(info.file);
|
cur->set_file(info.file);
|
||||||
cur->set_lineno(info.lineno);
|
cur->set_lineno(info.lineno);
|
||||||
|
|
||||||
|
if (pform_cur_generate)
|
||||||
|
pform_cur_generate->add_gate(cur);
|
||||||
|
else
|
||||||
pform_cur_module->add_gate(cur);
|
pform_cur_module->add_gate(cur);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -854,6 +938,9 @@ static void pform_make_modgate(perm_string type,
|
||||||
cur->set_parameters(overrides->by_order);
|
cur->set_parameters(overrides->by_order);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (pform_cur_generate)
|
||||||
|
pform_cur_generate->add_gate(cur);
|
||||||
|
else
|
||||||
pform_cur_module->add_gate(cur);
|
pform_cur_module->add_gate(cur);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -956,7 +1043,11 @@ static PGAssign* pform_make_pgassign(PExpr*lval, PExpr*rval,
|
||||||
cur->strength0(str.str0);
|
cur->strength0(str.str0);
|
||||||
cur->strength1(str.str1);
|
cur->strength1(str.str1);
|
||||||
|
|
||||||
|
if (pform_cur_generate)
|
||||||
|
pform_cur_generate->add_gate(cur);
|
||||||
|
else
|
||||||
pform_cur_module->add_gate(cur);
|
pform_cur_module->add_gate(cur);
|
||||||
|
|
||||||
return 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
|
* do check to see if the name has already been declared, as this
|
||||||
* function is called for every declaration.
|
* 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,
|
void pform_makewire(const vlltype&li, const char*nm,
|
||||||
NetNet::Type type, NetNet::PortType pt,
|
NetNet::Type type, NetNet::PortType pt,
|
||||||
ivl_variable_type_t dt,
|
ivl_variable_type_t dt,
|
||||||
svector<named_pexpr_t*>*attr)
|
svector<named_pexpr_t*>*attr)
|
||||||
{
|
{
|
||||||
hname_t name = hier_name(nm);
|
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) {
|
||||||
if ((cur->get_wire_type() != NetNet::IMPLICIT)
|
if ((cur->get_wire_type() != NetNet::IMPLICIT)
|
||||||
&& (cur->get_wire_type() != NetNet::IMPLICIT_REG)) {
|
&& (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);
|
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,
|
void pform_makewire(const vlltype&li,
|
||||||
svector<PExpr*>*range,
|
svector<PExpr*>*range,
|
||||||
bool signed_flag,
|
bool signed_flag,
|
||||||
|
|
@ -1155,6 +1263,9 @@ void pform_makewire(const vlltype&li,
|
||||||
delete range;
|
delete range;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* This form makes nets with delays and continuous assignments.
|
||||||
|
*/
|
||||||
void pform_makewire(const vlltype&li,
|
void pform_makewire(const vlltype&li,
|
||||||
svector<PExpr*>*range,
|
svector<PExpr*>*range,
|
||||||
bool signed_flag,
|
bool signed_flag,
|
||||||
|
|
@ -1174,7 +1285,7 @@ void pform_makewire(const vlltype&li,
|
||||||
pform_set_net_range(first->name, range, signed_flag, dt);
|
pform_set_net_range(first->name, range, signed_flag, dt);
|
||||||
|
|
||||||
hname_t name = hier_name(first->name);
|
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) {
|
if (cur != 0) {
|
||||||
PEIdent*lval = new PEIdent(hname_t(first->name));
|
PEIdent*lval = new PEIdent(hname_t(first->name));
|
||||||
lval->set_file(li.text);
|
lval->set_file(li.text);
|
||||||
|
|
@ -1596,6 +1707,9 @@ int pform_parse(const char*path, FILE*file)
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* $Log: pform.cc,v $
|
* $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
|
* Revision 1.134 2006/03/30 05:22:34 steve
|
||||||
* task/function ports can have types.
|
* 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
|
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
||||||
*/
|
*/
|
||||||
#ifdef HAVE_CVS_IDENT
|
#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
|
#endif
|
||||||
|
|
||||||
# include "netlist.h"
|
# include "netlist.h"
|
||||||
|
|
@ -167,6 +167,22 @@ extern void pform_pop_scope();
|
||||||
extern verinum* pform_verinum_with_size(verinum*s, verinum*val,
|
extern verinum* pform_verinum_with_size(verinum*s, verinum*val,
|
||||||
const char*file, unsigned loneno);
|
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
|
* The makewire functions announce to the pform code new wires. These
|
||||||
* go into a module that is currently opened.
|
* go into a module that is currently opened.
|
||||||
|
|
@ -307,6 +323,9 @@ extern void pform_dump(ostream&out, Module*mod);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* $Log: pform.h,v $
|
* $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
|
* Revision 1.85 2006/03/30 05:22:34 steve
|
||||||
* task/function ports can have types.
|
* 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
|
* This source code is free software; you can redistribute it
|
||||||
* and/or modify it in source code form under the terms of the GNU
|
* 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
|
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
||||||
*/
|
*/
|
||||||
#ifdef HAVE_CVS_IDENT
|
#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
|
#endif
|
||||||
|
|
||||||
# include "config.h"
|
# include "config.h"
|
||||||
|
|
@ -30,6 +30,7 @@
|
||||||
*/
|
*/
|
||||||
# include "pform.h"
|
# include "pform.h"
|
||||||
# include "PEvent.h"
|
# include "PEvent.h"
|
||||||
|
# include "PGenerate.h"
|
||||||
# include <iostream>
|
# include <iostream>
|
||||||
# include <iomanip>
|
# include <iomanip>
|
||||||
# include <typeinfo>
|
# 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_) {
|
switch (port_type_) {
|
||||||
case NetNet::PIMPLICIT:
|
case NetNet::PIMPLICIT:
|
||||||
|
|
@ -303,9 +304,9 @@ void PGate::dump_delays(ostream&out) const
|
||||||
delay_.dump_delays(out);
|
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);
|
delay_.dump_delays(out);
|
||||||
out << " " << get_name() << "(";
|
out << " " << get_name() << "(";
|
||||||
dump_pins(out);
|
dump_pins(out);
|
||||||
|
|
@ -313,45 +314,47 @@ void PGate::dump(ostream&out) const
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void PGAssign::dump(ostream&out) const
|
void PGAssign::dump(ostream&out, unsigned ind) const
|
||||||
{
|
{
|
||||||
out << " assign (" << strength0() << "0 " << strength1() << "1) ";
|
out << setw(ind) << "";
|
||||||
|
out << "assign (" << strength0() << "0 " << strength1() << "1) ";
|
||||||
dump_delays(out);
|
dump_delays(out);
|
||||||
out << " " << *pin(0) << " = " << *pin(1) << ";" << endl;
|
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()) {
|
switch (type()) {
|
||||||
case PGBuiltin::BUFIF0:
|
case PGBuiltin::BUFIF0:
|
||||||
out << " bufif0 ";
|
out << "bufif0 ";
|
||||||
break;
|
break;
|
||||||
case PGBuiltin::BUFIF1:
|
case PGBuiltin::BUFIF1:
|
||||||
out << " bufif1 ";
|
out << "bufif1 ";
|
||||||
break;
|
break;
|
||||||
case PGBuiltin::NOTIF0:
|
case PGBuiltin::NOTIF0:
|
||||||
out << " bufif0 ";
|
out << "bufif0 ";
|
||||||
break;
|
break;
|
||||||
case PGBuiltin::NOTIF1:
|
case PGBuiltin::NOTIF1:
|
||||||
out << " bufif1 ";
|
out << "bufif1 ";
|
||||||
break;
|
break;
|
||||||
case PGBuiltin::NAND:
|
case PGBuiltin::NAND:
|
||||||
out << " nand ";
|
out << "nand ";
|
||||||
break;
|
break;
|
||||||
case PGBuiltin::NMOS:
|
case PGBuiltin::NMOS:
|
||||||
out << " nmos ";
|
out << "nmos ";
|
||||||
break;
|
break;
|
||||||
case PGBuiltin::RNMOS:
|
case PGBuiltin::RNMOS:
|
||||||
out << " rnmos ";
|
out << "rnmos ";
|
||||||
break;
|
break;
|
||||||
case PGBuiltin::RPMOS:
|
case PGBuiltin::RPMOS:
|
||||||
out << " rpmos ";
|
out << "rpmos ";
|
||||||
break;
|
break;
|
||||||
case PGBuiltin::PMOS:
|
case PGBuiltin::PMOS:
|
||||||
out << " pmos ";
|
out << "pmos ";
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
out << " builtin gate ";
|
out << "builtin gate ";
|
||||||
}
|
}
|
||||||
|
|
||||||
out << "(" << strength0() << "0 " << strength1() << "1) ";
|
out << "(" << strength0() << "0 " << strength1() << "1) ";
|
||||||
|
|
@ -367,9 +370,9 @@ void PGBuiltin::dump(ostream&out) const
|
||||||
out << ");" << endl;
|
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 parameters are overridden by order, dump them.
|
||||||
if (overrides_) {
|
if (overrides_) {
|
||||||
|
|
@ -731,6 +734,44 @@ void PProcess::dump(ostream&out, unsigned ind) const
|
||||||
statement_->dump(out, ind+2);
|
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
|
void Module::dump(ostream&out) const
|
||||||
{
|
{
|
||||||
if (attributes.begin() != attributes.end()) {
|
if (attributes.begin() != attributes.end()) {
|
||||||
|
|
@ -796,6 +837,18 @@ void Module::dump(ostream&out) const
|
||||||
out << "/* ERROR */;" << endl;
|
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;
|
typedef map<perm_string,PExpr*>::const_iterator specparm_iter_t;
|
||||||
for (specparm_iter_t cur = specparams.begin()
|
for (specparm_iter_t cur = specparams.begin()
|
||||||
; cur != specparams.end() ; cur ++) {
|
; cur != specparams.end() ; cur ++) {
|
||||||
|
|
@ -914,6 +967,9 @@ void PUdp::dump(ostream&out) const
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* $Log: pform_dump.cc,v $
|
* $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
|
* Revision 1.91 2005/10/04 04:09:26 steve
|
||||||
* Add support for indexed select attached to parameters.
|
* 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
|
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
||||||
*/
|
*/
|
||||||
#ifdef HAVE_CVS_IDENT
|
#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
|
#endif
|
||||||
|
|
||||||
# include "config.h"
|
# include "config.h"
|
||||||
|
|
@ -2018,6 +2018,10 @@ void dll_target::scope(const NetScope*net)
|
||||||
scope->type_ = IVL_SCT_FORK;
|
scope->type_ = IVL_SCT_FORK;
|
||||||
scope->tname_ = scope->name_;
|
scope->tname_ = scope->name_;
|
||||||
break;
|
break;
|
||||||
|
case NetScope::GENBLOCK:
|
||||||
|
scope->type_ = IVL_SCT_GENERATE;
|
||||||
|
scope->tname_ = scope->name_;
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
assert(scope->parent != 0);
|
assert(scope->parent != 0);
|
||||||
|
|
@ -2163,6 +2167,9 @@ extern const struct target tgt_dll = { "dll", &dll_target_obj };
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* $Log: t-dll.cc,v $
|
* $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
|
* Revision 1.155 2006/01/02 05:33:19 steve
|
||||||
* Node delays can be more general expressions in structural contexts.
|
* 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
|
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
||||||
*/
|
*/
|
||||||
#ifdef HAVE_CVS_IDENT
|
#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
|
#endif
|
||||||
|
|
||||||
# include "vvp_priv.h"
|
# 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_TASK: type = "task"; break;
|
||||||
case IVL_SCT_BEGIN: type = "begin"; break;
|
case IVL_SCT_BEGIN: type = "begin"; break;
|
||||||
case IVL_SCT_FORK: type = "fork"; break;
|
case IVL_SCT_FORK: type = "fork"; break;
|
||||||
|
case IVL_SCT_GENERATE: type = "generate"; break;
|
||||||
default: type = "?"; assert(0);
|
default: type = "?"; assert(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -2204,6 +2205,9 @@ int draw_scope(ivl_scope_t net, ivl_scope_t parent)
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* $Log: vvp_scope.c,v $
|
* $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
|
* Revision 1.142 2006/03/18 22:53:38 steve
|
||||||
* Support more parameter syntax.
|
* Support more parameter syntax.
|
||||||
*
|
*
|
||||||
|
|
|
||||||
|
|
@ -17,7 +17,7 @@
|
||||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
||||||
*/
|
*/
|
||||||
#ifdef HAVE_CVS_IDENT
|
#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
|
#endif
|
||||||
|
|
||||||
# include "compile.h"
|
# 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;
|
struct __vpiScope*scope = new struct __vpiScope;
|
||||||
count_vpi_scopes += 1;
|
count_vpi_scopes += 1;
|
||||||
|
|
||||||
switch(type[2]) {
|
if (strcmp(type,"module") == 0)
|
||||||
case 'd': /* type == moDule */
|
|
||||||
scope->base.vpi_type = &vpip_scope_module_rt;
|
scope->base.vpi_type = &vpip_scope_module_rt;
|
||||||
break;
|
else if (strcmp(type,"function") == 0)
|
||||||
case 'n': /* type == fuNction */
|
|
||||||
scope->base.vpi_type = &vpip_scope_function_rt;
|
scope->base.vpi_type = &vpip_scope_function_rt;
|
||||||
break;
|
else if (strcmp(type,"task") == 0)
|
||||||
case 's': /* type == taSk */
|
|
||||||
scope->base.vpi_type = &vpip_scope_task_rt;
|
scope->base.vpi_type = &vpip_scope_task_rt;
|
||||||
break;
|
else if (strcmp(type,"fork") == 0)
|
||||||
case 'r': /* type == foRk */
|
|
||||||
scope->base.vpi_type = &vpip_scope_fork_rt;
|
scope->base.vpi_type = &vpip_scope_fork_rt;
|
||||||
break;
|
else if (strcmp(type,"begin") == 0)
|
||||||
case 'g': /* type == beGin */
|
|
||||||
scope->base.vpi_type = &vpip_scope_begin_rt;
|
scope->base.vpi_type = &vpip_scope_begin_rt;
|
||||||
break;
|
else if (strcmp(type,"generate") == 0)
|
||||||
default:
|
// 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;
|
scope->base.vpi_type = &vpip_scope_module_rt;
|
||||||
assert(0);
|
assert(0);
|
||||||
}
|
}
|
||||||
|
|
@ -389,6 +387,9 @@ void vpip_attach_to_current_scope(vpiHandle obj)
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* $Log: vpi_scope.cc,v $
|
* $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
|
* Revision 1.35 2006/03/06 05:43:15 steve
|
||||||
* Cleanup vpi_const to use vec4 values.
|
* Cleanup vpi_const to use vec4 values.
|
||||||
*
|
*
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue