|Summary |Design Units |Sequential Statements |Concurrent Statements |Predefined Types |Declarations |
|Resolution and Signatures |Reserved Words |Operators |Predefined Attributes |Standard Packages |
VHDL Concurrent Statements
These statements are for use in Architectures.
block statementUsed to group concurrent statements, possibly hierarchically. label : block [ ( guard expression ) ] [ is ] [ generic clause [ generic map aspect ; ] ] [ port clause [ port map aspect ; ] ] [ block declarative items ] begin concurrent statements endblock [ label ] ; clump : blockbegin A <= B or C; D <= B andnot C; endblock clump ; maybe : block ( B'stable(5 ns) ) isport (A, B, C : inout std_logic ); portmap ( A => S1, B => S2, C => outp ); constant delay: time := 2 ns; signal temp: std_logic; begin temp <= A xor B after delay; C <= temp nor B; endblock maybe;
process statementUsed to do have sequential statements be a part of concurrent processing. label : process [ ( sensitivity_list ) ] [ is ] [ process_declarative_items ] begin sequential statements endprocess [ label ] ; -- input and output are defined a type 'word' signals reg_32: process(clk, clear) beginif clear='1' then output <= (others=>'0'); elsif clk='1' then output <= input after 250 ps; end if; end process reg_32; -- assumes use IEEE.std_logic_textio.all printout: process(clk) -- used to show state when clock raises variable my_line : LINE; -- not part of working circuit beginif clk='1' then write(my_line, string'("at clock ")); write(my_line, counter); write(my_line, string'(" PC=")); write(my_line, IF_PC); writeline(output, my_line); counter <= counter+1; end if; end process printout; process_declarative_items are any of: subprogram declarationsubprogram bodytype declarationsubtype declarationconstant, object declarationvariable, object declarationfile, object declarationalias declarationattribute declarationattribute specificationuse clausegroup template declarationgroup declaration BUT NOT signal_declaration, all signals must be declared outside the process. sig1 <= sig2 and sig3; -- considered here as a sequential statement -- sig1 is set outside the process upon exit or wait A process may be designated as postponed in which case it starts in the same simulation cycle as an equivalent non postponed process, yet starts after all other non postponed processes have suspended in that simulation cycle.
concurrent procedure call statementA sequential procedure call statement may be used and its behavior is that of an equivalent process. [ label : ] [ postponed ] procedure name [ ( actual_parameters ) ] ; trigger_some_event ; Check_Timing(min_time, max_time, clk, sig_to_test); Note that a procedure can be defined in a library package and then used many places. A process can not be similarly defined in a package and may have to be physically copied. A process has some additional capability not available in a concurrent procedure.
concurrent assertion statementA sequential assertion statement may be used and its behavior is that of an equivalent process. [ label : ] [ postponed ] assertion_statement ;
concurrent signal assignment statementA sequential signal assignment statement is also a concurrent signal assignment statement. Additional control is provided by the use of postponed and guarded. [ label : ] sequential signal assignment statement [ label : ] [ postponed ] conditional_signal_assignment_statement ; [ label : ] [ postponed ] selected_signal_assignment_statement ; The optional guarded causes the statement to be executed when the guarded signal changes from False to True.
conditional signal assignment statementA conditional assignment statement is also a concurrent signal assignment statement. target <= waveform when choice; -- choice is a boolean expression target <= waveform when choice else waveform; sig <= a_sig when count>7; sig2 <= not a_sig after 1 ns when ctl='1' else b_sig; "waveform" for this statement seems to include [ delay_mechanism ] See sequential signal assignment statement
selected signal assignment statementA selected assignment statement is also a concurrent signal assignment statement. with expression select target <= waveform when choice [, waveform when choice ] ; with count/2 select my_ctrl <= '1' when 1, -- count/2 = 1 for this choice '0' when 2, 'X' whenothers;
component instantiation statementGet a specific architecture-entity instantiated component. part_name: entity library_name.entity_name(architecture_name) port map ( actual arguments ) ; optional (architecture_name) part_name: component_name port map ( actual arguments ) ; Given entity gate isport (in1 : in std_logic ; in2 : in std_logic ; out1 : out std_logic) ; end entity gate; architecture circuit of gate is ... architecture behavior of gate is ... A101: entity WORK.gate(circuit) port map ( in1 => a, in2 => b, out1 => c ); -- when gate has only one architecture A102: entity WORK.gate port map ( in1 => a, in2 => b, out1 => c ); -- when order of actual arguments is used A103: entity WORK.gate port map ( a, b, c ); Given an entity entity add_32 is -- could have several architectures port (a : in std_logic_vector (31 downto 0); b : in std_logic_vector (31 downto 0); cin : in std_logic; sum : out std_logic_vector (31 downto 0); cout : out std_logic); end entity add_32; Create a simple component interface component add_32 -- use same port as entity port (a : in std_logic_vector (31 downto 0); b : in std_logic_vector (31 downto 0); cin : in std_logic; sum : out std_logic_vector (31 downto 0); cout : out std_logic); end component add_32; Instantiate the component 'add_32' to part name 'PC_incr' PC_incr : add_32 port map (PC, four, zero, PC_next, nc1); Create a component interface, changing name and renaming arguments component adder -- can have any name but same types in port port (in1 : in std_logic_vector (31 downto 0); in2 : in std_logic_vector (31 downto 0); cin : in std_logic; sum : out std_logic_vector (31 downto 0); cout : out std_logic); end component adder; Instantiate the component 'adder' to part name 'PC_incr' PC_incr : adder -- configuration may associate a specific architecture port map (in1 => PC, in2 => four, cin => zero, sum => PC_next, cout => nc1);
generate statementMake copies of concurrent statements label: for variable in range generate -- label required block declarative items \__ optional begin / concurrent statements -- using variable endgenerate label ; label: if condition generate -- label required block declarative items \__ optional begin / concurrent statements endgenerate label ; band : for I in 1 to 10 generate b2 : for J in 1 to 11 generate b3 : ifabs(I-J)<2 generate part: foo portmap ( a(I), b(2*J-1), c(I, J) ); endgenerate b3; endgenerate b2; endgenerate band;
Go to top
Go to VHDL index
This article will review the concurrent signal assignment statements in VHDL.
This article will first review the concept of concurrency in hardware description languages. Then, it will discuss two concurrent signal assignment statements in VHDL: the selected signal assignment and the conditional signal assignment. After giving some examples, we will briefly compare these two types of signal assignment statements.
Please see my article introducing the concept of VHDL if you're not familiar with it.
Concurrent vs. Sequential Statements
To understand the difference between the concurrent statements and the sequential ones, let’s consider a simple combinational circuit as shown in Figure 1.
Figure 1. A combinational circuit.
If we consider the operation of the three logic gates of this figure, we observe that each gate processes its current input(s) in an independent manner from other gates. These physical components are operating simultaneously. The moment they are powered, they will “concurrently” fulfill their functionality. Note that while, in practice, the AND gate has a delay to produce a valid output, this does not mean that the OR gate will stop its functionality and wait until the output of the AND gate is produced. The OR gate will function all the time; however, its output will not be valid until its inputs have settled.
Now, let’s examine the VHDL description of Figure 1. This is shown below:
The main part that we are here interested in is the definition of the three gates:
Each of these lines describes a physical component in Figure 1. For example, the second line, which describes the OR gate, takes sig1 and c as inputs and produces the OR of these two values. We saw that the physical components of Figure 1 operate concurrently. Hence, it is reasonable to expect that the VHDL description of these gates should be evaluated in a concurrent manner. In other words, the above three lines of the code are executed at the same time and there is no significance to the order of these statements. As a result, we can rewrite the architecture section of the above code as below:
Since these statements are evaluated at the same time, we call them concurrent statements. This type of code is quite different from what we have learned in basic computer programming where the lines of code are executed one after the other. For example, consider the following MATLAB code:
This code produces out1=1 and out2=1. However, if we change the order of the statements to the following, the program will stop working because we are trying to use sig1 before it is generated.
While the VHDL code describing Figure 1 was executed concurrently, the above MATLAB code is evaluated sequentially (i.e., one line after the other). VHDL supports both the concurrent statements and the sequential ones. It's clear that the concurrent VHDL statements will allow us to easily describe a circuit such as the one in Figure 1 above. In a future article, we'll see that the sequential VHDL statements allow us to have a safer description of sequential circuits. Furthermore, using the sequential VHDL, we can easily describe a digital circuit in a behavioral manner. This capability can significantly facilitate digital hardware design.
The following figure illustrates the difference between concurrent and sequential statements.
Figure 2. The difference between concurrent and sequential statements. Image courtesy of VHDL Made Easy.
Now let's take a look at two concurrent signal assignment statements in VHDL: “the selected signal assignment statement” and “the conditional signal assignment statement”.
Selected Signal Assignment or the “With/Select” Statement
Consider an n-to-one multiplexer as shown in Figure 3. This block should choose one out of its n inputs and transfer the value of this input to the output terminal, i.e., output_signal.
Figure 3. A multiplexer selects one of its n inputs based on the value of the control_expression.
The selected signal assignment allows us to implement the functionality of a multiplexer. For example, the VHDL code describing the multiplexer of Figure 3 will be
Here, the value of the control_expression will be compared with the n possible options, i.e., option_1, option_2, …, option_n. When a match is found, the value corresponding to that particular option will be assigned to the output signal, i.e., output_signal. For example, if control_expression is the same as option_2, then value_2 will be assigned to the output_signal.
Note that the options of a “with/select” assignment must be mutually exclusive, i.e., one option cannot be used more than once. Moreover, all the possible values of the control_expression must be included in the set of the options. The following example clarifies these points.
Example 1: Use the "with/select" statement to describe a one-bit 4-to-1 multiplexer. Assume that the inputs to be selected are a, b, c, and d. And, a two-bit signal, sel, is used to choose the desired input and assign it to out1.
The code for this multiplexer is given below:
Note that since the std_logic data type can take values other than “0” and “1”, the last line of the “with/select” statement needs to use the keyword “others” to take all the possible values of sel into account.
The following figure shows the simulation of this code using the Xilinx ISE simulator. (In case you’re not familiar with ISE, see this tutorial.) As shown in this figure, from 0 nanosecond (ns) until 300 ns the select input, sel, is 00, and, hence, out1 follows the input a. Similarly, you can verify the intended operation for the rest of the simulation interval.
Figure 4. The ISE simulation for the multiplexer of Example 1.
Example 2: Use the “with/select” statement to describe a 4-to-2 priority encoder with the truth table shown below.
The following VHDL code can be used to describe the above truth table:
The ISE simulation is shown in Figure 5.
Figure 5. The ISE simulation for the priority encoder of Example 2.
Conditional Signal Assignment or the “When/Else” Statement
The “when/else” statement is another way to describe the concurrent signal assignments similar to those in Examples 1 and 2. Since the syntax of this type of signal assignment is quite descriptive, let’s first see the VHDL code of a one-bit 4-to-1 multiplexer using the “when/else” statement and then discuss some details.
Example 3: Use the when/else statement to describe a one-bit 4-to-1 multiplexer. Assume that the inputs to be selected are a, b, c, and d. And, a two-bit signal, sel, is used to choose the desired input and assign it to out1.
The code will be
In this case, the expressions after “when” are evaluated successively until a true expression is found. The assignment corresponding to this true expression will be performed. If none of these expressions are true, the last assignment will be executed. In general, the syntax of the “when/else” statement will be:
We should emphasize that the expressions after the “when” clauses are evaluated successively. As a result, the expressions evaluated earlier has a higher priority compared to the next ones. Considering this, we can obtain the conceptual diagram of this assignment as shown in Figure 6. This figure illustrates a conditional signal assignment with three “when” clauses.
Figure 6. The conceptual implementation of a “when/else” statement with three “when” clauses.
Let’s review the main features of the selected signal assignment and the conditional signal assignment.
“With/Select” vs. “When/Else” Assignment
As mentioned above, the options of a “with/select” assignment must be mutually exclusive, i.e., one option cannot be used more than once. Moreover, all the possible values of the control_expression must be included in the set of options. While the “with/select” assignment has a common controlling expression, a “when/else” assignment can operate on expressions with different arguments. For example, consider the following lines of code:
In this case, the expressions are evaluating two different signals, i.e., reset1 and clk.
For the “when/else” assignment, we may or may not include all the possible values of the expressions to be evaluated. For example, the multiplexer of Example 3 covers all the possible values of sel; however, the above code does not. The above code implies that out1 should retain its previous value when none of the expressions are true. This causes the inference of a latch in the synthesized circuit.
Another important difference between the “with/select” and “when/else” assignment can be seen by comparing the conceptual implementation of these two statements. The priority network of Figure 6 involves a cascade of several logic gates. However, the “with/select” assignment avoids this chain structure and has a balanced structure. As a result, in theory, the “with/select” statement may have better performance in terms of the delay and area (see RTL Hardware Design Using VHDL: Coding for Efficiency, Portability, and Scalability, Xilinx HDL Coding Hints, and Guide to HDL Coding Styles for Synthesis).
In practice, we generally don’t see this difference because many synthesis software packages, such as the Xilinx XST, try not to infer a priority encoded logic. Though we can use the PRIORITY_EXTRACT constraint of XST to force priority encoder inference, Xilinx strongly suggests that we use this constraint on a signal-by-signal basis; otherwise, the constraint may guide us towards sub-optimal results. For more details see page 79 of the XST user guide.
- Concurrent statements are executed at the same time and there is no significance to the order of these statements. This type of code is quite different from what we have learned in basic computer programming where the lines of code are executed one after the other.
- The selected signal assignment or the "with/select" assignment allows us to implement the functionality of a multiplexer.
- The options of a “with/select” assignment must be mutually exclusive, i.e., one option cannot be used more than once. Moreover, all the possible values of the control_expression must be included in the set of the options.
- For the "when/else" statement, the expressions after the “when” clauses are evaluated successively. As a result, the expressions evaluated earlier has a higher priority compared to the next ones.
- One important difference between the “with/select” and “when/else” assignment can be seen by comparing the conceptual implementation of these two statements. The "when/else" statement has a priority network; however, the “with/select” assignment avoids this chain structure and has a balanced structure.
To see a complete list of my articles, please visit this page.
Featured image used courtesy of Parallella.