gem5  v19.0.0.0
All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Modules Pages
scoreboard.cc
Go to the documentation of this file.
1 /*
2  * Copyright (c) 2013-2014, 2016-2017 ARM Limited
3  * All rights reserved
4  *
5  * The license below extends only to copyright in the software and shall
6  * not be construed as granting a license to any other intellectual
7  * property including but not limited to intellectual property relating
8  * to a hardware implementation of the functionality of the software
9  * licensed hereunder. You may use the software subject to the license
10  * terms below provided that you ensure that this notice is replicated
11  * unmodified and in its entirety in all distributions of the software,
12  * modified or unmodified, in source code or in binary form.
13  *
14  * Redistribution and use in source and binary forms, with or without
15  * modification, are permitted provided that the following conditions are
16  * met: redistributions of source code must retain the above copyright
17  * notice, this list of conditions and the following disclaimer;
18  * redistributions in binary form must reproduce the above copyright
19  * notice, this list of conditions and the following disclaimer in the
20  * documentation and/or other materials provided with the distribution;
21  * neither the name of the copyright holders nor the names of its
22  * contributors may be used to endorse or promote products derived from
23  * this software without specific prior written permission.
24  *
25  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
26  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
27  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
28  * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
29  * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
30  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
31  * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
32  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
33  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
34  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
35  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
36  *
37  * Authors: Andrew Bardsley
38  */
39 
40 #include "cpu/minor/scoreboard.hh"
41 
42 #include "arch/registers.hh"
43 #include "cpu/reg_class.hh"
44 #include "debug/MinorScoreboard.hh"
45 #include "debug/MinorTiming.hh"
46 
47 namespace Minor
48 {
49 
50 bool
51 Scoreboard::findIndex(const RegId& reg, Index &scoreboard_index)
52 {
53  bool ret = false;
54 
55  if (reg.isZeroReg()) {
56  /* Don't bother with the zero register */
57  ret = false;
58  } else {
59  switch (reg.classValue())
60  {
61  case IntRegClass:
62  scoreboard_index = reg.index();
63  ret = true;
64  break;
65  case FloatRegClass:
66  scoreboard_index = TheISA::NumIntRegs + TheISA::NumCCRegs +
67  reg.index();
68  ret = true;
69  break;
70  case VecRegClass:
71  scoreboard_index = TheISA::NumIntRegs + TheISA::NumCCRegs +
73  ret = true;
74  break;
75  case VecElemClass:
76  scoreboard_index = TheISA::NumIntRegs + TheISA::NumCCRegs +
78  ret = true;
79  break;
80  case VecPredRegClass:
81  scoreboard_index = TheISA::NumIntRegs + TheISA::NumCCRegs +
83  ret = true;
84  break;
85  case CCRegClass:
86  scoreboard_index = TheISA::NumIntRegs + reg.index();
87  ret = true;
88  break;
89  case MiscRegClass:
90  /* Don't bother with Misc registers */
91  ret = false;
92  break;
93  default:
94  panic("Unknown register class: %d",
95  static_cast<int>(reg.classValue()));
96  }
97  }
98 
99  return ret;
100 }
101 
103 static RegId
104 flattenRegIndex(const RegId& reg, ThreadContext *thread_context)
105 {
106  return thread_context->flattenRegId(reg);
107 }
108 
109 void
111  ThreadContext *thread_context, bool mark_unpredictable)
112 {
113  if (inst->isFault())
114  return;
115 
116  StaticInstPtr staticInst = inst->staticInst;
117  unsigned int num_dests = staticInst->numDestRegs();
118 
120  for (unsigned int dest_index = 0; dest_index < num_dests;
121  dest_index++)
122  {
124  staticInst->destRegIdx(dest_index), thread_context);
125  Index index;
126 
127  if (findIndex(reg, index)) {
128  if (mark_unpredictable)
130 
131  inst->flatDestRegIdx[dest_index] = reg;
132 
133  numResults[index]++;
134  returnCycle[index] = retire_time;
135  /* We should be able to rely on only being given accending
136  * execSeqNums, but sanity check */
137  if (inst->id.execSeqNum > writingInst[index]) {
138  writingInst[index] = inst->id.execSeqNum;
139  fuIndices[index] = inst->fuIndex;
140  }
141 
142  DPRINTF(MinorScoreboard, "Marking up inst: %s"
143  " regIndex: %d final numResults: %d returnCycle: %d\n",
144  *inst, index, numResults[index], returnCycle[index]);
145  } else {
146  /* Use ZeroReg to mark invalid/untracked dests */
147  inst->flatDestRegIdx[dest_index] = RegId(IntRegClass,
149  }
150  }
151 }
152 
155  ThreadContext *thread_context)
156 {
157  InstSeqNum ret = 0;
158 
159  if (inst->isFault())
160  return ret;
161 
162  StaticInstPtr staticInst = inst->staticInst;
163  unsigned int num_srcs = staticInst->numSrcRegs();
164 
165  for (unsigned int src_index = 0; src_index < num_srcs; src_index++) {
166  RegId reg = flattenRegIndex(staticInst->srcRegIdx(src_index),
167  thread_context);
168  unsigned short int index;
169 
170  if (findIndex(reg, index)) {
171  if (writingInst[index] > ret)
172  ret = writingInst[index];
173  }
174  }
175 
176  DPRINTF(MinorScoreboard, "Inst: %s depends on execSeqNum: %d\n",
177  *inst, ret);
178 
179  return ret;
180 }
181 
182 void
183 Scoreboard::clearInstDests(MinorDynInstPtr inst, bool clear_unpredictable)
184 {
185  if (inst->isFault())
186  return;
187 
188  StaticInstPtr staticInst = inst->staticInst;
189  unsigned int num_dests = staticInst->numDestRegs();
190 
192  for (unsigned int dest_index = 0; dest_index < num_dests;
193  dest_index++)
194  {
195  const RegId& reg = inst->flatDestRegIdx[dest_index];
196  Index index;
197 
198  if (findIndex(reg, index)) {
199  if (clear_unpredictable && numUnpredictableResults[index] != 0)
201 
202  numResults[index] --;
203 
204  if (numResults[index] == 0) {
205  returnCycle[index] = Cycles(0);
206  writingInst[index] = 0;
207  fuIndices[index] = -1;
208  }
209 
210  DPRINTF(MinorScoreboard, "Clearing inst: %s"
211  " regIndex: %d final numResults: %d\n",
212  *inst, index, numResults[index]);
213  }
214  }
215 }
216 
217 bool
219  const std::vector<Cycles> *src_reg_relative_latencies,
220  const std::vector<bool> *cant_forward_from_fu_indices,
221  Cycles now, ThreadContext *thread_context)
222 {
223  /* Always allow fault to be issued */
224  if (inst->isFault())
225  return true;
226 
227  StaticInstPtr staticInst = inst->staticInst;
228  unsigned int num_srcs = staticInst->numSrcRegs();
229 
230  /* Default to saying you can issue */
231  bool ret = true;
232 
233  unsigned int num_relative_latencies = 0;
234  Cycles default_relative_latency = Cycles(0);
235 
236  /* Where relative latencies are given, the default is the last
237  * one as that allows the rel. lat. list to be shorted than the
238  * number of src. regs */
239  if (src_reg_relative_latencies &&
240  src_reg_relative_latencies->size() != 0)
241  {
242  num_relative_latencies = src_reg_relative_latencies->size();
243  default_relative_latency = (*src_reg_relative_latencies)
244  [num_relative_latencies-1];
245  }
246 
247  /* For each source register, find the latest result */
248  unsigned int src_index = 0;
249  while (src_index < num_srcs && /* More registers */
250  ret /* Still possible */)
251  {
252  RegId reg = flattenRegIndex(staticInst->srcRegIdx(src_index),
253  thread_context);
254  unsigned short int index;
255 
256  if (findIndex(reg, index)) {
257  bool cant_forward = fuIndices[index] != 1 &&
258  cant_forward_from_fu_indices &&
259  index < cant_forward_from_fu_indices->size() &&
260  (*cant_forward_from_fu_indices)[index];
261 
262  Cycles relative_latency = (cant_forward ? Cycles(0) :
263  (src_index >= num_relative_latencies ?
264  default_relative_latency :
265  (*src_reg_relative_latencies)[src_index]));
266 
267  if (returnCycle[index] > (now + relative_latency) ||
269  {
270  ret = false;
271  }
272  }
273  src_index++;
274  }
275 
276  if (DTRACE(MinorTiming)) {
277  if (ret && num_srcs > num_relative_latencies &&
278  num_relative_latencies != 0)
279  {
280  DPRINTF(MinorTiming, "Warning, inst: %s timing extra decode has"
281  " more src. regs: %d than relative latencies: %d\n",
282  staticInst->disassemble(0), num_srcs, num_relative_latencies);
283  }
284  }
285 
286  return ret;
287 }
288 
289 void
291 {
292  std::ostringstream result_stream;
293 
294  bool printed_element = false;
295 
296  unsigned int i = 0;
297  while (i < numRegs) {
298  unsigned short int num_results = numResults[i];
299  unsigned short int num_unpredictable_results =
301 
302  if (!(num_results == 0 && num_unpredictable_results == Cycles(0))) {
303  if (printed_element)
304  result_stream << ',';
305 
306  result_stream << '(' << i << ','
307  << num_results << '/'
308  << num_unpredictable_results << '/'
309  << returnCycle[i] << '/'
310  << writingInst[i] << ')';
311 
312  printed_element = true;
313  }
314 
315  i++;
316  }
317 
318  MINORTRACE("busy=%s\n", result_stream.str());
319 }
320 
321 }
std::vector< Index > numUnpredictableResults
Count of the number of results which can&#39;t be predicted.
Definition: scoreboard.hh:78
#define panic(...)
This implements a cprintf based panic() function.
Definition: logging.hh:167
#define DPRINTF(x,...)
Definition: trace.hh:229
Bitfield< 30, 0 > index
int8_t numSrcRegs() const
Number of source registers.
Definition: static_inst.hh:133
Bitfield< 5, 3 > reg
Definition: types.hh:89
Cycles is a wrapper class for representing cycle counts, i.e.
Definition: types.hh:83
Floating-point register.
Definition: reg_class.hh:58
Bitfield< 7 > i
Control (misc) register.
Definition: reg_class.hh:65
unsigned short int Index
Type to use when indexing numResults.
Definition: scoreboard.hh:71
const int NumFloatRegs
Definition: registers.hh:94
virtual const std::string & disassemble(Addr pc, const SymbolTable *symtab=0) const
Return string representation of disassembled instruction.
Definition: static_inst.cc:123
int8_t numDestRegs() const
Number of destination registers.
Definition: static_inst.hh:135
const RegId & srcRegIdx(int i) const
Return logical index (architectural reg num) of i&#39;th source reg.
Definition: static_inst.hh:220
Minor contains all the definitions within the MinorCPU apart from the CPU class itself.
Definition: activity.cc:46
ThreadContext is the external interface to all thread state for anything outside of the CPU...
std::vector< int > fuIndices
Index of the FU generating this result.
Definition: scoreboard.hh:81
Vector Register Native Elem lane.
Definition: reg_class.hh:62
std::vector< InstSeqNum > writingInst
The execute sequence number of the most recent inst to generate this register value.
Definition: scoreboard.hh:91
void clearInstDests(MinorDynInstPtr inst, bool clear_unpredictable)
Clear down the dependencies for this instruction.
Definition: scoreboard.cc:183
#define DTRACE(x)
Definition: trace.hh:227
const int NumCCRegs
Definition: registers.hh:99
void markupInstDests(MinorDynInstPtr inst, Cycles retire_time, ThreadContext *thread_context, bool mark_unpredictable)
Mark up an instruction&#39;s effects by incrementing numResults counts.
Definition: scoreboard.cc:110
const RegIndex ZeroReg
Definition: registers.hh:75
Condition-code register.
Definition: reg_class.hh:64
void minorTrace() const
MinorTraceIF interface.
Definition: scoreboard.cc:290
A simple instruction scoreboard for tracking dependencies in Execute.
uint64_t InstSeqNum
Definition: inst_seq.hh:40
bool canInstIssue(MinorDynInstPtr inst, const std::vector< Cycles > *src_reg_relative_latencies, const std::vector< bool > *cant_forward_from_fu_indices, Cycles now, ThreadContext *thread_context)
Can this instruction be issued.
Definition: scoreboard.cc:218
InstSeqNum execSeqNumToWaitFor(MinorDynInstPtr inst, ThreadContext *thread_context)
Returns the exec sequence number of the most recent inst on which the given inst depends.
Definition: scoreboard.cc:154
std::vector< Index > numResults
Count of the number of in-flight instructions that have results for each register.
Definition: scoreboard.hh:75
const RegClass & classValue() const
Class accessor.
Definition: reg_class.hh:206
RegIndex flatIndex() const
Index flattening.
Definition: reg_class.hh:185
#define MINORTRACE(...)
DPRINTFN for MinorTrace reporting.
Definition: trace.hh:62
const RegIndex & index() const
Index accessors.
Definition: reg_class.hh:179
virtual RegId flattenRegId(const RegId &regId) const =0
static RegId flattenRegIndex(const RegId &reg, ThreadContext *thread_context)
Flatten a RegId, irrespective of what reg type it&#39;s pointing to.
Definition: scoreboard.cc:104
const RegId & destRegIdx(int i) const
Return logical index (architectural reg num) of i&#39;th destination reg.
Definition: static_inst.hh:216
Register ID: describe an architectural register with its class and index.
Definition: reg_class.hh:79
Integer register.
Definition: reg_class.hh:57
Vector Register.
Definition: reg_class.hh:60
bool findIndex(const RegId &reg, Index &scoreboard_index)
Sets scoreboard_index to the index into numResults of the given register index.
Definition: scoreboard.cc:51
std::vector< Cycles > returnCycle
The estimated cycle number that the result will be presented.
Definition: scoreboard.hh:87
bool isZeroReg() const
Check if this is the zero register.
Definition: reg_class.hh:141
const unsigned numRegs
The number of registers in the Scoreboard.
Definition: scoreboard.hh:68
const int NumVecRegs
Definition: registers.hh:95
const int NumIntRegs
Definition: registers.hh:93

Generated on Fri Feb 28 2020 16:26:59 for gem5 by doxygen 1.8.13