Handle processes within generate loops.
This commit is contained in:
parent
8c434ca6fa
commit
e6fa72c318
|
|
@ -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);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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.
|
||||
|
|
|
|||
|
|
@ -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.
|
||||
*
|
||||
|
|
|
|||
34
elab_lval.cc
34
elab_lval.cc
|
|
@ -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.
|
||||
*
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
161
elaborate.cc
161
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.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.
|
||||
*
|
||||
|
|
|
|||
11
pform.cc
11
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.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.
|
||||
*
|
||||
|
|
|
|||
|
|
@ -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.
|
||||
*
|
||||
|
|
|
|||
Loading…
Reference in New Issue