Refactor Kelvin's BUILD targets

- Split the giant ball of yarn that is the `kelvin` chisel library into
  a `base`, `scalar`, and `vector` chunk
- Pull some commonly used interfaces out into a new file that's part of
  the `base` library, and depended on by `scalar` and `vector`

Change-Id: Ibf8267064caf6983410280107d4fb750ce51a225
diff --git a/hdl/chisel/src/chai/BUILD b/hdl/chisel/src/chai/BUILD
index 1a1ffb5..2fe1b1e 100644
--- a/hdl/chisel/src/chai/BUILD
+++ b/hdl/chisel/src/chai/BUILD
@@ -26,6 +26,7 @@
     deps = [
         "//hdl/chisel/src/bus:bus",
         "//hdl/chisel/src/kelvin:kelvin",
+        "//hdl/chisel/src/kelvin:kelvin_params",
         "//hdl/chisel/src/matcha:matcha",
     ],
 )
diff --git a/hdl/chisel/src/kelvin/BUILD b/hdl/chisel/src/kelvin/BUILD
index fd14ade..d87939a 100644
--- a/hdl/chisel/src/kelvin/BUILD
+++ b/hdl/chisel/src/kelvin/BUILD
@@ -30,6 +30,7 @@
     ],
     deps = [
         ":kelvin",
+        ":kelvin_base",
         "//hdl/chisel/src/common:fma",
         "//hdl/chisel/src/common:fp",
     ],
@@ -43,6 +44,7 @@
     ],
     deps = [
         ":kelvin",
+        ":kelvin_base",
         ":kelvin_float",
         "//hdl/chisel/src/common:fp",
     ],
