Initial commit of OpenSPARC T2 design and verification files.
[OpenSPARC-T2-DV] / verif / env / fnx / vlib / XactorComponents / src / XactorManager.vr
CommitLineData
86530b38
AT
1// ========== Copyright Header Begin ==========================================
2//
3// OpenSPARC T2 Processor File: XactorManager.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 "XactorCtrl.vrh"
37#include "XactorUtilities.vrh"
38#include "XactorClk.port.vri"
39#include "XactorComponentsDefines.vri"
40
41#include "XactorDefines.vri"
42#include "XactorBasePacket.vrh"
43#include "XactorBaseManager.vrh"
44#include "XactorBaseExpectDataStruct.vrh"
45#include "XactorBaseBuilder.vrh"
46
47#include "cReport.vrh"
48
49class XactorManager extends XactorBaseManager {
50
51 // ++++++++ Expect Manager properties ++++++++
52 // This is the Fifo structure where expected packets from the signal
53 // interface are received (a mailbox is used).
54 integer ExpectFifo;
55 // Expect Data Structures are defined in XactorBaseManager
56
57 // ++++++++ Drive Manager properties ++++++++
58 // This is the Fifo structure where packets to be driven to the signal
59 // interface are sent (a mailbox is used).
60 integer DriveFifo;
61 // This semaphore is used to schedule requests to drive packets
62 protected integer DriverSemaphore;
63
64 // Enable/Disable/Reset Transactor property
65 XactorCtrl _XactorCtrl;
66
67 // +++++++ Sample transaction properties ++++++++
68 // this packet is used to store the values of transactions coming from the
69 // signal interface
70 protected XactorBasePacket SampledPkt;
71 // this event is triggered when sample flag is set and a new transaction
72 // was sampled from the DUT
73 protected event NewTransaction;
74
75 // Transactor name
76 protected string XactorName;
77
78 // Transactor clock port
79 protected XactorClk ClkPort;
80
81 // MyReport declared in XactorBaseManager
82
83 task new (XactorBaseBuilder Builder,
84 XactorClk _ClkPort
85 );
86
87 // --------------------------------------------------------------------------
88 // Expect and Drive Manager methods
89 // --------------------------------------------------------------------------
90 // Prints out pending expects. A packet has to be passed, since data structures
91 // store values in a "compressed way" and packets know how to decode that
92 // information
93 virtual task DumpExpects();
94
95 // Returns 1 if an expect with the value ExpectedPacket is pending and 0 otherwise
96 virtual function bit ExpectPending(XactorBasePacket ExpectedPacket);
97
98 // Returns 1 if the expect with the value in ExpectedPacket is removed successfully
99 // and 0 otherwise
100 virtual function bit Remove(XactorBasePacket ExpectedPacket);
101
102 // Returns the number of pending expects in all the data structures
103 // of the transactor
104 virtual function integer NumExpects();
105
106 // Removes Packet from ExpectDataStruct. Success is 1 if
107 // Packet is removed without problems and 0 otherwise
108 virtual protected task RemoveExpect(XactorBasePacket Packet,
109 var bit Success
110 );
111
112 // Same as RemoveExpect, but it will remove Packet from the XExpectDataStruct
113 virtual protected task RemoveXExpect(XactorBasePacket Packet,
114 var bit Success
115 );
116
117 // Same as RemoveExpect, but it will remove Packet from the XExpectDataStruct
118 // Compared to RemoveXExpect, this task will call WildCardDelete1
119 virtual protected task RemoveRefExpect(XactorBasePacket Packet,
120 var bit Success
121 );
122
123 // Same as RemoveExpect, but it will remove Packet from the XExpectDataStruct
124 // Compared to RemoveXExpect, this task will call WildCardDelete1
125 virtual protected task RemoveRefXExpect(XactorBasePacket Packet,
126 var bit Success
127 );
128
129 // This task will wait for a maximum of Window cycles for the ExpectedPkt to be removed from
130 // the expect data structures. Removed is an event variable that is triggered when ExpectedPkt is
131 // removed. TransactionRemoved will be 1 if ExpectedPkt was removed and 0 otherwise. Id is the
132 // id number of the expect transaction.
133 virtual task ExpectPkt(XactorBasePacket ExpectedPkt,
134 integer Window,
135 var bit [1:0] Status
136 );
137
138 // This task will wait for the next transaction driven by the DUT, it will then sample it and
139 // will return the values through Pkt
140 virtual task SamplePkt(XactorBasePacket Pkt,
141 integer Window
142 );
143
144 // This task will be waiting for transactions coming from the DUT
145 // and match them with the pending list of expects (stored in the data structures)
146 virtual protected task ExpectConsumer();
147
148 // This task will receive DrivenPkt and will wait D clock cycles before DrivenPkt is
149 // scheduled for driving
150 virtual task DrivePkt(XactorBasePacket DrivenPkt, integer D);
151
152 // This task will disable the transactor
153 virtual task DisableManager();
154
155 // This task will enable the transactor
156 virtual task EnableManager();
157
158 // This task will flush the Drive Fifo
159 virtual protected task FlushDriveFifo();
160
161 // This task will reset the transactor
162 virtual task ResetManager();
163
164}
165
166 ////////////////
167 // Definitions
168////////////////
169
170task XactorManager::new (XactorBaseBuilder Builder,
171 XactorClk _ClkPort
172 ) {
173 // ++++++++ Expect Manager Initialization ++++++++
174 // The Builder object will be in charge of creating the proper type of
175 // objects for each property handle of this class.
176 XactorName = Builder.CreateName();
177 ExpectDataStruct = Builder.CreateExpectDataStruct();
178 XExpectDataStruct = Builder.CreateXExpectDataStruct();
179 MyReport = Builder.CreateReport();
180 ExpectFifo = alloc(MAILBOX, 0, 1);
181 if(ExpectFifo == 0) {
182 MyReport.report(RTYP_XACTOR_FMWORK_MEM_ALLOCATION_ERROR,
183 "$0s: Failed to allocate ExpectFifo mailbox!!",
184 XactorName);
185 }
186 ClkPort = _ClkPort;
187
188 fork {
189 ExpectConsumer();
190 }
191 join none
192
193 // ++++++++ Drive Manager initialization +++++++++
194 DriveFifo = alloc(MAILBOX, 0, 1);
195 if(DriveFifo == 0) {
196 MyReport.report(RTYP_XACTOR_FMWORK_MEM_ALLOCATION_ERROR,
197 "$0s: Failed to allocate DriveFifo mailbox!!",
198 XactorName);
199 }
200 DriverSemaphore = alloc(SEMAPHORE, 0, 1, 1);
201 if(DriverSemaphore == 0) {
202 MyReport.report(RTYP_XACTOR_FMWORK_MEM_ALLOCATION_ERROR,
203 "$0s: Failed to allocate DriverSemaphore semaphore!!",
204 XactorName);
205 }
206
207 // ++++++++ General properties initialization ++++++++++
208 _XactorCtrl = new(Builder);
209}
210
211// --------------------------------------------------------------------------
212// Expect and Drive Manager methods
213// --------------------------------------------------------------------------
214// Prints out pending expects. A packet has to be passed, since data structures
215// store values in a "compressed way" and packets know how to decode that
216// information
217task XactorManager::DumpExpects() {
218
219 // First print nodes from the main expect data structure
220 semaphore_get(WAIT, _XactorCtrl.ExpectDataStructSemaphore, 1);
221 MyReport.report(RTYP_INFO, "XactorManager::DumpExpects(): Dumping Expect Structure:\n");
222 ExpectDataStruct.PrintNodes();
223 semaphore_put(_XactorCtrl.ExpectDataStructSemaphore, 1);
224
225 // Then print nodes from the expect data structure that was nodes
226 // with "wildcard" values (X's)
227 semaphore_get(WAIT, _XactorCtrl.XExpectDataStructSemaphore, 1);
228 MyReport.report(RTYP_INFO, "XactorManager::DumpExpects(): Dumping Wildcard Expect Structure:\n");
229 XExpectDataStruct.PrintNodes();
230 semaphore_put(_XactorCtrl.XExpectDataStructSemaphore, 1);
231}
232
233// Returns 1 if an expect with the value ExpectedPacket is pending and 0 otherwise
234function bit XactorManager::ExpectPending(XactorBasePacket ExpectedPacket) {
235 bit ExpectPendingBit = 1'b0;
236 bit XExpectPendingBit = 1'b0;
237
238 // First check if the expect is pending in the main expect data structure
239 semaphore_get(WAIT, _XactorCtrl.ExpectDataStructSemaphore, 1);
240 if((!(ExpectDataStruct.Empty())) && (!ExpectedPacket.PktUndef()))
241 ExpectPendingBit = ExpectDataStruct.InStructure(ExpectedPacket);
242 semaphore_put(_XactorCtrl.ExpectDataStructSemaphore, 1);
243
244 // Then check if the expect is in the expect data structure with "wildcards"
245 semaphore_get(WAIT, _XactorCtrl.XExpectDataStructSemaphore, 1);
246 if((!(XExpectDataStruct.Empty())) && (ExpectedPacket.PktUndef()))
247 XExpectPendingBit = XExpectDataStruct.InStructure(ExpectedPacket);
248 semaphore_put(_XactorCtrl.XExpectDataStructSemaphore, 1);
249
250 ExpectPending = ExpectPendingBit | XExpectPendingBit;
251}
252
253// Returns 1 if the expect with the value in ExpectedPacket is removed successfully
254// and 0 otherwise
255function bit XactorManager::Remove(XactorBasePacket ExpectedPacket) {
256 // Success flags when an expect transaction is removed from a data
257 // structure.
258 bit SuccessWildcard = 1'b0;
259 bit Success = 1'b0;
260
261 // First check if the expect is pending in the main expect data structure
262 RemoveRefExpect(ExpectedPacket, Success);
263 // Then check if the expect is in the expect data structure with "wildcards"
264 RemoveRefXExpect(ExpectedPacket, SuccessWildcard);
265
266 Remove = Success | SuccessWildcard;
267}
268
269// Returns the number of pending expects in all the data structures
270// of the transactor
271function integer XactorManager::NumExpects() {
272 integer Expects = 0;
273
274 // First count the expects pending in the main expect data structure
275 semaphore_get(WAIT, _XactorCtrl.ExpectDataStructSemaphore, 1);
276 Expects = ExpectDataStruct.CountNodes();
277 semaphore_put(_XactorCtrl.ExpectDataStructSemaphore, 1);
278
279 // Then count the expects pending in the expect data structure with "wildcards"
280 semaphore_get(WAIT, _XactorCtrl.XExpectDataStructSemaphore, 1);
281 Expects += XExpectDataStruct.CountNodes();
282 semaphore_put(_XactorCtrl.XExpectDataStructSemaphore, 1);
283
284 NumExpects = Expects;
285}
286
287// Removes Packet from ExpectDataStruct. Success is 1 if
288// Packet is removed without problems and 0 otherwise
289task XactorManager::RemoveExpect(XactorBasePacket Packet,
290 var bit Success
291 ) {
292
293 semaphore_get(WAIT, _XactorCtrl.ExpectDataStructSemaphore, 1);
294 if((!(ExpectDataStruct.Empty())) && (!(Packet.PktUndef()))) {
295 ExpectDataStruct.Delete(Packet,
296 Success
297 );
298 }
299 else
300 Success = 1'b0;
301 semaphore_put(_XactorCtrl.ExpectDataStructSemaphore, 1);
302
303 if (Success) {
304 Packet.PktDisplay(RTYP_DEBUG_2, "Sampled Transaction with match in ExpectDataSTtructure");
305 }
306 else {
307 Packet.PktDisplay(RTYP_DEBUG_2, "Sampled Transaction without match in ExpectDataStructure");
308 }
309}
310
311// Same as RemoveExpect, but it will remove Packet from the XExpectDataStruct
312task XactorManager::RemoveXExpect(XactorBasePacket Packet,
313 var bit Success
314 ) {
315
316 semaphore_get(WAIT, _XactorCtrl.XExpectDataStructSemaphore, 1);
317 if(!(XExpectDataStruct.Empty())) {
318 XExpectDataStruct.WildCardDelete1(Packet,
319 Success
320 );
321 }
322 else
323 Success = 1'b0;
324 semaphore_put(_XactorCtrl.XExpectDataStructSemaphore, 1);
325
326 if (Success) {
327 Packet.PktDisplay(RTYP_DEBUG_2, "Sampled Transaction with match in XExpectDataStructure");
328 }
329 else {
330 Packet.PktDisplay(RTYP_DEBUG_2, "Sampled Transaction without match in XExpectDataStructure");
331 }
332}
333
334// Same as RemoveExpect, but it will remove Packet from the XExpectDataStruct
335// Compared to RemoveXExpect, this task will call WildCardDelete1
336task XactorManager::RemoveRefExpect(XactorBasePacket Packet,
337 var bit Success
338 ) {
339
340 semaphore_get(WAIT, _XactorCtrl.ExpectDataStructSemaphore, 1);
341 if((!(ExpectDataStruct.Empty())) && (!Packet.PktUndef())) {
342 ExpectDataStruct.RefDelete(Packet,
343 Success
344 );
345 }
346 else
347 Success = 1'b0;
348 semaphore_put(_XactorCtrl.ExpectDataStructSemaphore, 1);
349
350 if (Success) {
351 Packet.PktDisplay(RTYP_DEBUG_2, "%0s: Removing expect from Expect Data Structure");
352 }
353 else {
354 Packet.PktDisplay(RTYP_DEBUG_2, "%0s: Removing expect from Expect Data Structure");
355 }
356}
357
358// Same as RemoveExpect, but it will remove Packet from the XExpectDataStruct
359// Compared to RemoveXExpect, this task will call WildCardDelete1
360task XactorManager::RemoveRefXExpect(XactorBasePacket Packet,
361 var bit Success
362 ) {
363
364 semaphore_get(WAIT, _XactorCtrl.XExpectDataStructSemaphore, 1);
365 if((!(XExpectDataStruct.Empty())) && (Packet.PktUndef())) {
366 XExpectDataStruct.RefDelete(Packet,
367 Success
368 );
369 }
370 else
371 Success = 1'b0;
372 semaphore_put(_XactorCtrl.XExpectDataStructSemaphore, 1);
373
374 if (Success) {
375 Packet.PktDisplay(RTYP_DEBUG_2, "%0s: Removing expect from XExpect Data Structure");
376 }
377 else {
378 Packet.PktDisplay(RTYP_DEBUG_2, "%0s: Removing expect from XExpect Data Structure");
379 }
380}
381
382// This task will wait for a maximum of Window cycles for the ExpectedPkt to be removed from
383// the expect data structures. Removed is an event variable that is triggered when ExpectedPkt is
384// removed. TransactionRemoved will be 1 if ExpectedPkt was removed and 0 otherwise. Id is the
385// id number of the expect transaction.
386task XactorManager::ExpectPkt(XactorBasePacket ExpectedPkt,
387 integer Window,
388 var bit [1:0] Status
389 ) {
390 // Success flags when an expect transaction is removed from a data
391 // structure.
392 bit SuccessWildcard = 1'b0;
393 bit Success = 1'b0;
394 // Events used when an expect is removed
395 event RemoveEvents[XACT_EXPECT_DATA_STRUCT_REMOVE_EVENTS];
396
397 Status = 2'b00; // Status[1] = 1'b0 Expect not removed
398 // Status[1] = 1'b1 Expect removed
399 // Status[0] = 1'b0 Expect removed by transactor
400 // Status[0] = 1'b1 Expect removed by user
401
402 // Check if the Expected value has "wildcards" or if it only has
403 // valid bits (0's and 1's) and store in the corresponding expect
404 // data structure.
405 if(ExpectedPkt.PktUndef()) {
406 semaphore_get(WAIT, _XactorCtrl.XExpectDataStructSemaphore, 1);
407 XExpectDataStruct.Insert(ExpectedPkt, RemoveEvents);
408 semaphore_put(_XactorCtrl.XExpectDataStructSemaphore, 1);
409 }
410 else {
411 semaphore_get(WAIT, _XactorCtrl.ExpectDataStructSemaphore, 1);
412 ExpectDataStruct.Insert(ExpectedPkt, RemoveEvents);
413 semaphore_put(_XactorCtrl.ExpectDataStructSemaphore, 1);
414 }
415
416 // Synchronize the waiting cycle to the negative edge of the clock
417 // Two negedges have to pass to start the while loop. This restricts
418 // the minimum value of the expect Window to 1 cycle. A Window with
419 // a value of 0 is not possible since race conditions would make
420 // the code execution unpredictable.
421 repeat(2)
422 @(negedge ClkPort.$XClk);
423
424 // Wait until the expect is satisfied or it times out.
425 while (!Status[1] && Window) {
426 if(_XactorCtrl.GetDisableFlag() === 1'b1)
427 sync(ANY, _XactorCtrl.GetEnableEvent());
428 if (sync(CHECK, RemoveEvents[XACT_COMP_EXPECT_REMOVED_EVENT])) {
429 Status[1] = 1'b1;
430 }
431
432 Window--;
433 if(!Status[1])
434 @(negedge ClkPort.$XClk);
435 }
436
437 // If the pending expect transaction was not removed and it has already
438 // timed out, then there is no need for it to stay in any of the expect
439 // data structures.
440 if(Status[1] !== 1'b1) {
441 fork {
442 // Check if the Expected value has "wildcards". If it does, do not
443 // try to delete from this data structure
444 RemoveRefExpect(ExpectedPkt, Success);
445 }
446 {
447 // Check if the Expected value has "wildcards". If it does, try to
448 // delete from this data structure
449 RemoveRefXExpect(ExpectedPkt, SuccessWildcard);
450 }
451 join all
452
453 Status[0] = 1'b0; // Expect timedout and is removed by transactor
454 }
455 else {
456 // Copy all the fields for the sampled transaction, if "wildcards' are used
457 // NOTE: this is done within the data structures. Look for WildCardDelete1() method.
458// if(ExpectedPkt.PktUndef()) {
459// ExpectedPkt.PktCopy(SampledPkt);
460// }
461
462 // Check who removed the expect, the transactor through the ExpectConsumer() or
463 // the user through Remove() or Reset(). If both tried to remove the expect, give
464 // priority to the transactor.
465 if (sync(CHECK, RemoveEvents[XACT_COMP_EXPECT_REMOVED_BY_XACTOR_EVENT])) {
466 Status[0] = 1'b0;
467 }
468 else if (sync(CHECK, RemoveEvents[XACT_COMP_EXPECT_REMOVED_BY_USER_EVENT])) {
469 Status[0] = 1'b1;
470 }
471 }
472}
473
474// This task will wait for the next transaction driven by the DUT, it will then sample it and
475// will return the values through Pkt
476// The transactor timesout when the DUT hasn't driven any transaction in "Window" cycles.
477task XactorManager::SamplePkt(XactorBasePacket Pkt,
478 integer Window
479 ) {
480
481 // This is a flag that is set when a new transaction is sampled
482 bit Success = 0;
483
484 fork {
485 sync(ANY, NewTransaction);
486 Pkt.PktCopy(SampledPkt);
487 Success = 1'b1;
488 }
489 {
490 while(Window && !Success) {
491 Window--;
492 @(negedge ClkPort.$XClk);
493 }
494 if(!Success) {
495 MyReport.report(RTYP_XACTOR_FMWORK_SAMPLE_TIMEOUT_ERR,
496 "%0s: Timeout waiting for the next transaction from the DUT",
497 XactorName);
498 }
499 else
500 Pkt.PktDisplay(RTYP_INFO, "Transaction Sampled");
501 }
502 join any
503}
504
505// This task will be waiting for transactions coming from the DUT
506// and match them with the pending list of expects (stored in the data structures)
507task XactorManager::ExpectConsumer() {
508
509 // This is not really used, just to receive the returned value of
510 // mailbox_get
511 integer MailVar;
512 // Success flags when an expect transaction is removed from a data
513 // structure.
514 bit SuccessWildcard;
515 bit Success;
516
517 // Main Expect Consumer loop
518 while(1) {
519
520 // Wait for another transaction coming from the Signal Interface
521 MailVar = mailbox_get(WAIT, ExpectFifo, SampledPkt);
522
523 // Check if sampled packet has undefined values
524 if(SampledPkt.PktUndef()) {
525 SampledPkt.PktDisplay(RTYP_XACTOR_FMWORK_SAMPLED_X_ERR,
526 "X values detected in transaction driven by DUT");
527 }
528
529 // Stop the Expect Consumer if the transactor was disabled
530 if(_XactorCtrl.GetDisableFlag())
531 sync(ANY, _XactorCtrl.GetEnableEvent());
532
533 // Trigger the event for a new transaction
534 trigger(ONE_BLAST, NewTransaction);
535
536 Success = 1'b0;
537 SuccessWildcard = 1'b0;
538 fork {
539 RemoveExpect(SampledPkt, Success);
540 }
541 {
542 RemoveXExpect(SampledPkt, SuccessWildcard);
543 }
544 join all
545
546 if(SuccessWildcard || Success) {
547 SampledPkt.PktDisplay(RTYP_DEBUG_1, "Expect Consumer: Match found, pending Expect removed");
548 }
549 else {
550 MyReport.report(RTYP_INFO, "%0s: Dumping Expects since an unexpected transaction was sampled", XactorName);
551 DumpExpects();
552 SampledPkt.PktDisplay(RTYP_XACTOR_FMWORK_UNEXPECTED_XACTION_ERR, "Expect Consumer: Sampled unexpected transaction");
553 }
554 }
555}
556
557// This task will receive DrivenPkt and will wait D clock cycles before DrivenPkt is
558// scheduled for driving
559task XactorManager::DrivePkt(XactorBasePacket DrivenPkt, integer D) {
560 // Wait D cycles before DrivenPkt is scheduled for driving
561 repeat(D) @(posedge ClkPort.$XClk);
562 // Wait if transactor was disabled
563 if(_XactorCtrl.GetDisableFlag() === 1'b1)
564 sync(ANY, _XactorCtrl.GetEnableEvent());
565 // Send DrivenPkt to the Signal Interface
566 mailbox_put(DriveFifo, DrivenPkt);
567 // Wait until the packet is driven
568 DrivenPkt.SyncOnDrive();
569 DrivenPkt.PktDisplay(RTYP_DEBUG_1, "Driving Transaction");
570}
571
572// This task will disable the transactor
573task XactorManager::DisableManager() {
574 _XactorCtrl.SetDisableFlag(1'b1);
575}
576
577// This task will enable the transactor
578task XactorManager::EnableManager() {
579 _XactorCtrl.SetDisableFlag(1'b0);
580 trigger(ONE_BLAST, _XactorCtrl.GetEnableEvent());
581}
582
583// This task will flush the Drive Fifo
584task XactorManager::FlushDriveFifo() {
585 integer FifoCount;
586 XactorBasePacket JunkPacket;
587
588 FifoCount = mailbox_get(NO_WAIT, DriveFifo);
589 while(FifoCount > 0) {
590 FifoCount = mailbox_get(NO_WAIT, DriveFifo, JunkPacket);
591 }
592}
593
594// This task will reset the transactor
595task XactorManager::ResetManager() {
596 // Reset the two data structures and flush the Drive Fifo
597 fork {
598 semaphore_get(WAIT, _XactorCtrl.ExpectDataStructSemaphore, 1);
599 ExpectDataStruct.Reset();
600 semaphore_put(_XactorCtrl.ExpectDataStructSemaphore, 1);
601 }
602 {
603 semaphore_get(WAIT, _XactorCtrl.XExpectDataStructSemaphore, 1);
604 XExpectDataStruct.Reset();
605 semaphore_put(_XactorCtrl.XExpectDataStructSemaphore, 1);
606 }
607 {
608 semaphore_get(WAIT, _XactorCtrl.DriveFifoSemaphore, 1);
609 FlushDriveFifo();
610 semaphore_put(_XactorCtrl.DriveFifoSemaphore, 1);
611 }
612 join none
613}
614
615