1 |
15 |
mihad |
//===========================================================================
|
2 |
35 |
mihad |
// $Id: pci_blue_arbiter.v,v 1.2 2002-03-21 07:35:50 mihad Exp $
|
3 |
15 |
mihad |
//
|
4 |
|
|
// Copyright 2001 Blue Beaver. All Rights Reserved.
|
5 |
|
|
//
|
6 |
|
|
// Summary: A synthesizable PCI Arbiter. This will have 4 external PCI
|
7 |
|
|
// Request/Grant pairs and one internal Request/Grant Pair.
|
8 |
|
|
// A Compile-time option selects whether to include an un-latched
|
9 |
|
|
// IRDY_L signal ithe arbitration. This might make the bus use
|
10 |
|
|
// slightly more efficient. But there would be more load in
|
11 |
|
|
// IRDY_L, a very timing critical signal. Not sure which is best.
|
12 |
|
|
//
|
13 |
|
|
// This library is free software; you can distribute it and/or modify it
|
14 |
|
|
// under the terms of the GNU Lesser General Public License as published
|
15 |
|
|
// by the Free Software Foundation; either version 2.1 of the License, or
|
16 |
|
|
// (at your option) any later version.
|
17 |
|
|
//
|
18 |
|
|
// This library is distributed in the hope that it will be useful, but
|
19 |
|
|
// WITHOUT ANY WARRANTY; without even the implied warranty of
|
20 |
|
|
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
21 |
|
|
// See the GNU Lesser General Public License for more details.
|
22 |
|
|
//
|
23 |
|
|
// You should have received a copy of the GNU Lesser General Public License
|
24 |
|
|
// along with this library. If not, write to
|
25 |
|
|
// Free Software Foundation, Inc.
|
26 |
|
|
// 59 Temple Place, Suite 330
|
27 |
|
|
// Boston, MA 02111-1307 USA
|
28 |
|
|
//
|
29 |
|
|
// Author's note about this license: The intention of the Author and of
|
30 |
|
|
// the Gnu Lesser General Public License is that users should be able to
|
31 |
|
|
// use this code for any purpose, including combining it with other source
|
32 |
|
|
// code, combining it with other logic, translated it into a gate-level
|
33 |
|
|
// representation, or projected it into gates in a programmable or
|
34 |
|
|
// hardwired chip, as long as the users of the resulting source, compiled
|
35 |
|
|
// source, or chip are given the means to get a copy of this source code
|
36 |
|
|
// with no new restrictions on redistribution of this source.
|
37 |
|
|
//
|
38 |
|
|
// If you make changes, even substantial changes, to this code, or use
|
39 |
|
|
// substantial parts of this code as an inseparable part of another work
|
40 |
|
|
// of authorship, the users of the resulting IP must be given the means
|
41 |
|
|
// to get a copy of the modified or combined source code, with no new
|
42 |
|
|
// restrictions on redistribution of the resulting source.
|
43 |
|
|
//
|
44 |
|
|
// Separate parts of the combined source code, compiled code, or chip,
|
45 |
|
|
// which are NOT derived from this source code do NOT need to be offered
|
46 |
|
|
// to the final user of the chip merely because they are used in
|
47 |
|
|
// combination with this code. Other code is not forced to fall under
|
48 |
|
|
// the GNU Lesser General Public License when it is linked to this code.
|
49 |
|
|
// The license terms of other source code linked to this code might require
|
50 |
|
|
// that it NOT be made available to users. The GNU Lesser General Public
|
51 |
|
|
// License does not prevent this code from being used in such a situation,
|
52 |
|
|
// as long as the user of the resulting IP is given the means to get a
|
53 |
|
|
// copy of this component of the IP with no new restrictions on
|
54 |
|
|
// redistribution of this source.
|
55 |
|
|
//
|
56 |
|
|
// This code was developed using VeriLogger Pro, by Synapticad.
|
57 |
|
|
// Their support is greatly appreciated.
|
58 |
|
|
//
|
59 |
|
|
// NOTE: This PCI Arbiter is an implementation of the arbiter ideas
|
60 |
|
|
// described in the PCI Local Bus Specification Revision 2.2,
|
61 |
|
|
// section 3.4.
|
62 |
|
|
//
|
63 |
|
|
// NOTE: This arbiter serves 4 external Request/Grant pairs and one
|
64 |
|
|
// internal Request/Grant pair. It would be attractive to
|
65 |
|
|
// try to implement the 2-level arbitration given in the
|
66 |
|
|
// implementation note.
|
67 |
|
|
//
|
68 |
|
|
// NOTE: Upon Reset, this Arbiter parks the bus on the Internal Grant.
|
69 |
|
|
//
|
70 |
|
|
// NOTE: The 4 arbitration rules given in the PCI Local Bus Specification
|
71 |
|
|
// Revision 2.2, section 3.4.1, are:
|
72 |
|
|
// 0) Be fair. Do not starve anyone. However, priorities are OK.
|
73 |
|
|
// 1) If GNT_L is Deasserted and FRAME_L is asserted on the same
|
74 |
|
|
// clock, a valid reference is started
|
75 |
|
|
// 2) One GNT_L can be deasserted the same clock which another
|
76 |
|
|
// GNT_L is asserted if NOT in Idle state. If in Idle state,
|
77 |
|
|
// one clock with no GNT at all must be inserted to avoid
|
78 |
|
|
// contention on the AD and PAR lines.
|
79 |
|
|
// 3) When FRAME_L is deasserted, GNT_L may be deasserted at
|
80 |
|
|
// any time.
|
81 |
|
|
//
|
82 |
|
|
// NOTE: The arbiter can assume a device is "broken" if it receives REQ,
|
83 |
|
|
// assertes GNT, and no FRAME is asserted, for 16 clocks. It is legal
|
84 |
|
|
// to ignore that device's REQ signal after that, and report the
|
85 |
|
|
// problem to the host. This device just moves on to the next REQ.
|
86 |
|
|
//
|
87 |
|
|
// NOTE: When the Arbiter is on-chip, the FRAME signal must NOT be the
|
88 |
|
|
// external FRAME signal when the internam PCI device is driving
|
89 |
|
|
// the bus. In the case that the internal device is driving the
|
90 |
|
|
// bus, the INTERNAL FRAME signal must be used. This is due to
|
91 |
|
|
// time-of-flight concerns on the external PCI bus. See the PCI
|
92 |
|
|
// Local Bus Specification Revision 2.2, section 3.10 item 9.
|
93 |
|
|
//
|
94 |
|
|
// NOTE: It is not clear when a change in bus ownership should occur.
|
95 |
|
|
// This arbiter grants a device the bus, and then waits until
|
96 |
|
|
// the device has started a reference before granting to a new
|
97 |
|
|
// device. If no other requests are pending, the grant stays put.
|
98 |
|
|
//
|
99 |
|
|
//===========================================================================
|
100 |
|
|
|
101 |
35 |
mihad |
// synopsys translate_off
|
102 |
|
|
`include "timescale.v"
|
103 |
|
|
// synopsys translate_on
|
104 |
15 |
mihad |
|
105 |
|
|
// Allows printing of Arbiter Debug info. Usually not defined
|
106 |
|
|
//`define PCI_TRACE_ARB 1
|
107 |
|
|
|
108 |
|
|
module pci_blue_arbiter (
|
109 |
|
|
pci_int_req_direct, pci_ext_req_prev,
|
110 |
|
|
pci_int_gnt_direct_out, pci_ext_gnt_direct_out,
|
111 |
|
|
pci_frame_prev, pci_irdy_prev, pci_irdy_now,
|
112 |
|
|
arbitration_enable,
|
113 |
|
|
pci_clk, pci_reset_comb
|
114 |
|
|
);
|
115 |
|
|
|
116 |
|
|
`include "pci_blue_options.vh"
|
117 |
|
|
`include "pci_blue_constants.vh"
|
118 |
|
|
|
119 |
|
|
input pci_int_req_direct; // direct from internal flop clocked with pci_clk
|
120 |
|
|
input [3:0] pci_ext_req_prev;
|
121 |
|
|
output pci_int_gnt_direct_out;
|
122 |
|
|
output [3:0] pci_ext_gnt_direct_out;
|
123 |
|
|
input pci_frame_prev, pci_irdy_prev, pci_irdy_now;
|
124 |
|
|
input arbitration_enable;
|
125 |
|
|
input pci_clk, pci_reset_comb;
|
126 |
|
|
|
127 |
|
|
// detect the deassertion of reset, hopefully without metastability
|
128 |
|
|
reg prev_unreset, prev_prev_unreset;
|
129 |
|
|
reg arbiter_init;
|
130 |
|
|
always @(posedge pci_clk or posedge pci_reset_comb)
|
131 |
|
|
begin
|
132 |
|
|
if (pci_reset_comb)
|
133 |
|
|
begin
|
134 |
|
|
prev_unreset <= 1'b0;
|
135 |
|
|
prev_prev_unreset <= 1'b0;
|
136 |
|
|
arbiter_init <= 1'b0;
|
137 |
|
|
end
|
138 |
|
|
else
|
139 |
|
|
begin
|
140 |
|
|
prev_unreset <= 1'b1;
|
141 |
|
|
prev_prev_unreset <= prev_unreset;
|
142 |
|
|
// init arbiter when reset goes away, or when user disables arbiter
|
143 |
|
|
arbiter_init <= ~prev_prev_unreset | ~arbitration_enable;
|
144 |
|
|
end
|
145 |
|
|
end
|
146 |
|
|
|
147 |
|
|
// watch for bus activity.
|
148 |
|
|
reg prev_prev_frame;
|
149 |
|
|
always @(posedge pci_clk)
|
150 |
|
|
begin
|
151 |
|
|
prev_prev_frame <= pci_frame_prev;
|
152 |
|
|
end
|
153 |
|
|
|
154 |
|
|
// approximate, but always conservative
|
155 |
|
|
// wire pci_bus_not_idle = pci_frame_prev;
|
156 |
|
|
// expensive because irdy is critical
|
157 |
|
|
`define INCLUDE_FAST_IRDY_INPUT
|
158 |
|
|
`ifdef INCLUDE_FAST_IRDY_INPUT
|
159 |
|
|
wire pci_bus_not_idle = pci_frame_prev | pci_irdy_now;
|
160 |
|
|
`else // INCLUDE_FAST_IRDY_INPUT
|
161 |
|
|
wire pci_bus_not_idle = pci_frame_prev;
|
162 |
|
|
`endif // INCLUDE_FAST_IRDY_INPUT
|
163 |
|
|
wire pci_bus_went_idle = ~pci_frame_prev & ~pci_irdy_prev;
|
164 |
|
|
wire pci_address_phase = pci_frame_prev & ~prev_prev_frame;
|
165 |
|
|
|
166 |
|
|
// upon assertion of reset, remove all bus grants.
|
167 |
|
|
// note that the PCI Local Bus Specification Revision 2.2,
|
168 |
|
|
// section 2.2.4, says the devices must ignore GNT_L when
|
169 |
|
|
// reset is asserted, no matter what it's value is.
|
170 |
|
|
// upon reset, all requests are pulled HIGH by motherboard pullups,
|
171 |
|
|
// because upon reset, all PCI devices are supposed to HIGH-Z
|
172 |
|
|
// their request lines. See the PCI Local Bus Specification
|
173 |
|
|
// Revision 2.2, section 2.2.4. The internal device cannot
|
174 |
|
|
// be tristated, Instead, it de-requests.
|
175 |
|
|
// upon deassertion of reset, park the bus on the internal device.
|
176 |
|
|
// note that the bus parking will not happen if the PCI Clock is
|
177 |
|
|
// not running.
|
178 |
|
|
// after initialization, the bus is parked at the last bus user.
|
179 |
|
|
|
180 |
|
|
// round_robin arbitration. No priorities or anything.
|
181 |
|
|
// Note this can change constantly as new requests come in
|
182 |
|
|
reg [4:0] prev_master; // remembered from last good arbitration
|
183 |
|
|
wire [4:0] present_requestors = {pci_ext_req_prev[3:0], pci_int_req_direct};
|
184 |
|
|
wire [4:0] no_master = 5'h00;
|
185 |
|
|
wire [4:0] internal_master = 5'h01;
|
186 |
|
|
|
187 |
|
|
wire New_Master_Wants_Bus =
|
188 |
|
|
(present_requestors != 5'h00)
|
189 |
|
|
&& (present_requestors != prev_master);
|
190 |
|
|
wire New_Master_Stopped_Requesting =
|
191 |
|
|
((present_requestors & prev_master) == 5'h00);
|
192 |
|
|
|
193 |
|
|
wire [4:0] next_master =
|
194 |
|
|
((prev_master == 5'h00) || (prev_master == 5'h01))
|
195 |
|
|
? ( (present_requestors[1]) ? 5'h02
|
196 |
|
|
: ((present_requestors[2]) ? 5'h04
|
197 |
|
|
: ((present_requestors[3]) ? 5'h08
|
198 |
|
|
: ((present_requestors[4]) ? 5'h10
|
199 |
|
|
: 5'h01))))
|
200 |
|
|
: ((prev_master == 5'h02)
|
201 |
|
|
? ( (present_requestors[2]) ? 5'h04
|
202 |
|
|
: ((present_requestors[3]) ? 5'h08
|
203 |
|
|
: ((present_requestors[4]) ? 5'h10
|
204 |
|
|
: ((present_requestors[0]) ? 5'h01
|
205 |
|
|
: 5'h02))))
|
206 |
|
|
: ((prev_master == 5'h04)
|
207 |
|
|
? ( (present_requestors[3]) ? 5'h08
|
208 |
|
|
: ((present_requestors[4]) ? 5'h10
|
209 |
|
|
: ((present_requestors[0]) ? 5'h01
|
210 |
|
|
: ((present_requestors[1]) ? 5'h02
|
211 |
|
|
: 5'h04))))
|
212 |
|
|
: ((prev_master == 5'h08)
|
213 |
|
|
? ( (present_requestors[4]) ? 5'h10
|
214 |
|
|
: ((present_requestors[0]) ? 5'h01
|
215 |
|
|
: ((present_requestors[1]) ? 5'h02
|
216 |
|
|
: ((present_requestors[2]) ? 5'h04
|
217 |
|
|
: 5'h08))))
|
218 |
|
|
: // ((prev_master == 5'h10) || (more than 1 bit set)) ?
|
219 |
|
|
( (present_requestors[0]) ? 5'h01
|
220 |
|
|
: ((present_requestors[1]) ? 5'h02
|
221 |
|
|
: ((present_requestors[2]) ? 5'h04
|
222 |
|
|
: ((present_requestors[3]) ? 5'h08
|
223 |
|
|
: 5'h10))))
|
224 |
|
|
) ) );
|
225 |
|
|
|
226 |
|
|
// state machine moves to next state when a new request is available and
|
227 |
|
|
// the previous grent has resulted in a memory reference, or when the
|
228 |
|
|
// bus has been idle too long.
|
229 |
|
|
//
|
230 |
|
|
// When the PCI Bus is not Idle, it is fine to deassert one grant and
|
231 |
|
|
// assert another the next clock. If the bus is NOT Idle, there must be
|
232 |
|
|
// a one clock delay between the deassertion of one GNT and the next GNT.
|
233 |
|
|
// Refer to the PCI Local Bus Specification Revision 2.2, section 3.4.1.
|
234 |
|
|
//
|
235 |
|
|
// In order to remove any dependence on the IRDY and TRDY signals directly
|
236 |
|
|
// received from the PCI Bus, this arbiter uses the latched versions.
|
237 |
|
|
// The PCI Bus is Idle whenever BOTH FRAME and IRDY are deasserted. This
|
238 |
|
|
// arbiter uses an approximation of that. It uses the Latched FRAME
|
239 |
|
|
// signal alone. This is not too bad, because each reference ends with
|
240 |
|
|
// FRAME going deasserted and IRDY going asserted for at least one clock.
|
241 |
|
|
// Latched FRAME is valid for 1 clock after Frame goes away, which is
|
242 |
|
|
// automatically also a non-idle clock. Latched FRAME is a conservative
|
243 |
|
|
// estimate of whether the bus is idle or not. When Latched FRAME is
|
244 |
|
|
// not asserted, the Arbiter will deassert all GNT signals for one clock
|
245 |
|
|
// before asserting a new GNT.
|
246 |
|
|
//
|
247 |
|
|
// The event sequence is as follows:
|
248 |
|
|
// 1) at time minus infinity, some device gets bus mastership
|
249 |
|
|
// 2) at time before 0, the arbiter decides the first device is done
|
250 |
|
|
// 3) at time -1, a new device requests
|
251 |
|
|
// 4) at time 0, the old device is ungranted, and the new device is granted
|
252 |
|
|
// 5) at time 0, the old device might start a new reference or continue an old one
|
253 |
|
|
// 6) at time 1, the new device gets a chance to see the grant
|
254 |
|
|
// 7) at time 1, the new device can drive the bus ONLY if it is idle
|
255 |
|
|
// 8) at time 2, the arbiter sees whether the bus was idle at time 1
|
256 |
|
|
// from time 2 on, it watches to see when the bus finally goes idle
|
257 |
|
|
// 9) whenever the arbiter sees the bus going idle, it starts counting
|
258 |
|
|
// a counter to 16. It also watches for a transition on frame indicating
|
259 |
|
|
// that an address phase has happened.
|
260 |
|
|
// 10) when the timer expires or the address phase happens, the arbiter
|
261 |
|
|
// rearbitrates to give the next requestor a chance.
|
262 |
|
|
|
263 |
|
|
parameter PCI_ARBITER_HAPPILY_WAITING = 5'b00001;
|
264 |
|
|
parameter PCI_ARBITER_REMOVE_GNT = 5'b00010;
|
265 |
|
|
parameter PCI_ARBITER_DELAY_ONE = 5'b00100;
|
266 |
|
|
parameter PCI_ARBITER_WAIT_FOR_IDLE = 5'b01000;
|
267 |
|
|
parameter PCI_ARBITER_WAIT_FOR_ADDRESS = 5'b10000;
|
268 |
|
|
reg [4:0] PCI_Arbiter_State;
|
269 |
|
|
|
270 |
|
|
reg [4:0] new_master;
|
271 |
|
|
reg [3:0] gnt_timeout;
|
272 |
|
|
always @(posedge pci_clk or posedge pci_reset_comb)
|
273 |
|
|
begin
|
274 |
|
|
if (pci_reset_comb)
|
275 |
|
|
begin
|
276 |
|
|
PCI_Arbiter_State <= PCI_ARBITER_HAPPILY_WAITING;
|
277 |
|
|
prev_master <= no_master;
|
278 |
|
|
new_master <= no_master;
|
279 |
|
|
gnt_timeout <= 4'h0;
|
280 |
|
|
end
|
281 |
|
|
else
|
282 |
|
|
begin
|
283 |
|
|
if (arbiter_init)
|
284 |
|
|
begin
|
285 |
|
|
PCI_Arbiter_State <= PCI_ARBITER_HAPPILY_WAITING;
|
286 |
|
|
prev_master <= internal_master;
|
287 |
|
|
new_master <= internal_master;
|
288 |
|
|
gnt_timeout <= 4'h0;
|
289 |
|
|
end
|
290 |
|
|
else
|
291 |
|
|
begin
|
292 |
|
|
case (PCI_Arbiter_State)
|
293 |
|
|
PCI_ARBITER_HAPPILY_WAITING:
|
294 |
|
|
begin
|
295 |
|
|
gnt_timeout <= 4'h0; // all cases
|
296 |
|
|
if (New_Master_Wants_Bus)
|
297 |
|
|
begin
|
298 |
|
|
if (pci_bus_not_idle)
|
299 |
|
|
begin // directly grant new bus owner
|
300 |
|
|
PCI_Arbiter_State <= PCI_ARBITER_DELAY_ONE;
|
301 |
|
|
prev_master <= next_master;
|
302 |
|
|
new_master <= next_master;
|
303 |
|
|
end
|
304 |
|
|
else
|
305 |
|
|
begin // case that bus is idle. make no grant for 1 clock
|
306 |
|
|
PCI_Arbiter_State <= PCI_ARBITER_REMOVE_GNT;
|
307 |
|
|
prev_master <= prev_master;
|
308 |
|
|
new_master <= no_master;
|
309 |
|
|
end
|
310 |
|
|
end
|
311 |
|
|
else
|
312 |
|
|
begin // no requestor or same requestor. Park on previous winner
|
313 |
|
|
PCI_Arbiter_State <= PCI_ARBITER_HAPPILY_WAITING;
|
314 |
|
|
prev_master <= prev_master;
|
315 |
|
|
new_master <= prev_master;
|
316 |
|
|
end
|
317 |
|
|
end
|
318 |
|
|
PCI_ARBITER_REMOVE_GNT:
|
319 |
|
|
begin
|
320 |
|
|
if (New_Master_Wants_Bus)
|
321 |
|
|
begin // directly grant new bus owner
|
322 |
|
|
PCI_Arbiter_State <= PCI_ARBITER_DELAY_ONE;
|
323 |
|
|
prev_master <= next_master;
|
324 |
|
|
new_master <= next_master;
|
325 |
|
|
end
|
326 |
|
|
else
|
327 |
|
|
begin // requestor gave up. Park on previous winner
|
328 |
|
|
PCI_Arbiter_State <= PCI_ARBITER_HAPPILY_WAITING;
|
329 |
|
|
prev_master <= prev_master;
|
330 |
|
|
new_master <= prev_master;
|
331 |
|
|
end
|
332 |
|
|
end
|
333 |
|
|
PCI_ARBITER_DELAY_ONE:
|
334 |
|
|
begin // wait for pipelined copy of FRAME, IRDY to become valid
|
335 |
|
|
prev_master <= prev_master; // all cases
|
336 |
|
|
new_master <= prev_master; // all cases
|
337 |
|
|
gnt_timeout <= 4'h0; // all cases
|
338 |
|
|
if (New_Master_Stopped_Requesting)
|
339 |
|
|
begin // requestor removed request! Never happens. Rearb immediately.
|
340 |
|
|
PCI_Arbiter_State <= PCI_ARBITER_HAPPILY_WAITING;
|
341 |
|
|
end
|
342 |
|
|
else
|
343 |
|
|
begin // start looking for bus idle, when new master takes over
|
344 |
|
|
PCI_Arbiter_State <= PCI_ARBITER_WAIT_FOR_IDLE;
|
345 |
|
|
end
|
346 |
|
|
end
|
347 |
|
|
PCI_ARBITER_WAIT_FOR_IDLE:
|
348 |
|
|
begin // A new master is granted, but can't start until the PCI bus is idle
|
349 |
|
|
prev_master <= prev_master; // all cases
|
350 |
|
|
new_master <= prev_master; // all cases
|
351 |
|
|
gnt_timeout <= 4'h0; // all cases
|
352 |
|
|
if (New_Master_Stopped_Requesting)
|
353 |
|
|
begin // requestor removed request! Never happens. Rearb immediately.
|
354 |
|
|
PCI_Arbiter_State <= PCI_ARBITER_HAPPILY_WAITING;
|
355 |
|
|
end
|
356 |
|
|
else
|
357 |
|
|
begin
|
358 |
|
|
if (pci_bus_went_idle)
|
359 |
|
|
begin // now the new master can take control by driving an address
|
360 |
|
|
PCI_Arbiter_State <= PCI_ARBITER_WAIT_FOR_ADDRESS;
|
361 |
|
|
end
|
362 |
|
|
else
|
363 |
|
|
begin // wait for old master to release bus
|
364 |
|
|
PCI_Arbiter_State <= PCI_ARBITER_WAIT_FOR_IDLE;
|
365 |
|
|
end
|
366 |
|
|
end
|
367 |
|
|
end
|
368 |
|
|
PCI_ARBITER_WAIT_FOR_ADDRESS:
|
369 |
|
|
begin
|
370 |
|
|
gnt_timeout <= gnt_timeout + 4'h1; // all cases
|
371 |
|
|
if (New_Master_Stopped_Requesting)
|
372 |
|
|
begin // requestor removed request! Never happens. Rearb immediately.
|
373 |
|
|
PCI_Arbiter_State <= PCI_ARBITER_HAPPILY_WAITING;
|
374 |
|
|
prev_master <= prev_master;
|
375 |
|
|
new_master <= prev_master;
|
376 |
|
|
end
|
377 |
|
|
else
|
378 |
|
|
begin
|
379 |
|
|
if (pci_address_phase || (gnt_timeout == 4'hF))
|
380 |
|
|
begin
|
381 |
|
|
`ifdef INCLUDE_FAST_IRDY_ON_IDLE_TERM
|
382 |
|
|
// This term makes some improvement in arbitration timing, but not sure how
|
383 |
|
|
// much. With the term, certain wait states at the end of single-word or burst
|
384 |
|
|
// transfers are eliminated. The arbitration time in the case of a genuinely
|
385 |
|
|
// idle bus isn't changed however. Presently not using this.
|
386 |
|
|
if (New_Master_Wants_Bus)
|
387 |
|
|
begin // safe to rearbitrate. Is anyone waiting?
|
388 |
|
|
if (pci_bus_not_idle) // bus is busy, switch instantly
|
389 |
|
|
begin
|
390 |
|
|
PCI_Arbiter_State <= PCI_ARBITER_DELAY_ONE;
|
391 |
|
|
prev_master <= next_master;
|
392 |
|
|
new_master <= next_master;
|
393 |
|
|
end
|
394 |
|
|
else // bus is idle, force an idle period
|
395 |
|
|
begin
|
396 |
|
|
PCI_Arbiter_State <= PCI_ARBITER_REMOVE_GNT;
|
397 |
|
|
prev_master <= prev_master;
|
398 |
|
|
new_master <= no_master;
|
399 |
|
|
end
|
400 |
|
|
end
|
401 |
|
|
else
|
402 |
|
|
`endif // INCLUDE_FAST_IRDY_ON_IDLE_TERM
|
403 |
|
|
begin // no requestor or same requestor. Park on previous winner
|
404 |
|
|
PCI_Arbiter_State <= PCI_ARBITER_HAPPILY_WAITING;
|
405 |
|
|
prev_master <= prev_master;
|
406 |
|
|
new_master <= prev_master;
|
407 |
|
|
end
|
408 |
|
|
end
|
409 |
|
|
else
|
410 |
|
|
begin // no addres phase or timeout yet. Just keep looking
|
411 |
|
|
PCI_Arbiter_State <= PCI_ARBITER_WAIT_FOR_ADDRESS;
|
412 |
|
|
prev_master <= prev_master;
|
413 |
|
|
new_master <= prev_master;
|
414 |
|
|
end
|
415 |
|
|
end
|
416 |
|
|
end
|
417 |
|
|
default:
|
418 |
|
|
begin
|
419 |
|
|
PCI_Arbiter_State <= PCI_ARBITER_HAPPILY_WAITING;
|
420 |
|
|
prev_master <= internal_master;
|
421 |
|
|
new_master <= internal_master;
|
422 |
|
|
gnt_timeout <= 4'h0;
|
423 |
|
|
end
|
424 |
|
|
endcase
|
425 |
|
|
end
|
426 |
|
|
end
|
427 |
|
|
end
|
428 |
|
|
|
429 |
|
|
assign pci_int_gnt_direct_out = new_master[0];
|
430 |
|
|
assign pci_ext_gnt_direct_out = new_master[4:1];
|
431 |
|
|
|
432 |
|
|
// synopsys translate_off
|
433 |
|
|
`ifdef PCI_TRACE_ARB
|
434 |
|
|
always @(posedge pci_clk or posedge pci_reset_comb)
|
435 |
|
|
begin
|
436 |
|
|
if (pci_reset_comb)
|
437 |
|
|
begin
|
438 |
|
|
$display ("async reset");
|
439 |
|
|
end
|
440 |
|
|
else
|
441 |
|
|
begin
|
442 |
|
|
if (arbiter_init)
|
443 |
|
|
begin
|
444 |
|
|
$display ("sync reset");
|
445 |
|
|
end
|
446 |
|
|
else
|
447 |
|
|
begin
|
448 |
|
|
case (PCI_Arbiter_State)
|
449 |
|
|
PCI_ARBITER_HAPPILY_WAITING:
|
450 |
|
|
begin
|
451 |
|
|
if (New_Master_Wants_Bus)
|
452 |
|
|
begin // new requestor. Either ungrant for 1 clock if idle or go directly
|
453 |
|
|
if (pci_bus_not_idle) // indication that bus is busy
|
454 |
|
|
begin
|
455 |
|
|
$display ("Waiting, New Master, Bus Not Idle %x %x",
|
456 |
|
|
present_requestors, prev_master);
|
457 |
|
|
end
|
458 |
|
|
else
|
459 |
|
|
begin // case that bus is idle. make no grant for 1 clock
|
460 |
|
|
$display ("Waiting, New Master, Bus Idle %x %x",
|
461 |
|
|
present_requestors, prev_master);
|
462 |
|
|
end
|
463 |
|
|
end
|
464 |
|
|
else
|
465 |
|
|
begin // no reason to change. Park on previous winner
|
466 |
|
|
$display ("Waiting, No New Master %x %x",
|
467 |
|
|
present_requestors, prev_master);
|
468 |
|
|
end
|
469 |
|
|
end
|
470 |
|
|
PCI_ARBITER_REMOVE_GNT:
|
471 |
|
|
begin // pick the new winner, or the previous winner if the requestor left
|
472 |
|
|
if (New_Master_Wants_Bus)
|
473 |
|
|
begin // new requestor wins. Wait for it's reference before rearbitrating
|
474 |
|
|
$display ("Remove Gnt, New Master still requesting %x %x",
|
475 |
|
|
present_requestors, prev_master);
|
476 |
|
|
end
|
477 |
|
|
else
|
478 |
|
|
begin // no reason to change. Park on previous winner
|
479 |
|
|
$display ("Remove Gnt, New Master removed request %x %x",
|
480 |
|
|
present_requestors, prev_master);
|
481 |
|
|
end
|
482 |
|
|
end
|
483 |
|
|
PCI_ARBITER_DELAY_ONE:
|
484 |
|
|
begin // wait for pipelined copy of FRAME, IRDY to become valid
|
485 |
|
|
$display ("Delay 1, wait for Frame and IRDY pipeline %x %x",
|
486 |
|
|
present_requestors, prev_master);
|
487 |
|
|
end
|
488 |
|
|
PCI_ARBITER_WAIT_FOR_IDLE:
|
489 |
|
|
begin // A new master is granted, but can't start until the PCI bus is idle
|
490 |
|
|
if (New_Master_Stopped_Requesting)
|
491 |
|
|
begin // requestor removed request! Never happens. Rearb immediately.
|
492 |
|
|
$display ("Waiting for Idle, New Master removed request %x %x",
|
493 |
|
|
present_requestors, prev_master);
|
494 |
|
|
end
|
495 |
|
|
else
|
496 |
|
|
begin
|
497 |
|
|
if (pci_bus_went_idle)
|
498 |
|
|
begin // now the new master can take control
|
499 |
|
|
$display ("Waiting for Idle, went idle, New Master still requesting %x %x",
|
500 |
|
|
present_requestors, prev_master);
|
501 |
|
|
end
|
502 |
|
|
else
|
503 |
|
|
begin // wait for old master to release bus
|
504 |
|
|
$display ("Waiting for Idle, not idle, New Master still requesting %x %x",
|
505 |
|
|
present_requestors, prev_master);
|
506 |
|
|
end
|
507 |
|
|
end
|
508 |
|
|
end
|
509 |
|
|
PCI_ARBITER_WAIT_FOR_ADDRESS:
|
510 |
|
|
begin
|
511 |
|
|
if (New_Master_Stopped_Requesting)
|
512 |
|
|
begin // requestor removed request! Never happens. Rearb immediately.
|
513 |
|
|
$display ("Waiting for Address, New Master removed request %x %x",
|
514 |
|
|
present_requestors, prev_master);
|
515 |
|
|
end
|
516 |
|
|
else
|
517 |
|
|
begin
|
518 |
|
|
if ((pci_address_phase == 1'b1) || (gnt_timeout == 4'hF))
|
519 |
|
|
begin // safe to rearbitrate. Is anyone waiting?
|
520 |
|
|
if (New_Master_Wants_Bus)
|
521 |
|
|
begin
|
522 |
|
|
if (pci_bus_not_idle) // bus is busy, switch instantly
|
523 |
|
|
begin
|
524 |
|
|
$display ("Waiting for Address, Address or Timeout, New Master still requesting, bus was busy %x %x",
|
525 |
|
|
present_requestors, prev_master);
|
526 |
|
|
end
|
527 |
|
|
else // bus is idle, force an idle period
|
528 |
|
|
begin
|
529 |
|
|
$display ("Waiting for Address, Address or Timeout, New Master still requesting, bus was idle %x %x",
|
530 |
|
|
present_requestors, prev_master);
|
531 |
|
|
end
|
532 |
|
|
end
|
533 |
|
|
else
|
534 |
|
|
begin // no reason to change. Park on previous winner
|
535 |
|
|
$display ("Waiting for Address, No New Master, giving up %x %x",
|
536 |
|
|
present_requestors, prev_master);
|
537 |
|
|
end
|
538 |
|
|
end
|
539 |
|
|
else
|
540 |
|
|
begin
|
541 |
|
|
$display ("Waiting for Address, New Master still requesting, no address or timeout yet %x %x",
|
542 |
|
|
present_requestors, prev_master);
|
543 |
|
|
end
|
544 |
|
|
end
|
545 |
|
|
end
|
546 |
|
|
default:
|
547 |
|
|
begin
|
548 |
|
|
$display ("PCI Arbiter went insane with REQ 'h%x at time %t",
|
549 |
|
|
present_requestors, $time);
|
550 |
|
|
end
|
551 |
|
|
endcase
|
552 |
|
|
end
|
553 |
|
|
end
|
554 |
|
|
end
|
555 |
|
|
`endif // PCI_TRACE_ARB
|
556 |
|
|
// synopsys translate_on
|
557 |
|
|
endmodule
|
558 |
|
|
|