Wednesday, August 5, 2015

Behavioral Modeling

BEHAVIORAL MODELING

In this modeling style, the behavior of the entity is expressed using sequentially executed, procedural type code, that is very similar in syntax and. semantics to that of a high-level programming language like C or Pascal. A process statement is the primary mechanism used to model the procedural type behavior of an entity.

Irrespective of the modeling style used, every entity is represented using an entity declaration and at least one architecture body.

Entity Declaration

An entity declaration describes the external interface of the entity, that is, it gives the black-box view. It specifies the name of the entity, the names of interface ports, their mode (i.e., direction), and the type of ports. The syntax for an entity declaration is

entity entity-name is
[ generic ( list-of-generics-and-their-types ) ; ]
[ port ( list-of-interface-port-names-and-their-types) ; ]
[ entity-item-declarations ]
[ begin
entity-statements ]
end [ entity-name ];

The entity-name is the name of the entity and the interface ports are the signals through which the entity passes information to and from its external environment.

Each interface port can have one of the following modes:

1.   in: the value of an input port can only be read within the entity model.

2.   out: the value of an output port can only be updated within the entity model; it cannot be read.

3.   inout: the value of a bidirectional port can be read and updated within the entity model.

4.   buffer: the value of a buffer port can be read and updated within the entity model. However, it differs from the inout mode in that it cannot have more than one source and that the only kind of signal that can be connected to it can be another buffer port or a signal with at most one source.

Declarations that are placed in the entity-item-declarations section are common to all the design units that are associated with that entity declaration (these may be architecture bodies and configuration declarations).

Eg., An And-Or-Invert circuit.

entity AOI is
port (A, B, C, D: in BIT; Z: out BIT);
end AOI;

The entity declaration specifies that the name of the entity is AOI and that it has four input signals of type BIT and one output signal of type BIT.

Note: it does not specify the composition or functionality of the entity.

Figure 15: An AND-OR-INVERT Circuit

Architecture Body

An architecture body describes the internal view of an entity, which describes the functionality or the structure of the entity.

The syntax of an architecture body is

architecture architecture-name of entity-name is
[ architecture-item-declarations ]
begin
concurrent-statements; these are —>
process-statement
block-statement
concurrent-procedure-call
concurrent-assertion-statement
concurrent-signal-assignment-statement
component-instantiation-statement
generate-statement
end [ architecture-name ] ;

The concurrent statements describe the internal composition of the entity.

All concurrent statements execute in parallel, and therefore, their textual order of appearance within the architecture body has no impact on the implied behavior.

The internal composition of an entity can be expressed in terms of structure, dataflow and sequential behavior. These are described using concurrent statements.

Eg., component instantiations are used to express structure, concurrent signal assignment statements are used to express dataflow and process statements are used to express sequential behavior.

Each concurrent statement is a different element operating in parallel in a similar sense that individual gates of a design are operating in parallel.
The item declarations declare items that are available for use within the architecture body. The names of items declared in the entity declaration, including ports and generics, are available for use within the architecture body
due to the association of the entity name with the architecture body by the statement

architecture architecture-name of entity-name is . . .

An entity can have many internal views, each of which is described using a separate architecture body.

In general, an entity is represented using one entity declaration (that provides the external view) and one or more architecture bodies (that provide die internal view).

Eg.,
architecture AOI_CONCURRENT of AOI is
begin
Z <= not ( (A and B) or (C and D) );
end AOI_CONCURRENT;

architecture AOI_SEQUENTIAL of AOI is
begin
process (A, B, C, D)
variable TEMPI ,TEMP2: BIT;
begin
TEMP1 := A and B; -- statement 1
TEMP2:=C and D; --statement 2
TEMP1 := TEMP1 or TEMP2; -- statement 3
Z<= not TEMP1; --statement 4
end process;
end AOI_SEQUENTIAL;

The first architecture body, AOI_CONCURRENT, describes the AOI entity using the dataflow style of modeling; the second architecture body, AOI_SEQUENTIAL, uses the behavioral style of modeling.

A process statement, which is a concurrent statement, is the primary mechanism used to describe the functionality of an entity in this modeling style.

Process Statement

A process statement contains sequential statements that describe the functionality of a portion of an entity in sequential terms.

The syntax of a process statement is

[ process-label: ] process [ ( sensitivity-list ) ]
[process-item-declarations]
begin
sequential-statements; these are ->
variable-assignment-statement
signal-assignment-statement
wait-statement
if-statement
case-statement
loop-statement
null-statement
exit-statement
next-statement
assertion-statement
procedure-call-statement
return-statement.
end process [ process-label];

A set of signals that the process is sensitive to is defined by the sensitivity list, i.e., each time an event occurs on any of the signals in the sensitivity list, the sequential statements within the process are executed in a sequential order, i.e., in the order in which they appear (similar to statements in a high-level programming language like C or Pascal).

The process then suspends after executing the last sequential statement and waits for another event to occur on a signal in the sensitivity list.

Items declared in the item declarations part are available for use only within the process.

The architecture body, AOI_SEQUENTIAL, contains one process statement, that has four signals in its sensitivity list and has one variable declaration. If an event occurs on any of the signals, A, B, C, or D, the process is executed. This is accomplished by executing statement I first, then statement 2, followed by statement 3, and then statement 4. After this, the process suspends (simulation does not stop, however) and waits for another event to occur on a signal in the sensitivity list.

Variable Assignment Statement

Variables can be declared and used inside a process statement.

A variable is assigned a value using the variable assignment statement that typically has the form

variable-object := expression;

The expression is evaluated when the statement is executed and the computed value is assigned to the variable object instantaneously, i.e., at the current simulation time.

Variables are created at the time of elaboration and retain their values throughout the entire simulation run, as a process is never exited; it is either in an active state, that is, being executed, or in a suspended state, i.e., waiting for a certain event to occur.

A process is first entered at the start of simulation (actually, during the initialization phase of simulation) at which time it is executed until it suspends because of a wait statement or a sensitivity list.

Eg.,

process (A)
variable EVENTS_ON_A: INTEGER := 0;
begin
EVENTS_ON_A := EVENTS_ON_A+1;
end process;

At start of simulation, the process is executed once. The variable EVENTS_ON_A gets initialized to 0 and then incremented by 1. After that, any time an event occurs on signal A, the process is activated and the single variable assignment statement is executed. This causes the variable EVENTS_ON_A to be incremented. At the end of simulation, variable EVENTS_ON_A contains the total number of events that occurred on signal A plus one.

Eg.,

signal A, Z: INTEGER;
. . .
PZ: process (A) --PZ is a label for the process.
variable V1, V2: INTEGER;
begin
V1 := A - V2; --statement 1
Z <= - V1; --statement 2
V2 := Z+V1 * 2; -- statement 3
end process PZ;

If an event occurred on signal A at time T1 and variable V2 was assigned a value, say 10, in statement 3, then when the next time an event occurs on signal A, say at time T2, the value of V2 used in statement 1 would still be 10.

Signal Assignment Statement

Signals are assigned values using a signal assignment statement

The simplest form of a signal assignment statement is

signal-object <= expression [ after delay-value ];

A signal assignment statement can appear within a process or outside of a process. If it occurs outside of a process, it is considered to be a concurrent signal assignment statement. When a signal assignment statement appears within a process, it is considered to be a sequential signal assignment statement and is executed in sequence with respect to the other sequential statements that appear within that process.

When a signal assignment statement is executed, the value of the expression is computed and this value is scheduled to be assigned to the signal after the specified delay.

Note: The expression is evaluated at the time the statement is executed (which is the current simulation time) and not after the specified delay. If no after clause is specified, the delay is assumed to be a default delta delay.

Eg.,

COUNTER <= COUNTER+ "0010"; - Assign after a delta delay.
PAR <= PAR xor DIN after 12 ns;
Z <= (AO and A1) or (BO and B1) or (CO and C1) after 6 ns;

Delta Delay

A delta delay is a very small delay (infinitesimally small), which does not correspond to any real delay and actual simulation time does not advance. It models hardware where a minimal amount of time is needed for a change to occur, eg., in performing zero delay simulation.

Delta delay allows for ordering of events that occur at the same simulation time during a simulation. Each unit of simulation time can be considered to be composed of an infinite number of delta delays. Therefore, an event always occurs at a real simulation time plus an integral multiple of delta delays.

Eg., events can occur at 15 ns, 15 ns+1Δ, 15 ns+2Δ, 15 ns+3Δ, 22 ns, 22 ns+Δ, 27 ns, 27ns+Δ, and so on.

