Вы находитесь на странице: 1из 17

Unit -2: Data Flow and Structural Modeling

Dataflow Modeling with examples: Concurrent Signal Assignment Statement, Concurrent versus sequential signal assignment statement, Delta Delay, Multiple Drivers, Conditional signal assignment statement, selected signal assignment statement, concurrent assertion statement. Structural Modeling with example: Component declaration, component instantiation and examples, Direct instantiation of component. 2.1 Dataflow Modeling with examples: 2.1.1 Concurrent Signal Assignment Statement: A signal assignment statement represents a process that assigns values to signals. These statements are used in dataflow style of modeling. An example of concurrent signal assignment statement is:

C <= A or B; E <= C and D; In the above example, if D changes earlier than A & B then, the second statement will execute earlier than the first statement i.e. the two statements are concurrent and the execution does not depend on their sequence. Statements that appear inside a process statement are sequential statements, while all the statements that appear in the architecture body are concurrent statements. Process statement is itself a concurrent statement i.e. if there were any concurrent signal assignment statement & process statement within an architecture body, the order of these statements also would not matter. Concurrent statements are included within architecture definitions and within "block" statements, representing concurrent behavior within the modeled design unit. These statements are executed in an asynchronous manner, with no defined order, modeling the behavior of independent hardware elements within a system. Concurrent signal assignment has three basic formats. 1. A <= B; A <= B when condition1 else C when condition2 else D when condition3 else E;

2. With expression select A <= B when choice1, C when choice2, D when choice3, E when others; For each of the above, waveforms (time-value pairs) can also be specified. Examples: A <= B after 10ns when condition1 else C after 12ns when condition2 else D after 11ns; -- 4-input multiplexer (Choice is a 2-bit vector) with Choice select Out <= In0 after 2ns when "00", In1 after 2ns when "01", In2 after 2ns when "10", In3 after 2ns when "11"; -- 2-to-4 decoder (Y = 4-bit and A = 2-bit vectors) Y <= "0001" after 2ns when A = "00" else "0010" after 2ns when A = "01" else "0100" after 2ns when A = "10" else "1000" after 2ns ; -- Tri-state driver: (Y is logic 4; X is bit_vector ) Y <= 0' after 1ns when En = '1' and X = '0' else '1' after 1ns when En = '1' and X = '1' else 'Z' after 1ns; -- A is a 16-bit vector A <= (others => '0'); -- set all bits of A to '0' The keyword "others" in the last example indicates that all elements of A not explicitly listed are to be set to '0'. 2.1.2 Concurrent versus Sequential Signal Assignment Statement: The sequential assignment statement is represented by a process or subprogram. These statements are executed in the order in which they appear within the process or subprogram, as in programming languages. The concurrent signal assignment statement is represented by an architecture that contains processes, concurrent procedure calls, concurrent signal assignments, and component instantiations. Concurrent statements in VHDL can refer only to signals. So, the order of execution of the concurrent statements is not important since the execution of one statement does not affect the execution of another statement during the same simulation cycle. Regarding sequential code, an important point to remember is that each subprogram is interpreted concurrently to any other statement or subprogram that the code might contain.

2.1.3 Delta Delay: In addition to real time delay, VHDL language also defines a simulation delay known as delta delay. This delay is used to model hardware concurrency. This concept can be better understood with the help of following example: In Unit-1, we dealt with the concept of inertial and transport delay. The examples of these delays are shown along with waveform. Examples
B <= A after 5ns; -- inertial delay C <= transport A after 5 ns; -- transport delay 5______15 17_________30 A _______| |_| |_____________ ____________________ B ___________| |_________ (Inertial Delay) _______ __________ C ___________| |_| |_________ (Transport Delay) 10 20 22 35

