lsq_unit_impl.hh (2674:6d4afef73a20) | lsq_unit_impl.hh (2678:1f86b91dc3bb) |
---|---|
1/* 2 * Copyright (c) 2004-2005 The Regents of The University of Michigan 3 * All rights reserved. 4 * 5 * Redistribution and use in source and binary forms, with or without 6 * modification, are permitted provided that the following conditions are 7 * met: redistributions of source code must retain the above copyright 8 * notice, this list of conditions and the following disclaimer; --- 18 unchanged lines hidden (view full) --- 27 */ 28 29#include "cpu/checker/cpu.hh" 30#include "cpu/o3/lsq_unit.hh" 31#include "base/str.hh" 32#include "mem/request.hh" 33 34template<class Impl> | 1/* 2 * Copyright (c) 2004-2005 The Regents of The University of Michigan 3 * All rights reserved. 4 * 5 * Redistribution and use in source and binary forms, with or without 6 * modification, are permitted provided that the following conditions are 7 * met: redistributions of source code must retain the above copyright 8 * notice, this list of conditions and the following disclaimer; --- 18 unchanged lines hidden (view full) --- 27 */ 28 29#include "cpu/checker/cpu.hh" 30#include "cpu/o3/lsq_unit.hh" 31#include "base/str.hh" 32#include "mem/request.hh" 33 34template<class Impl> |
35void 36LSQUnit<Impl>::completeDataAccess(PacketPtr pkt) | 35LSQUnit<Impl>::WritebackEvent::WritebackEvent(DynInstPtr &_inst, PacketPtr _pkt, 36 LSQUnit *lsq_ptr) 37 : Event(&mainEventQueue), inst(_inst), pkt(_pkt), lsqPtr(lsq_ptr) |
37{ | 38{ |
38/* 39 DPRINTF(IEW, "Load writeback event [sn:%lli]\n", inst->seqNum); 40 DPRINTF(Activity, "Activity: Ld Writeback event [sn:%lli]\n", inst->seqNum); | 39 this->setFlags(Event::AutoDelete); 40} |
41 | 41 |
42 //iewStage->ldstQueue.removeMSHR(inst->threadNumber,inst->seqNum); 43 44 if (iewStage->isSwitchedOut()) { 45 inst = NULL; 46 return; 47 } else if (inst->isSquashed()) { 48 iewStage->wakeCPU(); 49 inst = NULL; 50 return; | 42template<class Impl> 43void 44LSQUnit<Impl>::WritebackEvent::process() 45{ 46 if (!lsqPtr->isSwitchedOut()) { 47 lsqPtr->writeback(inst, pkt); |
51 } | 48 } |
49 delete pkt; 50} |
|
52 | 51 |
53 iewStage->wakeCPU(); 54 55 if (!inst->isExecuted()) { 56 inst->setExecuted(); 57 58 // Complete access to copy data to proper place. 59 inst->completeAcc(); 60 } 61 62 // Need to insert instruction into queue to commit 63 iewStage->instToCommit(inst); 64 65 iewStage->activityThisCycle(); 66 67 inst = NULL; 68*/ | 52template<class Impl> 53const char * 54LSQUnit<Impl>::WritebackEvent::description() 55{ 56 return "Store writeback event"; |
69} 70 71template<class Impl> 72void | 57} 58 59template<class Impl> 60void |
73LSQUnit<Impl>::completeStoreDataAccess(DynInstPtr &inst) | 61LSQUnit<Impl>::completeDataAccess(PacketPtr pkt) |
74{ | 62{ |
75/* 76 DPRINTF(LSQ, "Cache miss complete for store idx:%i\n", storeIdx); 77 DPRINTF(Activity, "Activity: st writeback event idx:%i\n", storeIdx); | 63 LSQSenderState *state = dynamic_cast<LSQSenderState *>(pkt->senderState); 64 DynInstPtr inst = state->inst; 65 DPRINTF(IEW, "Writeback event [sn:%lli]\n", inst->seqNum); 66// DPRINTF(Activity, "Activity: Ld Writeback event [sn:%lli]\n", inst->seqNum); |
78 | 67 |
79 //lsqPtr->removeMSHR(lsqPtr->storeQueue[storeIdx].inst->seqNum); | 68 //iewStage->ldstQueue.removeMSHR(inst->threadNumber,inst->seqNum); |
80 | 69 |
81 if (lsqPtr->isSwitchedOut()) { 82 if (wbEvent) 83 delete wbEvent; 84 | 70 if (isSwitchedOut() || inst->isSquashed()) { 71 delete state; 72 delete pkt; |
85 return; | 73 return; |
74 } else { 75 if (!state->noWB) { 76 writeback(inst, pkt); 77 } 78 79 if (inst->isStore()) { 80 completeStore(state->idx); 81 } |
|
86 } 87 | 82 } 83 |
88 lsqPtr->cpu->wakeCPU(); 89 90 if (wb) 91 lsqPtr->completeDataAccess(storeIdx); 92 lsqPtr->completeStore(storeIdx); 93*/ | 84 delete state; 85 delete pkt; |
94} 95 96template <class Impl> 97Tick 98LSQUnit<Impl>::DcachePort::recvAtomic(PacketPtr pkt) 99{ 100 panic("O3CPU model does not work with atomic mode!"); 101 return curTick; --- 39 unchanged lines hidden (view full) --- 141 cpu->_status = DcacheWaitResponse; 142 cpu->dcache_pkt = NULL; 143 } 144*/ 145} 146 147template <class Impl> 148LSQUnit<Impl>::LSQUnit() | 86} 87 88template <class Impl> 89Tick 90LSQUnit<Impl>::DcachePort::recvAtomic(PacketPtr pkt) 91{ 92 panic("O3CPU model does not work with atomic mode!"); 93 return curTick; --- 39 unchanged lines hidden (view full) --- 133 cpu->_status = DcacheWaitResponse; 134 cpu->dcache_pkt = NULL; 135 } 136*/ 137} 138 139template <class Impl> 140LSQUnit<Impl>::LSQUnit() |
149 : loads(0), stores(0), storesToWB(0), stalled(false), isLoadBlocked(false), | 141 : loads(0), stores(0), storesToWB(0), stalled(false), 142 isStoreBlocked(false), isLoadBlocked(false), |
150 loadBlockedHandled(false) 151{ 152} 153 154template<class Impl> 155void 156LSQUnit<Impl>::init(Params *params, unsigned maxLQEntries, 157 unsigned maxSQEntries, unsigned id) --- 13 unchanged lines hidden (view full) --- 171 172 loadHead = loadTail = 0; 173 174 storeHead = storeWBIdx = storeTail = 0; 175 176 usedPorts = 0; 177 cachePorts = params->cachePorts; 178 | 143 loadBlockedHandled(false) 144{ 145} 146 147template<class Impl> 148void 149LSQUnit<Impl>::init(Params *params, unsigned maxLQEntries, 150 unsigned maxSQEntries, unsigned id) --- 13 unchanged lines hidden (view full) --- 164 165 loadHead = loadTail = 0; 166 167 storeHead = storeWBIdx = storeTail = 0; 168 169 usedPorts = 0; 170 cachePorts = params->cachePorts; 171 |
179 Port *mem_dport = params->mem->getPort(""); 180 dcachePort->setPeer(mem_dport); 181 mem_dport->setPeer(dcachePort); | 172 mem = params->mem; |
182 183 memDepViolator = NULL; 184 185 blockedLoadSeqNum = 0; 186} 187 188template<class Impl> 189void 190LSQUnit<Impl>::setCPU(FullCPU *cpu_ptr) 191{ 192 cpu = cpu_ptr; 193 dcachePort = new DcachePort(cpu, this); | 173 174 memDepViolator = NULL; 175 176 blockedLoadSeqNum = 0; 177} 178 179template<class Impl> 180void 181LSQUnit<Impl>::setCPU(FullCPU *cpu_ptr) 182{ 183 cpu = cpu_ptr; 184 dcachePort = new DcachePort(cpu, this); |
185 186 Port *mem_dport = mem->getPort(""); 187 dcachePort->setPeer(mem_dport); 188 mem_dport->setPeer(dcachePort); |
|
194} 195 196template<class Impl> 197std::string 198LSQUnit<Impl>::name() const 199{ 200 if (Impl::MaxThreads == 1) { 201 return iewStage->name() + ".lsq"; --- 239 unchanged lines hidden (view full) --- 441 DPRINTF(LSQUnit, "Executing store PC %#x [sn:%lli]\n", 442 store_inst->readPC(), store_inst->seqNum); 443 444 // Check the recently completed loads to see if any match this store's 445 // address. If so, then we have a memory ordering violation. 446 int load_idx = store_inst->lqIdx; 447 448 Fault store_fault = store_inst->initiateAcc(); | 189} 190 191template<class Impl> 192std::string 193LSQUnit<Impl>::name() const 194{ 195 if (Impl::MaxThreads == 1) { 196 return iewStage->name() + ".lsq"; --- 239 unchanged lines hidden (view full) --- 436 DPRINTF(LSQUnit, "Executing store PC %#x [sn:%lli]\n", 437 store_inst->readPC(), store_inst->seqNum); 438 439 // Check the recently completed loads to see if any match this store's 440 // address. If so, then we have a memory ordering violation. 441 int load_idx = store_inst->lqIdx; 442 443 Fault store_fault = store_inst->initiateAcc(); |
449// Fault store_fault = store_inst->execute(); | |
450 451 if (storeQueue[store_idx].size == 0) { 452 DPRINTF(LSQUnit,"Fault on Store PC %#x, [sn:%lli],Size = 0\n", 453 store_inst->readPC(),store_inst->seqNum); 454 455 return store_fault; 456 } 457 --- 99 unchanged lines hidden (view full) --- 557LSQUnit<Impl>::writebackStores() 558{ 559 while (storesToWB > 0 && 560 storeWBIdx != storeTail && 561 storeQueue[storeWBIdx].inst && 562 storeQueue[storeWBIdx].canWB && 563 usedPorts < cachePorts) { 564 | 444 445 if (storeQueue[store_idx].size == 0) { 446 DPRINTF(LSQUnit,"Fault on Store PC %#x, [sn:%lli],Size = 0\n", 447 store_inst->readPC(),store_inst->seqNum); 448 449 return store_fault; 450 } 451 --- 99 unchanged lines hidden (view full) --- 551LSQUnit<Impl>::writebackStores() 552{ 553 while (storesToWB > 0 && 554 storeWBIdx != storeTail && 555 storeQueue[storeWBIdx].inst && 556 storeQueue[storeWBIdx].canWB && 557 usedPorts < cachePorts) { 558 |
559 if (isStoreBlocked) { 560 DPRINTF(LSQUnit, "Unable to write back any more stores, cache" 561 " is blocked!\n"); 562 break; 563 } 564 |
|
565 // Store didn't write any data so no need to write it back to 566 // memory. 567 if (storeQueue[storeWBIdx].size == 0) { 568 completeStore(storeWBIdx); 569 570 incrStIdx(storeWBIdx); 571 572 continue; 573 } | 565 // Store didn't write any data so no need to write it back to 566 // memory. 567 if (storeQueue[storeWBIdx].size == 0) { 568 completeStore(storeWBIdx); 569 570 incrStIdx(storeWBIdx); 571 572 continue; 573 } |
574/* 575 if (dcacheInterface && dcacheInterface->isBlocked()) { 576 DPRINTF(LSQUnit, "Unable to write back any more stores, cache" 577 " is blocked!\n"); 578 break; 579 } 580*/ | 574 |
581 ++usedPorts; 582 583 if (storeQueue[storeWBIdx].inst->isDataPrefetch()) { 584 incrStIdx(storeWBIdx); 585 586 continue; 587 } 588 589 assert(storeQueue[storeWBIdx].req); 590 assert(!storeQueue[storeWBIdx].committed); 591 592 DynInstPtr inst = storeQueue[storeWBIdx].inst; 593 594 Request *req = storeQueue[storeWBIdx].req; 595 storeQueue[storeWBIdx].committed = true; 596 597 assert(!inst->memData); 598 inst->memData = new uint8_t[64]; | 575 ++usedPorts; 576 577 if (storeQueue[storeWBIdx].inst->isDataPrefetch()) { 578 incrStIdx(storeWBIdx); 579 580 continue; 581 } 582 583 assert(storeQueue[storeWBIdx].req); 584 assert(!storeQueue[storeWBIdx].committed); 585 586 DynInstPtr inst = storeQueue[storeWBIdx].inst; 587 588 Request *req = storeQueue[storeWBIdx].req; 589 storeQueue[storeWBIdx].committed = true; 590 591 assert(!inst->memData); 592 inst->memData = new uint8_t[64]; |
599 memcpy(inst->memData, (uint8_t *)&storeQueue[storeWBIdx].data, req->getSize()); | 593 memcpy(inst->memData, (uint8_t *)&storeQueue[storeWBIdx].data, 594 req->getSize()); |
600 601 PacketPtr data_pkt = new Packet(req, Packet::WriteReq, Packet::Broadcast); 602 data_pkt->dataStatic(inst->memData); 603 | 595 596 PacketPtr data_pkt = new Packet(req, Packet::WriteReq, Packet::Broadcast); 597 data_pkt->dataStatic(inst->memData); 598 |
599 LSQSenderState *state = new LSQSenderState; 600 state->isLoad = false; 601 state->idx = storeWBIdx; 602 state->inst = inst; 603 data_pkt->senderState = state; 604 |
|
604 DPRINTF(LSQUnit, "D-Cache: Writing back store idx:%i PC:%#x " 605 "to Addr:%#x, data:%#x [sn:%lli]\n", 606 storeWBIdx, storeQueue[storeWBIdx].inst->readPC(), 607 req->getPaddr(), *(inst->memData), 608 storeQueue[storeWBIdx].inst->seqNum); 609 610 if (!dcachePort->sendTiming(data_pkt)) { 611 // Need to handle becoming blocked on a store. | 605 DPRINTF(LSQUnit, "D-Cache: Writing back store idx:%i PC:%#x " 606 "to Addr:%#x, data:%#x [sn:%lli]\n", 607 storeWBIdx, storeQueue[storeWBIdx].inst->readPC(), 608 req->getPaddr(), *(inst->memData), 609 storeQueue[storeWBIdx].inst->seqNum); 610 611 if (!dcachePort->sendTiming(data_pkt)) { 612 // Need to handle becoming blocked on a store. |
613 isStoreBlocked = true; |
|
612 } else { | 614 } else { |
613 /* 614 StoreCompletionEvent *store_event = new 615 StoreCompletionEvent(storeWBIdx, NULL, this); 616 */ | |
617 if (isStalled() && 618 storeQueue[storeWBIdx].inst->seqNum == stallingStoreIsn) { 619 DPRINTF(LSQUnit, "Unstalling, stalling store [sn:%lli] " 620 "load idx:%i\n", 621 stallingStoreIsn, stallingLoadIdx); 622 stalled = false; 623 stallingStoreIsn = 0; 624 iewStage->replayMemInst(loadQueue[stallingLoadIdx]); 625 } | 615 if (isStalled() && 616 storeQueue[storeWBIdx].inst->seqNum == stallingStoreIsn) { 617 DPRINTF(LSQUnit, "Unstalling, stalling store [sn:%lli] " 618 "load idx:%i\n", 619 stallingStoreIsn, stallingLoadIdx); 620 stalled = false; 621 stallingStoreIsn = 0; 622 iewStage->replayMemInst(loadQueue[stallingLoadIdx]); 623 } |
626/* 627 typename LdWritebackEvent *wb = NULL; 628 if (req->flags & LOCKED) { 629 // Stx_C should not generate a system port transaction 630 // if it misses in the cache, but that might be hard 631 // to accomplish without explicit cache support. 632 wb = new typename 633 LdWritebackEvent(storeQueue[storeWBIdx].inst, 634 iewStage); 635 store_event->wbEvent = wb; | 624 625 if (!(req->getFlags() & LOCKED)) { 626 assert(!storeQueue[storeWBIdx].inst->isStoreConditional()); 627 // Non-store conditionals do not need a writeback. 628 state->noWB = true; |
636 } | 629 } |
637*/ | 630 |
638 if (data_pkt->result != Packet::Success) { 639 DPRINTF(LSQUnit,"D-Cache Write Miss on idx:%i!\n", 640 storeWBIdx); 641 642 DPRINTF(Activity, "Active st accessing mem miss [sn:%lli]\n", 643 storeQueue[storeWBIdx].inst->seqNum); 644 645 //mshrSeqNums.push_back(storeQueue[storeWBIdx].inst->seqNum); --- 110 unchanged lines hidden (view full) --- 756 storeTail = store_idx; 757 758 decrStIdx(store_idx); 759 } 760} 761 762template <class Impl> 763void | 631 if (data_pkt->result != Packet::Success) { 632 DPRINTF(LSQUnit,"D-Cache Write Miss on idx:%i!\n", 633 storeWBIdx); 634 635 DPRINTF(Activity, "Active st accessing mem miss [sn:%lli]\n", 636 storeQueue[storeWBIdx].inst->seqNum); 637 638 //mshrSeqNums.push_back(storeQueue[storeWBIdx].inst->seqNum); --- 110 unchanged lines hidden (view full) --- 749 storeTail = store_idx; 750 751 decrStIdx(store_idx); 752 } 753} 754 755template <class Impl> 756void |
757LSQUnit<Impl>::writeback(DynInstPtr &inst, PacketPtr pkt) 758{ 759 iewStage->wakeCPU(); 760 761 // Squashed instructions do not need to complete their access. 762 if (inst->isSquashed()) { 763 assert(!inst->isStore()); 764 return; 765 } 766 767 if (!inst->isExecuted()) { 768 inst->setExecuted(); 769 770 // Complete access to copy data to proper place. 771 inst->completeAcc(pkt); 772 } 773 774 // Need to insert instruction into queue to commit 775 iewStage->instToCommit(inst); 776 777 iewStage->activityThisCycle(); 778} 779 780template <class Impl> 781void |
|
764LSQUnit<Impl>::completeStore(int store_idx) 765{ 766 assert(storeQueue[store_idx].inst); 767 storeQueue[store_idx].completed = true; 768 --storesToWB; 769 // A bit conservative because a store completion may not free up entries, 770 // but hopefully avoids two store completions in one cycle from making 771 // the CPU tick twice. --- 98 unchanged lines hidden --- | 782LSQUnit<Impl>::completeStore(int store_idx) 783{ 784 assert(storeQueue[store_idx].inst); 785 storeQueue[store_idx].completed = true; 786 --storesToWB; 787 // A bit conservative because a store completion may not free up entries, 788 // but hopefully avoids two store completions in one cycle from making 789 // the CPU tick twice. --- 98 unchanged lines hidden --- |