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 56

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

Line No. Rev Author Line
1 42 lmaarsen
--------------------------------------------------------------------------------
2 53 lmaarsen
--
3
-- This VHDL file was generated by EASE/HDL 7.4 Revision 4 from HDL Works B.V.
4
--
5
-- Ease library  : work
6
-- HDL library   : work
7
-- Host name     : S212065
8
-- User name     : df768
9
-- Time stamp    : Tue Aug 19 08:05:18 2014
10
--
11
-- Designed by   : L.Maarsen
12
-- Company       : LogiXA
13
-- Project info  : eSoC
14
--
15 42 lmaarsen
--------------------------------------------------------------------------------
16 53 lmaarsen
 
17 42 lmaarsen
--------------------------------------------------------------------------------
18
-- Object        : Entity work.esoc_search_engine_sa
19 53 lmaarsen
-- Last modified : Tue Aug 19 08:05:17 2014.
20 42 lmaarsen
--------------------------------------------------------------------------------
21
 
22
 
23
 
24
library ieee, std, work;
25
use ieee.std_logic_1164.all;
26
use std.textio.all;
27
use ieee.numeric_std.all;
28
use work.package_hash10_24b.all;
29
use work.package_esoc_configuration.all;
30
 
31
entity esoc_search_engine_sa is
32
  port(
33
    clk_search                : in     std_logic;
34
    reset                     : in     std_logic;
35
    search_aging_tick         : in     std_logic;
36
    search_entry_age_time     : in     std_logic_vector(11 downto 0);
37
    search_entry_age_time_ena : in     std_logic;
38
    search_sa_drop_cnt        : out    std_logic;
39
    search_sa_store_empty     : in     std_logic;
40
    search_sa_store_q         : in     std_logic_vector(79 downto 0);
41
    search_sa_store_rd        : out    std_logic;
42
    search_sa_store_words     : in     STD_LOGIC_VECTOR(6 downto 0);
43
    search_table_address      : out    STD_LOGIC_VECTOR(12 downto 0);
44
    search_table_data         : out    STD_LOGIC_VECTOR(79 downto 0);
45
    search_table_q            : in     STD_LOGIC_VECTOR(79 downto 0);
46
    search_table_rden         : out    STD_LOGIC;
47
    search_table_wren         : out    STD_LOGIC);
48
end entity esoc_search_engine_sa;
49
 
50
--------------------------------------------------------------------------------
51
-- Object        : Architecture work.esoc_search_engine_sa.esoc_search_engine_sa
52 53 lmaarsen
-- Last modified : Tue Aug 19 08:05:17 2014.
53 42 lmaarsen
--------------------------------------------------------------------------------
54
 
55
 
56
architecture esoc_search_engine_sa of esoc_search_engine_sa is
57
 
58
type   search_states is (idle, wait_sa, wait_hash, compare, add);
59
signal search_state: search_states;
60
 
61
type   aging_states is (idle, wait_empty, wait_entry, evaluate);
62
signal aging_state: aging_states;
63
 
