Add 'passive' simulation functions that are not taken into account while determining...
authorSebastien Bourdeauducq <sebastien@milkymist.org>
Mon, 27 Jan 2014 22:58:46 +0000 (23:58 +0100)
committerSebastien Bourdeauducq <sebastien@milkymist.org>
Mon, 27 Jan 2014 22:58:46 +0000 (23:58 +0100)
migen/bus/lasmibus.py
migen/bus/wishbone.py
migen/fhdl/module.py
migen/sim/generic.py
migen/sim/upper.py

index d907581b61f301dae4f5ae7827d551a7d5ed3105..481d2a8bf791452bead578c7f6cd3c5450999ff9 100644 (file)
@@ -260,6 +260,7 @@ class _ReqFIFO(Module):
                else:
                        selfp.bank.req_ack = 0
                selfp.bank.lock = bool(self.contents)
+       do_simulation.passive = True
 
 class Target(Module):
        def __init__(self, model, *ifargs, **ifkwargs):
@@ -305,3 +306,4 @@ class Target(Module):
                if done_wr_transaction is not None:
                        self.model.write(done_wr_transaction[0], done_wr_transaction[1],
                                selfp.bus.dat_w, selfp.bus.dat_we)
+       do_simulation.passive = True
index e2f95c40b010527425c8675dbfee6fdb52d72678..b09137efbf81976380c7f57ed3c35cc4718d42bc 100644 (file)
@@ -212,6 +212,7 @@ class Tap(Module):
                                transaction = TRead(selfp.bus.adr,
                                        selfp.bus.dat_r)
                        self.handler(transaction)
+       do_simulation.passive = True
 
 class Initiator(Module):
        def __init__(self, generator, bus=None):
@@ -277,6 +278,7 @@ class Target(Module):
                                bus.ack = 1
                else:
                        bus.ack = 0
+       do_simulation.passive = True
 
 class SRAM(Module):
        def __init__(self, mem_or_size, read_only=None, init=None, bus=None):
index eb236a943782c85d1d6496419243d6bbd07fdfcc..1d97dd41b5c0a37a419aee512337fb95f7286f54 100644 (file)
@@ -5,7 +5,7 @@ from migen.util.misc import flat_iteration
 from migen.fhdl.structure import *
 from migen.fhdl.structure import _Fragment
 from migen.fhdl.tools import rename_clock_domain
-from migen.sim.upper import GenSim, ProxySim
+from migen.sim.upper import gen_sim, proxy_sim
 
 class FinalizeError(Exception):
        pass
@@ -115,11 +115,9 @@ class Module:
                                except AttributeError:
                                        pass
                                else:
-                                       gs = GenSim(simg)
-                                       simf = gs.do_simulation
+                                       simf = gen_sim(simg)
                        if simf is not None:
-                               ps = ProxySim(self, simf)
-                               simf = ps.do_simulation
+                               simf = proxy_sim(self, simf)
                        sim = [] if simf is None else [simf]
                        self._fragment = _Fragment(sim=sim)
                        return self._fragment
index 02017e380fa537f50ed41cee3d469c200cd71471..c06d126533bd8cc29f60895633a06b69fed6b9ac 100644 (file)
@@ -72,16 +72,6 @@ end
                r += "\nendmodule"
                return r
 
-def _call_sim(fragment, simulator):
-       del_list = []
-       for s in fragment.sim:
-               try:
-                       s(simulator)
-               except StopSimulation:
-                       del_list.append(s)
-       for s in del_list:
-               fragment.sim.remove(s)
-
 class Simulator:
        def __init__(self, fragment, top_level=None, sim_runner=None, sockaddr="simsocket", **vopts):
                if not isinstance(fragment, _Fragment):
@@ -89,15 +79,15 @@ class Simulator:
                if top_level is None:
                        top_level = TopLevel()
                if sim_runner is None:
-                       sim_runner = icarus.Runner()            
-               self.fragment = fragment + _Fragment(clock_domains=top_level.clock_domains)
+                       sim_runner = icarus.Runner()
                self.top_level = top_level
                self.ipc = Initiator(sockaddr)
                self.sim_runner = sim_runner
                
                c_top = self.top_level.get(sockaddr)
                
