OpenCores
URL https://opencores.org/ocsvn/mips_enhanced/mips_enhanced/trunk

Subversion Repositories mips_enhanced

[/] [mips_enhanced/] [trunk/] [grlib-gpl-1.0.19-b3188/] [lib/] [esa/] [pci/] [pci_arb.vhd] - Blame information for rev 2

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 2 dimamali
 
2
 
3
 
4
 
5
----------------------------------------------------------------------------
6
--  This file is a part of the LEON VHDL model
7
--  Copyright (C) 1999  European Space Agency (ESA)
8
--
9
--  This library is free software; you can redistribute it and/or
10
--  modify it under the terms of the GNU Lesser General Public
11
--  License as published by the Free Software Foundation; either
12
--  version 2 of the License, or (at your option) any later version.
13
--
14
--  See the file COPYING.LGPL for the full details of the license.
15
 
16
 
17
--============================================================================--
18
-- Design unit  : pci_arb
19
--
20
-- File name    : pci_arb.vhd
21
--
22
-- Purpose      : Arbiter for the PCI bus
23
--                - configurable size: 4, 8, 16, 32 agents
24
--                - nested round-robbing in two different priority levels
25
--                - priority assignment hard-coded or APB-programmable
26
--
27
-- Reference    : PCI Local Bus Specification, Revision 2.1,
28
--                PCI Special Interest Group, 1st June 1995
29
--                (for information: http:
30
-- Reference    : AMBA(TM) Specification (Rev 2.0), ARM IHI 0011A,
31
--                13th May 1999, issue A, first release, ARM Limited
32
--                The document can be retrieved from http:
33
--
34
-- Note         : Numbering for req_n, gnt_n, or priority levels is in
35
--                increasing order <0 = left> to <NUMBER-1 = right>.
36
--                APB data/address arrays are in the conventional order:
37
--                The least significant bit is located to the
38
--                right, carrying the lower index number (usually 0).
39
--                The arbiter considers strong signal levels ('1' and '0')
40
--                only. Weak levels ('H', 'L') are not considered. The
41
--                appropriate translation function (to_X01) must be applied
42
--                to the inputs. This is usually done by the pads,
43
--                and therefore not contained in this model.
44
--
45
-- Configuration: The arbiter can be configured to NB_AGENTS = 4, 8, 16 or 32.
46
--                A priority level (0 = high, 1 = low) is assigned to each device.
47
--                Exception is agent NB_AGENTS-1, which has always lowest priority.
48
--
49
--                a) The priority levels are hard-coded, when APB_PRIOS = false.
50
--                In this case, the APB ports (pbi/pbo) are unconnected.
51
--                The constant ARB_LVL_C must then be set to appropriate values.
52
--
53
--                b) When APB_PRIOS = true, the levels are programmable via the
54
--                APB-address 0x80 (allows to be ored with the PCI interface):
55
--                Bit 31 (leftmost) = master 31 . . bit 0 (rightmost) = master 0.
56
--                Bit NB_AGENTS-1 is dont care at write and reads 1.
57
--                Bits NB_AGENTS to 31, if existing, are dont care and read 0.
58
--                The constant ARB_LVL_C is then the reset value.
59
--
60
-- Algorithm    : The algorithm is described in the implementation note of
61
--                section 3.4 of the PCI standard:
62
--                The bus is granted by two nested round-robbing loops.
63
--                An agent number and a priority level is assigned to each agent.
64
--                The agent number determines, the pair of req_n/gnt_n lines.
65
--                Agents are counted from 0 to NB_AGENTS-1.
66
--                All agents in one level have equal access to the bus
67
--                (round-robbing); all agents of level 1 as a group have access
68
--                equal to each agent of level 0.
69
--                Re-arbitration occurs, when frame_n is asserted, as soon
70
--                as any other master has requested the bus, but only
71
--                once per transaction.
72
--
73
--                b) With programmable priorities. The priority level of all
74
--                   agents (except NB_AGENTS-1) is  programmable via APB.
75
--                   In a 256 byte APB address range, the priority level of
76
--                   agent N is accessed via the address 0x80 + 4*N. The APB
77
--                   slave returns 0 on all non-implemented addresses, the
78
--                   address bits (1:0) are not decoded. Since only addresses
79
--                   >= 0x80 are occupied, it can be used in parallel (ored
80
--                   read data) with our PCI interface (uses <= 0x78).
81
--                   The constant ARB_LVL_C in pci_arb_pkg is the reset value.
82
--
83
-- Timeout:       The "broken master" timeout is another reason for
84
--                re-arbitration (section 3.4.1 of the standard). Grant is
85
--                removed from an agent, which has not started a cycle
86
--                within 16 cycles after request (and grant). Reporting of
87
--                such a 'broken' master is not implemented.
88
--
89
-- Turnover:      A turnover cycle is required by the standard, when re-
90
--                arbitration occurs during idle state of the bus.
91
--                Notwithstanding to the standard, "idle state" is assumed,
92
--                when frame_n is high for more than 1 cycle.
93
--
94
-- Bus parking  : The bus is parked to agent 0 after reset, it remains granted
95
--                to the last owner, if no other agent requests the bus.
96
--                When another request is asserted, re-arbitration occurs
97
--                after one turnover cycle.
98
--
99
-- Lock         : Lock is defined as a resource lock by the PCI standard.
100
--                The optional bus lock mentioned in the standard is not
101
--                considered here and there are no special conditions to
102
--                handle when lock_n is active.
103
--                in arbitration.
104
--
105
-- Latency      : Latency control in PCI is via the latency counters of each
106
--                agent. The arbiter does not perform any latency check and
107
--                a once granted agent continues its transaction until its
108
--                grant is removed AND its own latency counter has expired.
109
--                Even though, a bus re-arbitration occurs during a
110
--                transaction, the hand-over only becomes effective,
111
--                when the current owner deasserts frame_n.
112
--
113
-- Limitations  : [add here known bugs and limitations]
114
--
115
-- Library      : work
116
--
117
-- Dependencies : LEON config package
118
--                package amba, can be retrieved from:
119
--                http:
120
--
121
-- Author       : Roland Weigand  <Roland.Weigand@gmx.net>
122
--                European Space Agency (ESA)
123
--                Microelectronics Section (TOS-ESM)
124
--                P.O. Box 299
125
--                NL-2200 AG Noordwijk ZH
126
--                The Netherlands
127
--
128
-- Contact      : mailto:microelectronics@estec.esa.int
129
--                http:
130
 