64
signal search_table_address_i: std_logic_vector(search_table_address'high downto 0);
65
 
66
signal search_hash_delay_cnt: integer range esoc_search_engine_hash_delay downto 0;
67
signal search_table_coll_cnt: integer range esoc_search_engine_col_depth downto 0;
68
signal search_table_free_entry_os: integer range esoc_search_engine_col_depth downto 0;
69
signal search_table_free_entry: std_logic;
70
 
71
signal search_key_i: std_logic_vector(search_table_data'high downto 0);
72
 
73
signal aging_count_down: integer range 2**search_entry_age_time'length-1 downto 0;
74
signal aging_address: integer range 2**search_table_address'length-1 downto 0;
75
 
76
begin
77
 
78
--=============================================================================================================
79
-- Process                : proces search requests for source MAC address
80
-- Description  : 
81
--=============================================================================================================    
82
search_sa:  process(clk_search, reset)
83
            begin
84
              if reset = '1' then
85
                search_table_free_entry     <= '0';
86
                search_table_free_entry_os  <= 0;
87
                search_table_coll_cnt       <= 0;
88
 
89
                search_hash_delay_cnt       <= 0;
90
                search_sa_drop_cnt          <= '0';
91
 
92
                search_table_rden           <= '0';
93
                search_table_wren           <= '0';
94
                search_sa_store_rd          <= '0';
95
                search_key_i                <= (others => '0');
96
 
97
                search_table_address_i      <= (others => '0');
98
 
99
                search_state                <= idle;
100
                aging_state                 <= idle;
101
                aging_address               <= 0;
102
                aging_count_down            <= 0;
103
 
104
              elsif clk_search'event and clk_search = '1' then
105
                -- clear one-clock active signals
106
                search_sa_drop_cnt <= '0';
107
                search_table_rden  <= '0';
108
                search_table_wren  <= '0';
109
                search_sa_store_rd <= '0';
110
 
111
                --
112
                -- process new search requests 
113
                --
114
                case search_state is
115
                  when idle       =>  -- get Source Port + SA and calculate hash pointer (additional delay may be required after synthesis, due to large XOR tree)  
116
                                      if search_sa_store_empty = '0' then
117
                                        search_key_i                <= search_sa_store_q;
118
                                        search_table_address_i      <= CALC_HASH10_24b(search_sa_store_q(esoc_search_bus_mac+23 downto esoc_search_bus_mac)) & "000";
119
                                        search_table_rden           <= '1';
120
                                        search_table_free_entry     <= '0';
121
                                        search_table_free_entry_os  <= 0;
122
                                        search_table_coll_cnt       <= 0;
123
 
124
                                        -- use delay mechanism to give the hash function - large xor tree - time to provide stable result
125
                                        -- depends on target speed, use target timing analysis result to optimze this delay! At least one clock
126
                                        -- delay due to RAM latency
127
                                        search_hash_delay_cnt <= esoc_search_engine_hash_delay-1;
128
                                        search_state          <= wait_hash;
129
 
130
                                        search_sa_store_rd <= '1';
131
                                      end if;
132
 
133
                  when wait_hash  =>  -- hash result stable?  
134
                                      if search_hash_delay_cnt = 0 then
135
                                        search_table_address_i  <= std_logic_vector(to_unsigned(to_integer(unsigned(search_table_address_i))+1,search_table_address_i'length));
136
                                        search_state <= compare;
137
                                      else
138
                                        search_hash_delay_cnt <= search_hash_delay_cnt-1;
139
                                      end if;
140
 
141
                                      search_table_rden           <= '1';
142
 
143
                  when compare  => -- there is a hit on SA and VID and the entry is valid
144
                                   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
145
                                     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
146
                                     search_table_q(esoc_search_entry_valid) = '1' then
147
 
148
                                    search_table_address_i                 <= std_logic_vector(to_unsigned(to_integer(unsigned(search_table_address_i))-1,search_table_address_i'length));
149
                                    search_key_i(esoc_search_entry_valid)  <= '1';
150 53 lmaarsen
                                    search_key_i(esoc_search_entry_aging) <= '1';
151 42 lmaarsen
                                    search_table_wren                      <= '1';
152
                                    search_state                           <= idle;
153
 
154
                                  -- there is no hit on SA and VID
155
                                  else
156
                                    -- end of collission buffer not reached, prepare for next entry
157
                                    if search_table_coll_cnt < esoc_search_engine_col_depth then
158
                                      -- is the current entry empty, remember position to use it when end of collission buffer is reached without a hit
159
                                      if search_table_free_entry = '0' and search_table_q(esoc_search_entry_valid) = '0' then
160
                                        search_table_free_entry <= '1';
161
                                      elsif search_table_free_entry = '0' then
162
                                        search_table_free_entry_os <= search_table_free_entry_os + 1;
163
                                      end if;
164
 
165
                                      search_table_coll_cnt   <= search_table_coll_cnt + 1;
166
                                      search_table_address_i  <= std_logic_vector(to_unsigned(to_integer(unsigned(search_table_address_i))+1,search_table_address_i'length));
167
                                      search_table_rden       <= '1';
168
 
169
                                    -- end of collission buffer without a hit, check previous empty entries were found or that last entry is empty else report full collission buffer
170
                                    else
171
                                      -- previous entry of collission buffer was empty, use it to store new SA + VID
172
                                      if search_table_free_entry = '1' then
173
                                        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));
174
                                        search_table_wren      <= '1';
175
 
176
                                      -- no previous empty entries, if last entry of collission buffer is empty, use it to store new SA + VID
177
                                      elsif search_table_q(esoc_search_entry_valid) = '0' then
178
                                        search_table_address_i <= std_logic_vector(to_unsigned(to_integer(unsigned(search_table_address_i))-1,search_table_address_i'length));
179
                                        search_table_wren <= '1';
180
 
181
                                      -- no entry of collission buffer is empty, no space to store new SA + VID  
182
                                      else
183
                                        search_sa_drop_cnt <= '1';
184
                                      end if;
185
 
186
                                      search_key_i(esoc_search_entry_valid)  <= '1';
187 53 lmaarsen
                                      search_key_i(esoc_search_entry_aging) <= '1';
188 42 lmaarsen
                                      search_state <= idle;
189
                                    end if;
190
                                  end if;
191
 
192
                  when others =>  search_state <= idle;
193
                end case;
194
 
195
                --
196
                -- process aging cycles
197
                --
198
                if search_aging_tick = '1' then
199
                  -- create aging timer based upon aging time setting register
200
                  if aging_count_down = 0 then
201
                    aging_count_down <= to_integer(unsigned(search_entry_age_time))+1;
202
                  else
203
                    aging_count_down <= aging_count_down - 1;
204
                  end if;
205
                end if;
206
 
207
                case aging_state is
208
                  when idle       =>  -- start aging cycle when aging mechanism is enabled and timer expires
209
                                      if aging_count_down = 0 and search_entry_age_time_ena = '1' then
210
                                        aging_address <= 0;
211
                                        aging_state   <= wait_empty;
212
                                      end if;
213
 
214
                  when wait_empty =>  -- wait for access to table with learned address (SA Search request first!)
215
                                      -- provide access when table is free for aging process
216
                                      if search_sa_store_empty = '1' and search_state = idle then
217
                                        search_table_address_i <= std_logic_vector(to_unsigned(aging_address,search_table_address_i'length));
218
                                        search_table_rden      <= '1';
219
                                        aging_state            <= wait_entry;
220
                                      end if;
221
 
222
                  when wait_entry =>  -- if table is still free prepare for entry evaluation else return to wait for access
223
                                      if search_sa_store_empty = '0' then
224
                                        aging_state <= wait_empty;
225
                                      else
226
                                        aging_state <= evaluate;
227
                                      end if;
228
 
229
                  when evaluate   =>  -- if table is still free update entry and increment address pointer else return to wait for access
230
                                      if search_sa_store_empty = '0' then
231
                                        aging_state <= wait_empty;
232
                                      else
233
                                        -- update the entry or even invalidate the entry
234
                                        if search_table_q(esoc_search_entry_valid) = '1' then
235
                                          search_key_i <= search_table_q;
236 53 lmaarsen
                                          search_key_i(esoc_search_entry_valid)  <= search_table_q(esoc_search_entry_aging);
237
                                          search_key_i(esoc_search_entry_aging) <= '0';
238 42 lmaarsen
                                          search_table_wren      <= '1';
239
                                        end if;
240
 
241
                                        -- update address pointer to process next entry
242
                                        if aging_address = 2**search_table_address_i'length - 1 then
243
                                          aging_state <= idle;
244
                                        else
245
                                          aging_address <= aging_address + 1;
246
                                          aging_state <= wait_empty;
247
                                        end if;
248
                                      end if;
249
 
250
                  when others     =>  aging_state <= idle;
251
                end case;
252
              end if;
253
            end process;
254
 
255
            search_table_address <= search_table_address_i;
256
            search_table_data    <= search_key_i;
257
 
258
end architecture esoc_search_engine_sa ; -- of esoc_search_engine_sa
259
 

powered by: WebSVN 2.1.0

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