diff --git a/riscv/BUILD b/riscv/BUILD
index fd00819..5167147 100644
--- a/riscv/BUILD
+++ b/riscv/BUILD
@@ -1208,6 +1208,27 @@
     ],
 )
 
+cc_library(
+    name = "riscv_plic",
+    srcs = [
+        "riscv_plic.cc",
+    ],
+    hdrs = [
+        "riscv_plic.h",
+    ],
+    deps = [
+        "@com_google_absl//absl/container:btree",
+        "@com_google_absl//absl/log",
+        "@com_google_absl//absl/numeric:bits",
+        "@com_google_absl//absl/status",
+        "@com_google_absl//absl/strings",
+        "@com_google_mpact-sim//mpact/sim/generic:core",
+        "@com_google_mpact-sim//mpact/sim/generic:instruction",
+        "@com_google_mpact-sim//mpact/sim/util/memory",
+        "@com_googlesource_code_re2//:re2",
+    ],
+)
+
 cc_binary(
     name = "rv32g_test_sim",
     srcs = [
diff --git a/riscv/riscv_clint.h b/riscv/riscv_clint.h
index 468b8e6..9226c0b 100644
--- a/riscv/riscv_clint.h
+++ b/riscv/riscv_clint.h
@@ -18,6 +18,7 @@
 #include <cstdint>
 
 #include "mpact/sim/generic/counters.h"
+#include "mpact/sim/generic/counters_base.h"
 #include "mpact/sim/generic/data_buffer.h"
 #include "mpact/sim/generic/instruction.h"
 #include "mpact/sim/generic/ref_count.h"
@@ -117,4 +118,4 @@
 }  // namespace sim
 }  // namespace mpact
 
