VVM support for small sequential UDP objects.
This commit is contained in:
parent
10b345bd16
commit
4e2c0036aa
32
netlist.cc
32
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.12 1998/12/14 02:01:35 steve Exp $"
|
||||
#ident "$Id: netlist.cc,v 1.13 1998/12/17 23:54:58 steve Exp $"
|
||||
#endif
|
||||
|
||||
# include <cassert>
|
||||
|
|
@ -625,6 +625,33 @@ void NetUDP::cleanup_table()
|
|||
}
|
||||
}
|
||||
|
||||
char NetUDP::table_lookup(const string&from, char to, unsigned pin) const
|
||||
{
|
||||
assert(pin <= pin_count());
|
||||
assert(from.length() == pin_count());
|
||||
FSM_::const_iterator idx = fsm_.find(from);
|
||||
if (idx == fsm_.end())
|
||||
return 'x';
|
||||
|
||||
state_t_*next;
|
||||
switch (to) {
|
||||
case '0':
|
||||
next = (*idx).second->pins[pin].zer;
|
||||
break;
|
||||
case '1':
|
||||
next = (*idx).second->pins[pin].one;
|
||||
break;
|
||||
case 'x':
|
||||
next = (*idx).second->pins[pin].xxx;
|
||||
break;
|
||||
default:
|
||||
assert(0);
|
||||
next = 0;
|
||||
}
|
||||
|
||||
return next? next->out : 'x';
|
||||
}
|
||||
|
||||
void NetUDP::set_initial(char val)
|
||||
{
|
||||
assert(sequential_);
|
||||
|
|
@ -784,6 +811,9 @@ NetNet* Design::find_signal(bool (*func)(const NetNet*))
|
|||
|
||||
/*
|
||||
* $Log: netlist.cc,v $
|
||||
* Revision 1.13 1998/12/17 23:54:58 steve
|
||||
* VVM support for small sequential UDP objects.
|
||||
*
|
||||
* Revision 1.12 1998/12/14 02:01:35 steve
|
||||
* Fully elaborate Sequential UDP behavior.
|
||||
*
|
||||
|
|
|
|||
11
netlist.h
11
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.12 1998/12/14 02:01:35 steve Exp $"
|
||||
#ident "$Id: netlist.h,v 1.13 1998/12/17 23:54:58 steve Exp $"
|
||||
#endif
|
||||
|
||||
/*
|
||||
|
|
@ -389,7 +389,13 @@ class NetUDP : public NetNode {
|
|||
bool set_table(const string&input, char output);
|
||||
void cleanup_table();
|
||||
|
||||
/* Return the next output from the passed state. Each letter
|
||||
of the input string represents the pin of the same
|
||||
position. */
|
||||
char table_lookup(const string&from, char to, unsigned pin) const;
|
||||
|
||||
void set_initial(char);
|
||||
char get_initial() const { return init_; }
|
||||
|
||||
bool is_sequential() const { return sequential_; }
|
||||
|
||||
|
|
@ -888,6 +894,9 @@ extern ostream& operator << (ostream&, NetNet::Type);
|
|||
|
||||
/*
|
||||
* $Log: netlist.h,v $
|
||||
* Revision 1.13 1998/12/17 23:54:58 steve
|
||||
* VVM support for small sequential UDP objects.
|
||||
*
|
||||
* Revision 1.12 1998/12/14 02:01:35 steve
|
||||
* Fully elaborate Sequential UDP behavior.
|
||||
*
|
||||
|
|
|
|||
76
t-vvm.cc
76
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.6 1998/11/23 00:20:23 steve Exp $"
|
||||
#ident "$Id: t-vvm.cc,v 1.7 1998/12/17 23:54:58 steve Exp $"
|
||||
#endif
|
||||
|
||||
# include <iostream>
|
||||
|
|
@ -43,6 +43,7 @@ class target_vvm : public target_t {
|
|||
virtual void signal(ostream&os, const NetNet*);
|
||||
virtual void logic(ostream&os, const NetLogic*);
|
||||
virtual void bufz(ostream&os, const NetBUFZ*);
|
||||
virtual void udp(ostream&os, const NetUDP*);
|
||||
virtual void net_const(ostream&os, const NetConst*);
|
||||
virtual void net_pevent(ostream&os, const NetPEvent*);
|
||||
virtual void start_process(ostream&os, const NetProcTop*);
|
||||
|
|
@ -67,6 +68,7 @@ class target_vvm : public target_t {
|
|||
unsigned indent_;
|
||||
};
|
||||
|
||||
|
||||
/*
|
||||
* This class emits code for the rvalue of a procedural
|
||||
* assignment. The expression is evaluated to fit the width
|
||||
|
|
@ -378,6 +380,75 @@ void target_vvm::bufz(ostream&os, const NetBUFZ*gate)
|
|||
emit_gate_outputfun_(gate);
|
||||
}
|
||||
|
||||
static string state_to_string(unsigned state, unsigned npins)
|
||||
{
|
||||
static const char cur_table[3] = { '0', '1', 'x' };
|
||||
string res = "";
|
||||
for (unsigned idx = 0 ; idx < npins ; idx += 1) {
|
||||
char cur = cur_table[state%3];
|
||||
res = cur + res;
|
||||
state /= 3;
|
||||
}
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
void target_vvm::udp(ostream&os, const NetUDP*gate)
|
||||
{
|
||||
assert(gate->pin_count() <= 9);
|
||||
assert(gate->is_sequential());
|
||||
unsigned states = 1;
|
||||
for (unsigned idx = 0 ; idx < gate->pin_count() ; idx += 1)
|
||||
states *= 3;
|
||||
|
||||
os << "static vvm_u32 " << mangle(gate->name()) << "_table[" <<
|
||||
states << "] = {" << endl;
|
||||
os << hex;
|
||||
for (unsigned state = 0 ; state < states ; state += 1) {
|
||||
string sstr = state_to_string(state, gate->pin_count());
|
||||
|
||||
unsigned long entry = 0;
|
||||
for (unsigned idx = 1 ; idx < sstr.length() ; idx += 1) {
|
||||
char o[2];
|
||||
switch (sstr[idx]) {
|
||||
case '0':
|
||||
o[0] = '1';
|
||||
o[1] = 'x';
|
||||
break;
|
||||
case '1':
|
||||
o[0] = '0';
|
||||
o[1] = 'x';
|
||||
break;
|
||||
case 'x':
|
||||
o[0] = '0';
|
||||
o[1] = '1';
|
||||
break;
|
||||
}
|
||||
|
||||
o[0] = gate->table_lookup(sstr, o[0], idx);
|
||||
o[1] = gate->table_lookup(sstr, o[1], idx);
|
||||
entry <<= 2;
|
||||
entry |= (o[0] == '0')? 0 : (o[0] == '1')? 1 : 2;
|
||||
entry <<= 2;
|
||||
entry |= (o[1] == '0')? 0 : (o[1] == '1')? 1 : 2;
|
||||
}
|
||||
os << " 0x" << setw(8) << setfill('0') << entry << ",";
|
||||
if (state % 3 == 2)
|
||||
os << endl;
|
||||
}
|
||||
os << "};" << dec << setfill(' ') << endl;
|
||||
|
||||
os << "static void " << mangle(gate->name()) <<
|
||||
"_output_fun(vvm_simulation*, vvm_bit_t);" << endl;
|
||||
|
||||
os << "static vvm_udp_ssequ<" << gate->pin_count()-1 << "> " <<
|
||||
mangle(gate->name()) << "(&" << mangle(gate->name()) <<
|
||||
"_output_fun, V" << gate->get_initial() << ", " <<
|
||||
mangle(gate->name()) << "_table);" << endl;
|
||||
|
||||
emit_gate_outputfun_(gate);
|
||||
}
|
||||
|
||||
/*
|
||||
* The NetConst is a synthetic device created to represent constant
|
||||
* values. I represent them in the output as a vvm_bufz object that
|
||||
|
|
@ -671,6 +742,9 @@ extern const struct target tgt_vvm = {
|
|||
};
|
||||
/*
|
||||
* $Log: t-vvm.cc,v $
|
||||
* Revision 1.7 1998/12/17 23:54:58 steve
|
||||
* VVM support for small sequential UDP objects.
|
||||
*
|
||||
* Revision 1.6 1998/11/23 00:20:23 steve
|
||||
* NetAssign handles lvalues as pin links
|
||||
* instead of a signal pointer,
|
||||
|
|
|
|||
|
|
@ -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.2 1998/11/10 00:48:31 steve Exp $"
|
||||
#ident "$Id: vvm.h,v 1.3 1998/12/17 23:54:58 steve Exp $"
|
||||
#endif
|
||||
|
||||
# include <vector>
|
||||
|
|
@ -30,6 +30,8 @@
|
|||
* that executes models that the simulation generator makes.
|
||||
*/
|
||||
|
||||
typedef unsigned vvm_u32;
|
||||
|
||||
class vvm_event;
|
||||
class vvm_simulation;
|
||||
class vvm_simulation_cycle;
|
||||
|
|
@ -215,6 +217,9 @@ class vvm_monitor_t {
|
|||
|
||||
/*
|
||||
* $Log: vvm.h,v $
|
||||
* Revision 1.3 1998/12/17 23:54:58 steve
|
||||
* VVM support for small sequential UDP objects.
|
||||
*
|
||||
* Revision 1.2 1998/11/10 00:48:31 steve
|
||||
* Add support it vvm target for level-sensitive
|
||||
* triggers (i.e. the Verilog wait).
|
||||
|
|
|
|||
|
|
@ -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.2 1998/11/10 00:48:31 steve Exp $"
|
||||
#ident "$Id: vvm_gates.h,v 1.3 1998/12/17 23:54:58 steve Exp $"
|
||||
#endif
|
||||
|
||||
# include "vvm.h"
|
||||
|
|
@ -184,6 +184,65 @@ template <unsigned WIDTH, unsigned long DELAY> class vvm_xor {
|
|||
vvm_out_event::action_t output_;
|
||||
};
|
||||
|
||||
/*
|
||||
* A Sequential UDP has a more complex truth table, and handles
|
||||
* edges. Pin 0 is an output, and all the remaining pins are
|
||||
* input. The WIDTH is the number of input pins.
|
||||
*
|
||||
* See vvm.txt for a description of the gate transition table.
|
||||
*/
|
||||
template <unsigned WIDTH> class vvm_udp_ssequ {
|
||||
|
||||
public:
|
||||
explicit vvm_udp_ssequ(vvm_out_event::action_t o, vvm_bit_t i,
|
||||
const vvm_u32*tab)
|
||||
: output_(o), table_(tab)
|
||||
{ state_[0] = i;
|
||||
for (unsigned idx = 1; idx < WIDTH+1 ; idx += 1)
|
||||
state_[idx] = Vx;
|
||||
}
|
||||
|
||||
void set(vvm_simulation*sim, unsigned pin, vvm_bit_t val)
|
||||
{ assert(pin > 0);
|
||||
assert(pin < WIDTH+1);
|
||||
if (val == Vz) val = Vx;
|
||||
if (state_[pin] == val) return;
|
||||
// Convert the current state into a table index.
|
||||
unsigned entry = 0;
|
||||
for (unsigned idx = 0 ; idx < WIDTH+1 ; idx += 1) {
|
||||
entry *= 3;
|
||||
entry += state_[idx];
|
||||
}
|
||||
// Get the table entry, and the 4bits that encode
|
||||
// activity on this pin.
|
||||
vvm_u32 code = table_[entry];
|
||||
code >>= 4 * (WIDTH-pin);
|
||||
switch (state_[pin]*4 + val) {
|
||||
case (V0*4 + V1):
|
||||
case (V1*4 + V0):
|
||||
case (Vx*4 + V0):
|
||||
code = (code>>2) & 3;
|
||||
break;
|
||||
case (V0*4 + Vx):
|
||||
case (V1*4 + Vx):
|
||||
case (Vx*4 + V1):
|
||||
code &= 3;
|
||||
break;
|
||||
}
|
||||
// Convert the code to a vvm_bit_t and run with it.
|
||||
vvm_bit_t outval = (code == 0)? V0 : (code == 1)? V1 : Vx;
|
||||
state_[0] = outval;
|
||||
state_[pin] = val;
|
||||
vvm_event*ev = new vvm_out_event(sim, outval, output_);
|
||||
sim->insert_event(1, ev); // XXXX Delay not supported.
|
||||
}
|
||||
|
||||
private:
|
||||
vvm_out_event::action_t output_;
|
||||
const vvm_u32*const table_;
|
||||
vvm_bit_t state_[WIDTH+1];
|
||||
};
|
||||
|
||||
class vvm_bufz {
|
||||
public:
|
||||
explicit vvm_bufz(vvm_out_event::action_t o)
|
||||
|
|
@ -219,6 +278,9 @@ class vvm_pevent {
|
|||
|
||||
/*
|
||||
* $Log: vvm_gates.h,v $
|
||||
* Revision 1.3 1998/12/17 23:54:58 steve
|
||||
* VVM support for small sequential UDP objects.
|
||||
*
|
||||
* Revision 1.2 1998/11/10 00:48:31 steve
|
||||
* Add support it vvm target for level-sensitive
|
||||
* triggers (i.e. the Verilog wait).
|
||||
|
|
|
|||
Loading…
Reference in New Issue