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

merged with guenter

This commit is contained in:
Jan Decaluwe 2008-08-24 20:25:00 +02:00
commit 632b91f72b
4 changed files with 337 additions and 1 deletions

View File

@ -0,0 +1,24 @@
# could add to CFLAGS to turn on warnings if you are using gcc
WARNS=-Wall
# change this path to point to the pli include files directory for cver
INCS=-I /usr/include/pli_incs
# maybe want -O<something> and/or -g
CFLAGS= -fPIC -Wall -g -m32 $(INCS)
LFLAGS= -G -shared -export-dynamic -melf_i386
# change to your compiler
CC=gcc
all: myhdl_vpi.so
myhdl_vpi.o: myhdl_vpi.c
$(CC) $(CFLAGS) -c myhdl_vpi.c
# make rules for dynamic libaries
myhdl_vpi.so: myhdl_vpi.o
$(LD) $(LFLAGS) myhdl_vpi.o -o myhdl_vpi.so
clean:
-rm *.o *.so

View File

@ -384,6 +384,8 @@ 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
MyHDL supports enumeration types by providing a function :func:`enum`. The
arguments to :func:`enum` are the string representations of the identifiers, and
its return value is an enumeration type. The identifiers are available as

View File

@ -436,4 +436,61 @@ class intbv(object):
def __repr__(self):
return "intbv(" + repr(self._val) + ")"
def signed(self):
''' return integer with the signed value of the intbv instance
The intbv.signed() function will classify the value of the intbv
instance either as signed or unsigned. If the value is classified
as signed it will be returned unchanged as integer value. If the
value is considered unsigned, the bits as specified by _nrbits
will be considered as 2's complement number and returned. This
feature will allow to create slices and have the sliced bits be
considered a 2's complement number.
The classification is based on the following possible combinations
of the min and max value.
----+----+----+----+----+----+----+----
-3 -2 -1 0 1 2 3
1 min max
2 min max
3 min max
4 min max
5 min max
6 min max
7 min max
8 neither min nor max is set
9 only max is set
10 only min is set
From the above cases, # 1 and 2 are considered unsigned and the
signed() function will convert the value to a signed number.
Decision about the sign will be done based on the msb. The msb is
based on the _nrbits value.
So the test will be if min >= 0 and _nrbits > 0. Then the instance
is considered unsigned and the value is returned as 2's complement
number.
'''
# value is considered unsigned
if self.min >= 0 and self._nrbits > 0:
# get 2's complement value of bits
msb = self._nrbits-1
sign = ((self._val >> msb) & 0x1) > 0
# mask off the bits msb-1:lsb, they are always positive
mask = (1<<msb) - 1
retVal = self._val & mask
# if sign bit is set, subtract the value of the sign bit
if sign:
retVal -= 1<<msb
else: # value is returned just as is
retVal = self._val
return retVal

253
myhdl/test/core/test_signed.py Executable file
View File

