// Copyright lowRISC contributors.
// Licensed under the Apache License, Version 2.0, see LICENSE for details.
// SPDX-License-Identifier: Apache-2.0
//
// HMAC-SHA256

`include "prim_assert.sv"

module hmac
  import hmac_pkg::*;
  import hmac_reg_pkg::*;
#(
  parameter logic [NumAlerts-1:0] AlertAsyncOn = {NumAlerts{1'b1}}
) (
  input clk_i,
  input rst_ni,

  input  tlul_pkg::tl_h2d_t tl_i,
  output tlul_pkg::tl_d2h_t tl_o,

  input  prim_alert_pkg::alert_rx_t [NumAlerts-1:0] alert_rx_i,
  output prim_alert_pkg::alert_tx_t [NumAlerts-1:0] alert_tx_o,

  output logic intr_hmac_done_o,
  output logic intr_fifo_empty_o,
  output logic intr_hmac_err_o,

  output logic idle_o
);


  /////////////////////////
  // Signal declarations //
  /////////////////////////
  hmac_reg2hw_t reg2hw;
  hmac_hw2reg_t hw2reg;

  tlul_pkg::tl_h2d_t  tl_win_h2d;
  tlul_pkg::tl_d2h_t  tl_win_d2h;

  logic [255:0] secret_key;

  logic        wipe_secret;
  logic [31:0] wipe_v;

  logic        fifo_rvalid;
  logic        fifo_rready;
  sha_fifo_t   fifo_rdata;

  logic        fifo_wvalid, fifo_wready;
  sha_fifo_t   fifo_wdata;
  logic        fifo_full;
  logic        fifo_empty;
  logic [4:0]  fifo_depth;

  logic        msg_fifo_req;
  logic        msg_fifo_gnt;
  logic        msg_fifo_we;
  logic [31:0] msg_fifo_wdata;
  logic [31:0] msg_fifo_wmask;
  logic [31:0] msg_fifo_rdata;
  logic        msg_fifo_rvalid;
  logic [1:0]  msg_fifo_rerror;
  logic [31:0] msg_fifo_wdata_endian;
  logic [31:0] msg_fifo_wmask_endian;

  logic        packer_ready;
  logic        packer_flush_done;

  logic        reg_fifo_wvalid;
  sha_word_t   reg_fifo_wdata;
  sha_word_t   reg_fifo_wmask;
  logic        hmac_fifo_wsel;
  logic        hmac_fifo_wvalid;
  logic [2:0]  hmac_fifo_wdata_sel;

  logic        shaf_rvalid;
  sha_fifo_t   shaf_rdata;
  logic        shaf_rready;

  logic        sha_en;
  logic        hmac_en;
  logic        endian_swap;
  logic        digest_swap;

  logic        reg_hash_start;
  logic        sha_hash_start;
  logic        hash_start;      // Valid hash_start_signal
  logic        reg_hash_process;
  logic        sha_hash_process;

  logic        reg_hash_done;
  logic        sha_hash_done;

  logic [63:0] message_length;
  logic [63:0] sha_message_length;

  err_code_e   err_code;
  logic        err_valid;

  sha_word_t [7:0] digest;

  hmac_reg2hw_cfg_reg_t cfg_reg;
  logic                 cfg_block;  // Prevent changing config
  logic                 msg_allowed; // MSG_FIFO from software is allowed

  logic hmac_core_idle;
  logic sha_core_idle;

  ///////////////////////
  // Connect registers //
  ///////////////////////
  assign hw2reg.status.fifo_full.d  = fifo_full;
  assign hw2reg.status.fifo_empty.d = fifo_empty;
  assign hw2reg.status.fifo_depth.d = fifo_depth;

  // secret key
  assign wipe_secret = reg2hw.wipe_secret.qe;
  assign wipe_v      = reg2hw.wipe_secret.q;

  always_ff @(posedge clk_i or negedge rst_ni) begin
    if (!rst_ni) begin
      secret_key <= '0;
    end else if (wipe_secret) begin
      secret_key <= secret_key ^ {8{wipe_v}};
    end else if (!cfg_block) begin
      // Allow updating secret key only when the engine is in Idle.
      for (int i = 0; i < 8; i++) begin
        if (reg2hw.key[7-i].qe) begin
          secret_key[32*i+:32] <= reg2hw.key[7-i].q;
        end
      end
    end
  end

  for (genvar i = 0; i < 8; i++) begin : gen_key_digest
    assign hw2reg.key[7-i].d      = '0;
    // digest
    assign hw2reg.digest[i].d = conv_endian(digest[i], digest_swap);
  end

  logic [3:0] unused_cfg_qe;

  assign unused_cfg_qe = {cfg_reg.sha_en.qe,      cfg_reg.hmac_en.qe,
                          cfg_reg.endian_swap.qe, cfg_reg.digest_swap.qe};

  assign sha_en      = cfg_reg.sha_en.q;
  assign hmac_en     = cfg_reg.hmac_en.q;
  assign endian_swap = cfg_reg.endian_swap.q;
  assign digest_swap = cfg_reg.digest_swap.q;
  assign hw2reg.cfg.hmac_en.d     = cfg_reg.hmac_en.q;
  assign hw2reg.cfg.sha_en.d      = cfg_reg.sha_en.q;
  assign hw2reg.cfg.endian_swap.d = cfg_reg.endian_swap.q;
  assign hw2reg.cfg.digest_swap.d = cfg_reg.digest_swap.q;

  assign reg_hash_start   = reg2hw.cmd.hash_start.qe   & reg2hw.cmd.hash_start.q;
  assign reg_hash_process = reg2hw.cmd.hash_process.qe & reg2hw.cmd.hash_process.q;

  // Error code register
  assign hw2reg.err_code.de = err_valid;
  assign hw2reg.err_code.d  = err_code;

  /////////////////////
  // Control signals //
  /////////////////////
  assign hash_start = reg_hash_start & sha_en & ~cfg_block;

  always_ff @(posedge clk_i or negedge rst_ni) begin
    if (!rst_ni) begin
      cfg_block <= '0;
    end else if (hash_start) begin
      cfg_block <= 1'b 1;
    end else if (reg_hash_done) begin
      cfg_block <= 1'b 0;
    end
  end
  // Hold the configuration during the process
  always_ff @(posedge clk_i or negedge rst_ni) begin
    if (!rst_ni) begin
      cfg_reg <= '{endian_swap: '{q: 1'b1, qe: 1'b0}, default:'0};
    end else if (!cfg_block && reg2hw.cfg.hmac_en.qe) begin
      cfg_reg <= reg2hw.cfg ;
    end
  end

  // Open up the MSG_FIFO from the TL-UL port when it is ready
  always_ff @(posedge clk_i or negedge rst_ni) begin
    if (!rst_ni) begin
      msg_allowed <= '0;
    end else if (hash_start) begin
      msg_allowed <= 1'b 1;
    end else if (packer_flush_done) begin
      msg_allowed <= 1'b 0;
    end
  end
  ////////////////
  // Interrupts //
  ////////////////
  logic fifo_empty_q, fifo_empty_event;
  always_ff @(posedge clk_i or negedge rst_ni) begin
    if (!rst_ni) begin
      fifo_empty_q <= '1; // By default, it is empty
    end else if (!hmac_fifo_wsel) begin
      fifo_empty_q <= fifo_empty;
    end
  end
  assign fifo_empty_event = fifo_empty & ~fifo_empty_q;

  logic [2:0] event_intr;
  assign event_intr = {err_valid, fifo_empty_event, reg_hash_done};

  // instantiate interrupt hardware primitive
  prim_intr_hw #(.Width(1)) intr_hw_hmac_done (
    .clk_i,
    .rst_ni,
    .event_intr_i           (event_intr[0]),
    .reg2hw_intr_enable_q_i (reg2hw.intr_enable.hmac_done.q),
    .reg2hw_intr_test_q_i   (reg2hw.intr_test.hmac_done.q),
    .reg2hw_intr_test_qe_i  (reg2hw.intr_test.hmac_done.qe),
    .reg2hw_intr_state_q_i  (reg2hw.intr_state.hmac_done.q),
    .hw2reg_intr_state_de_o (hw2reg.intr_state.hmac_done.de),
    .hw2reg_intr_state_d_o  (hw2reg.intr_state.hmac_done.d),
    .intr_o                 (intr_hmac_done_o)
  );
  prim_intr_hw #(.Width(1)) intr_hw_fifo_empty (
    .clk_i,
    .rst_ni,
    .event_intr_i           (event_intr[1]),
    .reg2hw_intr_enable_q_i (reg2hw.intr_enable.fifo_empty.q),
    .reg2hw_intr_test_q_i   (reg2hw.intr_test.fifo_empty.q),
    .reg2hw_intr_test_qe_i  (reg2hw.intr_test.fifo_empty.qe),
    .reg2hw_intr_state_q_i  (reg2hw.intr_state.fifo_empty.q),
    .hw2reg_intr_state_de_o (hw2reg.intr_state.fifo_empty.de),
    .hw2reg_intr_state_d_o  (hw2reg.intr_state.fifo_empty.d),
    .intr_o                 (intr_fifo_empty_o)
  );
  prim_intr_hw #(.Width(1)) intr_hw_hmac_err (
    .clk_i,
    .rst_ni,
    .event_intr_i           (event_intr[2]),
    .reg2hw_intr_enable_q_i (reg2hw.intr_enable.hmac_err.q),
    .reg2hw_intr_test_q_i   (reg2hw.intr_test.hmac_err.q),
    .reg2hw_intr_test_qe_i  (reg2hw.intr_test.hmac_err.qe),
    .reg2hw_intr_state_q_i  (reg2hw.intr_state.hmac_err.q),
    .hw2reg_intr_state_de_o (hw2reg.intr_state.hmac_err.de),
    .hw2reg_intr_state_d_o  (hw2reg.intr_state.hmac_err.d),
    .intr_o                 (intr_hmac_err_o)
  );

  ///////////////
  // Instances //
  ///////////////

  assign msg_fifo_rvalid = msg_fifo_req & ~msg_fifo_we;
  assign msg_fifo_rdata  = '1;  // Return all F
  assign msg_fifo_rerror = '1;  // Return error for read access
  assign msg_fifo_gnt    = msg_fifo_req & ~hmac_fifo_wsel & packer_ready;

  // FIFO control
  sha_fifo_t reg_fifo_wentry;
  assign reg_fifo_wentry.data = conv_endian(reg_fifo_wdata, 1'b1); // always convert
  assign reg_fifo_wentry.mask = {reg_fifo_wmask[0],  reg_fifo_wmask[8],
                                 reg_fifo_wmask[16], reg_fifo_wmask[24]};
  assign fifo_full   = ~fifo_wready;
  assign fifo_empty  = ~fifo_rvalid;
  assign fifo_wvalid = (hmac_fifo_wsel && fifo_wready) ? hmac_fifo_wvalid : reg_fifo_wvalid;
  assign fifo_wdata  = (hmac_fifo_wsel) ? '{data: digest[hmac_fifo_wdata_sel], mask: '1}
                                       : reg_fifo_wentry;

  prim_fifo_sync #(
    .Width   ($bits(sha_fifo_t)),
    .Pass    (1'b1),
    .Depth   (MsgFifoDepth)
  ) u_msg_fifo (
    .clk_i,
    .rst_ni,
    .clr_i   (1'b0),

    .wvalid_i(fifo_wvalid & sha_en),
    .wready_o(fifo_wready),
    .wdata_i (fifo_wdata),

    .depth_o (fifo_depth),
    .full_o  (),

    .rvalid_o(fifo_rvalid),
    .rready_i(fifo_rready),
    .rdata_o (fifo_rdata)
  );

  // TL ADAPTER SRAM
  tlul_adapter_sram #(
    .SramAw (9),
    .SramDw (32),
    .Outstanding (1),
    .ByteAccess  (1),
    .ErrOnRead   (1)
  ) u_tlul_adapter (
    .clk_i,
    .rst_ni,
    .tl_i        (tl_win_h2d),
    .tl_o        (tl_win_d2h),
    .en_ifetch_i (prim_mubi_pkg::MuBi4False),
    .req_o       (msg_fifo_req   ),
    .req_type_o  (               ),
    .gnt_i       (msg_fifo_gnt   ),
    .we_o        (msg_fifo_we    ),
    .addr_o      (               ), // Doesn't care the address other than sub-word
    .wdata_o     (msg_fifo_wdata ),
    .wmask_o     (msg_fifo_wmask ),
    .intg_error_o(               ),
    .rdata_i     (msg_fifo_rdata ),
    .rvalid_i    (msg_fifo_rvalid),
    .rerror_i    (msg_fifo_rerror)
  );

  // TL-UL to MSG_FIFO byte write handling
  logic msg_write;

  assign msg_write = msg_fifo_req & msg_fifo_we & ~hmac_fifo_wsel & msg_allowed;

  logic [$clog2(32+1)-1:0] wmask_ones;

  always_comb begin
    wmask_ones = '0;
    for (int i = 0 ; i < 32 ; i++) begin
      wmask_ones = wmask_ones + msg_fifo_wmask[i];
    end
  end

  // Calculate written message
  always_ff @(posedge clk_i or negedge rst_ni) begin
    if (!rst_ni) begin
      message_length <= '0;
    end else if (hash_start) begin
      message_length <= '0;
    end else if (msg_write && sha_en && packer_ready) begin
      message_length <= message_length + 64'(wmask_ones);
    end
  end

  assign hw2reg.msg_length_upper.de = 1'b1;
  assign hw2reg.msg_length_upper.d = message_length[63:32];
  assign hw2reg.msg_length_lower.de = 1'b1;
  assign hw2reg.msg_length_lower.d = message_length[31:0];


  // Convert endian here
  //    prim_packer always packs to the right, but SHA engine assumes incoming
  //    to be big-endian, [31:24] comes first. So, the data is reverted after
  //    prim_packer before the message fifo. here to reverse if not big-endian
  //    before pushing to the packer.
  assign msg_fifo_wdata_endian = conv_endian(msg_fifo_wdata, ~endian_swap);
  assign msg_fifo_wmask_endian = conv_endian(msg_fifo_wmask, ~endian_swap);

  prim_packer #(
    .InW      (32),
    .OutW     (32)
  ) u_packer (
    .clk_i,
    .rst_ni,

    .valid_i      (msg_write & sha_en),
    .data_i       (msg_fifo_wdata_endian),
    .mask_i       (msg_fifo_wmask_endian),
    .ready_o      (packer_ready),

    .valid_o      (reg_fifo_wvalid),
    .data_o       (reg_fifo_wdata),
    .mask_o       (reg_fifo_wmask),
    .ready_i      (fifo_wready & ~hmac_fifo_wsel),

    .flush_i      (reg_hash_process),
    .flush_done_o (packer_flush_done) // ignore at this moment
  );


  hmac_core u_hmac (
    .clk_i,
    .rst_ni,

    .secret_key,

    .wipe_secret,
    .wipe_v,

    .hmac_en,

    .reg_hash_start   (hash_start),
    .reg_hash_process (packer_flush_done), // Trigger after all msg written
    .hash_done      (reg_hash_done),
    .sha_hash_start,
    .sha_hash_process,
    .sha_hash_done,

    .sha_rvalid     (shaf_rvalid),
    .sha_rdata      (shaf_rdata),
    .sha_rready     (shaf_rready),

    .fifo_rvalid,
    .fifo_rdata,
    .fifo_rready,

    .fifo_wsel      (hmac_fifo_wsel),
    .fifo_wvalid    (hmac_fifo_wvalid),
    .fifo_wdata_sel (hmac_fifo_wdata_sel),
    .fifo_wready,

    .message_length,
    .sha_message_length,

    .idle           (hmac_core_idle)
  );

  sha2 u_sha2 (
    .clk_i,
    .rst_ni,

    .wipe_secret,
    .wipe_v,

    .fifo_rvalid      (shaf_rvalid),
    .fifo_rdata       (shaf_rdata),
    .fifo_rready      (shaf_rready),

    .sha_en,
    .hash_start       (sha_hash_start),
    .hash_process     (sha_hash_process),
    .hash_done        (sha_hash_done),

    .message_length   (sha_message_length),

    .digest,

    .idle             (sha_core_idle)
  );

  // Register top
  logic [NumAlerts-1:0] alert_test, alerts;
  hmac_reg_top u_reg (
    .clk_i,
    .rst_ni,

    .tl_i,
    .tl_o,

    .tl_win_o   (tl_win_h2d),
    .tl_win_i   (tl_win_d2h),

    .reg2hw,
    .hw2reg,

    .intg_err_o (alerts[0]),
    .devmode_i  (1'b1)
  );

  // Alerts
  assign alert_test = {
    reg2hw.alert_test.q &
    reg2hw.alert_test.qe
  };

  for (genvar i = 0; i < NumAlerts; i++) begin : gen_alert_tx
    prim_alert_sender #(
      .AsyncOn(AlertAsyncOn[i]),
      .IsFatal(i)
    ) u_prim_alert_sender (
      .clk_i,
      .rst_ni,
      .alert_test_i  ( alert_test[i] ),
      .alert_req_i   ( alerts[0]     ),
      .alert_ack_o   (               ),
      .alert_state_o (               ),
      .alert_rx_i    ( alert_rx_i[i] ),
      .alert_tx_o    ( alert_tx_o[i] )
    );
  end

  /////////////////////////
  // HMAC Error Handling //
  /////////////////////////
  logic msg_push_sha_disabled, hash_start_sha_disabled, update_seckey_inprocess;
  logic hash_start_active;  // `reg_hash_start` set when hash already in active
  logic msg_push_not_allowed; // Message is received when `hash_start` isn't set
  assign msg_push_sha_disabled = msg_write & ~sha_en;
  assign hash_start_sha_disabled = reg_hash_start & ~sha_en;
  assign hash_start_active = reg_hash_start & cfg_block;
  assign msg_push_not_allowed = msg_fifo_req & ~msg_allowed;

  always_comb begin
    update_seckey_inprocess = 1'b0;
    if (cfg_block) begin
      for (int i = 0 ; i < 8 ; i++) begin
        if (reg2hw.key[i].qe) begin
          update_seckey_inprocess = update_seckey_inprocess | 1'b1;
        end
      end
    end else begin
      update_seckey_inprocess = 1'b0;
    end
  end

  // Update ERR_CODE register and interrupt only when no pending interrupt.
  // This ensures only the first event of the series of events can be seen to sw.
  // It is recommended that the software reads ERR_CODE register when interrupt
  // is pending to avoid any race conditions.
  assign err_valid = ~reg2hw.intr_state.hmac_err.q &
                   ( msg_push_sha_disabled | hash_start_sha_disabled
                   | update_seckey_inprocess | hash_start_active
                   | msg_push_not_allowed );

  always_comb begin
    err_code = NoError;
    unique case (1'b1)
      msg_push_sha_disabled: begin
        err_code = SwPushMsgWhenShaDisabled;
      end
      hash_start_sha_disabled: begin
        err_code = SwHashStartWhenShaDisabled;
      end

      update_seckey_inprocess: begin
        err_code = SwUpdateSecretKeyInProcess;
      end

      hash_start_active: begin
        err_code = SwHashStartWhenActive;
      end

      msg_push_not_allowed: begin
        err_code = SwPushMsgWhenDisallowed;
      end

      default: begin
        err_code = NoError;
      end
    endcase
  end

  /////////////////////
  // Unused Signals  //
  /////////////////////
  logic unused_wmask;
  assign unused_wmask = ^reg_fifo_wmask;

  /////////////////////
  // Idle output     //
  /////////////////////
  // TBD this should be connected later
  // Idle: AND condition of:
  //  - packer empty: Currently no way to guarantee the packer is empty.
  //    temporary, the logic uses packer output (reg_fifo_wvalid)
  //  - MSG_FIFO  --> fifo_rvalid
  //  - HMAC_CORE --> hmac_core_idle
  //  - SHA2_CORE --> sha_core_idle
  //  - Clean interrupt status
  logic idle;
  assign idle = !reg_fifo_wvalid && !fifo_rvalid
              && hmac_core_idle && sha_core_idle;
  always_ff @(posedge clk_i or negedge rst_ni) begin
    if (!rst_ni) begin
      idle_o <= 1'b 1;
    end else begin
      idle_o <= idle;
    end
  end

  //////////////////////////////////////////////
  // Assertions, Assumptions, and Coverpoints //
  //////////////////////////////////////////////

`ifndef VERILATOR
`ifndef SYNTHESIS
  // HMAC assumes TL-UL mask is byte-aligned.
  property wmask_bytealign_p(wmask_byte, clk, rst_n);
    @(posedge clk) disable iff (rst_n == 0)
      msg_fifo_req & msg_fifo_we |-> wmask_byte inside {'0, '1};
  endproperty

  for (genvar i = 0 ; i < 4; i++) begin: gen_assert_wmask_bytealign
    assert property (wmask_bytealign_p(msg_fifo_wmask[8*i+:8], clk_i, rst_ni));
  end

  // To pass FPV, this shouldn't add pragma translate_off even these two signals
  // are used in Assertion only
  logic in_process;
  always_ff @(posedge clk_i or negedge rst_ni) begin
    if (!rst_ni)               in_process <= 1'b0;
    else if (reg_hash_process) in_process <= 1'b1;
    else if (reg_hash_done)    in_process <= 1'b0;
  end

  logic initiated;
  always_ff @(posedge clk_i or negedge rst_ni) begin
    if (!rst_ni)               initiated <= 1'b0;
    else if (hash_start)       initiated <= 1'b1;
    else if (reg_hash_process) initiated <= 1'b0;
  end

  // the host doesn't write data after hash_process until hash_start.
  // Same as "message_length shouldn't be changed between hash_process and done
  `ASSERT(ValidWriteAssert, msg_fifo_req |-> !in_process)

  // `hash_process` shall be toggle and paired with `hash_start`.
  // Below condition is covered by the design (2020-02-19)
  //`ASSERT(ValidHashStartAssert, hash_start |-> !initiated)
  `ASSERT(ValidHashProcessAssert, reg_hash_process |-> initiated)

  // between `hash_done` and `hash_start`, message FIFO should be empty
  `ASSERT(MsgFifoEmptyWhenNoOpAssert,
          !in_process && !initiated |-> $stable(message_length))

  // hmac_en should be modified only when the logic is Idle
  `ASSERT(ValidHmacEnConditionAssert,
          hmac_en != $past(hmac_en) |-> !in_process && !initiated)

  // All outputs should be known value after reset
  `ASSERT_KNOWN(IntrHmacDoneOKnown, intr_hmac_done_o)
  `ASSERT_KNOWN(IntrFifoEmptyOKnown, intr_fifo_empty_o)
  `ASSERT_KNOWN(TlODValidKnown, tl_o.d_valid)
  `ASSERT_KNOWN(TlOAReadyKnown, tl_o.a_ready)
  `ASSERT_KNOWN(AlertKnownO_A, alert_tx_o)

`endif // SYNTHESIS
`endif // VERILATOR

endmodule
