add save/restore snapshot, seems to work except for UART, sigh,
authorLuke Kenneth Casson Leighton <lkcl@lkcl.net>
Fri, 21 Jan 2022 14:51:58 +0000 (14:51 +0000)
committerLuke Kenneth Casson Leighton <lkcl@lkcl.net>
Fri, 21 Jan 2022 14:51:58 +0000 (14:51 +0000)
which does actually need adding to save/restore

verilator/microwatt-verilator.cpp

index 0b6f6b616b834afaf3d6bb41964b436b1bb61ea5..485b23c8d68622651dcfeb45d6b3f63db34363ec 100644 (file)
@@ -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;