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

Subversion Repositories udp_ip_stack

[/] [udp_ip_stack/] [trunk/] [rtl/] [vhdl/] [arp_STORE_br.vhd] - Blame information for rev 13

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

Line No. Rev Author Line
1 10 pjf
----------------------------------------------------------------------------------
2
-- Company: 
3
-- Engineer:            Peter Fall
4
-- 
5
-- Create Date:    12:00:04 05/31/2011 
6
-- Design Name: 
7
-- Module Name:    arp_STORE_br - Behavioral 
8
-- Project Name: 
9
-- Target Devices: 
10
-- Tool versions: 
11
-- Description:
12
--              ARP storage table using block ram with lookup based on IP address
13
--              implements upto 255 entries with sequential search
14
--              uses round robin overwrite when full (LRU would be better, but ...)
15
--
16
--              store may take a number of cycles and the request is latched
17
--              lookup may take a number of cycles. Assumes that request signals remain valid during lookup
18
--
19
-- Dependencies: 
20
--
21
-- Revision: 
22
-- Revision 0.01 - File Created
23
-- Additional Comments: 
24
--
25
----------------------------------------------------------------------------------
26
library IEEE;
27
use IEEE.STD_LOGIC_1164.ALL;
28
use IEEE.NUMERIC_STD.ALL;
29
use ieee.std_logic_unsigned.all;
30
use work.arp_types.all;
31
 
32
entity arp_STORE_br is
33
        generic (
34
                        MAX_ARP_ENTRIES : integer := 255                                                        -- max entries in the store
35
                        );
36
        Port (
37
                        -- read signals
38
                        read_req                                : in arp_store_rdrequest_t;             -- requesting a lookup or store
39
                        read_result                     : out arp_store_result_t;                       -- the result
40
                        -- write signals
41
                        write_req                       : in arp_store_wrrequest_t;             -- requesting a lookup or store
42
                        -- control and status signals
43
                        clear_store                     : in std_logic;                                         -- erase all entries
44
                        entry_count                     : out unsigned(7 downto 0);              -- how many entries currently in store
45
                        -- system signals
46
                        clk                                     : in std_logic;
47
                        reset                           : in  STD_LOGIC
48
                        );
49
end arp_STORE_br;
50
 
51
architecture Behavioral of arp_STORE_br is
52
 
53
        type st_state_t is (IDLE,PAUSE,SEARCH,FOUND,NOT_FOUND);
54
 
55
        type ip_ram_t is array (0 to MAX_ARP_ENTRIES-1) of std_logic_vector(31 downto 0);
56
        type mac_ram_t is array (0 to MAX_ARP_ENTRIES-1) of std_logic_vector(47 downto 0);
57
        subtype addr_t is integer range 0 to MAX_ARP_ENTRIES;
58
 
59
        type count_mode_t is (RST,INCR,HOLD);
60
 
61
        type mode_t is (MREAD,MWRITE);
62
 
63
        -- state variables
64
        signal ip_ram                                   : ip_ram_t;                                                                             -- will be implemented as block ram
65
        signal mac_ram                                  : mac_ram_t;                                                                    -- will be implemented as block ram     
66
        signal st_state                         : st_state_t;
67
        signal next_write_addr          : addr_t;                                                                               -- where to make the next write
68
        signal num_entries                      : addr_t;                                                                               -- number of entries in the store
69
        signal next_read_addr           : addr_t;                                                                               -- next addr to read from
70
        signal entry_found                      : arp_entry_t;                                                                  -- entry found in search
71
        signal mode                                             : mode_t;                                                                               -- are we writing or reading?
72
        signal req_entry                                : arp_entry_t;                                                                  -- entry latched from req
73
 
74
        -- busses
75
        signal next_st_state                    : st_state_t;
76
        signal arp_entry_val                    : arp_entry_t;
77
        signal mode_val                         : mode_t;
78
        signal write_addr                               : addr_t;                                                                               -- actual write address to use
79
 
80
        -- control signals
81
        signal set_st_state             : std_logic;
82
        signal set_next_write_addr      : count_mode_t;
83
        signal set_num_entries          : count_mode_t;
84
        signal set_next_read_addr       : count_mode_t;
85
        signal write_ram                                : std_logic;
