| 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 |
} |
} |