sim: clean startup/shutdown

This commit is contained in:
Sebastien Bourdeauducq 2012-03-06 15:00:02 +01:00
parent 06de17b16c
commit 22b3c11b93
6 changed files with 43 additions and 20 deletions

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

View 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 + "." \

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

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

View file

@ -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;

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