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


/**
 * Utility functions
 */
package prim_util_pkg;
  /**
   * Math function: $clog2 as specified in Verilog-2005
   *
   * Do not use this function if $clog2() is available.
   *
   * clog2 =          0        for value == 0
   *         ceil(log2(value)) for value >= 1
   *
   * This implementation is a synthesizable variant of the $clog2 function as
   * specified in the Verilog-2005 standard (IEEE 1364-2005).
   *
   * To quote the standard:
   *   The system function $clog2 shall return the ceiling of the log
   *   base 2 of the argument (the log rounded up to an integer
   *   value). The argument can be an integer or an arbitrary sized
   *   vector value. The argument shall be treated as an unsigned
   *   value, and an argument value of 0 shall produce a result of 0.
   */
  function automatic integer _clog2(integer value);
    integer result;
    // Use an intermediate value to avoid assigning to an input port, which produces a warning in
    // Synopsys DC.
    integer v = value;
    v = v - 1;
    for (result = 0; v > 0; result++) begin
      v = v >> 1;
    end
    return result;
  endfunction


  /**
   * Math function: Number of bits needed to address |value| items.
   *
   *                  0        for value == 0
   * vbits =          1        for value == 1
   *         ceil(log2(value)) for value > 1
   *
   *
   * The primary use case for this function is the definition of registers/arrays
   * which are wide enough to contain |value| items.
   *
   * This function identical to $clog2() for all input values except the value 1;
   * it could be considered an "enhanced" $clog2() function.
   *
   *
   * Example 1:
   *   parameter Items = 1;
   *   localparam ItemsWidth = vbits(Items); // 1
   *   logic [ItemsWidth-1:0] item_register; // items_register is now [0:0]
   *
   * Example 2:
   *   parameter Items = 64;
   *   localparam ItemsWidth = vbits(Items); // 6
   *   logic [ItemsWidth-1:0] item_register; // items_register is now [5:0]
   *
   * Note: If you want to store the number "value" inside a register, you need
   * a register with size vbits(value + 1), since you also need to store
   * the number 0.
   *
   * Example 3:
   *   logic [vbits(64)-1:0]     store_64_logic_values; // width is [5:0]
   *   logic [vbits(64 + 1)-1:0] store_number_64;       // width is [6:0]
   */
  function automatic integer vbits(integer value);
`ifdef XCELIUM
    // The use of system functions was not allowed here in Verilog-2001, but is
    // valid since (System)Verilog-2005, which is also when $clog2() first
    // appeared.
    // Xcelium < 19.10 does not yet support the use of $clog2() here, fall back
    // to an implementation without a system function. Remove this workaround
    // if we require a newer Xcelium version.
    // See #2579 and #2597.
    return (value == 1) ? 1 : _clog2(value);
`else
    return (value == 1) ? 1 : $clog2(value);
`endif
  endfunction

endpackage