131
-- Copyright (C): European Space Agency (ESA) 2002.
132
--                This source code is free software; you can redistribute it
133
--                and/or modify it under the terms of the GNU Lesser General
134
--                Public License as published by the Free Software Foundation;
135
--                either version 2 of the License, or (at your option) any
136
--                later version. For full details of the license see file
137
--                http:
138
--
139
--                It is recommended that any use of this VHDL source code is
140
--                reported to the European Space Agency. It is also recommended
141
--                that any use of the VHDL source code properly acknowledges the
142
--                European Space Agency as originator.
143
 
144
-- Disclaimer   : All information is provided "as is", there is no warranty that
145
--                the information is correct or suitable for any purpose,
146
--                neither implicit nor explicit. This information does not
147
--                necessarily reflect the policy of the European Space Agency.
148
--
149
-- Simulator    : Modelsim 5.5e on Linux RedHat 7.2
150
--
151
-- Synthesis    : Synopsys Version 1999.10 on Sparc + Solaris 5.5.1
152
--
153
--------------------------------------------------------------------------------
154
-- Version  Author   Date       Changes
155
--
156
-- 0.0      R. W.    2000/11/02 File created
157
-- 0.1      J.Gaisler     2001/04/10   Integrated in LEON
158
-- 0.2      R. Weigand    2001/04/25   Connect arb_lvl reg to AMBA clock/reset
159
-- 0.3      R. Weigand    2002/03/19   Default assignment to owneri in find_next
160
-- 1.0      RW.           2002/04/08   Implementation of TMR registers
161
--                                     Removed recursive function call
162
--                                     Fixed ARB_LEVELS = 2
163
-- 3.0      R. Weigand    2002/04/16   Released for leon2
164
-- 4.0      M. Isomaki    2004/10/19   Minor changes for GRLIB integration
165
-- 4.1      J.Gaisler     2004/11/17   Minor changes for GRLIB integration
166
--$Log$
167
-- Revision 3.1  2002/07/31 13:22:09  weigand
168
-- Bugfix for cases where no valid request in level 0 (level 1 was not rearbitrated)
169
--
170
-- Revision 3.0  2002/07/24 12:19:38  weigand
171
-- Installed RCS with version 3.0
172
--------------------------------------------------------------------------------
173
library ieee;
174
use ieee.std_logic_1164.all;
175
 
