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

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

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

Добавлен: 13.06.2025

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

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

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

Functions and Procedures

255

------ Function body: -------------------------------

FUNCTION positive_edge(SIGNAL s: STD_LOGIC) RETURN BOOLEAN IS BEGIN

RETURN (s'EVENT AND s='1');

END positive_edge;

------ Function call: -------------------------------

...

IF positive_edge(clk) THEN...

...

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

Example 11.2: Function conv_integer( )

The FUNCTION presented next converts a parameter of type STD_LOGIC_ VECTOR into an INTEGER. Notice that the code is generic, that is, it works for any range or order (TO/DOWNTO) of the input STD_LOGIC_VECTOR parameter. A typical call to the function is also shown.

------ Function body: -------------------------------

FUNCTION conv_integer (SIGNAL vector: STD_LOGIC_VECTOR) RETURN INTEGER IS

VARIABLE result: INTEGER RANGE 0 TO 2**vector'LENGTH-1; BEGIN

IF (vector(vector'HIGH)='1') THEN result:=1;

ELSE result:=0;

END IF;

FOR i IN (vector'HIGH-1) DOWNTO (vector'LOW) LOOP

result:=result*2;

IF(vector(i)='1') THEN result:=result+1;

END IF;

END LOOP;

RETURN result;

END conv_integer;

------ Function call: -------------------------------

...

y <= conv_integer(a);

...

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

TLFeBOOK

256

Chapter 11

PACKAGE

LIBRARY

(+ PACKAGE BODY)

FUNCTION /

PROCEDURE

ARCHITECTURE

location

(declarative part)

Main code

ENTITY

Figure 11.1

Typical locations of a FUNCTION or PROCEDURE.

11.2 Function Location

The typical locations of a FUNCTION (or PROCEDURE) are depicted in figure 11.1. Though a FUNCTION is usually placed in a PACKAGE (for code partitioning, code reuse, and code sharing purposes), it can also be located in the main code (either inside the ARCHITECTURE or inside the ENTITY).

When placed in a PACKAGE, then a PACKAGE BODY is necessary, which must contain the body of each FUNCTION (or PROCEDURE) declared in the declarative part of the PACKAGE. Examples of both cases are presented below.

Example 11.3: FUNCTION Located in the Main Code

Let us consider the positive_edge( ) function of example 11.1 As mentioned above, when installed in the main code itself, the function can be located either in the ENTITY or in the declarative part of the ARCHITECTURE. In the present example, the function appears in the latter, and is used to construct a DFF.

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

2LIBRARY ieee;

3 USE ieee.std_logic_1164.all;

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

5ENTITY dff IS

6PORT ( d, clk, rst: IN STD_LOGIC;

7

q: OUT STD_LOGIC);

8

END dff;

9

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

10

ARCHITECTURE my_arch OF dff IS

11

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

TLFeBOOK


Functions and Procedures

257

12FUNCTION positive_edge(SIGNAL s: STD_LOGIC)

13RETURN BOOLEAN IS

14BEGIN

15RETURN s'EVENT AND s='1';

16END positive_edge;

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

18BEGIN

19PROCESS (clk, rst)

20BEGIN

21IF (rst='1') THEN q <= '0';

22ELSIF positive_edge(clk) THEN q <= d;

23END IF;

24END PROCESS;

25END my_arch;

26 ---------------------------------------------

Example 11.4: FUNCTION Located in a PACKAGE

This example is similar to example 11.3, with the only di¤erence being that the FUNCTION located in a PACKAGE can now be reused and shared by other projects. Notice that, when placed in a PACKAGE, the function is indeed declared in the PACKAGE, but described in the PACKAGE BODY.

Below two VHDL codes are presented, being one relative to the construction of the FUNCTION / PACKAGE, while the other is an example where a call to the FUNCTION is made. The two codes can be compiled as two separate files, or can be compiled as a single file (saved as d¤.vhd, which is the ENTITY’s name). Notice the inclusion of ‘‘USE work.my_package.all;’’ in the main code (line 4).

1 -------

Package: -----------------------------

2LIBRARY ieee;

3 USE ieee.std_logic_1164.all;

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

5PACKAGE my_package IS

6 FUNCTION positive_edge(SIGNAL s: STD_LOGIC) RETURN BOOLEAN; 7 END my_package;

8 ----------------------------------------------

9PACKAGE BODY my_package IS

10FUNCTION positive_edge(SIGNAL s: STD_LOGIC)

11RETURN BOOLEAN IS

TLFeBOOK

258

Chapter 11

12BEGIN

13RETURN s'EVENT AND s='1';

14END positive_edge;

15END my_package;

16

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

1 ------

Main code: ----------------------------

2LIBRARY ieee;

3 USE ieee.std_logic_1164.all;

4 USE work.my_package.all;

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

6ENTITY dff IS

7PORT ( d, clk, rst: IN STD_LOGIC;

8

q: OUT STD_LOGIC);

9

END dff;

10

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

11

ARCHITECTURE my_arch OF dff IS

12BEGIN

13PROCESS (clk, rst)

14BEGIN

15IF (rst='1') THEN q <= '0';

16ELSIF positive_edge(clk) THEN q <= d;

17END IF;

18END PROCESS;

19END my_arch;

20 ----------------------------------------------

Example 11.5: Function conv_integer( )

The conv_integer( ) function shown below was already seen in example 11.2; it converts a STD_LOGIC_VECTOR value into an INTEGER value. Below, the function was placed in a PACKAGE (plus PACKAGE BODY). A call to this function appears in the main code that follows the function implementation.

1 ---------

Package: ---------------------------

2LIBRARY ieee;

3 USE ieee.std_logic_1164.all;

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

5 PACKAGE my_package IS

TLFeBOOK


Functions and Procedures

259

6 FUNCTION conv_integer (SIGNAL vector: STD_LOGIC_VECTOR) 7 RETURN INTEGER;

8 END my_package;

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

10 PACKAGE BODY my_package IS

11FUNCTION conv_integer (SIGNAL vector: STD_LOGIC_VECTOR)

12RETURN INTEGER IS

13VARIABLE result: INTEGER RANGE 0 TO 2**vector'LENGTH-1;

14BEGIN

15IF (vector(vector'HIGH)='1') THEN result:=1;

16ELSE result:=0;

17END IF;

18FOR i IN (vector'HIGH-1) DOWNTO (vector'LOW) LOOP

19result:=result*2;

20IF(vector(i)='1') THEN result:=result+1;

21END IF;

22END LOOP;

23RETURN result;

24END conv_integer;

25END my_package;

26

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

1 --------

Main code: --------------------------

2LIBRARY ieee;

3 USE ieee.std_logic_1164.all;

4 USE work.my_package.all;

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

6ENTITY conv_int2 IS

7PORT ( a: IN STD_LOGIC_VECTOR(0 TO 3);

8

y: OUT INTEGER RANGE 0 TO 15);

9

END conv_int2;

10

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

11

ARCHITECTURE my_arch OF conv_int2 IS

12BEGIN

13y <= conv_integer(a);

14END my_arch;

15 ----------------------------------------------

TLFeBOOK

260

Chapter 11

Example 11.6: Overloaded ‘‘B’’ Operator

The function shown below, called ‘‘þ’’, overloads the pre-defined ‘‘þ’’ (addition) operator (section 4.1 and section 4.4). Recall that the latter accepts only INTEGER, SIGNED, or UNSIGNED values. However, we are interested in writing a function which should allow the sum of STD_LOGIC_VECTOR values as well (thus overloading the ‘‘þ’’ operator).

The function shown below was placed in a PACKAGE (plus PACKAGE BODY). An example utilizing this function is also presented in the main code that follows the function implementation. Notice that the two parameters passed to the function, as well as the return value, are all of type STD_LOGIC_VECTOR. We assume that they all have the same number of bits (an extension to this example is presented in problem 11.8).

1 --------

Package: ----------------------------

2LIBRARY ieee;

3 USE ieee.std_logic_1164.all;

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

5PACKAGE my_package IS

6 FUNCTION "+" (a, b: STD_LOGIC_VECTOR) 7 RETURN STD_LOGIC_VECTOR;

8 END my_package;

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

10 PACKAGE BODY my_package IS

11FUNCTION "+" (a, b: STD_LOGIC_VECTOR)

12RETURN STD_LOGIC_VECTOR IS

13VARIABLE result: STD_LOGIC_VECTOR;

14VARIABLE carry: STD_LOGIC;

15BEGIN

16carry := '0';

17FOR i IN a'REVERSE_RANGE LOOP

18result(i) := a(i) XOR b(i) XOR carry;

19carry := (a(i) AND b(i)) OR (a(i) AND carry) OR

20

(b(i) AND carry);

21END LOOP;

22RETURN result;

23END "+";

24END my_package;

25 ----------------------------------------------

TLFeBOOK


Functions and Procedures

261

Figure 11.2

Simulation results of example 11.6.

1 ---------

Main code: -------------------------

2LIBRARY ieee;

3 USE ieee.std_logic_1164.all;

4 USE work.my_package.all;

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

6ENTITY add_bit IS

7PORT ( a: IN STD_LOGIC_VECTOR(3 DOWNTO 0);

8

y: OUT STD_LOGIC_VECTOR(3 DOWNTO 0));

9

END add_bit;

10

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

11

ARCHITECTURE

my_arch OF add_bit IS

12CONSTANT b: STD_LOGIC_VECTOR(3 DOWNTO 0) := "0011";

13CONSTANT c: STD_LOGIC_VECTOR(3 DOWNTO 0) := "0110";

14BEGIN

15

y <= a + b + c;

-- overloaded "+" operator

16

END my_arch;

17

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

Simulation results, for 4-bit numbers, are presented in figure 11.2. We have entered b ¼ 3 and c ¼ 6 as two constants, which are added to the input signal a. The expected results is then y ¼ a þ 9.

Example 11.7: Arithmetic Shift Function

The function shown below arithmetically shifts a STD_LOGIC_VECTOR value to the left. Two arguments are passed to the function: arg1 and arg2. The first is the vector to be shifted, while the second specifies the amount of shift. Notice that the function (lines 13–26) is totally generic; that is, it works for any size (number of bits) or order (TO/DOWNTO) of the input vector. In this example, the function was located in the main code instead of in a package.

TLFeBOOK

262

Chapter 11

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

2LIBRARY ieee;

3 USE ieee.std_logic_1164.all;

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

5ENTITY shift_left IS

6GENERIC (size: INTEGER := 4);

7PORT ( a: IN STD_LOGIC_VECTOR(size-1 DOWNTO 0);

8

x,

y, z: OUT STD_LOGIC_VECTOR(size-1 DOWNTO 0));

9

END shift_left;

10

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

11

ARCHITECTURE

behavior OF shift_left IS

12

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

13FUNCTION slar (arg1: STD_LOGIC_VECTOR; arg2: NATURAL)

14RETURN STD_LOGIC_VECTOR IS

15VARIABLE input: STD_LOGIC_VECTOR(size-1 DOWNTO 0) := arg1;

16CONSTANT size : INTEGER := arg1'LENGTH;

17VARIABLE copy: STD_LOGIC_VECTOR(size-1 DOWNTO 0)

18:= (OTHERS => arg1(arg1'RIGHT));

19VARIABLE result: STD_LOGIC_VECTOR(size-1 DOWNTO 0);

20BEGIN

21IF (arg2 >= size-1) THEN result := copy;

22ELSE result := input(size-1-arg2 DOWNTO 1) &

23copy(arg2 DOWNTO 0);

24END IF;

25RETURN result;

26END slar;

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

28BEGIN

29x <= slar(a, 0);

30y <= slar(a, 1);

31z <= slar(a, 2);

32END behavior;

33 ------------------------------------------

Simulation results are shown in figure 11.3 (for y only). The upper set of curves corresponds to the a(size-1 DOWNTO 0) specification, as shown above in line 7 (that is, a(3) is the MSB), while the second set refers to the reverse order, that is, a(0 TO 3), in which case a(0) is the MSB.

TLFeBOOK


Functions and Procedures

263

Figure 11.3

Simulation results of example 11.7.

Example 11.8: Multiplier

In this example, a function called mult( ) is presented. It multiplies two UNSIGNED values, returning their UNSIGNED product. The parameters passed to the function do not need to have the same number of bits, and their order (TO/DOWNTO) can be any. The function was installed in a package called pack. An application example (main code) is also presented. Simulation results are shown in figure 11.4.

1 ---------

Package: -----------------------------------

2LIBRARY ieee;

3 USE ieee.std_logic_1164.all;

4 USE ieee.std_logic_arith.all;

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

6PACKAGE pack IS

7 FUNCTION mult(a, b: UNSIGNED) RETURN UNSIGNED;

TLFeBOOK

264

Chapter 11

Figure 11.4

Simulation results of example 11.8.

8 END pack;

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

10 PACKAGE BODY pack IS

11FUNCTION mult(a, b: UNSIGNED) RETURN UNSIGNED IS

12CONSTANT max: INTEGER := a'LENGTH + b'LENGTH - 1;

13VARIABLE aa: UNSIGNED(max DOWNTO 0) :=

14(max DOWNTO a'LENGTH => '0')

15& a(a'LENGTH-1 DOWNTO 0);

16VARIABLE prod: UNSIGNED(max DOWNTO 0) := (OTHERS => '0');

17BEGIN

18FOR i IN 0 TO a'LENGTH-1 LOOP

19IF (b(i)='1') THEN prod := prod + aa;

20END IF;

21aa := aa(max-1 DOWNTO 0) & '0';

22END LOOP;

23RETURN prod;

24END mult;

25END pack;

26

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

1 --------

Main code: ------------------------------------

2LIBRARY ieee;

3 USE ieee.std_logic_1164.all;

4 USE ieee.std_logic_arith.all;

5 USE work.my_package.all;

6 ---------------------------------------------

7ENTITY multiplier IS

8GENERIC (size: INTEGER := 4);

9 PORT ( a, b: IN UNSIGNED(size-1 DOWNTO 0);

TLFeBOOK