@@ -54,34 +56,32 @@
         "scalar/MluTest.scala",
     ],
     deps = [
-        ":kelvin",
+        ":kelvin_base",
+        ":kelvin_scalar",
     ],
 )
 
 chisel_library(
-    name = "kelvin",
+    name = "kelvin_base",
     srcs = [
         "ClockGate.scala",
-        "Core.scala",
         "DBus2Axi.scala",
         "DBusMux.scala",
+        "Interfaces.scala",
         "L1DCache.scala",
         "L1ICache.scala",
         "Library.scala",
         "Parameters.scala",
-        "scalar/Alu.scala",
-        "scalar/Bru.scala",
-        "scalar/Csr.scala",
-        "scalar/Debug.scala",
-        "scalar/Decode.scala",
-        "scalar/Dvu.scala",
-        "scalar/Fetch.scala",
-        "scalar/Flush.scala",
-        "scalar/Lsu.scala",
-        "scalar/Mlu.scala",
-        "scalar/Regfile.scala",
-        "scalar/SCore.scala",
-        "scalar/SLog.scala",
+    ],
+    deps = [
+        "//hdl/chisel/src/bus",
+        "//hdl/chisel/src/common",
+    ],
+)
+
+chisel_library(
+    name = "kelvin_vector",
+    srcs = [
         "vector/VAlu.scala",
         "vector/VAluInt.scala",
         "vector/VCmdq.scala",
@@ -102,6 +102,45 @@
         "vector/VSt.scala",
     ],
     deps = [
+        ":kelvin_base",
+        "//hdl/chisel/src/bus",
+        "//hdl/chisel/src/common",
+    ],
+)
+
+chisel_library(
+    name = "kelvin_scalar",
+    srcs = [
+        "scalar/Alu.scala",
+        "scalar/Bru.scala",
+        "scalar/Csr.scala",
+        "scalar/Debug.scala",
+        "scalar/Decode.scala",
+        "scalar/Dvu.scala",
+        "scalar/Fetch.scala",
+        "scalar/Flush.scala",
+        "scalar/Lsu.scala",
+        "scalar/Mlu.scala",
+        "scalar/Regfile.scala",
+        "scalar/SCore.scala",
+        "scalar/SLog.scala",
+    ],
+    deps = [
+        ":kelvin_base",
+        "//hdl/chisel/src/common",
+        "//hdl/chisel/src/common:instruction_buffer",
+    ],
+)
+
+chisel_library(
+    name = "kelvin",
+    srcs = [
+        "Core.scala",
+    ],
+    deps = [
+        ":kelvin_base",
+        ":kelvin_scalar",
+        ":kelvin_vector",
         "//hdl/chisel/src/bus",
         "//hdl/chisel/src/common",
     ],
diff --git a/hdl/chisel/src/kelvin/Interfaces.scala b/hdl/chisel/src/kelvin/Interfaces.scala
new file mode 100644
index 0000000..bf65a01
--- /dev/null
+++ b/hdl/chisel/src/kelvin/Interfaces.scala
@@ -0,0 +1,133 @@
+// 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.
+
+package kelvin
+
+import chisel3._
+import chisel3.util._
+
+object VInstOp extends ChiselEnum {
+  val GETVL = Value
+  val GETMAXVL = Value
+  val VLD = Value
+  val VST = Value
+  val VIOP = Value
+}
+
+class VInstCmd extends Bundle {
+  val addr = UInt(5.W)
+  val inst = UInt(32.W)
+  val op = VInstOp()
+}
+
+class VCoreIO(p: Parameters) extends Bundle {
+  // Decode cycle.
+  val vinst = Vec(p.instructionLanes, Flipped(Decoupled(new VInstCmd)))
+
+  // Execute cycle.
+  val rs = Vec(p.instructionLanes * 2, Flipped(new RegfileReadDataIO))
+  val rd = Vec(p.instructionLanes, Valid(Flipped(new RegfileWriteDataIO)))
+
+  // Status.
+  val mactive = Output(Bool())
+
+  // Faults.
+  val undef = Output(Bool())
+
+  val vrfwriteCount = Output(UInt(3.W))
+  val vstoreCount = Output(UInt(2.W))
+}
+
+class CsrInIO(p: Parameters) extends Bundle {
+  val value = Input(Vec(12, UInt(32.W)))
+}
+
+class CsrOutIO(p: Parameters) extends Bundle {
+  val value = Output(Vec(8, UInt(32.W)))
+}
+
+class CsrInOutIO(p: Parameters) extends Bundle {
+  val in  = new CsrInIO(p)
+  val out = new CsrOutIO(p)
+}
+
+class IBusIO(p: Parameters) extends Bundle {
+  // Control Phase.
+  val valid = Output(Bool())
+  val ready = Input(Bool())
+  val addr = Output(UInt(p.fetchAddrBits.W))
+  // Read Phase.
+  val rdata = Input(UInt(p.fetchDataBits.W))
+}
+
+class FetchInstruction(p: Parameters) extends Bundle {
+  val addr = UInt(p.programCounterBits.W)
+  val inst = UInt(p.instructionBits.W)
+  val brchFwd = Bool()
+}
+
+class FetchIO(p: Parameters) extends Bundle {
+  val lanes = Vec(p.instructionLanes, Decoupled(new FetchInstruction(p)))
+}
+
+class DBusIO(p: Parameters, bank: Boolean = false) extends Bundle {
+  // Control Phase.
+  val valid = Output(Bool())
+  val ready = Input(Bool())
+  val write = Output(Bool())
+  val addr = Output(UInt((p.lsuAddrBits - (if (bank) 1 else 0)).W))
+  val adrx = Output(UInt((p.lsuAddrBits - (if (bank) 1 else 0)).W))
+  val size = Output(UInt((log2Ceil(p.lsuDataBits / 8) + 1).W))
+  val wdata = Output(UInt(p.lsuDataBits.W))
+  val wmask = Output(UInt((p.lsuDataBits / 8).W))
+  // Read Phase.
+  val rdata = Input(UInt(p.lsuDataBits.W))
+}
+
+class IFlushIO(p: Parameters) extends Bundle {
+  val valid = Output(Bool())
+  val ready = Input(Bool())
+}
+
+class DFlushIO(p: Parameters) extends Bundle {
+  val valid = Output(Bool())
+  val ready = Input(Bool())
+  val all   = Output(Bool())  // all=0, see io.dbus.addr for line address.
+  val clean = Output(Bool())  // clean and flush
+}
+
+class SLogIO(p: Parameters) extends Bundle {
+  val valid = Output(Bool())
+  val addr = Output(UInt(5.W))
+  val data = Output(UInt(32.W))
+}
+
+// Debug signals for HDL development.
+class DebugIO(p: Parameters) extends Bundle {
+  val en = Output(UInt(4.W))
+  val addr = Vec(p.instructionLanes, UInt(32.W))
+  val inst = Vec(p.instructionLanes, UInt(32.W))
+  val cycles = Output(UInt(32.W))
+}
+
+class RegfileReadDataIO extends Bundle {
+  val valid = Output(Bool())
+  val data  = Output(UInt(32.W))
+}
+
+class RegfileWriteDataIO extends Bundle {
+  val addr  = Input(UInt(5.W))
+  val data  = Input(UInt(32.W))
+}
+
diff --git a/hdl/chisel/src/kelvin/scalar/Csr.scala b/hdl/chisel/src/kelvin/scalar/Csr.scala
index 7c0a34a..2d04c1f 100644
--- a/hdl/chisel/src/kelvin/scalar/Csr.scala
+++ b/hdl/chisel/src/kelvin/scalar/Csr.scala
@@ -35,19 +35,6 @@
   val User = Value(1.U(1.W))
 }
 
