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

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. Parallel input and
12
--             serial 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 10 jstefanowi
 
26 8 jstefanowi
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 layerPS_top is
33
 
34
   generic
35
   (
36 10 jstefanowi
      NumN    : natural := 64;  ------- Number of neurons of the layer
37
      NumIn   : natural := 8;   ------- Number of inputs of each neuron
38
      NbitIn  : natural := 12;  ------- Bit width of the input data
39
      NbitW   : natural := 8;   ------- Bit width of weights and biases
40 3 ojosynariz
      NbitOut : natural := 8;   ------- Bit width of the output data
41 10 jstefanowi
      lra_l   : natural := 10;  ------- Layer RAM address length. It should value log2(NumN)+log2(NumIn)
42
      wra_l   : natural := 3;   ------- Weight RAM address length. It should value log2(NumIn)
43 3 ojosynariz
      bra_l   : natural := 6;   ------- Bias RAM address length. It should value log2(NumN)
44 10 jstefanowi
      LSbit   : natural := 4;   ------- Less significant bit of the outputs
45
      WBinit  : boolean := false;
46
      LNum    : natural := 0    ------- layer number (needed for initialization)
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*NumIn)-1 downto 0); -- Input data (parallel)
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-1 downto 0) -- Output data (serial)
66
   );
67
 
68
end layerPS_top;
69
 
70
architecture Behavioral of layerPS_top is
71
 
72 10 jstefanowi
   --type ramd_type is array (pad_power2(NumN)-1 downto 0) of std_logic_vector(NbitW-1 downto 0); -- Optimal: 32 or 64 spaces -- pad_power2() only for simulation
73
   --type layer_ram is array (pad_power2(NumIn)-1 downto 0) of ramd_type;
74 3 ojosynariz
   type ramd_type is array (NumN-1 downto 0) of std_logic_vector(NbitW-1 downto 0); -- Optimal: 32 or 64 spaces
75
   type layer_ram is array (NumIn-1 downto 0) of ramd_type;
76
   type outm_type is array (NumIn-1 downto 0) of std_logic_vector(NbitW-1 downto 0);
77
 
78 8 jstefanowi
   function fw_init(LNum : natural) return layer_ram is
79
     variable tmp_arr : layer_ram := (others =>(others => (others => '0')));
80
   begin
81
      if WBinit = true then
82
         for i in 0 to NumIn-1 loop
83
            for j in 0 to NumN-1 loop
84
               tmp_arr(i)(j) := w_init(LNum)(i)(j);
85
            end loop;
86
         end loop;
87
      end if;
88
      return tmp_arr ;
89
   end fw_init;
90
 
91
 
92
 
93
 
94
   function fb_init(LNum : natural) return ramd_type is
95
      variable tmp_arr : ramd_type := (others => (others => '0')) ;
96
   begin
97
      if WBinit = true then
98
         for i in 0 to NumN-1 loop
99
           tmp_arr(i) := b_init(LNum)(i);
100
         end loop;
101
      end if;
102
      return tmp_arr;
103
   end fb_init;
104
 
105
   --function fb_init(LNum : natural) return ramd_type is
106
   --begin
107
   -- return ramd_type(b_init(LNum));
108
   --end fb_init;
109
 
110
   signal lram  : layer_ram := fw_init(LNum); -- Layer RAM. One RAM per input. It stores the weights
111
   signal breg  : ramd_type := fb_init(LNum); -- Bias RAM. They can be RAM because they are not accessed simultaneously
112 3 ojosynariz
   signal outm  : outm_type; -- RAM outputs to be multiplexed into rdata
113
   signal m_sel : std_logic_vector(NumIn-1 downto 0);   --------- RAM select
114
   signal Wyb   : std_logic_vector((NbitW*NumIn)-1 downto 0); -- Weight vectors
115
   signal bias  : std_logic_vector(NbitW-1 downto 0);   -------- Bias
116
   signal Nouts : std_logic_vector(NbitOut-1 downto 0);   ------ Outputs from neurons
