from ..hdl.ast import *
from ..hdl.cd import *
from ..hdl.mem import *
+from ..hdl.rec import *
from ..hdl.dsl import *
from ..hdl.ir import *
from ..back.pysim import *
stmt2 = lambda y, a: y[2:4].eq(a)
self.assertStatement(stmt2, [C(0b01, 2)], C(0b11110111, 8), reset=0b11111011)
- def test_part(self):
- stmt = lambda y, a, b: y.eq(a.part(b, 3))
+ def test_bit_select(self):
+ stmt = lambda y, a, b: y.eq(a.bit_select(b, 3))
self.assertStatement(stmt, [C(0b10110100, 8), C(0)], C(0b100, 3))
self.assertStatement(stmt, [C(0b10110100, 8), C(2)], C(0b101, 3))
self.assertStatement(stmt, [C(0b10110100, 8), C(3)], C(0b110, 3))
- def test_part_lhs(self):
- stmt = lambda y, a, b: y.part(a, 3).eq(b)
+ def test_bit_select_lhs(self):
+ stmt = lambda y, a, b: y.bit_select(a, 3).eq(b)
self.assertStatement(stmt, [C(0), C(0b100, 3)], C(0b11111100, 8), reset=0b11111111)
self.assertStatement(stmt, [C(2), C(0b101, 3)], C(0b11110111, 8), reset=0b11111111)
self.assertStatement(stmt, [C(3), C(0b110, 3)], C(0b11110111, 8), reset=0b11111111)
+ def test_word_select(self):
+ stmt = lambda y, a, b: y.eq(a.word_select(b, 3))
+ self.assertStatement(stmt, [C(0b10110100, 8), C(0)], C(0b100, 3))
+ self.assertStatement(stmt, [C(0b10110100, 8), C(1)], C(0b110, 3))
+ self.assertStatement(stmt, [C(0b10110100, 8), C(2)], C(0b010, 3))
+
+ def test_word_select_lhs(self):
+ stmt = lambda y, a, b: y.word_select(a, 3).eq(b)
+ self.assertStatement(stmt, [C(0), C(0b100, 3)], C(0b11111100, 8), reset=0b11111111)
+ self.assertStatement(stmt, [C(1), C(0b101, 3)], C(0b11101111, 8), reset=0b11111111)
+ self.assertStatement(stmt, [C(2), C(0b110, 3)], C(0b10111111, 8), reset=0b11111111)
+
def test_cat(self):
stmt = lambda y, *xs: y.eq(Cat(*xs))
self.assertStatement(stmt, [C(0b10, 2), C(0b01, 2)], C(0b0110, 4))
stmt = lambda y, a: [Cat(l, m, n).eq(a), y.eq(Cat(n, m, l))]
self.assertStatement(stmt, [C(0b100101110, 9)], C(0b110101100, 9))
+ def test_record(self):
+ rec = Record([
+ ("l", 1),
+ ("m", 2),
+ ])
+ stmt = lambda y, a: [rec.eq(a), y.eq(rec)]
+ self.assertStatement(stmt, [C(0b101, 3)], C(0b101, 3))
+
def test_repl(self):
stmt = lambda y, a: y.eq(Repl(a, 3))
self.assertStatement(stmt, [C(0b10, 2)], C(0b101010, 6))
self.assertStatement(stmt, [C(1)], C(4))
self.assertStatement(stmt, [C(2)], C(10))
+ def test_array_oob(self):
+ array = Array([1, 4, 10])
+ stmt = lambda y, a: y.eq(array[a])
+ self.assertStatement(stmt, [C(3)], C(10))
+ self.assertStatement(stmt, [C(4)], C(10))
+
def test_array_lhs(self):
l = Signal(3, reset=1)
m = Signal(3, reset=4)
self.assertStatement(stmt, [C(1), C(0b010)], C(0b111010001))
self.assertStatement(stmt, [C(2), C(0b100)], C(0b100100001))
+ def test_array_lhs_oob(self):
+ l = Signal(3)
+ m = Signal(3)
+ n = Signal(3)
+ array = Array([l, m, n])
+ stmt = lambda y, a, b: [array[a].eq(b), y.eq(Cat(*array))]
+ self.assertStatement(stmt, [C(3), C(0b001)], C(0b001000000))
+ self.assertStatement(stmt, [C(4), C(0b010)], C(0b010000000))
+
def test_array_index(self):
array = Array(Array(x * y for y in range(10)) for x in range(10))
stmt = lambda y, a, b: y.eq(array[a][b])
class SimulatorIntegrationTestCase(FHDLTestCase):
@contextmanager
def assertSimulation(self, module, deadline=None):
- with Simulator(module.lower(platform=None)) as sim:
+ with Simulator(module.elaborate(platform=None)) as sim:
yield sim
if deadline is None:
sim.run()
sim.add_clock(1e-6, domain="sync")
def process():
self.assertEqual((yield self.count), 4)
- self.assertEqual((yield self.sync.clk), 0)
+ self.assertEqual((yield self.sync.clk), 1)
yield
self.assertEqual((yield self.count), 5)
self.assertEqual((yield self.sync.clk), 1)
yield self.b.eq(1)
yield
self.assertEqual((yield self.x), 4)
+ yield
self.assertEqual((yield self.o), 6)
yield self.s.eq(1)
yield
+ yield
self.assertEqual((yield self.o), 4)
yield self.s.eq(2)
yield
+ yield
self.assertEqual((yield self.o), 0)
sim.add_sync_process(process)
with self.assertSimulation(Module(), deadline=100e-6) as sim:
sim.add_clock(1e-6)
def process():
- for _ in range(100):
- yield
+ for _ in range(101):
+ yield Delay(1e-6)
self.fail()
+ sim.add_process(process)
def test_add_process_wrong(self):
with self.assertSimulation(Module()) as sim:
"a generator function"):
sim.add_process(1)
+ def test_add_clock_wrong(self):
+ with self.assertSimulation(Module()) as sim:
+ sim.add_clock(1)
+ with self.assertRaises(ValueError,
+ msg="Domain 'sync' already has a clock driving it"):
+ sim.add_clock(1)
+
def test_eq_signal_unused_wrong(self):
self.setUp_lhs_rhs()
self.s = Signal()
self.m = Module()
self.memory = Memory(width=8, depth=4, init=[0xaa, 0x55])
self.m.submodules.rdport = self.rdport = \
- self.memory.read_port(synchronous=rd_synchronous, transparent=rd_transparent)
+ self.memory.read_port(domain="sync" if rd_synchronous else "comb",
+ transparent=rd_transparent)
self.m.submodules.wrport = self.wrport = \
self.memory.write_port(granularity=wr_granularity)
self.setUp_memory()
with self.assertSimulation(self.m) as sim:
def process():
- yield
self.assertEqual((yield self.rdport.data), 0xaa)
yield self.rdport.addr.eq(1)
yield
+ yield
self.assertEqual((yield self.rdport.data), 0x55)
yield self.rdport.addr.eq(2)
yield
+ yield
self.assertEqual((yield self.rdport.data), 0x00)
sim.add_clock(1e-6)
sim.add_sync_process(process)
yield self.wrport.en.eq(1)
yield self.rdport.en.eq(1)
yield
+ self.assertEqual((yield self.rdport.data), 0x00)
+ yield
self.assertEqual((yield self.rdport.data), 0xaa)
yield Delay(1e-6) # let comb propagate
- self.assertEqual((yield self.rdport.data), 0xaa)
+ self.assertEqual((yield self.rdport.data), 0x33)
sim.add_clock(1e-6)
sim.add_sync_process(process)
self.assertEqual((yield self.rdport.data), 0xaa)
yield Delay(1e-6) # let comb propagate
self.assertEqual((yield self.rdport.data), 0x33)
+ yield
+ yield self.rdport.addr.eq(1)
+ yield Delay(1e-6) # let comb propagate
+ self.assertEqual((yield self.rdport.data), 0x33)
sim.add_clock(1e-6)
sim.add_sync_process(process)
self.assertEqual((yield self.rdport.data), 0x33)
sim.add_clock(1e-6)
sim.add_process(process)
+
+ def test_memory_read_only(self):
+ self.m = Module()
+ self.memory = Memory(width=8, depth=4, init=[0xaa, 0x55])
+ self.m.submodules.rdport = self.rdport = self.memory.read_port()
+ with self.assertSimulation(self.m) as sim:
+ def process():
+ self.assertEqual((yield self.rdport.data), 0xaa)
+ yield self.rdport.addr.eq(1)
+ yield
+ yield
+ self.assertEqual((yield self.rdport.data), 0x55)
+ sim.add_clock(1e-6)
+ sim.add_sync_process(process)
+
+ def test_sample_helpers(self):
+ m = Module()
+ s = Signal(2)
+ def mk(x):
+ y = Signal.like(x)
+ m.d.comb += y.eq(x)
+ return y
+ p0, r0, f0, s0 = mk(Past(s, 0)), mk(Rose(s)), mk(Fell(s)), mk(Stable(s))
+ p1, r1, f1, s1 = mk(Past(s)), mk(Rose(s, 1)), mk(Fell(s, 1)), mk(Stable(s, 1))
+ p2, r2, f2, s2 = mk(Past(s, 2)), mk(Rose(s, 2)), mk(Fell(s, 2)), mk(Stable(s, 2))
+ p3, r3, f3, s3 = mk(Past(s, 3)), mk(Rose(s, 3)), mk(Fell(s, 3)), mk(Stable(s, 3))
+ with self.assertSimulation(m) as sim:
+ def process_gen():
+ yield s.eq(0b10)
+ yield
+ yield
+ yield s.eq(0b01)
+ yield
+ def process_check():
+ yield
+ yield
+ yield
+
+ self.assertEqual((yield p0), 0b01)
+ self.assertEqual((yield p1), 0b10)
+ self.assertEqual((yield p2), 0b10)
+ self.assertEqual((yield p3), 0b00)
+
+ self.assertEqual((yield s0), 0b0)
+ self.assertEqual((yield s1), 0b1)
+ self.assertEqual((yield s2), 0b0)
+ self.assertEqual((yield s3), 0b1)
+
+ self.assertEqual((yield r0), 0b01)
+ self.assertEqual((yield r1), 0b00)
+ self.assertEqual((yield r2), 0b10)
+ self.assertEqual((yield r3), 0b00)
+
+ self.assertEqual((yield f0), 0b10)
+ self.assertEqual((yield f1), 0b00)
+ self.assertEqual((yield f2), 0b00)
+ self.assertEqual((yield f3), 0b00)
+ sim.add_clock(1e-6)
+ sim.add_sync_process(process_gen)
+ sim.add_sync_process(process_check)
+
+ def test_wrong_not_run(self):
+ with self.assertWarns(UserWarning,
+ msg="Simulation created, but not run"):
+ with Simulator(Fragment()) as sim:
+ pass