diff --git a/hw/dv/sv/csrng_agent/csrng_agent_cov.sv b/hw/dv/sv/csrng_agent/csrng_agent_cov.sv index dddc3da9189bf..09c0ff4b09738 100644 --- a/hw/dv/sv/csrng_agent/csrng_agent_cov.sv +++ b/hw/dv/sv/csrng_agent/csrng_agent_cov.sv @@ -17,7 +17,7 @@ // covergroups // Depends on whether the agent is device or host mode, the "csrng_cmd_cp" are slightly different: -// In device mode: acmd INV, GENB, GENU are in the illegal bin. +// In device mode: acmd INV, is in the illegal bin. covergroup device_cmd_cg with function sample(csrng_item item, csrng_cmd_sts_e sts); option.name = "csrng_device_cmd_cg"; option.per_instance = 1; @@ -62,8 +62,6 @@ covergroup host_cmd_cg with function sample(csrng_item item, csrng_cmd_sts_e sts bins gen = {GEN}; bins upd = {UPD}; bins uni = {UNI}; - bins genb = {GENB}; - bins genu = {GENU}; illegal_bins il = default; } csrng_clen_cp: coverpoint item.clen { @@ -84,10 +82,10 @@ covergroup host_cmd_cg with function sample(csrng_item item, csrng_cmd_sts_e sts csrng_cmd_clen_flag_cross: cross csrng_cmd_cp, csrng_clen_cp, csrng_flag_cp; csrng_cmd_clen_flag_sts_cross: cross csrng_cmd_cp, csrng_clen_cp, csrng_flag_cp, csrng_sts { - // Illegal commands (INV, GENB, GENU) don't get a response, thus don't have a status. - ignore_bins illegal_cmds = binsof(csrng_cmd_cp) intersect {INV, GENB, GENU}; + // Illegal command INV doesn't get a response, thus doesn't have a status. + ignore_bins illegal_cmds = binsof(csrng_cmd_cp) intersect {INV}; // Ignore status error responses for legal commands. - ignore_bins legal_cmds_with_error_sts = !binsof(csrng_cmd_cp) intersect {INV, GENB, GENU} && + ignore_bins legal_cmds_with_error_sts = !binsof(csrng_cmd_cp) intersect {INV} && !binsof(csrng_sts) intersect {CMD_STS_SUCCESS}; } diff --git a/hw/dv/sv/push_pull_agent/push_pull_driver_lib.sv b/hw/dv/sv/push_pull_agent/push_pull_driver_lib.sv index 6d1e3e6a50bc8..242fa3056410a 100644 --- a/hw/dv/sv/push_pull_agent/push_pull_driver_lib.sv +++ b/hw/dv/sv/push_pull_agent/push_pull_driver_lib.sv @@ -258,6 +258,7 @@ class pull_device_driver #( `CB.ack_int <= 1'b0; if (!cfg.hold_d_data_until_next_req) `CB.d_data_int <= 'x;, wait (cfg.in_reset);) + if (cfg.in_reset) `CB.ack_int <= '0; endtask `undef CB diff --git a/hw/ip/csrng/csrng.core b/hw/ip/csrng/csrng.core index 413aac9c64428..a08b57dac0932 100644 --- a/hw/ip/csrng/csrng.core +++ b/hw/ip/csrng/csrng.core @@ -25,9 +25,7 @@ filesets: - rtl/csrng_state_db.sv - rtl/csrng_cmd_stage.sv - rtl/csrng_block_encrypt.sv - - rtl/csrng_ctr_drbg_cmd.sv - - rtl/csrng_ctr_drbg_upd.sv - - rtl/csrng_ctr_drbg_gen.sv + - rtl/csrng_ctr_drbg.sv - rtl/csrng_core.sv - rtl/csrng.sv file_type: systemVerilogSource diff --git a/hw/ip/csrng/data/csrng.hjson b/hw/ip/csrng/data/csrng.hjson index 2d5142f7e3366..24ca9fd3e7f68 100644 --- a/hw/ip/csrng/data/csrng.hjson +++ b/hw/ip/csrng/data/csrng.hjson @@ -175,29 +175,20 @@ { name: "INTERSIG.MUBI" desc: "OTP signal used to enable software access to registers." } + { name: "CMD_STAGE.FSM.SPARSE" + desc: "The CSRNG command stage state machines use a sparse state encoding." + } { name: "MAIN_SM.FSM.SPARSE" desc: "The CSRNG main state machine uses a sparse state encoding." } - { name: "UPDRSP.FSM.SPARSE" - desc: "The CSRNG update response state machine uses a sparse state encoding." - } - { name: "UPDATE.FSM.SPARSE" - desc: "The CSRNG update state machine uses a sparse state encoding." - } - { name: "BLK_ENC.FSM.SPARSE" - desc: "The CSRNG block encrypt state machine uses a sparse state encoding." - } - { name: "OUTBLK.FSM.SPARSE" - desc: "The CSRNG block output state machine uses a sparse state encoding." + { name: "CTR_DRBG.FSM.SPARSE" + desc: "The CTR DRBG state machine uses a sparse state encoding." } { name: "GEN_CMD.CTR.REDUN" desc: "The generate command uses a counter that is protected by a second counter that counts in the opposite direction." } - { name: "DRBG_UPD.CTR.REDUN" - desc: "The ctr_drbg update algorithm uses a counter that is protected by a second counter that counts in the opposite direction." - } - { name: "DRBG_GEN.CTR.REDUN" - desc: "The ctr_drbg generate algorithm uses a counter that is protected by a second counter that counts in the opposite direction." + { name: "CTR_DRBG.CTR.REDUN" + desc: "The ctr_drbg algorithm uses a counter that is protected by a second counter that counts in the opposite direction." } { name: "CTRL.MUBI" desc: "Multi-bit field used for selection control." @@ -731,42 +722,6 @@ This bit will stay set until the next reset. ''' } - { bits: "9", - name: "SFIFO_FINAL_ERR", - desc: ''' - This bit will be set to one when an error has been detected for the - final FIFO. The type of error is reflected in the type status - bits (bits 28 through 30 of this register). - This bit will stay set until the next reset. - ''' - } - { bits: "10", - name: "SFIFO_GBENCACK_ERR", - desc: ''' - This bit will be set to one when an error has been detected for the - gbencack FIFO. The type of error is reflected in the type status - bits (bits 28 through 30 of this register). - This bit will stay set until the next reset. - ''' - } - { bits: "13", - name: "SFIFO_GADSTAGE_ERR", - desc: ''' - This bit will be set to one when an error has been detected for the - gadstage FIFO. The type of error is reflected in the type status - bits (bits 28 through 30 of this register). - This bit will stay set until the next reset. - ''' - } - { bits: "15", - name: "SFIFO_CMDID_ERR", - desc: ''' - This bit will be set to one when an error has been detected for the - cmdid FIFO. The type of error is reflected in the type status - bits (bits 28 through 30 of this register). - This bit will stay set until the next reset. - ''' - } { bits: "20", name: "CMD_STAGE_SM_ERR", desc: ''' @@ -786,28 +741,10 @@ ''' } { bits: "22", - name: "DRBG_GEN_SM_ERR", - desc: ''' - This bit will be set to one when an illegal state has been detected for the - ctr_drbg gen state machine. This error will signal a fatal alert, and also - an interrupt if enabled. - This bit will stay set until the next reset. - ''' - } - { bits: "23", - name: "DRBG_UPDBE_SM_ERR", + name: "CTR_DRBG_SM_ERR", desc: ''' This bit will be set to one when an illegal state has been detected for the - ctr_drbg update block encode state machine. This error will signal a fatal alert, and also - an interrupt if enabled. - This bit will stay set until the next reset. - ''' - } - { bits: "24", - name: "DRBG_UPDOB_SM_ERR", - desc: ''' - This bit will be set to one when an illegal state has been detected for the - ctr_drbg update out block state machine. This error will signal a fatal alert, and also + ctr_drbg state machine. This error will signal a fatal alert, and also an interrupt if enabled. This bit will stay set until the next reset. ''' @@ -816,27 +753,16 @@ name: "AES_CIPHER_SM_ERR", desc: ''' This bit will be set to one when an AES fatal error has been detected. - This error will signal a fatal alert, and also - an interrupt if enabled. + This error will signal a fatal alert, and also an interrupt if enabled. This bit will stay set until the next reset. ''' } { bits: "26", - name: "CMD_GEN_CNT_ERR", + name: "CTR_ERR", desc: ''' This bit will be set to one when a mismatch in any of the hardened counters has been detected. - This error will signal a fatal alert, and also - an interrupt if enabled. - This bit will stay set until the next reset. - ''' - } - { bits: "27", - name: "DRBG_CMD_SM_ERR", - desc: ''' - This bit will be set when the state machine in the ctr_drbg_cmd unit has entered - an illegal state. - This error will signal a fatal alert, and also an interrupt, if enabled. + This error will signal a fatal alert, and also an interrupt if enabled. This bit will stay set until the next reset. ''' } diff --git a/hw/ip/csrng/data/csrng_sec_cm_testplan.hjson b/hw/ip/csrng/data/csrng_sec_cm_testplan.hjson index 8d1a0f0fe5eec..0be2e1b6f00ec 100644 --- a/hw/ip/csrng/data/csrng_sec_cm_testplan.hjson +++ b/hw/ip/csrng/data/csrng_sec_cm_testplan.hjson @@ -67,9 +67,9 @@ tests: ["csrng_sec_cm", "csrng_intr", "csrng_err"] } { - name: sec_cm_updrsp_fsm_sparse + name: sec_cm_cmd_stage_fsm_sparse desc: ''' - Verify the countermeasure(s) UPDRSP.FSM.SPARSE. + Verify the countermeasure(s) CMD_STAGE.FSM.SPARSE. The csrng_intr and csrng_err tests verify that if the FSM state is forced to an illegal state encoding 1) this is reported with a cs_fatal_err interrupt in the INTR_STATE register and 2) the corresponding bit in the ERR_CODE register is set. They currently don't check whether the DUT actually triggers a fatal alert. Alert connection and triggering are verified through automated FPV. @@ -78,9 +78,9 @@ tests: ["csrng_sec_cm", "csrng_intr", "csrng_err"] } { - name: sec_cm_update_fsm_sparse + name: sec_cm_ctr_drbg_fsm_sparse desc: ''' - Verify the countermeasure(s) UPDATE.FSM.SPARSE. + Verify the countermeasure(s) CTR_DRBG.FSM.SPARSE. The csrng_intr and csrng_err tests verify that if the FSM state is forced to an illegal state encoding 1) this is reported with a cs_fatal_err interrupt in the INTR_STATE register and 2) the corresponding bit in the ERR_CODE register is set. They currently don't check whether the DUT actually triggers a fatal alert. Alert connection and triggering are verified through automated FPV. @@ -89,21 +89,11 @@ tests: ["csrng_sec_cm", "csrng_intr", "csrng_err"] } { - name: sec_cm_blk_enc_fsm_sparse + // All counter errors are reported in ERR_CODE.CTR_ERR. + name: sec_cm_ctr_drbg_ctr_redun desc: ''' - Verify the countermeasure(s) BLK_ENC.FSM.SPARSE. - The csrng_intr and csrng_err tests verify that if the FSM state is forced to an illegal state encoding 1) this is reported with a cs_fatal_err interrupt in the INTR_STATE register and 2) the corresponding bit in the ERR_CODE register is set. - They currently don't check whether the DUT actually triggers a fatal alert. - Alert connection and triggering are verified through automated FPV. - ''' - stage: V2S - tests: ["csrng_sec_cm", "csrng_intr", "csrng_err"] - } - { - name: sec_cm_outblk_fsm_sparse - desc: ''' - Verify the countermeasure(s) OUTBLK.FSM.SPARSE. - The csrng_intr and csrng_err tests verify that if the FSM state is forced to an illegal state encoding 1) this is reported with a cs_fatal_err interrupt in the INTR_STATE register and 2) the corresponding bit in the ERR_CODE register is set. + Verify the countermeasure(s) CTR_DRBG.CTR.REDUN. + The csrng_intr and csrng_err tests verify that if there is a mismatch in the redundant counters of the CTR_DRBG generate counter 1) this is reported with a cs_fatal_err interrupt in the INTR_STATE register and 2) the corresponding bit in the ERR_CODE register is set. They currently don't check whether the DUT actually triggers a fatal alert. Alert connection and triggering are verified through automated FPV. ''' @@ -111,6 +101,7 @@ tests: ["csrng_sec_cm", "csrng_intr", "csrng_err"] } { + // All counter errors are reported in ERR_CODE.CTR_ERR. name: sec_cm_gen_cmd_ctr_redun desc: ''' Verify the countermeasure(s) GEN_CMD.CTR.REDUN. @@ -121,30 +112,6 @@ stage: V2S tests: ["csrng_sec_cm", "csrng_intr", "csrng_err"] } - { - // All counter errors are collected in ERR_CODE.CMD_GEN_CNT_ERR. - name: sec_cm_drbg_upd_ctr_redun - desc: ''' - Verify the countermeasure(s) DRBG_UPD.CTR.REDUN. - The csrng_intr and csrng_err tests verify that if there is a mismatch in the redundant counters of the CTR_DRBG update counter 1) this is reported with a cs_fatal_err interrupt in the INTR_STATE register and 2) the corresponding bit in the ERR_CODE register is set. - They currently don't check whether the DUT actually triggers a fatal alert. - Alert connection and triggering are verified through automated FPV. - ''' - stage: V2S - tests: ["csrng_sec_cm", "csrng_intr", "csrng_err"] - } - { - // All counter errors are collected in ERR_CODE.CMD_GEN_CNT_ERR. - name: sec_cm_drbg_gen_ctr_redun - desc: ''' - Verify the countermeasure(s) DRBG_GEN.CTR.REDUN. - The csrng_intr and csrng_err tests verify that if there is a mismatch in the redundant counters of the CTR_DRBG generate counter 1) this is reported with a cs_fatal_err interrupt in the INTR_STATE register and 2) the corresponding bit in the ERR_CODE register is set. - They currently don't check whether the DUT actually triggers a fatal alert. - Alert connection and triggering are verified through automated FPV. - ''' - stage: V2S - tests: ["csrng_sec_cm", "csrng_intr", "csrng_err"] - } { name: sec_cm_ctrl_mubi desc: ''' diff --git a/hw/ip/csrng/doc/interfaces.md b/hw/ip/csrng/doc/interfaces.md index 28e635080cf50..dad9f8ff381af 100644 --- a/hw/ip/csrng/doc/interfaces.md +++ b/hw/ip/csrng/doc/interfaces.md @@ -42,14 +42,11 @@ Referring to the [Comportable guideline for peripheral device functionality](htt | CSRNG.CONFIG.REGWEN | Registers are protected from writes. | | CSRNG.CONFIG.MUBI | Registers have multi-bit encoded fields. | | CSRNG.INTERSIG.MUBI | OTP signal used to enable software access to registers. | +| CSRNG.CMD_STAGE.FSM.SPARSE | The CSRNG command stage state machines use a sparse state encoding. | | CSRNG.MAIN_SM.FSM.SPARSE | The CSRNG main state machine uses a sparse state encoding. | -| CSRNG.UPDRSP.FSM.SPARSE | The CSRNG update response state machine uses a sparse state encoding. | -| CSRNG.UPDATE.FSM.SPARSE | The CSRNG update state machine uses a sparse state encoding. | -| CSRNG.BLK_ENC.FSM.SPARSE | The CSRNG block encrypt state machine uses a sparse state encoding. | -| CSRNG.OUTBLK.FSM.SPARSE | The CSRNG block output state machine uses a sparse state encoding. | +| CSRNG.CTR_DRBG.FSM.SPARSE | The CTR DRBG state machine uses a sparse state encoding. | | CSRNG.GEN_CMD.CTR.REDUN | The generate command uses a counter that is protected by a second counter that counts in the opposite direction. | -| CSRNG.DRBG_UPD.CTR.REDUN | The ctr_drbg update algorithm uses a counter that is protected by a second counter that counts in the opposite direction. | -| CSRNG.DRBG_GEN.CTR.REDUN | The ctr_drbg generate algorithm uses a counter that is protected by a second counter that counts in the opposite direction. | +| CSRNG.CTR_DRBG.CTR.REDUN | The ctr_drbg algorithm uses a counter that is protected by a second counter that counts in the opposite direction. | | CSRNG.CTRL.MUBI | Multi-bit field used for selection control. | | CSRNG.MAIN_SM.CTR.LOCAL_ESC | A mismatch detected inside any CSRNG counter moves the main state machine into a terminal error state. | | CSRNG.CONSTANTS.LC_GATED | Seed diversification based on the lifecycle state. | diff --git a/hw/ip/csrng/doc/registers.md b/hw/ip/csrng/doc/registers.md index ca98f1d9b9e0d..6c5a64f58e94c 100644 --- a/hw/ip/csrng/doc/registers.md +++ b/hw/ip/csrng/doc/registers.md @@ -555,38 +555,30 @@ Writing a zero resets this status bit. Hardware detection of error conditions status register - Offset: `0x54` - Reset default: `0x0` -- Reset mask: `0x7ff0a603` +- Reset mask: `0x76700003` ### Fields ```wavejson -{"reg": [{"name": "SFIFO_CMD_ERR", "bits": 1, "attr": ["ro"], "rotate": -90}, {"name": "SFIFO_GENBITS_ERR", "bits": 1, "attr": ["ro"], "rotate": -90}, {"bits": 7}, {"name": "SFIFO_FINAL_ERR", "bits": 1, "attr": ["ro"], "rotate": -90}, {"name": "SFIFO_GBENCACK_ERR", "bits": 1, "attr": ["ro"], "rotate": -90}, {"bits": 2}, {"name": "SFIFO_GADSTAGE_ERR", "bits": 1, "attr": ["ro"], "rotate": -90}, {"bits": 1}, {"name": "SFIFO_CMDID_ERR", "bits": 1, "attr": ["ro"], "rotate": -90}, {"bits": 4}, {"name": "CMD_STAGE_SM_ERR", "bits": 1, "attr": ["ro"], "rotate": -90}, {"name": "MAIN_SM_ERR", "bits": 1, "attr": ["ro"], "rotate": -90}, {"name": "DRBG_GEN_SM_ERR", "bits": 1, "attr": ["ro"], "rotate": -90}, {"name": "DRBG_UPDBE_SM_ERR", "bits": 1, "attr": ["ro"], "rotate": -90}, {"name": "DRBG_UPDOB_SM_ERR", "bits": 1, "attr": ["ro"], "rotate": -90}, {"name": "AES_CIPHER_SM_ERR", "bits": 1, "attr": ["ro"], "rotate": -90}, {"name": "CMD_GEN_CNT_ERR", "bits": 1, "attr": ["ro"], "rotate": -90}, {"name": "DRBG_CMD_SM_ERR", "bits": 1, "attr": ["ro"], "rotate": -90}, {"name": "FIFO_WRITE_ERR", "bits": 1, "attr": ["ro"], "rotate": -90}, {"name": "FIFO_READ_ERR", "bits": 1, "attr": ["ro"], "rotate": -90}, {"name": "FIFO_STATE_ERR", "bits": 1, "attr": ["ro"], "rotate": -90}, {"bits": 1}], "config": {"lanes": 1, "fontsize": 10, "vspace": 200}} +{"reg": [{"name": "SFIFO_CMD_ERR", "bits": 1, "attr": ["ro"], "rotate": -90}, {"name": "SFIFO_GENBITS_ERR", "bits": 1, "attr": ["ro"], "rotate": -90}, {"bits": 18}, {"name": "CMD_STAGE_SM_ERR", "bits": 1, "attr": ["ro"], "rotate": -90}, {"name": "MAIN_SM_ERR", "bits": 1, "attr": ["ro"], "rotate": -90}, {"name": "CTR_DRBG_SM_ERR", "bits": 1, "attr": ["ro"], "rotate": -90}, {"bits": 2}, {"name": "AES_CIPHER_SM_ERR", "bits": 1, "attr": ["ro"], "rotate": -90}, {"name": "CTR_ERR", "bits": 1, "attr": ["ro"], "rotate": -90}, {"bits": 1}, {"name": "FIFO_WRITE_ERR", "bits": 1, "attr": ["ro"], "rotate": -90}, {"name": "FIFO_READ_ERR", "bits": 1, "attr": ["ro"], "rotate": -90}, {"name": "FIFO_STATE_ERR", "bits": 1, "attr": ["ro"], "rotate": -90}, {"bits": 1}], "config": {"lanes": 1, "fontsize": 10, "vspace": 190}} ``` -| Bits | Type | Reset | Name | -|:------:|:------:|:-------:|:----------------------------------------------------| -| 31 | | | Reserved | -| 30 | ro | 0x0 | [FIFO_STATE_ERR](#err_code--fifo_state_err) | -| 29 | ro | 0x0 | [FIFO_READ_ERR](#err_code--fifo_read_err) | -| 28 | ro | 0x0 | [FIFO_WRITE_ERR](#err_code--fifo_write_err) | -| 27 | ro | 0x0 | [DRBG_CMD_SM_ERR](#err_code--drbg_cmd_sm_err) | -| 26 | ro | 0x0 | [CMD_GEN_CNT_ERR](#err_code--cmd_gen_cnt_err) | -| 25 | ro | 0x0 | [AES_CIPHER_SM_ERR](#err_code--aes_cipher_sm_err) | -| 24 | ro | 0x0 | [DRBG_UPDOB_SM_ERR](#err_code--drbg_updob_sm_err) | -| 23 | ro | 0x0 | [DRBG_UPDBE_SM_ERR](#err_code--drbg_updbe_sm_err) | -| 22 | ro | 0x0 | [DRBG_GEN_SM_ERR](#err_code--drbg_gen_sm_err) | -| 21 | ro | 0x0 | [MAIN_SM_ERR](#err_code--main_sm_err) | -| 20 | ro | 0x0 | [CMD_STAGE_SM_ERR](#err_code--cmd_stage_sm_err) | -| 19:16 | | | Reserved | -| 15 | ro | 0x0 | [SFIFO_CMDID_ERR](#err_code--sfifo_cmdid_err) | -| 14 | | | Reserved | -| 13 | ro | 0x0 | [SFIFO_GADSTAGE_ERR](#err_code--sfifo_gadstage_err) | -| 12:11 | | | Reserved | -| 10 | ro | 0x0 | [SFIFO_GBENCACK_ERR](#err_code--sfifo_gbencack_err) | -| 9 | ro | 0x0 | [SFIFO_FINAL_ERR](#err_code--sfifo_final_err) | -| 8:2 | | | Reserved | -| 1 | ro | 0x0 | [SFIFO_GENBITS_ERR](#err_code--sfifo_genbits_err) | -| 0 | ro | 0x0 | [SFIFO_CMD_ERR](#err_code--sfifo_cmd_err) | +| Bits | Type | Reset | Name | +|:------:|:------:|:-------:|:--------------------------------------------------| +| 31 | | | Reserved | +| 30 | ro | 0x0 | [FIFO_STATE_ERR](#err_code--fifo_state_err) | +| 29 | ro | 0x0 | [FIFO_READ_ERR](#err_code--fifo_read_err) | +| 28 | ro | 0x0 | [FIFO_WRITE_ERR](#err_code--fifo_write_err) | +| 27 | | | Reserved | +| 26 | ro | 0x0 | [CTR_ERR](#err_code--ctr_err) | +| 25 | ro | 0x0 | [AES_CIPHER_SM_ERR](#err_code--aes_cipher_sm_err) | +| 24:23 | | | Reserved | +| 22 | ro | 0x0 | [CTR_DRBG_SM_ERR](#err_code--ctr_drbg_sm_err) | +| 21 | ro | 0x0 | [MAIN_SM_ERR](#err_code--main_sm_err) | +| 20 | ro | 0x0 | [CMD_STAGE_SM_ERR](#err_code--cmd_stage_sm_err) | +| 19:2 | | | Reserved | +| 1 | ro | 0x0 | [SFIFO_GENBITS_ERR](#err_code--sfifo_genbits_err) | +| 0 | ro | 0x0 | [SFIFO_CMD_ERR](#err_code--sfifo_cmd_err) | ### ERR_CODE . FIFO_STATE_ERR This bit will be set to one when any of the source bits (bits 0 through 15 of this @@ -606,40 +598,20 @@ this register) are asserted as a result of an error pulse generated from any full FIFO that has been received a write pulse. This bit will stay set until the next reset. -### ERR_CODE . DRBG_CMD_SM_ERR -This bit will be set when the state machine in the ctr_drbg_cmd unit has entered -an illegal state. -This error will signal a fatal alert, and also an interrupt, if enabled. -This bit will stay set until the next reset. - -### ERR_CODE . CMD_GEN_CNT_ERR +### ERR_CODE . CTR_ERR This bit will be set to one when a mismatch in any of the hardened counters has been detected. -This error will signal a fatal alert, and also -an interrupt if enabled. +This error will signal a fatal alert, and also an interrupt if enabled. This bit will stay set until the next reset. ### ERR_CODE . AES_CIPHER_SM_ERR This bit will be set to one when an AES fatal error has been detected. -This error will signal a fatal alert, and also -an interrupt if enabled. -This bit will stay set until the next reset. - -### ERR_CODE . DRBG_UPDOB_SM_ERR -This bit will be set to one when an illegal state has been detected for the -ctr_drbg update out block state machine. This error will signal a fatal alert, and also -an interrupt if enabled. +This error will signal a fatal alert, and also an interrupt if enabled. This bit will stay set until the next reset. -### ERR_CODE . DRBG_UPDBE_SM_ERR +### ERR_CODE . CTR_DRBG_SM_ERR This bit will be set to one when an illegal state has been detected for the -ctr_drbg update block encode state machine. This error will signal a fatal alert, and also -an interrupt if enabled. -This bit will stay set until the next reset. - -### ERR_CODE . DRBG_GEN_SM_ERR -This bit will be set to one when an illegal state has been detected for the -ctr_drbg gen state machine. This error will signal a fatal alert, and also +ctr_drbg state machine. This error will signal a fatal alert, and also an interrupt if enabled. This bit will stay set until the next reset. @@ -655,30 +627,6 @@ command stage state machine. This error will signal a fatal alert, and also an interrupt if enabled. This bit will stay set until the next reset. -### ERR_CODE . SFIFO_CMDID_ERR -This bit will be set to one when an error has been detected for the -cmdid FIFO. The type of error is reflected in the type status -bits (bits 28 through 30 of this register). -This bit will stay set until the next reset. - -### ERR_CODE . SFIFO_GADSTAGE_ERR -This bit will be set to one when an error has been detected for the -gadstage FIFO. The type of error is reflected in the type status -bits (bits 28 through 30 of this register). -This bit will stay set until the next reset. - -### ERR_CODE . SFIFO_GBENCACK_ERR -This bit will be set to one when an error has been detected for the -gbencack FIFO. The type of error is reflected in the type status -bits (bits 28 through 30 of this register). -This bit will stay set until the next reset. - -### ERR_CODE . SFIFO_FINAL_ERR -This bit will be set to one when an error has been detected for the -final FIFO. The type of error is reflected in the type status -bits (bits 28 through 30 of this register). -This bit will stay set until the next reset. - ### ERR_CODE . SFIFO_GENBITS_ERR This bit will be set to one when an error has been detected for the command stage genbits FIFO. The type of error is reflected in the type status diff --git a/hw/ip/csrng/dv/cov/csrng_cov_if.sv b/hw/ip/csrng/dv/cov/csrng_cov_if.sv index 2d77be0baa3cd..80fb56dd889c1 100644 --- a/hw/ip/csrng/dv/cov/csrng_cov_if.sv +++ b/hw/ip/csrng/dv/cov/csrng_cov_if.sv @@ -243,15 +243,13 @@ interface csrng_cov_if ( // If ERR_CODE register has SFIFO related field set, it also needs to set at least one // FIFO_*_ERR field. illegal_bins illegal = !binsof(cp_err_codes) intersect { CMD_STAGE_SM_ERR, MAIN_SM_ERR, - DRBG_CMD_SM_ERR, DRBG_GEN_SM_ERR, - DRBG_UPDBE_SM_ERR, DRBG_UPDOB_SM_ERR, - AES_CIPHER_SM_ERR, CMD_GEN_CNT_ERR } + CTR_DRBG_SM_ERR, AES_CIPHER_SM_ERR, + CTR_ERR } && binsof(cp_fifo_err_type) intersect { 0 }; ignore_bins ignore = binsof(cp_err_codes) intersect { CMD_STAGE_SM_ERR, MAIN_SM_ERR, - DRBG_CMD_SM_ERR, DRBG_GEN_SM_ERR, - DRBG_UPDBE_SM_ERR, DRBG_UPDOB_SM_ERR, - AES_CIPHER_SM_ERR, CMD_GEN_CNT_ERR }; + CTR_DRBG_SM_ERR, AES_CIPHER_SM_ERR, + CTR_ERR }; } cp_csrng_aes_fsm_err: coverpoint @@ -303,7 +301,7 @@ interface csrng_cov_if ( bins Generate = { GEN }; bins Update = { UPD }; bins Uninstantiate = { UNI }; - bins Reserved = { INV, GENB, GENU }; + bins Reserved = { INV }; } cp_clen: coverpoint clen { @@ -349,20 +347,20 @@ interface csrng_cov_if ( } app_acmd_cross: cross cp_app, cp_acmd { - ignore_bins invalid = binsof(cp_acmd) intersect { INV, GENB, GENU }; + ignore_bins invalid = binsof(cp_acmd) intersect { INV }; } acmd_clen_cross: cross cp_acmd, cp_clen { - ignore_bins invalid = binsof(cp_acmd) intersect { UNI, INV, GENB, GENU } && + ignore_bins invalid = binsof(cp_acmd) intersect { UNI, INV } && binsof(cp_clen) intersect { [1:$] }; } acmd_flags_cross: cross cp_acmd, cp_flags { - ignore_bins invalid = binsof(cp_acmd) intersect { INV, GENB, GENU }; + ignore_bins invalid = binsof(cp_acmd) intersect { INV }; } acmd_glen_cross: cross cp_acmd, cp_glen { - ignore_bins invalid = binsof(cp_acmd) intersect { INV, GENB, GENU }; + ignore_bins invalid = binsof(cp_acmd) intersect { INV }; } gen_clen_glen_cross: cross cp_acmd, cp_clen, cp_glen { @@ -412,7 +410,7 @@ interface csrng_cov_if ( binsof(cp_clen) intersect { [1:$] } && binsof(cp_acmd) intersect { RES }; // Since other modes are not related with flag0, ignore them in this cross. - ignore_bins ignore_other_cmds = binsof(cp_acmd) intersect { UPD, UNI, GEN, INV, GENB, GENU }; + ignore_bins ignore_other_cmds = binsof(cp_acmd) intersect { UPD, UNI, GEN, INV }; // Ignore invalid MuBi values for flags. ignore_bins ignore_invalid_mubi = !binsof(cp_flags) intersect { MuBi4True, MuBi4False }; } diff --git a/hw/ip/csrng/dv/env/csrng_env_cfg.sv b/hw/ip/csrng/dv/env/csrng_env_cfg.sv index 77c666f5ccf4c..3d19e70fc4b70 100644 --- a/hw/ip/csrng/dv/env/csrng_env_cfg.sv +++ b/hw/ip/csrng/dv/env/csrng_env_cfg.sv @@ -70,7 +70,7 @@ class csrng_env_cfg extends cip_base_env_cfg #(.RAL_T(csrng_reg_block)); constraint which_cmd_inv_seq_c { which_cmd_inv_seq inside {INS, RES, GEN, UPD};} rand csrng_pkg::acmd_e which_invalid_acmd; - constraint which_invalid_acmd_c { which_invalid_acmd inside {INV, GENB, GENU};} + constraint which_invalid_acmd_c { which_invalid_acmd inside {INV};} rand bit [31:0] reseed_interval; constraint reseed_interval_c { reseed_interval inside {[1:10]};} @@ -142,17 +142,17 @@ class csrng_env_cfg extends cip_base_env_cfg #(.RAL_T(csrng_reg_block)); // distributions towards aes_cipher_sm_err to get away with a reasonable number of seeds. int num_bins_aes_cipher_sm_err = which_aes_cm.num() * Sp2VWidth; constraint which_fatal_err_c { which_fatal_err dist { - [sfifo_cmd_error : sfifo_cmdid_error] := 3, // 3 error types per sfifo - [cmd_stage_sm_error : drbg_updob_sm_error] := 1, // 1 error type per FSM - aes_cipher_sm_error := num_bins_aes_cipher_sm_err, - cmd_gen_cnt_error := 3, // 3 counters feed into this bit - [fifo_write_error : fifo_state_error] := 1 + [sfifo_cmd_error : sfifo_genbits_error] := 3, // 3 error types per sfifo + [cmd_stage_sm_error : ctr_drbg_sm_error] := 1, // 1 error type per FSM + aes_cipher_sm_error := num_bins_aes_cipher_sm_err, + ctr_error := 2, // 2 counters feed into this bit + [fifo_write_error : fifo_state_error] := 1 };} constraint which_err_code_c { which_err_code dist { - [sfifo_cmd_err : sfifo_cmdid_err] := 3, // 3 error types per sfifo - [cmd_stage_sm_err : drbg_updob_sm_err] := 1, // 1 error type per FSM + [sfifo_cmd_err : sfifo_genbits_err] := 3, // 3 error types per sfifo + [cmd_stage_sm_err : ctr_drbg_sm_err] := 1, // 1 error type per FSM aes_cipher_sm_err := num_bins_aes_cipher_sm_err, - cmd_gen_cnt_err := 3, // 3 counters feed into this bit + ctr_err := 2, // 2 counters feed into this bit [fifo_write_err : fifo_state_err_test] := 1 };} diff --git a/hw/ip/csrng/dv/env/csrng_env_pkg.sv b/hw/ip/csrng/dv/env/csrng_env_pkg.sv index 42ed2b7fbee32..51f02cd89e16a 100644 --- a/hw/ip/csrng/dv/env/csrng_env_pkg.sv +++ b/hw/ip/csrng/dv/env/csrng_env_pkg.sv @@ -53,65 +53,44 @@ package csrng_env_pkg; invalid_read_int_state = 2 } invalid_mubi_e; - // Keep these in groups and with ascending encodings as the env_cfg refers to + // Keep these in groups and with ascending encodings as csrng_env_cfg refers to // ranges of certain errors to define the distribution of error codes to test. typedef enum int { sfifo_cmd_error = 0, sfifo_genbits_error = 1, - sfifo_final_error = 3, - sfifo_gbencack_error = 4, - sfifo_gadstage_error = 7, - sfifo_cmdid_error = 9, - cmd_stage_sm_error = 10, - main_sm_error = 11, - drbg_cmd_sm_error = 12, - drbg_gen_sm_error = 13, - drbg_updbe_sm_error = 14, - drbg_updob_sm_error = 15, - aes_cipher_sm_error = 16, - cmd_gen_cnt_error = 17, - fifo_write_error = 18, - fifo_read_error = 19, - fifo_state_error = 20 + cmd_stage_sm_error = 2, + main_sm_error = 3, + ctr_drbg_sm_error = 4, + aes_cipher_sm_error = 5, + ctr_error = 6, + fifo_write_error = 7, + fifo_read_error = 8, + fifo_state_error = 9 } fatal_err_e; typedef enum int { // ERR_CODE sfifo_cmd_err = 0, sfifo_genbits_err = 1, - sfifo_final_err = 3, - sfifo_gbencack_err = 4, - sfifo_gadstage_err = 7, - sfifo_cmdid_err = 9, - cmd_stage_sm_err = 10, - main_sm_err = 11, - drbg_cmd_sm_err = 12, - drbg_gen_sm_err = 13, - drbg_updbe_sm_err = 14, - drbg_updob_sm_err = 15, - aes_cipher_sm_err = 16, - cmd_gen_cnt_err = 17, - fifo_write_err = 18, - fifo_read_err = 19, - fifo_state_err = 20, + cmd_stage_sm_err = 2, + main_sm_err = 3, + ctr_drbg_sm_err = 4, + aes_cipher_sm_err = 5, + ctr_err = 6, + fifo_write_err = 7, + fifo_read_err = 8, + fifo_state_err = 9, // ERR_CODE_TEST - sfifo_cmd_err_test = 21, - sfifo_genbits_err_test = 22, - sfifo_final_err_test = 24, - sfifo_gbencack_err_test = 25, - sfifo_gadstage_err_test = 28, - sfifo_cmdid_err_test = 30, - cmd_stage_sm_err_test = 31, - main_sm_err_test = 32, - drbg_cmd_sm_err_test = 33, - drbg_gen_sm_err_test = 34, - drbg_updbe_sm_err_test = 35, - drbg_updob_sm_err_test = 36, - aes_cipher_sm_err_test = 37, - cmd_gen_cnt_err_test = 38, - fifo_write_err_test = 39, - fifo_read_err_test = 40, - fifo_state_err_test = 41 + sfifo_cmd_err_test = 10, + sfifo_genbits_err_test = 11, + cmd_stage_sm_err_test = 12, + main_sm_err_test = 13, + ctr_drbg_sm_err_test = 14, + aes_cipher_sm_err_test = 15, + ctr_err_test = 16, + fifo_write_err_test = 17, + fifo_read_err_test = 18, + fifo_state_err_test = 19 } err_code_e; // These encodings must match the respective bit position of each @@ -119,18 +98,11 @@ package csrng_env_pkg; typedef enum int { SFIFO_CMD_ERR = 0, SFIFO_GENBITS_ERR = 1, - SFIFO_FINAL_ERR = 9, - SFIFO_GBENCACK_ERR = 10, - SFIFO_GADSTAGE_ERR = 13, - SFIFO_CMDID_ERR = 15, CMD_STAGE_SM_ERR = 20, MAIN_SM_ERR = 21, - DRBG_GEN_SM_ERR = 22, - DRBG_UPDBE_SM_ERR = 23, - DRBG_UPDOB_SM_ERR = 24, + CTR_DRBG_SM_ERR = 22, AES_CIPHER_SM_ERR = 25, - CMD_GEN_CNT_ERR = 26, - DRBG_CMD_SM_ERR = 27, + CTR_ERR = 26, FIFO_WRITE_ERR = 28, FIFO_READ_ERR = 29, FIFO_STATE_ERR = 30 @@ -148,12 +120,8 @@ package csrng_env_pkg; } recov_alert_bit_e; typedef enum int { - sfifo_cmdid = 0, - sfifo_gadstage = 2, - sfifo_gbencack = 5, - sfifo_final = 6, - sfifo_genbits = 7, - sfifo_cmd = 8 + sfifo_cmd = 0, + sfifo_genbits = 1 } which_fifo_e; typedef enum int { @@ -164,8 +132,7 @@ package csrng_env_pkg; typedef enum int { cmd_gen_cnt_sel = 0, - drbg_upd_cnt_sel = 1, - drbg_gen_cnt_sel = 2 + ctr_drbg_cnt_sel = 1 } which_cnt_e; typedef enum int { diff --git a/hw/ip/csrng/dv/env/csrng_path_if.sv b/hw/ip/csrng/dv/env/csrng_path_if.sv index 542f0ad0bebae..86e3f26294108 100644 --- a/hw/ip/csrng/dv/env/csrng_path_if.sv +++ b/hw/ip/csrng/dv/env/csrng_path_if.sv @@ -17,11 +17,6 @@ interface csrng_path_if case (fifo_name) inside "sfifo_cmd", "sfifo_genbits": return {core_path, $sformatf(".gen_cmd_stage[%0d]", app), ".u_csrng_cmd_stage.", fifo_name, "_", which_path}; - "sfifo_final": return {core_path, ".u_csrng_ctr_drbg_upd.", fifo_name, "_", which_path}; - "sfifo_gbencack", "sfifo_gadstage": - return {core_path,".u_csrng_ctr_drbg_gen.sfifo_", fifo_name.substr(7, fifo_name.len()-1), - "_", which_path}; - "sfifo_cmdid": return {core_path, ".u_csrng_block_encrypt.", fifo_name, "_", which_path}; default: `uvm_fatal("csrng_path_if", $sformatf("%s: Invalid fifo name!", fifo_name)) endcase // case (fifo_name.substr(6, fifo_name.len()-1)) endfunction // fifo_err_path @@ -31,10 +26,7 @@ interface csrng_path_if "cmd_stage_sm": return {core_path, $sformatf(".gen_cmd_stage[%0d]", app), ".u_csrng_cmd_stage.state_q"}; "main_sm": return {core_path, ".u_csrng_main_sm.state_q"}; - "drbg_gen_sm": return {core_path, ".u_csrng_ctr_drbg_gen.state_q"}; - "drbg_updbe_sm": return {core_path, ".u_csrng_ctr_drbg_upd.blk_enc_state_q"}; - "drbg_updob_sm": return {core_path, ".u_csrng_ctr_drbg_upd.outblk_state_q"}; - "drbg_cmd_sm": return {core_path, ".u_csrng_ctr_drbg_cmd.state_q"}; + "ctr_drbg_sm": return {core_path, ".u_csrng_ctr_drbg.state_q"}; default: `uvm_fatal("csrng_path_if", "Invalid sm name!") endcase // case (which_sm) endfunction // sm_err_path @@ -65,13 +57,9 @@ interface csrng_path_if ".u_csrng_cmd_stage.u_prim_count_cmd_gen_cntr.cnt_q[1]"}; endfunction // cmd_gen_cnt_err_path - function automatic string drbg_upd_cnt_err_path(); - return {core_path, ".u_csrng_ctr_drbg_upd.u_prim_count_ctr_drbg.cnt_q[1]"}; - endfunction // drbg_upd_cnt_err_path - - function automatic string drbg_gen_cnt_err_path(); - return {core_path, ".u_csrng_ctr_drbg_gen.u_prim_count_ctr_drbg.cnt_q[1]"}; - endfunction // drbg_gen_cnt_err_path + function automatic string ctr_drbg_ctr_err_path(); + return {core_path, ".u_csrng_ctr_drbg.u_prim_count_ctr_drbg.cnt_q[1]"}; + endfunction // ctr_drbg_ctr_err_path function automatic string csrng_core_path(string path_ext); return {core_path, ".", path_ext}; diff --git a/hw/ip/csrng/dv/env/seq_lib/csrng_alert_vseq.sv b/hw/ip/csrng/dv/env/seq_lib/csrng_alert_vseq.sv index 9c8eefcc90090..d3c62637ed426 100644 --- a/hw/ip/csrng/dv/env/seq_lib/csrng_alert_vseq.sv +++ b/hw/ip/csrng/dv/env/seq_lib/csrng_alert_vseq.sv @@ -350,8 +350,7 @@ class csrng_alert_vseq extends csrng_base_vseq; task body(); // Values for the CMD_STAGE_INVALID_ACMD_ALERT test. - `DV_CHECK_MEMBER_RANDOMIZE_WITH_FATAL(illegal_command, illegal_command inside {INV, GENB, - GENU};) + `DV_CHECK_MEMBER_RANDOMIZE_WITH_FATAL(illegal_command, illegal_command inside {INV};) // For clen we just care about 0, 1 and the max value (coverage). `DV_CHECK_MEMBER_RANDOMIZE_WITH_FATAL(clen, clen inside {0, 1, 11};) diff --git a/hw/ip/csrng/dv/env/seq_lib/csrng_err_vseq.sv b/hw/ip/csrng/dv/env/seq_lib/csrng_err_vseq.sv index d561ef60e6da3..5dcf2d7358533 100644 --- a/hw/ip/csrng/dv/env/seq_lib/csrng_err_vseq.sv +++ b/hw/ip/csrng/dv/env/seq_lib/csrng_err_vseq.sv @@ -100,8 +100,7 @@ class csrng_err_vseq extends csrng_base_vseq; cfg.which_app_err_alert, fld_name), UVM_MEDIUM) case (cfg.which_err_code) inside - sfifo_cmd_err, sfifo_genbits_err, sfifo_final_err, sfifo_gbencack_err, sfifo_gadstage_err, - sfifo_cmdid_err: begin + sfifo_cmd_err, sfifo_genbits_err: begin fld = csr.get_field_by_name(fld_name); fifo_base_path = fld_name.substr(0, last_index-1); @@ -113,42 +112,12 @@ class csrng_err_vseq extends csrng_base_vseq; `uvm_info(`gfn, $sformatf("Forcing this FIFO error type %s", cfg.which_fifo_err.name()), UVM_MEDIUM) - // For sfifo_gadstage_err the down stream FIFO also takes inputs from sources other than - // sfifo_gadstage. To avoid the propagation of undefined data through CSRNG we need to - // force the input of sfifo_gbencack to zero. Otherwise this will cause a lot of assertions - // to trigger and eventually CSRNG will output undefined bits which causes some tlul checks - // to fail. - if ((cfg.which_err_code == sfifo_gadstage_err) && (cfg.which_fifo_err == fifo_read)) begin - fifo_forced_path_ds = cfg.csrng_path_vif.fifo_err_path(cfg.which_app_err_alert, - "sfifo_gbencack", "rdata"); - uvm_hdl_force(fifo_forced_path_ds, 'b0); - force_all_fifo_errs(fifo_forced_paths, fifo_forced_values, path_exts, fld, - 1'b1, cfg.which_fifo_err); - uvm_hdl_release(fifo_forced_path_ds); - - // For sfifo_gbencack_err the downstream arbiter receives an undefined signal if we - // force the write signal of sfifo_gbencack. This causes some assertions to trigger. - // For this reason we need to force adstage_glast to zero such that the request signal - // to the downstream arbiter doesn't go high. - end else if ((cfg.which_err_code == sfifo_gbencack_err) && - (cfg.which_fifo_err == fifo_write)) begin - fifo_forced_path_ds = - cfg.csrng_path_vif.csrng_core_path("u_csrng_ctr_drbg_gen.adstage_glast"); - uvm_hdl_force(fifo_forced_path_ds, 'b0); - force_all_fifo_errs(fifo_forced_paths, fifo_forced_values, path_exts, fld, - 1'b1, cfg.which_fifo_err); - cfg.clk_rst_vif.wait_clks(1); - uvm_hdl_release(fifo_forced_path_ds); - - end else begin - force_all_fifo_errs(fifo_forced_paths, fifo_forced_values, path_exts, fld, - 1'b1, cfg.which_fifo_err); - end + force_all_fifo_errs(fifo_forced_paths, fifo_forced_values, path_exts, fld, 1'b1, + cfg.which_fifo_err); csr_rd(.ptr(ral.err_code), .value(backdoor_err_code_val)); cov_vif.cg_err_code_sample(.err_code(backdoor_err_code_val)); end - cmd_stage_sm_err, main_sm_err, drbg_cmd_sm_err, drbg_gen_sm_err, drbg_updbe_sm_err, - drbg_updob_sm_err: begin + cmd_stage_sm_err, main_sm_err, ctr_drbg_sm_err: begin fld = csr.get_field_by_name(fld_name); path = cfg.csrng_path_vif.sm_err_path(fld_name.substr(0, last_index-1), cfg.which_app_err_alert); @@ -208,7 +177,7 @@ class csrng_err_vseq extends csrng_base_vseq; `DV_CHECK(uvm_hdl_read(aes_fsm_path, aes_fsm_state)) `DV_CHECK_EQ(aes_fsm_state, aes_pkg::CIPHER_CTRL_ERROR) end - cmd_gen_cnt_err: begin + ctr_err: begin logic [csrng_pkg::MainSmStateWidth-1:0] sm_state; string sm_state_path = cfg.csrng_path_vif.sm_err_path("main_sm", cfg.which_app_err_alert); case(cfg.which_cnt) inside @@ -217,14 +186,9 @@ class csrng_err_vseq extends csrng_base_vseq; path = cfg.csrng_path_vif.cmd_gen_cnt_err_path(cfg.which_app_err_alert); force_cnt_err(path, fld, 1'b1, csrng_pkg::GenBitsCtrWidth); end - drbg_upd_cnt_sel: begin + ctr_drbg_cnt_sel: begin fld = csr.get_field_by_name(fld_name); - path = cfg.csrng_path_vif.drbg_upd_cnt_err_path(); - force_cnt_err(path, fld, 1'b1, csrng_pkg::CtrLen); - end - drbg_gen_cnt_sel: begin - fld = csr.get_field_by_name(fld_name); - path = cfg.csrng_path_vif.drbg_gen_cnt_err_path(); + path = cfg.csrng_path_vif.ctr_drbg_ctr_err_path(); force_cnt_err(path, fld, 1'b1, csrng_pkg::CtrLen); end endcase @@ -254,33 +218,7 @@ class csrng_err_vseq extends csrng_base_vseq; value1 = fifo_err_value[0][path_key]; value2 = fifo_err_value[1][path_key]; - // For sfifo_gadstage the down stream FIFO also takes inputs from sources other than - // sfifo_gadstage. To avoid the propagation of undefined data through CSRNG we need to - // force the input of sfifo_gbencack to zero. Otherwise this will cause a lot of assertions - // to trigger and eventually CSRNG will output undefined bits which causes some tlul checks - // to fail. - if ((cfg.which_err_code == fifo_read_error) && (cfg.which_fifo == sfifo_gadstage)) begin - fifo_forced_path_ds = cfg.csrng_path_vif.fifo_err_path(cfg.which_app_err_alert, - "sfifo_gbencack", "rdata"); - uvm_hdl_force(fifo_forced_path_ds, 'b0); - force_fifo_readwrite_err(path1, path2, path3, value1, value2, 8'b0, fld, 1'b1); - uvm_hdl_release(fifo_forced_path_ds); - - // For sfifo_gbencack_err the downstream arbiter receives an undefined signal if we - // force the write signal of sfifo_gbencack. This causes some assertions to trigger. - // For this reason we need to force adstage_glast to zero such that the request signal - // to the downstream arbiter doesn't go high. - end else if ((cfg.which_err_code == fifo_write_error) && - (cfg.which_fifo == sfifo_gbencack)) begin - fifo_forced_path_ds = - cfg.csrng_path_vif.csrng_core_path("u_csrng_ctr_drbg_gen.adstage_glast"); - uvm_hdl_force(fifo_forced_path_ds, 'b0); - force_fifo_readwrite_err(path1, path2, path3, value1, value2, 8'b0, fld, 1'b1); - cfg.clk_rst_vif.wait_clks(1); - uvm_hdl_release(fifo_forced_path_ds); - - end else if (cfg.which_err_code == fifo_write_error || - cfg.which_err_code == fifo_read_err) begin + if (cfg.which_err_code == fifo_write_error || cfg.which_err_code == fifo_read_err) begin force_fifo_readwrite_err(path1, path2, path3, value1, value2, 8'b0, fld, 1'b1); end else begin force_fifo_err(path1, path2, value1, value2, fld, 1'b1); @@ -288,11 +226,7 @@ class csrng_err_vseq extends csrng_base_vseq; csr_rd(.ptr(ral.err_code), .value(backdoor_err_code_val)); cov_vif.cg_err_code_sample(.err_code(backdoor_err_code_val)); end - sfifo_cmd_err_test, sfifo_genbits_err_test, sfifo_final_err_test, - sfifo_gbencack_err_test, sfifo_gadstage_err_test, - sfifo_cmdid_err_test, cmd_stage_sm_err_test, main_sm_err_test, drbg_cmd_sm_err_test, - drbg_gen_sm_err_test, drbg_updbe_sm_err_test, drbg_updob_sm_err_test, aes_cipher_sm_err_test, - cmd_gen_cnt_err_test, fifo_write_err_test, fifo_read_err_test, fifo_state_err_test: begin + [sfifo_cmd_err_test : fifo_state_err_test]: begin fld = csr.get_field_by_name(fld_name.substr(0, last_index-1)); err_code_test_bit = fld.get_lsb_pos(); csr_wr(.ptr(ral.err_code_test.err_code_test), .value(err_code_test_bit)); @@ -324,12 +258,9 @@ class csrng_err_vseq extends csrng_base_vseq; if (cfg.which_err_code inside {cmd_stage_sm_err, cmd_stage_sm_err_test, main_sm_err, main_sm_err_test, - drbg_cmd_sm_err, drbg_cmd_sm_err_test, - drbg_gen_sm_err, drbg_gen_sm_err_test, - drbg_updbe_sm_err, drbg_updbe_sm_err_test, - drbg_updob_sm_err, drbg_updob_sm_err_test, + ctr_drbg_sm_err, ctr_drbg_sm_err_test, aes_cipher_sm_err, aes_cipher_sm_err_test, - cmd_gen_cnt_err, cmd_gen_cnt_err_test}) begin + ctr_err, ctr_err_test}) begin // These errors are either not gated with the module enable or they cause the main FSM to // escalate of which the alert output itself isn't gated with the module enable. After // clearing the interrupt state register, the cs_fatal_err interrupt bit again gets asserted. diff --git a/hw/ip/csrng/dv/env/seq_lib/csrng_intr_vseq.sv b/hw/ip/csrng/dv/env/seq_lib/csrng_intr_vseq.sv index 2688d58b3a995..85b7eecfee8eb 100644 --- a/hw/ip/csrng/dv/env/seq_lib/csrng_intr_vseq.sv +++ b/hw/ip/csrng/dv/env/seq_lib/csrng_intr_vseq.sv @@ -220,8 +220,7 @@ class csrng_intr_vseq extends csrng_base_vseq; last_index = find_index("_", fld_name, "last"); case (cfg.which_fatal_err) inside - sfifo_cmd_error, sfifo_genbits_error, sfifo_final_error, sfifo_cmdid_error, - sfifo_gadstage_error, sfifo_gbencack_error: begin + sfifo_cmd_error, sfifo_genbits_error: begin fifo_base_path = fld_name.substr(0, last_index-1); foreach (path_exts[i]) begin @@ -231,8 +230,7 @@ class csrng_intr_vseq extends csrng_base_vseq; force_all_fifo_errs(fifo_forced_paths, fifo_forced_values, path_exts, ral.intr_state.cs_fatal_err, 1'b1, cfg.which_fifo_err); end - cmd_stage_sm_error, main_sm_error, drbg_cmd_sm_error, drbg_gen_sm_error, drbg_updbe_sm_error, - drbg_updob_sm_error: begin + cmd_stage_sm_error, main_sm_error, ctr_drbg_sm_error: begin path = cfg.csrng_path_vif.sm_err_path(fld_name.substr(0, last_index-1), cfg.NHwApps); force_path_err(path, 8'b0, ral.intr_state.cs_fatal_err, 1'b1); end @@ -285,7 +283,7 @@ class csrng_intr_vseq extends csrng_base_vseq; `DV_CHECK(uvm_hdl_read(aes_fsm_path, aes_fsm_state)) `DV_CHECK_EQ(aes_fsm_state, aes_pkg::CIPHER_CTRL_ERROR) end - cmd_gen_cnt_error: begin + ctr_error: begin path = cfg.csrng_path_vif.cmd_gen_cnt_err_path(cfg.NHwApps); force_path_err(path, 8'h01, ral.intr_state.cs_fatal_err, 1'b1); end @@ -365,10 +363,8 @@ class csrng_intr_vseq extends csrng_base_vseq; csr_wr(.ptr(ral.intr_state), .value(32'd15)); cfg.clk_rst_vif.wait_clks(100); - if (cfg.which_fatal_err inside {cmd_stage_sm_err, main_sm_err, drbg_cmd_sm_err, - drbg_gen_sm_err, drbg_updbe_sm_err, drbg_updob_sm_err, - aes_cipher_sm_err, - cmd_gen_cnt_err, cmd_gen_cnt_err_test}) begin + if (cfg.which_fatal_err inside {cmd_stage_sm_err, main_sm_err, ctr_drbg_sm_err, + aes_cipher_sm_err, ctr_err, ctr_err_test}) begin // These errors are either not gated with the module enable or they cause the main FSM to // escalate of which the alert output itself isn't gated with the module enable. After // clearing the interrupt state register, the cs_fatal_err interrupt bit again gets asserted. diff --git a/hw/ip/csrng/dv/sva/csrng_assert_if.sv b/hw/ip/csrng/dv/sva/csrng_assert_if.sv index 39755ed026753..4ccaf8c6dbb18 100644 --- a/hw/ip/csrng/dv/sva/csrng_assert_if.sv +++ b/hw/ip/csrng/dv/sva/csrng_assert_if.sv @@ -21,18 +21,8 @@ `define PATH2_3 \ gen_fsm[2].gen_fsm_n.u_aes_cipher_control_fsm_i.u_aes_cipher_control_fsm `define PATH3 \ - u_csrng_core.u_prim_mubi4_sync_cs_enable + u_csrng_core.u_csrng_ctr_drbg `define PATH4 \ - u_csrng_core.u_prim_mubi4_sync_sw_app_enable -`define PATH5 \ - u_csrng_core.u_prim_mubi4_sync_read_int_state -`define PATH6 \ - u_csrng_core.u_csrng_ctr_drbg_upd -`define PATH7 \ - u_csrng_core.u_csrng_ctr_drbg_gen -`define PATH8 \ - u_csrng_core.u_csrng_ctr_drbg_cmd -`define PATH9 \ u_csrng_core.u_csrng_main_sm interface csrng_assert_if @@ -48,11 +38,8 @@ interface csrng_assert_if $assertoff(0, `DUT_PATH.`PATH2.`PATH2_1.u_state_regs_A); $assertoff(0, `DUT_PATH.`PATH2.`PATH2_2.u_state_regs_A); $assertoff(0, `DUT_PATH.`PATH2.`PATH2_3.u_state_regs_A); - $assertoff(0, `DUT_PATH.`PATH6.u_outblk_state_regs_A); - $assertoff(0, `DUT_PATH.`PATH6.u_blk_enc_state_regs_A); - $assertoff(0, `DUT_PATH.`PATH7.u_state_regs_A); - $assertoff(0, `DUT_PATH.`PATH8.u_state_regs_A); - $assertoff(0, `DUT_PATH.`PATH9.u_state_regs_A); + $assertoff(0, `DUT_PATH.`PATH3.u_state_regs_A); + $assertoff(0, `DUT_PATH.`PATH4.u_state_regs_A); endtask // assert_off task automatic assert_on (); @@ -63,11 +50,8 @@ interface csrng_assert_if $asserton(0, `DUT_PATH.`PATH2.`PATH2_1.u_state_regs_A); $asserton(0, `DUT_PATH.`PATH2.`PATH2_2.u_state_regs_A); $asserton(0, `DUT_PATH.`PATH2.`PATH2_3.u_state_regs_A); - $asserton(0, `DUT_PATH.`PATH6.u_outblk_state_regs_A); - $asserton(0, `DUT_PATH.`PATH6.u_blk_enc_state_regs_A); - $asserton(0, `DUT_PATH.`PATH7.u_state_regs_A); - $asserton(0, `DUT_PATH.`PATH8.u_state_regs_A); - $asserton(0, `DUT_PATH.`PATH9.u_state_regs_A); + $asserton(0, `DUT_PATH.`PATH3.u_state_regs_A); + $asserton(0, `DUT_PATH.`PATH4.u_state_regs_A); endtask // assert_on task automatic assert_off_alert (); @@ -78,10 +62,6 @@ interface csrng_assert_if endtask // assert_on_alert endinterface -`undef PATH8 -`undef PATH7 -`undef PATH6 -`undef PATH5 `undef PATH4 `undef PATH3 `undef PATH2_3 diff --git a/hw/ip/csrng/dv/tb.sv b/hw/ip/csrng/dv/tb.sv index 67c4015d1b389..84eff7cd77bd1 100644 --- a/hw/ip/csrng/dv/tb.sv +++ b/hw/ip/csrng/dv/tb.sv @@ -139,17 +139,6 @@ module tb; `DV_ASSERT_CTRL("CmdStageFifoAsserts", CmdStageFifoFullNotReady) end - // Ensure that upon local escalation of the AES cipher core inside Block Encrypt, no intermediate - // v is released into the ctr_drbg_gen/update blocks. - `define BLOCK_ENCRYPT_PATH tb.dut.u_csrng_core.u_csrng_block_encrypt - `define CTR_DRBG_GEN tb.dut.u_csrng_core.u_csrng_ctr_drbg_gen - `define CTR_DRBG_GEN_FIFO `CTR_DRBG_GEN.u_prim_fifo_sync_bencack.gen_singleton_fifo - `ASSERT(CsrngSecCmAesCipherDataRegLocalEscGen, - $rose(`CTR_DRBG_GEN_FIFO.full_q) && `BLOCK_ENCRYPT_PATH.cipher_sm_err_o |=> - $past(`CTR_DRBG_GEN_FIFO.storage - [csrng_pkg::BencDataWidth-1 -: csrng_pkg::BlkLen]) != - $past(`BLOCK_ENCRYPT_PATH.cipher_data_out, 2), clk, !rst_n) - // Assertion controls `DV_ASSERT_CTRL("EntropySrcIf_ReqHighUntilAck_A_CTRL", entropy_src_if.ReqHighUntilAck_A) `DV_ASSERT_CTRL("EntropySrcIf_AckAssertedOnlyWhenReqAsserted_A_CTRL", diff --git a/hw/ip/csrng/rtl/csrng.sv b/hw/ip/csrng/rtl/csrng.sv index aab7502d4a0a2..a9fbb7e8933c1 100644 --- a/hw/ip/csrng/rtl/csrng.sv +++ b/hw/ip/csrng/rtl/csrng.sv @@ -165,12 +165,8 @@ module csrng `ASSERT_KNOWN(IntrCsHwInstExcKnownO_A, intr_cs_hw_inst_exc_o) `ASSERT_KNOWN(IntrCsFatalErrKnownO_A, intr_cs_fatal_err_o) - `ASSERT_PRIM_COUNT_ERROR_TRIGGER_ALERT(CtrDrbgUpdAlertCheck_A, - u_csrng_core.u_csrng_ctr_drbg_upd.u_prim_count_ctr_drbg, - alert_tx_o[1]) - `ASSERT_PRIM_COUNT_ERROR_TRIGGER_ALERT(CtrDrbgGenAlertCheck_A, - u_csrng_core.u_csrng_ctr_drbg_gen.u_prim_count_ctr_drbg, + u_csrng_core.u_csrng_ctr_drbg.u_prim_count_ctr_drbg, alert_tx_o[1]) for (genvar i = 0; i < NumHwApps + 1; i++) begin : gen_cnt_asserts @@ -187,21 +183,10 @@ module csrng u_csrng_core.u_csrng_main_sm.u_state_regs, alert_tx_o[1]) - `ASSERT_PRIM_FSM_ERROR_TRIGGER_ALERT(DrbgCmdFsmCheck_A, - u_csrng_core.u_csrng_ctr_drbg_cmd.u_state_regs, - alert_tx_o[1]) - `ASSERT_PRIM_FSM_ERROR_TRIGGER_ALERT(DrbgGenFsmCheck_A, - u_csrng_core.u_csrng_ctr_drbg_gen.u_state_regs, + u_csrng_core.u_csrng_ctr_drbg.u_state_regs, alert_tx_o[1]) - `ASSERT_PRIM_FSM_ERROR_TRIGGER_ALERT(DrbgUpdBlkEncFsmCheck_A, - u_csrng_core.u_csrng_ctr_drbg_upd.u_blk_enc_state_regs, - alert_tx_o[1]) - - `ASSERT_PRIM_FSM_ERROR_TRIGGER_ALERT(DrbgUpdOutBlkFsmCheck_A, - u_csrng_core.u_csrng_ctr_drbg_upd.u_outblk_state_regs, - alert_tx_o[1]) for (genvar i = 0; i < aes_pkg::Sp2VWidth; i++) begin : gen_aes_cipher_control_fsm_svas if (aes_pkg::SP2V_LOGIC_HIGH[i] == 1'b1) begin : gen_aes_cipher_control_fsm_svas_p diff --git a/hw/ip/csrng/rtl/csrng_block_encrypt.sv b/hw/ip/csrng/rtl/csrng_block_encrypt.sv index 5904b41d52f05..08862373b4ac7 100644 --- a/hw/ip/csrng/rtl/csrng_block_encrypt.sv +++ b/hw/ip/csrng/rtl/csrng_block_encrypt.sv @@ -2,51 +2,41 @@ // Licensed under the Apache License, Version 2.0, see LICENSE for details. // SPDX-License-Identifier: Apache-2.0 // -// Description: csrng block encrypt module +// Description: AES-based block encrypt module for CSRNG // module csrng_block_encrypt import csrng_pkg::*; #( parameter aes_pkg::sbox_impl_e SBoxImpl = aes_pkg::SBoxImplLut ) ( - input logic clk_i, - input logic rst_ni, + input logic clk_i, + input logic rst_ni, // Global enable - input logic enable_i, + input logic enable_i, - // Request from update and generate stages - input logic req_vld_i, - output logic req_rdy_o, - input csrng_benc_data_t req_data_i, + // Request from ctr_drbg + input logic req_vld_i, + output logic req_rdy_o, + input csrng_key_v_t req_data_i, - // Response to update and generate stages - output logic rsp_vld_o, - input logic rsp_rdy_i, - output csrng_benc_data_t rsp_data_o, + // Response to ctr_drbg + output logic rsp_vld_o, + input logic rsp_rdy_i, + output logic [BlkLen-1:0] rsp_data_o, // Status and error signals - output logic cipher_quiet_o, - output logic cipher_sm_err_o, - output logic [2:0] fifo_cmdid_err_o + output logic cipher_quiet_o, + output logic cipher_sm_err_o ); localparam int unsigned NumShares = 1; - localparam int unsigned CmdIdFifoWidth = CmdWidth + InstIdWidth; // Signals - logic sfifo_cmdid_wvld; - logic sfifo_cmdid_wrdy; - logic [CmdIdFifoWidth-1:0] sfifo_cmdid_wdata; - logic sfifo_cmdid_rvld; - logic sfifo_cmdid_rrdy; - logic [CmdIdFifoWidth-1:0] sfifo_cmdid_rdata; - aes_pkg::sp2v_e cipher_in_valid; aes_pkg::sp2v_e cipher_in_ready; aes_pkg::sp2v_e cipher_out_valid; aes_pkg::sp2v_e cipher_out_ready; aes_pkg::sp2v_e cipher_crypt_busy; - logic [BlkLen-1:0] cipher_data_out; logic [3:0][3:0][7:0] state_init[NumShares]; @@ -54,16 +44,15 @@ module csrng_block_encrypt import csrng_pkg::*; #( logic [3:0][3:0][7:0] state_done[NumShares]; logic [3:0][3:0][7:0] state_out; - //-------------------------------------------- - // aes cipher core + // AES cipher core //-------------------------------------------- assign state_init[0] = aes_pkg::aes_transpose({<<8{req_data_i.v}}); assign key_init[0] = {<<8{req_data_i.key}}; - assign state_out = aes_pkg::aes_transpose(state_done[0]); - assign cipher_data_out = {<<8{state_out}}; + assign state_out = aes_pkg::aes_transpose(state_done[0]); + assign rsp_data_o = {<<8{state_out}}; assign cipher_in_valid = (enable_i && req_vld_i) ? aes_pkg::SP2V_HIGH : aes_pkg::SP2V_LOW; @@ -116,40 +105,6 @@ module csrng_block_encrypt import csrng_pkg::*; #( .state_o (state_done) ); - //-------------------------------------------- - // cmd / id tracking fifo - //-------------------------------------------- - - prim_fifo_sync #( - .Width(CmdIdFifoWidth), - .Depth(1), - .Pass(0) - ) u_prim_fifo_sync_cmdid ( - .clk_i (clk_i), - .rst_ni (rst_ni), - .clr_i (!enable_i), - .wvalid_i(sfifo_cmdid_wvld), - .wready_o(sfifo_cmdid_wrdy), - .wdata_i (sfifo_cmdid_wdata), - .rvalid_o(sfifo_cmdid_rvld), - .rready_i(sfifo_cmdid_rrdy), - .rdata_o (sfifo_cmdid_rdata), - .full_o (), - .depth_o (), - .err_o () - ); - - assign sfifo_cmdid_wvld = req_vld_i && sfifo_cmdid_wrdy; - assign sfifo_cmdid_wdata = {req_data_i.inst_id, - req_data_i.cmd}; - - assign rsp_data_o = '{ - inst_id: sfifo_cmdid_rdata[CmdWidth +: InstIdWidth], - cmd: acmd_e'(sfifo_cmdid_rdata[CmdWidth-1:0]), - key: '0, // unused in rsp path - v: cipher_data_out - }; - // The cipher determines whether the response is ready for consumption assign rsp_vld_o = (cipher_out_valid == aes_pkg::SP2V_HIGH); @@ -157,14 +112,6 @@ module csrng_block_encrypt import csrng_pkg::*; #( assign req_rdy_o = (cipher_in_ready == aes_pkg::SP2V_HIGH); assign cipher_out_ready = rsp_rdy_i ? aes_pkg::SP2V_HIGH : aes_pkg::SP2V_LOW; - // Empty the cmdid FIFO when the data response is consumed - assign sfifo_cmdid_rrdy = rsp_rdy_i && rsp_vld_o; - - assign fifo_cmdid_err_o = - {( sfifo_cmdid_wvld && !sfifo_cmdid_wrdy), - ( sfifo_cmdid_rrdy && !sfifo_cmdid_rvld), - (!sfifo_cmdid_wrdy && !sfifo_cmdid_rvld)}; - //-------------------------------------------- // Cipher idle detection //-------------------------------------------- diff --git a/hw/ip/csrng/rtl/csrng_cmd_stage.sv b/hw/ip/csrng/rtl/csrng_cmd_stage.sv index e060147367aeb..63cc0daf56a1f 100644 --- a/hw/ip/csrng/rtl/csrng_cmd_stage.sv +++ b/hw/ip/csrng/rtl/csrng_cmd_stage.sv @@ -251,6 +251,7 @@ module csrng_cmd_stage import csrng_pkg::*; ( Error = 8'b01100111 // illegal state reached and hang } state_e; + // SEC_CM: CMD_STAGE.FSM.SPARSE state_e state_d, state_q; `PRIM_FLOP_SPARSE_FSM(u_state_regs, state_d, state_q, state_e, Idle) diff --git a/hw/ip/csrng/rtl/csrng_core.sv b/hw/ip/csrng/rtl/csrng_core.sv index 0dd7aa60052eb..4aac27968a7da 100644 --- a/hw/ip/csrng/rtl/csrng_core.sv +++ b/hw/ip/csrng/rtl/csrng_core.sv @@ -62,9 +62,6 @@ module csrng_core import csrng_pkg::*; #( // signals // interrupt signals - logic event_cs_cmd_req_done; - logic event_cs_entropy_req; - logic event_cs_hw_inst_exc; logic event_cs_fatal_err; logic [CsEnableCopies-1:1] cs_enable_fo; logic [Flag0Copies-1:0] flag0_fo; @@ -86,8 +83,6 @@ module csrng_core import csrng_pkg::*; #( logic acmd_eop; logic state_db_wr_vld; - csrng_core_data_t state_db_wr_data; - csrng_cmd_sts_e state_db_wr_sts; csrng_state_t state_db_rd_data; logic [CmdBusWidth-1:0] acmd_bus; @@ -101,112 +96,46 @@ module csrng_core import csrng_pkg::*; #( logic cmd_entropy_req; logic cmd_entropy_avail; - logic cmd_entropy_fips; - logic [SeedLen-1:0] cmd_entropy; - logic ctr_drbg_cmd_rsp_vld; - logic ctr_drbg_cmd_rsp_rdy; - csrng_core_data_t ctr_drbg_cmd_rsp_data; - logic ctr_drbg_cmd_rsp_glast; + logic ctr_drbg_req_vld; + logic ctr_drbg_req_rdy; + csrng_core_data_t ctr_drbg_req_data; - logic ctr_drbg_cmd_req_vld; - logic ctr_drbg_cmd_req_rdy; - csrng_core_data_t ctr_drbg_cmd_req_data; + logic ctr_drbg_rsp_vld; + csrng_core_data_t ctr_drbg_rsp_data; + csrng_cmd_sts_e ctr_drbg_rsp_sts; - logic ctr_drbg_gen_req_vld; - logic ctr_drbg_gen_req_rdy; - - logic ctr_drbg_gen_rsp_vld; - logic ctr_drbg_gen_rsp_rdy; - csrng_core_data_t ctr_drbg_gen_rsp_data; - logic [BlkLen-1:0] ctr_drbg_gen_rsp_bits; - csrng_cmd_sts_e ctr_drbg_gen_rsp_sts; - - logic state_db_sts_ack; - csrng_cmd_sts_e state_db_sts_sts; - logic [InstIdWidth-1:0] state_db_sts_id; + logic ctr_drbg_bits_vld; + logic [BlkLen-1:0] ctr_drbg_bits_data; + logic ctr_drbg_bits_fips; logic acmd_accept; logic main_sm_cmd_vld; logic clr_adata_packer; - logic ctr_drbg_upd_sfifo_final_err_sum; - logic [2:0] ctr_drbg_upd_sfifo_final_err; - logic ctr_drbg_gen_sfifo_gbencack_err_sum; - logic [2:0] ctr_drbg_gen_sfifo_gbencack_err; - logic ctr_drbg_gen_sfifo_gadstage_err_sum; - logic [2:0] ctr_drbg_gen_sfifo_gadstage_err; - logic block_encrypt_sfifo_cmdid_err_sum; - logic [2:0] block_encrypt_sfifo_cmdid_err; logic fifo_write_err_sum; logic fifo_read_err_sum; logic fifo_status_err_sum; + logic ctr_err_sum; - logic cmd_gen_cnt_err_sum; logic cmd_stage_sm_err_sum; logic main_sm_err_sum; logic cs_main_sm_err; logic [MainSmStateWidth-1:0] cs_main_sm_state; - logic drbg_cmd_sm_err_sum; - logic drbg_cmd_sm_err; - logic drbg_gen_sm_err_sum; - logic drbg_gen_sm_err; - logic drbg_updbe_sm_err_sum; - logic drbg_updbe_sm_err; - logic drbg_updob_sm_err_sum; - logic drbg_updob_sm_err; + logic ctr_drbg_sm_err_sum; + logic ctr_drbg_sm_err; + logic ctr_drbg_v_ctr_err; logic block_encrypt_sm_err_sum; logic block_encrypt_sm_err; - // blk encrypt arbiter - // request path - logic upd_benc_req_vld; - logic upd_benc_req_rdy; - csrng_benc_data_t upd_benc_req_data; - - logic gen_benc_req_vld; - logic gen_benc_req_rdy; - csrng_benc_data_t gen_benc_req_data; - + // Signals to and from block cipher logic block_encrypt_req_vld; logic block_encrypt_req_rdy; - csrng_benc_data_t block_encrypt_req_data; - - // response path - logic upd_benc_rsp_vld; - logic upd_benc_rsp_rdy; - - logic gen_benc_rsp_vld; - logic gen_benc_rsp_rdy; + csrng_key_v_t block_encrypt_req_data; logic block_encrypt_rsp_vld; logic block_encrypt_rsp_rdy; - csrng_benc_data_t block_encrypt_rsp_data; - - // update unit arbiter - // request path - logic cmd_upd_req_vld; - logic cmd_upd_req_rdy; - csrng_upd_data_t cmd_upd_req_data; - - logic gen_upd_req_vld; - logic gen_upd_req_rdy; - csrng_upd_data_t gen_upd_req_data; - - logic upd_arb_req_vld; - logic upd_arb_req_rdy; - csrng_upd_data_t upd_arb_req_data; - - // response path - logic cmd_upd_rsp_vld; - logic cmd_upd_rsp_rdy; - - logic gen_upd_rsp_vld; - logic gen_upd_rsp_rdy; - - logic upd_rsp_vld; - logic upd_rsp_rdy; - csrng_upd_data_t upd_rsp_data; + logic [BlkLen-1:0] block_encrypt_rsp_data; logic [2:0] cmd_stage_sfifo_cmd_err[NumApps]; @@ -219,10 +148,8 @@ module csrng_core import csrng_pkg::*; #( logic [NumApps-1:0] cmd_stage_sfifo_genbits_err_wr; logic [NumApps-1:0] cmd_stage_sfifo_genbits_err_rd; logic [NumApps-1:0] cmd_stage_sfifo_genbits_err_st; - logic [NumApps-1:0] cmd_gen_cnt_err; + logic [NumApps-1:0] cmd_stage_ctr_err; logic [NumApps-1:0] cmd_stage_sm_err; - logic ctr_drbg_upd_v_ctr_err; - logic ctr_drbg_gen_v_ctr_err; logic [NumApps-1:0] cmd_stage_vld; logic [InstIdWidth-1:0] cmd_stage_shid[NumApps]; @@ -246,27 +173,23 @@ module csrng_core import csrng_pkg::*; #( logic [NumApps-1:0] genbits_stage_fips; logic [BlkLen-1:0] genbits_stage_bus[NumApps]; logic [NumApps-1:0] genbits_stage_rdy; - logic genbits_stage_vldo_sw; + logic genbits_stage_vld_sw; logic genbits_stage_bus_rd_sw; logic [31:0] genbits_stage_bus_sw; - logic genbits_stage_fips_sw; logic [15:0] hw_exception_sts; logic [LcHwDebugCopies-1:0] lc_hw_debug_on_fo; logic state_db_reg_read_en; logic [30:0] err_code_test_bit; - logic ctr_drbg_upd_es_ack; - logic ctr_drbg_gen_es_ack; + logic ctr_drbg_es_halt_ack; logic block_encrypt_quiet; logic cs_rdata_capt_vld; logic cs_bus_cmp_alert; - logic cmd_rdy; logic [NumApps-1:0] invalid_cmd_seq_alert; logic [NumApps-1:0] invalid_acmd_alert; logic [NumApps-1:0] reseed_cnt_alert; - logic sw_sts_ack; logic [1:0] otp_sw_app_read_en; logic [NumApps-1:0][31:0] reseed_counter; @@ -276,31 +199,31 @@ module csrng_core import csrng_pkg::*; #( prim_mubi_pkg::mubi4_t [Flag0Copies-1:0] mubi_flag0_fanout; // flops - acmd_e acmd_q, acmd_d; - logic [3:0] shid_q, shid_d; - logic gen_last_q, gen_last_d; - mubi4_t flag0_q, flag0_d; - logic [NumAppsLg-1:0] cmd_arb_idx_q, cmd_arb_idx_d; - logic genbits_stage_fips_sw_q, genbits_stage_fips_sw_d; - acmd_e cmd_req_ccmd_dly_q, cmd_req_ccmd_dly_d; - logic cs_aes_halt_q, cs_aes_halt_d; - logic [SeedLen-1:0] entropy_src_seed_q, entropy_src_seed_d; - logic entropy_src_fips_q, entropy_src_fips_d; - logic [63:0] cs_rdata_capt_q, cs_rdata_capt_d; - logic cs_rdata_capt_vld_q, cs_rdata_capt_vld_d; - logic sw_rdy_sts_q, sw_rdy_sts_d; - logic sw_sts_ack_q, sw_sts_ack_d; - logic [NumApps-1:0] reseed_cnt_reached_q, reseed_cnt_reached_d; + acmd_e acmd_q, acmd_d; + logic [NumAppsLg-1:0] inst_id_q, inst_id_d; + logic gen_last_q, gen_last_d; + mubi4_t flag0_q, flag0_d; + logic [NumAppsLg-1:0] cmd_arb_idx_q, cmd_arb_idx_d; + logic genbits_stage_fips_sw_q, genbits_stage_fips_sw_d; + acmd_e ctr_drbg_cmd_q, ctr_drbg_cmd_d; + logic cs_aes_halt_q, cs_aes_halt_d; + logic [SeedLen-1:0] entropy_src_seed_q, entropy_src_seed_d; + logic entropy_src_fips_q, entropy_src_fips_d; + logic [63:0] cs_rdata_capt_q, cs_rdata_capt_d; + logic cs_rdata_capt_vld_q, cs_rdata_capt_vld_d; + logic sw_rdy_sts_q, sw_rdy_sts_d; + logic sw_sts_ack_q, sw_sts_ack_d; + logic [NumApps-1:0] reseed_cnt_reached_q, reseed_cnt_reached_d; always_ff @(posedge clk_i or negedge rst_ni) begin if (!rst_ni) begin acmd_q <= INV; - shid_q <= '0; + inst_id_q <= '0; gen_last_q <= '0; flag0_q <= prim_mubi_pkg::MuBi4False; cmd_arb_idx_q <= '0; genbits_stage_fips_sw_q <= '0; - cmd_req_ccmd_dly_q <= INV; + ctr_drbg_cmd_q <= INV; cs_aes_halt_q <= '0; entropy_src_seed_q <= '0; entropy_src_fips_q <= '0; @@ -311,12 +234,12 @@ module csrng_core import csrng_pkg::*; #( reseed_cnt_reached_q <= '0; end else begin acmd_q <= acmd_d; - shid_q <= shid_d; + inst_id_q <= inst_id_d; gen_last_q <= gen_last_d; flag0_q <= flag0_d; cmd_arb_idx_q <= cmd_arb_idx_d; genbits_stage_fips_sw_q <= genbits_stage_fips_sw_d; - cmd_req_ccmd_dly_q <= cmd_req_ccmd_dly_d; + ctr_drbg_cmd_q <= ctr_drbg_cmd_d; cs_aes_halt_q <= cs_aes_halt_d; entropy_src_seed_q <= entropy_src_seed_d; entropy_src_fips_q <= entropy_src_fips_d; @@ -338,7 +261,7 @@ module csrng_core import csrng_pkg::*; #( ) u_intr_hw_cs_cmd_req_done ( .clk_i (clk_i), .rst_ni (rst_ni), - .event_intr_i (event_cs_cmd_req_done), + .event_intr_i (cmd_stage_ack[NumApps-1]), .reg2hw_intr_enable_q_i(reg2hw.intr_enable.cs_cmd_req_done.q), .reg2hw_intr_test_q_i (reg2hw.intr_test.cs_cmd_req_done.q), .reg2hw_intr_test_qe_i (reg2hw.intr_test.cs_cmd_req_done.qe), @@ -353,7 +276,7 @@ module csrng_core import csrng_pkg::*; #( ) u_intr_hw_cs_entropy_req ( .clk_i (clk_i), .rst_ni (rst_ni), - .event_intr_i (event_cs_entropy_req), + .event_intr_i (entropy_src_hw_if_o.es_req), .reg2hw_intr_enable_q_i(reg2hw.intr_enable.cs_entropy_req.q), .reg2hw_intr_test_q_i (reg2hw.intr_test.cs_entropy_req.q), .reg2hw_intr_test_qe_i (reg2hw.intr_test.cs_entropy_req.qe), @@ -368,7 +291,7 @@ module csrng_core import csrng_pkg::*; #( ) u_intr_hw_cs_hw_inst_exc ( .clk_i (clk_i), .rst_ni (rst_ni), - .event_intr_i (event_cs_hw_inst_exc), + .event_intr_i (|hw_exception_sts), .reg2hw_intr_enable_q_i(reg2hw.intr_enable.cs_hw_inst_exc.q), .reg2hw_intr_test_q_i (reg2hw.intr_test.cs_hw_inst_exc.q), .reg2hw_intr_test_qe_i (reg2hw.intr_test.cs_hw_inst_exc.qe), @@ -398,131 +321,54 @@ module csrng_core import csrng_pkg::*; #( // inferring combo loops. However, to include the state machine error for testing, // we use the error code test bit (index 21) directly. logic fatal_loc_events; - assign fatal_loc_events = cmd_gen_cnt_err_sum || - cmd_stage_sm_err_sum || - drbg_cmd_sm_err_sum || - drbg_gen_sm_err_sum || - drbg_updbe_sm_err_sum || - drbg_updob_sm_err_sum || - block_encrypt_sm_err_sum || - err_code_test_bit[21]; + assign fatal_loc_events = block_encrypt_sm_err_sum || cmd_stage_sm_err_sum || ctr_drbg_sm_err_sum + || ctr_err_sum || err_code_test_bit[21]; // set the interrupt sources - assign event_cs_fatal_err = (cs_enable_fo[1] && ( - (|cmd_stage_sfifo_cmd_err_sum) || - (|cmd_stage_sfifo_genbits_err_sum) || - ctr_drbg_upd_sfifo_final_err_sum || - ctr_drbg_gen_sfifo_gbencack_err_sum || - ctr_drbg_gen_sfifo_gadstage_err_sum || - block_encrypt_sfifo_cmdid_err_sum || - fifo_write_err_sum || - fifo_read_err_sum || - fifo_status_err_sum)) || - // errs not gated by cs_enable - main_sm_err_sum || - fatal_loc_events; - - // set fifo errors that are single instances of source - assign ctr_drbg_upd_sfifo_final_err_sum = (|ctr_drbg_upd_sfifo_final_err) || - err_code_test_bit[9]; - assign ctr_drbg_gen_sfifo_gbencack_err_sum = (|ctr_drbg_gen_sfifo_gbencack_err) || - err_code_test_bit[10]; - assign ctr_drbg_gen_sfifo_gadstage_err_sum = (|ctr_drbg_gen_sfifo_gadstage_err) || - err_code_test_bit[13]; - assign block_encrypt_sfifo_cmdid_err_sum = (|block_encrypt_sfifo_cmdid_err) || - err_code_test_bit[15]; + assign event_cs_fatal_err = fatal_loc_events || main_sm_err_sum || (cs_enable_fo[1] && + ((|cmd_stage_sfifo_cmd_err_sum) || (|cmd_stage_sfifo_genbits_err_sum) + || fifo_write_err_sum || fifo_read_err_sum || fifo_status_err_sum)); + + + // Individual error signals/sources assign cmd_stage_sm_err_sum = (|cmd_stage_sm_err) || err_code_test_bit[20]; assign main_sm_err_sum = cs_main_sm_err || err_code_test_bit[21]; - assign drbg_gen_sm_err_sum = drbg_gen_sm_err || err_code_test_bit[22]; - assign drbg_updbe_sm_err_sum = drbg_updbe_sm_err || err_code_test_bit[23]; - assign drbg_updob_sm_err_sum = drbg_updob_sm_err || err_code_test_bit[24]; + assign ctr_drbg_sm_err_sum = ctr_drbg_sm_err || err_code_test_bit[22]; assign block_encrypt_sm_err_sum = block_encrypt_sm_err || err_code_test_bit[25]; - assign drbg_cmd_sm_err_sum = drbg_cmd_sm_err || err_code_test_bit[27]; - assign cmd_gen_cnt_err_sum = (|cmd_gen_cnt_err) || ctr_drbg_gen_v_ctr_err || - ctr_drbg_upd_v_ctr_err || err_code_test_bit[26]; - assign fifo_write_err_sum = - block_encrypt_sfifo_cmdid_err[2] || - ctr_drbg_gen_sfifo_gadstage_err[2] || - ctr_drbg_gen_sfifo_gbencack_err[2] || - ctr_drbg_upd_sfifo_final_err[2] || - (|cmd_stage_sfifo_genbits_err_wr) || - (|cmd_stage_sfifo_cmd_err_wr) || - err_code_test_bit[28]; - assign fifo_read_err_sum = - block_encrypt_sfifo_cmdid_err[1] || - ctr_drbg_gen_sfifo_gadstage_err[1] || - ctr_drbg_gen_sfifo_gbencack_err[1] || - ctr_drbg_upd_sfifo_final_err[1] || - (|cmd_stage_sfifo_genbits_err_rd) || - (|cmd_stage_sfifo_cmd_err_rd) || - err_code_test_bit[29]; - assign fifo_status_err_sum = - block_encrypt_sfifo_cmdid_err[0] || - ctr_drbg_gen_sfifo_gadstage_err[0] || - ctr_drbg_gen_sfifo_gbencack_err[0] || - ctr_drbg_upd_sfifo_final_err[0] || - (|cmd_stage_sfifo_genbits_err_st) || - (|cmd_stage_sfifo_cmd_err_st) || - err_code_test_bit[30]; + + // Collective error signals for each type of error + assign ctr_err_sum = (|cmd_stage_ctr_err) || ctr_drbg_v_ctr_err || err_code_test_bit[26]; + assign fifo_write_err_sum = (|cmd_stage_sfifo_genbits_err_wr) || (|cmd_stage_sfifo_cmd_err_wr) || + err_code_test_bit[28]; + assign fifo_read_err_sum = (|cmd_stage_sfifo_genbits_err_rd) || (|cmd_stage_sfifo_cmd_err_rd) || + err_code_test_bit[29]; + assign fifo_status_err_sum = (|cmd_stage_sfifo_genbits_err_st) || (|cmd_stage_sfifo_cmd_err_st) || + err_code_test_bit[30]; // set the err code source bits assign hw2reg.err_code.sfifo_cmd_err.d = 1'b1; - assign hw2reg.err_code.sfifo_cmd_err.de = cs_enable_fo[2] && - (|cmd_stage_sfifo_cmd_err_sum); + assign hw2reg.err_code.sfifo_cmd_err.de = cs_enable_fo[2] && (|cmd_stage_sfifo_cmd_err_sum); assign hw2reg.err_code.sfifo_genbits_err.d = 1'b1; assign hw2reg.err_code.sfifo_genbits_err.de = cs_enable_fo[3] && (|cmd_stage_sfifo_genbits_err_sum); - assign hw2reg.err_code.sfifo_final_err.d = 1'b1; - assign hw2reg.err_code.sfifo_final_err.de = cs_enable_fo[11] && - ctr_drbg_upd_sfifo_final_err_sum; - - assign hw2reg.err_code.sfifo_gbencack_err.d = 1'b1; - assign hw2reg.err_code.sfifo_gbencack_err.de = cs_enable_fo[12] && - ctr_drbg_gen_sfifo_gbencack_err_sum; - - assign hw2reg.err_code.sfifo_gadstage_err.d = 1'b1; - assign hw2reg.err_code.sfifo_gadstage_err.de = cs_enable_fo[15] && - ctr_drbg_gen_sfifo_gadstage_err_sum; - - assign hw2reg.err_code.sfifo_cmdid_err.d = 1'b1; - assign hw2reg.err_code.sfifo_cmdid_err.de = cs_enable_fo[17] && - block_encrypt_sfifo_cmdid_err_sum; - assign hw2reg.err_code.cmd_stage_sm_err.d = 1'b1; - assign hw2reg.err_code.cmd_stage_sm_err.de = cs_enable_fo[18] && - cmd_stage_sm_err_sum; + assign hw2reg.err_code.cmd_stage_sm_err.de = cs_enable_fo[19] && cmd_stage_sm_err_sum; assign hw2reg.err_code.main_sm_err.d = 1'b1; - assign hw2reg.err_code.main_sm_err.de = cs_enable_fo[19] && - main_sm_err_sum; - - assign hw2reg.err_code.drbg_cmd_sm_err.d = 1'b1; - assign hw2reg.err_code.drbg_cmd_sm_err.de = cs_enable_fo[10] && - drbg_cmd_sm_err_sum; - - assign hw2reg.err_code.drbg_gen_sm_err.d = 1'b1; - assign hw2reg.err_code.drbg_gen_sm_err.de = cs_enable_fo[20] && - drbg_gen_sm_err_sum; + assign hw2reg.err_code.main_sm_err.de = cs_enable_fo[20] && main_sm_err_sum; - assign hw2reg.err_code.drbg_updbe_sm_err.d = 1'b1; - assign hw2reg.err_code.drbg_updbe_sm_err.de = cs_enable_fo[21] && - drbg_updbe_sm_err_sum; - - assign hw2reg.err_code.drbg_updob_sm_err.d = 1'b1; - assign hw2reg.err_code.drbg_updob_sm_err.de = cs_enable_fo[22] && - drbg_updob_sm_err_sum; + assign hw2reg.err_code.ctr_drbg_sm_err.d = 1'b1; + assign hw2reg.err_code.ctr_drbg_sm_err.de = cs_enable_fo[21] && ctr_drbg_sm_err_sum; assign hw2reg.err_code.aes_cipher_sm_err.d = 1'b1; - assign hw2reg.err_code.aes_cipher_sm_err.de = cs_enable_fo[23] && - block_encrypt_sm_err_sum; - - assign hw2reg.err_code.cmd_gen_cnt_err.d = 1'b1; - assign hw2reg.err_code.cmd_gen_cnt_err.de = cmd_gen_cnt_err_sum; + assign hw2reg.err_code.aes_cipher_sm_err.de = cs_enable_fo[22] && block_encrypt_sm_err_sum; + // set the err code type bits + assign hw2reg.err_code.ctr_err.d = 1'b1; + assign hw2reg.err_code.ctr_err.de = cs_enable_fo[23] && ctr_err_sum; - // set the err code type bits assign hw2reg.err_code.fifo_write_err.d = 1'b1; assign hw2reg.err_code.fifo_write_err.de = cs_enable_fo[24] && fifo_write_err_sum; @@ -532,8 +378,8 @@ module csrng_core import csrng_pkg::*; #( assign hw2reg.err_code.fifo_state_err.d = 1'b1; assign hw2reg.err_code.fifo_state_err.de = cs_enable_fo[26] && fifo_status_err_sum; - // Error forcing - for (genvar i = 0; i < 31; i = i+1) begin : gen_err_code_test_bit + // Error testing decoding + for (genvar i = 0; i < 31; i++) begin : gen_err_code_test_bit assign err_code_test_bit[i] = (reg2hw.err_code_test.q == i) && reg2hw.err_code_test.qe; end : gen_err_code_test_bit @@ -702,35 +548,36 @@ module csrng_core import csrng_pkg::*; #( .genbits_fips_o (genbits_stage_fips[ai]), .cmd_stage_sfifo_cmd_err_o (cmd_stage_sfifo_cmd_err[ai]), .cmd_stage_sfifo_genbits_err_o(cmd_stage_sfifo_genbits_err[ai]), - .cmd_gen_cnt_err_o (cmd_gen_cnt_err[ai]), + .cmd_gen_cnt_err_o (cmd_stage_ctr_err[ai]), .cmd_stage_sm_err_o (cmd_stage_sm_err[ai]) ); // Set reseed_cnt_reached_d to true if the max number of generate requests between reseeds // has been reached for the respective counter. - assign reseed_cnt_reached_d[ai] = (state_db_wr_vld && (state_db_wr_data.inst_id == ai)) ? - (state_db_wr_data.rs_ctr >= reg2hw.reseed_interval.q) : + assign reseed_cnt_reached_d[ai] = (ctr_drbg_rsp_vld && (ctr_drbg_rsp_data.inst_id == ai)) ? + (ctr_drbg_rsp_data.rs_ctr >= reg2hw.reseed_interval.q) : reseed_cnt_reached_q[ai]; end : gen_cmd_stage // SW interface connection (only 1, and must be present) // cmd req - assign cmd_stage_vld[NumApps-1] = reg2hw.cmd_req.qe; + assign cmd_stage_vld[NumApps-1] = reg2hw.cmd_req.qe; + assign cmd_stage_bus[NumApps-1] = reg2hw.cmd_req.q; assign cmd_stage_shid[NumApps-1] = InstIdWidth'(NumApps-1); - assign cmd_stage_bus[NumApps-1] = reg2hw.cmd_req.q; + assign hw2reg.sw_cmd_sts.cmd_rdy.de = 1'b1; - assign hw2reg.sw_cmd_sts.cmd_rdy.d = cmd_rdy; - assign cmd_rdy = !cmd_stage_vld[NumApps-1] && sw_rdy_sts_q; + assign hw2reg.sw_cmd_sts.cmd_rdy.d = !cmd_stage_vld[NumApps-1] && sw_rdy_sts_q; + assign sw_rdy_sts_d = !cs_enable_fo[28] ? 1'b0 : cmd_stage_vld[NumApps-1] ? 1'b0 : cmd_stage_rdy[NumApps-1] ? 1'b1 : sw_rdy_sts_q; + // cmd sts ack assign hw2reg.sw_cmd_sts.cmd_ack.de = 1'b1; assign hw2reg.sw_cmd_sts.cmd_ack.d = sw_sts_ack_d; - assign sw_sts_ack = cmd_stage_ack[NumApps-1]; assign sw_sts_ack_d = !cs_enable_fo[28] ? 1'b0 : cmd_stage_vld[NumApps-1] ? 1'b0 : @@ -740,8 +587,8 @@ module csrng_core import csrng_pkg::*; #( assign hw2reg.sw_cmd_sts.cmd_sts.de = cmd_stage_ack[NumApps-1]; assign hw2reg.sw_cmd_sts.cmd_sts.d = cmd_stage_ack_sts[NumApps-1]; // genbits - assign hw2reg.genbits_vld.genbits_vld.d = genbits_stage_vldo_sw; - assign hw2reg.genbits_vld.genbits_fips.d = genbits_stage_fips_sw; + assign hw2reg.genbits_vld.genbits_vld.d = genbits_stage_vld_sw; + assign hw2reg.genbits_vld.genbits_fips.d = genbits_stage_fips_sw_q; assign hw2reg.genbits.d = (sw_app_enable && otp_sw_app_read_en[0]) ? genbits_stage_bus_sw : '0; assign genbits_stage_bus_rd_sw = reg2hw.genbits.re; @@ -770,7 +617,7 @@ module csrng_core import csrng_pkg::*; #( .wvalid_i(genbits_stage_vld[NumApps-1]), .wdata_i (genbits_stage_bus[NumApps-1]), .wready_o(genbits_stage_rdy[NumApps-1]), - .rvalid_o(genbits_stage_vldo_sw), + .rvalid_o(genbits_stage_vld_sw), .rdata_o (genbits_stage_bus_sw), .rready_i(genbits_stage_bus_rd_sw), .depth_o () @@ -783,9 +630,6 @@ module csrng_core import csrng_pkg::*; #( genbits_stage_fips[NumApps-1] : genbits_stage_fips_sw_q; - assign genbits_stage_fips_sw = genbits_stage_fips_sw_q; - - //-------------------------------------------- // data path integrity check // - a countermeasure to detect entropy bus tampering attempts @@ -823,30 +667,29 @@ module csrng_core import csrng_pkg::*; #( // HW interface connections (up to 16, numbered 0-14) for (genvar hai = 0; hai < (NumApps-1); hai = hai+1) begin : gen_app_if // cmd req - assign cmd_stage_vld[hai] = csrng_cmd_i[hai].csrng_req_valid; + assign cmd_stage_vld[hai] = csrng_cmd_i[hai].csrng_req_valid; assign cmd_stage_shid[hai] = hai; - assign cmd_stage_bus[hai] = csrng_cmd_i[hai].csrng_req_bus; + assign cmd_stage_bus[hai] = csrng_cmd_i[hai].csrng_req_bus; assign csrng_cmd_o[hai].csrng_req_ready = cmd_stage_rdy[hai]; // cmd ack assign csrng_cmd_o[hai].csrng_rsp_ack = cmd_stage_ack[hai]; assign csrng_cmd_o[hai].csrng_rsp_sts = cmd_stage_ack_sts[hai]; // genbits assign csrng_cmd_o[hai].genbits_valid = genbits_stage_vld[hai]; - assign csrng_cmd_o[hai].genbits_fips = genbits_stage_fips[hai]; - assign csrng_cmd_o[hai].genbits_bus = genbits_stage_bus[hai]; + assign csrng_cmd_o[hai].genbits_fips = genbits_stage_fips[hai]; + assign csrng_cmd_o[hai].genbits_bus = genbits_stage_bus[hai]; assign genbits_stage_rdy[hai] = csrng_cmd_i[hai].genbits_ready; end : gen_app_if - // set ack status for configured instances - for (genvar i = 0; i < NumHwApps; i = i+1) begin : gen_app_if_sts - assign hw_exception_sts[i] = cmd_stage_ack[i] && (cmd_stage_ack_sts[i] != CMD_STS_SUCCESS); + // Assign ack statuss + for (genvar i = 0; i < 16; i = i+1) begin : gen_app_if_sts + if (i < NumApps) begin : gen_assign + assign hw_exception_sts[i] = cmd_stage_ack[i] && (cmd_stage_ack_sts[i] != CMD_STS_SUCCESS); + end else begin : gen_dummy_assign + assign hw_exception_sts[i] = 1'b0; + end end : gen_app_if_sts - // set ack status to zero for un-configured instances - for (genvar i = NumHwApps; i < 16; i = i+1) begin : gen_app_if_zero_sts - assign hw_exception_sts[i] = 1'b0; - end : gen_app_if_zero_sts - // set fifo err status bits for (genvar i = 0; i < NumApps; i = i+1) begin : gen_fifo_sts assign cmd_stage_sfifo_cmd_err_sum[i] = (|cmd_stage_sfifo_cmd_err[i] || @@ -871,10 +714,10 @@ module csrng_core import csrng_pkg::*; #( assign cmd_arb_idx_d = (acmd_avail && acmd_accept) ? cmd_arb_idx : cmd_arb_idx_q; - assign acmd_sop = cmd_arb_sop[cmd_arb_idx_q]; - assign acmd_mop = cmd_arb_mop[cmd_arb_idx_q]; - assign acmd_eop = cmd_arb_eop[cmd_arb_idx_q]; - assign acmd_bus = cmd_arb_bus[cmd_arb_idx_q]; + assign acmd_sop = cmd_arb_sop[cmd_arb_idx_q]; // Start-of-Packet + assign acmd_mop = cmd_arb_mop[cmd_arb_idx_q]; // Mid-of-Packet + assign acmd_eop = cmd_arb_eop[cmd_arb_idx_q]; // End-of-Packet + assign acmd_bus = cmd_arb_bus[cmd_arb_idx_q]; // Actual bus data; content changes with s/m/eop prim_arbiter_ppc #( .EnDataPort(0), // Ignore data port @@ -906,10 +749,10 @@ module csrng_core import csrng_pkg::*; #( acmd_sop ? acmd_e'(acmd_bus[CmdWidth-1:0]) : acmd_q; - assign shid_d = + assign inst_id_d = (!cs_enable_fo[33]) ? '0 : - acmd_sop ? acmd_bus[15:12] : - shid_q; + acmd_sop ? acmd_bus[12 +: NumAppsLg] : + inst_id_q; assign gen_last_d = (!cs_enable_fo[34]) ? '0 : @@ -941,7 +784,6 @@ module csrng_core import csrng_pkg::*; #( // sm to process all instantiation requests // SEC_CM: MAIN_SM.CTR.LOCAL_ESC - // SEC_CM: MAIN_SM.FSM.SPARSE csrng_main_sm u_csrng_main_sm ( .clk_i (clk_i), .rst_ni (rst_ni), @@ -954,32 +796,23 @@ module csrng_core import csrng_pkg::*; #( .cmd_entropy_req_o (cmd_entropy_req), .cmd_entropy_avail_i (cmd_entropy_avail), .cmd_vld_o (main_sm_cmd_vld), - .cmd_rdy_i (ctr_drbg_cmd_req_rdy), + .cmd_rdy_i (ctr_drbg_req_rdy), .clr_adata_packer_o (clr_adata_packer), - .cmd_complete_i (state_db_wr_vld), + .cmd_complete_i (ctr_drbg_rsp_vld), .local_escalate_i (fatal_loc_events), .main_sm_state_o (cs_main_sm_state), .main_sm_err_o (cs_main_sm_err) ); - // interrupt for sw app interface only - assign event_cs_cmd_req_done = sw_sts_ack; - - // interrupt for entropy request - assign event_cs_entropy_req = entropy_src_hw_if_o.es_req; - - // interrupt for app interface exception - assign event_cs_hw_inst_exc = |hw_exception_sts; - // entropy available assign cmd_entropy_avail = entropy_src_hw_if_i.es_ack; for (genvar csi = 0; csi < NumApps; csi = csi+1) begin : gen_cmd_ack - assign cmd_core_ack[csi] = state_db_sts_ack && (state_db_sts_id == csi); - assign cmd_core_ack_sts[csi] = state_db_sts_sts; - assign genbits_core_vld[csi] = ctr_drbg_gen_rsp_vld && (ctr_drbg_gen_rsp_data.inst_id == csi); - assign genbits_core_bus[csi] = ctr_drbg_gen_rsp_bits; - assign genbits_core_fips[csi] = ctr_drbg_gen_rsp_data.fips; + assign cmd_core_ack[csi] = ctr_drbg_rsp_vld && (ctr_drbg_rsp_data.inst_id == csi); + assign cmd_core_ack_sts[csi] = ctr_drbg_rsp_sts; + assign genbits_core_vld[csi] = ctr_drbg_bits_vld && (ctr_drbg_rsp_data.inst_id == csi); + assign genbits_core_bus[csi] = ctr_drbg_bits_data; + assign genbits_core_fips[csi] = ctr_drbg_bits_fips; end : gen_cmd_ack @@ -1009,9 +842,7 @@ module csrng_core import csrng_pkg::*; #( //------------------------------------- // csrng_state_db instantiation //------------------------------------- - // This block holds the internal state - // of each csrng instance. The state - // is updated after each command. + // Holds the internal state of each csrng instance. Gets updated after every command. assign state_db_reg_read_en = cs_enable_fo[40] && read_int_state && otp_sw_app_read_en[1]; @@ -1020,12 +851,11 @@ module csrng_core import csrng_pkg::*; #( .rst_ni (rst_ni), .enable_i(cs_enable_fo[41]), - .rd_inst_id_i(shid_q), + .rd_inst_id_i(inst_id_q), .rd_state_o (state_db_rd_data), .wr_vld_i (state_db_wr_vld), - .wr_data_i (state_db_wr_data), - .wr_status_i(state_db_wr_sts), + .wr_data_i (ctr_drbg_rsp_data), .reg_rd_otp_en_i (state_db_reg_read_en), .reg_rd_regfile_en_i(reg2hw.int_state_read_enable.q), @@ -1035,30 +865,9 @@ module csrng_core import csrng_pkg::*; #( .reg_rd_strb_i (reg2hw.int_state_val.re), .reg_rd_val_o (hw2reg.int_state_val.d), - .status_vld_o (state_db_sts_ack), - .status_val_o (state_db_sts_sts), - .status_inst_id_o(state_db_sts_id), - .reseed_counter_o(reseed_counter) ); - logic cmd_rsp_to_state_db; - - // Keep forwarding gen unit responses to the state db unless the cmd unit has a valid response. - assign cmd_rsp_to_state_db = (ctr_drbg_cmd_rsp_data.cmd != GEN) && (ctr_drbg_cmd_rsp_vld == 1'b1); - - assign state_db_wr_vld = cmd_rsp_to_state_db ? ctr_drbg_cmd_rsp_vld : ctr_drbg_gen_rsp_vld; - assign state_db_wr_data = cmd_rsp_to_state_db ? ctr_drbg_cmd_rsp_data : ctr_drbg_gen_rsp_data; - assign state_db_wr_sts = cmd_rsp_to_state_db ? CMD_STS_SUCCESS : ctr_drbg_gen_rsp_sts; - - // Tie gen unit request to zero if cmd unit writes to state db - assign ctr_drbg_gen_req_vld = cmd_rsp_to_state_db ? 1'b0 : ctr_drbg_cmd_rsp_vld; - // State db is always ready to write; the respective response ready signal can be tied high - assign ctr_drbg_gen_rsp_rdy = cmd_rsp_to_state_db ? 1'b0 : 1'b1; - // Response ready for cmd unit cannot depend on its response valid to avoid combinational loop, - // hence cmd_rsp_to_state_db cannot be used here. - assign ctr_drbg_cmd_rsp_rdy = (ctr_drbg_cmd_rsp_data.cmd == GEN) ? ctr_drbg_gen_req_rdy : 1'b1; - // Forward the reseed counter values to the register interface. always_comb begin : reseed_counter_assign for (int i = 0; i < NumApps; i++) begin @@ -1085,46 +894,23 @@ module csrng_core import csrng_pkg::*; #( (entropy_src_hw_if_i.es_bits ^ seed_diversification) : entropy_src_seed_q; assign entropy_src_fips_d = - // Use shid_d here such that u_csrng_ctr_drbg_cmd gets the shid_q and the proper + // Use inst_id_d here such that u_csrng_ctr_drbg_cmd gets the inst_id_q and the proper // entropy_src_fips_q in the next clock cycle. - fips_force_enable && reg2hw.fips_force.q[shid_d[NumAppsLg-1:0]] ? 1'b1 : + fips_force_enable && reg2hw.fips_force.q[inst_id_d] ? 1'b1 : flag0_fo[2] ? '0 : // special case where zero is used cmd_entropy_req && cmd_entropy_avail ? entropy_src_hw_if_i.es_fips : entropy_src_fips_q; - assign cmd_entropy = entropy_src_seed_q; - assign cmd_entropy_fips = entropy_src_fips_q; - //------------------------------------- - // csrng_ctr_drbg_cmd instantiation + // CTR DRBG instantiation //------------------------------------- - // commands and input parameters - // ins -> send to csrng_state_db - // inputs: 384b entropy, 384b adata - // outputs: 416b K,V,RC - // - // res -> send to csrng_state_db - // inputs: 416b K,V,RC, 384b entropy, 384b adata - // outputs: 416b K,V,RC - // - // gen -> send to csrng_ctr_drbg_gen block - // inputs: 416b K,V,RC, 384b adata - // outputs: 416b K,V,RC, 384b adata - // - // gen blk -> send to csrng_state_db - // inputs: 416b K,V,RC, 384b adata - // outputs: 416b K,V,RC, 128b genbits - // - // upd -> send to csrng_state_db - // inputs: 416b K,V,RC, 384b adata - // outputs: 416b K,V,RC - - assign ctr_drbg_cmd_req_vld = !cs_enable_fo[45] ? 1'b0 : main_sm_cmd_vld; - assign cmd_req_ccmd_dly_d = !cs_enable_fo[44] ? INV : acmd_hold; - - assign ctr_drbg_cmd_req_data = '{ - inst_id: shid_q, - cmd: cmd_req_ccmd_dly_q, + + assign ctr_drbg_req_vld = !cs_enable_fo[45] ? 1'b0 : main_sm_cmd_vld; + assign ctr_drbg_cmd_d = !cs_enable_fo[44] ? INV : acmd_hold; + + assign ctr_drbg_req_data = '{ + inst_id: inst_id_q, + cmd: ctr_drbg_cmd_q, key: state_db_rd_data.key, v: state_db_rd_data.v, pdata: packer_adata, @@ -1132,142 +918,46 @@ module csrng_core import csrng_pkg::*; #( fips: state_db_rd_data.fips }; - csrng_ctr_drbg_cmd u_csrng_ctr_drbg_cmd ( + csrng_ctr_drbg u_csrng_ctr_drbg ( .clk_i (clk_i), .rst_ni (rst_ni), - .enable_i(cs_enable_fo[46]), + .enable_i(cs_enable_fo[49]), - .req_vld_i (ctr_drbg_cmd_req_vld), - .req_rdy_o (ctr_drbg_cmd_req_rdy), - .req_data_i (ctr_drbg_cmd_req_data), - .req_entropy_i (cmd_entropy), - .req_entropy_fips_i(cmd_entropy_fips), + .req_vld_i (ctr_drbg_req_vld), + .req_rdy_o (ctr_drbg_req_rdy), + .req_data_i (ctr_drbg_req_data), + .req_entropy_i (entropy_src_seed_q), + .req_entropy_fips_i(entropy_src_fips_q), .req_glast_i (gen_last_q), - .rsp_vld_o (ctr_drbg_cmd_rsp_vld), - .rsp_rdy_i (ctr_drbg_cmd_rsp_rdy), - .rsp_data_o (ctr_drbg_cmd_rsp_data), - .rsp_glast_o(ctr_drbg_cmd_rsp_glast), + .rsp_vld_o (ctr_drbg_rsp_vld), + .rsp_data_o(ctr_drbg_rsp_data), + .rsp_sts_o (ctr_drbg_rsp_sts), - // Request and response path to and from update unit - .update_req_vld_o (cmd_upd_req_vld), - .update_req_rdy_i (cmd_upd_req_rdy), - .update_req_data_o(cmd_upd_req_data), - - .update_rsp_vld_i (cmd_upd_rsp_vld), - .update_rsp_rdy_o (cmd_upd_rsp_rdy), - .update_rsp_data_i(upd_rsp_data), - - .sm_err_o (drbg_cmd_sm_err) - ); - - //------------------------------------- - // csrng_ctr_drbg_upd instantiation - //------------------------------------- - // The csrng_ctr_drbg_upd is shared - // between the csrng_ctr_drbg_cmd block - // and the csrng_ctr_drbg_gen block. - // The arbiter in this section will - // route requests and responses between - // these two blocks. - - csrng_ctr_drbg_upd u_csrng_ctr_drbg_upd ( - .clk_i (clk_i), - .rst_ni (rst_ni), - .enable_i(cs_enable_fo[47]), + .bits_vld_o (ctr_drbg_bits_vld), + .bits_data_o(ctr_drbg_bits_data), + .bits_fips_o(ctr_drbg_bits_fips), - .req_vld_i (upd_arb_req_vld), - .req_rdy_o (upd_arb_req_rdy), - .req_data_i(upd_arb_req_data), + .state_db_wr_o(state_db_wr_vld), - .rsp_vld_o (upd_rsp_vld), - .rsp_rdy_i (upd_rsp_rdy), - .rsp_data_o(upd_rsp_data), + .block_encrypt_req_vld_o (block_encrypt_req_vld), + .block_encrypt_req_rdy_i (block_encrypt_req_rdy), + .block_encrypt_req_data_o(block_encrypt_req_data), - .es_halt_req_i(cs_aes_halt_i.cs_aes_halt_req), - .es_halt_ack_o(ctr_drbg_upd_es_ack), - - .block_encrypt_req_vld_o (upd_benc_req_vld), - .block_encrypt_req_rdy_i (upd_benc_req_rdy), - .block_encrypt_req_data_o(upd_benc_req_data), - - .block_encrypt_rsp_vld_i (upd_benc_rsp_vld), - .block_encrypt_rsp_rdy_o (upd_benc_rsp_rdy), + .block_encrypt_rsp_vld_i (block_encrypt_rsp_vld), + .block_encrypt_rsp_rdy_o (block_encrypt_rsp_rdy), .block_encrypt_rsp_data_i(block_encrypt_rsp_data), - .ctr_err_o (ctr_drbg_upd_v_ctr_err), - .fifo_final_err_o (ctr_drbg_upd_sfifo_final_err), - .sm_block_enc_req_err_o(drbg_updbe_sm_err), - .sm_block_enc_rsp_err_o(drbg_updob_sm_err) - ); - - // update unit arbiter - - // local helper signals - csrng_upd_data_t upd_arb_din[2]; - - logic [1:0] upd_arb_gnt; - - prim_arbiter_ppc #( - .N(2), // (cmd req and gen req) - .DW(UpdDataWidth) - ) u_prim_arbiter_ppc_updblk_arb ( - .clk_i (clk_i), - .rst_ni (rst_ni), - .req_chk_i(cs_enable_fo[1]), - .req_i ({gen_upd_req_vld, cmd_upd_req_vld}), - .data_i (upd_arb_din), - .gnt_o (upd_arb_gnt), - .idx_o (), - .valid_o (upd_arb_req_vld), - .data_o (upd_arb_req_data), - .ready_i (upd_arb_req_rdy) - ); - - assign upd_arb_din[0] = cmd_upd_req_data; - assign upd_arb_din[1] = gen_upd_req_data; - - assign cmd_upd_req_rdy = upd_arb_gnt[0]; - assign gen_upd_req_rdy = upd_arb_gnt[1]; - - assign cmd_upd_rsp_vld = upd_rsp_vld && (upd_rsp_data.cmd != GENU); - assign gen_upd_rsp_vld = upd_rsp_vld && (upd_rsp_data.cmd == GENU); - - assign upd_rsp_rdy = (upd_rsp_data.cmd == GENU) ? gen_upd_rsp_rdy : cmd_upd_rsp_rdy; - - - //------------------------------------- - // life cycle logic - //------------------------------------- - // The chip level life cycle control - // provide control logic to determine - // how certain debug features are controlled. - - lc_ctrl_pkg::lc_tx_t [LcHwDebugCopies-1:0] lc_hw_debug_en_out; + .es_halt_req_i(cs_aes_halt_i.cs_aes_halt_req), + .es_halt_ack_o(ctr_drbg_es_halt_ack), - prim_lc_sync #( - .NumCopies(LcHwDebugCopies) - ) u_prim_lc_sync ( - .clk_i, - .rst_ni, - .lc_en_i(lc_hw_debug_en_i), - .lc_en_o({lc_hw_debug_en_out}) + .ctr_err_o(ctr_drbg_v_ctr_err), + .sm_err_o (ctr_drbg_sm_err) ); - for (genvar i = 0; i < LcHwDebugCopies; i = i+1) begin : gen_lc_dbg_copies - assign lc_hw_debug_on_fo[i] = lc_ctrl_pkg::lc_tx_test_true_strict(lc_hw_debug_en_out[i]); - end : gen_lc_dbg_copies - - //------------------------------------- // csrng_block_encrypt instantiation //------------------------------------- - // The csrng_block_encrypt is shared - // between the csrng_ctr_drbg_cmd block - // and the csrng_ctr_drbg_gen block. - // The arbiter in this section will - // route requests and responses between - // these two blocks. csrng_block_encrypt #( .SBoxImpl(SBoxImpl) @@ -1285,104 +975,43 @@ module csrng_core import csrng_pkg::*; #( .rsp_data_o(block_encrypt_rsp_data), .cipher_quiet_o (block_encrypt_quiet), - .cipher_sm_err_o (block_encrypt_sm_err), - .fifo_cmdid_err_o(block_encrypt_sfifo_cmdid_err) - ); - - // Local helper signals - csrng_benc_data_t block_encrypt_arb_data[2]; - - prim_arbiter_ppc #( - .N (2), // (upd req and gen req) - .DW(BencDataWidth) - ) u_prim_arbiter_ppc_benc_arb ( - .clk_i (clk_i), - .rst_ni (rst_ni), - .req_chk_i(cs_enable_fo[1]), - .req_i ({gen_benc_req_vld, upd_benc_req_vld}), - .data_i (block_encrypt_arb_data), - .gnt_o ({gen_benc_req_rdy, upd_benc_req_rdy}), - .idx_o (), - .valid_o (block_encrypt_req_vld), - .data_o (block_encrypt_req_data), - .ready_i (block_encrypt_req_rdy) + .cipher_sm_err_o (block_encrypt_sm_err) ); - assign block_encrypt_arb_data[0] = upd_benc_req_data; - assign block_encrypt_arb_data[1] = gen_benc_req_data; - - // Response valid/ready muxing, depending on the requesting unit - assign upd_benc_rsp_vld = (block_encrypt_rsp_vld && (block_encrypt_rsp_data.cmd != GENB)); - assign gen_benc_rsp_vld = (block_encrypt_rsp_vld && (block_encrypt_rsp_data.cmd == GENB)); - - assign block_encrypt_rsp_rdy = (block_encrypt_rsp_data.cmd == GENB) ? gen_benc_rsp_rdy : - upd_benc_rsp_rdy; + // Entropy source to CSRNG halt request to reduce power spikes + assign cs_aes_halt_d = (cs_aes_halt_i.cs_aes_halt_req && ctr_drbg_es_halt_ack && + block_encrypt_quiet); + assign cs_aes_halt_o.cs_aes_halt_ack = cs_aes_halt_q; //------------------------------------- - // csrng_ctr_drbg_gen instantiation + // life cycle logic //------------------------------------- - // this block performs the second sequence - // of the generate command. The first part - // of the sequence is done by the - // csrng_ctr_drbg_cmd block. - - csrng_ctr_drbg_gen u_csrng_ctr_drbg_gen ( - .clk_i (clk_i), - .rst_ni (rst_ni), - .enable_i(cs_enable_fo[49]), - - .cmd_req_vld_i (ctr_drbg_gen_req_vld), - .cmd_req_rdy_o (ctr_drbg_gen_req_rdy), - .cmd_req_data_i (ctr_drbg_cmd_rsp_data), - .cmd_req_glast_i(ctr_drbg_cmd_rsp_glast), - - .cmd_rsp_vld_o (ctr_drbg_gen_rsp_vld), - .cmd_rsp_rdy_i (ctr_drbg_gen_rsp_rdy), - .cmd_rsp_data_o(ctr_drbg_gen_rsp_data), - .cmd_rsp_bits_o(ctr_drbg_gen_rsp_bits), - .cmd_rsp_sts_o (ctr_drbg_gen_rsp_sts), - - .es_halt_req_i(cs_aes_halt_i.cs_aes_halt_req), - .es_halt_ack_o(ctr_drbg_gen_es_ack), - - .update_req_vld_o (gen_upd_req_vld), - .update_req_rdy_i (gen_upd_req_rdy), - .update_req_data_o(gen_upd_req_data), - - .update_rsp_vld_i (gen_upd_rsp_vld), - .update_rsp_rdy_o (gen_upd_rsp_rdy), - .update_rsp_data_i(upd_rsp_data), - - .block_encrypt_req_vld_o (gen_benc_req_vld), - .block_encrypt_req_rdy_i (gen_benc_req_rdy), - .block_encrypt_req_data_o(gen_benc_req_data), - - .block_encrypt_rsp_vld_i (gen_benc_rsp_vld), - .block_encrypt_rsp_rdy_o (gen_benc_rsp_rdy), - .block_encrypt_rsp_data_i(block_encrypt_rsp_data), + // The chip level life cycle control + // provide control logic to determine + // how certain debug features are controlled. - .ctr_err_o(ctr_drbg_gen_v_ctr_err), - .sm_err_o (drbg_gen_sm_err), + lc_ctrl_pkg::lc_tx_t [LcHwDebugCopies-1:0] lc_hw_debug_en_out; - .fifo_gbencack_err_o(ctr_drbg_gen_sfifo_gbencack_err), - .fifo_gadstage_err_o(ctr_drbg_gen_sfifo_gadstage_err) + prim_lc_sync #( + .NumCopies(LcHwDebugCopies) + ) u_prim_lc_sync ( + .clk_i, + .rst_ni, + .lc_en_i(lc_hw_debug_en_i), + .lc_en_o({lc_hw_debug_en_out}) ); - - // es to cs halt request to reduce power spikes - assign cs_aes_halt_d = - (ctr_drbg_upd_es_ack && ctr_drbg_gen_es_ack && block_encrypt_quiet && - cs_aes_halt_i.cs_aes_halt_req); - - assign cs_aes_halt_o.cs_aes_halt_ack = cs_aes_halt_q; + for (genvar i = 0; i < LcHwDebugCopies; i = i+1) begin : gen_lc_dbg_copies + assign lc_hw_debug_on_fo[i] = lc_ctrl_pkg::lc_tx_test_true_strict(lc_hw_debug_en_out[i]); + end : gen_lc_dbg_copies //-------------------------------------------- // observe state machine //-------------------------------------------- assign hw2reg.main_sm_state.de = 1'b1; - assign hw2reg.main_sm_state.d = cs_main_sm_state; + assign hw2reg.main_sm_state.d = cs_main_sm_state; //-------------------------------------------- // report csrng request summary @@ -1401,14 +1030,13 @@ module csrng_core import csrng_pkg::*; #( logic [SeedLen-1:0] unused_gen_rsp_pdata; logic unused_state_db_inst_state; - assign unused_err_code_test_bit = (|err_code_test_bit[19:16]) || err_code_test_bit[14] || - (|err_code_test_bit[12:11]) || (|err_code_test_bit[8:2]); - assign unused_enable_fo = cs_enable_fo[42] || cs_enable_fo[16] || (|cs_enable_fo[14:13]) || - (|cs_enable_fo[9:4]); + assign unused_err_code_test_bit = err_code_test_bit[27] || (|err_code_test_bit[24:23]) || + (|err_code_test_bit[19:2]); + assign unused_enable_fo = (|cs_enable_fo[47:46]) || cs_enable_fo[42] || (|cs_enable_fo[18:4]); assign unused_reg2hw_genbits = (|reg2hw.genbits.q); assign unused_int_state_val = (|reg2hw.int_state_val.q); assign unused_reseed_interval = reg2hw.reseed_interval.qe; - assign unused_gen_rsp_pdata = ctr_drbg_gen_rsp_data.pdata; + assign unused_gen_rsp_pdata = ctr_drbg_rsp_data.pdata; assign unused_state_db_inst_state = state_db_rd_data.inst_state; //-------------------------------------------- @@ -1440,16 +1068,12 @@ module csrng_core import csrng_pkg::*; #( end logic state_db_zeroize; - assign state_db_zeroize = state_db_wr_vld && (state_db_wr_data.cmd == UNI); - `ASSERT(CsrngUniZeroizeFips_A, state_db_zeroize -> (state_db_wr_data.fips == '0)) - `ASSERT(CsrngUniZeroizeKey_A, state_db_zeroize -> (state_db_wr_data.key == '0)) - `ASSERT(CsrngUniZeroizeV_A, state_db_zeroize -> (state_db_wr_data.v == '0)) - `ASSERT(CsrngUniZeroizeRc_A, state_db_zeroize -> (state_db_wr_data.rs_ctr == '0)) - `ASSERT(CsrngUniZeroizeSts_A, state_db_zeroize -> (state_db_wr_sts == '0)) - - // Ensure that the ctr_drbg_generate and ctr_drbg_command units never try to write to the - // state db at the same time. - `ASSERT(CsrngNoConcurrentGenCmdRsp_A, !(ctr_drbg_cmd_rsp_vld && ctr_drbg_gen_rsp_vld)) + assign state_db_zeroize = state_db_wr_vld && (ctr_drbg_rsp_data.cmd == UNI); + `ASSERT(CsrngUniZeroizeFips_A, state_db_zeroize -> (ctr_drbg_rsp_data.fips == '0)) + `ASSERT(CsrngUniZeroizeKey_A, state_db_zeroize -> (ctr_drbg_rsp_data.key == '0)) + `ASSERT(CsrngUniZeroizeV_A, state_db_zeroize -> (ctr_drbg_rsp_data.v == '0)) + `ASSERT(CsrngUniZeroizeRc_A, state_db_zeroize -> (ctr_drbg_rsp_data.rs_ctr == '0)) + `ASSERT(CsrngUniZeroizeSts_A, state_db_zeroize -> (ctr_drbg_rsp_sts == CMD_STS_SUCCESS)) `endif endmodule // csrng_core diff --git a/hw/ip/csrng/rtl/csrng_ctr_drbg.sv b/hw/ip/csrng/rtl/csrng_ctr_drbg.sv new file mode 100644 index 0000000000000..827d1c8a4463f --- /dev/null +++ b/hw/ip/csrng/rtl/csrng_ctr_drbg.sv @@ -0,0 +1,556 @@ +// Copyright lowRISC contributors (OpenTitan project). +// Licensed under the Apache License, Version 2.0, see LICENSE for details. +// SPDX-License-Identifier: Apache-2.0 +// +// Implementation of the NIST SP800-90A CTR DRBG algorithm, no derivation function. + +`include "prim_assert.sv" + +module csrng_ctr_drbg import csrng_pkg::*; ( + input logic clk_i, + input logic rst_ni, + + // Global enable + input logic enable_i, + + // Command interface request, arbitrated from command stages + input logic req_vld_i, + output logic req_rdy_o, + input csrng_core_data_t req_data_i, + input logic [SeedLen-1:0] req_entropy_i, + input logic req_entropy_fips_i, + input logic req_glast_i, + + // Command interface response to state db + output logic rsp_vld_o, + output csrng_core_data_t rsp_data_o, + output csrng_cmd_sts_e rsp_sts_o, + + // Generated bits output to command stages + output logic bits_vld_o, + output logic [BlkLen-1:0] bits_data_o, + output logic bits_fips_o, + + // Write to state db + output logic state_db_wr_o, + + // Block encrypt interface request + output logic block_encrypt_req_vld_o, + input logic block_encrypt_req_rdy_i, + output csrng_key_v_t block_encrypt_req_data_o, + + // Block encrypt interface response + input logic block_encrypt_rsp_vld_i, + output logic block_encrypt_rsp_rdy_o, + input logic [BlkLen-1:0] block_encrypt_rsp_data_i, + + // Halt request from entropy source + input logic es_halt_req_i, + output logic es_halt_ack_o, + + // Error status outputs + output logic ctr_err_o, + output logic sm_err_o +); + + import csrng_reg_pkg::NumApps; + + // Number of calls to the block cipher required for each call of UPDate() + localparam int unsigned NumBlkPerUpd = SeedLen/BlkLen; + localparam int unsigned NumBlkPerUpdLg = $clog2(NumBlkPerUpd); + + // The GENerate command consists of up to three sub commands + typedef enum logic [1:0] { + UPD_BEGIN, + GEN_LOOP, + UPD_FINAL + } gen_subcmd_e; + + //-------------------------------------------- + // Sparse FSM encoding and instantiation + //-------------------------------------------- + + // Encoding generated with: + // $ ./util/design/sparse-fsm-encode.py -d 3 -m 10 -n 7 \ + // -s 923483574589 --language=sv + // + // Hamming distance histogram: + // + // 0: -- + // 1: -- + // 2: -- + // 3: |||||||||||||||||||| (40.00%) + // 4: |||||||||||||||||||| (40.00%) + // 5: ||||||| (15.56%) + // 6: || (4.44%) + // 7: -- + // + // Minimum Hamming distance: 3 + // Maximum Hamming distance: 6 + // Minimum Hamming weight: 1 + // Maximum Hamming weight: 5 + // + localparam int StateWidth = 7; + typedef enum logic [StateWidth-1:0] { + Idle = 7'b1011101, + CtrInc = 7'b0011110, + ReqSend = 7'b1000010, + RspWait = 7'b1101001, + Hndshk = 7'b0101111, + HndshkGen = 7'b1110011, + HndshkLoad = 7'b0110000, + ESHalt = 7'b0001000, + ESHaltBenc = 7'b1100100, + Error = 7'b0000101 + } state_e; + + state_e state_q, state_d; + + // SEC_CM: CTR_DRBG.FSM.SPARSE + `PRIM_FLOP_SPARSE_FSM(u_state_regs, state_d, state_q, state_e, Idle) + + //-------------------------------------------- + // Signals + //-------------------------------------------- + + // Main data structure that encapsulates most of the (meta)data requried in this module + csrng_core_data_t core_data; + + // Control and data signals for the v and concat counters + logic [BlkLen-1:0] v_ctr_sized; + logic [CtrLen-1:0] v_ctr; + logic v_ctr_load; + logic v_ctr_inc; + csrng_key_v_t concat_key_v; + logic concat_ctr_inc; + logic concat_ctr_done; + + //-------------------------------------------- + // Registers, including sequential process + //-------------------------------------------- + + // adata flops for each app interface, plus one valid bit for each + // This rather large bank of flops is unfortunately required due to the way that we handle + // GENerate commands with more than one block of generated output bits: Instead of generating all + // blocks in one go, we always generate one block and then allow the arbiter to give another app + // interface access to the data path. However, on the last generated block, we require the adata + // that are supplied at the very beginning of the GENerate command for the final update() step + // (compare NIST specification). Since all app interfaces share a single packer for adata, its + // content can get overwritten after the first block of generated bits, and hence we must buffer + // adata for each app interface locally for the full "lifetime" of a multi-block GENerate command. + // TODO(#28153) Find a smaller solution (giving each app interface an unpacker does not help) + csrng_key_v_t [NumApps-1:0] generate_adata_q, generate_adata_d; + logic [NumApps-1:0] generate_adata_vld_q, generate_adata_vld_d; + + // Scratch register for commands that call block_encrypt more than once and pointer into it + logic [SeedLen-1:0] concat_key_v_q, concat_key_v_d; + logic [NumBlkPerUpdLg-1:0] concat_ctr_q, concat_ctr_d; + + // Keep track of current sub command for GENerates + gen_subcmd_e gen_subcmd_q, gen_subcmd_d; + + always_ff @(posedge clk_i or negedge rst_ni) begin + if (!rst_ni) begin + generate_adata_q <= '{default: '0}; + generate_adata_vld_q <= '0; + concat_ctr_q <= '0; + concat_key_v_q <= '0; + gen_subcmd_q <= UPD_BEGIN; + end else begin + generate_adata_q <= generate_adata_d; + generate_adata_vld_q <= generate_adata_vld_d; + concat_ctr_q <= concat_ctr_d; + concat_key_v_q <= concat_key_v_d; + gen_subcmd_q <= gen_subcmd_d; + end + end + + //-------------------------------------------- + // Prepare/mux input values depending on cmd + //-------------------------------------------- + + always_comb begin + core_data = req_data_i; + + unique case (req_data_i.cmd) + INS: begin + // Reset key, v, and reseed counter; inject entropy and FIPS status + core_data.key = '0; + core_data.v = '0; + core_data.rs_ctr = '0; + core_data.pdata = req_data_i.pdata ^ req_entropy_i; + core_data.fips = req_entropy_fips_i; + end + RES: begin + // Reset reseed counter; inject entropy and FIPS status + core_data.rs_ctr = '0; + core_data.pdata = req_data_i.pdata ^ req_entropy_i; + core_data.fips = req_entropy_fips_i; + end + UPD, GEN: /* leave everything as-is */ ; + UNI: begin + // Set everything to zero + core_data.key = '0; + core_data.v = '0; + core_data.rs_ctr = '0; + core_data.pdata = '0; + core_data.fips = 1'b0; + end + default: begin + // Invalid command, should never happen + core_data.cmd = INV; + end + endcase + end + + //-------------------------------------------- + // Handling of generate_adata(_vld) + //-------------------------------------------- + + for (genvar i = 0; i < NumApps; i++) begin : g_assign_gen_adata + logic capt_adata; + // 1) Write adata to local buffer upon a GENerate command and _vld not being set + // 2) Clear _vld when the last GENerate beat appears on the cmd_rsp port + assign capt_adata = (req_vld_i && (core_data.cmd == GEN) && (core_data.inst_id == i)); + + always_comb begin + generate_adata_vld_d[i] = generate_adata_vld_q[i]; + generate_adata_d[i] = generate_adata_q[i]; + + if (!enable_i) begin + generate_adata_vld_d[i] = 1'b0; + generate_adata_d[i] = '0; + end else if (capt_adata && !generate_adata_vld_q[i]) begin + generate_adata_vld_d[i] = 1'b1; + generate_adata_d[i] = core_data.pdata; + end else if (rsp_vld_o && req_glast_i && (core_data.inst_id == i)) begin + generate_adata_vld_d[i] = 1'b0; + end + end + end + + //-------------------------------------------- + // Counter logic for v + //-------------------------------------------- + + // SEC_CM: CTR_DRBG.CTR.REDUN + prim_count #( + .Width(CtrLen) + ) u_prim_count_ctr_drbg ( + .clk_i, + .rst_ni, + + .clr_i (!enable_i), + .set_i (v_ctr_load), + .set_cnt_i(core_data.v[CtrLen-1:0]), + + .incr_en_i(v_ctr_inc), + .decr_en_i(1'b0), + .step_i (CtrLen'(1)), + .commit_i (1'b1), + + .cnt_o (v_ctr), + .cnt_after_commit_o(), + .err_o (ctr_err_o) + ); + + // Combine the MSBs of the initial v from the state db with the current counter value as LSBs + if (CtrLen < BlkLen) begin : g_ctr_sized_lsb + assign v_ctr_sized = {core_data.v[BlkLen-1:CtrLen], v_ctr}; + end else begin : g_ctr_sized_full + // Need to distinguish this case as the slice select into core_data.v above would otherwise + // yield an incorrect range ([BlkLen-1:BlkLen]) + assign v_ctr_sized = v_ctr; + end + + //-------------------------------------------- + // Block encrypt request data assign + //-------------------------------------------- + + assign block_encrypt_req_data_o = '{ + key: core_data.key, + v: v_ctr_sized + }; + + //-------------------------------------------- + // Scratch register for block-wise derivation of new {key,v} + //-------------------------------------------- + + // Count the number of blocks that have been received back from block_encrypt until we have enough + // blocks for at least SeedLen bits in total. + assign concat_ctr_done = (concat_ctr_q >= NumBlkPerUpd); + + // Type conversion for easier usage + assign concat_key_v = csrng_key_v_t'(concat_key_v_q); + + always_comb begin + concat_ctr_d = concat_ctr_q; + concat_key_v_d = concat_key_v_q; + + if (!enable_i || concat_ctr_done) begin + concat_ctr_d = '0; + concat_key_v_d = '0; + end else if (concat_ctr_inc) begin + concat_ctr_d = concat_ctr_q + 1; + // Steer the v-response from block encrypt to the correct lane, MSB down + concat_key_v_d[(NumBlkPerUpd - 1 - concat_ctr_q) * BlkLen +: BlkLen] + = block_encrypt_rsp_data_i; + end + end + + //-------------------------------------------- + // FSM to orchestrate everything + //-------------------------------------------- + + always_comb begin + state_d = state_q; + gen_subcmd_d = gen_subcmd_q; + + // Handshake and data validity + req_rdy_o = 1'b0; + rsp_vld_o = 1'b0; + bits_vld_o = 1'b0; + state_db_wr_o = 1'b0; + es_halt_ack_o = 1'b0; + + block_encrypt_req_vld_o = 1'b0; + block_encrypt_rsp_rdy_o = 1'b0; + + // Counter control + v_ctr_load = 1'b0; + v_ctr_inc = 1'b0; + concat_ctr_inc = 1'b0; + + // Error output + sm_err_o = 1'b0; + + unique case (state_q) + Idle: begin + // Prioritize halt requests from entropy source over disable, as those requests would + // otherwise get starved when CSRNG is disabled. + if (es_halt_req_i) begin + state_d = ESHalt; + end else if (enable_i && req_vld_i) begin + unique case (core_data.cmd) + UNI: begin + // No further action needed, write to state db and flag response valid + req_rdy_o = 1'b1; + rsp_vld_o = 1'b1; + state_db_wr_o = 1'b1; + end + INS, RES, UPD: begin + // Load the counter with v from state db + v_ctr_load = 1'b1; + state_d = CtrInc; + end + GEN: begin + v_ctr_load = 1'b1; + // Decide which GENerate sub command to execute + // TODO(#28153) Clarify what the exact condition for skipping the initial UPDate() + // call on GENerate commands is (pdata/adata being an all-zero vector or pdata/adata + // LENGTH being zero). + if (core_data.pdata != '0) begin + gen_subcmd_d = UPD_BEGIN; + end else begin + gen_subcmd_d = GEN_LOOP; + end + state_d = CtrInc; + end + default: begin + // Everything else is an error + state_d = Error; + end + endcase + end else begin + // There is no "clear" on the AES cipher, so just flush out any outstanding responses + // Otherwise, there will be erroneous handshakes when re-enabling the CSRNG + block_encrypt_rsp_rdy_o = 1'b1; + end + end + ReqSend: begin + // Once a request has been accepted, also process its response, even if we get an + // es_halt_req (there is no point since the power-hungry processing will anyways happen) + block_encrypt_req_vld_o = 1'b1; + if (block_encrypt_req_rdy_i) begin + state_d = RspWait; + end else if (es_halt_req_i) begin + state_d = ESHaltBenc; + end + end + RspWait: begin + block_encrypt_rsp_rdy_o = 1'b1; + if (block_encrypt_rsp_vld_i) begin + // In the actual generate part of GENerate, the response of the cipher is the generated + // random bits. In all other cases, the response ends up in the scratch register. + if ((core_data.cmd == GEN) && (gen_subcmd_q == GEN_LOOP)) begin + bits_vld_o = 1'b1; + end else begin + v_ctr_inc = 1'b1; + concat_ctr_inc = 1'b1; + end + // GENerate requires a more involved, separate logic on how to continue + if (core_data.cmd == GEN) begin + state_d = HndshkGen; + end else begin + state_d = Hndshk; + end + end + end + Hndshk: begin + if (concat_ctr_done) begin + // Enough data has been received to make up the new {key,v}; command is completed + req_rdy_o = 1'b1; + rsp_vld_o = 1'b1; + state_db_wr_o = 1'b1; + state_d = Idle; + end else begin + // More data required + state_d = ReqSend; + end + end + HndshkGen: begin + unique case (gen_subcmd_q) + UPD_BEGIN: begin + if (concat_ctr_done) begin + // We have to commit the derived {key,v} to the state db as they are the basis for the + // UPD_FINAL step which we potentially must execute, also requiring the scratch reg + state_db_wr_o = 1'b1; + gen_subcmd_d = GEN_LOOP; + state_d = HndshkLoad; + end else begin + state_d = ReqSend; + end + end + GEN_LOOP: begin + if (req_glast_i) begin + // Do the initial v increment for the UPD_FINAL step that follows + v_ctr_inc = 1'b1; + gen_subcmd_d = UPD_FINAL; + state_d = ReqSend; + end else begin + // This was not the last beat of the generate loop; signal the command as completed + req_rdy_o = 1'b1; + rsp_vld_o = 1'b1; + state_db_wr_o = 1'b1; + state_d = Idle; + end + end + UPD_FINAL: begin + if (concat_ctr_done) begin + // Enough data has been received to make up the new {key,v}; command is completed + req_rdy_o = 1'b1; + rsp_vld_o = 1'b1; + state_db_wr_o = 1'b1; + state_d = Idle; + end else begin + // More data required + state_d = ReqSend; + end + end + default: begin + // We should never get here + state_d = Error; + end + endcase + end + HndshkLoad: begin + // Transitional state to load the prim_count with the new v + v_ctr_load = 1'b1; + state_d = CtrInc; + end + CtrInc: begin + // Transitional state to perform initial v-increment after (re)loading it from state db + v_ctr_inc = 1'b1; + state_d = ReqSend; + end + ESHalt: begin + es_halt_ack_o = 1'b1; + if (!es_halt_req_i) begin + state_d = Idle; + end + end + ESHaltBenc: begin + es_halt_ack_o = 1'b1; + if (!es_halt_req_i) begin + state_d = ReqSend; + end + end + Error: begin + sm_err_o = 1'b1; + end + default: begin + state_d = Error; + sm_err_o = 1'b1; + end + endcase + + // Avoid wrapping every state body in an `if (enable_i)` by collectively handling !enable_i + // here, at least for most states. + if (!enable_i && (state_q == RspWait)) begin + // We have to handle this edge case, where there is an outstanding response from block_encrypt + // while CSRNG gets disabled. Wait until the response arrives; otherwise, it can arrive at a + // somewhat random time during other states and might corrupt or deadlock the control flow + if (block_encrypt_rsp_vld_i) begin + state_d = Idle; + end + end else if (!(state_q inside {Idle, Error, ESHalt, ESHaltBenc}) && (state_d != Error)) begin + // Be careful to not enable error-state escape by accident (checked by assertions). + if (!enable_i) begin + state_d = Idle; + end + end + end + + //-------------------------------------------- + // Response/data out assignments + //-------------------------------------------- + + // Make sure the command stages get an error response in case we received an invalid command + assign rsp_sts_o = (core_data.cmd == INV) ? CMD_STS_INVALID_ACMD : CMD_STS_SUCCESS; + + always_comb begin + // Default case only relevant for UNInstantiate and invalid commands + rsp_data_o = core_data; + + // For all commands that update the internal state, send new {key,v} to state db + // For GENerate commands, we need a more involved handling of the three sub commands + if (core_data.cmd inside {INS, RES, UPD}) begin + rsp_data_o.key = concat_key_v.key ^ core_data.pdata[BlkLen +: KeyLen]; + rsp_data_o.v = concat_key_v.v ^ core_data.pdata[BlkLen-1:0]; + end else if (core_data.cmd == GEN) begin + unique case (gen_subcmd_q) + UPD_BEGIN: begin + rsp_data_o.key = concat_key_v.key ^ core_data.pdata[BlkLen +: KeyLen]; + rsp_data_o.v = concat_key_v.v ^ core_data.pdata[BlkLen-1:0]; + end + GEN_LOOP: begin + rsp_data_o.key = core_data.key; // Unchanged + rsp_data_o.v = v_ctr_sized; // Old value + 1 + end + UPD_FINAL: begin + rsp_data_o.key = concat_key_v.key ^ generate_adata_q[core_data.inst_id].key; + rsp_data_o.v = concat_key_v.v ^ generate_adata_q[core_data.inst_id].v; + // Increase the reseed counter on the last beat of every GENerate + rsp_data_o.rs_ctr = core_data.rs_ctr + 1; + end + default: /* We should never get here */ ; + endcase + end + end + + // Genbits out; actual bits taken directly from block cipher + assign bits_data_o = block_encrypt_rsp_data_i; + assign bits_fips_o = core_data.fips; + + //-------------------------------------------- + // Assertions and unused signal tie-off + //-------------------------------------------- + + // Make sure the FSM has a stable error state that cannot be escaped + `ASSERT(CsrngCtrDrbgSmErrorStStable_A, state_q == Error |=> $stable(state_q)) + // Outside of any non-error state, the FSM error output must be asserted + `ASSERT(CsrngCtrDrbgSmErrorOutput_A, !(state_q inside + {Idle, CtrInc, ReqSend, RspWait, Hndshk, HndshkGen, HndshkLoad, ESHalt, ESHaltBenc}) + |-> sm_err_o) + +endmodule diff --git a/hw/ip/csrng/rtl/csrng_ctr_drbg_cmd.sv b/hw/ip/csrng/rtl/csrng_ctr_drbg_cmd.sv deleted file mode 100644 index f9de16e6e124b..0000000000000 --- a/hw/ip/csrng/rtl/csrng_ctr_drbg_cmd.sv +++ /dev/null @@ -1,222 +0,0 @@ -// Copyright lowRISC contributors (OpenTitan project). -// Licensed under the Apache License, Version 2.0, see LICENSE for details. -// SPDX-License-Identifier: Apache-2.0 -// -// Description: csrng ctr_drbg commands module -// -// Decodes the command field of an operation, injects entropy to pdata if required, and performs -// the initial call to update() for all commands where this is required and pdata != 0. - -`include "prim_assert.sv" - -module csrng_ctr_drbg_cmd import csrng_pkg::*; ( - input logic clk_i, - input logic rst_ni, - - // Global enable - input logic enable_i, - - // Command interface request, arbitrated from command stages - input logic req_vld_i, - output logic req_rdy_o, - input csrng_core_data_t req_data_i, - input logic [SeedLen-1:0] req_entropy_i, - input logic req_entropy_fips_i, - input logic req_glast_i, - - // Command interface response to update unit or state db - output logic rsp_vld_o, - input logic rsp_rdy_i, - output csrng_core_data_t rsp_data_o, - output logic rsp_glast_o, - - // Update interface request - output logic update_req_vld_o, - input logic update_req_rdy_i, - output csrng_upd_data_t update_req_data_o, - - // Update interface response - input logic update_rsp_vld_i, - output logic update_rsp_rdy_o, - input csrng_upd_data_t update_rsp_data_i, - - // Error status outputs - output logic sm_err_o -); - - // signals - csrng_core_data_t req_data; - csrng_core_data_t prep_core_data; - - logic [SeedLen-1:0] prep_seed_material; - logic [KeyLen-1:0] prep_key; - logic [BlkLen-1:0] prep_v; - logic [CtrLen-1:0] prep_rc; - logic bypass_upd; - - - // Encoding generated with: - // $ ./util/design/sparse-fsm-encode.py -d 3 -m 3 -n 5 \ - // -s 68469135 --language=sv - // - // Hamming distance histogram: - // - // 0: -- - // 1: -- - // 2: -- - // 3: |||||||||||||||||||| (66.67%) - // 4: |||||||||| (33.33%) - // 5: -- - // - // Minimum Hamming distance: 3 - // Maximum Hamming distance: 4 - // Minimum Hamming weight: 1 - // Maximum Hamming weight: 3 - // - localparam int StateWidth = 5; - typedef enum logic [StateWidth-1:0] { - ReqIdle = 5'b10000, - RspPend = 5'b01010, - Error = 5'b00111 - } state_e; - - state_e state_d, state_q; - - // SEC_CM: UPDRSP.FSM.SPARSE - `PRIM_FLOP_SPARSE_FSM(u_state_regs, state_d, state_q, state_e, ReqIdle) - - //-------------------------------------------- - // Prepare/mux values for update step - //-------------------------------------------- - - always_comb begin - req_data = req_data_i; - // Insert the FIPS info from entropy source on instantiate and reseed commands. - // Else, keep the existing info (from state db). - req_data.fips = ((req_data_i.cmd == INS) || (req_data_i.cmd == RES)) ? - req_entropy_fips_i : req_data_i.fips; - end - - assign prep_seed_material = - (req_data.cmd == INS) ? (req_entropy_i ^ req_data.pdata) : - (req_data.cmd == RES) ? (req_entropy_i ^ req_data.pdata) : - (req_data.cmd == GEN) ? req_data.pdata : - (req_data.cmd == UPD) ? req_data.pdata : - '0; - - assign prep_key = - (req_data.cmd == INS) ? '0 : - (req_data.cmd == RES) ? req_data.key : - (req_data.cmd == GEN) ? req_data.key : - (req_data.cmd == UPD) ? req_data.key : - '0; - - assign prep_v = - (req_data.cmd == INS) ? '0 : - (req_data.cmd == RES) ? req_data.v : - (req_data.cmd == GEN) ? req_data.v : - (req_data.cmd == UPD) ? req_data.v : - '0; - - assign prep_rc = - (req_data.cmd == INS) ? '0 : - (req_data.cmd == RES) ? '0 : - (req_data.cmd == GEN) ? req_data.rs_ctr : - (req_data.cmd == UPD) ? req_data.rs_ctr : - '0; - - // Request data for the update unit - assign update_req_data_o = '{ - inst_id: req_data.inst_id, - cmd: req_data.cmd, - key: prep_key, - v: prep_v, - pdata: prep_seed_material - }; - - // Splice muxed data fields into internal data path - always_comb begin - prep_core_data = req_data; - prep_core_data.key = prep_key; - prep_core_data.v = prep_v; - prep_core_data.rs_ctr = prep_rc; - end - - // There are two cases in which we don't need the update unit: - // 1) Generate commands with pdata equal to all-zero - // 2) The (rather trivial) uninstantiate command - // TODO(#28153) Clarify what the exact condition for skipping the initial update() call on - // GENerate commands is (pdata/adata being an all-zero vector or pdata/adata LENGTH being zero). - assign bypass_upd = ((req_data.cmd == GEN) && (req_data.pdata == '0)) || (req_data.cmd == UNI); - - // Small FSM required to wait for a finished transaction on both the update unit - // request and response ports until asserting the req_rdy_o to the upstream requester - // in case the update unit is required. - always_comb begin - state_d = state_q; - req_rdy_o = 1'b0; - rsp_vld_o = 1'b0; - update_req_vld_o = 1'b0; - update_rsp_rdy_o = 1'b0; - sm_err_o = 1'b0; - - unique case (state_q) - ReqIdle: begin - if (bypass_upd) begin - // The update unit is not required for the command at hand and we can - // complete the request handshake internally. - req_rdy_o = enable_i && rsp_rdy_i; - rsp_vld_o = req_vld_i; - end else begin - // Update unit is required - complete first the request and then the - // response handshake before asserting the upstrem ready. - update_req_vld_o = req_vld_i; - if (update_req_vld_o && update_req_rdy_i) begin - state_d = RspPend; - end - end - end - RspPend: begin - // We get here after having done a request handshake with the update unit. - // Now, wait for the response handshake to complete the transaction. - rsp_vld_o = update_rsp_vld_i; - update_rsp_rdy_o = rsp_rdy_i; - if (update_rsp_vld_i && update_rsp_rdy_o) begin - req_rdy_o = 1'b1; - state_d = ReqIdle; - end - end - Error: begin - sm_err_o = 1'b1; - end - default: begin - state_d = Error; - sm_err_o = 1'b1; - end - endcase - end - - // Route either data from request input or update response to response output - always_comb begin - rsp_data_o = prep_core_data; - rsp_glast_o = req_glast_i; - if (req_data_i.cmd == UNI) begin - // Zeroize everything but inst_id and cmd (?) - rsp_data_o = '{cmd: INV, default: '0}; - rsp_data_o.inst_id = req_data_i.inst_id; - rsp_data_o.cmd = req_data_i.cmd; - end else if (!bypass_upd) begin - // Update key and v with values from the update unit if - // non-zero pdata were provided - rsp_data_o.key = update_rsp_data_i.key; - rsp_data_o.v = update_rsp_data_i.v; - rsp_data_o.inst_id = update_rsp_data_i.inst_id; - rsp_data_o.cmd = update_rsp_data_i.cmd; - end - end - - // Unused signals - logic [SeedLen-1:0] unused_upd_rsp_pdata; - assign unused_upd_rsp_pdata = update_rsp_data_i.pdata; - -endmodule diff --git a/hw/ip/csrng/rtl/csrng_ctr_drbg_gen.sv b/hw/ip/csrng/rtl/csrng_ctr_drbg_gen.sv deleted file mode 100644 index 859c47ed31044..0000000000000 --- a/hw/ip/csrng/rtl/csrng_ctr_drbg_gen.sv +++ /dev/null @@ -1,474 +0,0 @@ -// Copyright lowRISC contributors (OpenTitan project). -// Licensed under the Apache License, Version 2.0, see LICENSE for details. -// SPDX-License-Identifier: Apache-2.0 -// -// Description: csrng ctr_drbg generate module -// -// This module will process the second half of the generate function. -// It takes in the key, v, and reseed counter values processed by the -// ctr_drbg_cmd module. - -`include "prim_assert.sv" - -module csrng_ctr_drbg_gen import csrng_pkg::*; ( - input logic clk_i, - input logic rst_ni, - - // Global enable - input logic enable_i, - - // Command interface request from cmd stage - input logic cmd_req_vld_i, - output logic cmd_req_rdy_o, - input csrng_core_data_t cmd_req_data_i, - input logic cmd_req_glast_i, - - // Command interface response to state db - output logic cmd_rsp_vld_o, - input logic cmd_rsp_rdy_i, - output csrng_core_data_t cmd_rsp_data_o, - output logic [BlkLen-1:0] cmd_rsp_bits_o, - output csrng_cmd_sts_e cmd_rsp_sts_o, - - // Halt request from entropy source - input logic es_halt_req_i, - output logic es_halt_ack_o, - - // Update interface request - output logic update_req_vld_o, - input logic update_req_rdy_i, - output csrng_upd_data_t update_req_data_o, - - // Update interface response - input logic update_rsp_vld_i, - output logic update_rsp_rdy_o, - input csrng_upd_data_t update_rsp_data_i, - - // Block encrypt interface request - output logic block_encrypt_req_vld_o, - input logic block_encrypt_req_rdy_i, - output csrng_benc_data_t block_encrypt_req_data_o, - - // Block encrypt interface response - input logic block_encrypt_rsp_vld_i, - output logic block_encrypt_rsp_rdy_o, - input csrng_benc_data_t block_encrypt_rsp_data_i, - - // Error status signals - output logic ctr_err_o, - output logic sm_err_o, - output logic [2:0] fifo_gbencack_err_o, - output logic [2:0] fifo_gadstage_err_o -); - - import csrng_reg_pkg::NumApps; - - // FIFO widths. All are 1-element deep. - // Note: Often, the full width is not utilized but only declared to be able to - // convienently make use of common struct data types for read- and write data. - localparam int AdstageFifoWidth = KeyLen + BlkLen + CtrLen + 2; - - // FIFO signals. Two stages in total - logic sfifo_adstage_wvld; - logic sfifo_adstage_wrdy; - logic [AdstageFifoWidth-1:0] sfifo_adstage_wdata; - logic sfifo_adstage_rvld; - logic sfifo_adstage_rrdy; - logic [AdstageFifoWidth-1:0] sfifo_adstage_rdata; - - logic sfifo_bencack_wvld; - logic sfifo_bencack_wrdy; - csrng_benc_data_t sfifo_bencack_wdata; - logic sfifo_bencack_rvld; - logic sfifo_bencack_rrdy; - csrng_benc_data_t sfifo_bencack_rdata; - - // Helper/breakout signals between the FIFO stages - logic [KeyLen-1:0] adstage_key; - logic [BlkLen-1:0] adstage_v; - logic [CtrLen-1:0] adstage_rs_ctr; - logic adstage_fips; - logic adstage_glast; - - // Control and data signals, mostly for the v counter - logic [BlkLen-1:0] v_load; - logic [BlkLen-1:0] v_ctr_sized; - logic v_ctr_load; - logic v_ctr_inc; - logic [CtrLen-1:0] v_ctr; - logic [NumApps-1:0] capt_adata; - - // adata flops for each app interface, plus one valid bit for each - logic [SeedLen-1:0] update_adata_q[NumApps], update_adata_d[NumApps]; - logic [NumApps-1:0] update_adata_vld_q, update_adata_vld_d; - - // Encoding generated with: - // $ ./util/design/sparse-fsm-encode.py -d 3 -m 7 -n 6 \ - // -s 12450626389 --language=sv - // - // Hamming distance histogram: - // - // 0: -- - // 1: -- - // 2: -- - // 3: |||||||||||||||||||| (57.14%) - // 4: ||||||||||||||| (42.86%) - // 5: -- - // 6: -- - // - // Minimum Hamming distance: 3 - // Maximum Hamming distance: 4 - // Minimum Hamming weight: 2 - // Maximum Hamming weight: 3 - // - localparam int StateWidth = 6; - typedef enum logic [StateWidth-1:0] { - ReqIdle = 6'b010101, - ReqSend = 6'b111000, - ESHalt = 6'b010010, - ReqError = 6'b100100, - BencRspWait = 6'b100011, - UpdRspWait = 6'b001110, - UpdESHalt = 6'b001001 - } state_e; - - state_e state_d, state_q; - - // SEC_CM: UPDATE.FSM.SPARSE - `PRIM_FLOP_SPARSE_FSM(u_state_regs, state_d, state_q, state_e, ReqIdle) - - always_ff @(posedge clk_i or negedge rst_ni) begin - if (!rst_ni) begin - update_adata_q <= '{default:0}; - update_adata_vld_q <= '0; - end else begin - update_adata_q <= update_adata_d; - update_adata_vld_q <= update_adata_vld_d; - end - end - - - //-------------------------------------------- - // prepare value for block_encrypt step - //-------------------------------------------- - - // TODO(#28153) check if the (additional) increment here is really necessary and whether it - // violates the redundant counter encoding listed as a SEC_CM below. - if (CtrLen < BlkLen) begin : g_ctr_load_lsb - logic [CtrLen-1:0] v_inc; - assign v_inc = cmd_req_data_i.v[CtrLen-1:0] + 1; - assign v_load = {cmd_req_data_i.v[BlkLen-1:CtrLen], v_inc}; - end else begin : g_ctr_load_full - assign v_load = cmd_req_data_i.v + 1; - end - - // SEC_CM: DRBG_GEN.CTR.REDUN - prim_count #( - .Width(CtrLen) - ) u_prim_count_ctr_drbg ( - .clk_i, - .rst_ni, - - .clr_i (!enable_i), - .set_i (v_ctr_load), - .set_cnt_i(v_load[CtrLen-1:0]), - - .incr_en_i(v_ctr_inc), - .decr_en_i(1'b0), - .step_i (CtrLen'(1)), - .commit_i (1'b1), - - .cnt_o (v_ctr), - .cnt_after_commit_o(), - .err_o (ctr_err_o) - ); - - // Combine the MSBs of the initial v from the state db with the current counter value as LSBs - if (CtrLen < BlkLen) begin : g_ctr_sized_lsb - assign v_ctr_sized = {v_load[BlkLen-1:CtrLen], v_ctr}; - end else begin : g_ctr_sized_full - // Need to distinguish this case as the slice select into v_load above would otherwise yield an - // incorrect range ([BlkLen-1:BlkLen]) - assign v_ctr_sized = v_ctr; - end - - //-------------------------------------------- - // state machine to control conditional requests/responses to/from update unit - //-------------------------------------------- - - // Send genreq data with the altered v, and change the command code - // to an internal one for proper routing in csrng_core - assign block_encrypt_req_data_o = '{ - inst_id: cmd_req_data_i.inst_id, - cmd: (cmd_req_data_i.cmd == GEN) ? GENB : INV, - key: cmd_req_data_i.key, - v: v_ctr_sized - }; - - assign update_rsp_rdy_o = cmd_rsp_rdy_i; - - always_comb begin - state_d = state_q; - v_ctr_load = 1'b0; - v_ctr_inc = 1'b0; - sfifo_adstage_wvld = 1'b0; - sfifo_bencack_rrdy = 1'b0; - sfifo_adstage_rrdy = 1'b0; - cmd_req_rdy_o = 1'b0; - cmd_rsp_vld_o = 1'b0; - block_encrypt_req_vld_o = 1'b0; - update_req_vld_o = 1'b0; - sm_err_o = 1'b0; - es_halt_ack_o = 1'b0; - unique case (state_q) - // ReqIdle: increment v this cycle, push in next - ReqIdle: begin - // Prioritize halt requests from entropy_src over disable, as CSRNG would otherwise starve - // those requests while it is idle. - if (es_halt_req_i) begin - state_d = ESHalt; - end else if (!enable_i) begin - state_d = ReqIdle; - end else if (cmd_req_vld_i && sfifo_adstage_wrdy) begin - v_ctr_load = 1'b1; - state_d = ReqSend; - end - end - ReqSend: begin - if (!enable_i) begin - state_d = ReqIdle; - end else begin - block_encrypt_req_vld_o = 1'b1; - if (block_encrypt_req_rdy_i) begin - // Write to adstage and empty the genreq FIFO - sfifo_adstage_wvld = 1'b1; - cmd_req_rdy_o = 1'b1; - // Increment v & back to idle - v_ctr_inc = 1'b1; - state_d = BencRspWait; - end - end - end - BencRspWait: begin - if (!enable_i) begin - state_d = ReqIdle; - end else if (sfifo_bencack_rvld) begin - if (adstage_glast) begin - update_req_vld_o = 1'b1; - // Wait for update unit - if (update_req_rdy_i) begin - state_d = UpdRspWait; - end - // Abort the process in case of a halt request, as the - // update unit won't answer them until the halt ack - if (es_halt_req_i) begin - state_d = UpdESHalt; - end - end else begin - cmd_rsp_vld_o = 1'b1; - if (cmd_rsp_rdy_i) begin - sfifo_bencack_rrdy = 1'b1; - sfifo_adstage_rrdy = 1'b1; - state_d = ReqIdle; - end - end - end - end - UpdRspWait: begin - if (!enable_i) begin - state_d = ReqIdle; - end else if (update_rsp_vld_i) begin - cmd_rsp_vld_o = 1'b1; - if (cmd_rsp_rdy_i) begin - sfifo_bencack_rrdy = 1'b1; - sfifo_adstage_rrdy = 1'b1; - state_d = ReqIdle; - end - end - end - ESHalt: begin - es_halt_ack_o = 1'b1; - if (!es_halt_req_i) begin - state_d = ReqIdle; - end - end - UpdESHalt: begin - es_halt_ack_o = 1'b1; - // We have to keep the update_req_vld high, else we get - // the arbiter asserts firing - update_req_vld_o = 1'b1; - if (!es_halt_req_i) begin - state_d = BencRspWait; - end - end - ReqError: begin - sm_err_o = 1'b1; - end - default: begin - state_d = ReqError; - sm_err_o = 1'b1; - end - endcase - end - - - //-------------------------------------------- - // fifo to stage key, v, rs_ctr, and adata, waiting for update block to ack - //-------------------------------------------- - - prim_fifo_sync #( - .Width(AdstageFifoWidth), - .Pass(0), - .Depth(1), - .OutputZeroIfEmpty(1'b0) - ) u_prim_fifo_sync_adstage ( - .clk_i (clk_i), - .rst_ni (rst_ni), - .clr_i (!enable_i), - .wvalid_i(sfifo_adstage_wvld), - .wready_o(sfifo_adstage_wrdy), - .wdata_i (sfifo_adstage_wdata), - .rvalid_o(sfifo_adstage_rvld), - .rready_i(sfifo_adstage_rrdy), - .rdata_o (sfifo_adstage_rdata), - .full_o (), - .depth_o (), - .err_o () - ); - - assign sfifo_adstage_wdata = {cmd_req_glast_i, - cmd_req_data_i.key, - v_ctr_sized, - cmd_req_data_i.rs_ctr, - cmd_req_data_i.fips}; - - assign {adstage_glast, - adstage_key, - adstage_v, - adstage_rs_ctr, - adstage_fips} = sfifo_adstage_rdata; - - assign fifo_gadstage_err_o = - {( sfifo_adstage_wvld && !sfifo_adstage_wrdy), - ( sfifo_adstage_rrdy && !sfifo_adstage_rvld), - (!sfifo_adstage_wrdy && !sfifo_adstage_rvld)}; - - - // adata storage for each application interface: - // - Write from genreq stage if not currently valid - // - Clear valid upon sending request to update unit (== last generate beat done) - for (genvar i = 0; i < NumApps; i++) begin : gen_adata - assign capt_adata[i] = (sfifo_adstage_wvld && (cmd_req_data_i.inst_id == i)); - - always_comb begin - update_adata_vld_d[i] = update_adata_vld_q[i]; - update_adata_d[i] = update_adata_q[i]; - - if (!enable_i) begin - update_adata_vld_d[i] = 1'b0; - update_adata_d[i] = '0; - end else if (capt_adata[i] && !update_adata_vld_q[i]) begin - update_adata_vld_d[i] = 1'b1; - update_adata_d[i] = cmd_req_data_i.pdata; - end else if (update_req_vld_o && update_req_rdy_i && (sfifo_bencack_rdata.inst_id == i)) begin - update_adata_vld_d[i] = 1'b0; - end - end - end - - //-------------------------------------------- - // block_encrypt response fifo from block encrypt - //-------------------------------------------- - - prim_fifo_sync #( - .Width(BencDataWidth), - .Pass(0), - .Depth(1), - .OutputZeroIfEmpty(1'b0) - ) u_prim_fifo_sync_bencack ( - .clk_i (clk_i), - .rst_ni (rst_ni), - .clr_i (!enable_i), - .wvalid_i(sfifo_bencack_wvld), - .wready_o(sfifo_bencack_wrdy), - .wdata_i (sfifo_bencack_wdata), - .rvalid_o(sfifo_bencack_rvld), - .rready_i(sfifo_bencack_rrdy), - .rdata_o (sfifo_bencack_rdata), - .full_o (), - .depth_o (), - .err_o () - ); - - always_comb begin - sfifo_bencack_wdata = block_encrypt_rsp_data_i; - sfifo_bencack_wdata.cmd = (block_encrypt_rsp_data_i.cmd == GENB) ? GENU : INV; - end - - assign sfifo_bencack_wvld = sfifo_bencack_wrdy && block_encrypt_rsp_vld_i; - - assign block_encrypt_rsp_rdy_o = sfifo_bencack_wrdy; - - assign fifo_gbencack_err_o = - {( sfifo_bencack_wvld && !sfifo_bencack_wrdy), - ( sfifo_bencack_rrdy && !sfifo_bencack_rvld), - (!sfifo_bencack_wrdy && !sfifo_bencack_rvld)}; - - - //-------------------------------------------- - // prepare values for update step - //-------------------------------------------- - - assign update_req_data_o = '{ - inst_id: sfifo_bencack_rdata.inst_id, - cmd: sfifo_bencack_rdata.cmd, - key: adstage_key, - v: adstage_v, - pdata: update_adata_q[sfifo_bencack_rdata.inst_id[NumAppsLg-1:0]] - }; - - //-------------------------------------------- - // Mux results of update unit to output on last beat - //-------------------------------------------- - - always_comb begin - cmd_rsp_data_o = '{ - inst_id: sfifo_bencack_rdata.inst_id, - cmd: sfifo_bencack_rdata.cmd, - key: adstage_key, - v: adstage_v, - pdata: '0, // unused - rs_ctr: adstage_rs_ctr, - fips: adstage_fips - }; - - // On the last gen beat, splice in the updated key & v values from the - // update unit, and increase the reseed counter by one. - if (adstage_glast) begin - cmd_rsp_data_o.inst_id = update_rsp_data_i.inst_id; - cmd_rsp_data_o.cmd = update_rsp_data_i.cmd; - cmd_rsp_data_o.key = update_rsp_data_i.key; - cmd_rsp_data_o.v = update_rsp_data_i.v; - cmd_rsp_data_o.rs_ctr = adstage_rs_ctr + 1; - end - end - - assign cmd_rsp_bits_o = sfifo_bencack_rdata.v; - assign cmd_rsp_sts_o = (cmd_rsp_vld_o && (cmd_rsp_data_o.cmd != GENU)) ? CMD_STS_INVALID_GEN_CMD - : CMD_STS_SUCCESS; - - // Make sure that the state machine has a stable error state. This means that after the error - // state is entered it will not exit it unless a reset signal is received. - `ASSERT(CsrngDrbgGenErrorStStable_A, state_q == ReqError |=> $stable(state_q)) - // If in error state, the error output must be high. - `ASSERT(CsrngDrbgGenErrorOutput_A, - !(state_q inside {ReqIdle, ReqSend, ESHalt, BencRspWait, UpdRspWait, UpdESHalt}) - |-> sm_err_o) - - // Unused signals - logic [SeedLen-1:0] unused_upd_rsp_pdata; - logic [KeyLen-1:0] unused_bencack_sfifo_rdata_key; - assign unused_upd_rsp_pdata = update_rsp_data_i.pdata; - assign unused_bencack_sfifo_rdata_key = sfifo_bencack_rdata.key; - -endmodule diff --git a/hw/ip/csrng/rtl/csrng_ctr_drbg_upd.sv b/hw/ip/csrng/rtl/csrng_ctr_drbg_upd.sv deleted file mode 100644 index c7b765bb55a29..0000000000000 --- a/hw/ip/csrng/rtl/csrng_ctr_drbg_upd.sv +++ /dev/null @@ -1,447 +0,0 @@ -// Copyright lowRISC contributors (OpenTitan project). -// Licensed under the Apache License, Version 2.0, see LICENSE for details. -// SPDX-License-Identifier: Apache-2.0 -// -// Description: csrng ctr_drbg_update module -// -// implementation using security_strength = 256 - -`include "prim_assert.sv" - -module csrng_ctr_drbg_upd import csrng_pkg::*; ( - input logic clk_i, - input logic rst_ni, - - // Global enable - input logic enable_i, - - // Update interface request from cmd and generate stages - input logic req_vld_i, - output logic req_rdy_o, - input csrng_upd_data_t req_data_i, - - // Update interface response to cmd and generate stages - output logic rsp_vld_o, - input logic rsp_rdy_i, - output csrng_upd_data_t rsp_data_o, - - // Halt request from entropy source - input logic es_halt_req_i, - output logic es_halt_ack_o, - - // Block encrypt interface request - output logic block_encrypt_req_vld_o, - input logic block_encrypt_req_rdy_i, - output csrng_benc_data_t block_encrypt_req_data_o, - - // Block encrypt interface response - input logic block_encrypt_rsp_vld_i, - output logic block_encrypt_rsp_rdy_o, - input csrng_benc_data_t block_encrypt_rsp_data_i, - - // Error status outputs - output logic ctr_err_o, - output logic [2:0] fifo_final_err_o, - output logic sm_block_enc_req_err_o, - output logic sm_block_enc_rsp_err_o -); - - // signals - logic sfifo_final_wvld; - logic sfifo_final_wrdy; - logic [BencDataWidth-1:0] sfifo_final_wdata; - logic sfifo_final_rvld; - logic sfifo_final_rrdy; - logic [BencDataWidth-1:0] sfifo_final_rdata; - - logic v_ctr_load; - logic v_ctr_inc; - logic block_ctr_done; - logic concat_outblk_shift; - logic concat_ctr_done; - logic concat_ctr_inc; - logic [CtrLen-1:0] v_ctr; - - logic [SeedLen-1:0] updated_key_and_v; - logic [BlkLen-1:0] v_load; - logic [BlkLen-1:0] v_ctr_sized; - - // flops - logic [1:0] block_ctr_q, block_ctr_d; - logic [1:0] concat_ctr_q, concat_ctr_d; - logic [SeedLen-1:0] concat_outblk_q, concat_outblk_d; - logic [CmdWidth-1:0] concat_ccmd_q, concat_ccmd_d; - logic [InstIdWidth-1:0] concat_inst_id_q, concat_inst_id_d; - - // Encoding generated with: - // $ ./util/design/sparse-fsm-encode.py -d 3 -m 5 -n 6 \ - // -s 47377994 --language=sv - // - // Hamming distance histogram: - // - // 0: -- - // 1: -- - // 2: -- - // 3: |||||||||||||||||||| (50.00%) - // 4: |||||||||||||||| (40.00%) - // 5: |||| (10.00%) - // 6: -- - // - // Minimum Hamming distance: 3 - // Maximum Hamming distance: 5 - // Minimum Hamming weight: 2 - // Maximum Hamming weight: 5 - // - - localparam int BlkEncStateWidth = 6; - typedef enum logic [BlkEncStateWidth-1:0] { - ReqIdle = 6'b111011, - ReqSend = 6'b000111, - ReqWait = 6'b001010, - ESHalt = 6'b010100, - BEError = 6'b101101 - } blk_enc_state_e; - - blk_enc_state_e blk_enc_state_d, blk_enc_state_q; - - // SEC_CM: BLK_ENC.FSM.SPARSE - `PRIM_FLOP_SPARSE_FSM(u_blk_enc_state_regs, blk_enc_state_d, blk_enc_state_q, blk_enc_state_e, - ReqIdle) - - // Encoding generated with: - // $ ./util/design/sparse-fsm-encode.py -d 3 -m 4 -n 6 \ - // -s 400877681 --language=sv - // - // Hamming distance histogram: - // - // 0: -- - // 1: -- - // 2: -- - // 3: |||||||||||||||||||| (66.67%) - // 4: ||||| (16.67%) - // 5: -- - // 6: ||||| (16.67%) - // - // Minimum Hamming distance: 3 - // Maximum Hamming distance: 6 - // Minimum Hamming weight: 2 - // Maximum Hamming weight: 4 - // - - localparam int OutBlkStateWidth = 6; - typedef enum logic [OutBlkStateWidth-1:0] { - AckIdle = 6'b110110, - Load = 6'b110001, - Shift = 6'b001001, - OBError = 6'b011100 - } outblk_state_e; - - outblk_state_e outblk_state_d, outblk_state_q; - - // SEC_CM: OUTBLK.FSM.SPARSE - `PRIM_FLOP_SPARSE_FSM(u_outblk_state_regs, - outblk_state_d, outblk_state_q, outblk_state_e, AckIdle) - - always_ff @(posedge clk_i or negedge rst_ni) begin - if (!rst_ni) begin - block_ctr_q <= '0; - concat_ctr_q <= '0; - concat_outblk_q <= '0; - concat_ccmd_q <= '0; - concat_inst_id_q <= '0; - end else begin - block_ctr_q <= block_ctr_d; - concat_ctr_q <= concat_ctr_d; - concat_outblk_q <= concat_outblk_d; - concat_ccmd_q <= concat_ccmd_d; - concat_inst_id_q <= concat_inst_id_d; - end - end - - //-------------------------------------------- - // prepare value for block_encrypt step - //-------------------------------------------- - - // TODO(#28153) check if the (additional) increment here is really necessary and whether it - // violates the redundant counter encoding listed as a SEC_CM below. - if (CtrLen < BlkLen) begin : g_ctr_load_lsb - logic [CtrLen-1:0] v_inc; - assign v_inc = req_data_i.v[CtrLen-1:0] + 1; - assign v_load = {req_data_i.v[BlkLen-1:CtrLen], v_inc}; - end else begin : g_ctr_load_full - assign v_load = req_data_i.v + 1; - end - - // SEC_CM: DRBG_UPD.CTR.REDUN - prim_count #( - .Width(CtrLen) - ) u_prim_count_ctr_drbg ( - .clk_i, - .rst_ni, - - .clr_i (!enable_i), - .set_i (v_ctr_load), - .set_cnt_i(v_load[CtrLen-1:0]), - - .incr_en_i(v_ctr_inc), - .decr_en_i(1'b0), - .step_i (CtrLen'(1)), - .commit_i (1'b1), - - .cnt_o (v_ctr), - .cnt_after_commit_o(), - .err_o (ctr_err_o) - ); - - // Combine the MSBs of the initial v from the state db with the current counter value as LSBs - if (CtrLen < BlkLen) begin : g_ctr_sized_lsb - assign v_ctr_sized = {v_load[BlkLen-1:CtrLen], v_ctr}; - end else begin : g_ctr_sized_full - // Need to distinguish this case as the slice select into v_load above would otherwise yield an - // incorrect range ([BlkLen-1:BlkLen]) - assign v_ctr_sized = v_ctr; - end - - // Count the number of blocks that have been sent to block_encrypt for each call of the update - // function, until blocks adding to at least SeedLen bits have been sent. - // Counting up is done in sync with the 'main' v counter above - always_comb begin - block_ctr_d = block_ctr_q; - if (!enable_i) begin - block_ctr_d = '0; - end else if (block_ctr_done) begin - block_ctr_d = '0; - end else if (v_ctr_inc) begin - block_ctr_d = block_ctr_q + 1; - end - end - - // Doing this inside the always_comb above results in some simulator tools getting stuck at the - // beginning of the simulation. - assign block_ctr_done = (block_ctr_q >= SeedLen/BlkLen); - - //-------------------------------------------- - // state machine to send values to block_encrypt - //-------------------------------------------- - - always_comb begin - blk_enc_state_d = blk_enc_state_q; - v_ctr_load = 1'b0; - v_ctr_inc = 1'b0; - block_encrypt_req_vld_o = 1'b0; - sm_block_enc_req_err_o = 1'b0; - es_halt_ack_o = 1'b0; - unique case (blk_enc_state_q) - // ReqIdle: increment v this cycle, push in next - ReqIdle: begin - // Prioritize halt requests from entropy_src over disable, as CSRNG would otherwise starve - // those requests while it is idle. - if (es_halt_req_i) begin - blk_enc_state_d = ESHalt; - end else if (!enable_i) begin - blk_enc_state_d = ReqIdle; - end else if (req_vld_i) begin - v_ctr_load = 1'b1; - blk_enc_state_d = ReqSend; - end - end - ReqSend: begin - if (!enable_i) begin - blk_enc_state_d = ReqIdle; - end else if (!block_ctr_done) begin - block_encrypt_req_vld_o = 1'b1; - if (block_encrypt_req_rdy_i) begin - v_ctr_inc = 1'b1; - end - end else begin - // Wait for completion on the benc_rsp path - if (req_vld_i && req_rdy_o) begin - blk_enc_state_d = ReqIdle; - end else begin - blk_enc_state_d = ReqWait; - end - end - end - ReqWait: begin - if (!enable_i) begin - blk_enc_state_d = ReqIdle; - end else if (req_vld_i && req_rdy_o) begin - // Wait for completion on the benc_rsp path - blk_enc_state_d = ReqIdle; - end - end - ESHalt: begin - es_halt_ack_o = 1'b1; - if (!es_halt_req_i) begin - blk_enc_state_d = ReqIdle; - end - end - BEError: begin - sm_block_enc_req_err_o = 1'b1; - end - default: begin - blk_enc_state_d = BEError; - sm_block_enc_req_err_o = 1'b1; - end - endcase - end - - // Forward the upstream data together with the current counter value to block_encrypt - assign block_encrypt_req_data_o = {req_data_i.inst_id, - req_data_i.cmd, - req_data_i.key, - v_ctr_sized}; - - //-------------------------------------------- - // shifting logic to receive values from block_encrypt - //-------------------------------------------- - - always_comb begin - concat_inst_id_d = concat_inst_id_q; - concat_ccmd_d = concat_ccmd_q; - concat_outblk_d = concat_outblk_q; - if (!enable_i) begin - concat_inst_id_d = '0; - concat_ccmd_d = '0; - concat_outblk_d = '0; - end else if (block_encrypt_rsp_vld_i && block_encrypt_rsp_rdy_o) begin - concat_inst_id_d = block_encrypt_rsp_data_i.inst_id; - concat_ccmd_d = block_encrypt_rsp_data_i.cmd; - // Replace LSBs of shift value with data from block_encrypt - concat_outblk_d = {concat_outblk_q[SeedLen-1:BlkLen], - block_encrypt_rsp_data_i.v}; - end else if (concat_outblk_shift) begin - // Shift value left by BlkLen bits - concat_outblk_d = {concat_outblk_q[SeedLen-BlkLen-1:0], {BlkLen{1'b0}}}; - end - end - - // Count the number of blocks that have been received back from block_encrypt until enough blocks - // have been received for at least SeedLen bits in total. - always_comb begin - concat_ctr_d = concat_ctr_q; - if (!enable_i) begin - concat_ctr_d = '0; - end else if (concat_ctr_done) begin - concat_ctr_d = '0; - end else if (concat_ctr_inc) begin - concat_ctr_d = concat_ctr_q + 1; - end - end - - assign concat_ctr_done = (concat_ctr_q >= SeedLen/BlkLen); - - //-------------------------------------------- - // state machine to receive values from block_encrypt - //-------------------------------------------- - - always_comb begin - outblk_state_d = outblk_state_q; - concat_ctr_inc = 1'b0; - concat_outblk_shift = 1'b0; - block_encrypt_rsp_rdy_o = 1'b0; - sfifo_final_wvld = 1'b0; - req_rdy_o = 1'b0; - sm_block_enc_rsp_err_o = 1'b0; - unique case (outblk_state_q) - // AckIdle: increment v this cycle, push in next - AckIdle: begin - if (!enable_i) begin - // There is no "clear" on the AES cipher, so just flush out any outstanding responses - // Otherwise, there will be erroneous handshakes when re-enabling the CSRNG - block_encrypt_rsp_rdy_o = 1'b1; - outblk_state_d = AckIdle; - end else if (sfifo_final_wrdy) begin - outblk_state_d = Load; - end - end - Load: begin - if (!enable_i) begin - outblk_state_d = AckIdle; - end else begin - block_encrypt_rsp_rdy_o = 1'b1; - if (block_encrypt_rsp_vld_i) begin - concat_ctr_inc = 1'b1; - outblk_state_d = Shift; - end - end - end - Shift: begin - if (!enable_i) begin - outblk_state_d = AckIdle; - end else if (concat_ctr_done) begin - req_rdy_o = 1'b1; - sfifo_final_wvld = 1'b1; - outblk_state_d = AckIdle; - end else begin - concat_outblk_shift = 1'b1; - outblk_state_d = Load; - end - end - OBError: begin - sm_block_enc_rsp_err_o = 1'b1; - end - default: begin - outblk_state_d = OBError; - sm_block_enc_rsp_err_o = 1'b1; - end - endcase - end - - - //-------------------------------------------- - // final update processing - //-------------------------------------------- - - // XOR the additional data with the new key and value from block encryption - assign updated_key_and_v = concat_outblk_q ^ req_data_i.pdata; - - prim_fifo_sync #( - .Width(BencDataWidth), - .Pass(0), - .Depth(1), - .OutputZeroIfEmpty(1'b0) - ) u_prim_fifo_sync_final ( - .clk_i (clk_i), - .rst_ni (rst_ni), - .clr_i (!enable_i), - .wvalid_i(sfifo_final_wvld), - .wready_o(sfifo_final_wrdy), - .wdata_i (sfifo_final_wdata), - .rvalid_o(sfifo_final_rvld), - .rready_i(sfifo_final_rrdy), - .rdata_o (sfifo_final_rdata), - .full_o (), - .depth_o (), - .err_o () - ); - - assign sfifo_final_wdata = {concat_inst_id_q, - concat_ccmd_q, - updated_key_and_v}; - - assign sfifo_final_rrdy = rsp_rdy_i && sfifo_final_rvld; - assign rsp_vld_o = sfifo_final_rvld; - // pdata (in the MSBs) is unused in rsp path - assign rsp_data_o = csrng_upd_data_t'({{SeedLen{1'b0}}, sfifo_final_rdata}); - - assign fifo_final_err_o = - {( sfifo_final_wvld && !sfifo_final_wrdy), - ( sfifo_final_rrdy && !sfifo_final_rvld), - (!sfifo_final_wrdy && !sfifo_final_rvld)}; - - // Unused signals - logic [KeyLen-1:0] unused_block_encrypt_rsp_data_key; - assign unused_block_encrypt_rsp_data_key = block_encrypt_rsp_data_i.key; - - // Make sure that the two state machines have a stable error state. This means that after the - // error state is entered it will not exit it unless a reset signal is received. - `ASSERT(CsrngDrbgUpdBlkEncErrorStStable_A, - blk_enc_state_q == BEError |=> $stable(blk_enc_state_q)) - `ASSERT(CsrngDrbgUpdOutBlkErrorStStable_A, - outblk_state_q == OBError |=> $stable(outblk_state_q)) - - // If in error state, the error output must be high. - `ASSERT(CsrngDrbgUpdBlkEncErrorOutput_A, blk_enc_state_q == BEError |-> sm_block_enc_req_err_o) - `ASSERT(CsrngDrbgUpdOutBlkErrorOutput_A, outblk_state_q == OBError |-> sm_block_enc_rsp_err_o) -endmodule diff --git a/hw/ip/csrng/rtl/csrng_main_sm.sv b/hw/ip/csrng/rtl/csrng_main_sm.sv index c9da418cd5978..6838bf473e584 100644 --- a/hw/ip/csrng/rtl/csrng_main_sm.sv +++ b/hw/ip/csrng/rtl/csrng_main_sm.sv @@ -34,6 +34,7 @@ module csrng_main_sm import csrng_pkg::*; ( output logic main_sm_err_o ); + // SEC_CM: MAIN_SM.FSM.SPARSE main_sm_state_e state_d, state_q; `PRIM_FLOP_SPARSE_FSM(u_state_regs, state_d, state_q, main_sm_state_e, MainSmIdle) diff --git a/hw/ip/csrng/rtl/csrng_pkg.sv b/hw/ip/csrng/rtl/csrng_pkg.sv index 86cde3554094c..8c8797612bc28 100644 --- a/hw/ip/csrng/rtl/csrng_pkg.sv +++ b/hw/ip/csrng/rtl/csrng_pkg.sv @@ -80,9 +80,7 @@ package csrng_pkg; RES = 3'h2, GEN = 3'h3, UPD = 3'h4, - UNI = 3'h5, - GENB = 3'h6, // Rsp routing for block encrypt - GENU = 3'h7 // Rsp routing for update unit + UNI = 3'h5 } acmd_e; typedef struct packed { @@ -98,32 +96,20 @@ package csrng_pkg; // Struct data types for the core data path //------------------------------------------ - // Keep these structs identical in the LSBs and add less frequently used fields toward the MSBs - // to allow for easy assigns/conversions from smaller to more complex data types. typedef struct packed { logic fips; logic [RsCtrWidth-1:0] rs_ctr; logic [SeedLen-1:0] pdata; - logic [InstIdWidth-1:0] inst_id; + logic [NumAppsLg-1:0] inst_id; acmd_e cmd; logic [KeyLen-1:0] key; logic [BlkLen-1:0] v; } csrng_core_data_t; typedef struct packed { - logic [SeedLen-1:0] pdata; - logic [InstIdWidth-1:0] inst_id; - acmd_e cmd; - logic [KeyLen-1:0] key; - logic [BlkLen-1:0] v; - } csrng_upd_data_t; - - typedef struct packed { - logic [InstIdWidth-1:0] inst_id; - acmd_e cmd; - logic [KeyLen-1:0] key; - logic [BlkLen-1:0] v; - } csrng_benc_data_t; + logic [KeyLen-1:0] key; + logic [BlkLen-1:0] v; + } csrng_key_v_t; // Do not reorder these fields - software expects them in this order when doing the raw // state readout through the register interface. @@ -135,9 +121,6 @@ package csrng_pkg; logic [RsCtrWidth-1:0] rs_ctr; } csrng_state_t; - parameter int unsigned CoreDataWidth = $bits(csrng_core_data_t); - parameter int unsigned UpdDataWidth = $bits(csrng_upd_data_t); - parameter int unsigned BencDataWidth = $bits(csrng_benc_data_t); parameter int unsigned StateWidth = $bits(csrng_state_t); parameter int unsigned MainSmStateWidth = 6; diff --git a/hw/ip/csrng/rtl/csrng_reg_pkg.sv b/hw/ip/csrng/rtl/csrng_reg_pkg.sv index 876fbb6c5af02..ef5a4fe5bdf96 100644 --- a/hw/ip/csrng/rtl/csrng_reg_pkg.sv +++ b/hw/ip/csrng/rtl/csrng_reg_pkg.sv @@ -254,11 +254,7 @@ package csrng_reg_pkg; struct packed { logic d; logic de; - } drbg_cmd_sm_err; - struct packed { - logic d; - logic de; - } cmd_gen_cnt_err; + } ctr_err; struct packed { logic d; logic de; @@ -266,15 +262,7 @@ package csrng_reg_pkg; struct packed { logic d; logic de; - } drbg_updob_sm_err; - struct packed { - logic d; - logic de; - } drbg_updbe_sm_err; - struct packed { - logic d; - logic de; - } drbg_gen_sm_err; + } ctr_drbg_sm_err; struct packed { logic d; logic de; @@ -283,22 +271,6 @@ package csrng_reg_pkg; logic d; logic de; } cmd_stage_sm_err; - struct packed { - logic d; - logic de; - } sfifo_cmdid_err; - struct packed { - logic d; - logic de; - } sfifo_gadstage_err; - struct packed { - logic d; - logic de; - } sfifo_gbencack_err; - struct packed { - logic d; - logic de; - } sfifo_final_err; struct packed { logic d; logic de; @@ -333,15 +305,15 @@ package csrng_reg_pkg; // HW -> register type typedef struct packed { - csrng_hw2reg_intr_state_reg_t intr_state; // [253:246] - csrng_hw2reg_reseed_counter_mreg_t [2:0] reseed_counter; // [245:150] - csrng_hw2reg_sw_cmd_sts_reg_t sw_cmd_sts; // [149:142] - csrng_hw2reg_genbits_vld_reg_t genbits_vld; // [141:140] - csrng_hw2reg_genbits_reg_t genbits; // [139:108] - csrng_hw2reg_int_state_val_reg_t int_state_val; // [107:76] - csrng_hw2reg_hw_exc_sts_reg_t hw_exc_sts; // [75:59] - csrng_hw2reg_recov_alert_sts_reg_t recov_alert_sts; // [58:41] - csrng_hw2reg_err_code_reg_t err_code; // [40:7] + csrng_hw2reg_intr_state_reg_t intr_state; // [239:232] + csrng_hw2reg_reseed_counter_mreg_t [2:0] reseed_counter; // [231:136] + csrng_hw2reg_sw_cmd_sts_reg_t sw_cmd_sts; // [135:128] + csrng_hw2reg_genbits_vld_reg_t genbits_vld; // [127:126] + csrng_hw2reg_genbits_reg_t genbits; // [125:94] + csrng_hw2reg_int_state_val_reg_t int_state_val; // [93:62] + csrng_hw2reg_hw_exc_sts_reg_t hw_exc_sts; // [61:45] + csrng_hw2reg_recov_alert_sts_reg_t recov_alert_sts; // [44:27] + csrng_hw2reg_err_code_reg_t err_code; // [26:7] csrng_hw2reg_main_sm_state_reg_t main_sm_state; // [6:0] } csrng_hw2reg_t; diff --git a/hw/ip/csrng/rtl/csrng_reg_top.sv b/hw/ip/csrng/rtl/csrng_reg_top.sv index a9d67771a80e4..b91eebb7ae57d 100644 --- a/hw/ip/csrng/rtl/csrng_reg_top.sv +++ b/hw/ip/csrng/rtl/csrng_reg_top.sv @@ -216,18 +216,11 @@ module csrng_reg_top ( logic recov_alert_sts_cmd_stage_reseed_cnt_alert_wd; logic err_code_sfifo_cmd_err_qs; logic err_code_sfifo_genbits_err_qs; - logic err_code_sfifo_final_err_qs; - logic err_code_sfifo_gbencack_err_qs; - logic err_code_sfifo_gadstage_err_qs; - logic err_code_sfifo_cmdid_err_qs; logic err_code_cmd_stage_sm_err_qs; logic err_code_main_sm_err_qs; - logic err_code_drbg_gen_sm_err_qs; - logic err_code_drbg_updbe_sm_err_qs; - logic err_code_drbg_updob_sm_err_qs; + logic err_code_ctr_drbg_sm_err_qs; logic err_code_aes_cipher_sm_err_qs; - logic err_code_cmd_gen_cnt_err_qs; - logic err_code_drbg_cmd_sm_err_qs; + logic err_code_ctr_err_qs; logic err_code_fifo_write_err_qs; logic err_code_fifo_read_err_qs; logic err_code_fifo_state_err_qs; @@ -1441,114 +1434,6 @@ module csrng_reg_top ( .qs (err_code_sfifo_genbits_err_qs) ); - // F[sfifo_final_err]: 9:9 - prim_subreg #( - .DW (1), - .SwAccess(prim_subreg_pkg::SwAccessRO), - .RESVAL (1'h0), - .Mubi (1'b0) - ) u_err_code_sfifo_final_err ( - .clk_i (clk_i), - .rst_ni (rst_ni), - - // from register interface - .we (1'b0), - .wd ('0), - - // from internal hardware - .de (hw2reg.err_code.sfifo_final_err.de), - .d (hw2reg.err_code.sfifo_final_err.d), - - // to internal hardware - .qe (), - .q (), - .ds (), - - // to register interface (read) - .qs (err_code_sfifo_final_err_qs) - ); - - // F[sfifo_gbencack_err]: 10:10 - prim_subreg #( - .DW (1), - .SwAccess(prim_subreg_pkg::SwAccessRO), - .RESVAL (1'h0), - .Mubi (1'b0) - ) u_err_code_sfifo_gbencack_err ( - .clk_i (clk_i), - .rst_ni (rst_ni), - - // from register interface - .we (1'b0), - .wd ('0), - - // from internal hardware - .de (hw2reg.err_code.sfifo_gbencack_err.de), - .d (hw2reg.err_code.sfifo_gbencack_err.d), - - // to internal hardware - .qe (), - .q (), - .ds (), - - // to register interface (read) - .qs (err_code_sfifo_gbencack_err_qs) - ); - - // F[sfifo_gadstage_err]: 13:13 - prim_subreg #( - .DW (1), - .SwAccess(prim_subreg_pkg::SwAccessRO), - .RESVAL (1'h0), - .Mubi (1'b0) - ) u_err_code_sfifo_gadstage_err ( - .clk_i (clk_i), - .rst_ni (rst_ni), - - // from register interface - .we (1'b0), - .wd ('0), - - // from internal hardware - .de (hw2reg.err_code.sfifo_gadstage_err.de), - .d (hw2reg.err_code.sfifo_gadstage_err.d), - - // to internal hardware - .qe (), - .q (), - .ds (), - - // to register interface (read) - .qs (err_code_sfifo_gadstage_err_qs) - ); - - // F[sfifo_cmdid_err]: 15:15 - prim_subreg #( - .DW (1), - .SwAccess(prim_subreg_pkg::SwAccessRO), - .RESVAL (1'h0), - .Mubi (1'b0) - ) u_err_code_sfifo_cmdid_err ( - .clk_i (clk_i), - .rst_ni (rst_ni), - - // from register interface - .we (1'b0), - .wd ('0), - - // from internal hardware - .de (hw2reg.err_code.sfifo_cmdid_err.de), - .d (hw2reg.err_code.sfifo_cmdid_err.d), - - // to internal hardware - .qe (), - .q (), - .ds (), - - // to register interface (read) - .qs (err_code_sfifo_cmdid_err_qs) - ); - // F[cmd_stage_sm_err]: 20:20 prim_subreg #( .DW (1), @@ -1603,13 +1488,13 @@ module csrng_reg_top ( .qs (err_code_main_sm_err_qs) ); - // F[drbg_gen_sm_err]: 22:22 + // F[ctr_drbg_sm_err]: 22:22 prim_subreg #( .DW (1), .SwAccess(prim_subreg_pkg::SwAccessRO), .RESVAL (1'h0), .Mubi (1'b0) - ) u_err_code_drbg_gen_sm_err ( + ) u_err_code_ctr_drbg_sm_err ( .clk_i (clk_i), .rst_ni (rst_ni), @@ -1618,8 +1503,8 @@ module csrng_reg_top ( .wd ('0), // from internal hardware - .de (hw2reg.err_code.drbg_gen_sm_err.de), - .d (hw2reg.err_code.drbg_gen_sm_err.d), + .de (hw2reg.err_code.ctr_drbg_sm_err.de), + .d (hw2reg.err_code.ctr_drbg_sm_err.d), // to internal hardware .qe (), @@ -1627,61 +1512,7 @@ module csrng_reg_top ( .ds (), // to register interface (read) - .qs (err_code_drbg_gen_sm_err_qs) - ); - - // F[drbg_updbe_sm_err]: 23:23 - prim_subreg #( - .DW (1), - .SwAccess(prim_subreg_pkg::SwAccessRO), - .RESVAL (1'h0), - .Mubi (1'b0) - ) u_err_code_drbg_updbe_sm_err ( - .clk_i (clk_i), - .rst_ni (rst_ni), - - // from register interface - .we (1'b0), - .wd ('0), - - // from internal hardware - .de (hw2reg.err_code.drbg_updbe_sm_err.de), - .d (hw2reg.err_code.drbg_updbe_sm_err.d), - - // to internal hardware - .qe (), - .q (), - .ds (), - - // to register interface (read) - .qs (err_code_drbg_updbe_sm_err_qs) - ); - - // F[drbg_updob_sm_err]: 24:24 - prim_subreg #( - .DW (1), - .SwAccess(prim_subreg_pkg::SwAccessRO), - .RESVAL (1'h0), - .Mubi (1'b0) - ) u_err_code_drbg_updob_sm_err ( - .clk_i (clk_i), - .rst_ni (rst_ni), - - // from register interface - .we (1'b0), - .wd ('0), - - // from internal hardware - .de (hw2reg.err_code.drbg_updob_sm_err.de), - .d (hw2reg.err_code.drbg_updob_sm_err.d), - - // to internal hardware - .qe (), - .q (), - .ds (), - - // to register interface (read) - .qs (err_code_drbg_updob_sm_err_qs) + .qs (err_code_ctr_drbg_sm_err_qs) ); // F[aes_cipher_sm_err]: 25:25 @@ -1711,40 +1542,13 @@ module csrng_reg_top ( .qs (err_code_aes_cipher_sm_err_qs) ); - // F[cmd_gen_cnt_err]: 26:26 - prim_subreg #( - .DW (1), - .SwAccess(prim_subreg_pkg::SwAccessRO), - .RESVAL (1'h0), - .Mubi (1'b0) - ) u_err_code_cmd_gen_cnt_err ( - .clk_i (clk_i), - .rst_ni (rst_ni), - - // from register interface - .we (1'b0), - .wd ('0), - - // from internal hardware - .de (hw2reg.err_code.cmd_gen_cnt_err.de), - .d (hw2reg.err_code.cmd_gen_cnt_err.d), - - // to internal hardware - .qe (), - .q (), - .ds (), - - // to register interface (read) - .qs (err_code_cmd_gen_cnt_err_qs) - ); - - // F[drbg_cmd_sm_err]: 27:27 + // F[ctr_err]: 26:26 prim_subreg #( .DW (1), .SwAccess(prim_subreg_pkg::SwAccessRO), .RESVAL (1'h0), .Mubi (1'b0) - ) u_err_code_drbg_cmd_sm_err ( + ) u_err_code_ctr_err ( .clk_i (clk_i), .rst_ni (rst_ni), @@ -1753,8 +1557,8 @@ module csrng_reg_top ( .wd ('0), // from internal hardware - .de (hw2reg.err_code.drbg_cmd_sm_err.de), - .d (hw2reg.err_code.drbg_cmd_sm_err.d), + .de (hw2reg.err_code.ctr_err.de), + .d (hw2reg.err_code.ctr_err.d), // to internal hardware .qe (), @@ -1762,7 +1566,7 @@ module csrng_reg_top ( .ds (), // to register interface (read) - .qs (err_code_drbg_cmd_sm_err_qs) + .qs (err_code_ctr_err_qs) ); // F[fifo_write_err]: 28:28 @@ -2216,18 +2020,11 @@ module csrng_reg_top ( addr_hit[21]: begin reg_rdata_next[0] = err_code_sfifo_cmd_err_qs; reg_rdata_next[1] = err_code_sfifo_genbits_err_qs; - reg_rdata_next[9] = err_code_sfifo_final_err_qs; - reg_rdata_next[10] = err_code_sfifo_gbencack_err_qs; - reg_rdata_next[13] = err_code_sfifo_gadstage_err_qs; - reg_rdata_next[15] = err_code_sfifo_cmdid_err_qs; reg_rdata_next[20] = err_code_cmd_stage_sm_err_qs; reg_rdata_next[21] = err_code_main_sm_err_qs; - reg_rdata_next[22] = err_code_drbg_gen_sm_err_qs; - reg_rdata_next[23] = err_code_drbg_updbe_sm_err_qs; - reg_rdata_next[24] = err_code_drbg_updob_sm_err_qs; + reg_rdata_next[22] = err_code_ctr_drbg_sm_err_qs; reg_rdata_next[25] = err_code_aes_cipher_sm_err_qs; - reg_rdata_next[26] = err_code_cmd_gen_cnt_err_qs; - reg_rdata_next[27] = err_code_drbg_cmd_sm_err_qs; + reg_rdata_next[26] = err_code_ctr_err_qs; reg_rdata_next[28] = err_code_fifo_write_err_qs; reg_rdata_next[29] = err_code_fifo_read_err_qs; reg_rdata_next[30] = err_code_fifo_state_err_qs; diff --git a/hw/ip/csrng/rtl/csrng_state_db.sv b/hw/ip/csrng/rtl/csrng_state_db.sv index 4b6bdba5765ba..1373e4859742e 100644 --- a/hw/ip/csrng/rtl/csrng_state_db.sv +++ b/hw/ip/csrng/rtl/csrng_state_db.sv @@ -22,18 +22,12 @@ module csrng_state_db input logic enable_i, // Read interface for the core data path - input logic [InstIdWidth-1:0] rd_inst_id_i, + input logic [NumAppsLg-1:0] rd_inst_id_i, output csrng_state_t rd_state_o, // Write interface input logic wr_vld_i, input csrng_core_data_t wr_data_i, - input csrng_cmd_sts_e wr_status_i, - - // Write interface "status" feedback - output logic status_vld_o, - output csrng_cmd_sts_e status_val_o, - output logic [InstIdWidth-1:0] status_inst_id_o, // State dump interface via register access input logic reg_rd_otp_en_i, @@ -59,25 +53,16 @@ module csrng_state_db logic [NumRegTotBits-1:0] state_reg_readout; // Registers - logic status_vld_q, status_vld_d; - csrng_cmd_sts_e status_val_q, status_val_d; - logic [InstIdWidth-1:0] status_inst_id_q, status_inst_id_d; logic [NumRegStateLg-1:0] reg_rd_ptr_q, reg_rd_ptr_d; logic [NumAppsLg-1:0] reg_rd_id_q, reg_rd_id_d; always_ff @(posedge clk_i or negedge rst_ni) begin if (!rst_ni) begin - status_vld_q <= '0; - status_val_q <= CMD_STS_SUCCESS; - status_inst_id_q <= '0; - reg_rd_ptr_q <= '0; - reg_rd_id_q <= '0; + reg_rd_ptr_q <= '0; + reg_rd_id_q <= '0; end else begin - status_vld_q <= status_vld_d; - status_val_q <= status_val_d; - status_inst_id_q <= status_inst_id_d; - reg_rd_ptr_q <= reg_rd_ptr_d; - reg_rd_id_q <= reg_rd_id_d; + reg_rd_ptr_q <= reg_rd_ptr_d; + reg_rd_id_q <= reg_rd_id_d; end end @@ -89,7 +74,7 @@ module csrng_state_db end // State readout for core data path - assign rd_state_o = (rd_inst_id_i < NumApps) ? state_q[rd_inst_id_i[NumAppsLg-1:0]] : '0; + assign rd_state_o = (rd_inst_id_i < NumApps) ? state_q[rd_inst_id_i] : '0; //-------------------------------------------- // Regfile readout logic @@ -137,8 +122,8 @@ module csrng_state_db //-------------------------------------------- // All valid commands except UNInstatiate set the instance state as 'instantiated'. - assign instance_state = (wr_data_i.cmd == INS) || (wr_data_i.cmd == RES) || - (wr_data_i.cmd == GENU) || (wr_data_i.cmd == UPD); + assign instance_state = (wr_data_i.cmd == INS) || (wr_data_i.cmd == RES) || + (wr_data_i.cmd == GEN) || (wr_data_i.cmd == UPD); assign write_en = enable_i && wr_vld_i; @@ -148,7 +133,7 @@ module csrng_state_db if (!enable_i) begin state_d = '0; end else if (write_en && (wr_data_i.inst_id < NumApps)) begin - state_d[wr_data_i.inst_id[NumAppsLg-1:0]] = '{ + state_d[wr_data_i.inst_id] = '{ fips: wr_data_i.fips, key: wr_data_i.key, v: wr_data_i.v, @@ -158,20 +143,11 @@ module csrng_state_db end end - assign status_vld_d = write_en; - assign status_val_d = wr_status_i; - assign status_inst_id_d = wr_data_i.inst_id; - - assign status_vld_o = status_vld_q; - assign status_val_o = status_val_q; - assign status_inst_id_o = status_inst_id_q; - // Unused signals logic [SeedLen-1:0] unused_wdata_pdata; - logic [InstIdWidth-NumAppsLg-1:0] unused_reg_rd_id, unused_rd_inst_id; + logic [InstIdWidth-NumAppsLg-1:0] unused_reg_rd_id; assign unused_wdata_pdata = wr_data_i.pdata; assign unused_reg_rd_id = reg_rd_id_i[InstIdWidth-1:NumAppsLg]; - assign unused_rd_inst_id = rd_inst_id_i[InstIdWidth-1:NumAppsLg]; // Assertions // The current architecture assumes the reseed counter fits into a single register diff --git a/hw/ip/edn/dv/cov/edn_cov_if.sv b/hw/ip/edn/dv/cov/edn_cov_if.sv index d8a4b05370047..17fdde75a3699 100644 --- a/hw/ip/edn/dv/cov/edn_cov_if.sv +++ b/hw/ip/edn/dv/cov/edn_cov_if.sv @@ -75,7 +75,7 @@ interface edn_cov_if ( cp_acmd: coverpoint acmd { // ignore unused/invalid commands - ignore_bins unused = { csrng_pkg::GENB, csrng_pkg::GENU, csrng_pkg::INV }; + ignore_bins unused = { csrng_pkg::INV }; } cp_clen: coverpoint clen { @@ -285,7 +285,7 @@ interface edn_cov_if ( cp_acmd: coverpoint acmd { // Ignore unused/invalid HW commands. - ignore_bins unused = { csrng_pkg::GENB, csrng_pkg::GENU, csrng_pkg::INV, csrng_pkg::UPD }; + ignore_bins unused = { csrng_pkg::INV, csrng_pkg::UPD }; } // We want to see all of the boot commands in boot mode. diff --git a/sw/device/lib/dif/dif_csrng.c b/sw/device/lib/dif/dif_csrng.c index 285cf3bedb326..aa935ffeabf6e 100644 --- a/sw/device/lib/dif/dif_csrng.c +++ b/sw/device/lib/dif/dif_csrng.c @@ -184,15 +184,6 @@ dif_result_t dif_csrng_get_cmd_force_unhealthy_fifo(const dif_csrng_t *csrng, case kDifCsrngFifoGenBits: fifo_bit = CSRNG_ERR_CODE_SFIFO_GENBITS_ERR_BIT; break; - case kDifCsrngFifoGBencAck: - fifo_bit = CSRNG_ERR_CODE_SFIFO_GBENCACK_ERR_BIT; - break; - case kDifCsrngFifoGadStage: - fifo_bit = CSRNG_ERR_CODE_SFIFO_GADSTAGE_ERR_BIT; - break; - case kDifCsrngFifoCmdId: - fifo_bit = CSRNG_ERR_CODE_SFIFO_CMDID_ERR_BIT; - break; default: return kDifBadArg; } @@ -217,23 +208,14 @@ dif_result_t dif_csrng_get_cmd_force_error(const dif_csrng_t *csrng, case kDifCsrngErrorMainSm: error_bit = CSRNG_ERR_CODE_MAIN_SM_ERR_BIT; break; - case kDifCsrngErrorDrbgCmdSm: - error_bit = CSRNG_ERR_CODE_DRBG_CMD_SM_ERR_BIT; - break; - case kDifCsrngErrorDrbgGenSm: - error_bit = CSRNG_ERR_CODE_DRBG_GEN_SM_ERR_BIT; - break; - case kDifCsrngErrorDrbgUpdateBlockEncSm: - error_bit = CSRNG_ERR_CODE_DRBG_UPDBE_SM_ERR_BIT; - break; - case kDifCsrngErrorDrbgUpdateOutBlockSm: - error_bit = CSRNG_ERR_CODE_DRBG_UPDOB_SM_ERR_BIT; + case kDifCsrngErrorCtrDrbgSm: + error_bit = CSRNG_ERR_CODE_CTR_DRBG_SM_ERR_BIT; break; case kDifCsrngErrorAesSm: error_bit = CSRNG_ERR_CODE_AES_CIPHER_SM_ERR_BIT; break; - case kDifCsrngErrorGenerateCmdCounter: - error_bit = CSRNG_ERR_CODE_CMD_GEN_CNT_ERR_BIT; + case kDifCsrngErrorCounters: + error_bit = CSRNG_ERR_CODE_CTR_ERR_BIT; break; case kDifCsrngErrorFifoWrite: error_bit = CSRNG_ERR_CODE_FIFO_WRITE_ERR_BIT; diff --git a/sw/device/lib/dif/dif_csrng.h b/sw/device/lib/dif/dif_csrng.h index 166e028bd9fcf..63ade3e1c8e35 100644 --- a/sw/device/lib/dif/dif_csrng.h +++ b/sw/device/lib/dif/dif_csrng.h @@ -93,9 +93,6 @@ typedef enum dif_csrng_cmd_status_kind { typedef enum dif_csrng_fifo { kDifCsrngFifoCmd, kDifCsrngFifoGenBits, - kDifCsrngFifoGBencAck, - kDifCsrngFifoGadStage, - kDifCsrngFifoCmdId, } dif_csrng_fifo_t; /** @@ -111,29 +108,17 @@ typedef enum dif_csrng_error { */ kDifCsrngErrorMainSm, /** - * Indicates an error in the DRBG's command unit state machine. + * Indicates an error in the CTR_DRBG data path state machine. */ - kDifCsrngErrorDrbgCmdSm, - /** - * Indicates an error in the DRBG's generator state machine. - */ - kDifCsrngErrorDrbgGenSm, - /** - * Indicates an error in the DRBG's block encoding state machine. - */ - kDifCsrngErrorDrbgUpdateBlockEncSm, - /** - * Indicates an error in the DRBG's block output state machine. - */ - kDifCsrngErrorDrbgUpdateOutBlockSm, + kDifCsrngErrorCtrDrbgSm, /** * Indicates an error in the AES state machine. */ kDifCsrngErrorAesSm, /** - * Indicates an error in the generate command's counter. + * Indicates an error in one of the counters. */ - kDifCsrngErrorGenerateCmdCounter, + kDifCsrngErrorCounters, /** * Indicates a write to a full FIFO occurred. */