117
   signal uaddr : unsigned(lra_l-1 downto 0); -- Unsigned address of weight and bias memories
118
 
119 8 jstefanowi
   -- Señales de control
120 3 ojosynariz
   signal cont : integer range 0 to NumN-1; -- Neuron counter
121
   signal cntb : integer range 0 to NumN-1; -- Delayed counter for biases
122
   signal st  : bit;  ------- State
123
   signal en1 : std_logic; -- First step enable
124
   signal en2 : std_logic; -- Second stage enable
125
   signal en3 : std_logic; -- Shift register enable
126
   signal en_out : std_logic;
127
 
128 8 jstefanowi
   signal input_aux1 : std_logic_vector((NbitIn*NumIn)-1 downto 0);
129
   signal input_aux2 : std_logic_vector((NbitIn*NumIn)-1 downto 0);
130 9 jstefanowi
--   signal input_aux3 : std_logic_vector((NbitIn*NumIn)-1 downto 0);
131 3 ojosynariz
begin
132
 
133
layerPS_inst: entity work.layerPS
134
   generic map
135
   (
136
      NumN    => NumN,
137
      NumIn   => NumIn,
138
      NbitIn  => NbitIn,
139
      NbitW   => NbitW,
140
      NbitOut => NbitOut,
141
      LSbit   => LSbit
142
   )
143
   port map
144
   (
145
      -- Input ports
146
      reset  => reset,
147
      clk    => clk,
148
      en     => en1,
149
      en2    => en2,
150
      en_r   => en3,
151 8 jstefanowi
      inputs => input_aux2,
152 3 ojosynariz
      Wyb    => Wyb,
153
      bias   => bias,
154
 
155
      -- Output ports
156
      en_out  => en_out,
157
      outputs => Nouts
158
   );
159
 
160
   uaddr <= unsigned(addr(lra_l-1 downto 0));
161
 
162
ram_selector:
163
   process (uaddr(wra_l-1 downto 0),b_sel) -- Bottom part of memory address and b_sel
164
   begin
165
      m_sel <= (others => '0'); -- Default
166
      for i in (NumIn-1) downto 0 loop
167
         -- The bottom part of memory address selects which RAM
168
         if ( (to_integer(uaddr(wra_l-1 downto 0)) = i) and (b_sel = '0')) then
169
            m_sel(i) <= '1'; -- Enables the selected RAM
170
         end if;
171
      end loop;
172
   end process;
173
 
174
rams: -- Instence as weight and bias memories as inputs there are in the layer
175
   for i in (NumIn-1) downto 0 generate
176
      process (clk)
177
         variable d : std_logic_vector(NbitW-1 downto 0); -- Beware of elements whose length is not a multiple of 8
178
      begin
