a couple language improvements as discussed. -- Robert Jordens.
From 0d2a74c63d520036030086960a4e69131ae909b5 Mon Sep 17 00:00:00 2001 From: Robert Jordens <jord...@gmail.com> Date: Mon, 2 Dec 2013 17:19:32 -0700 Subject: [PATCH 1/3] migen.fhdl.size: add fiter(), fslice(), and freversed()
do not overload __len__, __iter__, __reversed__ as not all valid expressions (ints and bools) have them. furthermore len([]) is and should be different from flen([]) (the later raises an error). keep __getitem__ as an exception that proves the rule ;) --- doc/api.rst | 7 ++++ migen/fhdl/size.py | 98 ++++++++++++++++++++++++++++++++++++++++++++++++- migen/fhdl/std.py | 2 +- migen/test/test_size.py | 45 +++++++++++++++++++++++ 4 files changed, 150 insertions(+), 2 deletions(-) create mode 100644 migen/test/test_size.py diff --git a/doc/api.rst b/doc/api.rst index 06c8a55..d49b9b7 100644 --- a/doc/api.rst +++ b/doc/api.rst @@ -8,6 +8,13 @@ migen API Documentation :members: :show-inheritance: +:mod:`fhdl.size` Module +------------------------------ + +.. automodule:: migen.fhdl.size + :members: + :show-inheritance: + :mod:`genlib.fifo` Module ------------------------------ diff --git a/migen/fhdl/size.py b/migen/fhdl/size.py index a116901..e771ccc 100644 --- a/migen/fhdl/size.py +++ b/migen/fhdl/size.py @@ -96,7 +96,103 @@ def value_bits_sign(v): bsc = map(value_bits_sign, v.choices) return max(bs[0] for bs in bsc), any(bs[1] for bs in bsc) else: - raise TypeError + raise TypeError("Can not calculate bit length of {} {}".format( + type(v), v)) def flen(v): + """Bit length of an expression + + Parameters + ---------- + v : int, bool or Value + + Returns + ------- + int + Number of bits required to store `v` or available in `v` + + Examples + -------- + >>> flen(f.Signal(8)) + 8 + >>> flen(0xaa) + 8 + """ return value_bits_sign(v)[0] + +def fiter(v): + """Bit iterator + + Parameters + ---------- + v : int, bool or Value + + Returns + ------- + iter + Iterator over the bits in `v` + + Examples + -------- + >>> list(fiter(f.Signal(2))) #doctest: +ELLIPSIS + [<migen.fhdl.structure._Slice object at 0x...>, <migen.fhdl.structure._Slice object at 0x...>] + >>> list(fiter(4)) + [0, 0, 1] + """ + if isinstance(v, (bool, int)): + return ((v >> i) & 1 for i in range(bits_for(v))) + elif isinstance(v, f.Value): + return (v[i] for i in range(flen(v))) + else: + raise TypeError("Can not bit-iterate {} {}".format(type(v), v)) + +def fslice(v, s): + """Bit slice + + Parameters + ---------- + v : int, bool or Value + s : slice or int + + Returns + ------- + int or Value + Expression for the slice `s` of `v`. + + Examples + -------- + >>> fslice(Signal(2), 1) #doctest: +ELLIPSIS + <migen.fhdl.structure._Slice object at 0x...> + >>> bin(fslice(0b1101, slice(1, None, 2))) + '0b10' + """ + if isinstance(v, (bool, int)): + if isinstance(s, int): + s = slice(s) + idx = range(*s.indices(flen(v))) + return sum(((v>>i) & 1) << j for j, i in enumerate(idx)) + elif isinstance(v, f.Value): + return v[s] + else: + raise TypeError("Can not bit-slice {} {}".format(type(v), v)) + +def freversed(v): + """Bit reverse + + Parameters + ---------- + v : int, bool or Value + + Returns + ------- + int or Value + Expression containing the bit reversed input. + + Examples + -------- + >>> freversed(Signal(2)) #doctest: +ELLIPSIS + <migen.fhdl.structure._Slice object at 0x...> + >>> bin(freversed(0b1011)) + '0b1101' + """ + return fslice(v, slice(None, None, -1)) diff --git a/migen/fhdl/std.py b/migen/fhdl/std.py index 3a4a3de..b9ec729 100644 --- a/migen/fhdl/std.py +++ b/migen/fhdl/std.py @@ -1,5 +1,5 @@ from migen.fhdl.structure import * from migen.fhdl.module import Module from migen.fhdl.specials import TSTriple, Instance, Memory -from migen.fhdl.size import log2_int, bits_for, flen +from migen.fhdl.size import log2_int, bits_for, flen, fiter, fslice, freversed from migen.fhdl.decorators import DecorateModule, InsertCE, InsertReset, RenameClockDomains diff --git a/migen/test/test_size.py b/migen/test/test_size.py new file mode 100644 index 0000000..07b3052 --- /dev/null +++ b/migen/test/test_size.py @@ -0,0 +1,45 @@ +import unittest + +from migen.fhdl.std import * + +class SignalSizeCase(unittest.TestCase): + def setUp(self): + self.i = 0xaa + self.j = -127 + self.s = Signal((13, True)) + + def test_flen(self): + self.assertEqual(flen(self.s), 13) + self.assertEqual(flen(self.i), 8) + self.assertEqual(flen(self.j), 8) + + def test_flen_type(self): + self.assertRaises(TypeError, flen, []) + + def test_fiter(self): + for i, si in enumerate(fiter(self.s)): + self.assertEqual(si, self.s[i]) + self.assertEqual(list(fiter(self.i)), + [(self.i >> i) & 1 for i in range(8)]) + self.assertEqual(list(fiter(self.j)), + [(self.j >> i) & 1 for i in range(8)]) + + def test_fiter_type(self): + self.assertRaises(TypeError, fiter, []) + + def test_fslice(self): + sl = slice(1, None, 2) + fslice(self.s, sl) + self.assertEqual(fslice(self.i, sl), 15) + self.assertEqual(fslice(self.j, sl), 8) + + def test_fslice_type(self): + self.assertRaises(TypeError, fslice, [], 3) + + def test_freversed(self): + freversed(self.s) + freversed(self.i) + freversed(self.j) + + def test_freveseed_type(self): + self.assertRaises(TypeError, freversed, []) -- 1.8.3.2
From d1fc7a61e6b6142dd276a2712a6e98cd5b19df6a Mon Sep 17 00:00:00 2001 From: Robert Jordens <jord...@gmail.com> Date: Mon, 2 Dec 2013 17:23:22 -0700 Subject: [PATCH 2/3] migen.fhdl.tools: move flat_iteration to migen.util.misc as tools imports other things --- migen/fhdl/module.py | 3 ++- migen/fhdl/tools.py | 11 +---------- migen/util/misc.py | 10 ++++++++++ 3 files changed, 13 insertions(+), 11 deletions(-) diff --git a/migen/fhdl/module.py b/migen/fhdl/module.py index 4764abb..30e065b 100644 --- a/migen/fhdl/module.py +++ b/migen/fhdl/module.py @@ -4,7 +4,8 @@ from itertools import combinations from migen.fhdl.structure import * from migen.fhdl.structure import _Fragment from migen.fhdl.specials import Special -from migen.fhdl.tools import flat_iteration, rename_clock_domain +from migen.fhdl.tools import rename_clock_domain +from migen.util.misc import flat_iteration class FinalizeError(Exception): pass diff --git a/migen/fhdl/tools.py b/migen/fhdl/tools.py index d940759..b25280b 100644 --- a/migen/fhdl/tools.py +++ b/migen/fhdl/tools.py @@ -1,17 +1,8 @@ -import collections - from migen.fhdl.structure import * from migen.fhdl.structure import _Slice, _Assign from migen.fhdl.visit import NodeVisitor, NodeTransformer from migen.fhdl.size import value_bits_sign - -def flat_iteration(l): - for element in l: - if isinstance(element, collections.Iterable): - for element2 in flat_iteration(element): - yield element2 - else: - yield element +from migen.util.misc import flat_iteration class _SignalLister(NodeVisitor): def __init__(self): diff --git a/migen/util/misc.py b/migen/util/misc.py index fa04161..6846b4a 100644 --- a/migen/util/misc.py +++ b/migen/util/misc.py @@ -1,3 +1,13 @@ +import collections + +def flat_iteration(l): + for element in l: + if isinstance(element, collections.Iterable): + for element2 in flat_iteration(element): + yield element2 + else: + yield element + def xdir(obj, return_values=False): for attr in dir(obj): if attr[:2] != "__" and attr[-2:] != "__": -- 1.8.3.2
From 05bcd56179f4f564843636faf2cc5a7339143b79 Mon Sep 17 00:00:00 2001 From: Robert Jordens <jord...@gmail.com> Date: Mon, 2 Dec 2013 17:23:56 -0700 Subject: [PATCH 3/3] migen.fhdl.structure: have Cat() flat_iteration-ize its arguments --- migen/fhdl/structure.py | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/migen/fhdl/structure.py b/migen/fhdl/structure.py index a94c198..aba747b 100644 --- a/migen/fhdl/structure.py +++ b/migen/fhdl/structure.py @@ -4,6 +4,7 @@ import builtins from collections import defaultdict from migen.fhdl import tracer +from migen.util.misc import flat_iteration class HUID: __next_uid = 0 @@ -87,7 +88,7 @@ class Value(HUID): elif isinstance(key, slice): start, stop, step = key.indices(flen(self)) if step != 1: - return Cat(*(self[i] for i in range(start, stop, step))) + return Cat(self[i] for i in range(start, stop, step)) return _Slice(self, start, stop) else: raise KeyError @@ -155,11 +156,11 @@ class Cat(Value): meeting these properties. The bit length of the return value is the sum of the bit lengths of the arguments:: - flen(Cat(*args)) == sum(flen(arg) for arg in args) + flen(Cat(args)) == sum(flen(arg) for arg in args) Parameters ---------- - *args : Value, inout + *args : Values or iterables of Values, inout `Value` s to be concatenated. Returns @@ -169,7 +170,7 @@ class Cat(Value): """ def __init__(self, *args): Value.__init__(self) - self.l = args + self.l = list(flat_iteration(args)) class Replicate(Value): """Replicate a value -- 1.8.3.2
_______________________________________________ Devel mailing list Devel@lists.milkymist.org https://ssl.serverraum.org/lists/listinfo/devel