Skip to content

Commit f968bd6

Browse files
committed
Fixed limitations in random_integer_array min/max range.
1 parent f5d2cd9 commit f968bd6

File tree

2 files changed

+77
-7
lines changed

2 files changed

+77
-7
lines changed

vunit/vhdl/random/src/random_pkg.vhd

Lines changed: 29 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -113,17 +113,43 @@ package body random_pkg is
113113
return integer_vector_ptr;
114114
end;
115115

116-
function ilog2(value : natural) return natural is
116+
function ceil_log2(value : positive) return natural is
117117
variable res : natural := 0;
118118
variable pow : natural := 1;
119119
begin
120120
while pow < value loop
121-
pow := pow*2;
121+
pow := pow * 2;
122122
res := res + 1;
123123
end loop;
124+
124125
return res;
125126
end function;
126127

128+
function n_bits_needed(value : integer; signed_representation : boolean) return positive is
129+
variable n_bits : positive;
130+
begin
131+
if value > 0 then
132+
if value /= integer'high then
133+
n_bits := ceil_log2(value + 1);
134+
else
135+
n_bits := ceil_log2(value / 2 + 1) + 1;
136+
end if;
137+
if signed_representation then
138+
n_bits := n_bits + 1;
139+
end if;
140+
elsif value < 0 then
141+
if value /= integer'low then
142+
n_bits := ceil_log2(-value) + 1;
143+
else
144+
n_bits := ceil_log2(-(value / 2)) + 2;
145+
end if;
146+
else
147+
n_bits := 1;
148+
end if;
149+
150+
return n_bits;
151+
end;
152+
127153
procedure random_integer_array(variable rnd : inout RandomPType;
128154
variable integer_array : inout integer_array_t;
129155
width : natural := 1;
@@ -137,11 +163,7 @@ package body random_pkg is
137163
assert min_value <= max_value report "min_value must be lower or equal to max_value";
138164
is_signed := min_value < 0;
139165

140-
if is_signed then
141-
bit_width := ilog2(abs min_value) + 1;
142-
else
143-
bit_width := ilog2(max_value+1);
144-
end if;
166+
bit_width := maximum(n_bits_needed(min_value, is_signed), n_bits_needed(max_value, is_signed));
145167

146168
deallocate(integer_array);
147169
integer_array := new_3d(width => width, height => height, depth => depth,

vunit/vhdl/random/test/tb_random_pkg.vhd

Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -95,6 +95,54 @@ begin
9595
check_equal(integer_array.bit_width, 13);
9696
check_equal(integer_array.is_signed, false);
9797

98+
random_integer_array(rnd, integer_array, 13, min_value => 0, max_value => 0);
99+
check_equal(integer_array.bit_width, 1);
100+
check_equal(integer_array.is_signed, false);
101+
102+
random_integer_array(rnd, integer_array, 13, min_value => -2, max_value => -2);
103+
check_equal(integer_array.bit_width, 2);
104+
check_equal(integer_array.is_signed, true);
105+
106+
random_integer_array(rnd, integer_array, 13, min_value => -3, max_value => -3);
107+
check_equal(integer_array.bit_width, 3);
108+
check_equal(integer_array.is_signed, true);
109+
110+
random_integer_array(rnd, integer_array, 13, min_value => 1, max_value => 1);
111+
check_equal(integer_array.bit_width, 1);
112+
check_equal(integer_array.is_signed, false);
113+
114+
random_integer_array(rnd, integer_array, 13, min_value => 2, max_value => 2);
115+
check_equal(integer_array.bit_width, 2);
116+
check_equal(integer_array.is_signed, false);
117+
118+
random_integer_array(rnd, integer_array, 13, min_value => 0, max_value => 2);
119+
check_equal(integer_array.bit_width, 2);
120+
check_equal(integer_array.is_signed, false);
121+
122+
random_integer_array(rnd, integer_array, 13, min_value => -1, max_value => 2);
123+
check_equal(integer_array.bit_width, 3);
124+
check_equal(integer_array.is_signed, true);
125+
126+
random_integer_array(rnd, integer_array, 13, min_value => -3, max_value => 1);
127+
check_equal(integer_array.bit_width, 3);
128+
check_equal(integer_array.is_signed, true);
129+
130+
random_integer_array(rnd, integer_array, 13, min_value => 0, max_value => integer'high);
131+
check_equal(integer_array.bit_width, 31);
132+
check_equal(integer_array.is_signed, false);
133+
134+
random_integer_array(rnd, integer_array, 13, min_value => -1, max_value => integer'high);
135+
check_equal(integer_array.bit_width, 32);
136+
check_equal(integer_array.is_signed, true);
137+
138+
random_integer_array(rnd, integer_array, 13, min_value => integer'low, max_value => 0);
139+
check_equal(integer_array.bit_width, 32);
140+
check_equal(integer_array.is_signed, true);
141+
142+
random_integer_array(rnd, integer_array, 13, min_value => integer'low, max_value => integer'high);
143+
check_equal(integer_array.bit_width, 32);
144+
check_equal(integer_array.is_signed, true);
145+
98146
end if;
99147

100148
test_runner_cleanup(runner);

0 commit comments

Comments
 (0)