summaryrefslogtreecommitdiff
path: root/nandgame/Vcomputer__main.cpp
diff options
context:
space:
mode:
authoruvok2026-01-07 18:18:42 +0100
committeruvok2026-01-07 18:19:22 +0100
commite377f94c08b6305cd6114b3274e04f73a73829b4 (patch)
tree1c2e3e302908488660c8e05b77e8676df68e2395 /nandgame/Vcomputer__main.cpp
parentcab2f8fa41a13d73ed001be31e9ef17187b43a01 (diff)
add computer launcher
Diffstat (limited to 'nandgame/Vcomputer__main.cpp')
-rw-r--r--nandgame/Vcomputer__main.cpp116
1 files changed, 116 insertions, 0 deletions
diff --git a/nandgame/Vcomputer__main.cpp b/nandgame/Vcomputer__main.cpp
new file mode 100644
index 0000000..101d2fa
--- /dev/null
+++ b/nandgame/Vcomputer__main.cpp
@@ -0,0 +1,116 @@
+// Verilated -*- C++ -*-
+// DESCRIPTION: Verilator output: main() simulation loop, created with --main
+
+// Edited and completed to view contents.
+#include "Vcomputer___024root.h"
+#include "Vcomputer_computer.h"
+#include "Vcomputer_my_mem__D10_DB10000.h"
+#include "verilated.h"
+#include "Vcomputer.h"
+#include <cinttypes>
+#include <cstdint>
+#include <cstdio>
+#include <sched.h>
+
+//======================
+
+int main(int argc, char** argv, char**) {
+ // Setup context, defaults, and parse command line
+ Verilated::debug(0);
+ const std::unique_ptr<VerilatedContext> contextp{new VerilatedContext};
+ contextp->threads(1);
+ contextp->commandArgs(argc, argv);
+
+ // Construct the Verilated model, from Vtop.h generated from Verilating
+ const std::unique_ptr<Vcomputer> topp{new Vcomputer{contextp.get(), ""}};
+
+ if (argc != 2) {
+ fprintf(stderr, "Usage: %.20s [filename]\n\n", argv[0]);
+ exit(-1);
+ }
+ int i = 0;
+ puts("Start simulation.");
+ //topp->computer->clk_in = 0;
+ topp->clk_in = 0;
+ FILE* f = fopen(argv[1], "rb");
+ if (!f) {
+ fprintf(stderr, "Program file %.20s not found.\n", argv[1]);
+ exit(-1);
+ }
+ fseek(f, 0, SEEK_END);
+ long fpos = ftell(f);
+ fseek(f, 0, SEEK_SET);
+ size_t bytes_read = fread(
+ topp->computer->ROM->r_datastore.m_storage,
+ 2,
+ fpos/2,
+ f
+ );
+
+ if (bytes_read * 2 != fpos) {
+ fputs("Couldn't read program file completely.", stderr);
+ exit(-1);
+ }
+
+ while (VL_LIKELY(!contextp->gotFinish()) && i < 100) {
+ //topp->computer->clk_in = ~topp->computer->clk_in;
+ topp->clk_in = !topp->clk_in;
+ //uint16_t opcode = (topp->computer->PC_content_int & 0xff) << 8 | (topp->computer->PC_content_int >> 8);
+ uint16_t opcode = topp->computer->PC_content_int;
+ printf(
+ "CLK1: %4d, CLK2: %4d, PC: @0x%04X, INS: 0x%04X\n",
+ topp->clk_in,
+ topp->computer->clk_in,
+ topp->computer->PC_addr_int,
+ opcode
+ );
+ // This is fucking dirty
+ {
+ char command[128];
+ snprintf(command, sizeof(command) - 1, "python3 ../assembler/disas_ins.py %04X", opcode);
+ char buffer[256];
+ FILE* pipe = popen(command, "r");
+ if (!pipe) {
+ perror("popen failed");
+ exit(-1);
+ }
+
+ if (fgets(buffer, sizeof(buffer), pipe) != NULL) {
+ printf("%s", buffer);
+ }
+
+ (void) pclose(pipe);
+ }
+
+ printf(
+ " A: 0x%04X, D: 0x%04X, M: 0x%04X\n",
+ topp->computer->reg_A_int,
+ topp->computer->reg_D_int,
+ topp->computer->reg_pA_int
+ );
+ printf(
+ " A: %5" PRId16 ", D: %5" PRId16 ", M: %5" PRId16 "\n",
+ topp->computer->reg_A_int,
+ topp->computer->reg_D_int,
+ topp->computer->reg_pA_int
+ );
+ // Evaluate model
+ topp->eval();
+ // Advance time
+ contextp->timeInc(1);
+ i++;
+ }
+ puts("Simulation finished");
+
+ if (VL_LIKELY(!contextp->gotFinish())) {
+ VL_DEBUG_IF(VL_PRINTF("+ Exiting without $finish; no events left\n"););
+ }
+
+ // Execute 'final' processes
+ topp->final();
+
+ // Print statistical summary report
+ //contextp->statsPrintSummary();
+
+ return 0;
+}