mirror of
https://github.com/enjoy-digital/litex.git
synced 2025-01-04 09:52:26 -05:00
sim: use Simulator as a contextmanager
__del__ garbage collector callbacks are too delicate. E.g. imported modules can be garbage collected before the objects using them. Can't use os.remove, socket.SHUT_RDWR... * added a DeprecationWarning if a Simulator is garbage collected without having its .close() called * renamed all gc __del__ callbacks to close() * implemented context manager hooks for Simulator. Use like with Simulator(TestBench()) as s: s.run()
This commit is contained in:
parent
cf0fb5350f
commit
55afab2276
3 changed files with 23 additions and 2 deletions
|
@ -1,3 +1,5 @@
|
|||
import warnings
|
||||
|
||||
from migen.fhdl.std import *
|
||||
from migen.fhdl.structure import _Fragment
|
||||
from migen.fhdl import verilog
|
||||
|
@ -177,9 +179,23 @@ class Simulator:
|
|||
self.multiwrite(getattr(obj, k), v)
|
||||
|
||||
def __del__(self):
|
||||
if hasattr(self, "ipc"):
|
||||
warnings.warn("call Simulator.close() to clean up "
|
||||
"or use it as a contextmanager", DeprecationWarning)
|
||||
self.close()
|
||||
|
||||
def close(self):
|
||||
self.ipc.close()
|
||||
self.sim_runner.close()
|
||||
del self.ipc
|
||||
del self.sim_runner
|
||||
|
||||
def __enter__(self):
|
||||
return self
|
||||
|
||||
def __exit__(self, type, value, traceback):
|
||||
self.close()
|
||||
|
||||
# Contrary to multiread/multiwrite, Proxy fetches the necessary signals only and
|
||||
# immediately forwards writes into the simulation.
|
||||
class Proxy:
|
||||
|
|
|
@ -3,6 +3,7 @@
|
|||
|
||||
import subprocess
|
||||
import os
|
||||
import time
|
||||
|
||||
def _str2file(filename, contents):
|
||||
f = open(filename, "w")
|
||||
|
@ -27,8 +28,12 @@ class Runner:
|
|||
subprocess.check_call(["iverilog", "-o", self.vvp_file] + self.options + [self.top_file, self.dut_file] + self.extra_files)
|
||||
self.process = subprocess.Popen(["vvp", "-mmigensim", self.vvp_file])
|
||||
|
||||
def __del__(self):
|
||||
def close(self):
|
||||
if hasattr(self, "process"):
|
||||
self.process.terminate()
|
||||
if self.process.poll() is None:
|
||||
time.sleep(.1)
|
||||
self.process.kill()
|
||||
self.process.wait()
|
||||
if not self.keep_files:
|
||||
for f in [self.top_file, self.dut_file, self.vvp_file]:
|
||||
|
|
|
@ -166,7 +166,7 @@ class Initiator:
|
|||
raise PacketTooLarge
|
||||
return _unpack(packet)
|
||||
|
||||
def __del__(self):
|
||||
def close(self):
|
||||
if hasattr(self, "conn"):
|
||||
self.conn.shutdown(socket.SHUT_RDWR)
|
||||
self.conn.close()
|
||||
|
|
Loading…
Reference in a new issue