sim: support generators yielding statements
This commit is contained in:
parent
320dffb4ac
commit
7f767095ec
|
@ -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
|
||||
|
||||
|
||||
|
|
|
@ -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
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
14
migen/sim.py
14
migen/sim.py
|
@ -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
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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:
|
||||
|
|
|
@ -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))
|
||||
|
|
Loading…
Reference in New Issue