Improve test added in 29fee01f to not leak warnings.
[nmigen.git] / nmigen / test / test_sim.py
index 5b7722286db2835b3694b25f7e1630b8a0c514ac..2a3d93d34ab45f1c1f76471017de32a5774234a8 100644 (file)
@@ -151,18 +151,30 @@ class SimulatorUnitTestCase(FHDLTestCase):
         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))
@@ -238,7 +250,7 @@ class SimulatorUnitTestCase(FHDLTestCase):
 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()
@@ -280,7 +292,7 @@ class SimulatorIntegrationTestCase(FHDLTestCase):
             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)
@@ -317,12 +329,15 @@ class SimulatorIntegrationTestCase(FHDLTestCase):
                 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)
 
@@ -373,9 +388,10 @@ class SimulatorIntegrationTestCase(FHDLTestCase):
         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:
@@ -384,6 +400,13 @@ class SimulatorIntegrationTestCase(FHDLTestCase):
                         "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()
@@ -420,7 +443,8 @@ class SimulatorIntegrationTestCase(FHDLTestCase):
         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)
 
@@ -487,9 +511,11 @@ class SimulatorIntegrationTestCase(FHDLTestCase):
                 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)
 
@@ -531,6 +557,66 @@ class SimulatorIntegrationTestCase(FHDLTestCase):
             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"):