Support initialization of FF Q value.
This commit is contained in:
parent
cca036c4a8
commit
ea96c3ef66
51
cprop.cc
51
cprop.cc
|
|
@ -17,51 +17,15 @@
|
|||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
||||
*/
|
||||
#if !defined(WINNT) && !defined(macintosh)
|
||||
#ident "$Id: cprop.cc,v 1.9 2000/05/07 04:37:56 steve Exp $"
|
||||
#ident "$Id: cprop.cc,v 1.10 2000/05/14 17:55:04 steve Exp $"
|
||||
#endif
|
||||
|
||||
# include "netlist.h"
|
||||
# include "netmisc.h"
|
||||
# include "functor.h"
|
||||
# include <assert.h>
|
||||
|
||||
/*
|
||||
* This local function returns true if all the the possible drivers of
|
||||
* this link are constant. It will also return true if there are no
|
||||
* drivers at all.
|
||||
*/
|
||||
static bool all_drivers_constant(const Link&lnk)
|
||||
{
|
||||
for (const Link*cur = lnk.next_link()
|
||||
; *cur != lnk ; cur = cur->next_link()) {
|
||||
|
||||
if (cur->get_dir() == Link::INPUT)
|
||||
continue;
|
||||
if (cur->get_dir() == Link::PASSIVE)
|
||||
continue;
|
||||
if (! dynamic_cast<const NetConst*>(cur->get_obj()))
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/*
|
||||
* This function returns the value of the constant driving this link,
|
||||
* or Vz if there is no constant. The results of this function are
|
||||
* only meaningful if all_drivers_constant(lnk) == true.
|
||||
*/
|
||||
static verinum::V driven_value(const Link&lnk)
|
||||
{
|
||||
for (const Link*cur = lnk.next_link()
|
||||
; *cur != lnk ; cur = cur->next_link()) {
|
||||
|
||||
const NetConst*obj;
|
||||
if (obj = dynamic_cast<const NetConst*>(cur->get_obj()))
|
||||
return obj->value(cur->get_pin());
|
||||
}
|
||||
|
||||
return verinum::Vz;
|
||||
}
|
||||
|
||||
/*
|
||||
* The cprop function below invokes constant propogation where
|
||||
|
|
@ -90,7 +54,7 @@ void cprop_functor::lpm_add_sub(Design*des, NetAddSub*obj)
|
|||
// result. Don't reduce the adder smaller then a 1-bit
|
||||
// adder. These will be eliminated later.
|
||||
while ((obj->width() > 1)
|
||||
&& all_drivers_constant(obj->pin_DataA(0))
|
||||
&& link_drivers_constant(obj->pin_DataA(0))
|
||||
&& (driven_value(obj->pin_DataA(0)) == verinum::V0)) {
|
||||
|
||||
NetAddSub*tmp = 0;
|
||||
|
|
@ -115,7 +79,7 @@ void cprop_functor::lpm_add_sub(Design*des, NetAddSub*obj)
|
|||
|
||||
// Now do the same thing on the B side.
|
||||
while ((obj->width() > 1)
|
||||
&& all_drivers_constant(obj->pin_DataB(0))
|
||||
&& link_drivers_constant(obj->pin_DataB(0))
|
||||
&& (driven_value(obj->pin_DataB(0)) == verinum::V0)) {
|
||||
|
||||
NetAddSub*tmp = 0;
|
||||
|
|
@ -222,7 +186,7 @@ void cprop_functor::lpm_logic(Design*des, NetLogic*obj)
|
|||
// the resulting output is going to be zero and can
|
||||
// elininate the gate.
|
||||
for (unsigned idx = 1 ; idx < obj->pin_count() ; idx += 1) {
|
||||
if (! all_drivers_constant(obj->pin(idx)))
|
||||
if (! link_drivers_constant(obj->pin(idx)))
|
||||
continue;
|
||||
if (driven_value(obj->pin(idx)) == verinum::V0) {
|
||||
connect(obj->pin(0), obj->pin(idx));
|
||||
|
|
@ -235,7 +199,7 @@ void cprop_functor::lpm_logic(Design*des, NetLogic*obj)
|
|||
// There are no zero constant drivers. If there are any
|
||||
// non-constant drivers, give up.
|
||||
for (unsigned idx = 1 ; idx < obj->pin_count() ; idx += 1) {
|
||||
if (! all_drivers_constant(obj->pin(idx)))
|
||||
if (! link_drivers_constant(obj->pin(idx)))
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
@ -319,6 +283,9 @@ void cprop(Design*des)
|
|||
|
||||
/*
|
||||
* $Log: cprop.cc,v $
|
||||
* Revision 1.10 2000/05/14 17:55:04 steve
|
||||
* Support initialization of FF Q value.
|
||||
*
|
||||
* Revision 1.9 2000/05/07 04:37:56 steve
|
||||
* Carry strength values from Verilog source to the
|
||||
* pform and netlist for gates.
|
||||
|
|
|
|||
|
|
@ -17,12 +17,41 @@
|
|||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
||||
*/
|
||||
#if !defined(WINNT) && !defined(macintosh)
|
||||
#ident "$Id: link_const.cc,v 1.2 2000/05/07 04:37:56 steve Exp $"
|
||||
#ident "$Id: link_const.cc,v 1.3 2000/05/14 17:55:04 steve Exp $"
|
||||
#endif
|
||||
|
||||
# include "netlist.h"
|
||||
# include "netmisc.h"
|
||||
|
||||
bool link_drivers_constant(const Link&lnk)
|
||||
{
|
||||
for (const Link*cur = lnk.next_link()
|
||||
; *cur != lnk ; cur = cur->next_link()) {
|
||||
|
||||
if (cur->get_dir() == Link::INPUT)
|
||||
continue;
|
||||
if (cur->get_dir() == Link::PASSIVE)
|
||||
continue;
|
||||
if (! dynamic_cast<const NetConst*>(cur->get_obj()))
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
verinum::V driven_value(const Link&lnk)
|
||||
{
|
||||
for (const Link*cur = lnk.next_link()
|
||||
; *cur != lnk ; cur = cur->next_link()) {
|
||||
|
||||
const NetConst*obj;
|
||||
if (obj = dynamic_cast<const NetConst*>(cur->get_obj()))
|
||||
return obj->value(cur->get_pin());
|
||||
}
|
||||
|
||||
return verinum::Vz;
|
||||
}
|
||||
|
||||
NetConst* link_const_value(Link&pin, unsigned&idx)
|
||||
{
|
||||
NetConst*robj = 0;
|
||||
|
|
@ -49,6 +78,9 @@ NetConst* link_const_value(Link&pin, unsigned&idx)
|
|||
|
||||
/*
|
||||
* $Log: link_const.cc,v $
|
||||
* Revision 1.3 2000/05/14 17:55:04 steve
|
||||
* Support initialization of FF Q value.
|
||||
*
|
||||
* Revision 1.2 2000/05/07 04:37:56 steve
|
||||
* Carry strength values from Verilog source to the
|
||||
* pform and netlist for gates.
|
||||
|
|
|
|||
19
netmisc.h
19
netmisc.h
|
|
@ -19,7 +19,7 @@
|
|||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
||||
*/
|
||||
#if !defined(WINNT) && !defined(macintosh)
|
||||
#ident "$Id: netmisc.h,v 1.6 2000/05/07 04:37:56 steve Exp $"
|
||||
#ident "$Id: netmisc.h,v 1.7 2000/05/14 17:55:04 steve Exp $"
|
||||
#endif
|
||||
|
||||
# include "netlist.h"
|
||||
|
|
@ -49,8 +49,25 @@ extern string nexus_from_link(const Link*lnk);
|
|||
*/
|
||||
extern NetConst* link_const_value(Link&pin, unsigned&idx);
|
||||
|
||||
/*
|
||||
* This local function returns true if all the the possible drivers of
|
||||
* this link are constant. It will also return true if there are no
|
||||
* drivers at all.
|
||||
*/
|
||||
extern bool link_drivers_constant(const Link&lnk);
|
||||
|
||||
/*
|
||||
* This function returns the value of the constant driving this link,
|
||||
* or Vz if there is no constant. The results of this function are
|
||||
* only meaningful if link_drivers_constant(lnk) == true.
|
||||
*/
|
||||
extern verinum::V driven_value(const Link&lnk);
|
||||
|
||||
/*
|
||||
* $Log: netmisc.h,v $
|
||||
* Revision 1.7 2000/05/14 17:55:04 steve
|
||||
* Support initialization of FF Q value.
|
||||
*
|
||||
* Revision 1.6 2000/05/07 04:37:56 steve
|
||||
* Carry strength values from Verilog source to the
|
||||
* pform and netlist for gates.
|
||||
|
|
|
|||
52
syn-rules.y
52
syn-rules.y
|
|
@ -19,7 +19,7 @@
|
|||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
||||
*/
|
||||
#if !defined(WINNT) && !defined(macintosh)
|
||||
#ident "$Id: syn-rules.y,v 1.2 2000/05/13 22:46:22 steve Exp $"
|
||||
#ident "$Id: syn-rules.y,v 1.3 2000/05/14 17:55:04 steve Exp $"
|
||||
#endif
|
||||
|
||||
/*
|
||||
|
|
@ -31,7 +31,9 @@
|
|||
*/
|
||||
|
||||
# include "netlist.h"
|
||||
# include "netmisc.h"
|
||||
# include "functor.h"
|
||||
# include <assert.h>
|
||||
|
||||
struct syn_token_t {
|
||||
int token;
|
||||
|
|
@ -55,9 +57,12 @@ static void make_DFF_CE(Design*des, NetProcTop*top, NetEvWait*wclk,
|
|||
NetEvent*eclk, NetExpr*cexp, NetAssign*asn);
|
||||
static void make_RAM_CE(Design*des, NetProcTop*top, NetEvWait*wclk,
|
||||
NetEvent*eclk, NetExpr*cexp, NetAssignMem*asn);
|
||||
static void make_initializer(Design*des, NetProcTop*top, NetAssign*asn);
|
||||
|
||||
%}
|
||||
|
||||
%token S_ALWAYS S_ASSIGN S_ASSIGN_MEM S_ELSE S_EVENT S_EXPR S_IF S_INITIAL
|
||||
%token S_ALWAYS S_ASSIGN S_ASSIGN_MEM S_ASSIGN_MUX S_ELSE S_EVENT
|
||||
%token S_EXPR S_IF S_INITIAL
|
||||
|
||||
%%
|
||||
|
||||
|
|
@ -87,6 +92,13 @@ start
|
|||
$7->expr, $8->assign);
|
||||
}
|
||||
|
||||
/* Unconditional assignments in initial blocks should be made into
|
||||
initializers wherever possible. */
|
||||
|
||||
| S_INITIAL S_ASSIGN
|
||||
{ make_initializer(des_, $1->top, $2->assign);
|
||||
}
|
||||
|
||||
|
||||
/* These rules match RAM devices. They are similar to DFF, except
|
||||
that there is an index for the word. The typical Verilog that get
|
||||
|
|
@ -122,9 +134,11 @@ static void make_DFF_CE(Design*des, NetProcTop*top, NetEvWait*wclk,
|
|||
NetEvent*eclk, NetExpr*cexp, NetAssign*asn)
|
||||
{
|
||||
NetEvProbe*pclk = eclk->probe(0);
|
||||
NetNet*d = asn->rval()->synthesize(des);
|
||||
NetESignal*d = dynamic_cast<NetESignal*> (asn->rval());
|
||||
NetNet*ce = cexp? cexp->synthesize(des) : 0;
|
||||
|
||||
assert(d);
|
||||
|
||||
NetFF*ff = new NetFF(asn->name(), asn->pin_count());
|
||||
|
||||
for (unsigned idx = 0 ; idx < ff->width() ; idx += 1) {
|
||||
|
|
@ -150,9 +164,11 @@ static void make_RAM_CE(Design*des, NetProcTop*top, NetEvWait*wclk,
|
|||
NetNet*adr = asn->index();
|
||||
|
||||
NetEvProbe*pclk = eclk->probe(0);
|
||||
NetNet*d = asn->rval()->synthesize(des);
|
||||
NetESignal*d = dynamic_cast<NetESignal*> (asn->rval());
|
||||
NetNet*ce = cexp? cexp->synthesize(des) : 0;
|
||||
|
||||
assert(d);
|
||||
|
||||
NetRamDq*ram = new NetRamDq(des_->local_symbol(mem->name()), mem,
|
||||
adr->pin_count());
|
||||
|
||||
|
|
@ -174,6 +190,28 @@ static void make_RAM_CE(Design*des, NetProcTop*top, NetEvWait*wclk,
|
|||
des->delete_process(top);
|
||||
}
|
||||
|
||||
static void make_initializer(Design*des, NetProcTop*top, NetAssign*asn)
|
||||
{
|
||||
NetESignal*rsig = dynamic_cast<NetESignal*> (asn->rval());
|
||||
assert(rsig);
|
||||
|
||||
for (unsigned idx = 0 ; idx < asn->pin_count() ; idx += 1) {
|
||||
|
||||
verinum::V bit = driven_value(rsig->pin(idx));
|
||||
|
||||
Link*cur = asn->pin(idx).next_link();
|
||||
while (cur != &asn->pin(idx)) {
|
||||
|
||||
if (NetNet*net = dynamic_cast<NetNet*> (cur->get_obj()))
|
||||
net->set_ival(cur->get_pin(), bit);
|
||||
|
||||
cur = cur->next_link();
|
||||
}
|
||||
}
|
||||
|
||||
des->delete_process(top);
|
||||
}
|
||||
|
||||
static syn_token_t*first_ = 0;
|
||||
static syn_token_t*last_ = 0;
|
||||
static syn_token_t*ptr_ = 0;
|
||||
|
|
@ -191,15 +229,11 @@ struct tokenize : public proc_match_t {
|
|||
{
|
||||
syn_token_t*cur;
|
||||
cur = new syn_token_t;
|
||||
cur->token = S_ASSIGN;
|
||||
cur->token = dev->bmux() ? S_ASSIGN_MUX : S_ASSIGN;
|
||||
cur->assign = dev;
|
||||
cur->next_ = 0;
|
||||
last_->next_ = cur;
|
||||
last_ = cur;
|
||||
|
||||
if (dynamic_cast<NetEConst*>(dev->rval()))
|
||||
fprintf(stderr, "XXXX constant assignment.\n");
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
|
|||
40
t-xnf.cc
40
t-xnf.cc
|
|
@ -17,7 +17,7 @@
|
|||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
||||
*/
|
||||
#if !defined(WINNT) && !defined(macintosh)
|
||||
#ident "$Id: t-xnf.cc,v 1.28 2000/05/08 05:29:43 steve Exp $"
|
||||
#ident "$Id: t-xnf.cc,v 1.29 2000/05/14 17:55:04 steve Exp $"
|
||||
#endif
|
||||
|
||||
/* XNF BACKEND
|
||||
|
|
@ -75,6 +75,19 @@
|
|||
# include <fstream>
|
||||
# include <strstream>
|
||||
|
||||
verinum::V link_get_ival(const Link&lnk)
|
||||
{
|
||||
const Link*cur = lnk.next_link();
|
||||
while (cur != &lnk) {
|
||||
if (const NetNet*sig = dynamic_cast<const NetNet*>(cur->get_obj()))
|
||||
return sig->get_ival(cur->get_pin());
|
||||
|
||||
cur = cur->next_link();
|
||||
}
|
||||
|
||||
return verinum::Vx;
|
||||
}
|
||||
|
||||
class target_xnf : public target_t {
|
||||
|
||||
public:
|
||||
|
|
@ -682,10 +695,28 @@ void target_xnf::lpm_ff(ostream&os, const NetFF*net)
|
|||
|
||||
assert(net->attribute("XNF-LCA") == "");
|
||||
|
||||
/* Create a DFF object for each bit of width. The symbol name
|
||||
has the index number appended so that read XNF may be able
|
||||
to buss them. If the NetNet objects connected to the Q
|
||||
output of the DFF have an initial value, the write an INIT=
|
||||
parameter to set the power-up value. */
|
||||
|
||||
for (unsigned idx = 0 ; idx < net->width() ; idx += 1) {
|
||||
|
||||
os << "SYM, " << mangle(net->name()) << "<" << idx
|
||||
<< ">, DFF, LIBVER=2.0.0" << endl;
|
||||
verinum::V ival = link_get_ival(net->pin_Q(idx));
|
||||
|
||||
os << "SYM, " << mangle(net->name()) << "<" << idx << ">, DFF, ";
|
||||
|
||||
switch (ival) {
|
||||
case verinum::V0:
|
||||
os << "INIT=R, ";
|
||||
break;
|
||||
case verinum::V1:
|
||||
os << "INIT=S, ";
|
||||
break;
|
||||
}
|
||||
|
||||
os << "LIBVER=2.0.0" << endl;
|
||||
draw_pin(os, "Q", net->pin_Q(idx));
|
||||
draw_pin(os, "D", net->pin_Data(idx));
|
||||
|
||||
|
|
@ -887,6 +918,9 @@ extern const struct target tgt_xnf = { "xnf", &target_xnf_obj };
|
|||
|
||||
/*
|
||||
* $Log: t-xnf.cc,v $
|
||||
* Revision 1.29 2000/05/14 17:55:04 steve
|
||||
* Support initialization of FF Q value.
|
||||
*
|
||||
* Revision 1.28 2000/05/08 05:29:43 steve
|
||||
* no need for nobufz functor.
|
||||
*
|
||||
|
|
|
|||
Loading…
Reference in New Issue