|
VHDL Tutorial |
Loop and exit statements in VHDL | ||
|
Introduction Fundamental concepts Modelling concepts Elements of behaviour Elements of structure Analysis elaboration Lexical elements Identifiers Numbers Characters and strings Syntax descriptions Constants and variables Scalar type Integer types Floating point types Time type Enumeration types Character types Boolean type Bits type Standard logic Sequential statements Case statements Loop and exit statements Assertion statements Array types & array operations Architecture bodies Entity declarations Behavioral descriptions Wait statements Delta delays Process statements Conditional signal assignment Selected signal assigment Structural descriptions Library and library clauses Procedures Procedure parameters Signal parameters Default values Unconstrained array parameter Functions Package declarations and bodies Subprograms in package Use clauses Resolved signals and subtypes Resolved signals and ports Parameterizing behavior Parameterizing structure |
Loop and Exit Statements
Often we need to write a sequence of statements that is to be repeatedly executed. We use a loop statement to express this behavior. The syntax rule for a simple loop that iterates indefinitely is
loop_statement ⇐ [ loop_label : ] loop { sequential_statement } end loop [ loop_label ] ;
Usually we need to exit the loop when some condition arises. We can use an exit statement to exit a loop. The syntax rule is
exit_statement ⇐ [ label : ] exit [ loop_label ] [ when boolean_expression ] ;
The simplest form of exit statement is just
exit;
When this statement is executed, any remaining statements in the loop are skipped, and control is transferred to the statement after the end loop keywords. So in a loop we can write
if condition then exit; end if;
where condition is a Boolean expression. Since this is perhaps the most common use of the exit statement, VHDL provides a shorthand way of writing it, using the when clause. We use an exit statement with the when clause in a loop of the form
loop
exit when condition;
end loop; control transferred to here when condition becomes true within the loop
Want To have highly paid VLSI jobs ?? then you may contact at
Contact : webmaster@freehost7com
Figure 3-5 is a model for a counter that starts from zero and increments on each clock transition from 0 to 1. When the counter reaches 15, it wraps back to zero on the next clock transition. The counter has an asynchronous reset input that, when 1, causes the count output to be reset to zero. The output stays at zero as long as the reset input is 1 and resumes counting on the next clock tran- sition after reset changes to 0.
entity counter is port ( clk, reset : in bit; count : out natural ); end entity counter; architecture behavior of counter is begin incrementer : process is variable count_value : natural := 0; begin count <= count_value; loop loop wait until clk = '1' or reset = '1'; exit when reset = '1'; count_value := (count_value + 1) mod 16; count <= count_value; end loop; at this point, reset = '1' count_value := 0; count <= count_value; wait until reset = '0'; end loop; end process incrementer;
An entity and architecture body of the revised counter, including a reset input.
The architecture body contains two nested loops. The inner loop deals with normal counting operation. When reset changes to 1, the exit statement causes the inner loop to be terminated. Control is transferred to the statement just after the end of the inner loop. The count value and count outputs are reset, and the process then waits for reset to return to 0, after which the process resumes and
In some cases, we may wish to transfer control out of an inner loop and also a containing loop. We can do this by labeling the outer loop and using the label in the exit statement. We can write
loop_name : loop
exit loop_name;
end loop loop_name ;
This labels the loop with the name loop_name, so that we can indicate which loop to exit in the exit statement. The loop label can be any valid identifier. The exit state- ment referring to this label can be located within nested loop statements. While Loops
We can augment the basic loop statement introduced previously to form a while loop, which tests a condition before each iteration. If the condition is true, iteration pro- ceeds. If it is false, the loop is terminated. The syntax rule for a while loop is
loop_statement ⇐ [ loop_label : ] while boolean_expression loop { sequential_statement } end loop [ loop_label ] ;
The only difference between this form and the basic loop statement is that we have added the keyword while and the condition before the loop keyword. All of the things we said about the basic loop statement also apply to a while loop. The con- dition is tested before each iteration of the while loop, including the first iteration. This means that if the condition is false before we start the loop, it is terminated im- mediately, with no iterations being executed.
We can develop a model for an entity cos that calculates the cosine function of an input theta using the relation
We add successive terms of the series until the terms become smaller than one millionth of the result. The entity and architecture body declarations are shown in Figure 3-6. The cosine function is computed using a while loop that incre- ments n by two and uses it to calculate the next term based on the previous term. Iteration proceeds as long as the last term computed is larger in magnitude than one millionth of the sum. When the last term falls below this threshold, the while loop is terminated.
entity cos is port ( theta : in real; result : out real ); end entity cos; architecture series of cos is begin 31
summation : process (theta) is variable sum, term : real; variable n : natural; begin sum := 1.0; term := 1.0; n := 0; while abs term > abs (sum / 1.0E6) loop n := n + 2; term := (term) * theta**2 / real(((n1) * n)); sum := sum + term; end loop; result <= sum; end process summation; end architecture series; For Loops
Another way we can augment the basic loop statement is the for loop. A for loop includes a specification of how many times the body of the loop is to be executed. The syntax rule for a for loop is
loop_statement ⇐ [ loop_label : ] for identifier in discrete_range loop { sequential_statement } end loop [ loop_label ] ;
A discrete range can be of the form
simple_expression ( to I downto ) simple_expression
representing all the values between the left and right bounds, inclusive. The identifier is called the loop parameter, and for each iteration of the loop, it takes on successive values of the discrete range, starting from the left element. For example, in this for loop:
for count_value in 0 to 127 loop count_out <= count_value; wait for 5 ns; end loop;
the identifier count_value takes on the values 0, 1, 2 and so on, and for each value, the assignment and wait statements are executed. Thus the signal count_out will be assigned values 0, 1, 2 and so on, up to 127, at 5 ns intervals. Within the sequence of statements in the for loop body, the loop parameter is a constant. This means we can use its value by including it in an expression, but we cannot make assignments to it. Unlike other constants, we do not need to declare it. Instead, the loop parameter is implicitly declared over the for loop. It only exists when the loop is executing, and not before or after it. Like basic loop statements, for loops can enclose arbitrary sequential statements, including exit statements, and we can label a for loop by writing the label before the for keyword.
We now rewrite the cosine model in Figure 3-6 to calculate the result by sum- ming the first 10 terms of the series with a for loop. The entity declaration is un- changed. The revised architecture body is shown in Figure 3-7.
architecture fixed_length_series of cos is begin summation : process (theta) is variable sum, term : real; begin sum := 1.0; term := 1.0; for n in 1 to 9 loop term := (term) * theta**2 / real(((2*n1) * 2*n)); sum := sum + term; end loop; result <= sum; end process summation; end architecture fixed_length_series;
|