Add 'passive' simulation functions that are not taken into account while determining when to stop the simulator

This commit is contained in:
Sebastien Bourdeauducq 2014-01-27 23:58:46 +01:00
parent 63c1d7e4b7
commit 90f0dfad63
5 changed files with 60 additions and 43 deletions

View 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

View 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):

View 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

View 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):
@ -90,14 +80,14 @@ class Simulator:
top_level = TopLevel()
if sim_runner is None:
sim_runner = icarus.Runner()
self.fragment = fragment + _Fragment(clock_domains=top_level.clock_domains)
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,
@ -111,15 +101,30 @@ class Simulator:
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 + "." \

View 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
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