sim: clean startup/shutdown
authorSebastien Bourdeauducq <sebastien@milkymist.org>
Tue, 6 Mar 2012 14:00:02 +0000 (15:00 +0100)
committerSebastien Bourdeauducq <sebastien@milkymist.org>
Tue, 6 Mar 2012 14:00:02 +0000 (15:00 +0100)
examples/basic_sim.py
migen/sim/generic.py
migen/sim/icarus.py
migen/sim/ipc.py
vpi/ipc.c
vpi/main.c

index 332881d3ab43f6acc0e679a27be9ae3ea1ae230a..55db802cd0f720fbd5568cc1333c39b60a11de7b 100644 (file)
@@ -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()
index 56e82f732032fb2eed960457dbf2586b2f1f63ca..db9978a6fc36b4b3a60c10352004b93eb4b2a86a 100644 (file)
@@ -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 + "." \
index 680cacf1a2d6cb6f3304d5108f68faee07ba6245..0661c30714d7f8ab641b3f7dac22ea3e02ac19f4 100644 (file)
@@ -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:
index 0e45af27b07422871a303b338975ab314a663332..9464a12c916f1c9f58ac0d6e841e028eadc3c548 100644 (file)
@@ -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()
index 9b3e5299cf324ff7f94327e1fb2c55ee4741ea93..c78fd20ef485818f4d5be74276c414a78aec99f9 100644 (file)
--- 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;
index 44fc21cea9dc7be4c2b9f2a3a9c4c27591f256c4..0157df1f02b738de4799b0b564c74f5680c7b2f3 100644 (file)
@@ -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;
        }