|Summary |Design Units |Sequential Statements |Concurrent Statements |Predefined Types |Declarations |

|Resolution and Signatures |Reserved Words |Operators |Predefined Attributes |Standard Packages |

VHDL Design Units and Subprograms

A design unit may be the entire file or there may be more than
one design unit in a file. No less than a design unit may be
in a file.

Any design unit may contain a context clause as its initial part.
The context clause of a primary unit applies to all of the
primary units corresponding secondary units.  Architectures and
package bodies are the secondary units. Subprograms are
not library units and must be inside entities, architectures
or packages.

The analysis, compilation, of a design unit results in a library unit
is some design library.  Predefined libraries typically include but are
not limited to: STD, IEEE and WORK.  WORK is the default user library.

Design Units and Subprograms

  • Entity
  • Architecture
  • Configuration
  • Package Declaration
  • Package Body
  • Subprograms
  • Procedure Declaration
  • Procedure Body
  • Function Declaration
  • Function Body
  • Context Clause
  • Order of Analysis, Compilation
  • Entity

    The top of every design hierarchy must be an entity.
    Entities may range from primitive circuits to complex assemblies.
    
    The entity code typically defines just the interface of the entity.
    
      entity  identifier is
         generic ( generic_variable_declarations ) ; -- optional
         port ( input_and_output_variable_declarations ) ;
         [ declarations , see allowed list below ]   -- optional
      begin                                         \__ optional
         [ statements , see allowed list below ]    /    
      end entity identifier ;  
    
      generic_variable_declarations are of the form:
        variable_name : variable_type := variable_value ; -- := variable_value optional
    
      input_and_output_variable_declaration are of the form:
         variable_name : port_mode  variable_type ;
      port_mode may be in out inout buffer linkage
    
    
      entity adder is
         generic ( N : natural := 32 ) ;
         port ( A    : in  bit_vector(N-1 downto 0);
                B    : in  bit_vector(N-1 downto 0);
                cin  : in  bit;
                Sum  : out bit_vector(N-1 downto 0);
                Cout : out bit );
      end entity adder ;
    
    
      entity test_bench is   -- typical top level, simulatable, entity
      end entity test_bench;
    
    
      entity Latch is
         port ( Din:  in  Word;
                Dout: out Word;
                Load: in  Bit;
                Clk:  in  Bit);
         constant Setup: Time := 12 ns;
         constant PulseWidth: Time := 50 ns;
         use WORK.TimingMonitors.all
      begin
         assert Clk='1' or Clk'Delayed'Stable(PulseWidth);
         CheckTiming(Setup, Din, Load, Clk); -- passive concurrent procedure
      end entity Latch;
    
    The allowed declarations are:
      subprogram declaration
      subprogram body
      type declaration
      subtype declaration
      constant, object declaration
      signal, object declaration
      variable, object declaration - shared
      file, object declaration
      alias declaration
      attribute declaration
      attribute specification
      disconnection specification
      use clause
      group template declaration
      group declaration
    
    The allowed statements are:
      concurrent assertion statements
      passive concurrent procedure call
      passive process statement
    
    

    Architecture

    Used to implement a design entity. There may be more than one
    architecture for a design entity. Typical architectures fall
    into classes such as functional simulation or detailed logic
    implementation and may be structural, functional(dataflow)
    or behavioral. 
    
      architecture identifier of entity_name is
         [ declarations , see allowed list below ]
      begin -- optional
         [ statements , see allowed list below ]
      end architecture identifier ;  
    
    
      architecture circuits of add4c is
        signal c : std_logic_vector(3 downto 0);
        component fadd    -- duplicates entity port
          port(a    : in  std_logic;
               b    : in  std_logic;
               cin  : in  std_logic;
               s    : out std_logic;
               cout : out std_logic);
        end component fadd;
      begin  -- circuits of add4c
        a0: fadd port map(a(0), b(0), cin , sum(0), c(0));
        a1: fadd port map(a(1), b(1), c(0), sum(1), c(1));
        a2: fadd port map(a(2), b(2), c(1), sum(2), c(2));
        a3: fadd port map(a(3), b(3), c(2), sum(3), c(3));
        cout <= (a(3) and b(3)) or ((a(3) or b(3)) and
               ((a(2) and b(2)) or ((a(2) or b(2)) and
               ((a(1) and b(1)) or ((a(1) or b(1)) and
               ((a(0) and b(0)) or ((a(0) or b(0)) and cin)))))))
               after 1 ns;
      end architecture circuits;  -- of add4c
    
    
    The allowed declarations are:
      subprogram declaration
      subprogram body
      type declaration
      subtype declaration
      constant, object declaration
      signal, object declaration
      variable, object declaration - shared
      file, object declaration
      alias declaration
      component declaration
      attribute declaration
      attribute specification
      disconnection specification
      use clause
      group template declaration
      group declaration
    
    The allowed statements are:
      concurrent statements
    
    

    Configuration

    Used to bind component instances to design entities and
    collect architectures to make, typically, a simulatable
    test bench. One configuration could create a functional
    simulation while another configuration could create
    the complete detailed logic design. With an appropriate
    test bench the results of the two configurations
    can be compared.
    
    Note that significant nesting depth can occur on hierarchal
    designs. There is a capability to bind various architectures
    with instances of components in the hierarchy. To avoid nesting
    depth use a configuration for each architecture level and a
    configuration of configurations. Most VHDL compilation/simulation
    systems allow the top level configuration name to be elaborated
    and simulated.
    
    
      configuration identifier of entity_name is
         [ declarations , see allowed list below ]
         [ block configuration , see allowed list below ]
      end architecture identifier ;  
    
    
      -- entities and architecture circuits for fadd, add4c and add32 not shown
      entity add32_test is -- test bench
      end add32_test;
    
      architecture circuits of add32_test is
         -- details implementing test bench deleted
      end architecture circuits; -- of add32_test
    
    
      configuration add32_test_config of add32_test is
        for circuits -- of add32_test
          for all: add32
            use entity WORK.add32(circuits);
            for circuits -- of add32
              for all: add4c
                use entity WORK.add4c(circuits);
                for circuits -- of add4c
                  for all: fadd
                    use entity WORK.fadd(circuits);
                  end for;
                end for;
              end for;
            end for;
          end for;
        end for;
      end configuration add32_test_config;
    
      Note the architecture name in parenthesis following the entity name.
    
    Or an equivalent configuration of configurations:
    
      configuration add32_test_config of add32_test is
        for circuits -- of add32_test
          for all: add32
            use configuration WORK.add32_config;
          end for;
        end for;
      end configuration add32_test_config;
    
      
    The allowed declarations are:
      attribute specification
      use clause
      group declaration
    
    The allowed block configurations are:
      for component_instance_name : component_name
         -- use clause
      end for;
    
      for all : component_name
         -- use clause
      end for;
    
    use clauses are of the form:
       use entity library_name.entity_name[(architecture_name)]
       use configuration library_name.configuration_name
    
    

    Package Declaration

    Used to declare types, shared variables, subprograms, etc.
    
      package identifier is
          [ declarations, see allowed list below ]
      end package identifier ;
    
      The example is included in the next section, Package Body.
    
    The allowed declarations are:
      subprogram declaration
      type declaration
      subtype declaration
      constant, object declaration
      signal, object declaration
      variable, object declaration - shared
      file, object declaration
      alias declaration
      component declaration
      attribute declaration
      attribute specification
      use clause
      group template declaration
      group declaration
    
    Declarations not allowed include:
      subprogram body
      
    A package body is unnecessary if no subprograms or
    deferred constants are declared in the package declaration.
    
    

    Package Body

    Used to implement the subprograms declared in the package declaration.
    
      package body identifier is
          [ declarations, see allowed list below ]
      end package body identifier ;
    
      package my_pkg is -- sample package declaration
        type small is range 0 to 4096;
        procedure s_inc(A : inout small);
        function s_dec(B : small) return small;
      end package my_pkg;
    
      package body my_pkg is -- corresponding package body
        procedure s_inc(A : inout small) is
        begin
        A := A+1;
        end procedure s_inc;
        function s_dec(B : small) return small is
        begin
          return B-1;
        end function s_dec;
      end package body my_pkg;
    
    
    The allowed declarations are:
      subprogram declaration
      subprogram body
      type declaration
      subtype declaration
      constant, object declaration
      variable, object declaration - shared
      file, object declaration
      alias declaration
      use clause
      group template declaration
      group declaration
     
    Declarations not allowed include:
      signal, object declaration
      
    

    Subprograms

    There are two kinds of subprograms: procedures and functions.
    
    Both procedures and functions written in VHDL must have
    a body and may have declarations. 
    
    Procedures perform sequential computations and return values
    in global objects or by storing values into formal parameters.
    
    Functions perform sequential computations and return a value
    as the value of the function.  Functions do not change their
    formal parameters.
    
    Subprograms may exist as just a procedure body or a function body.
    Subprograms may also have a procedure declarations or a
    function declaration.
    
    When subprograms are provided in a package, the subprogram declaration
    is placed in the package declaration and the subprogram body is
    placed in the package body.
    
    

    Procedure Declaration

    Used to declare the calling interface to a procedure.
    
      procedure identifier [ ( formal parameter list ) ] ;
    
      procedure print_header ;
      procedure build ( A : in constant integer;
                        B : inout signal bit_vector;
                        C : out variable real;
                        D : file ) ;
    
    Formal parameters are separated by semicolons in the formal parameter
    list.  Each formal parameter is essentially a declaration of an
    object that is local to the procedure.  The type definitions used
    in formal parameters must be visible at the place where the procedure
    is being declared.  No semicolon follows the last formal parameter
    inside the parenthesis.
    
    Formal parameters may be constants, variables, signals or files.
    The default is variable.
    
    Formal parameters may have modes in, inout and out
    Files do not have a mode.
    The default is in .
    
    If no type is given and a mode of in is used, constant is the default.
    
    The equivalent default declaration of "build" is
    
      procedure build ( A : in integer;
                        B : inout signal bit_vector;
                        C : out real;
                        D : file ) ;
    
    

    Procedure Body

    Used to define the implementation of the procedure.
    
      procedure identifier [ ( formal parameter list ) ] is
          [ declarations, see allowed list below ]
      begin
          sequential statement(s)
      end procedure identifier ;
    
      procedure print_header is
          use STD.textio.all;
          variable my_line : line; 
      begin
          write ( my_line, string'("A    B    C"));
          writeline ( output, my_line );
      end procedure print_header ;
    
    The procedure body formal parameter list is defined above in
    Procedure Declaration.  When a procedure declaration is used then
    the corresponding procedure body should have exactly the same
    formal parameter list.
    
    The allowed declarations are:
      subprogram declaration
      subprogram body
      type declaration
      subtype declaration
      constant, object declaration
      variable, object declaration
      file, object declaration
      alias declaration
      use clause
      group template declaration
      group declaration
     
    Declarations not allowed include:
      signal, object declaration
     
    

    Function Declaration

    Used to declare the calling and return interface to a function.
    
      function identifier [ ( formal parameter list ) ] return a_type ;
    
      function random return float ;
      function is_even ( A : integer) return boolean ;
    
    Formal parameters are separated by semicolons in the formal parameter
    list.  Each formal parameter is essentially a declaration of an
    object that is local to the function.  The type definitions used
    in formal parameters must be visible at the place where the function
    is being declared.  No semicolon follows the last formal parameter
    inside the parenthesis.
    
    Formal parameters may be constants, signals or files.
    The default is constant.
    
    Formal parameters have the mode in.
    Files do not have a mode.
    Note that  inout and out are not allowed for functions.
    The default is in .
    
    The reserved word function may be preceded by nothing,
    implying pure , pure or impure .
    A pure function must not contain a reference to a file object,
    slice, subelement, shared variable or signal with attributes
    such as 'delayed, 'stable, 'quiet, 'transaction and must not
    be a parent of an impure function.
    
    

    Function Body

    Used to define the implementation of the function.
    
      function identifier [ ( formal parameter list ) ]
                      return a_type is
          [ declarations, see allowed list below ]
      begin
          sequential statement(s)
          return some_value; -- of type  a_type
      end function identifier ;
    
      function random return float is
           variable X : float;
      begin
           -- compute X
           return X;
      end function random ;
    
    The function body formal parameter list is defined above in
    Function Declaration.  When a function declaration is used then
    the corresponding function body should have exactly the same
    formal parameter list.
    
    The allowed declarations are:
      subprogram declaration
      subprogram body
      type declaration
      subtype declaration
      constant, object declaration
      variable, object declaration
      file, object declaration
      alias declaration
      use clause
      group template declaration
      group declaration
     
    Declarations not allowed include:
      signal, object declaration
    
    

    Context Clause

    Used to name a library and make library units visible
    to the design unit that immediately follows.
    
      library library_name ;
      use library_name.unit_name.all ;
    
      library STD ;
      use STD.textio.all;
    
      library ieee ;
      use ieee.std_logic_1164.all;
      use ieee.std_logic_textio.all;
      use ieee.std_logic_arith.all;
      use ieee.numeric_std.all;
      use ieee.numeric_bit.all;
      use WORK.my_pkg.s_inc; -- select one item from package
    
    Note that the .all makes everything visible. It is
    optional and when not used the prefix such as
       ieee.std_logic_1164.   must be used on every reference
    to an item in the library unit.  Specific items in the
    library unit may be listed in place of  .all .
    
    The libraries STD and WORK do not need a library specification
    on most systems.  library ieee or equivalent library IEEE
    is needed on most systems.
    
    

    Order of Analysis, Compilation

    Every design unit must be analyzed, compiled, before it can
    be used by another design unit. The result of the analysis
    or compilation results in an analyzed design in a library.
    The analyzed design goes into the default library WORK
    unless otherwise specified.
    
    An entity must be analyzed, compiled, before its corresponding
    architectures or configurations.
    
    A package declaration must be analyzed, compiled, before its
    corresponding package body.
    
    A package declaration must be analyzed, compiled, before it can
    be referenced in a context clause.  For example:
    
         Analyze, compile
              package my_package is
                -- declarations
              end package my_package;
    
         then analyze, compile
              library WORK;  -- this line usually not needed
              use WORK.my_package.all
              entity my_entity is
                -- entity stuff
              end entity my_entity;
    
    
    
    

    Other Links

    Go to top

    Go to VHDL index