// Read events from standard in. Step each emulator thread in lockstep // and ensure the side effects match. int runCosimulation(Core *core, bool verbose) { char line[1024]; uint32_t threadId; uint32_t address; uint32_t pc; uint64_t writeMask; uint32_t vectorValues[NUM_VECTOR_LANES]; char valueStr[256]; uint32_t reg; uint32_t scalarValue; bool verilogModelHalted = false; unsigned long len; enableCosimulation(core); if (verbose) enableTracing(core); while (fgets(line, sizeof(line), stdin)) { if (verbose) printf("%s", line); len = strlen(line); if (len > 0) line[len - 1] = '\0'; // Strip off newline if (sscanf(line, "store %x %x %x %" PRIx64 " %s", &pc, &threadId, &address, &writeMask, valueStr) == 5) { // Memory Store if (parseHexVector(valueStr, vectorValues, true) < 0) return 0; cosimCheckEvent = EVENT_MEM_STORE; cosimCheckPc = pc; cosimCheckThread = threadId; cosimCheckAddress = address; cosimCheckMask = writeMask; memcpy(cosimCheckValues, vectorValues, sizeof(uint32_t) * NUM_VECTOR_LANES); if (!cosimStep(core, threadId)) return -1; } else if (sscanf(line, "vwriteback %x %x %x %" PRIx64 " %s", &pc, &threadId, ®, &writeMask, valueStr) == 5) { // Vector writeback if (parseHexVector(valueStr, vectorValues, false) < 0) { printf("test failed\n"); return 0; } cosimCheckEvent = EVENT_VECTOR_WRITEBACK; cosimCheckPc = pc; cosimCheckThread = threadId; cosimCheckRegister = reg; cosimCheckMask = writeMask; memcpy(cosimCheckValues, vectorValues, sizeof(uint32_t) * NUM_VECTOR_LANES); if (!cosimStep(core, threadId)) return -1; } else if (sscanf(line, "swriteback %x %x %x %x", &pc, &threadId, ®, &scalarValue) == 4) { // Scalar Writeback cosimCheckEvent = EVENT_SCALAR_WRITEBACK; cosimCheckPc = pc; cosimCheckThread = threadId; cosimCheckRegister = reg; cosimCheckValues[0] = scalarValue; if (!cosimStep(core, threadId)) return -1; } else if (strcmp(line, "***HALTED***") == 0) { verilogModelHalted = true; break; } else if (sscanf(line, "interrupt %d %x", &threadId, &pc) == 2) cosimInterrupt(core, threadId, pc); else if (!verbose) printf("%s\n", line); // Echo unrecognized lines to stdout (verbose already does this for all lines) } if (!verilogModelHalted) { printf("program did not finish normally\n"); printf("%s\n", line); // Print error (if any) return -1; } // Ensure emulator is also halted. If it executes any more instructions // cosimError will be flagged. cosimEventTriggered = false; cosimCheckEvent = EVENT_NONE; while (!coreHalted(core)) { executeInstructions(core, ALL_THREADS, 1); if (cosimError) return -1; } return 0; }
// Read events from standard in. Step each emulator thread in lockstep // and ensure the side effects match. // Returns 1 if successful, 0 if there was an error int runCosimulation(Core *core, int verbose) { char line[1024]; int threadId; uint32_t address; uint32_t pc; uint64_t writeMask; uint32_t vectorValues[16]; char valueStr[256]; int reg; uint32_t scalarValue; int verilogModelHalted = 0; int len; enableCosimulation(core, 1); if (verbose) enableTracing(core); while (fgets(line, sizeof(line), stdin)) { if (verbose) printf("%s", line); len = strlen(line); if (len > 0) line[len - 1] = '\0'; // Strip off newline if (sscanf(line, "store %x %x %x %llx %s", &pc, &threadId, &address, &writeMask, valueStr) == 5) { // Memory Store if (!parseHexVector(valueStr, vectorValues, 1)) return 0; cosimCheckEvent = kEventMemStore; cosimCheckPc = pc; cosimCheckThread = threadId; cosimCheckAddress = address; cosimCheckMask = writeMask; memcpy(cosimCheckValues, vectorValues, sizeof(uint32_t) * 16); if (!cosimStep(core, threadId)) return 0; } else if (sscanf(line, "vwriteback %x %x %x %llx %s", &pc, &threadId, ®, &writeMask, valueStr) == 5) { // Vector writeback if (!parseHexVector(valueStr, vectorValues, 0)) { printf("test failed\n"); return 0; } cosimCheckEvent = kEventVectorWriteback; cosimCheckPc = pc; cosimCheckThread = threadId; cosimCheckRegister = reg; cosimCheckMask = writeMask; memcpy(cosimCheckValues, vectorValues, sizeof(uint32_t) * 16); if (!cosimStep(core, threadId)) return 0; } else if (sscanf(line, "swriteback %x %x %x %x", &pc, &threadId, ®, &scalarValue) == 4) { // Scalar Writeback cosimCheckEvent = kEventScalarWriteback; cosimCheckPc = pc; cosimCheckThread = threadId; cosimCheckRegister = reg; cosimCheckValues[0] = scalarValue; if (!cosimStep(core, threadId)) return 0; } else if (strcmp(line, "***HALTED***") == 0) { // Note: we don't check that the reference model is actually verilogModelHalted verilogModelHalted = 1; break; } else if (sscanf(line, "interrupt %d %x", &threadId, &pc) == 2) cosimInterrupt(core, threadId, pc); else if (!verbose) printf("%s\n", line); // Echo unrecognized lines to stdout (verbose already does this for all lines) } if (!verilogModelHalted) { printf("program did not finish normally\n"); printf("%s\n", line); // Print error (if any) return 0; } // Ensure emulator is also halted. If it executes any more instructions // cosimError will be flagged. cosimEventTriggered = 0; cosimCheckEvent = kEventNone; while (!coreHalted(core)) { executeInstructions(core, -1, 1); if (cosimError) return 0; } return 1; }