Initial commit of OpenSPARC T2 design and verification files.
[OpenSPARC-T2-DV] / design / sys / iop / pcie_common / rtl / pcie_common_frr_arbiter.v
CommitLineData
86530b38
AT
1// ========== Copyright Header Begin ==========================================
2//
3// OpenSPARC T2 Processor File: pcie_common_frr_arbiter.v
4// Copyright (C) 1995-2007 Sun Microsystems, Inc. All Rights Reserved
5// 4150 Network Circle, Santa Clara, California 95054, U.S.A.
6//
7// * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
8//
9// This program is free software; you can redistribute it and/or modify
10// it under the terms of the GNU General Public License as published by
11// the Free Software Foundation; version 2 of the License.
12//
13// This program is distributed in the hope that it will be useful,
14// but WITHOUT ANY WARRANTY; without even the implied warranty of
15// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16// GNU General Public License for more details.
17//
18// You should have received a copy of the GNU General Public License
19// along with this program; if not, write to the Free Software
20// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
21//
22// For the avoidance of doubt, and except that if any non-GPL license
23// choice is available it will apply instead, Sun elects to use only
24// the General Public License version 2 (GPLv2) at this time for any
25// software where a choice of GPL license versions is made
26// available with the language indicating that GPLv2 or any later version
27// may be used, or where a choice of which version of the GPL is applied is
28// otherwise unspecified.
29//
30// Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
31// CA 95054 USA or visit www.sun.com if you need additional information or
32// have any questions.
33//
34// ========== Copyright Header End ============================================
35module pcie_common_frr_arbiter (
36
37 //Clock and Reset
38
39 clk,
40 rst_l,
41
42
43 // Arbiter Inputs
44
45 current_request_vector,
46 update_winner,
47
48
49
50 // Arbiter Outputs
51
52 current_winner_vector
53
54
55 );
56
57
58//############################################################################
59// PARAMETERS
60//############################################################################
61parameter SIZE = 64;
62
63//############################################################################
64// PORT DECLARATIONS
65//############################################################################
66
67 //------------------------------------------------------------------------
68 // Clock and Reset
69 //------------------------------------------------------------------------
70 input clk;
71 input rst_l;
72
73
74 //------------------------------------------------------------------------
75 // Arbiter Inputs
76 //------------------------------------------------------------------------
77 input [SIZE-1:0] current_request_vector; //Requests to win arbitration
78 input update_winner; //Last Winner
79
80 //------------------------------------------------------------------------
81 // Arbiter Outputs
82 //------------------------------------------------------------------------
83 output [SIZE-1:0] current_winner_vector; // Arbiter Winner
84
85
86//############################################################################
87// SIGNAL DECLARATIONS
88//############################################################################
89
90
91//**************************************************
92// Wire
93//**************************************************
94
95 wire [SIZE-1:0] current_reqeust_mask; // Mask for the Current request
96
97 wire [SIZE-1:0] unmask_high_pri_regs;
98 wire [SIZE-1:0] mask_high_pri_regs;
99 wire [SIZE-1:0] grant_masked;
100 wire [SIZE-1:0] grant_unmasked;
101 wire [SIZE-1:0] grant;
102
103 wire no_req_masked;
104
105//**************************************************
106// Registers that Are Flops
107//**************************************************
108 reg [SIZE-1:0] arbiter_pointer;
109 reg [SIZE-1:0] current_winner_vector;
110
111
112
113//############################################################################
114// ZERO IN CHECKERS
115//############################################################################
116
117 //---------------------------------------------------------------------
118 // One Hot / Bits On Checkers
119 //---------------------------------------------------------------------
120
121 //0in bits_on -var current_winner_vector -max 1
122
123 //---------------------------------------------------------------------
124 // Arbiter Checker
125 //---------------------------------------------------------------------
126 /* 0in arbiter -req current_request_vector
127 -gnt current_winner_vector
128 -fair
129 -round_robin
130 -known_grant
131 -no_simultaneous_req_gnt
132 */
133
134
135//############################################################################
136// Combinational Logic
137//############################################################################
138
139//----------------------------------------------------------------------------
140// - Arbiter Pointer
141// - Needs to point to the location AFTER the last grant
142// - It is a vector as follows 11111100000
143// - It is with the first 1 at the next location after
144// the current winner
145//
146// - So by ANDing these two vectors together you
147//
148// current = 0101 pointer = 1110
149//
150// 1) 0101
151// 1110
152// -------
153// 0100
154//
155// current = 0111 pointer = 1110
156//
157// 2) 0111
158// 1110
159// -------
160// 0110
161//
162//
163// This is basically a vector of all of the incomming requests which are
164// to the LEFT or EQUAL to the Pointer
165//
166//----------------------------------------------------------------------------
167
168assign current_reqeust_mask = current_request_vector & arbiter_pointer;
169
170//----------------------------------------------------------------------------
171// Perform a Kind of Left shift Function
172//
173//
174// For Case 1
175//
176// curr_req_mask = 0100
177//
178// mask_high = xxx0
179// xx00
180// x000
181// 1000
182//
183// For Case 2
184//
185// curr_req_mask = 0110
186//
187// mask_high = xxx0
188// x100
189// 1100
190//
191// This basically creates a vector where if read from right to left the zero
192// before the first 1 is the bit making the request
193//
194// Or creates the pointer for the next arbitration if high priorty wins
195//
196//----------------------------------------------------------------------------
197
198assign mask_high_pri_regs[SIZE-1:1] = mask_high_pri_regs[SIZE-2:0] | current_reqeust_mask[SIZE-2:0];
199assign mask_high_pri_regs[0] = 1'b0;
200
201
202//----------------------------------------------------------------------------
203// Now Find your Winner
204//
205// - Invert the high priority mask to get a vector as follows 0000001111
206// - The first 1 left to right is the one who should go.
207//
208// - And together to get single bit winner.
209//
210//----------------------------------------------------------------------------
211assign grant_masked = current_reqeust_mask & ~mask_high_pri_regs;
212
213
214//----------------------------------------------------------------------------
215// Perform a Kind of Left shift Function
216//
217// This basically creates a vector where if read from right to left the zero
218// before the first 1 is the bit making the request
219//
220// Or creates the pointer for the next arbitration if low priorty wins
221//
222//----------------------------------------------------------------------------
223
224assign unmask_high_pri_regs[SIZE-1:1] = unmask_high_pri_regs[SIZE-2:0] | current_request_vector[SIZE-2:0];
225assign unmask_high_pri_regs[0] = 1'b0;
226
227
228//----------------------------------------------------------------------------
229// Now Find your Winner
230//
231// - Invert the high priority mask to get a vector as follows 0000001111
232// - The first 1 left to right is the one who should go.
233//
234// - And together to get single bit winner.
235//
236//----------------------------------------------------------------------------
237assign grant_unmasked = current_request_vector & ~unmask_high_pri_regs;
238
239
240//----------------------------------------------------------------------------
241// Determine which of the Grants to Use.
242//
243//----------------------------------------------------------------------------
244
245
246assign no_req_masked = ~(|current_reqeust_mask);
247
248assign grant = ({SIZE{no_req_masked}} & grant_unmasked) | grant_masked;
249
250
251
252
253//############################################################################
254// Sequential Logic
255//############################################################################
256
257
258//----------------------------------------------------------------------------
259// Flop the actual arbiter pointer when told to update
260//
261//----------------------------------------------------------------------------
262
263
264always @ (posedge clk)
265 begin
266 if(~rst_l)
267 begin
268 arbiter_pointer <= {SIZE{1'b1}};
269 end
270 else if (update_winner)
271 begin
272 if (|current_reqeust_mask)
273 begin
274 arbiter_pointer <= mask_high_pri_regs;
275 end
276 else
277 begin
278 arbiter_pointer <= unmask_high_pri_regs;
279 end
280 end
281 else
282 begin
283 arbiter_pointer <= arbiter_pointer;
284 end
285 end
286
287
288//----------------------------------------------------------------------------
289// Flop the actual winner
290//
291//----------------------------------------------------------------------------
292
293 always @(posedge clk)
294 begin
295 if (~rst_l)
296 current_winner_vector <= 64'b0;
297
298 else if (update_winner)
299 current_winner_vector <= grant;
300 else
301 current_winner_vector <= current_winner_vector;
302 end
303
304
305endmodule