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

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

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

Добавлен: 13.06.2025

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

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

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

Concurrent Code

75

21 END encoder1;

22 ---------------------------------------------

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

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

encoder2 OF encoder IS

11BEGIN

12WITH x SELECT

13

y <=

"000" WHEN "00000001",

14

"001" WHEN "00000010",

15

"010" WHEN "00000100",

16

"011" WHEN "00001000",

17

"100" WHEN "00010000",

18

"101" WHEN "00100000",

19

"110" WHEN "01000000",

20

"111" WHEN "10000000",

21

"ZZZ" WHEN OTHERS;

22

END encoder2;

23

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

Notice that the code above has a long test list (lines 12–20 in solution 1, lines 13– 21 in solution 2). The situation becomes even more cumbersome when the number of selection bits grows. In such a case, the GENERATE statement (section 5.4) or the LOOP statement (section 6.6) can be employed.

Simulation results (from either solution) are shown in figure 5.9.

Example 5.5: ALU

An ALU (Arithmetic Logic Unit) is shown in figure 5.10. As the name says, it is a circuit capable of executing both kinds of operations, arithmetic as well as logical. Its operation is described in the truth table of figure 5.10. The output (arithmetic or logical) is selected by the MSB of sel, while the specific operation is selected by sel’s other three bits.

TLFeBOOK


76

Chapter 5

Figure 5.9

Simulation results of example 5.4.

a (7:0)

Logic

b (7:0)

Unit

Mux

y (7:0)

Arithmetic

sel (3)

cin

Unit

sel (3:0)

sel

Operation

Function

Unit

0000

y <= a

Transfer a

0001

y <= a+1

Increment a

0010

y <= a-1

Decrement a

0011

y <= b

Transfer b

Arithmetic

0100

y <= b+1

Increment b

0101

y <= b-1

Decrement b

0110

y <= a+b

Add a and b

0111

y <= a+b+cin

Add a and b with carry

1000

y <= NOT a

Complement a

1001

y <= NOT b

Complement b

1010

y <= a AND b

AND

1011

y <= a OR b

OR

Logic

1100

y <= a NAND b

NAND

1101

y <= a NOR b

NOR

1110

y <= a XOR b

XOR

1111

y <= a XNOR b

XNOR

Figure 5.10

ALU of example 5.5.

TLFeBOOK


Concurrent Code

77

Figure 5.11

Simulation results of example 5.5.

The solution presented below, besides using only concurrent code, also illustrates the use of the same data type to perform both arithmetic and logical operations. That is possible due to the presence of the std_logic_unsigned package of the ieee library (discussed in section 3.6). Two signals, arith and logic, are used to hold the results from the arithmetic and logic units, respectively, being the value passed to the output selected by the multiplexer. Simulation results are shown in figure 5.11.

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

2LIBRARY ieee;

3USE ieee.std_logic_1164.all;

4 USE ieee.std_logic_unsigned.all;

5 ----------------------------------------------

6ENTITY ALU IS

7PORT (a, b: IN STD_LOGIC_VECTOR (7 DOWNTO 0);

8

sel: IN STD_LOGIC_VECTOR (3 DOWNTO 0);

9

cin: IN STD_LOGIC;

10

y: OUT STD_LOGIC_VECTOR (7 DOWNTO 0));

11

END ALU;

12

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

13

ARCHITECTURE dataflow OF ALU IS

14SIGNAL arith, logic: STD_LOGIC_VECTOR (7 DOWNTO 0);

15BEGIN

16----- Arithmetic unit: ------

17WITH sel(2 DOWNTO 0) SELECT

18arith <= a WHEN "000",

19

a+1

WHEN "001",

20

a-1

WHEN

"010",

21

b WHEN "011",

22

b+1

WHEN

"100",

TLFeBOOK

78

Chapter 5

23

b-1 WHEN "101",

24

a+b WHEN "110",

25

a+b+cin WHEN OTHERS;

26----- Logic unit: -----------

27WITH sel(2 DOWNTO 0) SELECT

