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

Subversion Repositories esoc

[/] [esoc/] [trunk/] [Sources/] [logixa/] [esoc_search_engine_sa.vhd] - Blame information for rev 42

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

Line No. Rev Author Line
1 42 lmaarsen
--------------------------------------------------------------------------------
2
----                                                                        ----
3
---- Ethernet Switch on Configurable Logic IP Core                          ----
4
----                                                                        ----
5
---- This file is part of the ESoCL project                                 ----
6
---- http://www.opencores.org/cores/esoc/                                   ----
7
----                                                                        ----
8
---- Description: see design description ESoCL_dd_71022001.pdf              ----
9
----                                                                        ----
10
---- To Do: see roadmap description ESoCL_dd_71022001.pdf                   ----
11
----        and/or release bulleting ESoCL_rb_71022001.pdf                  ----
12
----                                                                        ----
13
---- Author(s): L.Maarsen                                                   ----
14
---- Bert Maarsen, lmaarsen@opencores.org                                   ----
15
----                                                                        ----
16
--------------------------------------------------------------------------------
17
----                                                                        ----
18
---- Copyright (C) 2009 Authors and OPENCORES.ORG                           ----
19
----                                                                        ----
20
---- This source file may be used and distributed without                   ----
21
---- restriction provided that this copyright statement is not              ----
22
---- removed from the file and that any derivative work contains            ----
23
---- the original copyright notice and the associated disclaimer.           ----
24
----                                                                        ----
25
---- This source file is free software; you can redistribute it             ----
26
---- and/or modify it under the terms of the GNU Lesser General             ----
27
---- Public License as published by the Free Software Foundation;           ----
28
---- either version 2.1 of the License, or (at your option) any             ----
29
---- later version.                                                         ----
30
----                                                                        ----
31
---- This source is distributed in the hope that it will be                 ----
32
---- useful, but WITHOUT ANY WARRANTY; without even the implied             ----
33
---- warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR                ----
34
---- PURPOSE. See the GNU Lesser General Public License for more            ----
35
---- details.                                                               ----
36
----                                                                        ----
37
---- You should have received a copy of the GNU Lesser General              ----
38
---- Public License along with this source; if not, download it             ----
39
---- from http://www.opencores.org/lgpl.shtml                               ----
40
----                                                                        ----
41
--------------------------------------------------------------------------------
42
-- Object        : Entity work.esoc_search_engine_sa
43
-- Last modified : Mon Apr 14 12:50:09 2014.
44
--------------------------------------------------------------------------------
45
 
46
 
47
 
48
library ieee, std, work;
49
use ieee.std_logic_1164.all;
50
use std.textio.all;
51
use ieee.numeric_std.all;
52
use work.package_hash10_24b.all;
53
use work.package_esoc_configuration.all;
54
 
55
entity esoc_search_engine_sa is
56
  port(
57
    clk_search                : in     std_logic;
58
    reset                     : in     std_logic;
59
    search_aging_tick         : in     std_logic;
60
    search_entry_age_time     : in     std_logic_vector(11 downto 0);
61
    search_entry_age_time_ena : in     std_logic;
62
    search_sa_drop_cnt        : out    std_logic;
63
    search_sa_store_empty     : in     std_logic;
64
    search_sa_store_q         : in     std_logic_vector(79 downto 0);
65
    search_sa_store_rd        : out    std_logic;
66
    search_sa_store_words     : in     STD_LOGIC_VECTOR(6 downto 0);
67
    search_table_address      : out    STD_LOGIC_VECTOR(12 downto 0);
68
    search_table_data         : out    STD_LOGIC_VECTOR(79 downto 0);
69
    search_table_q            : in     STD_LOGIC_VECTOR(79 downto 0);
70
    search_table_rden         : out    STD_LOGIC;
71
    search_table_wren         : out    STD_LOGIC);
72
end entity esoc_search_engine_sa;
73
 
74
--------------------------------------------------------------------------------
75
-- Object        : Architecture work.esoc_search_engine_sa.esoc_search_engine_sa
76
-- Last modified : Mon Apr 14 12:50:09 2014.
77
--------------------------------------------------------------------------------
78
 
79
 
80
architecture esoc_search_engine_sa of esoc_search_engine_sa is
81
 
82
type   search_states is (idle, wait_sa, wait_hash, compare, add);
83
signal search_state: search_states;
84
 
85
type   aging_states is (idle, wait_empty, wait_entry, evaluate);
86
signal aging_state: aging_states;
87
 
