[fpga] Reduce noise for AES SCA

This commit contains the following changes to reduce the noise during
AES SCA experiments:
- A delay to the manual AES trigger is added to allow Ibex going into
  sleep (wfi) before the measurement starts.
- The reseeding of AES-internal PRNGs is disabled using a parameter.
- In the aes_serial application, the entropy complex (ES, CSRNG, EDN0/1)
  is disabled. This is only possible as the AES PRNGs aren't reseeded
  in this setup anymore.
- USB, HMAC, KMAC and OTBN clocks are disabled in the aes_serial
  application.

Signed-off-by: Pirmin Vogel <vogelpi@lowrisc.org>
diff --git a/hw/top_earlgrey/rtl/autogen/chip_earlgrey_cw310.sv b/hw/top_earlgrey/rtl/autogen/chip_earlgrey_cw310.sv
index 4870180..974b01f 100644
--- a/hw/top_earlgrey/rtl/autogen/chip_earlgrey_cw310.sv
+++ b/hw/top_earlgrey/rtl/autogen/chip_earlgrey_cw310.sv
@@ -748,6 +748,9 @@
   top_earlgrey #(
     .AesMasking(1'b1),
     .AesSBoxImpl(aes_pkg::SBoxImplDom),
+    .SecAesStartTriggerDelay(40),
+    .SecAesAllowForcingMasks(1'b1),
+    .SecAesSkipPRNGReseeding(1'b1),
     .KmacEnMasking(0),
     .CsrngSBoxImpl(aes_pkg::SBoxImplLut),
     .OtbnRegFile(otbn_pkg::RegFileFPGA),
diff --git a/sw/device/sca/aes_serial.c b/sw/device/sca/aes_serial.c
index a6cd8c0..50bee15 100644
--- a/sw/device/sca/aes_serial.c
+++ b/sw/device/sca/aes_serial.c
@@ -205,6 +205,9 @@
 
   LOG_INFO("Running AES serial");
 
+  LOG_INFO("Disabling entropy complex and unneeded clocks to reduce noise.");
+  sca_reduce_noise();
+
   LOG_INFO("Initializing simple serial interface to capture board.");
   simple_serial_init(uart1);
   simple_serial_register_handler('k', aes_serial_set_key);
diff --git a/sw/device/sca/lib/meson.build b/sw/device/sca/lib/meson.build
index 251aeed..3c9e9c9 100644
--- a/sw/device/sca/lib/meson.build
+++ b/sw/device/sca/lib/meson.build
@@ -5,8 +5,15 @@
 sw_sca_lib_sca  = declare_dependency(
   link_with: static_library(
     'lib_sca',
-    sources: ['sca.c'],
+    sources: [
+      'sca.c',
+      hw_ip_csrng_reg_h,
+      hw_ip_edn_reg_h,
+      hw_ip_clkmgr_reg_h,
+    ],
     dependencies: [
+      sw_lib_dif_clkmgr,
+      sw_lib_dif_entropy,
       sw_lib_dif_gpio,
       sw_lib_dif_rv_timer,
       sw_lib_dif_uart,
diff --git a/sw/device/sca/lib/sca.c b/sw/device/sca/lib/sca.c
index 758d330..9e732a8 100644
--- a/sw/device/sca/lib/sca.c
+++ b/sw/device/sca/lib/sca.c
@@ -5,6 +5,8 @@
 #include "sw/device/sca/lib/sca.h"
 
 #include "sw/device/lib/arch/device.h"
+#include "sw/device/lib/dif/dif_clkmgr.h"
+#include "sw/device/lib/dif/dif_entropy.h"
 #include "sw/device/lib/dif/dif_gpio.h"
 #include "sw/device/lib/dif/dif_rv_timer.h"
 #include "sw/device/lib/dif/dif_uart.h"
@@ -14,6 +16,9 @@
 #include "sw/device/lib/runtime/hart.h"
 #include "sw/device/lib/runtime/print.h"
 
+#include "clkmgr_regs.h"  // Generated
+#include "csrng_regs.h"   // Generated
+#include "edn_regs.h"     // Generated
 #include "hw/top_earlgrey/sw/autogen/top_earlgrey.h"
 
 /**
@@ -131,6 +136,47 @@
   sca_init_timer();
 }
 
+void sca_reduce_noise() {
+  // Disable/stopping functionality not yet provided by EDN and CSRNG DIFs.
+  mmio_region_write32(mmio_region_from_addr(TOP_EARLGREY_EDN0_BASE_ADDR),
+                      EDN_CTRL_REG_OFFSET, EDN_CTRL_REG_RESVAL);
+  mmio_region_write32(mmio_region_from_addr(TOP_EARLGREY_EDN1_BASE_ADDR),
+                      EDN_CTRL_REG_OFFSET, EDN_CTRL_REG_RESVAL);
+  mmio_region_write32(mmio_region_from_addr(TOP_EARLGREY_CSRNG_BASE_ADDR),
+                      CSRNG_CTRL_REG_OFFSET, CSRNG_CTRL_REG_RESVAL);
+
+  // Disable entropy source through DIF.
+  const dif_entropy_params_t entropy_params = {
+      .base_addr = mmio_region_from_addr(TOP_EARLGREY_ENTROPY_SRC_BASE_ADDR),
+  };
+  dif_entropy_t entropy;
+  IGNORE_RESULT(dif_entropy_init(entropy_params, &entropy) == kDifEntropyOk);
+  IGNORE_RESULT(dif_entropy_disable(&entropy) == kDifEntropyOk);
+
+  // Disable HMAC, KMAC, OTBN and USB clocks through CLKMGR DIF.
+  const dif_clkmgr_params_t clkmgr_params = {
+      .base_addr = mmio_region_from_addr(TOP_EARLGREY_CLKMGR_AON_BASE_ADDR),
+      .last_gateable_clock = CLKMGR_CLK_ENABLES_CLK_USB_PERI_EN_BIT,
+      .last_hintable_clock = CLKMGR_CLK_HINTS_STATUS_CLK_MAIN_OTBN_VAL_BIT};
+  dif_clkmgr_t clkmgr;
+  IGNORE_RESULT(dif_clkmgr_init(clkmgr_params, &clkmgr) == kDifClkmgrOk);
+  IGNORE_RESULT(dif_clkmgr_hintable_clock_set_hint(
+                    &clkmgr, CLKMGR_CLK_HINTS_CLK_MAIN_HMAC_HINT_BIT,
+                    kDifClkmgrToggleDisabled) == kDifClkmgrOk);
+  IGNORE_RESULT(dif_clkmgr_hintable_clock_set_hint(
+                    &clkmgr, CLKMGR_CLK_HINTS_CLK_MAIN_KMAC_HINT_BIT,
+                    kDifClkmgrToggleDisabled) == kDifClkmgrOk);
+  IGNORE_RESULT(dif_clkmgr_hintable_clock_set_hint(
+                    &clkmgr, CLKMGR_CLK_HINTS_CLK_IO_DIV4_OTBN_HINT_BIT,
+                    kDifClkmgrToggleDisabled) == kDifClkmgrOk);
+  IGNORE_RESULT(dif_clkmgr_hintable_clock_set_hint(
+                    &clkmgr, CLKMGR_CLK_HINTS_CLK_MAIN_OTBN_HINT_BIT,
+                    kDifClkmgrToggleDisabled) == kDifClkmgrOk);
+  IGNORE_RESULT(dif_clkmgr_gateable_clock_set_enabled(
+                    &clkmgr, CLKMGR_CLK_ENABLES_CLK_USB_PERI_EN_BIT,
+                    kDifClkmgrToggleDisabled) == kDifClkmgrOk);
+}
+
 void sca_get_uart(const dif_uart_t **uart_out) { *uart_out = &uart1; }
 
 void sca_set_trigger_high() {
diff --git a/sw/device/sca/lib/sca.h b/sw/device/sca/lib/sca.h
index 6ade58b..cd007d9 100644
--- a/sw/device/sca/lib/sca.h
+++ b/sw/device/sca/lib/sca.h
@@ -5,10 +5,10 @@
 #ifndef OPENTITAN_SW_DEVICE_SCA_LIB_SCA_H_
 #define OPENTITAN_SW_DEVICE_SCA_LIB_SCA_H_
 
-#include "sw/device/lib/dif/dif_uart.h"
-
 #include <stdint.h>
 
+#include "sw/device/lib/dif/dif_uart.h"
+
 /**
  * @file
  * @brief Side-channel analysis support library.
@@ -20,6 +20,16 @@
 void sca_init(void);
 
 /**
+ * Disables the entropy complex and clocks of IPs not needed for SCA to reduce
+ * noise in the power traces.
+ *
+ * We can only disable the entropy complex as AES features a parameter to skip
+ * PRNG reseeding for SCA experiments. Without this parameter, AES would simply
+ * get stalled with a disabled entropy complex.
+ */
+void sca_reduce_noise(void);
+
+/**
  * Returns a handle to the intialized UART device.
  *
  * @param[out] uart_out Handle to the initialized UART device.
diff --git a/util/topgen/templates/chiplevel.sv.tpl b/util/topgen/templates/chiplevel.sv.tpl
index 5426c00..e6ee5cc 100644
--- a/util/topgen/templates/chiplevel.sv.tpl
+++ b/util/topgen/templates/chiplevel.sv.tpl
@@ -1067,6 +1067,9 @@
 % if target["name"] == "cw310":
     .AesMasking(1'b1),
     .AesSBoxImpl(aes_pkg::SBoxImplDom),
+    .SecAesStartTriggerDelay(40),
+    .SecAesAllowForcingMasks(1'b1),
+    .SecAesSkipPRNGReseeding(1'b1),
     .KmacEnMasking(0),
     .CsrngSBoxImpl(aes_pkg::SBoxImplLut),
     .OtbnRegFile(otbn_pkg::RegFileFPGA),