diff options
| author | uvok | 2026-01-07 18:18:42 +0100 |
|---|---|---|
| committer | uvok | 2026-01-07 18:19:22 +0100 |
| commit | e377f94c08b6305cd6114b3274e04f73a73829b4 (patch) | |
| tree | 1c2e3e302908488660c8e05b77e8676df68e2395 /nandgame/Vcomputer__main.cpp | |
| parent | cab2f8fa41a13d73ed001be31e9ef17187b43a01 (diff) | |
add computer launcher
Diffstat (limited to 'nandgame/Vcomputer__main.cpp')
| -rw-r--r-- | nandgame/Vcomputer__main.cpp | 116 |
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; +} |
