Featured post

Top 5 books to refer for a VHDL beginner

VHDL (VHSIC-HDL, Very High-Speed Integrated Circuit Hardware Description Language) is a hardware description language used in electronic des...

Saturday, 29 December 2012

Generate Statement

Formal Definition

A mechanism for iterative or conditional elaboration of a portion of a description.

Simplified Syntax

label : for parameter in range generate

[ { declarations }

begin ]

{ concurrent_statements }

end generate [ label ] ;

label : if condition generate

[ { declarations }

begin ]

{ concurrent_statements }

end generate [ label ] ;

Description

The generate statement simplifies description of regular design structures. Usually it is used to specify a group of identical components using just one component specification and repeating it using the generate mechanism.

A generate statement consists of three main parts:

· generation scheme (either for scheme or if scheme);

· declarative part (local declarations of subprograms, types, signals, constants, components, attributes, configurations, files and groups);

· concurrent statements.

The generation scheme specifies how the concurrent structure statement should be generated. There are two generation schemes available: for scheme and if scheme.

The for generation scheme is used to describe regular structures in the design. In such a case, the generation parameter and its scope of values are generated in similar way as in the sequential loop statement. Example 1 illustrates this concept with N-bit binary counter created by the generate statement that instantiates N D-type flip-flops (Figure 1).

N_bit_counter

Fig. 1. The N-bit binary counter counting forward.

It is quite common that regular structures contain some irregularities. In such cases, the if scheme is very useful. Example 2 describes the synchronuous decimal counter that consists of JK flip-flops and NAND gates (Fig. 2). In that structure there are some irregularities related to the connection of the next level of flip-flops.

8421_BCD_counter

Fig. 2. The 8421 BCD counter counting forward.

A generate statement may contain any concurrent statement: process statement, block statement, concurrent assertion statement, concurrent procedure call statement, component instantiation statement, concurrent signal assignment statement, and another generate statement. The latter mechanism allows nesting the regular design structures and forming multidimensional arrays of components.

Examples

Example 1

entity D_FF is
port (D,CLK_S : in BIT;
      Q : out BIT := '0';
      NQ : out BIT := '1' );
end entity D_FF;
architecture A_RS_FF of D_FF is
begin
BIN_P_RS_FF: process(CLK_S)
begin
if CLK_S = '1' and CLK_S'Event
then Q <= D;
          NQ <= not D;
end if;
end process;
end architecture A_RS_FF;
entity COUNTER_BIN_N is
generic (N : Integer := 4);
port (Q : out Bit_Vector (0 to N-1);
      IN_1 : in Bit );
end entity COUNTER_BIN_N;
architecture BEH of COUNTER_BIN_N is
component D_FF
port(D, CLK_S : in BIT; Q, NQ : out BIT);
end component D_FF;
signal S : BIT_VECTOR(0 to N);
begin
S(0) <= IN_1;
G_1 : for I in 0 to N-1 generate
D_Flip_Flop :
D_FF port map
(S(I+1), S(I), Q(I), S(I+1));
         end generate;
end architecture BEH;

First, a specification of a D flip-flop is given which will be used by the component declaration. The generate statement here is used to define a counter of arbitrary length, determined only by its generic parameter (set here to 4).

Example 2

-- the 8421 BCD counter
entity COUNTER_BCD is
port (IN_1 : in Bit; Q:out Bit_Vector(0 to 3));
end entity COUNTER_BCD;
architecture STRUCT of COUNTER_BCD is
component D_FF
port (J, K, CLK_S : in BIT; Q: out BIT);
end component D_FF;
component NAND_GATE
port (IN1, IN2 : in Bit; OUT1 : out Bit);
end component NAND_GATE;
signal S: Bit_vector(0 to 2);
signal L: Bit_vector(0 to 1);
begin
D_FF_0 : D_FF port map ('1','1',IN_1, S(0));
Gen_1 : for I in 1 to 3 generate
Gen_2 : if I = 1 or I = 2 generate
D_FF_I : D_FF port map (S(I-1),S(I-1), IN_1, L(I-1));
NAND_I : NAND_GATE port map (S(I-1),L(I-1), S(I));
Q(I) <= L(I-1);
        end generate;
Gen_3 : if I = 3 generate
D_FF_3 : D_FF port map (S(I-1),S(I-1), IN_1, Q(I) );
          end generate;
   end generate;
Q(0) <= S(0);
end STRUCT;

Nested generate statements have been used here in order to shorten the description. The outmost generate statement specifies the complete counter, which component parts are generated by the inner statements depending on the index of the component (flip-flop) inside the counter.

