Support initialization of FF Q value.

This commit is contained in:
steve 2000-05-14 17:55:04 +00:00
parent cca036c4a8
commit ea96c3ef66
5 changed files with 140 additions and 56 deletions

View File

@ -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.

View File

@ -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.

View File

@ -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.

View File

@ -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;
}

View File

@ -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.
*