Consider the AOI_SEQUENTIAL architecture body, assume that an event occurs on input signal D (i.e., there is a change of value on signal D) at simulation time T. Statement I is executed first and TEMPI is assigned a value immediately since it is a variable. Statement 2 is executed next and TEMP2 is assigned a value immediately. Statement 3 is executed next which uses the values of TEMPI and TEMP2 computed in statements I and 2, respectively, to determine the new value for TEMPI. And finally, statement 4 is executed that causes signal Z to get the value of its right-hand-side expression after a delta delay, that is, signal Z gets its value only at time T+A; as shown in Fig. 16.


Figure 16: Delta Delay

Consider the process PZ, if an event occurs on signal A at time T, execution of statement I causes VI to get a value, signal Z is then scheduled to get a value at time T+A, and finally statement 3 is executed in which the old value of signal Z is used, that is, its value at time T, not the value that was scheduled to be assigned in statement 2. The reason for this is because simulation time is still at time T and has not advanced to time T+A.

Later when simulation time advances to T+A, signal Z will get its new value.

Note: Variable assignments cause variables to get their values instantaneously while signal assignments cause signals to get their values at a later time (at least a delta delay later).

Wait Statement

A process may be suspended by means of a sensitivity list, i.e., when a process has a sensitivity list, it always suspends after executing the last sequential statement in the process.

The wait statement provides an alternate way to suspend the execution of a process. There are three basic forms of the wait statement.
wait on sensitivity-list;
wait until boolean-expression ;
wait for time-expression ;
They may also be combined in a single wait statement.

wait on sensitivity-list until boolean-expression for time-expression-,

Eg.,
wait on A, B, C; -- statement 1
wait until (A = B); -- statement 2
wait for 10ns; -- statement 3
wait on CLOCK for 20ns; -- statement 4
wait until (SUM > 100) for 50 ms; -- statement 5

In statement 1, the execution of the wait statement causes the process to suspend and then it waits for an event to occur on signals A, B, or C. Once that happens, the process resumes execution from the next statement onwards.

In statement 2, the process is suspended until the specified condition becomes true. When an event occurs on signal A or B, the condition is evaluated and if it is true, the process resumes execution from the next statement onwards, otherwise, it suspends again.

When the wait statement in statement 3 is executed, say at time T, the process suspends for 10 ns and when simulation time advances to T+10 ns, the process resumes execution from the statement following the wait statement.

The execution of statement 4 causes the process to suspend and then it waits for an event to occur on the signal CLOCK for 20 ns. If no event occurs within 20 ns, the process resumes execution with the statement following the wait. In the last statement, the process suspends for a maximum of 50 ms until the value of signal SUM is greater than 100. The boolean condition is evaluated every time there is an event on signal SUM. If the boolean condition is not satisfied for 50 ms, the process resumes from the statement following the wait statement.

If a process not to have an explicit sensitivity list, then the process may have one or more wait statements.

A process must have at least one wait statement, otherwise, the process will never get suspended and would remain in an infinite loop during the initialization phase of simulation.

It is an error if both the sensitivity list and a wait statement are present within a process. The presence of a sensitivity list in a process implies the presence of an implicit "wait on sensitivity-list" statement as the last statement in the process.

An equivalent process statement for the process statement in the AOLSEQUENTIAL architecture body is

process -- No sensitivity list.
variable TEMP1 ,TEMP2: BIT;
begin
TEMP1 :=A and B:
TEMP2 := C and D;
TEMP1 := TEMP1 or TEMP2;
Z<= not TEMP1;
wait on A, B, C, D; -- Replaces the sensitivity list.
end process;

Therefore, a process with a sensitivity list always suspends at the end of the process and when reactivated due to an event, resumes execution from the first statement in the process.

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-expressionthen
sequential-statements
[ elsif boolean-expression then -- elsif clause; if stmt can have 0 or
sequential-statements ] -- more elsif clauses.
[ else -- else clause.
sequential-statements ]
end if;

The if statement is executed by checking each condition sequentially until the first true condition is found; then, the set of sequential statements associated with this condition is executed. The if statement can have zero or more elsif clauses and an optional else clause.

An if statement is also a sequential statement, and therefore, the previous syntax allows for arbitrary nesting of if statements.

