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
*/
#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
# include "PGenerate.h"
@ -55,3 +55,8 @@ void PGenerate::add_gate(PGate*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
*/
#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
# include "LineInfo.h"
@ -31,6 +31,7 @@
class Design;
class NetScope;
class PExpr;
class PProcess;
class PGate;
class PWire;
@ -65,6 +66,9 @@ class PGenerate : public LineInfo {
list<PGate*> gates;
void add_gate(PGate*);
list<PProcess*> behaviors;
void add_behavior(PProcess*behave);
// This method is called by the elaboration of a module to
// generate scopes. the container is the scope that is to
// contain the generated scope.

View File

@ -19,7 +19,7 @@
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/
#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
# include <string>
@ -55,6 +55,8 @@ class PProcess : public LineInfo {
virtual ~PProcess();
bool elaborate(Design*des, NetScope*scope) const;
Type type() const { return type_; }
Statement*statement() { return statement_; }
@ -458,6 +460,9 @@ class PWhile : public Statement {
/*
* $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
* Fixes for stubborn compilers.
*

View File

@ -17,7 +17,7 @@
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/
#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
# include "config.h"
@ -27,6 +27,7 @@
# include "netmisc.h"
# include "compiler.h"
# include <iostream>
# include "ivl_assert.h"
/*
* These methods generate a NetAssign_ object for the l-value of the
@ -198,8 +199,8 @@ NetAssign_* PEIdent::elaborate_lval(Design*des,
return 0;
}
assert(msb_ == 0);
assert(lsb_ == 0);
ivl_assert(*this, msb_ == 0);
ivl_assert(*this, lsb_ == 0);
long msb, lsb;
NetExpr*mux;
@ -210,20 +211,20 @@ NetAssign_* PEIdent::elaborate_lval(Design*des,
as a part select with a bit width of 1. If the
expression it not constant, then return the
expression as a mux. */
assert(idx_.size() == 1);
verinum*v = idx_[0]->eval_const(des, scope);
if (v == 0) {
NetExpr*m = idx_[0]->elaborate_expr(des, scope, -1, false);
assert(m);
msb = 0;
lsb = 0;
mux = m;
ivl_assert(*this, idx_.size() == 1);
NetExpr*index_expr = elab_and_eval(des, scope, idx_[0], -1);
if (NetEConst*index_con = dynamic_cast<NetEConst*> (index_expr)) {
msb = index_con->value().as_long();
lsb = index_con->value().as_long();
mux = 0;
} else {
msb = v->as_long();
lsb = v->as_long();
mux = 0;
msb = 0;
lsb = 0;
mux = index_expr;
}
} else {
@ -465,6 +466,9 @@ NetAssign_* PENumber::elaborate_lval(Design*des, NetScope*, bool) const
/*
* $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
* 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
*/
#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
# include "config.h"
@ -374,6 +374,11 @@ bool PGenerate::generate_scope_loop_(Design*des, NetScope*container)
loop_index,
genvar_verinum);
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);
@ -748,6 +753,9 @@ void PWhile::elaborate_scope(Design*des, NetScope*scope) const
/*
* $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
* Make elaborate_expr methods aware of the width that the context
* 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
*/
#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
# include "config.h"
@ -2905,6 +2905,79 @@ NetProc* PWhile::elaborate(Design*des, NetScope*scope) const
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
{
uint64_t delay_value[12];
@ -3171,80 +3244,9 @@ bool Module::elaborate(Design*des, NetScope*scope) const
const list<PProcess*>&sl = get_behaviors();
for (list<PProcess*>::const_iterator st = sl.begin()
; st != sl.end()
; 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);
; st != sl.end() ; st ++ ) {
result_flag &= (*st)->elaborate(des, scope);
}
// 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
{
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);
}
return true;
}
@ -3396,6 +3400,9 @@ Design* elaborate(list<perm_string>roots)
/*
* $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
* 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
*/
#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
# include "config.h"
@ -1719,7 +1719,11 @@ PProcess* pform_make_behavior(PProcess::Type type, Statement*st,
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;
}
@ -1764,6 +1768,9 @@ int pform_parse(const char*path, FILE*file)
/*
* $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
* Parse all specify paths to pform.
*

View File

@ -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.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
# include "config.h"
@ -819,6 +819,11 @@ void PGenerate::dump(ostream&out) const
(*idx)->dump(out, 6);
}
for (list<PProcess*>::const_iterator idx = behaviors.begin()
; idx != behaviors.end() ; idx++) {
(*idx)->dump(out, 6);
}
out << " endgenerate" << endl;
}
@ -1024,6 +1029,9 @@ void PUdp::dump(ostream&out) const
/*
* $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
* Parse all specify paths to pform.
*