OpenCores
URL https://opencores.org/ocsvn/artificial_neural_network/artificial_neural_network/trunk

Subversion Repositories artificial_neural_network

[/] [artificial_neural_network/] [trunk/] [ANN_kernel/] [RTL_VHDL_files/] [ann.vhd] - Blame information for rev 3

Go to most recent revision | Details | Compare with Previous | View Log

Line No. Rev Author Line
1 3 ojosynariz
----------------------------------------------------------------------------------
2
-- Company: CEI - UPM
3
-- Engineer: David Aledo
4
--
5
-- Create Date: 01.10.2015 15:15:28
6
-- Design Name: Configurable ANN
7
-- Module Name: ann - config_structural
8
-- Project Name:
9
-- Target Devices:
10
-- Tool Versions:
11
-- Description: generates the structure of an ANN with the given parameters.
12
--
13
-- Dependencies:
14
--
15
-- Revision:
16
-- Revision 0.01 - File Created
17
-- Additional Comments:
18
--
19
----------------------------------------------------------------------------------
20
 
21
 
22
library IEEE;
23
use IEEE.STD_LOGIC_1164.ALL;
24
use IEEE.NUMERIC_STD.ALL;
25
 
26
use work.layers_pkg.all;
27
 
28
entity ann is
29
   generic
30
   (
31
      Nlayer  : integer := 2;   ---- Number of layers
32
      NbitW   : natural := 16;  ---- Bit width of weights and biases
33
      NumIn   : natural := 64;  ---- Number of inputs to the network
34
      NbitIn  : natural := 8;   ---- Bit width of the inputs
35
      NumN    : int_vector;   ------ Number of neurons in each layer
36
      l_type  : string;   ---------- Layer type of each layer
37
      f_type  : string;   ---------- Activation function type of each layer
38
      LSbit   : int_vector;   ------ LSB of the output of each layer
39
      NbitO   : int_vector;   ------ Bit width of the outputs of each layer
40
      NbitOut : natural := 8   ----- Bit width of the network output
41
   );
42
 
43
   port
44
   (
45
      -- Input ports
46
      reset   : in  std_logic;
47
      clk     : in  std_logic;
48
      run_in  : in  std_logic; -- Start and input data validation
49
      m_en    : in  std_logic; -- Weight and bias memory enable (external interface)
50
      m_we    : in  std_logic_vector(((NbitW+7)/8)-1 downto 0); -- Weight and bias memory write enable (external interface)
51
      inputs  : in  std_logic_vector(NbitIn-1 downto 0); -- Input data
52
      wdata   : in  std_logic_vector(NbitW-1 downto 0);  -- Weight and bias memory write data
53
      addr    : in  std_logic_vector((calculate_lra_l(NumIn, NumN, Nlayer)+log2(Nlayer))-1 downto 0); -- Weight and bias memory address
54
 
55
      -- Output ports
56
      run_out : out std_logic; -- Output data validation
57
      rdata   : out std_logic_vector(NbitW-1 downto 0);  -- Weight and bias memory read data
58
      outputs : out std_logic_vector(NbitOut-1 downto 0) -- Output data
59
   );
60
end ann;
61
 
62
architecture config_structural of ann is
63
 
64
   -- Arrays of configuration constants, generated from string generics:
65
   constant ltype_v : ltype_vector(Nlayer-1 downto 0) := assign_ltype(l_type,Nlayer);
66
   constant ftype_v : ftype_vector(Nlayer-1 downto 0) := assign_ftype(f_type,Nlayer);
67
   constant lra_l  : int_vector(Nlayer-1 downto 0) := assign_addrl(NumIn,NumN,Nlayer); -- Layer RAM address length of each layer
68
   constant NumIn_v : int_vector(Nlayer-1 downto 0) := NumN(Nlayer-2 downto 0) & NumIn;
69
   constant wra_l   : int_vector(Nlayer-1 downto 0) := log2(NumIn_v, Nlayer); -- Weight RAM address length of each layer
70
   constant bra_l   : int_vector(Nlayer-1 downto 0) := log2(NumN, Nlayer); -- Bias ram address length of each layer
