lsq_unit.hh (2871:7ed5c9ef3eb6) | lsq_unit.hh (2907:7b0ababb4166) |
---|---|
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; | 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; |
|
67 typedef typename Impl::CPUPol::IssueStruct IssueStruct; 68 69 public: 70 /** Constructs an LSQ unit. init() must be called prior to use. */ 71 LSQUnit(); 72 73 /** Initializes the LSQ unit with the specified number of entries. */ | 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. */ |
74 void init(Params *params, unsigned maxLQEntries, | 75 void init(Params *params, LSQ *lsq_ptr, unsigned maxLQEntries, |
75 unsigned maxSQEntries, unsigned id); 76 77 /** Returns the name of the LSQ unit. */ 78 std::string name() const; 79 | 76 unsigned maxSQEntries, unsigned id); 77 78 /** Returns the name of the LSQ unit. */ 79 std::string name() const; 80 |
80 /** Returns the dcache port. 81 * @todo: Remove this once the port moves up to the LSQ level. 82 */ 83 Port *getDcachePort() { return dcachePort; } 84 | |
85 /** Registers statistics. */ 86 void regStats(); 87 88 /** Sets the CPU pointer. */ 89 void setCPU(O3CPU *cpu_ptr); 90 91 /** Sets the IEW stage pointer. */ 92 void setIEW(IEW *iew_ptr) 93 { iewStage = iew_ptr; } 94 | 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 | 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 |
|
214 private: 215 /** Writes back the instruction, sending it to IEW. */ 216 void writeback(DynInstPtr &inst, PacketPtr pkt); 217 218 /** Handles completing the send of a store to memory. */ 219 void storePostSend(Packet *pkt); 220 221 /** Completes the store at the specified index. */ 222 void completeStore(int store_idx); 223 | 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 |
224 /** Handles doing the retry. */ 225 void recvRetry(); 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 | 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 memory object. */ 248 MemObject *mem; | 247 /** Pointer to the LSQ. */ 248 LSQ *lsq; |
249 | 249 |
250 /** DcachePort class for this LSQ Unit. Handles doing the 251 * communication with the cache/memory. 252 * @todo: Needs to be moved to the LSQ level and have some sort 253 * of arbitration. 254 */ 255 class DcachePort : public Port 256 { 257 protected: 258 /** Pointer to CPU. */ 259 O3CPU *cpu; 260 /** Pointer to LSQ. */ 261 LSQUnit *lsq; | 250 /** Pointer to the dcache port. Used only for sending. */ 251 Port *dcachePort; |
262 | 252 |
263 public: 264 /** Default constructor. */ 265 DcachePort(O3CPU *_cpu, LSQUnit *_lsq) 266 : Port(_lsq->name() + "-dport"), cpu(_cpu), lsq(_lsq) 267 { } 268 269 protected: 270 /** Atomic version of receive. Panics. */ 271 virtual Tick recvAtomic(PacketPtr pkt); 272 273 /** Functional version of receive. Panics. */ 274 virtual void recvFunctional(PacketPtr pkt); 275 276 /** Receives status change. Other than range changing, panics. */ 277 virtual void recvStatusChange(Status status); 278 279 /** Returns the address ranges of this device. */ 280 virtual void getDeviceAddressRanges(AddrRangeList &resp, 281 AddrRangeList &snoop) 282 { resp.clear(); snoop.clear(); } 283 284 /** Timing version of receive. Handles writing back and 285 * completing the load or store that has returned from 286 * memory. */ 287 virtual bool recvTiming(PacketPtr pkt); 288 289 /** Handles doing a retry of the previous send. */ 290 virtual void recvRetry(); 291 }; 292 293 /** Pointer to the D-cache. */ 294 DcachePort *dcachePort; 295 | |
296 /** Derived class to hold any sender state the LSQ needs. */ 297 class LSQSenderState : public Packet::SenderState 298 { 299 public: 300 /** Default constructor. */ 301 LSQSenderState() 302 : noWB(false) 303 { } --- 349 unchanged lines hidden (view full) --- 653 store_idx, req->getVaddr()); 654 655 ++lsqBlockedLoads; 656 return NoFault; 657 } 658 } 659 660 // If there's no forwarding case, then go access memory | 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 |
661 DPRINTF(LSQUnit, "Doing functional access for inst [sn:%lli] PC %#x\n", | 618 DPRINTF(LSQUnit, "Doing memory access for inst [sn:%lli] PC %#x\n", |
662 load_inst->seqNum, load_inst->readPC()); 663 664 assert(!load_inst->memData); 665 load_inst->memData = new uint8_t[64]; 666 667 ++usedPorts; 668 | 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 |
669 DPRINTF(LSQUnit, "Doing timing access for inst PC %#x\n", 670 load_inst->readPC()); 671 | |
672 PacketPtr data_pkt = new Packet(req, Packet::ReadReq, Packet::Broadcast); 673 data_pkt->dataStatic(load_inst->memData); 674 675 LSQSenderState *state = new LSQSenderState; 676 state->isLoad = true; 677 state->idx = load_idx; 678 state->inst = load_inst; 679 data_pkt->senderState = state; 680 | 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 |
681 // if we have a cache, do cache access too 682 if (!dcachePort->sendTiming(data_pkt)) { | 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()) { |
683 ++lsqCacheBlocked; 684 // There's an older load that's already going to squash. 685 if (isLoadBlocked && blockedLoadSeqNum < load_inst->seqNum) 686 return NoFault; 687 688 // Record that the load was blocked due to memory. This 689 // load will squash all instructions after it, be 690 // refetched, and re-executed. --- 42 unchanged lines hidden --- | 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 --- |