![]() |
![]() |
A generate statement creates zero or more copies of an enclosed set of concurrent statements. The two kinds of generate statements follow.
The syntax follows.
label: for identifier in range generate
{ concurrent_statement }
end generate [ label ] ;
integer_expression to integer_expression
integer_expression downto integer_expression
A for...generate statement executes as follows.
The following example shows a code fragment that combines and interleaves two 4-bit arrays, A and B, into an 8-bit array, C. The resulting design is shown in the figure following the example.
signal A, B : bit_vector(3 downto 0);
signal C : bit_vector(7 downto 0);
signal X : bit;
. . .
GEN_LABEL: for I in 3 downto 0 generate
C(2*I + 1) <= A(I) nor X;
C(2*I) <= B(I) nor X;
end generate GEN_LABEL;
The most common use of the generate statement is to create multiple copies of components, processes, or blocks. The following example and figure demonstrates this use with components. (The example and figure following this example and figure show this usage with processes.)
The following example shows VHDL array attribute 'range used with the for...generate statement to instantiate a set of COMP components that connect corresponding elements of bit vectors A and B. The resulting design follows each of the examples.
component COMP
port (X : in bit;
Y : out bit);
end component;
. . .
signal A, B: BIT_VECTOR(0 to 7);
. . .
GEN: for I in A'range generate
U: COMP port map (X => A(I),
Y => B(I));
end generate GEN;
For more information about arrays, see Array Types section of the Data Types chapter.
The syntax follows.
label: if expression generate
{ concurrent_statement }
end generate [ label ] ;
Note: Unlike the if statement described in the if Statements section of the Sequential Statements chapter, the if...generate statement has no else or elsif branches.
You can use the if...generate statement to generate a regular structure that has different circuitry at its ends. Use a for...generate statement to iterate over the desired width of a design and use a set of if...generate statements to define the beginning, middle, and ending sets of connections.
The following example shows a technology-independent description of an N-bit serial-to-parallel converter. Data is clocked into an N-bit buffer from right to left. On each clock cycle, each bit in an N-bit buffer is shifted up 1 bit, and the incoming DATA bit is moved into the low-order bit. The resulting design follows the example.
entity CONVERTER is
generic(N: INTEGER := 8);
port(CLK, DATA: in BIT;
CONVERT: buffer BIT_VECTOR(N-1 downto 0));
end CONVERTER;
architecture BEHAVIOR of CONVERTER is
signal S : BIT_VECTOR(CONVERT'range);
begin
G: for I in CONVERT'range generate
G1: -- Shift (N-1) data bit into high-order bit
if (I = CONVERT'left) generate
process begin
wait until (CLK'event and CLK = `1');
CONVERT(I) <= S(I-1);
end process;
end generate G1;
G2: -- Shift middle bits up
if (I > CONVERT'right and
I < CONVERT'left) generate
S(I) <= S(I-1) and CONVERT(I);
process begin
wait until (CLK'event and CLK ='1');
CONVERT(I) <= S(I-1);
end process;
end generate G2;
G3: -- Move DATA into low-order bit
if (I = CONVERT'right) generate
process begin
wait until (CLK'event and CLK = `1');
CONVERT(I) <= DATA;
end process;
S(I) <= CONVERT(I);
end generate G3;
end generate G;
end BEHAVIOR;