mirror of
https://github.com/enjoy-digital/litex.git
synced 2025-01-04 09:52:26 -05:00
sim: clean startup/shutdown
This commit is contained in:
parent
06de17b16c
commit
22b3c11b93
6 changed files with 43 additions and 20 deletions
|
@ -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)
|
||||
|
||||
def main():
|
||||
dut = Counter()
|
||||
sim = Simulator(dut.get_fragment(), Runner())
|
||||
sim.run(10)
|
||||
|
||||
main()
|
||||
|
|
|
@ -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 + "." \
|
||||
|
|
|
@ -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:
|
||||
|
|
|
@ -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()
|
||||
|
|
|
@ -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;
|
||||
|
|
22
vpi/main.c
22
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;
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in a new issue