88
signal search_table_address_i: std_logic_vector(search_table_address'high downto 0);
89
 
90
signal search_hash_delay_cnt: integer range esoc_search_engine_hash_delay downto 0;
91
signal search_table_coll_cnt: integer range esoc_search_engine_col_depth downto 0;
92
signal search_table_free_entry_os: integer range esoc_search_engine_col_depth downto 0;
93
signal search_table_free_entry: std_logic;
94
 
95
signal search_key_i: std_logic_vector(search_table_data'high downto 0);
96
 
97
signal aging_count_down: integer range 2**search_entry_age_time'length-1 downto 0;
98
signal aging_address: integer range 2**search_table_address'length-1 downto 0;
99
 
100
begin
101
 
102
--=============================================================================================================
103
-- Process                : proces search requests for source MAC address
104
-- Description  : 
105
--=============================================================================================================    
106
search_sa:  process(clk_search, reset)
107
            begin
108
              if reset = '1' then
109
                search_table_free_entry     <= '0';
110
                search_table_free_entry_os  <= 0;
111
                search_table_coll_cnt       <= 0;
112
 
113
                search_hash_delay_cnt       <= 0;
114
                search_sa_drop_cnt          <= '0';
115
 
116
                search_table_rden           <= '0';
117
                search_table_wren           <= '0';
118
                search_sa_store_rd          <= '0';
119
                search_key_i                <= (others => '0');
120
 
121
                search_table_address_i      <= (others => '0');
122
 
123
                search_state                <= idle;
124
                aging_state                 <= idle;
125
                aging_address               <= 0;
126
                aging_count_down            <= 0;
127
 
128
              elsif clk_search'event and clk_search = '1' then
129
                -- clear one-clock active signals
130
                search_sa_drop_cnt <= '0';
131
                search_table_rden  <= '0';
132
                search_table_wren  <= '0';
133
                search_sa_store_rd <= '0';
134
 
135
                --
136
                -- process new search requests 
137
                --
138
                case search_state is
139
                  when idle       =>  -- get Source Port + SA and calculate hash pointer (additional delay may be required after synthesis, due to large XOR tree)  
140
                                      if search_sa_store_empty = '0' then
141
                                        search_key_i                <= search_sa_store_q;
142
                                        search_table_address_i      <= CALC_HASH10_24b(search_sa_store_q(esoc_search_bus_mac+23 downto esoc_search_bus_mac)) & "000";
143
                                        search_table_rden           <= '1';
144
                                        search_table_free_entry     <= '0';
145
                                        search_table_free_entry_os  <= 0;
146
                                        search_table_coll_cnt       <= 0;
147
 
148
                                        -- use delay mechanism to give the hash function - large xor tree - time to provide stable result
149
                                        -- depends on target speed, use target timing analysis result to optimze this delay! At least one clock
150
                                        -- delay due to RAM latency
151
                                        search_hash_delay_cnt <= esoc_search_engine_hash_delay-1;
152
                                        search_state          <= wait_hash;
153
 
154
                                        search_sa_store_rd <= '1';
155
                                      end if;
156
 
157
                  when wait_hash  =>  -- hash result stable?  
158
                                      if search_hash_delay_cnt = 0 then
159
                                        search_table_address_i  <= std_logic_vector(to_unsigned(to_integer(unsigned(search_table_address_i))+1,search_table_address_i'length));
160
                                        search_state <= compare;
161
                                      else
162
                                        search_hash_delay_cnt <= search_hash_delay_cnt-1;
163
                                      end if;
164
 
165
                                      search_table_rden           <= '1';
166
 
167
                  when compare  => -- there is a hit on SA and VID and the entry is valid
168
                                   if search_table_q(esoc_search_entry_vlan+11 downto esoc_search_entry_vlan) = search_key_i(esoc_search_entry_vlan+11 downto esoc_search_entry_vlan) and
169
                                     search_table_q(esoc_search_entry_mac+47 downto esoc_search_entry_mac)   = search_key_i(esoc_search_entry_mac+47 downto esoc_search_entry_mac)   and
170
                                     search_table_q(esoc_search_entry_valid) = '1' then
171
 
172
                                    search_table_address_i                 <= std_logic_vector(to_unsigned(to_integer(unsigned(search_table_address_i))-1,search_table_address_i'length));
173
                                    search_key_i(esoc_search_entry_valid)  <= '1';
174
                                    search_key_i(esoc_search_entry_update) <= '1';
175
                                    search_table_wren                      <= '1';
176
                                    search_state                           <= idle;
177
 
178
                                  -- there is no hit on SA and VID
179
                                  else
180
                                    -- end of collission buffer not reached, prepare for next entry
181
                                    if search_table_coll_cnt < esoc_search_engine_col_depth then
182
                                      -- is the current entry empty, remember position to use it when end of collission buffer is reached without a hit
183
                                      if search_table_free_entry = '0' and search_table_q(esoc_search_entry_valid) = '0' then
184
                                        search_table_free_entry <= '1';
185
                                      elsif search_table_free_entry = '0' then
186
                                        search_table_free_entry_os <= search_table_free_entry_os + 1;
187
                                      end if;
188
 
189
                                      search_table_coll_cnt   <= search_table_coll_cnt + 1;
190
                                      search_table_address_i  <= std_logic_vector(to_unsigned(to_integer(unsigned(search_table_address_i))+1,search_table_address_i'length));
191
                                      search_table_rden       <= '1';
192
 
193
                                    -- end of collission buffer without a hit, check previous empty entries were found or that last entry is empty else report full collission buffer
194
                                    else
195
                                      -- previous entry of collission buffer was empty, use it to store new SA + VID
196
                                      if search_table_free_entry = '1' then
197
                                        search_table_address_i <= std_logic_vector(to_unsigned(to_integer(unsigned(search_table_address_i))-esoc_search_engine_col_depth+search_table_free_entry_os-1,search_table_address_i'length));
198
                                        search_table_wren      <= '1';
199
 
200
                                      -- no previous empty entries, if last entry of collission buffer is empty, use it to store new SA + VID
201
                                      elsif search_table_q(esoc_search_entry_valid) = '0' then
202
                                        search_table_address_i <= std_logic_vector(to_unsigned(to_integer(unsigned(search_table_address_i))-1,search_table_address_i'length));
203
                                        search_table_wren <= '1';
204
 
205
                                      -- no entry of collission buffer is empty, no space to store new SA + VID  
206
                                      else
207
                                        search_sa_drop_cnt <= '1';
208
                                      end if;
209
 
210
                                      search_key_i(esoc_search_entry_valid)  <= '1';
211
                                      search_key_i(esoc_search_entry_update) <= '1';
212
                                      search_state <= idle;
213
                                    end if;
214
                                  end if;
215
 
216
                  when others =>  search_state <= idle;
217
                end case;
218
 
219
                --
220
                -- process aging cycles
221
                --
222
                if search_aging_tick = '1' then
223
                  -- create aging timer based upon aging time setting register
224
                  if aging_count_down = 0 then
225
                    aging_count_down <= to_integer(unsigned(search_entry_age_time))+1;
226
                  else
227
                    aging_count_down <= aging_count_down - 1;
228
                  end if;
229
                end if;
230
 
231
                case aging_state is
232
                  when idle       =>  -- start aging cycle when aging mechanism is enabled and timer expires
233
                                      if aging_count_down = 0 and search_entry_age_time_ena = '1' then
234
                                        aging_address <= 0;
235
                                        aging_state   <= wait_empty;
236
                                      end if;
237
 
238
                  when wait_empty =>  -- wait for access to table with learned address (SA Search request first!)
239
                                      -- provide access when table is free for aging process
240
                                      if search_sa_store_empty = '1' and search_state = idle then
241
                                        search_table_address_i <= std_logic_vector(to_unsigned(aging_address,search_table_address_i'length));
242
                                        search_table_rden      <= '1';
243
                                        aging_state            <= wait_entry;
244
                                      end if;
245
 
246
                  when wait_entry =>  -- if table is still free prepare for entry evaluation else return to wait for access
247
                                      if search_sa_store_empty = '0' then
248
                                        aging_state <= wait_empty;
249
                                      else
250
                                        aging_state <= evaluate;
251
                                      end if;
252
 
253
                  when evaluate   =>  -- if table is still free update entry and increment address pointer else return to wait for access
254
                                      if search_sa_store_empty = '0' then
255
                                        aging_state <= wait_empty;
256
                                      else
257
                                        -- update the entry or even invalidate the entry
258
                                        if search_table_q(esoc_search_entry_valid) = '1' then
259
                                          search_key_i <= search_table_q;
260
                                          search_key_i(esoc_search_entry_valid)  <= search_table_q(esoc_search_entry_update);
261
                                          search_key_i(esoc_search_entry_update) <= '0';
262
                                          search_table_wren      <= '1';
263
                                        end if;
264
 
265
                                        -- update address pointer to process next entry
266
                                        if aging_address = 2**search_table_address_i'length - 1 then
267
                                          aging_state <= idle;
268
                                        else
269
                                          aging_address <= aging_address + 1;
270
                                          aging_state <= wait_empty;
271
                                        end if;
272
                                      end if;
273
 
274
                  when others     =>  aging_state <= idle;
275
                end case;
276
              end if;
277
            end process;
278
 
279
            search_table_address <= search_table_address_i;
280
            search_table_data    <= search_key_i;
281
 
282
end architecture esoc_search_engine_sa ; -- of esoc_search_engine_sa
283
 

powered by: WebSVN 2.1.0

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