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: fd986210f811
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: 047d1f48b5d0
Choose a head ref
  • 7 commits
  • 7 files changed
  • 1 contributor

Commits on Sep 12, 2015

  1. Copy the full SHA
    7bd72a1 View commit details
  2. Copy the full SHA
    fa6d96b View commit details
  3. Copy the full SHA
    308c5d7 View commit details
  4. Copy the full SHA
    9556c33 View commit details
  5. Copy the full SHA
    5fa7f74 View commit details
  6. Copy the full SHA
    8ee361f View commit details
  7. Copy the full SHA
    047d1f4 View commit details
Showing with 72 additions and 91 deletions.
  1. +10 −11 examples/basic/graycounter.py
  2. +0 −1 migen/genlib/sort.py
  3. +33 −23 migen/sim.py
  4. +3 −13 migen/test/support.py
  5. +1 −17 migen/test/test_examples.py
  6. +15 −19 migen/test/test_signed.py
  7. +10 −7 migen/test/test_sort.py
21 changes: 10 additions & 11 deletions examples/basic/graycounter.py
Original file line number Diff line number Diff line change
@@ -2,19 +2,18 @@

from migen.fhdl.std import *
from migen.genlib.cdc import GrayCounter
from migen.sim.generic import run_simulation
from migen.sim import Simulator


class TB(Module):
def __init__(self, width=3):
self.width = width
self.submodules.gc = GrayCounter(self.width)
self.prng = Random(7345)
def tb(dut):
prng = Random(7345)
for i in range(35):
print("{0:0{1}b} CE={2} bin={3}".format((yield dut.q),
flen(dut.q), (yield dut.ce), (yield dut.q_binary)))
yield dut.ce, prng.getrandbits(1)
yield

def do_simulation(self, selfp):
print("{0:0{1}b} CE={2} bin={3}".format(selfp.gc.q,
self.width, selfp.gc.ce, selfp.gc.q_binary))
selfp.gc.ce = self.prng.getrandbits(1)

if __name__ == "__main__":
run_simulation(TB(), ncycles=35)
dut = GrayCounter(3)
Simulator(dut, tb(dut)).run()
1 change: 0 additions & 1 deletion migen/genlib/sort.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
from migen.fhdl.std import *
from migen.fhdl import verilog


class BitonicSort(Module):
56 changes: 33 additions & 23 deletions migen/sim.py
Original file line number Diff line number Diff line change
@@ -141,46 +141,56 @@ def __init__(self, fragment_or_module, generators, clocks={"sys": 100}):
for signal in list_inputs(statement):
self.comb_dependent_statements[signal].append(statement)

def _comb_propagate(self, modified):
def _commit_and_comb_propagate(self):
modified = self.evaluator.commit()
while modified:
for signal in modified:
self.evaluator.execute(self.comb_dependent_statements[signal])
modified = self.evaluator.commit()

def _eval_nested_lists(self, x):
if isinstance(x, list):
return [self._eval_nested_lists(e) for e in x]
elif isinstance(x, Signal):
return self.evaluator.eval(x)
else:
raise ValueError

def _process_generators(self, cd):
if cd in self.generators:
exhausted = []
for generator in self.generators[cd]:
reply = None
while True:
try:
request = generator.send(reply)
if request is None:
break # next cycle
elif isinstance(request, tuple):
self.evaluator.assign(*request)
else:
reply = self.evaluator.eval(request)
except StopIteration:
exhausted.append(generator)
break
for generator in exhausted:
self.generators[cd].remove(generator)
exhausted = []
for generator in self.generators[cd]:
reply = None
while True:
try:
request = generator.send(reply)
if request is None:
break # next cycle
elif isinstance(request, tuple):
self.evaluator.assign(*request)
else:
reply = self._eval_nested_lists(request)
except StopIteration:
exhausted.append(generator)
break
for generator in exhausted:
self.generators[cd].remove(generator)

def _continue_simulation(self):
# TODO: passive generators
return any(self.generators.values())

def run(self):
self.evaluator.execute(self.fragment.comb)
self._comb_propagate(self.evaluator.commit())
self._commit_and_comb_propagate()

while True:
cds = self.time.tick()
for cd in cds:
self.evaluator.execute(self.fragment.sync[cd])
self._process_generators(cd)
self._comb_propagate(self.evaluator.commit())
if cd in self.fragment.sync:
self.evaluator.execute(self.fragment.sync[cd])
if cd in self.generators:
self._process_generators(cd)
self._commit_and_comb_propagate()

