Sequential Statements in VHDL

A set of VHDL statements that executes in sequence is called sequential statements in VHDL.

Sequential Statements in VHDL

The syntax of a sequential signal assignment is identical to that of the simple concurrent signal assignment except that the former is inside a process.

Syntax

signal-name <= value-expression;

  • Note that the concurrent conditional and selected signal assignment statements cannot be used inside the process.
  • For a signal assignment with delay, the behavior of a sequential signal assignment statement is somewhat different from that of its concurrent counterpart.
  • If a process has a sensitivity list, the execution of sequential statements is treated as a “single abstract evaluation,” and the actual value of an expression will not be assigned to a signal until the end of the process.
  • Inside a process, a signal can be assigned multiple times. If all assignments are with & delays, only the last assignment takes effect. Because the signal is not updated until the end of the process, it never assumes any “intermediate” value.

Example

a,b,c,d,y: std-logic;

process (a, b, c, d)

begin

. . .

y <= a and c;

y <= a xor b;

y <= c or d;

end process;

— It is the same as

process(a,b,c,d)

begin

y <= c or d;

end process;

  • It is a good idea to avoid assigning a signal multiple times, if there is no strong reason. The only exception is the assignment of a default value in the if and case statements.
  • In above example, the result will be very different if the multiple assignments are the concurrent signal assignment statements.

The sequential statements in VHDL discussed in this article are:

  • IF
  • CASE
  • LOOP
  • EXIT
  • ASSERT
  • WAIT
  • Null

If Statement

An if statement selects a sequence of statements for execution based on the value of a condition. The condition can be any expression that evaluates to a boolean value.

Syntax

if boolean-expr-1 then

sequential-statements;

elsif boolean-expr-2 then

sequential-statements;

elsif boolean-expr-3 then

— sequential-statements;

else

sequential-statements;

end if ;

sequential-statements;

When an expression is evaluated as true, the statements in the corresponding branch will be executed and the remaining branches will be skipped. If none of the expressions is true and the else branch exists, the statements in the else branch will be executed.

The if statement description of an 4-to-1 multiplexer is shown in following example. Since the multiplexer is a combinational circuit, all input signals, including D and S are in the sensitivity list.

Note that the signals used in the Boolean expressions are also the input signals.

library IEEE;

use IEEE.STD_LOGIC_1164.all;

entity MUX41 is

port(D : in STD_LOGIC_VECTOR(3 downto 0);

S : in STD_LOGIC_VECTOR(1 downto 0);

Y : out STD_LOGIC);

end MUX41;

architecture behavioral of multiplexer_4_1 is

begin

process (D,S)

begin

if (S=”00″) then

Y <= D(3);

elsif (S=”01″) then

Y <= D(2);

elsif (S=”10″) then

Y <= D(1);

else

Y <= D(0);

 end if;

end process;

end behavioral;

Case Statement

Syntax

case expression is

when choices => sequential-statements — branch #1

when choices => sequential-statements — branch #2

— Can have any number of branches.

[ when others => sequential-statements ] — last branch

end case;

The case statement selects one of the branches for execution based on the value of the expression.

The expression value must be of a discrete type or of a one-dimensional array type. Choices may be expressed as single values, as a range of values, by using | (vertical bar: represents an “or”), or by using the others clause.

All possible values of the expression must be covered in the case statement. “The others clause can be used as a choice to cover the “catch-all” values and, if present, must be the last branch in the case statement.

The case statement is also a sequential statement and it is, therefore, possible to have nested case statements. A model for a 4:1 multiplexer using a case statement is shown next.

entity MUX is

port (A, B, C, D: in BIT;

Sel: in BIT_VECTOR(0 to 1);

Z: out BIT);

end MUX;

architecture MUX_BEHAVIOR of MUX is

constant MUX_DELAY: TIME := 10 ns;

begin

process (A, B, C, D, Sel)

variable TEMP: BIT;

begin

case Sel is

when “00” => TEMP := A:

when “01” => TEMP := B;

when “10” => TEMP := C;

when “11” => TEMP := D;

end case;

Z <= TEMP after MUX_DELAY;

end process;

end MUX_BEHAVIOR;

Loop Statement

A loop statement is used to iterate through a set of sequential statements.

Syntax

[ loop-label : ] iteration-scheme loop

sequential-statements

end loop [ loop-label ] ;

There are three types of iteration schemes.

The first is the for iteration scheme that has the form

for identifier in range

Example:

FACTORIAL := 1;

for NUMBER in 2 to N loop

FACTORIAL := FACTORIAL * NUMBER;

end loop;

  • The body of the for loop is executed (N-1) times, with the loop identifier, NUMBER, being incremented by 1 at the end of each iteration. The object NUMBER is implicitly declared within the for loop to belong to the integer type whose values are in the range 2 to N.
  • No explicit declaration for the loop identifier is, therefore, necessary. The loop identifier, also, cannot be assigned any value inside the for loop.
  • If another variable with the same name exists outside the for loop, these two variables are treated separately and the variable used inside the for loop refers to the loop identifier.

The second form of the iteration scheme is the while scheme that has the form

while boolean-expression;

Example:

a:=1;

