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/] [layerSP_top.vhd] - Blame information for rev 8

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

Line No. Rev Author Line
1 3 ojosynariz
----------------------------------------------------------------------------------
2
-- Company: CEI
3
-- Engineer: David Aledo
4
--
5
-- Create Date:    12:41:19 06/10/2013
6
-- Design Name:    Configurable ANN
7
-- Module Name:    layerSP_top - Behavioral
8
-- Project Name:
9
-- Target Devices:
10
-- Tool versions:
11
-- Description: neuron layer top for artificial neural networks. Serial input and
12
--             parallel output.
13
--
14
-- Dependencies:
15
--
16
-- Revision:
17
-- Revision 0.01 - File Created
18
-- Additional Comments:
19
--
20
----------------------------------------------------------------------------------
21
library IEEE;
22
use IEEE.STD_LOGIC_1164.ALL;
23
use ieee.numeric_std.all;
24
 
25 8 jstefanowi
library work;
26
use work.wb_init.all; -- initialization package, comment out when not used
27
 
28 3 ojosynariz
-- Deprecated XPS library:
29
--library proc_common_v3_00_a;
30
--use proc_common_v3_00_a.proc_common_pkg.all; -- Only for simulation ( pad_power2() )
31
 
32
entity layerSP_top is
33
 
34
   generic
35
   (
36 8 jstefanowi
      WBinit  : boolean := false;
37
      LNum    : natural := 0;   ------- layer number (needed for initialization)
38
      NumN    : natural := 34;   ------- Number of neurons of the layer
39
      NumIn   : natural := 27;  ------- Number of inputs of each neuron
40 3 ojosynariz
      NbitIn  : natural := 8;   ------- Bit width of the input data
41 8 jstefanowi
      NbitW   : natural := 32;   ------- Bit width of weights and biases
42
      NbitOut : natural := 8;  ------- Bit width of the output data
43
      lra_l   : natural := 11;  ------- Layer RAM address length. It should value log2(NumN)+log2(NumIn)
44
      wra_l   : natural := 5;   ------- Weight RAM address length. It should value log2(NumIn)
45
      bra_l   : natural := 6;   ------- Bias RAM address length. It should value log2(NumN)
46
      LSbit   : natural := 6    ------- Less significant bit of the outputs
47 3 ojosynariz
   );
48
 
49
   port
50
   (
51
      -- Input ports
52
      reset   : in  std_logic;
53
      clk     : in  std_logic;
54
      run_in  : in  std_logic; -- Start and input data validation
55
      m_en    : in  std_logic; -- Memory enable (external interface)
56
      b_sel   : in  std_logic; -- Bias memory select
57
      m_we    : in  std_logic_vector(((NbitW+7)/8)-1 downto 0); -- Memory write enable (external interface)
58
      inputs  : in  std_logic_vector(NbitIn-1 downto 0); -- Input data (serial)
59
      wdata   : in  std_logic_vector(NbitW-1 downto 0);  -- Write data of weight and bias memories
60
      addr    : in  std_logic_vector(lra_l-1 downto 0); -- Address of weight and bias memories
61
 
62
      -- Output ports
63
      run_out : out std_logic; -- Output data validation, run_in for the next layer
64
      rdata   : out std_logic_vector(NbitW-1 downto 0);  -- Read data of weight and bias memories
65
      outputs : out std_logic_vector((NbitOut*NumN)-1 downto 0) -- Output data (parallel)
66
   );
67
 
68
end layerSP_top;
69
 
70
architecture Behavioral of layerSP_top is
71
 
72
   type ramd_type is array (NumIn-1 downto 0) of std_logic_vector(NbitW-1 downto 0); -- Optimal: 32 or 64 spaces
73
   type layer_ram is array (NumN-1 downto 0) of ramd_type;
74
   type outm_type is array (NumN-1 downto 0) of std_logic_vector(NbitW-1 downto 0);
75 8 jstefanowi
 
76 3 ojosynariz
 
77 8 jstefanowi
   function fw_init(LNum : natural) return layer_ram is
78
     variable tmp_arr : layer_ram := (others => (others => (others => '0'))) ;
79
   begin
80
      if WBinit = true then
81
          for i in 0 to NumIn-1 loop
82
             for j in 0 to NumN-1 loop
83
                tmp_arr(j)(i) := w_init(LNum)(i)(j);
84
             end loop;
85
          end loop;
86
      end if;
87
      return tmp_arr ;
88
   end fw_init;
89
 
90
   function fb_init(LNum : natural) return outm_type is
91
      variable tmp_arr : outm_type := (others => (others => '0')) ;
92
   begin
93
      if WBinit = true then
94
         for i in 0 to NumN-1 loop
95
           tmp_arr(i) := b_init(LNum)(i);
96
         end loop;
97
      end if;
98
      return tmp_arr;
99
   end fb_init;
100
 
101
 
102
 
