Allow Kelvin to talk to internal peripherals

- If a region is marked as `Peripheral` in the memory map, set an extra
  bit of signaling on the ebus. When the extra bit is set, instead of
  emitting an AXI transaction out to the fabric we're connected to,
  send the transaction to our internal peripheral mux.

Change-Id: Idcc11039ffbdd4dffb61b3d6c58b2818706abb4a
diff --git a/hdl/chisel/src/kelvin/AxiSlave.scala b/hdl/chisel/src/kelvin/AxiSlave.scala
index 97b2e6f..06ba4f1 100644
--- a/hdl/chisel/src/kelvin/AxiSlave.scala
+++ b/hdl/chisel/src/kelvin/AxiSlave.scala
@@ -68,7 +68,8 @@
     x => !(x.U < io.axi.read.addr.bits.size)
   ))
   val alignedAddr = io.axi.read.addr.bits.addr & alignedAddrMask.asUInt
-  val readDataShift = ((io.axi.read.addr.bits.addr - alignedAddr) << 3.U)(8,0)
+  val msb = log2Ceil(p.axi2DataBits) - 1
+  val readDataShift = ((io.axi.read.addr.bits.addr - alignedAddr) << 3.U)(msb,0)
   io.axi.read.data.bits.data := io.fabric.readData << readDataShift
   io.axi.read.data.bits.id := Mux(readAddr.valid, readAddr.bits.id, 0.U)
   io.axi.read.data.bits.resp := 0.U
diff --git a/hdl/chisel/src/kelvin/Core.scala b/hdl/chisel/src/kelvin/Core.scala
index 1bc4532..8acfaf2 100644
--- a/hdl/chisel/src/kelvin/Core.scala
+++ b/hdl/chisel/src/kelvin/Core.scala
@@ -47,7 +47,7 @@
     // Bus between core and data memories.
     val dbus = new DBusIO(p)
     // Bus between core and and external memories or peripherals.
-    val ebus = new DBusIO(p)
+    val ebus = new EBusIO(p)
 
     val iflush = new IFlushIO(p)
     val dflush = new DFlushIO(p)
diff --git a/hdl/chisel/src/kelvin/CoreAxi.scala b/hdl/chisel/src/kelvin/CoreAxi.scala
index 93c7b80..7aae784 100644
--- a/hdl/chisel/src/kelvin/CoreAxi.scala
+++ b/hdl/chisel/src/kelvin/CoreAxi.scala
@@ -18,7 +18,7 @@
 import chisel3.util._
 import chisel3.util.experimental.decode._
 
-import bus.{AxiAddress, AxiMasterIO, AxiMasterReadIO, AxiWriteData}
+import bus._
 import common._
 import _root_.circt.stage.ChiselStage
 
@@ -164,11 +164,26 @@
     dtcmArbiter.io.out.ready := true.B
 
     val ebus2axi = DBus2Axi(p)
-    ebus2axi.io.axi <> io.axi_master
-    ebus2axi.io.dbus <> core.io.ebus
+    ebus2axi.io.dbus <> core.io.ebus.dbus
+    ebus2axi.io.axi <> 0.U.asTypeOf(ebus2axi.io.axi)
 
-    val axi_mux = Module(new CoreAxiSlaveMux(p, memoryRegions))
-    axi_mux.io.axi_slave <> io.axi_slave
+    val axi_mux = Module(new CoreAxiSlaveMux(p, memoryRegions, 2))
+    axi_mux.io.axi_slave(0) <> io.axi_slave
+    axi_mux.io.axi_slave(1) <> 0.U.asTypeOf(axi_mux.io.axi_slave(1))
+
+    io.axi_master <> 0.U.asTypeOf(io.axi_master)
+
+    // If an internal transaction is issued on the EBUS,
+    // connect the AXI master interface to the internal
+    // peripheral mux.
+    when (core.io.ebus.internal) {
+      axi_mux.io.axi_slave(1) <> ebus2axi.io.axi
+      io.axi_master <> 0.U.asTypeOf(io.axi_master)
+    } .otherwise {
+      axi_mux.io.axi_slave(1) <> 0.U.asTypeOf(axi_mux.io.axi_slave(1))
+      io.axi_master <> ebus2axi.io.axi
+    }
+
     axi_mux.io.ports(0) <> itcmBridge.io.axi
     axi_mux.io.ports(1) <> dtcmBridge.io.axi
     axi_mux.io.ports(2) <> csr.io.axi
