ClockGate wraps lowrisc's prim_clock_gating

- By default, this primitive provides a generic clock gate for
  simulation. There's also a preprocessor define that can be set at
  synth time, to get a Xilinx-specific gate implementation.

Change-Id: I011f3b6211ef27be4458d7c312ac06823e0b1edb
diff --git a/hdl/chisel/BUILD b/hdl/chisel/BUILD
index 88cf0d0..f32c099 100644
--- a/hdl/chisel/BUILD
+++ b/hdl/chisel/BUILD
@@ -17,14 +17,14 @@
     srcs = [
         "//hdl/chisel/src/matcha:Kelvin.sv",
         "//hdl/chisel/src/matcha:Crossbar.sv",
-        "//hdl/verilog:ClockGate.v",
+        "//hdl/verilog:ClockGate.sv",
         "//hdl/verilog:Sram_1rw_256x256.v",
         "//hdl/verilog:Sram_1rwm_256x288.v",
     ],
     outs = [
         "kelvin.sv",
         "crossbar.sv",
-        "ClockGate.v",
+        "ClockGate.sv",
         "Sram_1rw_256x256.v",
         "Sram_1rwm_256x288.v",
     ],
@@ -41,7 +41,7 @@
 \\`define ASSERT_VERBOSE_COND 0
 " > $(location crossbar.sv)
     cat $(location //hdl/chisel/src/matcha:Crossbar.sv) >> $(location crossbar.sv)
-    cp -f $(location //hdl/verilog:ClockGate.v) $(location ClockGate.v)
+    cp -f $(location //hdl/verilog:ClockGate.sv) $(location ClockGate.sv)
     cp -f $(location //hdl/verilog:Sram_1rw_256x256.v) $(location Sram_1rw_256x256.v)
     cp -f $(location //hdl/verilog:Sram_1rwm_256x288.v) $(location Sram_1rwm_256x288.v)
     """,
diff --git a/hdl/chisel/kelvin.core.in b/hdl/chisel/kelvin.core.in
index e8d61c6..95f7fa3 100644
--- a/hdl/chisel/kelvin.core.in
+++ b/hdl/chisel/kelvin.core.in
@@ -8,7 +8,7 @@
   files_rtl:
     files:
       - kelvin.sv
-      - ClockGate.v
+      - ClockGate.sv
       - Sram_1rw_256x256.v
       - Sram_1rwm_256x288.v
     file_type: systemVerilogSource
diff --git a/hdl/verilog/BUILD b/hdl/verilog/BUILD
index 802e2db..63f4925 100644
--- a/hdl/verilog/BUILD
+++ b/hdl/verilog/BUILD
@@ -16,7 +16,7 @@
 
 exports_files(
     srcs = [
-        "ClockGate.v",
+        "ClockGate.sv",
         "Sram_1rw_256x256.v",
         "Sram_1rwm_256x288.v",
     ],
@@ -25,7 +25,10 @@
 
 verilog_library(
     name = "clock_gate",
-    srcs = ["ClockGate.v"],
+    srcs = ["ClockGate.sv"],
+    deps = [
+        "//third_party/ip/lowrisc:prim",
+    ],
     visibility = ["//visibility:public"],
 )
 
diff --git a/hdl/verilog/ClockGate.v b/hdl/verilog/ClockGate.sv
similarity index 67%
rename from hdl/verilog/ClockGate.v
rename to hdl/verilog/ClockGate.sv
index f6b9e7c..02c7f09 100644
--- a/hdl/verilog/ClockGate.v
+++ b/hdl/verilog/ClockGate.sv
@@ -17,22 +17,12 @@
   input         enable,  // '1' passthrough, '0' disable.
   output        clk_o
 );
-// Note: Bypass clock gate for now. It causes FPGA build failures and
-// simulation issues
-assign clk_o = clk_i;
-/*
-reg clk_en;
-`ifdef FPGA
-    assign clk_o = clk_i;
-`else
-    // Capture 'enable' during low phase of the clock.
-    always @(clk_i or enable)
-    begin
-      if (~clk_i)
-      clk_en = enable;
-    end
 
-  assign clk_o = clk_i & clk_en;
-`endif
-*/
+prim_clock_gating u_cg(
+  .clk_i(clk_i),
+  .en_i(enable),
+  .test_en_i('0),
+  .clk_o(clk_o)
+);
+
 endmodule  // ClockGate
diff --git a/rules/repos.bzl b/rules/repos.bzl
index b6e8e55..e57dc73 100644
--- a/rules/repos.bzl
+++ b/rules/repos.bzl
@@ -80,3 +80,14 @@
         urls = ["https://repo1.maven.org/maven2/org/chipsalliance/llvm-firtool/1.52.0/llvm-firtool-1.52.0.jar"],
         build_file = "@kelvin_hw//third_party/llvm-firtool:BUILD.bazel",
     )
