ВУЗ: Не указан

Категория: Не указан

Дисциплина: Не указана

Добавлен: 13.06.2025

Просмотров: 3459

Скачиваний: 2

ВНИМАНИЕ! Если данный файл нарушает Ваши авторские права, то обязательно сообщите нам.

5Concurrent Code

Having finished laying out the basic foundations of VHDL (chapters 1 to 4), we can now concentrate on the design (code) itself.

VHDL code can be concurrent (parallel) or sequential. The former will be studied in this chapter, while the latter will be seen in chapter 6. This division is very important, for it allows a better understanding of which statements are intended for each kind of code, as well as the consequences of using one or the other.

The concurrent statements in VHDL are WHEN and GENERATE. Besides them, assignments using only operators (AND, NOT, þ, *, sll, etc.) can also be used to construct concurrent code. Finally, a special kind of assignment, called BLOCK, can also be employed in this kind of code.

5.1Concurrent versus Sequential

We start this chapter by reviewing the fundamental di¤erences between combinational logic and sequential logic, and by contrasting them with the di¤erences between concurrent code and sequential code.

Combinational versus Sequential Logic

By definition, combinational logic is that in which the output of the circuit depends solely on the current inputs (figure 5.1(a)). It is then clear that, in principle, the system requires no memory and can be implemented using conventional logic gates.

In contrast, sequential logic is defined as that in which the output does depend on previous inputs (figure 5.1(b)). Therefore, storage elements are required, which are connected to the combinational logic block through a feedback loop, such that now the stored states (created by previous inputs) will also a¤ect the output of the circuit.

A common mistake is to think that any circuit that possesses storage elements (flip-flops) is sequential. A RAM (Random Access Memory) is an example. A RAM can be modeled as in figure 5.2. Notice that the storage elements appear in a forward path rather than in a feedback loop. The memory-read operation depends only on the address vector presently applied to the RAM input, with the retrieved value having nothing to do with previous memory accesses.

Concurrent versus Sequential Code

VHDL code is inherently concurrent (parallel). Only statements placed inside a PROCESS, FUNCTION, or PROCEDURE are sequential. Still, though within these blocks the execution is sequential, the block, as a whole, is concurrent with any other (external) statements. Concurrent code is also called dataflow code.

TLFeBOOK

66

input

Combinational

output

Logic

(a)

Figure 5.1

Combinational (a) versus sequential (b) logic.

Chapter 5

input

Combinational

output

Logic

present

next

state

Storage

state

Elements

(b)

input

Combinational

output

Logic

Storage

Elements

Figure 5.2

RAM model.

As an example, let us consider a code with three concurrent statements (stat1, stat2, stat3). Then any of the alternatives below will render the same physical circuit:

stat1 stat3 stat1

stat2 C stat2 C stat3 C etc. stat3 stat1 stat2

It is then clear that, since the order does not matter, purely concurrent code can not be used to implement synchronous circuits (the only exception is when a GUARDED BLOCK is used). In other words, in general we can only build combinational logic circuits with concurrent code. To obtain sequential logic circuits, sequential code (chapter 6) must be employed. Indeed, with the latter we can implement both, sequential as well as combinational circuits.

TLFeBOOK


Concurrent Code

67

In this chapter, we will discuss concurrent code, that is, we will study the statements that can only be used outside PROCESSES, FUNCTIONS, or PROCEDURES. They are the WHEN statement and the GENERATE statement. Besides them, assignments using only operators (logical, arithmetic, etc) can obviously also be used to create combinational circuits. Finally, a special kind of statement, called BLOCK, can also be employed.

In summary, in concurrent code the following can be used:

Operators;

The WHEN statement (WHEN/ELSE or WITH/SELECT/WHEN);

The GENERATE statement;

The BLOCK statement.

Each of these cases is described below.

5.2Using Operators

This is the most basic way of creating concurrent code. Operators (AND, OR, þ, . *, sll, sra, etc.) were discussed in section 4.1, being a summary repeated in table 5.1 below.

Operators can be used to implement any combinational circuit. However, as will become apparent later, complex circuits are usually easier to write using sequential code, even if the circuit does not contain sequential logic. In the example that follows, a design using only logical operators is presented.

Table 5.1

Operators.

Operator type

Operators

Data types

Logical

NOT, AND, NAND,

BIT, BIT_VECTOR,

OR, NOR, XOR, XNOR

STD_LOGIC, STD_LOGIC_VECTOR,

STD_ULOGIC, STD_ULOGIC_VECTOR

Arithmetic

þ, , *, /, **

INTEGER, SIGNED, UNSIGNED

