/
memoryStage.c
153 lines (140 loc) · 2.95 KB
/
memoryStage.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
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
#include <stdbool.h>
#include "forwarding.h"
#include "bubbling.h"
#include "instructions.h"
#include "status.h"
#include "memory.h"
#include "memoryStage.h"
#include "executeStage.h"
#include "tools.h"
#include "writebackStage.h"
static mregister M;
//prototypes
static unsigned int mem_addr();
static bool mem_read();
static bool mem_write();
/*
* Returns: copy of the Mregister
*/
mregister getMregister()
{
return M;
}
/*
* clearWregister - clears Mregister
*/
void clearMregister()
{
clearBuffer((char *) &M, sizeof(M));
M.stat = SAOK;
M.icode = NOP;
}
/*
* memoryStage - writes or reads from memory when needed
* Updates values for writebackStage
*
* params - forwardType * forward, statusType* status, bubbleType* bubble
*
*/
void memoryStage(forwardType * forward, statusType* status, bubbleType* bubble)
{
unsigned int addr = mem_addr();
unsigned int valM = M.valA;
bool memError = false;
unsigned int stat = M.stat;
if(mem_write())
{
putWord(addr, valM, &memError);
}
if(mem_read())
{
valM = getWord(addr, &memError);
}
if(memError)
stat = SADR;
//forward values
forward->M_dstM = M.dstM;
forward->M_dstE = M.dstE;
forward->m_valM = valM;
forward->M_valE = M.valE;
forward->M_Cnd = M.Cnd;
forward->M_valA = M.valA;
forward->M_icode = M.icode;
status->m_stat = stat;
bubble->M_icode = M.icode;
updateWregister(stat, M.icode, M.valE, valM, M.dstE, M.dstM);
}
/*
* updateMregister- updates the memory register
*
* params unsigned int stat, unsigned int icode, unsigned int cnd,
* unsigned int valE, unsigned int valA, unsigned int valE
* unsigned int dstm
*/
void updateMregister(unsigned int stat, unsigned int icode, unsigned int Cnd,
unsigned int valE, unsigned int valA, unsigned int dstE,
unsigned int dstM)
{
M.stat = stat;
M.icode = icode;
M.Cnd = Cnd;
M.valE = valE;
M.valA = valA;
M.dstE = dstE;
M.dstM = dstM;
}
/*
* mem_addr - selects a memory address
*
* Returns: memory address
*/
unsigned int mem_addr()
{
switch(M.icode)
{
case RMMOVL:
case PUSHL:
case CALL:
case MRMOVL:
return M.valE;
case POPL:
case RET:
return M.valA;
default:
return 0;
}
}
/*
* mem_read - sets read control signal
*
* Returns: TRUE if instruction requires a read from memory
*/
bool mem_read()
{
switch(M.icode)
{
case MRMOVL:
case POPL:
case RET:
return true;
default:
return false;
}
}
/*
*mem_write - sets write control signal
*
* Returns: TRUE if instruction requires write to memory
*/
bool mem_write()
{
switch(M.icode)
{
case RMMOVL:
case PUSHL:
case CALL:
return true;
default:
return false;
}
}