1
0
mirror of https://github.com/myhdl/myhdl.git synced 2024-12-14 07:44:38 +08:00

Merged added documentation for intbv.signed() with tip

This commit is contained in:
Guenter Dannoritzer 2008-08-26 15:11:35 +02:00
commit e714e4fa05
3 changed files with 137 additions and 4 deletions

View File

@ -410,7 +410,9 @@ The simulation produces the following output::
Bit slicing
-----------
.. index:: single: bit slicing
.. index::
single: bit slicing
single: concat(); example usage
For a change, we will use a traditional function as an example to illustrate
slicing. The following function calculates the HEC byte of an ATM header. ::
@ -450,8 +452,125 @@ one-off count issues in practice. For example, the slice ``hex[8:]`` has exactly
about it as follows: for a slice ``[i:j]``, only bits below index ``i`` are
included, and the bit with index ``j`` is the last bit included.
When an intbv object is sliced, a new intbv object is returned. This new intbv
object is always positive, even when the original object was negative.
.. index::
single: intbv; min
single: intbv; max
single: intbv; _nrbits
When an :class:`intbv` object is sliced, a new :class:`intbv` object is returned.
This new :class:`intbv` object is always positive, even when the original object was negative.
Take the following example of a range restricted :class:`intbv`
instance::
>>> a = intbv(6,min=-8,max=8)
>>> a._nrbits
4
>>> b = a[4:]
>>> b
intbv(6L)
>>> b.min
0
>>> b.max
16
>>>
The value is set to 6 and the range to -8 ... 7. Note that the max value
is excluded. Checking the bit width with the *_nrbits* attribute shows
that it occupies 4 bits. If we slice now all bits, by using the convention
a[4:], which means to slice the 4 lsb bits, the returned :class:`intbv`
instance will still have 4 bits, the value will not change, but the range
will be changed to min=0 and max=16.
One thing to note here is that unlike bit width specified variables,
:class:`intbv` instances can be constructed with asymmetric value range.
Let's do a small variation to the above example::
>>> a = intbv(6,min=-4,max=8)
>>> a._nrbits
4
The lower range got reduced to -4, but looking at the required number of
bits, there are still 4 bits necessary to represent the value range.
Let's change that and increase the number range for the negative
numbers::
>>> a = intbv(6,min=-16,max=8)
>>> a._nrbits
5
Here now 5 bits are necessary to represent the negative value range down
to -16.
.. _intro-signed:
Unsigned to signed conversion
-----------------------------
.. index::
single: intbv; signed()
When using the :class:`intbv` class with restricted bit width, the *min* and
*max* attributes are used to restrict the value range. From an :class:`intbv`
instance with positive and negative value range we saw in the previous section
that it is possible to slice bits and the returned :class:`intbv` instance
will have a positive value range. In hardware description it is sometimes
desirable to have a bit vector with positive value range and create from it
a bit vector that allows positive and negative value range.
As an example let's take a 8 bit wide data bus that would be modeled as
follows::
data_bus = intbv(0, min=0, max=256)
Now consider that e.g. a complex number is transfered over this data
bus. The upper 4 bits of the data bus are used to transfer the real value and
the lower 4 bits for the imaginary value. As real and imaginary value
have a positive and negative value range, it would be good to have a way
to slice off bits and have them be considered of positive and negative
value range. The ``signed`` member function of the :class:`intbv` will
allow to do just that.
The basic functionality of the ``signed`` member function is to classify
the value of :class:`intbv` as either 'signed' or 'unsigned', based on the
*min* and *max* values. If the value is classified as 'signed', the ``signed``
member function will return the value unchanged as integer value. If it is
considered 'unsigned' the bits of the value, as specified by *_nrbits* are
considered a two's complement number and returned as integer. That means
that if the msb is set, the value is considered negative and if the msb
is not set, it is considered a positive value. The msb is here specified
by *_nrbits*-1.
The classification is done based on the *min* and *max* attributes. The
value is classified as 'unsigned' if *min* >= 0 and *max* > *min*. In all
other cases the value is classified as 'signed'.
Let's look at a basic example::
>>> a = intbv(12, min=0, max=16)
>>> bin(a)
'1100'
>>> b = a.signed()
>>> b
-4L
A 4 bits wide :class:`intbv` instance is assigned the value 12. In
binary representation this is '1100', that means the msb is set.
The instance is create with min=0 and max=16, which qualifies it for the
value to be classified as 'unsigned' by the ``signed`` function. The function
call will return the binary '1100' as two's complement value, which is -4.
Note that the return type is a integer type.
To come back to the initial data bus example, the ``signed`` function
can be used in connection with a slice to slice the real and the
imaginary part from the data bus as follows:
real = data_bus[].signed()
imag = data_bus[].signed()
.. _intro-python:

View File

@ -384,7 +384,7 @@ are defined. Also, the identifiers evaluate to integers, whereas a string
representation of the identifiers would be preferable. To solve these issues, we
need an *enumeration type*.
.. index:: single: enum
.. index:: single: enum(); example usage
MyHDL supports enumeration types by providing a function :func:`enum`. The
arguments to :func:`enum` are the string representations of the identifiers, and

View File

@ -349,6 +349,15 @@ attributes:
Read-only attribute that is the maximum value (exclusive) of an :class:`intbv`,
or *None* for no maximum.
.. method:: intbv.signed()
Return the bits as specified by the *_nrbits* attribute of the :class:`intbv`
value as two's complement number when classified as 'unsigned'. The value is
classfied as 'unsigned' if the *min* attribute is >= 0 and *max* > *min*.
Bit # *_nrbits*-1 specifies then the sign of the value.
:rtype: integer
Unlike :class:`int` objects, :class:`intbv` objects are mutable; this is also
the reason for their existence. Mutability is needed to support assignment to
indexes and slices, as is common in hardware design. For the same reason,
@ -430,6 +439,8 @@ Miscellaneous modeling support functions
This function complements the standard Python conversion functions ``hex`` and
``oct``. A binary string representation is often useful in hardware design.
:rtype: string
.. function:: concat(base [, arg ...])
@ -442,6 +453,7 @@ Miscellaneous modeling support functions
the previously mentioned objects, unsized :class:`intbv`, :class:`int` and
:class:`long` objects are supported, as well as signals of such objects.
:rtype: :class:`intbv`
.. function:: downrange(high [, low=0])
@ -476,6 +488,8 @@ Miscellaneous modeling support functions
Looks up all MyHDL instances in the local name space and returns them in a list.
:rtype: list
.. _ref-cosim: