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 18

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

Line No. Rev Author Line
1 10 pjf
----------------------------------------------------------------------------------
2
-- Company: 
3 18 pjf
-- Engineer:            Peter Fall
4 10 pjf
-- 
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 18 pjf
--              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 10 pjf
--
16 18 pjf
--              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 10 pjf
-- Dependencies: 
20
--
21
-- Revision: 
22 18 pjf
-- Revision 0.01 - File Created
23 10 pjf
-- Additional Comments: 
24
--
25
----------------------------------------------------------------------------------
26
library IEEE;
27 18 pjf
use IEEE.STD_LOGIC_1164.all;
28
use IEEE.NUMERIC_STD.all;
29 10 pjf
use ieee.std_logic_unsigned.all;
30
use work.arp_types.all;
31
 
32 18 pjf
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 10 pjf
end arp_STORE_br;
50
 
51
architecture Behavioral of arp_STORE_br is
52 18 pjf
 
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
  signal read_result_int        : arp_store_result_t;
80
 
81
  -- control signals
82
  signal set_st_state        : std_logic;
83
  signal set_next_write_addr : count_mode_t;
84
  signal set_num_entries     : count_mode_t;
85
  signal set_next_read_addr  : count_mode_t;
86
  signal write_ram           : std_logic;
87
  signal set_entry_found     : std_logic;
88
  signal set_mode            : std_logic;
89
 
90
  function read_status(status : arp_store_rslt_t; signal mode : mode_t) return arp_store_rslt_t is
91
    variable ret : arp_store_rslt_t;
92
  begin
93
    case status is
94
      when IDLE =>
95
        ret := status;
96
      when others =>
97
        if mode = MWRITE then
98
          ret := BUSY;
99
        else
100
          ret := status;
101
        end if;
102
    end case;
103
    return ret;
104
  end read_status;
105
 
106 10 pjf
begin
107 18 pjf
  combinatorial : process (
108
    -- input signals
109
    read_req, write_req, clear_store, reset,
110
    -- state variables
111
    ip_ram, mac_ram, st_state, next_write_addr, num_entries,
112
    next_read_addr, entry_found, mode, req_entry,
113
    -- busses
114
    next_st_state, arp_entry_val, mode_val, write_addr, read_result_int,
115
    -- control signals
116
    set_st_state, set_next_write_addr, set_num_entries, set_next_read_addr, set_entry_found,
117
    write_ram, set_mode
118
    )
119
  begin
120
    -- set output followers
121
    read_result_int.status <= IDLE;
122
    read_result_int.entry  <= entry_found;
123
    entry_count        <= to_unsigned(num_entries, 8);
124 10 pjf
 
125 18 pjf
    -- set bus defaults
126
    next_st_state <= IDLE;
127
    mode_val      <= MREAD;
128
    write_addr    <= next_write_addr;
129 10 pjf
 
130 18 pjf
    -- set signal defaults
131
    set_st_state        <= '0';
132
    set_next_write_addr <= HOLD;
133
    set_num_entries     <= HOLD;
134
    set_next_read_addr  <= HOLD;
135
    write_ram           <= '0';
136
    set_entry_found     <= '0';
137
    set_mode            <= '0';
138
 
139
    -- STORE FSM
140
    case st_state is
141
      when IDLE =>
142
        if write_req.req = '1' then
143
                                        -- need to search to see if this IP already there
144
          set_next_read_addr <= RST;    -- start lookup from beginning
145
          mode_val           <= MWRITE;
146
          set_mode           <= '1';
147
          next_st_state      <= PAUSE;
148
          set_st_state       <= '1';
149
        elsif read_req.req = '1' then
150
          set_next_read_addr <= RST;    -- start lookup from beginning
151
          mode_val           <= MREAD;
152
          set_mode           <= '1';
153
          next_st_state      <= PAUSE;
154
          set_st_state       <= '1';
155
        end if;
156
 
157
      when PAUSE =>
158
        -- wait until read addr is latched and we get first data out of the ram
159
        read_result_int.status <= read_status(BUSY, mode);
160
        set_next_read_addr <= INCR;
161
        next_st_state      <= SEARCH;
162
        set_st_state       <= '1';
163
 
164
      when SEARCH =>
165
        read_result_int.status                                    <= read_status(SEARCHING, mode);
166
        -- check if have a match at this entry
167
        if req_entry.ip = arp_entry_val.ip and next_read_addr <= num_entries then
168
                                        -- found it
169
          set_entry_found <= '1';
170
          next_st_state   <= FOUND;
171
          set_st_state    <= '1';
172
        elsif next_read_addr > num_entries or next_read_addr >= MAX_ARP_ENTRIES then
173
                                        -- reached end of entry table
