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:
commit
632b91f72b
24
cosimulation/cver/makefile.lnx64
Normal file
24
cosimulation/cver/makefile.lnx64
Normal 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
|
@ -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
|
||||
|
@ -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
253
myhdl/test/core/test_signed.py
Executable 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()
|
Loading…
x
Reference in New Issue
Block a user