86
        signal set_entry_found          : std_logic;
87
        signal set_mode                         : std_logic;
88
 
89
        function read_status(status : arp_store_rslt_t; signal mode : mode_t) return arp_store_rslt_t is
90
                variable ret : arp_store_rslt_t;
91
        begin
92
                case status is
93
                        when IDLE =>
94
                                ret := status;
95
                        when others =>
96
                                if mode = MWRITE then
97
                                        ret := BUSY;
98
                                else
99
                                        ret := status;
100
                                end if;
101
                end case;
102
                return ret;
103
        end read_status;
104
 
105
begin
106
        combinatorial : process (
107
                -- input signals
108
                read_req, write_req, clear_store, reset,
109
                -- state variables
110
                ip_ram, mac_ram, st_state, next_write_addr, num_entries,
111
                next_read_addr, entry_found, mode, req_entry,
112
                -- busses
113
                next_st_state, arp_entry_val, mode_val, write_addr,
114
                -- control signals
115
                set_st_state, set_next_write_addr, set_num_entries, set_next_read_addr, set_entry_found,
116
                write_ram, set_mode
117
                )
118
        begin
119
                -- set output followers
120
                read_result.status <= IDLE;
121
                read_result.entry <= entry_found;
122
                entry_count <= to_unsigned(num_entries,8);
123
 
124
                -- set bus defaults
125
                next_st_state <= IDLE;
126
                mode_val <= MREAD;
127
                write_addr <= next_write_addr;
128
 
129
                -- set signal defaults
130
                set_st_state <= '0';
131
                set_next_write_addr <= HOLD;
132
                set_num_entries <= HOLD;
133
                set_next_read_addr <= HOLD;
134
                write_ram <= '0';
135
                set_entry_found <= '0';
136
                set_mode <= '0';
137
 
138
                -- STORE FSM
139
                case st_state is
140
                        when IDLE =>
141
                                if write_req.req = '1' then
142
                                        -- need to search to see if this IP already there
143
                                        set_next_read_addr <= RST;                      -- start lookup from beginning
144
                                        mode_val <= MWRITE;
145
                                        set_mode <= '1';
146
                                        next_st_state <= PAUSE;
147
                                        set_st_state <= '1';
148
                                elsif read_req.req = '1' then
149
                                        set_next_read_addr <= RST;                      -- start lookup from beginning
150
                                        mode_val <= MREAD;
151
                                        set_mode <= '1';
152
                                        next_st_state <= PAUSE;
153
                                        set_st_state <= '1';
154
                                end if;
155
 
156
                        when PAUSE =>
157
                                -- wait until read addr is latched and we get first data out of the ram
158
                                read_result.status <= read_status(BUSY,mode);
159
                                set_next_read_addr <= INCR;
160
                                next_st_state <= SEARCH;
161
                                set_st_state <= '1';
162
 
163
                        when SEARCH =>
164
                                read_result.status <= read_status(SEARCHING,mode);
165
                                -- check if have a match at this entry
166
                                if req_entry.ip = arp_entry_val.ip and next_read_addr <= num_entries then
167
                                        -- found it
168
                                        set_entry_found <= '1';
169
                                        next_st_state <= FOUND;
170
                                        set_st_state <= '1';
171
                                elsif next_read_addr > num_entries or next_read_addr >= MAX_ARP_ENTRIES then
172
                                        -- reached end of entry table
173
                                        read_result.status <= read_status(NOT_FOUND,mode);
174
                                        next_st_state <= NOT_FOUND;
175
                                        set_st_state <= '1';
176
                                else
177
                                        -- no match at this entry , go to next
178
                                        set_next_read_addr <= INCR;
179
                                end if;
180
 
181
                        when FOUND =>
182
                                read_result.status <= read_status(FOUND,mode);
183
                                if mode = MWRITE then
184
                                        write_addr <= next_read_addr - 1;
185
                                        write_ram <= '1';
186
                                        next_st_state <= IDLE;
187
                                        set_st_state <= '1';
188
                                elsif read_req.req = '0' then                    -- wait in this state until request de-asserted
189
                                        next_st_state <= IDLE;
190
                                        set_st_state <= '1';
191
                                end if;
192
 
193
                        when NOT_FOUND =>