71
 
72
   -- Internal signals:
73
   signal lm_en  : std_logic_vector(Nlayer-1 downto 0); -- Weight and bias memory enable of each layer
74
   type lrd_type is array (Nlayer-1 downto 0) of std_logic_vector(NbitW-1 downto 0);
75
   signal lrdata : lrd_type; -- Weight and bias memory read data of each layer
76
 
77
   type lodata_t is array (Nlayer-1 downto 0) of std_logic_vector(calculate_max_mul(NbitO,NumN)-1 downto 0); -- Parallel or serial data
78
   type ladata_t is array (Nlayer-1 downto 0) of std_logic_vector(calculate_max(NbitO)-1 downto 0); -- Always serial data
79
   signal runO : std_logic_vector(Nlayer-1 downto 0); -- Output data validation of each layer (before activation function)
80
   signal runI : std_logic_vector(Nlayer-1 downto 0); -- Input data validation of each layer
81
   signal runA : std_logic_vector(Nlayer-1 downto 0); -- Auxiliar serial data validation of each layer
82
   signal lodata : lodata_t; -- Output data of each layer (before activation function)
83
   signal lidata : lodata_t; -- Input data of each layer
84
   signal ladata : ladata_t; -- Auxiliar serial data of each layer
85
 
86
begin
87
 
88
-- Weight and bias memory layer selection (combinational mux):
89
   process (addr(addr'length-1 downto addr'length-log2(Nlayer)), m_en, lrdata)
90
   begin
91
      for i in 0 to Nlayer-1 loop
92
         if to_integer(unsigned(addr(addr'length-1 downto addr'length-log2(Nlayer)))) = i then
93
            lm_en(i) <= m_en;
94
            rdata <= lrdata(i);
95
         else
96
            lm_en(i) <= '0';
97
         end if;
98
      end loop;
99
      -- Note: Attention with addresses greater than Nlayer when it is not a power of two
100
   end process;
101
 
102
-- ATTENTION: without the following if generate, the first layer must have serial input ('S')
103
parallelize_inputs:
104
if ltype_v(0)(1) = 'P' generate
105
   -- TODO: instantiate shift register with parallel output.
106
   -- synthesis translate_off
107
   assert ltype_v(0)(1) /= 'P'
108
      report "Current version does not accept parallel inputs."
109
      severity failure;
110
   -- synthesis translate_on
111
   -- TODO: delete above lines when instantiate shift register with parallel output.
112
end generate;
113
 
114
first_layer_SP:
115
if ltype_v(0) = "SP" generate
116
 
117
first_layerSP_top_inst: entity work.layerSP_top
118
   generic map
119
   (
120
      NumN    => NumN(0),   -- Number of neurons in the first layer
121
      NumIn   => NumIn,   ---- Number of inputs of the first layer
122
      NbitIn  => NbitIn,   --- Bit width of the input data
123
      NbitW   => NbitW,   ---- Bit width of weights and biases
124
      NbitOut => NbitO(0),  -- Bit width of the first layer output
125
      lra_l   => lra_l(0),  -- Layer RAM address length of the first layer
126
      wra_l   => wra_l(0),  -- Weight RAM address length of the first layer
127
      bra_l   => bra_l(0),  -- Bias RAM address length of the first layer
128
      LSbit   => LSbit(0)   -- Less significant bit of the first layer outputs
129
   )
130
   port map
