sim: support generators yielding statements

This commit is contained in:
Sebastien Bourdeauducq 2015-09-20 15:04:15 +08:00
parent 320dffb4ac
commit 7f767095ec
10 changed files with 31 additions and 28 deletions

View File

@ -9,7 +9,7 @@ def tb(dut):
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 dut.ce.eq(prng.getrandbits(1))
yield

View File

@ -18,9 +18,9 @@ def counter_test(dut):
# Only assert CE every second cycle.
# => each counter value is held for two cycles.
if cycle % 2:
yield dut.ce, 0 # This is how you write to a signal.
yield dut.ce.eq(0) # This is how you write to a signal.
else:
yield dut.ce, 1
yield dut.ce.eq(1)
print("Cycle: {} Count: {}".format(cycle, (yield dut.count)))
yield

View File

@ -38,7 +38,7 @@ def fir_tb(dut, frequency, inputs, outputs):
f = 2**(dut.wsize - 1)
for cycle in range(200):
v = 0.1*cos(2*pi*frequency*cycle)
yield dut.i, int(f*v)
yield dut.i.eq(int(f*v))
inputs.append(v)
outputs.append((yield dut.o)/f)
yield

View File

@ -11,7 +11,7 @@ class Mem(Module):
def memory_test(dut):
# write (only first 5 values)
for i in range(5):
yield dut.mem[i], 42 + i
yield dut.mem[i].eq(42 + i)
# remember: values are written after the tick, and read before the tick.
# wait one tick for the memory to update.
yield

View File

@ -1,7 +1,8 @@
import operator
from migen.fhdl.structure import *
from migen.fhdl.structure import (_Value, _Operator, _Slice, _ArrayProxy,
from migen.fhdl.structure import (_Value, _Statement,
_Operator, _Slice, _ArrayProxy,
_Assign, _Fragment)
from migen.fhdl.bitcontainer import flen
from migen.fhdl.tools import list_targets
@ -207,11 +208,14 @@ class Simulator:
self.evaluator.execute(self.fragment.comb)
modified = self.evaluator.commit()
def _eval_nested_lists(self, x):
def _evalexec_nested_lists(self, x):
if isinstance(x, list):
return [self._eval_nested_lists(e) for e in x]
return [self._evalexec_nested_lists(e) for e in x]
elif isinstance(x, _Value):
return self.evaluator.eval(x)
elif isinstance(x, _Statement):
self.evaluator.execute([x])
return None
else:
raise ValueError
@ -224,10 +228,8 @@ class Simulator:
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)
reply = self._evalexec_nested_lists(request)
except StopIteration:
exhausted.append(generator)
break

View File

@ -21,7 +21,7 @@ class EncCase(SimCase, unittest.TestCase):
def gen():
for _ in range(256):
if seq:
yield self.tb.dut.i, seq.pop(0)
yield self.tb.dut.i.eq(seq.pop(0))
if (yield self.tb.dut.n):
self.assertNotIn((yield self.tb.dut.i), [1<<i for i in range(8)])
else:
@ -45,7 +45,7 @@ class PrioEncCase(SimCase, unittest.TestCase):
def gen():
for _ in range(256):
if seq:
yield self.tb.dut.i, seq.pop(0)
yield self.tb.dut.i.eq(seq.pop(0))
i = yield self.tb.dut.i
if (yield self.tb.dut.n):
self.assertEqual(i, 0)
@ -74,8 +74,8 @@ class DecCase(SimCase, unittest.TestCase):
for _ in range(256):
if seq:
i = seq.pop()
yield self.tb.dut.i, i//2
yield self.tb.dut.n, i%2
yield self.tb.dut.i.eq(i//2)
yield self.tb.dut.n.eq(i%2)
i = yield self.tb.dut.i
o = yield self.tb.dut.o
if (yield self.tb.dut.n):
@ -100,7 +100,7 @@ class SmallPrioEncCase(SimCase, unittest.TestCase):
def gen():
for _ in range(5):
if seq:
yield self.tb.dut.i, seq.pop(0)
yield self.tb.dut.i.eq(seq.pop(0))
i = yield self.tb.dut.i
if (yield self.tb.dut.n):
self.assertEqual(i, 0)

View File

@ -14,11 +14,11 @@ class DivisionCase(SimCase, unittest.TestCase):
def gen():
for dividend in range(16):
for divisor in range(1, 16):
yield self.tb.dut.dividend_i, dividend
yield self.tb.dut.divisor_i, divisor
yield self.tb.dut.start_i, 1
yield self.tb.dut.dividend_i.eq(dividend)
yield self.tb.dut.divisor_i.eq(divisor)
yield self.tb.dut.start_i.eq(1)
yield
yield self.tb.dut.start_i, 0
yield self.tb.dut.start_i.eq(0)
while not (yield self.tb.dut.ready_o):
yield
self.assertEqual((yield self.tb.dut.quotient_o), dividend//divisor)

View File

@ -28,8 +28,8 @@ class SyncFIFOCase(SimCase, unittest.TestCase):
def gen():
for cycle in count():
# fire re and we at "random"
yield self.tb.dut.we, cycle % 2 == 0
yield self.tb.dut.re, cycle % 3 == 0
yield self.tb.dut.we.eq(cycle % 2 == 0)
yield self.tb.dut.re.eq(cycle % 3 == 0)
# the output if valid must be correct
if (yield self.tb.dut.readable) and (yield self.tb.dut.re):
try:
@ -45,9 +45,10 @@ class SyncFIFOCase(SimCase, unittest.TestCase):
seq = [x for x in range(20) if x % 5]
def gen():
for cycle in count():
yield self.tb.dut.we, cycle % 2 == 0
yield self.tb.dut.re, cycle % 7 == 0
yield self.tb.dut.replace, (yield self.tb.dut.din.a) % 5 == 1
yield self.tb.dut.we.eq(cycle % 2 == 0)
yield self.tb.dut.re.eq(cycle % 7 == 0)
yield self.tb.dut.replace.eq(
(yield self.tb.dut.din.a) % 5 == 1)
if (yield self.tb.dut.readable) and (yield self.tb.dut.re):
try:
i = seq.pop(0)

View File

@ -29,8 +29,8 @@ class SignedCase(SimCase, unittest.TestCase):
def test_comparisons(self):
def gen():
for i in range(-4, 4):
yield self.tb.a, i
yield self.tb.b, i
yield self.tb.a.eq(i)
yield self.tb.b.eq(i)
a = yield self.tb.a
b = yield self.tb.b
for asign, bsign, f, r, op in self.tb.vals:

View File

@ -23,7 +23,7 @@ class BitonicCase(SimCase, unittest.TestCase):
def gen():
for repeat in range(20):
for i in self.tb.dut.i:
yield i, randrange(1<<flen(i))
yield i.eq(randrange(1<<flen(i)))
yield
self.assertEqual(sorted((yield self.tb.dut.i)),
(yield self.tb.dut.o))