![]() |
![]() |
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;
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.
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;
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;