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

Subversion Repositories funbase_ip_library

[/] [funbase_ip_library/] [trunk/] [TUT/] [ip.hwp.interface/] [udp2hibi/] [1.0/] [vhd/] [ctrl_regs.vhd] - Blame information for rev 183

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

Line No. Rev Author Line
1 145 lanttu
-------------------------------------------------------------------------------
2
-- Title      : Control registers
3
-- Project    : UDP2HIBI
4
-------------------------------------------------------------------------------
5
-- File       : ctrl_regs.vhd
6
-- Author     : Jussi Nieminen
7
-- Last update: 2012-03-22
8
-- Platform   : 
9
-------------------------------------------------------------------------------
10
-- Description: Keep track of current sender and update a table with receiver
11
--              information.
12
--              Only 1 tx (fpga -> outside world) at a time,
13
--              but generic number of rx-operations.
14
--              
15
--              ES 2012-03-22: Check if there is a bug in table_valid.
16
--              That note is marked with "!!!", approx. at line 229
17
--              
18
-------------------------------------------------------------------------------
19
-- Revisions  :
20
-- Date        Version  Author  Description
21
-- 2009/12/08  1.0      niemin95        Created
22
-------------------------------------------------------------------------------
23
 
24
library ieee;
25
use ieee.std_logic_1164.all;
26
use work.udp2hibi_pkg.all;
27
 
28
 
29
entity ctrl_regs is
30
 
31
  generic (
32
    receiver_table_size_g : integer := 4;
33
    hibi_addr_width_g     : integer := 32
34
    );
35
 
36
  port (
37
    clk                : in  std_logic;
38
    rst_n              : in  std_logic;
39
 
40
    -- from hibi_receiver, new configurations
41
    release_lock_in    : in  std_logic;
42
    new_tx_conf_in     : in  std_logic;
43
    new_rx_conf_in     : in  std_logic;
44
    ip_in              : in  std_logic_vector( ip_addr_w_c-1 downto 0 );
45
    dest_port_in       : in  std_logic_vector( udp_port_w_c-1 downto 0 );
46
    source_port_in     : in  std_logic_vector( udp_port_w_c-1 downto 0 );
47
    lock_addr_in       : in  std_logic_vector( hibi_addr_width_g-1 downto 0 );
48
    response_addr_in   : in  std_logic_vector( hibi_addr_width_g-1 downto 0 );
49
    lock_out           : out std_logic;
50
    lock_addr_out      : out std_logic_vector( hibi_addr_width_g-1 downto 0 );
51
 
52
    -- to tx_ctrl, config params for sending
53
    tx_ip_out          : out std_logic_vector( ip_addr_w_c-1 downto 0 );
54
    tx_dest_port_out   : out std_logic_vector( udp_port_w_c-1 downto 0 );
55
    tx_source_port_out : out std_logic_vector( udp_port_w_c-1 downto 0 );
56
    timeout_release_in : in  std_logic;
57
 
58
    -- from rx_ctrl, params of the received ip packet
59
    rx_ip_in           : in  std_logic_vector( ip_addr_w_c-1 downto 0 );
60
    rx_dest_port_in    : in  std_logic_vector( udp_port_w_c-1 downto 0 );
61
    rx_source_port_in  : in  std_logic_vector( udp_port_w_c-1 downto 0 );
62
    rx_addr_valid_out  : out std_logic;
63
 
64
    -- to hibi_transmitter, send acknowledges
65
    ack_addr_out       : out std_logic_vector( hibi_addr_width_g-1 downto 0 );
66
    rx_addr_out        : out std_logic_vector( hibi_addr_width_g-1 downto 0 );
67
    send_tx_ack_out    : out std_logic;
68
    send_tx_nack_out   : out std_logic;
69
    send_rx_ack_out    : out std_logic;
70
    send_rx_nack_out   : out std_logic;
71
 
72
    -- from toplevel
73
    eth_link_up_in     : in  std_logic
74
    );
75
 
76
end ctrl_regs;
77
 
78
 
79
architecture rtl of ctrl_regs is
80
 
