44 #include "arch/decoder.hh"
45 #include "arch/utility.hh"
48 #include "debug/Branch.hh"
49 #include "debug/Fetch.hh"
50 #include "debug/MinorTrace.hh"
57 MinorCPUParams ¶ms,
66 branchInp(branchInp_),
67 predictionOut(predictionOut_),
69 nextStageReserve(next_stage_input_buffer),
70 outputWidth(params.decodeInputWidth),
71 processMoreThanOneInput(params.fetch2CycleInput),
72 branchPredictor(*params.branchPred),
73 fetchInfo(params.numThreads),
79 if (params.fetch2InputBufferSize < 1) {
80 fatal(
"%s: fetch2InputBufferSize must be >= 1 (%d)\n", name,
81 params.fetch2InputBufferSize);
85 for (
ThreadID tid = 0; tid < params.numThreads; tid++) {
88 name +
".inputBuffer" + std::to_string(tid),
"lines",
89 params.fetch2InputBufferSize));
118 DPRINTF(Fetch,
"Dumping whole input buffer\n");
131 if (inst->isFault() || !inst->triedToPredict)
153 DPRINTF(Branch,
"Unpredicted branch seen inst: %s\n", *inst);
155 branch.
target,
true, inst->id.threadId);
163 DPRINTF(Branch,
"Branch predicted correctly inst: %s\n", *inst);
169 DPRINTF(Branch,
"Branch mis-predicted inst: %s\n", *inst);
171 branch.
target ,
false, inst->id.threadId);
179 DPRINTF(Branch,
"Branch mis-predicted target inst: %s target: %s\n",
182 branch.
target,
true, inst->id.threadId);
193 assert(!inst->predictedTaken);
196 if (inst->staticInst->isControl() ||
197 inst->staticInst->isSyscall())
200 inst->triedToPredict =
true;
202 DPRINTF(Branch,
"Trying to predict for inst: %s\n", *inst);
205 inst->id.fetchSeqNum, inst_pc,
208 inst->predictedTaken =
true;
209 inst->predictedTarget = inst_pc;
213 DPRINTF(Branch,
"Not attempting prediction for inst: %s\n", *inst);
217 if (inst->predictedTaken) {
225 inst->predictedTarget, inst);
232 DPRINTF(Branch,
"Branch predicted taken inst: %s target: %s"
233 " new predictionSeqNum: %d\n",
242 if (!
inp.outputWire->isBubble())
258 DPRINTF(Fetch,
"Dumping all input as a stream changing branch"
267 for (
ThreadID tid = 0; tid <
cpu.numThreads; tid++) {
278 DPRINTF(Fetch,
"Discarding line %s"
279 " due to predictionSeqNum mismatch (expected: %d)\n",
295 DPRINTF(Fetch,
"Scheduled Thread: %d\n", tid);
303 unsigned int output_index = 0;
328 if (!discard_line && (!fetch_info.
havePC || set_pc)) {
332 (line_in->
pc.instAddr() & BaseCPU::PCMask) -
334 DPRINTF(Fetch,
"Setting new PC value: %s inputIndex: 0x%x"
335 " lineBaseAddr: 0x%x lineWidth: 0x%x\n",
338 fetch_info.
pc = line_in->
pc;
350 DPRINTF(Fetch,
"Discarding line %s (from inputIndex: %d)"
351 " due to predictionSeqNum mismatch (expected: %d)\n",
354 }
else if (line_in->
isFault()) {
366 assert(dyn_inst->id.execSeqNum == 0);
368 dyn_inst->pc = fetch_info.
pc;
373 dyn_inst->fault = line_in->
fault;
374 DPRINTF(Fetch,
"Fault being passed output_index: "
375 "%d: %s\n", output_index, dyn_inst->fault->name());
377 uint8_t *line = line_in->
line;
383 *(reinterpret_cast<TheISA::MachInst *>
386 if (!decoder->instReady()) {
387 decoder->moreBytes(fetch_info.
pc,
390 DPRINTF(Fetch,
"Offering MachInst to decoder addr: 0x%x\n",
397 if (decoder->instReady()) {
407 assert(dyn_inst->id.execSeqNum == 0);
413 dyn_inst->staticInst = decoded_inst;
415 dyn_inst->pc = fetch_info.
pc;
416 DPRINTF(Fetch,
"decoder inst %s\n", *dyn_inst);
419 DPRINTF(Fetch,
"Instruction extracted from line %s"
420 " lineWidth: %d output_index: %d inputIndex: %d"
421 " pc: %s inst: %s\n",
424 fetch_info.
pc, *dyn_inst);
426 #if THE_ISA == X86_ISA || THE_ISA == ARM_ISA
441 fetch_info.
pc.upc(0);
442 fetch_info.
pc.nupc(1);
452 DPRINTF(Fetch,
"Inst not ready yet\n");
457 if (decoder->needMoreBytes()) {
460 DPRINTF(Fetch,
"Updated inputIndex value PC: %s"
461 " inputIndex: 0x%x lineBaseAddr: 0x%x lineWidth: 0x%x\n",
472 if (output_index == 0) {
476 insts_out.
insts[output_index] = dyn_inst;
481 if (
DTRACE(MinorTrace) && !dyn_inst->isFault() &&
482 dyn_inst->staticInst->isMacroop())
484 dyn_inst->minorTraceInst(*
this);
497 DPRINTF(Fetch,
"Discarding all input on branch/fault\n");
499 fetch_info.
havePC =
false;
501 }
else if (discard_line) {
506 fetch_info.
havePC =
false;
550 if (!
inp.outputWire->isBubble())
561 case Enums::SingleThreaded:
562 priority_list.push_back(0);
564 case Enums::RoundRobin:
571 panic(
"Unknown fetch policy");
574 for (
auto tid : priority_list) {
592 return (*
inp.outputWire).isBubble() &&
599 std::ostringstream
data;
604 (*
out.inputWire).reportData(data);
606 MINORTRACE(
"inputIndex=%d havePC=%d predictionSeqNum=%d insts=%s\n",
InstSeqNum fetchSeqNum
Fetch2 is the source of fetch sequence numbers.
MinorDynInstPtr inst
Instruction which caused this branch.
Latch< BranchData >::Output branchInp
Input port carrying branches from Execute.
virtual TheISA::Decoder * getDecoderPtr()=0
Latch< ForwardInstData >::Input out
Output port carrying instructions into Decode.
const std::string & name()
bool processMoreThanOneInput
If true, more than one input word can be processed each cycle if there is room in the output to conta...
Addr lineBaseAddr
First byte address in the line.
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...
bool isFault() const
This is a fault, not a line.
ThreadID threadId
ThreadID associated with branch.
std::vector< InputBuffer< ForwardLineData > > inputBuffer
Line fetch data in the forward direction.
Reason reason
Explanation for this branch.
void activity()
Records that there is activity this cycle.
TheISA::PCState pc
Remembered program counter value.
Latch< BranchData >::Input predictionOut
Output port carrying predictions back to Fetch1.
std::vector< Fetch2ThreadInfo > fetchInfo
void update(const InstSeqNum &done_sn, ThreadID tid)
Tells the branch predictor to commit any updates until the given sequence number. ...
TheISA::PCState pc
PC of the first requested inst within this line.
Fetch2 receives lines of data from Fetch1, separates them into instructions and passes them to Decode...
ThreadContext is the external interface to all thread state for anything outside of the CPU...
unsigned int outputWidth
Width of output of this stage/input of next in instructions.
InstSeqNum predictionSeqNum
The predicted qualifier to stream, attached by Fetch2 as a consequence of branch prediction.
bool isDrained()
Is this stage drained? For Fetch2, draining is initiated by Execute halting Fetch1 causing Fetch2 to ...
MinorCPU & cpu
Pointer back to the containing CPU.
bool isBubble() const
BubbleIF interface.
InstSeqNum predictionSeqNum
Fetch2 is the source of prediction sequence numbers.
void popInput(ThreadID tid)
Pop an element off the input buffer, if there are any.
void activateStage(const int idx)
Marks a stage as active.
std::vector< ThreadID > randomPriority()
void resize(unsigned int width)
Resize a bubble/empty ForwardInstData and fill with bubbles.
MinorDynInstPtr insts[MAX_FORWARD_INSTS]
Array of carried insts, ref counted.
bool predict(const StaticInstPtr &inst, const InstSeqNum &seqNum, TheISA::PCState &pc, ThreadID tid)
Predicts whether or not the instruction is a taken branch, and the target of the branch if it is take...
Minor::MinorActivityRecorder * activityRecorder
Activity recording for pipeline.
unsigned int lineWidth
Explicit line width, don't rely on data.size.
InstId id
Thread, stream, prediction ...
void advancePC(PCState &pc, const StaticInstPtr &inst)
std::vector< ThreadID > roundRobinPriority(ThreadID priority)
Thread scheduling utility functions.
const ThreadID InvalidThreadID
void predictBranch(MinorDynInstPtr inst, BranchData &branch)
Predicts branches for the given instruction.
InstSeqNum streamSeqNum
The 'stream' this instruction belongs to.
int16_t ThreadID
Thread index/ID type.
unsigned int inputIndex
Index into an incompletely processed input line that instructions are to be extracted from...
InstSeqNum lastStreamSeqNum
Stream sequence number of the last seen line used to identify changes of instruction stream...
Dynamic instruction for Minor.
Forward data betwen Execute and Fetch1 carrying change-of-address/stream information.
Enums::ThreadPolicy threadPolicy
Thread Scheduling Policy (RoundRobin, Random, etc)
ThreadID getScheduledThread()
Use the current threading policy to determine the next thread to fetch from.
GenericISA::SimplePCState< MachInst > PCState
void dumpAllInput(ThreadID tid)
Dump the whole contents of the input buffer.
InstSeqNum expectedStreamSeqNum
Stream sequence number remembered from last time the predictionSeqNum changed.
Data members after this line are cycle-to-cycle state.
#define MINORTRACE(...)
DPRINTFN for MinorTrace reporting.
std::vector< InputBuffer< ForwardInstData > > & nextStageReserve
Interface to reserve space in the next stage.
Fault fault
This line has a fault.
Latch< ForwardLineData >::Output inp
Input port carrying lines from Fetch1.
The constructed pipeline.
BPredUnit & branchPredictor
Branch predictor passed from Python configuration.
void squash(const InstSeqNum &squashed_sn, ThreadID tid)
Squashes all outstanding updates until a given sequence number.
Fetch2(const std::string &name, MinorCPU &cpu_, MinorCPUParams ¶ms, Latch< ForwardLineData >::Output inp_, Latch< BranchData >::Output branchInp_, Latch< BranchData >::Input predictionOut_, Latch< ForwardInstData >::Input out_, std::vector< InputBuffer< ForwardInstData >> &next_stage_input_buffer)
void updateBranchPrediction(const BranchData &branch)
Update local branch prediction structures from feedback from Execute.
const ForwardLineData * getInput(ThreadID tid)
Get a piece of data to work on from the inputBuffer, or 0 if there is no data.
MinorCPU is an in-order CPU model with four fixed pipeline stages:
TheISA::PCState target
Starting PC of that stream.
bool blocked
Blocked indication for report.
bool havePC
PC is currently valid.
ThreadID threadId
The thread to which this line/instruction belongs.
Forward flowing data between Fetch2,Decode,Execute carrying a packet of instructions of a width appro...
void evaluate()
Pass on input/buffer data to the output if you can.
ThreadID threadId
Thread associated with these instructions.