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.communication/] [fh_crossbar/] [1.0/] [vhd/] [xbar_pkt.vhd] - Blame information for rev 145

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 145 lanttu
-------------------------------------------------------------------------------
2
-- File        : xbar_pkt.vhd
3
-- Description : Simple crossbar switch. based on mesh_router.
4
--              Actually, this is simple router with arbitrary number of ports.
5
--               Crossbar uses packets.
6
-- Author      : Erno Salminen
7
-- Date        : 28.08.2006
8
-- Modified    : 
9
-- 28.08.2006   ES Derived from mesh_router
10
-------------------------------------------------------------------------------
11
-------------------------------------------------------------------------------
12
-- Copyright (c) 2011 Tampere University of Technology
13
-------------------------------------------------------------------------------
14
--  This file is part of Transaction Generator.
15
--
16
--  Transaction Generator is free software: you can redistribute it and/or
17
--  modify it under the terms of the Lesser GNU General Public License as
18
--  published by the Free Software Foundation, either version 3 of the License,
19
--  or (at your option) any later version.
20
--
21
--  Transaction Generator is distributed in the hope that it will be useful,
22
--  but WITHOUT ANY WARRANTY; without even the implied warranty of
23
--  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
24
--  Lesser GNU General Public License for more details.
25
--
26
--  You should have received a copy of the Lesser GNU General Public License
27
--  along with Transaction Generator.  If not, see
28
--  <http://www.gnu.org/licenses/>.
29
-------------------------------------------------------------------------------
30
 
31
 
32
 
33
library ieee;
34
use ieee.std_logic_1164.all;
35
use ieee.std_logic_arith.all;
36
use ieee.std_logic_unsigned.all;
37
 
38
entity xbar_pkt is
39
  generic (
40
    stfwd_en_g   :    integer := 1;     --24.08.2006 es
41
    n_ag_g       :    integer;
42
    data_width_g :    integer;
43
    pkt_len_g    :    integer;          -- 2006/10/25, depth must be > 2 words
44
    fifo_depth_g :    integer;
45
    ip_freq_g    :    integer := 1;     -- relative IP frequency
46
    net_freq_g   :    integer := 1      --relative router frequency
47
    );
48
  port (
49
    clk_ip       : in std_logic;
50
    clk_net      : in std_logic;
51
    rst_n        : in std_logic;
52
 
53
    tx_data_in    : in  std_logic_vector(n_ag_g * data_width_g - 1 downto 0);
54
    tx_we_in      : in  std_logic_vector(n_ag_g - 1 downto 0);
55
    tx_empty_out  : out std_logic_vector(n_ag_g - 1 downto 0);
56
    tx_full_out   : out std_logic_vector(n_ag_g - 1 downto 0);
57
 
58
    rx_data_out  : out std_logic_vector(n_ag_g * data_width_g - 1 downto 0);
59
    rx_re_in     : in  std_logic_vector(n_ag_g - 1 downto 0);
60
    rx_empty_out : out std_logic_vector(n_ag_g - 1 downto 0);
61
    rx_full_out  : out std_logic_vector(n_ag_g - 1 downto 0)
62
    );
63
end xbar_pkt;
64
 
65
 
66
 
67
architecture rtl of xbar_pkt is
68
 
69
 
70
  constant addr_width_c : integer := data_width_g;
71
 
72
  -- Constants for accessing arrays (e.g. state_regs)
73
  constant N      : integer := 0;
74
  constant W      : integer := 1;
75
  constant S      : integer := 2;
76
  constant E      : integer := 3;
77
  constant Ip     : integer := 4;
78
  constant No_dir : integer := n_ag_g;       -- Illegal index
79
 
80
 
81
 
82
  component fifo
83
    generic (
84
      data_width_g : integer := 0;
85
      depth_g      : integer := 0);
86
    port (
87
      clk       : in  std_logic;
88
      rst_n     : in  std_logic;
89
      data_in   : in  std_logic_vector (data_width_g-1 downto 0);
90
      we_in     : in  std_logic;
91
      one_p_out : out std_logic;
92
      full_out  : out std_logic;
93
      data_out  : out std_logic_vector (data_width_g-1 downto 0);
94
      re_in     : in  std_logic;
95
      empty_out : out std_logic;
96
      one_d_out : out std_logic
97
      );
98
  end component;  --fifo;
99
 
100
  component multiclk_fifo
101
    generic (
102
      re_freq_g    : integer;
103
      we_freq_g    : integer;
104
      depth_g      : integer;
105
      data_width_g : integer);
