ВУЗ: Не указан
Категория: Не указан
Дисциплина: Не указана
Добавлен: 13.06.2025
Просмотров: 3471
Скачиваний: 2
Additional System Designs |
291 |
In the solution below, the coe‰cients were considered as CONSTANTS (line 19), thus inferring no flip-flops. The values chosen were coef(0) ¼ 4, coef(1) ¼ 3, coef(2) ¼ 2, and coef(3) ¼ 1. Small values were chosen for n and m (4 for both) in order to make the simulation results easy to visualize. With n ¼ m ¼ 4, the synthesized circuit required 20 flip-flops (four for each stage of the shift register, plus eight for the output). As described in chapter 7, flip-flops are inferred when a signal assignment is made on the transition of another signal, which occurs in lines 33–45 of the code below (notice that indeed VARIABLE assignments are made in lines 33–38, but since their values are then passed to a SIGNAL (y), registers are inferred).
1 -----------------------------------------------------------
2LIBRARY ieee;
3USE ieee.std_logic_1164.all;
4 |
USE ieee.std_logic_arith.all; -- package needed for SIGNED |
5 |
----------------------------------------------------------- |
6ENTITY fir2 IS
7GENERIC (n: INTEGER := 4; m: INTEGER := 4);
8-- n = # of coef., m = # of bits of input and coef.
9 -- Besides n and m, CONSTANT (line 19) also need adjust
10PORT ( x: IN SIGNED(m-1 DOWNTO 0);
11clk, rst: IN STD_LOGIC;
12y: OUT SIGNED(2*m-1 DOWNTO 0));
13END fir2;
14 |
----------------------------------------------------------- |
|
15 |
ARCHITECTURE rtl OF fir2 IS |
|
16 |
TYPE registers IS ARRAY (n-2 DOWNTO 0) OF |
|
17 |
SIGNED(m-1 DOWNTO |
0); |
18 |
TYPE coefficients IS ARRAY (n-1 DOWNTO 0) |
OF |
19 |
SIGNED(m-1 DOWNTO 0); |
|
20SIGNAL reg: registers;
21CONSTANT coef: coefficients := ("0001", "0010", "0011",
22 |
"0100"); |
23BEGIN
24PROCESS (clk, rst)
25VARIABLE acc, prod:
26SIGNED(2*m-1 DOWNTO 0) := (OTHERS=>'0');
27VARIABLE sign: STD_LOGIC;
28BEGIN
29----- reset: --------------------------
TLFeBOOK
292 |
Chapter 12 |
30IF (rst='1') THEN
31FOR i IN n-2 DOWNTO 0 LOOP
32FOR j IN m-1 DOWNTO 0 LOOP
33 |
reg(i)(j) <= '0'; |
34END LOOP;
35END LOOP;
36----- register inference + MAC: -------
37ELSIF (clk'EVENT AND clk='1') THEN
38acc := coef(0)*x;
39FOR i IN 1 TO n-1 LOOP
40sign := acc(2*m-1);
41prod := coef(i)*reg(n-1-i);
42acc := acc + prod;
43---- overflow check: ------------
44IF (sign=prod(prod'left)) AND
45 |
(acc(acc'left) /= sign) |
46 |
THEN |
47 |
acc := (acc'LEFT => sign, OTHERS => NOT sign); |
48END IF;
49END LOOP;
50reg <= x & reg(n-2 DOWNTO 1);
51END IF;
52y <= acc;
53END PROCESS;
54END rtl;
55-----------------------------------------------------------
Simulation results are shown in figure 12.10. Recall that the coe‰cients are coef(0) ¼ 4, coef(1) ¼ 3, coef(2) ¼ 2, and coef(3) ¼ 1, and that the numbers are
Figure 12.10
Simulation results of FIR filter of figure 12.9.
TLFeBOOK
Additional System Designs |
293 |
SIGNED (therefore, with 4-bit values, the range is from 8 to þ7). The sequence applied to the input was x[0] ¼ 0, x[1] ¼ 5, x[2] ¼ 6 (16 6 ¼ 10 in the graph), x[3] ¼ 1 (16 1 ¼ 15 in the graph), x[4] ¼ 4, x[5] ¼ 7 (16 7 ¼ 9 in the graph), and x[6] ¼ 2 (16 2 ¼ 14 in the graph). Therefore, with all flip-flops previously reset, at the first positive edge of clk the expected output is y[0] ¼ coef(0)*x[0] ¼ 0, which coincides with the first result for y in figure 12.10. At the next upward transition of clk, the expected value is y[1] ¼ coef(0)*x[1] þ coef(1)*x[0] ¼ 20. And one clock cycle later, y[1] ¼ coef(0)*x[2] þ coef(1)*x[1] þ coef(2)*x[0] ¼ 9 (256 9 ¼ 247 in the graph), and so on.
General Purpose FIR Filter
The design presented above contained fixed coe‰cients, and is therefore adequate for an ASIC with a dedicated filter. For a general purpose implementation (that is, with programmable coe‰cients), the architecture of figure 12.11 can be used instead. As can be seen, this structure is modular and allows several chips to be cascaded, which might be helpful in some applications, because FIR filters tend to have many taps (coe‰cients).
In this structure, there are two shift registers, one for storing the inputs (x) and the other for the coe‰cients (coef ). The structure is divided into n equal modules, called TAP1, . . . , TAPn. Each module (TAP) contains a slice of the shift registers, plus a multiplier and an adder. It also contains an output register, but this is optional (could be used at the last TAP only). This would, however, increase the ripple propagation
Figure 12.11
General purpose FIR filter.
TLFeBOOK
294 |
Chapter 12 |
x1 |
w11 |
y1 |
|||||
1 |
|||||||
w12 |
|||||||
w13 |
|||||||
x2 |
2 |
y2 |
|||||
Input |
Hidden layers |
Output layer |
x3 |
3 |
y3 |
(a) |
(b) |
Figure 12.12
Feedforward neural network.
between the adders. Of course, all coe‰cients must be loaded before the computation starts. This FIR architecture will be object of problem 12.4.
12.5 Neural Networks
Neural Networks (NN) are highly parallel, highly interconnected systems. Such characteristics make their implementation very challenging, and also very costly, due to the large amount of hardware required.
A feedforward NN is shown in figure 12.12(a). In this example, the circuit has three layers, with three 3-input neurons in each layer. Internal details of each layer are depicted in figure 12.12(b). xi represents the ith input, wij is the weight between input i and neuron j, and yj is the jth output. Therefore, y1 ¼ f(x1.w11 þ x2.w21 þ x3.w31), y2 ¼ f(x1.w12 þ x2.w22 þ x3.w32), and y3 ¼ f(x1.w13 þ x2.w23 þ x3.w33), where f( ) is the activation function (linear threshold, sigmoid, etc.).
A ‘‘ring’’ architecture for the NN of figure 12.12 is presented in figure 12.13, which implements one layer of the NN. Each box represents one neuron. As shown, there are several circular shift registers, one for each neuron (vertical shifters) plus one for the whole set (horizontal shifter). The vertical shifters hold the weights, while the horizontal one holds the inputs (shift registers with ‘data_load’ capability). Notice
TLFeBOOK
Additional System Designs |
295 |
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
Figure 12.13
Ring architecture for NN implementation.
that the relative position of the weights in their respective registers must match that of the input values. At the output of a vertical shifter there is a MAC circuit (section 12.3), which accumulates the product between the weights and the inputs. All shifters use the same clock signal. Therefore, after one complete circulation, the following values will be available at the output of the MAC circuits: x1.w11 þ x2.w21 þ x3.w31, x1.w12 þ x2.w22 þ x3.w32, and x1.w13 þ x2.w23 þ x3.w33. These values are then applied to a LUT (lookup table), which implements the activation function (sigmoid, for example), thus producing the actual outputs, yi, of the NN.
In this kind of circuit, truncation must be considered. Say that the inputs and weights are 16 bits long. Then at the output of the MAC cells 32-bit numbers would be the natural choice. However, since the actual outputs (after the LUT) might be connected to another layer of neurons, truncation to 16 bits is required. This can be done in the LUT or in the MAC circuit.
Another approach is presented in figure 12.14, which is appropriate for generalpurpose NNs (that is, with programmable weights). It employs only one input to load all weights (thus saving on chip pins). In figure 12.14, the weights are shifted in sequentially until each register is loaded with its respective weight. The weights are then multiplied by the inputs and accumulated to produce the desired outputs.
TLFeBOOK
296 |
Chapter 12 |
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
Figure 12.14
NN implementation with only one input for the weights.
Two VHDL codes are presented below, both implementing the architecture of figure 12.14. However, in both solutions the LUT was not included (this will be treated in problem 12.5). The main di¤erence between these two solutions is that the first code is not as generic, and is therefore adequate for specific, small designs. The second solution, being generic, is reusable and easily adaptable to any NN size.
Solution 1: For Small Neural Networks
The solution below has the advantage of being simple, easily understandable, and self-contained in the main code. Its only limitation is that the inputs (x) and outputs
(y) are specified one by one rather than using some kind of two-dimensional array, thus making it inappropriate for large NNs. Everything else is generic.
1 -----------------------------------------------------------
2LIBRARY ieee;
3USE ieee.std_logic_1164.all;
4 |
USE ieee.std_logic_arith.all; -- package needed for SIGNED |
5 |
----------------------------------------------------------- |
TLFeBOOK