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):
# simple "counter" thing
class Domain2(Elaboratable):
def __init__(self):
- self.counter = Signal(8)
+ self.counter = Signal(64)
self.rst = Signal()
def elaborate(self, platform):
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
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")
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")