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

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 145 lanttu
-----------------------------------------------------------------
2
-- File         : arbiter.vhd
3
-- Description  : Sub-block for allocator
4
-- Designer     : Hannu Penttinen 29.08.2006
5
--
6
-- Note: If there's problems with synthesis concerning the carry
7
--       chain. Try dublicating the first arbiter and
8
--       connecting '0' to the carry in of the first arbiter and
9
--       ORing the grants of the first and second arbiter.
10
--       Done with carry1 and carry2
11
--
12
--      Req and hold must be asserted simultanesouly. When granted, req can be
13
--      de-asserted
14
--
15
--      The structure shown in Dally,Towles, fig 18.5, 18.6 and 18.7
16
--      
17
-- Note:          arb_type_g  0 - round-robin
18
--                            1 - fixed priority
19
--                            2 - variable priority
20
-----------------------------------------------------------------
21
-------------------------------------------------------------------------------
22
-- Copyright (c) 2011 Tampere University of Technology
23
-------------------------------------------------------------------------------
24
--  This file is part of Transaction Generator.
25
--
26
--  Transaction Generator is free software: you can redistribute it and/or
27
--  modify it under the terms of the Lesser GNU General Public License as
28
--  published by the Free Software Foundation, either version 3 of the License,
29
--  or (at your option) any later version.
30
--
31
--  Transaction Generator is distributed in the hope that it will be useful,
32
--  but WITHOUT ANY WARRANTY; without even the implied warranty of
33
--  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
34
--  Lesser GNU General Public License for more details.
35
--
36
--  You should have received a copy of the Lesser GNU General Public License
37
--  along with Transaction Generator.  If not, see
38
--  <http://www.gnu.org/licenses/>.
39
-------------------------------------------------------------------------------
40
 
41
library ieee;
42
use ieee.std_logic_1164.all;
43
use ieee.numeric_std.all;
44
 
45
entity arbiter is
46
  generic (
47
    arb_width_g : integer;
48
    arb_type_g  : integer := 0
49
    );
50
  port(
51
    clk       : in  std_logic;
52
    rst_n     : in  std_logic;
53
    req_in    : in  std_logic_vector(arb_width_g - 1 downto 0);
54
    hold_in   : in  std_logic_vector(arb_width_g - 1 downto 0);
55
    grant_out : out std_logic_vector(arb_width_g - 1 downto 0)
56
    );
57
end arbiter;
58
 
59
architecture rtl of arbiter is
60
 
61
  signal priority_r   : std_logic_vector (arb_width_g - 1 downto 0);
62
  signal carry_1      : std_logic_vector (arb_width_g - 1 downto 0);
63
  signal carry_2      : std_logic_vector (arb_width_g - 1 downto 0);
64
  signal gc           : std_logic_vector (arb_width_g - 1 downto 0);
65
  signal grant_i      : std_logic_vector (arb_width_g - 1 downto 0);
66
  signal last_grant_r : std_logic_vector (arb_width_g - 1 downto 0);
67
 
68
begin  -- rtl
69
 
70
  grant_out <= grant_i;
71
 
72
  -- Generate intermediate grant with aid of carry signals
73
  -- Carry means that no higher prior has asserted any requests
74
  -- Carry logic is dupliacted to avoid combinatorial loop,
75
  -- only difference is in the bit carry_x(0)
76
  arbiter : process (rst_n, priority_r, req_in, carry_1, carry_2)
77
  begin  -- process arbiter
78
 
79
    if rst_n = '0' then
80
      carry_1 <= (others => '0');
81
      carry_2 <= (others => '0');
82
      gc      <= (others => '0');
83
 
84
    else
85
 
86
      -- generate carry signal
87
      carry_1(0) <= '0';
88
      for i in 1 to arb_width_g - 1 loop
89
        carry_1(i) <= ( (priority_r(i-1) or carry_1(i-1)) and not(req_in(i-1)));
90
      end loop;  -- i
91
 