174
          read_result_int.status <= read_status(NOT_FOUND, mode);
175
          next_st_state      <= NOT_FOUND;
176
          set_st_state       <= '1';
177
        else
178
                                        -- no match at this entry , go to next
179
          set_next_read_addr <= INCR;
180
        end if;
181
 
182
      when FOUND =>
183
        read_result_int.status <= read_status(FOUND, mode);
184
        if mode = MWRITE then
185
          write_addr    <= next_read_addr - 1;
186
          write_ram     <= '1';
187
          next_st_state <= IDLE;
188
          set_st_state  <= '1';
189
        elsif read_req.req = '0' then   -- wait in this state until request de-asserted
190
          next_st_state <= IDLE;
191
          set_st_state  <= '1';
192
        end if;
193
 
194
      when NOT_FOUND =>
195
        read_result_int.status <= read_status(NOT_FOUND, mode);
196
        if mode = MWRITE then
197
                                        -- need to write into the next free slot
198
          write_addr          <= next_write_addr;
199
          write_ram           <= '1';
200
          set_next_write_addr <= INCR;
201
          if num_entries < MAX_ARP_ENTRIES then
202
                                        -- if not full, count another entry (if full, it just wraps)
203
            set_num_entries <= INCR;
204
          end if;
205
          next_st_state <= IDLE;
206
          set_st_state  <= '1';
207
        elsif read_req.req = '0' then   -- wait in this state until request de-asserted
208
          next_st_state <= IDLE;
209
          set_st_state  <= '1';
210
        end if;
211
 
212
    end case;
213
  end process;
214
 
215
  sequential : process (clk)
216
  begin
217
    if rising_edge(clk) then
218
      -- ram processing
219
      if write_ram = '1' then
220
        ip_ram(write_addr)  <= req_entry.ip;
221
        mac_ram(write_addr) <= req_entry.mac;
222
      end if;
223
      if next_read_addr < MAX_ARP_ENTRIES then
224
        arp_entry_val.ip  <= ip_ram(next_read_addr);
225
        arp_entry_val.mac <= mac_ram(next_read_addr);
226
      else
227
        arp_entry_val.ip  <= (others => '0');
228
        arp_entry_val.mac <= (others => '0');
229
      end if;
230
 
231
      read_result <= read_result_int;
232
 
233
      if reset = '1' or clear_store = '1' then
234
        -- reset state variables
235
        st_state        <= IDLE;
236
        next_write_addr <= 0;
237
        num_entries     <= 0;
238
        next_read_addr  <= 0;
239
        entry_found.ip  <= (others => '0');
240
        entry_found.mac <= (others => '0');
241
        req_entry.ip    <= (others => '0');
242
        req_entry.mac   <= (others => '0');
243
        mode            <= MREAD;
244
 
245
      else
246
        -- Next req_state processing
247
        if set_st_state = '1' then
248
          st_state <= next_st_state;
249
        else
250
          st_state <= st_state;
251
        end if;
252
 
253
        -- mode setting and write request latching
254
        if set_mode = '1' then
255
          mode <= mode_val;
256
          if mode_val = MWRITE then
257
            req_entry <= write_req.entry;
258
          else
259
            req_entry.ip  <= read_req.ip;
260
            req_entry.mac <= (others => '0');
261
          end if;
262
        else
263
          mode      <= mode;
264
          req_entry <= req_entry;
265
        end if;
266
 
267
        -- latch entry found
268
        if set_entry_found = '1' then
269
          entry_found <= arp_entry_val;
270
        else
271
          entry_found <= entry_found;
272
        end if;
273
 
274
        -- next_write_addr counts and wraps
275
        case set_next_write_addr is
276
          when HOLD => next_write_addr                                             <= next_write_addr;
277
          when RST  => next_write_addr                                             <= 0;
278
          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;
279
        end case;
280
 
281
        -- num_entries counts and holds at max
282
        case set_num_entries is
283
          when HOLD => num_entries                                           <= num_entries;
284
          when RST  => num_entries                                           <= 0;
285
          when INCR => if next_write_addr < MAX_ARP_ENTRIES then num_entries <= num_entries + 1; else num_entries <= num_entries; end if;
286
        end case;
287
 
288
        -- next_read_addr counts and wraps
289
        case set_next_read_addr is
290
          when HOLD => next_read_addr                                          <= next_read_addr;
291
          when RST  => next_read_addr                                          <= 0;
292
          when INCR => if next_read_addr < MAX_ARP_ENTRIES then next_read_addr <= next_read_addr + 1; else next_read_addr <= 0; end if;
293
        end case;
294
 
295
      end if;
296
    end if;
297
  end process;
298
 
299 10 pjf
end Behavioral;

powered by: WebSVN 2.1.0

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