176
library grlib;
177
use grlib.stdlib.all;
178
 
179
library esa;
180
use esa.pci_arb_pkg.all;
181
 
182
entity pci_arb is
183
   generic(NB_AGENTS : integer  := 4;
184
           ARB_SIZE  : integer  := 2;
185
           APB_EN    : integer  := 1
186
           );
187
   port (clk     : in  clk_type;                            -- clock
188
         rst_n   : in  std_logic;                           -- async reset active low
189
         req_n   : in  std_logic_vector(0 to NB_AGENTS-1);  -- bus request
190
         frame_n : in  std_logic;
191
         gnt_n   : out std_logic_vector(0 to NB_AGENTS-1);  -- bus grant
192
         pclk    : in  clk_type;                            -- APB clock
193
         prst_n  : in  std_logic;                           -- APB reset
194
         pbi     : in  EAPB_Slv_In_Type;                     -- APB inputs
195
         pbo     : out EAPB_Slv_Out_Type                     -- APB outputs
196
         );
197
 
198
end pci_arb;
199
 
200
 
201
architecture rtl of pci_arb is
202
 
203
   subtype agent_t is std_logic_vector(ARB_SIZE-1 downto 0);
204
   subtype arb_lvl_t is std_logic_vector(NB_AGENTS-1 downto 0);
205
   subtype agentno_t is integer range 0 to NB_AGENTS-1;
206
 
207
   -- Note: the agent with the highest index (3, 7, 15, 31) is always in level 1
208
   -- Example: x010 = prio 0 for agent 2 and 0, prio 1 for agent 3 and 1.
209
   -- Default: start with all devices equal priority at level 1.
210
   constant ARB_LVL_C : arb_lvl_t := (others => '1');
211
 
212
   constant all_ones : std_logic_vector(0 to NB_AGENTS-1) := (others => '1');
213
 
214
   --Necessary definitions from amba.vhd and iface.vhd
215
   --added to pci_arb package with modified names to avoid
216
   --name clashes in GRLIB
217
 
218
   constant APB_PRIOS : boolean := APB_EN = 1;
219
 
220
   signal owner0, owneri0   : agent_t;  -- current owner in level 0
221
   signal owner1, owneri1   : agent_t;  -- current owner in level 1
222
   signal cown, cowni       : agent_t;  -- current level
223
   signal rearb, rearbi     : std_logic;            -- re-arbitration flag
224
   signal tout, touti       : std_logic_vector(3 downto 0);  -- timeout counter
225
   signal turn, turni       : std_logic;            -- turnaround cycle
226
   signal arb_lvl, arb_lvli : arb_lvl_t := ARB_LVL_C;  -- level registers
227
 
228
   type nmstarr is array (0 to 3) of agentno_t;
229
   type nvalarr is array (0 to 3) of boolean;
230
 
231
 
232
begin  -- rtl
233
 
