From 22b3c11b93436d9f15459ce3380aec82776a1053 Mon Sep 17 00:00:00 2001 From: Sebastien Bourdeauducq Date: Tue, 6 Mar 2012 15:00:02 +0100 Subject: [PATCH] sim: clean startup/shutdown --- examples/basic_sim.py | 16 ++++++++++++---- migen/sim/generic.py | 10 +++++----- migen/sim/icarus.py | 4 +++- migen/sim/ipc.py | 2 ++ vpi/ipc.c | 9 ++++++++- vpi/main.c | 22 +++++++++++++--------- 6 files changed, 43 insertions(+), 20 deletions(-) diff --git a/examples/basic_sim.py b/examples/basic_sim.py index 332881d3..55db802c 100644 --- a/examples/basic_sim.py +++ b/examples/basic_sim.py @@ -4,16 +4,24 @@ from migen.sim.icarus import Runner class Counter: def __init__(self): + self.ce = Signal() self.count = Signal(BV(4)) def do_simulation(self, s, cycle): + if cycle % 2: + s.wr(self.ce, 0) + else: + s.wr(self.ce, 1) print("Cycle: " + str(cycle) + " Count: " + str(s.rd(self.count))) def get_fragment(self): - sync = [self.count.eq(self.count + 1)] + sync = [If(self.ce, self.count.eq(self.count + 1))] sim = [self.do_simulation] return Fragment(sync=sync, sim=sim) -dut = Counter() -sim = Simulator(dut.get_fragment(), Runner()) -sim.run(10) +def main(): + dut = Counter() + sim = Simulator(dut.get_fragment(), Runner()) + sim.run(10) + +main() diff --git a/migen/sim/generic.py b/migen/sim/generic.py index 56e82f73..db9978a6 100644 --- a/migen/sim/generic.py +++ b/migen/sim/generic.py @@ -75,19 +75,19 @@ class Simulator: self.sim_runner = sim_runner self.sim_runner.start(c_top, c_fragment) self.ipc.accept() - - self.fragment.call_sim(self, 0) - self.ipc.send(MessageGo()) + reply = self.ipc.recv() + assert(isinstance(reply, MessageTick)) + self.fragment.call_sim(self, -1) def run(self, ncycles=-1): counter = 0 while not self.interrupt and (ncycles < 0 or counter < ncycles): + self.ipc.send(MessageGo()) reply = self.ipc.recv() assert(isinstance(reply, MessageTick)) + self.fragment.call_sim(self, self.cycle_counter) self.cycle_counter += 1 counter += 1 - self.fragment.call_sim(self, self.cycle_counter) - self.ipc.send(MessageGo()) def rd(self, signal): name = self.top_level.top_name + "." \ diff --git a/migen/sim/icarus.py b/migen/sim/icarus.py index 680cacf1..0661c307 100644 --- a/migen/sim/icarus.py +++ b/migen/sim/icarus.py @@ -20,9 +20,11 @@ class Runner: _str2file(self.top_file, c_top) _str2file(self.dut_file, c_dut) subprocess.check_call(["iverilog", "-o", self.vvp_file, self.top_file, self.dut_file] + self.extra_files) - subprocess.Popen(["vvp", "-mmigensim", self.vvp_file]) + self.process = subprocess.Popen(["vvp", "-mmigensim", self.vvp_file]) def __del__(self): + if hasattr(self, "process"): + self.process.wait() if not self.keep_files: for f in [self.top_file, self.dut_file, self.vvp_file]: try: diff --git a/migen/sim/ipc.py b/migen/sim/ipc.py index 0e45af27..9464a12c 100644 --- a/migen/sim/ipc.py +++ b/migen/sim/ipc.py @@ -145,7 +145,9 @@ class Initiator: def __del__(self): if hasattr(self, "conn"): + self.conn.shutdown(socket.SHUT_RDWR) self.conn.close() if hasattr(self, "socket"): + self.socket.shutdown(socket.SHUT_RDWR) self.socket.close() self._cleanup_file() diff --git a/vpi/ipc.c b/vpi/ipc.c index 9b3e5299..c78fd20e 100644 --- a/vpi/ipc.c +++ b/vpi/ipc.c @@ -64,6 +64,11 @@ enum { #define MAX_LEN 2048 +/* + * 0 -> error + * 1 -> success + * 2 -> graceful shutdown + */ int ipc_receive(struct ipc_softc *sc) { char buffer[MAX_LEN]; @@ -71,7 +76,9 @@ int ipc_receive(struct ipc_softc *sc) int i; l = recv(sc->socket, buffer, MAX_LEN, 0); - if((l <= 0) || (l >= MAX_LEN)) + if(l == 0) + return 2; + if((l < 0) || (l >= MAX_LEN)) return 0; i = 0; diff --git a/vpi/main.c b/vpi/main.c index 44fc21ce..0157df1f 100644 --- a/vpi/main.c +++ b/vpi/main.c @@ -105,10 +105,13 @@ static int h_read(char *name, void *user) static int process_until_go(struct migensim_softc *sc) { + int r; + sc->has_go = 0; while(!sc->has_go) { - if(!ipc_receive(sc->ipc)) - return 0; + r = ipc_receive(sc->ipc); + if(r != 1) + return r; } return 1; } @@ -134,25 +137,26 @@ static PLI_INT32 connect_calltf(PLI_BYTE8 *user) return 0; } - if(!process_until_go(sc)) { - vpi_control(vpiFinish, 1); - return 0; - } - return 0; } static PLI_INT32 tick_calltf(PLI_BYTE8 *user) { struct migensim_softc *sc = (struct migensim_softc *)user; + int r; if(!ipc_tick(sc->ipc)) { perror("ipc_tick"); vpi_control(vpiFinish, 1); + ipc_destroy(sc->ipc); + sc->ipc = NULL; return 0; } - if(!process_until_go(sc)) { - vpi_control(vpiFinish, 1); + r = process_until_go(sc); + if(r != 1) { + vpi_control(vpiFinish, r == 2 ? 0 : 1); + ipc_destroy(sc->ipc); + sc->ipc = NULL; return 0; } -- 2.30.2