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.storage/] [sdram2hibi/] [1.0/] [vhd/] [sdram_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
-- 2012-01-22     alhonen fixed names
21
-----------------------------------------------------------------
22
 
23
library ieee;
24
use ieee.std_logic_1164.all;
25
use ieee.numeric_std.all;
26
 
27
entity sdram_arbiter is
28
  generic (
29
    arb_width_g : integer;
30
    arb_type_g  : integer := 0
31
    );
32
  port(
33
    clk       : in  std_logic;
34
    rst_n     : in  std_logic;
35
    req_in    : in  std_logic_vector(arb_width_g - 1 downto 0);
36
    hold_in   : in  std_logic_vector(arb_width_g - 1 downto 0);
37
    grant_out : out std_logic_vector(arb_width_g - 1 downto 0)
38
    );
39
end sdram_arbiter;
40
 
41
architecture rtl of sdram_arbiter is
42
 
43
  signal priority_r   : std_logic_vector (arb_width_g - 1 downto 0);
44
  signal carry_1      : std_logic_vector (arb_width_g - 1 downto 0);
45
  signal carry_2      : std_logic_vector (arb_width_g - 1 downto 0);
46
  signal gc           : std_logic_vector (arb_width_g - 1 downto 0);
47
  signal grant_i      : std_logic_vector (arb_width_g - 1 downto 0);
48
  signal last_grant_r : std_logic_vector (arb_width_g - 1 downto 0);
49
 
50
begin  -- rtl
51
 
52
  grant_out <= grant_i;
53
 
54
  -- Generate intermediate grant with aid of carry signals
55
  -- Carry means that no higher prior has asserted any requests
56
  -- Carry logic is dupliacted to avoid combinatorial loop,
57
  -- only difference is in the bit carry_x(0)
58
  arbiter : process (rst_n, priority_r, req_in, carry_1, carry_2)
59
  begin  -- process arbiter
60
 
61
    if rst_n = '0' then
62
      carry_1 <= (others => '0');
63
      carry_2 <= (others => '0');
64
      gc      <= (others => '0');
65
 
66
    else
67
 
68
      -- generate carry signal
69
      carry_1(0) <= '0';
70
      for i in 1 to arb_width_g - 1 loop
71
        carry_1(i) <= ( (priority_r(i-1) or carry_1(i-1)) and not(req_in(i-1)));
72
      end loop;  -- i
73
 
74
      carry_2(0) <= ((priority_r(arb_width_g - 1) or carry_1(arb_width_g - 1))
75
                   and not(req_in(arb_width_g - 1)));
76
 
77
      for i in 1 to arb_width_g - 1 loop
78
        carry_2(i) <= ( (priority_r(i-1) or carry_2(i-1)) and not(req_in(i-1)));
79
      end loop;  -- i
80
 
81
      -- generate intermediate grant signal
82
      for i in 0 to arb_width_g - 1 loop
83
        gc(i) <= ((priority_r(i) or carry_1(i)) and req_in(i)) or
84
                 ((priority_r(i) or carry_2(i)) and req_in(i));
85
      end loop;  -- i
86
 
87
    end if;
88
  end process arbiter;
89
 
90
  -- grant-hold circuit
91
  -- a) Previous grant remains if hold is active
92
  -- b) new grant is given if no holds are asserted
93
  grant_hold_async : process(gc, last_grant_r, hold_in)
94
    variable anyhold_v : std_logic;
95
  begin  -- process grant_hold_async
96
 
97
    anyhold_v := '0';
98
    for i in 0 to arb_width_g - 1 loop
99
      anyhold_v := anyhold_v or (hold_in(i) and last_grant_r(i));
100
    end loop;  -- i
101
 
102
    for i in 0 to arb_width_g - 1 loop
103
      grant_i(i) <= (last_grant_r(i) and hold_in(i))
104
                    or (gc(i) and not(anyhold_v));
105
    end loop;  -- i
106
  end process grant_hold_async;
107
 
108
 
109
  -- grant-hold: register previous grant signal (one-hot)
110
  grant_hold_sync : process (clk, rst_n)
111
  begin  -- process grant_hold_sync
112
    if rst_n = '0' then                 -- asynchronous reset (active low)
113
      last_grant_r <= (others => '0');
114
    elsif clk'event and clk = '1' then  -- rising clock edge
115
      last_grant_r <= grant_i;
116
    end if;
117
  end process grant_hold_sync;
118
 
119
 
120
  -- purpose: update priority register(round-robin)
121
  -- Input that got grant is put to the lowest priority
122
  -- One-hot encoded: one bit shows the highest priority,
123
  -- if prior(i)=1, i has highest prior, i+1 has 2nd highest and so on
124
  pri_round_robin : process (clk, rst_n)
125
    variable anyg_v : std_logic;
126
  begin  -- process pri_round_robin
127
    if rst_n = '0' then                 -- asynchronous reset (active low)
128
      priority_r <= std_logic_vector (to_unsigned(1, arb_width_g));
129
 
130
    elsif clk'event and clk = '1' then  -- rising clock edge
131
 
132
      case arb_type_g is
133
 
134
 
135
        when 0 =>
136
          -- round-robin
137
          anyg_v := '0';
138
          for i in 0 to arb_width_g - 1 loop
139
            anyg_v := anyg_v or grant_i(i);
140
          end loop;  -- i
141
 
142
          priority_r(0) <= ( priority_r(0) and not(anyg_v) ) or grant_i(arb_width_g - 1);
143
 
144
          for i in 1 to arb_width_g - 1 loop
145
            priority_r(i) <= (priority_r(i) and not(anyg_v)) or grant_i(i-1);
146
          end loop;  -- i
147
 
148
        when 1 =>
149
          -- fixed_priority
150
          priority_r <= priority_r;
151
 
152
        when 2 =>
153
 
154
          -- variable priority
155
          if grant_i /= std_logic_vector(to_unsigned(0, grant_i'length)) then
156
            priority_r <= priority_r(priority_r'length - 2 downto 0) & priority_r(priority_r'length - 1);
157
          else
158
            priority_r <= priority_r;
159
          end if;
160
        when others => null;
161
      end case;
162
    end if;
163
 
164
  end process pri_round_robin;
165
 
166
end rtl;

powered by: WebSVN 2.1.0

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