| // Copyright lowRISC contributors. |
| // Licensed under the Apache License, Version 2.0, see LICENSE for details. |
| // SPDX-License-Identifier: Apache-2.0 |
| // |
| // Description: entropy_src core module |
| // |
| |
| module entropy_src_core import entropy_src_pkg::*; #( |
| parameter int EsFifoDepth = 4 |
| ) ( |
| input logic clk_i, |
| input logic rst_ni, |
| |
| input entropy_src_reg_pkg::entropy_src_reg2hw_t reg2hw, |
| output entropy_src_reg_pkg::entropy_src_hw2reg_t hw2reg, |
| |
| // Efuse Interface |
| input prim_mubi_pkg::mubi8_t otp_en_entropy_src_fw_read_i, |
| input prim_mubi_pkg::mubi8_t otp_en_entropy_src_fw_over_i, |
| |
| // RNG Interface |
| output logic rng_fips_o, |
| |
| // Entropy Interface |
| input entropy_src_hw_if_req_t entropy_src_hw_if_i, |
| output entropy_src_hw_if_rsp_t entropy_src_hw_if_o, |
| |
| // RNG Interface |
| output entropy_src_rng_req_t entropy_src_rng_o, |
| input entropy_src_rng_rsp_t entropy_src_rng_i, |
| |
| // CSRNG Interface |
| output cs_aes_halt_req_t cs_aes_halt_o, |
| input cs_aes_halt_rsp_t cs_aes_halt_i, |
| |
| // External Health Test Interface |
| output entropy_src_xht_req_t entropy_src_xht_o, |
| input entropy_src_xht_rsp_t entropy_src_xht_i, |
| |
| output logic recov_alert_test_o, |
| output logic fatal_alert_test_o, |
| output logic recov_alert_o, |
| output logic fatal_alert_o, |
| |
| output logic intr_es_entropy_valid_o, |
| output logic intr_es_health_test_failed_o, |
| output logic intr_es_observe_fifo_ready_o, |
| output logic intr_es_fatal_err_o |
| ); |
| |
| import entropy_src_reg_pkg::*; |
| import prim_mubi_pkg::mubi4_t; |
| import prim_mubi_pkg::mubi4_test_true_strict; |
| import prim_mubi_pkg::mubi4_and_hi; |
| import prim_mubi_pkg::mubi4_test_false_loose; |
| import prim_mubi_pkg::mubi4_test_invalid; |
| |
| localparam int Clog2EsFifoDepth = $clog2(EsFifoDepth); |
| localparam int PostHTWidth = 32; |
| localparam int RngBusWidth = 4; |
| localparam int HalfRegWidth = 16; |
| localparam int FullRegWidth = 32; |
| localparam int EighthRegWidth = 4; |
| localparam int SeedLen = 384; |
| localparam int ObserveFifoWidth = 32; |
| localparam int ObserveFifoDepth = 64; |
| localparam int PreCondWidth = 64; |
| localparam int Clog2ObserveFifoDepth = $clog2(ObserveFifoDepth); |
| localparam int EsEnableCopies = 20; |
| localparam int EsEnPulseCopies = 1; |
| |
| //----------------------- |
| // SHA3parameters |
| //----------------------- |
| // Do not enable masking |
| localparam bit Sha3EnMasking = 0; |
| // derived parameter |
| localparam int Sha3Share = (Sha3EnMasking) ? 2 : 1; |
| |
| // signals |
| logic fw_ov_mode; |
| logic fw_ov_mode_pfe; |
| logic fw_ov_mode_pfa; |
| logic fw_ov_wr_fifo_full; |
| logic fw_ov_mode_entropy_insert; |
| logic fw_ov_entropy_insert_pfe; |
| logic fw_ov_entropy_insert_pfa; |
| logic fw_ov_sha3_start_pfe; |
| logic fw_ov_sha3_start_pfe_q; |
| logic fw_ov_sha3_start_pfa; |
| logic fw_ov_sha3_disable_pulse; |
| logic [ObserveFifoWidth-1:0] fw_ov_wr_data; |
| logic fw_ov_fifo_rd_pulse; |
| logic fw_ov_fifo_wr_pulse; |
| logic es_enable_pfa; |
| |
| logic fips_enable_pfe; |
| logic fips_enable_pfa; |
| |
| logic rng_bit_en; |
| logic rng_bit_enable_pfe; |
| logic rng_bit_enable_pfa; |
| logic [1:0] rng_bit_sel; |
| logic rng_enable_q, rng_enable_d; |
| logic entropy_data_reg_en_pfe; |
| logic entropy_data_reg_en_pfa; |
| logic es_data_reg_rd_en; |
| logic sw_es_rd_pulse; |
| logic event_es_entropy_valid; |
| logic event_es_health_test_failed; |
| logic event_es_observe_fifo_ready; |
| logic event_es_fatal_err; |
| logic es_rng_src_valid; |
| logic [RngBusWidth-1:0] es_rng_bus; |
| |
| logic [RngBusWidth-1:0] sfifo_esrng_wdata; |
| logic [RngBusWidth-1:0] sfifo_esrng_rdata; |
| logic sfifo_esrng_push; |
| logic sfifo_esrng_pop; |
| logic sfifo_esrng_clr; |
| logic sfifo_esrng_full; |
| logic sfifo_esrng_not_empty; |
| logic sfifo_esrng_not_full; |
| logic [2:0] sfifo_esrng_err; |
| |
| logic [ObserveFifoWidth-1:0] sfifo_observe_wdata; |
| logic [ObserveFifoWidth-1:0] sfifo_observe_rdata; |
| logic sfifo_observe_push; |
| logic sfifo_observe_pop; |
| logic sfifo_observe_full; |
| logic sfifo_observe_clr; |
| logic sfifo_observe_not_empty; |
| logic [Clog2ObserveFifoDepth:0] sfifo_observe_depth; |
| logic [2:0] sfifo_observe_err; |
| |
| logic [Clog2EsFifoDepth:0] sfifo_esfinal_depth; |
| logic [(1+SeedLen)-1:0] sfifo_esfinal_wdata; |
| logic [(1+SeedLen)-1:0] sfifo_esfinal_rdata; |
| logic sfifo_esfinal_push_enable; |
| logic sfifo_esfinal_push; |
| logic sfifo_esfinal_pop; |
| logic sfifo_esfinal_clr; |
| logic sfifo_esfinal_not_full; |
| logic sfifo_esfinal_full; |
| logic sfifo_esfinal_not_empty; |
| logic [2:0] sfifo_esfinal_err; |
| logic [SeedLen-1:0] esfinal_data; |
| logic esfinal_fips_flag; |
| |
| logic any_fail_pulse; |
| logic main_stage_push; |
| logic main_stage_push_raw; |
| logic bypass_stage_pop; |
| logic boot_phase_done; |
| logic [HalfRegWidth-1:0] any_fail_count; |
| logic any_fails_cntr_err; |
| logic alert_threshold_fail; |
| logic [HalfRegWidth-1:0] alert_threshold; |
| logic [HalfRegWidth-1:0] alert_threshold_inv; |
| logic [Clog2ObserveFifoDepth:0] observe_fifo_thresh; |
| logic observe_fifo_thresh_met; |
| logic repcnt_active; |
| logic repcnts_active; |
| logic adaptp_active; |
| logic bucket_active; |
| logic markov_active; |
| logic extht_active; |
| logic alert_cntrs_clr; |
| logic health_test_clr; |
| logic health_test_done_pulse; |
| logic [RngBusWidth-1:0] health_test_esbus; |
| logic health_test_esbus_vld; |
| logic es_route_pfe; |
| logic es_route_pfa; |
| logic es_type_pfe; |
| logic es_type_pfa; |
| logic es_route_to_sw; |
| logic es_bypass_to_sw; |
| logic es_bypass_mode; |
| logic rst_alert_cntr; |
| logic threshold_scope; |
| logic threshold_scope_pfe; |
| logic threshold_scope_pfa; |
| logic fips_compliance; |
| |
| logic [HalfRegWidth-1:0] health_test_fips_window; |
| logic [HalfRegWidth-1:0] health_test_bypass_window; |
| logic [HalfRegWidth-1:0] health_test_window; |
| |
| logic [HalfRegWidth-1:0] repcnt_fips_threshold; |
| logic [HalfRegWidth-1:0] repcnt_fips_threshold_oneway; |
| logic repcnt_fips_threshold_wr; |
| logic [HalfRegWidth-1:0] repcnt_bypass_threshold; |
| logic [HalfRegWidth-1:0] repcnt_bypass_threshold_oneway; |
| logic repcnt_bypass_threshold_wr; |
| logic [HalfRegWidth-1:0] repcnt_threshold; |
| logic [HalfRegWidth-1:0] repcnt_event_cnt; |
| logic [HalfRegWidth-1:0] repcnt_event_hwm_fips; |
| logic [HalfRegWidth-1:0] repcnt_event_hwm_bypass; |
| logic [FullRegWidth-1:0] repcnt_total_fails; |
| logic [EighthRegWidth-1:0] repcnt_fail_count; |
| logic repcnt_fail_pulse; |
| logic repcnt_fails_cntr_err; |
| logic repcnt_alert_cntr_err; |
| |
| logic [HalfRegWidth-1:0] repcnts_fips_threshold; |
| logic [HalfRegWidth-1:0] repcnts_fips_threshold_oneway; |
| logic repcnts_fips_threshold_wr; |
| logic [HalfRegWidth-1:0] repcnts_bypass_threshold; |
| logic [HalfRegWidth-1:0] repcnts_bypass_threshold_oneway; |
| logic repcnts_bypass_threshold_wr; |
| logic [HalfRegWidth-1:0] repcnts_threshold; |
| logic [HalfRegWidth-1:0] repcnts_event_cnt; |
| logic [HalfRegWidth-1:0] repcnts_event_hwm_fips; |
| logic [HalfRegWidth-1:0] repcnts_event_hwm_bypass; |
| logic [FullRegWidth-1:0] repcnts_total_fails; |
| logic [EighthRegWidth-1:0] repcnts_fail_count; |
| logic repcnts_fail_pulse; |
| logic repcnts_fails_cntr_err; |
| logic repcnts_alert_cntr_err; |
| |
| logic [HalfRegWidth-1:0] adaptp_hi_fips_threshold; |
| logic [HalfRegWidth-1:0] adaptp_hi_fips_threshold_oneway; |
| logic adaptp_hi_fips_threshold_wr; |
| logic [HalfRegWidth-1:0] adaptp_hi_bypass_threshold; |
| logic [HalfRegWidth-1:0] adaptp_hi_bypass_threshold_oneway; |
| logic adaptp_hi_bypass_threshold_wr; |
| logic [HalfRegWidth-1:0] adaptp_hi_threshold; |
| logic [HalfRegWidth-1:0] adaptp_lo_fips_threshold; |
| logic [HalfRegWidth-1:0] adaptp_lo_fips_threshold_oneway; |
| logic adaptp_lo_fips_threshold_wr; |
| logic [HalfRegWidth-1:0] adaptp_lo_bypass_threshold; |
| logic [HalfRegWidth-1:0] adaptp_lo_bypass_threshold_oneway; |
| logic adaptp_lo_bypass_threshold_wr; |
| logic [HalfRegWidth-1:0] adaptp_lo_threshold; |
| logic [HalfRegWidth-1:0] adaptp_hi_event_cnt; |
| logic [HalfRegWidth-1:0] adaptp_lo_event_cnt; |
| logic [HalfRegWidth-1:0] adaptp_hi_event_hwm_fips; |
| logic [HalfRegWidth-1:0] adaptp_hi_event_hwm_bypass; |
| logic [HalfRegWidth-1:0] adaptp_lo_event_hwm_fips; |
| logic [HalfRegWidth-1:0] adaptp_lo_event_hwm_bypass; |
| logic [FullRegWidth-1:0] adaptp_hi_total_fails; |
| logic [FullRegWidth-1:0] adaptp_lo_total_fails; |
| logic [EighthRegWidth-1:0] adaptp_hi_fail_count; |
| logic [EighthRegWidth-1:0] adaptp_lo_fail_count; |
| logic adaptp_hi_fail_pulse; |
| logic adaptp_lo_fail_pulse; |
| logic adaptp_hi_fails_cntr_err; |
| logic adaptp_lo_fails_cntr_err; |
| logic adaptp_hi_alert_cntr_err; |
| logic adaptp_lo_alert_cntr_err; |
| |
| logic [HalfRegWidth-1:0] bucket_fips_threshold; |
| logic [HalfRegWidth-1:0] bucket_fips_threshold_oneway; |
| logic bucket_fips_threshold_wr; |
| logic [HalfRegWidth-1:0] bucket_bypass_threshold; |
| logic [HalfRegWidth-1:0] bucket_bypass_threshold_oneway; |
| logic bucket_bypass_threshold_wr; |
| logic [HalfRegWidth-1:0] bucket_threshold; |
| logic [HalfRegWidth-1:0] bucket_event_cnt; |
| logic [HalfRegWidth-1:0] bucket_event_hwm_fips; |
| logic [HalfRegWidth-1:0] bucket_event_hwm_bypass; |
| logic [FullRegWidth-1:0] bucket_total_fails; |
| logic [EighthRegWidth-1:0] bucket_fail_count; |
| logic bucket_fail_pulse; |
| logic bucket_fails_cntr_err; |
| logic bucket_alert_cntr_err; |
| |
| logic [HalfRegWidth-1:0] markov_hi_fips_threshold; |
| logic [HalfRegWidth-1:0] markov_hi_fips_threshold_oneway; |
| logic markov_hi_fips_threshold_wr; |
| logic [HalfRegWidth-1:0] markov_hi_bypass_threshold; |
| logic [HalfRegWidth-1:0] markov_hi_bypass_threshold_oneway; |
| logic markov_hi_bypass_threshold_wr; |
| logic [HalfRegWidth-1:0] markov_hi_threshold; |
| logic [HalfRegWidth-1:0] markov_lo_fips_threshold; |
| logic [HalfRegWidth-1:0] markov_lo_fips_threshold_oneway; |
| logic markov_lo_fips_threshold_wr; |
| logic [HalfRegWidth-1:0] markov_lo_bypass_threshold; |
| logic [HalfRegWidth-1:0] markov_lo_bypass_threshold_oneway; |
| logic markov_lo_bypass_threshold_wr; |
| logic [HalfRegWidth-1:0] markov_lo_threshold; |
| logic [HalfRegWidth-1:0] markov_hi_event_cnt; |
| logic [HalfRegWidth-1:0] markov_lo_event_cnt; |
| logic [HalfRegWidth-1:0] markov_hi_event_hwm_fips; |
| logic [HalfRegWidth-1:0] markov_hi_event_hwm_bypass; |
| logic [HalfRegWidth-1:0] markov_lo_event_hwm_fips; |
| logic [HalfRegWidth-1:0] markov_lo_event_hwm_bypass; |
| logic [FullRegWidth-1:0] markov_hi_total_fails; |
| logic [FullRegWidth-1:0] markov_lo_total_fails; |
| logic [EighthRegWidth-1:0] markov_hi_fail_count; |
| logic [EighthRegWidth-1:0] markov_lo_fail_count; |
| logic markov_hi_fail_pulse; |
| logic markov_lo_fail_pulse; |
| logic markov_hi_fails_cntr_err; |
| logic markov_lo_fails_cntr_err; |
| logic markov_hi_alert_cntr_err; |
| logic markov_lo_alert_cntr_err; |
| |
| logic [HalfRegWidth-1:0] extht_hi_fips_threshold; |
| logic [HalfRegWidth-1:0] extht_hi_fips_threshold_oneway; |
| logic extht_hi_fips_threshold_wr; |
| logic [HalfRegWidth-1:0] extht_hi_bypass_threshold; |
| logic [HalfRegWidth-1:0] extht_hi_bypass_threshold_oneway; |
| logic extht_hi_bypass_threshold_wr; |
| logic [HalfRegWidth-1:0] extht_hi_threshold; |
| logic [HalfRegWidth-1:0] extht_lo_fips_threshold; |
| logic [HalfRegWidth-1:0] extht_lo_fips_threshold_oneway; |
| logic extht_lo_fips_threshold_wr; |
| logic [HalfRegWidth-1:0] extht_lo_bypass_threshold; |
| logic [HalfRegWidth-1:0] extht_lo_bypass_threshold_oneway; |
| logic extht_lo_bypass_threshold_wr; |
| logic [HalfRegWidth-1:0] extht_lo_threshold; |
| logic [HalfRegWidth-1:0] extht_event_cnt_hi; |
| logic [HalfRegWidth-1:0] extht_event_cnt_lo; |
| logic [HalfRegWidth-1:0] extht_hi_event_hwm_fips; |
| logic [HalfRegWidth-1:0] extht_hi_event_hwm_bypass; |
| logic [HalfRegWidth-1:0] extht_lo_event_hwm_fips; |
| logic [HalfRegWidth-1:0] extht_lo_event_hwm_bypass; |
| logic [FullRegWidth-1:0] extht_hi_total_fails; |
| logic [FullRegWidth-1:0] extht_lo_total_fails; |
| logic [EighthRegWidth-1:0] extht_hi_fail_count; |
| logic [EighthRegWidth-1:0] extht_lo_fail_count; |
| logic extht_hi_fail_pulse; |
| logic extht_lo_fail_pulse; |
| logic extht_cont_test; |
| logic extht_hi_fails_cntr_err; |
| logic extht_lo_fails_cntr_err; |
| logic extht_hi_alert_cntr_err; |
| logic extht_lo_alert_cntr_err; |
| |
| |
| logic pfifo_esbit_wdata; |
| logic [RngBusWidth-1:0] pfifo_esbit_rdata; |
| logic pfifo_esbit_not_empty; |
| logic pfifo_esbit_not_full; |
| logic pfifo_esbit_push; |
| logic pfifo_esbit_clr; |
| logic pfifo_esbit_pop; |
| |
| logic [RngBusWidth-1:0] pfifo_postht_wdata; |
| logic [PostHTWidth-1:0] pfifo_postht_rdata; |
| logic pfifo_postht_not_empty; |
| logic pfifo_postht_not_full; |
| logic pfifo_postht_push; |
| logic pfifo_postht_clr; |
| logic pfifo_postht_pop; |
| |
| logic [PreCondWidth-1:0] pfifo_cond_wdata; |
| logic [SeedLen-1:0] pfifo_cond_rdata; |
| logic pfifo_cond_not_empty; |
| logic pfifo_cond_push; |
| |
| logic [ObserveFifoWidth-1:0] pfifo_precon_wdata; |
| logic [PreCondWidth-1:0] pfifo_precon_rdata; |
| logic pfifo_precon_not_empty; |
| logic pfifo_precon_not_full; |
| logic pfifo_precon_push; |
| logic pfifo_precon_clr; |
| logic pfifo_precon_pop; |
| |
| logic [PostHTWidth-1:0] pfifo_bypass_wdata; |
| logic [SeedLen-1:0] pfifo_bypass_rdata; |
| logic pfifo_bypass_not_empty; |
| logic pfifo_bypass_not_full; |
| logic pfifo_bypass_push; |
| logic pfifo_bypass_clr; |
| logic pfifo_bypass_pop; |
| |
| logic [SeedLen-1:0] pfifo_swread_wdata; |
| logic pfifo_swread_not_full; |
| logic [FullRegWidth-1:0] pfifo_swread_rdata; |
| logic pfifo_swread_not_empty; |
| logic pfifo_swread_push; |
| logic pfifo_swread_clr; |
| logic pfifo_swread_pop; |
| |
| logic [SeedLen-1:0] final_es_data; |
| logic es_hw_if_req; |
| logic es_hw_if_ack; |
| logic es_hw_if_fifo_pop; |
| logic sfifo_esrng_err_sum; |
| logic sfifo_observe_err_sum; |
| logic sfifo_esfinal_err_sum; |
| // For fifo errors that are generated through the |
| // ERR_CODE_TEST register, but are not associated |
| // with any errors: |
| logic sfifo_test_err_sum; |
| logic es_ack_sm_err_sum; |
| logic es_ack_sm_err; |
| logic es_main_sm_err_sum; |
| logic es_main_sm_err; |
| logic es_main_sm_alert; |
| logic es_bus_cmp_alert; |
| logic es_thresh_cfg_alert; |
| logic es_main_sm_idle; |
| logic [8:0] es_main_sm_state; |
| logic fifo_write_err_sum; |
| logic fifo_read_err_sum; |
| logic fifo_status_err_sum; |
| logic [30:0] err_code_test_bit; |
| logic sha3_msgfifo_ready; |
| logic sha3_state_vld; |
| logic sha3_start_raw; |
| logic sha3_start; |
| logic sha3_process; |
| logic sha3_msg_end; |
| logic sha3_msg_rdy_mask; |
| logic sha3_block_processed; |
| prim_mubi_pkg::mubi4_t sha3_done; |
| prim_mubi_pkg::mubi4_t sha3_absorbed; |
| logic sha3_squeezing; |
| logic [2:0] sha3_fsm; |
| logic [32:0] sha3_err; |
| logic cs_aes_halt_req; |
| logic sha3_msg_rdy; |
| logic [HalfRegWidth-1:0] window_cntr; |
| |
| logic [sha3_pkg::StateW-1:0] sha3_state[Sha3Share]; |
| logic [PreCondWidth-1:0] msg_data[Sha3Share]; |
| logic es_rdata_capt_vld; |
| logic window_cntr_err; |
| logic repcnt_cntr_err; |
| logic repcnts_cntr_err; |
| logic adaptp_cntr_err; |
| logic bucket_cntr_err; |
| logic markov_cntr_err; |
| logic es_cntr_err; |
| logic es_cntr_err_sum; |
| logic sha3_state_error_sum; |
| logic sha3_rst_storage_err_sum; |
| logic efuse_es_sw_reg_en; |
| logic efuse_es_sw_ov_en; |
| |
| logic sha3_state_error; |
| logic sha3_count_error; |
| logic sha3_rst_storage_err; |
| logic es_hw_regwen; |
| logic recov_alert_state; |
| logic es_fw_ov_wr_alert; |
| logic es_fw_ov_disable_alert; |
| logic fw_ov_corrupted; |
| |
| logic stale_seed_processing; |
| logic main_sm_enable; |
| |
| logic unused_err_code_test_bit; |
| logic unused_sha3_state; |
| logic unused_entropy_data; |
| logic unused_fw_ov_rd_data; |
| |
| prim_mubi_pkg::mubi8_t en_entropy_src_fw_read; |
| prim_mubi_pkg::mubi8_t en_entropy_src_fw_over; |
| |
| mubi4_t mubi_es_enable; |
| mubi4_t mubi_module_en_pulse; |
| |
| mubi4_t mubi_module_en_raw; |
| mubi4_t [2:0] mubi_module_en_raw_fanout; |
| |
| mubi4_t [EsEnableCopies-1:0] mubi_es_enable_fanout; |
| logic [EsEnableCopies-1:0] es_enable_fo; |
| |
| mubi4_t [EsEnPulseCopies-1:0] mubi_module_en_pulse_fanout; |
| logic [EsEnPulseCopies-1:0] module_en_pulse_fo; |
| |
| // A delayed copy of the enable signal, and enable pulse which are needed to cleanly handle any |
| // long-duration operations from the previous run. |
| logic es_delayed_enable; |
| |
| mubi4_t [1:0] mubi_rng_bit_en_fanout; |
| mubi4_t mubi_rng_bit_en; |
| |
| // flops |
| logic ht_failed_q, ht_failed_d; |
| logic ht_done_pulse_q, ht_done_pulse_d; |
| logic sha3_err_q, sha3_err_d; |
| logic cs_aes_halt_q, cs_aes_halt_d; |
| logic [63:0] es_rdata_capt_q, es_rdata_capt_d; |
| logic es_rdata_capt_vld_q, es_rdata_capt_vld_d; |
| logic sha3_msg_rdy_mask_q, sha3_msg_rdy_mask_d; |
| mubi4_t mubi_mod_en_dly_d, mubi_mod_en_dly_q; |
| |
| |
| logic sha3_start_mask_q, sha3_start_mask_d; |
| logic sha3_flush_q, sha3_flush_d; |
| logic [1:0] fw_ov_corrupted_q, fw_ov_corrupted_d; |
| |
| always_ff @(posedge clk_i or negedge rst_ni) begin |
| if (!rst_ni) begin |
| ht_failed_q <= '0; |
| ht_done_pulse_q <= '0; |
| sha3_err_q <= '0; |
| cs_aes_halt_q <= '0; |
| es_rdata_capt_q <= '0; |
| es_rdata_capt_vld_q <= '0; |
| fw_ov_sha3_start_pfe_q <= '0; |
| sha3_msg_rdy_mask_q <= '0; |
| mubi_mod_en_dly_q <= prim_mubi_pkg::MuBi4False; |
| sha3_flush_q <= '0; |
| sha3_start_mask_q <= '0; |
| fw_ov_corrupted_q <= 2'b00; |
| rng_enable_q <= 1'b 0; |
| end else begin |
| ht_failed_q <= ht_failed_d; |
| ht_done_pulse_q <= ht_done_pulse_d; |
| sha3_err_q <= sha3_err_d; |
| cs_aes_halt_q <= cs_aes_halt_d; |
| es_rdata_capt_q <= es_rdata_capt_d; |
| es_rdata_capt_vld_q <= es_rdata_capt_vld_d; |
| fw_ov_sha3_start_pfe_q <= fw_ov_sha3_start_pfe; |
| sha3_msg_rdy_mask_q <= sha3_msg_rdy_mask_d; |
| sha3_flush_q <= sha3_flush_d; |
| sha3_start_mask_q <= sha3_start_mask_d; |
| mubi_mod_en_dly_q <= mubi_mod_en_dly_d; |
| fw_ov_corrupted_q <= fw_ov_corrupted_d; |
| rng_enable_q <= rng_enable_d; |
| end |
| end |
| |
| assign fw_ov_sha3_disable_pulse = fw_ov_sha3_start_pfe_q & ~fw_ov_sha3_start_pfe; |
| |
| //-------------------------------------------- |
| // register lock gating |
| //-------------------------------------------- |
| |
| // Allow writes only if |
| // 1. SW_REGUPD is true, |
| // 2. The DUT is disabled |
| // Block writes if enabled or if internal activities are still in progress (as indicated by |
| // es_delayed_enable). |
| assign es_hw_regwen = reg2hw.sw_regupd.q && |
| mubi4_test_false_loose(mubi_module_en_raw_fanout[0]) && |
| !es_delayed_enable; |
| assign hw2reg.regwen.de = 1'b1; |
| assign hw2reg.regwen.d = es_hw_regwen; |
| |
| //-------------------------------------------- |
| // set up secure enable bits |
| //-------------------------------------------- |
| |
| // check for illegal enable field states, and set alert if detected |
| |
| // SEC_CM: CONFIG.MUBI |
| assign mubi_module_en_raw = mubi4_t'(reg2hw.module_enable.q); |
| assign es_enable_pfa = mubi4_test_invalid(mubi_module_en_raw_fanout[1]); |
| assign hw2reg.recov_alert_sts.module_enable_field_alert.de = es_enable_pfa; |
| assign hw2reg.recov_alert_sts.module_enable_field_alert.d = es_enable_pfa; |
| |
| prim_mubi4_sync #( |
| .NumCopies(3), |
| .AsyncOn(0) |
| ) u_prim_mubi4_sync_entropy_module_en ( |
| .clk_i, |
| .rst_ni, |
| .mubi_i(mubi_module_en_raw), |
| .mubi_o(mubi_module_en_raw_fanout) |
| ); |
| |
| // Generation of enable pulse, and main enable signals. |
| // |
| // This module creates a single mubi_encoded module_enable_pulse, as well as |
| // a general mubi_es_enable signal. |
| // |
| // The module enable pulse is MuBi4True for a single clock after the |
| // module_enable register is asserted MuBi4True. However in this first clock cycle |
| // most of the module is not enabled. (The enable pulse is for clearing the |
| // residual internal state.) |
| // |
| // The rest of the module is enabled in the second clock cycle after seting the |
| // module_enable register to MuBi4True. |
| // |
| // When module_enable is set to MuBi4False the module is disabled. No further |
| // RNG input is accepted and the state machines transition to Idle as soon as |
| // possible. Some delay may occur if the SHA3 conditioning block is busy, though |
| // otherwise the main_sm transitions to Idle without delay. |
| |
| assign mubi_mod_en_dly_d = mubi_module_en_raw_fanout[2]; |
| assign mubi_module_en_pulse = mubi4_and_hi(mubi_mod_en_dly_d, mubi4_t'(~mubi_mod_en_dly_q)); |
| assign mubi_es_enable = mubi4_and_hi(mubi_mod_en_dly_d, mubi_mod_en_dly_q); |
| |
| for (genvar i = 0; i < EsEnableCopies; i = i+1) begin : gen_mubi_en_copies |
| assign es_enable_fo[i] = mubi4_test_true_strict(mubi_es_enable_fanout[i]); |
| end : gen_mubi_en_copies |
| |
| prim_mubi4_sync #( |
| .NumCopies(EsEnableCopies), |
| .AsyncOn(0) |
| ) u_prim_mubi4_sync_es_enable ( |
| .clk_i, |
| .rst_ni, |
| .mubi_i(mubi_es_enable), |
| .mubi_o(mubi_es_enable_fanout) |
| ); |
| |
| for (genvar i = 0; i < EsEnPulseCopies; i = i+1) begin : gen_mubi_en_pulse_copies |
| assign module_en_pulse_fo[i] = mubi4_test_true_strict(mubi_module_en_pulse_fanout[i]); |
| end : gen_mubi_en_pulse_copies |
| |
| prim_mubi4_sync #( |
| .NumCopies(EsEnPulseCopies), |
| .AsyncOn(0) |
| ) u_prim_mubi4_sync_es_enable_pulse ( |
| .clk_i, |
| .rst_ni, |
| .mubi_i(mubi_module_en_pulse), |
| .mubi_o(mubi_module_en_pulse_fanout) |
| ); |
| |
| entropy_src_enable_delay u_enable_delay ( |
| .clk_i, |
| .rst_ni, |
| .enable_i(es_enable_fo[0]), |
| .esrng_fifo_not_empty_i(sfifo_esrng_not_empty), |
| .esbit_fifo_not_empty_i(pfifo_esbit_not_empty), |
| .postht_fifo_not_empty_i(pfifo_postht_not_empty), |
| .cs_aes_halt_req_i(cs_aes_halt_req), |
| .sha3_done_i(sha3_done), |
| .bypass_mode_i(es_bypass_mode), |
| .enable_o(es_delayed_enable) |
| ); |
| |
| mubi4_t mubi_fips_en; |
| mubi4_t [1:0] mubi_fips_en_fanout; |
| assign mubi_fips_en = mubi4_t'(reg2hw.conf.fips_enable.q); |
| assign fips_enable_pfe = mubi4_test_true_strict(mubi_fips_en_fanout[0]); |
| assign fips_enable_pfa = mubi4_test_invalid(mubi_fips_en_fanout[1]); |
| assign hw2reg.recov_alert_sts.fips_enable_field_alert.de = fips_enable_pfa; |
| assign hw2reg.recov_alert_sts.fips_enable_field_alert.d = fips_enable_pfa; |
| |
| prim_mubi4_sync #( |
| .NumCopies(2), |
| .AsyncOn(0) |
| ) u_prim_mubi4_sync_entropy_fips_en ( |
| .clk_i, |
| .rst_ni, |
| .mubi_i(mubi_fips_en), |
| .mubi_o(mubi_fips_en_fanout) |
| ); |
| |
| // SEC_CM: CONFIG.MUBI |
| mubi4_t mubi_entropy_reg_en; |
| mubi4_t [1:0] mubi_entropy_reg_en_fanout; |
| assign mubi_entropy_reg_en = mubi4_t'(reg2hw.conf.entropy_data_reg_enable.q); |
| assign entropy_data_reg_en_pfe = mubi4_test_true_strict(mubi_entropy_reg_en_fanout[0]); |
| assign entropy_data_reg_en_pfa = mubi4_test_invalid(mubi_entropy_reg_en_fanout[1]); |
| assign hw2reg.recov_alert_sts.entropy_data_reg_en_field_alert.de = entropy_data_reg_en_pfa; |
| assign hw2reg.recov_alert_sts.entropy_data_reg_en_field_alert.d = entropy_data_reg_en_pfa; |
| |
| prim_mubi4_sync #( |
| .NumCopies(2), |
| .AsyncOn(0) |
| ) u_prim_mubi4_sync_entropy_data_reg_en ( |
| .clk_i, |
| .rst_ni, |
| .mubi_i(mubi_entropy_reg_en), |
| .mubi_o(mubi_entropy_reg_en_fanout) |
| ); |
| |
| assign observe_fifo_thresh = reg2hw.observe_fifo_thresh.q; |
| |
| // SEC_CM: CONFIG.MUBI |
| mubi4_t mubi_fw_ov_mode; |
| mubi4_t [1:0] mubi_fw_ov_mode_fanout; |
| assign mubi_fw_ov_mode = mubi4_t'(reg2hw.fw_ov_control.fw_ov_mode.q); |
| assign fw_ov_mode_pfe = mubi4_test_true_strict(mubi_fw_ov_mode_fanout[0]); |
| assign fw_ov_mode_pfa = mubi4_test_invalid(mubi_fw_ov_mode_fanout[1]); |
| assign hw2reg.recov_alert_sts.fw_ov_mode_field_alert.de = fw_ov_mode_pfa; |
| assign hw2reg.recov_alert_sts.fw_ov_mode_field_alert.d = fw_ov_mode_pfa; |
| |
| prim_mubi4_sync #( |
| .NumCopies(2), |
| .AsyncOn(0) |
| ) u_prim_mubi4_sync_fw_ov_mode ( |
| .clk_i, |
| .rst_ni, |
| .mubi_i(mubi_fw_ov_mode), |
| .mubi_o(mubi_fw_ov_mode_fanout) |
| ); |
| |
| // SEC_CM: CONFIG.MUBI |
| mubi4_t mubi_fw_ov_entropy_insert; |
| mubi4_t [1:0] mubi_fw_ov_entropy_insert_fanout; |
| assign mubi_fw_ov_entropy_insert = mubi4_t'(reg2hw.fw_ov_control.fw_ov_entropy_insert.q); |
| assign fw_ov_entropy_insert_pfe = mubi4_test_true_strict(mubi_fw_ov_entropy_insert_fanout[0]); |
| assign fw_ov_entropy_insert_pfa = mubi4_test_invalid(mubi_fw_ov_entropy_insert_fanout[1]); |
| assign hw2reg.recov_alert_sts.fw_ov_entropy_insert_field_alert.de = fw_ov_entropy_insert_pfa; |
| assign hw2reg.recov_alert_sts.fw_ov_entropy_insert_field_alert.d = fw_ov_entropy_insert_pfa; |
| |
| prim_mubi4_sync #( |
| .NumCopies(2), |
| .AsyncOn(0) |
| ) u_prim_mubi4_sync_fw_ov_entropy_insert ( |
| .clk_i, |
| .rst_ni, |
| .mubi_i(mubi_fw_ov_entropy_insert), |
| .mubi_o(mubi_fw_ov_entropy_insert_fanout) |
| ); |
| |
| // SEC_CM: CONFIG.MUBI |
| mubi4_t mubi_fw_ov_sha3_start; |
| mubi4_t [1:0] mubi_fw_ov_sha3_start_fanout; |
| assign mubi_fw_ov_sha3_start = mubi4_t'(reg2hw.fw_ov_sha3_start.q); |
| assign fw_ov_sha3_start_pfe = mubi4_test_true_strict(mubi_fw_ov_sha3_start_fanout[0]); |
| assign fw_ov_sha3_start_pfa = mubi4_test_invalid(mubi_fw_ov_sha3_start_fanout[1]); |
| assign hw2reg.recov_alert_sts.fw_ov_sha3_start_field_alert.de = fw_ov_sha3_start_pfa; |
| assign hw2reg.recov_alert_sts.fw_ov_sha3_start_field_alert.d = fw_ov_sha3_start_pfa; |
| |
| prim_mubi4_sync #( |
| .NumCopies(2), |
| .AsyncOn(0) |
| ) u_prim_mubi4_sync_fw_ov_sha3_start ( |
| .clk_i, |
| .rst_ni, |
| .mubi_i(mubi_fw_ov_sha3_start), |
| .mubi_o(mubi_fw_ov_sha3_start_fanout) |
| ); |
| |
| // firmware override controls |
| assign fw_ov_mode = efuse_es_sw_ov_en && fw_ov_mode_pfe; |
| assign fw_ov_mode_entropy_insert = fw_ov_mode && fw_ov_entropy_insert_pfe; |
| assign fw_ov_fifo_rd_pulse = reg2hw.fw_ov_rd_data.re; |
| assign hw2reg.fw_ov_rd_data.d = sfifo_observe_rdata; |
| assign fw_ov_fifo_wr_pulse = reg2hw.fw_ov_wr_data.qe; |
| assign fw_ov_wr_data = reg2hw.fw_ov_wr_data.q; |
| |
| assign efuse_es_sw_ov_en = prim_mubi_pkg::mubi8_test_true_strict(en_entropy_src_fw_over); |
| |
| prim_mubi8_sync #( |
| .NumCopies(1), |
| .AsyncOn(1) // must be set to one, see note below |
| ) u_prim_mubi8_sync_es_fw_over ( |
| .clk_i, |
| .rst_ni, |
| .mubi_i(otp_en_entropy_src_fw_over_i), |
| .mubi_o({en_entropy_src_fw_over}) |
| ); |
| |
| // note: the input to the above sync module is from the OTP block. |
| // It is assumed that the source is in a different time domain, |
| // and requires the AsyncOn parameter to be set. |
| |
| // rng_enable is being used in other clock domains. Need to latch the |
| // signal. |
| assign rng_enable_d = es_enable_fo[1] && |
| es_delayed_enable && |
| sfifo_esrng_not_full; |
| |
| assign entropy_src_rng_o.rng_enable = rng_enable_q; |
| |
| assign es_rng_src_valid = entropy_src_rng_i.rng_valid; |
| assign es_rng_bus = entropy_src_rng_i.rng_b; |
| |
| |
| //-------------------------------------------- |
| // instantiate interrupt hardware primitives |
| //-------------------------------------------- |
| |
| prim_intr_hw #( |
| .Width(1) |
| ) u_intr_hw_es_entropy_valid ( |
| .clk_i (clk_i), |
| .rst_ni (rst_ni), |
| .event_intr_i (event_es_entropy_valid), |
| .reg2hw_intr_enable_q_i (reg2hw.intr_enable.es_entropy_valid.q), |
| .reg2hw_intr_test_q_i (reg2hw.intr_test.es_entropy_valid.q), |
| .reg2hw_intr_test_qe_i (reg2hw.intr_test.es_entropy_valid.qe), |
| .reg2hw_intr_state_q_i (reg2hw.intr_state.es_entropy_valid.q), |
| .hw2reg_intr_state_de_o (hw2reg.intr_state.es_entropy_valid.de), |
| .hw2reg_intr_state_d_o (hw2reg.intr_state.es_entropy_valid.d), |
| .intr_o (intr_es_entropy_valid_o) |
| ); |
| |
| prim_intr_hw #( |
| .Width(1) |
| ) u_intr_hw_es_health_test_failed ( |
| .clk_i (clk_i), |
| .rst_ni (rst_ni), |
| .event_intr_i (event_es_health_test_failed), |
| .reg2hw_intr_enable_q_i (reg2hw.intr_enable.es_health_test_failed.q), |
| .reg2hw_intr_test_q_i (reg2hw.intr_test.es_health_test_failed.q), |
| .reg2hw_intr_test_qe_i (reg2hw.intr_test.es_health_test_failed.qe), |
| .reg2hw_intr_state_q_i (reg2hw.intr_state.es_health_test_failed.q), |
| .hw2reg_intr_state_de_o (hw2reg.intr_state.es_health_test_failed.de), |
| .hw2reg_intr_state_d_o (hw2reg.intr_state.es_health_test_failed.d), |
| .intr_o (intr_es_health_test_failed_o) |
| ); |
| |
| |
| prim_intr_hw #( |
| .Width(1) |
| ) u_intr_hw_es_observe_fifo_ready ( |
| .clk_i (clk_i), |
| .rst_ni (rst_ni), |
| .event_intr_i (event_es_observe_fifo_ready), |
| .reg2hw_intr_enable_q_i (reg2hw.intr_enable.es_observe_fifo_ready.q), |
| .reg2hw_intr_test_q_i (reg2hw.intr_test.es_observe_fifo_ready.q), |
| .reg2hw_intr_test_qe_i (reg2hw.intr_test.es_observe_fifo_ready.qe), |
| .reg2hw_intr_state_q_i (reg2hw.intr_state.es_observe_fifo_ready.q), |
| .hw2reg_intr_state_de_o (hw2reg.intr_state.es_observe_fifo_ready.de), |
| .hw2reg_intr_state_d_o (hw2reg.intr_state.es_observe_fifo_ready.d), |
| .intr_o (intr_es_observe_fifo_ready_o) |
| ); |
| |
| prim_intr_hw #( |
| .Width(1) |
| ) u_intr_hw_es_fatal_err ( |
| .clk_i (clk_i), |
| .rst_ni (rst_ni), |
| .event_intr_i (event_es_fatal_err), |
| .reg2hw_intr_enable_q_i (reg2hw.intr_enable.es_fatal_err.q), |
| .reg2hw_intr_test_q_i (reg2hw.intr_test.es_fatal_err.q), |
| .reg2hw_intr_test_qe_i (reg2hw.intr_test.es_fatal_err.qe), |
| .reg2hw_intr_state_q_i (reg2hw.intr_state.es_fatal_err.q), |
| .hw2reg_intr_state_de_o (hw2reg.intr_state.es_fatal_err.de), |
| .hw2reg_intr_state_d_o (hw2reg.intr_state.es_fatal_err.d), |
| .intr_o (intr_es_fatal_err_o) |
| ); |
| |
| //-------------------------------------------- |
| // tlul register settings |
| //-------------------------------------------- |
| |
| |
| // set the interrupt event when enabled |
| assign event_es_entropy_valid = pfifo_swread_not_empty && es_enable_fo[2]; |
| |
| |
| // set the interrupt sources |
| assign event_es_fatal_err = (es_enable_fo[3] && |
| (sfifo_esrng_err_sum || |
| sfifo_observe_err_sum || |
| sfifo_esfinal_err_sum || |
| sfifo_test_err_sum) ) || |
| es_ack_sm_err_sum || |
| es_main_sm_err_sum || |
| es_cntr_err_sum || // prim_count err is always active |
| sha3_rst_storage_err_sum || |
| sha3_state_error_sum; |
| |
| // set fifo errors that are single instances of source |
| assign sfifo_esrng_err_sum = (|sfifo_esrng_err) || |
| err_code_test_bit[0]; |
| assign sfifo_observe_err_sum = (|sfifo_observe_err) || |
| err_code_test_bit[1]; |
| assign sfifo_esfinal_err_sum = (|sfifo_esfinal_err) || |
| err_code_test_bit[2]; |
| |
| // The following test bits help normally diagnose the _type_ of |
| // error when they are triggred by the fifo. However when |
| // they are triggered by softwre they are not linked to a |
| // particular sfifo and do not trigger an alert, unless |
| // we capture them here. |
| assign sfifo_test_err_sum = err_code_test_bit[28] || |
| err_code_test_bit[29] || |
| err_code_test_bit[30]; |
| |
| assign es_ack_sm_err_sum = es_ack_sm_err || |
| err_code_test_bit[20]; |
| assign es_main_sm_err_sum = es_main_sm_err || |
| err_code_test_bit[21]; |
| assign es_cntr_err_sum = es_cntr_err || |
| err_code_test_bit[22]; |
| assign sha3_state_error_sum = sha3_state_error || |
| err_code_test_bit[23]; |
| assign sha3_rst_storage_err_sum = sha3_rst_storage_err || |
| err_code_test_bit[24]; |
| assign fifo_write_err_sum = |
| sfifo_esrng_err[2] || |
| sfifo_observe_err[2] || |
| sfifo_esfinal_err[2] || |
| err_code_test_bit[28]; |
| assign fifo_read_err_sum = |
| sfifo_esrng_err[1] || |
| sfifo_observe_err[1] || |
| sfifo_esfinal_err[1] || |
| err_code_test_bit[29]; |
| assign fifo_status_err_sum = |
| sfifo_esrng_err[0] || |
| sfifo_observe_err[0] || |
| sfifo_esfinal_err[0] || |
| err_code_test_bit[30]; |
| |
| // set the err code source bits |
| assign hw2reg.err_code.sfifo_esrng_err.d = 1'b1; |
| assign hw2reg.err_code.sfifo_esrng_err.de = sfifo_esrng_err_sum; |
| |
| assign hw2reg.err_code.sfifo_observe_err.d = 1'b1; |
| assign hw2reg.err_code.sfifo_observe_err.de = sfifo_observe_err_sum; |
| |
| assign hw2reg.err_code.sfifo_esfinal_err.d = 1'b1; |
| assign hw2reg.err_code.sfifo_esfinal_err.de = sfifo_esfinal_err_sum; |
| |
| assign hw2reg.err_code.es_ack_sm_err.d = 1'b1; |
| assign hw2reg.err_code.es_ack_sm_err.de = es_ack_sm_err_sum; |
| |
| assign hw2reg.err_code.es_main_sm_err.d = 1'b1; |
| assign hw2reg.err_code.es_main_sm_err.de = es_main_sm_err_sum; |
| |
| assign hw2reg.err_code.es_cntr_err.d = 1'b1; |
| assign hw2reg.err_code.es_cntr_err.de = es_cntr_err_sum; |
| |
| assign hw2reg.err_code.sha3_state_err.d = 1'b1; |
| assign hw2reg.err_code.sha3_state_err.de = sha3_state_error_sum; |
| |
| assign hw2reg.err_code.sha3_rst_storage_err.d = 1'b1; |
| assign hw2reg.err_code.sha3_rst_storage_err.de = sha3_rst_storage_err_sum; |
| |
| |
| // set the err code type bits |
| assign hw2reg.err_code.fifo_write_err.d = 1'b1; |
| assign hw2reg.err_code.fifo_write_err.de = fifo_write_err_sum; |
| |
| assign hw2reg.err_code.fifo_read_err.d = 1'b1; |
| assign hw2reg.err_code.fifo_read_err.de = fifo_read_err_sum; |
| |
| assign hw2reg.err_code.fifo_state_err.d = 1'b1; |
| assign hw2reg.err_code.fifo_state_err.de = fifo_status_err_sum; |
| |
| // Error forcing |
| for (genvar i = 0; i < 31; i = i+1) begin : gen_err_code_test_bit |
| assign err_code_test_bit[i] = (reg2hw.err_code_test.q == i) && reg2hw.err_code_test.qe; |
| end : gen_err_code_test_bit |
| |
| // alert - send all interrupt sources to the alert for the fatal case |
| assign fatal_alert_o = event_es_fatal_err; |
| |
| // alert test |
| assign recov_alert_test_o = { |
| reg2hw.alert_test.recov_alert.q && |
| reg2hw.alert_test.recov_alert.qe |
| }; |
| assign fatal_alert_test_o = { |
| reg2hw.alert_test.fatal_alert.q && |
| reg2hw.alert_test.fatal_alert.qe |
| }; |
| |
| |
| // set the debug status reg |
| assign hw2reg.debug_status.entropy_fifo_depth.d = sfifo_esfinal_depth; |
| assign hw2reg.debug_status.sha3_fsm.d = sha3_fsm; |
| assign hw2reg.debug_status.sha3_block_pr.d = sha3_block_processed; |
| assign hw2reg.debug_status.sha3_squeezing.d = sha3_squeezing; |
| assign hw2reg.debug_status.sha3_absorbed.d = |
| prim_mubi_pkg::mubi4_test_true_strict(sha3_absorbed) ? 1'b 1 : 1'b 0; |
| assign hw2reg.debug_status.sha3_err.d = sha3_err_q; |
| |
| assign sha3_err_d = |
| es_enable_fo[4] ? 1'b0 : |
| {|sha3_err} ? 1'b1 : |
| sha3_err_q; |
| |
| // state machine status |
| assign hw2reg.debug_status.main_sm_idle.d = es_main_sm_idle; |
| assign hw2reg.debug_status.main_sm_boot_done.d = boot_phase_done; |
| assign hw2reg.main_sm_state.de = 1'b1; |
| assign hw2reg.main_sm_state.d = es_main_sm_state; |
| |
| // fw override wr data status indication |
| assign fw_ov_wr_fifo_full = fw_ov_mode_entropy_insert && |
| (es_bypass_mode ? !pfifo_bypass_not_full : !pfifo_precon_not_full); |
| |
| assign hw2reg.fw_ov_wr_fifo_full.d = fw_ov_wr_fifo_full; |
| |
| |
| //-------------------------------------------- |
| // receive in RNG bus input |
| //-------------------------------------------- |
| |
| |
| prim_fifo_sync #( |
| .Width(RngBusWidth), |
| .Pass(0), |
| .Depth(2) |
| ) u_prim_fifo_sync_esrng ( |
| .clk_i (clk_i), |
| .rst_ni (rst_ni), |
| .clr_i (sfifo_esrng_clr), |
| .wvalid_i (sfifo_esrng_push), |
| .wdata_i (sfifo_esrng_wdata), |
| .wready_o (sfifo_esrng_not_full), |
| .rvalid_o (sfifo_esrng_not_empty), |
| .rdata_o (sfifo_esrng_rdata), |
| .rready_i (sfifo_esrng_pop), |
| .full_o (sfifo_esrng_full), |
| .depth_o (), |
| .err_o () |
| ); |
| |
| // fifo controls |
| assign sfifo_esrng_push = es_enable_fo[5] && es_delayed_enable && es_rng_src_valid && |
| rng_enable_q; |
| |
| assign sfifo_esrng_clr = ~es_delayed_enable; |
| assign sfifo_esrng_wdata = es_rng_bus; |
| assign sfifo_esrng_pop = sfifo_esrng_not_empty & (rng_bit_en ? pfifo_esbit_not_full : |
| pfifo_postht_not_full ); |
| |
| // fifo err |
| // Note: for prim_fifo_sync is not an error to push to a fifo that is full. In fact, the |
| // backpressure mechanism applied to the RNG inputs counts on this. |
| assign sfifo_esrng_err = |
| {1'b0, |
| (sfifo_esrng_pop && !sfifo_esrng_not_empty), |
| (sfifo_esrng_full && !sfifo_esrng_not_empty)}; |
| |
| |
| // pack esrng bus into signal bit packer |
| |
| // SEC_CM: CONFIG.MUBI |
| assign mubi_rng_bit_en = mubi4_t'(reg2hw.conf.rng_bit_enable.q); |
| assign rng_bit_enable_pfe = mubi4_test_true_strict(mubi_rng_bit_en_fanout[0]); |
| assign rng_bit_enable_pfa = mubi4_test_invalid(mubi_rng_bit_en_fanout[1]); |
| assign hw2reg.recov_alert_sts.rng_bit_enable_field_alert.de = rng_bit_enable_pfa; |
| assign hw2reg.recov_alert_sts.rng_bit_enable_field_alert.d = rng_bit_enable_pfa; |
| |
| prim_mubi4_sync #( |
| .NumCopies(2), |
| .AsyncOn(0) |
| ) u_prim_mubi4_sync_rng_bit_en ( |
| .clk_i, |
| .rst_ni, |
| .mubi_i(mubi_rng_bit_en), |
| .mubi_o(mubi_rng_bit_en_fanout) |
| ); |
| |
| |
| assign rng_bit_en = rng_bit_enable_pfe; |
| assign rng_bit_sel = reg2hw.conf.rng_bit_sel.q; |
| |
| prim_packer_fifo #( |
| .InW(1), |
| .OutW(RngBusWidth), |
| .ClearOnRead(1'b0) |
| ) u_prim_packer_fifo_esbit ( |
| .clk_i (clk_i), |
| .rst_ni (rst_ni), |
| .clr_i (pfifo_esbit_clr), |
| .wvalid_i (pfifo_esbit_push), |
| .wdata_i (pfifo_esbit_wdata), |
| .wready_o (pfifo_esbit_not_full), |
| .rvalid_o (pfifo_esbit_not_empty), |
| .rdata_o (pfifo_esbit_rdata), |
| .rready_i (pfifo_esbit_pop), |
| .depth_o () |
| ); |
| |
| assign pfifo_esbit_push = rng_bit_en && sfifo_esrng_not_empty; |
| assign pfifo_esbit_clr = ~es_delayed_enable; |
| assign pfifo_esbit_pop = rng_bit_en && pfifo_esbit_not_empty && pfifo_postht_not_full; |
| assign pfifo_esbit_wdata = |
| (rng_bit_sel == 2'h0) ? sfifo_esrng_rdata[0] : |
| (rng_bit_sel == 2'h1) ? sfifo_esrng_rdata[1] : |
| (rng_bit_sel == 2'h2) ? sfifo_esrng_rdata[2] : |
| sfifo_esrng_rdata[3]; |
| |
| |
| // select source for health testing |
| |
| assign health_test_esbus = pfifo_postht_wdata; |
| assign health_test_esbus_vld = pfifo_postht_push & pfifo_postht_not_full & ~pfifo_postht_clr; |
| |
| // Health test any data that comes in on the RNG interface. |
| assign repcnt_active = 1'b1; |
| assign repcnts_active = 1'b1; |
| assign adaptp_active = 1'b1; |
| assign bucket_active = 1'b1; |
| assign markov_active = 1'b1; |
| assign extht_active = 1'b1; |
| |
| // Only reset health tests on re-enable |
| assign health_test_clr = module_en_pulse_fo[0]; |
| |
| assign health_test_fips_window = reg2hw.health_test_windows.fips_window.q; |
| assign health_test_bypass_window = reg2hw.health_test_windows.bypass_window.q; |
| |
| assign repcnt_fips_threshold = reg2hw.repcnt_thresholds.fips_thresh.q; |
| assign repcnt_fips_threshold_wr = reg2hw.repcnt_thresholds.fips_thresh.qe; |
| assign hw2reg.repcnt_thresholds.fips_thresh.d = repcnt_fips_threshold_oneway; |
| assign repcnt_bypass_threshold = reg2hw.repcnt_thresholds.bypass_thresh.q; |
| assign repcnt_bypass_threshold_wr = reg2hw.repcnt_thresholds.bypass_thresh.qe; |
| assign hw2reg.repcnt_thresholds.bypass_thresh.d = repcnt_bypass_threshold_oneway; |
| |
| assign repcnts_fips_threshold = reg2hw.repcnts_thresholds.fips_thresh.q; |
| assign repcnts_fips_threshold_wr = reg2hw.repcnts_thresholds.fips_thresh.qe; |
| assign hw2reg.repcnts_thresholds.fips_thresh.d = repcnts_fips_threshold_oneway; |
| assign repcnts_bypass_threshold = reg2hw.repcnts_thresholds.bypass_thresh.q; |
| assign repcnts_bypass_threshold_wr = reg2hw.repcnts_thresholds.bypass_thresh.qe; |
| assign hw2reg.repcnts_thresholds.bypass_thresh.d = repcnts_bypass_threshold_oneway; |
| |
| |
| assign adaptp_hi_fips_threshold = reg2hw.adaptp_hi_thresholds.fips_thresh.q; |
| assign adaptp_hi_fips_threshold_wr = reg2hw.adaptp_hi_thresholds.fips_thresh.qe; |
| assign hw2reg.adaptp_hi_thresholds.fips_thresh.d = adaptp_hi_fips_threshold_oneway; |
| assign adaptp_hi_bypass_threshold = reg2hw.adaptp_hi_thresholds.bypass_thresh.q; |
| assign adaptp_hi_bypass_threshold_wr = reg2hw.adaptp_hi_thresholds.bypass_thresh.qe; |
| assign hw2reg.adaptp_hi_thresholds.bypass_thresh.d = adaptp_hi_bypass_threshold_oneway; |
| |
| assign adaptp_lo_fips_threshold = reg2hw.adaptp_lo_thresholds.fips_thresh.q; |
| assign adaptp_lo_fips_threshold_wr = reg2hw.adaptp_lo_thresholds.fips_thresh.qe; |
| assign hw2reg.adaptp_lo_thresholds.fips_thresh.d = adaptp_lo_fips_threshold_oneway; |
| assign adaptp_lo_bypass_threshold = reg2hw.adaptp_lo_thresholds.bypass_thresh.q; |
| assign adaptp_lo_bypass_threshold_wr = reg2hw.adaptp_lo_thresholds.bypass_thresh.qe; |
| assign hw2reg.adaptp_lo_thresholds.bypass_thresh.d = adaptp_lo_bypass_threshold_oneway; |
| |
| |
| assign bucket_fips_threshold = reg2hw.bucket_thresholds.fips_thresh.q; |
| assign bucket_fips_threshold_wr = reg2hw.bucket_thresholds.fips_thresh.qe; |
| assign hw2reg.bucket_thresholds.fips_thresh.d = bucket_fips_threshold_oneway; |
| assign bucket_bypass_threshold = reg2hw.bucket_thresholds.bypass_thresh.q; |
| assign bucket_bypass_threshold_wr = reg2hw.bucket_thresholds.bypass_thresh.qe; |
| assign hw2reg.bucket_thresholds.bypass_thresh.d = bucket_bypass_threshold_oneway; |
| |
| |
| assign markov_hi_fips_threshold = reg2hw.markov_hi_thresholds.fips_thresh.q; |
| assign markov_hi_fips_threshold_wr = reg2hw.markov_hi_thresholds.fips_thresh.qe; |
| assign hw2reg.markov_hi_thresholds.fips_thresh.d = markov_hi_fips_threshold_oneway; |
| assign markov_hi_bypass_threshold = reg2hw.markov_hi_thresholds.bypass_thresh.q; |
| assign markov_hi_bypass_threshold_wr = reg2hw.markov_hi_thresholds.bypass_thresh.qe; |
| assign hw2reg.markov_hi_thresholds.bypass_thresh.d = markov_hi_bypass_threshold_oneway; |
| |
| assign markov_lo_fips_threshold = reg2hw.markov_lo_thresholds.fips_thresh.q; |
| assign markov_lo_fips_threshold_wr = reg2hw.markov_lo_thresholds.fips_thresh.qe; |
| assign hw2reg.markov_lo_thresholds.fips_thresh.d = markov_lo_fips_threshold_oneway; |
| assign markov_lo_bypass_threshold = reg2hw.markov_lo_thresholds.bypass_thresh.q; |
| assign markov_lo_bypass_threshold_wr = reg2hw.markov_lo_thresholds.bypass_thresh.qe; |
| assign hw2reg.markov_lo_thresholds.bypass_thresh.d = markov_lo_bypass_threshold_oneway; |
| |
| |
| assign extht_hi_fips_threshold = reg2hw.extht_hi_thresholds.fips_thresh.q; |
| assign extht_hi_fips_threshold_wr = reg2hw.extht_hi_thresholds.fips_thresh.qe; |
| assign hw2reg.extht_hi_thresholds.fips_thresh.d = extht_hi_fips_threshold_oneway; |
| assign extht_hi_bypass_threshold = reg2hw.extht_hi_thresholds.bypass_thresh.q; |
| assign extht_hi_bypass_threshold_wr = reg2hw.extht_hi_thresholds.bypass_thresh.qe; |
| assign hw2reg.extht_hi_thresholds.bypass_thresh.d = extht_hi_bypass_threshold_oneway; |
| |
| assign extht_lo_fips_threshold = reg2hw.extht_lo_thresholds.fips_thresh.q; |
| assign extht_lo_fips_threshold_wr = reg2hw.extht_lo_thresholds.fips_thresh.qe; |
| assign hw2reg.extht_lo_thresholds.fips_thresh.d = extht_lo_fips_threshold_oneway; |
| assign extht_lo_bypass_threshold = reg2hw.extht_lo_thresholds.bypass_thresh.q; |
| assign extht_lo_bypass_threshold_wr = reg2hw.extht_lo_thresholds.bypass_thresh.qe; |
| assign hw2reg.extht_lo_thresholds.bypass_thresh.d = extht_lo_bypass_threshold_oneway; |
| |
| |
| |
| assign health_test_window = es_bypass_mode ? health_test_bypass_window : health_test_fips_window; |
| |
| //------------------------------ |
| // repcnt one-way thresholds |
| //------------------------------ |
| assign repcnt_threshold = es_bypass_mode ? repcnt_bypass_threshold_oneway : |
| repcnt_fips_threshold_oneway; |
| |
| entropy_src_watermark_reg #( |
| .RegWidth(HalfRegWidth), |
| .HighWatermark(0) |
| ) u_entropy_src_watermark_reg_repcnt_thresh_fips ( |
| .clk_i (clk_i), |
| .rst_ni (rst_ni), |
| .clear_i (1'b0), |
| .event_i (repcnt_fips_threshold_wr), |
| .value_i (repcnt_fips_threshold), |
| .value_o (repcnt_fips_threshold_oneway) |
| ); |
| |
| entropy_src_watermark_reg #( |
| .RegWidth(HalfRegWidth), |
| .HighWatermark(0) |
| ) u_entropy_src_watermark_reg_repcnt_thresh_bypass ( |
| .clk_i (clk_i), |
| .rst_ni (rst_ni), |
| .clear_i (1'b0), |
| .event_i (repcnt_bypass_threshold_wr), |
| .value_i (repcnt_bypass_threshold), |
| .value_o (repcnt_bypass_threshold_oneway) |
| ); |
| |
| //------------------------------ |
| // repcnts one-way thresholds |
| //------------------------------ |
| assign repcnts_threshold = es_bypass_mode ? repcnts_bypass_threshold_oneway : |
| repcnts_fips_threshold_oneway; |
| |
| entropy_src_watermark_reg #( |
| .RegWidth(HalfRegWidth), |
| .HighWatermark(0) |
| ) u_entropy_src_watermark_reg_repcnts_thresh_fips ( |
| .clk_i (clk_i), |
| .rst_ni (rst_ni), |
| .clear_i (1'b0), |
| .event_i (repcnts_fips_threshold_wr), |
| .value_i (repcnts_fips_threshold), |
| .value_o (repcnts_fips_threshold_oneway) |
| ); |
| |
| entropy_src_watermark_reg #( |
| .RegWidth(HalfRegWidth), |
| .HighWatermark(0) |
| ) u_entropy_src_watermark_reg_repcnts_thresh_bypass ( |
| .clk_i (clk_i), |
| .rst_ni (rst_ni), |
| .clear_i (1'b0), |
| .event_i (repcnts_bypass_threshold_wr), |
| .value_i (repcnts_bypass_threshold), |
| .value_o (repcnts_bypass_threshold_oneway) |
| ); |
| |
| |
| //------------------------------ |
| // adaptp one-way thresholds |
| //------------------------------ |
| assign adaptp_hi_threshold = es_bypass_mode ? adaptp_hi_bypass_threshold_oneway : |
| adaptp_hi_fips_threshold_oneway; |
| |
| entropy_src_watermark_reg #( |
| .RegWidth(HalfRegWidth), |
| .HighWatermark(0) |
| ) u_entropy_src_watermark_reg_adaptp_hi_thresh_fips ( |
| .clk_i (clk_i), |
| .rst_ni (rst_ni), |
| .clear_i (1'b0), |
| .event_i (adaptp_hi_fips_threshold_wr), |
| .value_i (adaptp_hi_fips_threshold), |
| .value_o (adaptp_hi_fips_threshold_oneway) |
| ); |
| |
| entropy_src_watermark_reg #( |
| .RegWidth(HalfRegWidth), |
| .HighWatermark(0) |
| ) u_entropy_src_watermark_reg_adaptp_hi_thresh_bypass ( |
| .clk_i (clk_i), |
| .rst_ni (rst_ni), |
| .clear_i (1'b0), |
| .event_i (adaptp_hi_bypass_threshold_wr), |
| .value_i (adaptp_hi_bypass_threshold), |
| .value_o (adaptp_hi_bypass_threshold_oneway) |
| ); |
| |
| assign adaptp_lo_threshold = es_bypass_mode ? adaptp_lo_bypass_threshold_oneway : |
| adaptp_lo_fips_threshold_oneway; |
| |
| entropy_src_watermark_reg #( |
| .RegWidth(HalfRegWidth), |
| .HighWatermark(1) |
| ) u_entropy_src_watermark_reg_adaptp_lo_thresh_fips ( |
| .clk_i (clk_i), |
| .rst_ni (rst_ni), |
| .clear_i (1'b0), |
| .event_i (adaptp_lo_fips_threshold_wr), |
| .value_i (adaptp_lo_fips_threshold), |
| .value_o (adaptp_lo_fips_threshold_oneway) |
| ); |
| |
| entropy_src_watermark_reg #( |
| .RegWidth(HalfRegWidth), |
| .HighWatermark(1) |
| ) u_entropy_src_watermark_reg_adaptp_lo_thresh_bypass ( |
| .clk_i (clk_i), |
| .rst_ni (rst_ni), |
| .clear_i (1'b0), |
| .event_i (adaptp_lo_bypass_threshold_wr), |
| .value_i (adaptp_lo_bypass_threshold), |
| .value_o (adaptp_lo_bypass_threshold_oneway) |
| ); |
| |
| |
| //------------------------------ |
| // bucket one-way thresholds |
| //------------------------------ |
| assign bucket_threshold = es_bypass_mode ? bucket_bypass_threshold_oneway : |
| bucket_fips_threshold_oneway; |
| |
| entropy_src_watermark_reg #( |
| .RegWidth(HalfRegWidth), |
| .HighWatermark(0) |
| ) u_entropy_src_watermark_reg_bucket_thresh_fips ( |
| .clk_i (clk_i), |
| .rst_ni (rst_ni), |
| .clear_i (1'b0), |
| .event_i (bucket_fips_threshold_wr), |
| .value_i (bucket_fips_threshold), |
| .value_o (bucket_fips_threshold_oneway) |
| ); |
| |
| entropy_src_watermark_reg #( |
| .RegWidth(HalfRegWidth), |
| .HighWatermark(0) |
| ) u_entropy_src_watermark_reg_bucket_thresh_bypass ( |
| .clk_i (clk_i), |
| .rst_ni (rst_ni), |
| .clear_i (1'b0), |
| .event_i (bucket_bypass_threshold_wr), |
| .value_i (bucket_bypass_threshold), |
| .value_o (bucket_bypass_threshold_oneway) |
| ); |
| |
| |
| //------------------------------ |
| // markov one-way thresholds |
| //------------------------------ |
| assign markov_hi_threshold = es_bypass_mode ? markov_hi_bypass_threshold_oneway : |
| markov_hi_fips_threshold_oneway; |
| |
| entropy_src_watermark_reg #( |
| .RegWidth(HalfRegWidth), |
| .HighWatermark(0) |
| ) u_entropy_src_watermark_reg_markov_hi_thresh_fips ( |
| .clk_i (clk_i), |
| .rst_ni (rst_ni), |
| .clear_i (1'b0), |
| .event_i (markov_hi_fips_threshold_wr), |
| .value_i (markov_hi_fips_threshold), |
| .value_o (markov_hi_fips_threshold_oneway) |
| ); |
| |
| entropy_src_watermark_reg #( |
| .RegWidth(HalfRegWidth), |
| .HighWatermark(0) |
| ) u_entropy_src_watermark_reg_markov_hi_thresh_bypass ( |
| .clk_i (clk_i), |
| .rst_ni (rst_ni), |
| .clear_i (1'b0), |
| .event_i (markov_hi_bypass_threshold_wr), |
| .value_i (markov_hi_bypass_threshold), |
| .value_o (markov_hi_bypass_threshold_oneway) |
| ); |
| |
| assign markov_lo_threshold = es_bypass_mode ? markov_lo_bypass_threshold_oneway : |
| markov_lo_fips_threshold_oneway; |
| |
| entropy_src_watermark_reg #( |
| .RegWidth(HalfRegWidth), |
| .HighWatermark(1) |
| ) u_entropy_src_watermark_reg_markov_lo_thresh_fips ( |
| .clk_i (clk_i), |
| .rst_ni (rst_ni), |
| .clear_i (1'b0), |
| .event_i (markov_lo_fips_threshold_wr), |
| .value_i (markov_lo_fips_threshold), |
| .value_o (markov_lo_fips_threshold_oneway) |
| ); |
| |
| entropy_src_watermark_reg #( |
| .RegWidth(HalfRegWidth), |
| .HighWatermark(1) |
| ) u_entropy_src_watermark_reg_markov_lo_thresh_bypass ( |
| .clk_i (clk_i), |
| .rst_ni (rst_ni), |
| .clear_i (1'b0), |
| .event_i (markov_lo_bypass_threshold_wr), |
| .value_i (markov_lo_bypass_threshold), |
| .value_o (markov_lo_bypass_threshold_oneway) |
| ); |
| |
| |
| //------------------------------ |
| // extht one-way thresholds |
| //------------------------------ |
| assign extht_hi_threshold = es_bypass_mode ? extht_hi_bypass_threshold_oneway : |
| extht_hi_fips_threshold_oneway; |
| |
| entropy_src_watermark_reg #( |
| .RegWidth(HalfRegWidth), |
| .HighWatermark(0) |
| ) u_entropy_src_watermark_reg_extht_hi_thresh_fips ( |
| .clk_i (clk_i), |
| .rst_ni (rst_ni), |
| .clear_i (1'b0), |
| .event_i (extht_hi_fips_threshold_wr), |
| .value_i (extht_hi_fips_threshold), |
| .value_o (extht_hi_fips_threshold_oneway) |
| ); |
| |
| entropy_src_watermark_reg #( |
| .RegWidth(HalfRegWidth), |
| .HighWatermark(0) |
| ) u_entropy_src_watermark_reg_extht_hi_thresh_bypass ( |
| .clk_i (clk_i), |
| .rst_ni (rst_ni), |
| .clear_i (1'b0), |
| .event_i (extht_hi_bypass_threshold_wr), |
| .value_i (extht_hi_bypass_threshold), |
| .value_o (extht_hi_bypass_threshold_oneway) |
| ); |
| |
| |
| assign extht_lo_threshold = es_bypass_mode ? extht_lo_bypass_threshold_oneway : |
| extht_lo_fips_threshold_oneway; |
| |
| entropy_src_watermark_reg #( |
| .RegWidth(HalfRegWidth), |
| .HighWatermark(1) |
| ) u_entropy_src_watermark_reg_extht_lo_thresh_fips ( |
| .clk_i (clk_i), |
| .rst_ni (rst_ni), |
| .clear_i (1'b0), |
| .event_i (extht_lo_fips_threshold_wr), |
| .value_i (extht_lo_fips_threshold), |
| .value_o (extht_lo_fips_threshold_oneway) |
| ); |
| |
| entropy_src_watermark_reg #( |
| .RegWidth(HalfRegWidth), |
| .HighWatermark(1) |
| ) u_entropy_src_watermark_reg_extht_lo_thresh_bypass ( |
| .clk_i (clk_i), |
| .rst_ni (rst_ni), |
| .clear_i (1'b0), |
| .event_i (extht_lo_bypass_threshold_wr), |
| .value_i (extht_lo_bypass_threshold), |
| .value_o (extht_lo_bypass_threshold_oneway) |
| ); |
| |
| |
| |
| //------------------------------ |
| // misc control settings |
| //------------------------------ |
| |
| assign event_es_health_test_failed = es_main_sm_alert; |
| |
| assign event_es_observe_fifo_ready = observe_fifo_thresh_met; |
| |
| // SEC_CM: CONFIG.MUBI |
| mubi4_t mubi_es_route; |
| mubi4_t [1:0] mubi_es_route_fanout; |
| assign mubi_es_route = mubi4_t'(reg2hw.entropy_control.es_route.q); |
| assign es_route_pfe = mubi4_test_true_strict(mubi_es_route_fanout[0]); |
| assign es_route_pfa = mubi4_test_invalid(mubi_es_route_fanout[1]); |
| assign hw2reg.recov_alert_sts.es_route_field_alert.de = es_route_pfa; |
| assign hw2reg.recov_alert_sts.es_route_field_alert.d = es_route_pfa; |
| |
| prim_mubi4_sync #( |
| .NumCopies(2), |
| .AsyncOn(0) |
| ) u_prim_mubi4_sync_es_route ( |
| .clk_i, |
| .rst_ni, |
| .mubi_i(mubi_es_route), |
| .mubi_o(mubi_es_route_fanout) |
| ); |
| |
| // SEC_CM: CONFIG.MUBI |
| mubi4_t mubi_es_type; |
| mubi4_t [1:0] mubi_es_type_fanout; |
| assign mubi_es_type = mubi4_t'(reg2hw.entropy_control.es_type.q); |
| assign es_type_pfe = mubi4_test_true_strict(mubi_es_type_fanout[0]); |
| assign es_type_pfa = mubi4_test_invalid(mubi_es_type_fanout[1]); |
| assign hw2reg.recov_alert_sts.es_type_field_alert.de = es_type_pfa; |
| assign hw2reg.recov_alert_sts.es_type_field_alert.d = es_type_pfa; |
| |
| prim_mubi4_sync #( |
| .NumCopies(2), |
| .AsyncOn(0) |
| ) u_prim_mubi4_sync_es_type ( |
| .clk_i, |
| .rst_ni, |
| .mubi_i(mubi_es_type), |
| .mubi_o(mubi_es_type_fanout) |
| ); |
| |
| // SEC_CM: CONFIG.MUBI |
| mubi4_t mubi_thresh_scope; |
| assign mubi_thresh_scope = mubi4_t'(reg2hw.conf.threshold_scope.q); |
| assign threshold_scope_pfe = mubi4_test_true_strict(mubi_thresh_scope); |
| assign threshold_scope_pfa = mubi4_test_invalid(mubi_thresh_scope); |
| assign hw2reg.recov_alert_sts.threshold_scope_field_alert.de = threshold_scope_pfa; |
| assign hw2reg.recov_alert_sts.threshold_scope_field_alert.d = threshold_scope_pfa; |
| |
| assign es_route_to_sw = es_route_pfe; |
| assign es_bypass_to_sw = es_type_pfe; |
| assign threshold_scope = threshold_scope_pfe; |
| |
| assign es_bypass_mode = (!fips_enable_pfe) || (es_bypass_to_sw && es_route_to_sw); |
| |
| // send off to AST RNG for possibly faster entropy generation |
| assign rng_fips_o = !es_bypass_mode; |
| |
| //-------------------------------------------- |
| // common health test window counter |
| //-------------------------------------------- |
| |
| // Window counter |
| // SEC_CM: CTR.REDUN |
| prim_count #( |
| .Width(HalfRegWidth) |
| ) u_prim_count_window_cntr ( |
| .clk_i, |
| .rst_ni, |
| .clr_i(!es_delayed_enable), |
| .set_i(health_test_done_pulse), |
| .set_cnt_i(HalfRegWidth'(0)), |
| .incr_en_i(health_test_esbus_vld), |
| .decr_en_i(1'b0), |
| .step_i(HalfRegWidth'(1)), |
| .cnt_o(window_cntr), |
| .cnt_next_o(), |
| .err_o(window_cntr_err) |
| ); |
| |
| // Window wrap condition |
| assign health_test_done_pulse = (window_cntr >= health_test_window); |
| |
| // Summary of counter errors |
| assign es_cntr_err = |
| (window_cntr_err || |
| repcnt_cntr_err || |
| repcnts_cntr_err || |
| adaptp_cntr_err || |
| bucket_cntr_err || |
| markov_cntr_err || |
| repcnt_fails_cntr_err || |
| repcnt_alert_cntr_err || |
| repcnts_fails_cntr_err || |
| repcnts_alert_cntr_err || |
| adaptp_hi_fails_cntr_err || |
| adaptp_lo_fails_cntr_err || |
| adaptp_hi_alert_cntr_err || |
| adaptp_lo_alert_cntr_err || |
| bucket_fails_cntr_err || |
| bucket_alert_cntr_err || |
| markov_hi_fails_cntr_err || |
| markov_lo_fails_cntr_err || |
| markov_hi_alert_cntr_err || |
| markov_lo_alert_cntr_err || |
| extht_hi_fails_cntr_err || |
| extht_lo_fails_cntr_err || |
| extht_hi_alert_cntr_err || |
| extht_lo_alert_cntr_err || |
| any_fails_cntr_err || |
| sha3_count_error); |
| |
| //-------------------------------------------- |
| // repetitive count test |
| //-------------------------------------------- |
| |
| // SEC_CM: RNG.BKGN_CHK |
| entropy_src_repcnt_ht #( |
| .RegWidth(HalfRegWidth), |
| .RngBusWidth(RngBusWidth) |
| ) u_entropy_src_repcnt_ht ( |
| .clk_i (clk_i), |
| .rst_ni (rst_ni), |
| .entropy_bit_i (health_test_esbus), |
| .entropy_bit_vld_i (health_test_esbus_vld), |
| .clear_i (health_test_clr), |
| .active_i (repcnt_active), |
| .thresh_i (repcnt_threshold), |
| .test_cnt_o (repcnt_event_cnt), |
| .test_fail_pulse_o (repcnt_fail_pulse), |
| .count_err_o (repcnt_cntr_err) |
| ); |
| |
| entropy_src_watermark_reg #( |
| .RegWidth(HalfRegWidth), |
| .HighWatermark(1) |
| ) u_entropy_src_watermark_reg_repcnt_fips ( |
| .clk_i (clk_i), |
| .rst_ni (rst_ni), |
| .clear_i (health_test_clr), |
| .event_i (!es_bypass_mode), |
| .value_i (repcnt_event_cnt), |
| .value_o (repcnt_event_hwm_fips) |
| ); |
| |
| entropy_src_watermark_reg #( |
| .RegWidth(HalfRegWidth), |
| .HighWatermark(1) |
| ) u_entropy_src_watermark_reg_repcnt_bypass ( |
| .clk_i (clk_i), |
| .rst_ni (rst_ni), |
| .clear_i (health_test_clr), |
| .event_i (es_bypass_mode), |
| .value_i (repcnt_event_cnt), |
| .value_o (repcnt_event_hwm_bypass) |
| ); |
| |
| // SEC_CM: CTR.REDUN |
| entropy_src_cntr_reg #( |
| .RegWidth(FullRegWidth) |
| ) u_entropy_src_cntr_reg_repcnt ( |
| .clk_i (clk_i), |
| .rst_ni (rst_ni), |
| .clear_i (health_test_clr), |
| .event_i (repcnt_fail_pulse), |
| .value_o (repcnt_total_fails), |
| .err_o (repcnt_fails_cntr_err) |
| ); |
| |
| assign hw2reg.repcnt_hi_watermarks.fips_watermark.d = repcnt_event_hwm_fips; |
| assign hw2reg.repcnt_hi_watermarks.bypass_watermark.d = repcnt_event_hwm_bypass; |
| assign hw2reg.repcnt_total_fails.d = repcnt_total_fails; |
| |
| //-------------------------------------------- |
| // repetitive count symbol test |
| //-------------------------------------------- |
| |
| // SEC_CM: RNG.BKGN_CHK |
| entropy_src_repcnts_ht #( |
| .RegWidth(HalfRegWidth), |
| .RngBusWidth(RngBusWidth) |
| ) u_entropy_src_repcnts_ht ( |
| .clk_i (clk_i), |
| .rst_ni (rst_ni), |
| .entropy_bit_i (health_test_esbus), |
| .entropy_bit_vld_i (health_test_esbus_vld), |
| .clear_i (health_test_clr), |
| .active_i (repcnts_active), |
| .thresh_i (repcnts_threshold), |
| .test_cnt_o (repcnts_event_cnt), |
| .test_fail_pulse_o (repcnts_fail_pulse), |
| .count_err_o (repcnts_cntr_err) |
| ); |
| |
| entropy_src_watermark_reg #( |
| .RegWidth(HalfRegWidth), |
| .HighWatermark(1) |
| ) u_entropy_src_watermark_reg_repcnts_fips ( |
| .clk_i (clk_i), |
| .rst_ni (rst_ni), |
| .clear_i (health_test_clr), |
| .event_i (!es_bypass_mode), |
| .value_i (repcnts_event_cnt), |
| .value_o (repcnts_event_hwm_fips) |
| ); |
| |
| entropy_src_watermark_reg #( |
| .RegWidth(HalfRegWidth), |
| .HighWatermark(1) |
| ) u_entropy_src_watermark_reg_repcnts_bypass ( |
| .clk_i (clk_i), |
| .rst_ni (rst_ni), |
| .clear_i (health_test_clr), |
| .event_i (es_bypass_mode), |
| .value_i (repcnts_event_cnt), |
| .value_o (repcnts_event_hwm_bypass) |
| ); |
| |
| // SEC_CM: CTR.REDUN |
| entropy_src_cntr_reg #( |
| .RegWidth(FullRegWidth) |
| ) u_entropy_src_cntr_reg_repcnts ( |
| .clk_i (clk_i), |
| .rst_ni (rst_ni), |
| .clear_i (health_test_clr), |
| .event_i (repcnts_fail_pulse), |
| .value_o (repcnts_total_fails), |
| .err_o (repcnts_fails_cntr_err) |
| ); |
| |
| assign hw2reg.repcnts_hi_watermarks.fips_watermark.d = repcnts_event_hwm_fips; |
| assign hw2reg.repcnts_hi_watermarks.bypass_watermark.d = repcnts_event_hwm_bypass; |
| assign hw2reg.repcnts_total_fails.d = repcnts_total_fails; |
| |
| //-------------------------------------------- |
| // adaptive proportion test |
| //-------------------------------------------- |
| |
| // SEC_CM: RNG.BKGN_CHK |
| entropy_src_adaptp_ht #( |
| .RegWidth(HalfRegWidth), |
| .RngBusWidth(RngBusWidth) |
| ) u_entropy_src_adaptp_ht ( |
| .clk_i (clk_i), |
| .rst_ni (rst_ni), |
| .entropy_bit_i (health_test_esbus), |
| .entropy_bit_vld_i (health_test_esbus_vld), |
| .clear_i (health_test_clr), |
| .active_i (adaptp_active), |
| .thresh_hi_i (adaptp_hi_threshold), |
| .thresh_lo_i (adaptp_lo_threshold), |
| .window_wrap_pulse_i (health_test_done_pulse), |
| .threshold_scope_i (threshold_scope), |
| .test_cnt_hi_o (adaptp_hi_event_cnt), |
| .test_cnt_lo_o (adaptp_lo_event_cnt), |
| .test_fail_hi_pulse_o(adaptp_hi_fail_pulse), |
| .test_fail_lo_pulse_o(adaptp_lo_fail_pulse), |
| .count_err_o (adaptp_cntr_err) |
| ); |
| |
| |
| entropy_src_watermark_reg #( |
| .RegWidth(HalfRegWidth), |
| .HighWatermark(1) |
| ) u_entropy_src_watermark_reg_adaptp_hi_fips ( |
| .clk_i (clk_i), |
| .rst_ni (rst_ni), |
| .clear_i (health_test_clr), |
| .event_i (health_test_done_pulse && !es_bypass_mode), |
| .value_i (adaptp_hi_event_cnt), |
| .value_o (adaptp_hi_event_hwm_fips) |
| ); |
| |
| entropy_src_watermark_reg #( |
| .RegWidth(HalfRegWidth), |
| .HighWatermark(1) |
| ) u_entropy_src_watermark_reg_adaptp_hi_bypass ( |
| .clk_i (clk_i), |
| .rst_ni (rst_ni), |
| .clear_i (health_test_clr), |
| .event_i (health_test_done_pulse && es_bypass_mode), |
| .value_i (adaptp_hi_event_cnt), |
| .value_o (adaptp_hi_event_hwm_bypass) |
| ); |
| |
| // SEC_CM: CTR.REDUN |
| entropy_src_cntr_reg #( |
| .RegWidth(FullRegWidth) |
| ) u_entropy_src_cntr_reg_adaptp_hi ( |
| .clk_i (clk_i), |
| .rst_ni (rst_ni), |
| .clear_i (health_test_clr), |
| .event_i (adaptp_hi_fail_pulse), |
| .value_o (adaptp_hi_total_fails), |
| .err_o (adaptp_hi_fails_cntr_err) |
| ); |
| |
| |
| assign hw2reg.adaptp_hi_watermarks.fips_watermark.d = adaptp_hi_event_hwm_fips; |
| assign hw2reg.adaptp_hi_watermarks.bypass_watermark.d = adaptp_hi_event_hwm_bypass; |
| assign hw2reg.adaptp_hi_total_fails.d = adaptp_hi_total_fails; |
| |
| |
| entropy_src_watermark_reg #( |
| .RegWidth(HalfRegWidth), |
| .HighWatermark(0) |
| ) u_entropy_src_watermark_reg_adaptp_lo_fips ( |
| .clk_i (clk_i), |
| .rst_ni (rst_ni), |
| .clear_i (health_test_clr), |
| .event_i (health_test_done_pulse && !es_bypass_mode), |
| .value_i (adaptp_lo_event_cnt), |
| .value_o (adaptp_lo_event_hwm_fips) |
| ); |
| |
| entropy_src_watermark_reg #( |
| .RegWidth(HalfRegWidth), |
| .HighWatermark(0) |
| ) u_entropy_src_watermark_reg_adaptp_lo_bypass ( |
| .clk_i (clk_i), |
| .rst_ni (rst_ni), |
| .clear_i (health_test_clr), |
| .event_i (health_test_done_pulse && es_bypass_mode), |
| .value_i (adaptp_lo_event_cnt), |
| .value_o (adaptp_lo_event_hwm_bypass) |
| ); |
| |
| // SEC_CM: CTR.REDUN |
| entropy_src_cntr_reg #( |
| .RegWidth(FullRegWidth) |
| ) u_entropy_src_cntr_reg_adaptp_lo ( |
| .clk_i (clk_i), |
| .rst_ni (rst_ni), |
| .clear_i (health_test_clr), |
| .event_i (adaptp_lo_fail_pulse), |
| .value_o (adaptp_lo_total_fails), |
| .err_o (adaptp_lo_fails_cntr_err) |
| ); |
| |
| assign hw2reg.adaptp_lo_watermarks.fips_watermark.d = adaptp_lo_event_hwm_fips; |
| assign hw2reg.adaptp_lo_watermarks.bypass_watermark.d = adaptp_lo_event_hwm_bypass; |
| assign hw2reg.adaptp_lo_total_fails.d = adaptp_lo_total_fails; |
| |
| |
| //-------------------------------------------- |
| // bucket test |
| //-------------------------------------------- |
| |
| // SEC_CM: RNG.BKGN_CHK |
| entropy_src_bucket_ht #( |
| .RegWidth(HalfRegWidth), |
| .RngBusWidth(RngBusWidth) |
| ) u_entropy_src_bucket_ht ( |
| .clk_i (clk_i), |
| .rst_ni (rst_ni), |
| .entropy_bit_i (health_test_esbus), |
| .entropy_bit_vld_i (health_test_esbus_vld), |
| .clear_i (health_test_clr), |
| .active_i (bucket_active), |
| .thresh_i (bucket_threshold), |
| .window_wrap_pulse_i (health_test_done_pulse), |
| .test_cnt_o (bucket_event_cnt), |
| .test_fail_pulse_o (bucket_fail_pulse), |
| .count_err_o (bucket_cntr_err) |
| ); |
| |
| entropy_src_watermark_reg #( |
| .RegWidth(HalfRegWidth), |
| .HighWatermark(1) |
| ) u_entropy_src_watermark_reg_bucket_fips ( |
| .clk_i (clk_i), |
| .rst_ni (rst_ni), |
| .clear_i (health_test_clr), |
| .event_i (health_test_done_pulse && !es_bypass_mode), |
| .value_i (bucket_event_cnt), |
| .value_o (bucket_event_hwm_fips) |
| ); |
| |
| entropy_src_watermark_reg #( |
| .RegWidth(HalfRegWidth), |
| .HighWatermark(1) |
| ) u_entropy_src_watermark_reg_bucket_bypass ( |
| .clk_i (clk_i), |
| .rst_ni (rst_ni), |
| .clear_i (health_test_clr), |
| .event_i (health_test_done_pulse && es_bypass_mode), |
| .value_i (bucket_event_cnt), |
| .value_o (bucket_event_hwm_bypass) |
| ); |
| |
| // SEC_CM: CTR.REDUN |
| entropy_src_cntr_reg #( |
| .RegWidth(FullRegWidth) |
| ) u_entropy_src_cntr_reg_bucket ( |
| .clk_i (clk_i), |
| .rst_ni (rst_ni), |
| .clear_i (health_test_clr), |
| .event_i (bucket_fail_pulse), |
| .value_o (bucket_total_fails), |
| .err_o (bucket_fails_cntr_err) |
| ); |
| |
| assign hw2reg.bucket_hi_watermarks.fips_watermark.d = bucket_event_hwm_fips; |
| assign hw2reg.bucket_hi_watermarks.bypass_watermark.d = bucket_event_hwm_bypass; |
| assign hw2reg.bucket_total_fails.d = bucket_total_fails; |
| |
| |
| //-------------------------------------------- |
| // Markov test |
| //-------------------------------------------- |
| |
| // SEC_CM: RNG.BKGN_CHK |
| entropy_src_markov_ht #( |
| .RegWidth(HalfRegWidth), |
| .RngBusWidth(RngBusWidth) |
| ) u_entropy_src_markov_ht ( |
| .clk_i (clk_i), |
| .rst_ni (rst_ni), |
| .entropy_bit_i (health_test_esbus), |
| .entropy_bit_vld_i (health_test_esbus_vld), |
| .clear_i (health_test_clr), |
| .active_i (markov_active), |
| .thresh_hi_i (markov_hi_threshold), |
| .thresh_lo_i (markov_lo_threshold), |
| .window_wrap_pulse_i (health_test_done_pulse), |
| .threshold_scope_i (threshold_scope), |
| .test_cnt_hi_o (markov_hi_event_cnt), |
| .test_cnt_lo_o (markov_lo_event_cnt), |
| .test_fail_hi_pulse_o (markov_hi_fail_pulse), |
| .test_fail_lo_pulse_o (markov_lo_fail_pulse), |
| .count_err_o (markov_cntr_err) |
| ); |
| |
| entropy_src_watermark_reg #( |
| .RegWidth(HalfRegWidth), |
| .HighWatermark(1) |
| ) u_entropy_src_watermark_reg_markov_hi_fips ( |
| .clk_i (clk_i), |
| .rst_ni (rst_ni), |
| .clear_i (health_test_clr), |
| .event_i (health_test_done_pulse && !es_bypass_mode), |
| .value_i (markov_hi_event_cnt), |
| .value_o (markov_hi_event_hwm_fips) |
| ); |
| |
| entropy_src_watermark_reg #( |
| .RegWidth(HalfRegWidth), |
| .HighWatermark(1) |
| ) u_entropy_src_watermark_reg_markov_hi_bypass ( |
| .clk_i (clk_i), |
| .rst_ni (rst_ni), |
| .clear_i (health_test_clr), |
| .event_i (health_test_done_pulse && es_bypass_mode), |
| .value_i (markov_hi_event_cnt), |
| .value_o (markov_hi_event_hwm_bypass) |
| ); |
| |
| // SEC_CM: CTR.REDUN |
| entropy_src_cntr_reg #( |
| .RegWidth(FullRegWidth) |
| ) u_entropy_src_cntr_reg_markov_hi ( |
| .clk_i (clk_i), |
| .rst_ni (rst_ni), |
| .clear_i (health_test_clr), |
| .event_i (markov_hi_fail_pulse), |
| .value_o (markov_hi_total_fails), |
| .err_o (markov_hi_fails_cntr_err) |
| ); |
| |
| assign hw2reg.markov_hi_watermarks.fips_watermark.d = markov_hi_event_hwm_fips; |
| assign hw2reg.markov_hi_watermarks.bypass_watermark.d = markov_hi_event_hwm_bypass; |
| assign hw2reg.markov_hi_total_fails.d = markov_hi_total_fails; |
| |
| |
| entropy_src_watermark_reg #( |
| .RegWidth(HalfRegWidth), |
| .HighWatermark(0) |
| ) u_entropy_src_watermark_reg_markov_lo_fips ( |
| .clk_i (clk_i), |
| .rst_ni (rst_ni), |
| .clear_i (health_test_clr), |
| .event_i (health_test_done_pulse && !es_bypass_mode), |
| .value_i (markov_lo_event_cnt), |
| .value_o (markov_lo_event_hwm_fips) |
| ); |
| |
| entropy_src_watermark_reg #( |
| .RegWidth(HalfRegWidth), |
| .HighWatermark(0) |
| ) u_entropy_src_watermark_reg_markov_lo_bypass ( |
| .clk_i (clk_i), |
| .rst_ni (rst_ni), |
| .clear_i (health_test_clr), |
| .event_i (health_test_done_pulse && es_bypass_mode), |
| .value_i (markov_lo_event_cnt), |
| .value_o (markov_lo_event_hwm_bypass) |
| ); |
| |
| // SEC_CM: CTR.REDUN |
| entropy_src_cntr_reg #( |
| .RegWidth(FullRegWidth) |
| ) u_entropy_src_cntr_reg_markov_lo ( |
| .clk_i (clk_i), |
| .rst_ni (rst_ni), |
| .clear_i (health_test_clr), |
| .event_i (markov_lo_fail_pulse), |
| .value_o (markov_lo_total_fails), |
| .err_o (markov_lo_fails_cntr_err) |
| ); |
| |
| assign hw2reg.markov_lo_watermarks.fips_watermark.d = markov_lo_event_hwm_fips; |
| assign hw2reg.markov_lo_watermarks.bypass_watermark.d = markov_lo_event_hwm_bypass; |
| assign hw2reg.markov_lo_total_fails.d = markov_lo_total_fails; |
| |
| |
| //-------------------------------------------- |
| // External health test |
| //-------------------------------------------- |
| |
| // set outputs to external health test |
| assign entropy_src_xht_o.entropy_bit = health_test_esbus; |
| assign entropy_src_xht_o.entropy_bit_valid = health_test_esbus_vld; |
| assign entropy_src_xht_o.clear = health_test_clr; |
| assign entropy_src_xht_o.active = extht_active; |
| assign entropy_src_xht_o.thresh_hi = extht_hi_threshold; |
| assign entropy_src_xht_o.thresh_lo = extht_lo_threshold; |
| assign entropy_src_xht_o.window_wrap_pulse = health_test_done_pulse; |
| assign entropy_src_xht_o.health_test_window = health_test_window; |
| assign entropy_src_xht_o.threshold_scope = threshold_scope; |
| // get inputs from external health test |
| assign extht_event_cnt_hi = entropy_src_xht_i.test_cnt_hi; |
| assign extht_event_cnt_lo = entropy_src_xht_i.test_cnt_lo; |
| assign extht_hi_fail_pulse = entropy_src_xht_i.test_fail_hi_pulse; |
| assign extht_lo_fail_pulse = entropy_src_xht_i.test_fail_lo_pulse; |
| assign extht_cont_test = entropy_src_xht_i.continuous_test; |
| |
| entropy_src_watermark_reg #( |
| .RegWidth(HalfRegWidth), |
| .HighWatermark(1) |
| ) u_entropy_src_watermark_reg_extht_hi_fips ( |
| .clk_i (clk_i), |
| .rst_ni (rst_ni), |
| .clear_i (health_test_clr), |
| .event_i ((extht_cont_test || health_test_done_pulse) && !es_bypass_mode), |
| .value_i (extht_event_cnt_hi), |
| .value_o (extht_hi_event_hwm_fips) |
| ); |
| |
| entropy_src_watermark_reg #( |
| .RegWidth(HalfRegWidth), |
| .HighWatermark(1) |
| ) u_entropy_src_watermark_reg_extht_hi_bypass ( |
| .clk_i (clk_i), |
| .rst_ni (rst_ni), |
| .clear_i (health_test_clr), |
| .event_i ((extht_cont_test || health_test_done_pulse) && es_bypass_mode), |
| .value_i (extht_event_cnt_hi), |
| .value_o (extht_hi_event_hwm_bypass) |
| ); |
| |
| // SEC_CM: CTR.REDUN |
| entropy_src_cntr_reg #( |
| .RegWidth(FullRegWidth) |
| ) u_entropy_src_cntr_reg_extht_hi ( |
| .clk_i (clk_i), |
| .rst_ni (rst_ni), |
| .clear_i (health_test_clr), |
| .event_i (extht_hi_fail_pulse), |
| .value_o (extht_hi_total_fails), |
| .err_o (extht_hi_fails_cntr_err) |
| ); |
| |
| |
| assign hw2reg.extht_hi_watermarks.fips_watermark.d = extht_hi_event_hwm_fips; |
| assign hw2reg.extht_hi_watermarks.bypass_watermark.d = extht_hi_event_hwm_bypass; |
| assign hw2reg.extht_hi_total_fails.d = extht_hi_total_fails; |
| |
| |
| entropy_src_watermark_reg #( |
| .RegWidth(HalfRegWidth), |
| .HighWatermark(0) |
| ) u_entropy_src_watermark_reg_extht_lo_fips ( |
| .clk_i (clk_i), |
| .rst_ni (rst_ni), |
| .clear_i (health_test_clr), |
| .event_i ((extht_cont_test || health_test_done_pulse) && !es_bypass_mode), |
| .value_i (extht_event_cnt_lo), |
| .value_o (extht_lo_event_hwm_fips) |
| ); |
| |
| entropy_src_watermark_reg #( |
| .RegWidth(HalfRegWidth), |
| .HighWatermark(0) |
| ) u_entropy_src_watermark_reg_extht_lo_bypass ( |
| .clk_i (clk_i), |
| .rst_ni (rst_ni), |
| .clear_i (health_test_clr), |
| .event_i ((extht_cont_test || health_test_done_pulse) && es_bypass_mode), |
| .value_i (extht_event_cnt_lo), |
| .value_o (extht_lo_event_hwm_bypass) |
| ); |
| |
| // SEC_CM: CTR.REDUN |
| entropy_src_cntr_reg #( |
| .RegWidth(FullRegWidth) |
| ) u_entropy_src_cntr_reg_extht_lo ( |
| .clk_i (clk_i), |
| .rst_ni (rst_ni), |
| .clear_i (health_test_clr), |
| .event_i (extht_lo_fail_pulse), |
| .value_o (extht_lo_total_fails), |
| .err_o (extht_lo_fails_cntr_err) |
| ); |
| |
| assign hw2reg.extht_lo_watermarks.fips_watermark.d = extht_lo_event_hwm_fips; |
| assign hw2reg.extht_lo_watermarks.bypass_watermark.d = extht_lo_event_hwm_bypass; |
| assign hw2reg.extht_lo_total_fails.d = extht_lo_total_fails; |
| |
| |
| //-------------------------------------------- |
| // summary and alert registers |
| //-------------------------------------------- |
| |
| assign alert_cntrs_clr = health_test_clr || rst_alert_cntr; |
| |
| // SEC_CM: CTR.REDUN |
| entropy_src_cntr_reg #( |
| .RegWidth(HalfRegWidth) |
| ) u_entropy_src_cntr_reg_any_alert_fails ( |
| .clk_i (clk_i), |
| .rst_ni (rst_ni), |
| .clear_i (alert_cntrs_clr), |
| .event_i (any_fail_pulse), |
| .value_o (any_fail_count), |
| .err_o (any_fails_cntr_err) |
| ); |
| |
| assign any_fail_pulse = |
| repcnt_fail_pulse || |
| repcnts_fail_pulse || |
| adaptp_hi_fail_pulse || adaptp_lo_fail_pulse || |
| bucket_fail_pulse || |
| markov_hi_fail_pulse || markov_lo_fail_pulse || |
| extht_hi_fail_pulse || extht_lo_fail_pulse; |
| |
| assign ht_failed_d = |
| (!es_enable_fo[6]) ? 1'b0 : |
| ht_done_pulse_q ? 1'b0 : |
| any_fail_pulse ? 1'b1 : |
| ht_failed_q; |
| |
| |
| // delay health pulse so that main_sm will |
| // get the correct threshold value comparisons |
| assign ht_done_pulse_d = health_test_done_pulse; |
| |
| assign hw2reg.alert_summary_fail_counts.d = any_fail_count; |
| |
| // signal an alert |
| // SEC_CM: CONFIG.REDUN |
| assign alert_threshold = reg2hw.alert_threshold.alert_threshold.q; |
| assign alert_threshold_inv = reg2hw.alert_threshold.alert_threshold_inv.q; |
| assign es_thresh_cfg_alert = (~alert_threshold_inv != alert_threshold); |
| |
| assign alert_threshold_fail = |
| ((any_fail_count >= ~alert_threshold_inv) && (~alert_threshold_inv != '0)) || |
| (any_fail_count >= alert_threshold) && (alert_threshold != '0); |
| |
| |
| prim_edge_detector #( |
| .Width(1), |
| .ResetValue(0), |
| .EnSync(0) |
| ) u_prim_edge_detector_recov_alert ( |
| .clk_i, |
| .rst_ni, |
| .d_i(recov_alert_state), |
| .q_sync_o(), |
| .q_posedge_pulse_o(recov_alert_o), |
| .q_negedge_pulse_o() |
| ); |
| |
| assign recov_alert_state = |
| es_enable_pfa || |
| fips_enable_pfa || |
| entropy_data_reg_en_pfa || |
| threshold_scope_pfa || |
| rng_bit_enable_pfa || |
| fw_ov_mode_pfa || |
| fw_ov_entropy_insert_pfa || |
| fw_ov_sha3_start_pfa || |
| es_route_pfa || |
| es_type_pfa || |
| es_main_sm_alert || |
| es_bus_cmp_alert || |
| es_thresh_cfg_alert || |
| es_fw_ov_wr_alert || |
| es_fw_ov_disable_alert; |
| |
| assign hw2reg.recov_alert_sts.es_main_sm_alert.de = es_main_sm_alert; |
| assign hw2reg.recov_alert_sts.es_main_sm_alert.d = es_main_sm_alert; |
| |
| assign hw2reg.recov_alert_sts.es_bus_cmp_alert.de = es_bus_cmp_alert; |
| assign hw2reg.recov_alert_sts.es_bus_cmp_alert.d = es_bus_cmp_alert; |
| |
| assign hw2reg.recov_alert_sts.es_thresh_cfg_alert.de = es_thresh_cfg_alert; |
| assign hw2reg.recov_alert_sts.es_thresh_cfg_alert.d = es_thresh_cfg_alert; |
| |
| assign hw2reg.recov_alert_sts.es_fw_ov_wr_alert.de = es_fw_ov_wr_alert; |
| assign hw2reg.recov_alert_sts.es_fw_ov_wr_alert.d = es_fw_ov_wr_alert; |
| |
| assign hw2reg.recov_alert_sts.es_fw_ov_disable_alert.de = es_fw_ov_disable_alert; |
| assign hw2reg.recov_alert_sts.es_fw_ov_disable_alert.d = es_fw_ov_disable_alert; |
| |
| // repcnt fail counter |
| // SEC_CM: CTR.REDUN |
| entropy_src_cntr_reg #( |
| .RegWidth(EighthRegWidth) |
| ) u_entropy_src_cntr_reg_repcnt_alert_fails ( |
| .clk_i (clk_i), |
| .rst_ni (rst_ni), |
| .clear_i (alert_cntrs_clr), |
| .event_i (repcnt_fail_pulse), |
| .value_o (repcnt_fail_count), |
| .err_o (repcnt_alert_cntr_err) |
| ); |
| |
| assign hw2reg.alert_fail_counts.repcnt_fail_count.d = repcnt_fail_count; |
| |
| // repcnts fail counter |
| // SEC_CM: CTR.REDUN |
| entropy_src_cntr_reg #( |
| .RegWidth(EighthRegWidth) |
| ) u_entropy_src_cntr_reg_repcnts_alert_fails ( |
| .clk_i (clk_i), |
| .rst_ni (rst_ni), |
| .clear_i (alert_cntrs_clr), |
| .event_i (repcnts_fail_pulse), |
| .value_o (repcnts_fail_count), |
| .err_o (repcnts_alert_cntr_err) |
| ); |
| |
| assign hw2reg.alert_fail_counts.repcnts_fail_count.d = repcnts_fail_count; |
| |
| // adaptp fail counter hi and lo |
| // SEC_CM: CTR.REDUN |
| entropy_src_cntr_reg #( |
| .RegWidth(EighthRegWidth) |
| ) u_entropy_src_cntr_reg_adaptp_hi_alert_fails ( |
| .clk_i (clk_i), |
| .rst_ni (rst_ni), |
| .clear_i (alert_cntrs_clr), |
| .event_i (adaptp_hi_fail_pulse), |
| .value_o (adaptp_hi_fail_count), |
| .err_o (adaptp_hi_alert_cntr_err) |
| ); |
| |
| assign hw2reg.alert_fail_counts.adaptp_hi_fail_count.d = adaptp_hi_fail_count; |
| |
| // SEC_CM: CTR.REDUN |
| entropy_src_cntr_reg #( |
| .RegWidth(EighthRegWidth) |
| ) u_entropy_src_cntr_reg_adaptp_lo_alert_fails ( |
| .clk_i (clk_i), |
| .rst_ni (rst_ni), |
| .clear_i (alert_cntrs_clr), |
| .event_i (adaptp_lo_fail_pulse), |
| .value_o (adaptp_lo_fail_count), |
| .err_o (adaptp_lo_alert_cntr_err) |
| ); |
| |
| assign hw2reg.alert_fail_counts.adaptp_lo_fail_count.d = adaptp_lo_fail_count; |
| |
| // bucket fail counter |
| // SEC_CM: CTR.REDUN |
| entropy_src_cntr_reg #( |
| .RegWidth(EighthRegWidth) |
| ) u_entropy_src_cntr_reg_bucket_alert_fails ( |
| .clk_i (clk_i), |
| .rst_ni (rst_ni), |
| .clear_i (alert_cntrs_clr), |
| .event_i (bucket_fail_pulse), |
| .value_o (bucket_fail_count), |
| .err_o (bucket_alert_cntr_err) |
| ); |
| |
| assign hw2reg.alert_fail_counts.bucket_fail_count.d = bucket_fail_count; |
| |
| |
| // markov fail counter hi and lo |
| // SEC_CM: CTR.REDUN |
| entropy_src_cntr_reg #( |
| .RegWidth(EighthRegWidth) |
| ) u_entropy_src_cntr_reg_markov_hi_alert_fails ( |
| .clk_i (clk_i), |
| .rst_ni (rst_ni), |
| .clear_i (alert_cntrs_clr), |
| .event_i (markov_hi_fail_pulse), |
| .value_o (markov_hi_fail_count), |
| .err_o (markov_hi_alert_cntr_err) |
| ); |
| |
| assign hw2reg.alert_fail_counts.markov_hi_fail_count.d = markov_hi_fail_count; |
| |
| // SEC_CM: CTR.REDUN |
| entropy_src_cntr_reg #( |
| .RegWidth(EighthRegWidth) |
| ) u_entropy_src_cntr_reg_markov_lo_alert_fails ( |
| .clk_i (clk_i), |
| .rst_ni (rst_ni), |
| .clear_i (alert_cntrs_clr), |
| .event_i (markov_lo_fail_pulse), |
| .value_o (markov_lo_fail_count), |
| .err_o (markov_lo_alert_cntr_err) |
| ); |
| |
| assign hw2reg.alert_fail_counts.markov_lo_fail_count.d = markov_lo_fail_count; |
| |
| // extht fail counter hi and lo |
| // SEC_CM: CTR.REDUN |
| entropy_src_cntr_reg #( |
| .RegWidth(EighthRegWidth) |
| ) u_entropy_src_cntr_reg_extht_hi_alert_fails ( |
| .clk_i (clk_i), |
| .rst_ni (rst_ni), |
| .clear_i (alert_cntrs_clr), |
| .event_i (extht_hi_fail_pulse), |
| .value_o (extht_hi_fail_count), |
| .err_o (extht_hi_alert_cntr_err) |
| ); |
| |
| assign hw2reg.extht_fail_counts.extht_hi_fail_count.d = extht_hi_fail_count; |
| |
| // SEC_CM: CTR.REDUN |
| entropy_src_cntr_reg #( |
| .RegWidth(EighthRegWidth) |
| ) u_entropy_src_cntr_reg_extht_lo_alert_fails ( |
| .clk_i (clk_i), |
| .rst_ni (rst_ni), |
| .clear_i (alert_cntrs_clr), |
| .event_i (extht_lo_fail_pulse), |
| .value_o (extht_lo_fail_count), |
| .err_o (extht_lo_alert_cntr_err) |
| ); |
| |
| assign hw2reg.extht_fail_counts.extht_lo_fail_count.d = extht_lo_fail_count; |
| |
| |
| //-------------------------------------------- |
| // pack tested entropy into 32 bit packer |
| //-------------------------------------------- |
| |
| prim_packer_fifo #( |
| .InW(RngBusWidth), |
| .OutW(PostHTWidth), |
| .ClearOnRead(1'b0) |
| ) u_prim_packer_fifo_postht ( |
| .clk_i (clk_i), |
| .rst_ni (rst_ni), |
| .clr_i (pfifo_postht_clr), |
| .wvalid_i (pfifo_postht_push), |
| .wdata_i (pfifo_postht_wdata), |
| .wready_o (pfifo_postht_not_full), |
| .rvalid_o (pfifo_postht_not_empty), |
| .rdata_o (pfifo_postht_rdata), |
| .rready_i (pfifo_postht_pop), |
| .depth_o () |
| ); |
| |
| assign pfifo_postht_push = rng_bit_en ? pfifo_esbit_not_empty : |
| sfifo_esrng_not_empty; |
| |
| assign pfifo_postht_wdata = rng_bit_en ? pfifo_esbit_rdata : |
| sfifo_esrng_rdata; |
| |
| // For verification purposes, let post-disable data continue through to the SHA engine if it has |
| // made it past the health checks, when in standard (non-fw_ov) mode. This allows scoreboards |
| // to use the same data set for computing both the SHA engine outputs and the health-check stats. |
| // |
| // In fw_ov mode it is preferable (from a verification standpoint) to clear all FIFOs whenever |
| // disabled. Given the lack of handshaking on the fw_ov register path, this is easier to predict. |
| // Also, there is no association between SHA data and health test windows in FW_OV mode, so there |
| // is no benefit in this mode to clearing the SHA FIFOs at the same time we clear the HT |
| // statistics. |
| |
| assign pfifo_postht_clr = fw_ov_mode_entropy_insert ? !es_enable_fo[7] : !es_delayed_enable; |
| assign pfifo_postht_pop = fw_ov_mode_entropy_insert ? pfifo_postht_not_empty : |
| es_bypass_mode ? pfifo_bypass_push : |
| pfifo_precon_push & pfifo_precon_not_full; |
| |
| |
| //-------------------------------------------- |
| // store entropy into a 64 entry deep FIFO |
| //-------------------------------------------- |
| |
| prim_fifo_sync #( |
| .Width(ObserveFifoWidth), |
| .Pass(0), |
| .Depth(ObserveFifoDepth) |
| ) u_prim_fifo_sync_observe ( |
| .clk_i (clk_i), |
| .rst_ni (rst_ni), |
| .clr_i (sfifo_observe_clr), |
| .wvalid_i (sfifo_observe_push), |
| .wdata_i (sfifo_observe_wdata), |
| .wready_o (), |
| .rvalid_o (sfifo_observe_not_empty), |
| .rdata_o (sfifo_observe_rdata), |
| .rready_i (sfifo_observe_pop), |
| .full_o (sfifo_observe_full), |
| .depth_o (sfifo_observe_depth), |
| .err_o () |
| ); |
| |
| // The Observe fifo is intended to hold kilobits of contiguous data, yet still gracefully |
| // drop data when full. This flop gates the observe fifo. If it ever overflows, no new data is |
| // allowed until it is empty. Thus if the rate of CSR uptake almost matches the RNG data rate |
| // the FIFO avoids unnecessary segmentation, and guarantees that the remaining RNG data is as |
| // contiguous as possible. |
| logic sfifo_observe_gate_d, sfifo_observe_gate_q; |
| |
| assign sfifo_observe_gate_d = (sfifo_observe_push && sfifo_observe_full) ? 1'b0 : |
| !sfifo_observe_not_empty ? 1'b1 : |
| sfifo_observe_gate_q; |
| |
| always_ff @(posedge clk_i or negedge rst_ni) begin |
| if (!rst_ni) begin |
| sfifo_observe_gate_q <= 1'b1; |
| end else begin |
| sfifo_observe_gate_q <= sfifo_observe_gate_d; |
| end |
| end |
| |
| assign hw2reg.fw_ov_rd_fifo_overflow.d = (pfifo_postht_pop && sfifo_observe_full); |
| assign hw2reg.fw_ov_rd_fifo_overflow.de = 1'b1; |
| |
| assign observe_fifo_thresh_met = fw_ov_mode && (observe_fifo_thresh != '0) && |
| (observe_fifo_thresh <= sfifo_observe_depth) && es_enable_fo[8]; |
| |
| assign hw2reg.observe_fifo_depth.d = sfifo_observe_depth; |
| |
| // fifo controls |
| assign sfifo_observe_push = fw_ov_mode && pfifo_postht_pop && !sfifo_observe_full && |
| (sfifo_observe_gate_q || !sfifo_observe_not_empty); |
| |
| assign sfifo_observe_clr = ~es_enable_fo[9]; |
| |
| assign sfifo_observe_wdata = pfifo_postht_rdata; |
| |
| assign sfifo_observe_pop = |
| (fw_ov_mode && fw_ov_fifo_rd_pulse); |
| |
| // fifo err |
| assign sfifo_observe_err = |
| {(sfifo_observe_push && sfifo_observe_full), |
| (sfifo_observe_pop && !sfifo_observe_not_empty), |
| (sfifo_observe_full && !sfifo_observe_not_empty)}; |
| |
| |
| //-------------------------------------------- |
| // pack entropy into 64 bit packer |
| //-------------------------------------------- |
| |
| prim_packer_fifo #( |
| .InW(ObserveFifoWidth), |
| .OutW(PreCondWidth), |
| .ClearOnRead(1'b0) |
| ) u_prim_packer_fifo_precon ( |
| .clk_i (clk_i), |
| .rst_ni (rst_ni), |
| .clr_i (pfifo_precon_clr), |
| .wvalid_i (pfifo_precon_push), |
| .wdata_i (pfifo_precon_wdata), |
| .wready_o (pfifo_precon_not_full), |
| .rvalid_o (pfifo_precon_not_empty), |
| .rdata_o (pfifo_precon_rdata), |
| .rready_i (pfifo_precon_pop), |
| .depth_o () |
| ); |
| |
| assign pfifo_precon_push = es_bypass_mode ? 1'b0 : |
| fw_ov_mode_entropy_insert ? fw_ov_fifo_wr_pulse : |
| pfifo_postht_not_empty; |
| |
| assign pfifo_precon_wdata = fw_ov_mode_entropy_insert ? fw_ov_wr_data : |
| pfifo_postht_rdata; |
| |
| // For verification purposes, let post-disable data continue through to the SHA engine if it has |
| // made it past the health checks, when in standard (non-fw_ov) mode. This allows scoreboards |
| // to use the same data set for computing both the SHA engine outputs and the health-check stats. |
| // |
| // In fw_ov mode it is preferable (from a verification standpoint) to clear all FIFOs whenever |
| // disabled. Given the lack of handshaking on the fw_ov register path, this is easier to predict. |
| // Also, there is no association between SHA data and health test windows in FW_OV mode, so there |
| // is no benefit in this mode to clearing the SHA FIFOs at the same time we clear the HT |
| // statistics. |
| // |
| // Corner case: Even in FW_OV mode, if a full SHA word is ready as the disable comes in, |
| // let it stay in the FIFO until the SHA engine has picked it up, as verification has no way |
| // of knowing if a word will get stalled by SHA backpressure. This is not a problem however |
| // as the reset is only important for clearing 32-bit half-SHA-words. |
| assign pfifo_precon_clr = fw_ov_mode_entropy_insert ? |
| ~es_enable_fo[10] & ~pfifo_precon_not_empty : |
| ~es_delayed_enable & ~pfifo_precon_not_empty; |
| |
| assign pfifo_precon_pop = (pfifo_cond_push && sha3_msgfifo_ready); |
| |
| assign es_fw_ov_wr_alert = fw_ov_mode && fw_ov_mode_entropy_insert && |
| fw_ov_fifo_wr_pulse && fw_ov_wr_fifo_full; |
| |
| assign es_fw_ov_disable_alert = fw_ov_mode && fw_ov_mode_entropy_insert && |
| !es_bypass_mode && fw_ov_sha3_disable_pulse && fw_ov_wr_fifo_full; |
| |
| //-------------------------------------------- |
| // entropy conditioner |
| //-------------------------------------------- |
| // This block will take in raw entropy from the noise source block |
| // and compress it such that a perfect entropy source is created |
| // This block will take in 2048 (by default setting) bits to create 384 bits. |
| |
| // Note on backpressure from the SHA block: |
| // If we use the full sha3_msgfifo_ready signal, we create a combinational logic |
| // loop. However, the SHA3 seems to have a hiccup by which it some times |
| // asserts ready even though it is processing data, so we mask our push |
| // signal with our (flop-based) sha3_msg_rdy_mask |
| assign pfifo_cond_push = pfifo_precon_not_empty && !es_bypass_mode && sha3_msg_rdy_mask; |
| |
| assign pfifo_cond_wdata = pfifo_precon_rdata; |
| |
| assign msg_data[0] = pfifo_cond_wdata; |
| |
| // The SHA3 block cannot take messages except between the |
| // start and cs_aes_req pulses |
| assign sha3_msg_end = cs_aes_halt_req; |
| |
| assign sha3_msg_rdy_mask_d = sha3_start ? 1'b1 : |
| sha3_msg_end ? 1'b0 : |
| sha3_msg_rdy_mask_q; |
| |
| assign sha3_msg_rdy_mask = sha3_msg_rdy_mask_q & ~sha3_msg_end & |
| ~cs_aes_halt_req; |
| |
| assign pfifo_cond_rdata = sha3_state[0][SeedLen-1:0]; |
| assign pfifo_cond_not_empty = sha3_state_vld; |
| assign sha3_msgfifo_ready = sha3_msg_rdy & sha3_msg_rdy_mask; |
| |
| // SHA3 hashing engine |
| sha3 #( |
| .EnMasking (Sha3EnMasking) |
| ) u_sha3 ( |
| .clk_i, |
| .rst_ni, |
| |
| // MSG_FIFO interface |
| .msg_valid_i (pfifo_cond_push), |
| .msg_data_i (msg_data), |
| .msg_strb_i ({8{pfifo_cond_push}}), |
| .msg_ready_o (sha3_msg_rdy), |
| |
| // Entropy interface - not using |
| .rand_valid_i (1'b0), |
| .rand_early_i (1'b0), |
| .rand_data_i ('0), |
| .rand_aux_i ('0), |
| .rand_consumed_o (), |
| |
| // N, S: Used in cSHAKE mode |
| .ns_data_i ('0), // ns_prefix), |
| |
| // Configurations |
| .mode_i (sha3_pkg::Sha3), // Use SHA3 mode |
| .strength_i (sha3_pkg::L384), // Use keccak_strength_e of L384 |
| |
| // Controls (CMD register) |
| .start_i (sha3_start ), |
| .process_i (sha3_process ), |
| .run_i (1'b0 ), // For software application |
| .done_i (sha3_done ), |
| |
| // LC escalation |
| .lc_escalate_en_i (lc_ctrl_pkg::Off), |
| |
| .absorbed_o (sha3_absorbed), |
| .squeezing_o (sha3_squeezing), |
| |
| .block_processed_o (sha3_block_processed), |
| |
| .sha3_fsm_o (sha3_fsm), |
| |
| .state_valid_o (sha3_state_vld), |
| .state_o (sha3_state), |
| |
| .error_o (sha3_err), |
| .sparse_fsm_error_o (sha3_state_error), |
| .count_error_o (sha3_count_error), |
| .keccak_storage_rst_error_o (sha3_rst_storage_err) |
| ); |
| |
| //-------------------------------------------- |
| // bypass SHA conditioner path |
| //-------------------------------------------- |
| |
| prim_packer_fifo #( |
| .InW(PostHTWidth), |
| .OutW(SeedLen), |
| .ClearOnRead(1'b0) |
| ) u_prim_packer_fifo_bypass ( |
| .clk_i (clk_i), |
| .rst_ni (rst_ni), |
| .clr_i (pfifo_bypass_clr), |
| .wvalid_i (pfifo_bypass_push), |
| .wdata_i (pfifo_bypass_wdata), |
| .wready_o (pfifo_bypass_not_full), |
| .rvalid_o (pfifo_bypass_not_empty), |
| .rdata_o (pfifo_bypass_rdata), |
| .rready_i (pfifo_bypass_pop), |
| .depth_o () |
| ); |
| |
| assign pfifo_bypass_push = !es_bypass_mode ? 1'b0 : |
| fw_ov_mode_entropy_insert ? fw_ov_fifo_wr_pulse : |
| pfifo_postht_not_empty; |
| assign pfifo_bypass_wdata = fw_ov_mode_entropy_insert ? fw_ov_wr_data : |
| pfifo_postht_rdata; |
| |
| assign pfifo_bypass_clr = !es_enable_fo[11]; |
| |
| // Corner case: If the main state machine encounters an alert, drain the |
| // bypass fifo, to get rid of the seeds and let the HT stats continue. |
| assign pfifo_bypass_pop = |
| fw_ov_mode_entropy_insert ? pfifo_bypass_not_empty : |
| bypass_stage_pop; |
| |
| // mux to select between fips and bypass mode |
| assign final_es_data = es_bypass_mode ? pfifo_bypass_rdata : pfifo_cond_rdata; |
| |
| |
| //-------------------------------------------- |
| // state machine to coordinate fifo flow |
| //-------------------------------------------- |
| |
| // SEC_CM: CTR.LOCAL_ESC |
| // SEC_CM: MAIN_SM.FSM.SPARSE |
| entropy_src_main_sm |
| u_entropy_src_main_sm ( |
| .clk_i (clk_i), |
| .rst_ni (rst_ni), |
| .enable_i (main_sm_enable), |
| .fw_ov_ent_insert_i (fw_ov_mode_entropy_insert), |
| .fw_ov_sha3_start_i (fw_ov_sha3_start_pfe), |
| .ht_done_pulse_i (ht_done_pulse_q), |
| .ht_fail_pulse_i (ht_failed_q), |
| .alert_thresh_fail_i (alert_threshold_fail), |
| .rst_alert_cntr_o (rst_alert_cntr), |
| .bypass_mode_i (es_bypass_mode), |
| .main_stage_rdy_i (pfifo_cond_not_empty), |
| .bypass_stage_rdy_i (pfifo_bypass_not_empty), |
| .sha3_state_vld_i (sha3_state_vld), |
| .main_stage_push_o (main_stage_push_raw), |
| .bypass_stage_pop_o (bypass_stage_pop), |
| .boot_phase_done_o (boot_phase_done), |
| .sha3_start_o (sha3_start_raw), |
| .sha3_process_o (sha3_process), |
| .sha3_done_o (sha3_done), |
| .cs_aes_halt_req_o (cs_aes_halt_req), |
| .cs_aes_halt_ack_i (cs_aes_halt_i.cs_aes_halt_ack), |
| .local_escalate_i (es_cntr_err_sum), |
| .main_sm_alert_o (es_main_sm_alert), |
| .main_sm_idle_o (es_main_sm_idle), |
| .main_sm_state_o (es_main_sm_state), |
| .main_sm_err_o (es_main_sm_err) |
| ); |
| |
| // es to cs halt request to reduce power spikes |
| assign cs_aes_halt_d = cs_aes_halt_req; |
| assign cs_aes_halt_o.cs_aes_halt_req = cs_aes_halt_q; |
| |
| //-------------------------------------------- |
| // Corner case masking of main_sm inputs/outputs |
| //-------------------------------------------- |
| |
| // When operating in RNG mode the state machine does not respond |
| // immediately to disable requests if it processing the SHA output |
| // (here indicated by the cs_aes_halt_req handshake). The SHA engine |
| // will continue to process even if the module is disabled. These seeds |
| // that continue to process after the disable signal are referred to as |
| // stale. |
| // |
| // If the SHA processing were instantaneous, stale seeds would be discarded |
| // when the esfinal fifo was cleard on diable. Though since processing |
| // can push through a disable pulse, stale seeds need to be identified, |
| // and held back from the esfinal FIFO. |
| // |
| // There is at most one seed processing at a time so, we simply need to |
| // detect when a stale seed has commenced processing, and mask the following |
| // main_stage_push signal. |
| |
| assign stale_seed_processing = ~es_bypass_mode & ~fw_ov_mode_entropy_insert & |
| cs_aes_halt_req & ~es_enable_fo[12]; |
| assign sha3_flush_d = stale_seed_processing ? 1'b1 : |
| main_stage_push_raw ? 1'b0 : |
| sha3_flush_q; |
| |
| // If the user incorrectly disables the fw_ov SHA3 processing while |
| // data is in the pipeline, it can potentially scramble two outputs. |
| // Thus in addition to triggering a recoverable alert, we mark the |
| // following _two_ outputs as corrupted and to not let them in the |
| // esfinal FIFO |
| assign fw_ov_corrupted_d = es_fw_ov_disable_alert ? 2'b11 : |
| !es_bypass_mode && main_stage_push_raw ? {1'b0, fw_ov_corrupted_q[1]} : |
| fw_ov_corrupted_q; |
| |
| assign fw_ov_corrupted = (|fw_ov_corrupted_q) & !es_bypass_mode; |
| |
| |
| assign main_stage_push = main_stage_push_raw & !sha3_flush_q & !fw_ov_corrupted; |
| |
| // Use the delayed enable signal to keep the Main SM enabled while Data is in flight, and |
| // to make sure it receives a delayed disable pulse after finishing any final SHA processing |
| // commands |
| assign main_sm_enable = es_delayed_enable; |
| |
| // The main SM can also generate redundant start pulses. After data can be pushed into SHA, |
| // the SM can be disabled leaving entropy in the SHA sponge. This is fine, but the SM will |
| // have no recollection of this previous start pulse. We track redundant start pulses |
| // outside the SM and suppress them as needed. |
| assign sha3_start_mask_d = sha3_start_raw ? 1'b1 : |
| sha3_process ? 1'b0 : |
| sha3_start_mask_q; |
| assign sha3_start = sha3_start_raw & ~sha3_start_mask_q; |
| |
| //-------------------------------------------- |
| // send processed entropy to final fifo |
| //-------------------------------------------- |
| |
| prim_fifo_sync #( |
| .Width(1+SeedLen), |
| .Pass(0), |
| .Depth(EsFifoDepth) |
| ) u_prim_fifo_sync_esfinal ( |
| .clk_i (clk_i), |
| .rst_ni (rst_ni), |
| .clr_i (sfifo_esfinal_clr), |
| .wvalid_i (sfifo_esfinal_push), |
| .wready_o (sfifo_esfinal_not_full), |
| .wdata_i (sfifo_esfinal_wdata), |
| .rvalid_o (sfifo_esfinal_not_empty), |
| .rready_i (sfifo_esfinal_pop), |
| .rdata_o (sfifo_esfinal_rdata), |
| .full_o (sfifo_esfinal_full), |
| .depth_o (sfifo_esfinal_depth), |
| .err_o () |
| ); |
| |
| assign fips_compliance = !es_bypass_mode && es_enable_fo[13] && !rng_bit_en; |
| |
| // fifo controls |
| assign sfifo_esfinal_push_enable = |
| fw_ov_mode_entropy_insert && es_bypass_mode ? pfifo_bypass_not_empty : |
| main_stage_push; |
| |
| assign sfifo_esfinal_push = sfifo_esfinal_not_full && sfifo_esfinal_push_enable; |
| assign sfifo_esfinal_clr = !es_enable_fo[14]; |
| assign sfifo_esfinal_wdata = {fips_compliance,final_es_data}; |
| assign sfifo_esfinal_pop = es_route_to_sw ? pfifo_swread_push : |
| es_hw_if_fifo_pop; |
| assign {esfinal_fips_flag,esfinal_data} = sfifo_esfinal_rdata; |
| |
| // fifo err |
| // Note: for prim_fifo_sync is not an error to push to a fifo that is full. In fact, the |
| // backpressure mechanism applied to the previous FIFO counts on this. |
| assign sfifo_esfinal_err = |
| {1'b0, |
| (sfifo_esfinal_pop && !sfifo_esfinal_not_empty), |
| (sfifo_esfinal_full && !sfifo_esfinal_not_empty)}; |
| |
| // drive out hw interface |
| assign es_hw_if_req = entropy_src_hw_if_i.es_req; |
| assign entropy_src_hw_if_o.es_ack = es_hw_if_ack; |
| assign entropy_src_hw_if_o.es_bits = esfinal_data; |
| assign entropy_src_hw_if_o.es_fips = esfinal_fips_flag; |
| |
| // SEC_CM: ACK_SM.FSM.SPARSE |
| entropy_src_ack_sm u_entropy_src_ack_sm ( |
| .clk_i (clk_i), |
| .rst_ni (rst_ni), |
| .enable_i (es_enable_fo[15]), |
| .req_i (es_hw_if_req), |
| .ack_o (es_hw_if_ack), |
| .fifo_not_empty_i (sfifo_esfinal_not_empty && !es_route_to_sw), |
| .local_escalate_i (es_cntr_err), |
| .fifo_pop_o (es_hw_if_fifo_pop), |
| .ack_sm_err_o (es_ack_sm_err) |
| ); |
| |
| //-------------------------------------------- |
| // data path integrity check |
| // - a countermeasure to detect entropy bus tampering attempts |
| // - checks to make sure repeated data sets off |
| // an alert for sw to handle |
| //-------------------------------------------- |
| |
| // SEC_CM: ESFINAL_RDATA.BUS.CONSISTENCY |
| |
| // capture a copy of the entropy data |
| assign es_rdata_capt_vld = (sfifo_esfinal_pop && sfifo_esfinal_not_empty); |
| |
| assign es_rdata_capt_d = es_rdata_capt_vld ? sfifo_esfinal_rdata[63:0] : es_rdata_capt_q; |
| |
| assign es_rdata_capt_vld_d = |
| !es_enable_fo[16] ? 1'b0 : |
| es_rdata_capt_vld ? 1'b1 : |
| es_rdata_capt_vld_q; |
| |
| // continuous compare of the entropy data |
| assign es_bus_cmp_alert = es_rdata_capt_vld && es_rdata_capt_vld_q && |
| (es_rdata_capt_q == sfifo_esfinal_rdata[63:0]); |
| |
| |
| //-------------------------------------------- |
| // software es read path |
| //-------------------------------------------- |
| |
| prim_packer_fifo #( |
| .InW(SeedLen), |
| .OutW(FullRegWidth), |
| .ClearOnRead(1'b0) |
| ) u_prim_packer_fifo_swread ( |
| .clk_i (clk_i), |
| .rst_ni (rst_ni), |
| .clr_i (pfifo_swread_clr), |
| .wvalid_i (pfifo_swread_push), |
| .wdata_i (pfifo_swread_wdata), |
| .wready_o (pfifo_swread_not_full), |
| .rvalid_o (pfifo_swread_not_empty), |
| .rdata_o (pfifo_swread_rdata), |
| .rready_i (pfifo_swread_pop), |
| .depth_o () |
| ); |
| |
| assign pfifo_swread_push = es_route_to_sw && pfifo_swread_not_full && sfifo_esfinal_not_empty; |
| assign pfifo_swread_wdata = esfinal_data; |
| |
| assign pfifo_swread_clr = !(es_enable_fo[17] && es_data_reg_rd_en); |
| assign pfifo_swread_pop = es_enable_fo[18] && sw_es_rd_pulse; |
| |
| // set the es entropy to the read reg |
| assign es_data_reg_rd_en = es_enable_fo[19] && efuse_es_sw_reg_en && entropy_data_reg_en_pfe; |
| assign hw2reg.entropy_data.d = es_data_reg_rd_en ? pfifo_swread_rdata : '0; |
| assign sw_es_rd_pulse = es_data_reg_rd_en && reg2hw.entropy_data.re; |
| |
| assign efuse_es_sw_reg_en = prim_mubi_pkg::mubi8_test_true_strict(en_entropy_src_fw_read); |
| |
| prim_mubi8_sync #( |
| .NumCopies(1), |
| .AsyncOn(1) // must be set to one, see note below |
| ) u_prim_mubi8_sync_es_fw_read ( |
| .clk_i, |
| .rst_ni, |
| .mubi_i(otp_en_entropy_src_fw_read_i), |
| .mubi_o({en_entropy_src_fw_read}) |
| ); |
| |
| // note: the input to the above sync module is from the OTP block. |
| // It is assumed that the source is in a different time domain, |
| // and requires the AsyncOn parameter to be set. |
| |
| |
| //-------------------------------------------- |
| // unused signals |
| //-------------------------------------------- |
| |
| assign unused_err_code_test_bit = (|{err_code_test_bit[27:25],err_code_test_bit[19:3]}); |
| assign unused_sha3_state = (|sha3_state[0][sha3_pkg::StateW-1:SeedLen]); |
| assign unused_entropy_data = (|reg2hw.entropy_data.q); |
| assign unused_fw_ov_rd_data = (|reg2hw.fw_ov_rd_data.q); |
| |
| |
| endmodule |