Return to previous page Advance to next page
Xilinx Synthesis Technology (XST) User Guide
Chapter 6: VHDL Language Support

Combinatorial Circuits

The following subsections describes XST usage with various VHDL constructs for combinatorial circuits.

Concurrent Signal Assignments

Combinatorial logic may be described using concurrent signal assignments which can be defined within the body of the architecture. VHDL offers three types of concurrent signal assignments: simple, selected, and conditional. You can describe as many concurrent statements as needed; the order of concurrent signal definition in the architecture is irrelevant.

A concurrent assignment is made of two parts: left hand side, and right hand side. The assignment changes when any signal in the right part changes; in this case, the result is assigned to the signal on the left part.

Simple Signal Assignment

T = A and B;

Selected Signal Assignment

Example 6-4: Mux Description Using Selected Signal Assignment

library IEEE;
use IEEE.std_logic_1164.all;

entity select_bhv is
generic (width: integer := 8);
port (a, b, c, d: in std_logic_vector (width-1 downto 0);
selector: in std_logic_vector (1 downto 0);
T: out std_logic_vector (width-1 downto 0) );
end select_bhv;
architecture bhv of select_bhv is
begin
with selector select
T = a when "00",
b when "01",
c when "10",
d when others;
end bhv;

Conditional Signal Assignment

Example 6-5: Mux Description Using Conditional Signal Assignment

entity when_ent is
generic (width: integer := 8);
port (a, b, c, d: in std_logic_vector (width-1 downto 0);
selector: in std_logic_vector (1 downto 0);
T: out std_logic_vector (width-1 downto 0) );
end when_ent;
architecture bhv of when_ent is
begin
T = a when selector = "00" else
b when selector ="01" else
c when selector ="10" else
d;
end bhv;

Generate Statement

The repetitive structures are declared with the "generate" VHDL statement. For this purpose "for I in 1 to N generate" means that the bit slice description will be repeated N times. As an example, Example 6-6 gives the description of an 8-bit adder by declaring the bit slice structure.

Example 6-6: 8 Bit Adder Described with a "for...generate" Statement

entity EXAMPLE is
port ( A,B : in BIT_VECTOR (0 to 7);
CIN : in BIT;
SUM : out BIT_VECTOR (0 to 7);
COUT : out BIT
);
end EXAMPLE;
architecture ARCHI of EXAMPLE is
signal C : BIT_VECTOR (0 to 8);
begin
C(0) = CIN;
COUT = C(8);
LOOP_ADD : for I in 0 to 7 generate
SUM(I) = A(I) xor B(I) xor C(I);
C(I+1) = (A(I) and B(I)) or (A(I) and C(I)) or (B(I) and
C(I));
end generate;
end ARCHI;

The "if condition generate" statement is also supported for static (non-dynamic) conditions. Example 6-7 shows such an example. It is a generic N-bit adder with a width ranging between 4 and 32.

Example 6-7: N Bit Adder Described with an "if...generate" and a "for... generate" Statement

entity EXAMPLE is
generic ( N : INTEGER := 8);
port ( A,B : in BIT_VECTOR (N downto 0);
CIN : in BIT;
SUM : out BIT_VECTOR (N downto 0);
COUT : out BIT
);
end EXAMPLE;
architecture ARCHI of EXAMPLE is
signal C : BIT_VECTOR (N+1 downto 0);
begin
L1: if (N=4 and N=32) generate
C(0) = CIN;
COUT = C(N+1);
LOOP_ADD : for I in 0 to N generate
SUM(I) = A(I) xor B(I) xor C(I);
C(I+1) = (A(I)and B(I))or (A(I) and C(I)) or (B(I) and C(I));
end generate;
end generate;
end ARCHI;

Combinatorial Process

A process assigns values to signals in a different way than when using concurrent signal assignments. The value assignments are made in a sequential mode. The latest assignments may cancel previous ones. See Example 6-8. First the signal S is assigned to 0, but later on (for (A and B) =1), the value for S is changed to 1.

Example 6-8: Assignments in a Process

entity EXAMPLE is
port ( A, B : in BIT;
S : out BIT );
end EXAMPLE;
architecture ARCHI of EXAMPLE is
begin
process ( A, B )
begin
S = '0' ;
if ((A and B) = '1') then
S = '1' ;
end if;
end process;
end ARCHI;

A process is called combinatorial when its inferred hardware does not involve any memory elements. Said differently, when all assigned signals in a process are always explicitly assigned in all paths of the process statements, then the process in combinatorial.