131
   (
132
      -- Input ports
133
      reset   => reset,
134
      clk     => clk,
135
      run_in  => run_in,   --- Input data validation of the first layer
136
      m_en    => lm_en(0),  -- Weight and bias memory enable of the first layer
137
      b_sel   => addr((addr'length-log2(Nlayer))-1), -- Bias select. Selects between layer or bias memories
138
      m_we    => m_we,   ----- Weight and bias memory write enable
139
      inputs  => inputs,   --- Inputs of the first layer (serial data)
140
      wdata   => wdata,   ---- Weight and bias memory write data
141
      addr    => addr(lra_l(0)-1 downto 0), -- Weight and bias memory address of the first layer
142
 
143
      -- Output ports
144
      run_out => runO(0),   -- Output data validation of the first layer
145
      rdata   => lrdata(0), -- Weight and bias memory read data of the first layer
146
      outputs => lodata(0)((NumN(0)*NbitO(0))-1 downto 0) -- Outputs of the first layer (parallel data)
147
   );
148
end generate;
149
 
150
 
151
layers_insts:
152
for i in 1 to Nlayer-1 generate
153
 
154
   -- If the previous layer (i-1) has parallel outputs and actual layer (i) has serial inputs, a serializer
155
   -- is inserted before the activation function (i-1). So, parallel activations functions are avoided.
156
serializer:
157
   if (ltype_v(i-1)(2) = 'P') and (ltype_v(i)(1) = 'S') generate
158
 
159
      -- Instantiate shift-register with parallel load:
160
shiftreg_parallel_load: entity work.shiftreg_pl
161
      generic map
162
      (
163
         Nreg => NumN(i-1),   --- Number of registers in the shift-register corresponds with the number of neurons in the previous layer (i-1)
164
         Nbit => NbitO(i-1)   --- Bit width of the registers corresponds with the bit width of the outputs of the previous layer (i-1)
165
      )
166
      port map
167
      (
168
         reset   => reset,
169
         clk     => clk,
170
         run_in  => runO(i-1), -- Input data validation of the shift-register comes from the output data validation of the previous layer (i-1)
171
         inputs  => lodata(i-1)((NumN(i-1)*NbitO(i-1))-1 downto 0), -- Parallel input data to the shift-register come from the previous layer (i-1)
172
         run_out => runA(i-1), -- Output data validation goes to the activation function of the previous layer (i-1)
173
         outputs => ladata(i-1)(NbitO(i-1)-1 downto 0) -- Output serial data go to the activation function of the previous layer (i-1)
174
      );
175
 
176
      -- Instantiate single activation function of the previous layer (i-1):
177
activation_function_inst: entity work.activation_function
178
      generic map
179
      (
180
         f_type => ftype_v(i-1), -- Activation function type of the previous layer (i-1)
181
         Nbit   => NbitO(i-1)   --- Bit width of the outputs of the previous layer (i-1)
182
      )
183
      port map
184
      (
185
         reset   => reset,
186
         clk     => clk,
187
         run_in  => runA(i-1),   -- Input data validation comes from the shift-register
188
         inputs  => ladata(i-1)(NbitO(i-1)-1 downto 0), -- Serial input data come from the shift-register
189
         run_out => runI(i-1),   -- Output data validation goes to the input data validation of this layer
190
         outputs => lidata(i-1)(NbitO(i-1)-1 downto 0) -- Serial output data go to the inputs of this layer
191
      );
192
 
193
   end generate; -- serializer
194
 
195
   -- If the previous layer (i-1) has serial outputs and actual layer (i) has serial inputs,
196
   -- a single activation function is instantiated:
197
single_activation_function:
198
   if (ltype_v(i-1)(2) = 'S') and (ltype_v(i)(1) = 'S') generate
199
 
200
      -- Instantiate single activation function of the previous layer (i-1):
201
activation_function_inst: entity work.activation_function
202
      generic map
203
      (
204
         f_type => ftype_v(i-1), -- Activation function type of the previous layer (i-1)
205
         Nbit   => NbitO(i-1)   --- Bit width of the outputs of the previous layer (i-1)
206
      )
207
      port map
208
      (
209
         reset   => reset,
210
         clk     => clk,
211
         run_in  => runO(i-1),   -- Input data validation comes from the previous layer (i-1)
212
         inputs  => lodata(i-1)(NbitO(i-1)-1 downto 0), -- Serial input data come from the previous layer (i-1)
213
         run_out => runI(i-1),   -- Output data validation goes to the input data validation of this layer
214
         outputs => lidata(i-1)(NbitO(i-1)-1 downto 0) -- Serial output data go to the inputs of this layer
215
      );
216
 
217
   end generate; -- single_activation_function
218
 
219
   -- If the previous layer (i-1) has parallel outputs and actual layer (i) has parallel inputs,
220
   -- multiple parallel activation functions are instantiated:
221
multiple_activation_functions:
222
   if (ltype_v(i-1)(2) = 'P') and (ltype_v(i)(1) = 'P') generate
223
 
224
      -- First of the parallel activation functions. This is the one which generates the output data validation
225
act_function_inst_0: entity work.activation_function
226
      generic map
227
      (
228
         f_type => ftype_v(i-1), -- Activation function type of the previous layer (i-1)
229
         Nbit   => NbitO(i-1)   --- Bit width of the outputs of the previous layer (i-1)
230
      )
231
      port map
232
      (
233
         reset   => reset,
234
         clk     => clk,
235
         run_in  => runO(i-1),   -- Input data validation comes from the previous layer (i-1)
236
         inputs  => lodata(i-1)(NbitO(i-1)-1 downto 0), -- First of the parallel input data wich comes from the previous layer (i-1)
237
         run_out => runI(i-1),   -- Output data validation goes to the input data validation of this layer
238
         outputs => lidata(i-1)(NbitO(i-1)-1 downto 0)  -- First of the parallel inputs of this layer
239
      );
240
 
241
      -- Rest of the parallel activation functions of the previous layer (i-1)
242
multiple_activation_function_insts:
243
      for j in 1 to NumN(i-1)-1 generate
244
activation_function_inst: entity work.activation_function
245
         generic map
246
         (
247
            f_type => ftype_v(i-1), -- Activation function type of the previous layer (i-1)
248
            Nbit   => NbitO(i-1)   --- Bit width of the outputs of the previous layer (i-1)
249
         )
250
         port map
251
         (
252
            reset   => reset,
253
            clk     => clk,
254
            run_in  => runO(i-1),   -- Input data validation comes from the previous layer (i-1)
255
            inputs  => lodata(i-1)((NbitO(i-1)*(j+1))-1 downto NbitO(i-1)*j), -- Rest of the parallel input data which come from the previous layer (i-1)
256
            run_out => open,   ------- As only one output data validation is needed, the rest ones are left unconnected
257
            outputs => lidata(i-1)((NbitO(i-1)*(j+1))-1 downto NbitO(i-1)*j)  -- Rest of the parallel inputs of this layer
258
         );
259
      end generate;
260
 
261
   end generate; -- multiple_activation_functions
262
 
263
   -- If the previous layer (i-1) has serial outputs and actual layer (i) has parallel inputs, a parallelizer
264
   -- is insested after the activation function (i-1):
265
parallelizer:
266
   if (ltype_v(i-1)(2) = 'S') and (ltype_v(i)(1) = 'P') generate
267
 
268
      -- Instantiate single activation function of the previous layer (i-1):
269
activation_function_inst: entity work.activation_function
270
      generic map
271
      (
272
         f_type => ftype_v(i-1),
273
         Nbit   => NbitO(i-1)
274
      )
275
      port map
276
      (
277
         reset   => reset,
278
         clk     => clk,
279
         run_in  => runO(i-1),
280
         inputs  => lodata(i-1)(NbitO(i-1)-1 downto 0),
281
         run_out => runA(i-1),
282
         outputs => ladata(i-1)(NbitO(i-1)-1 downto 0)
283
      );
284
 
285
      -- Instantiate shift-register with parallel unload:
286
shiftreg_parallel_unload: entity work.shiftreg_pu
287
      generic map
288
      (
289
         Nreg => NumN(i-1),   --- Number of registers in the shift-register corresponds with the number of neurons in the previous layer (i-1)
290
         Nbit => NbitO(i-1)   --- Bit width of the registers corresponds with the bit width of the outputs of the previous layer (i-1)
291
      )
292
      port map
293
      (
294
         reset   => reset,
295
         clk     => clk,
296
         run_in  => runA(i-1), -- Input data validation comes from the activation function of the previous layer (i-1)
297
         inputs  => ladata(i-1)(NbitO(i-1)-1 downto 0), -- Serial input data
298
         run_out => runO(i-1), -- Output data validation goes to the input data validation of this layer
299
         outputs => lodata(i-1)((NumN(i-1)*NbitO(i-1))-1 downto 0) -- Parallel output data
300
      );
301
 
302
   end generate; -- parallelizer
303
 
304
   -- Instance the layer (i), cases SP, PS or PP:
305
 
306
   -- Serial-input parallel-output layer:
307
SP_case:
308
   if ltype_v(i) = "SP" generate
309
layerSP_top_inst: entity work.layerSP_top
310
      generic map
311
      (
312
         NumN    => NumN(i),   --- Number of neurons in layer (i)
313
         NumIn   => NumN(i-1),  -- Number of inputs, is the number of neurons in previous layer (i-1)
314
         NbitIn  => NbitO(i-1), -- Bit width of the input data, is the bit width of output data of layer (i-1)
315
         NbitW   => NbitW,   ----- Bit width of weights and biases
316
         NbitOut => NbitO(i),   -- Bit width of layer (i) output
317
         lra_l   => lra_l(i),   -- Layer RAM address length of layer (i)
318
         wra_l   => wra_l(i),   -- Weight RAM address length of layer (i)
319
         bra_l   => bra_l(i),   -- Bias RAM address length of layer (i)
320
         LSbit   => LSbit(i)   --- Less significant bit of layer (i) outputs
321
      )
322
      port map
323
      (
324
         -- Input ports
325
         reset   => reset,
326
         clk     => clk,
327
         run_in  => runI(i-1),  -- Input data validation of this layer
328
         m_en    => lm_en(i),   -- Weight and bias memory enable of this layer
329
         b_sel   => addr((addr'length-log2(Nlayer))-1), -- Bias select. Selects between layer or bias memories
330
         m_we    => m_we,   ------ Weight and bias memory write enable
331
         inputs  => lidata(i-1)(NbitO(i-1)-1 downto 0), -- Inputs of this layer (serial data)
332
         wdata   => wdata,   ----- Weight and bias memory write data
333
         addr    => addr(lra_l(i)-1 downto 0), -- Weight and bias memory address of this layer
334
 
335
         -- Output ports
336
         run_out => runO(i),   -- Output data validation of this layer
337
         rdata   => lrdata(i), -- Weight and bias memory read data of this layer
338
         outputs => lodata(i)((NumN(i)*NbitO(i))-1 downto 0) -- Outputs of this layer (parallel data)
339
      );
340
   end generate;
341
 
342
   -- Parallel-input serial-output layer:
343
PS_case:
344
   if ltype_v(i) = "PS" generate
345
layerPS_top_inst: entity work.layerPS_top
346
      generic map
347
      (
348
         NumN    => NumN(i),   --- Number of neurons in layer (i)
349
         NumIn   => NumN(i-1),  -- Number of inputs, is the number of neurons in previous layer (i-1)
350
         NbitIn  => NbitO(i-1), -- Bit width of the input data, is the bit width of output data of layer (i-1)
351
         NbitW   => NbitW,   ----- Bit width of weights and biases
352
         NbitOut => NbitO(i),   -- Bit width of layer (i) output
353
         lra_l   => lra_l(i),   -- Layer RAM address length of layer (i)
354
         wra_l   => wra_l(i),   -- Weight RAM address length of layer (i)
355
         bra_l   => bra_l(i),   -- Bias ram address length of layer (i)
356
         LSbit   => LSbit(i)   --- Less significant bit of layer (i) outputs
357
      )
358
      port map
359
      (
360
         -- Input ports
361
         reset   => reset,
362
         clk     => clk,
363
         run_in  => runI(i-1),  -- Input data validation of this layer
364
         m_en    => lm_en(i),   -- Weight and bias memory enable of this layer
365
         b_sel   => addr((addr'length-log2(Nlayer))-1), -- Bias select. Selects between layer or bias memories
366
         m_we    => m_we,   ------ Weight and bias memory write enable
367
         inputs  => lidata(i-1)((NumN(i-1)*NbitO(i-1))-1 downto 0), -- Inputs of this layer (parallel data)
368
         wdata   => wdata,   ----- Weight and bias memory write data
369
         addr    => addr(lra_l(i)-1 downto 0), -- Weight and bias memory address of this layer
370
 
371
         -- Output ports
372
         run_out => runO(i),   -- Output data validation of this layer
373
         rdata   => lrdata(i), -- Weight and bias memory read data of this layer
374
         outputs => lodata(i)(NbitO(i)-1 downto 0) -- Outputs of this layer (serial data)
375
      );
376
   end generate;
377
 
378
   -- Parallel-input parallel-output layer:
379
PP_case:
380
   if ltype_v(i) = "PP" generate
381
      -- TODO: instance a full parallel layer. At current version this layer type has not been developed.
382
      -- synthesis translate_off
383
      assert l_type(i) /= "PP"
384
         report "Current version does not accept parallel-input parallel-output (PP) layer type."
385
         severity failure;
386
      -- synthesis translate_on
387
      -- TODO: delete above lines when instantiate the parallel-input parallel-output layer.
388
   end generate;
389
 
390
end generate; -- layers_insts
391
 
392
-- If the last layer (Nlayer-1) has parallel outputs, a serializer is inserted before the activation function:
393
last_serializer:
394
if (ltype_v(Nlayer-1)(2) = 'P') generate
395
 
396
   -- Instantiate shift-register with parallel load:
397
last_shiftreg_parallel_load: entity work.shiftreg_pl
398
   generic map
399
   (
400
      Nreg => NumN(Nlayer-1),   --- Number of registers corresponds with the number of neurons in the last layer (Nlayer-1)
401
      Nbit => NbitO(Nlayer-1)   --- Bit width of the registers corresponds with the bit width of the outputs of the last layer (Nlayer-1)
402
   )
403
   port map
404
   (
405
      reset   => reset,
406
      clk     => clk,
407
      run_in  => runO(Nlayer-1), -- Input data validation comes from the output data validation of the last layer (Nlayer-1)
408
      inputs  => lodata(Nlayer-1)((NumN(Nlayer-1)*NbitO(Nlayer-1))-1 downto 0), -- Parallel input data come from the last layer
409
      run_out => runA(Nlayer-1), -- Output data validation goes to the last activation function (Nlayer-1)
410
      outputs => ladata(Nlayer-1)(NbitO(Nlayer-1)-1 downto 0) -- Serial output data go to the last activation function
411
   );
412
 
413
last_activation_function_inst: entity work.activation_function
414
      generic map
415
      (
416
         f_type => ftype_v(Nlayer-1), -- Activation function type of the last layer (Nlayer-1)
417
         Nbit   => NbitO(Nlayer-1)   --- Bit width of the outputs of the last layer (Nlayer-1)
418
      )
419
      port map
420
      (
421
         reset   => reset,
422
         clk     => clk,
423
         run_in  => runA(Nlayer-1),   -- Input data validation comes from the shift-register output validation
424
         inputs  => ladata(Nlayer-1)(NbitO(Nlayer-1)-1 downto 0), -- Serial input data come from the shift-register
425
         run_out => run_out,   --------- Output data validation of the network
426
         outputs => outputs   ---------- Outputs of the network (serial data)
427
      );
428
 
429
end generate; -- last_serializer
430
 
431
-- If the las layer has serial outputs:
432
last_simple_activation_function:
433
if (ltype_v(Nlayer-1)(2) = 'S') generate
434
last_activation_function_inst: entity work.activation_function
435
      generic map
436
      (
437
         f_type => ftype_v(Nlayer-1), -- Activation function type of the last layer (Nlayer-1)
438
         Nbit   => NbitO(Nlayer-1)   --- Bit width of the outputs of the last layer (Nlayer-1)
439
      )
440
      port map
441
      (
442
         reset   => reset,
443
         clk     => clk,
444
         run_in  => runO(Nlayer-1),   -- Input data validation comes from the last layer (Nlayer-1) output validation
445
         inputs  => lodata(Nlayer-1)(NbitO(Nlayer-1)-1 downto 0), -- Inputs come from the outputs of the last layer (serial data)
446
         run_out => run_out,   --------- Output data validation of the network
447
         outputs => outputs   ---------- Outputs of the network (serial data)
448
      );
449
end generate;
450
 
451
end config_structural;

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.