Return to previous page Advance to next page
VHDL Reference Guide
Chapter 5: Sequential Statements

return Statements

The return statement terminates a subprogram. A function definition requires a return statement. In a procedure definition, a return statement is optional. The syntax follows.

return expression ;         -- Functions
return ; -- Procedures

In the following example, the function OPERATE returns either the AND logical operator or the OR logical parameters of its parameters A and B. The return depends on the value of the parameter OPERATION. The corresponding circuit design is shown in the figure following the example.

package test is
   function OPERATE (A, B, OPERATION: BIT) return BIT;
end test;

package body test is

function OPERATE(A, B, OPERATION: BIT) return BIT is
begin
if (OPERATION = '1') then
return (A and B);
else
return (A or B);
end if;
end OPERATE;
end test;

library IEEE;
use IEEE.std_logic_1164.all;
use WORK.test.all;

entity example5_20 is
   port(
      signal A, B, OPERATION: in BIT;
      signal RETURNED_VALUE: out BIT
      );
end example5_20;

architecture behave of example5_20 is

begin

RETURNED_VALUE <= OPERATE(A, B, OPERATION);
end behave;

Figure 5.10 Circuit for Using Multiple return Statements

Procedures and Functions as Design Components

In VHDL, entities cannot be invoked from within behavioral code. Procedures and functions cannot exist as entities (components) but must be represented by gates.

You can overcome this limitation with the Foundation Express directive map_to_entity, which directs Foundation Express to implement a function or procedure as a component instantiation. Procedures and functions that use map_to_entity are represented as components in designs in which they are called.

When you add a map_to_entity directive to a subprogram definition, Foundation Express assumes the existence of an entity with the identified name and the same interface. Foundation Express does not check this assumption until it links the parent design. The matching entity must have the same input and output port names. If the subprogram is a function, you must also provide a return_port_name directive, where the matching entity has an output port of the same name.

These two directives are called component implication directives.

-- pragma map_to_entity    entity_name
-- pragma return_port_name port_name

Insert these directives after the function or procedure definition.The following example shows how to insert these directives.

   function MUX_FUNC(A,B: in TWO_BIT; C: in BIT)
      return TWO_BIT is

-- pragma map_to_entity MUX_ENTITY
-- pragma return_port_name Z
...

When Foundation Express encounters the map_to_entity directive, it parses but ignores the contents of the subprogram definition. Use --- pragma synthesis_off and -- pragma synthesis_on to hide simulation-specific constructs in a map_to_entity subprogram (see “Translation Stop and Start Pragma Directives” section of the “Foundation Express Directives” chapter for more information about synthesis_off and synthesis_on).

The matching entity (entity_name) does not need to be written in VHDL. It can be in any format that Foundation Express supports.

Note: The behavioral description of the subprogram is not checked against the functionality of the entity overloading it. Presynthesis and post-synthesis simulation results might not match if differences in functionality exist between the VHDL subprogram and the overloaded entity.

Example with Component Implication Directives

The following example shows a function that uses component implication directives. The corresponding circuit design follows the example.

package MY_PACK is
subtype TWO_BIT is BIT_VECTOR(1 to 2);
function MUX_FUNC(A,B: in TWO_BIT; C: in BIT) return
TWO_BIT;
end;

package body MY_PACK is

  function MUX_FUNC(A,B: in TWO_BIT; C: in BIT) return
TWO_BIT is

  -- pragma map_to_entity MUX_ENTITY
-- pragma return_port_name Z

  -- contents of this function are ignored but should
-- match the functionality of the module MUX_ENTITY
-- so pre- and post simulation will match
begin
if(C = '1') then
return(A);
else
return(B);
end if;
end;
end;

use WORK.MY_PACK.ALL;
entity TEST is
port(A: in TWO_BIT; C: in BIT; TEST_OUT: out        TWO_BIT);
end;

architecture ARCH of TEST is
begin
process
begin
TEST_OUT <= MUX_FUNC(not A, A, C);
                       -- Component implication call
end process;
end ARCH;

use WORK.MY_PACK.ALL;

-- the following entity 'overloads' the function
-- MUX_FUNC above

entity MUX_ENTITY is
port(A, B: in TWO_BIT; C: in BIT; Z: out TWO_BIT);
end;

architecture ARCH of MUX_ENTITY is
begin
process
begin
case C is
when '1' => Z <= A;
when '0' => Z <= B;
end case;
end process;
end ARCH;

Figure 5.11 Circuit for Using Component Implication Directives on a Function

Example without Component Implication Directives

The following example shows the same design as the previous example but without the creation of an entity for the function. The component implication directives have been removed. The corresponding circuit design is shown in the figure following the example.

package MY_PACK is
subtype TWO_BIT is BIT_VECTOR(1 to 2);
function MUX_FUNC(A,B: in TWO_BIT; C: in BIT)
return TWO_BIT;
end;

package body MY_PACK is
  function MUX_FUNC(A,B: in TWO_BIT; C: in BIT)
return TWO_BIT is
begin
if(C = '1') then
return(A);
else
return(B);
end if;
end;
end;

use WORK.MY_PACK.ALL;

entity TEST is
port(A: in TWO_BIT; C: in BIT; Z: out TWO_BIT);
end;

architecture ARCH of TEST is
begin
process
begin
Z <= MUX_FUNC(not A, A, C);
end process;
end ARCH;

Figure 5.12 Circuit Design without Component Implication Directives