106
    port (
107
      clk_re    : in  std_logic;
108
      clk_we    : in  std_logic;
109
      rst_n     : in  std_logic;
110
      data_in   : in  std_logic_vector (data_width_g-1 downto 0);
111
      we_in     : in  std_logic;
112
      full_out  : out std_logic;
113
      one_p_out : out std_logic;
114
      re_in     : in  std_logic;
115
      data_out  : out std_logic_vector (data_width_g-1 downto 0);
116
      empty_out : out std_logic;
117
      one_d_out : out std_logic);
118
  end component;
119
 
120
  -- Arrays are easier to handle than names with direction identification
121
  -- (e.g. data_arr(i) vs. data_N)
122
  type data_arr_type is array (n_ag_g-1 downto 0) of std_logic_vector (data_width_g-1 downto 0);
123
  type ctrl_arr_type is array (n_ag_g-1 downto 0) of std_logic;
124
  type source_type is array (n_ag_g-1 downto 0) of integer range 0 to n_ag_g;
125
 
126
 
127
  -- 17.03.2006
128
  type   counter_arr_type is array (n_ag_g-1 downto 0) of integer range 0 to pkt_len_g; --  --fifo_depth_g;
129
  signal send_counter_r : counter_arr_type;
130
 
131
 
132
  -- From fifos. Mapped directly to outputs pins 
133
  signal data_txf_xbar  : data_arr_type;
134
  signal data_txf_dbg   : data_arr_type;
135
  signal full_from_txf  : std_logic_vector (n_ag_g-1 downto 0);
136
  signal empty_from_txf : std_logic_vector (n_ag_g-1 downto 0);
137
  signal re_xbar_txf_r  : ctrl_arr_type;
138
 
139
  -- From ctrl
140
  signal data_xbar_rxf_r : data_arr_type;
141
  signal we_xbar_rxf_r   : ctrl_arr_type;
142
  signal full_from_rxf   : std_logic_vector (n_ag_g-1 downto 0);  --ctrl_arr_type;
143
  signal empty_from_rxf  : std_logic_vector (n_ag_g-1 downto 0);
144
 
145
  -- 24.10.2006. Try wormhole, combinatorial enable signals
146
  signal re_tmp : ctrl_arr_type;
147
  signal we_tmp : ctrl_arr_type;
148
 
149
 
150
  -- State registers
151
  signal State_writing_r : std_logic_vector (n_ag_g-1 downto 0);
152
  signal State_reading_r : std_logic_vector (n_ag_g-1 downto 0);
153
 
154
  -- state_src_r(i) tells which port the source for output port i
155
  signal state_src_r : source_type;
156
 
157
  -- state_dst_r(i) tells which port the destination for input port i
158
  signal state_dst_r : source_type;
159
 
160
  -- Marks which input is checked on current cycle
161
  signal curr_src_r : integer range 0 to n_ag_g-1;
162
 
163
  -- Decoded address in input port pointed by curr_src_r, _not_ a register!
164
  signal curr_dst : integer range 0 to n_ag_g;
165
 
166
 
167
 
168
 
169
begin  -- rtl
170
 
171
 
172
 
173
  map_infifos : for i in 0 to n_ag_g-1 generate
174
    tx_fifo   : multiclk_fifo
175
      generic map (
176
        re_freq_g    => net_freq_g,
177
        we_freq_g    => ip_freq_g,
178
        depth_g      => fifo_depth_g,
179
        data_width_g => data_width_g
180
        )
181
      port map (
182
        clk_re       => clk_net,
183
        clk_we       => clk_ip,
184
        rst_n        => rst_n,
185
 
186
        data_in  => tx_data_in ((i+1)*data_width_g-1 downto i*data_width_g),
187
        full_out => full_from_txf (i),
188
        we_in    => tx_we_in (i),
189
 
190
        -- Fifo outputs go ctrl logic
191
        data_out  => data_txf_xbar (i),
192
        empty_out => empty_from_txf (i),
193
        re_in     => re_tmp (i) --re_xbar_txf_r (i)
194
        );
195
 
196
 
197
    rx_fifo : multiclk_fifo
198
      generic map (
199
        re_freq_g    => ip_freq_g,
200
        we_freq_g    => net_freq_g,
201
        depth_g      => fifo_depth_g,
202
        data_width_g => data_width_g
203
        )
204
      port map (
205
        clk_re       => clk_ip,
206
        clk_we       => clk_net,
207
        rst_n        => rst_n,
208
 
209
        data_in  => data_xbar_rxf_r (i),
210
        full_out => full_from_rxf (i),
211
        we_in    => we_tmp (i), --we_xbar_rxf_r (i),
212
 
213
        -- Fifo outputs go ctrl logic
214
        data_out  => rx_data_out ((i+1)*data_width_g-1 downto i*data_width_g),
215
        empty_out => empty_from_rxf (i),
216
        re_in     => rx_re_in (i)
217
        );
