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

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

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

Добавлен: 13.06.2025

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

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

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

Sequential Code

101

WHEN "01" => x<=b; y<=c;

WHEN OTHERS => x<="0000"; y<="ZZZZ";

END CASE;

The CASE statement (sequential) is very similar to WHEN (combinational). Here too all permutations must be tested, so the keyword OTHERS is often helpful. Another important keyword is NULL (the counterpart of UNAFFECTED), which should be used when no action is to take place. For example, WHEN OTHERS => NULL;. However, CASE allows multiple assignments for each test condition (as shown in the example above), while WHEN allows only one.

Like in the case of WHEN (section 5.3), here too ‘‘WHEN value’’ can 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 6.6: DFF with Asynchronous Reset #3

The code below implements the same DFF of example 6.1 (figures 6.1 and 6.2). However, here CASE was used instead of IF only. Notice that a few unnecessary declarations were intentionally included in the code to illustrate their usage.

1

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

2

LIBRARY ieee;

-- Unnecessary declaration,

3

-- because

4USE ieee.std_logic_1164.all; -- BIT was used instead of

5

-- STD_LOGIC

6

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

7ENTITY dff IS

8PORT (d, clk, rst: IN BIT;

9

q: OUT BIT);

10

END dff;

11

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

12

ARCHITECTURE dff3 OF dff IS

13BEGIN

14PROCESS (clk, rst)

15BEGIN

16CASE rst IS

TLFeBOOK


102

Chapter 6

SSD

C

a

O

U

f

b

clk

N

T

digit2

g

e

c

E

R

digit1

d

x

reset

Input: “xabcdefg”

Figure 6.7

2-digit counter of example 6.7.

17WHEN '1' => q<='0';

18WHEN '0' =>

