Commit | Line | Data |
---|---|---|
86530b38 AT |
1 | // ========== Copyright Header Begin ========================================== |
2 | // | |
3 | // OpenSPARC T2 Processor File: FNXPCIEXactorManager.vr | |
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 ============================================ | |
35 | #include <vera_defines.vrh> | |
36 | #include "XactorList.vrh" | |
37 | #include "XactorListWildCard.vrh" | |
38 | #include "XactorManager.vrh" | |
39 | ||
40 | class FNXPCIEXactorManager extends XactorManager { | |
41 | // inherited members | |
42 | // integer ExpectFifo | |
43 | // integer DriveFifo | |
44 | // integer DriverSemaphore | |
45 | // XactorCtrl _XactorCtrl | |
46 | // XactorBasePacket SampledPkt | |
47 | // event NewTransaction | |
48 | // string XactorName | |
49 | // XactorClk ClkPort | |
50 | ||
51 | // inherited virtual methods | |
52 | // task DumpExpects() | |
53 | // function bit ExpectPending(XactorBasePacket ExpectedPacket) | |
54 | // function bit Remove(XactorBasePacket ExpectedPacket) | |
55 | // function integer NumExpects(); | |
56 | // task RemoveExpect(XactorBasePacket Packet, var bit Success) | |
57 | // task RemoveXExpect(XactorBasePacket Packet, var bit Success) | |
58 | // task RemoveRefExpect(XactorBasePacket Packet, var bit Success) | |
59 | // task RemoveRefXExpect(XactorBasePacket Packet, var bit Success) | |
60 | // task ExpectPkt(XactorBasePacket ExpectedPkt, integer Window, var bit [1:0] Status) | |
61 | // task SamplePkt(XactorBasePacket Pkt, integer Window) | |
62 | // task DisableManager() | |
63 | // task EnableManager() | |
64 | // task FlushDriveFifo() | |
65 | // task ResetManager() | |
66 | ||
67 | // public members | |
68 | integer RetryPktFifo; | |
69 | integer DllpExpectFifo; | |
70 | integer Bluntend_TX_fifo; | |
71 | integer DllpExpectDataStructSemaphore; | |
72 | integer DllpXExpectDataStructSemaphore; | |
73 | ||
74 | // private memebers | |
75 | protected XactorList DllpExpectDataStruct; | |
76 | protected XactorListWildCard DllpXExpectDataStruct; | |
77 | ||
78 | // Base Class and Method Names For QR Macros | |
79 | local string ClassName = "FNXPCIEXactorManager"; | |
80 | local string MethodName = null; | |
81 | ||
82 | bit ExpectsOn; | |
83 | bit UnexpectedTLPIsErr; | |
84 | bit disablteTlpExpectTimeout = 0; | |
85 | ||
86 | local event eNewTLPXaction; | |
87 | local event eNewDLLPXaction; | |
88 | ||
89 | // constructor | |
90 | task new( XactorBaseBuilder Builder, | |
91 | XactorClk _ClkPort ); | |
92 | ||
93 | // pubic methods | |
94 | virtual task DrivePkt( XactorBasePacket DrivenPkt, | |
95 | integer D ); | |
96 | virtual task ExpectPkt( XactorBasePacket ExpectedPkt, | |
97 | integer Window, | |
98 | var bit [1:0] Status ); | |
99 | virtual task SampleTlpPkt( XactorBasePacket Pkt, integer Window ); | |
100 | virtual task SampleDllpPkt( XactorBasePacket Pkt, integer Window ); | |
101 | virtual function bit Remove(XactorBasePacket ExpectedPacket); | |
102 | virtual task DumpExpects(); | |
103 | virtual function integer NumExpects(); | |
104 | virtual function integer NumTlpExpects(); | |
105 | virtual function integer NumDllpExpects(); | |
106 | virtual function bit ExpectPending(XactorBasePacket ExpectedPacket); | |
107 | ||
108 | // private methods | |
109 | protected task ExpectConsumer(); | |
110 | protected task DllpExpectConsumer(); | |
111 | protected task RetryExpectIssuer(); | |
112 | protected task RemoveDllpExpect( XactorBasePacket Packet, | |
113 | var bit Success ); | |
114 | protected task RemoveDllpXExpect( XactorBasePacket Packet, | |
115 | var bit Success ); | |
116 | protected task RemoveDllpRefExpect( XactorBasePacket Packet, | |
117 | var bit Success ); | |
118 | protected task RemoveDllpRefXExpect( XactorBasePacket Packet, | |
119 | var bit Success ); | |
120 | } | |
121 | ||
122 | task FNXPCIEXactorManager::new( XactorBaseBuilder Builder, | |
123 | XactorClk _ClkPort ) | |
124 | { | |
125 | string MethodName = "new"; | |
126 | ||
127 | super.new( Builder, | |
128 | _ClkPort ); | |
129 | ||
130 | ExpectsOn = 1; | |
131 | UnexpectedTLPIsErr = 1; | |
132 | ||
133 | RetryPktFifo = alloc(MAILBOX, 0, 1); | |
134 | if (RetryPktFifo == 0) | |
135 | PCIEX_QR_ERR( "%s-> Failed to Allocate RetryPktFifo Mailbox.", | |
136 | XactorName ); | |
137 | ||
138 | DllpExpectFifo = alloc(MAILBOX, 0, 1); | |
139 | if (DllpExpectFifo == 0) | |
140 | PCIEX_QR_ERR( "%s-> Failed to Allocate DllpExpectFifo Mailbox.", | |
141 | XactorName ); | |
142 | ||
143 | Bluntend_TX_fifo = alloc(MAILBOX, 0, 1); | |
144 | if (Bluntend_TX_fifo == 0) | |
145 | PCIEX_QR_ERR( "%s-> Failed to Allocate Bluntend_TX_fifo Mailbox.", | |
146 | XactorName ); | |
147 | ||
148 | ||
149 | DllpExpectDataStruct = new; | |
150 | DllpXExpectDataStruct = new; | |
151 | ||
152 | DllpExpectDataStructSemaphore = alloc(SEMAPHORE, 0, 1, 1); | |
153 | if (DllpExpectDataStructSemaphore == 0) | |
154 | PCIEX_QR_ERR( "%s %s-> Allocation of DllpExpectDataStructSemaphore Failed.", | |
155 | XactorName ); | |
156 | ||
157 | DllpXExpectDataStructSemaphore = alloc(SEMAPHORE, 0, 1, 1); | |
158 | if (DllpXExpectDataStructSemaphore == 0) | |
159 | PCIEX_QR_ERR( "%s %s-> Allocation of DllpXExpectDataStructSemaphore Failed.", | |
160 | XactorName ); | |
161 | ||
162 | fork { | |
163 | DllpExpectConsumer(); | |
164 | } | |
165 | { | |
166 | RetryExpectIssuer(); | |
167 | } join none | |
168 | } | |
169 | ||
170 | task FNXPCIEXactorManager::DllpExpectConsumer() | |
171 | { | |
172 | bit Success, SuccessWildcard; | |
173 | string MethodName = "DllpExpectConsumer"; | |
174 | ||
175 | // Main DLLP Expect Consumer loop | |
176 | while (1) { | |
177 | ||
178 | // Wait for another transaction coming from the Signal Interface | |
179 | void = mailbox_get(WAIT, DllpExpectFifo, SampledPkt); | |
180 | ||
181 | // Check if sampled packet has undefined values | |
182 | if (SampledPkt.PktUndef()) | |
183 | SampledPkt.PktDisplay( RTYP_XACTOR_FMWORK_SAMPLED_X_ERR, | |
184 | psprintf("at time %d, %s %s -> X Values Detected in Xaction Driven by DUT", get_time(LO), PCIEX_QR_PREFIX, XactorName )); | |
185 | ||
186 | // Stop the DLLP Expect Consumer if the Transactor is Disabled | |
187 | if (_XactorCtrl.GetDisableFlag()) | |
188 | sync(ANY, _XactorCtrl.GetEnableEvent()); | |
189 | ||
190 | // Trigger the event for a new transaction | |
191 | trigger(ONE_BLAST, NewTransaction); | |
192 | trigger(ONE_BLAST, eNewDLLPXaction ); | |
193 | ||
194 | Success = 1'b0; | |
195 | SuccessWildcard = 1'b0; | |
196 | fork { | |
197 | RemoveDllpExpect(SampledPkt, Success); | |
198 | } | |
199 | { | |
200 | RemoveDllpXExpect(SampledPkt, SuccessWildcard); | |
201 | } join all | |
202 | ||
203 | if (SuccessWildcard || Success) | |
204 | SampledPkt.PktDisplay( RTYP_FNX_PCIE_XTR_DEBUG_1, psprintf("%s %s -> Match Found, Pending Expect Removed", PCIEX_QR_PREFIX, XactorName )); | |
205 | // else | |
206 | // Unexpected DLLPs Are Allowed Hence Not Unexpected Transaction Error Is Thrown Here | |
207 | } // while (1) | |
208 | } | |
209 | ||
210 | task FNXPCIEXactorManager::ExpectConsumer() | |
211 | { | |
212 | bit Success, SuccessWildcard; | |
213 | string MethodName = "ExpectConsumer"; | |
214 | ReportType rptType; | |
215 | ||
216 | // Main TLP Expect Consumer loop | |
217 | while (1) { | |
218 | ||
219 | // Wait for another transaction coming from the Signal Interface | |
220 | void = mailbox_get(WAIT, ExpectFifo, SampledPkt); | |
221 | ||
222 | // Check if sampled packet has undefined values | |
223 | if (SampledPkt.PktUndef()) | |
224 | SampledPkt.PktDisplay( RTYP_XACTOR_FMWORK_SAMPLED_X_ERR, | |
225 | psprintf("%s %s -> X Values Detected in Xaction Driven by DUT", PCIEX_QR_PREFIX, XactorName )); | |
226 | ||
227 | // Stop the Expect Consumer if the transactor was disabled | |
228 | if (_XactorCtrl.GetDisableFlag()) | |
229 | sync(ANY, _XactorCtrl.GetEnableEvent()); | |
230 | ||
231 | // Trigger the event for a new transaction | |
232 | trigger(ONE_BLAST, NewTransaction); | |
233 | trigger(ONE_BLAST, eNewTLPXaction ); | |
234 | ||
235 | if (ExpectsOn) { | |
236 | ||
237 | Success = 1'b0; | |
238 | SuccessWildcard = 1'b0; | |
239 | fork { | |
240 | RemoveExpect(SampledPkt, Success); | |
241 | } | |
242 | { | |
243 | RemoveXExpect(SampledPkt, SuccessWildcard); | |
244 | } | |
245 | join all | |
246 | ||
247 | if (SuccessWildcard || Success) { | |
248 | ||
249 | SampledPkt.PktDisplay( RTYP_DEBUG_1, psprintf("%s %s -> Match Found, Pending Expect Removed", PCIEX_QR_PREFIX, XactorName )); | |
250 | } | |
251 | else { | |
252 | // Handle Unexpected TLP | |
253 | if (UnexpectedTLPIsErr) { | |
254 | PCIEX_QR_I( "%s -> Unexpected Xaction Sampled, Dumping Expect Structure:", XactorName ); | |
255 | DumpExpects(); | |
256 | rptType = RTYP_XACTOR_FMWORK_UNEXPECTED_XACTION_ERR; | |
257 | } | |
258 | else | |
259 | rptType = RTYP_FNX_PCIE_XTR_INFO; | |
260 | SampledPkt.PktDisplay( rptType, psprintf("%s %s -> Sampled Unexpected Xaction", PCIEX_QR_PREFIX, XactorName )); | |
261 | } | |
262 | } | |
263 | } // while (1) | |
264 | } | |
265 | ||
266 | // This task will receive DrivenPkt and will wait D clock cycles before DrivenPkt is | |
267 | // scheduled for driving | |
268 | task FNXPCIEXactorManager::DrivePkt( XactorBasePacket DrivenPkt, | |
269 | integer D) | |
270 | { | |
271 | string MethodName = "DrivePkt"; | |
272 | FNXPCIEXactorPacket drivePkt; | |
273 | ||
274 | cast_assign( drivePkt, DrivenPkt ); | |
275 | ||
276 | // Wait D cycles before drivePkt is scheduled for driving | |
277 | repeat (D) @(posedge ClkPort.$XClk); | |
278 | ||
279 | // Wait if transactor was disabled | |
280 | if (_XactorCtrl.GetDisableFlag() === 1'b1) | |
281 | sync(ANY, _XactorCtrl.GetEnableEvent()); | |
282 | ||
283 | // Send drivePkt to the Signal Interface | |
284 | mailbox_put(DriveFifo, drivePkt); | |
285 | ||
286 | drivePkt.PktDisplay( RTYP_FNX_PCIE_XTR_DEBUG_3, psprintf("%s %s-> Drive Enqueued", PCIEX_QR_PREFIX, XactorName ) ); | |
287 | ||
288 | // Wait until the packet is complete driven on serial links | |
289 | drivePkt.SyncDriveEnd(); | |
290 | ||
291 | drivePkt.PktDisplay( RTYP_FNX_PCIE_XTR_INFO, psprintf("at time %d, %s %s-> Xaction Driven", get_time(LO), PCIEX_QR_PREFIX, XactorName ) ); | |
292 | } | |
293 | ||
294 | // Removes Packet from DllpExpectDataStruct if Present. Success is 1 if | |
295 | // Packet is removed without problems and 0 otherwise | |
296 | task FNXPCIEXactorManager::RemoveDllpExpect( XactorBasePacket Packet, | |
297 | var bit Success ) | |
298 | { | |
299 | string MethodName = "RemoveDllpExpect"; | |
300 | ||
301 | semaphore_get(WAIT, DllpExpectDataStructSemaphore, 1); | |
302 | if ((!(DllpExpectDataStruct.Empty())) && (!(Packet.PktUndef()))) | |
303 | DllpExpectDataStruct.Delete( Packet, Success ); | |
304 | else | |
305 | Success = 1'b0; | |
306 | semaphore_put(DllpExpectDataStructSemaphore, 1); | |
307 | ||
308 | if (Success) | |
309 | Packet.PktDisplay( RTYP_FNX_PCIE_XTR_DEBUG_2, psprintf( "%s %s-> Sampled Xaction Match Found in DllpExpectDataStructure", | |
310 | PCIEX_QR_PREFIX, XactorName ) ); | |
311 | else | |
312 | Packet.PktDisplay( RTYP_FNX_PCIE_XTR_DEBUG_2, psprintf( "%s %s-> Sampled Xaction Has No Match in DllpExpectDataStructure", | |
313 | PCIEX_QR_PREFIX, XactorName ) ); | |
314 | } | |
315 | ||
316 | // Same as RemoveDllpExpect, but it will remove Packet from the DllpXExpectDataStruct | |
317 | task FNXPCIEXactorManager::RemoveDllpXExpect( XactorBasePacket Packet, | |
318 | var bit Success ) | |
319 | { | |
320 | string MethodName = "RemoveDllpXExpect"; | |
321 | ||
322 | semaphore_get(WAIT, DllpXExpectDataStructSemaphore, 1); | |
323 | if (!(DllpXExpectDataStruct.Empty())) | |
324 | DllpXExpectDataStruct.WildCardDelete1( Packet, Success ); | |
325 | else | |
326 | Success = 1'b0; | |
327 | semaphore_put(DllpXExpectDataStructSemaphore, 1); | |
328 | ||
329 | if (Success) | |
330 | Packet.PktDisplay( RTYP_FNX_PCIE_XTR_DEBUG_2, | |
331 | psprintf( "%s %s-> Sampled Xaction Match Found in DllpXExpectDataStructure", | |
332 | PCIEX_QR_PREFIX, XactorName ) ); | |
333 | else | |
334 | Packet.PktDisplay( RTYP_FNX_PCIE_XTR_DEBUG_2, | |
335 | psprintf( "%s %s-> Sampled Xaction Has No Match in DllpXExpectDataStructure", | |
336 | PCIEX_QR_PREFIX, XactorName ) ); | |
337 | } | |
338 | ||
339 | // Removes Packet from DllpExpectDataStruct if Present. Success is 1 if | |
340 | // Packet is removed without problems and 0 otherwise | |
341 | task FNXPCIEXactorManager::RemoveDllpRefExpect( XactorBasePacket Packet, | |
342 | var bit Success ) | |
343 | { | |
344 | string MethodName = "RemoveDllpRefExpect"; | |
345 | ||
346 | semaphore_get(WAIT, DllpExpectDataStructSemaphore, 1); | |
347 | if ((!(DllpExpectDataStruct.Empty())) && (!(Packet.PktUndef()))) | |
348 | DllpExpectDataStruct.RefDelete( Packet, Success ); | |
349 | else | |
350 | Success = 1'b0; | |
351 | semaphore_put(DllpExpectDataStructSemaphore, 1); | |
352 | ||
353 | if (Success) | |
354 | Packet.PktDisplay( RTYP_FNX_PCIE_XTR_DEBUG_2, | |
355 | psprintf( "%s %s-> Removing Expect From DllpExpectDataStructure", | |
356 | PCIEX_QR_PREFIX, XactorName ) ); | |
357 | } | |
358 | ||
359 | // Same as RemoveDllpExpect, but it will remove Packet from the DllpXExpectDataStruct | |
360 | task FNXPCIEXactorManager::RemoveDllpRefXExpect( XactorBasePacket Packet, | |
361 | var bit Success ) | |
362 | { | |
363 | string MethodName = "RemoveDllpRefXExpect"; | |
364 | ||
365 | semaphore_get(WAIT, DllpXExpectDataStructSemaphore, 1); | |
366 | if (!(DllpXExpectDataStruct.Empty())) | |
367 | DllpXExpectDataStruct.WildCardDelete1( Packet, Success ); | |
368 | else | |
369 | Success = 1'b0; | |
370 | semaphore_put(DllpXExpectDataStructSemaphore, 1); | |
371 | ||
372 | if (Success) | |
373 | Packet.PktDisplay( RTYP_FNX_PCIE_XTR_DEBUG_2, | |
374 | psprintf( "%s %s-> Removing Expect From DllpXExpectDataStructure", | |
375 | PCIEX_QR_PREFIX, XactorName ) ); | |
376 | } | |
377 | ||
378 | task FNXPCIEXactorManager::ExpectPkt( XactorBasePacket ExpectedPkt, | |
379 | integer Window, | |
380 | var bit [1:0] Status ) | |
381 | { | |
382 | FNXPCIEXactorPacket fnxExpectedPkt; | |
383 | bit SuccessWildcard = 1'b0; | |
384 | bit Success = 1'b0; | |
385 | event RemoveEvents[XACT_EXPECT_DATA_STRUCT_REMOVE_EVENTS]; | |
386 | ||
387 | cast_assign( fnxExpectedPkt, ExpectedPkt ); | |
388 | ||
389 | Status = 2'b00; | |
390 | ||
391 | /////////////////////////////////////////////////////////// | |
392 | // Begin -> Handle TLP Expects | |
393 | // | |
394 | if (fnxExpectedPkt.isTlp()) { | |
395 | ||
396 | if (fnxExpectedPkt.PktUndef()) { | |
397 | semaphore_get(WAIT, _XactorCtrl.XExpectDataStructSemaphore, 1); | |
398 | XExpectDataStruct.Insert(fnxExpectedPkt, RemoveEvents); | |
399 | semaphore_put(_XactorCtrl.XExpectDataStructSemaphore, 1); | |
400 | } | |
401 | else { | |
402 | semaphore_get(WAIT, _XactorCtrl.ExpectDataStructSemaphore, 1); | |
403 | ExpectDataStruct.Insert(fnxExpectedPkt, RemoveEvents); | |
404 | semaphore_put(_XactorCtrl.ExpectDataStructSemaphore, 1); | |
405 | } | |
406 | ||
407 | // nasty race condition | |
408 | repeat (2) | |
409 | @(negedge ClkPort.$XClk); | |
410 | ||
411 | // Wait until the expect is satisfied or it times out. | |
412 | while (!Status[1] && Window) { | |
413 | if (_XactorCtrl.GetDisableFlag() === 1'b1) | |
414 | sync(ANY, _XactorCtrl.GetEnableEvent()); | |
415 | if (sync(CHECK, RemoveEvents[XACT_COMP_EXPECT_REMOVED_EVENT])) { | |
416 | Status[1] = 1'b1; | |
417 | } | |
418 | ||
419 | if( !disablteTlpExpectTimeout ){ | |
420 | Window--; | |
421 | } | |
422 | if (!Status[1]) | |
423 | @(negedge ClkPort.$XClk); | |
424 | } | |
425 | ||
426 | if (Status[1] !== 1'b1) { | |
427 | fork { | |
428 | RemoveRefExpect(fnxExpectedPkt, Success); | |
429 | } | |
430 | { | |
431 | RemoveRefXExpect(fnxExpectedPkt, SuccessWildcard); | |
432 | } join all | |
433 | Status[0] = 1'b0; // Expect timedout and is removed by transactor | |
434 | } | |
435 | else { | |
436 | if (sync(CHECK, RemoveEvents[XACT_COMP_EXPECT_REMOVED_BY_XACTOR_EVENT])) | |
437 | Status[0] = 1'b0; | |
438 | else if (sync(CHECK, RemoveEvents[XACT_COMP_EXPECT_REMOVED_BY_USER_EVENT])) | |
439 | Status[0] = 1'b1; | |
440 | } | |
441 | } | |
442 | // End -> Handle TLP Expects | |
443 | /////////////////////////////////////////////////////////// | |
444 | ||
445 | /////////////////////////////////////////////////////////// | |
446 | // Begin -> Handle DLLP Expects | |
447 | // | |
448 | if (fnxExpectedPkt.isDllp()) { | |
449 | ||
450 | if (fnxExpectedPkt.PktUndef()) { | |
451 | semaphore_get(WAIT, DllpXExpectDataStructSemaphore, 1); | |
452 | DllpXExpectDataStruct.Insert(fnxExpectedPkt, RemoveEvents); | |
453 | semaphore_put(DllpXExpectDataStructSemaphore, 1); | |
454 | } | |
455 | else { | |
456 | semaphore_get(WAIT, DllpExpectDataStructSemaphore, 1); | |
457 | ExpectDataStruct.Insert(fnxExpectedPkt, RemoveEvents); | |
458 | semaphore_put(DllpExpectDataStructSemaphore, 1); | |
459 | } | |
460 | ||
461 | // nasty race condition | |
462 | repeat (2) | |
463 | @(negedge ClkPort.$XClk); | |
464 | ||
465 | // Wait until the expect is satisfied or it times out. | |
466 | while (!Status[1] && Window) { | |
467 | if (_XactorCtrl.GetDisableFlag() === 1'b1) | |
468 | sync(ANY, _XactorCtrl.GetEnableEvent()); | |
469 | if (sync(CHECK, RemoveEvents[XACT_COMP_EXPECT_REMOVED_EVENT])) { | |
470 | Status[1] = 1'b1; | |
471 | } | |
472 | ||
473 | Window--; | |
474 | if (!Status[1]) | |
475 | @(negedge ClkPort.$XClk); | |
476 | } | |
477 | ||
478 | if (Status[1] !== 1'b1) { | |
479 | fork { | |
480 | RemoveDllpRefExpect(fnxExpectedPkt, Success); | |
481 | } | |
482 | { | |
483 | RemoveDllpRefXExpect(fnxExpectedPkt, SuccessWildcard); | |
484 | } join all | |
485 | Status[0] = 1'b0; // Expect timedout and is removed by transactor | |
486 | } | |
487 | else { | |
488 | if (sync(CHECK, RemoveEvents[XACT_COMP_EXPECT_REMOVED_BY_XACTOR_EVENT])) | |
489 | Status[0] = 1'b0; | |
490 | else if (sync(CHECK, RemoveEvents[XACT_COMP_EXPECT_REMOVED_BY_USER_EVENT])) | |
491 | Status[0] = 1'b1; | |
492 | } | |
493 | } | |
494 | // End -> Handle DLLP Expects | |
495 | /////////////////////////////////////////////////////////// | |
496 | } | |
497 | ||
498 | task FNXPCIEXactorManager::RetryExpectIssuer() | |
499 | { | |
500 | FNXPCIEXactorPacket retryPkt; | |
501 | bit [1:0] status; | |
502 | ||
503 | while (1) { | |
504 | ||
505 | // Wait For Retry Packet To Come From Signal Interface (Denali retry_buffer_exit Callback) | |
506 | void = mailbox_get(WAIT, RetryPktFifo, retryPkt); | |
507 | ||
508 | retryPkt.PktDisplay( RTYP_FNX_PCIE_XTR_INFO, psprintf( "%s %s-> Launching Expect (Replay)", PCIEX_QR_PREFIX, XactorName ) ); | |
509 | ||
510 | // Stop the Retry Expect Issuer if the Transactor is Disabled | |
511 | if (_XactorCtrl.GetDisableFlag()) | |
512 | sync(ANY, _XactorCtrl.GetEnableEvent()); | |
513 | ||
514 | // [review jbanta 10/13/03] What should window for replay packet expects be? | |
515 | // [review jbanta 10/13/03] Setting it to 1000 for now | |
516 | // Block Until Retry Expect is Satisfied (No Need to Fork as Retries Should Happen in Order) | |
517 | ExpectPkt( retryPkt, 1000, status ); | |
518 | ||
519 | if ( status === 2'b10 ) { // Expect removed by transactor | |
520 | retryPkt.PktDisplay( RTYP_FNX_PCIE_XTR_INFO, psprintf("%s %s -> Expect Satisfied (Replay)", PCIEX_QR_PREFIX, XactorName ) ); | |
521 | } | |
522 | else { // Expect removed by user | |
523 | if ( status === 2'b11 ) | |
524 | retryPkt.PktDisplay( RTYP_XACTOR_FMWORK_EXPECT_REMOVED_BY_USER, | |
525 | psprintf("%s %s -> Expect Removed by User (Replay)", PCIEX_QR_PREFIX, XactorName ) ); | |
526 | else // Expect timeout | |
527 | retryPkt.PktDisplay( RTYP_XACTOR_FMWORK_EXPECT_TIMEOUT_ERR, | |
528 | psprintf("%s %s -> Expect Expired (Replay)", PCIEX_QR_PREFIX, XactorName ) ); | |
529 | } | |
530 | } | |
531 | } | |
532 | ||
533 | task FNXPCIEXactorManager::SampleTlpPkt( XactorBasePacket Pkt, | |
534 | integer Window ) | |
535 | { | |
536 | string MethodName = "SampleTlpPkt"; | |
537 | bit Success = 0; | |
538 | ||
539 | fork { | |
540 | sync(ANY, eNewTLPXaction); | |
541 | Pkt.PktCopy(SampledPkt); | |
542 | Success = 1'b1; | |
543 | } | |
544 | { | |
545 | while (Window && !Success) { | |
546 | Window--; | |
547 | @(negedge ClkPort.$XClk); | |
548 | } | |
549 | if (!Success) | |
550 | PCIEX_QR_ERR( "%s-> Timeout. No TLP received from the DUT.", XactorName ); | |
551 | else | |
552 | Pkt.PktDisplay( RTYP_INFO, psprintf("%s %s -> Transaction Sampled", PCIEX_QR_PREFIX, XactorName ) ); | |
553 | } | |
554 | join any | |
555 | } | |
556 | ||
557 | task FNXPCIEXactorManager::SampleDllpPkt( XactorBasePacket Pkt, | |
558 | integer Window ) | |
559 | { | |
560 | string MethodName = "SampleDllpPkt"; | |
561 | bit Success = 0; | |
562 | ||
563 | fork { | |
564 | sync(ANY, eNewDLLPXaction); | |
565 | Pkt.PktCopy(SampledPkt); | |
566 | Success = 1'b1; | |
567 | } | |
568 | { | |
569 | while (Window && !Success) { | |
570 | Window--; | |
571 | @(negedge ClkPort.$XClk); | |
572 | } | |
573 | if (!Success) | |
574 | PCIEX_QR_ERR( "%s-> Timeout. No DLLP received from the DUT.", XactorName ); | |
575 | else | |
576 | Pkt.PktDisplay( RTYP_INFO, psprintf("%s %s -> Transaction Sampled", PCIEX_QR_PREFIX, XactorName ) ); | |
577 | } | |
578 | join any | |
579 | } | |
580 | ||
581 | // Returns 1 if the expect with the value in ExpectedPacket is removed successfully and 0 otherwise | |
582 | function bit FNXPCIEXactorManager::Remove(XactorBasePacket ExpectedPacket) | |
583 | { | |
584 | FNXPCIEXactorPacket fnxExpectedPkt; | |
585 | bit SuccessWildcard = 1'b0; | |
586 | bit Success = 1'b0; | |
587 | ||
588 | cast_assign( fnxExpectedPkt, ExpectedPacket ); | |
589 | ||
590 | if (fnxExpectedPkt.isTlp()) { | |
591 | RemoveRefExpect(ExpectedPacket, Success); | |
592 | RemoveRefXExpect(ExpectedPacket, SuccessWildcard); | |
593 | } | |
594 | ||
595 | if (fnxExpectedPkt.isDllp()) { | |
596 | RemoveDllpRefExpect(ExpectedPacket, Success); | |
597 | RemoveDllpRefXExpect(ExpectedPacket, SuccessWildcard); | |
598 | } | |
599 | ||
600 | Remove = Success | SuccessWildcard; | |
601 | } | |
602 | ||
603 | task FNXPCIEXactorManager::DumpExpects() { | |
604 | string MethodName = "DumpExpects"; | |
605 | ||
606 | // TLP Expects | |
607 | semaphore_get(WAIT, _XactorCtrl.ExpectDataStructSemaphore, 1); | |
608 | PCIEX_QR_I( "%s -> Dumping TLP Expect Structure:", XactorName ); | |
609 | ExpectDataStruct.PrintNodes(); | |
610 | semaphore_put(_XactorCtrl.ExpectDataStructSemaphore, 1); | |
611 | ||
612 | // TLP XExpects | |
613 | semaphore_get(WAIT, _XactorCtrl.XExpectDataStructSemaphore, 1); | |
614 | PCIEX_QR_I( "%s -> Dumping TLP Wilcard Expect Structure:", XactorName ); | |
615 | XExpectDataStruct.PrintNodes(); | |
616 | semaphore_put(_XactorCtrl.XExpectDataStructSemaphore, 1); | |
617 | ||
618 | // DLLP Expects | |
619 | semaphore_get(WAIT, DllpExpectDataStructSemaphore, 1); | |
620 | PCIEX_QR_I( "%s -> Dumping DLLP Expect Structure:", XactorName ); | |
621 | DllpExpectDataStruct.PrintNodes(); | |
622 | semaphore_put(DllpExpectDataStructSemaphore, 1); | |
623 | ||
624 | // DLLP XExpects | |
625 | semaphore_get(WAIT, DllpXExpectDataStructSemaphore, 1); | |
626 | PCIEX_QR_I( "%s -> Dumping DLLP Wilcard Expect Structure:", XactorName ); | |
627 | DllpXExpectDataStruct.PrintNodes(); | |
628 | semaphore_put(DllpXExpectDataStructSemaphore, 1); | |
629 | } | |
630 | ||
631 | function integer FNXPCIEXactorManager::NumExpects() | |
632 | { | |
633 | NumExpects = NumTlpExpects() + NumDllpExpects(); | |
634 | } | |
635 | ||
636 | function integer FNXPCIEXactorManager::NumTlpExpects() | |
637 | { | |
638 | // NOTE: TLP Expects Are Stored in ExpectDataStruct and XExpectDataStruct | |
639 | // Structures Present in Base XactorManger class, hence super.NumExpects | |
640 | // Returns Numberof TLP Expects Outstanding | |
641 | NumTlpExpects = super.NumExpects(); | |
642 | } | |
643 | ||
644 | function integer FNXPCIEXactorManager::NumDllpExpects() | |
645 | { | |
646 | NumDllpExpects = 0; | |
647 | ||
648 | // First count the expects pending in the DLLP expect data structure | |
649 | semaphore_get(WAIT, DllpExpectDataStructSemaphore, 1); | |
650 | NumDllpExpects = DllpExpectDataStruct.CountNodes(); | |
651 | semaphore_put(DllpExpectDataStructSemaphore, 1); | |
652 | ||
653 | // Then add the expects pending in the DLLP wildcard expect data structure | |
654 | semaphore_get(WAIT, DllpXExpectDataStructSemaphore, 1); | |
655 | NumDllpExpects += DllpXExpectDataStruct.CountNodes(); | |
656 | semaphore_put(DllpXExpectDataStructSemaphore, 1); | |
657 | } | |
658 | ||
659 | function bit FNXPCIEXactorManager::ExpectPending(XactorBasePacket ExpectedPacket) | |
660 | { | |
661 | bit dllpExpectPendingBit = 1'b0; | |
662 | bit dllpXExpectPendingBit = 1'b0; | |
663 | ||
664 | // First check if the expect is pending in the main expect data structure | |
665 | semaphore_get(WAIT, DllpExpectDataStructSemaphore, 1); | |
666 | if ((!(DllpExpectDataStruct.Empty())) && (!ExpectedPacket.PktUndef())) | |
667 | dllpExpectPendingBit = DllpExpectDataStruct.InStructure(ExpectedPacket); | |
668 | semaphore_put(DllpExpectDataStructSemaphore, 1); | |
669 | ||
670 | // Then check if the expect is in the expect data structure with "wildcards" | |
671 | semaphore_get(WAIT, DllpXExpectDataStructSemaphore, 1); | |
672 | if ((!(DllpXExpectDataStruct.Empty())) && (ExpectedPacket.PktUndef())) | |
673 | dllpXExpectPendingBit = DllpXExpectDataStruct.InStructure(ExpectedPacket); | |
674 | semaphore_put(DllpXExpectDataStructSemaphore, 1); | |
675 | ||
676 | // NOTE: TLP Expects Are Stored in ExpectDataStruct and XExpectDataStruct | |
677 | // Structures Present in Base XactorManger class, hence super.ExpectPending() | |
678 | // Checks For Packet Presence in TLP Data Structures | |
679 | ExpectPending = super.ExpectPending(ExpectedPacket) | dllpExpectPendingBit | dllpXExpectPendingBit; | |
680 | } |