103
   signal lram  : layer_ram := fw_init(LNum); -- Layer RAM. One RAM per neuron. It stores the weights
104
   signal breg  : outm_type := fb_init(LNum); -- Bias registers. They can not be RAM because they are accessed simultaneously
105 3 ojosynariz
   signal outm  : outm_type; -- RAM outputs to be multiplexed into rdata
106
   signal m_sel : std_logic_vector(NumN-1 downto 0);     -------- RAM select
107
   signal Wyb   : std_logic_vector((NbitW*NumN)-1 downto 0);  --- Weight vectors
108
   signal bias  : std_logic_vector((NbitW*NumN)-1 downto 0);  --- Bias vector
109
   signal Nouts : std_logic_vector((NbitOut*NumN)-1 downto 0); -- Outputs from neurons
110
   signal uaddr : unsigned(lra_l-1 downto 0); -- Unsigned address of weight and bias memories
111
 
112
   signal inreg : std_logic_vector(NbitIn-1 downto 0); -- Input data register -- en1 is delayed 1 cycle in order to insert a register for Wyb
113
 
114
   -- Control signals
115
   signal cont : integer range 0 to NumIn-1; -- Input counter
116
   signal en1 : std_logic; -- First step enable (multiplication of MAC)
117
   signal en2 : std_logic; -- Second stage enable (accumulation of MAC)
118
   signal en3 : std_logic; -- Shift register enable
119
   signal a0  : std_logic; -- Signal to load accumulators with the multiplication result
120
   signal aux_en3 : std_logic; -- Auxiliary signal to delay en3 two cycles
121
   signal aux_a0 : std_logic;
122
   signal aux2_en3 : std_logic;
123
 
124
begin
125
 
126
layerSP_inst: entity work.layerSP
127
   generic map
128
   (
129
      NumN    => NumN,
130
      NumIn   => NumIn,
131
      NbitIn  => NbitIn,
132
      NbitW   => NbitW,
133
      NbitOut => NbitOut,
134
      LSbit   => LSbit
135
   )
136
   port map
137
   (
138
      -- Input ports
139
      reset  => reset,
140
      clk    => clk,
141
      en     => en1,
142
      en2    => en2,
143
      en_r   => en3,
144
      a0     => a0,
145
      inputs => inreg,
146
      Wyb    => Wyb,
147
      bias   => bias,
148
 
149
      -- Output ports
150
      outputs => Nouts
151
   );
152
 
153
   uaddr <= unsigned(addr);
154
 
155
ram_selector:
156
   process (uaddr(lra_l-1 downto wra_l),b_sel) -- Top part of memory address and b_sel
157
   begin
158
      m_sel <= (others => '0'); -- Default
159
      for i in (NumN-1) downto 0 loop
160
         -- The top part of memory address selects which RAM
161
         if ( (to_integer(uaddr(lra_l-1 downto wra_l)) = i) and (b_sel = '0')) then
162
            m_sel(i) <= '1'; -- Enables the selected RAM
163
         end if;
164
      end loop;
165
   end process;
166
 
167
rams: -- Instance as weight and bias memories as neurons there are in the layer
168
   for i in (NumN-1) downto 0 generate
169
      process (clk)
170
         variable d : std_logic_vector(NbitW-1 downto 0); -- Beware of elements whose length is not a multiple of 8
171
      begin