179
         if (clk'event and clk = '1') then
180
            if (m_en = '1' and m_sel(i) = '1') then
181
               for j in ((NbitW+7)/8)-1 downto 0 loop -- we byte to byte
182
                  if (m_we(j) = '1') then
183
                     d((8*(j+1))-1 downto 8*j) := wdata((8*(j+1))-1 downto 8*j);
184
                  else
185
                     d((8*(j+1))-1 downto 8*j) := lram(i)(to_integer(uaddr(lra_l-1 downto wra_l)))((8*(j+1))-1 downto 8*j);
186
                  end if;
187
               end loop;
188
               -- Top part of weight and bias memory selects weights inside the selected RAM
189
               lram(i)(to_integer(uaddr(lra_l-1 downto wra_l))) <= d; -- Write
190
               --
191
            end if;
192
         end if;
193
      end process;
194
      -- Outpus are read in parallel, resulting in a bus of weights:
195
      --Wyb((NbitW*(i+1))-1 downto NbitW*i) <= lram(i)(cont); -- Asynchronous read (forces distributed RAM)
196
      process (clk) -- Synchronous read
197
      begin
198
         if clk'event and clk = '1' then
199
            if reset = '1' then
200
               --Wyb((NbitW*(i+1))-1 downto NbitW*i) <= (others => '0');
201
            else
202
               Wyb((NbitW*(i+1))-1 downto NbitW*i) <= lram(i)(cont);
203
            end if;
204
         end if;
205
      end process;
206
      outm(i) <= lram(i)(to_integer(uaddr(lra_l-1 downto wra_l))); -- Read all RAM
207
   end generate;
208
 
209
   -- Synchronous read including breg:
210
   process (clk)
211
   begin
212
      if (clk'event and clk = '1') then
213
         if (m_en = '1') then
214
            if (b_sel = '1') then
215
               rdata <= breg(to_integer(uaddr(bra_l-1 downto 0))); -- Bias RAM selected
216
            else -- Other RAM selected:
217
               rdata <= outm(to_integer(uaddr(wra_l-1 downto 0))); -- Multiplexes RAM outputs
218
               -- May be safer if accesses to bottom address grater than NumIn are avoided
219
            end if;
220
         end if;
221
      end if;
222
   end process;
223
 
224
bias_ram:
225
   process (clk)
226
      variable d : std_logic_vector(NbitW-1 downto 0); -- Beware of elements whose length is not a multiple of 8
227
   begin
228
      if (clk'event and clk = '1') then
229
         if ( (m_en = '1') and (b_sel = '1') ) then
230
            for i in ((NbitW+7)/8)-1 downto 0 loop -- we byte to byte
231
               if (m_we(i) = '1') then
232
                  d((8*(i+1))-1 downto 8*i) := wdata((8*(i+1))-1 downto 8*i);
233
               else
234
                  d((8*(i+1))-1 downto 8*i) := breg(to_integer(uaddr(bra_l-1 downto 0)))((8*(i+1))-1 downto 8*i);
235
               end if;
236
            end loop;
237
            -- The bottom part (extended) of memories address selects the bias
238
            breg(to_integer(uaddr(bra_l-1 downto 0))) <= d;
239
         end if;
240
      end if;
241
   end process;
242
 
243
-- Bias read: -- Here, parallel read of bias is not necessary, so it can be RAM
244
   --bias <= breg(cont); -- Asynchronous read
245
   process (clk) -- Synchronous read
246
   begin
247
      if clk'event and clk = '1' then
248
         if reset = '1' then
249
            --bias <= (others => '0');
250
         else
251
            bias <= breg(cntb);
252
         end if;
253
      end if;
254
   end process;
255
 
256
   outputs <= Nouts;
257
 
258
control: -- With counter and control signal shifts
259
   process (clk)
260
   begin
261
      if (clk'event and clk = '1') then
262
         if (reset = '1') then
263
            cont <= 0;
264
            cntb <= 0;
265
            st  <= '0';
266
            en1 <= '0';
267
            en2 <= '0';
268
            run_out <= '0';
269
         else
270 8 jstefanowi
            input_aux1 <= inputs;
271
            input_aux2 <= input_aux1;
272
            --input_aux3 <=input_aux3 input_aux2;
273
 
274 3 ojosynariz
            cntb <= cont; -- Bias counter is delayed to assure correctness of pipeline data
275
            case st is
276
               when '0' =>
277
                  en1 <= '0'; -- en1 is delayed 1 cycle in order to insert a register for Wyb
278
                  case run_in is
279
                     when '1' => st <= '1';
280
                     when '0' => st <= '0';
281
                     when others => st <= '0';
282
                  end case;
283
               when '1' =>
284
                  en1 <= '1'; -- en1 is delayed 1 cycle in order to insert a register for Wyb
285 8 jstefanowi
                  if cont = NumN-1 then
286
                     cont <= 0;
287
                     st <= '0';
288
                  else
289
                     cont <= cont +1;
290
                  end if;
291 3 ojosynariz
            end case;
292
 
293
            en2 <= en1;
294
 
295
            run_out <= en3; -- It lasts for 1 cycle, just after the output enable of the layer (when all outputs have just updated)
296
         end if;
297
      end if;
298
   end process;
299
 
300
   en3 <= en_out;
301
 
302
end Behavioral;

powered by: WebSVN 2.1.0

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