The block statement is a representation of design or hierarchy section, used for partitioning architecture into self-contained parts.
block_label : block (optional_guard_condition)
declarations
begin
concurrent statements
end block block_label;
The block statement is a way of grouping concurrent statements in an architecture. There are two main purposes for using blocks: to improve readability of the specification and to disable some signals by using the guard expression (see guard for details).
The main purpose of block statement is organisational only - introduction of a block does not directly affect the execution of a simulation model. For example, both the upper and lower sections of code in Example 1 will generate the same simulation results.
Each block must be assigned a label placed just before the block reserved word. The same label may be optionally repeated at the end of the block, right after the end block reserved words.
A block statement can be preceded by two optional parts: a header and a declarative part. The latter allows to introduce declarations of subprograms, types, subtypes, constants, signals, shared variables, files, aliases, components, attributes, configurations, disconnections, use clauses and groups (i.e. any of the declarations possible for an architecture). All declarations specified here are local to the block and are not visible outside it.
A block header may contain port and generic declarations (like in an entity), as well as so called port map and generic map declarations. The purpose of port map and generic map statements is to map signals and other objects declared outside of the block into the ports and generic parameters that have been declared inside of the block, respectively. This construct, however, has only a small practical importance. The Example 2 illustrates typical block declarations.
If an optional guard condition is specified at the beginning of the block then this block becomes a guarded block. See guard for details.
The statements part may contain any concurrent constructs allowed in an architecture. In particular, other block statements can be used here. This way, a kind of hierarchical structure can be introduced into a single architecture body.
Example 1
A1: OUT1 <= '1' after 5 ns;
LEVEL1 : block
begin
A2: OUT2
<= '1' after 5 ns;
A3: OUT3
<= '0' after 4 ns;
end block LEVEL1;
A1: OUT1 <= '1' after 5 ns;
A2: OUT2 <= '1' after 5 ns;
A3: OUT3 <= '0' after 4 ns;
Both pieces of code above will behave in exactly the same way during
simulation - block construct only separates part of the code without
adding any functionality.
Example 2
entity X_GATE is
generic (LongTime : Time;
ShortTime : Time);
port (P1, P2, P3
: inout BIT);
end X_GATE;
architecture STRUCTURE of
X_GATE is
-- global declarations of signal:
signal A, B : BIT;
begin
LEVEL1 : block
-- local declaration of generic parameters
generic
(GB1, GB2 : Time);
-- local binding of generic parameters
generic map
(GB1 => LongTime, GB2 => ShortTime);
-- local declaration of ports
port (PB1:
in BIT; PB2 : inout BIT );
-- local binding of ports and signals
port map
(PB1 => P1, PB2 => B);
-- local declarations:
constant
Delay : Time := 1 ms;
signal S1
: BIT;
begin
S1 <= PB1 after Delay;
PB2 <= S1 after
GB1, P1 after GB2;
end block LEVEL1;
end architecture STRUCTURE;
The signals PB1 and PB2
have here the same values as P1
and B (in port
map statement), respectively, and the generics GB1
and GB2 (see generic
map statement) have the same values as LongTime
and ShortTime,
respectively. However, such assignment is redundant because a block may
use any declarations of an entity, including generics and ports. The Example
2 is presented here only for illustration purpose of the
block syntax.
Guarded blocks are generally not synthesizeable.
Unguarded blocks are usually ignored by synthesis tools.
It is strongly recommended NOT to use blocks in non-VITAL designs - the package Std_logic_1164 supports mechanisms and multiple value logic which make the reserved words bus, disconnect, guarded and register unnecessary. Also, instead of guarded blocks for modelling sequential behaviour it is recommended to used clocked processes.
VITAL specifications require the use of blocks.
VHDL supports a more powerful mechanism of design partitioning which is called component instantiation. Component instantiation allows connecting a component reference in one entity with its declaration in another entity.