50#include "debug/Drain.hh"
51#include "debug/Fetch.hh"
52#include "debug/MinorTrace.hh"
62 const BaseMinorCPUParams ¶ms,
71 prediction(prediction_),
72 nextStageReserve(next_stage_input_buffer),
73 icachePort(name_ +
".icache_port", *this, cpu_),
74 lineSnap(params.fetch1LineSnapWidth),
75 maxLineWidth(params.fetch1LineWidth),
76 fetchLimit(params.fetch1FetchLimit),
77 fetchInfo(params.numThreads),
79 requests(name_ +
".requests",
"lines", params.fetch1FetchLimit),
80 transfers(name_ +
".transfers",
"lines", params.fetch1FetchLimit),
81 icacheState(IcacheRunning),
82 lineSeqNum(
InstId::firstLineSeqNum),
83 numFetchesInMemorySystem(0),
87 info.pc.reset(params.isa[0]->newPCState());
91 DPRINTF(Fetch,
"lineSnap set to cache line size of: %d\n",
97 DPRINTF(Fetch,
"maxLineWidth set to cache line size of: %d\n",
101 size_t inst_size =
cpu.
threads[0]->decoder->moreBytesSize();
105 fatal(
"%s: fetch1LineSnapWidth must be a multiple "
106 "of the inst width (%d)\n", name_,
111 fatal(
"%s: fetch1LineWidth must be a multiple of"
112 " the inst width (%d), and >= fetch1LineSnapWidth (%d)\n",
117 fatal(
"%s: fetch1FetchLimit must be >= 1 (%d)\n", name_,
129 case enums::SingleThreaded:
130 priority_list.push_back(0);
132 case enums::RoundRobin:
139 panic(
"Unknown fetch policy");
142 for (
auto tid : priority_list) {
164 unsigned int line_offset = aligned_pc %
lineSnap;
175 DPRINTF(Fetch,
"Inserting fetch into the fetch queue "
176 "%s addr: 0x%x pc: %s line_offset: %d request_size: %d\n",
177 request_id, aligned_pc, thread.
fetchAddr, line_offset, request_size);
185 DPRINTF(Fetch,
"Submitting ITLB request\n");
207 thread.
fetchAddr = aligned_pc + request_size;
215 os <<
"IcacheRunning";
218 os <<
"IcacheNeedsRetry";
221 os <<
"IcacheState-" <<
static_cast<int>(
state);
246 fetch.handleTLBResponse(
this);
258 DPRINTF(Fetch,
"Fault in address ITLB translation: %s, "
259 "paddr: 0x%x, vaddr: 0x%x\n",
260 response->
fault->name(),
261 (response->
request->hasPaddr() ?
262 response->
request->getPaddr() : 0),
263 response->
request->getVaddr());
265 if (debug::MinorTrace)
268 DPRINTF(Fetch,
"Got ITLB response\n");
286 DPRINTF(Fetch,
"Fetch not at front of requests queue, can't"
287 " issue to memory\n");
292 DPRINTF(Fetch,
"Fetch still in translation, not issuing to"
317 DPRINTF(Fetch,
"Not advancing line fetch\n");
345 DPRINTF(Fetch,
"Issued fetch request to memory: %s\n",
351 DPRINTF(Fetch,
"Line fetch needs to retry: %s\n",
375 DPRINTF(Fetch,
"Step in state %s moving to state %s\n",
383 if (!queue.
empty()) {
384 delete queue.
front();
404 minorLine(*
this,
"id=F;%s vaddr=0x%x fault=\"error packet\"\n",
405 response->
id, request->getVaddr());
407 minorLine(*
this,
"id=F;%s vaddr=0x%x fault=\"%s\"\n",
408 response->
id, request->getVaddr(), response->
fault->name());
410 minorLine(*
this,
"id=%s size=%d vaddr=0x%x paddr=0x%x\n",
411 response->
id, request->getSize(),
412 request->getVaddr(), request->getPaddr());
428 assert(!fetch_request->
packet);
429 fetch_request->
packet = response;
434 if (debug::MinorTrace)
438 DPRINTF(Fetch,
"Received error response packet: %s\n",
476 os <<
"FetchWaitingForPC";
479 os <<
"FetchRunning";
482 os <<
"FetchState-" <<
static_cast<int>(
state);
500 DPRINTF(Fetch,
"Not suspending fetch due to guard: %s\n",
503 DPRINTF(Fetch,
"Suspending fetch: %s\n", branch);
509 DPRINTF(Fetch,
"Halting fetch\n");
513 DPRINTF(Fetch,
"Changing stream on branch: %s\n", branch);
526 DPRINTF(Fetch,
"Updating streamSeqNum from: %d to %d,"
527 " predictionSeqNum from: %d to %d\n",
550 line.
id = response->
id;
564 DPRINTF(Fetch,
"Stopping line fetch because of fault: %s\n",
565 response->
fault->name());
597 DPRINTF(Fetch,
"Halted, ignoring branch: %s\n", execute_branch);
603 DPRINTF(Fetch,
"Ignoring simultaneous prediction: %s\n",
615 DPRINTF(Fetch,
"Not changing stream on prediction: %s,"
616 " streamSeqNum mismatch\n",
628 DPRINTF(Fetch,
"Halted, ignoring branch: %s\n", execute_branch);
638 DPRINTF(Fetch,
"Halted, ignoring branch: %s\n", fetch2_branch);
640 DPRINTF(Fetch,
"Not changing stream on prediction: %s,"
641 " streamSeqNum mismatch\n", fetch2_branch);
652 DPRINTF(Fetch,
"Fetching from thread %d\n", fetch_tid);
659 DPRINTF(Fetch,
"No active threads available to fetch from\n");
678 DPRINTF(Fetch,
"Discarding translated fetch as it's for"
685 DPRINTF(Fetch,
"Processing fetched line: %s\n",
712 thread.wakeupGuard =
false;
725 DPRINTF(Fetch,
"[tid:%d]: Changing stream wakeup %s\n", tid, *thread.
pc);
736 DPRINTF(Drain,
"isDrained[tid:%d]: %s %s%s\n",
740 ((*
out.inputWire).isBubble() ?
"" :
"outputtingLine"));
759 return state != InTranslation &&
state != RequestIssuing &&
771 std::ostringstream
data;
776 (*
out.inputWire).reportData(
data);
void activity()
Records that there is activity this cycle.
RequestorID instRequestorId() const
Reads this CPU's unique instruction requestor ID.
Addr cacheLineSize() const
Get the cache line size of the system.
virtual ThreadContext * getContext(int tn)
Given a thread num get tho thread context for it.
ThreadID numThreads
Number of threads we're actually simulating (<= SMT_MAX_THREADS).
MinorCPU is an in-order CPU model with four fixed pipeline stages:
minor::MinorActivityRecorder * activityRecorder
Activity recording for pipeline.
void wakeupOnEvent(unsigned int stage_id)
Interface for stages to signal that they have become active after a callback or eventq event where th...
std::vector< ThreadID > randomPriority()
std::vector< ThreadID > roundRobinPriority(ThreadID priority)
Thread scheduling utility functions.
enums::ThreadPolicy threadPolicy
Thread Scheduling Policy (RoundRobin, Random, etc)
std::vector< minor::MinorThread * > threads
These are thread state-representing objects for this CPU.
Interface for things with names.
virtual std::string name() const
A Packet is used to encapsulate a transfer between two objects in the memory system (e....
bool needsResponse() const
void pushSenderState(SenderState *sender_state)
Push a new sender state to the packet and make the current sender state the predecessor of the new on...
SenderState * popSenderState()
Pop the top of the state stack and return a pointer to it.
void allocate()
Allocate memory for the packet.
bool sendTimingReq(PacketPtr pkt)
Attempt to send a timing request to the responder port by calling its corresponding receive function.
@ INST_FETCH
The request was an instruction fetch.
ThreadContext is the external interface to all thread state for anything outside of the CPU.
virtual const PCStateBase & pcState() const =0
virtual Status status() const =0
Forward data betwen Execute and Fetch1 carrying change-of-address/stream information.
static bool isStreamChange(const BranchData::Reason reason)
Is a request with this reason actually a request to change the PC rather than a bubble or branch pred...
InstSeqNum newStreamSeqNum
Sequence number of new stream/prediction to be adopted.
Reason reason
Explanation for this branch.
InstSeqNum newPredictionSeqNum
ThreadID threadId
ThreadID associated with branch.
std::unique_ptr< PCStateBase > target
Starting PC of that stream.
InstId id
Identity of the line that this request will generate.
bool isComplete() const
Is this a complete read line or fault.
bool isDiscardable() const
Is this line out of date with the current stream/prediction sequence and can it be discarded without ...
void reportData(std::ostream &os) const
Report interface.
void finish(const Fault &fault_, const RequestPtr &request_, ThreadContext *tc, BaseMMU::Mode mode)
Interface for ITLB responses.
Addr pc
PC to fixup with line address.
void makePacket()
Make a packet to use with the memory transaction.
Fault fault
Fill in a fault if one happens during fetch, check this by picking apart the response packet.
RequestPtr request
The underlying request that this fetch represents.
PacketPtr packet
FetchRequests carry packets while they're in the requests and transfers responses queues.
FetchState
Cycle-by-cycle state.
unsigned int numFetchesInITLB
Number of requests inside the ITLB rather than in the queues.
Fetch1(const std::string &name_, MinorCPU &cpu_, const BaseMinorCPUParams ¶ms, Latch< BranchData >::Output inp_, Latch< ForwardLineData >::Input out_, Latch< BranchData >::Output prediction_, std::vector< InputBuffer< ForwardLineData > > &next_stage_input_buffer)
virtual void recvReqRetry()
void changeStream(const BranchData &branch)
Start fetching from a new address.
void minorTraceResponseLine(const std::string &name, FetchRequestPtr response) const
Print the appropriate MinorLine line for a fetch response.
unsigned int numFetchesInMemorySystem
Count of the number fetches which have left the transfers queue and are in the 'wild' in the memory s...
Latch< BranchData >::Output inp
Input port carrying branch requests from Execute.
ThreadID getScheduledThread()
Use the current threading policy to determine the next thread to fetch from.
void tryToSendToTransfers(FetchRequestPtr request)
Try and issue a fetch for a translated request at the head of the requests queue.
void popAndDiscard(FetchQueue &queue)
Pop a request from the given queue and correctly deallocate and discard it.
std::vector< Fetch1ThreadInfo > fetchInfo
IcacheState icacheState
Retry state of icache_port.
virtual bool recvTimingResp(PacketPtr pkt)
Memory interface.
IcachePort icachePort
IcachePort to pass to the CPU.
Addr lineSnap
Line snap size in bytes.
std::vector< InputBuffer< ForwardLineData > > & nextStageReserve
Interface to reserve space in the next stage.
Addr maxLineWidth
Maximum fetch width in bytes.
void wakeupFetch(ThreadID tid)
Initiate fetch1 fetching.
friend std::ostream & operator<<(std::ostream &os, Fetch1::FetchState state)
bool tryToSend(FetchRequestPtr request)
Try to send (or resend) a memory request's next/only packet to the memory system.
void handleTLBResponse(FetchRequestPtr response)
Handle pushing a TLB response onto the right queue.
bool isDrained()
Is this stage drained? For Fetch1, draining is initiated by Execute signalling a branch with the reas...
Latch< BranchData >::Output prediction
Input port carrying branch predictions from Fetch2.
void evaluate()
Pass on input/buffer data to the output if you can.
unsigned int fetchLimit
Maximum number of fetches allowed in flight (in queues or memory)
void processResponse(FetchRequestPtr response, ForwardLineData &line)
Convert a response to a ForwardLineData.
unsigned int numInFlightFetches()
Returns the total number of queue occupancy, in-ITLB and in-memory system fetches.
MinorCPU & cpu
Construction-assigned data members.
FetchQueue transfers
Queue of in-memory system requests and responses.
void stepQueues()
Step requests along between requests and transfers queues.
void updateExpectedSeqNums(const BranchData &branch)
Update streamSeqNum and predictionSeqNum from the given branch (and assume these have changed and dis...
InstSeqNum lineSeqNum
Sequence number for line fetch used for ordering lines to flush.
void fetchLine(ThreadID tid)
Insert a line fetch into the requests.
Latch< ForwardLineData >::Input out
Output port carrying read lines to Fetch2.
FetchQueue requests
Queue of address translated requests from Fetch1.
void moveFromRequestsToTransfers(FetchRequestPtr request)
Move a request between queues.
IcacheState
State of memory access for head instruction fetch.
Line fetch data in the forward direction.
void setFault(Fault fault_)
Set fault and possible clear the bubble flag.
void adoptPacketData(Packet *packet)
Use the data from a packet as line instead of allocating new space.
Addr fetchAddr
Address of this line of data.
InstId id
Thread, stream, prediction ... id of this line.
std::unique_ptr< PCStateBase > pc
PC of the first inst within this sequence.
Addr lineBaseAddr
First byte address in the line.
Id for lines and instructions.
ThreadID threadId
The thread to which this line/instruction belongs.
bool empty() const
Is the queue empty?
void pop()
Pop the head item.
unsigned int occupiedSpace() const
Number of slots already occupied in this buffer.
ElemType & front()
Head value.
void reserve()
Reserve space in the queue for future pushes.
void push(ElemType &data)
Push an element into the buffer if it isn't a bubble.
Fetch1 is responsible for fetching "lines" from memory and passing them to Fetch2.
#define panic(...)
This implements a cprintf based panic() function.
#define fatal(...)
This implements a cprintf based fatal() function.
std::ostream & operator<<(std::ostream &os, const InstId &id)
Print this id in the usual slash-separated format expected by MinorTrace.
void minorTrace(const char *fmt, Args ...args)
DPRINTFN for MinorTrace reporting.
void minorLine(const Named &named, const char *fmt, Args ...args)
DPRINTFN for MinorTrace MinorLine line reporting.
Copyright (c) 2024 - Pranith Kumar Copyright (c) 2020 Inria All rights reserved.
std::shared_ptr< FaultBase > Fault
int16_t ThreadID
Thread index/ID type.
T safe_cast(U &&ref_or_ptr)
std::shared_ptr< Request > RequestPtr
const ThreadID InvalidThreadID
uint64_t Addr
Address type This will probably be moved somewhere else in the near future.
constexpr decltype(nullptr) NoFault
Minor contains all the definitions within the MinorCPU apart from the CPU class itself.
The constructed pipeline.
Stage cycle-by-cycle state.
std::unique_ptr< PCStateBase > pc
Fetch PC value.
InstSeqNum streamSeqNum
Stream sequence number.
InstSeqNum predictionSeqNum
Prediction sequence number.
bool blocked
Blocked indication for report.
bool wakeupGuard
Signal to guard against sleeping first cycle of wakeup.
Addr fetchAddr
The address we're currently fetching lines from.