A combinatorial process has a sensitivity list appearing within parenthesis after the word "process". A process is activated if an event (value change) appears on one of the sensitivity list signals. For a combinatorial process, this sensitivity list must contain all signals which appear in conditions (if, case, etc.) and any signal appearing on the right hand side of a assignment.

If one or more signals are missing from the sensitivity list, XST generates a warning for the missing signals and adds them to the sensitivity list. In this case, the result of the synthesis may be different from the initial design specification.

A process may contain local variables. The variables are handled in a similar manner as signals (but are not, of course, outputs to the design).

In Example 6-9, a variable named AUX is declared in the declarative part of the process and is assigned to a value (with ":=") in the statement part of the process. Examples 9 and 10 are two examples of a VHDL design using combinatorial processes.

Example 6-9: Combinatorial Process

library ASYL;
use ASYL.ARITH.all;

entity ADDSUB is
port ( A,B : in BIT_VECTOR (3 downto 0) ;
ADD_SUB : in BIT;
S : out BIT_VECTOR (3 downto 0));
end ADDSUB;
architecture ARCHI of ADDSUB is
begin
process ( A, B, ADD_SUB )
variable AUX : BIT_VECTOR (3 downto 0);
begin
if ADD_SUB = '1' then
AUX := A + B ;
else
AUX := A - B ;
end if;
S = AUX;
end process;
end ARCHI;

Example 6-10: Combinatorial Process

entity EXAMPLE is
port ( A, B : in BIT;
S : out BIT );
end EXAMPLE;
architecture ARCHI of EXAMPLE is
begin
process ( A,B )
variable X, Y : BIT;
begin
X := A and B;
Y := B and A;
if X = Y then
S = '1' ;
end if;
end process;
end ARCHI;
Note In combinatorial processes, if a signal is not explicitly assigned in all branches of "if" or "case" statements, XST will generate a latch to hold the last value. To avoid latch creation, assure that all assigned signals in a combinatorial process are always explicitly assigned in all paths of the process statements.

Different statements can be used in a process:

The following sections provide examples of each of these statements.

If .. Else Statement

If ... else statements use true/false conditions to execute statements. If the expression evaluates to true, the first statement is executed. If the expression evaluates to false (or x or z), the else statement is executed. A block of multiple statements may be executed using begin and end keywords. If ... else statements may be nested.

Example 6-11: Mux Description Using If ... Else Statement

library IEEE;
use IEEE.std_logic_1164.all;

entity mux4 is
port (a, b, c, d: in std_logic_vector (7 downto 0);
sel1, sel2: in std_logic;
outmux: out std_logic_vector (7 downto 0));
end mux4;
architecture behavior of mux4 is
begin
process (a, b, c, d, sel1, sel2)
begin
if (sel1 = '1') then
if (sel2 = '1' ) then
outmux = a;
else
outmux = b;
endif;
else
if (sel2 = '1' ) then
outmux = c;
else
outmux = d;
end if;
end if;
end process;
end behavior;

Case Statement

Case statements perform a comparison to an expression to evaluate one of a number of parallel branches. The case statement evaluates the branches in the order they are written; the first branch that evaluates to true is executed. If none of the branches match, the default branch is executed

Example 6-12: Mux Description Using the Case Statement

library IEEE;
use IEEE.std_logic_1164.all;

entity mux4 is
port (a, b, c, d: in std_logic_vector (7 downto 0);
sel: in std_logic_vector (1 downto 0);
outmux: out std_logic_vector (7 downto 0));
end mux4;
architecture behavior of mux4 is
begin
process (a, b, c, d, sel)
begin
case sel is
when "00" = outmux = a;
when "01" = outmux = b;
when "10" = outmux = c;
when others =
outmux = d;-- case statement must be complete
end case;
end process;
end behavior;

For .. Loop Statement

The "for" statement is supported for :

(where var is the loop variable and step is a constant value).

Example 6-13: For ... Loop Description

library IEEE;
use IEEE.std_logic_1164.all;
use IEEE.std_logic_unsigned.all;

entity countzeros is
port (a: in std_logic_vector (7 downto 0);
Count: out std_logic_vector (2 downto 0));
end mux4;
architecture behavior of mux4 is
signal Count_Aux: std_logic_vector (2 downto 0);
begin
process (a)
begin
Count_Aux = "000";
for i in a'rangeloop
if (a[i] = '0') then
Count_Aux = Count_Aux + 1; -- operator "+" defined
--in std_logic_unsigned
end if;
end loop;
Count = Count_Aux;
end process;
end behavior;
Top of page