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):
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
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):
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):
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
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
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):
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,
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 + "." \
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