Mention contrib/test_failfast in test README
[gram.git] / gram / test / test_compat.py
index 041bb0b996fd40dbb4182fd3bce49870243ecb87..11100543af71f8af6777f1bef5ab6478f8df7b33 100644 (file)
@@ -1,10 +1,12 @@
-import unittest
-
+#nmigen: UnusedElaboratable=no
 from nmigen import *
+from nmigen.hdl.ast import Past
+from nmigen.asserts import Assert, Assume
 
 from gram.compat import *
+from utils import *
 
-class DelayedEnterTestCase(unittest.TestCase):
+class DelayedEnterTestCase(FHDLTestCase):
     def test_sequence(self):
         def sequence(expected_delay):
             m = Module()
@@ -33,11 +35,7 @@ class DelayedEnterTestCase(unittest.TestCase):
 
                 self.assertEqual(delay, expected_delay)
 
-            sim = Simulator(m)
-            with sim.write_vcd("test_compat.vcd"):
-                sim.add_clock(1e-6)
-                sim.add_sync_process(process)
-                sim.run()
+            runSimulation(m, process, "test_delayedenter.vcd")
 
         with self.assertRaises(AssertionError):
             sequence(0)
@@ -47,7 +45,7 @@ class DelayedEnterTestCase(unittest.TestCase):
         sequence(100)
         sequence(1000)
 
-class TimelineTestCase(unittest.TestCase):
+class TimelineTestCase(FHDLTestCase):
     def test_sequence(self):
         sigA = Signal()
         sigB = Signal()
@@ -59,8 +57,6 @@ class TimelineTestCase(unittest.TestCase):
             (10, sigB.eq(1)),
             (11, sigB.eq(0)),
         ])
-        m = Module()
-        m.submodules.timeline = timeline
 
         def process():
             # Test default value for unset signals
@@ -102,8 +98,48 @@ class TimelineTestCase(unittest.TestCase):
                 self.assertFalse((yield sigA))
                 self.assertFalse((yield sigB))
 
-        sim = Simulator(m)
-        with sim.write_vcd("test_compat.vcd"):
-            sim.add_clock(1e-6)
-            sim.add_sync_process(process)
-            sim.run()
+        runSimulation(timeline, process, "test_timeline.vcd")
+
+class RoundRobinOutputMatchSpec(Elaboratable):
+    def __init__(self, dut):
+        self.dut = dut
+
+    def elaborate(self, platform):
+        m = Module()
+
+        m.d.comb += Assume(Rose(self.dut.stb).implies(self.dut.request == Past(self.dut.request)))
+
+        m.d.sync += Assert(((Past(self.dut.request) != 0) & Past(self.dut.stb)).implies(Past(self.dut.request) & (1 << self.dut.grant)))
+
+        return m
+
+class RoundRobinTestCase(FHDLTestCase):
+    def test_sequence(self):
+        m = Module()
+        m.submodules.rb = roundrobin = RoundRobin(8)
+
+        def process():
+            yield roundrobin.request.eq(0b10001000)
+            yield roundrobin.stb.eq(1)
+            yield
+            yield
+
+            self.assertEqual((yield roundrobin.grant), 3)
+            yield
+
+            self.assertEqual((yield roundrobin.grant), 7)
+            yield
+
+            self.assertEqual((yield roundrobin.grant), 3)
+            yield roundrobin.request.eq(0b00000001)
+            yield
+            yield
+
+            self.assertEqual((yield roundrobin.grant), 0)
+
+        runSimulation(m, process, "test_roundrobin.vcd")
+
+    # def test_output_match(self):
+    #     roundrobin = RoundRobin(32)
+    #     spec = RoundRobinOutputMatchSpec(roundrobin)
+    #     self.assertFormal(spec, mode="bmc", depth=10)
\ No newline at end of file