50#include "debug/Drain.hh"
51#include "debug/Fetch.hh"
52#include "debug/MinorTrace.hh"
62 const BaseMinorCPUParams ¶ms,
73 icachePort(name_ +
".icache_port", *this, cpu_),
74 lineSnap(params.fetch1LineSnapWidth),
79 requests(name_ +
".requests",
"lines", params.fetch1FetchLimit),
80 transfers(name_ +
".transfers",
"lines", params.fetch1FetchLimit),
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_,
128 switch (
cpu.threadPolicy) {
129 case enums::SingleThreaded:
130 priority_list.push_back(0);
132 case enums::RoundRobin:
136 priority_list =
cpu.randomPriority();
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);
179 request->
request->setContext(
cpu.threads[tid]->getTC()->contextId());
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);
236 packet->pushSenderState(
this);
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());
584 for (
ThreadID tid = 0; tid <
cpu.numThreads; tid++)
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",
697 cpu.activityRecorder->activity();
712 thread.wakeupGuard =
false;
725 DPRINTF(Fetch,
"[tid:%d]: Changing stream wakeup %s\n", tid, *thread.
pc);
734 for (
ThreadID tid = 0; tid <
cpu.numThreads; tid++) {
736 DPRINTF(Drain,
"isDrained[tid:%d]: %s %s%s\n",
740 ((*
out.inputWire).isBubble() ?
"" :
"outputtingLine"));
771 std::ostringstream
data;
776 (*
out.inputWire).reportData(
data);
MinorCPU is an in-order CPU model with four fixed pipeline stages:
Named(std::string_view name_)
virtual std::string name() const
A Packet is used to encapsulate a transfer between two objects in the memory system (e....
bool needsResponse() const
SenderState * popSenderState()
Pop the top of the state stack and return a pointer to it.
@ 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
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 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.
Fetch1 & fetch
Owning fetch unit.
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?
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.
Queue< FetchRequestPtr, ReportTraitsPtrAdaptor< FetchRequestPtr >, NoBubbleTraits< FetchRequestPtr > > FetchQueue
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...
FetchRequest * FetchRequestPtr
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.
ElemType & front()
Head value.
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 Arm Limited 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
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.