Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP
Browse files

Add the synth functor to do generic synthesis

 and add the LPM_FF device to handle rows of
 flip-flops.
  • Loading branch information...
commit 89881adece3d3849fe3011bd7c2fddb40e31d1bd 1 parent f80c4a3
steve authored
View
4 Makefile.in
@@ -18,7 +18,7 @@
# 59 Temple Place - Suite 330
# Boston, MA 02111-1307, USA
#
-#ident "$Id: Makefile.in,v 1.25 1999/10/31 20:08:24 steve Exp $"
+#ident "$Id: Makefile.in,v 1.26 1999/11/01 02:07:40 steve Exp $"
#
#
SHELL = /bin/sh
@@ -66,7 +66,7 @@ distclean: clean
rm -f Makefile
TT = t-null.o t-verilog.o t-vvm.o t-xnf.o
-FF = nobufz.o propinit.o sigfold.o xnfio.o xnfsyn.o
+FF = nobufz.o propinit.o sigfold.o synth.o xnfio.o xnfsyn.o
O = main.o cprop.o design_dump.o elaborate.o elab_expr.o elab_net.o \
emit.o eval.o eval_tree.o functor.o \
View
14 design_dump.cc
@@ -17,7 +17,7 @@
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/
#if !defined(WINNT)
-#ident "$Id: design_dump.cc,v 1.52 1999/10/31 20:08:24 steve Exp $"
+#ident "$Id: design_dump.cc,v 1.53 1999/11/01 02:07:40 steve Exp $"
#endif
/*
@@ -168,6 +168,13 @@ void NetConst::dump_node(ostream&o, unsigned ind) const
dump_node_pins(o, ind+4);
}
+void NetFF::dump_node(ostream&o, unsigned ind) const
+{
+ o << setw(ind) << "" << "LPM_FF: " << name() << endl;
+ dump_node_pins(o, ind+4);
+ dump_obj_attr(o, ind+4);
+}
+
void NetLogic::dump_node(ostream&o, unsigned ind) const
{
o << setw(ind) << "" << "logic: ";
@@ -798,6 +805,11 @@ void Design::dump(ostream&o) const
/*
* $Log: design_dump.cc,v $
+ * Revision 1.53 1999/11/01 02:07:40 steve
+ * Add the synth functor to do generic synthesis
+ * and add the LPM_FF device to handle rows of
+ * flip-flops.
+ *
* Revision 1.52 1999/10/31 20:08:24 steve
* Include subtraction in LPM_ADD_SUB device.
*
View
12 emit.cc
@@ -17,7 +17,7 @@
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/
#if !defined(WINNT)
-#ident "$Id: emit.cc,v 1.24 1999/10/10 01:59:54 steve Exp $"
+#ident "$Id: emit.cc,v 1.25 1999/11/01 02:07:40 steve Exp $"
#endif
/*
@@ -70,6 +70,11 @@ void NetConst::emit_node(ostream&o, struct target_t*tgt) const
tgt->net_const(o, this);
}
+void NetFF::emit_node(ostream&o, struct target_t*tgt) const
+{
+ tgt->lpm_ff(o, this);
+}
+
void NetNEvent::emit_node(ostream&o, struct target_t*tgt) const
{
tgt->net_event(o, this);
@@ -357,6 +362,11 @@ bool emit(ostream&o, const Design*des, const char*type)
/*
* $Log: emit.cc,v $
+ * Revision 1.25 1999/11/01 02:07:40 steve
+ * Add the synth functor to do generic synthesis
+ * and add the LPM_FF device to handle rows of
+ * flip-flops.
+ *
* Revision 1.24 1999/10/10 01:59:54 steve
* Structural case equals device.
*
View
31 functor.cc
@@ -17,7 +17,7 @@
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/
#if !defined(WINNT)
-#ident "$Id: functor.cc,v 1.2 1999/07/18 05:52:46 steve Exp $"
+#ident "$Id: functor.cc,v 1.3 1999/11/01 02:07:40 steve Exp $"
#endif
# include "functor.h"
@@ -35,6 +35,10 @@ void functor_t::process(class Design*, class NetProcTop*)
{
}
+void functor_t::lpm_ff(class Design*, class NetFF*)
+{
+}
+
void Design::functor(functor_t*fun)
{
// apply to signals
@@ -53,10 +57,35 @@ void Design::functor(functor_t*fun)
procs_idx_ = idx->next_;
fun->process(this, idx);
}
+
+ // apply to nodes
+ if (nodes_) {
+ NetNode*cur = nodes_->node_next_;
+ do {
+ NetNode*tmp = cur->node_next_;
+ cur->functor_node(this, fun);
+ cur = tmp;
+ } while (cur != nodes_->node_next_);
+ }
+}
+
+
+void NetNode::functor_node(Design*, functor_t*)
+{
+}
+
+void NetFF::functor_node(Design*des, functor_t*fun)
+{
+ fun->lpm_ff(des, this);
}
/*
* $Log: functor.cc,v $
+ * Revision 1.3 1999/11/01 02:07:40 steve
+ * Add the synth functor to do generic synthesis
+ * and add the LPM_FF device to handle rows of
+ * flip-flops.
+ *
* Revision 1.2 1999/07/18 05:52:46 steve
* xnfsyn generates DFF objects for XNF output, and
* properly rewrites the Design netlist in the process.
View
9 functor.h
@@ -19,7 +19,7 @@
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/
#if !defined(WINNT)
-#ident "$Id: functor.h,v 1.1 1999/07/17 22:01:13 steve Exp $"
+#ident "$Id: functor.h,v 1.2 1999/11/01 02:07:40 steve Exp $"
#endif
/*
@@ -42,10 +42,17 @@ struct functor_t {
/* This method is called for each process in the design. */
virtual void process(class Design*des, class NetProcTop*);
+ /* This method is called for each FF in the design. */
+ virtual void lpm_ff(class Design*des, class NetFF*);
};
/*
* $Log: functor.h,v $
+ * Revision 1.2 1999/11/01 02:07:40 steve
+ * Add the synth functor to do generic synthesis
+ * and add the LPM_FF device to handle rows of
+ * flip-flops.
+ *
* Revision 1.1 1999/07/17 22:01:13 steve
* Add the functor interface for functor transforms.
*
View
26 lpm.txt
@@ -0,0 +1,26 @@
+
+WHAT IS LPM
+
+LPM (Library of Paramaterized Modules) is EIS-IS standard 103-A. It is
+a standard library of abstract devices that are designed to be close
+enough to the target hardware to be easily translated, yet abstract
+enough to support a variety of target technologies without excessive
+constraints. Icarus Verilog uses LPM internally to represent idealized
+hardware, especially when doing target neutral synthesis.
+
+In general, the user does not even see the LPM that Icarus Verilog
+generates, because the LPM devices are translated into technology
+specific devices by the final code generator or target specific
+optimizers.
+
+INTERNAL USES OF LPM
+
+Internally, Icarus Verilog uses LPM devices to represent the design in
+abstract, especially when synthesizing such functions as addition,
+flip-flops, etc. The ``synth'' functor generates LPM modules when
+interpreting procedural constructs. The functor generates the LPM
+objects needed to replace a behavioral description, and uses
+attributes to tag the devices with LPM properties.
+
+Code generators need to understand the supported LPM devices so that
+they can translate the devices into technology specific devices.
View
9 main.cc
@@ -19,7 +19,7 @@ const char COPYRIGHT[] =
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/
#if !defined(WINNT)
-#ident "$Id: main.cc,v 1.23 1999/09/22 16:57:23 steve Exp $"
+#ident "$Id: main.cc,v 1.24 1999/11/01 02:07:40 steve Exp $"
#endif
const char NOTICE[] =
@@ -79,6 +79,7 @@ extern Design* elaborate(const map<string,Module*>&modules,
extern void cprop(Design*des);
extern void propinit(Design*des);
extern void sigfold(Design*des);
+extern void synth(Design*des);
extern void nobufz(Design*des);
extern void xnfio(Design*des);
extern void xnfsyn(Design*des);
@@ -92,6 +93,7 @@ static struct net_func_map {
{ "nobufz", &nobufz },
{ "propinit", &propinit },
{ "sigfold", &sigfold },
+ { "synth", &synth },
{ "xnfio", &xnfio },
{ "xnfsyn", &xnfsyn },
{ 0, 0 }
@@ -277,6 +279,11 @@ int main(int argc, char*argv[])
/*
* $Log: main.cc,v $
+ * Revision 1.24 1999/11/01 02:07:40 steve
+ * Add the synth functor to do generic synthesis
+ * and add the LPM_FF device to handle rows of
+ * flip-flops.
+ *
* Revision 1.23 1999/09/22 16:57:23 steve
* Catch parallel blocks in vvm emit.
*
View
124 netlist.cc
@@ -17,7 +17,7 @@
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/
#if !defined(WINNT)
-#ident "$Id: netlist.cc,v 1.78 1999/10/31 04:11:27 steve Exp $"
+#ident "$Id: netlist.cc,v 1.79 1999/11/01 02:07:40 steve Exp $"
#endif
# include <cassert>
@@ -376,7 +376,122 @@ const NetProc* NetProcTop::statement() const
}
/*
- * The NetAddSub class represents an LPM ADD_SUB device. The pinout is
+ * The NetFF class represents an LPM_FF device. The pinout is assigned
+ * like so:
+ * 0 -- Clock
+ * 1 -- Enable
+ * 2 -- Aload
+ * 3 -- Aset
+ * 4 -- Aclr
+ * 5 -- Sload
+ * 6 -- Sset
+ * 7 -- Sclr
+ *
+ * 8 -- Data[0]
+ * 9 -- Q[0]
+ * ...
+ */
+
+NetFF::NetFF(const string&n, unsigned wid)
+: NetNode(n, 8 + 2*wid)
+{
+ pin_Clock().set_dir(Link::INPUT);
+ pin_Clock().set_name("Clock", 0);
+ pin_Enable().set_dir(Link::INPUT);
+ pin_Enable().set_name("Enable", 0);
+ pin_Aload().set_dir(Link::INPUT);
+ pin_Aload().set_name("Aload", 0);
+ pin_Aset().set_dir(Link::INPUT);
+ pin_Aset().set_name("Aset", 0);
+ pin_Aclr().set_dir(Link::INPUT);
+ pin_Aclr().set_name("Aclr", 0);
+ pin_Sload().set_dir(Link::INPUT);
+ pin_Sload().set_name("Sload", 0);
+ pin_Sset().set_dir(Link::INPUT);
+ pin_Sset().set_name("Sset", 0);
+ pin_Sclr().set_dir(Link::INPUT);
+ pin_Sclr().set_name("Sclr", 0);
+ for (unsigned idx = 0 ; idx < wid ; idx += 1) {
+ pin_Data(idx).set_dir(Link::INPUT);
+ pin_Data(idx).set_name("Data", idx);
+ pin_Q(idx).set_dir(Link::OUTPUT);
+ pin_Q(idx).set_name("Q", idx);
+ }
+}
+
+NetFF::~NetFF()
+{
+}
+
+unsigned NetFF::width() const
+{
+ return (pin_count() - 8) / 2;
+}
+
+NetObj::Link& NetFF::pin_Clock()
+{
+ return pin(0);
+}
+
+NetObj::Link& NetFF::pin_Enable()
+{
+ return pin(1);
+}
+
+NetObj::Link& NetFF::pin_Aload()
+{
+ return pin(2);
+}
+
+NetObj::Link& NetFF::pin_Aset()
+{
+ return pin(3);
+}
+
+NetObj::Link& NetFF::pin_Aclr()
+{
+ return pin(4);
+}
+
+NetObj::Link& NetFF::pin_Sload()
+{
+ return pin(5);
+}
+
+NetObj::Link& NetFF::pin_Sset()
+{
+ return pin(6);
+}
+
+NetObj::Link& NetFF::pin_Sclr()
+{
+ return pin(7);
+}
+
+NetObj::Link& NetFF::pin_Data(unsigned w)
+{
+ unsigned pn = 8 + 2*w;
+ assert(pn < pin_count());
+ return pin(pn);
+}
+
+NetObj::Link& NetFF::pin_Q(unsigned w)
+{
+ unsigned pn = 9 + w*2;
+ assert(pn < pin_count());
+ return pin(pn);
+}
+
+const NetObj::Link& NetFF::pin_Q(unsigned w) const
+{
+ unsigned pn = 9 + w*2;
+ assert(pn < pin_count());
+ return pin(pn);
+}
+
+
+/*
+ * The NetAddSub class represents an LPM_ADD_SUB device. The pinout is
* assigned like so:
* 0 -- Add_Sub
* 1 -- Aclr
@@ -1878,6 +1993,11 @@ NetNet* Design::find_signal(bool (*func)(const NetNet*))
/*
* $Log: netlist.cc,v $
+ * Revision 1.79 1999/11/01 02:07:40 steve
+ * Add the synth functor to do generic synthesis
+ * and add the LPM_FF device to handle rows of
+ * flip-flops.
+ *
* Revision 1.78 1999/10/31 04:11:27 steve
* Add to netlist links pin name and instance number,
* and arrange in vvm for pin connections by name
View
40 netlist.h
@@ -19,7 +19,7 @@
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/
#if !defined(WINNT)
-#ident "$Id: netlist.h,v 1.81 1999/10/31 04:11:27 steve Exp $"
+#ident "$Id: netlist.h,v 1.82 1999/11/01 02:07:40 steve Exp $"
#endif
/*
@@ -211,6 +211,8 @@ class NetNode : public NetObj {
virtual void emit_node(ostream&, struct target_t*) const;
virtual void dump_node(ostream&, unsigned) const;
+ virtual void functor_node(Design*, functor_t*);
+
private:
friend class Design;
NetNode*node_next_, *node_prev_;
@@ -322,6 +324,37 @@ class NetAddSub : public NetNode {
};
/*
+ * This class represents an LPM_FF device. There is no literal gate
+ * type in Verilog that maps, but gates of this type can be inferred.
+ */
+class NetFF : public NetNode {
+
+ public:
+ NetFF(const string&n, unsigned width);
+ ~NetFF();
+
+ unsigned width() const;
+
+ NetObj::Link& pin_Clock();
+ NetObj::Link& pin_Enable();
+ NetObj::Link& pin_Aload();
+ NetObj::Link& pin_Aset();
+ NetObj::Link& pin_Aclr();
+ NetObj::Link& pin_Sload();
+ NetObj::Link& pin_Sset();
+ NetObj::Link& pin_Sclr();
+
+ NetObj::Link& pin_Data(unsigned);
+ NetObj::Link& pin_Q(unsigned);
+
+ const NetObj::Link& pin_Q(unsigned) const;
+
+ virtual void dump_node(ostream&, unsigned ind) const;
+ virtual void emit_node(ostream&, struct target_t*) const;
+ virtual void functor_node(Design*des, functor_t*fun);
+};
+
+/*
* This class represents the declared memory object. The parser
* creates one of these for each declared memory in the elaborated
* design. A reference to one of these is handled by the NetEMemory
@@ -1749,6 +1782,11 @@ extern ostream& operator << (ostream&, NetNet::Type);
/*
* $Log: netlist.h,v $
+ * Revision 1.82 1999/11/01 02:07:40 steve
+ * Add the synth functor to do generic synthesis
+ * and add the LPM_FF device to handle rows of
+ * flip-flops.
+ *
* Revision 1.81 1999/10/31 04:11:27 steve
* Add to netlist links pin name and instance number,
* and arrange in vvm for pin connections by name
View
244 synth.cc
@@ -0,0 +1,244 @@
+/*
+ * Copyright (c) 1999 Stephen Williams (steve@icarus.com)
+ *
+ * This source code is free software; you can redistribute it
+ * and/or modify it in source code form under the terms of the GNU
+ * General Public License as published by the Free Software
+ * Foundation; either version 2 of the License, or (at your option)
+ * any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
+ */
+#if !defined(WINNT)
+#ident "$Id: synth.cc,v 1.1 1999/11/01 02:07:41 steve Exp $"
+#endif
+
+/*
+ * The synth function searches the behavioral description for
+ * patterns that are known to represent LPM library components. This
+ * is especially interesting for the sequential components such as
+ * flip flops and latches. As threads are transformed into components,
+ * the design is rewritten.
+ *
+ * Currently, this transform recognizes the following patterns:
+ *
+ * always @(posedge CLK) Q = D
+ * always @(negedge CLK) Q = D
+ *
+ * always @(posedge CLK) if (CE) Q = D;
+ * always @(negedge CLK) if (CE) Q = D;
+ *
+ * The r-value of the assignments must be identifiers (i.e. wires or
+ * registers) and the CE must be single-bit identifiers. The generated
+ * device will be wide enough to accomodate Q and D.
+ */
+# include "functor.h"
+# include "netlist.h"
+
+class synth_f : public functor_t {
+
+ public:
+ void process(class Design*, class NetProcTop*);
+
+ private:
+ void proc_always_(class Design*);
+ void proc_casn_(class Design*);
+ void proc_ccon_(class Design*);
+
+ // The matcher does something like a recursive descent search
+ // for the templates. These variables are filled in as the
+ // searcher finds them.
+
+ class NetProcTop*top_;
+
+ class NetPEvent *pclk_;
+ class NetNEvent *nclk_;
+
+ class NetCondit *con_;
+ class NetAssign *asn_;
+};
+
+
+/*
+ * Look at a process, and divide the problem into always and initial
+ * threads.
+ */
+void synth_f::process(class Design*des, class NetProcTop*top)
+{
+ switch (top->type()) {
+ case NetProcTop::KALWAYS:
+ top_ = top;
+ proc_always_(des);
+ break;
+ }
+}
+
+/*
+ * An "always ..." statement has been found.
+ */
+void synth_f::proc_always_(class Design*des)
+{
+ // The statement must be a NetPEvent, ...
+ pclk_ = dynamic_cast<class NetPEvent*>(top_->statement());
+ if (pclk_ == 0)
+ return;
+
+ // ... there must be a single event source, ...
+ svector<class NetNEvent*>*neb = pclk_->back_list();
+ if (neb == 0)
+ return;
+ if (neb->count() != 1) {
+ delete neb;
+ return;
+ }
+ nclk_ = (*neb)[0];
+ delete neb;
+
+ // ... the event must be an edge, ...
+ switch (nclk_->type()) {
+ case NetNEvent::POSEDGE:
+ case NetNEvent::NEGEDGE:
+ break;
+ default:
+ return;
+ }
+
+ // Is this a clocked assignment?
+ asn_ = dynamic_cast<NetAssign*>(pclk_->statement());
+ if (asn_) {
+ proc_casn_(des);
+ return;
+ }
+
+ con_ = dynamic_cast<NetCondit*>(pclk_->statement());
+ if (con_) {
+ proc_ccon_(des);
+ return;
+ }
+}
+
+/*
+ * The process so far has been matched as:
+ *
+ * always @(posedge nclk_) asn_ = <r>;
+ * always @(negedge nclk_) asn_ = <r>;
+ */
+void synth_f::proc_casn_(class Design*des)
+{
+
+ // ... and the rval must be a simple signal.
+ NetESignal*sig = dynamic_cast<NetESignal*>(asn_->rval());
+ if (sig == 0) {
+ cerr << "Noted complex rval in DFF, name " << asn_->name() <<
+ ", not yet implemented" << endl;
+ return ;
+ }
+
+ // The signal and the assignment must be the same width...
+ assert(asn_->pin_count() == sig->pin_count());
+
+ NetFF*ff = new NetFF(asn_->name(), asn_->pin_count());
+ ff->attribute("LPM_FFType", "DFF");
+
+ for (unsigned idx = 0 ; idx < ff->width() ; idx += 1) {
+ connect(ff->pin_Data(idx), sig->pin(idx));
+ connect(ff->pin_Q(idx), asn_->pin(idx));
+ }
+
+ switch (nclk_->type()) {
+ case NetNEvent::POSEDGE:
+ connect(ff->pin_Clock(), nclk_->pin(0));
+ break;
+
+ case NetNEvent::NEGEDGE:
+ connect(ff->pin_Clock(), nclk_->pin(0));
+ ff->attribute("Clock:LPM_Polarity", "INVERT");
+ break;
+ }
+
+ des->add_node(ff);
+
+ // This process is matched and replaced with a DFF. Get
+ // rid of the now useless NetProcTop.
+ des->delete_process(top_);
+}
+
+/*
+ * The process so far has been matched as:
+ *
+ * always @(posedge nclk_) if ...;
+ * always @(negedge nclk_) if ...;
+ */
+void synth_f::proc_ccon_(class Design*des)
+{
+ if (con_->else_clause())
+ return;
+
+ asn_ = dynamic_cast<NetAssign*>(con_->if_clause());
+ if (asn_ == 0)
+ return;
+
+ NetESignal*sig = dynamic_cast<NetESignal*>(asn_->rval());
+ if (sig == 0)
+ return;
+
+ // The signal and the assignment must be the same width...
+ assert(asn_->pin_count() == sig->pin_count());
+
+ NetESignal*ce = dynamic_cast<NetESignal*>(con_->expr());
+ if (ce == 0)
+ return;
+ if (ce->pin_count() != 1)
+ return;
+
+ NetFF*ff = new NetFF(asn_->name(), asn_->pin_count());
+ ff->attribute("LPM_FFType", "DFF");
+
+ for (unsigned idx = 0 ; idx < ff->width() ; idx += 1) {
+ connect(ff->pin_Data(idx), sig->pin(idx));
+ connect(ff->pin_Q(idx), asn_->pin(idx));
+ }
+
+ switch (nclk_->type()) {
+ case NetNEvent::POSEDGE:
+ connect(ff->pin_Clock(), nclk_->pin(0));
+ connect(ff->pin_Enable(), ce->pin(0));
+ break;
+
+ case NetNEvent::NEGEDGE:
+ connect(ff->pin_Clock(), nclk_->pin(0));
+ connect(ff->pin_Enable(), ce->pin(0));
+ ff->attribute("Clock:LPM_Polarity", "INVERT");
+ break;
+ }
+
+ des->add_node(ff);
+
+
+ // This process is matched and replaced with a DFF. Get
+ // rid of the now useless NetProcTop.
+ des->delete_process(top_);
+}
+
+void synth(Design*des)
+{
+ synth_f synth_obj;
+ des->functor(&synth_obj);
+}
+
+/*
+ * $Log: synth.cc,v $
+ * Revision 1.1 1999/11/01 02:07:41 steve
+ * Add the synth functor to do generic synthesis
+ * and add the LPM_FF device to handle rows of
+ * flip-flops.
+ *
+ */
+
View
23 t-vvm.cc
@@ -17,7 +17,7 @@
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/
#if !defined(WINNT)
-#ident "$Id: t-vvm.cc,v 1.70 1999/10/31 20:08:24 steve Exp $"
+#ident "$Id: t-vvm.cc,v 1.71 1999/11/01 02:07:41 steve Exp $"
#endif
# include <iostream>
@@ -53,6 +53,7 @@ class target_vvm : public target_t {
virtual void func_def(ostream&os, const NetFuncDef*);
virtual void lpm_add_sub(ostream&os, const NetAddSub*);
+ virtual void lpm_ff(ostream&os, const NetFF*);
virtual void logic(ostream&os, const NetLogic*);
virtual void bufz(ostream&os, const NetBUFZ*);
@@ -835,6 +836,21 @@ void target_vvm::lpm_add_sub(ostream&os, const NetAddSub*gate)
}
}
+void target_vvm::lpm_ff(ostream&os, const NetFF*gate)
+{
+ string mname = mangle(gate->name());
+ os << "static vvm_ff<" << gate->width() << "> " << mname << ";"
+ << endl;
+
+ for (unsigned idx = 0 ; idx < gate->width() ; idx += 1) {
+ unsigned pin = gate->pin_Q(idx).get_pin();
+ string outfun = defn_gate_outputfun_(os, gate, pin);
+ init_code << " " << mangle(gate->name()) <<
+ ".config_rout(" << idx << ", &" << outfun << ");" << endl;
+ emit_gate_outputfun_(gate, pin);
+ }
+}
+
void target_vvm::logic(ostream&os, const NetLogic*gate)
{
string outfun = defn_gate_outputfun_(os, gate, 0);
@@ -1802,6 +1818,11 @@ extern const struct target tgt_vvm = {
};
/*
* $Log: t-vvm.cc,v $
+ * Revision 1.71 1999/11/01 02:07:41 steve
+ * Add the synth functor to do generic synthesis
+ * and add the LPM_FF device to handle rows of
+ * flip-flops.
+ *
* Revision 1.70 1999/10/31 20:08:24 steve
* Include subtraction in LPM_ADD_SUB device.
*
View
13 target.cc
@@ -17,7 +17,7 @@
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/
#if !defined(WINNT)
-#ident "$Id: target.cc,v 1.21 1999/10/10 01:59:55 steve Exp $"
+#ident "$Id: target.cc,v 1.22 1999/11/01 02:07:41 steve Exp $"
#endif
# include "target.h"
@@ -75,6 +75,12 @@ void target_t::lpm_add_sub(ostream&, const NetAddSub*)
"Unhandled NetAddSub." << endl;
}
+void target_t::lpm_ff(ostream&, const NetFF*)
+{
+ cerr << "target (" << typeid(*this).name() << "): "
+ "Unhandled NetFF." << endl;
+}
+
void target_t::net_assign(ostream&os, const NetAssign*)
{
}
@@ -275,6 +281,11 @@ void expr_scan_t::expr_binary(const NetEBinary*ex)
/*
* $Log: target.cc,v $
+ * Revision 1.22 1999/11/01 02:07:41 steve
+ * Add the synth functor to do generic synthesis
+ * and add the LPM_FF device to handle rows of
+ * flip-flops.
+ *
* Revision 1.21 1999/10/10 01:59:55 steve
* Structural case equals device.
*
View
8 target.h
@@ -19,7 +19,7 @@
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/
#if !defined(WINNT)
-#ident "$Id: target.h,v 1.20 1999/10/10 01:59:55 steve Exp $"
+#ident "$Id: target.h,v 1.21 1999/11/01 02:07:41 steve Exp $"
#endif
# include "netlist.h"
@@ -67,6 +67,7 @@ struct target_t {
/* LPM style components are handled here. */
virtual void lpm_add_sub(ostream&os, const NetAddSub*);
+ virtual void lpm_ff(ostream&os, const NetFF*);
/* Output a gate (called for each gate) */
virtual void logic(ostream&os, const NetLogic*);
@@ -137,6 +138,11 @@ extern const struct target *target_table[];
/*
* $Log: target.h,v $
+ * Revision 1.21 1999/11/01 02:07:41 steve
+ * Add the synth functor to do generic synthesis
+ * and add the LPM_FF device to handle rows of
+ * flip-flops.
+ *
* Revision 1.20 1999/10/10 01:59:55 steve
* Structural case equals device.
*
View
10 vvm/vvm.h
@@ -19,7 +19,7 @@
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/
#if !defined(WINNT)
-#ident "$Id: vvm.h,v 1.19 1999/10/31 04:11:28 steve Exp $"
+#ident "$Id: vvm.h,v 1.20 1999/11/01 02:07:41 steve Exp $"
#endif
# include <vector>
@@ -98,6 +98,9 @@ inline vpip_bit_t not(vpip_bit_t l)
}
}
+extern bool posedge(vpip_bit_t from, vpip_bit_t to);
+
+
class vvm_bits_t {
public:
virtual ~vvm_bits_t() =0;
@@ -253,6 +256,11 @@ template <unsigned WIDTH> class vvm_signal_t : public __vpiSignal {
/*
* $Log: vvm.h,v $
+ * Revision 1.20 1999/11/01 02:07:41 steve
+ * Add the synth functor to do generic synthesis
+ * and add the LPM_FF device to handle rows of
+ * flip-flops.
+ *
* Revision 1.19 1999/10/31 04:11:28 steve
* Add to netlist links pin name and instance number,
* and arrange in vvm for pin connections by name
View
21 vvm/vvm_bit.cc
@@ -17,7 +17,7 @@
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/
#if !defined(WINNT)
-#ident "$Id: vvm_bit.cc,v 1.3 1999/10/28 00:47:25 steve Exp $"
+#ident "$Id: vvm_bit.cc,v 1.4 1999/11/01 02:07:41 steve Exp $"
#endif
# include "vvm.h"
@@ -41,6 +41,20 @@ ostream& operator << (ostream&os, vpip_bit_t bit)
return os;
}
+bool posedge(vpip_bit_t from, vpip_bit_t to)
+{
+ switch (from) {
+ case V1:
+ return false;
+ case V0:
+ return from != to;
+ case Vx:
+ case Vz:
+ return to == V1;
+ }
+ return false;
+}
+
ostream& operator << (ostream&os, const vvm_bits_t&str)
{
os << str.get_width() << "b'";
@@ -100,6 +114,11 @@ vpip_bit_t add_with_carry(vpip_bit_t l, vpip_bit_t r, vpip_bit_t&carry)
/*
* $Log: vvm_bit.cc,v $
+ * Revision 1.4 1999/11/01 02:07:41 steve
+ * Add the synth functor to do generic synthesis
+ * and add the LPM_FF device to handle rows of
+ * flip-flops.
+ *
* Revision 1.3 1999/10/28 00:47:25 steve
* Rewrite vvm VPI support to make objects more
* persistent, rewrite the simulation scheduler
View
57 vvm/vvm_gates.h
@@ -19,7 +19,7 @@
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/
#if !defined(WINNT)
-#ident "$Id: vvm_gates.h,v 1.17 1999/10/31 20:08:24 steve Exp $"
+#ident "$Id: vvm_gates.h,v 1.18 1999/11/01 02:07:41 steve Exp $"
#endif
# include "vvm.h"
@@ -152,6 +152,56 @@ template <unsigned WIDTH, unsigned long DELAY> class vvm_and {
vvm_out_event::action_t output_;
};
+/*
+ * This class simulates the LPM flip-flop device.
+ * XXXX Inverted clock not yet supported.
+ */
+template <unsigned WIDTH> class vvm_ff {
+
+ public:
+ explicit vvm_ff()
+ { clk_ = Vx;
+ for (unsigned idx = 0 ; idx < WIDTH ; idx += 1)
+ q_[idx] = Vx;
+ }
+ ~vvm_ff() { }
+
+ void init_Data(unsigned idx, vpip_bit_t val) { d_[idx] = val; }
+ void init_Clock(unsigned, vpip_bit_t val) { clk_ = val; }
+
+ void set_Clock(vvm_simulation*sim, unsigned, vpip_bit_t val)
+ { if (val == clk_) return;
+ bool flag = posedge(clk_, val);
+ clk_ = val;
+ if (flag) latch_(sim);
+ }
+
+ void set_Data(vvm_simulation*sim, unsigned idx, vpip_bit_t val)
+ { d_[idx] = val;
+ }
+
+ void config_rout(unsigned idx, vvm_out_event::action_t o)
+ { out_[idx] = o;
+ }
+
+ private:
+ vpip_bit_t d_[WIDTH];
+ vpip_bit_t q_[WIDTH];
+ vpip_bit_t clk_;
+
+ vvm_out_event::action_t out_[WIDTH];
+
+ void latch_(vvm_simulation*sim)
+ { q_ = d_;
+ for (unsigned idx = 0 ; idx < WIDTH ; idx += 1)
+ if (out_[idx]) {
+ vvm_event*ev = new vvm_out_event(sim, q_[idx],
+ out_[idx]);
+ sim->active_event(ev);
+ }
+ }
+};
+
template <unsigned WIDTH, unsigned long DELAY> class vvm_or {
public:
@@ -599,6 +649,11 @@ template <unsigned WIDTH> class vvm_pevent {
/*
* $Log: vvm_gates.h,v $
+ * Revision 1.18 1999/11/01 02:07:41 steve
+ * Add the synth functor to do generic synthesis
+ * and add the LPM_FF device to handle rows of
+ * flip-flops.
+ *
* Revision 1.17 1999/10/31 20:08:24 steve
* Include subtraction in LPM_ADD_SUB device.
*
Please sign in to comment.
Something went wrong with that request. Please try again.