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 ---