From: Luke Kenneth Casson Leighton Date: Fri, 21 Jan 2022 14:51:58 +0000 (+0000) Subject: add save/restore snapshot, seems to work except for UART, sigh, X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=59544cf1648375a968b32b181532adf002cc19b1;p=microwatt.git add save/restore snapshot, seems to work except for UART, sigh, which does actually need adding to save/restore --- diff --git a/verilator/microwatt-verilator.cpp b/verilator/microwatt-verilator.cpp index 0b6f6b6..485b23c 100644 --- a/verilator/microwatt-verilator.cpp +++ b/verilator/microwatt-verilator.cpp @@ -91,17 +91,19 @@ void restore_model(vluint64_t time, Vmicrowatt* topp) } //save bram memory out to a file. use for snapshots -int memdump(unsigned char *mem, size_t sz) +int memdump(vluint64_t time, unsigned char *mem, size_t sz) { char fname[128]; - sprintf(fname, "bram.snapshot.%ld", main_time); + sprintf(fname, "bram.snapshot.%ld", time); int fd = open(fname, O_RDWR | O_CREAT, (mode_t)0600); lseek(fd, sz, SEEK_SET); write(fd, "", 1); void *map = mmap(NULL, sz, PROT_READ|PROT_WRITE, MAP_SHARED, fd, 0); + lseek(fd, sz, SEEK_SET); memcpy(map, mem, sz); msync(map, sz, MS_SYNC); munmap(map, sz); + ftruncate(fd, sz); close(fd); return 0; } @@ -147,6 +149,15 @@ static void mem_write(unsigned char *mem, int main(int argc, char **argv) { Verilated::commandArgs(argc, argv); + // init top verilog instance + Vmicrowatt* top = new Vmicrowatt; +#if VM_TRACE + // init trace dump + Verilated::traceEverOn(true); + tfp = new VerilatedVcdC; + top->trace(tfp, 99); + tfp->open("microwatt-verilator.vcd"); +#endif // allocate a stonking chunk of memory but don't use it yet unsigned char *_mem = NULL; // gets deleted if not required @@ -154,6 +165,7 @@ int main(int argc, char **argv) size_t sz = 0x10000000; _mem = (unsigned char*)malloc(sz); memset(_mem, sz, 0); + vluint64_t restore_time = 0; // identify bram files to load (if not starting "+[verilator]") // here we can specify any number of files, but at present only @@ -163,7 +175,14 @@ int main(int argc, char **argv) // of hassle for (int i = 1; i < argc; i++) { char *bram_file = NULL; - if (argv[i][0] != '+') { + if (strcmp("-s", argv[i]) == 0) { + bram_file = (char*)malloc(128); // okok not freed, i know + restore_time = atol(argv[i+1]); // yees, we knoow, check argc + restore_model(restore_time, top); + sprintf(bram_file, "bram.snapshot.%lld", restore_time); + i++; + } + else if (argv[i][0] != '+') { // assume rest of argument is "+verilator", assume a filename bram_file = argv[i]; } @@ -198,7 +217,7 @@ int main(int argc, char **argv) // copy the file over (bit of a hack, here) mem = _mem; size_t offs = 0x0; // normal start - if (i == 2) { + if (i == 2 && restore_time == 0) { offs = 0x600000; // hard-coded offset of the linux binary } printf("loading %s at 0x%x size 0x%x\n", bram_file, offs, @@ -216,17 +235,6 @@ int main(int argc, char **argv) unsigned long long bram_data1 = 0; // another clock delay int bram_rd = false; - // init top verilog instance - Vmicrowatt* top = new Vmicrowatt; - -#if VM_TRACE - // init trace dump - Verilated::traceEverOn(true); - tfp = new VerilatedVcdC; - top->trace(tfp, 99); - tfp->open("microwatt-verilator.vcd"); -#endif - // dump file for memory read/write traces [uart takes over stdin/stdout] FILE *dump = fopen("bram.dump", "w"); @@ -234,11 +242,15 @@ int main(int argc, char **argv) bool next_read = false; unsigned long bram_addr = 0; - // Reset - top->ext_rst = 0; - for (unsigned long i = 0; i < 5; i++) - tick(top, true); - top->ext_rst = 1; + if (restore_time == 0) { + // Reset + top->ext_rst = 0; + for (unsigned long i = 0; i < 5; i++) + tick(top, true); + top->ext_rst = 1; + } else { + printf("restored at %lld\n", main_time); + } unsigned long long bram_do = 0; @@ -258,6 +270,9 @@ int main(int argc, char **argv) fprintf(dump, "snapshot saving at %ld\n", main_time); fflush(dump); save_model(main_time, top); + if (mem != NULL) { + memdump(main_time, mem, sz); + } save_countdown = save_offset; // loop for next snapshot } else { --save_countdown;