diff --git a/hdl/chisel/src/kelvin/CoreAxiSlaveMux.scala b/hdl/chisel/src/kelvin/CoreAxiSlaveMux.scala
index 16cb1a6..881b9fa 100644
--- a/hdl/chisel/src/kelvin/CoreAxiSlaveMux.scala
+++ b/hdl/chisel/src/kelvin/CoreAxiSlaveMux.scala
@@ -20,10 +20,10 @@
 import bus.AxiMasterIO
 import common._
 
-class CoreAxiSlaveMux(p: Parameters, regions: Seq[MemoryRegion]) extends Module {
+class CoreAxiSlaveMux(p: Parameters, regions: Seq[MemoryRegion], sourceCount: Int) extends Module {
   val portCount = regions.length
   val io = IO(new Bundle {
-    val axi_slave = Flipped(new AxiMasterIO(p.axi2AddrBits, p.axi2DataBits, p.axi2IdBits))
+    val axi_slave = Vec(sourceCount, Flipped(new AxiMasterIO(p.axi2AddrBits, p.axi2DataBits, p.axi2IdBits)))
     val ports = Vec(portCount, new AxiMasterIO(p.axi2AddrBits, p.axi2DataBits, p.axi2IdBits))
   })
 
@@ -33,41 +33,51 @@
   // gap: (base + 0x4000, base + 0x8000)
   // DTCM: (base + 0x8000, base + 0x10000)
   val portTieOff = 0.U.asTypeOf(io.ports(0))
+  val sourceTieOff = 0.U.asTypeOf(io.axi_slave(0))
   val readTarget = RegInit(0.U(portCount.W))
-  when (io.axi_slave.read.addr.valid && !readTarget.orR) {
-    val contains = VecInit(regions.map(_.contains(io.axi_slave.read.addr.bits.addr))).asUInt
+  val readSource = RegInit(0.U(sourceCount.W))
+  val readAddrValids = VecInit(io.axi_slave.map(_.read.addr.valid)).asUInt
+  when (readAddrValids.orR && !readTarget.orR) {
+    val source = PriorityEncoderOH(readAddrValids)
+    readSource := source
+    val contains = VecInit(regions.map(_.contains(io.axi_slave(OHToUInt(source)).read.addr.bits.addr))).asUInt
     assert(PopCount(contains) <= 1.U)
     readTarget := contains
   }
 
   for (i <- 0 until portCount) {
     when (readTarget(i)) {
-      io.ports(i).read.addr <> io.axi_slave.read.addr
-      io.ports(i).read.addr.bits.addr := io.axi_slave.read.addr.bits.addr & ~regions(i).memStart.U(p.fetchAddrBits.W)
-      io.axi_slave.read.data <> io.ports(i).read.data
+      io.ports(i).read.addr <> io.axi_slave(OHToUInt(readSource)).read.addr
+      io.ports(i).read.addr.bits.addr := io.axi_slave(OHToUInt(readSource)).read.addr.bits.addr & ~regions(i).memStart.U(p.fetchAddrBits.W)
+      io.axi_slave(OHToUInt(readSource)).read.data <> io.ports(i).read.data
     } .otherwise {
       io.ports(i).read.addr <> portTieOff.read.addr
       portTieOff.read.data <> io.ports(i).read.data
     }
   }
 
-  when (io.axi_slave.read.data.fire && io.axi_slave.read.data.bits.last) {
+  when (io.axi_slave(OHToUInt(readSource)).read.data.fire && io.axi_slave(OHToUInt(readSource)).read.data.bits.last) {
     readTarget := 0.U(portCount.W)
+    readSource := 0.U(sourceCount.W)
   }
 
   val writeTarget = RegInit(0.U(portCount.W))
-  when (io.axi_slave.write.addr.valid && !writeTarget.orR) {
-    val contains = VecInit(regions.map(_.contains(io.axi_slave.write.addr.bits.addr))).asUInt
+  val writeSource = RegInit(0.U(sourceCount.W))
+  val writeAddrValids = VecInit(io.axi_slave.map(_.write.addr.valid)).asUInt
+  when (writeAddrValids.orR && !writeTarget.orR) {
+    val source = PriorityEncoderOH(writeAddrValids)
+    writeSource := source
+    val contains = VecInit(regions.map(_.contains(io.axi_slave(OHToUInt(source)).write.addr.bits.addr))).asUInt
     assert(PopCount(contains) <= 1.U)
     writeTarget := contains
   }
 
   for (i <- 0 until portCount) {
     when (writeTarget(i)) {
-      io.ports(i).write.addr <> io.axi_slave.write.addr
-      io.ports(i).write.addr.bits.addr := io.axi_slave.write.addr.bits.addr & ~regions(i).memStart.U(p.fetchAddrBits.W)
-      io.ports(i).write.data <> io.axi_slave.write.data
-      io.axi_slave.write.resp <> io.ports(i).write.resp
+      io.ports(i).write.addr <> io.axi_slave(OHToUInt(writeSource)).write.addr
+      io.ports(i).write.addr.bits.addr := io.axi_slave(OHToUInt(writeSource)).write.addr.bits.addr & ~regions(i).memStart.U(p.fetchAddrBits.W)
+      io.ports(i).write.data <> io.axi_slave(OHToUInt(writeSource)).write.data
+      io.axi_slave(OHToUInt(writeSource)).write.resp <> io.ports(i).write.resp
     } .otherwise {
       io.ports(i).write.addr <> portTieOff.write.addr
       io.ports(i).write.data <> portTieOff.write.data
@@ -75,28 +85,39 @@
     }
   }
 
-  when (io.axi_slave.write.resp.fire) {
+  when (io.axi_slave(OHToUInt(writeSource)).write.resp.fire) {
     writeTarget := 0.U(portCount.W)
+    writeSource := 0.U(sourceCount.W)
   }
 
-  io.axi_slave.write.addr.ready :=
-    Mux(writeTarget.orR, io.ports(OHToUInt(writeTarget)).write.addr.ready, false.B)
+  for (i <- 0 until sourceCount) {
+    io.axi_slave(i).write.addr.ready :=
+      Mux(writeTarget.orR && OHToUInt(writeSource) === i.U,
+          io.ports(OHToUInt(writeTarget)).write.addr.ready, false.B)
 
-  io.axi_slave.write.data.ready :=
-    Mux(writeTarget.orR, io.ports(OHToUInt(writeTarget)).write.data.ready, false.B)
+    io.axi_slave(i).write.data.ready :=
+      Mux(writeTarget.orR && OHToUInt(writeSource) === i.U,
+          io.ports(OHToUInt(writeTarget)).write.data.ready, false.B)
 
-  io.axi_slave.write.resp.valid :=
-    Mux(writeTarget.orR, io.ports(OHToUInt(writeTarget)).write.resp.valid, false.B)
-  io.axi_slave.write.resp.bits.id :=
-    Mux(writeTarget.orR, io.ports(OHToUInt(writeTarget)).write.resp.bits.id, 0.U)
-  io.axi_slave.write.resp.bits.resp :=
-    Mux(writeTarget.orR, io.ports(OHToUInt(writeTarget)).write.resp.bits.resp, 0.U)
+    io.axi_slave(i).write.resp.valid :=
+      Mux(writeTarget.orR && OHToUInt(writeSource) === i.U,
+          io.ports(OHToUInt(writeTarget)).write.resp.valid, false.B)
+    io.axi_slave(i).write.resp.bits.id :=
+      Mux(writeTarget.orR && OHToUInt(writeSource) === i.U,
+          io.ports(OHToUInt(writeTarget)).write.resp.bits.id, 0.U)
+    io.axi_slave(i).write.resp.bits.resp :=
+      Mux(writeTarget.orR && OHToUInt(writeSource) === i.U,
+          io.ports(OHToUInt(writeTarget)).write.resp.bits.resp, 0.U)
 
-  io.axi_slave.read.addr.ready :=
-    Mux(readTarget.orR, io.ports(OHToUInt(readTarget)).read.addr.ready, false.B)
+    io.axi_slave(i).read.addr.ready :=
+      Mux(readTarget.orR && OHToUInt(readSource) === i.U,
+          io.ports(OHToUInt(readTarget)).read.addr.ready, false.B)
 
-  io.axi_slave.read.data.valid :=
-    Mux(readTarget.orR, io.ports(OHToUInt(readTarget)).read.data.valid, false.B)
-  io.axi_slave.read.data.bits :=
-    Mux(readTarget.orR, io.ports(OHToUInt(readTarget)).read.data.bits, 0.U.asTypeOf(io.axi_slave.read.data.bits))
+    io.axi_slave(i).read.data.valid :=
+      Mux(readTarget.orR && OHToUInt(readSource) === i.U,
+          io.ports(OHToUInt(readTarget)).read.data.valid, false.B)
+    io.axi_slave(i).read.data.bits :=
+      Mux(readTarget.orR && OHToUInt(readSource) === i.U,
+          io.ports(OHToUInt(readTarget)).read.data.bits, 0.U.asTypeOf(io.axi_slave(i).read.data.bits))
+  }
 }
\ No newline at end of file
diff --git a/hdl/chisel/src/kelvin/CoreAxiSlaveMuxTest.scala b/hdl/chisel/src/kelvin/CoreAxiSlaveMuxTest.scala
index c53bcde..f039d22 100644
--- a/hdl/chisel/src/kelvin/CoreAxiSlaveMuxTest.scala
+++ b/hdl/chisel/src/kelvin/CoreAxiSlaveMuxTest.scala
@@ -31,42 +31,42 @@
   )
 
   "Initialization" in {
-    test(new CoreAxiSlaveMux(p, memoryRegions)) { dut =>
-      assertResult(0) { dut.io.axi_slave.read.addr.ready.peekInt() }
-      assertResult(0) { dut.io.axi_slave.read.data.valid.peekInt() }
-      assertResult(0) { dut.io.axi_slave.write.addr.ready.peekInt() }
-      assertResult(0) { dut.io.axi_slave.write.data.ready.peekInt() }
-      assertResult(0) { dut.io.axi_slave.write.resp.valid.peekInt() }
+    test(new CoreAxiSlaveMux(p, memoryRegions, 1)) { dut =>
+      assertResult(0) { dut.io.axi_slave(0).read.addr.ready.peekInt() }
+      assertResult(0) { dut.io.axi_slave(0).read.data.valid.peekInt() }
+      assertResult(0) { dut.io.axi_slave(0).write.addr.ready.peekInt() }
+      assertResult(0) { dut.io.axi_slave(0).write.data.ready.peekInt() }
+      assertResult(0) { dut.io.axi_slave(0).write.resp.valid.peekInt() }
     }
   }
 
   "Read" in {
-    test(new CoreAxiSlaveMux(p, memoryRegions)) { dut =>
-      dut.io.axi_slave.read.addr.valid.poke(true.B)
-      dut.io.axi_slave.read.addr.bits.addr.poke(0x2000.U)
+    test(new CoreAxiSlaveMux(p, memoryRegions, 1)) { dut =>
+      dut.io.axi_slave(0).read.addr.valid.poke(true.B)
+      dut.io.axi_slave(0).read.addr.bits.addr.poke(0x2000.U)
       dut.clock.step()
       assertResult(1) { dut.io.ports(1).read.addr.valid.peekInt() }
       dut.io.ports(1).read.addr.ready.poke(true.B)
-      assertResult(1) { dut.io.axi_slave.read.addr.ready.peekInt() }
+      assertResult(1) { dut.io.axi_slave(0).read.addr.ready.peekInt() }
       dut.clock.step()
-      dut.io.axi_slave.read.addr.valid.poke(false.B)
+      dut.io.axi_slave(0).read.addr.valid.poke(false.B)
       dut.clock.step()
-      assertResult(0) { dut.io.axi_slave.read.addr.valid.peekInt() }
+      assertResult(0) { dut.io.axi_slave(0).read.addr.valid.peekInt() }
     }
   }
 
   "Write" in {
-    test(new CoreAxiSlaveMux(p, memoryRegions)) { dut =>
-      dut.io.axi_slave.write.addr.valid.poke(true.B)
-      dut.io.axi_slave.write.addr.bits.addr.poke(0x2000.U)
+    test(new CoreAxiSlaveMux(p, memoryRegions, 1)) { dut =>
+      dut.io.axi_slave(0).write.addr.valid.poke(true.B)
+      dut.io.axi_slave(0).write.addr.bits.addr.poke(0x2000.U)
       dut.clock.step()
       assertResult(1) { dut.io.ports(1).write.addr.valid.peekInt() }
       dut.io.ports(1).write.addr.ready.poke(true.B)
-      assertResult(1) { dut.io.axi_slave.write.addr.ready.peekInt() }
+      assertResult(1) { dut.io.axi_slave(0).write.addr.ready.peekInt() }
       dut.clock.step()
-      dut.io.axi_slave.write.addr.valid.poke(false.B)
+      dut.io.axi_slave(0).write.addr.valid.poke(false.B)
       dut.clock.step()
-      assertResult(0) { dut.io.axi_slave.write.addr.valid.peekInt() }
+      assertResult(0) { dut.io.axi_slave(0).write.addr.valid.peekInt() }
     }
   }
 }
diff --git a/hdl/chisel/src/kelvin/Interfaces.scala b/hdl/chisel/src/kelvin/Interfaces.scala
index 329dc25..0a7e270 100644
--- a/hdl/chisel/src/kelvin/Interfaces.scala
+++ b/hdl/chisel/src/kelvin/Interfaces.scala
@@ -119,6 +119,11 @@
   val rdata = Input(UInt(p.lsuDataBits.W))
 }
 
+class EBusIO(p: Parameters) extends Bundle {
+  val dbus = new DBusIO(p)
+  val internal = Output(Bool())
+}
+
 class IFlushIO(p: Parameters) extends Bundle {
   val valid = Output(Bool())
   val ready = Input(Bool())
diff --git a/hdl/chisel/src/kelvin/scalar/Lsu.scala b/hdl/chisel/src/kelvin/scalar/Lsu.scala
index 0052db2..a5703cb 100644
--- a/hdl/chisel/src/kelvin/scalar/Lsu.scala
+++ b/hdl/chisel/src/kelvin/scalar/Lsu.scala
@@ -89,7 +89,7 @@
     // DBus that will eventually reach an external bus.
     // Intended for sending a transaction to an external
     // peripheral, likely on TileLink or AXI.
-    val ebus = new DBusIO(p)
+    val ebus = new EBusIO(p)
 
     // Vector switch.
     val vldst = Output(Bool())
@@ -126,9 +126,6 @@
                   .map(_.contains(io.busPort.addr(i))).reduceOption(_ || _).getOrElse(false.B)
     val external = !(itcm || dtcm || peri)
     assert(PopCount(Cat(itcm | dtcm | peri)) <= 1.U)
-    // NB: Should raise a load/store exception here.
-    assert(!(peri && io.req(i).valid && ctrlready(i)),
-           "Accessing internal peripherals via the memory interface is unsupported!")
 
     val opstore = io.req(i).bits.op.isOneOf(LsuOp.SW, LsuOp.SH, LsuOp.SB)
     val opiload = io.req(i).bits.op.isOneOf(LsuOp.LW, LsuOp.LH, LsuOp.LB, LsuOp.LHU, LsuOp.LBU)
@@ -207,13 +204,15 @@
   assert(!(io.dbus.valid && io.dbus.addr(31)))
   assert(!(io.dbus.valid && io.dbus.adrx(31)))
 
-  io.ebus.valid := ctrl.io.out.valid && ctrl.io.out.bits.sldst && (ctrl.io.out.bits.regionType === MemoryRegionType.External)
-  io.ebus.write := ctrl.io.out.bits.write
-  io.ebus.addr := ctrl.io.out.bits.addr
-  io.ebus.adrx := ctrl.io.out.bits.adrx
-  io.ebus.size := ctrl.io.out.bits.size
-  io.ebus.wdata := wdata
-  io.ebus.wmask := wmask
+  io.ebus.dbus.valid := ctrl.io.out.valid && ctrl.io.out.bits.sldst &&
+    ((ctrl.io.out.bits.regionType === MemoryRegionType.External) || (ctrl.io.out.bits.regionType === MemoryRegionType.Peripheral))
+  io.ebus.dbus.write := ctrl.io.out.bits.write
+  io.ebus.dbus.addr := ctrl.io.out.bits.addr
+  io.ebus.dbus.adrx := ctrl.io.out.bits.adrx
+  io.ebus.dbus.size := ctrl.io.out.bits.size
+  io.ebus.dbus.wdata := wdata
+  io.ebus.dbus.wmask := wmask
+  io.ebus.internal := ctrl.io.out.bits.regionType === MemoryRegionType.Peripheral
 
   io.ibus.valid := ctrl.io.out.valid && ctrl.io.out.bits.sldst && (ctrl.io.out.bits.regionType === MemoryRegionType.IMEM)
   // TODO(atv): This should actually raise some sort of error, and trigger a store fault
@@ -223,7 +222,7 @@
 
   io.storeCount := PopCount(Cat(
     io.dbus.valid && io.dbus.write,
-    io.ebus.valid && io.ebus.write
+    io.ebus.dbus.valid && io.ebus.dbus.write
   ))
 
   io.flush.valid  := ctrl.io.out.valid && (ctrl.io.out.bits.fencei || ctrl.io.out.bits.flushat || ctrl.io.out.bits.flushall)
@@ -233,7 +232,7 @@
 
   ctrl.io.out.ready := io.flush.valid && io.flush.ready ||
                        io.dbus.valid && io.dbus.ready ||
-                       io.ebus.valid && io.ebus.ready ||
+                       io.ebus.dbus.valid && io.ebus.dbus.ready ||
                        io.ibus.valid && io.ibus.ready ||
                        ctrl.io.out.bits.vldst && io.dbus.ready
 
@@ -242,7 +241,7 @@
   // ---------------------------------------------------------------------------
   // Load response.
   data.io.in.valid := io.dbus.valid && io.dbus.ready && !io.dbus.write ||
-                      io.ebus.valid && io.ebus.ready && !io.ebus.write ||
+                      io.ebus.dbus.valid && io.ebus.dbus.ready && !io.ebus.dbus.write ||
                       io.ibus.valid && io.ibus.ready
 
   data.io.in.bits.addr  := ctrl.io.out.bits.addr
@@ -299,7 +298,8 @@
   val srdata = MuxLookup(regionType, 0.U.asTypeOf(io.dbus.rdata))(Seq(
     MemoryRegionType.DMEM -> io.dbus.rdata,
     MemoryRegionType.IMEM -> io.ibus.rdata,
-    MemoryRegionType.External -> io.ebus.rdata,
+    MemoryRegionType.External -> io.ebus.dbus.rdata,
+    MemoryRegionType.Peripheral -> io.ebus.dbus.rdata,
   ))
   val rdata = RotSignExt(MuxOR(data.io.out.bits.sldst, srdata))
 
diff --git a/hdl/chisel/src/kelvin/scalar/SCore.scala b/hdl/chisel/src/kelvin/scalar/SCore.scala
index fcdb3da..a077f88 100644
--- a/hdl/chisel/src/kelvin/scalar/SCore.scala
+++ b/hdl/chisel/src/kelvin/scalar/SCore.scala
@@ -35,7 +35,7 @@
 
     val ibus = new IBusIO(p)
     val dbus = new DBusIO(p)
-    val ebus = new DBusIO(p)
+    val ebus = new EBusIO(p)
 
     val vldst = if (p.enableVector) { Some(Output(Bool())) } else { None }
     val vcore = if (p.enableVector) {
diff --git a/tests/renode/rv_core/kelvin_hello_world.c b/tests/renode/rv_core/kelvin_hello_world.c
index 027d935..255532e 100644
--- a/tests/renode/rv_core/kelvin_hello_world.c
+++ b/tests/renode/rv_core/kelvin_hello_world.c
@@ -50,6 +50,8 @@
 int main(int argc, char *argv[]) {
   uint32_t* rv_core_memory = (uint32_t*)0x20000000L;
   print_uint32(*rv_core_memory);
+  uint32_t* our_pc_csr = (uint32_t*)0x2110L;
+  print_uint32(*our_pc_csr);
   print_string("beefb0ba\n");
   print_uint32(0xb0bacafeL);
   asm volatile(".word 0x26000077");  // flushall
diff --git a/tests/verilator_sim/kelvin/core_tb.cc b/tests/verilator_sim/kelvin/core_tb.cc
index 223ed6a..082b6a8 100644
--- a/tests/verilator_sim/kelvin/core_tb.cc
+++ b/tests/verilator_sim/kelvin/core_tb.cc
@@ -62,9 +62,9 @@
   sc_signal<bool> io_dbus_valid;
   sc_signal<bool> io_dbus_ready;
   sc_signal<bool> io_dbus_write;
-  sc_signal<bool> io_ebus_valid;
-  sc_signal<bool> io_ebus_ready;
-  sc_signal<bool> io_ebus_write;
+  sc_signal<bool> io_ebus_dbus_valid;
+  sc_signal<bool> io_ebus_dbus_ready;
+  sc_signal<bool> io_ebus_dbus_write;
   sc_signal<bool> io_iflush_valid;
   sc_signal<bool> io_iflush_ready;
   sc_signal<bool> io_dflush_valid;
@@ -101,12 +101,13 @@
   sc_signal<sc_bv<KP_lsuDataBits> > io_dbus_wdata;
   sc_signal<sc_bv<KP_lsuDataBits / 8> > io_dbus_wmask;
   sc_signal<sc_bv<KP_lsuDataBits> > io_dbus_rdata;
-  sc_signal<sc_bv<32> > io_ebus_addr;
-  sc_signal<sc_bv<32> > io_ebus_adrx;
-  sc_signal<sc_bv<KP_dbusSize> > io_ebus_size;
-  sc_signal<sc_bv<KP_lsuDataBits> > io_ebus_wdata;
-  sc_signal<sc_bv<KP_lsuDataBits / 8> > io_ebus_wmask;
-  sc_signal<sc_bv<KP_lsuDataBits> > io_ebus_rdata;
+  sc_signal<sc_bv<32> > io_ebus_dbus_addr;
+  sc_signal<sc_bv<32> > io_ebus_dbus_adrx;
+  sc_signal<sc_bv<KP_dbusSize> > io_ebus_dbus_size;
+  sc_signal<sc_bv<KP_lsuDataBits> > io_ebus_dbus_wdata;
+  sc_signal<sc_bv<KP_lsuDataBits / 8> > io_ebus_dbus_wmask;
+  sc_signal<sc_bv<KP_lsuDataBits> > io_ebus_dbus_rdata;
+  sc_signal<bool> io_ebus_internal;
   sc_signal<sc_bv<5> > io_slog_addr;
   sc_signal<sc_bv<32> > io_slog_data;
   sc_signal<sc_bv<4> > io_debug_en;
@@ -134,9 +135,9 @@
   core.io_dbus_valid(io_dbus_valid);
   core.io_dbus_ready(io_dbus_ready);
   core.io_dbus_write(io_dbus_write);
-  core.io_ebus_valid(io_ebus_valid);
-  core.io_ebus_ready(io_ebus_ready);
-  core.io_ebus_write(io_ebus_write);
+  core.io_ebus_dbus_valid(io_ebus_dbus_valid);
+  core.io_ebus_dbus_ready(io_ebus_dbus_ready);
+  core.io_ebus_dbus_write(io_ebus_dbus_write);
   core.io_iflush_valid(io_iflush_valid);
   core.io_iflush_ready(io_iflush_ready);
   core.io_dflush_valid(io_dflush_valid);
@@ -173,12 +174,13 @@
   core.io_dbus_wdata(io_dbus_wdata);
   core.io_dbus_wmask(io_dbus_wmask);
   core.io_dbus_rdata(io_dbus_rdata);
-  core.io_ebus_addr(io_ebus_addr);
-  core.io_ebus_adrx(io_ebus_adrx);
-  core.io_ebus_size(io_ebus_size);
-  core.io_ebus_wdata(io_ebus_wdata);
-  core.io_ebus_wmask(io_ebus_wmask);
-  core.io_ebus_rdata(io_ebus_rdata);
+  core.io_ebus_dbus_addr(io_ebus_dbus_addr);
+  core.io_ebus_dbus_adrx(io_ebus_dbus_adrx);
+  core.io_ebus_dbus_size(io_ebus_dbus_size);
+  core.io_ebus_dbus_wdata(io_ebus_dbus_wdata);
+  core.io_ebus_dbus_wmask(io_ebus_dbus_wmask);
+  core.io_ebus_dbus_rdata(io_ebus_dbus_rdata);
+  core.io_ebus_internal(io_ebus_internal);
   core.io_slog_addr(io_slog_addr);
   core.io_slog_data(io_slog_data);
   core.io_debug_en(io_debug_en);