back.pysim: accept (and evaluate) generator functions.
authorwhitequark <cz@m-labs.hk>
Fri, 14 Dec 2018 13:30:09 +0000 (13:30 +0000)
committerwhitequark <cz@m-labs.hk>
Fri, 14 Dec 2018 13:32:30 +0000 (13:32 +0000)
nmigen/back/pysim.py

index 88cd7a3a618d5671f88c1f31df66cdfbb5c02628..469ef4b60702755f9537e331330158b675ec2a18 100644 (file)
@@ -1,4 +1,5 @@
 import math
+import inspect
 from vcd import VCDWriter
 from vcd.gtkw import GTKWSave
 
@@ -223,9 +224,30 @@ class Simulator:
         self._gtkw_file       = gtkw_file
         self._gtkw_signals    = gtkw_signals
 
+    def _check_process(self, process):
+        if inspect.isgeneratorfunction(process):
+            process = process()
+        if not inspect.isgenerator(process):
+            raise TypeError("Cannot add a process '{!r}' because it is not a generator or"
+                            "a generator function"
+                            .format(process))
+        return process
+
     def add_process(self, process):
+        process = self._check_process(process)
         self._processes.add(process)
 
+    def add_sync_process(self, process, domain="sync"):
+        process = self._check_process(process)
+        def sync_process():
+            try:
+                result = process.send(None)
+                while True:
+                    result = process.send((yield (result or Tick(domain))))
+            except StopIteration:
+                pass
+        self.add_process(sync_process())
+
     def add_clock(self, period, domain="sync"):
         if self._fastest_clock == self._epsilon or period < self._fastest_clock:
             self._fastest_clock = period
@@ -242,16 +264,6 @@ class Simulator:
                 yield Delay(half_period)
         self.add_process(clk_process())
 
-    def add_sync_process(self, process, domain="sync"):
-        def sync_process():
-            try:
-                result = process.send(None)
-                while True:
-                    result = process.send((yield (result or Tick(domain))))
-            except StopIteration:
-                pass
-        self.add_process(sync_process())
-
     def __enter__(self):
         if self._vcd_file:
             self._vcd_writer = VCDWriter(self._vcd_file, timescale="100 ps",