81
  -- Wildcards
82
  constant any_ip_c   : std_logic_vector( ip_addr_w_c-1 downto 0 )  := x"FFFFFFFF";
83
  constant any_port_c : std_logic_vector( udp_port_w_c-1 downto 0 ) := x"FFFF";
84
 
85
 
86
  -- Registers holding current tx info
87
  signal current_ip_r          : std_logic_vector(ip_addr_w_c-1 downto 0);
88
  signal current_dest_port_r   : std_logic_vector(udp_port_w_c-1 downto 0);
89
  signal current_source_port_r : std_logic_vector(udp_port_w_c-1 downto 0);
90
 
91
  -- Tx lock information
92
  signal locked_r : std_logic;
93
  signal lock_addr_r : std_logic_vector( hibi_addr_width_g-1 downto 0 );
94
 
95
 
96
  -- Table for rx receivers (each agent willing to receive data will have to
97
  -- register its hibi address to some source ip and ports)
98
  type receiver_info_type is
99
    record
100
      source_ip   : std_logic_vector(ip_addr_w_c-1 downto 0);
101
      source_port : std_logic_vector(udp_port_w_c-1 downto 0);
102
      dest_port   : std_logic_vector(udp_port_w_c-1 downto 0);
103
      hibi_addr   : std_logic_vector(hibi_addr_width_g-1 downto 0);
104
    end record;
105
  type     receiver_table_type is array (0 to receiver_table_size_g-1) of receiver_info_type;
106
  signal   receiver_table_r    : receiver_table_type;
107
  -- validness
108
  signal   table_valid_array_r : std_logic_vector(receiver_table_size_g-1 downto 0);
109
  -- to easily compare if full:
110
  constant table_full_c        : std_logic_vector(receiver_table_size_g-1 downto 0) := (others => '1');
111
 
112
 
113
 
114
 
115
-------------------------------------------------------------------------------
116
begin  -- rtl
117
-------------------------------------------------------------------------------
118
 
119
  lock_out      <= locked_r;
120
  lock_addr_out <= lock_addr_r;
121
  tx_ip_out     <= current_ip_r;
122
 
123
  tx_dest_port_out   <= current_dest_port_r;
124
  tx_source_port_out <= current_source_port_r;
125
 
126
  -----------------------------------------------------------------------------
127
  --
128
  -----------------------------------------------------------------------------
129
  main: process (clk, rst_n)
130
    variable spot_found_v : std_logic;
131
    variable match_found_v : std_logic;
132
  begin  -- process main
133
    if rst_n = '0' then                 -- asynchronous reset (active low)
134
 
135
      current_source_port_r <= (others => '0');
136
      current_dest_port_r   <= (others => '0');
137
      current_ip_r          <= (others => '0');
138
      locked_r              <= '0';
139
      lock_addr_r           <= (others => '0');
140
      table_valid_array_r   <= (others => '0');
141
      receiver_table_r      <= (others => ( (others => '0'), (others => '0'), (others => '0'), (others => '0') ));
142
 
143
      send_rx_nack_out  <= '0';
144
      send_rx_ack_out   <= '0';
145
      send_tx_nack_out  <= '0';
146
      send_tx_ack_out   <= '0';
147
      ack_addr_out      <= (others => '0');
148
      rx_addr_out       <= (others => '0');
149
      rx_addr_valid_out <= '0';
150
 
151
    elsif clk'event and clk = '1' then  -- rising clock edge
152
 
153
      -- default values
154
      send_tx_ack_out  <= '0';
155
      send_tx_nack_out <= '0';
156
      send_rx_ack_out  <= '0';
157
      send_rx_nack_out <= '0';
158
 
159
 
160
 
161
      -------------------------------------------------------------------------
162
      -- Handle the configuration requests
163
      -------------------------------------------------------------------------
164
      if new_tx_conf_in = '1' then
165
        -- New tx conf coming. Ensure that is not already locked at all, or
166
        -- locked to the same address, and then update values and send ack.
167
        -- Otherwise send nack.
