165 lines
5.2 KiB
C++
165 lines
5.2 KiB
C++
#ifndef __vvm_vvm_nexus_H
|
|
#define __vvm_vvm_nexus_H
|
|
/*
|
|
* 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_nexus.h,v 1.3 2000/04/23 03:45:25 steve Exp $"
|
|
#endif
|
|
|
|
# include "vvm.h"
|
|
|
|
|
|
class vvm_force;
|
|
|
|
/*
|
|
* The nexus class represents a connection point for drivers and
|
|
* receivers of signals. The signal carries a single bit, has drivers,
|
|
* has fan_out and has a current value. Classes derive from the nexus
|
|
* in order to provide specific kinds of N-driver resolution.
|
|
*
|
|
* The driver_t and recvr_t classes are the means to connect to a
|
|
* nexus. In general, other then to connect the drivers and receivers,
|
|
* there should be no cause to manipulate the nexus object directly.
|
|
*
|
|
* The driver_t class represents a driver on the nexus. There can be
|
|
* any number of drivers on a nexus, so long as the
|
|
* recolution_function can handle the situation. The drivers are
|
|
* normally members of some gate object somewhere. When the driver
|
|
* receives a value, it saves the value in itself and tells the
|
|
* connected nexus that something has changed.
|
|
*
|
|
* The nexus object, when it notices that one of its drivers changed,
|
|
* collects the values of the drivers and passes the set to the
|
|
* resolution function. The resolution function calculates what the
|
|
* value of the nexus should be given the values driving it.
|
|
*
|
|
* When the value of the nexus is ready, it scans the list of
|
|
* connected receivers and passes the new value out. The receiver is
|
|
* actually a pointer to the recvr_t object and a key. This is so the
|
|
* receiver object can receive many different pins worth of data. The
|
|
* idea is that a gate can be a single recvr_t object, and the key can
|
|
* be used and the number of the affected pin.
|
|
*/
|
|
class vvm_nexus {
|
|
|
|
public:
|
|
class drive_t {
|
|
friend class ::vvm_nexus;
|
|
public:
|
|
drive_t();
|
|
~drive_t();
|
|
vpip_bit_t peek_value() const;
|
|
void set_value(vpip_bit_t);
|
|
private:
|
|
vpip_bit_t value_;
|
|
vvm_nexus*nexus_;
|
|
drive_t*next_;
|
|
private: // not implemented
|
|
drive_t(const drive_t&);
|
|
drive_t& operator= (const drive_t&);
|
|
};
|
|
|
|
class recvr_t {
|
|
friend class ::vvm_nexus;
|
|
public:
|
|
recvr_t();
|
|
virtual ~recvr_t() =0;
|
|
virtual void take_value(unsigned key, vpip_bit_t val) =0;
|
|
private: // not implemented
|
|
recvr_t(const recvr_t&);
|
|
recvr_t& operator= (const recvr_t&);
|
|
};
|
|
|
|
public:
|
|
vvm_nexus();
|
|
~vvm_nexus();
|
|
|
|
// These methods support connecting the receiver and driver to
|
|
// the nexus.
|
|
void connect(drive_t*drv);
|
|
void connect(recvr_t*rcv, unsigned key);
|
|
|
|
void disconnect(drive_t*drv);
|
|
void disconnect(recvr_t*rcv);
|
|
|
|
|
|
// If there are no drivers to this nexus, this can be used to
|
|
// to procedural assignments to the node, as if it where a reg.
|
|
void reg_assign(vpip_bit_t val);
|
|
|
|
// This method causes the specified value to be forced onto
|
|
// the nexus. This overrides all drivers that are attached.
|
|
void force_set(class vvm_force*frc, unsigned key);
|
|
void force_assign(vpip_bit_t val);
|
|
void release();
|
|
|
|
// The run_values() method collects all the current driver
|
|
// values and, with the aid of the resolution_function,
|
|
// generates the current value for the nexus. It also passes
|
|
// that value on to the receuvers.
|
|
void run_values();
|
|
vpip_bit_t resolution_function(const vpip_bit_t*, unsigned) const;
|
|
|
|
private:
|
|
vpip_bit_t value_;
|
|
drive_t*drivers_;
|
|
struct recvr_cell {
|
|
recvr_t *dev;
|
|
unsigned key;
|
|
recvr_cell*next;
|
|
} *recvrs_;
|
|
|
|
vpip_bit_t*ival_;
|
|
unsigned nival_;
|
|
|
|
vpip_bit_t force_;
|
|
vvm_force *forcer_;
|
|
unsigned forcer_key_;
|
|
|
|
private: // not implemented
|
|
vvm_nexus(const vvm_nexus&);
|
|
vvm_nexus& operator= (const vvm_nexus&);
|
|
};
|
|
|
|
|
|
/*
|
|
* This function arranges for a non-blocking reg_assign to a nexus. It
|
|
* creates all the events needed to make it happen after the specified
|
|
* delay.
|
|
*/
|
|
extern void vvm_delayed_assign(vvm_nexus&l_val, vpip_bit_t r_val,
|
|
unsigned long delay);
|
|
|
|
/*
|
|
* $Log: vvm_nexus.h,v $
|
|
* Revision 1.3 2000/04/23 03:45:25 steve
|
|
* Add support for the procedural release statement.
|
|
*
|
|
* Revision 1.2 2000/04/22 04:20:20 steve
|
|
* Add support for force assignment.
|
|
*
|
|
* Revision 1.1 2000/03/16 19:03:04 steve
|
|
* Revise the VVM backend to use nexus objects so that
|
|
* drivers and resolution functions can be used, and
|
|
* the t-vvm module doesn't need to write a zillion
|
|
* output functions.
|
|
*
|
|
*/
|
|
#endif
|