tsfpga VHDL coverage


Directory: generated/vunit_out/preprocessed/
File: generated/vunit_out/preprocessed/math/math_pkg.vhd
Date: 2021-07-26 04:08:16
Exec Total Coverage
Lines: 49 49 100.0%
Branches: 103 196 52.6%

Line Branch Exec Source
1
3/6
✗ Branch 0 not taken.
✓ Branch 1 taken 181 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 181 times.
✗ Branch 6 not taken.
✓ Branch 7 taken 181 times.
16592200 -- -------------------------------------------------------------------------------------------------
2 -- Copyright (c) Lukas Vik. All rights reserved.
3 --
4 -- This file is part of the tsfpga project.
5 -- https://tsfpga.com
6 -- https://gitlab.com/tsfpga/tsfpga
7 -- -------------------------------------------------------------------------------------------------
8
9 library ieee;
10 use ieee.std_logic_1164.all;
11 use ieee.numeric_std.all;
12 use ieee.math_real.all;
13
14
15 package math_pkg is
16
17 function ceil_log2(value : positive) return natural;
18 function log2(value : positive) return natural;
19 function is_power_of_two(value : positive) return boolean;
20
21 function num_bits_needed(value : natural) return positive;
22 function num_bits_needed(value : unsigned) return positive;
23
24 function round_up_to_power_of_two(value : positive) return positive;
25
26 function lt_0(value : signed) return boolean;
27 function geq_0(value : signed) return boolean;
28
29 function to_gray(value : unsigned) return std_logic_vector;
30 function from_gray(code : std_logic_vector) return unsigned;
31
32 function abs_vector(vector : integer_vector) return integer_vector;
33 function vector_sum(vector : integer_vector) return integer;
34
35 function greatest_common_divisor(value1, value2 : positive) return positive;
36 function is_mutual_prime(candidate : positive; check_against : integer_vector) return boolean;
37
38 end package;
39
40 package body math_pkg is
41
42 function ceil_log2(value : positive) return natural is
43 begin
44 -- 2-base logarithm rounded up
45
3/6
✗ Branch 0 not taken.
✓ Branch 1 taken 16 times.
✓ Branch 5 taken 16 times.
✗ Branch 6 not taken.
✗ Branch 7 not taken.
✓ Branch 8 taken 16 times.
478 return natural(ceil(log2(real(value))));
46 end function;
47
48 function floor_log2(value : positive) return natural is
49 begin
50
3/6
✗ Branch 0 not taken.
✓ Branch 1 taken 446 times.
✓ Branch 4 taken 446 times.
✗ Branch 5 not taken.
✗ Branch 6 not taken.
✓ Branch 7 taken 446 times.
446 return natural(log2(real(value)));
51 end function;
52
53 function log2(value : positive) return natural is
54 begin
55 -- 2-base logarithm where argument must be a power of two
56
1/6
✗ Branch 1 not taken.
✓ Branch 2 taken 117 times.
✗ Branch 5 not taken.
✗ Branch 6 not taken.
✗ Branch 7 not taken.
✗ Branch 8 not taken.
234 assert is_power_of_two(value) report "Must be power of two: " & to_string(value) severity failure;
57 234 return floor_log2(value);
58 end function;
59
60 function is_power_of_two(value : positive) return boolean is
61 658 constant log2_value : integer := floor_log2(value);
62 begin
63 658 return 2 ** log2_value = value;
64 end function;
65
66 function num_bits_needed(value : unsigned) return positive is
67 begin
68 -- The number of bits needed to express the given value.
69
3/6
✓ Branch 0 taken 565 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 565 times.
✗ Branch 4 not taken.
✓ Branch 5 taken 565 times.
1130 assert value'high > value'low report "Use only with descending range" severity failure;
70
2/4
✗ Branch 0 not taken.
✓ Branch 1 taken 565 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 565 times.
1130 assert value'low = 0 report "Use vector that starts at zero" severity failure;
71
72
3/6
✓ Branch 0 taken 565 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 565 times.
✓ Branch 4 taken 565 times.
✗ Branch 5 not taken.
1130 for bit_idx in value'high downto value'low loop
73
4/6
✗ Branch 0 not taken.
✓ Branch 1 taken 30052 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 30052 times.
✓ Branch 5 taken 563 times.
✓ Branch 6 taken 29489 times.
60104 if value(bit_idx) = '1' then
74
3/4
✗ Branch 0 not taken.
✓ Branch 1 taken 563 times.
✓ Branch 3 taken 29487 times.
✓ Branch 4 taken 2 times.
60104 return bit_idx + 1;
75 end if;
76 end loop;
77 4 return 1;
78 end function;
79
80 function num_bits_needed(value : natural) return positive is
81
1/2
✓ Branch 2 taken 480 times.
✗ Branch 3 not taken.
960 constant value_vector : unsigned(64 - 1 downto 0) := to_unsigned(value, 64);
82 960 constant result : positive := num_bits_needed(value_vector);
83 begin
84 -- The number of bits needed to express the given value in an unsigned vector.
85
1/6
✗ Branch 1 not taken.
✓ Branch 2 taken 480 times.
✗ Branch 6 not taken.
✗ Branch 7 not taken.
✗ Branch 8 not taken.
✗ Branch 9 not taken.
960 assert value <= 2**result - 1 report "Calculated value not correct: " & to_string(value) & " " & to_string(result) severity failure;
86 960 return result;
87 end function;
88
89 function round_up_to_power_of_two(value : positive) return positive is
90 begin
91
1/2
✗ Branch 2 not taken.
✓ Branch 3 taken 8 times.
16 return 2 ** ceil_log2(value);
92 end function;
93
94 function lt_0(value : signed) return boolean is
95 begin
96 -- The Vivado synthesis engine has been shown to produce a lot of logic (20-30 LUTs) when
97 -- doing simply "if value < 0 then ...", hence this bit operation is used instead.
98
2/4
✗ Branch 0 not taken.
✓ Branch 1 taken 1203203 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 1203203 times.
2406406 return value(value'left) = '1';
99 end function;
100
101 function geq_0(value : signed) return boolean is
102 begin
103 -- The Vivado synthesis engine has been shown to produce a lot of logic (20-30 LUTs) when
104 -- doing simply "if value < 0 then ...", hence this bit operation is used instead.
105
2/4
✗ Branch 0 not taken.
✓ Branch 1 taken 3 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 3 times.
6 return value(value'left) = '0';
106 end function;
107
108 function to_gray(value : unsigned) return std_logic_vector is
109
6/8
✗ Branch 1 not taken.
✓ Branch 2 taken 6881366 times.
✓ Branch 5 taken 42421056 times.
✓ Branch 6 taken 6881366 times.
✗ Branch 8 not taken.
✓ Branch 9 taken 6881366 times.
✓ Branch 12 taken 42421056 times.
✓ Branch 13 taken 6881366 times.
183446956 variable value_slv, result : std_logic_vector(value'range);
110 begin
111
1/2
✓ Branch 0 taken 6881366 times.
✗ Branch 1 not taken.
13762732 value_slv := std_logic_vector(value);
112
7/14
✓ Branch 1 taken 6881366 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✓ Branch 4 taken 6881366 times.
✗ Branch 6 not taken.
✓ Branch 7 taken 6881366 times.
✗ Branch 8 not taken.
✓ Branch 9 taken 6881366 times.
✗ Branch 11 not taken.
✓ Branch 12 taken 6881366 times.
✗ Branch 13 not taken.
✓ Branch 14 taken 6881366 times.
✓ Branch 20 taken 6881366 times.
✗ Branch 21 not taken.
13762732 result := value_slv xor "0" & value_slv(value_slv'high downto 1);
113 13762732 return result;
114 end function;
115
116 function from_gray(code : std_logic_vector) return unsigned is
117
3/4
✗ Branch 1 not taken.
✓ Branch 2 taken 209596 times.
✓ Branch 5 taken 1524797 times.
✓ Branch 6 taken 209596 times.
3468786 variable result : unsigned(code'range);
118 begin
119
6/12
✓ Branch 0 taken 209596 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 209596 times.
✗ Branch 4 not taken.
✓ Branch 5 taken 209596 times.
✓ Branch 7 taken 209596 times.
✗ Branch 8 not taken.
✗ Branch 9 not taken.
✓ Branch 10 taken 209596 times.
✗ Branch 11 not taken.
✓ Branch 12 taken 209596 times.
419192 result(code'high) := code(code'high);
120
2/4
✓ Branch 0 taken 209596 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 209596 times.
✗ Branch 3 not taken.
419192 for bit_num in code'high -1 downto 0 loop
121
8/14
✗ Branch 0 not taken.
✓ Branch 1 taken 1315201 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 1315201 times.
✗ Branch 5 not taken.
✓ Branch 6 taken 1315201 times.
✗ Branch 7 not taken.
✓ Branch 8 taken 1315201 times.
✗ Branch 10 not taken.
✓ Branch 11 taken 1315201 times.
✗ Branch 12 not taken.
✓ Branch 13 taken 1315201 times.
✓ Branch 16 taken 1105605 times.
✓ Branch 17 taken 209596 times.
2630402 result(bit_num) := result(bit_num + 1) xor code(bit_num);
122 end loop;
123
124 419192 return result;
125 end function;
126
127 function abs_vector(vector : integer_vector) return integer_vector is
128
3/4
✗ Branch 1 not taken.
✓ Branch 2 taken 1 times.
✓ Branch 5 taken 4 times.
✓ Branch 6 taken 1 times.
10 variable result : integer_vector(vector'range);
129 begin
130
1/2
✓ Branch 0 taken 1 times.
✗ Branch 1 not taken.
2 for idx in vector'range loop
131
7/12
✓ Branch 0 taken 4 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 4 times.
✓ Branch 5 taken 4 times.
✗ Branch 6 not taken.
✗ Branch 7 not taken.
✓ Branch 8 taken 4 times.
✓ Branch 10 taken 3 times.
✓ Branch 11 taken 1 times.
✓ Branch 12 taken 3 times.
✗ Branch 13 not taken.
8 result(idx) := abs(vector(idx));
132 end loop;
133 2 return result;
134 end function;
135
136 function vector_sum(vector : integer_vector) return integer is
137 4 variable result : integer := 0;
138 begin
139
1/2
✓ Branch 0 taken 2 times.
✗ Branch 1 not taken.
4 for idx in vector'range loop
140
5/8
✓ Branch 0 taken 6 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 6 times.
✓ Branch 5 taken 4 times.
✓ Branch 6 taken 2 times.
✓ Branch 7 taken 4 times.
✗ Branch 8 not taken.
12 result := result + vector(idx);
141 end loop;
142
0/10
✗ Branch 0 not taken.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✗ Branch 6 not taken.
✗ Branch 7 not taken.
✗ Branch 9 not taken.
✗ Branch 10 not taken.
✗ Branch 11 not taken.
✗ Branch 12 not taken.
4 return result;
143 end function;
144
145 function greatest_common_divisor(value1, value2 : positive) return positive is
146 60 variable tmp, smaller_value, larger_value : natural;
147 begin
148 -- Calculate the greatest_common_divisor between two values.
149 -- Uses the euclidean algorithm
150
3/4
✓ Branch 0 taken 20 times.
✓ Branch 1 taken 10 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 30 times.
60 smaller_value := minimum(value1, value2);
151
3/4
✓ Branch 0 taken 10 times.
✓ Branch 1 taken 20 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 30 times.
60 larger_value := maximum(value1, value2);
152
153
2/2
✓ Branch 0 taken 51 times.
✓ Branch 1 taken 30 times.
162 while smaller_value /= 0 loop
154 102 tmp := smaller_value;
155
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 51 times.
102 smaller_value := larger_value mod smaller_value;
156 162 larger_value := tmp;
157 end loop;
158
159
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 30 times.
60 return larger_value;
160 end function;
161
162 function is_mutual_prime(candidate : positive; check_against : integer_vector) return boolean is
163 begin
164 -- Check if a number is a mutual prime (i.e. the greatest common divisor is one)
165 -- with all numbers in a list.
166
1/2
✓ Branch 0 taken 22 times.
✗ Branch 1 not taken.
44 for idx in check_against'range loop
167
5/8
✓ Branch 0 taken 26 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 26 times.
✗ Branch 5 not taken.
✓ Branch 6 taken 26 times.
✓ Branch 9 taken 13 times.
✓ Branch 10 taken 13 times.
52 if greatest_common_divisor(candidate, check_against(idx)) /= 1 then
168
3/4
✓ Branch 0 taken 4 times.
✓ Branch 1 taken 9 times.
✓ Branch 2 taken 4 times.
✗ Branch 3 not taken.
52 return false;
169 end if;
170 end loop;
171
172 -- Greatest common divisor was 1 with all other factors, meaning that this
173 -- factor was a mutual prime with all.
174
2/4
✗ Branch 0 not taken.
✓ Branch 1 taken 181 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 181 times.
380 return true;
175 end function;
176
177 end package body;
178