In Sections 3.2.3 and 3.2.4 we showed how a structural description can declare a component specification and create instances of components. We mentioned that a component declared can be thought of as a template for a design entity. The binding of an entity to this template is achieved through a configuration declaration. This declaration can also be used to specify actual generic constants for components and blocks. So the configuration declaration plays a pivotal role in organising a design description in preparation for simulation or other processing.
The syntax of a configuration declaration is:
configuration_declaration ::=
configuration identifier of
entity_name is
configuration_declarative_part
block_configuration
end [ configuration_simple_name
] ;
configuration_declarative_part ::= { configuration_declarative_item }
configuration_declarative_item ::= use_clause
block_configuration ::=
for block_specification
{ use_clause
}
{ configuration_item
}
end for ;
block_specification ::= architecture_name | block_statement_label
configuration_item ::= block_configuration | component_configuration
component_configuration ::=
for component_specification
[ use
binding_indication ; ]
[ block_configuration
]
end for ;
component_specification ::= instantiation_list : component_name
instantiation_list ::=
instantiation_label { , instantiation_label
)
| others
| all
binding_indication ::=
entity_aspect
[ generic_map_aspect ]
[ port_map_aspect ]
entity_aspect ::=
entity entity_name [ (
architecture_identifier ) ]
| configuration configuration_name
| open
generic_map_aspect ::= generic map ( generic_association_list )
port_map_aspect ::= port map ( port_association_list )
entity processor is
generic (max_clock_speed :
frequency := 30 MHz);
port ( port list );
end processor;
architecture block_structure of processor is
declarations
begin
control_unit : block
port
( port list );
port
map ( association list );
declarations
for control_unit
begin
statements
for control_unit
end block control_unit;
data_path : block
port
( port list );
port
map ( association list );
declarations
for data_path
begin
statements
for data_path
end block data_path;
end block_structure;
Figure 5-1. Example processor entity and architecture body.
The declarative part of the configuration declaration allows the configuration to use items from libraries and packages. The outermost block configuration in the configuration declaration defines the configuration for an architecture of the named entity. For example, in Chapter 3 we had an example of a processor entity and architecture, outlined again in Figure 5-1. The overall structure of a configuration declaration for this architecture might be:
configuration test_config of processor is
use work.processor_types.all
for block_structure
configuration
items
end for;
end test_config;
In this example, the contents of a package called processor_types in the current working library are made visible, and the block configuration refers to the architecture block_structure of the entity processor.
Within the block configuration for the architecture, the submodules of the architecture may be configured. These submodules include blocks and component instances. A block is configured with a nested block configuration. For example, the blocks in the above architecture can be configured as shown in Figure 5-2.
configuration test_config of processor is
use work.processor_types.all
for block_structure
for
control_unit
configuration
items
end
for;
for
data_path
configuration
items
end
for;
end for;
end test_config;
Figure 5-2. Configuration of processor example.
Where a submodule is an instance of a component, a component configuration is used to bind an entity to the component instance. To illustrate, suppose the data_path block in the above example contained an instance of the component alu, declared as shown in Figure 5-3. Suppose also that a library project_cells contains an entity called alu_cell defined as:
entity alu_cell is
generic (width : positive);
port (function_code : in alu_function;
operand1,
operand2 : in bit_vector(width-1 downto 0);
result
: out bit_vector(width-1 downto 0);
flags
: out alu_flags);
end alu_cell;
data_path : block
port ( port list );
port map ( association list
);
component alu
port
(function : in alu_function;
op1,
op2 : in bit_vector_32;
result
: out bit_vector_32);
end component;
other declarations for data_path
begin
data_alu : alu
port
map (function => alu_fn, op1 => b1, op2 => b2, result =>
alu_r);
other statements for data_path
end block data_path;
Figure 5-3. Structure of processor data-path block.
with an architecture called behaviour. This entity matches the alu component template, since its operand and result ports can be constrained to match those of the component, and the flags port can be left unconnected. A block configuration for data_path could be specified as shown in Figure 5-4.
for data_path
for data_alu : alu
use
entity project_cells.alu_cell(behaviour)
generic
map (width => 32)
port
map (function_code => function, operand1 => op1, operand2 =>
op2,
result
=> result, flags => open);
end for;
other configuration items
end for;
Figure 5-4. Block configuration using library entity.
Alternatively, if the library also contained a configuration called alu_struct for an architecture structure of the entity alu_cell, then the block configuration could use this, as shown in Figure 5-5.
for data_path
for data_alu : alu
use
configuration project_cells.alu_struct
generic
map (width => 32)
port
map (function_code => function, operand1 => op1, operand2 =>
op2,
result
=> result, flags => open);
end for;
other configuration items
end for;
Figure 5-5. Block configuration using another configuration.