Skip to content
Permalink

Comparing changes

Choose two branches to see what’s changed or to start a new pull request. If you need to, you can also or learn more about diff comparisons.

Open a pull request

Create a new pull request by comparing changes across two branches. If you need to, you can also . Learn more about diff comparisons here.
base repository: m-labs/migen
Failed to load repositories. Confirm that selected base ref is valid, then try again.
Loading
base: 6e08df75ee8f
Choose a base ref
...
head repository: m-labs/migen
Failed to load repositories. Confirm that selected head ref is valid, then try again.
Loading
compare: ec1d4edf848c
Choose a head ref
  • 9 commits
  • 6 files changed
  • 1 contributor

Commits on Sep 17, 2015

  1. minor bugfixes

    sbourdeauducq committed Sep 17, 2015

    Verified

    This commit was signed with the committer’s verified signature.
    headius Charles Oliver Nutter
    Copy the full SHA
    c2109f8 View commit details
  2. Copy the full SHA
    bcf6299 View commit details
  3. Copy the full SHA
    776579f View commit details
  4. Copy the full SHA
    12cd390 View commit details
  5. Copy the full SHA
    4a3a1bc View commit details
  6. Copy the full SHA
    049a8f0 View commit details
  7. Copy the full SHA
    2688d66 View commit details
  8. Copy the full SHA
    9d3fd50 View commit details
  9. sim: support Case

    sbourdeauducq committed Sep 17, 2015
    Copy the full SHA
    ec1d4ed View commit details
Showing with 79 additions and 120 deletions.
  1. +1 −27 migen/fhdl/bitcontainer.py
  2. +3 −1 migen/fhdl/structure.py
  3. +1 −0 migen/genlib/misc.py
  4. +16 −10 migen/sim.py
  5. +56 −49 migen/test/test_coding.py
  6. +2 −33 migen/test/test_size.py
28 changes: 1 addition & 27 deletions migen/fhdl/bitcontainer.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
from migen.fhdl import structure as f


__all__ = ["log2_int", "bits_for", "flen", "fiter"]
__all__ = ["log2_int", "bits_for", "flen"]


