Internal change PiperOrigin-RevId: 550427286
diff --git a/sim/kelvin_encoding.cc b/sim/kelvin_encoding.cc index 9bd3987..a92b6c3 100644 --- a/sim/kelvin_encoding.cc +++ b/sim/kelvin_encoding.cc
@@ -202,6 +202,9 @@ return new mpact::sim::generic::IntLiteralOperand<0>( {1}, xreg_alias_[0]); } + // `vs1` is stored in bit[19:14], but scalar xs1 is in bit[19:15] + // (same as the regular riscv32 encoding) + reg_num >>= 1; return GetRegisterSourceOp<mpact::sim::riscv::RV32Register>( state_, absl::StrCat(mpact::sim::riscv::RiscVState::kXregPrefix, reg_num), @@ -222,6 +225,9 @@ return new mpact::sim::generic::IntLiteralOperand<0>( {1}, xreg_alias_[0]); } + // `vs2` is stored in bit[26:20], but scalar xs2 is in bit[25:20] + // (same as in the regular riscv32 encoding) + reg_num = reg_num & 0x1F; return GetRegisterSourceOp<mpact::sim::riscv::RV32Register>( state_, absl::StrCat(mpact::sim::riscv::RiscVState::kXregPrefix, reg_num), @@ -230,6 +236,17 @@ return GetVectorRegisterSourceOp<mpact::sim::riscv::RVVectorRegister>( state_, reg_num, strip_mine, 1 /* widen_factor */); }); + source_op_getters_.emplace( + // vst and vstq use `vd` field as the source for the vector store. + static_cast<int>(SourceOpEnum::kVd), + [this]() -> SourceOperandInterface * { + auto reg_num = encoding::kelvin_v2_args_type::ExtractVd(inst_word_); + bool strip_mine = encoding::kelvin_v2_args_type::ExtractM(inst_word_); + if (opcode_ < OpcodeEnum::kVstBLXx || opcode_ > OpcodeEnum::kVstqWSpXxM) + return nullptr; + return GetVectorRegisterSourceOp<mpact::sim::riscv::RVVectorRegister>( + state_, reg_num, strip_mine, 1 /* widen_factor */); + }); source_op_getters_.insert(std::make_pair( static_cast<int>(SourceOpEnum::kNone), []() { return nullptr; })); }
diff --git a/sim/test/BUILD b/sim/test/BUILD index f0c8147..7cf1e1d 100644 --- a/sim/test/BUILD +++ b/sim/test/BUILD
@@ -2,6 +2,7 @@ exports_files([ "testfiles/hello_world_rv32imf.elf", + "testfiles/kelvin_vldvst.elf", "testfiles/rv32i.elf", "testfiles/rv32m.elf", "testfiles/rv32soft_fp.elf", @@ -52,6 +53,7 @@ data = [ "testfiles/hello_world_mpause.elf", "testfiles/hello_world_rv32imf.elf", + "testfiles/kelvin_vldvst.elf", "testfiles/rv32i.elf", "testfiles/rv32m.elf", "testfiles/rv32soft_fp.elf",
diff --git a/sim/test/kelvin_top_test.cc b/sim/test/kelvin_top_test.cc index 6b218c9..28e4b8b 100644 --- a/sim/test/kelvin_top_test.cc +++ b/sim/test/kelvin_top_test.cc
@@ -29,6 +29,7 @@ constexpr char kRV32mElfFileName[] = "rv32m.elf"; constexpr char kRV32SoftFloatElfFileName[] = "rv32soft_fp.elf"; constexpr char kRV32fElfFileName[] = "rv32uf_fadd.elf"; +constexpr char kKelvinVldVstFileName[] = "kelvin_vldvst.elf"; // The depot path to the test directory. constexpr char kDepotPath[] = "sim/test/"; @@ -329,4 +330,18 @@ } } +TEST_F(KelvinTopTest, RunKelvinVectorProgram) { + LoadFile(kKelvinVldVstFileName); + testing::internal::CaptureStdout(); + 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 stdout_str = testing::internal::GetCapturedStdout(); + EXPECT_THAT(stdout_str, testing::HasSubstr("vld_vst test passed!")); +} + } // namespace
diff --git a/sim/test/testfiles/kelvin_vldvst.elf b/sim/test/testfiles/kelvin_vldvst.elf new file mode 100755 index 0000000..34916db --- /dev/null +++ b/sim/test/testfiles/kelvin_vldvst.elf Binary files differ