If no delay ( i.e. after clause) is specified or a delay of 0ns is specified, then delta delay is assumed. Example of delta delay is: C <= A AND B; In this statement, no after clause is given. So, theoretically target signal C will be evaluated as soon as signals A and B are assigned values. But practically, if A and B is assigned value at time T, then C will be evaluated at time (T+). is the default delay i.e. delta delay. 2.1.4 Multiple Drivers: Multiple drivers or Signal Drivers can be defined as a container for a projected output waveform. The value of a signal is a function of the current values of its drivers. Each process that assigns to a given signal implicitly contains a driver for that signal. A signal assignment statement affects only the associated driver. Each signal assignment statement defines a driver for each scalar signal that is a target of this assignment. In case of signals of complex type, each element has its own driver. Inside processes each signal has only one driver, no matter how many assignment to it are specified. When an assignment statement is executed a new value is assigned to the signal driver. The value of the signal is determined based on all its drivers using the resolution function. Each signal has one or more "drivers" which determine the value and timing of changes to the signal. Each driver is a queue of events which indicate when and to what value a signal is to be changed. Each signal assignment results in the corresponding event queue being modified to schedule the new event. signal line x 10ns '0' Driver of 20ns '1' signal x Event Values Times

NOTE: If no delay is specified, the signal event is scheduled for one infinitessimallysmall "delta" delay from the current time. The signal change will occur in the next simulation cycle. Example: (Assume current time is T) clock <= not clock after 10ns; -- change at T + 10ns databus <= mem1 and mem2 after delay; -- change at T + delay x <= '1'; -- change to '1' at time T + "delta"; 2.1.5 Conditional Signal Assignment Statement: Standard if..then and case constructs can be used for selective operations. 2.1.5.1 If Statements: If statements are used to implement the decision control instruction. It selects a sequence of statements for execution based on the value of a condition. Syntax: If Boolean expression then Sequential statements [ elsif Boolean expression then Sequential statements ] [ else Sequential statements ] End if; Example: 4:1 MUX

Entity Mux is Port (A, B, C, D: in bit; S: in bit_vector(1 downto 0);

Y: out bit); End Mux; Architecture Mux_Beh of Mux is begin P1: process (A, B, C, D, S) begin if S = 00 then Y<= A; elsif S = 01 then Y<= B; elsif S = 10 then Y<= C; else Y<= D; End if; End process P1; End Mux_Beh; 2.1.5.2 Case statements: Case statements allows to make a decision from a number of choices. They are used to specify a set of statements to execute based on the value of a given selection signal. Syntax: Case expression is When choices => sequential statements When choices => sequential statements . . [ When others => sequential statements ] End case; Example: 4:1 MUX (shown in fig 2.1) Entity Mux is Port ( A, B, C, D: in bit; S: in bit_vector(1 downto 0); Y: out bit); End Mux; Architecture Mux_Beh of Mux is begin P1: process (A, B, C, D, S) begin Case S is When 00 => Y<= A; When 01 => Y<= B; When 10 => Y<= C;

When 11 => Y<= D; When others => null; End case; End process P1; End Mux_Beh; More than one values may be specified by separating by a symbol | e.g. 00| 01. 2.1.5.3 Loop Statements: The versatility of a programming language lies in its ability to perform a set of instructions repeatedly. This repetitive operation is done through a control loop structure. A loop statement is used to iterate through a set of sequential statements. There are three kinds of iteration statements. 1) The first form of the iteration scheme is for the scheme. Syntax: [ label: ] for variable in range loop sequence-of-statements end loop [ label ] ; Example: A := 1; for I in 1 to 10 loop A := A +I; end loop; In this example, loop executes for 10 times & each time the value of I is incremented by 1. 2) The second form of the iteration scheme is the while scheme. Syntax: [ label: ] while condition loop sequence-of-statements end loop [ label ] ; Example: A := 1,B:=1; while A <10 loop B := B +1; end loop; In this example, loop executes for 10 times & each time the value of A is incremented by 1 3) The third form of the iteration scheme is the one where no iteration scheme is specified.

Syntax: [ label: ] loop sequence-of-statements end loop [ label ] ; Example: A := 1,B:=1; Loop B := B +1; A := A +1; exit when A > 10; end loop; All kinds of the loops may contain the 'next' and 'exit' statements. 2.1.5.4 Null Statements: These statements are used when nothing is required to be done. Execution continues with the statement which is appearing next to the null statement. Wherever in the program, we need to use this statement, we simply write null The example for null statement is the same as used for case statement. This statement can be used in if statement or in case statement where certain condition is to be satisfied. Null statement can be used to indicate that when some conditions are met, no action is to performed. Example: Case ABC is When 001 => Y1 := A and B; When 010 => Y2:= A or B; When 100 => Y3:= Not A; When others => null; 2.1.5.5 Exit statements: A statement that may be used in a loop to immediately exit the loop. Syntax: [ label: ] exit [ label2 ] [ when condition ] ; Label2 identifies the loop from which the execution jumps out. If no label is defined, the execution jumps out of the innermost loop. Example: exit; exit outer_loop;

