Merge "Add Zero Forcing for for power saving"
diff --git a/hdl/chisel/src/common/BUILD b/hdl/chisel/src/common/BUILD
index 78e3391..6b6147a 100644
--- a/hdl/chisel/src/common/BUILD
+++ b/hdl/chisel/src/common/BUILD
@@ -12,8 +12,12 @@
# See the License for the specific language governing permissions and
# limitations under the License.
-load("@kelvin_hw//rules:chisel.bzl",
- "chisel_cc_library", "chisel_library", "chisel_test")
+load(
+ "@kelvin_hw//rules:chisel.bzl",
+ "chisel_cc_library",
+ "chisel_library",
+ "chisel_test",
+)
chisel_library(
name = "library",
@@ -26,21 +30,21 @@
chisel_library(
name = "common",
srcs = [
- "FifoXe.scala",
- "FifoX.scala",
- "FifoIxO.scala",
"Fifo.scala",
+ "FifoIxO.scala",
+ "FifoX.scala",
+ "FifoXe.scala",
"IDiv.scala",
"MathUtil.scala",
"Slice.scala",
],
- deps = [
- ":library",
- ],
+ visibility = ["//visibility:public"],
exports = [
":library",
],
- visibility = ["//visibility:public"],
+ deps = [
+ ":library",
+ ],
)
chisel_library(
@@ -48,10 +52,10 @@
srcs = [
"Fp.scala",
],
+ visibility = ["//visibility:public"],
deps = [
":library",
],
- visibility = ["//visibility:public"],
)
chisel_library(
@@ -59,11 +63,11 @@
srcs = [
"FpTestUtils.scala",
],
- deps = [
- "@edu_berkeley_cs_chiseltest//jar",
- ":fp",
- ],
visibility = ["//visibility:public"],
+ deps = [
+ ":fp",
+ "@edu_berkeley_cs_chiseltest//jar",
+ ],
)
chisel_test(
@@ -77,16 +81,27 @@
],
)
+chisel_test(
+ name = "library_test",
+ srcs = [
+ "LibraryTest.scala",
+ ],
+ deps = [
+ ":library",
+ # ":fp_test_utils",
+ ],
+)
+
chisel_library(
name = "fma",
srcs = [
"Fma.scala",
],
+ visibility = ["//visibility:public"],
deps = [
":common",
":fp",
],
- visibility = ["//visibility:public"],
)
chisel_test(
@@ -95,7 +110,7 @@
"FmaTest.scala",
],
deps = [
- ":fp",
":fma",
+ ":fp",
],
)
diff --git a/hdl/chisel/src/common/Library.scala b/hdl/chisel/src/common/Library.scala
index 381519f..5e31771 100644
--- a/hdl/chisel/src/common/Library.scala
+++ b/hdl/chisel/src/common/Library.scala
@@ -36,8 +36,19 @@
}
}
+// Gate the bits of an interface based on it's validity bit. This prevents
+// invalid data from propagating down stream, thus reducing dynamic power
+object ForceZero {
+ def apply[T <: Data](input: ValidIO[T]): ValidIO[T] = {
+ val result = Wire(chiselTypeOf(input))
+ result.valid := input.valid
+ result.bits := Mux(input.valid, input.bits, 0.U.asTypeOf(input).bits)
+ result
+ }
+}
+
object Clz {
def apply(bits: UInt): UInt = {
PriorityEncoder(Cat(1.U(1.W), Reverse(bits)))
}
-}
\ No newline at end of file
+}
diff --git a/hdl/chisel/src/common/LibraryTest.scala b/hdl/chisel/src/common/LibraryTest.scala
new file mode 100644
index 0000000..346e831
--- /dev/null
+++ b/hdl/chisel/src/common/LibraryTest.scala
@@ -0,0 +1,50 @@
+// 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 common
+
+import chisel3._
+import chisel3.util._
+import chiseltest._
+import org.scalatest.freespec.AnyFreeSpec
+import chisel3.experimental.BundleLiterals._
+
+class ForceZeroTester extends Module {
+ val io = IO(new Bundle {
+ val in = Input(Valid(SInt(32.W)))
+ val out = Output(Valid(SInt(32.W)))
+ })
+
+ io.out := ForceZero(io.in)
+}
+
+class LibrarySpec extends AnyFreeSpec with ChiselScalatestTester {
+ "ForceZero when invalid" in {
+ test(new ForceZeroTester) { dut =>
+ dut.io.in.bits.poke(9001)
+ dut.io.in.valid.poke(0)
+ dut.clock.step()
+ assertResult(0) { dut.io.out.bits.peekInt() }
+ }
+ }
+
+ "ForceZeroForceZero propogates when valid" in {
+ test(new ForceZeroTester) { dut =>
+ dut.io.in.bits.poke(9001)
+ dut.io.in.valid.poke(1)
+ dut.clock.step()
+ assertResult(9001) { dut.io.out.bits.peekInt() }
+ }
+ }
+}