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 3

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

powered by: WebSVN 2.1.0

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