(mod, rem, abs)

Comparison

¼, =¼, <, >, <¼, >¼

All above

Shift

sll, srl, sla, sra, rol, ror

BIT_VECTOR

Concatenation

&, ( , , , )

Same as for logical operators, plus SIGNED and

UNSIGNED

TLFeBOOK

68

Chapter 5

a

b

MUX y

c

d

s1 s0

Figure 5.3

Multiplexer of example 5.1.

Example 5.1: Multiplexer #1

Figure 5.3 shows a 4-input, one bit per input multiplexer. The output must be equal to the input selected by the selection bits, s1-s0. Its implementation, using only logical operators, can be done as follows:

1 ---------------------------------------

2LIBRARY ieee;

3 USE ieee.std_logic_1164.all;

4 ---------------------------------------

5ENTITY mux IS

6PORT ( a, b, c, d, s0, s1: IN STD_LOGIC;

7

y: OUT STD_LOGIC);

8

END mux;

9

---------------------------------------

10

ARCHITECTURE pure_logic OF mux IS

11BEGIN

12y <= (a AND NOT s1 AND NOT s0) OR

13(b AND NOT s1 AND s0) OR

14(c AND s1 AND NOT s0) OR

15(d AND s1 AND s0);

16END pure_logic;

17 ---------------------------------------

Simulation results, confirming the functionality of the circuit, are shown in figure 5.4.

TLFeBOOK


Concurrent Code

69

Figure 5.4

Simulation results of example 5.1.

5.3WHEN (Simple and Selected)

As mentioned above, WHEN is one of the fundamental concurrent statements (along with operators and GENERATE). It appears in two forms: WHEN / ELSE (simple WHEN) and WITH / SELECT / WHEN (selected WHEN). Its syntax is shown below.

WHEN / ELSE:

assignment WHEN condition ELSE assignment WHEN condition ELSE

...;

WITH / SELECT / WHEN:

WITH identifier SELECT assignment WHEN value, assignment WHEN value,

...;

Whenever WITH / SELECT / WHEN is used, all permutations must be tested, so the keyword OTHERS is often useful. Another important keyword is UNAFFECTED, which should be used when no action is to take place.

TLFeBOOK

70

Chapter 5

Example:

------ With WHEN/ELSE -------------------------

outp <= "000" WHEN (inp='0' OR reset='1') ELSE "001" WHEN ctl='1' ELSE

"010";

---- With WITH/SELECT/WHEN --------------------

WITH control SELECT

output <= "000" WHEN reset, "111" WHEN set,

UNAFFECTED WHEN OTHERS;

-----------------------------------------------

Another important aspect related to the WHEN statement is that the ‘‘WHEN value’’ shown in the syntax above can indeed take up three forms:

WHEN value

-- single value

WHEN

value1 to value2

-- range, for enumerated data types

--

only

WHEN

value1 | value2 |...

--

value1 or value2 or ...

Example 5.2: Multiplexer #2

This example shows the implementation of the same multiplexer of example 5.1, but with a slightly di¤erent representation for the sel input (figure 5.5). However, in it WHEN was employed instead of logical operators. Two solutions are presented: one using WHEN/ELSE (simple WHEN) and the other with WITH/SELECT/WHEN (selected WHEN). The experimental results are obviously similar to those obtained in example 5.1.

a

b

MUX y

c

d

sel (1:0)

Figure 5.5

Multiplexer of example 5.2.

TLFeBOOK

Concurrent Code

71

1 ------- Solution 1: with WHEN/ELSE --------

2LIBRARY ieee;

3 USE ieee.std_logic_1164.all;

4 -------------------------------------------

5ENTITY mux IS

6PORT ( a, b, c, d: IN STD_LOGIC;

7sel: IN STD_LOGIC_VECTOR (1 DOWNTO 0);

8

y: OUT STD_LOGIC);

9

END mux;

10

-------------------------------------------

11

ARCHITECTURE mux1 OF mux IS

12BEGIN

13y <= a WHEN sel="00" ELSE

14b WHEN sel="01" ELSE

15c WHEN sel="10" ELSE

16d;

17END mux1;

18 -------------------------------------------

1 --- Solution 2: with WITH/SELECT/WHEN -----

2LIBRARY ieee;

3 USE ieee.std_logic_1164.all;

4 -------------------------------------------

5ENTITY mux IS

6PORT ( a, b, c, d: IN STD_LOGIC;

7sel: IN STD_LOGIC_VECTOR (1 DOWNTO 0);

8

y: OUT STD_LOGIC);

9

END mux;

10

-------------------------------------------

11

ARCHITECTURE mux2 OF mux IS

