Merge "Add top_matcha_smc_irq.h for cantrip."
diff --git a/hw/top_matcha/sw/autogen/top_matcha_smc_irq.h b/hw/top_matcha/sw/autogen/top_matcha_smc_irq.h
new file mode 100644
index 0000000..76dc6ae
--- /dev/null
+++ b/hw/top_matcha/sw/autogen/top_matcha_smc_irq.h
@@ -0,0 +1,72 @@
+// Copyright Google Inc.
+// Licensed under the Apache License, Version 2.0, see LICENSE for details.
+// SPDX-License-Identifier: Apache-2.0
+
+#ifndef MATCHA_HW_TOP_MATCHA_SW_AUTOGEN_TOP_MATCHA_IRQ_H_
+#define MATCHA_HW_TOP_MATCHA_SW_AUTOGEN_TOP_MATCHA_IRQ_H_
+
+/**
+ * @file
+ * @brief Assembler-only Top-specific Definitions
+ *
+ * This file contains preprocessor definitions for use within assembly code.
+ */
+
+#ifdef __ASSEMBLER__
+
+/**
+ * SMC PLIC Interrupt Source.
+ *
+ * Enumeration of all SMC PLIC interrupt sources. The interrupt sources belonging to
+ * the same peripheral are guaranteed to be consecutive.
+ */
+#define TOP_MATCHA_PLIC_IRQ_ID_NONE_SMC 0 /**< No Interrupt */
+#define TOP_MATCHA_PLIC_IRQ_ID_SMC_UART_TX_WATERMARK 1 /**< smc_uart_tx_watermark */
+#define TOP_MATCHA_PLIC_IRQ_ID_SMC_UART_RX_WATERMARK 2 /**< smc_uart_rx_watermark */
+#define TOP_MATCHA_PLIC_IRQ_ID_SMC_UART_TX_EMPTY 3 /**< smc_uart_tx_empty */
+#define TOP_MATCHA_PLIC_IRQ_ID_SMC_UART_RX_OVERFLOW 4 /**< smc_uart_rx_overflow */
+#define TOP_MATCHA_PLIC_IRQ_ID_SMC_UART_RX_FRAME_ERR 5 /**< smc_uart_rx_frame_err */
+#define TOP_MATCHA_PLIC_IRQ_ID_SMC_UART_RX_BREAK_ERR 6 /**< smc_uart_rx_break_err */
+#define TOP_MATCHA_PLIC_IRQ_ID_SMC_UART_RX_TIMEOUT 7 /**< smc_uart_rx_timeout */
+#define TOP_MATCHA_PLIC_IRQ_ID_SMC_UART_RX_PARITY_ERR 8 /**< smc_uart_rx_parity_err */
+#define TOP_MATCHA_PLIC_IRQ_ID_RV_TIMER_SMC_TIMER_EXPIRED_HART0_TIMER0 9 /**< rv_timer_smc_timer_expired_hart0_timer0 */
+#define TOP_MATCHA_PLIC_IRQ_ID_CAM_I2C_FMT_THRESHOLD 10 /**< cam_i2c_fmt_threshold */
+#define TOP_MATCHA_PLIC_IRQ_ID_CAM_I2C_RX_THRESHOLD 11 /**< cam_i2c_rx_threshold */
+#define TOP_MATCHA_PLIC_IRQ_ID_CAM_I2C_FMT_OVERFLOW 12 /**< cam_i2c_fmt_overflow */
+#define TOP_MATCHA_PLIC_IRQ_ID_CAM_I2C_RX_OVERFLOW 13 /**< cam_i2c_rx_overflow */
+#define TOP_MATCHA_PLIC_IRQ_ID_CAM_I2C_NAK 14 /**< cam_i2c_nak */
+#define TOP_MATCHA_PLIC_IRQ_ID_CAM_I2C_SCL_INTERFERENCE 15 /**< cam_i2c_scl_interference */
+#define TOP_MATCHA_PLIC_IRQ_ID_CAM_I2C_SDA_INTERFERENCE 16 /**< cam_i2c_sda_interference */
+#define TOP_MATCHA_PLIC_IRQ_ID_CAM_I2C_STRETCH_TIMEOUT 17 /**< cam_i2c_stretch_timeout */
+#define TOP_MATCHA_PLIC_IRQ_ID_CAM_I2C_SDA_UNSTABLE 18 /**< cam_i2c_sda_unstable */
+#define TOP_MATCHA_PLIC_IRQ_ID_CAM_I2C_CMD_COMPLETE 19 /**< cam_i2c_cmd_complete */
+#define TOP_MATCHA_PLIC_IRQ_ID_CAM_I2C_TX_STRETCH 20 /**< cam_i2c_tx_stretch */
+#define TOP_MATCHA_PLIC_IRQ_ID_CAM_I2C_TX_OVERFLOW 21 /**< cam_i2c_tx_overflow */
+#define TOP_MATCHA_PLIC_IRQ_ID_CAM_I2C_ACQ_FULL 22 /**< cam_i2c_acq_full */
+#define TOP_MATCHA_PLIC_IRQ_ID_CAM_I2C_UNEXP_STOP 23 /**< cam_i2c_unexp_stop */
+#define TOP_MATCHA_PLIC_IRQ_ID_CAM_I2C_HOST_TIMEOUT 24 /**< cam_i2c_host_timeout */
+#define TOP_MATCHA_PLIC_IRQ_ID_CAM_CTRL_CAM_MOTION_DETECT 25 /**< cam_ctrl_cam_motion_detect */
+#define TOP_MATCHA_PLIC_IRQ_ID_ISP_WRAPPER_ISP 26 /**< isp_wrapper_isp */
+#define TOP_MATCHA_PLIC_IRQ_ID_ISP_WRAPPER_MI 27 /**< isp_wrapper_mi */
+#define TOP_MATCHA_PLIC_IRQ_ID_DMA_SMC_WRITER_DONE 28 /**< dma_smc_writer_done */
+#define TOP_MATCHA_PLIC_IRQ_ID_DMA_SMC_READER_DONE 29 /**< dma_smc_reader_done */
+#define TOP_MATCHA_PLIC_IRQ_ID_TLUL_MAILBOX_SMC_WTIRQ 30 /**< tlul_mailbox_smc_wtirq */
+#define TOP_MATCHA_PLIC_IRQ_ID_TLUL_MAILBOX_SMC_RTIRQ 31 /**< tlul_mailbox_smc_rtirq */
+#define TOP_MATCHA_PLIC_IRQ_ID_TLUL_MAILBOX_SMC_EIRQ 32 /**< tlul_mailbox_smc_eirq */
+#define TOP_MATCHA_PLIC_IRQ_ID_ML_TOP_HOST_REQ 33 /**< ml_top_host_req */
+#define TOP_MATCHA_PLIC_IRQ_ID_ML_TOP_FINISH 34 /**< ml_top_finish */
+#define TOP_MATCHA_PLIC_IRQ_ID_ML_TOP_FAULT 35 /**< ml_top_fault */
+#define TOP_MATCHA_PLIC_IRQ_ID_ML_TOP_DATA_FAULT 36 /**< ml_top_data_fault */
+#define TOP_MATCHA_PLIC_IRQ_ID_SPI_HOST2_ERROR 37 /**< spi_host2_error */
+#define TOP_MATCHA_PLIC_IRQ_ID_SPI_HOST2_SPI_EVENT 38 /**< spi_host2_spi_event */
+#define TOP_MATCHA_PLIC_IRQ_ID_RV_TIMER_SMC2_TIMER_EXPIRED_HART0_TIMER0 39 /**< rv_timer_smc2_timer_expired_hart0_timer0 */
+#define TOP_MATCHA_PLIC_IRQ_ID_I2S0_TX_WATERMARK 40 /**< i2s0_tx_watermark */
+#define TOP_MATCHA_PLIC_IRQ_ID_I2S0_RX_WATERMARK 41 /**< i2s0_rx_watermark */
+#define TOP_MATCHA_PLIC_IRQ_ID_I2S0_TX_EMPTY 42 /**< i2s0_tx_empty */
+#define TOP_MATCHA_PLIC_IRQ_ID_I2S0_RX_OVERFLOW 43 /**< i2s0_rx_overflow */
+#define TOP_MATCHA_PLIC_IRQ_ID_LAST_SMC 43 /**< \internal The Last Valid Interrupt ID. */
+
+
+#endif  // __ASSEMBLER__
+
+#endif  // MATCHA_HW_TOP_MATCHA_SW_AUTOGEN_TOP_MATCHA_IRQ_H_
diff --git a/util/topgen_matcha.py b/util/topgen_matcha.py
index f86a27b..117f153 100755
--- a/util/topgen_matcha.py
+++ b/util/topgen_matcha.py
@@ -1414,6 +1414,12 @@
                             memory_cheader_path,
                             helper=c_helper)
 
+            # "toplevel_smc_irq.h.tpl" -> "sw/autogen/top_{topname}_smc_irq.h"
+            smc_irq_cheader_path = cformat_dir / f"top_{topname}_smc_irq.h"
+            render_template(TOPGEN_TEMPLATE_MATCHA_PATH / "toplevel_smc_irq.h.tpl",
+                            smc_irq_cheader_path,
+                            helper=c_helper)
+
         # generate chip level xbar and alert_handler TB
         tb_files = [
             "xbar_env_pkg__params.sv", "tb__xbar_connect.sv",
diff --git a/util/topgen_matcha/templates/toplevel_smc_irq.h.tpl b/util/topgen_matcha/templates/toplevel_smc_irq.h.tpl
new file mode 100644
index 0000000..217a5e9
--- /dev/null
+++ b/util/topgen_matcha/templates/toplevel_smc_irq.h.tpl
@@ -0,0 +1,27 @@
+// Copyright Google Inc.
+// Licensed under the Apache License, Version 2.0, see LICENSE for details.
+// SPDX-License-Identifier: Apache-2.0
+
+#ifndef ${helper.header_macro_prefix}_TOP_${top["name"].upper()}_IRQ_H_
+#define ${helper.header_macro_prefix}_TOP_${top["name"].upper()}_IRQ_H_
+
+/**
+ * @file
+ * @brief Assembler-only Top-specific Definitions
+ *
+ * This file contains preprocessor definitions for use within assembly code.
+ */
+
+#ifdef __ASSEMBLER__
+
+/**
+ * SMC PLIC Interrupt Source.
+ *
+ * Enumeration of all SMC PLIC interrupt sources. The interrupt sources belonging to
+ * the same peripheral are guaranteed to be consecutive.
+ */
+${helper.smc_helper.smc_plic_interrupts_define_render()}
+
+#endif  // __ASSEMBLER__
+
+#endif  // ${helper.header_macro_prefix}_TOP_${top["name"].upper()}_IRQ_H_
diff --git a/util/topgen_utils/toputils.py b/util/topgen_utils/toputils.py
index 84d3df6..826c1ca 100644
--- a/util/topgen_utils/toputils.py
+++ b/util/topgen_utils/toputils.py
@@ -40,6 +40,9 @@
     def smc_plic_interrupts_render(self):
         return self._smc_c_enum_render(self.plic_interrupts)
 
+    def smc_plic_interrupts_define_render(self):
+        return self._smc_c_define_render(self.plic_interrupts)
+
     def smc_plic_mapping_render_declaration(self):
         template = (
             "extern const ${mapping.output_type_name.as_snake_case()}_smc_t\n"
@@ -65,6 +68,12 @@
                     "} ${enum.name.as_snake_case()}_smc_t;")
         return Template(template).render(enum=enum)
 
+    def _smc_c_define_render(self, enum):
+        """ Add the c_helper CDefine rendering code for smc."""
+        template = ("% for name, value, docstring in enum.constants:\n"
+                    "#define ${name.as_c_define()} ${value} /**< ${docstring} */\n"
+                    "% endfor\n")
+        return Template(template).render(enum=enum)
 
 def _separate_interrupt_modules(top: OrderedDict, name_to_block: Dict[str,
                                                                       IpBlock],