Update Kelvin illegal instruction halt

Change illegal instruction handler to halt the system with user request. Add a KelvinTopTest subtest to check this handler.

PiperOrigin-RevId: 549663012
diff --git a/sim/kelvin_top.cc b/sim/kelvin_top.cc
index 8cdaf64..ffcd3c3 100644
--- a/sim/kelvin_top.cc
+++ b/sim/kelvin_top.cc
@@ -151,7 +151,7 @@
         static_cast<uint64_t>(
             mpact::sim::riscv::ExceptionCode::kIllegalInstruction)) {
       std::cerr << "Illegal instruction at 0x" << std::hex << epc << std::endl;
-      RequestHalt(HaltReason::kSoftwareBreakpoint, nullptr);
+      RequestHalt(HaltReason::kUserRequest, nullptr);
       return true;
     }
     return false;
diff --git a/sim/test/BUILD b/sim/test/BUILD
index c365fd9..f0c8147 100644
--- a/sim/test/BUILD
+++ b/sim/test/BUILD
@@ -5,6 +5,7 @@
     "testfiles/rv32i.elf",
     "testfiles/rv32m.elf",
     "testfiles/rv32soft_fp.elf",
+    "testfiles/rv32uf_fadd.elf",
 ])
 
 cc_test(
@@ -54,6 +55,7 @@
         "testfiles/rv32i.elf",
         "testfiles/rv32m.elf",
         "testfiles/rv32soft_fp.elf",
+        "testfiles/rv32uf_fadd.elf",
     ],
     deps = [
         "//sim:kelvin_top",
diff --git a/sim/test/kelvin_top_test.cc b/sim/test/kelvin_top_test.cc
index 807b6b5..6b218c9 100644
--- a/sim/test/kelvin_top_test.cc
+++ b/sim/test/kelvin_top_test.cc
@@ -28,6 +28,7 @@
 constexpr char kRV32iElfFileName[] = "rv32i.elf";
 constexpr char kRV32mElfFileName[] = "rv32m.elf";
 constexpr char kRV32SoftFloatElfFileName[] = "rv32soft_fp.elf";
+constexpr char kRV32fElfFileName[] = "rv32uf_fadd.elf";
 
 // The depot path to the test directory.
 constexpr char kDepotPath[] = "sim/test/";
@@ -160,6 +161,21 @@
   absl::SetFlag(&FLAGS_use_semihost, false);
 }
 
+// Runs the rv32f program (not supported)
+TEST_F(KelvinTopTest, RunIllegalRV32FProgram) {
+  LoadFile(kRV32fElfFileName);
+  testing::internal::CaptureStderr();
+  EXPECT_OK(kelvin_top_->WriteRegister("pc", entry_point_));
+  EXPECT_OK(kelvin_top_->Run());
+  EXPECT_OK(kelvin_top_->Wait());
+  auto halt_result = kelvin_top_->GetLastHaltReason();
+  CHECK_OK(halt_result);
+  EXPECT_EQ(static_cast<int>(halt_result.value()),
+            static_cast<int>(HaltReason::kUserRequest));
+  const std::string stderr_str = testing::internal::GetCapturedStderr();
+  EXPECT_THAT(stderr_str, testing::HasSubstr("Illegal instruction at 0x"));
+}
+
 // Steps through the program from beginning to end.
 TEST_F(KelvinTopTest, StepProgram) {
   LoadFile(kRV32imfElfFileName);
diff --git a/sim/test/testfiles/rv32uf_fadd.elf b/sim/test/testfiles/rv32uf_fadd.elf
new file mode 100644
index 0000000..5bd93a7
--- /dev/null
+++ b/sim/test/testfiles/rv32uf_fadd.elf
Binary files differ