28logic <= NOT a WHEN "000",

29

NOT b

WHEN "001",

30

a AND

b WHEN "010",

31

a OR b WHEN "011",

32

a NAND b WHEN "100",

33

a NOR b WHEN "101",

34

a XOR b WHEN "110",

35

NOT (a XOR b) WHEN OTHERS;

36-------- Mux: ---------------

37WITH sel(3) SELECT

38y <= arith WHEN '0',

39logic WHEN OTHERS;

40END dataflow;

41----------------------------------------------

5.4GENERATE

GENERATE is another concurrent statement (along with operators and WHEN). It is equivalent to the sequential statement LOOP (chapter 6) in the sense that it allows a section of code to be repeated a number of times, thus creating several instances of the same assignments. Its regular form is the FOR / GENERATE construct, with the syntax shown below. Notice that GENERATE must be labeled.

FOR / GENERATE:

label: FOR identifier IN range GENERATE (concurrent assignments)

END GENERATE;

An irregular form is also available, which uses IF/GENERATE (with an IF equivalent; recall that originally IF is a sequential statement). Here ELSE is not allowed. In the same way that IF/GENERATE can be nested inside FOR/ GENERATE (syntax below), the opposite can also be done.

TLFeBOOK


Concurrent Code

79

IF / GENERATE nested inside FOR / GENERATE:

label1: FOR identifier IN range GENERATE

...

label2: IF condition GENERATE (concurrent assignments)

END GENERATE;

...

END GENERATE;

Example:

SIGNAL x: BIT_VECTOR (7 DOWNTO 0);

SIGNAL y: BIT_VECTOR (15 DOWNTO 0);

SIGNAL z: BIT_VECTOR (7 DOWNTO 0);

...

G1: FOR i IN x'RANGE GENERATE z(i) <= x(i) AND y(i+8);

END GENERATE;

One important remark about GENERATE (and the same is true for LOOP, which will be seen in chapter 6) is that both limits of the range must be static. As an example, let us consider the code below, where choice is an input (non-static) parameter. This kind of code is generally not synthesizable.

NotOK: FOR i IN 0 TO choice GENERATE

(concurrent statements)

END GENERATE;

We also must to be aware of multiply-driven (unresolved) signals. For example,

OK: FOR i IN 0 TO 7 GENERATE

output(i)<='1' WHEN (a(i) AND b(i))='1' ELSE '0';

END GENERATE;

is fine. However, the compiler will complain that accum is multiply driven (and stop compilation) in either of the following two cases:

NotOK: FOR i IN 0 TO 7 GENERATE

accum <="11111111" WHEN (a(i) AND b(i))='1' ELSE "00000000";

END GENERATE;

TLFeBOOK

80

Chapter 5

NotOK: For i IN 0 to 7 GENERATE accum <= accum + 1 WHEN x(i)='1';

END GENERATE;

Example 5.6: Vector Shifter

This example illustrates the use of GENERATE. In it, the output vector must be a shifted version of the input vector, with twice its width and an amount of shift specified by another input. For example, if the input bus has width 4, and the present value is ‘‘1111’’, then the output should be one of the lines of the following matrix (the original vector is underscored):

row(0): 0 0 0 0 1 1 1 1

row(1): 0 0 0 1 1 1 1 0

row(2): 0 0 1 1 1 1 0 0

row(3): 0 1 1 1 1 0 0 0

row(4): 1 1 1 1 0 0 0 0

The first row corresponds to the input itself, with no shift and the most significant bits filled with ‘0’s. Each successive row is equal to the previous row shifted one position to the left.

The solution below has input inp, output outp, and shift selection sel. Each row of the array above (called matrix, line 14) is defined as subtype vector (line 12).

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

2LIBRARY ieee;

3 USE ieee.std_logic_1164.all;

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

5ENTITY shifter IS

6PORT ( inp: IN STD_LOGIC_VECTOR (3 DOWNTO 0);

7sel: IN INTEGER RANGE 0 TO 4;

8

outp: OUT STD_LOGIC_VECTOR (7 DOWNTO 0));