@ -0,0 +1,253 @@
#!/usr/bin/env python
# This file is part of the myhdl library, a Python package for using
# Python as a Hardware Description Language.
#
# Copyright (C) 2008 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
""" Run the intbv.signed() unit tests. """
__author__ = "Jan Decaluwe <jan@jandecaluwe.com>"
__revision__ = "$Revision$"
__date__ = "$Date$"
import unittest
from unittest import TestCase
from myhdl._intbv import intbv
from myhdl._concat import concat
class TestIntbvSigned(TestCase):
'''Test cases to verify the intbv.signed() member function'''
def testPlainIntbvInstance(self):
'''Test a plain intbv instance with .signed()
----+----+----+----+----+----+----+----
-3 -2 -1 0 1 2 3
min max
min max
min max
min max
min max
min max
min max
neither min nor max is set
only max is set
only min is set
'''
#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
# in the following cases the .signed() function should classify the
# value of the intbv instance as unsigned and return the 2's
# complement value of the bits as specified by _nrbits.
#
# intbv with positive range, pos number, and msb not set, return signed()
# Expect the number to be returned
a = intbv(0x3b, min=0, max=0x7c)
b = a.signed()
self.assertEqual(b, 0x3b)
# intbv with positive range, pos number, and msb set, return signed()
# test various bit patterns to see that the 2's complement
# conversion works correct
# Expect the number to be converted to a negative number
a = intbv(7, min=0, max=8)
b = a.signed()
self.assertEqual(b, -1)
a = intbv(6, min=0, max=8)
b = a.signed()
self.assertEqual(b, -2)
a = intbv(5, min=0, max=8)
b = a.signed()
self.assertEqual(b, -3)
# set bit #3 and increase the range so that the set bit is considered
# the sign bit. Here min = 0
# Expect to return -4
a = intbv(4, min=0, max=5)
b = a.signed()
self.assertEqual(b, -4)
a = intbv(4, min=0, max=6)
b = a.signed()
self.assertEqual(b, -4)
a = intbv(4, min=0, max=7)
b = a.signed()
self.assertEqual(b, -4)
a = intbv(4, min=0, max=8)
b = a.signed()
self.assertEqual(b, -4)
# here it is not the sign bit anymore
# Expect the value to be 4
a = intbv(4, min=0, max=9)
b = a.signed()
self.assertEqual(b, 4)
# set bit #3 and increase the range so that the set bit is considered
# the sign bit. Here min > 0
# Expect to return -4
a = intbv(4, min=1, max=5)
b = a.signed()
self.assertEqual(b, -4)
a = intbv(4, min=2, max=6)
b = a.signed()
self.assertEqual(b, -4)
a = intbv(4, min=3, max=7)
b = a.signed()
self.assertEqual(b, -4)
a = intbv(4, min=4, max=8)
b = a.signed()
self.assertEqual(b, -4)
# again with min > 0, here it is not the sign bit anymore
# Expect the value to be 4
a = intbv(4, min=2, max=9)
b = a.signed()
self.assertEqual(b, 4)
# intbv with positive range, value = 0, return signed()
# Expect the number to be returned
a = intbv(0, min=0, max=0x8)
b = a.signed()
self.assertEqual(b, 0)
#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
# in these cases the .signed() function should classify the
# value of the intbv instance as signed and return the value as is
#
# intbv without range, pos number, return signed()
# Expect value to be returned as is
a = intbv(8)
b = a.signed()
self.assertEqual(b, 8)
# intbv without range, neg number, return signed()
# Expect value to be returned as is
a = intbv(-8)
b = a.signed()
self.assertEqual(b, -8)
# set bit #3 and increase the range that the set bit is actually the
# msb, but due to the negative range not considered signed
# Expect to return 4
a = intbv(4, min=-1, max=5)
b = a.signed()
self.assertEqual(b, 4)
a = intbv(4, min=-1, max=6)
b = a.signed()
self.assertEqual(b, 4)
a = intbv(4, min=-1, max=7)
b = a.signed()
self.assertEqual(b, 4)
a = intbv(4, min=-1, max=8)
b = a.signed()
self.assertEqual(b, 4)
# intbv with negative range, pos number, and msb set, return signed()
# Expect the number to returned as is
a = intbv(7, min=-1, max=8)
b = a.signed()
self.assertEqual(b, 7)
a = intbv(6, min=-1, max=8)
b = a.signed()
self.assertEqual(b, 6)
a = intbv(5, min=-1, max=8)
b = a.signed()
self.assertEqual(b, 5)
# intbv with symmetric (min = -max) range, pos value, msb set
# return signed()
# Expect value returned as is
a = intbv(4, min=-8, max=8)
b = a.signed()
self.assertEqual(b, 4)
# intbv with symmetric (min = -max) range, neg value,
# return signed()
# Expect value returned as is
a = intbv(-4, min=-8, max=8)
b = a.signed()
self.assertEqual(b, -4)
# intbv with symmetric (min=-max) range, value = 0,
# return signed()
# Expect value returned as is
a = intbv(0, min=-8, max=8)
b = a.signed()
self.assertEqual(b, 0)
def testSlicedSigned(self):
'''Test a slice with .signed()
This test can actually be simplified, as a slice will always have
min=0 and max > min, which will result in an intbv instance that
will be considered unsigned by the intbv.signed() function.
'''
a = intbv(4, min=-8, max=8)
b = a[4:]
self.assertEqual(b, 4)
b = a[4:].signed()
self.assertEqual(b, 4) # msb is not set with a 4 bit slice
b = a[3:]
self.assertEqual(b, 4)
b = a[3:].signed()
self.assertEqual(b, -4) # msb is set with 3 bits sliced
def testSignedConcat(self):
'''Test the .signed() function in connection with the concatenate
function
'''
# concat 3 bits
# Expect the signed function to return a negative value
a = concat(True, True, True).signed()
self.assertEqual(a, -1)
# concate a 3 bit intbv with msb set and two bits
# Expect a negative number
b = concat(intbv(5,min=0,max=8), True, True).signed()
self.assertEqual(b, -9)
########################################################################
# main
#
if __name__ == "__main__":
unittest.main()