mirror of
https://github.com/myhdl/myhdl.git
synced 2025-01-24 21:52:56 +08:00
Add invariants tests of signed operator
This commit is contained in:
parent
632b91f72b
commit
d8feb6cc5a
@ -25,11 +25,11 @@ __date__ = "$Date$"
|
||||
|
||||
import test_Simulation, test_Signal, test_intbv, test_Cosimulation, test_misc, \
|
||||
test_always_comb, test_bin, test_traceSignals, test_enum, test_concat, \
|
||||
test_unparse, test_inferWaiter, test_always, test_instance
|
||||
test_unparse, test_inferWaiter, test_always, test_instance, test_signed
|
||||
|
||||
modules = (test_Simulation, test_Signal, test_intbv, test_misc, test_always_comb,
|
||||
test_bin, test_traceSignals, test_enum, test_concat,
|
||||
test_unparse, test_inferWaiter, test_always, test_instance
|
||||
test_unparse, test_inferWaiter, test_always, test_instance, test_signed
|
||||
)
|
||||
|
||||
import unittest
|
||||
|
@ -20,229 +20,245 @@
|
||||
|
||||
""" Run the intbv.signed() unit tests. """
|
||||
|
||||
__author__ = "Jan Decaluwe <jan@jandecaluwe.com>"
|
||||
__revision__ = "$Revision$"
|
||||
__date__ = "$Date$"
|
||||
|
||||
import unittest
|
||||
from unittest import TestCase
|
||||
|
||||
from random import randrange
|
||||
|
||||
from myhdl._intbv import intbv
|
||||
from myhdl._concat import concat
|
||||
|
||||
class TestIntbvSigned(TestCase):
|
||||
'''Test cases to verify the intbv.signed() member function'''
|
||||
'''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
|
||||
def testPlainIntbvInstance(self):
|
||||
'''Test a plain intbv instance with .signed()
|
||||
|
||||
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
|
||||
----+----+----+----+----+----+----+----
|
||||
-3 -2 -1 0 1 2 3
|
||||
|
||||
'''
|
||||
#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
# 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)
|
||||
|
||||
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 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)
|
||||
'''
|
||||
#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
# 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 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 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)
|
||||
|
||||
|
||||
# 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)
|
||||
#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
# in these cases the .signed() function should classify the
|
||||
# value of the intbv instance as signed and return the value as is
|
||||
#
|
||||
|
||||
# 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 without range, pos number, return signed()
|
||||
# Expect value to be returned as is
|
||||
a = intbv(8)
|
||||
b = a.signed()
|
||||
self.assertEqual(b, 8)
|
||||
|
||||
# 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)
|
||||
# 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
|
||||
def testSlicedSigned(self):
|
||||
'''Test a slice with .signed()
|
||||
|
||||
b = a[3:]
|
||||
self.assertEqual(b, 4)
|
||||
b = a[3:].signed()
|
||||
self.assertEqual(b, -4) # msb is set with 3 bits sliced
|
||||
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
|
||||
'''
|
||||
def testSignedConcat(self):
|
||||
'''Test the .signed() function 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)
|
||||
# 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)
|
||||
# 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)
|
||||
|
||||
|
||||
def checkInvariants(self, a):
|
||||
"""Check invariants of signed operator."""
|
||||
W = len(a)
|
||||
b = intbv(a.signed())
|
||||
if W > 0:
|
||||
self.assertEqual(a[W:], b[W:])
|
||||
self.assertEqual(b[:W], -a[W-1])
|
||||
else:
|
||||
self.assertEqual(a, b)
|
||||
|
||||
def testRandom(self):
|
||||
NRTESTS = 1000
|
||||
for L in (10, 1000, 2**32, 2**68):
|
||||
for i in range(NRTESTS):
|
||||
lo = randrange(-L, L)
|
||||
hi = randrange(lo+1, 2*L)
|
||||
v = randrange(lo, hi)
|
||||
self.checkInvariants(intbv(v, min=lo, max=hi))
|
||||
|
||||
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user