if not self._continue_simulation():
break
16 changes: 3 additions & 13 deletions migen/test/support.py
Original file line number Diff line number Diff line change
@@ -1,24 +1,14 @@
from migen.fhdl.std import *
from migen.sim.generic import run_simulation
from migen.sim import Simulator
from migen.fhdl import verilog


class SimBench(Module):
callback = None
def do_simulation(self, selfp):
if self.callback is not None:
return self.callback(self, selfp)


class SimCase:
TestBench = SimBench

def setUp(self, *args, **kwargs):
self.tb = self.TestBench(*args, **kwargs)

def test_to_verilog(self):
verilog.convert(self.tb)

def run_with(self, cb, ncycles=None):
self.tb.callback = cb
run_simulation(self.tb, ncycles=ncycles)
def run_with(self, generator):
Simulator(self.tb, generator).run()
18 changes: 1 addition & 17 deletions migen/test/test_examples.py
Original file line number Diff line number Diff line change
@@ -21,10 +21,8 @@ def test_method(self):
class TestExamplesSim(unittest.TestCase):
pass

for name in ("abstract_transactions_wb",
"basic1",
for name in ("basic1",
"basic2",
"dataflow",
# skip "fir" as it depends on SciPy
# "fir",
"memory"):
@@ -36,30 +34,16 @@ class TestExamplesBasic(unittest.TestCase):
pass

for name in ("arrays",
"complex",
"fsm",
"graycounter",
"hamming",
"local_cd",
"memory",
"namer",
"psync",
"record",
"reslice",
"simple_gpio",
"tristate",
"two_dividers"):
setattr(TestExamplesBasic, "test_" + name,
_make_test_method(name, "basic"))


class TestDataflow(unittest.TestCase):
pass

for name in ("dma",
"misc",
# skip "structuring" as it depends on networkx, SciPy
# "structuring",
):
setattr(TestDataflow, "test_" + name,
_make_test_method(name, "dataflow"))
34 changes: 15 additions & 19 deletions migen/test/test_signed.py
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
import unittest

from migen.fhdl.std import *
from migen.test.support import SimCase, SimBench
from migen.test.support import SimCase


class SignedCase(SimCase, unittest.TestCase):
class TestBench(SimBench):
class TestBench(Module):
def __init__(self):
self.a = Signal((3, True))
self.b = Signal((4, True))
@@ -27,20 +27,16 @@ def __init__(self):
self.vals.append((asign, bsign, f, r, r0.op))

def test_comparisons(self):
values = range(-4, 4)
agen = iter(values)
bgen = iter(values)
def cb(tb, tbp):
try:
tbp.a = next(agen)
tbp.b = next(bgen)
except StopIteration:
raise StopSimulation
a = tbp.a
b = tbp.b
for asign, bsign, f, r, op in self.tb.vals:
r, r0 = tbp.simulator.rd(r), f(asign*a, bsign*b)
self.assertEqual(r, int(r0),
"got {}, want {}*{} {} {}*{} = {}".format(
r, asign, a, op, bsign, b, r0))
self.run_with(cb)
def gen():
for i in range(-4, 4):
yield self.tb.a, i
yield self.tb.b, i
a = yield self.tb.a
b = yield self.tb.b
for asign, bsign, f, r, op in self.tb.vals:
r, r0 = (yield r), f(asign*a, bsign*b)
self.assertEqual(r, int(r0),
"got {}, want {}*{} {} {}*{} = {}".format(
r, asign, a, op, bsign, b, r0))
yield
self.run_with(gen())
17 changes: 10 additions & 7 deletions migen/test/test_sort.py
Original file line number Diff line number Diff line change
@@ -4,11 +4,11 @@
from migen.fhdl.std import *
from migen.genlib.sort import *

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


class BitonicCase(SimCase, unittest.TestCase):
class TestBench(SimBench):
class TestBench(Module):
def __init__(self):
self.submodules.dut = BitonicSort(8, 4, ascending=True)

@@ -20,8 +20,11 @@ def test_sizes(self):
self.assertEqual(flen(self.tb.dut.o[i]), 4)

def test_sort(self):
def cb(tb, tbp):
for i in tb.dut.i:
tbp.simulator.wr(i, randrange(1<<flen(i)))
self.assertEqual(sorted(list(tbp.dut.i)), list(tbp.dut.o))
self.run_with(cb, 20)
def gen():
for repeat in range(20):
for i in self.tb.dut.i:
yield i, randrange(1<<flen(i))
yield
self.assertEqual(sorted((yield self.tb.dut.i)),
(yield self.tb.dut.o))
self.run_with(gen())