-class CsrInIO(p: Parameters) extends Bundle {
-  val value = Input(Vec(12, UInt(32.W)))
-}
-
-class CsrOutIO(p: Parameters) extends Bundle {
-  val value = Output(Vec(8, UInt(32.W)))
-}
-
-class CsrInOutIO(p: Parameters) extends Bundle {
-  val in  = new CsrInIO(p)
-  val out = new CsrOutIO(p)
-}
-
 class CsrCounters(p: Parameters) extends Bundle {
   val rfwriteCount = UInt(3.W)
   val storeCount = UInt(2.W)
diff --git a/hdl/chisel/src/kelvin/scalar/Debug.scala b/hdl/chisel/src/kelvin/scalar/Debug.scala
index d2123c6..2c676eb 100644
--- a/hdl/chisel/src/kelvin/scalar/Debug.scala
+++ b/hdl/chisel/src/kelvin/scalar/Debug.scala
@@ -18,10 +18,3 @@
 import chisel3.util._
 import common._
 
-// Debug signals for HDL development.
-class DebugIO(p: Parameters) extends Bundle {
-  val en = Output(UInt(4.W))
-  val addr = Vec(p.instructionLanes, UInt(32.W))
-  val inst = Vec(p.instructionLanes, UInt(32.W))
-  val cycles = Output(UInt(32.W))
-}
diff --git a/hdl/chisel/src/kelvin/scalar/Fetch.scala b/hdl/chisel/src/kelvin/scalar/Fetch.scala
index 86a47c4..c6928d5 100644
--- a/hdl/chisel/src/kelvin/scalar/Fetch.scala
+++ b/hdl/chisel/src/kelvin/scalar/Fetch.scala
@@ -30,24 +30,6 @@
   }
 }
 
-class IBusIO(p: Parameters) extends Bundle {
-  // Control Phase.
-  val valid = Output(Bool())
-  val ready = Input(Bool())
-  val addr = Output(UInt(p.fetchAddrBits.W))
-  // Read Phase.
-  val rdata = Input(UInt(p.fetchDataBits.W))
-}
-
-class FetchInstruction(p: Parameters) extends Bundle {
-  val addr = UInt(p.programCounterBits.W)
-  val inst = UInt(p.instructionBits.W)
-  val brchFwd = Bool()
-}
-
-class FetchIO(p: Parameters) extends Bundle {
-  val lanes = Vec(p.instructionLanes, Decoupled(new FetchInstruction(p)))
-}
 
 class Fetch(p: Parameters) extends Module {
   val io = IO(new Bundle {
diff --git a/hdl/chisel/src/kelvin/scalar/Flush.scala b/hdl/chisel/src/kelvin/scalar/Flush.scala
index 0766ee0..d6d0c54 100644
--- a/hdl/chisel/src/kelvin/scalar/Flush.scala
+++ b/hdl/chisel/src/kelvin/scalar/Flush.scala
@@ -18,18 +18,6 @@
 import chisel3.util._
 import common._
 
-class IFlushIO(p: Parameters) extends Bundle {
-  val valid = Output(Bool())
-  val ready = Input(Bool())
-}
-
-class DFlushIO(p: Parameters) extends Bundle {
-  val valid = Output(Bool())
-  val ready = Input(Bool())
-  val all   = Output(Bool())  // all=0, see io.dbus.addr for line address.
-  val clean = Output(Bool())  // clean and flush
-}
-
 class DFlushFenceiIO(p: Parameters) extends DFlushIO(p) {
   val fencei = Output(Bool())
 }
diff --git a/hdl/chisel/src/kelvin/scalar/Lsu.scala b/hdl/chisel/src/kelvin/scalar/Lsu.scala
index 8d88202..d52b003 100644
--- a/hdl/chisel/src/kelvin/scalar/Lsu.scala
+++ b/hdl/chisel/src/kelvin/scalar/Lsu.scala
@@ -24,20 +24,6 @@
   }
 }
 
-class DBusIO(p: Parameters, bank: Boolean = false) extends Bundle {
-  // Control Phase.
-  val valid = Output(Bool())
-  val ready = Input(Bool())
-  val write = Output(Bool())
-  val addr = Output(UInt((p.lsuAddrBits - (if (bank) 1 else 0)).W))
-  val adrx = Output(UInt((p.lsuAddrBits - (if (bank) 1 else 0)).W))
-  val size = Output(UInt((log2Ceil(p.lsuDataBits / 8) + 1).W))
-  val wdata = Output(UInt(p.lsuDataBits.W))
-  val wmask = Output(UInt((p.lsuDataBits / 8).W))
-  // Read Phase.
-  val rdata = Input(UInt(p.lsuDataBits.W))
-}
-
 object LsuOp extends ChiselEnum {
   val LB  = Value
   val LH  = Value
diff --git a/hdl/chisel/src/kelvin/scalar/Regfile.scala b/hdl/chisel/src/kelvin/scalar/Regfile.scala
index 2ec8351..055977b 100644
--- a/hdl/chisel/src/kelvin/scalar/Regfile.scala
+++ b/hdl/chisel/src/kelvin/scalar/Regfile.scala
@@ -39,21 +39,11 @@
   val value = Input(UInt(32.W))
 }
 
-class RegfileReadDataIO extends Bundle {
-  val valid = Output(Bool())
-  val data  = Output(UInt(32.W))
-}
-
 class RegfileWriteAddrIO extends Bundle {
   val valid = Input(Bool())
   val addr  = Input(UInt(5.W))
 }
 
-class RegfileWriteDataIO extends Bundle {
-  val addr  = Input(UInt(5.W))
-  val data  = Input(UInt(32.W))
-}
-
 class RegfileBusAddrIO extends Bundle {
   val valid = Input(Bool())
   val bypass = Input(Bool())
diff --git a/hdl/chisel/src/kelvin/scalar/SLog.scala b/hdl/chisel/src/kelvin/scalar/SLog.scala
index b756821..99b7a87 100644
--- a/hdl/chisel/src/kelvin/scalar/SLog.scala
+++ b/hdl/chisel/src/kelvin/scalar/SLog.scala
@@ -19,8 +19,3 @@
 import common._
 
 // Scalar instrumentation logging (printf).
-class SLogIO(p: Parameters) extends Bundle {
-  val valid = Output(Bool())
-  val addr = Output(UInt(5.W))
-  val data = Output(UInt(32.W))
-}
diff --git a/hdl/chisel/src/kelvin/vector/VCore.scala b/hdl/chisel/src/kelvin/vector/VCore.scala
index 52cba52..a85b829 100644
--- a/hdl/chisel/src/kelvin/vector/VCore.scala
+++ b/hdl/chisel/src/kelvin/vector/VCore.scala
@@ -28,24 +28,6 @@
   }
 }
 