12BEGIN

13WITH sel SELECT

14y <= a WHEN "00", -- notice "," instead of ";"

15b WHEN "01",

16c WHEN "10",

17

d WHEN OTHERS;

-- cannot be "d WHEN "11" "

18

END mux2;

19

--------------------------------------------

TLFeBOOK


72

Chapter 5

In the solutions above, sel could have been declared as an INTEGER, in which case the code would be the following:

1 ----------------------------------------------

2LIBRARY ieee;

3 USE ieee.std_logic_1164.all;

4 ----------------------------------------------

5ENTITY mux IS

6PORT ( a, b, c, d: IN STD_LOGIC;

7sel: IN INTEGER RANGE 0 TO 3;

8

y: OUT STD_LOGIC);

9END mux;

10 ---- Solution 1: with WHEN/ELSE ---------------

11 ARCHITECTURE mux1 OF mux IS

12BEGIN

13y <= a WHEN sel=0 ELSE

14b WHEN sel=1 ELSE

15c WHEN sel=2 ELSE

16d;

17END mux1;

18-- Solution 2: with WITH/SELECT/WHEN --------

19ARCHITECTURE mux2 OF mux IS

20BEGIN

21WITH sel SELECT

22y <= a WHEN 0,

23b WHEN 1,

24c WHEN 2,

25d WHEN 3; -- here, 3 or OTHERS are equivalent,

26

END mux2;

-- for all options are tested anyway

27

-----------------------------------------------

Note: Only one ARCHITECTURE can be synthesized at a time. Therefore, whenever we show more than one solution within the same overall code (like above), it is implicit that all solutions but one must be commented out (with ‘‘- -’’), or a synthesis script must be used, in order to synthesize the remaining solution. In simulations, the CONFIGURATION statement can be used to select a specific architecture.

Note: For a generic mux, please refer to problem 5.1.

TLFeBOOK

Concurrent Code

73

ena

input (7:0)

output (7:0)

Figure 5.6

Tri-state bu¤er of example 5.3.

Example 5.3: Tri-state Bu¤er

This is another example that illustrates the use of WHEN. The 3-state bu¤er of figure 5.6 must provide output ¼ input when ena (enable) is low, or output ¼ ‘‘ZZZZZZZZ’’ (high impedance) otherwise.

1LIBRARY ieee;

2 USE ieee.std_logic_1164.all;

3 ----------------------------------------------

4ENTITY tri_state IS

5PORT ( ena: IN STD_LOGIC;

6input: IN STD_LOGIC_VECTOR (7 DOWNTO 0);

7

output: OUT STD_LOGIC_VECTOR (7 DOWNTO 0));

8

END tri_state;

9

----------------------------------------------

10

ARCHITECTURE tri_state OF tri_state IS

11BEGIN

12output <= input WHEN (ena='0') ELSE

13

(OTHERS => 'Z');

14

END tri_state;

15

----------------------------------------------

Simulation results from the circuit synthesized with the code above are shown in figure 5.7. As expected, the output stays in the high-impedance state while ena is high, being a copy of the input when ena is turned low.

Example 5.4: Encoder

The top-level diagram of an n-by-m encoder is shown in figure 5.8. We assume that n is a power of two, so m ¼ log2n. One and only one input bit is expected to be high at a time, whose address must be encoded at the output. Two solutions are presented, one using WHEN / ELSE, and the other with WITH / SELECT / WHEN.

TLFeBOOK


74

Chapter 5

Figure 5.7

Simulation results of example 5.3.

x(n-1)

x(n-2)

n x m

(m-1:0)

ENCODER

x(1)

x(0)

Figure 5.8

Encoder of example 5.4.

1 ---- Solution 1: with WHEN/ELSE -------------

2LIBRARY ieee;

3 USE ieee.std_logic_1164.all;

4 ---------------------------------------------

5ENTITY encoder IS

6PORT ( x: IN STD_LOGIC_VECTOR (7 DOWNTO 0);

7

y: OUT STD_LOGIC_VECTOR (2 DOWNTO 0));

8

END encoder;

9

---------------------------------------------

10

ARCHITECTURE encoder1 OF encoder IS

11

BEGIN

12

y <=

"000" WHEN x="00000001" ELSE

13"001" WHEN x="00000010" ELSE

14"010" WHEN x="00000100" ELSE

15"011" WHEN x="00001000" ELSE

16"100" WHEN x="00010000" ELSE

17"101" WHEN x="00100000" ELSE

18"110" WHEN x="01000000" ELSE

19"111" WHEN x="10000000" ELSE

20"ZZZ";

TLFeBOOK