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/] [io_block.vhd] - Blame information for rev 145

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 145 lanttu
-----------------------------------------------------------------
2
-- file         : io_block.vhd
3
-- Description  : Includes in and out fifos and controller
4
--             
5
-- Designer     : Vesa Lahtinen 6.11.2003
6
--
7
-- Last modified 30.8.2006 added hold signal from io_ctrl
8
--
9
-------------------------------------------------------------------------------
10
-------------------------------------------------------------------------------
11
-- Copyright (c) 2011 Tampere University of Technology
12
-------------------------------------------------------------------------------
13
--  This file is part of Transaction Generator.
14
--
15
--  Transaction Generator is free software: you can redistribute it and/or
16
--  modify it under the terms of the Lesser GNU General Public License as
17
--  published by the Free Software Foundation, either version 3 of the License,
18
--  or (at your option) any later version.
19
--
20
--  Transaction Generator is distributed in the hope that it will be useful,
21
--  but WITHOUT ANY WARRANTY; without even the implied warranty of
22
--  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
23
--  Lesser GNU General Public License for more details.
24
--
25
--  You should have received a copy of the Lesser GNU General Public License
26
--  along with Transaction Generator.  If not, see
27
--  <http://www.gnu.org/licenses/>.
28
-------------------------------------------------------------------------------
29
 
30
 
31
library ieee;
32
use ieee.std_logic_1164.all;
33
use ieee.std_logic_arith.all;
34
 
35
entity io_block is
36
  generic (
37
    data_width_g    :    integer;
38
    fifo_depth_g    :    integer;
39
    addr_width_g    :    integer;
40
    pkt_switch_en_g :    integer := 0;  --14.10.06 es
41
    stfwd_en_g      :    integer := 0;  --14.10.06 es
42
    max_send_g      :    integer := 9;  -- 0=no limit
43
    net_freq_g      :    integer := 1;
44
    sim_dbg_en_g    :    integer := 0;
45
    ip_freq_g       :    integer := 1
46
    );
47
  port (
48
    clk_net         : in std_logic;
49
    clk_ip          : in std_logic;
50
    rst_n           : in std_logic;
51
 
52
    -- Signals from agent
53
    ip_av_in        : in  std_logic;
54
    ip_data_in      : in  std_logic_vector (data_width_g-1 downto 0);
55
    ip_we_in        : in  std_logic;
56
    ip_tx_full_out  : out std_logic;
57
    ip_tx_empty_out : out std_logic;
58
 
59
    -- Signals to bus and arbiter
60
    -- Flit-out contains either addr or data
61
    net_av_out   : out std_logic;
62
    net_flit_out : out std_logic_vector (data_width_g-1 downto 0);
63
    net_we_out   : out std_logic;
64
 
65
    net_req_addr_out : out std_logic_vector (addr_width_g - 1 downto 0);
66
    net_req_out      : out std_logic;
67
    net_hold_out     : out std_logic;
68
    net_grant_in     : in  std_logic;
69
    net_full_in      : in  std_logic;
70
 
71
    -- Signals from bus and arbiter
72
    net_av_in     : in  std_logic;
73
    net_data_in   : in  std_logic_vector (data_width_g-1 downto 0);
74
    net_we_in     : in  std_logic;
75
    net_full_out  : out std_logic;
76
    net_empty_out : out std_logic;
77
 
78
    -- Signals to agent
79
    ip_av_out       : out std_logic;
80
    ip_data_out     : out std_logic_vector (data_width_g-1 downto 0);
81
    ip_re_in        : in  std_logic;
82
    ip_rx_full_out  : out std_logic;
83
    ip_rx_empty_out : out std_logic
84
    );
85
end io_block;
86
 
87
architecture structural of io_block is
88
 
89
  component multiclk_fifo
90
    generic (
91
      re_freq_g    : integer;
92
      we_freq_g    : integer;
93
      depth_g      : integer;
94
      data_width_g : integer);
95
    port (
96
      clk_re    : in  std_logic;
97
      clk_we    : in  std_logic;
98
      rst_n     : in  std_logic;
99
      data_in   : in  std_logic_vector (data_width_g-1 downto 0);
100
      we_in     : in  std_logic;
101
      full_out  : out std_logic;
102
      one_p_out : out std_logic;
103
      re_in     : in  std_logic;
104
      data_out  : out std_logic_vector (data_width_g-1 downto 0);
105
      empty_out : out std_logic;
106
      one_d_out : out std_logic);