-               c_fragment, self.namespace = verilog.convert(self.fragment,
+               fragment = fragment + _Fragment(clock_domains=top_level.clock_domains)
+               c_fragment, self.namespace = verilog.convert(fragment,
                        ios=self.top_level.ios,
                        name=self.top_level.dut_type,
                        return_ns=True,
@@ -110,16 +100,31 @@ class Simulator:
                self.ipc.accept()
                reply = self.ipc.recv()
                assert(isinstance(reply, MessageTick))
+
+               self.sim_functions = fragment.sim
+               self.active_sim_functions = set(f for f in fragment.sim if not hasattr(f, "passive") or not f.passive)
        
        def run(self, ncycles=None):
                counter = 0
-               while self.fragment.sim and (ncycles is None or counter < ncycles):
+               while self.active_sim_functions and (ncycles is None or counter < ncycles):
                        self.cycle_counter += 1
                        counter += 1
                        self.ipc.send(MessageGo())
                        reply = self.ipc.recv()
                        assert(isinstance(reply, MessageTick))
-                       _call_sim(self.fragment, self)
+
+                       del_list = []
+                       for s in self.sim_functions:
+                               try:
+                                       s(self)
+                               except StopSimulation:
+                                       del_list.append(s)
+                       for s in del_list:
+                               self.sim_functions.remove(s)
+                               try:
+                                       self.active_sim_functions.remove(s)
+                               except KeyError:
+                                       pass
 
        def rd(self, item, index=0):
                name = self.top_level.top_name + "." \
index 34b3e141575953f18165fd26ed9691a60b89be4e..b681a4a46f4bae469e70d919f11d66b96b25fe91 100644 (file)
@@ -52,48 +52,58 @@ class Proxy:
                assert(isinstance(item, Signal))
                self.simulator.wr(item, value)
 
-class GenSim:
-       def __init__(self, simg):
-               self.simg = simg
-               self.gens = dict()
-               self.resume_cycle = 0
+def gen_sim(simg):
+       gens = dict()
+       resume_cycle = 0
+
+       def do_simulation(s):
+               nonlocal resume_cycle, gens
 
-       def do_simulation(self, s):
                if isinstance(s, Proxy):
                        simulator = s.simulator
                else:
                        simulator = s
 
-               if simulator.cycle_counter >= self.resume_cycle:
+               if simulator.cycle_counter >= resume_cycle:
                        try:
-                               gen = self.gens[simulator]
+                               gen = gens[simulator]
                        except KeyError:
-                               gen = self.simg(s)
-                               self.gens[simulator] = gen
+                               gen = simg(s)
+                               gens[simulator] = gen
                        try:
                                n = next(gen)
                        except StopIteration:
-                               del self.gens[simulator]
+                               del gens[simulator]
                                raise StopSimulation
                        else:
                                if n is None:
                                        n = 1
-                               self.resume_cycle = simulator.cycle_counter + n
+                               resume_cycle = simulator.cycle_counter + n
+
+       if hasattr(simg, "passive"):
+               do_simulation.passive = simg.passive
+
+       return do_simulation
+
 
-class ProxySim:
-       def __init__(self, target, simf):
-               self.target = target
-               self.simf = simf
-               self.proxies = dict()
+def proxy_sim(target, simf):
+       proxies = dict()
+
+       def do_simulation(simulator):
+               nonlocal proxies
 
-       def do_simulation(self, simulator):
                try:
-                       proxy = self.proxies[simulator]
+                       proxy = proxies[simulator]
                except KeyError:
-                       proxy = Proxy(simulator, self.target)
-                       self.proxies[simulator] = proxy
+                       proxy = Proxy(simulator, target)
+                       proxies[simulator] = proxy
                try:
-                       self.simf(proxy)
+                       simf(proxy)
                except StopSimulation:
-                       del self.proxies[simulator]
+                       del proxies[simulator]
                        raise
+
+       if hasattr(simf, "passive"):
+               do_simulation.passive = simf.passive
+
+       return do_simulation