var:=5;

Loop_wh: while a < 10 loop — This loop has a label, loop_wh.

var := var * 2;

a:=a+2;

end loop;

  • The statements within the body of the loop are executed sequentially and repeatedly as long as the loop condition, a < 10, is true. At this point, execution continues with the statement following the loop statement.

The third form of the iteration scheme is one where no iteration scheme is specified. In this form of loop statement, all statements in the loop body are repeatedly executed until some other action causes it to exit the loop.

These actions can be caused by an exit statement, a next statement, or a return statement.

Example

SUM:=1;

J:=0;

L3: loop — This loop also has a label.

J:=J+21;

SUM := SUM* 10;

exit when SUM > 50;

end loop L3; — This loop label, if present, must be the same as the initial loop label.

In this example, the exit statement causes the execution to jump out of loop L3 when SUM becomes greater than 50. If the exit statement were not present, the loop would execute indefinitely.

Exit Statement

The exit statement is a sequential statement that can be used only inside a loop. It causes execution to jump out of the innermost loop or the loop whose label is specified.

Syntax

exit [ loop-label] [ when condition ];

OR

If condition then exit[ loop-label];

If no loop label is specified, the innermost loop is exited. If the when clause is used, the specified loop is exited only if the given condition is true, otherwise, execution continues with the next statement.

An alternate form for loop L2 described in the previous section is

SUM := 1;

J := 0;

L3: loop

J:=J+21;

SUM := SUM* 10;

if (SUM > 50) then

exit L3; — “exit;” also would have been sufficient.

end if;

end loop L3;

Assert Statement

  • The ASSERT statement is a very useful statement for reporting textual strings to the designer. The ASSERT statement checks the value of a boolean expression for true or false.
  • If the value is true, the statement does nothing. If the value is false, the ASSERT statement outputs a user specified text string to the standard output to the terminal.
  • The designer can also specify a severity level with which to output the text string. The four levels are, in increasing level of severity, note, warning, error, and failure. The severity level gives the designer the ability to classify messages into proper categories.
  • The ASSERT statement is currently ignored by synthesis tools. Because the ASSERT statement is used mainly for exception handling while writing a model, no hardware is built.

Syntax

assert_statement ::=

ASSERT condition

[REPORT expression]

[SEVERITY expression];

  • The keyword ASSERT is followed by a boolean-valued expression called a condition. The condition determines whether the text expression specified by the REPORT clause is output or not.

 If false, the text expression is output;

 if true, the text expression is not output.

  • There are two optional clauses in the ASSERT statement. The first is the REPORT clause. The REPORT clause gives the designer the ability to specify the value of a text expression to output.
  • The second is the SEVERITY clause. The SEVERITY clause allows the designer to specify the severity level of the ASSERT statement.
  • If the REPORT clause is not specified, the default value for the ASSERT statement is assertion violation. If the SEVERITY clause is not specified, the default value is error.

Example

PROCESS(clk, din)

VARIABLE last_d_change : TIME := 0 ns;

VARIABLE last_d_value : std_logic := ‘X’;

VARIABLE last_clk_value : std_logic := ‘X’;

BEGIN

IF (last_d_value /= din) THEN — /= is

last_d_change := NOW; — not equal

last_d_value := din;

END IF;

IF (last_clk_value /= clk) THEN

last_clk_value := clk;

IF (clk = ‘1’) THEN

ASSERT (NOW – last_d_change >= 20 ns)

REPORT “setup violation”

SEVERITY WARNING;

END IF;

END IF;

END PROCESS;

The example performs a data setup check between two signals that control a D flip-flop.

Most flip-flops require the din (data) input to be at a stable value a certain amount of time before a clock edge appears. This time is called the setup time and guarantees that the din value will be clocked into the flip-flop if the setup time is met.

Wait Statement

The wait statement can also be used to suspend a process. It can be used to wait for a certain amount of time or to wait until a certain condition becomes true, or to wait until an event occurs on one or more signals.

There are three basic forms of the wait statement

wait on sensitivity clause;

wait until condition;

wait for time_out expression;

we can use statements like

wait on clock;

wait until clock=’1’;

wait for 20 ns;

Here is an example of a process statement that generates a clock with a different on-off period. Figure shows the generated waveform.

process

begin

CLK <= ‘0’ ;

wait for 20 ns;

CLK <= ‘1’ ;

wait for 12 ns;

end process;

VHDL code for clock pulse
  • This process does not have a sensitivity list since explicit wait statements are present inside the process. It is important to remember that a process never terminates. It is always either being executed or in a suspended state.
  • All processes are executed once during the initialization phase of simulation until they get suspended. Therefore, a process with no sensitivity list and with no explicit wait statements will never suspend itself.
  • A signal can represent not only a wire but also a place holder for a value, that is, it can be used to model a flip-flop. Here is such an example.

Null Statement

The statement

null;

is a sequential statement that does not cause any action to take place and execution continues with the next statement.

One example of this statement’s use is in an if statement or in a case statement where for certain conditions, it may be useful or necessary to explicitly specify that no action needs to be performed.

Recent posts

2 thoughts on “Sequential Statements in VHDL”

Comments are closed.