Skip to content

Flexible bin creation

Pre-release
Pre-release
Compare
Choose a tag to compare

New way to flexibly create bins

The bin_array can now be constructed from a std::vector of either

  • intervals : std::vector<fc4sc::interval_t<T>>
  • values : std::vector<T>

The result is that for each value/interval from the vector passed to the bin_array constructor, a different bin will be created in the coverpoint.
This can be used together with a function which returns a vector of intervals or values in order to more flexibly create coverpoint bins.

Values Example:

// lambda function returning a vector of N fibonacci numbers generated by starting with 1 and 2
auto fibonacci = [](size_t N) -> std::vector<int> {
  // start with 1 and 2, so that we don't have repeating elements
  int f0 = 1, f1 = 2;
  // resulting vector containing all generated values
  std::vector<int> result(N, f0);

  for (size_t i = 1; i < N; i++) {
    std::swap(f0, f1);
    result[i] = f0;
    f1 += f0;
  }
  return result;
};

class flexible_bin_array_cvg: public covergroup {
private:
  int val = 0;
public:
  CG_CONS(flexible_bin_array_cvg) {};
  COVERPOINT(int, bin_array_cvp, val) {
    // this bin_array expands to 5 different bins for values: 1, 2, 3, 5, 8
    bin_array<int>("fibonacci", fibonacci(5))
  };
  void sample(int val) { this->val = val; sample(); }
};

Intervals Example:

// returns the first N fibonacci intervals, starting with 1 and 2
// a fibonacci interval is an interval of form [f0+1, f1],
// where f0 and f1 are successive fibonacci numbers
auto fibonacci_intervals = [](size_t N) -> std::vector<fc4sc::interval_t<int>> {
  int f0 = 1, f1 = 2; // starting numbers
  std::vector<fc4sc::interval_t<int>> result(N, interval(f0, f1));

  for (size_t i = 1; i < N; i++) {
    std::swap(f0, f1);
    f1 += f0;
    result[i] = interval(f0+1, f1);
  }
  return result;
};
class flexible_bin_array_cvg: public covergroup {
private:
  int val = 0;
public:
  CG_CONS(flexible_bin_array_cvg) {};
  COVERPOINT(int, bin_array_cvp, val) {
    // this bin_array expands to 10 different bins for the following intervals
    // {[1:2], [3:3], [4:5], [6:8], [9:13], [14:21], [22:34], [35:55], [56:89], [90:144]}
    bin_array<int>("fibonacci_intervals", fibonacci_intervals(10))
  };
  void sample(int val) { this->val = val; sample(); }
};

Fix for the bin_array interval splitting method

The functionality of bin_array for splitting an interval has now been fixed to properly slice the interval according to the method described in the IEEE 1800-2012 - IEEE Standard for SystemVerilog:

If the number of automatic bins is smaller than the number of possible values (N < 2^M), then the 2^M values
are uniformly distributed in the N bins. If the number of values, 2^M, is not divisible by N, then the last bin
will include the additional remaining items. For example, if M is 3 and N is 3, then the eight possible values
are distributed as follows: <0:1>, <2:3>, <4,5,6,7>.

Example:

bin_array<int>("1_to_5", 5, interval(1,5));
// previously would result in: {[1:2], [2:3], [3:4], [4:5], 5}
// now correctly results in : {1,2,3,4,5}

This means that bin_arrays will now possibly split intervals into pieces differently, compared to previous FC4SC versions.