Eg.,

if SUM <= 100 then -- This is a less-than-or-equal-to operator.
SUM := SUM+10;
end if;
if NICKEL_IN then
DEPOSITED <=TOTAL_10; --This"<=" is a signal assignment operator.
elsif DIME_IN then
DEPOSITED <= TOTAL_15;
elsif QUARTERJN then
DEPOSITED <= TOTAL_30;
else
DEPOSITED <= TOTAL_ERROR;
end if;

if CTRLI = '1' then
if CTRL2 = '0' then
MUX_OUT<= "0010";
else
MUX_OUT<= "0001";
end if;
else if CTRL2 = '0' then
MUX_OUT <= "1000";
else
MUX_OUT <= "0100";
end if;
end if;

Eg., a 2-input nor gate using an if statement

entity NOR2 is
port (A, B: in BIT; Z: out BIT);
end NOR2;

architecture NOR2 of NOR2 is -- Architecture body can have
-- same name as entity.
begin
PI: process (A, B)
constant RISE_TIME: TIME := 10 ns;
constant FALL_TIME: TIME := 5 ns:
variable TEMP: BIT;
begin
TEMP := A nor B;
if (TEMP = '1 ') then
Z <= TEMP after RISE_TIME;
else
Z <= TEMP after FALLJIME;
end if;
end process PI;
end NOR2;
Case Statement

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.

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;

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.

Eg.,

type WEEK_DAY is (MON, TUE, WED, THU, FRI, SAT, SUN);
type DOLLARS is range 0 to 10;
variable DAY: WEEK_DAY;
variable POCKET_MONEY: DOLLARS;
case DAY is
when TUE => POCKET_MONEY := 6; -- branch 1
when MON I WED => POCKET_MONEY := 2; -- branch 2
when FRI to SUN => POCKET_MONEY := 7; -- branch 3
when others => POCKET_MONEY := 0; -- branch 4
end case;

Branch 2 is chosen if DAY has the value of either MON or WED. Branch 3 covers the values FRI, SAT, and SUN, while branch 4 covers the remaining value, THU. The case statement is also a sequential statement and it is, therefore, possible to have nested case statements.

Eg., a 4*1 multiplexer using case statement

entity MUX is
port (A, B, C, D: in BIT; CTRL: in BIT_VECTOR(0 to 1);
Z: out BIT);
end MUX;

architecture MUX_BEHAVIOR of MUX is
constant MUX_DELAY: TIME := 10 ns;
begin
PMUX: process (A, B, C, D, CTRL)
Variable TEMP: BIT;
begin
case CTRL 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 PMUX;
end MUX_BEHAVIOR;

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.

Eg., it can be used 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.

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.

1.   The first is the for iteration scheme that has the form

for identifier in range

Eg.,

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 I 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 range in a for loop can also be a range of an enumeration type such as

type HEXA is ('0', '1', '2', '3', '4', ' 5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F'):
. . .
for NUM in HEXA'('9') downto HEXA'('0') loop
-- NUM will take values in type HEXA from '9' through '0'.
. . .
end loop;
for CHAR in HEXA loop
-- CHAR will take all values in type HEXA from '0' through 'F'.
. . .
end loop;