Important Notes

· Each generate statement must have a label.

· If the generate statement does not contain any local declarations then the reserved word begin need not to be used.

· Generate statements can be nested.

Generic

Formal Definition

An interface constant declared in the block header of a block statement, a component declaration, or an entity declaration. Generics provide a channel for static information to be communicated to a block from its environment. Unlike constants, however, the value of a generic can be supplied externally, either in a component instantiation statement or in a configuration specification.

Simplified Syntax

generic ( generic_interface_list ) ;

Description

Generics support static information to blocks in a similar way as constants, but unlike the constants the values of generics can be supplied externally. Similar to ports, they can be declared in entities and component declarations, and always before ports.

Values supported by generics declared in an entity can be read either in entity or in architecture associated with the entity. In particular, a generic can be used to specify the size of ports (example 1), the number of subcomponents within a block, the timing characteristics of a block (example 2), physical characteristics of a design, width of vectors inside an architecture, number of loop iterations, etc. In general, generic can be treated inside an architecture in the same way as constant.

Examples

Example 1

entity CPU is
  generic (BusWidth : Integer := 16);
  port(DataBus : inout Std_Logic_Vector(BusWidth-1 downto 0));
. . .

The generic value BusWidth is used here to declare the width of the port DataBus, and can be successively in all declarations of buses inside associated architecture(s). This way the user supplies only one value, which parameterizes complete design.

Example 2

entity Gen_Gates is
generic (Delay : Time := 10 ns);
port (In1, In2 : in Std_Logic;
      Output : out Std_Logic);
end Gen_Gates;
architecture Gates of Gen_Gates is
begin
  . . .
  Output <= In1 or In2 after Delay;
  . . .
end Gates;

The Delay generic value Delay specifies here the delay through a device or part of the device.

Important Notes

· In most synthesis tools only generics of type integer are supported.

Group

Formal Definition

A named collection of named entities. Groups relate different named entities for the purposes not specified by the language. In particular, groups may be decorated with attributes.

Simplified Syntax

group group_template_name is ( entity_class_list ) ;

group group_name : group_template_name ( group_constituent_list );

Description

The user-defined attributes are connected individually with each named entity. That is why each separate named entity can have its own attributes. In case when the user wants to assign information to several related named entities, he/she should define a group consisting of these units, and then specify attributes for the entire group. The set of units with the specified characteristics can be defined by means of group declaration. The group declaration in turn requires group template declaration to be defined earlier.

THE GROUP TEMPLATE DECLARATION

The group template declaration defines pattern of a group connecting named entities with the specified class. The set of possible entity classes contains entity, architecture, configuration, procedure, function, package, type, subtype, constant, signal, variable, component, label, literal, units, group, and file. Each entity class entry defines an entity class that may appear at that particular position in the group type (Example 1).

The box symbol (<>) can be used together with the name of an entity class to allow zero or more units belonging to this group (Example 2). If such a declaration appears on the list, it must be the last one.

THE GROUP DECLARATION

Group declaration connects named entities having the specified characteristics.

The group declaration consists of identifier, group template name and group constituent list. The identifier represents a group, the group template name indicates group's template declaration, and the group constituent indicates the chosen named entities belonging to this group (Example 3).

THE ATTRIBUTES OF GROUPS

The attribute specification of a group is realized in a similar way to other attribute specifications. First, the attribute of a given type is declared and it is specified for the given group in its declaration part which contains declaration of the particular group (Example 4).

Examples

Example 1

group Variable_group is ( variable, variable );

The Variable_group template group declaration creates two variables which serve as a pattern for the variables belonging to this group.

Example 2

group Component_group is ( component <> );

The Component_group pattern declaration creates a group, which consists of a component list of arbitrary length.

Example 3

group Input_pair : Variable_group ( A1, A2 );

The Input_pair group declaration creates a group, which consists of A1 and A2 variables and is based on the Variable_group group template (declared in Example 1).

Example 4

function Compute_Values (A, B:Integer) return BOOLEAN is
variable A1, A2: Integer;
group Variable_group is ( variable, variable );
group Input_pair : Variable_group ( A1, A2 );
attribute Input_name: String;
attribute Input_name of Input_pair : group is "Input variables";
begin
  .......
end function;

The value of the attribute Input_name for the group Input_pair is equal to ”Input variables”.

Important Notes

· Groups can be nested.

Guard

Formal Definition

A Boolean-valued expression associated with a block statement that controls assignments to guarded signals within a block. A guard expression defines an implicit signal GUARD that may be used to control the operation of certain statements within the block.

