I have written a vhdl code something like this
entity myentity is
port( number : in integer range 0 to 15; result : out integer);
function myfunction(num: integer range 0 to 15) return integer is
variable i: integer :=1;
variable error1, error2, error, temp, concat: integer;
variable res: integer;
begin
if (num<=1)then
res := num;
else
while (2**i < num) loop
i:=i+1;
end loop;
error2 := num-(2**i);
error1 := num-(2**(i-1));
if abs(error1)<error2 then
error := error1;
else error := error2;
end if;
if error=0 then
res := to_integer(to_unsigned(num,8) sll i);
else
temp := num-error;
concat := myfunction(temp);
res :=to_integer(to_unsigned(temp,4) & to_unsigned(concat,i-1));
end if;
end if;
return res;
end myfunction;
end myentity;
architecture Behavioral of myentity is
begin
result<=myfunction(number);
end Behavioral;
Function is recursive. The problem is, the architecture body is not calling the function. i.e., function lines are not being executed. When I compile the program, it shows no error. Any help? I changed the example to the original code.
With your new question code formatted for readability, report statements added for debugging and an added testbench to drive all possible integer values of number (0 to 15), creating a Minimal, Complete and Verifiable example:
library ieee; -- CONTEXT CLAUSE ADDED
use ieee.numeric_std.all; -- unsigned, to_unsigned, to_integer, sll
-- superfluous parentheses removed, indentation added for clarity:
entity myentity is
port (
number: in integer range 0 to 15;
result: out integer
);
function myfunction (num: integer range 0 to 15) return integer is
variable i: integer := 1;
variable error1, error2, error, temp, concat: integer;
variable res: integer;
begin
if num <= 1 then -- CONDITION COULD BE num = 0
res := num;
report "num = " & integer'image(num); -- ADDED REPORT
else
while 2 ** i < num loop
i := i + 1;
end loop;
report "i = " & integer'image(i); -- ADDED REPORT
error2 := num - 2 ** i;
report "error2 = " & integer'image(error2); -- ADDED REPORT
error1 := num - 2 ** (i - 1);
report "error1 = " & integer'image(error1); -- ADDED REPORT
if abs error1 < error2 then
error := error1;
else
error := error2;
end if;
report "error = " & integer'image(error); -- ADDED REPORT
if error = 0 then
res := to_integer(to_unsigned(num, 8) sll i);
report "res = " & integer'image(res); -- ADDED REPORT
else
temp := num - error;
report "temp = " & integer'image(temp); -- ADDED REPORT
concat := myfunction(temp);
report "concat = " & integer'image(concat); -- ADDED REPORT
res := to_integer(to_unsigned(temp, 4) &
to_unsigned(concat, i - 1) );
report "res = " & integer'image(res); -- ADDED REPORT
end if;
end if;
return res;
end myfunction;
end entity myentity;
architecture behavioral of myentity is
begin
result <= myfunction(number);
end architecture behavioral;
entity myentity_tb is
end entity;
architecture foo of myentity_tb is
signal result: integer;
signal number: integer range 0 to 15;
begin
DUT:
entity work.myentity
port map (
number => number,
result => result
);
STIMULI:
process
begin
for i in 0 to 15 loop
number <= i;
report "number = " & integer'image(i);
wait for 10 ns;
end loop;
wait;
end process;
end architecture;
Analyzing the code, elaborating and running the testbench produces with a VHDL implementation dependent report statement format:
myentity.vhdl:17:13:@0ms:(report note): num = 0 myentity.vhdl:74:13:@0ms:(report note): number = 0 myentity.vhdl:74:13:@10ns:(report note): number = 1 myentity.vhdl:17:13:@10ns:(report note): num = 1 myentity.vhdl:74:13:@20ns:(report note): number = 2 myentity.vhdl:22:13:@20ns:(report note): i = 1 myentity.vhdl:24:13:@20ns:(report note): error2 = 0 myentity.vhdl:26:13:@20ns:(report note): error1 = 1 myentity.vhdl:32:13:@20ns:(report note): error = 0 myentity.vhdl:35:17:@20ns:(report note): res = 4 myentity.vhdl:74:13:@30ns:(report note): number = 3 myentity.vhdl:22:13:@30ns:(report note): i = 2 myentity.vhdl:24:13:@30ns:(report note): error2 = -1 myentity.vhdl:26:13:@30ns:(report note): error1 = 1 myentity.vhdl:32:13:@30ns:(report note): error = -1 myentity.vhdl:38:17:@30ns:(report note): temp = 4 myentity.vhdl:22:13:@30ns:(report note): i = 2 myentity.vhdl:24:13:@30ns:(report note): error2 = 0 myentity.vhdl:26:13:@30ns:(report note): error1 = 2 myentity.vhdl:32:13:@30ns:(report note): error = 0 myentity.vhdl:35:17:@30ns:(report note): res = 16 myentity.vhdl:40:17:@30ns:(report note): concat = 16 ../../src/ieee/numeric_std-body.v93:2151:7:@30ns:(assertion warning): NUMERIC_STD.TO_UNSIGNED: vector truncated myentity.vhdl:43:17:@30ns:(report note): res = 8 myentity.vhdl:74:13:@40ns:(report note): number = 4 myentity.vhdl:22:13:@40ns:(report note): i = 2 myentity.vhdl:24:13:@40ns:(report note): error2 = 0 myentity.vhdl:26:13:@40ns:(report note): error1 = 2 myentity.vhdl:32:13:@40ns:(report note): error = 0 myentity.vhdl:35:17:@40ns:(report note): res = 16 myentity.vhdl:74:13:@50ns:(report note): number = 5 myentity.vhdl:22:13:@50ns:(report note): i = 3 myentity.vhdl:24:13:@50ns:(report note): error2 = -3 myentity.vhdl:26:13:@50ns:(report note): error1 = 1 myentity.vhdl:32:13:@50ns:(report note): error = -3 myentity.vhdl:38:17:@50ns:(report note): temp = 8 myentity.vhdl:22:13:@50ns:(report note): i = 3 myentity.vhdl:24:13:@50ns:(report note): error2 = 0 myentity.vhdl:26:13:@50ns:(report note): error1 = 4 myentity.vhdl:32:13:@50ns:(report note): error = 0 myentity.vhdl:35:17:@50ns:(report note): res = 64 myentity.vhdl:40:17:@50ns:(report note): concat = 64 ../../src/ieee/numeric_std-body.v93:2151:7:@50ns:(assertion warning): NUMERIC_STD.TO_UNSIGNED: vector truncated myentity.vhdl:43:17:@50ns:(report note): res = 32 myentity.vhdl:74:13:@60ns:(report note): number = 6 myentity.vhdl:22:13:@60ns:(report note): i = 3 myentity.vhdl:24:13:@60ns:(report note): error2 = -2 myentity.vhdl:26:13:@60ns:(report note): error1 = 2 myentity.vhdl:32:13:@60ns:(report note): error = -2 myentity.vhdl:38:17:@60ns:(report note): temp = 8 myentity.vhdl:22:13:@60ns:(report note): i = 3 myentity.vhdl:24:13:@60ns:(report note): error2 = 0 myentity.vhdl:26:13:@60ns:(report note): error1 = 4 myentity.vhdl:32:13:@60ns:(report note): error = 0 myentity.vhdl:35:17:@60ns:(report note): res = 64 myentity.vhdl:40:17:@60ns:(report note): concat = 64 ../../src/ieee/numeric_std-body.v93:2151:7:@60ns:(assertion warning): NUMERIC_STD.TO_UNSIGNED: vector truncated myentity.vhdl:43:17:@60ns:(report note): res = 32 myentity.vhdl:74:13:@70ns:(report note): number = 7 myentity.vhdl:22:13:@70ns:(report note): i = 3 myentity.vhdl:24:13:@70ns:(report note): error2 = -1 myentity.vhdl:26:13:@70ns:(report note): error1 = 3 myentity.vhdl:32:13:@70ns:(report note): error = -1 myentity.vhdl:38:17:@70ns:(report note): temp = 8 myentity.vhdl:22:13:@70ns:(report note): i = 3 myentity.vhdl:24:13:@70ns:(report note): error2 = 0 myentity.vhdl:26:13:@70ns:(report note): error1 = 4 myentity.vhdl:32:13:@70ns:(report note): error = 0 myentity.vhdl:35:17:@70ns:(report note): res = 64 myentity.vhdl:40:17:@70ns:(report note): concat = 64 ../../src/ieee/numeric_std-body.v93:2151:7:@70ns:(assertion warning): NUMERIC_STD.TO_UNSIGNED: vector truncated myentity.vhdl:43:17:@70ns:(report note): res = 32 myentity.vhdl:74:13:@80ns:(report note): number = 8 myentity.vhdl:22:13:@80ns:(report note): i = 3 myentity.vhdl:24:13:@80ns:(report note): error2 = 0 myentity.vhdl:26:13:@80ns:(report note): error1 = 4 myentity.vhdl:32:13:@80ns:(report note): error = 0 myentity.vhdl:35:17:@80ns:(report note): res = 64 myentity.vhdl:74:13:@90ns:(report note): number = 9 myentity.vhdl:22:13:@90ns:(report note): i = 4 myentity.vhdl:24:13:@90ns:(report note): error2 = -7 myentity.vhdl:26:13:@90ns:(report note): error1 = 1 myentity.vhdl:32:13:@90ns:(report note): error = -7 myentity.vhdl:38:17:@90ns:(report note): temp = 16 ./myentity_tb:error: bound check failure at myentity.vhdl:39 ./myentity_tb:error: simulation failed
Where we can see for a number value of 0 the function returns 0 which is assigned to result. That explains why without driving different values (1 through 15) on number through stimuli (here a testbench, a higher level in the design hierarchy) why result is 0 and produces no error. (Note without an assignment to result it's value would have been INTEGER'LOW the minimum value for that type, result has no subtype constraint and inherits it's subtype from the type mark in the port declaration for result).
There are two classes of messages causing concern in the output for number values 1 through 15.
The first is the report message from package numeric_std telling you you clipped left elements from the binary number eventually converted to integer and assigned to res. This represents inaccuracy in your algorithm that needs to be addressed. You can note that res (assigned to result in the concurrent signal assignment statement) is 64 when that occurs.
The second is the error message when number was assigned a value of 9 and the value passed to the recursive call to myfunction was outside it's parameter num's range (0 to 15, the value 16 for variable temp). A bounds violation error is sufficient to cause simulation to cease, the integrity of the simulation is compromised. (And this is what strong typing does for you, the subtype of parameter num should have been chosen for a purpose in implementing myfunction).
You can easily remove every report statement added for debugging when your algorithm functions satisfactorily after which you can test again.
Note the values of number can be distinguished by what time they occur at during simulation.
This answer shows why your code reports no error as well as showing how to tell what it's doing to allow debugging for other values of number.
As we can see my the presence of the very first report statement the function myfunction is getting called. Also if result were not assigned it's default value would be a negative number.