Handle processes within generate loops.

This commit is contained in:
steve 2007-03-05 05:59:10 +00:00
parent 8c434ca6fa
commit e6fa72c318
8 changed files with 147 additions and 99 deletions

View File

@ -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: PGenerate.cc,v 1.1 2006/04/10 02:40:18 steve Exp $" #ident "$Id: PGenerate.cc,v 1.2 2007/03/05 05:59:10 steve Exp $"
#endif #endif
# include "PGenerate.h" # include "PGenerate.h"
@ -55,3 +55,8 @@ void PGenerate::add_gate(PGate*gate)
{ {
gates.push_back(gate); gates.push_back(gate);
} }
void PGenerate::add_behavior(PProcess*proc)
{
behaviors.push_back(proc);
}

View File

@ -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: PGenerate.h,v 1.1 2006/04/10 02:40:18 steve Exp $" #ident "$Id: PGenerate.h,v 1.2 2007/03/05 05:59:10 steve Exp $"
#endif #endif
# include "LineInfo.h" # include "LineInfo.h"
@ -31,6 +31,7 @@
class Design; class Design;
class NetScope; class NetScope;
class PExpr; class PExpr;
class PProcess;
class PGate; class PGate;
class PWire; class PWire;
@ -65,6 +66,9 @@ class PGenerate : public LineInfo {
list<PGate*> gates; list<PGate*> gates;
void add_gate(PGate*); void add_gate(PGate*);
list<PProcess*> behaviors;
void add_behavior(PProcess*behave);
// This method is called by the elaboration of a module to // This method is called by the elaboration of a module to
// generate scopes. the container is the scope that is to // generate scopes. the container is the scope that is to
// contain the generated scope. // contain the generated scope.

View File

@ -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: Statement.h,v 1.42 2005/12/05 21:21:18 steve Exp $" #ident "$Id: Statement.h,v 1.43 2007/03/05 05:59:10 steve Exp $"
#endif #endif
# include <string> # include <string>
@ -55,6 +55,8 @@ class PProcess : public LineInfo {
virtual ~PProcess(); virtual ~PProcess();
bool elaborate(Design*des, NetScope*scope) const;
Type type() const { return type_; } Type type() const { return type_; }
Statement*statement() { return statement_; } Statement*statement() { return statement_; }
@ -458,6 +460,9 @@ class PWhile : public Statement {
/* /*
* $Log: Statement.h,v $ * $Log: Statement.h,v $
* Revision 1.43 2007/03/05 05:59:10 steve
* Handle processes within generate loops.
*
* Revision 1.42 2005/12/05 21:21:18 steve * Revision 1.42 2005/12/05 21:21:18 steve
* Fixes for stubborn compilers. * Fixes for stubborn compilers.
* *

View File

@ -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_lval.cc,v 1.40 2007/02/27 05:14:38 steve Exp $" #ident "$Id: elab_lval.cc,v 1.41 2007/03/05 05:59:10 steve Exp $"
#endif #endif
# include "config.h" # include "config.h"
@ -27,6 +27,7 @@
# include "netmisc.h" # include "netmisc.h"
# include "compiler.h" # include "compiler.h"
# include <iostream> # include <iostream>
# include "ivl_assert.h"
/* /*
* These methods generate a NetAssign_ object for the l-value of the * These methods generate a NetAssign_ object for the l-value of the
@ -198,8 +199,8 @@ NetAssign_* PEIdent::elaborate_lval(Design*des,
return 0; return 0;
} }
assert(msb_ == 0); ivl_assert(*this, msb_ == 0);
assert(lsb_ == 0); ivl_assert(*this, lsb_ == 0);
long msb, lsb; long msb, lsb;
NetExpr*mux; NetExpr*mux;
@ -210,20 +211,20 @@ NetAssign_* PEIdent::elaborate_lval(Design*des,
as a part select with a bit width of 1. If the as a part select with a bit width of 1. If the
expression it not constant, then return the expression it not constant, then return the
expression as a mux. */ expression as a mux. */
assert(idx_.size() == 1);
verinum*v = idx_[0]->eval_const(des, scope); ivl_assert(*this, idx_.size() == 1);
if (v == 0) {
NetExpr*m = idx_[0]->elaborate_expr(des, scope, -1, false); NetExpr*index_expr = elab_and_eval(des, scope, idx_[0], -1);
assert(m);
msb = 0; if (NetEConst*index_con = dynamic_cast<NetEConst*> (index_expr)) {
lsb = 0; msb = index_con->value().as_long();
mux = m; lsb = index_con->value().as_long();
mux = 0;
} else { } else {
msb = 0;
msb = v->as_long(); lsb = 0;
lsb = v->as_long(); mux = index_expr;
mux = 0;
} }
} else { } else {
@ -465,6 +466,9 @@ NetAssign_* PENumber::elaborate_lval(Design*des, NetScope*, bool) const
/* /*
* $Log: elab_lval.cc,v $ * $Log: elab_lval.cc,v $
* Revision 1.41 2007/03/05 05:59:10 steve
* Handle processes within generate loops.
*
* Revision 1.40 2007/02/27 05:14:38 steve * Revision 1.40 2007/02/27 05:14:38 steve
* Detect and warn about lval array index out fo bounds. * Detect and warn about lval array index out fo bounds.
* *

View File

@ -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.41 2006/06/02 04:48:50 steve Exp $" #ident "$Id: elab_scope.cc,v 1.42 2007/03/05 05:59:10 steve Exp $"
#endif #endif
# include "config.h" # include "config.h"
@ -374,6 +374,11 @@ bool PGenerate::generate_scope_loop_(Design*des, NetScope*container)
loop_index, loop_index,
genvar_verinum); genvar_verinum);
scope->set_localparam(loop_index, gp); scope->set_localparam(loop_index, gp);
if (debug_elaborate)
cerr << get_line() << ": debug: "
<< "Create implicit localparam "
<< loop_index << " = " << genvar_verinum << endl;
} }
scope_list_.push_back(scope); scope_list_.push_back(scope);
@ -748,6 +753,9 @@ void PWhile::elaborate_scope(Design*des, NetScope*scope) const
/* /*
* $Log: elab_scope.cc,v $ * $Log: elab_scope.cc,v $
* Revision 1.42 2007/03/05 05:59:10 steve
* Handle processes within generate loops.
*
* Revision 1.41 2006/06/02 04:48:50 steve * Revision 1.41 2006/06/02 04:48:50 steve
* Make elaborate_expr methods aware of the width that the context * Make elaborate_expr methods aware of the width that the context
* requires of it. In the process, fix sizing of the width of unary * requires of it. In the process, fix sizing of the width of unary

View File

@ -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.362 2007/03/03 05:56:55 steve Exp $" #ident "$Id: elaborate.cc,v 1.363 2007/03/05 05:59:10 steve Exp $"
#endif #endif
# include "config.h" # include "config.h"
@ -2905,6 +2905,79 @@ NetProc* PWhile::elaborate(Design*des, NetScope*scope) const
return loop; return loop;
} }
bool PProcess::elaborate(Design*des, NetScope*scope) const
{
NetProc*cur = statement_->elaborate(des, scope);
if (cur == 0) {
return false;
}
NetProcTop*top=0;
switch (type()) {
case PProcess::PR_INITIAL:
top = new NetProcTop(scope, NetProcTop::KINITIAL, cur);
break;
case PProcess::PR_ALWAYS:
top = new NetProcTop(scope, NetProcTop::KALWAYS, cur);
break;
}
ivl_assert(*this, top);
// Evaluate the attributes for this process, if there
// are any. These attributes are to be attached to the
// NetProcTop object.
struct attrib_list_t*attrib_list = 0;
unsigned attrib_list_n = 0;
attrib_list = evaluate_attributes(attributes, attrib_list_n, des, scope);
for (unsigned adx = 0 ; adx < attrib_list_n ; adx += 1)
top->attribute(attrib_list[adx].key,
attrib_list[adx].val);
delete[]attrib_list;
top->set_line(*this);
des->add_process(top);
/* Detect the special case that this is a combinational
always block. We want to attach an _ivl_schedule_push
attribute to this process so that it starts up and
gets into its wait statement before non-combinational
code is executed. */
do {
if (top->type() != NetProcTop::KALWAYS)
break;
NetEvWait*st = dynamic_cast<NetEvWait*>(top->statement());
if (st == 0)
break;
if (st->nevents() != 1)
break;
NetEvent*ev = st->event(0);
if (ev->nprobe() == 0)
break;
bool anyedge_test = true;
for (unsigned idx = 0 ; anyedge_test && (idx<ev->nprobe())
; idx += 1) {
const NetEvProbe*pr = ev->probe(idx);
if (pr->edge() != NetEvProbe::ANYEDGE)
anyedge_test = false;
}
if (! anyedge_test)
break;
top->attribute(perm_string::literal("_ivl_schedule_push"),
verinum(1));
} while (0);
return true;
}
void PSpecPath::elaborate(Design*des, NetScope*scope) const void PSpecPath::elaborate(Design*des, NetScope*scope) const
{ {
uint64_t delay_value[12]; uint64_t delay_value[12];
@ -3171,80 +3244,9 @@ bool Module::elaborate(Design*des, NetScope*scope) const
const list<PProcess*>&sl = get_behaviors(); const list<PProcess*>&sl = get_behaviors();
for (list<PProcess*>::const_iterator st = sl.begin() for (list<PProcess*>::const_iterator st = sl.begin()
; st != sl.end() ; st != sl.end() ; st ++ ) {
; st ++ ) {
NetProc*cur = (*st)->statement()->elaborate(des, scope);
if (cur == 0) {
result_flag = false;
continue;
}
NetProcTop*top=NULL;
switch ((*st)->type()) {
case PProcess::PR_INITIAL:
top = new NetProcTop(scope, NetProcTop::KINITIAL, cur);
break;
case PProcess::PR_ALWAYS:
top = new NetProcTop(scope, NetProcTop::KALWAYS, cur);
break;
}
assert(top);
// Evaluate the attributes for this process, if there
// are any. These attributes are to be attached to the
// NetProcTop object.
struct attrib_list_t*attrib_list = 0;
unsigned attrib_list_n = 0;
attrib_list = evaluate_attributes((*st)->attributes,
attrib_list_n,
des, scope);
for (unsigned adx = 0 ; adx < attrib_list_n ; adx += 1)
top->attribute(attrib_list[adx].key,
attrib_list[adx].val);
delete[]attrib_list;
top->set_line(*(*st));
des->add_process(top);
/* Detect the special case that this is a combinational
always block. We want to attach an _ivl_schedule_push
attribute to this process so that it starts up and
gets into its wait statement before non-combinational
code is executed. */
do {
if (top->type() != NetProcTop::KALWAYS)
break;
NetEvWait*st = dynamic_cast<NetEvWait*>(top->statement());
if (st == 0)
break;
if (st->nevents() != 1)
break;
NetEvent*ev = st->event(0);
if (ev->nprobe() == 0)
break;
bool anyedge_test = true;
for (unsigned idx = 0 ; anyedge_test && (idx<ev->nprobe())
; idx += 1) {
const NetEvProbe*pr = ev->probe(idx);
if (pr->edge() != NetEvProbe::ANYEDGE)
anyedge_test = false;
}
if (! anyedge_test)
break;
top->attribute(perm_string::literal("_ivl_schedule_push"),
verinum(1));
} while (0);
result_flag &= (*st)->elaborate(des, scope);
} }
// Elaborate the specify paths of the module. // Elaborate the specify paths of the module.
@ -3279,10 +3281,12 @@ bool PGenerate::elaborate(Design*des) const
bool PGenerate::elaborate_(Design*des, NetScope*scope) const bool PGenerate::elaborate_(Design*des, NetScope*scope) const
{ {
typedef list<PGate*>::const_iterator gates_it_t; typedef list<PGate*>::const_iterator gates_it_t;
for (gates_it_t cur = gates.begin() ; cur != gates.end() ; cur ++ ) { for (gates_it_t cur = gates.begin() ; cur != gates.end() ; cur ++ )
(*cur)->elaborate(des, scope);
typedef list<PProcess*>::const_iterator proc_it_t;
for (proc_it_t cur = behaviors.begin(); cur != behaviors.end(); cur++)
(*cur)->elaborate(des, scope); (*cur)->elaborate(des, scope);
}
return true; return true;
} }
@ -3396,6 +3400,9 @@ Design* elaborate(list<perm_string>roots)
/* /*
* $Log: elaborate.cc,v $ * $Log: elaborate.cc,v $
* Revision 1.363 2007/03/05 05:59:10 steve
* Handle processes within generate loops.
*
* Revision 1.362 2007/03/03 05:56:55 steve * Revision 1.362 2007/03/03 05:56:55 steve
* Check that path source/destination are ports. * Check that path source/destination are ports.
* *

View File

@ -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.140 2007/02/12 01:52:21 steve Exp $" #ident "$Id: pform.cc,v 1.141 2007/03/05 05:59:10 steve Exp $"
#endif #endif
# include "config.h" # include "config.h"
@ -1719,7 +1719,11 @@ PProcess* pform_make_behavior(PProcess::Type type, Statement*st,
delete attr; delete attr;
} }
pform_cur_module->add_behavior(pp); if (pform_cur_generate)
pform_cur_generate->add_behavior(pp);
else
pform_cur_module->add_behavior(pp);
return pp; return pp;
} }
@ -1764,6 +1768,9 @@ int pform_parse(const char*path, FILE*file)
/* /*
* $Log: pform.cc,v $ * $Log: pform.cc,v $
* Revision 1.141 2007/03/05 05:59:10 steve
* Handle processes within generate loops.
*
* Revision 1.140 2007/02/12 01:52:21 steve * Revision 1.140 2007/02/12 01:52:21 steve
* Parse all specify paths to pform. * Parse all specify paths to pform.
* *

View File

@ -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.95 2007/02/12 01:52:21 steve Exp $" #ident "$Id: pform_dump.cc,v 1.96 2007/03/05 05:59:10 steve Exp $"
#endif #endif
# include "config.h" # include "config.h"
@ -819,6 +819,11 @@ void PGenerate::dump(ostream&out) const
(*idx)->dump(out, 6); (*idx)->dump(out, 6);
} }
for (list<PProcess*>::const_iterator idx = behaviors.begin()
; idx != behaviors.end() ; idx++) {
(*idx)->dump(out, 6);
}
out << " endgenerate" << endl; out << " endgenerate" << endl;
} }
@ -1024,6 +1029,9 @@ void PUdp::dump(ostream&out) const
/* /*
* $Log: pform_dump.cc,v $ * $Log: pform_dump.cc,v $
* Revision 1.96 2007/03/05 05:59:10 steve
* Handle processes within generate loops.
*
* Revision 1.95 2007/02/12 01:52:21 steve * Revision 1.95 2007/02/12 01:52:21 steve
* Parse all specify paths to pform. * Parse all specify paths to pform.
* *