-#endif  // THIRD_PARTY_MPACT_RISCV_RISCV_CLINT_H_
\ No newline at end of file
+#endif  // THIRD_PARTY_MPACT_RISCV_RISCV_CLINT_H_
diff --git a/riscv/riscv_plic.cc b/riscv/riscv_plic.cc
new file mode 100644
index 0000000..10fb89c
--- /dev/null
+++ b/riscv/riscv_plic.cc
@@ -0,0 +1,587 @@
+// Copyright 2024 Google LLC
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+#include "riscv/riscv_plic.h"
+
+#include <cstdint>
+#include <cstring>
+
+#include "absl/log/log.h"
+#include "absl/numeric/bits.h"
+#include "absl/status/status.h"
+#include "absl/strings/str_cat.h"
+#include "absl/strings/string_view.h"
+#include "re2/re2.h"
+
+namespace mpact {
+namespace sim {
+namespace riscv {
+
+RiscVPlic::RiscVPlic(int num_sources, int num_contexts)
+    : num_sources_(num_sources), num_contexts_(num_contexts) {
+  // Initialize the gateway info.
+  gateway_info_ = new GatewayInfo[num_sources_];
+  // Initialize the context interface.
+  context_if_ = new RiscVPlicIrqInterface *[num_contexts_];
+  context_irq_ = new bool[num_contexts_];
+  for (int i = 0; i < num_contexts_; ++i) {
+    context_if_[i] = nullptr;
+    context_irq_[i] = false;
+  }
+  // Initialize the interrupt priority.
+  interrupt_priority_ = new uint32_t[num_sources_];
+  std::memset(interrupt_priority_, 0, sizeof(uint32_t) * num_sources_);
+  // Initialize the interrupt pending bits.
+  interrupt_pending_ = new uint32_t[num_sources_ / 32 + 1];
+  std::memset(interrupt_pending_, 0,
+              sizeof(uint32_t) * (num_sources_ / 32 + 1));
+  // Initialize the interrupt enabled bits.
+  interrupt_enabled_ = new uint32_t *[num_contexts_];
+  for (int i = 0; i < num_contexts_; ++i) {
+    interrupt_enabled_[i] = new uint32_t[num_sources_ / 32 + 1];
+    std::memset(interrupt_enabled_[i], 0,
+                sizeof(uint32_t) * (num_sources_ / 32 + 1));
+  }
+  // Initialize the priority threshold.
+  priority_threshold_ = new uint32_t[num_contexts_];
+  std::memset(priority_threshold_, 0, sizeof(uint32_t) * num_contexts_);
+  // Initialize the interrupt claim/complete bits.
+  interrupt_claim_complete_ = new uint32_t[num_contexts_];
+  std::memset(interrupt_claim_complete_, 0, sizeof(uint32_t) * num_contexts_);
+}
+
+RiscVPlic::~RiscVPlic() {
+  // Clean up all the allocated memory.
+  delete[] gateway_info_;
+  gateway_info_ = nullptr;
+  delete[] context_if_;
+  context_if_ = nullptr;
+  delete[] context_irq_;
+  context_irq_ = nullptr;
+  delete[] interrupt_priority_;
+  interrupt_priority_ = nullptr;
+  delete[] interrupt_pending_;
+  interrupt_pending_ = nullptr;
+  for (int i = 0; i < num_contexts_; ++i) {
+    delete[] interrupt_enabled_[i];
+  }
+  delete[] interrupt_enabled_;
+  interrupt_enabled_ = nullptr;
+  delete[] priority_threshold_;
+  priority_threshold_ = nullptr;
+  delete[] interrupt_claim_complete_;
+  interrupt_claim_complete_ = nullptr;
+}
+
+absl::Status RiscVPlic::Configure(absl::string_view source_cfg,
+                                  absl::string_view context_cfg) {
+  // List of "<source>=<priority>;" items.
+  RE2 re_source("^(\\d+)\\s*=\\s*(\\d+)\\s*(;|$)");
+  int source;
+  int priority;
+  absl::string_view cfg = source_cfg;
+  while (RE2::Consume(&cfg, re_source, &source, &priority)) {
+    if (source >= num_sources_) {
+      return absl::InvalidArgumentError(
+          absl::StrCat("Invalid source number: ", source));
+    }
+    interrupt_priority_[source] = priority;
+  }
+  if (!cfg.empty()) {
+    return absl::InvalidArgumentError(
+        absl::StrCat("Invalid source configuration: ", cfg));
+  }
+  // List of "<context>=<source>,<threshold>,<enable>;" items.
+  RE2 re_context("^(\\d+)\\s*=\\s*(\\d+)\\s*,\\s*");
+  RE2 re_context_source("(\\d+)\\s*,\\s*(\\d)\\s*(,|;)\\s*");
+  int context;
+  int threshold;
+  int enable;
+  char terminator;
+  cfg = context_cfg;
+  while (RE2::Consume(&cfg, re_context, &context, &threshold)) {
+    if (context >= num_contexts_) {
+      return absl::InvalidArgumentError(
+          absl::StrCat("Invalid context number: ", context));
+    }
+    priority_threshold_[context] = threshold;
+    while (
+        RE2::Consume(&cfg, re_context_source, &source, &enable, &terminator)) {
+      if (source >= num_sources_) {
+        return absl::InvalidArgumentError(
+            absl::StrCat("Invalid source number: ", source));
+      }
+      source_to_context_.insert({source, context});
+      context_to_source_.insert({context, source});
+      int bit = source & 0x1f;
+      int word = source / 32;
+      uint32_t mask = ~(1 << bit);
+      uint32_t value = interrupt_enabled_[context][word];
+      value = (value & mask) | (enable << bit);
+      interrupt_enabled_[context][word] = value;
+      if (terminator == ';') break;
+    }
+  }
+  if (!cfg.empty()) {
+    return absl::InvalidArgumentError(
+        absl::StrCat("Invalid context configuration: ", cfg));
+  }
+  return absl::OkStatus();
+}
+
+void RiscVPlic::SetInterrupt(int source, bool value, bool is_level) {
+  // Make sure the source is in range.
+  if ((source < 0) || (source >= num_sources_)) {
+    LOG(WARNING) << "Invalid interrupt source: " << source;
+    return;
+  }
+  // No action for clearing a non-level based interrupt.
+  if (!value && !is_level) return;
+
+  auto &info = gateway_info_[source];
+  if (!info.ready || !value) {
+    if (is_level) info.pending = value;
+    return;
+  }
+
+  // If it is level based, latch the pending bit in the gateway.
+  if (is_level) info.pending = true;
+
+  // If the priority is 0, the interrupt is disabled.
+  if (interrupt_priority_[source] == 0) return;
+
+  // Accept the request, set ready to false to prevent any other requests
+  // until this has been processed.
+  info.ready = false;
+  // Set the plic pending bit.
+  SetPlicPendingInterrupt(source);
+}
+
+void RiscVPlic::SetPlicPendingInterrupt(int source) {
+  if ((source <= 0) || (source >= num_sources_)) {
+    LOG(ERROR) << "Invalid interrupt source: " << source;
+    return;
+  }
+  // Return if source is already pending.
+  if (IsPending(source)) return;
+  // Get interrupt priority.
+  auto priority = interrupt_priority_[source];
+  // Return if source has priority 0.
+  if (priority == 0) return;
+  // Set source to pending.
+  SetPending(source, true);
+  // Iterate over all contexts that have this source enabled.
+  auto [begin, end] = source_to_context_.equal_range(source);
+  for (auto it = begin; it != end; ++it) {
+    auto context = it->second;
+    // If the priority is less or equal to the threshold, do not trigger the
+    // interrupt.
+    if (priority <= priority_threshold_[context]) continue;
+    if (context_if_[context] == nullptr) continue;
+    // Trigger the interrupt.
+    context_if_[context]->SetIrq(true);
+    context_irq_[context] = true;
+  }
+}
+
+// Implementation of the memory load interface for reading memory mapped
+// registers.
+void RiscVPlic::Load(uint64_t address, DataBuffer *db, Instruction *inst,
+                     ReferenceCount *context) {
+  uint32_t offset = address & 0xff'ffff;
+  switch (db->size<uint8_t>()) {
+    case 1:
+      db->Set<uint8_t>(0, static_cast<uint8_t>(Read(offset)));
+      break;
+    case 2:
+      db->Set<uint16_t>(0, static_cast<uint16_t>(Read(offset)));
+      break;
+    case 4:
+      db->Set<uint32_t>(0, static_cast<uint32_t>(Read(offset)));
+      break;
+    case 8:
+      db->Set<uint32_t>(0, static_cast<uint32_t>(Read(offset)));
+      db->Set<uint32_t>(1, static_cast<uint32_t>(Read(offset + 4)));
+      break;
+    default:
+      ::memset(db->raw_ptr(), 0, sizeof(db->size<uint8_t>()));
+      break;
+  }
+  // Execute the instruction to process and write back the load data.
+  if (nullptr != inst) {
+    if (db->latency() > 0) {
+      inst->IncRef();
+      if (context != nullptr) context->IncRef();
+      inst->state()->function_delay_line()->Add(db->latency(),
+                                                [inst, context]() {
+                                                  inst->Execute(context);
+                                                  if (context != nullptr)
+                                                    context->DecRef();
+                                                  inst->DecRef();
+                                                });
+    } else {
+      inst->Execute(context);
+    }
+  }
+}
+
+// No support for vector loads.
+void RiscVPlic::Load(DataBuffer *address_db, DataBuffer *mask_db, int el_size,
+                     DataBuffer *db, Instruction *inst,
+                     ReferenceCount *context) {
+  LOG(FATAL) << "RiscVPlic does not support vector loads";
+}
+
+// Implementation of memory store interface to support writes to memory mapped
+// registers.
+void RiscVPlic::Store(uint64_t address, DataBuffer *db) {
+  uint32_t offset = address & 0xff'ffff;
+  switch (db->size<uint8_t>()) {
+    case 1:
+      return Write(offset, static_cast<uint32_t>(db->Get<uint8_t>(0)));
+    case 2:
+      return Write(offset, static_cast<uint32_t>(db->Get<uint16_t>(0)));
+    case 4:
+      return Write(offset, static_cast<uint32_t>(db->Get<uint32_t>(0)));
+    case 8:
+      return Write(offset, static_cast<uint32_t>(db->Get<uint32_t>(0)));
+      return Write(offset + 4, static_cast<uint32_t>(db->Get<uint32_t>(1)));
+    default:
+      return;
+  }
+}
+
+void RiscVPlic::SetContext(int context_no, RiscVPlicIrqInterface *context_if) {
+  context_if_[context_no] = context_if;
+}
+
+// No support for vector stores.
+void RiscVPlic::Store(DataBuffer *address, DataBuffer *mask, int el_size,
+                      DataBuffer *db) {
+  LOG(FATAL) << "RiscVPlic does not support vector stores";
+}
+
+uint32_t RiscVPlic::Read(uint32_t offset) {
+  uint32_t value = 0;
+  // Interrupt priority bit by source.
+  if (offset < 0x00'1000) {
+    value = interrupt_priority_[offset >> 2];
+    return value;
+  }
+
+  // Interrupt pending bits by source/
+  if (offset < 0x00'2000) {
+    offset -= 0x00'1000;
+    if (offset > (num_sources_ / 32)) {
+      LOG(WARNING) << "Invalid offset: " << offset;
+      return 0;
+    }
+    value = interrupt_pending_[offset];
+    return value;
+  }
+
+  // Interrupt enable bits for sources by context.
+  if (offset < 0x20'0000) {
+    offset -= 0x00'2000;
+    int context = offset >> 7;
+    // Get the context id.
+    if (context >= num_contexts_) {
+      LOG(ERROR) << "Invalid context number: " << context;
+      return 0;
+    }
+    // Get the word index in the source dimension.
+    int word = offset & 0x7f;
+    if (word * 32 >= num_sources_ + 32) {
+      LOG(ERROR) << "Invalid source number";
+      return 0;
+    }
+    value = interrupt_enabled_[context][word];
+    return value;
+  }
+
+  // Interrupt priority threshold and claim/complete.
+  // Get context id.
+  offset -= 0x20'0000;
+  int context = offset >> 12;
+  if (context >= num_contexts_) {
+    LOG(ERROR) << "Invalid context number: " << context;
+    return 0;
+  }
+  auto reg_id = offset & 0xfff;
+  switch (reg_id) {
+    case 0x0:
+      // Priority threshold.
+      value = priority_threshold_[context];
+      return value;
+    case 0x4:
+      // Claim/complete interrupt.
+      value = ClaimInterrupt(context);
+      return value;
+    default:
+      LOG(ERROR) << "Invalid offset: " << offset;
+      break;
+  }
+  return value;
+}
+
+void RiscVPlic::Write(uint32_t offset, uint32_t value) {
+  // Interrupt priority bit by source.
+  if (offset < 0x00'1000) {
+    int source = offset >> 3;
+    if (source >= num_sources_) {
+      LOG(ERROR) << "Invalid source number: " << source;
+      return;
+    }
+    uint32_t prev = interrupt_priority_[source];
+    interrupt_priority_[source] = value;
+    // If the priority is being changed from 0 to non-zero, see if there is a
+    // pending level based interrupt, and if so, set the plic pending bit.
+    if (prev == 0 && value != 0) {
+      auto &info = gateway_info_[source];
+      if (info.ready && info.pending) {
+        SetPlicPendingInterrupt(source);
+      }
+    }
+    return;
+  }
+
+  // Interrupt pending bits.
+  if (offset < 0x00'2000) {
+    offset -= 0x00'1000;
+    if (offset > (num_sources_ / 32)) {
+      LOG(WARNING) << "Invalid offset: " << offset;
+      return;
+    }
+    uint32_t prev = interrupt_pending_[offset];
+    interrupt_pending_[offset] = value;
+    // Determine which bits are being set.
+    uint32_t bits_set = (value ^ prev) & value;
+    // Trigger interrupts for any of the newly set pending bits.
+    while (bits_set != 0) {
+      int bit = absl::countr_zero(bits_set);
+      int source = offset * 32 + bit;
+      bits_set &= ~(1 << bit);
+      auto [begin, end] = source_to_context_.equal_range(source);
+      for (auto it = begin; it != end; ++it) {
+        auto context = it->second;
+        // If the context IRQ line is not already set, see if the priority is
+        // above the threshold, and if so, set the IRQ line.
+        if (!context_irq_[context]) {
+          // If the priority is less or equal to the threshold, do not trigger
+          // the interrupt.
+          if (interrupt_priority_[source] <= priority_threshold_[context])
+            continue;
+          if (context_if_[context] == nullptr) {
+            LOG(ERROR) << "No context interface for context " << context;
+            continue;
+          }
+          // Trigger the interrupt.
+          context_if_[context]->SetIrq(true);
+          context_irq_[context] = true;
+        }
+      }
+    }
+    return;
+  }
+
+  // Interrupt enable bits for sources by context.
+  if (offset < 0x20'0000) {
+    offset -= 0x00'2000;
+    // Convert from word address to index.
+    offset >>= 2;
+    // Get the word index in the source dimension.
+    int word = (offset >> 2) & 0x1f;
+    // Get the context id.
+    int context = offset >> 7;
+    uint32_t prev = interrupt_enabled_[context][word];
+    // Determine which bits are being set.
+    uint32_t bits_set = (value ^ prev) & value;
+    uint32_t bits_cleared = (value ^ prev) & ~value;
+    // Update the enable bits.
+    interrupt_enabled_[context][word] = value;
+    // Iterate over the set bits and add them to the source/context maps.
+    while (bits_set != 0) {
+      int bit = absl::countr_zero(bits_set);
+      int source = word * 32 + bit;
+      source_to_context_.insert({source, context});
+      context_to_source_.insert({context, source});
+      bits_set &= ~(1 << bit);
+      if (context_if_[context] == nullptr) {
+        LOG(ERROR) << "No context interface for context " << context;
+        continue;
+      }
+      // If there is no pending IRQ for this context, and the priority is
+      // above the threshold, set the IRQ.
+      if (!context_irq_[context]) {
+        if (interrupt_priority_[source] > priority_threshold_[context]) {
+          context_irq_[context] = true;
+          context_if_[context]->SetIrq(true);
+        }
+      }
+    }
+    // Iterate over the cleared bits and erase them from the source/context
+    // maps.
+    while (bits_cleared != 0) {
+      int bit = absl::countr_zero(bits_cleared);
+      int source = word * 32 + bit;
+      auto [s2c_begin, s2c_end] = source_to_context_.equal_range(source);
+      for (auto s2c_it = s2c_begin; s2c_it != s2c_end; ++s2c_it) {
+        if (s2c_it->second == context) {
+          source_to_context_.erase(s2c_it);
+          break;
+        }
+      }
+      auto [c2s_begin, c2s_end] = context_to_source_.equal_range(context);
+      for (auto c2s_it = c2s_begin; c2s_it != c2s_end; ++c2s_it) {
+        if (c2s_it->second == source) {
+          context_to_source_.erase(c2s_it);
+          break;
+        }
+      }
+      bits_cleared &= ~(1 << bit);
+    }
+    return;
+  }
+
+  offset -= 0x20'0000;
+  // Interrupt priority threshold and claim/complete.
+  // Get context id.
+  int context = offset >> 12;
+  if (context >= num_contexts_) {
+    LOG(ERROR) << "Invalid context number: " << context;
+    return;
+  }
+  auto reg_id = offset & 0xfff;
+  switch (reg_id) {
+    case 0x0: {
+      // Priority threshold.
+      uint32_t prev = priority_threshold_[context];
+      priority_threshold_[context] = value;
+      if (value < prev) {
+        // If the priority threshold is being lowered and there is no active
+        // interrupt, see if there is a pending interrupt for this context,
+        // and if so, set the IRQ.
+        if (!context_irq_[context]) {
+          if (context_if_[context] == nullptr) {
+            LOG(ERROR) << "No context interface for context " << context;
+            return;
+          }
+          auto [begin, end] = context_to_source_.equal_range(context);
+          for (auto it = begin; it != end; ++it) {
+            if (interrupt_priority_[it->second] > value) {
+              context_irq_[context] = true;
+              context_if_[context]->SetIrq(true);
+              break;
+            }
+          }
+        }
+      }
+      return;
+    }
+    case 0x4:
+      // Claim/complete interrupt.
+      CompleteInterrupt(context, value);
+      return;
+    default:
+      LOG(ERROR) << "Invalid offset: " << offset;
+      break;
+  }
+}
+
+uint32_t RiscVPlic::ClaimInterrupt(int context) {
+  if (context < 0 || context >= num_contexts_) return 0;
+  uint32_t id = 0;
+  int priority = 0;
+  // Find the id of the highest-priority pending interrupt for this context.
+  auto [begin, end] = context_to_source_.equal_range(context);
+  int count = 0;
+  int source = 0;
+  for (auto it = begin; it != end; ++it) {
+    source = it->second;
+    // If the source is not pending, skip it.
+    if (!IsPending(source)) continue;
+    // If the priority is less or equal to the current priority, skip it.
+    if (priority > interrupt_priority_[source]) continue;
+    // If the priority is the same, the lower id is chosen, so if the new
+    // source is greater than the current, go to the next.
+    if ((priority == interrupt_priority_[source]) && (id < source)) continue;
+    id = source;
+    priority = interrupt_priority_[source];
+    count++;
+  }
+  if (id != 0) {
+    SetPending(id, false);
+    interrupt_claim_complete_[context] = id;
+    count--;
+  }
+  if (count == 0) {
+    // If there are zero remaining pending interrupts, clear the IRQ line.
+    context_if_[context]->SetIrq(false);
+    context_irq_[context] = false;
+  }
+  return id;
+}
+
+void RiscVPlic::CompleteInterrupt(int context, uint32_t id) {
+  if (context < 0 || context >= num_contexts_) return;
+  // Check if id is in the set of enabled sources for context.
+  auto [begin, end] = context_to_source_.equal_range(context);
+  bool found = false;
+  for (auto it = begin; it != end; ++it) {
+    if (it->second == id) {
+      found = true;
+      break;
+    }
+  }
+  if (!found) return;
+  // The PLIC spec only requires that the id be valid for the set of
+  // interrupts enabled for the context, not that it matches the
+  // interrupt_claim_complete_ value.
+  auto source = interrupt_claim_complete_[context];
+  interrupt_claim_complete_[context] = 0;
+  auto &info = gateway_info_[source];
+  // Check to see if there's a pending level based interrupt w priority > 0.
+  if (info.pending && (interrupt_priority_[source] > 0)) {
+    // Set the plic pending bit but no need to set the ready bit as this will
+    // be forwarded to the plic core right away.
+    SetPlicPendingInterrupt(source);
+    return;
+  }
+  // Set the gateway ready bit to true.
+  info.ready = true;
+}
+
+void RiscVPlic::SetPending(int source, bool value) {
+  int word = source >> 5;
+  int bit = source & 0x1f;
+  if (value) {
+    interrupt_pending_[word] |= 1 << bit;
+  } else {
+    interrupt_pending_[word] &= ~(1 << bit);
+  }
+}
+
+bool RiscVPlic::IsPending(int source) {
+  int word = source >> 5;
+  int bit = source & 0x1f;
+  return (interrupt_pending_[word] & (1 << bit)) != 0;
+}
+
+RiscVPlicSourceInterface::RiscVPlicSourceInterface(RiscVPlic *plic, int source,
+                                                   bool is_level)
+    : plic_(plic), source_(source), is_level_(is_level) {}
+
+}  // namespace riscv
+}  // namespace sim
+}  // namespace mpact
diff --git a/riscv/riscv_plic.h b/riscv/riscv_plic.h
new file mode 100644
index 0000000..8d8745f
--- /dev/null
+++ b/riscv/riscv_plic.h
@@ -0,0 +1,173 @@
+// Copyright 2024 Google LLC
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+#ifndef THIRD_PARTY_MPACT_RISCV_RISCV_PLIC_H_
+#define THIRD_PARTY_MPACT_RISCV_RISCV_PLIC_H_
+
+#include <cstdint>
+
+#include "absl/container/btree_map.h"
+#include "absl/status/status.h"
+#include "absl/strings/string_view.h"
+#include "mpact/sim/generic/data_buffer.h"
+#include "mpact/sim/generic/instruction.h"
+#include "mpact/sim/generic/ref_count.h"
+#include "mpact/sim/util/memory/memory_interface.h"
+
+// This file implements the RiscV PLIC (Platform Level Interrupt Controller).
+// It has a memory mapped register interface that is used to control the
+// interrupts to one or more contexts across one or more RiscV cores.
+//
+// The interrupt targets (contexts) are notified using the
+// RiscVPlicIrqInterface interface. Therefore each target much register its
+// own instance of this interface with the plic using the SetContext method.
+//
+// Interrupt sources communicate with the PLIC using the SetInterrupt method.
+//
+// The PLIC supports both level and edge triggered interrupts.
+
+namespace mpact {
+namespace sim {
+namespace riscv {
+
+using ::mpact::sim::generic::DataBuffer;
+using ::mpact::sim::generic::Instruction;
+using ::mpact::sim::generic::ReferenceCount;
+
+using ::mpact::sim::util::MemoryInterface;
+
+class RiscVPlicIrqInterface {
+ public:
+  virtual ~RiscVPlicIrqInterface() = default;
+  virtual void SetIrq(bool irq_value) = 0;
+};
+
+class RiscVPlic : public MemoryInterface {
+ public:
+  // The constructor takes the number of interrupt sources and the number of
+  // contexts that the PLIC can send interrupts to. A core usually has multiple
+  // contexts, one for each privilege level (machine, supervisor, etc.) that is
+  // capable of receiving and handling interrupts.
+  RiscVPlic(int num_sources, int num_contexts);
+  RiscVPlic() = delete;
+  RiscVPlic(const RiscVPlic &) = delete;
+  RiscVPlic &operator=(const RiscVPlic &) = delete;
+  ~RiscVPlic() override;
+
+  // Configure the PLIC state according to the source and context configuration
+  // strings. The source configuration string is a semicolon separated list of
+  // <source>=<priority> items, where <source> is the interrupt source number
+  // and <priority> is an non-negative integer priority value. Higher values
+  // have higher priorities. A value of zero disables the source. Any source
+  // that is not configured is disabled by default. However, MMR writes can
+  // change the configured values.
+  //
+  // The context configuration string is a semicolon separated list of
+  // <context>=<threshold>,(<source>,<enable>)+ items, where <context> is the
+  // context number, <source> is the source number, <threshold> is a non
+  // negative integer that is the priority threshold for that context, and
+  // <enable> is a 0 or 1 value that indicates whether the interrupt source is
+  // enabled for that context. Multiple lines for the same context with
+  // different sources is allowed. Any context not configured is assumed to
+  // disable all sources with a zero priority threshold.
+  absl::Status Configure(absl::string_view source_cfg,
+                         absl::string_view context_cfg);
+  // Interrupt request from the given interrupt source.
+  void SetInterrupt(int source, bool value, bool is_level);
+
+  // MemoryInterface overrides.
+  // Non-vector load method.
+  void Load(uint64_t address, DataBuffer *db, Instruction *inst,
+            ReferenceCount *context) override;
+  // Vector load method - this is stubbed out.
+  void Load(DataBuffer *address_db, DataBuffer *mask_db, int el_size,
+            DataBuffer *db, Instruction *inst,
+            ReferenceCount *context) override;
+  // Non-vector store method.
+  void Store(uint64_t address, DataBuffer *db) override;
+  // Vector store method - this is stubbed out.
+  void Store(DataBuffer *address, DataBuffer *mask, int el_size,
+             DataBuffer *db) override;
+
+  void SetContext(int context_no, RiscVPlicIrqInterface *context_if);
+
+ private:
+  struct GatewayInfo {
+    // The gateway is able to accept the interrupt and send it to the plic core.
+    bool ready;
+    // Pending bit in gateway. Only gets set if the interrupt is level based.
+    bool pending;
+    GatewayInfo() : ready(true), pending(false) {}
+  };
+
+  // MMR read/write methods.
+  uint32_t Read(uint32_t offset);
+  void Write(uint32_t offset, uint32_t value);
+  // Interrupt claim.
+  uint32_t ClaimInterrupt(int context);
+  // Signal interrupt completion for the given context and interrupt id.
+  void CompleteInterrupt(int context, uint32_t id);
+  // Set plic core pending interrupt bit and trigger interrupt to context as
+  // needed.
+  void SetPlicPendingInterrupt(int source);
+  // Handling pending bits.
+  void SetPending(int source, bool value);
+  bool IsPending(int source);
+
+  int num_sources_;
+  int num_contexts_;
+  // Interface to call to write the IRQ line for a context.
+  RiscVPlicIrqInterface **context_if_;
+  // Last value written to the IRQ line for a context.
+  bool *context_irq_ = nullptr;
+  // Source gateway info.
+  GatewayInfo *gateway_info_ = nullptr;
+  // Interrupt priorities by source.
+  uint32_t *interrupt_priority_ = nullptr;
+  // Pending interrupts by source - 32 bits per word.
+  uint32_t *interrupt_pending_ = nullptr;
+  // Enable bits per context per source - 32 bits per word.
+  // Array is organized as interrupt_enabled_[context][source / 32].
+  uint32_t **interrupt_enabled_ = nullptr;
+  // Priority threshold by context.
+  uint32_t *priority_threshold_ = nullptr;
+  // Interrupt claim/complete register by context.
+  uint32_t *interrupt_claim_complete_ = nullptr;
+  // Map from source to context that has the source enabled. This must be
+  // updated whenever an an enable bit is changed for a context.
+  absl::btree_multimap<int, int> source_to_context_;
+  // Map from context to source for which the context has the source enabled.
+  absl::btree_multimap<int, int> context_to_source_;
+};
+
+class RiscVPlicSourceInterface : public RiscVPlicIrqInterface {
+ public:
+  RiscVPlicSourceInterface(RiscVPlic *plic, int source, bool is_level);
+  RiscVPlicSourceInterface() = delete;
+  ~RiscVPlicSourceInterface() override = default;
+  void SetIrq(bool irq_value) override {
+    if (plic_ != nullptr) plic_->SetInterrupt(source_, irq_value, is_level_);
+  };
+
+ private:
+  RiscVPlic *plic_ = nullptr;
+  int source_ = 0;
+  bool is_level_ = false;
+};
+
+}  // namespace riscv
+}  // namespace sim
+}  // namespace mpact
+
+#endif  // THIRD_PARTY_MPACT_RISCV_RISCV_PLIC_H_
diff --git a/riscv/test/BUILD b/riscv/test/BUILD
index 82910b6..ea7a94d 100644
--- a/riscv/test/BUILD
+++ b/riscv/test/BUILD
@@ -727,6 +727,21 @@
 )
 
 cc_test(
+    name = "riscv_plic_test",
+    size = "small",
+    srcs = [
+        "riscv_plic_test.cc",
+    ],
+    deps = [
+        "//riscv:riscv_plic",
+        "@com_google_absl//absl/log:check",
+        "@com_google_googletest//:gtest_main",
+        "@com_google_mpact-sim//mpact/sim/generic:core",
+        "@com_googlesource_code_re2//:re2",
+    ],
+)
+
+cc_test(
     name = "librenode_mpact_riscv32.so_test",
     size = "small",
     srcs = ["librenode_mpact_riscv32_so_test.cc"],
diff --git a/riscv/test/riscv_plic_test.cc b/riscv/test/riscv_plic_test.cc
new file mode 100644
index 0000000..62c150c
--- /dev/null
+++ b/riscv/test/riscv_plic_test.cc
@@ -0,0 +1,315 @@
+
+// Copyright 2024 Google LLC
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+#include "riscv/riscv_plic.h"
+
+#include <cstdint>
+
+#include "absl/log/check.h"
+#include "googlemock/include/gmock/gmock.h"
+#include "mpact/sim/generic/data_buffer.h"
+
+// This file contains unit tests for the RiscV PLIC model.
+
+namespace {
+
+using ::mpact::sim::generic::DataBuffer;
+using ::mpact::sim::generic::DataBufferFactory;
+using ::mpact::sim::riscv::RiscVPlic;
+using ::mpact::sim::riscv::RiscVPlicIrqInterface;
+
+constexpr int kNumSources = 32;
+constexpr int kNumContexts = 3;
+
+// Mock interrupt target for a context.
+class MockRiscVInterruptTarget : public RiscVPlicIrqInterface {
+ public:
+  void SetIrq(bool irq_value) override { irq_value_ = irq_value; }
+
+  bool irq_value() const { return irq_value_; }
+  void set_irq_value(bool value) { irq_value_ = value; }
+
+ private:
+  bool irq_value_ = false;
+};
+
+// Test fixture.
+class RiscVPlicTest : public ::testing::Test {
+ protected:
+  RiscVPlicTest() {
+    plic_ = new RiscVPlic(kNumSources, kNumContexts);
+    for (int i = 0; i < kNumContexts; ++i) {
+      target_[i] = new MockRiscVInterruptTarget();
+      plic_->SetContext(i, target_[i]);
+    }
+    db_ = db_factory_.Allocate<uint32_t>(1);
+    db_->set_latency(0);
+  }
+
+  ~RiscVPlicTest() override {
+    delete plic_;
+    for (int i = 0; i < kNumContexts; ++i) {
+      delete target_[i];
+    }
+    db_->DecRef();
+  }
+
+  // Convenience methods to read/write the PLIC state using its memory
+  // interface.
+  bool GetEnable(int source, int context) {
+    uint32_t word = 0x2000 + (context * 0x80) + (source >> 5);
+    int bit = source & 0x1f;
+    plic()->Load(word, db_, nullptr, nullptr);
+    return (db_->Get<uint32_t>(0) & (1 << bit)) != 0;
+  }
+
+  void SetEnable(int source, int context, bool value) {
+    uint32_t word = 0x2000 + (context * 0x80) + (source >> 5);
+    int bit = source & 0x1f;
+    plic()->Load(word, db_, nullptr, nullptr);
+    auto span = db_->Get<uint32_t>();
+    uint32_t mask = ~(1 << bit);
+    uint32_t u_val = static_cast<uint32_t>(value);
+    span[0] = (span[0] & mask) | (u_val << bit);
+    plic()->Store(word, db_);
+  }
+
+  bool GetPending(int source) {
+    uint32_t word = 0x1000 + ((source >> 5) << 2);
+    int bit = source & 0x1f;
+    plic()->Load(word, db_, nullptr, nullptr);
+    return (db_->Get<uint32_t>(0) & (1 << bit)) != 0;
+  }
+
+  void SetPending(int source, bool value) {
+    int word = 0x1000 + ((source >> 5) << 2);
+    int bit = source & 0x1f;
+    plic()->Load(word, db_, nullptr, nullptr);
+    auto span = db_->Get<uint32_t>();
+    uint32_t mask = ~(1 << bit);
+    span[0] = (span[0] & mask) | (static_cast<uint32_t>(value) << bit);
+    plic()->Store(word, db_);
+  }
+
+  uint32_t GetPriority(int source) {
+    plic()->Load(source << 2, db_, nullptr, nullptr);
+    return db_->Get<uint32_t>(0);
+  }
+
+  void SetPriority(int source, uint32_t priority) {
+    db_->Set<uint32_t>(0, priority);
+    plic()->Store(source << 2, db_);
+  }
+
+  int GetPriorityThreshold(int context) {
+    plic()->Load(0x20'0000 + context * 0x1000, db_, nullptr, nullptr);
+    return db_->Get<uint32_t>(0);
+  }
+
+  void SetPriorityThreshold(int context, uint32_t threshold) {
+    db_->Set<uint32_t>(0, threshold);
+    plic()->Store(0x20'0000 + context * 0x1000, db_);
+  }
+
+  uint32_t GetInterruptClaim(int context) {
+    plic()->Load(0x20'0000 + context * 0x1000 + 4, db_, nullptr, nullptr);
+    return db_->Get<uint32_t>(0);
+  }
+
+  void SetInterruptClaim(int context, uint32_t claim) {
+    db_->Set<uint32_t>(0, claim);
+    plic()->Store(0x20'0000 + context * 0x1000 + 4, db_);
+  }
+
+  void SetDefaultConfig() {
+    // Set priorities to increasing values for all sources.
+    // Thresholds are set 8, 16 and 24 for the three contexts respectively.
+    // Source 30 is enabled for all contexts.
+    auto status = plic()->Configure(
+        "0=0;1=1;2=2;3=3;4=4;5=5;6=6;7=7;8=8;9=9;10=10;11=11;"
+        "12=12;13=13;14=14;15=15;16=16;17=17;18=18;19=19;20=20;"
+        "21=21;22=22;23=23;24=24;25=25;26=26;27=27;28=28;29=29;"
+        "30=30;31=31;",
+        "0=8,1,1,2,1,3,1,4,1,5,1,6,1,7,1,8,1,9,1,10,1,30,1;"
+        "1=16,11,1,12,1,13,1,14,1,15,1,16,1,17,1,18,1,19,1,20,1,30,1;"
+        "2=24,19,1,20,1,21,1,22,1,23,1,24,1,25,1,26,1,27,1,28,1,29,1,30,1,31,"
+        "1;");
+    CHECK_OK(status);
+  }
+
+  // Accessors.
+  RiscVPlic *plic() { return plic_; }
+  DataBufferFactory &db_factory() { return db_factory_; }
+  MockRiscVInterruptTarget *target(int i) { return target_[i]; }
+
+ private:
+  DataBuffer *db_;
+  DataBufferFactory db_factory_;
+  RiscVPlic *plic_ = nullptr;
+  MockRiscVInterruptTarget *target_[kNumContexts];
+};
+
+// Test that the initial state of the PLIC is as expected. Nothing enabled,
+// priorities at zero, priority thresholds at zero, no pending interrupts,
+// no claimed interrupts, no IRQ lines set.
+TEST_F(RiscVPlicTest, InitialState) {
+  for (int s = 0; s < kNumSources; ++s) {
+    for (int c = 0; c < kNumContexts; ++c) {
+      EXPECT_FALSE(GetEnable(s, c));
+      EXPECT_FALSE(GetPending(s));
+      EXPECT_EQ(GetPriority(s), 0) << "Source " << s;
+      EXPECT_EQ(GetPriorityThreshold(c), 0);
+      EXPECT_EQ(GetInterruptClaim(c), 0);
+      EXPECT_FALSE(target(c)->irq_value());
+    }
+  }
+}
+
+// Verify that the PLIC is configured as expected with the default configuration
+// strings.
+TEST_F(RiscVPlicTest, DefaultConfiguration) {
+  SetDefaultConfig();
+  for (int s = 0; s < kNumSources; ++s) {
+    for (int c = 0; c < kNumContexts; ++c) {
+      switch (c) {
+        case 0:
+          EXPECT_EQ(GetEnable(s, c), ((s >= 1) && (s <= 10)) || (s == 30))
+              << "Source " << s << " context " << c;
+          break;
+        case 1:
+          EXPECT_EQ(GetEnable(s, c), ((s >= 11) && (s <= 20)) || (s == 30))
+              << "Source " << s << " context " << c;
+          break;
+        case 2:
+          EXPECT_EQ(GetEnable(s, c), (s >= 19) && (s <= 31))
+              << "Source " << s << " context " << c;
+          break;
+      }
+      EXPECT_FALSE(GetPending(s));
+      EXPECT_EQ(GetPriority(s), s) << "Source " << s;
+      EXPECT_EQ(GetPriorityThreshold(c), (c + 1) * 8) << "Context " << c;
+      EXPECT_EQ(GetInterruptClaim(c), 0) << "Context " << c;
+      EXPECT_FALSE(target(c)->irq_value()) << "Context " << c;
+    }
+  }
+}
+
+// Test operation of level triggered interrupts.
+TEST_F(RiscVPlicTest, LevelTriggeredInterrupt) {
+  SetDefaultConfig();
+  // Set irq for source 10 level sensitive.
+  plic()->SetInterrupt(10, /*value=*/true, /*is_level=*/true);
+  // Expect pending to be set.
+  EXPECT_TRUE(GetPending(10));
+  // Clear the irq.
+  plic()->SetInterrupt(10, /*value=*/false, /*is_level=*/true);
+  // Expect pending to still be set.
+  EXPECT_TRUE(GetPending(10));
+  // Expect irq to be set for context 0;
+  EXPECT_TRUE(target(0)->irq_value());
+  // Clear the irq.
+  target(0)->set_irq_value(false);
+  // Now raise the irq again.
+  plic()->SetInterrupt(10, /*value=*/true, /*is_level=*/true);
+  // Expect pending to be set.
+  EXPECT_TRUE(GetPending(10));
+  // Claim the interrupt.
+  uint32_t id = GetInterruptClaim(0);
+  EXPECT_EQ(id, 10);
+  // A second claim should return 0.
+  EXPECT_EQ(GetInterruptClaim(0), 0);
+  // Interrupt is no longer pending.
+  EXPECT_FALSE(GetPending(10));
+  // Complete the interrupt.
+  SetInterruptClaim(0, id);
+  // Expect pending to be set, as the level is still high.
+  EXPECT_TRUE(GetPending(10));
+  // Lower the irq.
+  plic()->SetInterrupt(10, /*value=*/false, /*is_level=*/true);
+  // Expect pending to still be set.
+  EXPECT_TRUE(GetPending(10));
+}
+
+// Test operation of edge triggered interrupts.
+TEST_F(RiscVPlicTest, EdgeTriggeredInterrupt) {
+  SetDefaultConfig();
+  // Set irq for source 10 level sensitive.
+  plic()->SetInterrupt(10, /*value=*/true, /*is_level=*/false);
+  // Expect pending to be set.
+  EXPECT_TRUE(GetPending(10));
+  // Expect irq to be set for context 0;
+  EXPECT_TRUE(target(0)->irq_value());
+  // Claim the interrupt.
+  uint32_t id = GetInterruptClaim(0);
+  EXPECT_EQ(id, 10);
+  // A second claim should return 0.
+  EXPECT_EQ(GetInterruptClaim(0), 0);
+  // Interrupt is no longer pending.
+  EXPECT_FALSE(GetPending(10));
+  // Complete the interrupt.
+  SetInterruptClaim(0, id);
+  // Expect pending to be cleared.
+  EXPECT_FALSE(GetPending(10));
+}
+
+TEST_F(RiscVPlicTest, PriorityThreshold) {
+  SetDefaultConfig();
+  // Signal interrupts for sources 5-10.
+  for (int i = 5; i <= 10; ++i) {
+    plic()->SetInterrupt(i, /*value=*/true, /*is_level=*/false);
+    // Only sources 9 and 10 should trigger interrupts.
+    EXPECT_EQ(target(0)->irq_value(), i > 8);
+  }
+  // Now claim the interrupts, all should be claimed in order of priority,'
+  // even those below the threshold. The IRQ line should remain high until
+  // there are no more pending interrupts.
+  for (int i = 10; i >= 5; --i) {
+    EXPECT_TRUE(target(0)->irq_value());
+    EXPECT_TRUE(GetPending(i));
+    uint32_t id = GetInterruptClaim(0);
+    EXPECT_EQ(id, i);
+    SetInterruptClaim(0, id);
+    EXPECT_FALSE(GetPending(i));
+    // IRQ remains high until the last interrupt is completed.
+    EXPECT_EQ(target(0)->irq_value(), i != 5);
+  }
+}
+
+TEST_F(RiscVPlicTest, MultipleTargets) {
+  SetDefaultConfig();
+  // Signal interrupt for source 30.
+  plic()->SetInterrupt(30, /*value=*/true, /*is_level=*/false);
+  EXPECT_TRUE(GetPending(30));
+  // Expect irq to be set for all contexts.
+  for (int c = 0; c < kNumContexts; ++c) {
+    EXPECT_TRUE(target(c)->irq_value());
+  }
+  // Try claiming the interrupt for each context, only the first will succeed.
+  for (int c = 0; c < kNumContexts; ++c) {
+    uint32_t id = GetInterruptClaim(c);
+    // Expect pending to be cleared.
+    EXPECT_FALSE(GetPending(30));
+    if (c == 0) {
+      EXPECT_EQ(id, 30);
+    } else {
+      EXPECT_EQ(id, 0);
+    }
+    // The target should be cleared.
+    EXPECT_EQ(target(c)->irq_value(), 0);
+  }
+  // Complete the interrupt for context 0.
+  SetInterruptClaim(0, 30);
+}
+}  // namespace
