ВУЗ: Не указан
Категория: Не указан
Дисциплина: Не указана
Добавлен: 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