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 36

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 36 pjf
    st_state, next_write_addr, num_entries,
112 18 pjf
    next_read_addr, entry_found, mode, req_entry,
113
    -- busses
114 36 pjf
    arp_entry_val
115 18 pjf
    -- control signals
116
    )
117
  begin
118
    -- set output followers
119
    read_result_int.status <= IDLE;
120
    read_result_int.entry  <= entry_found;
121
    entry_count        <= to_unsigned(num_entries, 8);
122 10 pjf
 
123 18 pjf
    -- set bus defaults
124
    next_st_state <= IDLE;
125
    mode_val      <= MREAD;
126
    write_addr    <= next_write_addr;
127 10 pjf
 
128 18 pjf
    -- set signal defaults
129
    set_st_state        <= '0';
130
    set_next_write_addr <= HOLD;
131
    set_num_entries     <= HOLD;
132
    set_next_read_addr  <= HOLD;
133
    write_ram           <= '0';
134
    set_entry_found     <= '0';
135
    set_mode            <= '0';
136
 
137
    -- STORE FSM
138
    case st_state is
139
      when IDLE =>
140
        if write_req.req = '1' then
141
                                        -- need to search to see if this IP already there
142
          set_next_read_addr <= RST;    -- start lookup from beginning
143
          mode_val           <= MWRITE;
144
          set_mode           <= '1';
145
          next_st_state      <= PAUSE;
146
          set_st_state       <= '1';
147
        elsif read_req.req = '1' then
148
          set_next_read_addr <= RST;    -- start lookup from beginning
149
          mode_val           <= MREAD;
150
          set_mode           <= '1';
151
          next_st_state      <= PAUSE;
152
          set_st_state       <= '1';
153
        end if;
154
 
155
      when PAUSE =>
156
        -- wait until read addr is latched and we get first data out of the ram
157
        read_result_int.status <= read_status(BUSY, mode);
158
        set_next_read_addr <= INCR;
159
        next_st_state      <= SEARCH;
160
        set_st_state       <= '1';
161
 
162
      when SEARCH =>
163
        read_result_int.status                                    <= read_status(SEARCHING, mode);
164
        -- check if have a match at this entry
165
        if req_entry.ip = arp_entry_val.ip and next_read_addr <= num_entries then
166
                                        -- found it
167
          set_entry_found <= '1';
168
          next_st_state   <= FOUND;
169
          set_st_state    <= '1';
170
        elsif next_read_addr > num_entries or next_read_addr >= MAX_ARP_ENTRIES then
171
                                        -- reached end of entry table
172
          read_result_int.status <= read_status(NOT_FOUND, mode);
173
          next_st_state      <= NOT_FOUND;
174
          set_st_state       <= '1';
175
        else
176
                                        -- no match at this entry , go to next
177
          set_next_read_addr <= INCR;
178
        end if;
179
 
180
      when FOUND =>
181
        read_result_int.status <= read_status(FOUND, mode);
182
        if mode = MWRITE then
183
          write_addr    <= next_read_addr - 1;
184
          write_ram     <= '1';
185
          next_st_state <= IDLE;
186
          set_st_state  <= '1';
187
        elsif read_req.req = '0' then   -- wait in this state until request de-asserted
188
          next_st_state <= IDLE;
189
          set_st_state  <= '1';
190
        end if;
191
 
192
      when NOT_FOUND =>
193
        read_result_int.status <= read_status(NOT_FOUND, mode);
194
        if mode = MWRITE then
195
                                        -- need to write into the next free slot
196
          write_addr          <= next_write_addr;
197
          write_ram           <= '1';
198
          set_next_write_addr <= INCR;
199
          if num_entries < MAX_ARP_ENTRIES then
200
                                        -- if not full, count another entry (if full, it just wraps)
201
            set_num_entries <= INCR;
202
          end if;
203
          next_st_state <= IDLE;
204
          set_st_state  <= '1';
205
        elsif read_req.req = '0' then   -- wait in this state until request de-asserted
206
          next_st_state <= IDLE;
207
          set_st_state  <= '1';
208
        end if;
209
 
210
    end case;
211
  end process;
212
 
213
  sequential : process (clk)
214
  begin
215
    if rising_edge(clk) then
216
      -- ram processing
217
      if write_ram = '1' then
218
        ip_ram(write_addr)  <= req_entry.ip;
219
        mac_ram(write_addr) <= req_entry.mac;
220
      end if;
221
      if next_read_addr < MAX_ARP_ENTRIES then
222
        arp_entry_val.ip  <= ip_ram(next_read_addr);
223
        arp_entry_val.mac <= mac_ram(next_read_addr);
224
      else
225
        arp_entry_val.ip  <= (others => '0');
226
        arp_entry_val.mac <= (others => '0');
227
      end if;
228
 
229
      read_result <= read_result_int;
230
 
231
      if reset = '1' or clear_store = '1' then
232
        -- reset state variables
233
        st_state        <= IDLE;
234
        next_write_addr <= 0;
235
        num_entries     <= 0;
236
        next_read_addr  <= 0;
237
        entry_found.ip  <= (others => '0');
238
        entry_found.mac <= (others => '0');
239
        req_entry.ip    <= (others => '0');
240
        req_entry.mac   <= (others => '0');
241
        mode            <= MREAD;
242
 
243
      else
244
        -- Next req_state processing
245
        if set_st_state = '1' then
246
          st_state <= next_st_state;
247
        else
248
          st_state <= st_state;
249
        end if;
250
 
251
        -- mode setting and write request latching
252
        if set_mode = '1' then
253
          mode <= mode_val;
254
          if mode_val = MWRITE then
255
            req_entry <= write_req.entry;
256
          else
257
            req_entry.ip  <= read_req.ip;
258
            req_entry.mac <= (others => '0');
259
          end if;
260
        else
261
          mode      <= mode;
262
          req_entry <= req_entry;
263
        end if;
264
 
265
        -- latch entry found
266
        if set_entry_found = '1' then
267
          entry_found <= arp_entry_val;
268
        else
269
          entry_found <= entry_found;
270
        end if;
271
 
272
        -- next_write_addr counts and wraps
273
        case set_next_write_addr is
274
          when HOLD => next_write_addr                                             <= next_write_addr;
275
          when RST  => next_write_addr                                             <= 0;
276
          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;
277
        end case;
278
 
279
        -- num_entries counts and holds at max
280
        case set_num_entries is
281
          when HOLD => num_entries                                           <= num_entries;
282
          when RST  => num_entries                                           <= 0;
283
          when INCR => if next_write_addr < MAX_ARP_ENTRIES then num_entries <= num_entries + 1; else num_entries <= num_entries; end if;
284
        end case;
285
 
286
        -- next_read_addr counts and wraps
287
        case set_next_read_addr is
288
          when HOLD => next_read_addr                                          <= next_read_addr;
289
          when RST  => next_read_addr                                          <= 0;
290
          when INCR => if next_read_addr < MAX_ARP_ENTRIES then next_read_addr <= next_read_addr + 1; else next_read_addr <= 0; end if;
291
        end case;
292
 
293
      end if;
294
    end if;
295
  end process;
296
 
297 10 pjf
end Behavioral;

powered by: WebSVN 2.1.0

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