9

END shifter;

10

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

11

ARCHITECTURE

shifter OF shifter IS

12SUBTYPE vector IS STD_LOGIC_VECTOR (7 DOWNTO 0);

13TYPE matrix IS ARRAY (4 DOWNTO 0) OF vector;

14SIGNAL row: matrix;

15BEGIN

TLFeBOOK


Concurrent Code

81

Figure 5.12

Simulation results of example 5.6.

16row(0) <= "0000" & inp;

17G1: FOR i IN 1 TO 4 GENERATE

18row(i) <= row(i-1)(6 DOWNTO 0) & '0';

19END GENERATE;

20outp <= row(sel);

21END shifter;

22------------------------------------------------

Simulation results are presented in figure 5.12. As can be seen, inp ¼ ‘‘0011’’ (decimal 3) was applied to the circuit. The result was outp ¼ ‘‘00000011’’ (decimal 3) when sel ¼ 0 (no shift), outp ¼ ‘‘00000110’’ (decimal 6) when sel ¼ 1 (one shift to the left), outp ¼ ‘‘00001100’’ (decimal 12) when sel ¼ 2 (two shifts to the left), and so on.

5.5BLOCK

There are two kinds of BLOCK statements: Simple and Guarded.

Simple BLOCK

The BLOCK statement, in its simple form, represents only a way of locally partitioning the code. It allows a set of concurrent statements to be clustered into a BLOCK, with the purpose of turning the overall code more readable and more manageable (which might be helpful when dealing with long codes). Its syntax is shown below.

label: BLOCK [declarative part]

BEGIN

(concurrent statements) END BLOCK label;

TLFeBOOK

82

Chapter 5

Therefore, the overall aspect of a ‘‘blocked’’ code is the following:

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

ARCHITECTURE example ...

BEGIN

...

block1: BLOCK

BEGIN

...

END BLOCK block1

...

block2: BLOCK

BEGIN

...

END BLOCK block2;

...

END example;

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

Example:

b1: BLOCK

SIGNAL a: STD_LOGIC;

BEGIN

a <= input_sig

WHEN ena='1' ELSE 'Z';

END BLOCK b1;

A BLOCK (simple or guarded) can be nested inside another BLOCK. The corresponding syntax is shown below.

label1: BLOCK

[declarative part of top block] BEGIN

[concurrent statements of top block] label2: BLOCK

[declarative part nested block] BEGIN

(concurrent statements of nested block) END BLOCK label2;

[more concurrent statements of top block] END BLOCK label1;

TLFeBOOK

Concurrent Code

83

Note: Although code partitioning techniques are the object of Part II of the book, and the BLOCK statement seen above serves exactly to this purpose, BLOCK is described in this section due to the fact that it is self-contained within the main code (that is, it does not invoke any extra PACKAGE, COMPONENT, FUNCTION, or PROCEDURE—these four units are the actual focus of Part II).

Guarded BLOCK

A guarded BLOCK is a special kind of BLOCK, which includes an additional expression, called guard expression. A guarded statement in a guarded BLOCK is executed only when the guard expression is TRUE.

Guarded BLOCK:

label: BLOCK (guard expression) [declarative part]

BEGIN

(concurrent guarded and unguarded statements) END BLOCK label;

As the examples below illustrate, even though only concurrent statements can be written within a BLOCK, with a guarded BLOCK even sequential circuits can be constructed. This, however, is not a usual design approach.

Example 5.7: Latch Implemented with a Guarded BLOCK

The example presented below implements a transparent latch. In it, clk='1' (line 12) is the guard expression, while q<=GUARDED d (line 14) is a guarded statement. Therefore, q<=d will only occur if clk='1'.

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

2LIBRARY ieee;

3USE ieee.std_logic_1164.all;

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

5ENTITY latch IS

6PORT (d, clk: IN STD_LOGIC;

7

q: OUT STD_LOGIC);

8END latch;

9 -------------------------------

10 ARCHITECTURE latch OF latch IS

TLFeBOOK