19IF (clk'EVENT AND clk='1') THEN

20

q <= d;

21

END IF;

22

WHEN OTHERS => NULL;

--

Unnecessary, rst is of type

23

--

BIT

24END CASE;

25END PROCESS;

26END dff3;

27----------------------------------------------

Example 6.7: Two-digit Counter with SSD Output

The code below implements a progressive 2-digit decimal counter (0 ! 99 ! 0), with external asynchronous reset plus binary-coded decimal (BCD) to seven-segment display (SSD) conversion. Diagrams of the circuit and SSD are shown in figure 6.7. The CASE statement (lines 31–56) was employed to determine the output signals that will feed the SSDs. Notice that we have chosen the following connection between the circuit and the SSD: xabcdefg (that is, the MSB feeds the decimal point, while the LSB feeds segment g).

As can be seen, this circuit is a straight extension of that presented in example 6.2, with the di¤erences that now two digits are necessary rather than one, and that the outputs must be connected to SSD displays. The operation of the circuit can be verified in the simulation results of figure 6.8.

TLFeBOOK


Sequential Code

103

Figure 6.8

Simulation results of example 6.7.

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

2LIBRARY ieee;

3 USE ieee.std_logic_1164.all;

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

5ENTITY counter IS

6PORT (clk, reset : IN STD_LOGIC;

7

digit1, digit2 : OUT STD_LOGIC_VECTOR (6 DOWNTO 0));

8

END counter;

9

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

10 ARCHITECTURE

counter OF counter IS

11BEGIN

12PROCESS(clk, reset)

13VARIABLE temp1: INTEGER RANGE 0 TO 10;

14VARIABLE temp2: INTEGER RANGE 0 TO 10;

15BEGIN

16---- counter: ----------------------

17IF (reset='1') THEN

18temp1 := 0;

19temp2 := 0;

20ELSIF (clk'EVENT AND clk='1') THEN

21temp1 := temp1 + 1;

22IF (temp1=10) THEN

23temp1 := 0;

24temp2 := temp2 + 1;

25IF (temp2=10) THEN

26

temp2 := 0;

TLFeBOOK

104

Chapter 6

27END IF;

28END IF;

29END IF;

30---- BCD to SSD conversion: --------

31CASE temp1 IS

32

WHEN 0 => digit1 <= "1111110";

--7E

33

WHEN 1 => digit1 <= "0110000";

--30

34

WHEN 2 => digit1 <= "1101101";

--6D

35

WHEN 3 => digit1 <= "1111001";

--79

36

WHEN 4 => digit1 <= "0110011";

--33

37

WHEN 5 => digit1 <= "1011011";

--5B

38

WHEN 6

=> digit1 <= "1011111";

--5F

39

WHEN 7

=> digit1 <= "1110000";

--70

40

WHEN 8

=> digit1 <= "1111111";

--7F

41

WHEN 9

=> digit1 <= "1111011";

--7B

42WHEN OTHERS => NULL;

43END CASE;

44CASE temp2 IS

45

WHEN 0 => digit2 <= "1111110";

--7E

46

WHEN 1 => digit2 <= "0110000";

--30

47

WHEN 2 => digit2 <= "1101101";

--6D

48

WHEN 3 => digit2 <= "1111001";

--79

49

WHEN 4 => digit2 <= "0110011";

--33

50

WHEN 5 => digit2 <= "1011011";

--5B

51

WHEN 6

=> digit2 <= "1011111";

--5F

52

WHEN 7

=> digit2 <= "1110000";

--70

53

WHEN 8

=> digit2 <= "1111111";

--7F

54

WHEN 9

=> digit2 <= "1111011";

--7B

55WHEN OTHERS => NULL;

56END CASE;

57END PROCESS;

58END counter;

59--------------------------------------------------

Comment: Notice above that the same routine was repeated twice (using CASE statements). We will learn, in Part II, how to write and compile frequently used pieces of code into user-defined libraries, so that such repetitions can be avoided.

TLFeBOOK


Sequential Code

105

6.6LOOP

As the name says, LOOP is useful when a piece of code must be instantiated several times. Like IF, WAIT, and CASE, LOOP is intended exclusively for sequential code, so it too can only be used inside a PROCESS, FUNCTION, or PROCEDURE.

There are several ways of using LOOP, as shown in the syntaxes below.

FOR / LOOP: The loop is repeated a fixed number of times.

[label:] FOR identifier IN range LOOP (sequential statements)

END LOOP [label];

WHILE / LOOP: The loop is repeated until a condition no longer holds.

[label:] WHILE condition LOOP (sequential statements)

END LOOP [label];

EXIT: Used for ending the loop.

[label:] EXIT [label] [WHEN condition];

NEXT: Used for skipping loop steps.

[label:] NEXT [loop_label] [WHEN condition];

Example of FOR / LOOP:

FOR i IN 0 TO 5 LOOP

x(i) <= enable AND w(i+2);

y(0, i) <= w(i);

END LOOP;

In the code above, the loop will be repeated unconditionally until i reaches 5 (that is, six times).

TLFeBOOK

106

Chapter 6

One important remark regarding FOR / LOOP (similar to that made for GENERATE, in chapter 5) is that both limits of the range must be static. Thus a declaration of the type "FOR i IN 0 TO choice LOOP", where choice is an input (nonstatic) parameter, is generally not synthesizable.

Example of WHILE / LOOP: In this example, LOOP will keep repeating while i < 10.

WHILE (i < 10) LOOP

WAIT UNTIL clk'EVENT AND clk='1';

(other statements)

END LOOP;

Example with EXIT: In the code below, EXIT implies not an escape from the current iteration of the loop, but rather a definite exit (that is, even if i is still within the data range, the LOOP statement will be considered as concluded). In this case, the loop will end as soon as a value di¤erent from ‘0’ is found in the data vector.

FOR i IN data'RANGE LOOP

CASE data(i) IS

WHEN '0' => count:=count+1;

WHEN OTHERS => EXIT;

END CASE;

END LOOP;

Example with NEXT: In the example below, NEXT causes LOOP to skip one iteration when i ¼ skip.

FOR i IN 0 TO 15 LOOP

NEXT WHEN i=skip;

-- jumps to next iteration

(...)

END LOOP;

Several complete design examples, illustrating various applications of LOOP, are presented below.

Example 6.8: Carry Ripple Adder

Figure 6.9 shows an 8-bit unsigned carry ripple adder. The top-level diagram shows the inputs and outputs of the circuit: a and b are the input vectors to be added, cin is the carry-in bit, s is the sum vector, and cout is the carry-out bit. The one-level- below-top diagram shows how the carry bits propagate (ripple).

TLFeBOOK

Sequential Code

107

Top level:

One level below top:

a0

b0

a1 b1

a7 b7

a

s

b

+

c0

+

+

+

c8

c1

c2

c7

cin

cout

(cin

(cout)

s0

s1

s7

Figure 6.9

8-bit carry ripple adder of example 6.8

Figure 6.10

Simulation results of example 6.8.

Each section of the latter diagram is a full-adder unit (section 1.4). Thus its outputs can be computed by means of:

sj ¼ aj XOR bj XOR cj

cjþ1 ¼ (aj AND bj) OR (aj AND cj) OR (bj AND cj)

Two solutions are presented, being one generic (that is, for any number of bits, based on what we saw in chapter 4) and the other specific for 8-bit numbers. Moreover, we illustrate the use of vectors and FOR/LOOP in the first solution, and of integers and IF in the second. Simulation results from either solution are shown in figure 6.10.

Note: We will see more about adders in chapter 9.

1 ----- Solution 1: Generic, with VECTORS --------

2LIBRARY ieee;

3USE ieee.std_logic_1164.all;

TLFeBOOK


108

Chapter 6

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

5ENTITY adder IS

6GENERIC (length : INTEGER := 8);

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

8cin: IN STD_LOGIC;

9s: OUT STD_LOGIC_VECTOR (length-1 DOWNTO 0);

10cout: OUT STD_LOGIC);

11END adder;

12 ------------------------------------------------

13 ARCHITECTURE adder OF adder IS

14BEGIN

15PROCESS (a, b, cin)

16VARIABLE carry : STD_LOGIC_VECTOR (length DOWNTO 0);

17BEGIN

18carry(0) := cin;

19FOR i IN 0 TO length-1 LOOP

20s(i) <= a(i) XOR b(i) XOR carry(i);

21carry(i+1) := (a(i) AND b(i)) OR (a(i) AND

22

carry(i)) OR (b(i) AND carry(i));

23END LOOP;

24cout <= carry(length);

25END PROCESS;

26END adder;

27 ------------------------------------------------

1 ---- Solution 2: non-generic, with INTEGERS ----

2LIBRARY ieee;

3 USE ieee.std_logic_1164.all;

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

5ENTITY adder IS

6PORT ( a, b: IN INTEGER RANGE 0 TO 255;

7c0: IN STD_LOGIC;

8s: OUT INTEGER RANGE 0 TO 255;

9

c8: OUT STD_LOGIC);

10

END adder;

11

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

12

ARCHITECTURE adder OF adder IS

13

BEGIN

TLFeBOOK

Sequential Code

109

14PROCESS (a, b, c0)

15VARIABLE temp : INTEGER RANGE 0 TO 511;

16BEGIN

17IF (c0='1') THEN temp:=1;

18ELSE temp:=0;

19END IF;

20temp := a + b + temp;

21IF (temp > 255) THEN

22c8 <= '1';

23

temp := temp---

256;

24ELSE c8 <= '0';

25END IF;

26s <= temp;

27END PROCESS;

28END adder;

29 ------------------------------------------------

Example 6.9: Simple Barrel Shifter

Figure 6.11 shows the diagram of a very simple barrel shifter. In this case, the circuit must shift the input vector (of size 8) either 0 or 1 position to the left. When actually shifted (shift ¼ 1), the LSB bit must be filled with ‘0’ (shown in the botton left corner of the diagram). If shift ¼ 0, then outp ¼ inp; if shift ¼ 1, then outp(0) ¼ ‘0’ and outp(i) ¼ inp(i 1), for 1 ai a7.

A complete VHDL code is presented below, which illustrates the use of FOR/ LOOP. Simulation results appear in figure 6.12.

Note: A complete barrel shifter (with shift ¼ 0 to n 1, where n is the size of the input vector) will be seen in chapter 9.

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

2LIBRARY ieee;

3 USE ieee.std_logic_1164.all;

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

5ENTITY barrel IS

6GENERIC (n: INTEGER := 8);

7PORT ( inp: IN STD_LOGIC_VECTOR (n-1 DOWNTO 0);

8shift: IN INTEGER RANGE 0 TO 1;

9

outp: OUT STD_LOGIC_VECTOR (n-1 DOWNTO 0));

TLFeBOOK