Note: It is necessary to qualify the values being used for NUM [e.g., HEXA'('9')] since the literals '0' through '9' are overloaded, once being defined in type HEXA and the second time being defined in the predefined type CHARACTER.

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

while boolean-expression
Eg.,

J:=0;SUM:=10;
WH-LOOP: while J < 20 loop - This loop has a label, WH_LOOP.
SUM := SUM * 2;
J:=J+3;
end loop;

The statements within the body of the loop are executed sequentially and repeatedly as long as the loop condition, J < 20, is true. At this point, execution continues with the statement following the loop statement.
3.   The third and final 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.

Eg.,
SUM:=1;J:=0;
L2: loop -- This loop also has a label.
J:=J+21;
SUM := SUM* 10;
exit when SUM > 100;
end loop L2; -- This loop label, if present, must be the same
-- as the initial loop label.

=> The exit statement causes the execution to jump out of loop L2 when SUM becomes greater than 100.

If the exit statement were not present, the loop would execute indefinitely.

Exit Statement

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

Syntax:

exit [ loop-label] [ when condition ];

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.

Eg.,
SUM := 1; J := 0;
L3: loop
J:=J+21;
SUM := SUM* 10;
if (SUM > 100) then
exit L3; -- "exit;" also would have been sufficient.
end if;
end loop L3;

Next Statement

It is also a sequential statement that can be used only inside a loop. The syntax is the same as that for the exit statement except that the keyword next replaces the keyword exit.

Syntax:

next [ loop-label] [ when condition ];

The next statement results in skipping the remaining statements in the current iteration of the specified loop and execution resumes with the first statement in the next iteration of this loop.

If no loop label is specified, the innermost loop is assumed.

In contrast to the exit statement that causes the loop to be terminated (i.e., exits the specified loop), the next statement causes the current loop iteration of the specified loop to be prematurely terminated and execution resumes with the next iteration.

Eg.,

for J in 10 downto 5 loop
if (SUM < TOTAL_SUM) then
SUM := SUM +2;
elsif (SUM = TOTAL_SUM) then
next;
else
null;
end if;
K:=K+1;
end loop;

When the next statement is executed, execution jumps to the end of the loop (the last statement, K := K+1, is not executed), decrements the value of the loop identifier, J, and resumes loop execution with this new value of J.

The next statement can also cause an inner loop to be exited.

Eg.,

L4: for K in 10 downto 1 loop
--statements section 1
L5: loop
-- statements section 2
next L4 when WR_DONE = '1';
-- statements section 3
end loop L5;
-- statements section 4
end loop L4;

When WR_DONE = 1' becomes true, statements sections 3 and 4 are skipped and execution jumps to the beginning of the next iteration of loop L4.

Note: The loop L5 was terminated because of the result of next statement.

Assertion Statement

Assertion statements are useful in modeling constraints of an entity.
Eg., to check if a signal value lies within a specified range, or check the setup and hold times for signals arriving at the inputs of an entity. If the check fails, an error is reported.

Syntax:

assert boolean-expression
[ report string-expression ]
[ severity expression ]:

If the value of the boolean expression is false, the report message is printed along with the severity level. The expression in the severity clause must generate a value of type SEVERTTY_LEVEL (a predefined enumerated type in the language with values NOTE, WARNING, ERROR, and FAILURE).

The severity level is typically used by a simulator to initiate appropriate actions depending on its value.

Eg., if the severity level is ERROR, the simulator may abort the simulation process and provide relevant diagnostic information.

At the very least, the severity level is displayed.

Eg., a D-type rising-edge-triggered flip-flop that uses assertion statements to check for setup and hold times.

entity DFF is
port (D, CK: in BIT: Q, NOTQ: out BIT);
end DFF;

architecture CHECK_TIMES of DFF is
constant HOLD_TIME: TIME := 5 ns;
constant SETUP_TIME: TIME := 3 ns;
begin
process (D, CK)
variable LastEventOnD, LastEventOnCk: TIME;
begin
--Check for hold time:
if D' EVENT then
assert (NOW = 0ns) or
((NOW - LastEventOnCk) >= HOLD_TIME)
report "Hold time too short!"
severity FAILURE;
LastEventOnD := NOW;
end if;
-- Check for setup time:
if (CK = '1') and CK'EVENT then
assert (NOW = 0ns) or
((NOW - LastEventOnD) >= SETUP_TIME)
report "Setup time too short!"
severity FAILURE;
LastEventOnCk := NOW;
end if;
-- Behavior of FF:
if (CK = '1' ) and CK'EVENT then
Q<=D;
NOTQ <= not D;
end if;
end process;
end CHECK_TIMES;

EVENT is a predefined attribute of a signal and is true if an event (a change of value) occurred on that signal at the time the value of the attribute is determined.

NOW is a predefined function that returns the current simulation time.

The process is sensitive to signals D and CK. When an event occurs on either of these signals, the first if statement is executed. This checks to see if an event occurred on D. If so, the assertion is checked to make sure that the difference between the current simulation time and the last time an event occurred on signal CK is greater than a constant HOLD_TIME delay. If not, a report message is printed and the severity level is returned to the simulator.

Similarly, the next if statement checks for the setup time. The last if statement describes the latch behavior of the D-type flip-flop. The setup and hold times have been modeled as constants which could also be modeled as generic parameters of the flip-flop.
Eg., an assertion statement to check for spikes at the input of an inverter.

package PACK1 is
constant MIN_PULSE: TIME := 5 ns;
constant PROPAGATE_DLY: TIME := 10 ns;
end PACK1;
use WORK.PACK1.all;

entity INV is
port (A: in BIT; NOT_A: out BIT):
end INV;

architecture CHECK_INV of INV is
begin
process (A)
variable LastEventOnA: TIME := 0 ns;
begin
assert (NOW = 0ns) or
((NOW - LastEventOnA) >= MIN_PULSE)
report "Spike detected on input of inverter"
severity WARNING;
LastEventOnA := NOW:
NOT_A <= not A after PROPAGATE_DLY;
end process;
end CHECK_INV;

Eg.,

assert (DATA <= 255)
report "Data out of range.';
assert (CLK = '0') or (CLK = '1'); --CLK is of type ('X', '0', 'I ', 'Z').

In the last assertion statement, the default report message "Assertion violation" is printed. The default severity level is ERROR if the severity clause is not specified.

Signal Assignment Statement

Aside from the delta delay model, there are two other types of delay models that can be used with signal assignments, inertial and transport.

1. Inertial Delay Model

Inertial delay models the delays often found in switching circuits which represents the time for which an input value must be stable before the value is allowed to propagate to the output. In addition, the value appears at the output after the specified delay.

If the input is not stable for the specified time, no output change occurs. When used with signal assignments, the input value is represented by the value of the expression on the right-hand-side and the output is represented by the target signal.

Eg., a noninverting buffer with an inertial delay of 10 ns.


Figure 17: Inertial Delay

Events on signal A that occur at 5 ns and 8 ns are not stable for the inertial delay duration and hence do not propagate to the output. Event on A at 10ns remains stable for more than the inertial delay, and therefore, the value is propagated to the target signal Z after the inertial delay; Z gets the value 1' at 20 ns. Events on signal A at 25ns and 28 ns do not affect the output since they are not stable for the inertial delay duration. Transition 1' to '0' at time 30 ns on signal A remains stable for at least the inertial delay duration, and therefore, a '0' is propagated to signal Z with a delay of 10 ns; Z gets the new value at 40 ns. Other events on A do not affect the target signal Z.

Since inertial delay is most commonly found in digital circuits, it is the default delay model. This delay model is often used to filter out unwanted spikes and transients on signals.

2. Transport Delay Model

Transport delay models the delays in hardware that do not exhibit any inertial delay. This delay represents pure propagation delay, i.e., any changes on an input is transported to the output, no matter how small, after the specified delay. To use a transport delay model, the keyword transport must be used in a signal assignment statement.

Eg., a noninverting buffer using a transport delay of 10 ns.


Figure 18: Transport Delay

Ideal delay modeling can be obtained by using this delay model. In this case, spikes would be propagated through instead of being ignored as in the inertial delay case. Routing delays can be modeled using transport delay.

Eg., a routing delay model is

Entity WIRE14 is
port (A: in BIT; Z: out BIT);
end WIRE14;

architedture WIRE14_TRANSPORT of WIRE14 is
begin
process (A)
begin
Z <= transport A after 0.1 ms;
end process;
end WIRE14_TRANSPORT;

3. Creating Signal Waveforms

It is possible to assign multiple values to a signal, each with a different delay value.

Eg.,
PHASE1 <= '0', '1' after 8 ns, '0' after 13 ns, '1' after 50 ns;

When this signal assignment statement is executed, say at time T, it causes four values to be scheduled for signal PHASEl, the value '0' is scheduled to be assigned at time T+A, 1' at T+8 ns, '0' at T+13 ns, and 1' at T+50 ns. Thus, a waveform appears on the signal PHASEl as shown in Fig. 4.5.



Figure 19: A Signal Waveform

A more general syntax of a signal assignment statement is

signal-object <= waveform-element, waveform-element,
waveform-element, waveform-element;
-- Can have any number of waveform elements.

Each waveform element has a value part, specified by an expression (called the waveform expression), and a delay part, specified by an after clause that specifies the delay. The delays in the waveform elements must appear in increasing order.

A waveform element is of the form

expression after time-expression

Any arbitrary waveform can, therefore, be easily created using a signal assignment statement.
Other Sequential Statements

There are two other forms of sequential statements
1. Procedure call statement,

2. Return statement.