22 |
|
|
23 |
vmachine::vmachine( void ) : |
vmachine::vmachine( void ) : |
24 |
phase_active(5), |
phase_active(5), |
25 |
|
phase_was_active(5), |
26 |
|
phase_was_stall(5), |
27 |
phase_stall(5), |
phase_stall(5), |
28 |
|
|
29 |
nPC(3), |
nPC(3), |
161 |
Mpx2.set( 1 ); |
Mpx2.set( 1 ); |
162 |
|
|
163 |
phase_active[IF] = true; |
phase_active[IF] = true; |
164 |
phase_stall[IF] = stall_no; |
for( int i = ID ; i <= WB ; i++ ) |
|
for( int i = ID ; i <= WB ; i++ ){ |
|
165 |
phase_active[i] = false; |
phase_active[i] = false; |
166 |
|
|
167 |
|
for( int i = IF ; i <= WB ; i++ ){ |
168 |
phase_stall[i] = stall_no; |
phase_stall[i] = stall_no; |
169 |
|
phase_was_active[i] = false; |
170 |
|
phase_was_stall[i] = false; |
171 |
} |
} |
172 |
|
|
173 |
on = true; |
on = true; |
178 |
#ifdef VMDEBUG |
#ifdef VMDEBUG |
179 |
cout.form("*** NEW STEP ***\n"); |
cout.form("*** NEW STEP ***\n"); |
180 |
#endif |
#endif |
181 |
|
phase_was_active = phase_active; |
182 |
if (phase_active[WB]) |
|
183 |
|
if (phase_active[WB] && phase_stall[WB] == stall_no) |
184 |
do_WB(); |
do_WB(); |
185 |
if (phase_active[MA]) |
if (phase_active[MA] && phase_stall[MA] == stall_no) |
186 |
do_MA(); |
do_MA(); |
187 |
if (phase_active[EX]) |
if (phase_active[EX] && phase_stall[EX] == stall_no) |
188 |
do_EX(); |
do_EX(); |
189 |
if (phase_active[ID]) |
if (phase_active[ID] && phase_stall[ID] == stall_no) |
190 |
do_ID(); |
do_ID(); |
191 |
if (phase_active[IF] && phase_stall[IF] != stall_jmpl) |
if (phase_active[IF] && phase_stall[IF] == stall_no) |
192 |
do_IF(); |
do_IF(); |
193 |
|
|
194 |
|
for( int i = IF; i <= WB ; i++ ) |
195 |
|
phase_was_stall[i] = (phase_stall[i] != stall_no); |
196 |
|
|
197 |
ppOP = pOP; |
ppOP = pOP; |
198 |
pOP = OP; |
pOP = OP; |
201 |
pppsr = ppsr; |
pppsr = ppsr; |
202 |
ppsr = psr; |
ppsr = psr; |
203 |
|
|
204 |
do_ADDR(); |
if (phase_stall[IF] != stall_load ) |
205 |
|
do_ADDR(); |
206 |
|
|
207 |
|
// turning off load stall |
208 |
|
if (phase_stall[WB] == stall_load) |
209 |
|
phase_stall[WB] = stall_no; |
210 |
|
|
211 |
|
// third phase of load stall |
212 |
|
if (phase_stall[MA] == stall_load){ |
213 |
|
phase_stall[MA] = stall_no; |
214 |
|
|
215 |
|
phase_stall[WB] = stall_load; |
216 |
|
} |
217 |
|
|
218 |
|
// second phase of load stall |
219 |
|
if (phase_stall[IF] == stall_load && phase_stall[ID] == stall_load ){ |
220 |
|
phase_stall[IF] = stall_no; |
221 |
|
phase_stall[ID] = stall_no; |
222 |
|
|
223 |
|
phase_stall[MA] = stall_load; |
224 |
|
} |
225 |
|
|
226 |
// delayed IF phase after processing new |
// turning off jmpl stall |
227 |
|
if ( phase_stall[ID] == stall_jmpl ) |
228 |
|
for( int i = ID ; i <= WB ; i++ ) |
229 |
|
phase_stall[i] = stall_no; |
230 |
|
|
231 |
|
// second phase of jmpl stall |
232 |
if (phase_stall[IF] == stall_jmpl){ |
if (phase_stall[IF] == stall_jmpl){ |
|
do_IF(); |
|
233 |
// setting mplexer 2. to normal state |
// setting mplexer 2. to normal state |
234 |
// [was changed by jmpl intruction] |
// [was changed by jmpl intruction] |
235 |
Mpx2.set(1); |
Mpx2.set(1); |
236 |
do_ADDR(); |
|
237 |
phase_stall[IF] = stall_no; |
phase_stall[IF] = stall_no; |
238 |
|
for( int i = ID ; i <= WB ; i++ ) |
239 |
|
phase_stall[i] = stall_jmpl; |
240 |
} |
} |
241 |
|
|
|
/* |
|
|
phase_stall[WB] = phase_stall[MA]; |
|
|
phase_stall[MA] = phase_stall[EX]; |
|
|
phase_stall[EX] = phase_stall[ID]; |
|
|
phase_stall[ID] = phase_stall[IF]; |
|
|
phase_stall[IF] = stall_no; |
|
|
*/ |
|
242 |
} |
} |
243 |
void vmachine::do_ADDR( void ) |
void vmachine::do_ADDR( void ) |
244 |
{ |
{ |
247 |
Add2.process(); |
Add2.process(); |
248 |
Mpx1.process(); |
Mpx1.process(); |
249 |
Mpx2.process(); |
Mpx2.process(); |
|
nPC.remember(); |
|
250 |
#ifdef VMDEBUG |
#ifdef VMDEBUG |
251 |
cout.form("Address calc: nPC: %08X\n",nPC.get()); |
cout.form("Address calc: nPC: %08X\n",nPC.get()); |
252 |
#endif |
#endif |
256 |
{ |
{ |
257 |
nPC.pass_through(); |
nPC.pass_through(); |
258 |
ICache.process(cache::rd, cache::word); |
ICache.process(cache::rd, cache::word); |
|
PC.remember(); |
|
|
IR.remember(); |
|
259 |
|
|
260 |
if ( IR.get() == 0 ){ /* halt [0] */ |
if ( IR.get_slave() == 0 ){ /* halt [0] */ |
261 |
phase_active[IF] = false; |
phase_active[IF] = false; |
262 |
return; |
return; |
263 |
} |
} |
271 |
|
|
272 |
void vmachine::do_ID( void ) |
void vmachine::do_ID( void ) |
273 |
{ |
{ |
|
nOP = instr_word( IR.get() ); |
|
|
|
|
274 |
IR.pass_through(); |
IR.pass_through(); |
275 |
PC.pass_through(); |
PC.pass_through(); |
276 |
|
|
277 |
|
nOP = instr_word( IR.get() ); |
278 |
|
|
279 |
#ifdef VMDEBUG |
#ifdef VMDEBUG |
280 |
cout.form("ID phase: IR: %08X, PC: %08X\n",IR.get(), PC.get()); |
cout.form("ID phase: IR: %08X, PC: %08X\n",IR.get(), PC.get()); |
281 |
#endif |
#endif |
282 |
|
|
283 |
if ( nOP.instr == instr_word::halt ){ |
if ( nOP.instr == instr_word::halt ){ |
|
phase_active[IF] = false; |
|
284 |
phase_active[ID] = false; |
phase_active[ID] = false; |
|
pPC.remember(); |
|
285 |
return; |
return; |
286 |
} |
} |
287 |
|
|
320 |
else |
else |
321 |
Mpx1.set(1); |
Mpx1.set(1); |
322 |
|
|
|
|
|
|
A1.remember(); |
|
|
A2.remember(); |
|
|
R.remember(); |
|
|
pPC.remember(); |
|
323 |
if ( nOP.instr == instr_word::call ) |
if ( nOP.instr == instr_word::call ) |
324 |
DR.remember(15); |
DR.set_slave(15); |
325 |
else |
else |
326 |
DR.remember(nOP.dst); |
DR.set_slave(nOP.dst); |
327 |
|
|
328 |
phase_active[EX]=true; |
phase_active[EX]=true; |
329 |
} |
} |
342 |
#endif |
#endif |
343 |
if ( OP.instr == instr_word::halt ){ |
if ( OP.instr == instr_word::halt ){ |
344 |
phase_active[EX] = false; |
phase_active[EX] = false; |
|
ppPC.remember(); |
|
345 |
return; |
return; |
346 |
} |
} |
347 |
|
|
348 |
if ( phase_active[WB] && OP.is_arlog_src() && |
if ( phase_active[WB] && OP.is_arlog_src() && |
349 |
(ppOP.is_arlog_dst() || ppOP.group==instr_word::load) && |
(ppOP.is_arlog_dst() || ppOP.group==instr_word::load) && |
350 |
|
OP.src1 != 0 && |
351 |
Registers.real_regnum(pppsr.CWP, ppOP.dst) |
Registers.real_regnum(pppsr.CWP, ppOP.dst) |
352 |
== Registers.real_regnum(psr.CWP, OP.src1) ) |
== Registers.real_regnum(psr.CWP, OP.src1) ) |
353 |
Mpx4.process( 3 ); |
Mpx4.process( 3 ); |
354 |
else if ( phase_active[MA] && OP.is_arlog_src() && |
else if ( phase_active[MA] && OP.is_arlog_src() && |
355 |
pOP.is_arlog_dst() && |
pOP.is_arlog_dst() && OP.src1 != 0 && |
356 |
Registers.real_regnum(ppsr.CWP, pOP.dst) |
Registers.real_regnum(ppsr.CWP, pOP.dst) |
357 |
== Registers.real_regnum(psr.CWP, OP.src1)) |
== Registers.real_regnum(psr.CWP, OP.src1)) |
358 |
Mpx4.process( 1 ); |
Mpx4.process( 1 ); |
359 |
else if ( phase_active[MA] && OP.is_arlog_src() && |
else if ( phase_active[MA] && OP.is_arlog_src() && |
360 |
pOP.group == instr_word::load && |
pOP.group == instr_word::load && OP.src1 != 0 && |
361 |
Registers.real_regnum(ppsr.CWP, pOP.dst) |
Registers.real_regnum(ppsr.CWP, pOP.dst) |
362 |
== Registers.real_regnum(psr.CWP,OP.src1) ){ |
== Registers.real_regnum(psr.CWP,OP.src1) ){ |
363 |
// phase_stall[IF] = stall_load; |
phase_stall[IF] = stall_load; |
364 |
; /* FIXME: stall */ |
phase_stall[ID] = stall_load; |
365 |
} else |
} else |
366 |
Mpx4.process( 2 ); |
Mpx4.process( 2 ); |
367 |
|
|
368 |
if ( phase_active[WB] && OP.is_arlog_src() && |
if ( phase_active[WB] && OP.is_arlog_src() && |
369 |
(ppOP.is_arlog_dst() || ppOP.group==instr_word::load) && |
(ppOP.is_arlog_dst() || ppOP.group==instr_word::load) && |
370 |
|
OP.src2 != 0 && |
371 |
Registers.real_regnum(pppsr.CWP, ppOP.dst) |
Registers.real_regnum(pppsr.CWP, ppOP.dst) |
372 |
== Registers.real_regnum(psr.CWP, OP.src2) ) |
== Registers.real_regnum(psr.CWP, OP.src2) ) |
373 |
Mpx5.process( 3 ); |
Mpx5.process( 3 ); |
374 |
else if ( phase_active[MA] && OP.is_arlog_src() && |
else if ( phase_active[MA] && OP.is_arlog_src() && |
375 |
pOP.is_arlog_dst() && |
pOP.is_arlog_dst() && OP.src2 != 0 && |
376 |
Registers.real_regnum(ppsr.CWP, pOP.dst) |
Registers.real_regnum(ppsr.CWP, pOP.dst) |
377 |
== Registers.real_regnum(psr.CWP, OP.src2)) |
== Registers.real_regnum(psr.CWP, OP.src2)) |
378 |
Mpx5.process( 1 ); |
Mpx5.process( 1 ); |
379 |
else if ( phase_active[MA] && OP.is_arlog_src() && |
else if ( phase_active[MA] && OP.is_arlog_src() && |
380 |
pOP.group == instr_word::load && |
pOP.group == instr_word::load && OP.src2 != 0 && |
381 |
Registers.real_regnum(ppsr.CWP, pOP.dst) |
Registers.real_regnum(ppsr.CWP, pOP.dst) |
382 |
== Registers.real_regnum(psr.CWP, OP.src2) ){ |
== Registers.real_regnum(psr.CWP, OP.src2) ){ |
383 |
// phase_stall[IF] = stall_load; |
phase_stall[IF] = stall_load; |
384 |
; /* FIXME: stall */ |
phase_stall[ID] = stall_load; |
385 |
} else |
} else |
386 |
Mpx5.process( 2 ); |
Mpx5.process( 2 ); |
387 |
|
|
388 |
if ( phase_active[WB] && OP.group == instr_word::store && |
if ( phase_active[WB] && OP.group == instr_word::store && |
389 |
(ppOP.is_arlog_dst() || ppOP.group==instr_word::load) && |
(ppOP.is_arlog_dst() || ppOP.group==instr_word::load) && |
390 |
|
OP.dst != 0 && |
391 |
Registers.real_regnum(pppsr.CWP, ppOP.dst) |
Registers.real_regnum(pppsr.CWP, ppOP.dst) |
392 |
== Registers.real_regnum(psr.CWP, OP.dst) ) |
== Registers.real_regnum(psr.CWP, OP.dst) ) |
393 |
Mpx7.process( 2 ); |
Mpx7.process( 2 ); |
394 |
else |
else |
395 |
Mpx7.process( 1 ); |
Mpx7.process( 1 ); |
396 |
|
|
397 |
|
if ( phase_stall[IF] == stall_load && phase_stall[ID] == stall_load ) |
398 |
|
return; |
399 |
|
|
400 |
if (OP.group == instr_word::shift || OP.instr == instr_word::sethi) |
if (OP.group == instr_word::shift || OP.instr == instr_word::sethi) |
401 |
Shifter.process( OP ); |
Shifter.process( OP ); |
402 |
else if (OP.group == instr_word::arith |
else if (OP.group == instr_word::arith |
418 |
if (OP.instr == instr_word::jmpl){ |
if (OP.instr == instr_word::jmpl){ |
419 |
Mpx2.set(2); |
Mpx2.set(2); |
420 |
phase_stall[IF] = stall_jmpl; |
phase_stall[IF] = stall_jmpl; |
|
|
|
|
/* FIXME: stall */ |
|
421 |
} |
} |
422 |
|
|
423 |
if (OP.instr == instr_word::save) |
if (OP.instr == instr_word::save) |
425 |
else if (OP.instr == instr_word::restore) |
else if (OP.instr == instr_word::restore) |
426 |
psr.CWP = Registers.inc_cwp( psr.CWP ); |
psr.CWP = Registers.inc_cwp( psr.CWP ); |
427 |
|
|
|
T.remember(); |
|
|
pR.remember(); |
|
|
pDR.remember(); |
|
|
|
|
|
ppPC.remember(); |
|
|
|
|
428 |
phase_active[MA]=true; |
phase_active[MA]=true; |
429 |
} |
} |
430 |
void vmachine::do_MA( void ) |
void vmachine::do_MA( void ) |
440 |
#endif |
#endif |
441 |
if ( pOP.instr == instr_word::halt ){ |
if ( pOP.instr == instr_word::halt ){ |
442 |
phase_active[MA] = false; |
phase_active[MA] = false; |
|
pppPC.remember(); |
|
443 |
return; |
return; |
444 |
} |
} |
445 |
|
|
446 |
if ( phase_active[WB] && pOP.group == instr_word::store && |
if ( phase_active[WB] && pOP.group == instr_word::store && |
447 |
(ppOP.is_arlog_dst() || ppOP.group==instr_word::load) && |
(ppOP.is_arlog_dst() || ppOP.group==instr_word::load) && |
448 |
|
pOP.dst != 0 && |
449 |
Registers.real_regnum(pppsr.CWP, ppOP.dst) |
Registers.real_regnum(pppsr.CWP, ppOP.dst) |
450 |
== Registers.real_regnum(ppsr.CWP, pOP.dst) ) |
== Registers.real_regnum(ppsr.CWP, pOP.dst) ) |
451 |
Mpx8.process( 2 ); |
Mpx8.process( 2 ); |
469 |
else if ( pOP.instr == instr_word::stb ) |
else if ( pOP.instr == instr_word::stb ) |
470 |
DCache.process(cache::wr, cache::byte); |
DCache.process(cache::wr, cache::byte); |
471 |
|
|
|
pT.remember(); |
|
|
D.remember(); |
|
|
ppDR.remember(); |
|
|
pppPC.remember(); |
|
|
|
|
472 |
phase_active[WB]=true; |
phase_active[WB]=true; |
473 |
} |
} |
474 |
void vmachine::do_WB( void ) |
void vmachine::do_WB( void ) |
480 |
|
|
481 |
if ( ppOP.instr == instr_word::halt ){ |
if ( ppOP.instr == instr_word::halt ){ |
482 |
phase_active[WB] = false; |
phase_active[WB] = false; |
|
ppppPC.remember(); |
|
483 |
return; |
return; |
484 |
} |
} |
485 |
|
|
495 |
|
|
496 |
if ( ppOP.is_arlog_dst() || ppOP.group == instr_word::load ) |
if ( ppOP.is_arlog_dst() || ppOP.group == instr_word::load ) |
497 |
Registers.process_in( pppsr.CWP ); |
Registers.process_in( pppsr.CWP ); |
|
|
|
|
ppppPC.remember(); |
|
498 |
} |
} |