168
 
169
        if ( locked_r = '0' or lock_addr_r = lock_addr_in )
170
          and eth_link_up_in = '1'
171
        then
172
          -- accept configuration
173
          current_ip_r          <= ip_in;
174
          current_dest_port_r   <= dest_port_in;
175
          current_source_port_r <= source_port_in;
176
          lock_addr_r           <= lock_addr_in;
177
          locked_r              <= '1';
178
 
179
          -- send ack
180
          send_tx_ack_out <= '1';
181
 
182
        else
183
          -- reject configuration attempt
184
          send_tx_nack_out <= '1';
185
        end if;
186
 
187
        ack_addr_out <= response_addr_in;
188
 
189
 
190
      elsif new_rx_conf_in = '1' then
191
        -- New rx conf coming. Check if there's room in the table, and store
192
        -- information if possible. Otherwise send a nack.
193
 
194
        -- Check if table full
195
        if table_valid_array_r = table_full_c then
196
          -- send a nack
197
          send_rx_nack_out <= '1';
198
        else
199
 
200
          -- Find an empty spot
201
          spot_found_v := '0';
202
          for n in 0 to receiver_table_size_g-1 loop
203
            if table_valid_array_r(n) = '0' and spot_found_v = '0' then
204
              -- Put it here, to smallest empty spot
205
              receiver_table_r(n).source_ip   <= ip_in;
206
              receiver_table_r(n).source_port <= source_port_in;
207
              receiver_table_r(n).dest_port   <= dest_port_in;
208
              receiver_table_r(n).hibi_addr   <= response_addr_in;
209
              table_valid_array_r(n)          <= '1';
210
 
211
              spot_found_v := '1';
212
            end if;
213
          end loop;  -- n
214
 
215
          send_rx_ack_out <= '1';
216
 
217
        end if;
218
 
219
        ack_addr_out <= response_addr_in;
220
 
221
 
222
      elsif release_lock_in = '1' then
223
        -- Release tx lock if requested
224
        locked_r    <= '0';
225
      end if;
226
      -- /conf requests
227
 
228
 
229
 
230
      -- !!! ES 2012-03-22
231
      -- It seems that signal table_valid_array_r(n) is never
232
      -- assigned to '0' after reset? Once the table gets full,
233
      -- there is not way to get more room.
234
      -- !!!
235
 
236
 
237
      -------------------------------------------------------------------------
238
      -- Address translation to rx address (hibi addr) according to info
239
      -- provided by rx_ctrl.
240
      -- Check that all 3 fields: src ip addr, src port and dst port match.
241
      -- Wildcards are accepted.
242
      -------------------------------------------------------------------------
243
      match_found_v := '0';
244
      for n in 0 to receiver_table_size_g-1 loop
245
        if table_valid_array_r(n) = '1'
246
          and (rx_ip_in = receiver_table_r(n).source_ip
247
                or
248
                receiver_table_r(n).source_ip = any_ip_c)
249
          and (rx_source_port_in = receiver_table_r(n).source_port
250
                or
251
                receiver_table_r(n).source_port = any_port_c)
252
          and (rx_dest_port_in = receiver_table_r(n).dest_port
253
                or
254
                receiver_table_r(n).dest_port = any_port_c)
255
        then
256
          rx_addr_out   <= receiver_table_r(n).hibi_addr;
257
          match_found_v := '1';
258
        end if;
259
      end loop;  -- n
260
 
261
      if match_found_v = '1' then
262
        rx_addr_valid_out <= '1';
263
      else
264
        rx_addr_valid_out <= '0';
265
      end if;
266
 
267
      -------------------------------------------------------------------------
268
      -- If timeout occures during a tx, tx_ctrl notifies about it and lock
269
      -- must be released in order to reset hibi_receiver's state
270
      -------------------------------------------------------------------------
271
      if timeout_release_in = '1' then
272
        locked_r <= '0';
273
      end if;
274
 
275
    end if;
276
  end process main;
277
 
278
 
279
 
280
end rtl;

powered by: WebSVN 2.1.0

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