}
//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;
}
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
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
// 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];
}
// 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,
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");
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;
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;