summaryrefslogtreecommitdiff
path: root/src/cpu/minor/fetch1.hh
diff options
context:
space:
mode:
Diffstat (limited to 'src/cpu/minor/fetch1.hh')
-rw-r--r--src/cpu/minor/fetch1.hh381
1 files changed, 381 insertions, 0 deletions
diff --git a/src/cpu/minor/fetch1.hh b/src/cpu/minor/fetch1.hh
new file mode 100644
index 000000000..29a63d1f1
--- /dev/null
+++ b/src/cpu/minor/fetch1.hh
@@ -0,0 +1,381 @@
+/*
+ * Copyright (c) 2013-2014 ARM Limited
+ * All rights reserved
+ *
+ * The license below extends only to copyright in the software and shall
+ * not be construed as granting a license to any other intellectual
+ * property including but not limited to intellectual property relating
+ * to a hardware implementation of the functionality of the software
+ * licensed hereunder. You may use the software subject to the license
+ * terms below provided that you ensure that this notice is replicated
+ * unmodified and in its entirety in all distributions of the software,
+ * modified or unmodified, in source code or in binary form.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met: redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer;
+ * redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution;
+ * neither the name of the copyright holders nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * Authors: Andrew Bardsley
+ */
+
+/**
+ * @file
+ *
+ * Fetch1 is responsible for fetching "lines" from memory and passing
+ * them to Fetch2
+ */
+
+#ifndef __CPU_MINOR_FETCH1_HH__
+#define __CPU_MINOR_FETCH1_HH__
+
+#include "cpu/minor/buffers.hh"
+#include "cpu/minor/cpu.hh"
+#include "cpu/minor/pipe_data.hh"
+#include "cpu/base.hh"
+#include "mem/packet.hh"
+
+namespace Minor
+{
+
+/** A stage responsible for fetching "lines" from memory and passing
+ * them to Fetch2 */
+class Fetch1 : public Named
+{
+ protected:
+ /** Exposable fetch port */
+ class IcachePort : public MinorCPU::MinorCPUPort
+ {
+ protected:
+ /** My owner */
+ Fetch1 &fetch;
+
+ public:
+ IcachePort(std::string name, Fetch1 &fetch_, MinorCPU &cpu) :
+ MinorCPU::MinorCPUPort(name, cpu), fetch(fetch_)
+ { }
+
+ protected:
+ bool recvTimingResp(PacketPtr pkt)
+ { return fetch.recvTimingResp(pkt); }
+
+ void recvRetry() { fetch.recvRetry(); }
+ };
+
+ /** Memory access queuing.
+ *
+ * A request can be submitted by pushing it onto the requests queue after
+ * issuing an ITLB lookup (state becomes InTranslation) with a
+ * FetchSenderState senderState containing the current lineSeqNum and
+ * stream/predictionSeqNum.
+ *
+ * Translated packets (state becomes Translation) are then passed to the
+ * memory system and the transfers queue (state becomes RequestIssuing).
+ * Retries are handled by leaving the packet on the requests queue and
+ * changing the state to IcacheNeedsRetry).
+ *
+ * Responses from the memory system alter the request object (state
+ * become Complete). Responses can be picked up from the head of the
+ * transfers queue to pass on to Fetch2. */
+
+ /** Structure to hold SenderState info through
+ * translation and memory accesses. */
+ class FetchRequest :
+ public BaseTLB::Translation, /* For TLB lookups */
+ public Packet::SenderState /* For packing into a Packet */
+ {
+ protected:
+ /** Owning fetch unit */
+ Fetch1 &fetch;
+
+ public:
+ /** Progress of this request through address translation and
+ * memory */
+ enum FetchRequestState
+ {
+ NotIssued, /* Just been made */
+ InTranslation, /* Issued to ITLB, must wait for reqply */
+ Translated, /* Translation complete */
+ RequestIssuing, /* Issued to memory, must wait for response */
+ Complete /* Complete. Either a fault, or a fetched line */
+ };
+
+ FetchRequestState state;
+
+ /** Identity of the line that this request will generate */
+ InstId id;
+
+ /** FetchRequests carry packets while they're in the requests and
+ * transfers responses queues. When a Packet returns from the memory
+ * system, its request needs to have its packet updated as this may
+ * have changed in flight */
+ PacketPtr packet;
+
+ /** The underlying request that this fetch represents */
+ Request request;
+
+ /** PC to fixup with line address */
+ TheISA::PCState pc;
+
+ /** Fill in a fault if one happens during fetch, check this by
+ * picking apart the response packet */
+ Fault fault;
+
+ /** Make a packet to use with the memory transaction */
+ void makePacket();
+
+ /** Report interface */
+ void reportData(std::ostream &os) const;
+
+ /** Is this line out of date with the current stream/prediction
+ * sequence and can it be discarded without orphaning in flight
+ * TLB lookups/memory accesses? */
+ bool isDiscardable() const;
+
+ /** Is this a complete read line or fault */
+ bool isComplete() const { return state == Complete; }
+
+ protected:
+ /** BaseTLB::Translation interface */
+
+ /** Interface for ITLB responses. We can handle delay, so don't
+ * do anything */
+ void markDelayed() { }
+
+ /** Interface for ITLB responses. Populates self and then passes
+ * the request on to the ports' handleTLBResponse member
+ * function */
+ void finish(Fault fault_, RequestPtr request_, ThreadContext *tc,
+ BaseTLB::Mode mode);
+
+ public:
+ FetchRequest(Fetch1 &fetch_, InstId id_, TheISA::PCState pc_) :
+ SenderState(),
+ fetch(fetch_),
+ state(NotIssued),
+ id(id_),
+ packet(NULL),
+ request(),
+ pc(pc_),
+ fault(NoFault)
+ { }
+
+ ~FetchRequest();
+ };
+
+ typedef FetchRequest *FetchRequestPtr;
+
+ protected:
+ /** Construction-assigned data members */
+
+ /** Pointer back to the containing CPU */
+ MinorCPU &cpu;
+
+ /** Input port carrying branch requests from Execute */
+ Latch<BranchData>::Output inp;
+ /** Output port carrying read lines to Fetch2 */
+ Latch<ForwardLineData>::Input out;
+ /** Input port carrying branch predictions from Fetch2 */
+ Latch<BranchData>::Output prediction;
+
+ /** Interface to reserve space in the next stage */
+ Reservable &nextStageReserve;
+
+ /** IcachePort to pass to the CPU. Fetch1 is the only module that uses
+ * it. */
+ IcachePort icachePort;
+
+ /** Line snap size in bytes. All fetches clip to make their ends not
+ * extend beyond this limit. Setting this to the machine L1 cache line
+ * length will result in fetches never crossing line boundaries. */
+ unsigned int lineSnap;
+
+ /** Maximum fetch width in bytes. Setting this (and lineSnap) to the
+ * machine L1 cache line length will result in fetches of whole cache
+ * lines. Setting this to sizeof(MachInst) will result it fetches of
+ * single instructions (except near the end of lineSnap lines) */
+ unsigned int maxLineWidth;
+
+ /** Maximum number of fetches allowed in flight (in queues or memory) */
+ unsigned int fetchLimit;
+
+ protected:
+ /** Cycle-by-cycle state */
+
+ /** State of memory access for head instruction fetch */
+ enum FetchState
+ {
+ FetchHalted, /* Not fetching, waiting to be woken by transition
+ to FetchWaitingForPC. The PC is not valid in this state */
+ FetchWaitingForPC, /* Not fetching, waiting for stream change.
+ This doesn't stop issued fetches from being returned and
+ processed or for branches to change the state to Running. */
+ FetchRunning /* Try to fetch, when possible */
+ };
+
+ /** Stage cycle-by-cycle state */
+
+ FetchState state;
+
+ /** Fetch PC value. This is updated by branches from Execute, branch
+ * prediction targets from Fetch2 and by incrementing it as we fetch
+ * lines subsequent to those two sources. */
+ TheISA::PCState pc;
+
+ /** Stream sequence number. This changes on request from Execute and is
+ * used to tag instructions by the fetch stream to which they belong.
+ * Execute originates new prediction sequence numbers. */
+ InstSeqNum streamSeqNum;
+
+ /** Prediction sequence number. This changes when requests from Execute
+ * or Fetch2 ask for a change of fetch address and is used to tag lines
+ * by the prediction to which they belong. Fetch2 originates
+ * prediction sequence numbers. */
+ InstSeqNum predictionSeqNum;
+
+ /** The sequence number expected for the next returned cache line. The
+ * responses queue should be ordered and so, if the front of that queue
+ * has a lower lineSeqNum than this, lines need to be discarded. If it
+ * has a higher lineSeqNum, our line hasn't appeared yet */
+ InstSeqNum expectedLineSeqNum;
+
+ /** Blocked indication for report */
+ bool blocked;
+
+ /** State of memory access for head instruction fetch */
+ enum IcacheState
+ {
+ IcacheRunning, /* Default. Step icache queues when possible */
+ IcacheNeedsRetry /* Request rejected, will be asked to retry */
+ };
+
+ typedef Queue<FetchRequestPtr,
+ ReportTraitsPtrAdaptor<FetchRequestPtr>,
+ NoBubbleTraits<FetchRequestPtr> >
+ FetchQueue;
+
+ /** Queue of address translated requests from Fetch1 */
+ FetchQueue requests;
+
+ /** Queue of in-memory system requests and responses */
+ FetchQueue transfers;
+
+ /** Retry state of icache_port */
+ IcacheState icacheState;
+
+ /** Sequence number for line fetch used for ordering lines to flush */
+ InstSeqNum lineSeqNum;
+
+ /** Count of the number fetches which have left the transfers queue
+ * and are in the 'wild' in the memory system. Try not to rely on
+ * this value, it's better to code without knowledge of the number
+ * of outstanding accesses */
+ unsigned int numFetchesInMemorySystem;
+ /** Number of requests inside the ITLB rather than in the queues.
+ * All requests so located *must* have reserved space in the
+ * transfers queue */
+ unsigned int numFetchesInITLB;
+
+ protected:
+ friend std::ostream &operator <<(std::ostream &os,
+ Fetch1::FetchState state);
+
+ /** Start fetching from a new address. */
+ void changeStream(const BranchData &branch);
+
+ /** Update streamSeqNum and predictionSeqNum from the given branch (and
+ * assume these have changed and discard (on delivery) all lines in
+ * flight) */
+ void updateExpectedSeqNums(const BranchData &branch);
+
+ /** Convert a response to a ForwardLineData */
+ void processResponse(FetchRequestPtr response,
+ ForwardLineData &line);
+
+ friend std::ostream &operator <<(std::ostream &os,
+ IcacheState state);
+
+ /** Insert a line fetch into the requests. This can be a partial
+ * line request where the given address has a non-0 offset into a
+ * line. */
+ void fetchLine();
+
+ /** Try and issue a fetch for a translated request at the
+ * head of the requests queue. Also tries to move the request
+ * between queues */
+ void tryToSendToTransfers(FetchRequestPtr request);
+
+ /** Try to send (or resend) a memory request's next/only packet to
+ * the memory system. Returns true if the fetch was successfully
+ * sent to memory */
+ bool tryToSend(FetchRequestPtr request);
+
+ /** Move a request between queues */
+ void moveFromRequestsToTransfers(FetchRequestPtr request);
+
+ /** Step requests along between requests and transfers queues */
+ void stepQueues();
+
+ /** Pop a request from the given queue and correctly deallocate and
+ * discard it. */
+ void popAndDiscard(FetchQueue &queue);
+
+ /** Handle pushing a TLB response onto the right queue */
+ void handleTLBResponse(FetchRequestPtr response);
+
+ /** Returns the total number of queue occupancy, in-ITLB and
+ * in-memory system fetches */
+ unsigned int numInFlightFetches();
+
+ /** Print the appropriate MinorLine line for a fetch response */
+ void minorTraceResponseLine(const std::string &name,
+ FetchRequestPtr response) const;
+
+ /** Memory interface */
+ virtual bool recvTimingResp(PacketPtr pkt);
+ virtual void recvRetry();
+
+ public:
+ Fetch1(const std::string &name_,
+ MinorCPU &cpu_,
+ MinorCPUParams &params,
+ Latch<BranchData>::Output inp_,
+ Latch<ForwardLineData>::Input out_,
+ Latch<BranchData>::Output prediction_,
+ Reservable &next_stage_input_buffer);
+
+ public:
+ /** Returns the IcachePort owned by this Fetch1 */
+ MinorCPU::MinorCPUPort &getIcachePort() { return icachePort; }
+
+ /** Pass on input/buffer data to the output if you can */
+ void evaluate();
+
+ void minorTrace() const;
+
+ /** Is this stage drained? For Fetch1, draining is initiated by
+ * Execute signalling a branch with the reason HaltFetch */
+ bool isDrained();
+};
+
+}
+
+#endif /* __CPU_MINOR_FETCH1_HH__ */