107
  end component;
108
 
109
  constant rst_val_arr_c : std_logic_vector(1 downto 0) := "Z0";
110
 
111
  constant vittu_saatana : std_logic_vector ( data_width_g-1 downto 0) := (others => '0');
112
 
113
  -- Internal signals
114
  signal tx_flit : std_logic_vector (data_width_g-1 downto 0);
115
  signal tx_we   : std_logic;
116
 
117
  signal re_to_txf      : std_logic;
118
  signal empty_from_txf : std_logic;
119
  signal full_from_txf  : std_logic;
120
 
121
 
122
  signal empty_from_rxf         : std_logic;
123
  signal full_from_rxf          : std_logic;
124
  signal one_place_left_rx_fifo : std_logic;
125
 
126
  -- From io_ctrl
127
  signal   we_r           : std_logic;
128
  --signal   we_ioctrl_xbar : std_logic;
129
  signal   addr_r         : std_logic_vector(addr_width_g-1 downto 0);
130
 
131
 
132
  signal a_d_net_rxf : std_logic_vector ( data_width_g+1 -1 downto 0);
133
  signal a_d_rxf_ip  : std_logic_vector ( data_width_g+1 -1 downto 0);
134
 
135
 
136
 
137
 
138
  signal a_d_ip_txf   : std_logic_vector (data_width_g+1 -1 downto 0);
139
  signal a_d_txf_net  : std_logic_vector (data_width_g+1 -1 downto 0);
140
  signal av_from_txf  : std_logic;
141
  signal av_ctrl_xbar : std_logic;
142
 
143
 
144
  type state_type is (wait_grant, tx_addr, tx_data);
145
  signal curr_state_r : state_type;
146
  --signal curr_state_r : integer range 0 to 10;
147
 
148
  constant max_value_for_counter_c : integer :=1024-1;
149
  signal send_counter_r : integer range 0 to max_value_for_counter_c;
150
 
151
begin
152
 
153
  assert max_send_g < max_value_for_counter_c report "Send_counter is too small for given max_send limit" severity ERROR;
154
 
155
  -- From io_ctrl
156
 
157
 
158
  out_flit : process (tx_flit, net_grant_in, tx_we)
159
  begin  -- process out_flit
160
 
161
    if tx_we = '1' then
162
      if net_grant_in = '1' then
163
        net_flit_out <= tx_flit;
164
        net_we_out   <= '1';
165
      else
166
        net_flit_out <= (others => rst_val_arr_c(sim_dbg_en_g));
167
        net_we_out   <= '0';
168
      end if;
169
 
170
    else
171
      -- tx-fifo is empty
172
      net_we_out   <= '0';
173
 
174
      --net_flit_out <= (others => '0');      
175
      if net_grant_in = '1' then net_flit_out <= (others => rst_val_arr_c(sim_dbg_en_g));
176
      else net_flit_out                       <= (others => rst_val_arr_c(sim_dbg_en_g));
177
      end if;
178
    end if;
179
 
180
  end process out_flit;
181
 
182
 
183
  av_from_txf     <= a_d_txf_net (data_width_g);
184
  a_d_ip_txf      <= ip_av_in & ip_data_in;
185
  ip_tx_empty_out <= empty_from_txf;
186
  ip_tx_full_out  <= full_from_txf;
187
  net_av_out      <= av_ctrl_xbar;
188
 
189
  ip_av_out       <= a_d_rxf_ip (data_width_g);
190
  ip_data_out     <= a_d_rxf_ip (data_width_g-1 downto 0);
191
  ip_rx_empty_out <= empty_from_rxf;
192
  ip_rx_full_out  <= full_from_rxf;
193
 
194
  a_d_net_rxf   <= net_av_in & net_data_in;
195
  net_full_out  <= full_from_rxf;       -- 13.09.2006 ES removed 0ne_p!!
196
  net_empty_Out <= empty_from_rxf;
197
 
198
 
199
  tx_fifo : multiclk_fifo
