-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathstage.cpp
103 lines (93 loc) · 3.08 KB
/
stage.cpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
#include <cassert>
#include "stage.h"
#include "fetch.h"
#include "decode.h"
#include "execute.h"
#include "memaccess.h"
#include "writeback.h"
AbstractStage::getPcPtr AbstractStage::getPc = NULL;
AbstractStage::setPcPtr AbstractStage::setPc = NULL;
AbstractStage::getNextInsPtr AbstractStage::getNextIns = NULL;
AbstractStage::getRegPtr AbstractStage::getReg = NULL;
AbstractStage::setRegPtr AbstractStage::setReg = NULL;
AbstractStage::getDataPtr AbstractStage::getData = NULL;
AbstractStage::setDataPtr AbstractStage::setData = NULL;
AbstractStage::setStopSimulationPtr AbstractStage::stopSimulation = NULL;
AbstractStage::getCyclePtr AbstractStage::getCycle = NULL;
AbstractStage::incStatisticsPtr AbstractStage::incStatistics = NULL;
AbstractStage::AbstractStage(StageType _type, AbstractStage *_prevStage) : stalled(false), type(_type),
prevStage(_prevStage) {
if (prevStage != NULL)
prevStage->nextStage = this;
nextStage = NULL;
}
AbstractStage* AbstractStage::createStage(StageType _type, AbstractStage *_prevStage) {
// Create a new stage of type _type and set the previous stage to _prevStage
// Return the newly created stage
AbstractStage *newStage;
switch(_type) {
case IF:
newStage = new FetchStage(_type, _prevStage);
break;
case ID:
newStage = new DecodeStage(_type, _prevStage);
break;
case EX:
newStage = new ExecuteStage(_type, _prevStage);
break;
case MEM:
newStage = new MemaccessStage(_type, _prevStage);
break;
case WR:
newStage = new WritebackStage(_type, _prevStage);
break;
default:
cout << "Incorrect stage type!" << endl;
assert(0);
break;
}
return newStage; //NULL;
}
void AbstractStage::setStalled() {
stalled = true;
if (prevStage)
prevStage->setStalled();
}
void AbstractStage::setUnstalled() {
stalled = false;
if (prevStage)
prevStage->setUnstalled();
}
void AbstractStage::updateDependences(int _srcCycle) {
// This function is used to notify (and possibly unstall) the consumer instruction that was stalled
// due to the current instruction (i.e., producer instruction) of this stage
AbstractStage* checkStages = prevStage;
while(checkStages!= NULL) {
//check if instruction is the one stalled
//if instruction is halt, left stalled
if(!checkStages->getInstruction().isHlt() && checkStages->isStalled()) {
if(checkStages->getInstruction().getSrcCycle1() == _srcCycle) {
checkStages->getInstruction().setSrcCycle1(0);
}
if(checkStages->getInstruction().getSrcCycle2() == _srcCycle) {
checkStages->getInstruction().setSrcCycle2(0);
}
if(checkStages->getInstruction().getSrcCycle1() == 0 &&
checkStages->getInstruction().getSrcCycle2() == 0) {
checkStages->setUnstalled();
}
else {
break; // if could not remove stall from this stage exit the loop
}
}
checkStages = checkStages->getPrevStage();
}
}
void AbstractStage::setInstruction(Instruction& _ins) {
ins = _ins;
}
Instruction& AbstractStage::getInstruction() {
return ins;
}
AbstractStage::~AbstractStage() {
}