#  This file is part of the myhdl library, a Python package for using
#  Python as a Hardware Description Language.
#
#  Copyright (C) 2003 Jan Decaluwe
#
#  The myhdl library is free software; you can redistribute it and/or
#  modify it under the terms of the GNU Lesser General Public License as
#  published by the Free Software Foundation; either version 2.1 of the
#  License, or (at your option) any later version.
#
#  This library 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
#  Lesser General Public License for more details.

#  You should have received a copy of the GNU Lesser General Public
#  License along with this library; if not, write to the Free Software
#  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA


Specification for the Signal class
----------------------------------

In the following, attribute and method names starting with an
underscore are intended to be "private". In other words, they are not
part of the public interface of the Signal class. The private
attributes and methods are for internal use or for use by a simulator
object that interacts with Signal objects.

In the following, a "sig" denotes an object of the Signal class.

* A sig should have a read-only attribute 'val' that represents its
  current value.

* The Signal constructor should have one mandatory parameter 'val' to
  initialize its current value and future value.

* The Signal contractor should have an optional parameter 'delay' to
  specify an initial delay value for the signal. The default value is
  None, meaning no delay.

* A sig should have a 'delay' attribute that represents its current
  delay. It is acceptable that this attribute is only present if the
  sig has been constructed with a non-zero delay.

* A sig should have a 'next' attribute that represents its future
  value. The 'next' attribute provides both write and read
  access. (Read access is required to support mutable values.)

* In principle, any object could be assigned to sig.next; however, for
  meaningful modeling its type should be "compatible" with the type
  of the current value. Python's ultra-dynamic nature is not useful in
  this case, and could in fact be the source of hard-to-trace
  bugs. Therefore, there should be a check that the type of the object
  assigned to sig.next is compatible with the type of the initial
  value. "Compatible" means that the type should either be a subtype
  of the initial type, or that the types have been designed to work
  transparently together by other means. In particular, int (and long)
  and intbv are not subtypes of each other, but they are designed to
  work together.

* A sig has 'min' and a 'max' read-only attributes that default to
  None. They are possibly set to numeric values according to the
  initial sig constructor object. In particular, the attributes are
  inherited from an intbv object, and they are set for a bool
  object. These attributes are used to implement or complement the
  checks on the object assigned to sig.next.

* A sig should have a number of private list attributes that can hold
  generators that are waiting for a particular change on the sig's value:
  - '_eventWaiters': generators waiting for a value change
  - '_posedgeWaiters': generators waiting for a change from false to true
  - '_negedgeWaiters': generators waiting for a change from true to false

* A sig should have read-only attributes 'posedge' and 'negedge' to
  represent a posedge and negedge value change in yield clauses of
  generators. To represent an event (a value change), the sig itself
  is used in a yield clause.

* A sig should have an '_update()' method that performs the actions
  required to make the future value current. When 'delay' is 0, it
  assigns the future value to the current value. In addition, it
  returns a list of waiters for which a particular value change is
  satisfied, and removes them from the internal lists that held
  them. When 'delay' is nonzero, it schedules the application of the
  future value in the _simulator._futureEvents list and returns an
  empty list.

* A sig should have an '_apply(next, ...)' method that handles the
  application of a scheduled 'next' value. It implements inertial
  delay by only applying the 'next' value if there has been no change
  to the sig's 'next' attribute since the 'next' value was scheduled.
  If so, it assigns the 'next' value to the current value. In
  addition, it returns a list of waiters for which a particular value
  change is satisfied, and removes them from the internal lists that
  held them.

* When the 'next' attribute is accessed to modify a mutable value, the
  change should be made to an object that is distinct from the current
  value object.

* Whenever the 'next' attribute is accessed, a sig should be entered
  in the '_simulator._siglist'.  A simulator can thus know which sig's
  need updating.

* A sig should have no other public attributes than those described
  above.

* In practice, Signals will often have numbers as their underlying
  values. As a matter of convenience, the special Python object
  methods for numeric and bitwise operators are supported on Signal
  objects, by delegation to the corresponding method on the underlying
  current value. As an exception, augmented assignment methods are not
  supported, as these would provide write access to the current value.
  The current value of a Signal object should always behave as a
  read-only attribute.

* In addition, the special methods for logical interpretation and
  comparision are supported by delegation to the current value.

* In addition, index access and slice access is supported by
  delegation to the current value. However, for the same reasons as
  above, index and slice assignment are not supported.

