VVM support for small sequential UDP objects.

This commit is contained in:
steve 1998-12-17 23:54:58 +00:00
parent 10b345bd16
commit 4e2c0036aa
5 changed files with 185 additions and 5 deletions

View File

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

View File

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

View File

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

View File

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

View File

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