Re: [myhdl-list] intbv wrap
Brought to you by:
jandecaluwe
From: Christopher F. <chr...@gm...> - 2011-05-10 11:27:56
|
I made a couple of minor adjustments to this patch. 1. Made the wrap function private (_wrap) and moved _wrap to __wrap. The wrap function should not be used directly because it will not covert correctly. I think for a future (todo) enhancement the wrap function can be made public and handled by the converter. This is an involved modification. For now I think it is good to advertise the wrap function was private. 2. Added myrange to a slot, _range. 3. Modified a couple comments. wrap4.patch is the text version. Thanks Chris Felton On 5/5/11 4:25 PM, Christopher Felton wrote: > On 5/5/2011 9:21 AM, Ben wrote: >> Hi Christopher, >> >> I took the liberty to review and edit your patch. >> >> As you can see, I added some tests, and removed the inclusion of the >> val property. It became quite smaller ! I left your name in it as the >> idea and the logic is from you. >> >> I also moved the check from the wrap function to the constructor (no >> need to check every time.). > > Perfect! Thanks for the contributions and for the additional test > cases, very nice. Also, good catch on the range checking! > > Is there an opinion if 'myrange' should be a class member so that it > doesn't need to be recalculated on each check? I don't know if there is > a down side to having too many slots (_range)? > > In the future we will need to address if wrap() can be converted or > changed to a private function? As discussed in previous threads. > > Thanks again Benoît. > > Chris > >> >> Here is a text version, enclosed a bundle. All tests pass fine. >> >> # HG changeset patch >> # User cfelton >> # Date 1303212809 18000 >> # Node ID 145d558e234f363c3e43e9a79ab48ad7e20d7b9b >> # Parent f77cf2c4a5894013ceb2f5c184d84136ea4f04a3 >> Add a wrap parameter to intbv. When set, no overflow will occur. >> >> diff -r f77cf2c4a589 -r 145d558e234f myhdl/_intbv.py >> --- a/myhdl/_intbv.py Wed May 04 21:33:14 2011 +0200 >> +++ b/myhdl/_intbv.py Tue Apr 19 06:33:29 2011 -0500 >> @@ -31,37 +31,46 @@ >> from __builtin__ import max as maxfunc >> >> class intbv(object): >> - __slots__ = ('_val', '_min', '_max', '_nrbits') >> + __slots__ = ('_min', '_max', '_nrbits', '_wrap', '__val') >> >> - def __init__(self, val=0, min=None, max=None, _nrbits=0): >> + def __init__(self, val=0, min=None, max=None, wrap=False, _nrbits=0): >> if _nrbits: >> self._min = 0 >> self._max = 2**_nrbits >> + self._nrbits = _nrbits >> else: >> self._min = min >> self._max = max >> if max is not None and min is not None: >> if min>= 0: >> - _nrbits = len(bin(max-1)) >> + self._nrbits = len(bin(max-1)) >> elif max<= 1: >> - _nrbits = len(bin(min)) >> + self._nrbits = len(bin(min)) >> else: >> # make sure there is a leading zero bit in positive numbers >> - _nrbits = maxfunc(len(bin(max-1))+1, len(bin(min))) >> + self._nrbits = maxfunc(len(bin(max-1))+1, len(bin(min))) >> + else: >> + self._nrbits = 0 >> + >> + if wrap: >> + myrange = self._nrbits**2 >> + if (abs(self.min) != self.max) or ((abs(self.min) + >> self.max) != myrange): >> + raise ValueError, "Cannot use wrapping if -min != max >> (%d != %d)" % (-self.min, self.max) >> + self._wrap = wrap >> if isinstance(val, (int, long)): >> self._val = val >> elif isinstance(val, StringType): >> mval = val.replace('_', '') >> + self._nrbits = len(mval) >> self._val = long(mval, 2) >> - _nrbits = len(val) >> elif isinstance(val, intbv): >> self._val = val._val >> self._min = val._min >> self._max = val._max >> - _nrbits = val._nrbits >> + self._wrap = val._wrap >> + self._nrbits = val._nrbits >> else: >> raise TypeError("intbv constructor arg should be int or string") >> - self._nrbits = _nrbits >> self._checkBounds() >> >> # support for the 'min' and 'max' attribute >> @@ -82,6 +91,20 @@ >> raise ValueError("intbv value %s< minimum %s" % >> (self._val, self._min)) >> >> + # val property >> + def _get_val(self): >> + return self.__val >> + >> + def _set_val(self, pval): >> + >> + if self._wrap: >> + self.__val = self.wrap(pval) >> + else: >> + self.__val = pval >> + >> + self._checkBounds() >> + >> + _val = property(_get_val, _set_val) >> >> # hash >> def __hash__(self): >> @@ -433,6 +456,21 @@ >> return "intbv(" + repr(self._val) + ")" >> >> >> + def wrap(self, val): >> + """ Wrap the value back to the range of the inbv >> + >> + The following will check that the defined min-max is the full >> + range of the binary word. If the full range is specified if >> + the value is outside the bounds of the range it will be adjusted >> + to the proper value in bounds. >> + """ >> + myrange = 2**self._nrbits >> + >> + rval = self.min + ((val +self.max) % myrange) >> + >> + return rval >> + >> + >> def signed(self): >> ''' return integer with the signed value of the intbv instance >> >> diff -r f77cf2c4a589 -r 145d558e234f myhdl/test/core/test_intbv.py >> --- a/myhdl/test/core/test_intbv.py Wed May 04 21:33:14 2011 +0200 >> +++ b/myhdl/test/core/test_intbv.py Tue Apr 19 06:33:29 2011 -0500 >> @@ -576,8 +576,50 @@ >> self.assertEqual(n.max, m.max) >> self.assertEqual(len(n), len(m)) >> >> +class TestIntbvWrap(TestCase): >> + >> + def testWrap(self): >> + x = intbv(0, min=-8, max=8, wrap=True) >> + x[:] = x + 1 >> + self.assertEqual(1, x) >> + x[:] = x + 2 >> + self.assertEqual(3, x) >> + x[:] = x + 5 >> + self.assertEqual(-8, x) >> + x[:] = x + 1 >> + self.assertEqual(-7, x) >> + x[:] = x - 5 >> + self.assertEqual(4, x) >> + x[:] = x - 4 >> + self.assertEqual(0, x) >> + x[:] += 15 >> + x[:] = x - 1 >> + self.assertEqual(-2, x) >> + >> + def testInit(self): >> + self.assertRaises(ValueError, intbv, 15, min=-8, max=8) >> + x = intbv(15, min=-8, max=8, wrap=True) >> + self.assertEqual(-1, x) >> + >> + self.assertRaises(ValueError, intbv, 5, min=-3, max=8, wrap=True) >> + intbv(5, min=-3, max=8) >> >> >> + def testNoWrap(self): >> + x = intbv(0, min=-8, max=8, wrap=False) >> + try: >> + x[:] += 15 >> + self.fail() >> + except ValueError: >> + pass >> + >> + x = intbv(0, min=-8, max=8) >> + try: >> + x[:] += 15 >> + self.fail() >> + except ValueError: >> + pass >> + >> if __name__ == "__main__": >> unittest.main() >> >> >> >> ------------------------------------------------------------------------------ >> WhatsUp Gold - Download Free Network Management Software >> The most intuitive, comprehensive, and cost-effective network >> management toolset available today. Delivers lowest initial >> acquisition cost and overall TCO of any competing solution. >> http://p.sf.net/sfu/whatsupgold-sd >> >> >> >> _______________________________________________ >> myhdl-list mailing list >> myh...@li... >> https://lists.sourceforge.net/lists/listinfo/myhdl-list > > > > ------------------------------------------------------------------------------ > WhatsUp Gold - Download Free Network Management Software > The most intuitive, comprehensive, and cost-effective network > management toolset available today. Delivers lowest initial > acquisition cost and overall TCO of any competing solution. > http://p.sf.net/sfu/whatsupgold-sd |