21 |
#include "vmachine.h" |
#include "vmachine.h" |
22 |
|
|
23 |
vmachine::vmachine( void ) : |
vmachine::vmachine( void ) : |
24 |
|
phase_active(5), |
25 |
|
|
26 |
nPC(3), |
nPC(3), |
27 |
PC(2), IR(3), Registers(3,3),Const(2), Mpx3(2,1), |
PC(2), IR(2), Registers(3,3),Const(2), Mpx3(2,1), |
28 |
Mpx1(2,1), |
Mpx1(2,1), |
29 |
pPC(1), A1(1), A2(1), R(1), DR(1), |
pPC(1), A1(1), A2(1), R(1), DR(1), |
30 |
Mpx4(3,2), Mpx5(3,2), Mpx6(3,1), Mpx7(2,1), Shifter(1), ALU(2), |
Mpx4(3,2), Mpx5(3,2), Mpx6(3,1), Mpx7(2,1), Shifter(1), ALU(2), |
49 |
|
|
50 |
IR.link(0, Const, 0 ); |
IR.link(0, Const, 0 ); |
51 |
IR.link(1, Registers, 0 ); |
IR.link(1, Registers, 0 ); |
|
IR.link(2, DR, 0 ); |
|
52 |
|
|
53 |
Const.link(0, Add2, 1 ); |
Const.link(0, Add2, 1 ); |
54 |
Const.link(1, Mpx3, 0 ); |
Const.link(1, Mpx3, 0 ); |
119 |
|
|
120 |
} |
} |
121 |
|
|
122 |
|
void vmachine::init( vector<unsigned long> /*data*/, |
123 |
|
vector<unsigned long> /*instr*/ ) |
124 |
|
{ |
125 |
|
// loading to mem |
126 |
|
|
127 |
|
nPC.remember(0); |
128 |
|
Mpx1.set( 1 ); |
129 |
|
Mpx2.set( 1 ); |
130 |
|
|
131 |
|
phase_active[IF] = true; |
132 |
|
} |
133 |
|
|
134 |
|
void vmachine::step( void ) |
135 |
|
{ |
136 |
|
if (phase_active[WB]) |
137 |
|
do_WB(); |
138 |
|
if (phase_active[MA] ) |
139 |
|
do_MA(); |
140 |
|
if (phase_active[EX] ) |
141 |
|
do_EX(); |
142 |
|
if (phase_active[ID] ) |
143 |
|
do_ID(); |
144 |
|
if (phase_active[IF] ) |
145 |
|
do_IF(); |
146 |
|
|
147 |
|
c4.process(); |
148 |
|
Add1.process(); |
149 |
|
Add2.process(); |
150 |
|
Mpx1.process(); |
151 |
|
Mpx2.process(); |
152 |
|
nPC.remember(); |
153 |
|
} |
154 |
|
|
155 |
|
void vmachine::do_IF( void ) |
156 |
|
{ |
157 |
|
nPC.pass_through(); |
158 |
|
ICache.process(); |
159 |
|
|
160 |
|
PC.remember(); |
161 |
|
IR.remember(); |
162 |
|
|
163 |
|
phase_active[ID]=true; |
164 |
|
} |
165 |
|
|
166 |
|
void vmachine::do_ID( void ) |
167 |
|
{ |
168 |
|
nOP = instr_word( IR.get() ); |
169 |
|
|
170 |
|
IR.pass_through(); |
171 |
|
|
172 |
|
|
173 |
|
Const.process(); |
174 |
|
Registers.process_out( psr.CWP ); |
175 |
|
|
176 |
|
if ( nOP.format == instr_word::primary_imm || |
177 |
|
nOP.format == instr_word::branch_format || |
178 |
|
nOP.format == instr_word::call_format || |
179 |
|
nOP.format == instr_word::sethi_format ) |
180 |
|
Mpx3.process( 1 ); |
181 |
|
else |
182 |
|
Mpx3.process( 2 ); |
183 |
|
|
184 |
|
if ( nOP.group == instr_word::branch && ( |
185 |
|
(nOP.instr == instr_word::ba) || |
186 |
|
(nOP.instr == instr_word::bne && !psr.Z) || |
187 |
|
(nOP.instr == instr_word::be && psr.Z) || |
188 |
|
(nOP.instr == instr_word::bg && !(psr.Z || (psr.N ^ psr.V))) || |
189 |
|
(nOP.instr == instr_word::ble && (psr.Z || (psr.N ^ psr.V) )) || |
190 |
|
(nOP.instr == instr_word::bge && !(psr.N ^ psr.V) ) || |
191 |
|
(nOP.instr == instr_word::bl && (psr.N ^ psr.V) ) || |
192 |
|
(nOP.instr == instr_word::bgu && !(psr.C || psr.Z) ) || |
193 |
|
(nOP.instr == instr_word::bleu && (psr.C || psr.Z) ) || |
194 |
|
(nOP.instr == instr_word::bcc && !psr.C ) || |
195 |
|
(nOP.instr == instr_word::bcs && psr.C ) || |
196 |
|
(nOP.instr == instr_word::bpos && !psr.N ) || |
197 |
|
(nOP.instr == instr_word::bneg && psr.N ) || |
198 |
|
(nOP.instr == instr_word::bvc && !psr.V ) || |
199 |
|
(nOP.instr == instr_word::bvs && psr.V ) |
200 |
|
)) |
201 |
|
|
202 |
|
Mpx1.set(2); |
203 |
|
else if ( nOP.instr == instr_word::call ) |
204 |
|
Mpx1.set(2); |
205 |
|
else |
206 |
|
Mpx1.set(1); |
207 |
|
|
208 |
|
OP = nOP; |
209 |
|
A1.remember(); |
210 |
|
A2.remember(); |
211 |
|
R.remember(); |
212 |
|
if ( nOP.instr == instr_word::call ) |
213 |
|
DR.remember(15); |
214 |
|
else |
215 |
|
DR.remember(OP.dst); |
216 |
|
|
217 |
|
phase_active[EX]=true; |
218 |
|
} |
219 |
|
|
220 |
|
void vmachine::do_EX( void ) |
221 |
|
{ |
222 |
|
A1.pass_through(); |
223 |
|
A2.pass_through(); |
224 |
|
R.pass_through(); |
225 |
|
DR.pass_through(); |
226 |
|
|
227 |
|
if ( phase_active[WB] && OP.is_arlog_src() && |
228 |
|
(ppOP.is_arlog_dst() || ppOP.group==instr_word::load) && |
229 |
|
ppOP.dst == OP.src1 ) |
230 |
|
Mpx4.process( 3 ); |
231 |
|
else if ( phase_active[MA] && OP.is_arlog_src() && |
232 |
|
pOP.is_arlog_dst() && pOP.dst == OP.src1) |
233 |
|
Mpx4.process( 1 ); |
234 |
|
else if ( phase_active[MA] && OP.is_arlog_src() && |
235 |
|
pOP.group == instr_word::load && pOP.dst == OP.src1 ) |
236 |
|
; /* FIXME: stall */ |
237 |
|
else |
238 |
|
Mpx4.process( 2 ); |
239 |
|
|
240 |
|
if ( phase_active[WB] && OP.is_arlog_src() && |
241 |
|
(ppOP.is_arlog_dst() || ppOP.group==instr_word::load) && |
242 |
|
ppOP.dst == OP.src2 ) |
243 |
|
Mpx5.process( 3 ); |
244 |
|
else if ( phase_active[MA] && OP.is_arlog_src() && |
245 |
|
pOP.is_arlog_dst() && pOP.dst == OP.src2) |
246 |
|
Mpx5.process( 1 ); |
247 |
|
else if ( phase_active[MA] && OP.is_arlog_src() && |
248 |
|
pOP.group == instr_word::load && pOP.dst == OP.src2 ) |
249 |
|
; /* FIXME: stall */ |
250 |
|
else |
251 |
|
Mpx5.process( 2 ); |
252 |
|
|
253 |
|
if ( phase_active[WB] && OP.group == instr_word::store && |
254 |
|
(ppOP.is_arlog_dst() || ppOP.group==instr_word::load) && |
255 |
|
ppOP.dst == OP.dst ) |
256 |
|
Mpx7.process( 2 ); |
257 |
|
else |
258 |
|
Mpx7.process( 1 ); |
259 |
|
|
260 |
|
if (OP.group == instr_word::shift || OP.instr == instr_word::sethi) |
261 |
|
Shifter.process( OP ); |
262 |
|
else if (OP.group == instr_word::arith |
263 |
|
|| OP.group == instr_word::logic |
264 |
|
|| OP.group == instr_word::load |
265 |
|
|| OP.group == instr_word::store |
266 |
|
|| OP.instr == instr_word::save |
267 |
|
|| OP.instr == instr_word::restore |
268 |
|
|| OP.instr == instr_word::jmpl ) |
269 |
|
ALU.process( OP , psr); |
270 |
|
|
271 |
|
if (OP.instr == instr_word::jmpl || OP.instr == instr_word::call) |
272 |
|
Mpx6.process(1); |
273 |
|
else if (OP.group == instr_word::shift || OP.instr == instr_word::sethi) |
274 |
|
Mpx6.process(3); |
275 |
|
else |
276 |
|
Mpx6.process(2); |
277 |
|
|
278 |
|
if (OP.instr == instr_word::jmpl){ |
279 |
|
Mpx2.set(2); |
280 |
|
/* FIXME: here should be stall!!! */ |
281 |
|
} |
282 |
|
|
283 |
|
if (OP.instr == instr_word::save) |
284 |
|
psr.CWP = Registers.dec_cwp( psr.CWP ); |
285 |
|
else if (OP.instr == instr_word::restore) |
286 |
|
psr.CWP = Registers.inc_cwp( psr.CWP ); |
287 |
|
|
288 |
|
pOP = OP; |
289 |
|
T.remember(); |
290 |
|
pR.remember(); |
291 |
|
pDR.remember(); |
292 |
|
|
293 |
|
phase_active[MA]=true; |
294 |
|
} |
295 |
|
void vmachine::do_MA( void ) |
296 |
|
{ |
297 |
|
T.pass_through(); |
298 |
|
pR.pass_through(); |
299 |
|
pDR.pass_through(); |
300 |
|
|
301 |
|
|
302 |
|
if ( phase_active[WB] && pOP.group == instr_word::store && |
303 |
|
(ppOP.is_arlog_dst() || ppOP.group==instr_word::load) && |
304 |
|
ppOP.dst == pOP.dst ) |
305 |
|
Mpx8.process( 2 ); |
306 |
|
else |
307 |
|
Mpx8.process( 1 ); |
308 |
|
|
309 |
|
if ( pOP.group == instr_word::load || pOP.group == instr_word::store ) |
310 |
|
DCache.process(); |
311 |
|
|
312 |
|
ppOP = pOP; |
313 |
|
D.remember(); |
314 |
|
ppDR.remember(); |
315 |
|
|
316 |
|
phase_active[MA]=true; |
317 |
|
} |
318 |
|
void vmachine::do_WB( void ) |
319 |
|
{ |
320 |
|
pT.pass_through(); |
321 |
|
D.pass_through(); |
322 |
|
ppDR.pass_through(); |
323 |
|
|
324 |
|
if ( ppOP.group == instr_word::load ) |
325 |
|
Mpx9.process(2); |
326 |
|
else |
327 |
|
Mpx9.process(1); |
328 |
|
|
329 |
|
Registers.process_in( psr.CWP ); |
330 |
|
} |