1/* 2 * Copyright (c) 2004-2006 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; --- 50 unchanged lines hidden (view full) --- 59class LSQUnit { 60 protected: 61 typedef TheISA::IntReg IntReg; 62 public: 63 typedef typename Impl::Params Params; 64 typedef typename Impl::O3CPU O3CPU; 65 typedef typename Impl::DynInstPtr DynInstPtr; 66 typedef typename Impl::CPUPol::IEW IEW; |
67 typedef typename Impl::CPUPol::LSQ LSQ; |
68 typedef typename Impl::CPUPol::IssueStruct IssueStruct; 69 70 public: 71 /** Constructs an LSQ unit. init() must be called prior to use. */ 72 LSQUnit(); 73 74 /** Initializes the LSQ unit with the specified number of entries. */ |
75 void init(Params *params, LSQ *lsq_ptr, unsigned maxLQEntries, |
76 unsigned maxSQEntries, unsigned id); 77 78 /** Returns the name of the LSQ unit. */ 79 std::string name() const; 80 |
81 /** Registers statistics. */ 82 void regStats(); 83 84 /** Sets the CPU pointer. */ 85 void setCPU(O3CPU *cpu_ptr); 86 87 /** Sets the IEW stage pointer. */ 88 void setIEW(IEW *iew_ptr) 89 { iewStage = iew_ptr; } 90 |
91 /** Sets the pointer to the dcache port. */ 92 void setDcachePort(Port *dcache_port) 93 { dcachePort = dcache_port; } 94 |
95 /** Switches out LSQ unit. */ 96 void switchOut(); 97 98 /** Takes over from another CPU's thread. */ 99 void takeOverFrom(); 100 101 /** Returns if the LSQ is switched out. */ 102 bool isSwitchedOut() { return switchedOut; } --- 103 unchanged lines hidden (view full) --- 206 /** Returns the number of stores to writeback. */ 207 int numStoresToWB() { return storesToWB; } 208 209 /** Returns if the LSQ unit will writeback on this cycle. */ 210 bool willWB() { return storeQueue[storeWBIdx].canWB && 211 !storeQueue[storeWBIdx].completed && 212 !isStoreBlocked; } 213 |
214 /** Handles doing the retry. */ 215 void recvRetry(); 216 |
217 private: 218 /** Writes back the instruction, sending it to IEW. */ 219 void writeback(DynInstPtr &inst, PacketPtr pkt); 220 221 /** Handles completing the send of a store to memory. */ 222 void storePostSend(Packet *pkt); 223 224 /** Completes the store at the specified index. */ 225 void completeStore(int store_idx); 226 |
227 /** Increments the given store index (circular queue). */ 228 inline void incrStIdx(int &store_idx); 229 /** Decrements the given store index (circular queue). */ 230 inline void decrStIdx(int &store_idx); 231 /** Increments the given load index (circular queue). */ 232 inline void incrLdIdx(int &load_idx); 233 /** Decrements the given load index (circular queue). */ 234 inline void decrLdIdx(int &load_idx); --- 4 unchanged lines hidden (view full) --- 239 240 private: 241 /** Pointer to the CPU. */ 242 O3CPU *cpu; 243 244 /** Pointer to the IEW stage. */ 245 IEW *iewStage; 246 |
247 /** Pointer to the LSQ. */ 248 LSQ *lsq; |
249 |
250 /** Pointer to the dcache port. Used only for sending. */ 251 Port *dcachePort; |
252 |
253 /** Derived class to hold any sender state the LSQ needs. */ 254 class LSQSenderState : public Packet::SenderState 255 { 256 public: 257 /** Default constructor. */ 258 LSQSenderState() 259 : noWB(false) 260 { } --- 349 unchanged lines hidden (view full) --- 610 store_idx, req->getVaddr()); 611 612 ++lsqBlockedLoads; 613 return NoFault; 614 } 615 } 616 617 // If there's no forwarding case, then go access memory |
618 DPRINTF(LSQUnit, "Doing memory access for inst [sn:%lli] PC %#x\n", |
619 load_inst->seqNum, load_inst->readPC()); 620 621 assert(!load_inst->memData); 622 load_inst->memData = new uint8_t[64]; 623 624 ++usedPorts; 625 |
626 PacketPtr data_pkt = new Packet(req, Packet::ReadReq, Packet::Broadcast); 627 data_pkt->dataStatic(load_inst->memData); 628 629 LSQSenderState *state = new LSQSenderState; 630 state->isLoad = true; 631 state->idx = load_idx; 632 state->inst = load_inst; 633 data_pkt->senderState = state; 634 |
635 // if we the cache is not blocked, do cache access 636 if (!lsq->cacheBlocked()) { 637 if (!dcachePort->sendTiming(data_pkt)) { 638 // If the access didn't succeed, tell the LSQ by setting 639 // the retry thread id. 640 lsq->setRetryTid(lsqID); 641 } 642 } 643 644 // If the cache was blocked, or has become blocked due to the access, 645 // handle it. 646 if (lsq->cacheBlocked()) { |
647 ++lsqCacheBlocked; 648 // There's an older load that's already going to squash. 649 if (isLoadBlocked && blockedLoadSeqNum < load_inst->seqNum) 650 return NoFault; 651 652 // Record that the load was blocked due to memory. This 653 // load will squash all instructions after it, be 654 // refetched, and re-executed. --- 42 unchanged lines hidden --- |