Simplified Syntax

some_signal_in_a_block <= guarded expression;

Description

The characteristic feature of the block statement is the guard expression. It is a logical expression of the Boolean type, declared implicitly after the reserved word block whenever a guarded expression appears inside the block (Example 1).

The guard expression implies a signal named 'guard' at the beginning of the block declaration part. This signal can be read as any other signal inside the block statement but no assignment statement cant update it. This signal is visible only within the given block. Whenever a transaction occurs on any of the signals on the right hand side of the guardexpression, the expression is evaluated and the 'guard' signal is immediately updated. The 'guard' signal takes on the TRUE value when the value of the guard expression is true. Otherwise, 'guard' takes on the FALSE value.

The 'guard' signal may also be declared explicitly as a Boolean signal in the block statement. The advantage of this approach is that more complex (than a simple Boolean expression) algorithm to control the guard signal can be used. In particular, a separate process (Example 2) can drive the guard signal.

If there is no guard expression and the guard signal is not declared explicitly, then by default the guard signal is always true.

The guard signal is used to control so called guarded concurrent signal assignment statements contained inside the block. Each such statement contains the reserved word guardplaced after the symbol "<=". They assign a new value to the signal only when the guard signal is true. Otherwise, the signal assignment statement does not change the value of the given signal. In Example 1, the signal OUT_1 will take on the value of not IN_1 only when the value of the expression CLS'EVENT and CLK='1' will be true.

Examples

Example 1

