ВУЗ: Не указан
Категория: Не указан
Дисциплина: Не указана
Добавлен: 13.06.2025
Просмотров: 3470
Скачиваний: 2
Additional System Designs |
297 |
6ENTITY nn IS
7 GENERIC ( n: INTEGER := 3; -- # of neurons
8m: INTEGER := 3; -- # of inputs or weights per neuron
9 |
b: INTEGER := 4); -- # of bits per input or weight |
10 PORT ( x1: IN SIGNED(b-1 DOWNTO 0);
11x2: IN SIGNED(b-1 DOWNTO 0);
12x3: IN SIGNED(b-1 DOWNTO 0);
13w: IN SIGNED(b-1 DOWNTO 0);
14clk: IN STD_LOGIC;
15test: OUT SIGNED(b-1 DOWNTO 0); -- register test output
16y1: OUT SIGNED(2*b-1 DOWNTO 0);
17y2: OUT SIGNED(2*b-1 DOWNTO 0);
18y3: OUT SIGNED(2*b-1 DOWNTO 0));
19END nn;
20 -----------------------------------------------------------
21 ARCHITECTURE neural OF nn IS
22TYPE weights IS ARRAY (1 TO n*m) OF SIGNED(b-1 DOWNTO 0);
23TYPE inputs IS ARRAY (1 TO m) OF SIGNED(b-1 DOWNTO 0);
24TYPE outputs IS ARRAY (1 TO m) OF SIGNED(2*b-1 DOWNTO 0);
25BEGIN
26PROCESS (clk, w, x1, x2, x3)
27VARIABLE weight: weights;
28VARIABLE input: inputs;
29VARIABLE output: outputs;
30VARIABLE prod, acc: SIGNED(2*b-1 DOWNTO 0);
31VARIABLE sign: STD_LOGIC;
32BEGIN
33----- shift register inference: -------------
34IF (clk'EVENT AND clk='1') THEN
35weight := w & weight(1 TO n*m-1);
36END IF;
37 --------- |
initialization: ------------------- |
38input(1) := x1;
39input(2) := x2;
40input(3) := x3;
41 ------ |
multiply-accumulate: ----------------- |
42L1: FOR i IN 1 TO n LOOP
43acc := (OTHERS => '0');
TLFeBOOK
298 |
Chapter 12 |
44L2: FOR j IN 1 TO m LOOP
45prod := input(j)*weigth(m*(i-1)+j);
46sign := acc(acc'LEFT);
47acc := acc + prod;
48---- overflow check: -----------------
49IF (sign=prod(prod'left)) AND
50 |
(acc(acc'left) /= sign) THEN |
51 |
acc := (acc'LEFT => sign, OTHERS => NOT sign); |
52END IF;
53END LOOP L2;
54output(i) := acc;
55END LOOP L1;
56 --------- |
outputs: -------------------------- |
57test <= weight(n*m);
58y1 <= output(1);
59y2 <= output(2);
60y3 <= output(3);
61END PROCESS;
62END neural;
63 -----------------------------------------------------------------
Simulation results are shown in figure 12.15. Notice that a small number of bits and a small quantity of neurons were used in order to ease the visualization of the simulation results. As can be seen in lines 7–9 of the code above, the NN has three neurons with three 4-bit inputs each. Since type SIGNED was employed, the range
Figure 12.15
Simulation results of NN implemented in solution 1.
TLFeBOOK
Additional System Designs |
299 |
of the input values and weights runs from 8 to 7, and the range of the outputs (8 bits) runs from 128 to 127. The inputs were kept fixed at x1 ¼ 3, x2 ¼ 4, and x3 ¼ 5. Since there are nine weights, nine clock cycles are needed to shift them in, as shown in figure 12.5. The values chosen for the weights were w9 ¼ 1, w8 ¼ 2, . . . , w1 ¼ 9 (notice that the first weight in is indeed w9, for it is shifted nine positions over). Recall, however, that 9 is indeed 7, and 8 is 8, because our data type is SIGNED. Therefore, after the weights have been all loaded, the system immediately
furnishes its first set of outputs; that is: |
y1 ¼ x1.w1 þ x2.w2 þ x3.w3 ¼ (3)( 7) |
þ |
|
(4)( 8) þ (5)(7) ¼ 18 (represented |
as |
256 18 ¼ 238); y2 ¼ x1.w4 þ x2.w5 þ |
|
x3.w6 ¼ (3)(6) þ (4)(5) þ (5)(4) ¼ 58; |
and |
y3 ¼ x1.w7 þ x2.w8 þ x3.w9 ¼ (3)(3) þ |
|
(4)(2) þ (5)(1) ¼ 22. These values (238, 58, and 22) can be seen at the right end of figure 12.15.
Solution 2: For Large Neural Networks
The code below is generic. Moreover, the inputs and outputs were declared as twodimensional arrays (section 3.5), thus easily allowing the construction of NNs of any size.
To specify the arrays needed in the design, a PACKAGE named my_data_types was employed. As can be seen, it contains two user-defined data types, vector_ array_in and vector_array_out. The PACKAGE was then made visible to the design by means of a USE clause (line 5 of the main code). In this way, the new data types are truly global, and so can be used even in the ENTITY of the main code (that is, in the specification of PORT). These data types were used to specify the inputs and outputs of the systems (lines 11 and 15, respectively). Therefore, all parameters are now generic and easily modifiable, regardless of the size of the NN to be constructed.
Notice in the code below that this solution was divided into two very short parts: sequential logic (shift register implementation) in lines 26–28, followed by combinational logic (MAC) implementation. A test output (for checking the last register) was also included, which is obviously optional. As in all our previous MAC circuit implementations, a routine to check for overflow was also included (lines 39–41).
1 -------- |
Package my_data_types: ---------------------------- |
2LIBRARY ieee;
3USE ieee.std_logic_1164.all;
4 |
USE ieee.std_logic_arith.all; -- package needed for SIGNED |
5 |
---------------------------- |
6PACKAGE my_data_types IS
7 CONSTANT b: INTEGER := 3; -- # of bits per input or weight
TLFeBOOK
300 |
Chapter 12 |
8TYPE vector_array_in IS ARRAY (NATURAL RANGE <>) OF
9 |
SIGNED(b-1 DOWNTO 0); |
10 |
TYPE vector_array_out IS ARRAY (NATURAL RANGE <>) OF |
11 |
SIGNED(2*b-1 DOWNTO 0); |
12 |
END my_data_types; |
13 |
------------------------------------------------------------ |
1 |
--------- Project nn (main code): -------------------------- |
2LIBRARY ieee;
3USE ieee.std_logic_1164.all;
4 |
USE ieee.std_logic_arith.all; |
-- |
package needed for SIGNED |
5 |
USE work.my_data_types.all; |
-- |
package of user-defined types |
6 |
------------------------------------------------------------ |
7ENTITY nn3 IS
8 |
GENERIC ( n: INTEGER := 3; |
-- # of neurons |
||||
9 |
m: INTEGER := |
3; |
-- # |
of |
inputs or weights per |
|
10 |
-- neuron |
|||||
11 |
b: INTEGER := |
3); -- |
# |
of |
bits per input or |
|
12 |
-- |
weight |
||||
13PORT ( x: IN VECTOR_ARRAY_IN (1 TO m);
14w: IN SIGNED(b-1 DOWNTO 0);
15clk: IN STD_LOGIC;
16test: OUT SIGNED(b-1 DOWNTO 0); -- register test
17 |
-- output |
18y: OUT VECTOR_ARRAY_OUT(1 TO n));
19END nn3;
20 ----------------------------------------------------------------
21 ARCHITECTURE neural OF nn3 IS
22BEGIN
23PROCESS (clk, w, x)
24VARIABLE weight: VECTOR_ARRAY_IN (1 TO m*n);
25VARIABLE prod, acc: SIGNED(2*b-1 DOWNTO 0);
26VARIABLE sign: STD_LOGIC;
27BEGIN
28----- shift register inference: --------------
29IF (clk'EVENT AND clk='1') THEN
30weight := w & weight(1 TO n*m-1);
31END IF;
TLFeBOOK
Additional System Designs |
301 |
32test <= weight(n*m);
33---- initialization: -------------------------
34acc := (OTHERS => '0');
35 ------ |
multiply-accumulate: ------------------ |
36L1: FOR i IN 1 TO n LOOP
37L2: FOR j IN 1 TO m LOOP
38prod := x(j)*weight(m*(i-1)+j);
39sign := acc(acc'LEFT);
40acc := acc + prod;
41---- overflow check: ------------------
42IF (sign=prod(prod'LEFT)) AND
43 |
(acc(acc'LEFT)/=sign) THEN |
44 |
acc := (acc’LEFT => sign, OTHERS => NOT sign); |
45END IF;
46END LOOP L2;
47 ------ |
output: --------------------------- |
48y(i) <= acc;
49acc := (OTHERS => ’0’);
50END LOOP L1;
51END PROCESS;
52END neural;
53 -----------------------------------------------------------------
Other aspects related to the design of NNs will be treated in problem 12.5.
12.6Problems
This section contains a series of problems regarding the use of system-level VHDL units (PACKAGES, COMPONENTS, FUNCTIONS, and PROCEDURES).
Problem 12.1: Parallel Multiplier
We have seen, in section 12.2, the implementation of a parallel multiplier from scratch. It was also mentioned that the pre-defined ‘‘*’’ (multiplication) operator implements a parallel multiplier too. Though there are several architectures for such a circuit (one was shown in figure 12.3), it is reasonable to assume that the amount of hardware necessary to implement either solution presented in section 12.2 (from scratch or using ‘‘*’’) should not di¤er substantially. You are asked to synthesize
TLFeBOOK
302 |
Chapter 12 |
q3 |
q2 |
q1 |
q0 |
|
d |
||||
DFF |
DFF |
DFF |
DFF |
clk
MUX q
sel
Figure P12.2.
both solutions and compare the resulting report files. Choose several PLD/FPGA target chips. What is the number of product terms and logic cells required in each case? Are their quantities of the same order?
Problem 12.2: Shifter
Consider the 4-stage shift register of figure P12.2, whose actual output (q) is selected by means of a multiplexer. Say that the data bus is eight-bit wide (thus each register is composed of eight D-type flip-flops).
(a)Create two COMPONENTS, reg and mux, and then make use of them to construct the complete circuit of figure P12.2.
(b)Assume now that we want to implement only the shift register, without the multiplexer, but that all registered values (q0, q1, q2, and q3) must be available at the output. Write a VHDL code for such a circuit.
(c)Let us consider the same situation of (b) above. However, we now want the design to be generic (that is, to have n stages, and b bits per stage, with such parameters specified by means of a GENERIC statement). In this case, an user-defined array will be necessary to specify the outputs (call the outputs qout). Write such a code. (Suggestion: review section 3.5 and/or examine the second design of section 12.5).
(d)Finally, in continuation to the design of (c) above, assume that we want to add ‘data load’ capability to the shift register. Add an extra input (call it x) to each register and an extra pin to (call it load ), such that when load is asserted all registers are overwritten with the values presented at the inputs. For x, the same user-defined TYPE created for qout can (and should) be used.
TLFeBOOK
Additional System Designs |
303 |
Problem 12.3: MAC Circuit
In section 12.3, we studied the implementation of a MAC (multiply-accumulate) circuit (figure 12.6). In the implementation shown there, a FUNCTION was employed, but COMPONENTS were not. Write another solution, this time using COMPONENTS (multiplier, adder, and register). Create the components, then instantiate them in the main code. Compile and simulate your project, comparing your results with those obtained in figure 12.7
Problem 12.4: General Purpose FIR Filter
In section 12.4, we discussed the implementation of FIR filters. One complete design was presented, in which the coe‰cients of the filter were fixed (figure 12.9). For a general purpose filter (programmable coe‰cients), a modular architecture was suggested in figure 12.11. You are asked to write a VHDL code for that filter. As a suggestion, review first sections 12.3 and 12.4. Do not forget to include overflow check in your design. Consider that the number of bits of all signals from the input (x and coef) up to the multiplier inputs is m, and 2m from there on (that is, from the multiplier outputs up to y). Consider also that the number of taps (stages) is n. Write a code as generic as possible. Then synthesize and simulate your circuit.
Problem 12.5: Neural Network
In section 12.5, we discussed the implementation of a highly interconnected system: a neural network. Two architectures were presented, and two VHDL codes were written regarding the second architecture. However, the LUT was not included in those solutions. In this problem, the following is asked:
(a)Write a VHDL code that implements a LUT (you can choose the function to be implemented, because what we want to practice here is how to implement a LUT). Recall that a lookup table is simply a ROM (section 9.10).
(b)Write a VHDL code that implements the neural architecture depicted in figure 12.13. Then synthesize and simulate your solution to verify whether it works as expected.
(c)There certainly are other ways of implementing a NN besides the two approaches presented in section 12.5. Can you suggest another one? Can you suggest improvements on the architectures and solutions presented there?
TLFeBOOK
TLFeBOOK