200
    generic map (
201
      re_freq_g    => net_freq_g,
202
      we_freq_g    => ip_freq_g,
203
      data_width_g => data_width_g +1,
204
      depth_g      => fifo_depth_g
205
      -- depth=1 does not work 15.09.2006
206
      )
207
    port map (
208
      clk_re    => clk_net,
209
      clk_we    => clk_ip,
210
      rst_n     => rst_n,
211
 
212
      data_in   => a_d_ip_txf, --ip_data_in,
213
      we_in     => ip_we_in,
214
      full_out  => full_from_txf,
215
 
216
      data_Out  => a_d_txf_net,
217
      empty_out => empty_from_txf,
218
      re_in     => re_to_txf
219
      );
220
 
221
 
222
 
223
  rx_fifo : multiclk_fifo
224
    generic map (
225
      re_freq_g    => ip_freq_g,
226
      we_freq_g    => net_freq_g,
227
      data_width_g => data_width_g +1,
228
      depth_g      => fifo_depth_g
229
      -- All depths (dep=1 or greater) should work 15.09.2006
230
      )
231
    port map (
232
      clk_re       => clk_ip,
233
      clk_we       => clk_net,
234
      rst_n        => rst_n,
235
 
236
      data_in      => a_d_net_rxf,      --net_data_in(data_width_g-1 downto 0),
237
      we_in        => net_we_in,
238
      full_out     => full_from_rxf,
239
      one_p_out    => one_place_left_rx_fifo,
240
 
241
      data_out     => a_d_rxf_ip,       --ip_data_out
242
      empty_out    => empty_from_rxf,
243
      re_in        => ip_re_in
244
      );
245
 
246
 
247
  main_fsm : process (clk_net, rst_n)
248
  begin  -- process main_fsm
249
    if rst_n = '0' then                 -- asynchronous reset (active low)
250
      we_r           <= '0';
251
      curr_state_r   <= wait_grant;     --0;
252
      send_counter_r <= 0;
253
 
254
      addr_r <= (others => rst_val_arr_c(sim_dbg_en_g));
255
 
256
    elsif clk_net'event and clk_net = '1' then  -- rising clock edge
257
 
258
      case curr_state_r is
259
        when wait_grant =>              --0 => 
260
          -- Nothing to do
261
          we_r           <= '0';
262
          send_counter_r <= 0;
263
 
264
          -- Req is asserted in another process,
265
          -- wait for grant here
266
          if net_grant_in = '1' then
267
            curr_state_r <= tx_addr; --3;
268
            we_r         <= '1';
269
 
270
          end if;
271
 
272
        -- -- States 1+2 removed
273
 
274
 
275
        when tx_addr =>                 --3 =>   
276
          -- Transfer address
277
          curr_state_r   <= tx_data;    --4;
278
          send_counter_r <= 1;
279
 
280
        when tx_data =>  --4 =>   
281
          -- Transfer data
282
          we_r <= '1';
283
 
284
          -- No_pkts: Send as long as data available
285
          --    or when send_limit reached
286
          -- Pkt: send pkt_amount (=max_send)
287
          -- Both:stop at new addr
288
 
289
            if (empty_from_txf = '0' and av_from_txf = '1')
290
              or (send_counter_r = max_send_g)  --14.10.06 es
291
              or (empty_from_txf = '1' and pkt_switch_en_g = 0)
292
            then
293
              curr_state_r   <= wait_grant;  --0;
294
              send_counter_r <= 0;
295
            else
296
              curr_state_r   <= tx_data;     --3;
297
 
298
              if tx_we = '1' then
299
                send_counter_r <= send_counter_r +1;
300
              end if;
301
            end if;
302
 
303
        when others =>
304
          null;
305
      end case;
306
 
307
 
308
      -- this code replaces req_addr_storage
309
      if (av_from_txf = '1' and empty_from_txf = '0')
310
       then
311
          addr_r <= a_d_txf_net (data_width_g-1 downto 0); --tx_flit(addr_width_g - 1 downto 0);
312
      else
313
         addr_r  <= addr_r;
314
      end if;
315
 
316
 
317
    end if;
318
  end process main_fsm;
319
 
320
  -- net_req_addr_out <= addr_r;