194
                                read_result.status <= read_status(NOT_FOUND,mode);
195
                                if mode = MWRITE then
196
                                        -- need to write into the next free slot
197
                                        write_addr <= next_write_addr;
198
                                        write_ram <= '1';
199
                                        set_next_write_addr <= INCR;
200
                                        if num_entries < MAX_ARP_ENTRIES then
201
                                                -- if not full, count another entry (if full, it just wraps)
202
                                                set_num_entries <= INCR;
203
                                        end if;
204
                                        next_st_state <= IDLE;
205
                                        set_st_state <= '1';
206
                                elsif read_req.req = '0' then                    -- wait in this state until request de-asserted
207
                                        next_st_state <= IDLE;
208
                                        set_st_state <= '1';
209
                                end if;
210
 
211
                end case;
212
        end process;
213
 
214
        sequential : process (clk)
215
        begin
216
                if rising_edge(clk) then
217
                        -- ram processing
218
                        if write_ram = '1' then
219
                                ip_ram(write_addr) <= req_entry.ip;
220
                                mac_ram(write_addr) <= req_entry.mac;
221
                        end if;
222
                        if next_read_addr < MAX_ARP_ENTRIES then
223
                                arp_entry_val.ip <= ip_ram(next_read_addr);
224
                                arp_entry_val.mac <= mac_ram(next_read_addr);
225
                        else
226
                                arp_entry_val.ip <= (others => '0');
227
                                arp_entry_val.mac <= (others => '0');
228
                        end if;
229
 
230
                        if reset = '1' or clear_store = '1' then
231
                                -- reset state variables
232
                                st_state <= IDLE;
233
                                next_write_addr <= 0;
234
                                num_entries <= 0;
235
                                next_read_addr <= 0;
236
                                entry_found.ip <= (others => '0');
237
                                entry_found.mac <= (others => '0');
238
                                req_entry.ip <= (others => '0');
239
                                req_entry.mac <= (others => '0');
240
                                mode <= MREAD;
241
 
242
                        else
243
                                -- Next req_state processing
244
                                if set_st_state = '1' then
245
                                        st_state <= next_st_state;
246
                                else
247
                                        st_state <= st_state;
248
                                end if;
249
 
250
                                -- mode setting and write request latching
251
                                if set_mode = '1' then
252
                                        mode <= mode_val;
253
                                        if mode_val = MWRITE then
254
                                                req_entry <= write_req.entry;
255
                                        else
256
                                                req_entry.ip <= read_req.ip;
257
                                                req_entry.mac <= (others => '0');
258
                                        end if;
259
                                else
260
                                        mode <= mode;
261
                                        req_entry <= req_entry;
262
                                end if;
263
 
264
                                -- latch entry found
265
                                if set_entry_found = '1' then
266
                                        entry_found <= arp_entry_val;
267
                                else
268
                                        entry_found <= entry_found;
269
                                end if;
270
 
271
                                -- next_write_addr counts and wraps
272
                                case set_next_write_addr is
273
                                        when HOLD => next_write_addr <= next_write_addr;
274
                                        when RST => next_write_addr <= 0;
275
                                        when INCR => if next_write_addr < MAX_ARP_ENTRIES-1 then next_write_addr <= next_write_addr + 1;  else next_write_addr <= 0; end if;
276
                                end case;
277
 
278
                                -- num_entries counts and holds at max
279
                                case set_num_entries is
280
                                        when HOLD => num_entries <= num_entries;
281
                                        when RST => num_entries <= 0;
282
                                        when INCR => if next_write_addr < MAX_ARP_ENTRIES then num_entries <= num_entries + 1; else num_entries <= num_entries; end if;
283
                                end case;
284
 
285
                                -- next_read_addr counts and wraps
286
                                case set_next_read_addr is
287
                                        when HOLD => next_read_addr <= next_read_addr;
288
                                        when RST => next_read_addr <= 0;
289
                                        when INCR => if next_read_addr < MAX_ARP_ENTRIES then next_read_addr <= next_read_addr + 1; else next_read_addr <= 0; end if;
290
                                end case;
291
 
292
                        end if;
293
                end if;
294
        end process;
295
 
296
end Behavioral;

powered by: WebSVN 2.1.0

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