add ASCII dump of BRAM read/write data and add one-cycle delay on read
authorLuke Kenneth Casson Leighton <lkcl@lkcl.net>
Thu, 30 Dec 2021 22:04:06 +0000 (22:04 +0000)
committerLuke Kenneth Casson Leighton <lkcl@lkcl.net>
Thu, 30 Dec 2021 22:04:06 +0000 (22:04 +0000)
the BRAM outputs its data one cycle late from the read-enable (bram_re)

verilator/microwatt-verilator.cpp

index 89d4ce488c5355f294d34f1df256800341aa1977..4eaed1125cf79958d786a7a897c77cc7b6bea093 100644 (file)
@@ -47,6 +47,18 @@ void tick(Vmicrowatt *top)
 void uart_tx(unsigned char tx);
 unsigned char uart_rx(void);
 
+// pretty-print dumped data in ASCII (to help identify strings)
+static void ascii_dump(unsigned char *data, int len, FILE *dump)
+{
+    for (int i = 0; i < len; i++) {
+        if (isalnum(data[i]))
+            putc(data[i], dump);
+        else
+            putc('.', dump);
+    }
+    putc('\n', dump);
+}
+
 int main(int argc, char **argv)
 {
        Verilated::commandArgs(argc, argv);
@@ -62,6 +74,12 @@ int main(int argc, char **argv)
        tfp->open("microwatt-verilator.vcd");
 #endif
 
+    // dump file for memory read/write traces [uart takes over stdin/stdout]
+    FILE *dump = fopen("bram.dump", "w");
+
+    // read data is one clock cycle delayed
+    bool next_read = false;
+
        // Reset
        top->ext_rst = 0;
        for (unsigned long i = 0; i < 5; i++)
@@ -73,16 +91,24 @@ int main(int argc, char **argv)
 
                uart_tx(top->uart0_txd);
                top->uart0_rxd = uart_rx();
+
         if (top->bram_we) {
-            printf("bram wr addr %x dout %x sel %x\n",
+            fprintf(dump, "bram wr addr %08x dout %16lx sel %x ",
                     top->bram_addr, top->bram_di, top->bram_sel);
+            ascii_dump((unsigned char*)&top->bram_di, 8, dump);
+            fflush(dump);
         }
-        if (top->bram_re) {
-            printf("bram rd addr %x din %x sel %x\n",
+        if (next_read) { // read on one clock delay
+            fprintf(dump, "bram rd addr %08x din %16lx sel %x ",
                     top->bram_addr, top->bram_do, top->bram_sel);
+            ascii_dump((unsigned char*)&top->bram_do, 8, dump);
+            fflush(dump);
         }
+        next_read = top->bram_re;
        }
 
+    fclose(dump);
+
 #if VM_TRACE
        tfp->close();
        delete tfp;