92
      carry_2(0) <= ((priority_r(arb_width_g - 1) or carry_1(arb_width_g - 1))
93
                   and not(req_in(arb_width_g - 1)));
94
 
95
      for i in 1 to arb_width_g - 1 loop
96
        carry_2(i) <= ( (priority_r(i-1) or carry_2(i-1)) and not(req_in(i-1)));
97
      end loop;  -- i
98
 
99
      -- generate intermediate grant signal
100
      for i in 0 to arb_width_g - 1 loop
101
        gc(i) <= ((priority_r(i) or carry_1(i)) and req_in(i)) or
102
                 ((priority_r(i) or carry_2(i)) and req_in(i));
103
      end loop;  -- i
104
 
105
    end if;
106
  end process arbiter;
107
 
108
  -- grant-hold circuit
109
  -- a) Previous grant remains if hold is active
110
  -- b) new grant is given if no holds are asserted
111
  grant_hold_async : process(gc, last_grant_r, hold_in)
112
    variable anyhold_v : std_logic;
113
  begin  -- process grant_hold_async
114
 
115
    anyhold_v := '0';
116
    for i in 0 to arb_width_g - 1 loop
117
      anyhold_v := anyhold_v or (hold_in(i) and last_grant_r(i));
118
    end loop;  -- i
119
 
120
    for i in 0 to arb_width_g - 1 loop
121
      grant_i(i) <= (last_grant_r(i) and hold_in(i))
122
                    or (gc(i) and not(anyhold_v));
123
    end loop;  -- i
124
  end process grant_hold_async;
125
 
126
 
127
  -- grant-hold: register previous grant signal (one-hot)
128
  grant_hold_sync : process (clk, rst_n)
129
  begin  -- process grant_hold_sync
130
    if rst_n = '0' then                 -- asynchronous reset (active low)
131
      last_grant_r <= (others => '0');
132
    elsif clk'event and clk = '1' then  -- rising clock edge
133
      last_grant_r <= grant_i;
134
    end if;
135
  end process grant_hold_sync;
136
 
137
 
138
  -- purpose: update priority register(round-robin)
139
  -- Input that got grant is put to the lowest priority
140
  -- One-hot encoded: one bit shows the highest priority,
141
  -- if prior(i)=1, i has highest prior, i+1 has 2nd highest and so on
142
  pri_round_robin : process (clk, rst_n)
143
    variable anyg_v : std_logic;
144
  begin  -- process pri_round_robin
145
    if rst_n = '0' then                 -- asynchronous reset (active low)
146
      priority_r <= std_logic_vector (to_unsigned(1, arb_width_g));
147
 
148
    elsif clk'event and clk = '1' then  -- rising clock edge
149
 
150
      case arb_type_g is
151
 
152
 
153
        when 0 =>
154
          -- round-robin
155
          anyg_v := '0';
156
          for i in 0 to arb_width_g - 1 loop
157
            anyg_v := anyg_v or grant_i(i);
158
          end loop;  -- i
159
 
160
          priority_r(0) <= ( priority_r(0) and not(anyg_v) ) or grant_i(arb_width_g - 1);
161
 
162
          for i in 1 to arb_width_g - 1 loop
163
            priority_r(i) <= (priority_r(i) and not(anyg_v)) or grant_i(i-1);
164
          end loop;  -- i
165
 
166
        when 1 =>
167
          -- fixed_priority
168
          priority_r <= priority_r;
169
 
170
        when 2 =>
171
 
172
          -- variable priority
173
          if grant_i /= std_logic_vector(to_unsigned(0, grant_i'length)) then
174
            priority_r <= priority_r(priority_r'length - 2 downto 0) & priority_r(priority_r'length - 1);
175
          else
176
            priority_r <= priority_r;
177
          end if;
178
        when others => null;
179
      end case;
180
    end if;
181
 
182
  end process pri_round_robin;
183
 
184
end rtl;

powered by: WebSVN 2.1.0

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