218
 
219
    data_txf_dbg (i) <= data_txf_xbar (i) when empty_from_txf (i)='0' else (others => 'Z');
220
 
221
  end generate map_infifos;
222
  tx_empty_out <= empty_from_txf;
223
  tx_full_out  <= full_from_txf;
224
 
225
  rx_full_out  <= full_from_rxf;
226
  rx_empty_out <= empty_from_rxf;
227
 
228
 
229
  -- 13.09.2006
230
  read_en_tmp: process (--we_xbar_rxf_r,
231
                        re_xbar_txf_r,
232
                        empty_from_txf, --state_src_r,
233
                        state_dst_r, full_from_rxf)
234
 
235
  begin  -- process read_en_tmp
236
    for i in 0 to n_ag_g-1 loop
237
 
238
      -- i viittaa kohteeseen (fifo)
239
--      we_tmp (i) <= we_xbar_rxf_r (i)
240
--                    and (not (full_from_rxf (i)));
241
 
242
 
243
      -- i viittaa llähteeseen (=input_port)
244
      if state_dst_r (i) = No_dir then
245
        -- sisääntulossa i ei ole järkevää dataa
246
        re_tmp (i) <= '0';
247
      else
248
        -- ei lueta sisääntulosta i ellei
249
        --  a) tilakone ole lukemass sieltä (re_xbar_txf_r pitää olla 1)
250
        --  b) sisääntulossa ole validia dataa  (empty pitää olla 0)
251
        --  c) kohde ei ole varattu
252
        re_tmp (i) <= re_xbar_txf_r (i)
253
                      and (not empty_from_txf (i))
254
                      and (not full_from_rxf (state_dst_r (i)));
255
      end if;
256
 
257
    end loop;  -- i
258
  end process read_en_tmp;
259
 
260
 
261
 
262
  -- PROC
263
  -- Check where the incoming packet is heading
264
  -- Input ports are handled one per clock cycle
265
 
266
  Check_dst : process (State_reading_r,
267
                       curr_src_r,
268
                       data_txf_xbar,
269
                       empty_from_txf,
270
                       full_from_txf)
271
  begin  -- process Check_dst
272
 
273
    -- new way
274
    if State_reading_r (curr_src_r) = '0'
275
      and ( (full_from_txf  ( curr_src_r) = '1' and stfwd_en_g=1)
276
           or
277
            (empty_from_txf (curr_src_r) = '0'and stfwd_en_g=0))
278
    then                                -- 1)
279
      curr_dst <= conv_integer (data_txf_xbar (curr_src_r)(addr_width_c-1 downto 0));
280
 
281
     else                               --1)
282
       -- No packet on curr src port or read operation already started
283
      curr_dst <= No_dir;
284
    end if;
285
 
286
 
287
 
288
  end process Check_dst;
289
 
290
 
291
 
292
  Main_control : process (clk_net, rst_n)
293
  begin  -- process Main_control
294
    if rst_n = '0' then                 -- asynchronous reset (active low)
295
      for i in 0 to n_ag_g-1 loop
296
        data_xbar_rxf_r (i) <= (others => '0');  --'0');
297
        send_counter_r (i)  <= 0;
298
      end loop;  -- i
299
 
300
      we_xbar_rxf_r   <= (others => '0');
301
      re_xbar_txf_r   <= (others => '0');
302
      -- Write/Read_Enable signal seem to be identical
303
      -- to State_Writing/Reading ? 25.07.2003 
304
      State_writing_r <= (others => '0');
305
      State_reading_r <= (others => '0');
306
      state_src_r     <= (others => No_dir);
307
      state_dst_r     <= (others => No_dir);
308
      curr_src_r      <= N;
309
 
310
 
311
      we_tmp <= (others => '0');
312
 
313
    elsif clk_net'event and clk_net = '1' then  -- rising clock edge
314
 
315
 
316
      for i in 0 to n_ag_g-1 loop
317
 
318
        -- 2006/10/24
319
        -- i =target
320
        if state_src_r(i) = No_dir then
321
          we_tmp (i)  <= '0';
322
        else
323
          we_tmp(i) <= re_tmp (state_src_r (i));
324
 
325
        end if;
326
 
327
 
328
        -- Handle all directions
329
        -- Loop variable i refers to source port
330
 
331
 
332
        if State_reading_r (i) = '1' then
333
          -- Already reading from direction i 
334
 
335
          -- 17.03.2006 use counters to enable cut-through switching.
336
          -- The same thing works also with store-and-forward switching
