Flexible bin creation
Pre-releaseNew 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.