// Copyright lowRISC contributors.
// Licensed under the Apache License, Version 2.0, see LICENSE for details.
// SPDX-License-Identifier: Apache-2.0
//
// Key manager top level
//

`include "prim_assert.sv"

module keymgr_ctrl
  import keymgr_pkg::*;
  import keymgr_reg_pkg::*;
#(
  parameter bit KmacEnMasking = 1'b1
) (
  input clk_i,
  input rst_ni,

  // lifecycle enforcement
  // SEC_CM: CTRL.FSM.GLOBAL_ESC
  input en_i,

  // faults that can occur outside of operations
  input regfile_intg_err_i,
  input shadowed_update_err_i,
  input shadowed_storage_err_i,
  input reseed_cnt_err_i,
  input sideload_sel_err_i,
  input sideload_fsm_err_i,

  // Software interface
  input op_start_i,
  input keymgr_ops_e op_i,
  input [CdiWidth-1:0] op_cdi_sel_i,
  output logic op_done_o,
  output keymgr_op_status_e status_o,
  output logic [ErrLastPos-1:0] error_o,
  output logic [FaultLastPos-1:0] fault_o,
  output logic data_hw_en_o,
  output logic data_sw_en_o,
  output logic data_valid_o,
  output logic wipe_key_o,
  output keymgr_working_state_e working_state_o,
  output logic sw_binding_unlock_o,
  output logic init_o,

  // Data input
  input  otp_ctrl_pkg::otp_keymgr_key_t root_key_i,
  output prim_mubi_pkg::mubi4_t hw_sel_o,
  output keymgr_stage_e stage_sel_o,
  output logic invalid_stage_sel_o,
  output logic [CdiWidth-1:0] cdi_sel_o,

  // KMAC ctrl interface
  output logic adv_en_o,
  output logic id_en_o,
  output logic gen_en_o,
  output hw_key_req_t key_o,
  input kmac_done_i,
  input kmac_input_invalid_i, // asserted when selected data fails criteria check
  input kmac_fsm_err_i, // asserted when kmac fsm reaches unexpected state
  input kmac_op_err_i,  // asserted when kmac itself reports an error
  input kmac_done_err_i,// asserted when kmac unexpectedly toggles done
  input kmac_cmd_err_i, // asserted when more than one command given to kmac
  input [Shares-1:0][KeyWidth-1:0] kmac_data_i,

  // prng control interface
  input [Shares-1:0][RandWidth-1:0] entropy_i,
  input prng_reseed_ack_i,
  output logic prng_reseed_req_o,
  output logic prng_en_o
);

  localparam int EntropyWidth = LfsrWidth / 2;
  localparam int EntropyRounds = KeyWidth / EntropyWidth;
  localparam int EntropyRndWidth = prim_util_pkg::vbits(EntropyRounds);
  localparam int CntWidth = EntropyRounds > CDIs ? EntropyRndWidth : CdiWidth;
  localparam int EccDataWidth = 64;
  localparam int EccWidth = 8;
  localparam int EccWords = KeyWidth / EccDataWidth;
  localparam int TotalEccWords = EccWords * Shares * CDIs;


  // Enumeration for working state
  // Encoding generated with:
  // $ ./util/design/sparse-fsm-encode.py -d 5 -m 11 -n 10 \
  //      -s 4101887575 --language=sv
  //
  // Hamming distance histogram:
  //
  //  0: --
  //  1: --
  //  2: --
  //  3: --
  //  4: --
  //  5: |||||||||||||||||||| (54.55%)
  //  6: |||||||||||||||| (45.45%)
  //  7: --
  //  8: --
  //  9: --
  // 10: --
  //
  // Minimum Hamming distance: 5
  // Maximum Hamming distance: 6
  // Minimum Hamming weight: 2
  // Maximum Hamming weight: 8
  //
  localparam int StateWidth = 10;
  typedef enum logic [StateWidth-1:0] {
    StCtrlReset          = 10'b1101100001,
    StCtrlEntropyReseed  = 10'b1110010010,
    StCtrlRandom         = 10'b0011110100,
    StCtrlRootKey        = 10'b0110101111,
    StCtrlInit           = 10'b0100000100,
    StCtrlCreatorRootKey = 10'b1000011101,
    StCtrlOwnerIntKey    = 10'b0001001010,
    StCtrlOwnerKey       = 10'b1101111110,
    StCtrlDisabled       = 10'b1010101000,
    StCtrlWipe           = 10'b0000110011,
    StCtrlInvalid        = 10'b1011000111
  } state_e;
  state_e state_q, state_d;

  // A variable that represents differentiates states before root key and after root key.
  logic initialized;

  // There are two versions of the key state, one for sealing one for attestation
  // Among each version, there are multiple shares
  // Each share is a fixed multiple of the entropy width
  logic [CDIs-1:0][Shares-1:0][EntropyRounds-1:0][EntropyWidth-1:0] key_state_d;
  logic [CDIs-1:0][Shares-1:0][EccWords-1:0][EccDataWidth-1:0] key_state_ecc_words_d;
  logic [CDIs-1:0][Shares-1:0][EccWords-1:0][EccDataWidth-1:0] key_state_q;
  logic [CDIs-1:0][Shares-1:0][EccWords-1:0][EccWidth-1:0] key_state_ecc_q;
  logic [CntWidth-1:0] cnt;
  logic [CdiWidth-1:0] cdi_cnt;

  // error conditions
  logic invalid_kmac_out;
  logic invalid_op;
  logic cnt_err;
  // states fall out of sparsely encoded range
  logic state_intg_err_q, state_intg_err_d;

  ///////////////////////////
  //  General operation decode
  ///////////////////////////

  logic adv_op, dis_op, gen_id_op, gen_sw_op, gen_hw_op, gen_op;
  assign adv_op    = (op_i == OpAdvance);
  assign gen_id_op = (op_i == OpGenId);
  assign gen_sw_op = (op_i == OpGenSwOut);
  assign gen_hw_op = (op_i == OpGenHwOut);
  assign dis_op    = ~(op_i inside {OpAdvance, OpGenId, OpGenSwOut, OpGenHwOut});
  assign gen_op    = (gen_id_op | gen_sw_op | gen_hw_op);

  ///////////////////////////
  //  interaction between software and main fsm
  ///////////////////////////
  // disable is treated like an advanced call
  logic advance_sel;
  logic disable_sel;
  logic gen_out_hw_sel;

  assign advance_sel    = op_start_i & adv_op    & en_i;
  assign gen_out_hw_sel = op_start_i & gen_hw_op & en_i;

  // disable is selected whenever a normal operation is not set
  assign disable_sel    = (op_start_i & dis_op) | !en_i;


  ///////////////////////////
  //  interaction between main control fsm and operation fsm
  ///////////////////////////

  // req/ack interface with op handling fsm
  logic op_req;
  logic op_ack;
  logic op_update;
  logic op_busy;
  logic disabled;
  logic invalid;

  logic adv_req, dis_req, id_req, gen_req;
  assign adv_req = op_req & adv_op;
  assign dis_req = op_req & dis_op;
  assign id_req  = op_req & gen_id_op;
  assign gen_req = op_req & (gen_sw_op | gen_hw_op);

  ///////////////////////////
  //  interaction between operation fsm and software
  ///////////////////////////
  // categories of keymgr errors
  logic [SyncErrLastIdx-1:0] sync_err;
  logic [SyncFaultLastIdx-1:0] sync_fault;
  logic [AsyncFaultLastIdx-1:0] async_fault;

  logic op_err;
  logic op_fault_err;

  // unlock sw binding configuration whenever an advance call is made without errors
  assign sw_binding_unlock_o = adv_req & op_ack & ~(op_err | op_fault_err);

  // error definition
  // check incoming kmac data validity
  // Only check during the periods when there is actual kmac output
  assign invalid_kmac_out = (op_update | op_ack) &
                            (~valid_data_chk(kmac_data_i[0]) |
                            (~valid_data_chk(kmac_data_i[1]) & KmacEnMasking));

  // async errors have nothing to do with the operation and thus should not
  // impact operation results.
  assign op_err = |sync_err;

  assign op_fault_err = |{sync_fault, async_fault};

  ///////////////////////////
  //  key update controls
  ///////////////////////////

  // update select can come from both main and operation fsm's
  keymgr_key_update_e update_sel, op_update_sel;

  // req from main control fsm to key update controls
  logic wipe_req;
  logic random_req;
  logic random_ack;

  // wipe and initialize take precedence
  assign update_sel = wipe_req             ? KeyUpdateWipe   :
                      random_req           ? KeyUpdateRandom :
                      init_o               ? KeyUpdateRoot   : op_update_sel;

  ///////////////////////////
  //  interaction between main fsm and prng
  ///////////////////////////

  assign prng_en_o = random_req | disabled | invalid | wipe_req;

  //////////////////////////
  // Main Control FSM
  //////////////////////////
  // SEC_CM: CTRL.FSM.SPARSE
  `PRIM_FLOP_SPARSE_FSM(u_state_regs, state_d, state_q, state_e, StCtrlReset)

  always_ff @(posedge clk_i or negedge rst_ni) begin
    if (!rst_ni) begin
      state_intg_err_q <= '0;
    end else begin
      state_intg_err_q <= state_intg_err_d;
    end
  end

  // prevents unknowns from reaching the outside world.
  // - whatever operation causes the input data select to be disabled should not expose the key
  //   state.
  // - when there are no operations, the key state also should be exposed.
  assign key_o.valid = op_req;

  assign cdi_sel_o = advance_sel ? cdi_cnt : op_cdi_sel_i;

  assign invalid_stage_sel_o = ~(stage_sel_o inside {Creator, OwnerInt, Owner});
  for (genvar i = 0; i < Shares; i++) begin : gen_key_out_assign
    assign key_o.key[i] = invalid_stage_sel_o ?
                          {EntropyRounds{entropy_i[i]}} :
                          key_state_q[cdi_sel_o][i];
  end


  //SEC_CM: CTRL.KEY.INTEGRITY
  assign key_state_ecc_words_d = key_state_d;
  always_ff @(posedge clk_i or negedge rst_ni) begin
    if (!rst_ni) begin
      key_state_q <= '0;
      key_state_ecc_q <= {TotalEccWords{prim_secded_pkg::SecdedInv7264ZeroEcc}};
    end else begin
      for (int i = 0; i < CDIs; i++) begin
        for (int j = 0; j < Shares; j++) begin
          for (int k = 0; k < EccWords; k++) begin
            {key_state_ecc_q[i][j][k], key_state_q[i][j][k]} <=
                prim_secded_pkg::prim_secded_inv_72_64_enc(key_state_ecc_words_d[i][j][k]);
          end
        end
      end
    end
  end

  logic [CDIs-1:0][Shares-1:0][EccWords-1:0] ecc_errs;
  for (genvar i = 0; i < CDIs; i++) begin : gen_ecc_loop_cdi
    for (genvar j = 0; j < Shares; j++) begin : gen_ecc_loop_shares
      for (genvar k = 0; k < EccWords; k++) begin : gen_ecc_loop_words
        logic [1:0] errs;
        prim_secded_inv_72_64_dec u_dec (
          .data_i({key_state_ecc_q[i][j][k], key_state_q[i][j][k]}),
          .data_o(),
          .syndrome_o(),
          .err_o(errs)
        );
        assign ecc_errs[i][j][k] = |errs;
      end
    end
  end

  // root key valid sync
  logic root_key_valid_q;

  prim_flop_2sync # (
    .Width(1)
  ) u_key_valid_sync (
    .clk_i,
    .rst_ni,
    .d_i(root_key_i.valid),
    .q_o(root_key_valid_q)
  );

  // Do not let the count toggle unless an advance operation is
  // selected
  assign cdi_cnt = op_req ? cnt[CdiWidth-1:0] : '0;

  always_comb begin
    key_state_d = key_state_q;
    data_valid_o = 1'b0;
    wipe_key_o = 1'b0;

    // if a wipe request arrives, immediately destroy the
    // keys regardless of current state
    unique case (update_sel)
      KeyUpdateRandom: begin
        for (int i = 0; i < CDIs; i++) begin
          for (int j = 0; j < Shares; j++) begin
            // Load each share with the same randomness so we can
            // later simply XOR root key on them
            key_state_d[i][j][cnt[EntropyRndWidth-1:0]] = entropy_i[i];
          end
        end
      end

      KeyUpdateRoot: begin
        if (root_key_valid_q) begin
          for (int i = 0; i < CDIs; i++) begin
            if (KmacEnMasking) begin : gen_two_share_key
              key_state_d[i][0] ^= root_key_i.key_share0;
              key_state_d[i][1] ^= root_key_i.key_share1;
            end else begin : gen_one_share_key
              key_state_d[i][0] = root_key_i.key_share0 ^ root_key_i.key_share1;
              key_state_d[i][1] = '0;
            end
          end
        end else begin
          // if root key is not valid, load and invalid value
          for (int i = 0; i < CDIs; i++) begin
              key_state_d[i][0] = '0;
              key_state_d[i][1] = '{default: '1};
          end
        end
      end

      KeyUpdateKmac: begin
        data_valid_o = gen_op;
        key_state_d[cdi_sel_o] = (adv_op || dis_op) ? kmac_data_i : key_state_q[cdi_sel_o];
      end

      KeyUpdateWipe: begin
        wipe_key_o = 1'b1;
        for (int i = 0; i < CDIs; i++) begin
          for (int j = 0; j < Shares; j++) begin
            key_state_d[i][j] = {EntropyRounds{entropy_i[j]}};
          end
        end
      end

      default:;
    endcase // unique case (update_sel)
  end

  // SEC_CM: CTRL.CTR.REDUN
  prim_count #(
    .Width(CntWidth)
  ) u_cnt (
    .clk_i,
    .rst_ni,
    .clr_i(op_ack | random_ack),
    .set_i('0),
    .set_cnt_i('0),
    .incr_en_i(op_update | random_req),
    .decr_en_i(1'b0),
    .step_i(CntWidth'(1'b1)),
    .cnt_o(cnt),
    .cnt_next_o(),
    .err_o(cnt_err)
  );


  prim_mubi4_sender u_hw_sel (
    .clk_i,
    .rst_ni,
    .mubi_i (prim_mubi_pkg::mubi4_bool_to_mubi(gen_out_hw_sel)),
    .mubi_o (hw_sel_o)
  );

  // when in a state that accepts commands, look at op_ack for completion
  // when in a state that does not accept commands, wait for other triggers.
  assign op_done_o = op_req ? op_ack :
                     (init_o | invalid_op);


  // There are 3 possibilities
  // advance to next state (software command)
  // advance to disabled state (software command)
  // advance to invalid state (detected fault)
  logic adv_state;
  logic dis_state;
  logic inv_state;
  assign adv_state = op_ack & adv_req & ~op_err;
  assign dis_state = op_ack & dis_req;

  // SEC_CM: CTRL.FSM.LOCAL_ESC
  // begin invalidation when faults are observed.
  // sync faults only invalidate on transaction boudaries
  // async faults begin invalidating immediately
  assign inv_state = |fault_o;

  always_comb begin
    // persistent data
    state_d = state_q;

    // request to op handling
    op_req = 1'b0;
    random_req = 1'b0;
    random_ack = 1'b0;

    // request to key updates
    wipe_req = 1'b0;

    // invalid operation issued
    invalid_op = '0;

    // data update and select signals
    stage_sel_o = Disable;

    // indication that state is disabled
    disabled = 1'b0;

    // indication that state is invalid
    invalid = 1'b0;

    // enable prng toggling
    prng_reseed_req_o = 1'b0;

    // initialization complete
    init_o = 1'b0;

    // Most states are initialized, mark the exceptions
    initialized = 1'b1;

    // if state is ever faulted, hold on to this indication
    // until reset.
    state_intg_err_d = state_intg_err_q;

    unique case (state_q)
      // Only advance can be called from reset state
      StCtrlReset: begin
        initialized = 1'b0;

        // always use random data for advance, since out of reset state
        // the key state will be randomized.
        stage_sel_o = Disable;

        // key state is updated when it is an advance call
        // all other operations are invalid, including disable
        invalid_op = op_start_i & ~advance_sel;

        // if there was a structural fault before anything began, wipe immediately
        if (inv_state) begin
          state_d = StCtrlWipe;
        end else if (advance_sel) begin
          state_d = StCtrlEntropyReseed;
        end
      end

      // reseed entropy
      StCtrlEntropyReseed: begin
        initialized = 1'b0;
        prng_reseed_req_o = 1'b1;

        if (prng_reseed_ack_i) begin
          state_d = StCtrlRandom;
        end
      end

      // This state does not accept any command.
      StCtrlRandom: begin
        initialized = 1'b0;
        random_req = 1'b1;

        // when mask population is complete, xor the root_key into the zero share
        // if in the future the root key is updated to 2 shares, it will direclty overwrite
        // the values here
        if (int'(cnt) == EntropyRounds-1) begin
          random_ack = 1'b1;
          state_d = StCtrlRootKey;
        end
      end

      // load the root key.
      StCtrlRootKey: begin
        init_o = 1'b1;
        initialized = 1'b1;
        state_d = en_i ? StCtrlInit : StCtrlWipe;
      end

      // Beginning from the Init state, operations are accepted.
      // Only valid operation is advance state. If invalid command received,
      // random data is selected for operation and no persistent state is changed.
      StCtrlInit: begin
        op_req = op_start_i;

        // when advancing select creator data, otherwise use random input
        stage_sel_o = advance_sel ? Creator : Disable;
        invalid_op = op_start_i & ~(advance_sel | disable_sel);

        if (!en_i || inv_state) begin
          state_d = StCtrlWipe;
        end else if (dis_state) begin
          state_d = StCtrlDisabled;
        end else if (adv_state) begin
          state_d = StCtrlCreatorRootKey;
        end
      end

      // all commands  are valid during this stage
      StCtrlCreatorRootKey: begin
        op_req = op_start_i;

        // when generating, select creator data input
        // when advancing, select owner intermediate key as target
        // when disabling, select random data input
        stage_sel_o = disable_sel ? Disable  :
                      advance_sel ? OwnerInt : Creator;

        if (!en_i || inv_state) begin
          state_d = StCtrlWipe;
        end else if (dis_state) begin
          state_d = StCtrlDisabled;
        end else if (adv_state) begin
          state_d = StCtrlOwnerIntKey;
        end
      end

      // all commands are valid during this stage
      StCtrlOwnerIntKey: begin
        op_req = op_start_i;

        // when generating, select owner intermediate data input
        // when advancing, select owner as target
        // when disabling, select random data input
        stage_sel_o = disable_sel ? Disable  :
                      advance_sel ? Owner : OwnerInt;

        if (!en_i || inv_state) begin
          state_d = StCtrlWipe;
        end else if (dis_state) begin
          state_d = StCtrlDisabled;
        end else if (adv_state) begin
          state_d = StCtrlOwnerKey;
        end
      end

      // all commands are valid during this stage
      // however advance goes directly to disabled state
      StCtrlOwnerKey: begin
        op_req = op_start_i;

        // when generating, select owner data input
        // when advancing, select disable as target
        // when disabling, select random data input
        stage_sel_o = disable_sel | advance_sel ? Disable : Owner;

        if (!en_i || inv_state) begin
          state_d = StCtrlWipe;
        end else if (adv_state || dis_state) begin
          state_d = StCtrlDisabled;
        end
      end

      // The wipe state immediately clears out the key state, but waits for any ongoing
      // transaction to finish before going to disabled state.
      // Unlike the random state, this is an immedaite shutdown request, so all parts of the
      // key are wiped.
      StCtrlWipe: begin
        wipe_req = 1'b1;
        // if there was already an operation ongoing, maintain the request until completion
        op_req = op_busy;
        invalid_op = op_start_i;

        // If the enable is dropped during the middle of a transaction, we clear and wait for that
        // transaction to gracefully complete (if it can).
        // There are two scenarios:
        // 1. the operation completed right when we started wiping, in which case the done would
        //    clear the start.
        // 2. the operation completed before we started wiping, or there was never an operation to
        //    begin with (op_start_i == 0), in this case, don't wait and immediately transition
        if (!op_start_i) begin
          state_d = StCtrlInvalid;
        end
      end

      // StCtrlDisabled and StCtrlInvalid are almost functionally equivalent
      // The only difference is that Disabled is entered through software invocation,
      // while Invalid is entered through life cycle disable or operational fault.
      //
      // Both states continue to kick off random transactions
      // All transactions are treated as invalid despite completing
      StCtrlDisabled: begin
        op_req = op_start_i;
        disabled = 1'b1;

        if (!en_i || inv_state) begin
          state_d = StCtrlWipe;
        end
      end

      StCtrlInvalid: begin
        op_req = op_start_i;
        invalid = 1'b1;
      end

      // latch the fault indication and start to wipe the key manager
      default: begin
        state_intg_err_d = 1'b1;
        state_d = StCtrlWipe;
      end

    endcase // unique case (state_q)
  end // always_comb

  // Current working state provided for software read
  // Certain states are collapsed for simplicity
  keymgr_working_state_e last_working_st;
  logic update_en;

  always_ff @(posedge clk_i or negedge rst_ni) begin
    if (!rst_ni) begin
      last_working_st <= StReset;
    end else if (update_en) begin
      last_working_st <= working_state_o;
    end
  end

  always_comb begin
    update_en = 1'b1;
    working_state_o = StInvalid;

    unique case (state_q)
      StCtrlReset, StCtrlEntropyReseed, StCtrlRandom:
        working_state_o = StReset;

      StCtrlRootKey, StCtrlInit:
        working_state_o = StInit;

      StCtrlCreatorRootKey:
        working_state_o = StCreatorRootKey;

      StCtrlOwnerIntKey:
        working_state_o = StOwnerIntKey;

      StCtrlOwnerKey:
        working_state_o = StOwnerKey;

      StCtrlDisabled:
        working_state_o = StDisabled;

      StCtrlWipe: begin
        update_en = 1'b0;
        working_state_o = last_working_st;
      end

      StCtrlInvalid:
        working_state_o = StInvalid;

      default:
        working_state_o = StInvalid;
    endcase // unique case (state_q)
  end

  always_comb begin
    status_o = OpIdle;
    if (op_done_o) begin
      // It is possible for an operation to finish the same cycle en_i goes low.
      // The main fsm handling is one cycle behind, but still report operation
      // fail.
      status_o = |{error_o, fault_o} ? OpDoneFail : OpDoneSuccess;
    end else if (op_start_i) begin
      status_o = OpWip;
    end
  end


  /////////////////////////
  // Operateion state, handle advance and generate
  /////////////////////////

  logic op_fsm_err;
  keymgr_op_state_ctrl u_op_state (
    .clk_i,
    .rst_ni,
    .adv_req_i(adv_req),
    .dis_req_i(dis_req),
    .id_req_i(id_req),
    .gen_req_i(gen_req),
    .cnt_i(cdi_cnt),
    .op_ack_o(op_ack),
    .op_busy_o(op_busy),
    .op_update_o(op_update),
    .kmac_done_i,
    .adv_en_o,
    .id_en_o,
    .gen_en_o,
    .op_fsm_err_o(op_fsm_err)
  );

  // operational state cross check.  The state value must be consistent with
  // the input operations.
  logic op_state_cmd_err;
  assign op_state_cmd_err = (adv_en_o & ~(advance_sel | disable_sel)) |
                            (gen_en_o & ~gen_op);

  // operations fsm update precedence
  // when in invalid state, always update.
  // when in disabled state, always update unless a fault is encountered.
  assign op_update_sel = (op_ack | op_update) & invalid      ? KeyUpdateKmac :
                         (op_ack | op_update) & op_fault_err ? KeyUpdateWipe :
                         (op_ack | op_update) & disabled     ? KeyUpdateKmac :
                         (op_ack | op_update) & op_err       ? KeyUpdateIdle :
                         (op_ack | op_update)                ? KeyUpdateKmac : KeyUpdateIdle;


  ///////////////////////////////
  // Suppress kmac return data
  ///////////////////////////////

  logic data_fsm_err;
  keymgr_data_en_state u_data_en (
    .clk_i,
    .rst_ni,
    .hw_sel_i(hw_sel_o),
    .adv_en_i(adv_en_o),
    .id_en_i(id_en_o),
    .gen_en_i(gen_en_o),
    .op_done_i(op_done_o),
    .op_start_i,
    .data_hw_en_o,
    .data_sw_en_o,
    .fsm_err_o(data_fsm_err)
  );

  /////////////////////////
  // Cross-checks, errors and faults
  /////////////////////////

  logic vld_state_change_d, vld_state_change_q;
  assign vld_state_change_d = (state_d != state_q) &
                              (state_d inside {StCtrlRootKey,
                                               StCtrlCreatorRootKey,
                                               StCtrlOwnerIntKey,
                                               StCtrlOwnerKey});

  // capture for cross check in following cycle
  always_ff @(posedge clk_i or negedge rst_ni) begin
    if (!rst_ni) begin
      vld_state_change_q <= '0;
    end else begin
      vld_state_change_q <= vld_state_change_d;
    end
  end

  // state cross check
  // if the state advanced, ensure that it was due to an advanced operation
  logic state_change_err;
  assign state_change_err = vld_state_change_q & !adv_op;

  keymgr_err u_err (
    .clk_i,
    .rst_ni,
    .invalid_op_i(invalid_op),
    .disabled_i(disabled | (initialized & ~en_i)),
    .invalid_i(invalid),
    .kmac_input_invalid_i,
    .shadowed_update_err_i,
    .kmac_op_err_i,
    .invalid_kmac_out_i(invalid_kmac_out),
    .sideload_sel_err_i,
    .kmac_cmd_err_i,
    .kmac_fsm_err_i,
    .kmac_done_err_i,
    .regfile_intg_err_i,
    .shadowed_storage_err_i,
    .ctrl_fsm_err_i(state_intg_err_q | state_intg_err_d),
    .data_fsm_err_i(data_fsm_err),
    .op_fsm_err_i(op_fsm_err),
    .ecc_err_i(|ecc_errs),
    .state_change_err_i(state_change_err),
    .op_state_cmd_err_i(op_state_cmd_err),
    .cnt_err_i(cnt_err),
    .reseed_cnt_err_i,
    .sideload_fsm_err_i,

    .op_update_i(op_update),
    .op_done_i(op_done_o),

    .sync_err_o(sync_err),
    .async_err_o(),
    .sync_fault_o(sync_fault),
    .async_fault_o(async_fault),
    .error_o,
    .fault_o
  );

  ///////////////////////////////
  // Functions
  ///////////////////////////////

  // unclear what this is supposed to be yet
  // right now just check to see if it not all 0's and not all 1's
 function automatic logic valid_data_chk (logic [KeyWidth-1:0] value);

    return |value & ~&value;

  endfunction // byte_mask

  /////////////////////////////////
  // Assertions
  /////////////////////////////////

  // This assertion will not work if fault_status ever takes on metafields such as
  // qe / re etc.
  `ASSERT_INIT(SameErrCnt_A, $bits(keymgr_reg2hw_fault_status_reg_t) ==
                             (SyncFaultLastIdx + AsyncFaultLastIdx))

  // stage select should always be Disable whenever it is not enabled
  `ASSERT(StageDisableSel_A, !en_i |-> stage_sel_o == Disable)

  // Unless it is a legal command, only select disable
  `ASSERT(InitLegalCommands_A, op_start_i & en_i & state_q inside {StCtrlInit} &
                               !(op_i inside {OpAdvance}) |-> stage_sel_o == Disable)

  // All commands are legal, so select disable only if operation is disable
  `ASSERT(GeneralLegalCommands_A, op_start_i & en_i &
                                  state_q inside {StCtrlCreatorRootKey, StCtrlOwnerIntKey} &
                                  (op_i inside {OpDisable}) |-> stage_sel_o == Disable)

  `ASSERT(OwnerLegalCommands_A, op_start_i & en_i & state_q inside {StCtrlOwnerKey} &
                                (op_i inside {OpAdvance, OpDisable}) |-> stage_sel_o == Disable)

  // load_key should not be high if there is no ongoing operation
  `ASSERT(LoadKey_A, key_o.valid |-> op_start_i)

  // The count value should always be 0 when a transaction start
  `ASSERT(CntZero_A, $rose(op_start_i) |-> cnt == '0)

  // Whenever a transaction completes, data_en must return to 0 on the next cycle
  `ASSERT(DataEnDis_A, op_start_i & op_done_o |=> ~data_hw_en_o && ~data_sw_en_o)

  // Whenever data enable asserts, it must be the case that there was a generate or
  // id operation
  `ASSERT(DataEn_A, data_hw_en_o | data_sw_en_o |-> (id_en_o | gen_en_o) & ~adv_en_o)

  // Check that the FSM is linear and does not contain any loops
  `ASSERT_FPV_LINEAR_FSM(SecCmCFILinear_A, state_q, state_e)

endmodule