172
         if (clk'event and clk = '1') then
173
            if (m_en = '1' and m_sel(i) = '1') then
174
               for j in ((NbitW+7)/8)-1 downto 0 loop -- we byte to byte
175
                  if (m_we(j) = '1') then
176
                     d((8*(j+1))-1 downto 8*j) := wdata((8*(j+1))-1 downto 8*j);
177
                  else
178
                     d((8*(j+1))-1 downto 8*j) := lram(i)(to_integer(uaddr(wra_l-1 downto 0)))((8*(j+1))-1 downto 8*j);
179
                  end if;
180
               end loop;
181
               -- Bottom part of layer memory selects weights inside the selected RAM
182
               lram(i)(to_integer(uaddr(wra_l-1 downto 0))) <= d;
183
               --
184
            end if;
185
         end if;
186
      end process;
187
      -- Outputs are read in parallel, resulting in a bus of weights:
188
      --Wyb((NbitW*(i+1))-1 downto NbitW*i) <= lram(i)(cont); -- Asynchronous read (forces distributed RAM)
189
      process (clk) -- Synchronous read
190
      begin
191
         if clk'event and clk = '1' then
192
            if reset = '1' then
193
               --Wyb((NbitW*(i+1))-1 downto NbitW*i) <= (others => '0');
194
            else
195
               Wyb((NbitW*(i+1))-1 downto NbitW*i) <= lram(i)(cont);
196
            end if;
197
         end if;
198
      end process;
199 8 jstefanowi
      outm(i) <= lram(i)(to_integer(uaddr(wra_l-1 downto 0))) when (uaddr(wra_l-1 downto 0) <= NumIn-1) else
200
                 (others => '0')  ; -- Read all RAM
201
      -- In my case I have 27 inputs and 34 neurons in the first layer. When I address
202
      -- the 1 layer's inputs for the second neuron the layer which acccepts a 6 bit wide
203
      -- input address (layer 2) sees the ..1 00100 (34) number and interprets it as an input
204
      -- address (which goes only up to 33) hence the bound check failure 
205
      -- fix: I've changed the assignment to a conditional one to check if we are not
206
      -- trying to read a weight of an input higher than the number of this layer's inputs. 
207 3 ojosynariz
   end generate;
208
 
209
   -- Synchronous read including breg:
210
   process (clk)
211
   begin
212
      if (clk'event and clk = '1') then
213 8 jstefanowi
         --report "addr: " & integer'image(wra_l-1);
214
         --report "addr: " & integer'image(to_integer(uaddr(wra_l-1 downto 0))  );
215 3 ojosynariz
         if (m_en = '1') then
216
            if (b_sel = '1') then
217
               rdata <= breg(to_integer(uaddr(bra_l-1 downto 0))); -- Bias registers selected
218
            else -- Other RAM selected:
219
               rdata <= outm(to_integer(uaddr(lra_l-1 downto wra_l))); -- Multiplexes RAM outputs
220
               -- May be safer if accesses to top address grater than NumN are avoided
221
            end if;
222
         end if;
223
      end if;
224
   end process;
225
 
226
bias_reg:
227
   process (clk)
228
      variable d : std_logic_vector(NbitW-1 downto 0); -- Beware of elements whose length is not a multiple of 8
229
   begin
230
      if (clk'event and clk = '1') then
231
         if ( (m_en = '1') and (b_sel = '1') ) then
232
            for i in ((NbitW+7)/8)-1 downto 0 loop -- we byte to byte
233
               if (m_we(i) = '1') then
234
                  d((8*(i+1))-1 downto 8*i) := wdata((8*(i+1))-1 downto 8*i);
235
               else
236
                  d((8*(i+1))-1 downto 8*i) := breg(to_integer(uaddr(bra_l-1 downto 0)))((8*(i+1))-1 downto 8*i);
237
               end if;
238
            end loop;
239
            -- The bottom part (reduced) of layer RAM address selects the bias
240
            breg(to_integer(uaddr(bra_l-1 downto 0))) <= d;
241
         end if;
242
      end if;
243
   end process;
244
bias_read:
245
   for i in (NumN-1) downto 0 generate
246
      --bias((NbitW*(i+1))-1 downto NbitW*i) <= breg(i); -- Asynchronous read of all biases in parallel
247
      process (clk)
248
      begin
249
        if clk'event and clk = '1' then
250
           if reset = '1' then
251
              --bias((NbitW*(i+1))-1 downto NbitW*i) <= (others => '0');
252
           else
253
              bias((NbitW*(i+1))-1 downto NbitW*i) <= breg(i); -- Synchronous read of all biases in parallel
254
           end if;
255
        end if;
256
      end process;
257
   end generate;
258
 
259
   outputs <= Nouts;
260
 
261
control:
262
   process (clk)
263
   begin
264
      if (clk'event and clk = '1') then
265
         if (reset = '1') then
266
            cont <= 0;
267
            en1 <= '0';
268
            en2 <= '0';
269
            en3 <= '0';
270
            a0  <= '0';
271
            run_out <= '0';
272
            aux_en3 <= '0';
273
            aux2_en3 <= '0';
274
            aux_a0 <= '0';
275
            inreg <= (others => '0');
276
         else
277
            en1 <= run_in; -- en1 is delayed 1 cycle in order to insert a register for Wyb
278
            inreg <= inputs;
279
            -- Default:
280
            aux2_en3 <= '0';
281
            if (run_in = '1') then
282
               if (cont = NumIn-1) then
283
                  cont <= 0; -- Restarts input counter
284
                  aux2_en3 <= '1';
285
               else
286
                  cont <= cont +1;
287
               end if;
288 8 jstefanowi
            --elsif (cont = NumIn-1) then -- for layers with more that
289
            --   cont <= 0;               -- 1 neuron uncommenting this
290
            --   aux2_en3 <= '1';         -- solved a problem with cont resetting
291 3 ojosynariz
            end if;
292
            en2 <= en1;
293
            if (cont = 0 and run_in = '1') then
294
               aux_a0 <= '1'; -- At the count beginning
295
            else
296
               aux_a0 <= '0';
297
            end if;
298
            a0 <= aux_a0;
299
            aux_en3 <= aux2_en3;
300
            en3 <= aux_en3;
301
            run_out <= en3; -- It lasts for 1 cycle, just after the output enable of the layer (when all outputs have just updated)
302
         end if;
303
      end if;
304
   end process;
305
 
306
end Behavioral;

powered by: WebSVN 2.1.0

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