exit when A>B; exit this_loop when C=D or done;

-- done is a Boolean variable

The exit statement terminates entirely the execution of the loop in which it is located. The execution of the exit statement depends on a condition placed at the end of statement right after the WHEN reserved word. When the condition is TRUE (or if there is no condition at all), the exit statement is executed and the control is passed to the first statement after the end loop. 2.1.5.6 Next statements: A statement that may be used in a loop to cause the next iteration. This statement can only be used inside a loop & it replaces the keyword exit. Next statement skips the remaining statements and execution goes to next iteration of the loop. Syntax : [ label: ] next [ label2 ] [ when condition ] ; Example: next; next outer_loop; next when A>B; next this_loop when C=D or done;

-- done is a Boolean variable

The NEXT statement allows to skip a part of an iteration loop. If the condition specified after the WHEN reserved word is TRUE, or if there is no condition at all, then the statement is executed. This results in skipping all the statements below it until the end of the loop & passing the control to the first statement in the next iteration. A NEXT statement may specify the name of the loop it is expected to influence. If no label is supported, then the statement applies to the innermost enclosing loop. The NEXT statement is often confused with the EXIT statement. The difference between the two is that the EXIT statement exits the loop entirely, while the NEXT statement skips to the next loop iteration (in other words, it exits the current iteration of the loop. 2.1.5.7 Assertion statement: Assertion statement is used for internal consistency check or error message generation. Syntax : [ label: ] assert boolean_condition [ report string ] [ severity name ] ; Example: assert a=(b or c);

assert j<i report "internal error, tell someone"; assert clk='1' report "clock not up" severity WARNING; Predefined severity names are: NOTE, WARNING, ERROR, FAILURE. Default severity for assert is ERROR. The assertion statement has three optional fields and usually all three are used. The condition specified in an assertion statement must evaluate to a Boolean value (TRUE or FALSE). If it is FALSE, it is said that an assertion violation occurred. The expression specified in the report clause must be of predefined type STRING and is a message to be reported when assertion violation occurred. If the severity clause is present, it must specify an expression of predefined type SEVERITY_LEVEL, which determines the severity level of the assertion violation. The SEVERITY_LEVEL type is specified in the standard package and contains the following values: NOTE, WARNING, ERROR and FAILURE. If the severity clause is omitted it is implicitly assumed to be ERROR. When an assertion violation occurs, the report clause is issued and displayed on the screen. The supported severity level supplies information to the simulator. The severity level defines the degree to which the violation of the assertion affects the operation of the process. NOTE can be used to pass information messages from simulation. WARNING can be used in unusual situation in which the simulation can be continued, but the results may be unpredictable. ERROR can be used when the assertion violation makes continuation of the simulation not feasible. FAILURE can be used when the assertion violation is a fatal error & the simulation must be stopped at once. Assertion statements are not only sequential, but can be used as concurrent statements as well. A concurrent assertion statement represents a passive process statement containing the specified assertion statement. 2.1.5.8 Report statement: Report statement is used to output messages. It is similar to assertion statement except that it does not have the assertion check. Syntax : [ label: ] report string [ severity name ] ; report "finished pass1"; -- default severity name is NOTE report "Inconsistent data." severity FAILURE; The report statement is very much similar to assertion statement. The main difference is that the message is displayed unconditionally. Its main purpose is to help in the debugging process. The expression specified in the report clause must be of predefined

type STRING, and it is a message that will be reported when the assertion violation occurred. The report statement was introduced as late as in VHDL93 and is equivalent to the assert false statement. The latter form was the only acceptable form in VHDL83. 2.1.5.9 Procedure call statement: Procedure call statement invoke an externally-defined subprogram in the same manner as a concurrent procedure call. A procedure call statement can either be a sequential statement or concurrent statement. If the statement is inside a process statement or another subprogram, it is sequential procedure call statement otherwise concurrent procedure call statement Syntax : [ label: ] procedure-name [ ( actual parameters ) ] ; Actual parameters specifies the list of formal parameters for the procedure. Actuals may be specified using positional association or named association. Example: do_it; -- no actual parameters compute(stuff, A=>a, B=>c+d); -- positional association first, -- then named association of -- formal parameters to actual parameters

2.1.5.10 Return Statement: Return statement is a special STATEMENT allowed only within subprograms. It is a required statement in a function, optional in a procedure. Syntax : [ label: ] return [ expression ] ; Return statement causes the subprogram to terminate & control to be returned to the calling program. return; return a+b; -- from somewhere in a procedure -- returned value in a function

The return statement ends the execution of a subprogram (Procedure or function) in which it appears. It causes an unconditional jump to the end of the subprogram. If a return statement appears inside nested subprogram it applies to the innermost subprogram (i.e. the jump is performed to the next end procedure or end function clause). This statement can only be used in a procedure or function body. The return statement in a procedure may not return any value, while a return in a function must return a value (an

expression) which is of the same type as specified in the function after the return keyword. 2.1.6 Selected Signal Assignment Statement: Selected Signal Assignment Statement is another form of concurrent signal assignment statement. In this statement, selection is based on the value of an included expression. The syntax for this statement is: with <expression> select target signal <= waveform when expression_value,

. .
waveform when expression_value; Example: signal s : std_logic_vector (0 to 1); with s select w <= A And B when 11, A OR B when 10, 0 when others; In the above example, selection expression has a data type std_logic_vector(0 to 1). For synthesis, only values 11 and 10 are meaningful. It is to be noted that the first when clause is followed by a comma (,) and that the last when is followed by a semicolon (;).The comma indicates that another when follows the current clause, while the semicolon indicates the end of the statement. Selected signal assignment statement is a concurrent signal assignment statement, so they must have at least one signal that causes the statement to execute.

2.1.7 Concurrent Assertion Statement: Concurrent Assertion Statement is used in behavioral modeling. This statement represents a process whose body contains an ordinary sequential assertion statement. Assertion statement is used for internal consistency check or error message generation. Syntax: [ label: ] assert boolean_condition [ report string ] [ severity name ] ; The optional label on the statement serves the same purpose as that on a process statement. Example:

assert a=(b or c); assert j<i report "internal error, tell someone"; assert clk='1' report "clock not up" severity WARNING; Predefined severity names are: NOTE, WARNING, ERROR, FAILURE default severity for assert is ERROR Concurrent assertions provide a very compact and useful way of including timing and correctness checks in a model. 2.1.7.1 Report statement: Report statement is used to output messages. It is similar to assertion statement except that it does not have the assertion check. Syntax : [ label: ] report string [ severity name ] ; Example: report "finished pass1"; -- default severity name is NOTE report "Inconsistent data." severity FAILURE; 2.2 Structural Modeling with Examples: In structural style of modeling, an entity is described as a set of interconnected components. 2.2.1 Component Declaration: The "component declaration" defines the component interface, which corresponds to the component's entity declaration. This allows the VHDL compiler to check signal compatibilities. An architecture body can also make use of other entities described separately and placed in design libraries. In order to do this, the architecture must declare a component, which can be thought of as a template defining a virtual design entity, to be instantiated within the architecture. Syntax: component_declaration ::= component identifier [ local_generic_clause ] [ local_port_clause ] end component ; Examples: 1. component nand3 generic (Tpd : Time := 1 ns); port (a, b, c : in logic_level; y : out logic_level); end component; 2. component read_only_memory

generic (data_bits, addr_bits : positive); port (en : in bit; addr : in bit_vector(depth1 downto 0); data :out bit_vector(width1 downto 0) ); end component; 3. component adder port(a,b: in bit_vector(7 downto 0); s : out bit_vector(7 downto 0); cin: in bit; cout: out bit); end component; The first example declares a three-input gate with a generic parameter specifying its propagation delay. Different instances can later be used with possibly different propagation delays. The second example declares a read only memory component with address depth and data width dependent on generic constants. This component could act as a template for the ROM entity. A component represents an entity/ architecture pair. It specifies a subsystem, which can be instantiated in another architecture leading to a hierarchical specification. Component instantiation is like plugging a hard component into a socket in a board as shown in fig 2.2. A component must be declared before it is instantiated. The component declaration defines the virtual interface of the instantiated design entity (the socket) but it does not directly indicates the design entity. The binding of a design entity to a given component may be delayed and may be placed either in the configuration specification or configuration declaration. The component can be defined in package, design entity, architecture or block declarations. If the component is declared in an architecture, it must be declared before the begin statement of the architecture. In such a case, the component can be used (instantiated) in the architecture only. A more universal approach is to declare a component in the package. Such a component is visible in any architecture, which uses this package. Generic and ports of a component are copies of generics and ports of the entity the component represents. Example: Architecture stru_x of ABC is Component Xor1 is Port (A,B : in bit_vector (0 to 3); C : out bit_vector (0 to 3); End component Xor1; Signal S1, S2 : bit_vector (0 to 3); Signal S3 : bit_vector (0 to 3); Begin X1 : Xor1 portmap (S1, S2, S3); End architecture stru_x;

2.2.2 Component Instantiation: A component represents an entity/ architecture pair. It specifies a subsystem, which can be instantiated in another architecture leading to a hierarchical specification. Component instantiation is like plugging a hard component into a socket in a board. The component instantiation statement introduce a subsystem declared elsewhere, either as a component or as an entity/architecture pair (without declaring it as a component). Instantiates (i.e. create instances of) predefined components within a design architecture. Each such component is first declared in the declaration section of that architecture, and then "instantiated" one or more times in the body of the architecture. A component defined in an architecture may be instantiated using the syntax:

Syntax: component_instantiation_statement ::= instantiation_label : component_name [ generic_map_aspect ] [ port_map_aspect ] ; This indicates that the architecture contains an instance of the named component, with actual values specified for generic constants, and with the component ports connected to actual signals or entity ports. The example components declared in the previous section might be instantiated as: Example: enable_gate: nand3 port map (a => en1, b => en2, c => int_req, y => interrupt); parameter_rom: read_only_memory generic map (data_bits => 16, addr_bits => 8); port map (en => rom_sel, data => param, addr => a (7 downto 0); In the first instance, no generic map specification is given, so the default value for the generic constant Tpd is used. In the second instance, values are specified for the address and data port sizes. Note that the actual signal associated with the port addr is a slice of an array signal. This illustrates that a port which is an array can be connected to part of a signal which is a larger array, a very common practice with bus signals. The component instantiation contains a reference to the instantiated unit and actual values for generics and ports. There are three forms of component instantiation: Instantiation of a component. Instantiation of a design entity. Instantiation of a configuration. The actual values of generic map aspect and portmap aspect connections allow assigning the components of the actual values to generic parameters and ports. Instantiation of a component: Instantiation of a component introduces a relationship to a unit defined earlier as a component. The name of the instantiated component must match the name of the declared component. The instantiated component is called with the actual parameters for generics and ports. The association list can be either positional or named. In the positional list, the actual parameters (generics and ports) are connected in the same order in which ports were declared in the component. Named association allows to list the generics and ports in an order that is different from the one declared for the component. In such a case, the ports have to be explicitly referenced. Instantiation of a Design Entity It is not necessary to define a component to instantiate it. The entity/ architecture pair can be instantiated directly. In such a direct instantiation, the component instantiation statement contains the design entity name and optionally the name of the architecture to be used for this design entity. The reserved word entity follows the declaration of this type of the component instantiation statements.

If architecture name is not specified in an instantiation of a design entity, the last compiled architecture associated with the entity will be taken. Example: Positional Association architecture ABC_1 of ABC is signal X, Y, S, C: bit; component H_A is port (I1, I2 : in bit; S0, C0 : out bit); End component H_A; Begin HA : H_A portmap (X, Y, S, C); End architecture ABC_1; Named Association (Direct Instantiation) architecture ABC_1 of ABC is signal X, Y, S, C: bit; component H_A is port (I1, I2 : in bit; S0, C0 : out bit); End component H_A; Begin HA : H_A portmap (S0 => S, C0 => C, I1 => X, I2 => Y); End architecture ABC_1; Instantiation Entity XOR_ G is Port (I1, I2: in bit_vector (0 to 3); Out1 : out bit_vector (0 to 3)); end entity XOR_G; architecture XOR_G1 of XOR_G is begin Out1 <= I1 XOR I2 signal after 5ns; End architecture XOR_G1 Entity ABC is End entity ABC; Architecture stru_X1 of ABC is Signal S1, S2 : bit_vector (0 to 3); Signal S3 : bit_vector (0 to 3); Begin X1 : entity work XOR_G (XOR_G1) portmap (S1, S2, S3); End architecture stru_X1;

Вам также может понравиться