def log2_int(n, need_pow2=True):
@@ -123,29 +123,3 @@ def flen(v):
"""
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))
4 changes: 3 additions & 1 deletion migen/fhdl/structure.py
Original file line number Diff line number Diff line change
@@ -432,7 +432,7 @@ def __init__(self, l, r):


def _check_statement(s):
if isinstance(s, Iterable):
if isinstance(s, _collections.Iterable):
return all(_check_statement(ss) for ss in s)
else:
return isinstance(s, _Statement)
@@ -547,6 +547,8 @@ def __init__(self, test, cases):
if (not isinstance(k, Constant)
and not (isinstance(k, str) and k == "default")):
raise TypeError("Case object is not a Migen constant")
if not isinstance(v, _collections.Iterable):
v = [v]
if not _check_statement(v):
raise TypeError("Not all objects for case {} "
"are Migen statements".format(k))
1 change: 1 addition & 0 deletions migen/genlib/misc.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
from migen.fhdl.structure import *
from migen.fhdl.module import Module
from migen.fhdl.bitcontainer import bits_for


def split(v, *counts):
26 changes: 16 additions & 10 deletions migen/sim.py
Original file line number Diff line number Diff line change
@@ -4,7 +4,7 @@
from migen.fhdl.structure import *
from migen.fhdl.structure import _Operator, _Slice, _Assign, _Fragment
from migen.fhdl.bitcontainer import flen
from migen.fhdl.tools import list_inputs
from migen.fhdl.tools import list_targets


__all__ = ["Simulator"]
@@ -80,7 +80,7 @@ def eval(self, node):
try:
return self.signal_values[node]
except KeyError:
return node.reset
return node.reset.value
elif isinstance(node, _Operator):
operands = [self.eval(o) for o in node.operands]
if node.op == "-":
@@ -110,6 +110,7 @@ def eval(self, node):
raise NotImplementedError

def assign(self, signal, value):
assert not signal.variable
value = value & (2**signal.nbits - 1)
if signal.signed and (value & 2**(signal.nbits - 1)):
value -= 2**signal.nbits
@@ -129,8 +130,15 @@ def execute(self, statements):
self.execute(s.t)
else:
self.execute(s.f)
elif isinstance(s, Case):
test = self.eval(s.test)
for k, v in s.cases.items():
if isinstance(k, Constant) and k.value == test:
self.execute(v)
return
if "default" in s.cases:
self.execute(s.cases["default"])
else:
# TODO: Case
raise NotImplementedError


@@ -152,19 +160,17 @@ def __init__(self, fragment_or_module, generators, clocks={"sys": 100}):
self.generators[k] = [v]

# TODO: insert_resets
self.fragment.comb[0:0] = [s.eq(s.reset)
for s in list_targets(self.fragment.comb)]

self.time = TimeManager(clocks)
self.evaluator = Evaluator()

self.comb_dependent_statements = defaultdict(list)
for statement in self.fragment.comb:
for signal in list_inputs(statement):
self.comb_dependent_statements[signal].append(statement)

def _commit_and_comb_propagate(self):
# TODO: optimize
modified = self.evaluator.commit()
while modified:
for signal in modified:
self.evaluator.execute(self.comb_dependent_statements[signal])
self.evaluator.execute(self.fragment.comb)
modified = self.evaluator.commit()

def _eval_nested_lists(self, x):
105 changes: 56 additions & 49 deletions migen/test/test_coding.py
Original file line number Diff line number Diff line change
@@ -3,11 +3,11 @@
from migen import *
from migen.genlib.coding import *

from migen.test.support import SimCase, SimBench
from migen.test.support import SimCase


class EncCase(SimCase, unittest.TestCase):
class TestBench(SimBench):
class TestBench(Module):
def __init__(self):
self.submodules.dut = Encoder(8)

@@ -18,18 +18,20 @@ def test_sizes(self):

def test_run_sequence(self):
seq = list(range(1<<8))
def cb(tb, tbp):
if seq:
tbp.dut.i = seq.pop(0)
if tbp.dut.n:
self.assertNotIn(tbp.dut.i, [1<<i for i in range(8)])
else:
self.assertEqual(tbp.dut.i, 1<<tbp.dut.o)
self.run_with(cb, 256)
def gen():
for _ in range(256):
if seq:
yield self.tb.dut.i, seq.pop(0)
if (yield self.tb.dut.n):
self.assertNotIn((yield self.tb.dut.i), [1<<i for i in range(8)])
else:
self.assertEqual((yield self.tb.dut.i), 1<<(yield self.tb.dut.o))
yield
self.run_with(gen())


class PrioEncCase(SimCase, unittest.TestCase):
class TestBench(SimBench):
class TestBench(Module):
def __init__(self):
self.submodules.dut = PriorityEncoder(8)

@@ -40,22 +42,24 @@ def test_sizes(self):

def test_run_sequence(self):
seq = list(range(1<<8))
def cb(tb, tbp):
if seq:
tbp.dut.i = seq.pop(0)
i = tbp.dut.i
if tbp.dut.n:
self.assertEqual(i, 0)
else:
o = tbp.dut.o
if o > 0:
self.assertEqual(i & 1<<(o - 1), 0)
self.assertGreaterEqual(i, 1<<o)
self.run_with(cb, 256)
def gen():
for _ in range(256):
if seq:
yield self.tb.dut.i, seq.pop(0)
i = yield self.tb.dut.i
if (yield self.tb.dut.n):
self.assertEqual(i, 0)
else:
o = yield self.tb.dut.o
if o > 0:
self.assertEqual(i & 1<<(o - 1), 0)
self.assertGreaterEqual(i, 1<<o)
yield
self.run_with(gen())


class DecCase(SimCase, unittest.TestCase):
class TestBench(SimBench):
class TestBench(Module):
def __init__(self):
self.submodules.dut = Decoder(8)

@@ -66,22 +70,23 @@ def test_sizes(self):

def test_run_sequence(self):
seq = list(range(8*2))
def cb(tb, tbp):
if seq:
i = seq.pop()
tbp.dut.i = i//2
tbp.dut.n = i%2
i = tbp.dut.i
o = tbp.dut.o
if tbp.dut.n:
self.assertEqual(o, 0)
else:
self.assertEqual(o, 1<<i)
self.run_with(cb, 256)
def gen():
for _ in range(256):
if seq:
i = seq.pop()
yield self.tb.dut.i, i//2
yield self.tb.dut.n, i%2
i = yield self.tb.dut.i
o = yield self.tb.dut.o
if (yield self.tb.dut.n):
self.assertEqual(o, 0)
else:
self.assertEqual(o, 1<<i)
self.run_with(gen())


class SmallPrioEncCase(SimCase, unittest.TestCase):
class TestBench(SimBench):
class TestBench(Module):
def __init__(self):
self.submodules.dut = PriorityEncoder(1)

@@ -92,15 +97,17 @@ def test_sizes(self):

def test_run_sequence(self):
seq = list(range(1))
def cb(tb, tbp):
if seq:
tbp.dut.i = seq.pop(0)
i = tbp.dut.i
if tbp.dut.n:
self.assertEqual(i, 0)
else:
o = tbp.dut.o
if o > 0:
self.assertEqual(i & 1<<(o - 1), 0)
self.assertGreaterEqual(i, 1<<o)
self.run_with(cb, 5)
def gen():
for _ in range(5):
if seq:
yield self.tb.dut.i, seq.pop(0)
i = yield self.tb.dut.i
if (yield self.tb.dut.n):
self.assertEqual(i, 0)
else:
o = yield self.tb.dut.o
if o > 0:
self.assertEqual(i & 1<<(o - 1), 0)
self.assertGreaterEqual(i, 1<<o)
yield
self.run_with(gen())
35 changes: 2 additions & 33 deletions migen/test/test_size.py
Original file line number Diff line number Diff line change
@@ -9,8 +9,8 @@ def _same_slices(a, b):

class SignalSizeCase(unittest.TestCase):
def setUp(self):
self.i = 0xaa
self.j = -127
self.i = C(0xaa)
self.j = C(-127)
self.s = Signal((13, True))

def test_flen(self):
@@ -20,34 +20,3 @@ def test_flen(self):

def test_flen_type(self):
self.assertRaises(TypeError, flen, [])

def test_fiter(self):
for i, si in enumerate(fiter(self.s)):
self.assertTrue(_same_slices(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)
self.assertEqual(fslice(-1, 9), 1)
self.assertEqual(fslice(-1, slice(0, 4)), 0b1)
self.assertEqual(fslice(-7, slice(0, None, 1)), 0b1001)

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, [])