321
  --net_req_addr_out <= addr_r when av_from_txf = '0' else a_d_txf_net (data_width_g-1 downto 0);
322
  net_req_addr_out <=  a_d_txf_net (data_width_g-1 downto 0)when (av_from_txf = '1' and empty_from_txf='0') else addr_r;
323
 
324
 
325
  set_outputs: process (curr_state_r, av_from_txf,
326
                        --we_ioctrl_xbar,
327
                        tx_we, empty_from_txf,
328
                        we_r,
329
                        full_from_txf,
330
                        send_counter_r,
331
                        a_d_txf_net, addr_r,
332
                        net_grant_in, net_full_in)
333
  begin  -- process set_outputs
334
 
335
    tx_we <= we_r and not(empty_from_txf) and not(net_full_in);
336
    -- These might be overriden in state4
337
 
338
    tx_flit (data_width_g-1 downto 0) <= a_d_txf_net (data_width_g-1 downto 0);
339
    re_to_txf                         <= tx_we and net_grant_in;
340
 
341
 
342
    -- orig.
343
    --we_ioctrl_xbar <= we_r and not(empty_from_txf) and not(net_full_in);
344
    --tx_we          <= we_ioctrl_xbar;
345
    --re_to_txf      <= we_ioctrl_xbar and net_grant_in;
346
 
347
      case curr_state_r is
348
        when wait_grant =>  --0 =>
349
          -- Nothing to do except
350
          -- asserting the request if data in fifo
351
          av_ctrl_xbar <= '0';
352
          --net_hold_out <= not empty_from_txf; --'0';
353
          --net_req_out  <= not empty_from_txf;
354
 
355
          if pkt_switch_en_g = 1 then
356
            if stfwd_en_g = 1 then
357
              -- Store-and-forward
358
              net_req_out  <= full_from_txf;
359
              net_hold_out <= full_from_txf;  --'0';  
360
            else
361
              -- Cut-through
362
              net_req_out  <= not empty_from_txf;
363
              net_hold_out <= not empty_from_txf; --'0';
364
            end if;
365
 
366
          else
367
            -- Packets not used           
368
            net_req_out  <= not empty_from_txf;
369
            net_hold_out <= not empty_from_txf; --'0';
370
          end if;
371
 
372
 
373
 
374
        when tx_addr => -- 3 =>
375
          -- Transfer address
376
          av_ctrl_xbar <= '1';
377
          net_req_out  <= '0';
378
          net_hold_out <= '1';
379
 
380
          if (empty_from_txf = '0' and av_from_txf = '0')
381
          then
382
            -- Take addr from register not from fifo
383
            -- Overrrides for default assigments
384
            tx_we                                        <= '1';
385
 
386
            --tx_flit (data_width_g-1 downto addr_width_g) <= (others => '0');
387
            tx_flit (data_width_g-1 downto  addr_width_g) <= vittu_saatana (data_width_g-1 downto addr_width_g);
388
 
389
            tx_flit (addr_width_g-1 downto 0)            <= addr_r;
390
            re_to_txf                                    <= '0';
391
          end if;
392
 
393
        when tx_data =>  --4 =>
394
          -- Transfer data
395
          av_ctrl_xbar <= '0';
396
          net_req_out  <= '0';
397
 
398
          -- New addr or no more data to send => stop and start again with req
399
          if (empty_from_txf = '0' and av_from_txf = '1')
400
            or (send_counter_r = max_send_g)  --14.10.06 es
401
            or (empty_from_txf = '1' and pkt_switch_en_g = 0)
402
          then
403
            net_hold_out <= '0';
404
 
405
            -- Overrides for default assigments
406
            tx_we                             <= '0';
407
            --tx_flit (data_width_g-1 downto 0) <= (others => '0');  --'Z');
408
            tx_flit (data_width_g-1 downto 0) <= vittu_saatana (data_width_g-1 downto 0);
409
 
410
            re_to_txf                         <= '0';
411
 
412
          else
413
            net_hold_out <= '1';
414
          end if;
415
 
416
        when others =>
417
          null;
418
 
419
      end case;
420
  end process set_outputs;
421
 
422
 
423
 
424
end structural;

powered by: WebSVN 2.1.0

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