234
   ----------------------------------------------------------------------------
235
   -- PCI ARBITER
236
   ----------------------------------------------------------------------------
237
   -- purpose: Grants the bus depending on the request signals. All agents have
238
   -- equal priority, if another request occurs during a transaction, the bus is
239
   -- granted to the new agent. However, PCI protocol specifies that the master
240
   -- can finish the current transaction within the limit of its latency timer.
241
   arbiter : process(cown, owner0, owner1, req_n, rearb, tout, turn, frame_n,
242
                     arb_lvl, rst_n)
243
 
244
      variable owner0v, owner1v : agentno_t;  -- integer variables for current owner
245
      variable new_request      : agentno_t;  -- detected request
246
      variable nmst             : nmstarr;
247
      variable nvalid           : nvalarr;
248
 
249
   begin  -- process arbiter
250
 
251
      -- default assignments
252
      rearbi  <= rearb;
253
      owneri0 <= owner0;
254
      owneri1 <= owner1;
255
      cowni   <= cown;
256
      touti   <= tout;
257
      turni   <= '0';                    -- no turnaround
258
 
259
      -- re-arbitrate once during the transaction,
260
      -- or when timeout counter expired (bus idle).
261
      if (frame_n = '0' and rearb = '0') or turn = '1' then
262
 
263
         owner0v        := conv_integer(owner0);
264
         owner1v        := conv_integer(owner1);
265
         new_request    := conv_integer(cown);
266
         nvalid(0 to 3) := (others => false);
267
         nmst(0 to 3)   := (others => 0);
268
 
269
         -- Determine next request in both priority levels
270
         rob : for i in NB_AGENTS-1 downto 0 loop
271
            -- consider all masters with valid request
272
            if req_n(i) = '0' then
273
               -- next in prio level 0
274
               if arb_lvl(i) = '0' then
275
                  if i > owner0v then
276
                     nmst(0) := i; nvalid(0) := true;
277
                  elsif i < owner0v then
278
                     nmst(1) := i; nvalid(1) := true;
279
                  end if;
280
               -- next in prio level 1
281
               elsif arb_lvl(i) = '1' then
282
                  if i > owner1v then
283
                     nmst(2) := i; nvalid(2) := true;
284
                  elsif i < owner1v then
285
                     nmst(3) := i; nvalid(3) := true;
286
                  end if;
287
               end if;                  -- arb_lvl
288
            end if;                     -- req_n
289
         end loop rob;
290
 
291
         -- select new master
292
         if nvalid(0) then              -- consider level 0 before wrap
293
            new_request    := nmst(0);
294
            owner0v        := nmst(0);
295
         -- consider level 1 only once, except when no request in level 0
296
         elsif owner0v /= NB_AGENTS-1 or not nvalid(1) then
297
            if nvalid(2) then           -- level 1 before wrap
298
               new_request := nmst(2);
299
               owner0v     := NB_AGENTS-1;
300
               owner1v     := nmst(2);
301
            elsif nvalid(3) then        -- level 1 after wrap
302
               new_request := nmst(3);
303
               owner0v     := NB_AGENTS-1;
304
               owner1v     := nmst(3);
305
            end if;
306
         elsif nvalid(1) then           -- level 0 after wrap
307
            new_request    := nmst(1);
308
            owner0v        := nmst(1);
309
         end if;
310
 
311
         owneri0 <= conv_std_logic_vector(owner0v, ARB_SIZE);
312
         owneri1 <= conv_std_logic_vector(owner1v, ARB_SIZE);
313
 
314
         -- rearbitration if any request asserted & different from current owner
315
         if conv_integer(cown) /= new_request then
316
            -- if idle state: turnaround cycle required by PCI standard
317
            cowni <= conv_std_logic_vector(new_request, ARB_SIZE);
318
            touti <= "0000";                 -- reset timeout counter
319
            if turn = '0' then
320
               rearbi <= '1';           -- only one re-arbitration
