forked from dotcom900825/cse240
-
Notifications
You must be signed in to change notification settings - Fork 0
/
memQueue.C
120 lines (91 loc) · 2.65 KB
/
memQueue.C
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
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
#include "memQueue.h"
#include "mem-sim.h"
#include "cache.h"
#include <stdlib.h>
#include <stdio.h>
void memQueue::printQueue() {
int i = _front;
while(i != _rear) {
printf("addr: %x, ready at: %u\n",_queue[i].addr,_readyTime[i]);
i++;
if(i == _capacity) i = 0;
}
}
int memQueue::findDup(u_int32_t tag, u_int32_t index) {
int dupLoc = -1;
int i = _front;
while(i != _rear) {
if(_tags[i] == tag && _indexes[i] == index) dupLoc = i;
i++;
if(i == _capacity) i = 0;
}
return dupLoc;
}
memQueue::memQueue(u_int32_t capacity, Cache *c, u_int32_t latency, bool pipelined, bool write, char name) {
_id = name;
_capacity = capacity;
_source = c;
_latency = latency;
_pipelined = pipelined;
_write = write;
_front = 0;
_rear = 0;
_size = 0;
_queue = (Request*)calloc(_capacity, sizeof(Request));
_readyTime = (u_int32_t*)calloc(_capacity, sizeof(u_int32_t));
_tags = (u_int32_t*)calloc(_capacity, sizeof(u_int32_t));
_indexes = (u_int32_t*)calloc(_capacity, sizeof(u_int32_t));
}
memQueue::~memQueue() {
free(_queue);
free(_readyTime);
free(_tags);
free(_indexes);
}
bool memQueue::add(Request req, u_int32_t cycle) {
bool success = true;
u_int32_t tag, index;
if(_size == _capacity) success = false;
else {
// first check to see if this is a duplicate
index = _source->getIndex(req.addr);
tag = _source->getTag(req.addr);
int dupLoc = findDup(tag,index); // see if there is a duplicate request (-1 = not found)
if(dupLoc == -1||_queue[dupLoc].fromCPU) { // no duplicate found
_queue[_rear] = req;
_tags[_rear] = tag;
_indexes[_rear] = index;
// pipelined will be ready _latency cycles after entering the queue
if(_pipelined || _size == 0) _readyTime[_rear] = cycle + _latency;
else { // will be ready _latency cycles after the last item in the queue
int i = _rear - 1;
if(i < 0) i = _capacity - 1;
_readyTime[_rear] = _latency + _readyTime[i];
}
//printf("adding to %c: readyTime is %u\n",_id,_readyTime[_rear]);
_size++; // increase size
_rear++; // move rear
if(_rear == _capacity) _rear = 0;
}
else if(req.fromCPU) { // if our new request is from the CPU, we want to replace the old duplicate
_queue[dupLoc] = req;
}
}
return success;
}
bool memQueue::remove() {
bool success = true;
if(_size == 0) success = false;
else {
_size--; // decrease size
_front++; // move front
if(_front == _capacity) _front = 0;
}
return success;
}
u_int32_t memQueue::getSize() { return _size; }
bool memQueue::frontReady(u_int32_t cycle) {
if(_size > 0 && _readyTime[_front] <= cycle) return true;
else return false;
}
Request memQueue::getFront() { return _queue[_front]; }