RISING_EDGE : block (CLK'EVENT and CLK='1')
begin
  OUT_1 <= guarded not IN_1 after 5 ns;
  ..................................
end block RISING_EDGE;

The assignment to the signal OUT_1 is guarded, which introduces the implicit GUARD signal into the block.

Example 2

ALU : block
signal GUARD: Boolean := False;
begin
  OUT_1 <= guarded not IN_1 after 5 ns;
  ..............................
  P_1: process
    begin
      GUARD <= True;
      ...............
    end process P_1;
end block ALU;

Signal GUARD is declared explicitly and can be assigned value like any other signal.

Important Notes

  • Guarded blocks are usually not supported for synthesis.

Sunday, 23 December 2012

Identifier

Formal Definition

Names that identify various VHDL named entities.

Syntax:

identifier ::= basic_identifier | extended_identifier

basic_identifier ::= letter { [ underline } letter_or_digit }

letter_or_digit ::= letter | digit

letter ::= upper_case_letter | lower_case_letter

extended_indentifier ::= \graphic_character { graphic_character } \

Description

Identifiers are used both as names for VHDL objects, procedures, functions, processes, design entities, etc., and as reserved words. There are two classes of identifiers: basic identifiers and extended identifiers.

The basic identifiers are used for naming all named entities in VHDL. They can be of any length, provided that the whole identifier is written in one line of code. Reserved words cannot be used as basic identifiers (see reserved words for complete list of reserved words). Underscores are significant characters in an identifier and basic identifiers may contain underscores, but it is not allowed to place an underscore as a first or last character of an identifier. Moreover, two underscores side by side are not allowed as well. Underscores are significant characters in an identifier.

The extended identifiers were included in VHDL '93 in order to make the code more compatible with tools which make use of extended identifiers. The extended identifiers are braced between two backslash characters. They may contain any graphic character (including spaces and non-ASCII characters), as well as reserved words. If a backslash is to be used as one of the graphic characters of an extended literal, it must be doubled. Upper- and lower-case letters are distinguished in extended literals.

Examples

Example 1

-- legal identifiers
Decoder_1       FFT            Sig_N      Not_Ack
\signal\        \C:\\Cads\     \Signal @#\

All above identifiers are legal in VHDL '93. Note that a single backslash inside an extended name is denoted by two backslashes.

Example 2

-- illegal identifiers
_Decoder_1     2FFT       Sig_#N       Not-Ack

No VHDL tool would accept any of the four identifiers above. The errors are as follows: underscore at the beginning of the first identifier, digit at the beginning of the second, special character (#) inside the third and hyphen (special character as well) in the fourth.

Important Notes

· A basic identifier must begin with a letter.

· No spaces are allowed in basic identifiers.

· Basic identifiers are not case sensitive, i.e. upper- and lower-case letters are considered identical.

· Basic identifiers consist of Latin letters (a..z), underscores ( _ ) and digits (0..9). It is not allowed to use any special characters here, including non-Latin (language-specific) letters.

If Statement

Definition:

The if statement is a statement that depending on the value of one or more corresponding conditions, selects for execution one or none of the enclosed sequences of statements,.

Simplified Syntax

if condition then

  sequential_statements

end if;

if condition then

  sequential_statements

else

  sequential_statements

end if;

if condition then

  sequential_statements

  elsif condition then

    sequential_statements

  else

    sequential_statements

end if;

Description

The if statement controls conditional execution of other sequential statements. It contains at least one Boolean condition (specified after the if keyword). The remaining conditions are specified with the elsif clause. The else clause is treated as elsif true then. Conditions are evaluated one by one until any of them turns to be true or there are no more conditions to be checked for. When a condition is true then the sequence of statements specified after the then clause is executed. If no condition is met then the control is passed to the next statement after the if statement.

The if statement can be used in a simplified form, often called if-then statement, where neither elsif nor else clause is supported (example 1).

In case when meeting a condition should cause some statements to be executed, but when it is not met some other actions should be performed, the else clause is used (example 2).

The elsif clause is used when different nested conditions have to be checked (example 3). This can be used for prioritizing conditions and signals.

The if statements can be nested (example 4).

Examples

Example 1

I1: if Status_Signal = hold
      then A1: Outputs <= 'X';
    end if I1;

The assignment will be realized only when the condition Status_Signal = hold is true. Otherwise, the statement that follows the end if I1 will be executed.

Example 2

function AND_FUNC (x, y: in Bit) return Bit is
begin
  I2: if x = '1' and y = '1'
        then return '1';
      else return '0';
      end if I2;
end AND_FUNC;

When the variables x and y are both equal to '1', then the function returns the value '1'. Otherwise, '0' is returned.

Example 3

Signal Code_of_Operation : Bit_Vector(1 downto 0);
I3: if Code_of_Operation(1) = '1'
      then F := Operand_1 + Operand_2;
    elsif Code_of_Operation(0) = '1'
      then F := Operand_1 - Operand_2;
      else F := "00000000";
    end if I3;

In this example, the bit number 1 of the Code_of_Operation has a higher priority than bit number 0. When the bit number 1 has a '1'value, then the two operands are added. If not (i.e. it is '0'), then the bit number 0 is checked. If it is '1', then the two operands are subtracted. Otherwise, when both bits of the Code_of_Operation are '0', the F signal is assigned all zeros.

Example 4

if Status = RUN
  then
    if Code_of_Operation = CONC
      then
        F := Operand_1 & Operand_2 ;
      else
        F := "00000000";
    end if;
  Output_1 <= F;
end if;

Nesting of if statements is legal, but you should be careful not to confuse the statement levels.

Important Notes

· One of the most typical errors with the if statements is to skip the space between end and if, at the end of the statement, and writing it as endif.

· If is a sequential statement that cannot be used in the concurrent statements section of an architecture. If assigning a new value to a signal must be influenced by a specific condition, then a conditional signal assignment should be used (which in turn cannot be used inside processes and procedures).

Integer Type

Definition:

The integer type is a scalar whose set of values includes integer numbers of the specified range.

Simplified Syntax

type type_name is integer_left_bound to integer_right_bound;

type type_name is integer_left_bound downto integer_right_bound;

Description

An integer type is a numeric type which consists of integer numbers within the specified range. There is a predefined INTEGER type, which range depends on the implementation, however, must cover at least the range -2147483648 to +2147483647.

A user-defined integer type can be constructed on the basis of the predefined INTEGER type by constraining its range (example 1). The bounds of the range of a user-defined integer type should be in the form of a locally static expression. (In VHDL an expression is said to be locally static if it can be evaluated at compile time.) The value of an expression used as a range for an integer type must also be of integer type, not necessarily the same for both bounds (example 2). Negative bounds are allowed.

All integer types (including user-defined) have the same set of arithmetic operators, defined in the package STANDARD, namely: addition, subtraction, multiplication, division, modulus, and remainder. In all cases both operands and the result are of the integer type.

Besides arithmetic operations, relations can also be checked on such integer operands as: equal, unequal, greater than, less than, greater or equal than, and less or equal than. In all cases, the result is Boolean.

Examples

Example 1

type Voltage_Level is range 0 to 5;
type Int_64K is range -65536 to 65535;
type WORD is range 31 downto 0;

An integer type can be defined either as an ascending or descending range.

Example 2

type MUX_ADDRESS is range (2**(N+1))- 1 downto 0;

The parameter N must have an explicitly stated value (e.g. as a constant).

Important Notes

· It is an error to assign to an integer object a value which is from outside its range.