Add 'passive' simulation functions that are not taken into account while determining when to stop the simulator
This commit is contained in:
parent
63c1d7e4b7
commit
90f0dfad63
|
@ -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
|
||||
|
|
|
@ -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):
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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 + "." \
|
||||
|
|
|
@ -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
|
||||
|
||||
class ProxySim:
|
||||
def __init__(self, target, simf):
|
||||
self.target = target
|
||||
self.simf = simf
|
||||
self.proxies = dict()
|
||||
if hasattr(simg, "passive"):
|
||||
do_simulation.passive = simg.passive
|
||||
|
||||
return do_simulation
|
||||
|
||||
|
||||
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
|
||||
|
|
Loading…
Reference in New Issue