Update the FF device to nexus style.
This commit is contained in:
parent
09e0d668a6
commit
2deb379c06
223
t-vvm.cc
223
t-vvm.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-vvm.cc,v 1.117 2000/03/18 02:26:02 steve Exp $"
|
||||
#ident "$Id: t-vvm.cc,v 1.118 2000/03/18 23:22:37 steve Exp $"
|
||||
#endif
|
||||
|
||||
# include <iostream>
|
||||
|
|
@ -119,9 +119,6 @@ class target_vvm : public target_t {
|
|||
char*defn_name;
|
||||
ofstream defn;
|
||||
|
||||
char*delayed_name;
|
||||
ofstream delayed;
|
||||
|
||||
char*init_code_name;
|
||||
ofstream init_code;
|
||||
|
||||
|
|
@ -150,7 +147,7 @@ class target_vvm : public target_t {
|
|||
|
||||
|
||||
target_vvm::target_vvm()
|
||||
: function_def_flag_(false), delayed_name(0), init_code_name(0)
|
||||
: function_def_flag_(false), init_code_name(0)
|
||||
{
|
||||
}
|
||||
|
||||
|
|
@ -650,9 +647,6 @@ void target_vvm::start_design(ostream&os, const Design*mod)
|
|||
defn_name = tempnam(0, "ivldf");
|
||||
defn.open(defn_name, ios::in | ios::out | ios::trunc);
|
||||
|
||||
delayed_name = tempnam(0, "ivlde");
|
||||
delayed.open(delayed_name, ios::in | ios::out | ios::trunc);
|
||||
|
||||
init_code_name = tempnam(0, "ivlic");
|
||||
init_code.open(init_code_name, ios::in | ios::out | ios::trunc);
|
||||
|
||||
|
|
@ -730,16 +724,6 @@ void target_vvm::end_design(ostream&os, const Design*mod)
|
|||
defn_name = 0;
|
||||
os << "// **** end definition code" << endl;
|
||||
|
||||
delayed.close();
|
||||
os << "// **** Delayed code" << endl;
|
||||
{ ifstream rdelayed (delayed_name);
|
||||
os << rdelayed.rdbuf();
|
||||
}
|
||||
unlink(delayed_name);
|
||||
free(delayed_name);
|
||||
delayed_name = 0;
|
||||
os << "// **** end delayed code" << endl;
|
||||
|
||||
|
||||
os << "// **** init_code" << endl;
|
||||
init_code << "}" << endl;
|
||||
|
|
@ -928,15 +912,8 @@ string target_vvm::defn_gate_outputfun_(ostream&os,
|
|||
const NetNode*gate,
|
||||
unsigned gpin)
|
||||
{
|
||||
const NetObj::Link&lnk = gate->pin(gpin);
|
||||
|
||||
ostrstream tmp;
|
||||
tmp << mangle(gate->name()) << "_output_" << lnk.get_name() <<
|
||||
"_" << lnk.get_inst() << ends;
|
||||
string name = tmp.str();
|
||||
|
||||
os << "static void " << name << "(vpip_bit_t);" << endl;
|
||||
return name;
|
||||
assert(0);
|
||||
return "";
|
||||
}
|
||||
|
||||
void target_vvm::emit_init_value_(const NetObj::Link&lnk, verinum::V val)
|
||||
|
|
@ -980,41 +957,7 @@ void target_vvm::emit_init_value_(const NetObj::Link&lnk, verinum::V val)
|
|||
*/
|
||||
void target_vvm::emit_gate_outputfun_(const NetNode*gate, unsigned gpin)
|
||||
{
|
||||
const NetObj::Link&lnk = gate->pin(gpin);
|
||||
|
||||
delayed << "static void " << mangle(gate->name()) <<
|
||||
"_output_" << lnk.get_name() << "_" << lnk.get_inst() <<
|
||||
"(vpip_bit_t val)" <<
|
||||
endl << "{" << endl;
|
||||
|
||||
/* The output function connects to gpin of the netlist part
|
||||
and causes the inputs that it is connected to to be set
|
||||
with the new value. */
|
||||
|
||||
const NetObj*cur;
|
||||
unsigned pin;
|
||||
gate->pin(gpin).next_link(cur, pin);
|
||||
for ( ; cur != gate ; cur->pin(pin).next_link(cur, pin)) {
|
||||
|
||||
// Skip pins that are output only.
|
||||
if (cur->pin(pin).get_dir() == NetObj::Link::OUTPUT)
|
||||
continue;
|
||||
|
||||
if (cur->pin(pin).get_name() != "") {
|
||||
|
||||
delayed << " " << mangle(cur->name()) << ".set_"
|
||||
<< cur->pin(pin).get_name() << "(" <<
|
||||
cur->pin(pin).get_inst() << ", val);" << endl;
|
||||
|
||||
} else {
|
||||
|
||||
delayed << " " << mangle(cur->name()) << ".set("
|
||||
<< pin << ", val);" << endl;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
delayed << "}" << endl;
|
||||
assert(0);
|
||||
}
|
||||
|
||||
void target_vvm::lpm_add_sub(ostream&os, const NetAddSub*gate)
|
||||
|
|
@ -1179,16 +1122,40 @@ void target_vvm::lpm_compare(ostream&os, const NetCompare*gate)
|
|||
|
||||
void target_vvm::lpm_ff(ostream&os, const NetFF*gate)
|
||||
{
|
||||
string nexus;
|
||||
unsigned ncode;
|
||||
string mname = mangle(gate->name());
|
||||
os << "static vvm_ff<" << gate->width() << "> " << mname << ";"
|
||||
<< endl;
|
||||
|
||||
os << "static vvm_ff " << mname << "(" << gate->width() << ");" << endl;
|
||||
|
||||
/* Connect the clock input... */
|
||||
|
||||
nexus = nexus_from_link(&gate->pin_Clock());
|
||||
ncode = nexus_wire_map[nexus];
|
||||
|
||||
init_code << " nexus_wire_table["<<ncode<<"].connect(&"
|
||||
<< mname << ", " << mname << ".key_Clock());" << endl;
|
||||
|
||||
/* Connect the Q output pins... */
|
||||
|
||||
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);
|
||||
nexus = nexus_from_link(&gate->pin_Q(idx));
|
||||
ncode = nexus_wire_map[nexus];
|
||||
|
||||
init_code << " nexus_wire_table["<<ncode<<"].connect("
|
||||
<< mname << ".config_rout(" << idx << "));" << endl;
|
||||
}
|
||||
|
||||
|
||||
/* Connect the Data input pins... */
|
||||
|
||||
for (unsigned idx = 0 ; idx < gate->width() ; idx += 1) {
|
||||
nexus = nexus_from_link(&gate->pin_Data(idx));
|
||||
ncode = nexus_wire_map[nexus];
|
||||
|
||||
init_code << " nexus_wire_table["<<ncode<<"].connect(&"
|
||||
<< mname << ", " << mname << ".key_Data(" << idx
|
||||
<< "));" << endl;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -2292,6 +2259,9 @@ extern const struct target tgt_vvm = {
|
|||
};
|
||||
/*
|
||||
* $Log: t-vvm.cc,v $
|
||||
* Revision 1.118 2000/03/18 23:22:37 steve
|
||||
* Update the FF device to nexus style.
|
||||
*
|
||||
* Revision 1.117 2000/03/18 02:26:02 steve
|
||||
* Update bufz to nexus style.
|
||||
*
|
||||
|
|
@ -2332,120 +2302,5 @@ extern const struct target tgt_vvm = {
|
|||
* drivers and resolution functions can be used, and
|
||||
* the t-vvm module doesn't need to write a zillion
|
||||
* output functions.
|
||||
*
|
||||
* Revision 1.107 2000/03/08 04:36:54 steve
|
||||
* Redesign the implementation of scopes and parameters.
|
||||
* I now generate the scopes and notice the parameters
|
||||
* in a separate pass over the pform. Once the scopes
|
||||
* are generated, I can process overrides and evalutate
|
||||
* paremeters before elaboration begins.
|
||||
*
|
||||
* Revision 1.106 2000/02/29 05:20:21 steve
|
||||
* Remove excess variable.
|
||||
*
|
||||
* Revision 1.105 2000/02/29 05:02:30 steve
|
||||
* Handle scope of complex guards when writing case in functions.
|
||||
*
|
||||
* Revision 1.104 2000/02/24 01:57:10 steve
|
||||
* I no longer need to declare string and number tables early.
|
||||
*
|
||||
* Revision 1.103 2000/02/23 02:56:55 steve
|
||||
* Macintosh compilers do not support ident.
|
||||
*
|
||||
* Revision 1.102 2000/02/14 01:20:50 steve
|
||||
* Support case in functions.
|
||||
*
|
||||
* Revision 1.101 2000/02/14 00:12:09 steve
|
||||
* support if-else in function definitions.
|
||||
*
|
||||
* Revision 1.100 2000/02/13 19:59:33 steve
|
||||
* Handle selecting memory words at run time.
|
||||
*
|
||||
* Revision 1.99 2000/02/13 19:18:27 steve
|
||||
* Accept memory words as parameter to $display.
|
||||
*
|
||||
* Revision 1.98 2000/01/18 04:53:57 steve
|
||||
* missing break is switch.
|
||||
*
|
||||
* Revision 1.97 2000/01/13 06:05:46 steve
|
||||
* Add the XNOR operator.
|
||||
*
|
||||
* Revision 1.96 2000/01/13 05:11:25 steve
|
||||
* Support for multiple VPI modules.
|
||||
*
|
||||
* Revision 1.95 2000/01/13 03:35:35 steve
|
||||
* Multiplication all the way to simulation.
|
||||
*
|
||||
* Revision 1.94 2000/01/08 03:09:14 steve
|
||||
* Non-blocking memory writes.
|
||||
*
|
||||
* Revision 1.93 2000/01/02 17:57:56 steve
|
||||
* It is possible for node to initialize several pins of a signal.
|
||||
*
|
||||
* Revision 1.92 1999/12/17 03:38:46 steve
|
||||
* NetConst can now hold wide constants.
|
||||
*
|
||||
* Revision 1.91 1999/12/16 02:42:15 steve
|
||||
* Simulate carry output on adders.
|
||||
*
|
||||
* Revision 1.90 1999/12/12 19:47:54 steve
|
||||
* Remove the useless vvm_simulation class.
|
||||
*
|
||||
* Revision 1.89 1999/12/12 06:03:14 steve
|
||||
* Allow memories without indices in expressions.
|
||||
*
|
||||
* Revision 1.88 1999/12/05 02:24:09 steve
|
||||
* Synthesize LPM_RAM_DQ for writes into memories.
|
||||
*
|
||||
* Revision 1.87 1999/12/02 16:58:58 steve
|
||||
* Update case comparison (Eric Aardoom).
|
||||
*
|
||||
* Revision 1.86 1999/11/29 00:38:27 steve
|
||||
* Properly initialize registers.
|
||||
*
|
||||
* Revision 1.85 1999/11/28 23:59:22 steve
|
||||
* Remove useless tests for NetESignal.
|
||||
*
|
||||
* Revision 1.84 1999/11/28 23:42:03 steve
|
||||
* NetESignal object no longer need to be NetNode
|
||||
* objects. Let them keep a pointer to NetNet objects.
|
||||
*
|
||||
* Revision 1.83 1999/11/28 18:05:37 steve
|
||||
* Set VPI_MODULE_PATH in the target code, if desired.
|
||||
*
|
||||
* Revision 1.82 1999/11/28 01:16:19 steve
|
||||
* gate outputs need to set signal values.
|
||||
*
|
||||
* Revision 1.81 1999/11/28 00:56:08 steve
|
||||
* Build up the lists in the scope of a module,
|
||||
* and get $dumpvars to scan the scope for items.
|
||||
*
|
||||
* Revision 1.80 1999/11/27 19:07:58 steve
|
||||
* Support the creation of scopes.
|
||||
*
|
||||
* Revision 1.79 1999/11/24 04:38:49 steve
|
||||
* LT and GT fixes from Eric Aardoom.
|
||||
*
|
||||
* Revision 1.78 1999/11/21 01:16:51 steve
|
||||
* Fix coding errors handling names of logic devices,
|
||||
* and add support for buf device in vvm.
|
||||
*
|
||||
* Revision 1.77 1999/11/21 00:13:09 steve
|
||||
* Support memories in continuous assignments.
|
||||
*
|
||||
* Revision 1.76 1999/11/14 23:43:45 steve
|
||||
* Support combinatorial comparators.
|
||||
*
|
||||
* Revision 1.75 1999/11/14 20:24:28 steve
|
||||
* Add support for the LPM_CLSHIFT device.
|
||||
*
|
||||
* Revision 1.74 1999/11/13 03:46:52 steve
|
||||
* Support the LPM_MUX in vvm.
|
||||
*
|
||||
* Revision 1.73 1999/11/10 02:52:24 steve
|
||||
* Create the vpiMemory handle type.
|
||||
*
|
||||
* Revision 1.72 1999/11/06 16:00:17 steve
|
||||
* Put number constants into a static table.
|
||||
*/
|
||||
|
||||
|
|
|
|||
|
|
@ -18,7 +18,7 @@
|
|||
# 59 Temple Place - Suite 330
|
||||
# Boston, MA 02111-1307, USA
|
||||
#
|
||||
#ident "$Id: Makefile.in,v 1.24 2000/03/18 01:26:59 steve Exp $"
|
||||
#ident "$Id: Makefile.in,v 1.25 2000/03/18 23:22:37 steve Exp $"
|
||||
#
|
||||
#
|
||||
SHELL = /bin/sh
|
||||
|
|
@ -59,7 +59,7 @@ all: libvvm.a
|
|||
mv $*.d dep
|
||||
|
||||
O = vvm_add_sub.o vvm_bit.o vvm_calltf.o vvm_clshift.o vvm_compare.o \
|
||||
vvm_event.o \
|
||||
vvm_event.o vvm_ff.o \
|
||||
vvm_func.o vvm_gates.o vvm_mult.o vvm_mux.o \
|
||||
vvm_nexus.o vvm_pevent.o vvm_signal.o vvm_thread.o vpip.o
|
||||
|
||||
|
|
|
|||
|
|
@ -0,0 +1,103 @@
|
|||
/*
|
||||
* Copyright (c) 2000 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) && !defined(macintosh)
|
||||
#ident "$Id: vvm_ff.cc,v 1.1 2000/03/18 23:22:37 steve Exp $"
|
||||
#endif
|
||||
|
||||
# include "vvm_gates.h"
|
||||
|
||||
vvm_ff::vvm_ff(unsigned w)
|
||||
: width_(w)
|
||||
{
|
||||
out_ = new vvm_nexus::drive_t[width_];
|
||||
bits_ = new vpip_bit_t[width_*2];
|
||||
for (unsigned idx = 0 ; idx < width_*2 ; idx += 1)
|
||||
bits_[idx] = Vx;
|
||||
}
|
||||
|
||||
vvm_ff::~vvm_ff()
|
||||
{
|
||||
delete[]bits_;
|
||||
delete[]out_;
|
||||
}
|
||||
|
||||
vvm_nexus::drive_t* vvm_ff::config_rout(unsigned idx)
|
||||
{
|
||||
assert(idx < width_);
|
||||
return out_+idx;
|
||||
}
|
||||
|
||||
unsigned vvm_ff::key_Data(unsigned idx) const
|
||||
{
|
||||
assert(idx < width_);
|
||||
return idx+width_;
|
||||
}
|
||||
|
||||
unsigned vvm_ff::key_Clock() const
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
void vvm_ff::init_Data(unsigned idx, vpip_bit_t val)
|
||||
{
|
||||
assert(idx < width_);
|
||||
bits_[idx+width_] = val;
|
||||
}
|
||||
|
||||
void vvm_ff::init_Clock(unsigned, vpip_bit_t val)
|
||||
{
|
||||
clk_ = val;
|
||||
}
|
||||
|
||||
void vvm_ff::take_value(unsigned key, vpip_bit_t val)
|
||||
{
|
||||
if (key == 0) {
|
||||
if (val == clk_)
|
||||
return;
|
||||
bool flag = posedge(clk_, val);
|
||||
clk_ = val;
|
||||
if (flag)
|
||||
latch_();
|
||||
return;
|
||||
}
|
||||
|
||||
bits_[key] = val;
|
||||
}
|
||||
|
||||
void vvm_ff::latch_()
|
||||
{
|
||||
vpip_bit_t*q = bits_;
|
||||
vpip_bit_t*d = bits_+width_;
|
||||
|
||||
for (unsigned idx = 0 ; idx < width_ ; idx += 1) {
|
||||
if (q[idx] == d[idx])
|
||||
continue;
|
||||
|
||||
q[idx] = d[idx];
|
||||
out_[idx].set_value(q[idx]);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* $Log: vvm_ff.cc,v $
|
||||
* Revision 1.1 2000/03/18 23:22:37 steve
|
||||
* Update the FF device to nexus style.
|
||||
*
|
||||
*/
|
||||
|
||||
|
|
@ -19,7 +19,7 @@
|
|||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
||||
*/
|
||||
#if !defined(WINNT) && !defined(macintosh)
|
||||
#ident "$Id: vvm_gates.h,v 1.47 2000/03/18 02:26:02 steve Exp $"
|
||||
#ident "$Id: vvm_gates.h,v 1.48 2000/03/18 23:22:37 steve Exp $"
|
||||
#endif
|
||||
|
||||
# include "vvm.h"
|
||||
|
|
@ -246,52 +246,37 @@ class vvm_compare : public vvm_nexus::recvr_t {
|
|||
|
||||
|
||||
/*
|
||||
* This class simulates the LPM flip-flop device.
|
||||
* XXXX Inverted clock not yet supported.
|
||||
* This class simulates the LPM flip-flop device. The vvm_ff class
|
||||
* supports arbitrary width devices. For each output Q, there is a
|
||||
* unique input D. The CLK input is common for all the bit lanes.
|
||||
*/
|
||||
template <unsigned WIDTH> class vvm_ff {
|
||||
class vvm_ff : public vvm_nexus::recvr_t {
|
||||
|
||||
public:
|
||||
explicit vvm_ff()
|
||||
{ clk_ = Vx;
|
||||
for (unsigned idx = 0 ; idx < WIDTH ; idx += 1)
|
||||
q_[idx] = Vx;
|
||||
}
|
||||
~vvm_ff() { }
|
||||
explicit vvm_ff(unsigned wid);
|
||||
~vvm_ff();
|
||||
|
||||
void init_Data(unsigned idx, vpip_bit_t val) { d_[idx] = val; }
|
||||
void init_Clock(unsigned, vpip_bit_t val) { clk_ = val; }
|
||||
vvm_nexus::drive_t* config_rout(unsigned idx);
|
||||
|
||||
void set_Clock(unsigned, vpip_bit_t val)
|
||||
{ if (val == clk_) return;
|
||||
bool flag = posedge(clk_, val);
|
||||
clk_ = val;
|
||||
if (flag) latch_();
|
||||
}
|
||||
unsigned key_Data(unsigned idx) const;
|
||||
unsigned key_Clock() const;
|
||||
|
||||
void set_Data(unsigned idx, vpip_bit_t val)
|
||||
{ d_[idx] = val;
|
||||
}
|
||||
|
||||
void config_rout(unsigned idx, vvm_out_event::action_t o)
|
||||
{ out_[idx] = o;
|
||||
}
|
||||
void init_Data(unsigned idx, vpip_bit_t val);
|
||||
void init_Clock(unsigned, vpip_bit_t val);
|
||||
|
||||
private:
|
||||
vpip_bit_t d_[WIDTH];
|
||||
vpip_bit_t q_[WIDTH];
|
||||
void take_value(unsigned key, vpip_bit_t val);
|
||||
unsigned width_;
|
||||
vpip_bit_t*bits_;
|
||||
vpip_bit_t clk_;
|
||||
|
||||
vvm_out_event::action_t out_[WIDTH];
|
||||
vvm_nexus::drive_t* out_;
|
||||
|
||||
void latch_()
|
||||
{ q_ = d_;
|
||||
for (unsigned idx = 0 ; idx < WIDTH ; idx += 1)
|
||||
if (out_[idx]) {
|
||||
vvm_event*ev = new vvm_out_event(q_[idx], out_[idx]);
|
||||
ev->schedule();
|
||||
}
|
||||
}
|
||||
void latch_();
|
||||
|
||||
private: // not implemeneted
|
||||
vvm_ff(const vvm_ff&);
|
||||
vvm_ff& operator= (const vvm_ff&);
|
||||
};
|
||||
|
||||
/*
|
||||
|
|
@ -817,6 +802,9 @@ template <unsigned WIDTH> class vvm_pevent : public vvm_nexus::recvr_t {
|
|||
|
||||
/*
|
||||
* $Log: vvm_gates.h,v $
|
||||
* Revision 1.48 2000/03/18 23:22:37 steve
|
||||
* Update the FF device to nexus style.
|
||||
*
|
||||
* Revision 1.47 2000/03/18 02:26:02 steve
|
||||
* Update bufz to nexus style.
|
||||
*
|
||||
|
|
|
|||
Loading…
Reference in New Issue