337
          if send_counter_r (i) = pkt_len_g --fifo_depth_g
338
          then
339
            -- stop
340
            we_xbar_rxf_r (state_dst_r (i))   <= '0';
341
            re_xbar_txf_r (i)                 <= '0';
342
            data_xbar_rxf_r (state_dst_r (i)) <= (others => '0');  --Z');
343
            State_writing_r (state_dst_r (i)) <= '0';
344
            State_reading_r (i)               <= '0';
345
            state_src_r (state_dst_r (i))     <= No_dir;
346
            state_dst_r (i)                   <= No_dir;
347
            --assert false report "tx to north fifo completed" severity note;
348
 
349
            send_counter_r (i) <= 0;
350
 
351
 
352
          else
353
            -- Packet transfer not yet complete
354
            -- Continue transfer
355
            we_xbar_rxf_r (state_dst_r (i))   <= '1';
356
            State_writing_r (state_dst_r (i)) <= State_writing_r (state_dst_r (i));
357
            State_reading_r (i)               <= State_reading_r (i);
358
            state_src_r (state_dst_r (i))     <= state_src_r (state_dst_r (i));
359
            state_dst_r (i)                   <= state_dst_r (i);
360
            --assert false report "tx to north fifo in progress" severity note;
361
 
362
            --data_xbar_rxf_r (state_dst_r (i)) <= data_txf_xbar (i);
363
            --send_counter_r (i) <= send_counter_r (i) +1;
364
            -- 24.10.2006 ES
365
            if re_tmp (i) = '1' then
366
              send_counter_r (i)                <= send_counter_r (i) +1;
367
              data_xbar_rxf_r (state_dst_r (i)) <= data_txf_xbar (i);
368
            end if;
369
 
370
 
371
            -- if send_counter_r (i) = fifo_depth_g-1
372
            --  and full_from_rxf (state_dst_r(i)) = '0'
373
            if send_counter_r (i) = pkt_len_g-1 --fifo_depth_g-1
374
              and empty_from_txf (i) = '0'  -- 2006/10/24
375
              and full_from_rxf (state_dst_r(i)) = '0'
376
            then
377
              re_xbar_txf_r (i) <= '0';
378
            else
379
              re_xbar_txf_r (i) <= '1';
380
            end if;
381
 
382
 
383
          end if;
384
 
385
        else
386
          -- Not yet reading from direction i 
387
          -- Check one direction (curr_src_r) per clock cycle
388
          -- for possible new transfers
389
 
390
          -- Direction i has to be current source,
391
          -- there must be valid address on port i
392
          -- and target fifo has to be empty (i.e. it is not full or reserved)
393
          if curr_src_r = i
394
            and curr_dst /= No_dir
395
            and empty_from_rxf (curr_dst) = '1'
396
            and State_writing_r (curr_dst) = '0'
397
          then
398
            -- Start reading
399
 
400
            data_xbar_rxf_r (curr_dst)   <= data_txf_xbar (curr_src_r);
401
            we_xbar_rxf_r (curr_dst)     <= '0';
402
            -- WE not yet '1' because RE is just being asserted to one
403
            -- Otherwise, the first data (i.e.) would be written twice and the
404
            -- last data would be discarded
405
            State_writing_r (curr_dst)   <= '1';
406
            re_xbar_txf_r (curr_src_r)   <= '1';
407
            State_reading_r (curr_src_r) <= '1';
408
            state_src_r (curr_dst)       <= curr_src_r;
409
            state_dst_r (curr_src_r)     <= curr_dst;
410
 
411
            send_counter_r (i) <= send_counter_r (i);  --??
412
 
413
          else
414
            -- Can't start reading from current source
415
            -- Do nothing
416
          end if;  --State_reading_r = i
417
        end if;  --State_reading_r(i)=1
418
 
419
      end loop;  -- i
420
 
421
 
422
 
423
 
424
 
425
 
426
      if curr_src_r = n_ag_g-1 then
427
        curr_src_r <= 0;
428
      else
429
        curr_src_r <= curr_src_r+1;
430
      end if;
431
--      -- Change currect source for the next cycle
432
--      case curr_src_r is        
433
--         when N  => curr_src_r <= W;
434
--         when W  => curr_src_r <= S;
435
--         when S  => curr_src_r <= E;
436
--         when E  => curr_src_r <= Ip;
437
--         when Ip => curr_src_r <= N;
438
--         when others => curr_src_r <= N;
439
--      end case;
440
 
441
 
442
 
443
    end if;  --rst_n/clk'event
444
  end process Main_control;
445
 
446
 
447
 
448
 
449
 
450
 
451
 
452
end rtl;

powered by: WebSVN 2.1.0

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