-class VCoreIO(p: Parameters) extends Bundle {
-  // Decode cycle.
-  val vinst = Vec(p.instructionLanes, Flipped(Decoupled(new VInstCmd)))
-
-  // Execute cycle.
-  val rs = Vec(p.instructionLanes * 2, Flipped(new RegfileReadDataIO))
-  val rd = Vec(p.instructionLanes, Valid(Flipped(new RegfileWriteDataIO)))
-
-  // Status.
-  val mactive = Output(Bool())
-
-  // Faults.
-  val undef = Output(Bool())
-
-  val vrfwriteCount = Output(UInt(3.W))
-  val vstoreCount = Output(UInt(2.W))
-}
-
 class VCore(p: Parameters) extends Module {
   val io = IO(new Bundle {
     // Score <> VCore
diff --git a/hdl/chisel/src/kelvin/vector/VInst.scala b/hdl/chisel/src/kelvin/vector/VInst.scala
index ebd5976..00811a1 100644
--- a/hdl/chisel/src/kelvin/vector/VInst.scala
+++ b/hdl/chisel/src/kelvin/vector/VInst.scala
@@ -26,20 +26,6 @@
   }
 }
 
-object VInstOp extends ChiselEnum {
-  val GETVL = Value
-  val GETMAXVL = Value
-  val VLD = Value
-  val VST = Value
-  val VIOP = Value
-}
-
-class VInstCmd extends Bundle {
-  val addr = UInt(5.W)
-  val inst = UInt(32.W)
-  val op = VInstOp()
-}
-
 class VectorInstructionIO(p: Parameters) extends Bundle {
   val valid = Output(Bool())
   val ready = Input(Bool())
diff --git a/hdl/chisel/src/matcha/BUILD b/hdl/chisel/src/matcha/BUILD
index 16caad5..f537a71 100644
--- a/hdl/chisel/src/matcha/BUILD
+++ b/hdl/chisel/src/matcha/BUILD
@@ -28,6 +28,7 @@
         "//hdl/chisel/src/bus:bus",
         "//hdl/chisel/src/common:common",
         "//hdl/chisel/src/kelvin:kelvin",
+        "//hdl/chisel/src/kelvin:kelvin_base",
     ],
 )