synth_asych of if/else requires redirecting the target
if sub-statements. Use NetNet objects to manage the situation.
This commit is contained in:
parent
3595b6d186
commit
d5e9e13555
|
|
@ -17,11 +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
|
||||||
*/
|
*/
|
||||||
#if !defined(WINNT)
|
#if !defined(WINNT)
|
||||||
#ident "$Id: net_nex_output.cc,v 1.1 2002/06/30 02:21:32 steve Exp $"
|
#ident "$Id: net_nex_output.cc,v 1.2 2002/07/01 00:54:21 steve Exp $"
|
||||||
#endif
|
|
||||||
|
|
||||||
#if !defined(WINNT)
|
|
||||||
#ident "$Id: net_nex_output.cc,v 1.1 2002/06/30 02:21:32 steve Exp $"
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
# include "config.h"
|
# include "config.h"
|
||||||
|
|
@ -40,23 +36,38 @@ void NetProc::nex_output(NexusSet&out)
|
||||||
<< endl;
|
<< endl;
|
||||||
}
|
}
|
||||||
|
|
||||||
void NetAssign::nex_output(NexusSet&out)
|
void NetAssignBase::nex_output(NexusSet&out)
|
||||||
{
|
{
|
||||||
cerr << get_line()
|
NetNet*lsig = lval_->sig();
|
||||||
<< ": internal error: NetProc::nex_output not implemented"
|
assert(lsig);
|
||||||
<< endl;
|
assert(lval_->more == 0);
|
||||||
|
|
||||||
|
for (unsigned idx = 0 ; idx < lsig->pin_count() ; idx += 1)
|
||||||
|
out.add(lsig->pin(idx).nexus());
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void NetCondit::nex_output(NexusSet&out)
|
void NetCondit::nex_output(NexusSet&out)
|
||||||
{
|
{
|
||||||
cerr << get_line()
|
if (if_ != 0)
|
||||||
<< ": internal error: NetProc::nex_output not implemented"
|
if_->nex_output(out);
|
||||||
<< endl;
|
if (else_ != 0)
|
||||||
|
else_->nex_output(out);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void NetEvWait::nex_output(NexusSet&out)
|
||||||
|
{
|
||||||
|
assert(statement_);
|
||||||
|
statement_->nex_output(out);
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* $Log: net_nex_output.cc,v $
|
* $Log: net_nex_output.cc,v $
|
||||||
|
* Revision 1.2 2002/07/01 00:54:21 steve
|
||||||
|
* synth_asych of if/else requires redirecting the target
|
||||||
|
* if sub-statements. Use NetNet objects to manage the
|
||||||
|
* situation.
|
||||||
|
*
|
||||||
* Revision 1.1 2002/06/30 02:21:32 steve
|
* Revision 1.1 2002/06/30 02:21:32 steve
|
||||||
* Add structure for asynchronous logic synthesis.
|
* Add structure for asynchronous logic synthesis.
|
||||||
*
|
*
|
||||||
|
|
|
||||||
27
netlist.h
27
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
|
||||||
*/
|
*/
|
||||||
#if !defined(WINNT) && !defined(macintosh)
|
#if !defined(WINNT) && !defined(macintosh)
|
||||||
#ident "$Id: netlist.h,v 1.248 2002/06/30 02:21:32 steve Exp $"
|
#ident "$Id: netlist.h,v 1.249 2002/07/01 00:54:21 steve Exp $"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|
@ -1204,7 +1204,8 @@ class NetProc : public LineInfo {
|
||||||
virtual bool is_asynchronous();
|
virtual bool is_asynchronous();
|
||||||
|
|
||||||
// synthesize as asynchronous logic, and return true.
|
// synthesize as asynchronous logic, and return true.
|
||||||
virtual bool synth_async(Design*, NetScope*scope);
|
virtual bool synth_async(Design*des, NetScope*scope,
|
||||||
|
const NetNet*nex_map, NetNet*nex_out);
|
||||||
|
|
||||||
virtual void dump(ostream&, unsigned ind) const;
|
virtual void dump(ostream&, unsigned ind) const;
|
||||||
|
|
||||||
|
|
@ -1312,12 +1313,15 @@ class NetAssignBase : public NetProc {
|
||||||
const NetExpr* get_delay() const;
|
const NetExpr* get_delay() const;
|
||||||
|
|
||||||
virtual NexusSet* nex_input();
|
virtual NexusSet* nex_input();
|
||||||
|
virtual void nex_output(NexusSet&o);
|
||||||
|
|
||||||
|
|
||||||
// This returns the total width of the accumulated l-value. It
|
// This returns the total width of the accumulated l-value. It
|
||||||
// accounts for any grouping of NetAssign_ objects that might happen.
|
// accounts for any grouping of NetAssign_ objects that might happen.
|
||||||
unsigned lwidth() const;
|
unsigned lwidth() const;
|
||||||
|
|
||||||
bool synth_async(Design*des, NetScope*scope);
|
bool synth_async(Design*des, NetScope*scope,
|
||||||
|
const NetNet*nex_map, NetNet*nex_out);
|
||||||
|
|
||||||
// This dumps all the lval structures.
|
// This dumps all the lval structures.
|
||||||
void dump_lval(ostream&) const;
|
void dump_lval(ostream&) const;
|
||||||
|
|
@ -1336,8 +1340,6 @@ class NetAssign : public NetAssignBase {
|
||||||
|
|
||||||
bool is_asynchronous();
|
bool is_asynchronous();
|
||||||
|
|
||||||
void nex_output(NexusSet&o);
|
|
||||||
|
|
||||||
virtual bool emit_proc(struct target_t*) const;
|
virtual bool emit_proc(struct target_t*) const;
|
||||||
virtual int match_proc(struct proc_match_t*);
|
virtual int match_proc(struct proc_match_t*);
|
||||||
virtual void dump(ostream&, unsigned ind) const;
|
virtual void dump(ostream&, unsigned ind) const;
|
||||||
|
|
@ -1503,7 +1505,8 @@ class NetCondit : public NetProc {
|
||||||
virtual void nex_output(NexusSet&o);
|
virtual void nex_output(NexusSet&o);
|
||||||
|
|
||||||
bool is_asynchronous();
|
bool is_asynchronous();
|
||||||
bool synth_async(Design*des, NetScope*scope);
|
bool synth_async(Design*des, NetScope*scope,
|
||||||
|
const NetNet*nex_map, NetNet*nex_out);
|
||||||
|
|
||||||
virtual bool emit_proc(struct target_t*) const;
|
virtual bool emit_proc(struct target_t*) const;
|
||||||
virtual int match_proc(struct proc_match_t*);
|
virtual int match_proc(struct proc_match_t*);
|
||||||
|
|
@ -1626,6 +1629,8 @@ class NetEvent : public LineInfo {
|
||||||
NetScope* scope();
|
NetScope* scope();
|
||||||
const NetScope* scope() const;
|
const NetScope* scope() const;
|
||||||
|
|
||||||
|
void nex_output(NexusSet&);
|
||||||
|
|
||||||
// Locate the first event that matches my behavior and
|
// Locate the first event that matches my behavior and
|
||||||
// monitors the same signals.
|
// monitors the same signals.
|
||||||
NetEvent* find_similar_event();
|
NetEvent* find_similar_event();
|
||||||
|
|
@ -1708,7 +1713,10 @@ class NetEvWait : public NetProc {
|
||||||
// process. This method checks.
|
// process. This method checks.
|
||||||
virtual bool is_asynchronous();
|
virtual bool is_asynchronous();
|
||||||
|
|
||||||
virtual bool synth_async(Design*des, NetScope*scope);
|
virtual void nex_output(NexusSet&out);
|
||||||
|
|
||||||
|
virtual bool synth_async(Design*des, NetScope*scope,
|
||||||
|
const NetNet*nex_map, NetNet*nex_out);
|
||||||
|
|
||||||
virtual void dump(ostream&, unsigned ind) const;
|
virtual void dump(ostream&, unsigned ind) const;
|
||||||
|
|
||||||
|
|
@ -2985,6 +2993,11 @@ extern ostream& operator << (ostream&, NetNet::Type);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* $Log: netlist.h,v $
|
* $Log: netlist.h,v $
|
||||||
|
* Revision 1.249 2002/07/01 00:54:21 steve
|
||||||
|
* synth_asych of if/else requires redirecting the target
|
||||||
|
* if sub-statements. Use NetNet objects to manage the
|
||||||
|
* situation.
|
||||||
|
*
|
||||||
* Revision 1.248 2002/06/30 02:21:32 steve
|
* Revision 1.248 2002/06/30 02:21:32 steve
|
||||||
* Add structure for asynchronous logic synthesis.
|
* Add structure for asynchronous logic synthesis.
|
||||||
*
|
*
|
||||||
|
|
|
||||||
112
synth2.cc
112
synth2.cc
|
|
@ -17,54 +17,123 @@
|
||||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
||||||
*/
|
*/
|
||||||
#if !defined(WINNT) && !defined(macintosh)
|
#if !defined(WINNT) && !defined(macintosh)
|
||||||
#ident "$Id: synth2.cc,v 1.1 2002/06/30 02:21:32 steve Exp $"
|
#ident "$Id: synth2.cc,v 1.2 2002/07/01 00:54:21 steve Exp $"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
# include "config.h"
|
# include "config.h"
|
||||||
|
|
||||||
# include "functor.h"
|
# include "functor.h"
|
||||||
# include "netlist.h"
|
# include "netlist.h"
|
||||||
|
# include "compiler.h"
|
||||||
# include <assert.h>
|
# include <assert.h>
|
||||||
|
|
||||||
|
static unsigned find_nexus_in_set(const NetNet*nset, const Nexus*nex)
|
||||||
|
{
|
||||||
|
unsigned idx = 0;
|
||||||
|
for (idx = 0 ; idx < nset->pin_count() ; idx += 1)
|
||||||
|
if (nset->pin(idx).nexus() == nex)
|
||||||
|
return idx;
|
||||||
|
|
||||||
|
return idx;
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Async synthesis of assignments is done by synthesizing the rvalue
|
* Async synthesis of assignments is done by synthesizing the rvalue
|
||||||
* expression, then connecting the l-value directly to the output of
|
* expression, then connecting the l-value directly to the output of
|
||||||
* the r-value.
|
* the r-value.
|
||||||
|
*
|
||||||
|
* The nex_map is the O-set for the statement, and lists the positions
|
||||||
|
* of the outputs as the caller wants results linked up. The nex_out,
|
||||||
|
* however, is the set of nexa that are to actually get linked to the
|
||||||
|
* r-value.
|
||||||
*/
|
*/
|
||||||
bool NetAssignBase::synth_async(Design*des, NetScope*scope)
|
bool NetAssignBase::synth_async(Design*des, NetScope*scope,
|
||||||
|
const NetNet*nex_map, NetNet*nex_out)
|
||||||
{
|
{
|
||||||
NetNet*rsig = rval_->synthesize(des);
|
NetNet*rsig = rval_->synthesize(des);
|
||||||
|
assert(rsig);
|
||||||
|
|
||||||
NetNet*lsig = lval_->sig();
|
NetNet*lsig = lval_->sig();
|
||||||
assert(lsig);
|
assert(lsig);
|
||||||
assert(lval_->more == 0);
|
assert(lval_->more == 0);
|
||||||
|
|
||||||
|
assert(nex_map->pin_count() == rsig->pin_count());
|
||||||
assert(lsig->pin_count() == rsig->pin_count());
|
assert(lsig->pin_count() == rsig->pin_count());
|
||||||
for (unsigned idx = 0 ; idx < lsig->pin_count() ; idx += 1)
|
|
||||||
connect(lsig->pin(idx), rsig->pin(idx));
|
for (unsigned idx = 0 ; idx < lsig->pin_count() ; idx += 1) {
|
||||||
|
unsigned ptr = find_nexus_in_set(nex_map, lsig->pin(idx).nexus());
|
||||||
|
connect(nex_out->pin(ptr), rsig->pin(idx));
|
||||||
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool NetCondit::synth_async(Design*des, NetScope*scope)
|
bool NetCondit::synth_async(Design*des, NetScope*scope,
|
||||||
|
const NetNet*nex_map, NetNet*nex_out)
|
||||||
{
|
{
|
||||||
return false;
|
NetNet*ssig = expr_->synthesize(des);
|
||||||
|
assert(ssig);
|
||||||
|
|
||||||
|
assert(if_ != 0);
|
||||||
|
assert(else_ != 0);
|
||||||
|
|
||||||
|
NetNet*asig = new NetNet(scope, scope->local_hsymbol(),
|
||||||
|
NetNet::WIRE, nex_map->pin_count());
|
||||||
|
asig->local_flag(true);
|
||||||
|
|
||||||
|
if_->synth_async(des, scope, nex_map, asig);
|
||||||
|
|
||||||
|
NetNet*bsig = new NetNet(scope, scope->local_hsymbol(),
|
||||||
|
NetNet::WIRE, nex_map->pin_count());
|
||||||
|
bsig->local_flag(true);
|
||||||
|
|
||||||
|
else_->synth_async(des, scope, nex_map, bsig);
|
||||||
|
|
||||||
|
NetMux*mux = new NetMux(scope, scope->local_hsymbol(),
|
||||||
|
nex_out->pin_count(), 2, 1);
|
||||||
|
|
||||||
|
connect(mux->pin_Sel(0), ssig->pin(0));
|
||||||
|
|
||||||
|
for (unsigned idx = 0 ; idx < asig->pin_count() ; idx += 1)
|
||||||
|
connect(mux->pin_Data(idx, 1), asig->pin(idx));
|
||||||
|
|
||||||
|
for (unsigned idx = 0 ; idx < bsig->pin_count() ; idx += 1)
|
||||||
|
connect(mux->pin_Data(idx, 0), bsig->pin(idx));
|
||||||
|
|
||||||
|
for (unsigned idx = 0 ; idx < mux->width() ; idx += 1)
|
||||||
|
connect(nex_out->pin(idx), mux->pin_Result(idx));
|
||||||
|
|
||||||
|
des->add_node(mux);
|
||||||
|
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool NetEvWait::synth_async(Design*des, NetScope*scope)
|
bool NetEvWait::synth_async(Design*des, NetScope*scope,
|
||||||
|
const NetNet*nex_map, NetNet*nex_out)
|
||||||
{
|
{
|
||||||
return statement_->synth_async(des, scope);
|
return statement_->synth_async(des, scope, nex_map, nex_out);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool NetProc::synth_async(Design*des, NetScope*scope)
|
bool NetProc::synth_async(Design*des, NetScope*scope,
|
||||||
|
const NetNet*nex_map, NetNet*nex_out)
|
||||||
{
|
{
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool NetProcTop::synth_async(Design*des)
|
bool NetProcTop::synth_async(Design*des)
|
||||||
{
|
{
|
||||||
return statement_->synth_async(des, scope());
|
NexusSet nex_set;
|
||||||
|
statement_->nex_output(nex_set);
|
||||||
|
|
||||||
|
NetNet*nex_out = new NetNet(scope(), "tmp", NetNet::WIRE,
|
||||||
|
nex_set.count());
|
||||||
|
for (unsigned idx = 0 ; idx < nex_out->pin_count() ; idx += 1)
|
||||||
|
connect(nex_set[idx], nex_out->pin(idx));
|
||||||
|
|
||||||
|
bool flag = statement_->synth_async(des, scope(), nex_out, nex_out);
|
||||||
|
|
||||||
|
delete nex_out;
|
||||||
|
return flag;
|
||||||
}
|
}
|
||||||
|
|
||||||
class synth2_f : public functor_t {
|
class synth2_f : public functor_t {
|
||||||
|
|
@ -77,18 +146,26 @@ class synth2_f : public functor_t {
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Look at a process, and divide the problem into always and initial
|
* Look at a process. If it is asynchronous, then synthesize it as an
|
||||||
* threads.
|
* asynchronous process and delete the process itself for its gates.
|
||||||
*/
|
*/
|
||||||
void synth2_f::process(class Design*des, class NetProcTop*top)
|
void synth2_f::process(class Design*des, class NetProcTop*top)
|
||||||
{
|
{
|
||||||
if (! top->is_asynchronous())
|
if (! top->is_asynchronous()) {
|
||||||
|
if (top->attribute("asynchronous").as_ulong() != 0)
|
||||||
|
cerr << top->get_line() << ": warning: "
|
||||||
|
<< "Process is marked asynchronous,"
|
||||||
|
<< " but isn't really." << endl;
|
||||||
return;
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
if (! top->synth_async(des))
|
if (! top->synth_async(des)) {
|
||||||
|
cerr << top->get_line() << ": internal error: "
|
||||||
|
<< "is_asynchronous does not match "
|
||||||
|
<< "sync_async results." << endl;
|
||||||
return;
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
cerr << top->get_line() << ": info: thread is asynchronous." << endl;
|
|
||||||
des->delete_process(top);
|
des->delete_process(top);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -100,6 +177,11 @@ void synth2(Design*des)
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* $Log: synth2.cc,v $
|
* $Log: synth2.cc,v $
|
||||||
|
* Revision 1.2 2002/07/01 00:54:21 steve
|
||||||
|
* synth_asych of if/else requires redirecting the target
|
||||||
|
* if sub-statements. Use NetNet objects to manage the
|
||||||
|
* situation.
|
||||||
|
*
|
||||||
* Revision 1.1 2002/06/30 02:21:32 steve
|
* Revision 1.1 2002/06/30 02:21:32 steve
|
||||||
* Add structure for asynchronous logic synthesis.
|
* Add structure for asynchronous logic synthesis.
|
||||||
*
|
*
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue