diff --git a/hw/ip/kmac/data/kmac.hjson b/hw/ip/kmac/data/kmac.hjson index 91ff277fd93b32..c3aa6bf871aa15 100644 --- a/hw/ip/kmac/data/kmac.hjson +++ b/hw/ip/kmac/data/kmac.hjson @@ -45,7 +45,13 @@ desc: "KMAC/SHA3 absorbing has been completed" } { name: "fifo_empty" - desc: "Message FIFO empty condition" + type: "status" + desc: ''' + The message FIFO is empty. + This interrupt is not raised or de-asserts if any of the following conditions are met: + 1) The KMAC block is exercised by a hardware application interface. + 2) The KMAC block is completely idle, e.g., after finishing an operation. + ''' } { name: "kmac_err" desc: "KMAC/SHA3 error occurred. ERR_CODE register shows the details" diff --git a/hw/ip/kmac/doc/interfaces.md b/hw/ip/kmac/doc/interfaces.md index d51d520a04a582..abfac1441a4f9c 100644 --- a/hw/ip/kmac/doc/interfaces.md +++ b/hw/ip/kmac/doc/interfaces.md @@ -22,11 +22,11 @@ Referring to the [Comportable guideline for peripheral device functionality](htt ## Interrupts -| Interrupt Name | Type | Description | -|:-----------------|:-------|:--------------------------------------------------------------| -| kmac_done | Event | KMAC/SHA3 absorbing has been completed | -| fifo_empty | Event | Message FIFO empty condition | -| kmac_err | Event | KMAC/SHA3 error occurred. ERR_CODE register shows the details | +| Interrupt Name | Type | Description | +|:-----------------|:-------|:----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| +| kmac_done | Event | KMAC/SHA3 absorbing has been completed | +| fifo_empty | Status | The message FIFO is empty. This interrupt is not raised or de-asserts if any of the following conditions are met: 1) The KMAC block is exercised by a hardware application interface. 2) The KMAC block is completely idle, e.g., after finishing an operation. | +| kmac_err | Event | KMAC/SHA3 error occurred. ERR_CODE register shows the details | ## Security Alerts diff --git a/hw/ip/kmac/doc/registers.md b/hw/ip/kmac/doc/registers.md index 9e61443bd92df4..1f959c3d83369b 100644 --- a/hw/ip/kmac/doc/registers.md +++ b/hw/ip/kmac/doc/registers.md @@ -78,15 +78,27 @@ Interrupt State Register ### Fields ```wavejson -{"reg": [{"name": "kmac_done", "bits": 1, "attr": ["rw1c"], "rotate": -90}, {"name": "fifo_empty", "bits": 1, "attr": ["rw1c"], "rotate": -90}, {"name": "kmac_err", "bits": 1, "attr": ["rw1c"], "rotate": -90}, {"bits": 29}], "config": {"lanes": 1, "fontsize": 10, "vspace": 120}} +{"reg": [{"name": "kmac_done", "bits": 1, "attr": ["rw1c"], "rotate": -90}, {"name": "fifo_empty", "bits": 1, "attr": ["ro"], "rotate": -90}, {"name": "kmac_err", "bits": 1, "attr": ["rw1c"], "rotate": -90}, {"bits": 29}], "config": {"lanes": 1, "fontsize": 10, "vspace": 120}} ``` -| Bits | Type | Reset | Name | Description | -|:------:|:------:|:-------:|:-----------|:--------------------------------------------------------------| -| 31:3 | | | | Reserved | -| 2 | rw1c | 0x0 | kmac_err | KMAC/SHA3 error occurred. ERR_CODE register shows the details | -| 1 | rw1c | 0x0 | fifo_empty | Message FIFO empty condition | -| 0 | rw1c | 0x0 | kmac_done | KMAC/SHA3 absorbing has been completed | +| Bits | Type | Reset | Name | +|:------:|:------:|:-------:|:--------------------------------------| +| 31:3 | | | Reserved | +| 2 | rw1c | 0x0 | [kmac_err](#intr_state--kmac_err) | +| 1 | ro | 0x0 | [fifo_empty](#intr_state--fifo_empty) | +| 0 | rw1c | 0x0 | [kmac_done](#intr_state--kmac_done) | + +### INTR_STATE . kmac_err +KMAC/SHA3 error occurred. ERR_CODE register shows the details + +### INTR_STATE . fifo_empty +The message FIFO is empty. +This interrupt is not raised or de-asserts if any of the following conditions are met: +1) The KMAC block is exercised by a hardware application interface. +2) The KMAC block is completely idle, e.g., after finishing an operation. + +### INTR_STATE . kmac_done +KMAC/SHA3 absorbing has been completed ## INTR_ENABLE Interrupt Enable Register diff --git a/hw/ip/kmac/dv/env/kmac_scoreboard.sv b/hw/ip/kmac/dv/env/kmac_scoreboard.sv index 3c6a76fbc734ab..52013287282d0f 100644 --- a/hw/ip/kmac/dv/env/kmac_scoreboard.sv +++ b/hw/ip/kmac/dv/env/kmac_scoreboard.sv @@ -663,7 +663,6 @@ class kmac_scoreboard extends cip_base_scoreboard #( if (data_phase_write) begin // clear internal state on a write if (item.a_data[KmacDone]) intr_kmac_done = 0; - if (item.a_data[KmacFifoEmpty]) intr_fifo_empty = 0; if (item.a_data[KmacErr]) intr_kmac_err = 0; end else if (data_phase_read) begin // ICEBOX: check below diff --git a/hw/ip/kmac/rtl/kmac.sv b/hw/ip/kmac/rtl/kmac.sv index 857be162cfbf43..7d3bc8e6dcf9d8 100644 --- a/hw/ip/kmac/rtl/kmac.sv +++ b/hw/ip/kmac/rtl/kmac.sv @@ -582,8 +582,6 @@ module kmac // Interrupt // /////////////// - logic event_msgfifo_empty, msgfifo_empty_q; - // Hash process absorbed interrupt // Convert mubi4_t to logic to generate interrupts assign event_absorbed = prim_mubi_pkg::mubi4_test_true_strict(app_absorbed); @@ -605,17 +603,22 @@ module kmac $rose(prim_mubi_pkg::mubi4_test_true_strict(sha3_absorbed)) |=> prim_mubi_pkg::mubi4_test_false_strict(sha3_absorbed)) - always_ff @(posedge clk_i or negedge rst_ni) begin - if (!rst_ni) msgfifo_empty_q <= 1'b1; - else msgfifo_empty_q <= msgfifo_empty; - end - - assign event_msgfifo_empty = ~msgfifo_empty_q & msgfifo_empty; - - prim_intr_hw #(.Width(1)) intr_fifo_empty ( + // Message FIFO empty interrupt + // The message FIFO empty interrupt is not useful for software if: + // - One of the hardware application interfaces is actively using the KMAC block. In this case + // the message FIFO including the empty condition is managed entirely by the application + // interface. + // - The KMAC block is completely idle. The FIFO should anyway be empty in that case. + logic status_msgfifo_empty; + assign status_msgfifo_empty = msgfifo_empty & ~app_active & (sha3_fsm != sha3_pkg::StIdle); + + prim_intr_hw #( + .Width(1), + .IntrT("Status") + ) intr_fifo_empty ( .clk_i, .rst_ni, - .event_intr_i (event_msgfifo_empty), + .event_intr_i (status_msgfifo_empty), .reg2hw_intr_enable_q_i (reg2hw.intr_enable.fifo_empty.q), .reg2hw_intr_test_q_i (reg2hw.intr_test.fifo_empty.q), .reg2hw_intr_test_qe_i (reg2hw.intr_test.fifo_empty.qe), diff --git a/hw/ip/kmac/rtl/kmac_reg_top.sv b/hw/ip/kmac/rtl/kmac_reg_top.sv index 404f9d6d8bad2b..20411787bfa51a 100644 --- a/hw/ip/kmac/rtl/kmac_reg_top.sv +++ b/hw/ip/kmac/rtl/kmac_reg_top.sv @@ -181,7 +181,6 @@ module kmac_reg_top ( logic intr_state_kmac_done_qs; logic intr_state_kmac_done_wd; logic intr_state_fifo_empty_qs; - logic intr_state_fifo_empty_wd; logic intr_state_kmac_err_qs; logic intr_state_kmac_err_wd; logic intr_enable_we; @@ -418,7 +417,7 @@ module kmac_reg_top ( // F[fifo_empty]: 1:1 prim_subreg #( .DW (1), - .SwAccess(prim_subreg_pkg::SwAccessW1C), + .SwAccess(prim_subreg_pkg::SwAccessRO), .RESVAL (1'h0), .Mubi (1'b0) ) u_intr_state_fifo_empty ( @@ -426,8 +425,8 @@ module kmac_reg_top ( .rst_ni (rst_ni), // from register interface - .we (intr_state_we), - .wd (intr_state_fifo_empty_wd), + .we (1'b0), + .wd ('0), // from internal hardware .de (hw2reg.intr_state.fifo_empty.de), @@ -2846,8 +2845,6 @@ module kmac_reg_top ( assign intr_state_kmac_done_wd = reg_wdata[0]; - assign intr_state_fifo_empty_wd = reg_wdata[1]; - assign intr_state_kmac_err_wd = reg_wdata[2]; assign intr_enable_we = addr_hit[1] & reg_we & !reg_error; diff --git a/sw/device/lib/dif/autogen/dif_kmac_autogen.c b/sw/device/lib/dif/autogen/dif_kmac_autogen.c index a6c2d9e13b4ff4..3044c2ec19f94b 100644 --- a/sw/device/lib/dif/autogen/dif_kmac_autogen.c +++ b/sw/device/lib/dif/autogen/dif_kmac_autogen.c @@ -73,7 +73,7 @@ static bool kmac_get_irq_bit_index(dif_kmac_irq_t irq, static dif_irq_type_t irq_types[] = { kDifIrqTypeEvent, - kDifIrqTypeEvent, + kDifIrqTypeStatus, kDifIrqTypeEvent, }; diff --git a/sw/device/lib/dif/autogen/dif_kmac_autogen.h b/sw/device/lib/dif/autogen/dif_kmac_autogen.h index ab0938f33a0587..8d37f7adeaa3ca 100644 --- a/sw/device/lib/dif/autogen/dif_kmac_autogen.h +++ b/sw/device/lib/dif/autogen/dif_kmac_autogen.h @@ -89,7 +89,10 @@ typedef enum dif_kmac_irq { */ kDifKmacIrqKmacDone = 0, /** - * Message FIFO empty condition + * The message FIFO has run empty. This interrupt is not raised or de-asserts + * if any of the following conditions are met: 1) The KMAC block is exercised + * by a hardware application interface. 2) The KMAC block is completely idle, + * e.g., after finishing an operation. */ kDifKmacIrqFifoEmpty = 1, /**