+
+    http_archive(
+        name = "lowrisc_opentitan",
+        sha256 = "cffed2c3c9c026ecb0b14a48b6cc300aa145bb2a316903dcb4cb7976ca8857af",
+        strip_prefix = "opentitan-f243e6802143374741739d2c164c4f2f61697669",
+        urls = ["https://github.com/lowrisc/opentitan/archive/f243e6802143374741739d2c164c4f2f61697669.zip"],
+        patches = [
+            "@kelvin_hw//third_party/ip/lowrisc:0001-Add-BUILD.bazel.patch",
+        ],
+        patch_args = ["-p1"],
+    )
diff --git a/third_party/ip/lowrisc/0001-Add-BUILD.bazel.patch b/third_party/ip/lowrisc/0001-Add-BUILD.bazel.patch
new file mode 100644
index 0000000..2ab35be
--- /dev/null
+++ b/third_party/ip/lowrisc/0001-Add-BUILD.bazel.patch
@@ -0,0 +1,37 @@
+From 35d1dec2153a5d5e9f45d86215708d046d05f85a Mon Sep 17 00:00:00 2001
+From: Alex Van Damme <atv@google.com>
+Date: Thu, 15 Feb 2024 11:25:11 -0800
+Subject: [PATCH 1/3] Add BUILD.bazel
+
+---
+ hw/BUILD.bazel | 18 ++++++++++++++++++
+ 1 file changed, 18 insertions(+)
+ create mode 100644 hw/BUILD.bazel
+
+diff --git a/hw/BUILD.bazel b/hw/BUILD.bazel
+new file mode 100644
+index 0000000000..7f502f35ea
+--- /dev/null
++++ b/hw/BUILD.bazel
+@@ -0,0 +1,18 @@
++# 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.
++
++exports_files(
++    glob(["vendor/lowrisc_ibex/dv/uvm/core_ibex/common/prim/*.sv*"]),
++)
++
+-- 
+2.43.0.687.g38aa6559b0-goog
+
diff --git a/third_party/ip/lowrisc/BUILD b/third_party/ip/lowrisc/BUILD
new file mode 100644
index 0000000..8eb1241
--- /dev/null
+++ b/third_party/ip/lowrisc/BUILD
@@ -0,0 +1,45 @@
+# 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.
+
+load("@rules_hdl//verilog:providers.bzl", "verilog_library")
+
+verilog_library(
+    name = "prim_generic",
+    srcs = [
+        "@lowrisc_opentitan//hw/ip/prim_generic:rtl/prim_generic_clock_gating.sv",
+    ],
+    visibility = ["//visibility:public"],
+)
+
+verilog_library(
+    name = "prim_xilinx",
+    srcs = [
+        "@lowrisc_opentitan//hw/ip/prim_xilinx:rtl/prim_xilinx_clock_gating.sv",
+    ],
+    visibility = ["//visibility:public"],
+)
+
+verilog_library(
+    name = "prim",
+    # Do not sort: "*_pkg" comes first.
+    srcs = [
+        "@lowrisc_opentitan//hw:vendor/lowrisc_ibex/dv/uvm/core_ibex/common/prim/prim_pkg.sv",
+        "@lowrisc_opentitan//hw:vendor/lowrisc_ibex/dv/uvm/core_ibex/common/prim/prim_clock_gating.sv",
+    ],
+    deps = [
+        ":prim_generic",
+        ":prim_xilinx",
+    ],
+    visibility = ["//visibility:public"],
+)