Show rdmaskn and wrmask in GTKWave
[soc.git] / src / soc / experiment / test / async_sim.py
index aef6de8e1cf4f8f087d918a101ea7b6016a4510a..964bfb6ea3f291965f544672dfc110f8035aec0e 100644 (file)
@@ -12,7 +12,7 @@ class Domain1(Elaboratable):
     def __init__(self):
         self.tick = Signal()
         self.tick_clear_wait = Signal()
-        self.counter = Signal(8)
+        self.counter = Signal(64)
         self.rst = Signal()
 
     def elaborate(self, platform):
@@ -33,7 +33,7 @@ class Domain1(Elaboratable):
 # simple "counter" thing
 class Domain2(Elaboratable):
     def __init__(self):
-        self.counter = Signal(8)
+        self.counter = Signal(64)
         self.rst = Signal()
 
     def elaborate(self, platform):
@@ -64,7 +64,8 @@ class AsyncThing(Elaboratable):
         comb += core_sync.clk.eq(self.core_clk) # driven externally
         comb += core.rst.eq(ResetSignal())
 
-        m.submodules += AsyncFFSynchronizer(self.core_tick, core.tick)
+        m.submodules += AsyncFFSynchronizer(self.core_tick, core.tick,
+                                            domain="coresync")
 
         return m
 
@@ -74,37 +75,58 @@ def domain_sim(dut):
     for i in range(50):
         yield Tick("coresync")
         counter = (yield dut.core.counter)
-        print ("count", counter)
+        print ("count i", i, counter)
 
 
-# fires the manually-driven clock at 1/3 the rate
+# fires the manually-driven clock at 1/3 the rate (actually about 1/4)
 def async_sim_clk(dut):
 
     for i in range(100):
         yield dut.core_clk.eq(1)
         yield Tick("sync")
         yield Tick("sync")
+        yield Tick("sync")
+        yield Tick("sync")
+        yield Tick("sync")
+        yield Tick("sync")
+        yield Tick("sync")
+        yield Tick("sync")
+        yield Tick("sync")
+
+        # deliberately "unbalance" the duty cycle
         yield dut.core_clk.eq(0)
         yield Tick("sync")
         yield Tick("sync")
+        yield Tick("sync")
 
     counter = yield dut.core2.counter
     print ("async counter", counter)
+    assert counter == 100 # same as number of loops
 
 
-# runs at the coresync tick-rate, arbitrarily switching core_tick on and off
+# runs at the *sync* simulation rate but yields *coresync*-sized ticks,
+# arbitrarily switching core_tick on and off
 # this deliberately does not quite match up with when the *clock* ticks
 # (see async_sim_clk above)
+#
+# experimenting by deleting some of these coresyncs (both the on and off ones)
+# does in fact "miss" things.
+
 def async_sim(dut):
     for i in range(5):
         yield dut.core_tick.eq(1)
         yield Tick("coresync")
         yield Tick("coresync")
         yield Tick("coresync")
+
+        # switch off but must wait at least 3 coresync ticks because
+        # otherwise the coresync domain that the counter is in might
+        # miss it (actually AsyncFFSynchronizer would)
+        yield dut.core_tick.eq(0)
+        yield Tick("coresync")
         yield Tick("coresync")
         yield Tick("coresync")
         yield Tick("coresync")
-        yield dut.core_tick.eq(0)
         yield Tick("coresync")
         yield Tick("coresync")
 
@@ -116,7 +138,10 @@ if __name__ == '__main__':
 
     sim = Simulator(m)
     sim.add_clock(1e-6, domain="sync")      # standard clock
-    sim.add_clock(3e-6, domain="coresync")  # manually-driven. 1/3 rate
+
+    # nooo don't do this, it requests that the simulation start driving
+    # coresync_clk!  and it's to be *manually* driven by async_sim_clk
+    #sim.add_clock(3e-6, domain="coresync")  # manually-driven. 1/3 rate
 
     sim.add_sync_process(wrap(domain_sim(dut)))
     sim.add_sync_process(wrap(async_sim(dut)), domain="coresync")