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/] [hibi_receiver.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      : HIBI receiver
3
-- Project    : UDP2HIBI
4
-------------------------------------------------------------------------------
5
-- File       : hibi_receiver.vhd
6
-- Author     : Jussi Nieminen
7
-- Last update: 2012-03-22
8
-- Platform   : 
9
-------------------------------------------------------------------------------
10
-- Description: Decides what to do with packets coming from HIBI.
11
--              Gives parameters to ctrl-registers and data to tx-ctrl.
12
-------------------------------------------------------------------------------
13
-- Revisions  :
14
-- Date        Version  Author  Description
15
-- 2009/12/02  1.0      niemin95        Created
16
-------------------------------------------------------------------------------
17
 
18
library ieee;
19
use ieee.std_logic_1164.all;
20
use ieee.numeric_std.all;
21
use work.udp2hibi_pkg.all;
22
 
23
 
24
entity hibi_receiver is
25
 
26
  generic (
27
    hibi_comm_width_g : integer := 3;
28
    hibi_addr_width_g : integer := 32;
29
    hibi_data_width_g : integer := 32
30
    );
31
 
32
  port (
33
    clk              : in  std_logic;
34
    rst_n            : in  std_logic;
35
    -- to HIBI
36
    hibi_comm_in     : in  std_logic_vector( hibi_comm_width_g-1 downto 0 );
37
    hibi_data_in     : in  std_logic_vector( hibi_data_width_g-1 downto 0 );
38
    hibi_av_in       : in  std_logic;
39
    hibi_re_out      : out std_logic;
40
    hibi_empty_in    : in  std_logic;
41
    -- to tx multiclk fifo (width 16) (the fifo is really inside tx_ctrl)
42
    tx_data_out      : out std_logic_vector( udp_block_data_w_c-1 downto 0 );
43
    tx_we_out        : out std_logic;
44
    tx_full_in       : in  std_logic;
45
    -- to tx_ctrl
46
    new_tx_out       : out std_logic;
47
    tx_length_out    : out std_logic_vector( tx_len_w_c-1 downto 0 );
48
    new_tx_ack_in    : in  std_logic;
49
    timeout_out      : out std_logic_vector( timeout_w_c-1 downto 0 );
50
    timeout_in       : in  std_logic;
51
    -- to ctrl_regs
52
    release_lock_out  : out std_logic;
53
    new_tx_conf_out   : out std_logic;
54
    new_rx_conf_out   : out std_logic;
55
    ip_out            : out std_logic_vector( ip_addr_w_c-1 downto 0 );
56
    dest_port_out     : out std_logic_vector( udp_port_w_c-1 downto 0 );
57
    source_port_out   : out std_logic_vector( udp_port_w_c-1 downto 0 );
58
    lock_addr_out     : out std_logic_vector( hibi_addr_width_g-1 downto 0 );
59
    response_addr_out : out std_logic_vector( hibi_addr_width_g-1 downto 0 );
60
    lock_in           : in  std_logic;
61
    lock_addr_in      : in  std_logic_vector( hibi_addr_width_g-1 downto 0 )
62
    );
63
 
64
end hibi_receiver;
65
 
66
 
67
architecture rtl of hibi_receiver is
68
 
69
  -- store the address data is coming to
70
  signal current_hibi_addr_r : std_logic_vector( hibi_addr_width_g-1 downto 0 );
71
 
72
  signal hibi_re   : std_logic;
73
  signal hibi_re_r : std_logic;
74
  signal tx_we_r   : std_logic;
75
  signal new_tx_r  : std_logic;
76
 
77
  -- state machine to ease up tx configuring
78
  type conf_state_type is (idle, ip, ports, hibi_addr);
79
  signal conf_state_r : conf_state_type;
80
 
81
  type conf_type is (tx, rx);
82
  signal conf_type_r : conf_type;
83
 
84
  -- we must count the amount of data we get
85
  signal data_cnt_r : integer range 0 to 2**tx_len_w_c-1;
86
  signal tx_ongoing_r : std_logic;
87
  signal tx_data_select_r : std_logic;
88
  signal store_upper_half_r : std_logic;
89
 
90
  signal timeout_dump_r : std_logic;
91
  signal dump_data_r    : std_logic;
92
 
93
-------------------------------------------------------------------------------
94
begin  -- rtl
95
-------------------------------------------------------------------------------
96
 
97
  -----------------------------------------------------------------------------
98
  -- connect multiclk fifo's data_in to either upper of lower half of the word
99
  -- in hibi's data according to store_upper_half_r
100
  tx_data_mux: process (hibi_data_in, store_upper_half_r)
101
  begin  -- process tx_data_mux
102
    if store_upper_half_r = '1' then
103
      -- upper half
104
      tx_data_out <= hibi_data_in(31 downto 16);
105
    else
106
      -- lower half
107
      tx_data_out <= hibi_data_in(15 downto 0);
108
    end if;
109
  end process tx_data_mux;
110
  -----------------------------------------------------------------------------
111
 
112
 
113
  -- the we signal must not be high, if there's nothing or an address coming
114
  tx_we_out <= tx_we_r and (not hibi_empty_in) and (not hibi_av_in);
115
  -- the re signal must remain down, if multiclk fifo is full
116
  hibi_re <= hibi_re_r and ((not tx_full_in) or timeout_dump_r);
117
  hibi_re_out <= hibi_re;
118
  new_tx_out <= new_tx_r;
119
 
120
 
121
  -----------------------------------------------------------------------------
122
  main : process (clk, rst_n)
123
    variable hibi_re_v : std_logic;
124
  begin  -- process main
125
    if rst_n = '0' then                 -- asynchronous reset (active low)
126
 
127
      conf_state_r <= idle;
128
      conf_type_r <= tx;
129
 
130
      hibi_re_r        <= '0';
131
      current_hibi_addr_r <= (others => '0');
132
      tx_we_r             <= '0';
133
      new_tx_r            <= '0';
134
      data_cnt_r          <= 0;
135
      tx_ongoing_r        <= '0';
136
      dump_data_r         <= '0';
137
      timeout_dump_r      <= '0';
138
      store_upper_half_r    <= '0';
139
 
140
      tx_we_r          <= '0';
141
      new_tx_r         <= '0';
142
      tx_length_out    <= (others => '0');
143
      new_tx_conf_out  <= '0';
144
      new_rx_conf_out  <= '0';
145
      ip_out           <= (others => '0');
146
      dest_port_out    <= (others => '0');
147
      source_port_out  <= (others => '0');
148
      lock_addr_out    <= (others => '0');
149
      response_addr_out <= (others => '0');
150
      timeout_out      <= (others => '0');
151
      release_lock_out <= '0';
152
 
153
 
154
    elsif clk'event and clk = '1' then  -- rising clock edge
155
 
156
      -- default values
157
      hibi_re_r <= '0';
158
      tx_we_r      <= '0';
159
 
160
      new_tx_conf_out  <= '0';
161
      new_rx_conf_out  <= '0';
162
      release_lock_out <= '0';
163
 
164
 
165
      if new_tx_r = '1' and new_tx_ack_in = '1' then
166
        new_tx_r <= '0';
167
      end if;
168
 
169
      if timeout_in = '1' and
170
        tx_ongoing_r = '1' and
171
        current_hibi_addr_r = lock_addr_in
172
      then
173
        -- dump data that is waiting and clear tx_ongoing_r
174
        timeout_dump_r  <= '1';
175
        tx_ongoing_r <= '0';
176
      end if;
177
 
178
 
179
      -------------------------------------------------------------------------
180
      -- if there is data incoming, and we already have written half the
181
      -- current word to the multiclk fifo, now we write the other half
182
      if store_upper_half_r = '1' then
183
        -- this means, that we are writing the upper half of current data word
184
 
185
        tx_we_r <= '1';
186
 
187
        if tx_full_in = '0' then
188
          store_upper_half_r <= '0';
189
          -- if we have one halfword left, we can read out the final data next
190
          -- cycle already
191
          if data_cnt_r = 1 then
192
            hibi_re_r <= '1';
193
          else
194
            hibi_re_r <= '0';
195
          end if;
196
 
197
        else
198
          -- keep hibi_re_r up (full signal will keep the final re to hibi
199
          -- down), so that the data is read out right after full comes down
200
          hibi_re_r <= '1';
201
        end if;
202
      -------------------------------------------------------------------------
203
 
204
 
205
      -------------------------------------------------------------------------
206
      elsif hibi_empty_in = '0' then
207
 
208
        -- read, unless we are reading first half of data (that is decided later)
209
        hibi_re_v := '1';
210
 
211
        -- if address valid, store it
212
        if hibi_av_in = '1' then
213
 
214
          if hibi_re_r = '1' then
215
            current_hibi_addr_r <= hibi_data_in;
216
            dump_data_r <= '0';
217
            -- don't read next data yet, if data coming
218
            if lock_in = '1' and hibi_data_in = lock_addr_in and tx_ongoing_r = '1' then
219
              hibi_re_v := '0';
220
            end if;
221
          end if;
222
 
223
        else
224
 
225
          ---------------------------------------------------------------------
226
          if timeout_dump_r = '1' and lock_in = '0' and
227
            current_hibi_addr_r = lock_addr_in and hibi_re = '1'
228
          then
229
            -- Timeout has happened, no new tx_confs, and there's still data coming.
230
            -- (This might be due to some ethernet problems.)
231
            -- Dump data.
232
            if data_cnt_r <= 2 then
233
              data_cnt_r <= 0;
234
              timeout_dump_r <= '0';
235
            else
236
              data_cnt_r <= data_cnt_r - 2;
237
            end if;
238
 
239
 
240
          -- not dumping
241
          elsif dump_data_r = '0'
242
          then
243
 
244
            -------------------------------------------------------------------
245
            -- if we are receiving data to locked address
246
            if lock_in = '1' and current_hibi_addr_r = lock_addr_in and tx_ongoing_r = '1' then
247
 
248
 
249
              if tx_we_r = '1' and tx_full_in = '0' then
250
                -- we are currently writing the lower half, so move on to write
251
                -- the upper if necessary
252
 
253
                if data_cnt_r = 2 then
254
 
255
                  -- last two 16-bit words
256
                  store_upper_half_r <= '1';
257
                  tx_ongoing_r <= '0';
258
                  tx_we_r <= '1';
259
                  data_cnt_r <= 0;
260
 
261
                elsif data_cnt_r = 1 then
262
                  -- one halfword left, read it out right away, don't store other
263
                  -- half
264
                  tx_ongoing_r <= '0';
265
                  data_cnt_r <= 0;
266
 
267
                else
268
                  -- more data left, just write as usual
269
                  store_upper_half_r <= '1';
270
 
271
                  -- don't read yet, because we still need to write the upper
272
                  -- half too
273
                  data_cnt_r <= data_cnt_r - 2;
274
                  tx_we_r <= '1';
275
                end if;
276
 
277
              else
278
 
279
                -- if we is not up, or full is up, lift/keep we up and wait for a cycle
280
                hibi_re_v := '0';
281
                tx_we_r <= '1';
282
              end if;
283
 
284
 
285
 
286
            -------------------------------------------------------------------
287
            -- if we are in the middle of receiving a conf word
288
            elsif conf_state_r /= idle and hibi_re = '1' then
289
 
290
              case conf_state_r is
291
                when ip =>
292
                  ip_out <= hibi_data_in;
293
                  conf_state_r <= ports;
294
                when ports =>
295
                  dest_port_out <= hibi_data_in( 31 downto 16 );
296
                  source_port_out <= hibi_data_in( 15 downto 0 );
297
                  conf_state_r <= hibi_addr;
298
                when hibi_addr =>
299
                  response_addr_out <= hibi_data_in;
300
                  lock_addr_out <= current_hibi_addr_r;
301
 
302
                  if conf_type_r = tx then
303
                    new_tx_conf_out <= '1';
304
                  else
305
                    new_rx_conf_out <= '1';
306
                  end if;
307
 
308
                  conf_state_r <= idle;
309
                when others => null;
310
              end case;
311
 
312
 
313
            -------------------------------------------------------------------
314
            -- when receiving conf words we can wait until re is up before
315
            -- doing anything. With data we cant, because tx fifo's write
316
            -- enable must be up in time.
317
            elsif hibi_data_in( id_hi_idx_c downto id_lo_idx_c ) = tx_conf_header_id_c
318
              and hibi_re = '1'
319
            then
320
              -- tx conf packet received
321
              conf_type_r <= tx;
322
              conf_state_r <= ip;
323
              timeout_out <= hibi_data_in( timeout_w_c-1 downto 0 );
324
 
325
            -------------------------------------------------------------------
326
            elsif hibi_data_in( id_hi_idx_c downto id_lo_idx_c ) = rx_conf_header_id_c
327
              and hibi_re = '1'
328
            then
329
              -- rx conf packet received
330
              conf_type_r <= rx;
331
              conf_state_r <= ip;
332
 
333
 
334
            -------------------------------------------------------------------  
335
            -- if there is a valid tx start word to the correct address
336
            elsif lock_in = '1' and lock_addr_in = current_hibi_addr_r and
337
              hibi_data_in( id_hi_idx_c downto id_lo_idx_c ) = tx_data_header_id_c
338
              and hibi_re = '1'
339
            then
340
 
341
              -- get the length in 16-bit words (first divide with 2, then add
342
              -- last bit of the original value)
343
              data_cnt_r <= to_integer( unsigned( hibi_data_in( id_lo_idx_c-1 downto id_lo_idx_c-tx_len_w_c + 1 ) ))
344
                            + to_integer( unsigned( hibi_data_in( id_lo_idx_c-tx_len_w_c downto id_lo_idx_c-tx_len_w_c ) ));
345
 
346
              -- length in bytes to the tx_ctrl
347
              tx_length_out <= hibi_data_in( id_lo_idx_c-1 downto id_lo_idx_c-tx_len_w_c );
348
              -- notify the tx_ctrl
349
              new_tx_r <= '1';
350
              tx_ongoing_r <= '1';
351
 
352
              -- already lift the we to tx fifo, so that the data gets written in
353
              -- time
354
              tx_we_r <= '1';
355
 
356
              -- don't read yet, cause it takes two cycles to store word in halfwords
357
              hibi_re_v := '0';
358
 
359
 
360
            -------------------------------------------------------------------
361
            -- if there is a release word
362
            elsif lock_in = '1' and lock_addr_in = current_hibi_addr_r and
363
              hibi_data_in( id_hi_idx_c downto id_lo_idx_c ) = tx_release_header_id_c
364
              and hibi_re = '1'
365
            then
366
              release_lock_out <= '1';
367
 
368
 
369
            -------------------------------------------------------------------
370
            elsif hibi_re = '1' then
371
              -- what the heck, invalid header, dump the data (that is, do nothing)
372
              report "Invalid header" severity warning;
373
              -- all data gets dumped untill next av = '1'
374
              dump_data_r <= '1';
375
            end if;
376
 
377
          ---------------------------------------------------------------------
378
 
379
          end if;
380
        end if;
381
 
382
        hibi_re_r <= hibi_re_v;
383
 
384
      end if; -- empty from fifo = '0'
385
    end if;
386
  end process main;
387
 
388
end rtl;

powered by: WebSVN 2.1.0

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