From 156427cd320fb18893692edb1c95f42d97179bfa Mon Sep 17 00:00:00 2001 From: Hakim Filali Date: Mon, 29 Apr 2024 15:54:59 +0000 Subject: [PATCH] [csrng/rtl] Add reseed interval status error This commit adds a new status error response, that is triggered whenever the number of generates between reseeds exceeds the reseed_interval. Signed-off-by: Hakim Filali --- hw/ip/csrng/data/csrng.hjson | 38 ++- hw/ip/csrng/doc/registers.md | 127 ++++++---- hw/ip/csrng/dv/env/csrng_env_cfg.sv | 18 +- hw/ip/csrng/dv/env/csrng_scoreboard.sv | 6 +- .../csrng/dv/env/seq_lib/csrng_alert_vseq.sv | 217 +++++++++++++++++- hw/ip/csrng/dv/env/seq_lib/csrng_base_vseq.sv | 9 + hw/ip/csrng/rtl/csrng_cmd_stage.sv | 40 +++- hw/ip/csrng/rtl/csrng_core.sv | 196 ++++++++++------ hw/ip/csrng/rtl/csrng_ctr_drbg_cmd.sv | 4 +- hw/ip/csrng/rtl/csrng_main_sm.sv | 48 ++-- hw/ip/csrng/rtl/csrng_pkg.sv | 3 +- hw/ip/csrng/rtl/csrng_reg_pkg.sv | 85 ++++--- hw/ip/csrng/rtl/csrng_reg_top.sv | 201 +++++++++++----- hw/ip/edn/doc/registers.md | 127 ++++++---- 14 files changed, 809 insertions(+), 310 deletions(-) diff --git a/hw/ip/csrng/data/csrng.hjson b/hw/ip/csrng/data/csrng.hjson index 829cbd3679cc2c..fab156115e9568 100644 --- a/hw/ip/csrng/data/csrng.hjson +++ b/hw/ip/csrng/data/csrng.hjson @@ -317,6 +317,29 @@ } ] }, + { name: "RESEED_INTERVAL", + desc: "CSRNG maximum number of generate requests allowed between reseeds register", + swaccess: "rw", + hwaccess: "hro", + hwqe: "true", + fields: [ + { bits: "31:0", + name: "RESEED_INTERVAL", + desc: ''' + Setting this field will set the number of generate requests that can be + made to CSRNG before a reseed request needs to be made. + This register supports a maximum of 2^32 requests between reseeds. + This register will be compared to a counter, which counts the number of + generate commands between reseed or instantiate commands. + If the counter reaches the value of this register the violating command + will be acknowledged with a status error. + If the violating command was issued by a HW instance, an interrupt will + be triggered. + ''' + resval: 0xffff_ffff + } + ] + }, { name: "SW_CMD_STS", desc: "Application interface command status register", @@ -364,6 +387,8 @@ 0x3: This error indicates that the last command was issued out of sequence. This happens when a command other than instantiate was issued without sending an instantiate command first. This can also happen when an uninstantiate command is sent without instantiating first. + 0x5: This error indicates that the number of generate commands between reseeds exceeded the maximum number allowed. + This happens only for generate commands. ''' resval: "0" } @@ -522,7 +547,7 @@ ''' } { bits: "13", - name: "CS_MAIN_SM_ALERT", + name: "CS_MAIN_SM_INVALID_CMD_ALERT", desc: ''' This bit is set when an unsupported/illegal CSRNG command is received by the main state machine. @@ -531,7 +556,7 @@ ''' } { bits: "14", - name: "CS_MAIN_SM_INVALID_CMD_SEQ", + name: "CS_MAIN_SM_INVALID_CMD_SEQ_ALERT", desc: ''' This bit is set when an out of order command is received by the main state machine. This happens when an instantiate command is sent for a state that was already @@ -541,6 +566,15 @@ Writing a zero resets this status bit. ''' } + { bits: "15", + name: "CS_MAIN_SM_RESEED_CNT_ALERT", + desc: ''' + This bit is set when the maximum number of generate requests between reseeds is + exceeded. + The invalid generate command is ignored and CSRNG continues to operate. + Writing a zero resets this status bit. + ''' + } ] }, { diff --git a/hw/ip/csrng/doc/registers.md b/hw/ip/csrng/doc/registers.md index 4cbee03f72ee03..64b34f3109e431 100644 --- a/hw/ip/csrng/doc/registers.md +++ b/hw/ip/csrng/doc/registers.md @@ -3,25 +3,26 @@ ## Summary -| Name | Offset | Length | Description | -|:--------------------------------------------|:---------|---------:|:-------------------------------------------------------| -| csrng.[`INTR_STATE`](#intr_state) | 0x0 | 4 | Interrupt State Register | -| csrng.[`INTR_ENABLE`](#intr_enable) | 0x4 | 4 | Interrupt Enable Register | -| csrng.[`INTR_TEST`](#intr_test) | 0x8 | 4 | Interrupt Test Register | -| csrng.[`ALERT_TEST`](#alert_test) | 0xc | 4 | Alert Test Register | -| csrng.[`REGWEN`](#regwen) | 0x10 | 4 | Register write enable for all control registers | -| csrng.[`CTRL`](#ctrl) | 0x14 | 4 | Control register | -| csrng.[`CMD_REQ`](#cmd_req) | 0x18 | 4 | Command request register | -| csrng.[`SW_CMD_STS`](#sw_cmd_sts) | 0x1c | 4 | Application interface command status register | -| csrng.[`GENBITS_VLD`](#genbits_vld) | 0x20 | 4 | Generate bits returned valid register | -| csrng.[`GENBITS`](#genbits) | 0x24 | 4 | Generate bits returned register | -| csrng.[`INT_STATE_NUM`](#int_state_num) | 0x28 | 4 | Internal state number register | -| csrng.[`INT_STATE_VAL`](#int_state_val) | 0x2c | 4 | Internal state read access register | -| csrng.[`HW_EXC_STS`](#hw_exc_sts) | 0x30 | 4 | Hardware instance exception status register | -| csrng.[`RECOV_ALERT_STS`](#recov_alert_sts) | 0x34 | 4 | Recoverable alert status register | -| csrng.[`ERR_CODE`](#err_code) | 0x38 | 4 | Hardware detection of error conditions status register | -| csrng.[`ERR_CODE_TEST`](#err_code_test) | 0x3c | 4 | Test error conditions register | -| csrng.[`MAIN_SM_STATE`](#main_sm_state) | 0x40 | 4 | Main state machine state debug register | +| Name | Offset | Length | Description | +|:--------------------------------------------|:---------|---------:|:---------------------------------------------------------------------------| +| csrng.[`INTR_STATE`](#intr_state) | 0x0 | 4 | Interrupt State Register | +| csrng.[`INTR_ENABLE`](#intr_enable) | 0x4 | 4 | Interrupt Enable Register | +| csrng.[`INTR_TEST`](#intr_test) | 0x8 | 4 | Interrupt Test Register | +| csrng.[`ALERT_TEST`](#alert_test) | 0xc | 4 | Alert Test Register | +| csrng.[`REGWEN`](#regwen) | 0x10 | 4 | Register write enable for all control registers | +| csrng.[`CTRL`](#ctrl) | 0x14 | 4 | Control register | +| csrng.[`CMD_REQ`](#cmd_req) | 0x18 | 4 | Command request register | +| csrng.[`RESEED_INTERVAL`](#reseed_interval) | 0x1c | 4 | CSRNG maximum number of generate requests allowed between reseeds register | +| csrng.[`SW_CMD_STS`](#sw_cmd_sts) | 0x20 | 4 | Application interface command status register | +| csrng.[`GENBITS_VLD`](#genbits_vld) | 0x24 | 4 | Generate bits returned valid register | +| csrng.[`GENBITS`](#genbits) | 0x28 | 4 | Generate bits returned register | +| csrng.[`INT_STATE_NUM`](#int_state_num) | 0x2c | 4 | Internal state number register | +| csrng.[`INT_STATE_VAL`](#int_state_val) | 0x30 | 4 | Internal state read access register | +| csrng.[`HW_EXC_STS`](#hw_exc_sts) | 0x34 | 4 | Hardware instance exception status register | +| csrng.[`RECOV_ALERT_STS`](#recov_alert_sts) | 0x38 | 4 | Recoverable alert status register | +| csrng.[`ERR_CODE`](#err_code) | 0x3c | 4 | Hardware detection of error conditions status register | +| csrng.[`ERR_CODE_TEST`](#err_code_test) | 0x40 | 4 | Test error conditions register | +| csrng.[`MAIN_SM_STATE`](#main_sm_state) | 0x44 | 4 | Main state machine state debug register | ## INTR_STATE Interrupt State Register @@ -154,9 +155,36 @@ Command request register |:------:|:------:|:-------:|:--------|:------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| | 31:0 | wo | 0x0 | CMD_REQ | Writing this request with defined CSRNG commands will initiate all possible CSRNG actions. The application interface must wait for the "ack" to return before issuing new commands. | +## RESEED_INTERVAL +CSRNG maximum number of generate requests allowed between reseeds register +- Offset: `0x1c` +- Reset default: `0xffffffff` +- Reset mask: `0xffffffff` + +### Fields + +```wavejson +{"reg": [{"name": "RESEED_INTERVAL", "bits": 32, "attr": ["rw"], "rotate": 0}], "config": {"lanes": 1, "fontsize": 10, "vspace": 80}} +``` + +| Bits | Type | Reset | Name | +|:------:|:------:|:----------:|:-----------------------------------------------------| +| 31:0 | rw | 0xffffffff | [RESEED_INTERVAL](#reseed_interval--reseed_interval) | + +### RESEED_INTERVAL . RESEED_INTERVAL +Setting this field will set the number of generate requests that can be +made to CSRNG before a reseed request needs to be made. +This register supports a maximum of 2^32 requests between reseeds. +This register will be compared to a counter, which counts the number of +generate commands between reseed or instantiate commands. +If the counter reaches the value of this register the violating command +will be acknowledged with a status error. +If the violating command was issued by a HW instance, an interrupt will +be triggered. + ## SW_CMD_STS Application interface command status register -- Offset: `0x1c` +- Offset: `0x20` - Reset default: `0x0` - Reset mask: `0x1e` @@ -189,6 +217,8 @@ To check whether a command was succesful, wait for [`INTR_STATE.CS_CMD_REQ_DONE` 0x3: This error indicates that the last command was issued out of sequence. This happens when a command other than instantiate was issued without sending an instantiate command first. This can also happen when an uninstantiate command is sent without instantiating first. +0x5: This error indicates that the number of generate commands between reseeds exceeded the maximum number allowed. + This happens only for generate commands. ### SW_CMD_STS . CMD_ACK This one bit field indicates when a SW command has been acknowledged by the CSRNG. @@ -205,7 +235,7 @@ Before starting to write a new command to [`SW_CMD_REQ`](#sw_cmd_req), this fiel ## GENBITS_VLD Generate bits returned valid register -- Offset: `0x20` +- Offset: `0x24` - Reset default: `0x0` - Reset mask: `0x3` @@ -223,7 +253,7 @@ Generate bits returned valid register ## GENBITS Generate bits returned register -- Offset: `0x24` +- Offset: `0x28` - Reset default: `0x0` - Reset mask: `0xffffffff` @@ -249,7 +279,7 @@ Otherwise, the register reads as 0. ## INT_STATE_NUM Internal state number register -- Offset: `0x28` +- Offset: `0x2c` - Reset default: `0x0` - Reset mask: `0xf` @@ -277,7 +307,7 @@ that the [`INT_STATE_VAL`](#int_state_val) read back is accurate. ## INT_STATE_VAL Internal state read access register -- Offset: `0x2c` +- Offset: `0x30` - Reset default: `0x0` - Reset mask: `0xffffffff` @@ -304,7 +334,7 @@ Otherwise, the register reads as 0. ## HW_EXC_STS Hardware instance exception status register -- Offset: `0x30` +- Offset: `0x34` - Reset default: `0x0` - Reset mask: `0xffff` @@ -329,29 +359,36 @@ resets the status bits. ## RECOV_ALERT_STS Recoverable alert status register -- Offset: `0x34` +- Offset: `0x38` - Reset default: `0x0` -- Reset mask: `0x700f` +- Reset mask: `0xf00f` ### Fields ```wavejson -{"reg": [{"name": "ENABLE_FIELD_ALERT", "bits": 1, "attr": ["rw0c"], "rotate": -90}, {"name": "SW_APP_ENABLE_FIELD_ALERT", "bits": 1, "attr": ["rw0c"], "rotate": -90}, {"name": "READ_INT_STATE_FIELD_ALERT", "bits": 1, "attr": ["rw0c"], "rotate": -90}, {"name": "ACMD_FLAG0_FIELD_ALERT", "bits": 1, "attr": ["rw0c"], "rotate": -90}, {"bits": 8}, {"name": "CS_BUS_CMP_ALERT", "bits": 1, "attr": ["rw0c"], "rotate": -90}, {"name": "CS_MAIN_SM_ALERT", "bits": 1, "attr": ["rw0c"], "rotate": -90}, {"name": "CS_MAIN_SM_INVALID_CMD_SEQ", "bits": 1, "attr": ["rw0c"], "rotate": -90}, {"bits": 17}], "config": {"lanes": 1, "fontsize": 10, "vspace": 280}} +{"reg": [{"name": "ENABLE_FIELD_ALERT", "bits": 1, "attr": ["rw0c"], "rotate": -90}, {"name": "SW_APP_ENABLE_FIELD_ALERT", "bits": 1, "attr": ["rw0c"], "rotate": -90}, {"name": "READ_INT_STATE_FIELD_ALERT", "bits": 1, "attr": ["rw0c"], "rotate": -90}, {"name": "ACMD_FLAG0_FIELD_ALERT", "bits": 1, "attr": ["rw0c"], "rotate": -90}, {"bits": 8}, {"name": "CS_BUS_CMP_ALERT", "bits": 1, "attr": ["rw0c"], "rotate": -90}, {"name": "CS_MAIN_SM_INVALID_CMD_ALERT", "bits": 1, "attr": ["rw0c"], "rotate": -90}, {"name": "CS_MAIN_SM_INVALID_CMD_SEQ_ALERT", "bits": 1, "attr": ["rw0c"], "rotate": -90}, {"name": "CS_MAIN_SM_RESEED_CNT_ALERT", "bits": 1, "attr": ["rw0c"], "rotate": -90}, {"bits": 16}], "config": {"lanes": 1, "fontsize": 10, "vspace": 340}} ``` -| Bits | Type | Reset | Name | -|:------:|:------:|:-------:|:---------------------------------------------------------------------------| -| 31:15 | | | Reserved | -| 14 | rw0c | 0x0 | [CS_MAIN_SM_INVALID_CMD_SEQ](#recov_alert_sts--cs_main_sm_invalid_cmd_seq) | -| 13 | rw0c | 0x0 | [CS_MAIN_SM_ALERT](#recov_alert_sts--cs_main_sm_alert) | -| 12 | rw0c | 0x0 | [CS_BUS_CMP_ALERT](#recov_alert_sts--cs_bus_cmp_alert) | -| 11:4 | | | Reserved | -| 3 | rw0c | 0x0 | [ACMD_FLAG0_FIELD_ALERT](#recov_alert_sts--acmd_flag0_field_alert) | -| 2 | rw0c | 0x0 | [READ_INT_STATE_FIELD_ALERT](#recov_alert_sts--read_int_state_field_alert) | -| 1 | rw0c | 0x0 | [SW_APP_ENABLE_FIELD_ALERT](#recov_alert_sts--sw_app_enable_field_alert) | -| 0 | rw0c | 0x0 | [ENABLE_FIELD_ALERT](#recov_alert_sts--enable_field_alert) | - -### RECOV_ALERT_STS . CS_MAIN_SM_INVALID_CMD_SEQ +| Bits | Type | Reset | Name | +|:------:|:------:|:-------:|:---------------------------------------------------------------------------------------| +| 31:16 | | | Reserved | +| 15 | rw0c | 0x0 | [CS_MAIN_SM_RESEED_CNT_ALERT](#recov_alert_sts--cs_main_sm_reseed_cnt_alert) | +| 14 | rw0c | 0x0 | [CS_MAIN_SM_INVALID_CMD_SEQ_ALERT](#recov_alert_sts--cs_main_sm_invalid_cmd_seq_alert) | +| 13 | rw0c | 0x0 | [CS_MAIN_SM_INVALID_CMD_ALERT](#recov_alert_sts--cs_main_sm_invalid_cmd_alert) | +| 12 | rw0c | 0x0 | [CS_BUS_CMP_ALERT](#recov_alert_sts--cs_bus_cmp_alert) | +| 11:4 | | | Reserved | +| 3 | rw0c | 0x0 | [ACMD_FLAG0_FIELD_ALERT](#recov_alert_sts--acmd_flag0_field_alert) | +| 2 | rw0c | 0x0 | [READ_INT_STATE_FIELD_ALERT](#recov_alert_sts--read_int_state_field_alert) | +| 1 | rw0c | 0x0 | [SW_APP_ENABLE_FIELD_ALERT](#recov_alert_sts--sw_app_enable_field_alert) | +| 0 | rw0c | 0x0 | [ENABLE_FIELD_ALERT](#recov_alert_sts--enable_field_alert) | + +### RECOV_ALERT_STS . CS_MAIN_SM_RESEED_CNT_ALERT +This bit is set when the maximum number of generate requests between reseeds is +exceeded. +The invalid generate command is ignored and CSRNG continues to operate. +Writing a zero resets this status bit. + +### RECOV_ALERT_STS . CS_MAIN_SM_INVALID_CMD_SEQ_ALERT This bit is set when an out of order command is received by the main state machine. This happens when an instantiate command is sent for a state that was already instantiated or when any command other than instantiate is sent for a state that @@ -359,7 +396,7 @@ wasn't instantiated yet. The invalid command is ignored and CSRNG continues to operate. Writing a zero resets this status bit. -### RECOV_ALERT_STS . CS_MAIN_SM_ALERT +### RECOV_ALERT_STS . CS_MAIN_SM_INVALID_CMD_ALERT This bit is set when an unsupported/illegal CSRNG command is received by the main state machine. The invalid command is ignored and CSRNG continues to operate. @@ -392,7 +429,7 @@ Writing a zero resets this status bit. ## ERR_CODE Hardware detection of error conditions status register -- Offset: `0x38` +- Offset: `0x3c` - Reset default: `0x0` - Reset mask: `0x77f0ffff` @@ -593,7 +630,7 @@ This bit will stay set until the next reset. ## ERR_CODE_TEST Test error conditions register -- Offset: `0x3c` +- Offset: `0x40` - Reset default: `0x0` - Reset mask: `0x1f` - Register enable: [`REGWEN`](#regwen) @@ -619,7 +656,7 @@ an interrupt or an alert. ## MAIN_SM_STATE Main state machine state debug register -- Offset: `0x40` +- Offset: `0x44` - Reset default: `0x4e` - Reset mask: `0xff` diff --git a/hw/ip/csrng/dv/env/csrng_env_cfg.sv b/hw/ip/csrng/dv/env/csrng_env_cfg.sv index 3cfb4cb78f1563..dd3995ec6f648b 100644 --- a/hw/ip/csrng/dv/env/csrng_env_cfg.sv +++ b/hw/ip/csrng/dv/env/csrng_env_cfg.sv @@ -61,14 +61,20 @@ class csrng_env_cfg extends cip_base_env_cfg #(.RAL_T(csrng_reg_block)); int NApps = NHwApps + 1; int Sp2VWidth = 3; - rand uint which_app_err_alert; - constraint which_app_err_alert_c { which_app_err_alert inside {[0:NApps-1]};} + rand uint which_app_err_alert; + constraint which_app_err_alert_c { which_app_err_alert inside {[0:NApps-1]};} - rand uint which_hw_inst_exc; - constraint which_hw_inst_exc_c { which_hw_inst_exc inside {[0:NHwApps-1]};} + rand acmd_e which_cmd_alert; + constraint which_cmd_alert_c { which_cmd_alert inside {INS, GEN, RES};} - rand uint which_sp2v; - constraint which_sp2v_c { which_sp2v inside {[0:Sp2VWidth-1]};} + rand uint max_reseed_count; + constraint max_reseed_count_c { max_reseed_count inside {[0:100]};} + + rand uint which_hw_inst_exc; + constraint which_hw_inst_exc_c { which_hw_inst_exc inside {[0:NHwApps-1]};} + + rand uint which_sp2v; + constraint which_sp2v_c { which_sp2v inside {[0:Sp2VWidth-1]};} constraint otp_en_cs_sw_app_read_c { `DV_MUBI8_DIST(otp_en_cs_sw_app_read, diff --git a/hw/ip/csrng/dv/env/csrng_scoreboard.sv b/hw/ip/csrng/dv/env/csrng_scoreboard.sv index c48b038eab993d..ee9ce06f129158 100644 --- a/hw/ip/csrng/dv/env/csrng_scoreboard.sv +++ b/hw/ip/csrng/dv/env/csrng_scoreboard.sv @@ -266,6 +266,8 @@ class csrng_scoreboard extends cip_base_scoreboard #( end end end + "reseed_interval": begin + end "sw_cmd_sts": begin do_read_check = 1'b0; end @@ -447,7 +449,7 @@ class csrng_scoreboard extends cip_base_scoreboard #( cfg.key[app] = 'h0; cfg.v[app] = 'h0; ctr_drbg_update(app, seed_material); - cfg.reseed_counter[app] = 1'b1; + cfg.reseed_counter[app] = 1'b0; cfg.compliance[app] = fips; cfg.status[app] = 1'b1; cov_vif.cg_csrng_state_db_sample(cfg.compliance[app], compliance_previous, app); @@ -464,7 +466,7 @@ class csrng_scoreboard extends cip_base_scoreboard #( `uvm_info(`gfn, $sformatf("Reseed of app %0d", app), UVM_MEDIUM) seed_material = entropy_input ^ additional_input; ctr_drbg_update(app, seed_material); - cfg.reseed_counter[app] = 1'b1; + cfg.reseed_counter[app] = 1'b0; cfg.compliance[app] = fips; cov_vif.cg_csrng_state_db_sample(cfg.compliance[app], compliance_previous, app); endfunction 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 d8803b80364544..e8fa5ef530294d 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 @@ -23,7 +23,7 @@ class csrng_alert_vseq extends csrng_base_vseq; uvm_reg csr; uvm_reg_field fld; - // Values for the cs_main_sm_alert test. + // Values for the cs_main_sm_invalid_cmd_alert test. `DV_CHECK_MEMBER_RANDOMIZE_WITH_FATAL(illegal_command, illegal_command inside {INV, GENB, GENU};) // For clen we just care about 0, 1 and the max value (coverage). @@ -88,6 +88,7 @@ class csrng_alert_vseq extends csrng_base_vseq; // We run some CSRNG commands and either provide an invalid encoding for the FLAG0 field of an // Instantiate or a Reseed command. // Instantiate Command. + `uvm_info(`gfn, $sformatf("qqqqqqqqqqqqqqqqqqqqqqqqqq1"), UVM_LOW) cs_item.acmd = csrng_pkg::INS; cs_item.clen = 'h0; cs_item.flags = flag0_flip_ins_cmd ? @@ -97,6 +98,7 @@ class csrng_alert_vseq extends csrng_base_vseq; send_cmd_req(cfg.which_app_err_alert, cs_item, .edn_rst_as_ack(0)); // Reseed Command. + `uvm_info(`gfn, $sformatf("qqqqqqqqqqqqqqqqqqqqqqqqqq2"), UVM_LOW) cs_item.acmd = csrng_pkg::RES; cs_item.clen = 'h0; cs_item.flags = !flag0_flip_ins_cmd ? @@ -110,6 +112,7 @@ class csrng_alert_vseq extends csrng_base_vseq; // to run another command with a valid MuBi encoded flag0 to clear the previous // value internally. Otherwise the corresponding RECOV_ALERT_STS status bit keeps getting // asserted. + `uvm_info(`gfn, $sformatf("qqqqqqqqqqqqqqqqqqqqqqqqqq3"), UVM_LOW) cs_item.acmd = csrng_pkg::RES; cs_item.clen = 'h0; cs_item.flags = MuBi4True; @@ -118,10 +121,10 @@ class csrng_alert_vseq extends csrng_base_vseq; send_cmd_req(cfg.which_app_err_alert, cs_item, .edn_rst_as_ack(0)); end - `uvm_info(`gfn, $sformatf("Waiting for alert ack to complete"), UVM_MEDIUM) + `uvm_info(`gfn, $sformatf("Waiting for alert ack to complete"), UVM_LOW) cfg.m_alert_agent_cfgs["recov_alert"].vif.wait_ack_complete(); - `uvm_info(`gfn, $sformatf("Checking RECOV_ALERT_STS register"), UVM_MEDIUM) + `uvm_info(`gfn, $sformatf("Checking RECOV_ALERT_STS register"), UVM_LOW) exp_recov_alert_sts = 32'b0; exp_recov_alert_sts[ral.recov_alert_sts.acmd_flag0_field_alert.get_lsb_pos()] = 1; csr_rd_check(.ptr(ral.recov_alert_sts), .compare_value(exp_recov_alert_sts)); @@ -205,12 +208,17 @@ class csrng_alert_vseq extends csrng_base_vseq; // Check recov_alert_sts register has cleared. csr_rd_check(.ptr(ral.recov_alert_sts), .compare_value(0)); - `uvm_info(`gfn, $sformatf("Testing cs_main_sm_alert for app %d", cfg.which_app_err_alert), UVM_MEDIUM) + ////////////////////////////////////////// + // Testing cs_main_sm_invalid_cmd_alert // + ////////////////////////////////////////// + + `uvm_info(`gfn, $sformatf("Testing cs_main_sm_invalid_cmd_alert for app %d", + cfg.which_app_err_alert), UVM_MEDIUM) - // Here we send an illegal command to CSRNG to check that cs_main_sm_alert is triggered. + // Here we send an illegal command to CSRNG to check that cs_main_sm_invalid_cmd_alert is triggered. // Sending an illegal command does not get a response from CSRNG. cs_item.acmd = illegal_command; - cs_item.clen = clen; + cs_item.clen = 'h0; cs_item.flags = get_rand_mubi4_val(.t_weight(4), .f_weight(4), .other_weight(0)); cs_item.glen = glen; send_cmd_req(cfg.which_app_err_alert, cs_item, .await_response(1'b0)); @@ -220,11 +228,205 @@ class csrng_alert_vseq extends csrng_base_vseq; `uvm_info(`gfn, $sformatf("Checking RECOV_ALERT_STS register"), UVM_MEDIUM) exp_recov_alert_sts = 32'b0; - exp_recov_alert_sts[ral.recov_alert_sts.cs_main_sm_alert.get_lsb_pos()] = 1; + exp_recov_alert_sts[ral.recov_alert_sts.cs_main_sm_invalid_cmd_alert.get_lsb_pos()] = 1; csr_spinwait(.ptr(ral.recov_alert_sts), .exp_data(exp_recov_alert_sts)); // Since we already did a backdoor check, sampling with this value is sufficient. cov_vif.cg_recov_alert_sample(.recov_alert(exp_recov_alert_sts)); + if (cfg.which_app_err_alert == SW_APP) begin + // Read the value of the SW_CMD_STS and check if it is equal to CMD_STS_INVALID_ACMD. + csr_rd_check(.ptr(ral.sw_cmd_sts.cmd_sts), .compare_value(CMD_STS_INVALID_ACMD)); + end + + `uvm_info(`gfn, $sformatf("Checking RECOV_ALERT_STS reset"), UVM_MEDIUM) + // Toggle enable to put main FSM back into legal state. + ral.ctrl.enable.set(prim_mubi_pkg::MuBi4False); + csr_update(.csr(ral.ctrl)); + cfg.clk_rst_vif.wait_clks(100); + ral.ctrl.enable.set(prim_mubi_pkg::MuBi4True); + csr_update(.csr(ral.ctrl)); + + // Clear recov_alert_sts register. + csr_wr(.ptr(ral.recov_alert_sts), .value(32'b0)); + cfg.clk_rst_vif.wait_clks(100); + // Check recov_alert_sts register has cleared. + csr_rd_check(.ptr(ral.recov_alert_sts), .compare_value(0)); + + // Read the value of the SW_CMD_STS and check if it is equal to CMD_STS_SUCCESS. + csr_rd_check(.ptr(ral.sw_cmd_sts.cmd_sts), .compare_value(CMD_STS_SUCCESS)); + + ////////////////////////////////////////////// + // Testing cs_main_sm_invalid_cmd_seq_alert // + ////////////////////////////////////////////// + + `uvm_info(`gfn, $sformatf("Testing cs_main_sm_invalid_cmd_seq_alert for app %d", + cfg.which_app_err_alert), UVM_MEDIUM) + + // Here we send an out of sequence command to CSRNG to check that + // cs_main_sm_invalid_cmd_seq_alert is triggered. + // Sending an out of sequence command does not get a successful response from CSRNG. + + // If which_cmd_alert is an INS we need to instantiate before being able to send the + // out of sequence command. + if (cfg.which_cmd_alert == INS) begin + `uvm_info(`gfn, $sformatf("aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa1"), UVM_LOW) + cs_item.acmd = csrng_pkg::INS; + cs_item.clen = 'h0; + cs_item.flags = get_rand_mubi4_val(.t_weight(4), .f_weight(4), .other_weight(0)); + cs_item.glen = 'h0; + send_cmd_req(cfg.which_app_err_alert, cs_item); + + // Read the value of the SW_CMD_STS and check if it is equal to CMD_STS_SUCCESS. + csr_rd_check(.ptr(ral.sw_cmd_sts.cmd_sts), .compare_value(CMD_STS_SUCCESS)); + end + `uvm_info(`gfn, $sformatf("aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa2"), UVM_LOW) + + // Send the out of sequence command. + cs_item.acmd = cfg.which_cmd_alert; + cs_item.clen = 'h0; + cs_item.flags = get_rand_mubi4_val(.t_weight(4), .f_weight(4), .other_weight(0)); + cs_item.glen = 'h0; + send_cmd_req(cfg.which_app_err_alert, cs_item, .await_response(1'b0)); + `uvm_info(`gfn, $sformatf("aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa3"), UVM_LOW) + + `uvm_info(`gfn, $sformatf("Waiting for alert ack to complete"), UVM_MEDIUM) + cfg.m_alert_agent_cfgs["recov_alert"].vif.wait_ack_complete(); + + `uvm_info(`gfn, $sformatf("Checking RECOV_ALERT_STS register"), UVM_MEDIUM) + exp_recov_alert_sts = 32'b0; + exp_recov_alert_sts[ral.recov_alert_sts.cs_main_sm_invalid_cmd_seq_alert.get_lsb_pos()] = 1; + csr_spinwait(.ptr(ral.recov_alert_sts), .exp_data(exp_recov_alert_sts)); + // Since we already did a backdoor check, sampling with this value is sufficient. + cov_vif.cg_recov_alert_sample(.recov_alert(exp_recov_alert_sts)); + + `uvm_info(`gfn, $sformatf("aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa4"), UVM_LOW) + if (cfg.which_app_err_alert == SW_APP) begin + // Read the value of the SW_CMD_STS and check if it is equal to CMD_STS_INVALID_CMD_SEQ. + csr_rd_check(.ptr(ral.sw_cmd_sts.cmd_sts), .compare_value(CMD_STS_INVALID_CMD_SEQ)); + end + `uvm_info(`gfn, $sformatf("aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa5"), UVM_LOW) + + `uvm_info(`gfn, $sformatf("Checking RECOV_ALERT_STS reset"), UVM_MEDIUM) + // Toggle enable and clear the alerts. + ral.ctrl.enable.set(prim_mubi_pkg::MuBi4False); + csr_update(.csr(ral.ctrl)); + cfg.clk_rst_vif.wait_clks(100); + ral.ctrl.enable.set(prim_mubi_pkg::MuBi4True); + csr_update(.csr(ral.ctrl)); + + // Clear recov_alert_sts register. + csr_wr(.ptr(ral.recov_alert_sts), .value(32'b0)); + cfg.clk_rst_vif.wait_clks(100); + // Check recov_alert_sts register has cleared. + csr_rd_check(.ptr(ral.recov_alert_sts), .compare_value(0)); + csr_rd_check(.ptr(ral.sw_cmd_sts.cmd_sts), .compare_value(CMD_STS_SUCCESS)); + + ///////////////////////////////////////// + // Testing cs_main_sm_reseed_cnt_alert // + ///////////////////////////////////////// + + `uvm_info(`gfn, $sformatf("Testing cs_main_sm_reseed_cnt_alert for app %d", + cfg.which_app_err_alert), UVM_LOW) + + // Here we set the reseed interval to 1 to see if the corresponding alert is triggered + // by sending to many generate commands. + + // Toggle the enable and set the reseed interval to 1 make it easier to trigger + // cs_main_sm_reseed_cnt_alert. + ral.ctrl.enable.set(prim_mubi_pkg::MuBi4False); + csr_update(.csr(ral.ctrl)); + ral.reseed_interval.set(32'b1); + csr_update(.csr(ral.reseed_interval)); + cfg.clk_rst_vif.wait_clks(100); + ral.ctrl.enable.set(prim_mubi_pkg::MuBi4True); + csr_update(.csr(ral.ctrl)); + + + // Instantiate Command. + `uvm_info(`gfn, $sformatf("wwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwww1"), UVM_LOW) + cs_item.acmd = csrng_pkg::INS; + cs_item.clen = 'h0; + cs_item.flags = get_rand_mubi4_val(.t_weight(4), .f_weight(4), .other_weight(0)); + cs_item.glen = 'h0; + send_cmd_req(cfg.which_app_err_alert, cs_item); + + // Send the first generate command, which should succeed. + `uvm_info(`gfn, $sformatf("wwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwww3"), UVM_LOW) + cs_item.acmd = csrng_pkg::GEN; + cs_item.clen = 'h0; + cs_item.flags = get_rand_mubi4_val(.t_weight(4), .f_weight(4), .other_weight(0)); + cs_item.glen = 'h1; + send_cmd_req(cfg.which_app_err_alert, cs_item); + `uvm_info(`gfn, $sformatf("wwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwww4"), UVM_LOW) + + // Send the second generate command, which should fail. + cs_item.acmd = csrng_pkg::GEN; + cs_item.clen = 'h0; + cs_item.flags = get_rand_mubi4_val(.t_weight(4), .f_weight(4), .other_weight(0)); + cs_item.glen = 'h1; + send_cmd_req(cfg.which_app_err_alert, cs_item, .await_response(1'b0)); + + `uvm_info(`gfn, $sformatf("Waiting for alert ack to complete"), UVM_MEDIUM) + cfg.m_alert_agent_cfgs["recov_alert"].vif.wait_ack_complete(); + csr_spinwait_or_edn_rst_n(.ptr(ral.intr_state.cs_cmd_req_done), .exp_data(1'b1)); + check_interrupts(.interrupts((1 << CmdReqDone)), .check_set(1'b1)); + + `uvm_info(`gfn, $sformatf("Checking RECOV_ALERT_STS register"), UVM_MEDIUM) + exp_recov_alert_sts = 32'b0; + exp_recov_alert_sts[ral.recov_alert_sts.cs_main_sm_reseed_cnt_alert.get_lsb_pos()] = 1; + csr_spinwait(.ptr(ral.recov_alert_sts), .exp_data(exp_recov_alert_sts)); + // Since we already did a backdoor check, sampling with this value is sufficient. + cov_vif.cg_recov_alert_sample(.recov_alert(exp_recov_alert_sts)); + + if (cfg.which_app_err_alert == SW_APP) begin + // Read the value of the SW_CMD_STS and check if it is equal to CMD_STS_RESEED_CNT_OVERFLOW. + csr_rd_check(.ptr(ral.sw_cmd_sts.cmd_sts), .compare_value(CMD_STS_RESEED_CNT_OVERFLOW)); + end + + // Clear recov_alert_sts register. + csr_wr(.ptr(ral.recov_alert_sts), .value(32'b0)); + `uvm_info(`gfn, $sformatf("wwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwww6"), UVM_LOW) + + // Send a reseed command and check if the counter is reset correctly by trying to trigger + // cs_main_sm_reseed_cnt_alert again. + cs_item.acmd = csrng_pkg::RES; + cs_item.clen = 'h0; + cs_item.flags = get_rand_mubi4_val(.t_weight(4), .f_weight(4), .other_weight(0)); + cs_item.glen = 'h0; + send_cmd_req(cfg.which_app_err_alert, cs_item); + `uvm_info(`gfn, $sformatf("wwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwww7"), UVM_LOW) + + // Send the first generate command, which should succeed. + cs_item.acmd = csrng_pkg::GEN; + cs_item.clen = 'h0; + cs_item.flags = get_rand_mubi4_val(.t_weight(4), .f_weight(4), .other_weight(0)); + cs_item.glen = 'h1; + send_cmd_req(cfg.which_app_err_alert, cs_item); + `uvm_info(`gfn, $sformatf("wwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwww8"), UVM_LOW) + + // Send the second generate command, which should fail. + cs_item.acmd = csrng_pkg::GEN; + cs_item.clen = 'h0; + cs_item.flags = get_rand_mubi4_val(.t_weight(4), .f_weight(4), .other_weight(0)); + cs_item.glen = 'h1; + send_cmd_req(cfg.which_app_err_alert, cs_item, .await_response(1'b0)); + `uvm_info(`gfn, $sformatf("wwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwww9"), UVM_LOW) + + `uvm_info(`gfn, $sformatf("Waiting for alert ack to complete"), UVM_MEDIUM) + cfg.m_alert_agent_cfgs["recov_alert"].vif.wait_ack_complete(); + + `uvm_info(`gfn, $sformatf("Checking RECOV_ALERT_STS register"), UVM_MEDIUM) + exp_recov_alert_sts = 32'b0; + exp_recov_alert_sts[ral.recov_alert_sts.cs_main_sm_reseed_cnt_alert.get_lsb_pos()] = 1; + csr_spinwait(.ptr(ral.recov_alert_sts), .exp_data(exp_recov_alert_sts)); + // Since we already did a backdoor check, sampling with this value is sufficient. + cov_vif.cg_recov_alert_sample(.recov_alert(exp_recov_alert_sts)); + + if (cfg.which_app_err_alert == SW_APP) begin + // Read the value of the SW_CMD_STS and check if it is equal to CMD_STS_RESEED_CNT_OVERFLOW. + csr_rd_check(.ptr(ral.sw_cmd_sts.cmd_sts), .compare_value(CMD_STS_RESEED_CNT_OVERFLOW)); + end + `uvm_info(`gfn, $sformatf("Checking RECOV_ALERT_STS reset"), UVM_MEDIUM) // Toggle enable to put main FSM back into legal state. ral.ctrl.enable.set(prim_mubi_pkg::MuBi4False); @@ -238,6 +440,7 @@ class csrng_alert_vseq extends csrng_base_vseq; cfg.clk_rst_vif.wait_clks(100); // Check recov_alert_sts register has cleared. csr_rd_check(.ptr(ral.recov_alert_sts), .compare_value(0)); + csr_rd_check(.ptr(ral.sw_cmd_sts.cmd_sts), .compare_value(CMD_STS_SUCCESS)); // Turn assertions back on. cfg.csrng_assert_vif.assert_on_alert(); diff --git a/hw/ip/csrng/dv/env/seq_lib/csrng_base_vseq.sv b/hw/ip/csrng/dv/env/seq_lib/csrng_base_vseq.sv index 8c7c42ec2018b0..07011d061198d4 100644 --- a/hw/ip/csrng/dv/env/seq_lib/csrng_base_vseq.sv +++ b/hw/ip/csrng/dv/env/seq_lib/csrng_base_vseq.sv @@ -100,6 +100,7 @@ class csrng_base_vseq extends cip_base_vseq #( cmd = {cs_item.glen, cs_item.flags, cs_item.clen, 1'b0, cs_item.acmd}; end if (app != SW_APP) begin + `uvm_info(`gfn, $sformatf("HW INTERFACE"), UVM_LOW) cfg.m_edn_agent_cfg[app].m_cmd_push_agent_cfg.add_h_user_data(cmd); m_edn_push_seq[app].num_trans = cs_item.clen + 1; for (int i = 0; i < cs_item.clen; i++) @@ -111,19 +112,24 @@ class csrng_base_vseq extends cip_base_vseq #( join_none if (await_response) begin // Wait for ack + `uvm_info(`gfn, $sformatf("HW WAITING FOR ACK"), UVM_LOW) if (edn_rst_as_ack) cfg.m_edn_agent_cfg[app].vif.wait_cmd_ack_or_rst_n(); else cfg.m_edn_agent_cfg[app].vif.wait_cmd_ack(); + `uvm_info(`gfn, $sformatf("HW DONE WAITING FOR ACK"), UVM_LOW) end end else begin + `uvm_info(`gfn, $sformatf("SW INTERFACE"), UVM_LOW) // Wait for CSRNG cmd_rdy csr_spinwait_or_edn_rst_n(.ptr(ral.sw_cmd_sts.cmd_rdy), .exp_data(1'b1)); + `uvm_info(`gfn, $sformatf("SW INTERFACE RDY FOUND"), UVM_LOW) if (edn_under_reset()) begin `uvm_info(`gfn, "SW app stopped due to EDN reset", UVM_HIGH) return; end csr_wr(.ptr(ral.cmd_req), .value(cmd)); + `uvm_info(`gfn, $sformatf("SW INTERFACE VALUE WRITTEN"), UVM_LOW) if (edn_under_reset()) begin `uvm_info(`gfn, "SW app stopped due to EDN reset", UVM_HIGH) return; @@ -146,11 +152,14 @@ class csrng_base_vseq extends cip_base_vseq #( end if (await_response) begin if (cs_item.acmd != csrng_pkg::GEN) begin + `uvm_info(`gfn, $sformatf("SW INTERFACE WAIT CMD REQ DONE"), UVM_LOW) wait_cmd_req_done(); end else begin for (int i = 0; i < cs_item.glen; i++) begin + `uvm_info(`gfn, $sformatf("SW INTERFACE WAIT WAIT FOR GENBITS"), UVM_LOW) csr_spinwait_or_edn_rst_n(.ptr(ral.genbits_vld.genbits_vld), .exp_data(1'b1)); + `uvm_info(`gfn, $sformatf("SW INTERFACE WAIT FOUND GENBITS"), UVM_LOW) if (edn_under_reset()) begin `uvm_info(`gfn, "SW app stopped due to EDN reset", UVM_HIGH) return; diff --git a/hw/ip/csrng/rtl/csrng_cmd_stage.sv b/hw/ip/csrng/rtl/csrng_cmd_stage.sv index d69ac8c8942545..f9e20b5474d7ae 100644 --- a/hw/ip/csrng/rtl/csrng_cmd_stage.sv +++ b/hw/ip/csrng/rtl/csrng_cmd_stage.sv @@ -28,6 +28,8 @@ module csrng_cmd_stage import csrng_pkg::*; #( // Ack from core. input logic cmd_ack_i, input csrng_cmd_sts_e cmd_ack_sts_i, + // Status error from core. + input logic cmd_sts_err_i, // Ack to app i/f. output logic cmd_stage_ack_o, output csrng_cmd_sts_e cmd_stage_ack_sts_o, @@ -72,16 +74,17 @@ module csrng_cmd_stage import csrng_pkg::*; #( logic sfifo_genbits_not_empty; // Command signals. - logic [3:0] cmd_len; - logic cmd_fifo_zero; - logic cmd_fifo_pop; - logic cmd_len_dec; - logic cmd_gen_cnt_dec; - logic cmd_gen_1st_req; - logic cmd_gen_inc_req; - logic cmd_gen_cnt_last; - logic cmd_final_ack; + logic [3:0] cmd_len; + logic cmd_fifo_zero; + logic cmd_fifo_pop; + logic cmd_len_dec; + logic cmd_gen_cnt_dec; + logic cmd_gen_1st_req; + logic cmd_gen_inc_req; + logic cmd_gen_cnt_last; + logic cmd_final_ack; logic [GenBitsCntrWidth-1:0] cmd_gen_cnt; + logic cmd_sts_err_release; // Flops. logic cmd_ack_q, cmd_ack_d; @@ -89,6 +92,7 @@ module csrng_cmd_stage import csrng_pkg::*; #( logic [3:0] cmd_len_q, cmd_len_d; logic cmd_gen_flag_q, cmd_gen_flag_d; logic [11:0] cmd_gen_cmd_q, cmd_gen_cmd_d; + logic cmd_sts_err_q, cmd_sts_err_d; logic local_escalate; @@ -100,12 +104,14 @@ module csrng_cmd_stage import csrng_pkg::*; #( cmd_len_q <= '0; cmd_gen_flag_q <= '0; cmd_gen_cmd_q <= '0; + cmd_sts_err_q <= '0; end else begin cmd_ack_q <= cmd_ack_d; cmd_ack_sts_q <= cmd_ack_sts_d; cmd_len_q <= cmd_len_d; cmd_gen_flag_q <= cmd_gen_flag_d; cmd_gen_cmd_q <= cmd_gen_cmd_d; + cmd_sts_err_q <= cmd_sts_err_d; end assign cmd_stage_sfifo_cmd_err_o = sfifo_cmd_err; @@ -177,6 +183,14 @@ module csrng_cmd_stage import csrng_pkg::*; #( (!cs_enable_i) ? '0 : cmd_gen_1st_req ? {sfifo_cmd_rdata[11:0]} : cmd_gen_cmd_q; + + // Capture the cmd_sts_err_i in case an error status response is handled in core and release it + // once we reached the CmdAck state and transition back to Idle. + assign cmd_sts_err_d = + (!cs_enable_i) ? 1'b0 : + cmd_sts_err_i ? 1'b1 : + cmd_sts_err_release ? 1'b0 : + cmd_sts_err_q; // SEC_CM: GEN_CMD.CTR.REDUN prim_count #( @@ -255,6 +269,7 @@ module csrng_cmd_stage import csrng_pkg::*; #( cmd_arb_mop_o = 1'b0; cmd_arb_eop_o = 1'b0; cmd_stage_sm_err_o = 1'b0; + cmd_sts_err_release = 1'b0; if (state_q == Error) begin // In case we are in the Error state we must ignore the local escalate and enable signals. @@ -310,12 +325,15 @@ module csrng_cmd_stage import csrng_pkg::*; #( end GenCmdChk: begin if (cmd_gen_flag_q) begin - cmd_gen_cnt_dec= 1'b1; + cmd_gen_cnt_dec = 1'b1; end state_d = CmdAck; end CmdAck: begin - if (cmd_ack_i) begin + if (cmd_sts_err_q) begin + state_d = Idle; + cmd_sts_err_release = 1'b1; + end if (cmd_ack_i) begin // The state database has successfully been updated. // In case of Generate commands, we get the generated bits one clock cycle before // receiving the ACK from the state database (from csrng_ctr_drbg_gen). diff --git a/hw/ip/csrng/rtl/csrng_core.sv b/hw/ip/csrng/rtl/csrng_core.sv index 7283e50a4f717b..4821b67fe8bf13 100644 --- a/hw/ip/csrng/rtl/csrng_core.sv +++ b/hw/ip/csrng/rtl/csrng_core.sv @@ -195,8 +195,9 @@ module csrng_core import csrng_pkg::*; #( logic cmd_gen_cnt_err_sum; logic cmd_stage_sm_err_sum; logic main_sm_err_sum; - logic cs_main_sm_invalid_cmd_seq; - logic cs_main_sm_alert; + logic cs_main_sm_invalid_cmd_alert; + logic cs_main_sm_invalid_cmd_seq_alert; + logic cs_main_sm_reseed_cnt_alert; logic cs_main_sm_err; logic [MainSmStateWidth-1:0] cs_main_sm_state; logic drbg_gen_sm_err_sum; @@ -349,7 +350,11 @@ module csrng_core import csrng_pkg::*; #( logic cs_rdata_capt_vld; logic cs_bus_cmp_alert; logic cmd_rdy; + logic invalid_cmd_alert[NApps]; + logic invalid_cmd_seq_alert[NApps]; + logic reseed_cnt_alert[NApps]; logic sw_sts_ack; + logic cmd_sts_err[NApps]; logic [1:0] efuse_sw_app_enable; logic unused_err_code_test_bit; @@ -361,22 +366,23 @@ module csrng_core import csrng_pkg::*; #( prim_mubi_pkg::mubi4_t [Flag0Copies-1:0] mubi_flag0_fanout; // flops - logic [2:0] 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 [$clog2(NApps)-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 cmd_req_dly_q, cmd_req_dly_d; - logic [Cmd-1:0] 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 [2:0] 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 [$clog2(NApps)-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 cmd_req_dly_q, cmd_req_dly_d; + logic [Cmd-1:0] 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_cmd_rdy_q, sw_cmd_rdy_d; + logic sw_cmd_ack_q, sw_cmd_ack_d; + logic [CSRNG_CMD_STS_WIDTH-1:0] sw_cmd_sts_q, sw_cmd_sts_d; always_ff @(posedge clk_i or negedge rst_ni) begin if (!rst_ni) begin @@ -394,8 +400,9 @@ module csrng_core import csrng_pkg::*; #( entropy_src_fips_q <= '0; cs_rdata_capt_q <= '0; cs_rdata_capt_vld_q <= '0; - sw_rdy_sts_q <= '0; - sw_sts_ack_q <= '0; + sw_cmd_rdy_q <= '0; + sw_cmd_ack_q <= '0; + sw_cmd_sts_q <= '0; end else begin acmd_q <= acmd_d; shid_q <= shid_d; @@ -411,8 +418,9 @@ module csrng_core import csrng_pkg::*; #( entropy_src_fips_q <= entropy_src_fips_d; cs_rdata_capt_q <= cs_rdata_capt_d; cs_rdata_capt_vld_q <= cs_rdata_capt_vld_d; - sw_rdy_sts_q <= sw_rdy_sts_d; - sw_sts_ack_q <= sw_sts_ack_d; + sw_cmd_rdy_q <= sw_cmd_rdy_d; + sw_cmd_ack_q <= sw_cmd_ack_d; + sw_cmd_sts_q <= sw_cmd_sts_d; end end @@ -737,8 +745,9 @@ module csrng_core import csrng_pkg::*; #( sw_app_enable_pfa || read_int_state_pfa || acmd_flag0_pfa || - cs_main_sm_alert || - cs_main_sm_invalid_cmd_seq || + cs_main_sm_invalid_cmd_alert || + cs_main_sm_invalid_cmd_seq_alert || + cs_main_sm_reseed_cnt_alert || cs_bus_cmp_alert; @@ -853,6 +862,7 @@ module csrng_core import csrng_pkg::*; #( .cmd_arb_bus_o (cmd_arb_bus[ai]), .cmd_ack_i (cmd_core_ack[ai]), .cmd_ack_sts_i (cmd_core_ack_sts[ai]), + .cmd_sts_err_i (cmd_sts_err[ai]), .cmd_stage_ack_o (cmd_stage_ack[ai]), .cmd_stage_ack_sts_o (cmd_stage_ack_sts[ai]), .genbits_vld_i (genbits_core_vld[ai]), @@ -875,31 +885,49 @@ module csrng_core import csrng_pkg::*; #( assign cmd_stage_vld[NApps-1] = reg2hw.cmd_req.qe; assign cmd_stage_shid[NApps-1] = StateId'(NApps-1); assign cmd_stage_bus[NApps-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[NApps-1] && sw_rdy_sts_q; - assign sw_rdy_sts_d = + + assign cmd_rdy = !cmd_stage_vld[NApps-1] && sw_cmd_rdy_q; + assign sw_cmd_rdy_d = !cs_enable_fo[28] ? 1'b0 : cmd_stage_vld[NApps-1] ? 1'b0 : cmd_stage_rdy[NApps-1] ? 1'b1 : - sw_rdy_sts_q; + sw_cmd_rdy_q; + + assign hw2reg.sw_cmd_sts.cmd_rdy.de = 1'b1; + assign hw2reg.sw_cmd_sts.cmd_rdy.d = cmd_rdy; + // 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[NApps-1] || - (cs_main_sm_invalid_cmd_seq && (shid_q == StateId'(NApps-1))) || - (cs_main_sm_alert && (shid_q == StateId'(NApps-1))); - assign sw_sts_ack_d = + assign invalid_cmd_alert[NApps-1] = + (shid_hold == StateId'(NApps-1)) && cs_main_sm_invalid_cmd_alert; + assign invalid_cmd_seq_alert[NApps-1] = + (shid_hold == StateId'(NApps-1)) && cs_main_sm_invalid_cmd_seq_alert; + assign reseed_cnt_alert[NApps-1] = + (shid_hold == StateId'(NApps-1)) && cs_main_sm_reseed_cnt_alert; + assign cmd_sts_err[NApps-1] = + invalid_cmd_seq_alert[NApps-1] || reseed_cnt_alert[NApps-1] || invalid_cmd_alert[NApps-1]; + + assign sw_sts_ack = cmd_stage_ack[NApps-1] || cmd_sts_err[NApps-1]; + assign sw_cmd_ack_d = !cs_enable_fo[28] ? 1'b0 : cmd_stage_vld[NApps-1] ? 1'b0 : sw_sts_ack ? 1'b1 : - sw_sts_ack_q; + sw_cmd_ack_q; + + assign hw2reg.sw_cmd_sts.cmd_ack.de = 1'b1; + assign hw2reg.sw_cmd_sts.cmd_ack.d = sw_cmd_ack_d; + // cmd ack sts - assign hw2reg.sw_cmd_sts.cmd_sts.de = sw_sts_ack; - assign hw2reg.sw_cmd_sts.cmd_sts.d = - ((shid_q == StateId'(NApps-1)) && cs_main_sm_invalid_cmd_seq) ? CMD_STS_INVALID_ACMD : - ((shid_q == StateId'(NApps-1)) && cs_main_sm_alert) ? CMD_STS_INVALID_CMD_SEQ : - cmd_stage_ack_sts[NApps-1]; + assign sw_cmd_sts_d = + !cs_enable_fo[28] ? CMD_STS_SUCCESS : + invalid_cmd_alert[NApps-1] ? CMD_STS_INVALID_ACMD: + invalid_cmd_seq_alert[NApps-1] ? CMD_STS_INVALID_CMD_SEQ: + reseed_cnt_alert[NApps-1] ? CMD_STS_RESEED_CNT_OVERFLOW: + cmd_stage_ack[NApps-1] ? CMD_STS_SUCCESS : + sw_cmd_sts_q; + + assign hw2reg.sw_cmd_sts.cmd_sts.de = 1'b1; + assign hw2reg.sw_cmd_sts.cmd_sts.d = sw_cmd_sts_d; + // genbits assign hw2reg.genbits_vld.genbits_vld.d = genbits_stage_vldo_sw; assign hw2reg.genbits_vld.genbits_fips.d = genbits_stage_fips_sw; @@ -973,11 +1001,16 @@ module csrng_core import csrng_pkg::*; #( assign hw2reg.recov_alert_sts.cs_bus_cmp_alert.de = cs_bus_cmp_alert; assign hw2reg.recov_alert_sts.cs_bus_cmp_alert.d = cs_bus_cmp_alert; - assign hw2reg.recov_alert_sts.cs_main_sm_alert.de = cs_main_sm_alert; - assign hw2reg.recov_alert_sts.cs_main_sm_alert.d = cs_main_sm_alert; + assign hw2reg.recov_alert_sts.cs_main_sm_invalid_cmd_alert.de = cs_main_sm_invalid_cmd_alert; + assign hw2reg.recov_alert_sts.cs_main_sm_invalid_cmd_alert.d = cs_main_sm_invalid_cmd_alert; - assign hw2reg.recov_alert_sts.cs_main_sm_invalid_cmd_seq.de = cs_main_sm_invalid_cmd_seq; - assign hw2reg.recov_alert_sts.cs_main_sm_invalid_cmd_seq.d = cs_main_sm_invalid_cmd_seq; + assign hw2reg.recov_alert_sts.cs_main_sm_invalid_cmd_seq_alert.de = + cs_main_sm_invalid_cmd_seq_alert; + assign hw2reg.recov_alert_sts.cs_main_sm_invalid_cmd_seq_alert.d = + cs_main_sm_invalid_cmd_seq_alert; + + assign hw2reg.recov_alert_sts.cs_main_sm_reseed_cnt_alert.de = cs_main_sm_reseed_cnt_alert; + assign hw2reg.recov_alert_sts.cs_main_sm_reseed_cnt_alert.d = cs_main_sm_reseed_cnt_alert; // HW interface connections (up to 16, numbered 0-14) for (genvar hai = 0; hai < (NApps-1); hai = hai+1) begin : gen_app_if @@ -986,13 +1019,21 @@ module csrng_core import csrng_pkg::*; #( assign cmd_stage_shid[hai] = hai; assign cmd_stage_bus[hai] = csrng_cmd_i[hai].csrng_req_bus; assign csrng_cmd_o[hai].csrng_req_ready = cmd_stage_rdy[hai]; + // alerts + assign invalid_cmd_alert[hai] = + (shid_hold == StateId'(hai)) && cs_main_sm_invalid_cmd_alert; + assign invalid_cmd_seq_alert[hai] = + (shid_hold == StateId'(hai)) && cs_main_sm_invalid_cmd_seq_alert; + assign reseed_cnt_alert[hai] = + (shid_hold == StateId'(hai)) && cs_main_sm_reseed_cnt_alert; + assign cmd_sts_err[hai] = + invalid_cmd_seq_alert[hai] || reseed_cnt_alert[hai] || invalid_cmd_alert[hai]; // cmd ack - assign csrng_cmd_o[hai].csrng_rsp_ack = cmd_stage_ack[hai] || - ((cs_main_sm_alert || cs_main_sm_invalid_cmd_seq) && (shid_q == StateId'(hai))); - assign csrng_cmd_o[hai].csrng_rsp_sts = - (cs_main_sm_alert && (shid_q == StateId'(hai))) ? CMD_STS_INVALID_ACMD : - (cs_main_sm_invalid_cmd_seq && (shid_q == StateId'(hai))) ? CMD_STS_INVALID_CMD_SEQ : - cmd_stage_ack_sts[hai]; + assign csrng_cmd_o[hai].csrng_rsp_ack = cmd_stage_ack[hai] || cmd_sts_err[hai]; + assign csrng_cmd_o[hai].csrng_rsp_sts = invalid_cmd_alert[hai] ? CMD_STS_INVALID_ACMD : + invalid_cmd_seq_alert[hai] ? CMD_STS_INVALID_CMD_SEQ : + reseed_cnt_alert[hai] ? CMD_STS_RESEED_CNT_OVERFLOW : + 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]; @@ -1113,30 +1154,32 @@ module csrng_core import csrng_pkg::*; #( csrng_main_sm #( .NApps(NApps) ) u_csrng_main_sm ( - .clk_i (clk_i), - .rst_ni (rst_ni), - .enable_i (cs_enable_fo[36]), - .acmd_avail_i (acmd_avail), - .acmd_accept_o (acmd_accept), - .shid_i (shid_hold), - .acmd_i (acmd_hold), - .acmd_eop_i (acmd_eop), - .ctr_drbg_cmd_req_rdy_i (ctr_drbg_cmd_req_rdy), - .flag0_i (flag0_fo[0]), - .cmd_entropy_req_o (cmd_entropy_req), - .cmd_entropy_avail_i (cmd_entropy_avail), - .instant_req_o (instant_req), - .reseed_req_o (reseed_req), - .generate_req_o (generate_req), - .update_req_o (update_req), - .uninstant_req_o (uninstant_req), - .clr_adata_packer_o (clr_adata_packer), - .cmd_complete_i (state_db_wr_req), - .local_escalate_i (cmd_gen_cnt_err_sum), - .invalid_cmd_seq_o (cs_main_sm_invalid_cmd_seq), - .main_sm_state_o (cs_main_sm_state), - .main_sm_alert_o (cs_main_sm_alert), - .main_sm_err_o (cs_main_sm_err) + .clk_i (clk_i), + .rst_ni (rst_ni), + .enable_i (cs_enable_fo[36]), + .acmd_avail_i (acmd_avail), + .acmd_accept_o (acmd_accept), + .shid_i (shid_hold), + .acmd_i (acmd_hold), + .acmd_eop_i (acmd_eop), + .ctr_drbg_cmd_req_rdy_i (ctr_drbg_cmd_req_rdy), + .flag0_i (flag0_fo[0]), + .cmd_entropy_req_o (cmd_entropy_req), + .cmd_entropy_avail_i (cmd_entropy_avail), + .instant_req_o (instant_req), + .reseed_req_o (reseed_req), + .generate_req_o (generate_req), + .update_req_o (update_req), + .uninstant_req_o (uninstant_req), + .clr_adata_packer_o (clr_adata_packer), + .cmd_complete_i (state_db_wr_req), + .local_escalate_i (cmd_gen_cnt_err_sum), + .reseed_cnt_reached_i (reseed_cnt_reached), + .reseed_cnt_alert_o (cs_main_sm_reseed_cnt_alert), + .invalid_cmd_alert_o (cs_main_sm_invalid_cmd_alert), + .invalid_cmd_seq_alert_o (cs_main_sm_invalid_cmd_seq_alert), + .main_sm_state_o (cs_main_sm_state), + .main_sm_err_o (cs_main_sm_err) ); // interrupt for sw app interface only @@ -1151,6 +1194,9 @@ module csrng_core import csrng_pkg::*; #( // entropy available assign cmd_entropy_avail = entropy_src_hw_if_i.es_ack; + // Max number of generate requests between reseeds reached. + assign reseed_cnt_reached = (state_db_rd_rc == reg2hw.reseed_interval.q); + for (genvar csi = 0; csi < NApps; 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; diff --git a/hw/ip/csrng/rtl/csrng_ctr_drbg_cmd.sv b/hw/ip/csrng/rtl/csrng_ctr_drbg_cmd.sv index bc8b3952426919..65862bcbe7f87a 100644 --- a/hw/ip/csrng/rtl/csrng_ctr_drbg_cmd.sv +++ b/hw/ip/csrng/rtl/csrng_ctr_drbg_cmd.sv @@ -213,8 +213,8 @@ module csrng_ctr_drbg_cmd import csrng_pkg::*; #( '0; assign prep_rc = - (cmdreq_ccmd == INS) ? {{(CtrLen-1){1'b0}},1'b1} : - (cmdreq_ccmd == RES) ? {{(CtrLen-1){1'b0}},1'b1} : + (cmdreq_ccmd == INS) ? {{(CtrLen-1){1'b0}},1'b0} : + (cmdreq_ccmd == RES) ? {{(CtrLen-1){1'b0}},1'b0} : (cmdreq_ccmd == GEN) ? cmdreq_rc : (cmdreq_ccmd == UPD) ? cmdreq_rc : '0; diff --git a/hw/ip/csrng/rtl/csrng_main_sm.sv b/hw/ip/csrng/rtl/csrng_main_sm.sv index b47dbe14f25458..6465fb69e6dd0f 100644 --- a/hw/ip/csrng/rtl/csrng_main_sm.sv +++ b/hw/ip/csrng/rtl/csrng_main_sm.sv @@ -31,9 +31,11 @@ module csrng_main_sm import csrng_pkg::*; #( output logic clr_adata_packer_o, input logic cmd_complete_i, input logic local_escalate_i, - output logic invalid_cmd_seq_o, + input logic reseed_cnt_reached_i, + output logic reseed_cnt_alert_o, + output logic invalid_cmd_alert_o, + output logic invalid_cmd_seq_alert_o, output logic [MainSmStateWidth-1:0] main_sm_state_o, - output logic main_sm_alert_o, output logic main_sm_err_o ); @@ -62,19 +64,21 @@ module csrng_main_sm import csrng_pkg::*; #( ); always_comb begin - state_d = state_q; - instantiated_d = instantiated_q; - acmd_accept_o = 1'b0; - cmd_entropy_req_o = 1'b0; - instant_req_o = 1'b0; - reseed_req_o = 1'b0; - generate_req_o = 1'b0; - update_req_o = 1'b0; - uninstant_req_o = 1'b0; - clr_adata_packer_o = 1'b0; - main_sm_alert_o = 1'b0; - main_sm_err_o = 1'b0; - invalid_cmd_seq_o = 1'b0; + state_d = state_q; + instantiated_d = instantiated_q; + acmd_accept_o = 1'b0; + cmd_entropy_req_o = 1'b0; + instant_req_o = 1'b0; + reseed_req_o = 1'b0; + generate_req_o = 1'b0; + update_req_o = 1'b0; + uninstant_req_o = 1'b0; + clr_adata_packer_o = 1'b0; + invalid_cmd_alert_o = 1'b0; + invalid_cmd_seq_alert_o = 1'b0; + reseed_cnt_alert_o = 1'b0; + main_sm_err_o = 1'b0; + reseed_cnt_alert_o = 1'b0; if (state_q == MainSmError) begin // In case we are in the Error state we must ignore the local escalate and enable signals. @@ -115,7 +119,7 @@ module csrng_main_sm import csrng_pkg::*; #( end if ((instantiated_q & shid_one_hot) != 'b0) begin state_d = MainSmIdle; - invalid_cmd_seq_o = 1'b1; + invalid_cmd_seq_alert_o = 1'b1; end end end else if (acmd_i == RES) begin @@ -125,7 +129,7 @@ module csrng_main_sm import csrng_pkg::*; #( end if ((instantiated_q & shid_one_hot) == 'b0) begin state_d = MainSmIdle; - invalid_cmd_seq_o = 1'b1; + invalid_cmd_seq_alert_o = 1'b1; end end end else if (acmd_i == GEN) begin @@ -135,7 +139,11 @@ module csrng_main_sm import csrng_pkg::*; #( end if ((instantiated_q & shid_one_hot) == 'b0) begin state_d = MainSmIdle; - invalid_cmd_seq_o = 1'b1; + invalid_cmd_seq_alert_o = 1'b1; + end + if (reseed_cnt_reached_i) begin + state_d = MainSmIdle; + reseed_cnt_alert_o = 1'b1; end end end else if (acmd_i == UPD) begin @@ -145,7 +153,7 @@ module csrng_main_sm import csrng_pkg::*; #( end if ((instantiated_q & shid_one_hot) == 'b0) begin state_d = MainSmIdle; - invalid_cmd_seq_o = 1'b1; + invalid_cmd_seq_alert_o = 1'b1; end end end else if (acmd_i == UNI) begin @@ -157,7 +165,7 @@ module csrng_main_sm import csrng_pkg::*; #( end else begin // Command was not supported. state_d = MainSmIdle; - main_sm_alert_o = 1'b1; + invalid_cmd_alert_o = 1'b1; end end end diff --git a/hw/ip/csrng/rtl/csrng_pkg.sv b/hw/ip/csrng/rtl/csrng_pkg.sv index 0a6b4f521456a3..532bc6599d595f 100644 --- a/hw/ip/csrng/rtl/csrng_pkg.sv +++ b/hw/ip/csrng/rtl/csrng_pkg.sv @@ -14,7 +14,7 @@ package csrng_pkg; parameter int unsigned FIPS_GENBITS_BUS_WIDTH = entropy_src_pkg::FIPS_BUS_WIDTH + GENBITS_BUS_WIDTH; parameter int unsigned MainSmStateWidth = 8; - parameter int unsigned CSRNG_CMD_STS_WIDTH = 2; + parameter int unsigned CSRNG_CMD_STS_WIDTH = 3; // instantiation interface typedef struct packed { @@ -28,6 +28,7 @@ package csrng_pkg; CMD_STS_INVALID_ACMD = 'h1, CMD_STS_INVALID_GEN_CMD = 'h2, CMD_STS_INVALID_CMD_SEQ = 'h3, + CMD_STS_RESEED_CNT_OVERFLOW = 'h4, CMD_STS_UNDRIVEN = 'z } csrng_cmd_sts_e; diff --git a/hw/ip/csrng/rtl/csrng_reg_pkg.sv b/hw/ip/csrng/rtl/csrng_reg_pkg.sv index 043c1b743fd3e0..fab35c8678118d 100644 --- a/hw/ip/csrng/rtl/csrng_reg_pkg.sv +++ b/hw/ip/csrng/rtl/csrng_reg_pkg.sv @@ -93,6 +93,11 @@ package csrng_reg_pkg; logic qe; } csrng_reg2hw_cmd_req_reg_t; + typedef struct packed { + logic [31:0] q; + logic qe; + } csrng_reg2hw_reseed_interval_reg_t; + typedef struct packed { logic [31:0] q; logic re; @@ -193,11 +198,15 @@ package csrng_reg_pkg; struct packed { logic d; logic de; - } cs_main_sm_alert; + } cs_main_sm_invalid_cmd_alert; + struct packed { + logic d; + logic de; + } cs_main_sm_invalid_cmd_seq_alert; struct packed { logic d; logic de; - } cs_main_sm_invalid_cmd_seq; + } cs_main_sm_reseed_cnt_alert; } csrng_hw2reg_recov_alert_sts_reg_t; typedef struct packed { @@ -314,12 +323,13 @@ package csrng_reg_pkg; // Register -> HW type typedef struct packed { - csrng_reg2hw_intr_state_reg_t intr_state; // [141:138] - csrng_reg2hw_intr_enable_reg_t intr_enable; // [137:134] - csrng_reg2hw_intr_test_reg_t intr_test; // [133:126] - csrng_reg2hw_alert_test_reg_t alert_test; // [125:122] - csrng_reg2hw_ctrl_reg_t ctrl; // [121:110] - csrng_reg2hw_cmd_req_reg_t cmd_req; // [109:77] + csrng_reg2hw_intr_state_reg_t intr_state; // [174:171] + csrng_reg2hw_intr_enable_reg_t intr_enable; // [170:167] + csrng_reg2hw_intr_test_reg_t intr_test; // [166:159] + csrng_reg2hw_alert_test_reg_t alert_test; // [158:155] + csrng_reg2hw_ctrl_reg_t ctrl; // [154:143] + csrng_reg2hw_cmd_req_reg_t cmd_req; // [142:110] + csrng_reg2hw_reseed_interval_reg_t reseed_interval; // [109:77] csrng_reg2hw_genbits_reg_t genbits; // [76:44] csrng_reg2hw_int_state_num_reg_t int_state_num; // [43:39] csrng_reg2hw_int_state_val_reg_t int_state_val; // [38:6] @@ -328,13 +338,13 @@ package csrng_reg_pkg; // HW -> register type typedef struct packed { - csrng_hw2reg_intr_state_reg_t intr_state; // [172:165] - csrng_hw2reg_sw_cmd_sts_reg_t sw_cmd_sts; // [164:158] - csrng_hw2reg_genbits_vld_reg_t genbits_vld; // [157:156] - csrng_hw2reg_genbits_reg_t genbits; // [155:124] - csrng_hw2reg_int_state_val_reg_t int_state_val; // [123:92] - csrng_hw2reg_hw_exc_sts_reg_t hw_exc_sts; // [91:75] - csrng_hw2reg_recov_alert_sts_reg_t recov_alert_sts; // [74:61] + csrng_hw2reg_intr_state_reg_t intr_state; // [174:167] + csrng_hw2reg_sw_cmd_sts_reg_t sw_cmd_sts; // [166:160] + csrng_hw2reg_genbits_vld_reg_t genbits_vld; // [159:158] + csrng_hw2reg_genbits_reg_t genbits; // [157:126] + csrng_hw2reg_int_state_val_reg_t int_state_val; // [125:94] + csrng_hw2reg_hw_exc_sts_reg_t hw_exc_sts; // [93:77] + csrng_hw2reg_recov_alert_sts_reg_t recov_alert_sts; // [76:61] csrng_hw2reg_err_code_reg_t err_code; // [60:9] csrng_hw2reg_main_sm_state_reg_t main_sm_state; // [8:0] } csrng_hw2reg_t; @@ -347,16 +357,17 @@ package csrng_reg_pkg; parameter logic [BlockAw-1:0] CSRNG_REGWEN_OFFSET = 7'h 10; parameter logic [BlockAw-1:0] CSRNG_CTRL_OFFSET = 7'h 14; parameter logic [BlockAw-1:0] CSRNG_CMD_REQ_OFFSET = 7'h 18; - parameter logic [BlockAw-1:0] CSRNG_SW_CMD_STS_OFFSET = 7'h 1c; - parameter logic [BlockAw-1:0] CSRNG_GENBITS_VLD_OFFSET = 7'h 20; - parameter logic [BlockAw-1:0] CSRNG_GENBITS_OFFSET = 7'h 24; - parameter logic [BlockAw-1:0] CSRNG_INT_STATE_NUM_OFFSET = 7'h 28; - parameter logic [BlockAw-1:0] CSRNG_INT_STATE_VAL_OFFSET = 7'h 2c; - parameter logic [BlockAw-1:0] CSRNG_HW_EXC_STS_OFFSET = 7'h 30; - parameter logic [BlockAw-1:0] CSRNG_RECOV_ALERT_STS_OFFSET = 7'h 34; - parameter logic [BlockAw-1:0] CSRNG_ERR_CODE_OFFSET = 7'h 38; - parameter logic [BlockAw-1:0] CSRNG_ERR_CODE_TEST_OFFSET = 7'h 3c; - parameter logic [BlockAw-1:0] CSRNG_MAIN_SM_STATE_OFFSET = 7'h 40; + parameter logic [BlockAw-1:0] CSRNG_RESEED_INTERVAL_OFFSET = 7'h 1c; + parameter logic [BlockAw-1:0] CSRNG_SW_CMD_STS_OFFSET = 7'h 20; + parameter logic [BlockAw-1:0] CSRNG_GENBITS_VLD_OFFSET = 7'h 24; + parameter logic [BlockAw-1:0] CSRNG_GENBITS_OFFSET = 7'h 28; + parameter logic [BlockAw-1:0] CSRNG_INT_STATE_NUM_OFFSET = 7'h 2c; + parameter logic [BlockAw-1:0] CSRNG_INT_STATE_VAL_OFFSET = 7'h 30; + parameter logic [BlockAw-1:0] CSRNG_HW_EXC_STS_OFFSET = 7'h 34; + parameter logic [BlockAw-1:0] CSRNG_RECOV_ALERT_STS_OFFSET = 7'h 38; + parameter logic [BlockAw-1:0] CSRNG_ERR_CODE_OFFSET = 7'h 3c; + parameter logic [BlockAw-1:0] CSRNG_ERR_CODE_TEST_OFFSET = 7'h 40; + parameter logic [BlockAw-1:0] CSRNG_MAIN_SM_STATE_OFFSET = 7'h 44; // Reset values for hwext registers and their fields parameter logic [3:0] CSRNG_INTR_TEST_RESVAL = 4'h 0; @@ -380,6 +391,7 @@ package csrng_reg_pkg; CSRNG_REGWEN, CSRNG_CTRL, CSRNG_CMD_REQ, + CSRNG_RESEED_INTERVAL, CSRNG_SW_CMD_STS, CSRNG_GENBITS_VLD, CSRNG_GENBITS, @@ -393,7 +405,7 @@ package csrng_reg_pkg; } csrng_id_e; // Register width information to check illegal writes - parameter logic [3:0] CSRNG_PERMIT [17] = '{ + parameter logic [3:0] CSRNG_PERMIT [18] = '{ 4'b 0001, // index[ 0] CSRNG_INTR_STATE 4'b 0001, // index[ 1] CSRNG_INTR_ENABLE 4'b 0001, // index[ 2] CSRNG_INTR_TEST @@ -401,16 +413,17 @@ package csrng_reg_pkg; 4'b 0001, // index[ 4] CSRNG_REGWEN 4'b 0011, // index[ 5] CSRNG_CTRL 4'b 1111, // index[ 6] CSRNG_CMD_REQ - 4'b 0001, // index[ 7] CSRNG_SW_CMD_STS - 4'b 0001, // index[ 8] CSRNG_GENBITS_VLD - 4'b 1111, // index[ 9] CSRNG_GENBITS - 4'b 0001, // index[10] CSRNG_INT_STATE_NUM - 4'b 1111, // index[11] CSRNG_INT_STATE_VAL - 4'b 0011, // index[12] CSRNG_HW_EXC_STS - 4'b 0011, // index[13] CSRNG_RECOV_ALERT_STS - 4'b 1111, // index[14] CSRNG_ERR_CODE - 4'b 0001, // index[15] CSRNG_ERR_CODE_TEST - 4'b 0001 // index[16] CSRNG_MAIN_SM_STATE + 4'b 1111, // index[ 7] CSRNG_RESEED_INTERVAL + 4'b 0001, // index[ 8] CSRNG_SW_CMD_STS + 4'b 0001, // index[ 9] CSRNG_GENBITS_VLD + 4'b 1111, // index[10] CSRNG_GENBITS + 4'b 0001, // index[11] CSRNG_INT_STATE_NUM + 4'b 1111, // index[12] CSRNG_INT_STATE_VAL + 4'b 0011, // index[13] CSRNG_HW_EXC_STS + 4'b 0011, // index[14] CSRNG_RECOV_ALERT_STS + 4'b 1111, // index[15] CSRNG_ERR_CODE + 4'b 0001, // index[16] CSRNG_ERR_CODE_TEST + 4'b 0001 // index[17] CSRNG_MAIN_SM_STATE }; endpackage diff --git a/hw/ip/csrng/rtl/csrng_reg_top.sv b/hw/ip/csrng/rtl/csrng_reg_top.sv index ec816b4d19b0cd..d517121c425503 100644 --- a/hw/ip/csrng/rtl/csrng_reg_top.sv +++ b/hw/ip/csrng/rtl/csrng_reg_top.sv @@ -52,9 +52,9 @@ module csrng_reg_top ( // also check for spurious write enables logic reg_we_err; - logic [16:0] reg_we_check; + logic [17:0] reg_we_check; prim_reg_we_check #( - .OneHotWidth(17) + .OneHotWidth(18) ) u_prim_reg_we_check ( .clk_i(clk_i), .rst_ni(rst_ni), @@ -159,6 +159,9 @@ module csrng_reg_top ( logic [3:0] ctrl_read_int_state_wd; logic cmd_req_we; logic [31:0] cmd_req_wd; + logic reseed_interval_we; + logic [31:0] reseed_interval_qs; + logic [31:0] reseed_interval_wd; logic sw_cmd_sts_cmd_rdy_qs; logic sw_cmd_sts_cmd_ack_qs; logic [1:0] sw_cmd_sts_cmd_sts_qs; @@ -186,10 +189,12 @@ module csrng_reg_top ( logic recov_alert_sts_acmd_flag0_field_alert_wd; logic recov_alert_sts_cs_bus_cmp_alert_qs; logic recov_alert_sts_cs_bus_cmp_alert_wd; - logic recov_alert_sts_cs_main_sm_alert_qs; - logic recov_alert_sts_cs_main_sm_alert_wd; - logic recov_alert_sts_cs_main_sm_invalid_cmd_seq_qs; - logic recov_alert_sts_cs_main_sm_invalid_cmd_seq_wd; + logic recov_alert_sts_cs_main_sm_invalid_cmd_alert_qs; + logic recov_alert_sts_cs_main_sm_invalid_cmd_alert_wd; + logic recov_alert_sts_cs_main_sm_invalid_cmd_seq_alert_qs; + logic recov_alert_sts_cs_main_sm_invalid_cmd_seq_alert_wd; + logic recov_alert_sts_cs_main_sm_reseed_cnt_alert_qs; + logic recov_alert_sts_cs_main_sm_reseed_cnt_alert_wd; logic err_code_sfifo_cmd_err_qs; logic err_code_sfifo_genbits_err_qs; logic err_code_sfifo_cmdreq_err_qs; @@ -702,6 +707,46 @@ module csrng_reg_top ( assign reg2hw.cmd_req.qe = cmd_req_qe; + // R[reseed_interval]: V(False) + logic reseed_interval_qe; + logic [0:0] reseed_interval_flds_we; + prim_flop #( + .Width(1), + .ResetValue(0) + ) u_reseed_interval0_qe ( + .clk_i(clk_i), + .rst_ni(rst_ni), + .d_i(&reseed_interval_flds_we), + .q_o(reseed_interval_qe) + ); + prim_subreg #( + .DW (32), + .SwAccess(prim_subreg_pkg::SwAccessRW), + .RESVAL (32'hffffffff), + .Mubi (1'b0) + ) u_reseed_interval ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (reseed_interval_we), + .wd (reseed_interval_wd), + + // from internal hardware + .de (1'b0), + .d ('0), + + // to internal hardware + .qe (reseed_interval_flds_we[0]), + .q (reg2hw.reseed_interval.q), + .ds (), + + // to register interface (read) + .qs (reseed_interval_qs) + ); + assign reg2hw.reseed_interval.qe = reseed_interval_qe; + + // R[sw_cmd_sts]: V(False) // F[cmd_rdy]: 1:1 prim_subreg #( @@ -1053,23 +1098,23 @@ module csrng_reg_top ( .qs (recov_alert_sts_cs_bus_cmp_alert_qs) ); - // F[cs_main_sm_alert]: 13:13 + // F[cs_main_sm_invalid_cmd_alert]: 13:13 prim_subreg #( .DW (1), .SwAccess(prim_subreg_pkg::SwAccessW0C), .RESVAL (1'h0), .Mubi (1'b0) - ) u_recov_alert_sts_cs_main_sm_alert ( + ) u_recov_alert_sts_cs_main_sm_invalid_cmd_alert ( .clk_i (clk_i), .rst_ni (rst_ni), // from register interface .we (recov_alert_sts_we), - .wd (recov_alert_sts_cs_main_sm_alert_wd), + .wd (recov_alert_sts_cs_main_sm_invalid_cmd_alert_wd), // from internal hardware - .de (hw2reg.recov_alert_sts.cs_main_sm_alert.de), - .d (hw2reg.recov_alert_sts.cs_main_sm_alert.d), + .de (hw2reg.recov_alert_sts.cs_main_sm_invalid_cmd_alert.de), + .d (hw2reg.recov_alert_sts.cs_main_sm_invalid_cmd_alert.d), // to internal hardware .qe (), @@ -1077,26 +1122,26 @@ module csrng_reg_top ( .ds (), // to register interface (read) - .qs (recov_alert_sts_cs_main_sm_alert_qs) + .qs (recov_alert_sts_cs_main_sm_invalid_cmd_alert_qs) ); - // F[cs_main_sm_invalid_cmd_seq]: 14:14 + // F[cs_main_sm_invalid_cmd_seq_alert]: 14:14 prim_subreg #( .DW (1), .SwAccess(prim_subreg_pkg::SwAccessW0C), .RESVAL (1'h0), .Mubi (1'b0) - ) u_recov_alert_sts_cs_main_sm_invalid_cmd_seq ( + ) u_recov_alert_sts_cs_main_sm_invalid_cmd_seq_alert ( .clk_i (clk_i), .rst_ni (rst_ni), // from register interface .we (recov_alert_sts_we), - .wd (recov_alert_sts_cs_main_sm_invalid_cmd_seq_wd), + .wd (recov_alert_sts_cs_main_sm_invalid_cmd_seq_alert_wd), // from internal hardware - .de (hw2reg.recov_alert_sts.cs_main_sm_invalid_cmd_seq.de), - .d (hw2reg.recov_alert_sts.cs_main_sm_invalid_cmd_seq.d), + .de (hw2reg.recov_alert_sts.cs_main_sm_invalid_cmd_seq_alert.de), + .d (hw2reg.recov_alert_sts.cs_main_sm_invalid_cmd_seq_alert.d), // to internal hardware .qe (), @@ -1104,7 +1149,34 @@ module csrng_reg_top ( .ds (), // to register interface (read) - .qs (recov_alert_sts_cs_main_sm_invalid_cmd_seq_qs) + .qs (recov_alert_sts_cs_main_sm_invalid_cmd_seq_alert_qs) + ); + + // F[cs_main_sm_reseed_cnt_alert]: 15:15 + prim_subreg #( + .DW (1), + .SwAccess(prim_subreg_pkg::SwAccessW0C), + .RESVAL (1'h0), + .Mubi (1'b0) + ) u_recov_alert_sts_cs_main_sm_reseed_cnt_alert ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (recov_alert_sts_we), + .wd (recov_alert_sts_cs_main_sm_reseed_cnt_alert_wd), + + // from internal hardware + .de (hw2reg.recov_alert_sts.cs_main_sm_reseed_cnt_alert.de), + .d (hw2reg.recov_alert_sts.cs_main_sm_reseed_cnt_alert.d), + + // to internal hardware + .qe (), + .q (), + .ds (), + + // to register interface (read) + .qs (recov_alert_sts_cs_main_sm_reseed_cnt_alert_qs) ); @@ -1884,7 +1956,7 @@ module csrng_reg_top ( - logic [16:0] addr_hit; + logic [17:0] addr_hit; always_comb begin addr_hit = '0; addr_hit[ 0] = (reg_addr == CSRNG_INTR_STATE_OFFSET); @@ -1894,16 +1966,17 @@ module csrng_reg_top ( addr_hit[ 4] = (reg_addr == CSRNG_REGWEN_OFFSET); addr_hit[ 5] = (reg_addr == CSRNG_CTRL_OFFSET); addr_hit[ 6] = (reg_addr == CSRNG_CMD_REQ_OFFSET); - addr_hit[ 7] = (reg_addr == CSRNG_SW_CMD_STS_OFFSET); - addr_hit[ 8] = (reg_addr == CSRNG_GENBITS_VLD_OFFSET); - addr_hit[ 9] = (reg_addr == CSRNG_GENBITS_OFFSET); - addr_hit[10] = (reg_addr == CSRNG_INT_STATE_NUM_OFFSET); - addr_hit[11] = (reg_addr == CSRNG_INT_STATE_VAL_OFFSET); - addr_hit[12] = (reg_addr == CSRNG_HW_EXC_STS_OFFSET); - addr_hit[13] = (reg_addr == CSRNG_RECOV_ALERT_STS_OFFSET); - addr_hit[14] = (reg_addr == CSRNG_ERR_CODE_OFFSET); - addr_hit[15] = (reg_addr == CSRNG_ERR_CODE_TEST_OFFSET); - addr_hit[16] = (reg_addr == CSRNG_MAIN_SM_STATE_OFFSET); + addr_hit[ 7] = (reg_addr == CSRNG_RESEED_INTERVAL_OFFSET); + addr_hit[ 8] = (reg_addr == CSRNG_SW_CMD_STS_OFFSET); + addr_hit[ 9] = (reg_addr == CSRNG_GENBITS_VLD_OFFSET); + addr_hit[10] = (reg_addr == CSRNG_GENBITS_OFFSET); + addr_hit[11] = (reg_addr == CSRNG_INT_STATE_NUM_OFFSET); + addr_hit[12] = (reg_addr == CSRNG_INT_STATE_VAL_OFFSET); + addr_hit[13] = (reg_addr == CSRNG_HW_EXC_STS_OFFSET); + addr_hit[14] = (reg_addr == CSRNG_RECOV_ALERT_STS_OFFSET); + addr_hit[15] = (reg_addr == CSRNG_ERR_CODE_OFFSET); + addr_hit[16] = (reg_addr == CSRNG_ERR_CODE_TEST_OFFSET); + addr_hit[17] = (reg_addr == CSRNG_MAIN_SM_STATE_OFFSET); end assign addrmiss = (reg_re || reg_we) ? ~|addr_hit : 1'b0 ; @@ -1927,7 +2000,8 @@ module csrng_reg_top ( (addr_hit[13] & (|(CSRNG_PERMIT[13] & ~reg_be))) | (addr_hit[14] & (|(CSRNG_PERMIT[14] & ~reg_be))) | (addr_hit[15] & (|(CSRNG_PERMIT[15] & ~reg_be))) | - (addr_hit[16] & (|(CSRNG_PERMIT[16] & ~reg_be))))); + (addr_hit[16] & (|(CSRNG_PERMIT[16] & ~reg_be))) | + (addr_hit[17] & (|(CSRNG_PERMIT[17] & ~reg_be))))); end // Generate write-enables @@ -1976,16 +2050,19 @@ module csrng_reg_top ( assign cmd_req_we = addr_hit[6] & reg_we & !reg_error; assign cmd_req_wd = reg_wdata[31:0]; - assign genbits_vld_re = addr_hit[8] & reg_re & !reg_error; - assign genbits_re = addr_hit[9] & reg_re & !reg_error; - assign int_state_num_we = addr_hit[10] & reg_we & !reg_error; + assign reseed_interval_we = addr_hit[7] & reg_we & !reg_error; + + assign reseed_interval_wd = reg_wdata[31:0]; + assign genbits_vld_re = addr_hit[9] & reg_re & !reg_error; + assign genbits_re = addr_hit[10] & reg_re & !reg_error; + assign int_state_num_we = addr_hit[11] & reg_we & !reg_error; assign int_state_num_wd = reg_wdata[3:0]; - assign int_state_val_re = addr_hit[11] & reg_re & !reg_error; - assign hw_exc_sts_we = addr_hit[12] & reg_we & !reg_error; + assign int_state_val_re = addr_hit[12] & reg_re & !reg_error; + assign hw_exc_sts_we = addr_hit[13] & reg_we & !reg_error; assign hw_exc_sts_wd = reg_wdata[15:0]; - assign recov_alert_sts_we = addr_hit[13] & reg_we & !reg_error; + assign recov_alert_sts_we = addr_hit[14] & reg_we & !reg_error; assign recov_alert_sts_enable_field_alert_wd = reg_wdata[0]; @@ -1997,10 +2074,12 @@ module csrng_reg_top ( assign recov_alert_sts_cs_bus_cmp_alert_wd = reg_wdata[12]; - assign recov_alert_sts_cs_main_sm_alert_wd = reg_wdata[13]; + assign recov_alert_sts_cs_main_sm_invalid_cmd_alert_wd = reg_wdata[13]; - assign recov_alert_sts_cs_main_sm_invalid_cmd_seq_wd = reg_wdata[14]; - assign err_code_test_we = addr_hit[15] & reg_we & !reg_error; + assign recov_alert_sts_cs_main_sm_invalid_cmd_seq_alert_wd = reg_wdata[14]; + + assign recov_alert_sts_cs_main_sm_reseed_cnt_alert_wd = reg_wdata[15]; + assign err_code_test_we = addr_hit[16] & reg_we & !reg_error; assign err_code_test_wd = reg_wdata[4:0]; @@ -2014,16 +2093,17 @@ module csrng_reg_top ( reg_we_check[4] = regwen_we; reg_we_check[5] = ctrl_gated_we; reg_we_check[6] = cmd_req_we; - reg_we_check[7] = 1'b0; + reg_we_check[7] = reseed_interval_we; reg_we_check[8] = 1'b0; reg_we_check[9] = 1'b0; - reg_we_check[10] = int_state_num_we; - reg_we_check[11] = 1'b0; - reg_we_check[12] = hw_exc_sts_we; - reg_we_check[13] = recov_alert_sts_we; - reg_we_check[14] = 1'b0; - reg_we_check[15] = err_code_test_gated_we; - reg_we_check[16] = 1'b0; + reg_we_check[10] = 1'b0; + reg_we_check[11] = int_state_num_we; + reg_we_check[12] = 1'b0; + reg_we_check[13] = hw_exc_sts_we; + reg_we_check[14] = recov_alert_sts_we; + reg_we_check[15] = 1'b0; + reg_we_check[16] = err_code_test_gated_we; + reg_we_check[17] = 1'b0; end // Read data return @@ -2071,43 +2151,48 @@ module csrng_reg_top ( end addr_hit[7]: begin + reg_rdata_next[31:0] = reseed_interval_qs; + end + + addr_hit[8]: begin reg_rdata_next[1] = sw_cmd_sts_cmd_rdy_qs; reg_rdata_next[2] = sw_cmd_sts_cmd_ack_qs; reg_rdata_next[4:3] = sw_cmd_sts_cmd_sts_qs; end - addr_hit[8]: begin + addr_hit[9]: begin reg_rdata_next[0] = genbits_vld_genbits_vld_qs; reg_rdata_next[1] = genbits_vld_genbits_fips_qs; end - addr_hit[9]: begin + addr_hit[10]: begin reg_rdata_next[31:0] = genbits_qs; end - addr_hit[10]: begin + addr_hit[11]: begin reg_rdata_next[3:0] = int_state_num_qs; end - addr_hit[11]: begin + addr_hit[12]: begin reg_rdata_next[31:0] = int_state_val_qs; end - addr_hit[12]: begin + addr_hit[13]: begin reg_rdata_next[15:0] = hw_exc_sts_qs; end - addr_hit[13]: begin + addr_hit[14]: begin reg_rdata_next[0] = recov_alert_sts_enable_field_alert_qs; reg_rdata_next[1] = recov_alert_sts_sw_app_enable_field_alert_qs; reg_rdata_next[2] = recov_alert_sts_read_int_state_field_alert_qs; reg_rdata_next[3] = recov_alert_sts_acmd_flag0_field_alert_qs; reg_rdata_next[12] = recov_alert_sts_cs_bus_cmp_alert_qs; - reg_rdata_next[13] = recov_alert_sts_cs_main_sm_alert_qs; - reg_rdata_next[14] = recov_alert_sts_cs_main_sm_invalid_cmd_seq_qs; + reg_rdata_next[13] = recov_alert_sts_cs_main_sm_invalid_cmd_alert_qs; + reg_rdata_next[14] = recov_alert_sts_cs_main_sm_invalid_cmd_seq_alert_qs; + reg_rdata_next[15] = recov_alert_sts_cs_main_sm_reseed_cnt_alert_qs; end - addr_hit[14]: begin + addr_hit[15]: begin reg_rdata_next[0] = err_code_sfifo_cmd_err_qs; reg_rdata_next[1] = err_code_sfifo_genbits_err_qs; reg_rdata_next[2] = err_code_sfifo_cmdreq_err_qs; @@ -2136,11 +2221,11 @@ module csrng_reg_top ( reg_rdata_next[30] = err_code_fifo_state_err_qs; end - addr_hit[15]: begin + addr_hit[16]: begin reg_rdata_next[4:0] = err_code_test_qs; end - addr_hit[16]: begin + addr_hit[17]: begin reg_rdata_next[7:0] = main_sm_state_qs; end diff --git a/hw/ip/edn/doc/registers.md b/hw/ip/edn/doc/registers.md index 4cbee03f72ee03..64b34f3109e431 100644 --- a/hw/ip/edn/doc/registers.md +++ b/hw/ip/edn/doc/registers.md @@ -3,25 +3,26 @@ ## Summary -| Name | Offset | Length | Description | -|:--------------------------------------------|:---------|---------:|:-------------------------------------------------------| -| csrng.[`INTR_STATE`](#intr_state) | 0x0 | 4 | Interrupt State Register | -| csrng.[`INTR_ENABLE`](#intr_enable) | 0x4 | 4 | Interrupt Enable Register | -| csrng.[`INTR_TEST`](#intr_test) | 0x8 | 4 | Interrupt Test Register | -| csrng.[`ALERT_TEST`](#alert_test) | 0xc | 4 | Alert Test Register | -| csrng.[`REGWEN`](#regwen) | 0x10 | 4 | Register write enable for all control registers | -| csrng.[`CTRL`](#ctrl) | 0x14 | 4 | Control register | -| csrng.[`CMD_REQ`](#cmd_req) | 0x18 | 4 | Command request register | -| csrng.[`SW_CMD_STS`](#sw_cmd_sts) | 0x1c | 4 | Application interface command status register | -| csrng.[`GENBITS_VLD`](#genbits_vld) | 0x20 | 4 | Generate bits returned valid register | -| csrng.[`GENBITS`](#genbits) | 0x24 | 4 | Generate bits returned register | -| csrng.[`INT_STATE_NUM`](#int_state_num) | 0x28 | 4 | Internal state number register | -| csrng.[`INT_STATE_VAL`](#int_state_val) | 0x2c | 4 | Internal state read access register | -| csrng.[`HW_EXC_STS`](#hw_exc_sts) | 0x30 | 4 | Hardware instance exception status register | -| csrng.[`RECOV_ALERT_STS`](#recov_alert_sts) | 0x34 | 4 | Recoverable alert status register | -| csrng.[`ERR_CODE`](#err_code) | 0x38 | 4 | Hardware detection of error conditions status register | -| csrng.[`ERR_CODE_TEST`](#err_code_test) | 0x3c | 4 | Test error conditions register | -| csrng.[`MAIN_SM_STATE`](#main_sm_state) | 0x40 | 4 | Main state machine state debug register | +| Name | Offset | Length | Description | +|:--------------------------------------------|:---------|---------:|:---------------------------------------------------------------------------| +| csrng.[`INTR_STATE`](#intr_state) | 0x0 | 4 | Interrupt State Register | +| csrng.[`INTR_ENABLE`](#intr_enable) | 0x4 | 4 | Interrupt Enable Register | +| csrng.[`INTR_TEST`](#intr_test) | 0x8 | 4 | Interrupt Test Register | +| csrng.[`ALERT_TEST`](#alert_test) | 0xc | 4 | Alert Test Register | +| csrng.[`REGWEN`](#regwen) | 0x10 | 4 | Register write enable for all control registers | +| csrng.[`CTRL`](#ctrl) | 0x14 | 4 | Control register | +| csrng.[`CMD_REQ`](#cmd_req) | 0x18 | 4 | Command request register | +| csrng.[`RESEED_INTERVAL`](#reseed_interval) | 0x1c | 4 | CSRNG maximum number of generate requests allowed between reseeds register | +| csrng.[`SW_CMD_STS`](#sw_cmd_sts) | 0x20 | 4 | Application interface command status register | +| csrng.[`GENBITS_VLD`](#genbits_vld) | 0x24 | 4 | Generate bits returned valid register | +| csrng.[`GENBITS`](#genbits) | 0x28 | 4 | Generate bits returned register | +| csrng.[`INT_STATE_NUM`](#int_state_num) | 0x2c | 4 | Internal state number register | +| csrng.[`INT_STATE_VAL`](#int_state_val) | 0x30 | 4 | Internal state read access register | +| csrng.[`HW_EXC_STS`](#hw_exc_sts) | 0x34 | 4 | Hardware instance exception status register | +| csrng.[`RECOV_ALERT_STS`](#recov_alert_sts) | 0x38 | 4 | Recoverable alert status register | +| csrng.[`ERR_CODE`](#err_code) | 0x3c | 4 | Hardware detection of error conditions status register | +| csrng.[`ERR_CODE_TEST`](#err_code_test) | 0x40 | 4 | Test error conditions register | +| csrng.[`MAIN_SM_STATE`](#main_sm_state) | 0x44 | 4 | Main state machine state debug register | ## INTR_STATE Interrupt State Register @@ -154,9 +155,36 @@ Command request register |:------:|:------:|:-------:|:--------|:------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| | 31:0 | wo | 0x0 | CMD_REQ | Writing this request with defined CSRNG commands will initiate all possible CSRNG actions. The application interface must wait for the "ack" to return before issuing new commands. | +## RESEED_INTERVAL +CSRNG maximum number of generate requests allowed between reseeds register +- Offset: `0x1c` +- Reset default: `0xffffffff` +- Reset mask: `0xffffffff` + +### Fields + +```wavejson +{"reg": [{"name": "RESEED_INTERVAL", "bits": 32, "attr": ["rw"], "rotate": 0}], "config": {"lanes": 1, "fontsize": 10, "vspace": 80}} +``` + +| Bits | Type | Reset | Name | +|:------:|:------:|:----------:|:-----------------------------------------------------| +| 31:0 | rw | 0xffffffff | [RESEED_INTERVAL](#reseed_interval--reseed_interval) | + +### RESEED_INTERVAL . RESEED_INTERVAL +Setting this field will set the number of generate requests that can be +made to CSRNG before a reseed request needs to be made. +This register supports a maximum of 2^32 requests between reseeds. +This register will be compared to a counter, which counts the number of +generate commands between reseed or instantiate commands. +If the counter reaches the value of this register the violating command +will be acknowledged with a status error. +If the violating command was issued by a HW instance, an interrupt will +be triggered. + ## SW_CMD_STS Application interface command status register -- Offset: `0x1c` +- Offset: `0x20` - Reset default: `0x0` - Reset mask: `0x1e` @@ -189,6 +217,8 @@ To check whether a command was succesful, wait for [`INTR_STATE.CS_CMD_REQ_DONE` 0x3: This error indicates that the last command was issued out of sequence. This happens when a command other than instantiate was issued without sending an instantiate command first. This can also happen when an uninstantiate command is sent without instantiating first. +0x5: This error indicates that the number of generate commands between reseeds exceeded the maximum number allowed. + This happens only for generate commands. ### SW_CMD_STS . CMD_ACK This one bit field indicates when a SW command has been acknowledged by the CSRNG. @@ -205,7 +235,7 @@ Before starting to write a new command to [`SW_CMD_REQ`](#sw_cmd_req), this fiel ## GENBITS_VLD Generate bits returned valid register -- Offset: `0x20` +- Offset: `0x24` - Reset default: `0x0` - Reset mask: `0x3` @@ -223,7 +253,7 @@ Generate bits returned valid register ## GENBITS Generate bits returned register -- Offset: `0x24` +- Offset: `0x28` - Reset default: `0x0` - Reset mask: `0xffffffff` @@ -249,7 +279,7 @@ Otherwise, the register reads as 0. ## INT_STATE_NUM Internal state number register -- Offset: `0x28` +- Offset: `0x2c` - Reset default: `0x0` - Reset mask: `0xf` @@ -277,7 +307,7 @@ that the [`INT_STATE_VAL`](#int_state_val) read back is accurate. ## INT_STATE_VAL Internal state read access register -- Offset: `0x2c` +- Offset: `0x30` - Reset default: `0x0` - Reset mask: `0xffffffff` @@ -304,7 +334,7 @@ Otherwise, the register reads as 0. ## HW_EXC_STS Hardware instance exception status register -- Offset: `0x30` +- Offset: `0x34` - Reset default: `0x0` - Reset mask: `0xffff` @@ -329,29 +359,36 @@ resets the status bits. ## RECOV_ALERT_STS Recoverable alert status register -- Offset: `0x34` +- Offset: `0x38` - Reset default: `0x0` -- Reset mask: `0x700f` +- Reset mask: `0xf00f` ### Fields ```wavejson -{"reg": [{"name": "ENABLE_FIELD_ALERT", "bits": 1, "attr": ["rw0c"], "rotate": -90}, {"name": "SW_APP_ENABLE_FIELD_ALERT", "bits": 1, "attr": ["rw0c"], "rotate": -90}, {"name": "READ_INT_STATE_FIELD_ALERT", "bits": 1, "attr": ["rw0c"], "rotate": -90}, {"name": "ACMD_FLAG0_FIELD_ALERT", "bits": 1, "attr": ["rw0c"], "rotate": -90}, {"bits": 8}, {"name": "CS_BUS_CMP_ALERT", "bits": 1, "attr": ["rw0c"], "rotate": -90}, {"name": "CS_MAIN_SM_ALERT", "bits": 1, "attr": ["rw0c"], "rotate": -90}, {"name": "CS_MAIN_SM_INVALID_CMD_SEQ", "bits": 1, "attr": ["rw0c"], "rotate": -90}, {"bits": 17}], "config": {"lanes": 1, "fontsize": 10, "vspace": 280}} +{"reg": [{"name": "ENABLE_FIELD_ALERT", "bits": 1, "attr": ["rw0c"], "rotate": -90}, {"name": "SW_APP_ENABLE_FIELD_ALERT", "bits": 1, "attr": ["rw0c"], "rotate": -90}, {"name": "READ_INT_STATE_FIELD_ALERT", "bits": 1, "attr": ["rw0c"], "rotate": -90}, {"name": "ACMD_FLAG0_FIELD_ALERT", "bits": 1, "attr": ["rw0c"], "rotate": -90}, {"bits": 8}, {"name": "CS_BUS_CMP_ALERT", "bits": 1, "attr": ["rw0c"], "rotate": -90}, {"name": "CS_MAIN_SM_INVALID_CMD_ALERT", "bits": 1, "attr": ["rw0c"], "rotate": -90}, {"name": "CS_MAIN_SM_INVALID_CMD_SEQ_ALERT", "bits": 1, "attr": ["rw0c"], "rotate": -90}, {"name": "CS_MAIN_SM_RESEED_CNT_ALERT", "bits": 1, "attr": ["rw0c"], "rotate": -90}, {"bits": 16}], "config": {"lanes": 1, "fontsize": 10, "vspace": 340}} ``` -| Bits | Type | Reset | Name | -|:------:|:------:|:-------:|:---------------------------------------------------------------------------| -| 31:15 | | | Reserved | -| 14 | rw0c | 0x0 | [CS_MAIN_SM_INVALID_CMD_SEQ](#recov_alert_sts--cs_main_sm_invalid_cmd_seq) | -| 13 | rw0c | 0x0 | [CS_MAIN_SM_ALERT](#recov_alert_sts--cs_main_sm_alert) | -| 12 | rw0c | 0x0 | [CS_BUS_CMP_ALERT](#recov_alert_sts--cs_bus_cmp_alert) | -| 11:4 | | | Reserved | -| 3 | rw0c | 0x0 | [ACMD_FLAG0_FIELD_ALERT](#recov_alert_sts--acmd_flag0_field_alert) | -| 2 | rw0c | 0x0 | [READ_INT_STATE_FIELD_ALERT](#recov_alert_sts--read_int_state_field_alert) | -| 1 | rw0c | 0x0 | [SW_APP_ENABLE_FIELD_ALERT](#recov_alert_sts--sw_app_enable_field_alert) | -| 0 | rw0c | 0x0 | [ENABLE_FIELD_ALERT](#recov_alert_sts--enable_field_alert) | - -### RECOV_ALERT_STS . CS_MAIN_SM_INVALID_CMD_SEQ +| Bits | Type | Reset | Name | +|:------:|:------:|:-------:|:---------------------------------------------------------------------------------------| +| 31:16 | | | Reserved | +| 15 | rw0c | 0x0 | [CS_MAIN_SM_RESEED_CNT_ALERT](#recov_alert_sts--cs_main_sm_reseed_cnt_alert) | +| 14 | rw0c | 0x0 | [CS_MAIN_SM_INVALID_CMD_SEQ_ALERT](#recov_alert_sts--cs_main_sm_invalid_cmd_seq_alert) | +| 13 | rw0c | 0x0 | [CS_MAIN_SM_INVALID_CMD_ALERT](#recov_alert_sts--cs_main_sm_invalid_cmd_alert) | +| 12 | rw0c | 0x0 | [CS_BUS_CMP_ALERT](#recov_alert_sts--cs_bus_cmp_alert) | +| 11:4 | | | Reserved | +| 3 | rw0c | 0x0 | [ACMD_FLAG0_FIELD_ALERT](#recov_alert_sts--acmd_flag0_field_alert) | +| 2 | rw0c | 0x0 | [READ_INT_STATE_FIELD_ALERT](#recov_alert_sts--read_int_state_field_alert) | +| 1 | rw0c | 0x0 | [SW_APP_ENABLE_FIELD_ALERT](#recov_alert_sts--sw_app_enable_field_alert) | +| 0 | rw0c | 0x0 | [ENABLE_FIELD_ALERT](#recov_alert_sts--enable_field_alert) | + +### RECOV_ALERT_STS . CS_MAIN_SM_RESEED_CNT_ALERT +This bit is set when the maximum number of generate requests between reseeds is +exceeded. +The invalid generate command is ignored and CSRNG continues to operate. +Writing a zero resets this status bit. + +### RECOV_ALERT_STS . CS_MAIN_SM_INVALID_CMD_SEQ_ALERT This bit is set when an out of order command is received by the main state machine. This happens when an instantiate command is sent for a state that was already instantiated or when any command other than instantiate is sent for a state that @@ -359,7 +396,7 @@ wasn't instantiated yet. The invalid command is ignored and CSRNG continues to operate. Writing a zero resets this status bit. -### RECOV_ALERT_STS . CS_MAIN_SM_ALERT +### RECOV_ALERT_STS . CS_MAIN_SM_INVALID_CMD_ALERT This bit is set when an unsupported/illegal CSRNG command is received by the main state machine. The invalid command is ignored and CSRNG continues to operate. @@ -392,7 +429,7 @@ Writing a zero resets this status bit. ## ERR_CODE Hardware detection of error conditions status register -- Offset: `0x38` +- Offset: `0x3c` - Reset default: `0x0` - Reset mask: `0x77f0ffff` @@ -593,7 +630,7 @@ This bit will stay set until the next reset. ## ERR_CODE_TEST Test error conditions register -- Offset: `0x3c` +- Offset: `0x40` - Reset default: `0x0` - Reset mask: `0x1f` - Register enable: [`REGWEN`](#regwen) @@ -619,7 +656,7 @@ an interrupt or an alert. ## MAIN_SM_STATE Main state machine state debug register -- Offset: `0x40` +- Offset: `0x44` - Reset default: `0x4e` - Reset mask: `0xff`