321
            end if;
322
         end if;
323
      elsif frame_n = '1' then
324
         rearbi <= '0';
325
      end if;
326
 
327
      -- if frame deasserted, but request asserted: count timeout
328
      if req_n = all_ones then          -- no request: prepare timeout counter
329
         touti <= "1111";
330
      elsif frame_n = '1' then          -- request, but no transaction
331
         if tout = "1111" then              -- timeout expired, re-arbitrate
332
            turni <= '1';               -- remove grant, turnaround cycle
333
            touti <= "0000";                 -- next cycle re-arbitrate
334
         else
335
            touti <= tout + 1;
336
         end if;
337
      end if;
338
 
339
      grant : for i in 0 to NB_AGENTS-1 loop
340
         if i = conv_integer(cown) and turn = '0' then
341
            gnt_n(i) <= '0';
342
         else
343
            gnt_n(i) <= '1';
344
         end if;
345
      end loop grant;
346
 
347
      -- synchronous reset
348
      if rst_n = '0' then
349
         touti    <= "0000";
350
         cowni    <= (others => '0');
351
         owneri0  <= (others => '0');
352
         owneri1  <= (others => '0');
353
         rearbi   <= '0';
354
         turni    <= '0';
355
         new_request := 0;
356
      end if;
357
 
358
   end process arbiter;
359
 
360
   arb_lvl(NB_AGENTS-1) <= '1';  -- always prio 1.
361
 
362
   fixed_prios : if not APB_PRIOS generate  -- assign constant value
363
      arb_lvl(NB_AGENTS-2 downto 0) <= ARB_LVL_C(NB_AGENTS-2 downto 0);
364
   end generate fixed_prios;
365
 
366
   -- Generate APB regs and APB slave
367
   apbgen : if APB_PRIOS generate
368
      -- purpose: APB read and write of arb_lvl configuration registers
369
      -- type:    memoryless
370
      -- inputs:  pbi, arb_lvl, prst_n
371
      -- outputs: pbo, arb_lvli
372
      config : process (pbi, arb_lvl, prst_n)
373
 
374
      begin  -- process config
375
         arb_lvli <= arb_lvl;
376
 
377
         pbo.PRDATA <= (others => '0');  -- default for unimplemented addresses
378
 
379
         -- register select at (byte-) addresses 0x80
380
         if pbi.PADDR(7 downto 0) = "10000000" and pbi.PSEL = '1' then -- address select
381
            if (pbi.PWRITE and pbi.PENABLE) = '1' then  -- APB write
382
                  arb_lvli <= pbi.PWDATA(NB_AGENTS-1 downto 0);
383
            end if;
384
            pbo.PRDATA(NB_AGENTS-1 downto 0) <= arb_lvl;
385
         end if;
386
         -- synchronous reset
387
         if prst_n = '0' then
388
            arb_lvli <= ARB_LVL_C;          -- assign default value
389
         end if;
390
      end process config;
391
 
392
      -- APB registers
393
 
394
      apb_regs : process (pclk)
395
      begin  -- process regs
396
         -- activities triggered by asynchronous reset (active low)
397
         if pclk'event and pclk = '1' then  -- '
398
            arb_lvl(NB_AGENTS-2 downto 0) <= arb_lvli(NB_AGENTS-2 downto 0);
399
         end if;
400
      end process apb_regs;
401
 
402
   end generate apbgen;
403
 
404
   -- PCI registers
405
 
406
   regs0 : process (clk)
407
 
408
   begin  -- process regs
409
      if clk'event and clk = '1' then  -- '
410
         tout    <= touti;
411
         owner0  <= owneri0;
412
         owner1  <= owneri1;
413
         cown    <= cowni;
414
         rearb   <= rearbi;
415
         turn    <= turni;
416
      end if;
417
   end process regs0;
418
 
419
end rtl;
420
 
421
 
422
 

powered by: WebSVN 2.1.0

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