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

`include "prim_assert.sv"

/**
 * OpenTitan Big Number Accelerator (OTBN)
 */
module otbn
  import prim_alert_pkg::*;
  import otbn_pkg::*;
(
  input clk_i,
  input rst_ni,

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

  // Inter-module signals
  output logic idle_o,

  // Interrupts
  output logic intr_done_o,
  output logic intr_err_o,

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

  // CSRNG interface
  // TODO: Needs to be connected to RNG distribution network (#2638)
);

  import otbn_reg_pkg::*;
  import prim_util_pkg::vbits;

  // The OTBN_*_SIZE parameters are auto-generated by regtool and come from the
  // bus window sizes; they are given in bytes.
  localparam int ImemSizeByte = otbn_reg_pkg::OTBN_IMEM_SIZE;
  localparam int DmemSizeByte = otbn_reg_pkg::OTBN_DMEM_SIZE;

  localparam int ImemAddrWidth = vbits(ImemSizeByte);
  localparam int DmemAddrWidth = vbits(DmemSizeByte);

  logic start;
  logic busy_d, busy_q;
  logic done;

  logic        err_valid;
  logic [31:0] err_code;

  logic [ImemAddrWidth-1:0] start_addr;

  otbn_reg2hw_t reg2hw;
  otbn_hw2reg_t hw2reg;

  // Bus device windows, as specified in otbn.hjson
  typedef enum int {
    TlWinImem = 0,
    TlWinDmem = 1
  } tl_win_e;

  tlul_pkg::tl_h2d_t tl_win_h2d [2];
  tlul_pkg::tl_d2h_t tl_win_d2h [2];


  // Inter-module signals ======================================================

  // TODO: Better define what "idle" means -- only the core, or also the
  // register interface?
  assign idle_o = ~busy_q | ~start;


  // Interrupts ================================================================

  prim_intr_hw #(
    .Width(1)
  ) u_intr_hw_done (
    .event_intr_i           (done),
    .reg2hw_intr_enable_q_i (reg2hw.intr_enable.done.q),
    .reg2hw_intr_test_q_i   (reg2hw.intr_test.done.q),
    .reg2hw_intr_test_qe_i  (reg2hw.intr_test.done.qe),
    .reg2hw_intr_state_q_i  (reg2hw.intr_state.done.q),
    .hw2reg_intr_state_de_o (hw2reg.intr_state.done.de),
    .hw2reg_intr_state_d_o  (hw2reg.intr_state.done.d),
    .intr_o                 (intr_done_o)
  );
  prim_intr_hw #(
    .Width(1)
  ) u_intr_hw_err (
    .event_intr_i           (err_valid),
    .reg2hw_intr_enable_q_i (reg2hw.intr_enable.err.q),
    .reg2hw_intr_test_q_i   (reg2hw.intr_test.err.q),
    .reg2hw_intr_test_qe_i  (reg2hw.intr_test.err.qe),
    .reg2hw_intr_state_q_i  (reg2hw.intr_state.err.q),
    .hw2reg_intr_state_de_o (hw2reg.intr_state.err.de),
    .hw2reg_intr_state_d_o  (hw2reg.intr_state.err.d),
    .intr_o                 (intr_err_o)
  );


  // Registers =================================================================

  otbn_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,

    .devmode_i (1'b1)
  );

  // CMD register
  assign start = reg2hw.cmd.start.qe & reg2hw.cmd.start.q;

  // STATUS register
  assign hw2reg.status.busy.d = busy_q;
  assign hw2reg.status.dummy.d = 1'b0;

  // ERR_CODE register
  assign hw2reg.err_code.de = err_valid;
  assign hw2reg.err_code.d  = err_code;

  // START_ADDR register
  assign start_addr = reg2hw.start_addr.q[ImemAddrWidth-1:0];

  // Errors ====================================================================

  // err_valid goes high if there is a new error this cycle. This causes the
  // register block to take a new error code (stored as ERR_CODE) and triggers
  // an interrupt. To ensure software on the host CPU only sees the first event
  // in a series, err_valid is squashed if there is an existing error. Software
  // should read the ERR_CODE register before clearing the interrupt to avoid
  // race conditions.
  assign err_valid = ~reg2hw.intr_state.err.q &
    (1'b0); // TODO: OR error signals here.

  always_comb begin
    err_code = ErrCodeNoError;
    unique case (1'b1)
      // TODO: Add more errors here.

      default: begin
        err_code = ErrCodeNoError;
      end
    endcase
  end

  // Instruction Memory (IMEM) =================================================

  localparam int ImemSizeWords = ImemSizeByte / 4;
  localparam int ImemIndexWidth = vbits(ImemSizeWords);

  // Access select to IMEM: core (1), or bus (0)
  logic imem_access_core;

  logic imem_req;
  logic imem_write;
  logic [ImemIndexWidth-1:0] imem_index;
  logic [31:0] imem_wdata;
  logic [31:0] imem_wmask;
  logic [31:0] imem_rdata;
  logic imem_rvalid;
  logic [1:0] imem_rerror;

  logic imem_req_core;
  logic imem_write_core;
  logic [ImemIndexWidth-1:0] imem_index_core;
  logic [31:0] imem_wdata_core;
  logic [31:0] imem_rdata_core;
  logic imem_rvalid_core;
  logic [1:0] imem_rerror_core;

  logic imem_req_bus;
  logic imem_write_bus;
  logic [ImemIndexWidth-1:0] imem_index_bus;
  logic [31:0] imem_wdata_bus;
  logic [31:0] imem_wmask_bus;
  logic [31:0] imem_rdata_bus;
  logic imem_rvalid_bus;
  logic [1:0] imem_rerror_bus;

  logic [ImemAddrWidth-1:0] imem_addr_core;
  assign imem_index_core = imem_addr_core[ImemAddrWidth-1:2];

  logic [1:0] unused_imem_addr_core_wordbits;
  assign unused_imem_addr_core_wordbits = imem_addr_core[1:0];

  prim_ram_1p_adv #(
    .Width           (32),
    .Depth           (ImemSizeWords),
    .DataBitsPerMask (32), // Write masks are not supported.
    .CfgW            (8)
  ) u_imem (
    .clk_i,
    .rst_ni,
    .req_i    (imem_req),
    .write_i  (imem_write),
    .addr_i   (imem_index),
    .wdata_i  (imem_wdata),
    .wmask_i  (imem_wmask),
    .rdata_o  (imem_rdata),
    .rvalid_o (imem_rvalid),
    .rerror_o (imem_rerror),
    .cfg_i    ('0)
  );

  // IMEM access from main TL-UL bus
  logic imem_gnt_bus;
  assign imem_gnt_bus = imem_req_bus & ~imem_access_core;

  tlul_adapter_sram #(
    .SramAw      (ImemIndexWidth),
    .SramDw      (32),
    .Outstanding (1),
    .ByteAccess  (0),
    .ErrOnRead   (0)
  ) u_tlul_adapter_sram_imem (
    .clk_i,
    .rst_ni,
    .tl_i   (tl_win_h2d[TlWinImem]),
    .tl_o   (tl_win_d2h[TlWinImem]),

    .req_o    (imem_req_bus   ),
    .gnt_i    (imem_gnt_bus   ),
    .we_o     (imem_write_bus ),
    .addr_o   (imem_index_bus ),
    .wdata_o  (imem_wdata_bus ),
    .wmask_o  (imem_wmask_bus ),
    .rdata_i  (imem_rdata_bus ),
    .rvalid_i (imem_rvalid_bus),
    .rerror_i (imem_rerror_bus)
  );

  // Mux core and bus access into IMEM
  assign imem_access_core = busy_q;

  assign imem_req   = imem_access_core ? imem_req_core   : imem_req_bus;
  assign imem_write = imem_access_core ? imem_write_core : imem_write_bus;
  assign imem_index = imem_access_core ? imem_index_core : imem_index_bus;
  assign imem_wdata = imem_access_core ? imem_wdata_core : imem_wdata_bus;

  // The instruction memory only supports 32b word writes, so we hardcode its
  // wmask here.
  //
  // Since this could cause confusion if the bus tried to do a partial write
  // (which wasn't caught in the TLUL adapter for some reason), we assert that
  // the wmask signal from the bus is indeed '1 when it requests a write. We
  // don't have the corresponding check for writes from the core because the
  // core cannot perform writes (and has no imem_wmask_o port).
  assign imem_wmask = 32'hFFFFFFFF;
  `ASSERT(ImemWmaskBusIsFullWord_A,
      imem_req_bus && imem_write_bus |-> imem_wmask_bus == 32'hFFFFFFFF)

  // Explicitly tie off bus interface during core operation to avoid leaking
  // the currently executed instruction from IMEM through the bus
  // unintentionally.
  assign imem_rdata_bus  = !imem_access_core ? imem_rdata : 32'b0;
  assign imem_rdata_core = imem_rdata;

  assign imem_rvalid_bus  = !imem_access_core ? imem_rvalid : 1'b0;
  assign imem_rvalid_core = imem_access_core ? imem_rvalid : 1'b0;

  // Since rerror depends on rvalid we could save this mux, but could
  // potentially leak rerror to the bus. Err on the side of caution.
  assign imem_rerror_bus  = !imem_access_core ? imem_rerror : 2'b00;
  assign imem_rerror_core = imem_rerror;


  // Data Memory (DMEM) ========================================================

  localparam int DmemSizeWords = DmemSizeByte / (WLEN / 8);
  localparam int DmemIndexWidth = vbits(DmemSizeWords);

  // Access select to DMEM: core (1), or bus (0)
  logic dmem_access_core;

  logic dmem_req;
  logic dmem_write;
  logic [DmemIndexWidth-1:0] dmem_index;
  logic [WLEN-1:0] dmem_wdata;
  logic [WLEN-1:0] dmem_wmask;
  logic [WLEN-1:0] dmem_rdata;
  logic dmem_rvalid;
  logic [1:0] dmem_rerror;

  logic dmem_req_core;
  logic dmem_write_core;
  logic [DmemIndexWidth-1:0] dmem_index_core;
  logic [WLEN-1:0] dmem_wdata_core;
  logic [WLEN-1:0] dmem_wmask_core;
  logic [WLEN-1:0] dmem_rdata_core;
  logic dmem_rvalid_core;
  logic [1:0] dmem_rerror_core;

  logic dmem_req_bus;
  logic dmem_write_bus;
  logic [DmemIndexWidth-1:0] dmem_index_bus;
  logic [WLEN-1:0] dmem_wdata_bus;
  logic [WLEN-1:0] dmem_wmask_bus;
  logic [WLEN-1:0] dmem_rdata_bus;
  logic dmem_rvalid_bus;
  logic [1:0] dmem_rerror_bus;

  logic [DmemAddrWidth-1:0] dmem_addr_core;
  assign dmem_index_core = dmem_addr_core[DmemAddrWidth-1:DmemAddrWidth-DmemIndexWidth];

  prim_ram_1p_adv #(
    .Width           (WLEN),
    .Depth           (DmemSizeWords),
    .DataBitsPerMask (32), // 32b write masks for 32b word writes from bus
    .CfgW            (8)
  ) u_dmem (
    .clk_i,
    .rst_ni,
    .req_i    (dmem_req),
    .write_i  (dmem_write),
    .addr_i   (dmem_index),
    .wdata_i  (dmem_wdata),
    .wmask_i  (dmem_wmask),
    .rdata_o  (dmem_rdata),
    .rvalid_o (dmem_rvalid),
    .rerror_o (dmem_rerror),
    .cfg_i    ('0)
  );

  // DMEM access from main TL-UL bus
  logic dmem_gnt_bus;
  assign dmem_gnt_bus = dmem_req_bus & ~dmem_access_core;

  tlul_adapter_sram #(
    .SramAw      (DmemIndexWidth),
    .SramDw      (WLEN),
    .Outstanding (1),
    .ByteAccess  (0),
    .ErrOnRead   (0)
  ) u_tlul_adapter_sram_dmem (
    .clk_i,
    .rst_ni,

    .tl_i     (tl_win_h2d[TlWinDmem]),
    .tl_o     (tl_win_d2h[TlWinDmem]),

    .req_o    (dmem_req_bus   ),
    .gnt_i    (dmem_gnt_bus   ),
    .we_o     (dmem_write_bus ),
    .addr_o   (dmem_index_bus ),
    .wdata_o  (dmem_wdata_bus ),
    .wmask_o  (dmem_wmask_bus ),
    .rdata_i  (dmem_rdata_bus ),
    .rvalid_i (dmem_rvalid_bus),
    .rerror_i (dmem_rerror_bus)
  );

  // Mux core and bus access into dmem
  assign dmem_access_core = busy_q;

  assign dmem_req   = dmem_access_core ? dmem_req_core   : dmem_req_bus;
  assign dmem_write = dmem_access_core ? dmem_write_core : dmem_write_bus;
  assign dmem_wmask = dmem_access_core ? dmem_wmask_core : dmem_wmask_bus;
  assign dmem_index = dmem_access_core ? dmem_index_core : dmem_index_bus;
  assign dmem_wdata = dmem_access_core ? dmem_wdata_core : dmem_wdata_bus;

  // Explicitly tie off bus interface during core operation to avoid leaking
  // DMEM data through the bus unintentionally.
  assign dmem_rdata_bus  = !dmem_access_core ? dmem_rdata : '0;
  assign dmem_rdata_core = dmem_rdata;

  assign dmem_rvalid_bus  = !dmem_access_core ? dmem_rvalid : 1'b0;
  assign dmem_rvalid_core = dmem_access_core  ? dmem_rvalid : 1'b0;

  // Since rerror depends on rvalid we could save this mux, but could
  // potentially leak rerror to the bus. Err on the side of caution.
  assign dmem_rerror_bus  = !dmem_access_core ? dmem_rerror : 2'b00;
  assign dmem_rerror_core = dmem_rerror;


  // Alerts ====================================================================

  logic [NumAlerts-1:0] alerts;
  assign alerts[AlertImemUncorrectable] = imem_rerror[1];
  assign alerts[AlertDmemUncorrectable] = dmem_rerror[1];
  assign alerts[AlertRegUncorrectable] = 1'b0; // TODO: Implement
  for (genvar i = 0; i < NumAlerts; i++) begin: gen_alert_tx
    prim_alert_sender #(
      .AsyncOn(AlertAsyncOn[i])
    ) i_prim_alert_sender (
      .clk_i,
      .rst_ni,
      .alert_i    (alerts[i]    ),
      .alert_rx_i (alert_rx_i[i]),
      .alert_tx_o (alert_tx_o[i])
    );
  end


  // OTBN Core =================================================================

  always_ff @(posedge clk_i or negedge rst_ni) begin
    if (!rst_ni) begin
      busy_q <= 1'b0;
    end else begin
      busy_q <= busy_d;
    end
  end
  assign busy_d = (busy_q | start) & ~done;

  otbn_core #(
    .DmemSizeByte(DmemSizeByte),
    .ImemSizeByte(ImemSizeByte)
  ) u_otbn_core (
    .clk_i,
    .rst_ni,

    .start_i (start),
    .done_o  (done),

    .start_addr_i  (start_addr),

    .imem_req_o    (imem_req_core),
    .imem_addr_o   (imem_addr_core),
    .imem_wdata_o  (imem_wdata_core),
    .imem_rdata_i  (imem_rdata_core),
    .imem_rvalid_i (imem_rvalid_core),
    .imem_rerror_i (imem_rerror_core),

    .dmem_req_o    (dmem_req_core),
    .dmem_write_o  (dmem_write_core),
    .dmem_addr_o   (dmem_addr_core),
    .dmem_wdata_o  (dmem_wdata_core),
    .dmem_wmask_o  (dmem_wmask_core),
    .dmem_rdata_i  (dmem_rdata_core),
    .dmem_rvalid_i (dmem_rvalid_core),
    .dmem_rerror_i (dmem_rerror_core)
  );

  // The core can never signal a write to IMEM
  assign imem_write_core = 1'b0;

  // LFSR ======================================================================

  // TODO: Potentially insert local LFSR, or use output from RNG distribution
  // network directly, depending on availability. Revisit once CSRNG interface
  // is known (#2638).


  // Asserts ===================================================================

  // All outputs should be known value after reset
  `ASSERT_KNOWN(TlODValidKnown_A, tl_o.d_valid)
  `ASSERT_KNOWN(TlOAReadyKnown_A, tl_o.a_ready)
  `ASSERT_KNOWN(IntrDoneOKnown_A, intr_done_o)
  `ASSERT_KNOWN(IntrErrOKnown_A, intr_err_o)
  `ASSERT_KNOWN(AlertTxOKnown_A, alert_tx_o)

endmodule
