diff --git a/hw/ip/csrng/data/csrng.hjson b/hw/ip/csrng/data/csrng.hjson index 0a03c51c8dd23..a50ab78f0cc1d 100644 --- a/hw/ip/csrng/data/csrng.hjson +++ b/hw/ip/csrng/data/csrng.hjson @@ -178,6 +178,9 @@ { 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." } @@ -188,13 +191,13 @@ desc: "The CSRNG block output 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." + 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." + 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." + desc: "The ctr_drbg generate 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." @@ -728,33 +731,6 @@ This bit will stay set until the next reset. ''' } - { bits: "3", - name: "SFIFO_RCSTAGE_ERR", - desc: ''' - This bit will be set to one when an error has been detected for the - rcstage 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: "4", - name: "SFIFO_KEYVRC_ERR", - desc: ''' - This bit will be set to one when an error has been detected for the - keyvrc 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: "7", - name: "SFIFO_BENCACK_ERR", - desc: ''' - This bit will be set to one when an error has been detected for the - bencack 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: "9", name: "SFIFO_FINAL_ERR", desc: ''' @@ -882,6 +858,15 @@ 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 bit will stay set until the next reset. + ''' + } { bits: "28", name: "FIFO_WRITE_ERR", desc: ''' diff --git a/hw/ip/csrng/data/csrng_sec_cm_testplan.hjson b/hw/ip/csrng/data/csrng_sec_cm_testplan.hjson index e90307caa8a24..8d1a0f0fe5eec 100644 --- a/hw/ip/csrng/data/csrng_sec_cm_testplan.hjson +++ b/hw/ip/csrng/data/csrng_sec_cm_testplan.hjson @@ -66,6 +66,17 @@ stage: V2S tests: ["csrng_sec_cm", "csrng_intr", "csrng_err"] } + { + name: sec_cm_updrsp_fsm_sparse + desc: ''' + Verify the countermeasure(s) UPDRSP.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_update_fsm_sparse desc: ''' diff --git a/hw/ip/csrng/doc/interfaces.md b/hw/ip/csrng/doc/interfaces.md index 1c5c79ebb4a64..28e635080cf50 100644 --- a/hw/ip/csrng/doc/interfaces.md +++ b/hw/ip/csrng/doc/interfaces.md @@ -43,6 +43,7 @@ Referring to the [Comportable guideline for peripheral device functionality](htt | CSRNG.CONFIG.MUBI | Registers have multi-bit encoded fields. | | CSRNG.INTERSIG.MUBI | OTP signal used to enable software access to registers. | | 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. | diff --git a/hw/ip/csrng/doc/registers.md b/hw/ip/csrng/doc/registers.md index 7446bf242e5e3..817c9c981f2a0 100644 --- a/hw/ip/csrng/doc/registers.md +++ b/hw/ip/csrng/doc/registers.md @@ -555,12 +555,12 @@ Writing a zero resets this status bit. Hardware detection of error conditions status register - Offset: `0x54` - Reset default: `0x0` -- Reset mask: `0x77f0fe9b` +- Reset mask: `0x7ff0fe03` ### Fields ```wavejson -{"reg": [{"name": "SFIFO_CMD_ERR", "bits": 1, "attr": ["ro"], "rotate": -90}, {"name": "SFIFO_GENBITS_ERR", "bits": 1, "attr": ["ro"], "rotate": -90}, {"bits": 1}, {"name": "SFIFO_RCSTAGE_ERR", "bits": 1, "attr": ["ro"], "rotate": -90}, {"name": "SFIFO_KEYVRC_ERR", "bits": 1, "attr": ["ro"], "rotate": -90}, {"bits": 2}, {"name": "SFIFO_BENCACK_ERR", "bits": 1, "attr": ["ro"], "rotate": -90}, {"bits": 1}, {"name": "SFIFO_FINAL_ERR", "bits": 1, "attr": ["ro"], "rotate": -90}, {"name": "SFIFO_GBENCACK_ERR", "bits": 1, "attr": ["ro"], "rotate": -90}, {"name": "SFIFO_GRCSTAGE_ERR", "bits": 1, "attr": ["ro"], "rotate": -90}, {"name": "SFIFO_GGENREQ_ERR", "bits": 1, "attr": ["ro"], "rotate": -90}, {"name": "SFIFO_GADSTAGE_ERR", "bits": 1, "attr": ["ro"], "rotate": -90}, {"name": "SFIFO_GGENBITS_ERR", "bits": 1, "attr": ["ro"], "rotate": -90}, {"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}, {"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": 200}} +{"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}, {"name": "SFIFO_GRCSTAGE_ERR", "bits": 1, "attr": ["ro"], "rotate": -90}, {"name": "SFIFO_GGENREQ_ERR", "bits": 1, "attr": ["ro"], "rotate": -90}, {"name": "SFIFO_GADSTAGE_ERR", "bits": 1, "attr": ["ro"], "rotate": -90}, {"name": "SFIFO_GGENBITS_ERR", "bits": 1, "attr": ["ro"], "rotate": -90}, {"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}} ``` | Bits | Type | Reset | Name | @@ -569,7 +569,7 @@ Hardware detection of error conditions status register | 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 | +| 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) | @@ -585,12 +585,7 @@ Hardware detection of error conditions status register | 11 | ro | 0x0 | [SFIFO_GRCSTAGE_ERR](#err_code--sfifo_grcstage_err) | | 10 | ro | 0x0 | [SFIFO_GBENCACK_ERR](#err_code--sfifo_gbencack_err) | | 9 | ro | 0x0 | [SFIFO_FINAL_ERR](#err_code--sfifo_final_err) | -| 8 | | | Reserved | -| 7 | ro | 0x0 | [SFIFO_BENCACK_ERR](#err_code--sfifo_bencack_err) | -| 6:5 | | | Reserved | -| 4 | ro | 0x0 | [SFIFO_KEYVRC_ERR](#err_code--sfifo_keyvrc_err) | -| 3 | ro | 0x0 | [SFIFO_RCSTAGE_ERR](#err_code--sfifo_rcstage_err) | -| 2 | | | Reserved | +| 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) | @@ -612,6 +607,12 @@ 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 This bit will be set to one when a mismatch in any of the hardened counters has been detected. @@ -697,24 +698,6 @@ 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_BENCACK_ERR -This bit will be set to one when an error has been detected for the -bencack 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_KEYVRC_ERR -This bit will be set to one when an error has been detected for the -keyvrc 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_RCSTAGE_ERR -This bit will be set to one when an error has been detected for the -rcstage 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 fb1c74bdaa8b8..c762cc3013635 100644 --- a/hw/ip/csrng/dv/cov/csrng_cov_if.sv +++ b/hw/ip/csrng/dv/cov/csrng_cov_if.sv @@ -243,15 +243,15 @@ 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_GEN_SM_ERR, DRBG_UPDBE_SM_ERR, - DRBG_UPDOB_SM_ERR, AES_CIPHER_SM_ERR, - CMD_GEN_CNT_ERR } && - binsof(cp_fifo_err_type) intersect { 0 }; + DRBG_CMD_SM_ERR, DRBG_GEN_SM_ERR, + DRBG_UPDBE_SM_ERR, DRBG_UPDOB_SM_ERR, + AES_CIPHER_SM_ERR, CMD_GEN_CNT_ERR } + && binsof(cp_fifo_err_type) intersect { 0 }; ignore_bins ignore = binsof(cp_err_codes) intersect { CMD_STAGE_SM_ERR, MAIN_SM_ERR, - DRBG_GEN_SM_ERR, DRBG_UPDBE_SM_ERR, - DRBG_UPDOB_SM_ERR, AES_CIPHER_SM_ERR, - CMD_GEN_CNT_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 }; } cp_csrng_aes_fsm_err: coverpoint diff --git a/hw/ip/csrng/dv/env/csrng_env_pkg.sv b/hw/ip/csrng/dv/env/csrng_env_pkg.sv index 7fbfb7319c470..67b6d6d566fb1 100644 --- a/hw/ip/csrng/dv/env/csrng_env_pkg.sv +++ b/hw/ip/csrng/dv/env/csrng_env_pkg.sv @@ -53,86 +53,81 @@ 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 + // 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_rcstage_error = 3, - sfifo_keyvrc_error = 4, - sfifo_bencack_error = 7, - sfifo_final_error = 9, - sfifo_gbencack_error = 10, - sfifo_grcstage_error = 11, - sfifo_ggenreq_error = 12, - sfifo_gadstage_error = 13, - sfifo_ggenbits_error = 14, - sfifo_cmdid_error = 15, - cmd_stage_sm_error = 16, - main_sm_error = 17, - drbg_gen_sm_error = 18, - drbg_updbe_sm_error = 19, - drbg_updob_sm_error = 20, - aes_cipher_sm_error = 21, - cmd_gen_cnt_error = 22, - fifo_write_error = 23, - fifo_read_error = 24, - fifo_state_error = 25 + sfifo_final_error = 3, + sfifo_gbencack_error = 4, + sfifo_grcstage_error = 5, + sfifo_ggenreq_error = 6, + sfifo_gadstage_error = 7, + sfifo_ggenbits_error = 8, + 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 } fatal_err_e; typedef enum int { // ERR_CODE sfifo_cmd_err = 0, sfifo_genbits_err = 1, - sfifo_rcstage_err = 3, - sfifo_keyvrc_err = 4, - sfifo_bencack_err = 7, - sfifo_final_err = 9, - sfifo_gbencack_err = 10, - sfifo_grcstage_err = 11, - sfifo_ggenreq_err = 12, - sfifo_gadstage_err = 13, - sfifo_ggenbits_err = 14, - sfifo_cmdid_err = 15, - cmd_stage_sm_err = 16, - main_sm_err = 17, - drbg_gen_sm_err = 18, - drbg_updbe_sm_err = 19, - drbg_updob_sm_err = 20, - aes_cipher_sm_err = 21, - cmd_gen_cnt_err = 22, - fifo_write_err = 23, - fifo_read_err = 24, - fifo_state_err = 25, + sfifo_final_err = 3, + sfifo_gbencack_err = 4, + sfifo_grcstage_err = 5, + sfifo_ggenreq_err = 6, + sfifo_gadstage_err = 7, + sfifo_ggenbits_err = 8, + 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, // ERR_CODE_TEST - sfifo_cmd_err_test = 26, - sfifo_genbits_err_test = 27, - sfifo_rcstage_err_test = 29, - sfifo_keyvrc_err_test = 30, - sfifo_bencack_err_test = 33, - sfifo_final_err_test = 35, - sfifo_gbencack_err_test = 36, - sfifo_grcstage_err_test = 37, - sfifo_ggenreq_err_test = 38, - sfifo_gadstage_err_test = 39, - sfifo_ggenbits_err_test = 40, - sfifo_cmdid_err_test = 41, - cmd_stage_sm_err_test = 42, - main_sm_err_test = 43, - drbg_gen_sm_err_test = 44, - drbg_updbe_sm_err_test = 45, - drbg_updob_sm_err_test = 46, - aes_cipher_sm_err_test = 47, - cmd_gen_cnt_err_test = 48, - fifo_write_err_test = 49, - fifo_read_err_test = 50, - fifo_state_err_test = 51 + sfifo_cmd_err_test = 21, + sfifo_genbits_err_test = 22, + sfifo_final_err_test = 24, + sfifo_gbencack_err_test = 25, + sfifo_grcstage_err_test = 26, + sfifo_ggenreq_err_test = 27, + sfifo_gadstage_err_test = 28, + sfifo_ggenbits_err_test = 29, + 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 } err_code_e; + // These encodings must match the respective bit position of each + // field in the regfile/IP hjson. typedef enum int { SFIFO_CMD_ERR = 0, SFIFO_GENBITS_ERR = 1, - SFIFO_RCSTAGE_ERR = 3, - SFIFO_KEYVRC_ERR = 4, - SFIFO_BENCACK_ERR = 7, SFIFO_FINAL_ERR = 9, SFIFO_GBENCACK_ERR = 10, SFIFO_GRCSTAGE_ERR = 11, @@ -147,6 +142,7 @@ package csrng_env_pkg; DRBG_UPDOB_SM_ERR = 24, AES_CIPHER_SM_ERR = 25, CMD_GEN_CNT_ERR = 26, + DRBG_CMD_SM_ERR = 27, FIFO_WRITE_ERR = 28, FIFO_READ_ERR = 29, FIFO_STATE_ERR = 30 @@ -171,11 +167,8 @@ package csrng_env_pkg; sfifo_grcstage = 4, sfifo_gbencack = 5, sfifo_final = 6, - sfifo_bencack = 8, - sfifo_keyvrc = 11, - sfifo_rcstage = 12, - sfifo_genbits = 14, - sfifo_cmd = 15 + sfifo_genbits = 7, + sfifo_cmd = 8 } which_fifo_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 05d8a18aab637..741f1985c1fc9 100644 --- a/hw/ip/csrng/dv/env/csrng_path_if.sv +++ b/hw/ip/csrng/dv/env/csrng_path_if.sv @@ -17,10 +17,7 @@ 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_rcstage", "sfifo_keyvrc": return {core_path, ".u_csrng_ctr_drbg_cmd.", - fifo_name, "_", which_path}; - "sfifo_bencack", "sfifo_final": return - {core_path, ".u_csrng_ctr_drbg_upd.", fifo_name, "_", which_path}; + "sfifo_final": return {core_path, ".u_csrng_ctr_drbg_upd.", fifo_name, "_", which_path}; "sfifo_gbencack", "sfifo_grcstage", "sfifo_ggenreq", "sfifo_gadstage", "sfifo_ggenbits": return {core_path,".u_csrng_ctr_drbg_gen.sfifo_", fifo_name.substr(7, fifo_name.len()-1), "_", which_path}; @@ -37,6 +34,7 @@ interface csrng_path_if "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"}; default: `uvm_fatal("csrng_path_if", "Invalid sm name!") endcase // case (which_sm) endfunction // sm_err_path 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 7f8acdbeb4e20..5ca1ad6fea824 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 @@ -60,6 +60,7 @@ class csrng_err_vseq extends csrng_base_vseq; $assertoff(0, "tb.dut.u_csrng_core.u_prim_arbiter_ppc_updblk_arb.LockArbDecision_A"); $assertoff(0, "tb.dut.u_csrng_core.u_prim_arbiter_ppc_benblk_arb.ReqStaysHighUntilGranted0_M"); $assertoff(0, "tb.dut.u_csrng_core.u_prim_arbiter_ppc_updblk_arb.ReqStaysHighUntilGranted0_M"); + $assertoff(0, "tb.dut.u_csrng_core.CsrngNoConcurrentGenCmdRsp_A"); $assertoff(0, `HIER_PATH(`CMD_STAGE_0, u_state_regs_A)); $assertoff(0, `HIER_PATH(`CMD_STAGE_1, u_state_regs_A)); $assertoff(0, `HIER_PATH(`CMD_STAGE_2, u_state_regs_A)); @@ -99,10 +100,8 @@ 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_rcstage_err, sfifo_keyvrc_err, - sfifo_final_err, sfifo_gbencack_err, sfifo_grcstage_err, - sfifo_gadstage_err, sfifo_ggenbits_err, sfifo_cmdid_err, - sfifo_bencack_err, sfifo_ggenreq_err: begin + sfifo_cmd_err, sfifo_genbits_err, sfifo_final_err, sfifo_gbencack_err, sfifo_grcstage_err, + sfifo_gadstage_err, sfifo_ggenbits_err, sfifo_cmdid_err, sfifo_ggenreq_err: begin fld = csr.get_field_by_name(fld_name); fifo_base_path = fld_name.substr(0, last_index-1); @@ -114,8 +113,7 @@ 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) - if (cfg.which_err_code == sfifo_ggenreq_err || - cfg.which_err_code == sfifo_bencack_err) begin + if (cfg.which_err_code == sfifo_ggenreq_err) begin force_all_fifo_errs_exception(fifo_forced_paths, fifo_forced_values, path_exts, fld, 1'b1, cfg.which_fifo_err); @@ -154,7 +152,8 @@ 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 - cmd_stage_sm_err, main_sm_err, drbg_gen_sm_err, drbg_updbe_sm_err, drbg_updob_sm_err: begin + cmd_stage_sm_err, main_sm_err, drbg_cmd_sm_err, drbg_gen_sm_err, drbg_updbe_sm_err, + drbg_updob_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); @@ -262,8 +261,7 @@ class csrng_err_vseq extends csrng_base_vseq; value1 = fifo_err_value[0][path_key]; value2 = fifo_err_value[1][path_key]; - if (cfg.which_err_code == fifo_read_error && - ((cfg.which_fifo == sfifo_ggenreq) || (cfg.which_fifo == sfifo_bencack))) begin + if ((cfg.which_err_code == fifo_read_error) && (cfg.which_fifo == sfifo_ggenreq)) begin force_fifo_err_exception(path1, path2, 1'b1, 1'b0, 1'b0, fld, 1'b1); // For sfifo_gadstage the down stream FIFO also takes inputs from sources other than @@ -301,13 +299,12 @@ 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_rcstage_err_test, - sfifo_keyvrc_err_test, sfifo_bencack_err_test, + sfifo_cmd_err_test, sfifo_genbits_err_test, sfifo_final_err_test, sfifo_gbencack_err_test, sfifo_grcstage_err_test, sfifo_ggenreq_err_test, sfifo_gadstage_err_test, sfifo_ggenbits_err_test, - sfifo_cmdid_err_test, cmd_stage_sm_err_test, main_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_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 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)); @@ -339,6 +336,7 @@ 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, @@ -361,6 +359,7 @@ class csrng_err_vseq extends csrng_base_vseq; $asserton(0, "tb.dut.u_csrng_core.u_prim_arbiter_ppc_updblk_arb.LockArbDecision_A"); $asserton(0, "tb.dut.u_csrng_core.u_prim_arbiter_ppc_benblk_arb.ReqStaysHighUntilGranted0_M"); $asserton(0, "tb.dut.u_csrng_core.u_prim_arbiter_ppc_updblk_arb.ReqStaysHighUntilGranted0_M"); + $asserton(0, "tb.dut.u_csrng_core.CsrngNoConcurrentGenCmdRsp_A"); $asserton(0, `HIER_PATH(`CMD_STAGE_0, u_state_regs_A)); $asserton(0, `HIER_PATH(`CMD_STAGE_1, u_state_regs_A)); $asserton(0, `HIER_PATH(`CMD_STAGE_2, u_state_regs_A)); 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 7cb4bdc90d9b2..9449ac7d549ab 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,18 +220,16 @@ 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_rcstage_error, - sfifo_keyvrc_error, sfifo_final_error, sfifo_gbencack_error, - sfifo_grcstage_error, sfifo_gadstage_error, sfifo_ggenbits_error, - sfifo_cmdid_error, sfifo_bencack_error, sfifo_ggenreq_error: begin + sfifo_cmd_error, sfifo_genbits_error, sfifo_final_error, sfifo_gbencack_error, + sfifo_grcstage_error, sfifo_gadstage_error, sfifo_ggenbits_error, sfifo_cmdid_error, + sfifo_ggenreq_error: begin fifo_base_path = fld_name.substr(0, last_index-1); foreach (path_exts[i]) begin fifo_forced_paths[i] = cfg.csrng_path_vif.fifo_err_path(cfg.NHwApps, fifo_base_path, path_exts[i]); end - if (cfg.which_fatal_err == sfifo_bencack_error || - cfg.which_fatal_err == sfifo_ggenreq_error) begin + if (cfg.which_fatal_err == sfifo_ggenreq_error) begin force_all_fifo_errs_exception(fifo_forced_paths, fifo_forced_values, path_exts, ral.intr_state.cs_fatal_err, 1'b1, cfg.which_fifo_err); end else begin @@ -239,7 +237,7 @@ class csrng_intr_vseq extends csrng_base_vseq; ral.intr_state.cs_fatal_err, 1'b1, cfg.which_fifo_err); end end - cmd_stage_sm_error, main_sm_error, drbg_gen_sm_error, drbg_updbe_sm_error, + cmd_stage_sm_error, main_sm_error, drbg_cmd_sm_error, drbg_gen_sm_error, drbg_updbe_sm_error, drbg_updob_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); @@ -308,8 +306,7 @@ class csrng_intr_vseq extends csrng_base_vseq; value1 = fifo_err_value[0][path_key]; value2 = fifo_err_value[1][path_key]; - if (cfg.which_fatal_err == fifo_read_error && - ((cfg.which_fifo == sfifo_ggenreq) || (cfg.which_fifo == sfifo_bencack))) begin + if ((cfg.which_fatal_err == fifo_read_error) && (cfg.which_fifo == sfifo_ggenreq)) begin force_fifo_err_exception(path1, path2, value1, value2, 1'b0, ral.intr_state.cs_fatal_err, 1'b1); end else begin @@ -359,6 +356,7 @@ class csrng_intr_vseq extends csrng_base_vseq; $assertoff(0, "tb.dut.u_csrng_core.u_prim_arbiter_ppc_updblk_arb.LockArbDecision_A"); $assertoff(0, "tb.dut.u_csrng_core.u_prim_arbiter_ppc_benblk_arb.ReqStaysHighUntilGranted0_M"); $assertoff(0, "tb.dut.u_csrng_core.u_prim_arbiter_ppc_updblk_arb.ReqStaysHighUntilGranted0_M"); + $assertoff(0, "tb.dut.u_csrng_core.CsrngNoConcurrentGenCmdRsp_A"); $assertoff(0, `HIER_PATH(`CMD_STAGE_0, CsrngCmdStageGenbitsFifoPushExpected_A)); $assertoff(0, `HIER_PATH(`CMD_STAGE_1, CsrngCmdStageGenbitsFifoPushExpected_A)); $assertoff(0, `HIER_PATH(`CMD_STAGE_2, CsrngCmdStageGenbitsFifoPushExpected_A)); @@ -378,7 +376,7 @@ 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, + 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 @@ -399,6 +397,7 @@ class csrng_intr_vseq extends csrng_base_vseq; $asserton(0, "tb.dut.u_csrng_core.u_prim_arbiter_ppc_updblk_arb.LockArbDecision_A"); $asserton(0, "tb.dut.u_csrng_core.u_prim_arbiter_ppc_benblk_arb.ReqStaysHighUntilGranted0_M"); $asserton(0, "tb.dut.u_csrng_core.u_prim_arbiter_ppc_updblk_arb.ReqStaysHighUntilGranted0_M"); + $asserton(0, "tb.dut.u_csrng_core.CsrngNoConcurrentGenCmdRsp_A"); $asserton(0, `HIER_PATH(`CMD_STAGE_0, CsrngCmdStageGenbitsFifoPushExpected_A)); $asserton(0, `HIER_PATH(`CMD_STAGE_1, CsrngCmdStageGenbitsFifoPushExpected_A)); $asserton(0, `HIER_PATH(`CMD_STAGE_2, CsrngCmdStageGenbitsFifoPushExpected_A)); diff --git a/hw/ip/csrng/dv/sva/csrng_assert_if.sv b/hw/ip/csrng/dv/sva/csrng_assert_if.sv index 1fa3059c8a27a..39755ed026753 100644 --- a/hw/ip/csrng/dv/sva/csrng_assert_if.sv +++ b/hw/ip/csrng/dv/sva/csrng_assert_if.sv @@ -31,6 +31,8 @@ `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 @@ -50,6 +52,7 @@ interface csrng_assert_if $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); endtask // assert_off task automatic assert_on (); @@ -64,6 +67,7 @@ interface csrng_assert_if $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); endtask // assert_on task automatic assert_off_alert (); diff --git a/hw/ip/csrng/dv/tb.sv b/hw/ip/csrng/dv/tb.sv index 5675910050c98..67c4015d1b389 100644 --- a/hw/ip/csrng/dv/tb.sv +++ b/hw/ip/csrng/dv/tb.sv @@ -150,14 +150,6 @@ module tb; [csrng_pkg::BencDataWidth-1 -: csrng_pkg::BlkLen]) != $past(`BLOCK_ENCRYPT_PATH.cipher_data_out, 2), clk, !rst_n) - `define CTR_DRBG_UPD tb.dut.u_csrng_core.u_csrng_ctr_drbg_upd - `define CTR_DRBG_UPD_FIFO `CTR_DRBG_UPD.u_prim_fifo_sync_bencack.gen_singleton_fifo - `ASSERT(CsrngSecCmAesCipherDataRegLocalEscUpd, - $rose(`CTR_DRBG_UPD_FIFO.full_q) && `BLOCK_ENCRYPT_PATH.cipher_sm_err_o |=> - $past(`CTR_DRBG_UPD_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 78a2335a1d58c..aab7502d4a0a2 100644 --- a/hw/ip/csrng/rtl/csrng.sv +++ b/hw/ip/csrng/rtl/csrng.sv @@ -187,6 +187,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, alert_tx_o[1]) diff --git a/hw/ip/csrng/rtl/csrng_block_encrypt.sv b/hw/ip/csrng/rtl/csrng_block_encrypt.sv index 6d97461184569..3818ea96a8636 100644 --- a/hw/ip/csrng/rtl/csrng_block_encrypt.sv +++ b/hw/ip/csrng/rtl/csrng_block_encrypt.sv @@ -116,7 +116,6 @@ module csrng_block_encrypt import csrng_pkg::*; #( .state_o (state_done) ); - //-------------------------------------------- // cmd / id tracking fifo //-------------------------------------------- @@ -144,8 +143,6 @@ module csrng_block_encrypt import csrng_pkg::*; #( assign sfifo_cmdid_wdata = {req_data_i.inst_id, req_data_i.cmd}; - assign req_rdy_o = (cipher_in_ready == aes_pkg::SP2V_HIGH); - assign rsp_data_o = '{ inst_id: sfifo_cmdid_rdata[CmdWidth +: InstIdWidth], cmd: sfifo_cmdid_rdata[0 +: CmdWidth], @@ -153,9 +150,15 @@ module csrng_block_encrypt import csrng_pkg::*; #( v: cipher_data_out }; - assign rsp_vld_o = rsp_rdy_i && (cipher_out_valid == aes_pkg::SP2V_HIGH); + // The cipher determines whether the response is ready for consumption + assign rsp_vld_o = (cipher_out_valid == aes_pkg::SP2V_HIGH); + + // Type conversion for AES compatibility + 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; - assign sfifo_cmdid_rrdy = rsp_vld_o; + + // 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), diff --git a/hw/ip/csrng/rtl/csrng_core.sv b/hw/ip/csrng/rtl/csrng_core.sv index cf6fb2375140f..8c2611e69d728 100644 --- a/hw/ip/csrng/rtl/csrng_core.sv +++ b/hw/ip/csrng/rtl/csrng_core.sv @@ -85,11 +85,7 @@ module csrng_core import csrng_pkg::*; #( logic acmd_mop; logic acmd_eop; - logic cmd_blk_select; - logic gen_blk_select; - logic state_db_wr_vld; - logic state_db_wr_rdy; csrng_core_data_t state_db_wr_data; csrng_cmd_sts_e state_db_wr_sts; csrng_state_t state_db_rd_data; @@ -112,7 +108,6 @@ module csrng_core import csrng_pkg::*; #( logic ctr_drbg_cmd_rsp_rdy; csrng_core_data_t ctr_drbg_cmd_rsp_data; logic ctr_drbg_cmd_rsp_glast; - logic ctr_drbg_cmd_rsp_wr; logic ctr_drbg_cmd_req_vld; logic ctr_drbg_cmd_req_rdy; @@ -135,12 +130,6 @@ module csrng_core import csrng_pkg::*; #( logic main_sm_cmd_vld; logic clr_adata_packer; - logic ctr_drbg_cmd_sfifo_rcstage_err_sum; - logic [2:0] ctr_drbg_cmd_sfifo_rcstage_err; - logic ctr_drbg_cmd_sfifo_keyvrc_err_sum; - logic [2:0] ctr_drbg_cmd_sfifo_keyvrc_err; - logic ctr_drbg_upd_sfifo_bencack_err_sum; - logic [2:0] ctr_drbg_upd_sfifo_bencack_err; 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; @@ -164,6 +153,8 @@ module csrng_core import csrng_pkg::*; #( 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; @@ -296,7 +287,6 @@ module csrng_core import csrng_pkg::*; #( 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 statedb_wr_select_q, statedb_wr_select_d; logic genbits_stage_fips_sw_q, genbits_stage_fips_sw_d; logic [CmdWidth-1:0] cmd_req_ccmd_dly_q, cmd_req_ccmd_dly_d; logic cs_aes_halt_q, cs_aes_halt_d; @@ -315,7 +305,6 @@ module csrng_core import csrng_pkg::*; #( gen_last_q <= '0; flag0_q <= prim_mubi_pkg::MuBi4False; cmd_arb_idx_q <= '0; - statedb_wr_select_q <= '0; genbits_stage_fips_sw_q <= '0; cmd_req_ccmd_dly_q <= '0; cs_aes_halt_q <= '0; @@ -332,7 +321,6 @@ module csrng_core import csrng_pkg::*; #( gen_last_q <= gen_last_d; flag0_q <= flag0_d; cmd_arb_idx_q <= cmd_arb_idx_d; - statedb_wr_select_q <= statedb_wr_select_d; genbits_stage_fips_sw_q <= genbits_stage_fips_sw_d; cmd_req_ccmd_dly_q <= cmd_req_ccmd_dly_d; cs_aes_halt_q <= cs_aes_halt_d; @@ -418,6 +406,7 @@ module csrng_core import csrng_pkg::*; #( 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 || @@ -428,9 +417,6 @@ module csrng_core import csrng_pkg::*; #( assign event_cs_fatal_err = (cs_enable_fo[1] && ( (|cmd_stage_sfifo_cmd_err_sum) || (|cmd_stage_sfifo_genbits_err_sum) || - ctr_drbg_cmd_sfifo_rcstage_err_sum || - ctr_drbg_cmd_sfifo_keyvrc_err_sum || - ctr_drbg_upd_sfifo_bencack_err_sum || ctr_drbg_upd_sfifo_final_err_sum || ctr_drbg_gen_sfifo_gbencack_err_sum || ctr_drbg_gen_sfifo_grcstage_err_sum || @@ -446,12 +432,6 @@ module csrng_core import csrng_pkg::*; #( fatal_loc_events; // set fifo errors that are single instances of source - assign ctr_drbg_cmd_sfifo_rcstage_err_sum = (|ctr_drbg_cmd_sfifo_rcstage_err) || - err_code_test_bit[3]; - assign ctr_drbg_cmd_sfifo_keyvrc_err_sum = (|ctr_drbg_cmd_sfifo_keyvrc_err) || - err_code_test_bit[4]; - assign ctr_drbg_upd_sfifo_bencack_err_sum = (|ctr_drbg_upd_sfifo_bencack_err) || - err_code_test_bit[7]; 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) || @@ -466,18 +446,13 @@ module csrng_core import csrng_pkg::*; #( err_code_test_bit[14]; assign block_encrypt_sfifo_cmdid_err_sum = (|block_encrypt_sfifo_cmdid_err) || err_code_test_bit[15]; - 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 block_encrypt_sm_err_sum = block_encrypt_sm_err || - err_code_test_bit[25]; + 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 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 = @@ -488,9 +463,6 @@ module csrng_core import csrng_pkg::*; #( ctr_drbg_gen_sfifo_grcstage_err[2] || ctr_drbg_gen_sfifo_gbencack_err[2] || ctr_drbg_upd_sfifo_final_err[2] || - ctr_drbg_upd_sfifo_bencack_err[2] || - ctr_drbg_cmd_sfifo_keyvrc_err[2] || - ctr_drbg_cmd_sfifo_rcstage_err[2] || (|cmd_stage_sfifo_genbits_err_wr) || (|cmd_stage_sfifo_cmd_err_wr) || err_code_test_bit[28]; @@ -502,9 +474,6 @@ module csrng_core import csrng_pkg::*; #( ctr_drbg_gen_sfifo_grcstage_err[1] || ctr_drbg_gen_sfifo_gbencack_err[1] || ctr_drbg_upd_sfifo_final_err[1] || - ctr_drbg_upd_sfifo_bencack_err[1] || - ctr_drbg_cmd_sfifo_keyvrc_err[1] || - ctr_drbg_cmd_sfifo_rcstage_err[1] || (|cmd_stage_sfifo_genbits_err_rd) || (|cmd_stage_sfifo_cmd_err_rd) || err_code_test_bit[29]; @@ -516,9 +485,6 @@ module csrng_core import csrng_pkg::*; #( ctr_drbg_gen_sfifo_grcstage_err[0] || ctr_drbg_gen_sfifo_gbencack_err[0] || ctr_drbg_upd_sfifo_final_err[0] || - ctr_drbg_upd_sfifo_bencack_err[0] || - ctr_drbg_cmd_sfifo_keyvrc_err[0] || - ctr_drbg_cmd_sfifo_rcstage_err[0] || (|cmd_stage_sfifo_genbits_err_st) || (|cmd_stage_sfifo_cmd_err_st) || err_code_test_bit[30]; @@ -532,18 +498,6 @@ module csrng_core import csrng_pkg::*; #( assign hw2reg.err_code.sfifo_genbits_err.de = cs_enable_fo[3] && (|cmd_stage_sfifo_genbits_err_sum); - assign hw2reg.err_code.sfifo_rcstage_err.d = 1'b1; - assign hw2reg.err_code.sfifo_rcstage_err.de = cs_enable_fo[5] && - ctr_drbg_cmd_sfifo_rcstage_err_sum; - - assign hw2reg.err_code.sfifo_keyvrc_err.d = 1'b1; - assign hw2reg.err_code.sfifo_keyvrc_err.de = cs_enable_fo[6] && - ctr_drbg_cmd_sfifo_keyvrc_err_sum; - - assign hw2reg.err_code.sfifo_bencack_err.d = 1'b1; - assign hw2reg.err_code.sfifo_bencack_err.de = cs_enable_fo[9] && - ctr_drbg_upd_sfifo_bencack_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; @@ -580,6 +534,10 @@ module csrng_core import csrng_pkg::*; #( 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; @@ -786,10 +744,9 @@ module csrng_core import csrng_pkg::*; #( // 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_rdy && (state_db_wr_data.inst_id == ai) ? - (state_db_wr_data.rs_ctr >= reg2hw.reseed_interval.q) : - reseed_cnt_reached_q[ai]; + 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) : + reseed_cnt_reached_q[ai]; end : gen_cmd_stage @@ -1092,7 +1049,6 @@ module csrng_core import csrng_pkg::*; #( // of each csrng instance. The state // is updated after each command. - assign ctr_drbg_cmd_rsp_wr = ctr_drbg_cmd_rsp_vld && (ctr_drbg_cmd_rsp_data.cmd != GEN); assign state_db_reg_read_en = cs_enable_fo[40] && read_int_state && otp_sw_app_read_en[1]; csrng_state_db u_csrng_state_db ( @@ -1104,7 +1060,6 @@ module csrng_core import csrng_pkg::*; #( .rd_state_o (state_db_rd_data), .wr_vld_i (state_db_wr_vld), - .wr_rdy_o (state_db_wr_rdy), .wr_data_i (state_db_wr_data), .wr_status_i(state_db_wr_sts), @@ -1123,19 +1078,22 @@ module csrng_core import csrng_pkg::*; #( .reseed_counter_o(reseed_counter) ); - assign statedb_wr_select_d = (!cs_enable_fo[42]) ? 1'b0 : !statedb_wr_select_q; + logic cmd_rsp_to_state_db; - assign cmd_blk_select = !statedb_wr_select_q; - assign gen_blk_select = statedb_wr_select_q; + // 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); - // return to requesting block - assign ctr_drbg_cmd_rsp_rdy = (cmd_blk_select && state_db_wr_rdy) && ctr_drbg_gen_req_rdy; - assign ctr_drbg_gen_rsp_rdy = gen_blk_select && state_db_wr_rdy; + 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; - // Mux either generate or command stage result to state db - assign state_db_wr_vld = gen_blk_select ? ctr_drbg_gen_rsp_vld : ctr_drbg_cmd_rsp_wr; - assign state_db_wr_data = gen_blk_select ? ctr_drbg_gen_rsp_data : ctr_drbg_cmd_rsp_data; - assign state_db_wr_sts = gen_blk_select ? ctr_drbg_gen_rsp_sts : CMD_STS_SUCCESS; + // 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 @@ -1236,8 +1194,7 @@ module csrng_core import csrng_pkg::*; #( .update_rsp_rdy_o (cmd_upd_rsp_rdy), .update_rsp_data_i(upd_rsp_data), - .fifo_rcstage_err_o(ctr_drbg_cmd_sfifo_rcstage_err), - .fifo_keyvrc_err_o (ctr_drbg_cmd_sfifo_keyvrc_err) + .sm_err_o (drbg_cmd_sm_err) ); //------------------------------------- @@ -1275,7 +1232,6 @@ module csrng_core import csrng_pkg::*; #( .block_encrypt_rsp_data_i(block_encrypt_rsp_data), .ctr_err_o (ctr_drbg_upd_v_ctr_err), - .fifo_bencack_err_o (ctr_drbg_upd_sfifo_bencack_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) @@ -1407,8 +1363,6 @@ module csrng_core import csrng_pkg::*; #( // of the sequence is done by the // csrng_ctr_drbg_cmd block. - assign ctr_drbg_gen_req_vld = ctr_drbg_cmd_rsp_vld && (ctr_drbg_cmd_rsp_data.cmd == GEN); - csrng_ctr_drbg_gen u_csrng_ctr_drbg_gen ( .clk_i (clk_i), .rst_ni (rst_ni), @@ -1486,10 +1440,8 @@ 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[27:26]) || - err_code_test_bit[8] || (|err_code_test_bit[6:5]) || - err_code_test_bit[2]; - assign unused_enable_fo = cs_enable_fo[10] || (|cs_enable_fo[8:7]) || cs_enable_fo[4]; + assign unused_err_code_test_bit = (|err_code_test_bit[19:16]) || (|err_code_test_bit[8:2]); + assign unused_enable_fo = cs_enable_fo[42] || (|cs_enable_fo[9: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; @@ -1531,6 +1483,10 @@ module csrng_core import csrng_pkg::*; #( `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)) `endif endmodule // csrng_core diff --git a/hw/ip/csrng/rtl/csrng_ctr_drbg_cmd.sv b/hw/ip/csrng/rtl/csrng_ctr_drbg_cmd.sv index 5ab21ab4177fe..24b77915ec532 100644 --- a/hw/ip/csrng/rtl/csrng_ctr_drbg_cmd.sv +++ b/hw/ip/csrng/rtl/csrng_ctr_drbg_cmd.sv @@ -41,62 +41,54 @@ module csrng_ctr_drbg_cmd import csrng_pkg::*; ( input csrng_upd_data_t update_rsp_data_i, // Error status outputs - output logic [2:0] fifo_rcstage_err_o, - output logic [2:0] fifo_keyvrc_err_o + output logic sm_err_o ); - localparam int RCStageFifoWidth = CoreDataWidth + 1; - localparam int KeyVRCFifoWidth = CoreDataWidth + 1; - // signals csrng_core_data_t req_data; - - csrng_core_data_t rcstage_data; - logic rcstage_glast; - - csrng_core_data_t keyvrc_data; - logic keyvrc_glast; + 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 prep_gen_adata_null; - - // rcstage fifo - logic sfifo_rcstage_wvld; - logic sfifo_rcstage_wrdy; - logic [RCStageFifoWidth-1:0] sfifo_rcstage_wdata; - logic sfifo_rcstage_rvld; - logic sfifo_rcstage_rrdy; - logic [RCStageFifoWidth-1:0] sfifo_rcstage_rdata; - - // keyvrc fifo - logic sfifo_keyvrc_wvld; - logic sfifo_keyvrc_wrdy; - logic [KeyVRCFifoWidth-1:0] sfifo_keyvrc_wdata; - logic sfifo_keyvrc_rvld; - logic sfifo_keyvrc_rrdy; - logic [KeyVRCFifoWidth-1:0] sfifo_keyvrc_rdata; - - // flops - logic gen_adata_null_q, gen_adata_null_d; - - always_ff @(posedge clk_i or negedge rst_ni) begin - if (!rst_ni) begin - gen_adata_null_q <= '0; - end else begin - gen_adata_null_q <= gen_adata_null_d; - end - end - + 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 //-------------------------------------------- - assign req_rdy_o = enable_i && sfifo_rcstage_wrdy && (update_req_rdy_i || prep_gen_adata_null); - always_comb begin req_data = req_data_i; // Insert the FIPS info from entropy source on instantiate and reseed commands. @@ -133,13 +125,7 @@ module csrng_ctr_drbg_cmd import csrng_pkg::*; ( (req_data.cmd == UPD) ? req_data.rs_ctr : '0; - assign prep_gen_adata_null = (req_data.cmd == GEN) && (req_data.pdata == '0); - - assign gen_adata_null_d = !enable_i ? 1'b0 : - ((req_vld_i && req_rdy_o) ? prep_gen_adata_null : gen_adata_null_q); - - // send to the update block - assign update_req_vld_o = req_vld_i && !prep_gen_adata_null; + // Request data for the update unit assign update_req_data_o = '{ inst_id: req_data.inst_id, cmd: req_data.cmd, @@ -148,115 +134,87 @@ module csrng_ctr_drbg_cmd import csrng_pkg::*; ( pdata: prep_seed_material }; - //-------------------------------------------- - // fifo to stage rc and command, waiting for update block to ack - //-------------------------------------------- - - csrng_core_data_t rcstage_core_data_fifo; - - prim_fifo_sync #( - .Width(RCStageFifoWidth), - .Pass(0), - .Depth(1), - .OutputZeroIfEmpty(1'b0) - ) u_prim_fifo_sync_rcstage ( - .clk_i (clk_i), - .rst_ni (rst_ni), - .clr_i (!enable_i), - .wvalid_i(sfifo_rcstage_wvld), - .wready_o(sfifo_rcstage_wrdy), - .wdata_i (sfifo_rcstage_wdata), - .rvalid_o(sfifo_rcstage_rvld), - .rready_i(sfifo_rcstage_rrdy), - .rdata_o (sfifo_rcstage_rdata), - .full_o (), - .depth_o (), - .err_o () - ); - + // Splice muxed data fields into internal data path always_comb begin - rcstage_core_data_fifo = req_data; - rcstage_core_data_fifo.key = prep_key; - rcstage_core_data_fifo.v = prep_v; - rcstage_core_data_fifo.rs_ctr = prep_rc; + 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 - assign sfifo_rcstage_wdata = {req_glast_i, - rcstage_core_data_fifo}; - - assign {rcstage_glast, - rcstage_data} = sfifo_rcstage_rdata; - - assign sfifo_rcstage_wvld = req_vld_i && req_rdy_o; - assign sfifo_rcstage_rrdy = sfifo_rcstage_rvld && (update_rsp_vld_i || gen_adata_null_q); - - assign update_rsp_rdy_o = sfifo_rcstage_rvld && sfifo_keyvrc_wrdy; - - assign fifo_rcstage_err_o = - {( sfifo_rcstage_wvld && !sfifo_rcstage_wrdy), - ( sfifo_rcstage_rrdy && !sfifo_rcstage_rvld), - (!sfifo_rcstage_wrdy && !sfifo_rcstage_rvld)}; - - //-------------------------------------------- - // final cmd block processing - //-------------------------------------------- - - prim_fifo_sync #( - .Width(KeyVRCFifoWidth), - .Pass(0), - .Depth(1), - .OutputZeroIfEmpty(1'b0) - ) u_prim_fifo_sync_keyvrc ( - .clk_i (clk_i), - .rst_ni (rst_ni), - .clr_i (!enable_i), - .wvalid_i(sfifo_keyvrc_wvld), - .wready_o(sfifo_keyvrc_wrdy), - .wdata_i (sfifo_keyvrc_wdata), - .rvalid_o(sfifo_keyvrc_rvld), - .rready_i(sfifo_keyvrc_rrdy), - .rdata_o (sfifo_keyvrc_rdata), - .full_o (), - .depth_o (), - .err_o () - ); + // 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); - assign sfifo_keyvrc_wvld = sfifo_rcstage_rrdy; + // 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 - keyvrc_data = rcstage_data; - keyvrc_glast = rcstage_glast; - if (rcstage_data.cmd == UNI) 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 (?) - keyvrc_data = '{default: '0}; - keyvrc_data.inst_id = rcstage_data.inst_id; - keyvrc_data.cmd = rcstage_data.cmd; - end else if (!gen_adata_null_q) begin + rsp_data_o = '{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 - keyvrc_data.key = update_rsp_data_i.key; - keyvrc_data.v = update_rsp_data_i.v; - keyvrc_data.inst_id = update_rsp_data_i.inst_id; - keyvrc_data.cmd = update_rsp_data_i.cmd; + 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 - assign sfifo_keyvrc_wdata = {keyvrc_glast, - keyvrc_data}; - - assign sfifo_keyvrc_rrdy = rsp_rdy_i && sfifo_keyvrc_rvld; - - // cmd response output assignments - assign {rsp_glast_o, - rsp_data_o} = sfifo_keyvrc_rdata; - - assign rsp_vld_o = sfifo_keyvrc_rrdy; - - assign fifo_keyvrc_err_o = - {( sfifo_keyvrc_wvld && !sfifo_keyvrc_wrdy), - ( sfifo_keyvrc_rrdy && !sfifo_keyvrc_rvld), - (!sfifo_keyvrc_wrdy && !sfifo_keyvrc_rvld)}; - // Unused signals logic [SeedLen-1:0] unused_upd_rsp_pdata; assign unused_upd_rsp_pdata = update_rsp_data_i.pdata; diff --git a/hw/ip/csrng/rtl/csrng_ctr_drbg_upd.sv b/hw/ip/csrng/rtl/csrng_ctr_drbg_upd.sv index 45ea1253941ca..b9fc940d9dbbd 100644 --- a/hw/ip/csrng/rtl/csrng_ctr_drbg_upd.sv +++ b/hw/ip/csrng/rtl/csrng_ctr_drbg_upd.sv @@ -41,24 +41,12 @@ module csrng_ctr_drbg_upd import csrng_pkg::*; ( // Error status outputs output logic ctr_err_o, - output logic [2:0] fifo_bencack_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 - // blk_encrypt_ack fifo - logic sfifo_bencack_wvld; - logic sfifo_bencack_wrdy; - logic [BencDataWidth-1:0] sfifo_bencack_wdata; - logic sfifo_bencack_rvld; - logic sfifo_bencack_rrdy; - logic [BencDataWidth-1:0] sfifo_bencack_rdata; - - csrng_benc_data_t benc_rsp_data_fifo; - - // key_v fifo logic sfifo_final_wvld; logic sfifo_final_wrdy; logic [BencDataWidth-1:0] sfifo_final_wdata; @@ -304,41 +292,6 @@ module csrng_ctr_drbg_upd import csrng_pkg::*; ( req_data_i.key, v_ctr_sized}; - //-------------------------------------------- - // 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 () - ); - - assign sfifo_bencack_wvld = block_encrypt_rsp_vld_i && sfifo_bencack_wrdy; - assign sfifo_bencack_wdata = block_encrypt_rsp_data_i; - assign block_encrypt_rsp_rdy_o = sfifo_bencack_wrdy; - - assign benc_rsp_data_fifo = sfifo_bencack_rdata; - - assign fifo_bencack_err_o = - {( sfifo_bencack_wvld && !sfifo_bencack_wrdy), - ( sfifo_bencack_rrdy && !sfifo_bencack_rvld), - (!sfifo_bencack_wrdy && !sfifo_bencack_rvld)}; - //-------------------------------------------- // shifting logic to receive values from block_encrypt //-------------------------------------------- @@ -351,12 +304,12 @@ module csrng_ctr_drbg_upd import csrng_pkg::*; ( concat_inst_id_d = '0; concat_ccmd_d = '0; concat_outblk_d = '0; - end else if (sfifo_bencack_rrdy) begin - concat_inst_id_d = benc_rsp_data_fifo.inst_id; - concat_ccmd_d = benc_rsp_data_fifo.cmd; + 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], - benc_rsp_data_fifo.v}; + 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}}}; @@ -386,7 +339,7 @@ module csrng_ctr_drbg_upd import csrng_pkg::*; ( outblk_state_d = outblk_state_q; concat_ctr_inc = 1'b0; concat_outblk_shift = 1'b0; - sfifo_bencack_rrdy = 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; @@ -394,18 +347,23 @@ module csrng_ctr_drbg_upd import csrng_pkg::*; ( // 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_bencack_rvld && sfifo_final_wrdy) begin + 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 if (sfifo_bencack_rvld) begin - concat_ctr_inc = 1'b1; - sfifo_bencack_rrdy = 1'b1; - outblk_state_d = Shift; + 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 @@ -473,8 +431,8 @@ module csrng_ctr_drbg_upd import csrng_pkg::*; ( (!sfifo_final_wrdy && !sfifo_final_rvld)}; // Unused signals - logic [KeyLen-1:0] unused_benc_rsp_data_fifo_key; - assign unused_benc_rsp_data_fifo_key = benc_rsp_data_fifo.key; + 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. diff --git a/hw/ip/csrng/rtl/csrng_main_sm.sv b/hw/ip/csrng/rtl/csrng_main_sm.sv index 2cf617c5f38d2..c9da418cd5978 100644 --- a/hw/ip/csrng/rtl/csrng_main_sm.sv +++ b/hw/ip/csrng/rtl/csrng_main_sm.sv @@ -95,11 +95,22 @@ module csrng_main_sm import csrng_pkg::*; ( end MainSmCmdVld: begin cmd_vld_o = 1'b1; - if (cmd_rdy_i) state_d = MainSmClrAData; + if (cmd_rdy_i) begin + if (cmd_complete_i) begin + clr_adata_packer_o = 1'b1; + state_d = MainSmIdle; + end else begin + state_d = MainSmClrAData; + end + end end MainSmClrAData: begin clr_adata_packer_o = 1'b1; - state_d = MainSmCmdCompWait; + if (cmd_complete_i) begin + state_d = MainSmIdle; + end else begin + state_d = MainSmCmdCompWait; + end end MainSmCmdCompWait: begin if (cmd_complete_i) begin diff --git a/hw/ip/csrng/rtl/csrng_reg_pkg.sv b/hw/ip/csrng/rtl/csrng_reg_pkg.sv index 626f0439f0d99..e8cc741201305 100644 --- a/hw/ip/csrng/rtl/csrng_reg_pkg.sv +++ b/hw/ip/csrng/rtl/csrng_reg_pkg.sv @@ -251,6 +251,10 @@ package csrng_reg_pkg; logic d; logic de; } fifo_write_err; + struct packed { + logic d; + logic de; + } drbg_cmd_sm_err; struct packed { logic d; logic de; @@ -307,18 +311,6 @@ package csrng_reg_pkg; logic d; logic de; } sfifo_final_err; - struct packed { - logic d; - logic de; - } sfifo_bencack_err; - struct packed { - logic d; - logic de; - } sfifo_keyvrc_err; - struct packed { - logic d; - logic de; - } sfifo_rcstage_err; struct packed { logic d; logic de; @@ -353,15 +345,15 @@ package csrng_reg_pkg; // HW -> register type typedef struct packed { - csrng_hw2reg_intr_state_reg_t intr_state; // [263:256] - csrng_hw2reg_reseed_counter_mreg_t [2:0] reseed_counter; // [255:160] - csrng_hw2reg_sw_cmd_sts_reg_t sw_cmd_sts; // [159:152] - csrng_hw2reg_genbits_vld_reg_t genbits_vld; // [151:150] - csrng_hw2reg_genbits_reg_t genbits; // [149:118] - csrng_hw2reg_int_state_val_reg_t int_state_val; // [117:86] - csrng_hw2reg_hw_exc_sts_reg_t hw_exc_sts; // [85:69] - csrng_hw2reg_recov_alert_sts_reg_t recov_alert_sts; // [68:51] - csrng_hw2reg_err_code_reg_t err_code; // [50:7] + csrng_hw2reg_intr_state_reg_t intr_state; // [259:252] + csrng_hw2reg_reseed_counter_mreg_t [2:0] reseed_counter; // [251:156] + csrng_hw2reg_sw_cmd_sts_reg_t sw_cmd_sts; // [155:148] + csrng_hw2reg_genbits_vld_reg_t genbits_vld; // [147:146] + csrng_hw2reg_genbits_reg_t genbits; // [145:114] + csrng_hw2reg_int_state_val_reg_t int_state_val; // [113:82] + csrng_hw2reg_hw_exc_sts_reg_t hw_exc_sts; // [81:65] + csrng_hw2reg_recov_alert_sts_reg_t recov_alert_sts; // [64:47] + csrng_hw2reg_err_code_reg_t err_code; // [46: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 b431701e1bac7..027dbdfc7df6a 100644 --- a/hw/ip/csrng/rtl/csrng_reg_top.sv +++ b/hw/ip/csrng/rtl/csrng_reg_top.sv @@ -216,9 +216,6 @@ 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_rcstage_err_qs; - logic err_code_sfifo_keyvrc_err_qs; - logic err_code_sfifo_bencack_err_qs; logic err_code_sfifo_final_err_qs; logic err_code_sfifo_gbencack_err_qs; logic err_code_sfifo_grcstage_err_qs; @@ -233,6 +230,7 @@ module csrng_reg_top ( logic err_code_drbg_updob_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_fifo_write_err_qs; logic err_code_fifo_read_err_qs; logic err_code_fifo_state_err_qs; @@ -1446,87 +1444,6 @@ module csrng_reg_top ( .qs (err_code_sfifo_genbits_err_qs) ); - // F[sfifo_rcstage_err]: 3:3 - prim_subreg #( - .DW (1), - .SwAccess(prim_subreg_pkg::SwAccessRO), - .RESVAL (1'h0), - .Mubi (1'b0) - ) u_err_code_sfifo_rcstage_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_rcstage_err.de), - .d (hw2reg.err_code.sfifo_rcstage_err.d), - - // to internal hardware - .qe (), - .q (), - .ds (), - - // to register interface (read) - .qs (err_code_sfifo_rcstage_err_qs) - ); - - // F[sfifo_keyvrc_err]: 4:4 - prim_subreg #( - .DW (1), - .SwAccess(prim_subreg_pkg::SwAccessRO), - .RESVAL (1'h0), - .Mubi (1'b0) - ) u_err_code_sfifo_keyvrc_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_keyvrc_err.de), - .d (hw2reg.err_code.sfifo_keyvrc_err.d), - - // to internal hardware - .qe (), - .q (), - .ds (), - - // to register interface (read) - .qs (err_code_sfifo_keyvrc_err_qs) - ); - - // F[sfifo_bencack_err]: 7:7 - prim_subreg #( - .DW (1), - .SwAccess(prim_subreg_pkg::SwAccessRO), - .RESVAL (1'h0), - .Mubi (1'b0) - ) u_err_code_sfifo_bencack_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_bencack_err.de), - .d (hw2reg.err_code.sfifo_bencack_err.d), - - // to internal hardware - .qe (), - .q (), - .ds (), - - // to register interface (read) - .qs (err_code_sfifo_bencack_err_qs) - ); - // F[sfifo_final_err]: 9:9 prim_subreg #( .DW (1), @@ -1905,6 +1822,33 @@ module csrng_reg_top ( .qs (err_code_cmd_gen_cnt_err_qs) ); + // F[drbg_cmd_sm_err]: 27:27 + prim_subreg #( + .DW (1), + .SwAccess(prim_subreg_pkg::SwAccessRO), + .RESVAL (1'h0), + .Mubi (1'b0) + ) u_err_code_drbg_cmd_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_cmd_sm_err.de), + .d (hw2reg.err_code.drbg_cmd_sm_err.d), + + // to internal hardware + .qe (), + .q (), + .ds (), + + // to register interface (read) + .qs (err_code_drbg_cmd_sm_err_qs) + ); + // F[fifo_write_err]: 28:28 prim_subreg #( .DW (1), @@ -2356,9 +2300,6 @@ 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[3] = err_code_sfifo_rcstage_err_qs; - reg_rdata_next[4] = err_code_sfifo_keyvrc_err_qs; - reg_rdata_next[7] = err_code_sfifo_bencack_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[11] = err_code_sfifo_grcstage_err_qs; @@ -2373,6 +2314,7 @@ module csrng_reg_top ( reg_rdata_next[24] = err_code_drbg_updob_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[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 e4e077b341c1b..4b6bdba5765ba 100644 --- a/hw/ip/csrng/rtl/csrng_state_db.sv +++ b/hw/ip/csrng/rtl/csrng_state_db.sv @@ -27,7 +27,6 @@ module csrng_state_db // Write interface input logic wr_vld_i, - output logic wr_rdy_o, input csrng_core_data_t wr_data_i, input csrng_cmd_sts_e wr_status_i, @@ -167,8 +166,6 @@ module csrng_state_db assign status_val_o = status_val_q; assign status_inst_id_o = status_inst_id_q; - assign wr_rdy_o = 1'b1; - // Unused signals logic [SeedLen-1:0] unused_wdata_pdata; logic [InstIdWidth-NumAppsLg-1:0] unused_reg_rd_id, unused_rd_inst_id; diff --git a/sw/device/lib/dif/dif_csrng.c b/sw/device/lib/dif/dif_csrng.c index 7727c207a97c0..5fcc98eaf1b69 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 kDifCsrngFifoRcStage: - fifo_bit = CSRNG_ERR_CODE_SFIFO_RCSTAGE_ERR_BIT; - break; - case kDifCsrngFifoKeyVrc: - fifo_bit = CSRNG_ERR_CODE_SFIFO_KEYVRC_ERR_BIT; - break; - case kDifCsrngFifoBencAck: - fifo_bit = CSRNG_ERR_CODE_SFIFO_BENCACK_ERR_BIT; - break; case kDifCsrngFifoFinal: fifo_bit = CSRNG_ERR_CODE_SFIFO_FINAL_ERR_BIT; break; @@ -235,6 +226,9 @@ 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; diff --git a/sw/device/lib/dif/dif_csrng.h b/sw/device/lib/dif/dif_csrng.h index 53b7a361a7d8c..a420de756afe3 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, - kDifCsrngFifoRcStage, - kDifCsrngFifoKeyVrc, - kDifCsrngFifoBencAck, kDifCsrngFifoFinal, kDifCsrngFifoGBencAck, kDifCsrngFifoGrcStage, @@ -116,6 +113,10 @@ typedef enum dif_csrng_error { * Indicates an error in the main state machine. */ kDifCsrngErrorMainSm, + /** + * Indicates an error in the DRBG's command unit state machine. + */ + kDifCsrngErrorDrbgCmdSm, /** * Indicates an error in the DRBG's generator state machine. */