| 26 |
nPC(3), |
nPC(3), |
| 27 |
PC(2), IR(2), 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(2), 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), |
| 31 |
Mpx2(2,1), |
Mpx2(2,1), |
| 32 |
T(4), pR(1), pDR(1), Mpx8(2,1), |
T(4), pR(1), pDR(1), Mpx8(2,1), |
| 33 |
pT(1), D(1), ppDR(1), Mpx9(2,5) |
ppPC(1), |
| 34 |
|
pT(1), D(1), ppDR(1), Mpx9(2,5), |
| 35 |
|
pppPC(1),ppppPC(0) |
| 36 |
{ |
{ |
| 37 |
// 1. phase IF |
// 1. phase IF |
| 38 |
nPC.link(0, Add1, 1); |
nPC.link(0, Add1, 1); |
| 67 |
Mpx1.link(0, Mpx2, 0 ); |
Mpx1.link(0, Mpx2, 0 ); |
| 68 |
|
|
| 69 |
pPC.link(0, Mpx6, 0 ); |
pPC.link(0, Mpx6, 0 ); |
| 70 |
|
pPC.link(1, ppPC, 0 ); |
| 71 |
|
|
| 72 |
A1.link( 0, Mpx4, 1 ); |
A1.link( 0, Mpx4, 1 ); |
| 73 |
|
|
| 105 |
|
|
| 106 |
Mpx8.link(0, DCache, 1 ); |
Mpx8.link(0, DCache, 1 ); |
| 107 |
|
|
| 108 |
DCache.link(0, ppDR, 0 ); |
DCache.link(0, D, 0 ); |
| 109 |
|
|
| 110 |
|
ppPC.link(0, pppPC, 0 ); |
| 111 |
|
|
| 112 |
// 5. phase WB |
// 5. phase WB |
| 113 |
pT.link( 0, Mpx9, 0); |
pT.link( 0, Mpx9, 0); |
| 114 |
|
|
| 122 |
Mpx9.link( 3, Mpx7, 1 ); |
Mpx9.link( 3, Mpx7, 1 ); |
| 123 |
Mpx9.link( 4, Mpx8, 1 ); |
Mpx9.link( 4, Mpx8, 1 ); |
| 124 |
|
|
| 125 |
|
pppPC.link(0, ppppPC, 0 ); |
| 126 |
} |
} |
| 127 |
|
|
| 128 |
void vmachine::init( vector<unsigned long> data, vector<unsigned long> instr ) |
void vmachine::init( vector<unsigned long> data, vector<unsigned long> instr ) |
| 130 |
// loading to mem |
// loading to mem |
| 131 |
ICache.load( instr ); |
ICache.load( instr ); |
| 132 |
DCache.load( data ); |
DCache.load( data ); |
| 133 |
|
Registers.zero(); |
| 134 |
|
|
| 135 |
nPC.remember(0); |
nPC.remember(0); |
| 136 |
|
PC.remember(0); |
| 137 |
|
pPC.remember(0); |
| 138 |
|
ppPC.remember(0); |
| 139 |
|
pppPC.remember(0); |
| 140 |
|
ppppPC.remember(0); |
| 141 |
|
|
| 142 |
|
IR.remember(0); |
| 143 |
|
PC.remember(0); |
| 144 |
|
A1.remember(0); |
| 145 |
|
A2.remember(0); |
| 146 |
|
R.remember(0); |
| 147 |
|
DR.remember(0); |
| 148 |
|
T.remember(0); |
| 149 |
|
pR.remember(0); |
| 150 |
|
pDR.remember(0); |
| 151 |
|
pT.remember(0); |
| 152 |
|
D.remember(0); |
| 153 |
|
ppDR.remember(0); |
| 154 |
|
|
| 155 |
|
psr.zero(); |
| 156 |
|
|
| 157 |
Mpx1.set( 1 ); |
Mpx1.set( 1 ); |
| 158 |
Mpx2.set( 1 ); |
Mpx2.set( 1 ); |
| 159 |
|
|
| 166 |
|
|
| 167 |
void vmachine::step( void ) |
void vmachine::step( void ) |
| 168 |
{ |
{ |
| 169 |
|
#ifdef VMDEBUG |
| 170 |
|
cout.form("*** NEW STEP ***\n"); |
| 171 |
|
#endif |
| 172 |
|
|
| 173 |
if (phase_active[WB]) |
if (phase_active[WB]) |
| 174 |
do_WB(); |
do_WB(); |
| 175 |
if (phase_active[MA] ) |
if (phase_active[MA] ) |
| 181 |
if (phase_active[IF] ) |
if (phase_active[IF] ) |
| 182 |
do_IF(); |
do_IF(); |
| 183 |
|
|
| 184 |
|
|
| 185 |
|
ppOP = pOP; |
| 186 |
|
pOP = OP; |
| 187 |
|
OP = nOP; |
| 188 |
|
|
| 189 |
c4.process(); |
c4.process(); |
| 190 |
Add1.process(); |
Add1.process(); |
| 191 |
Add2.process(); |
Add2.process(); |
| 202 |
PC.remember(); |
PC.remember(); |
| 203 |
IR.remember(); |
IR.remember(); |
| 204 |
|
|
| 205 |
|
#ifdef VMDEBUG |
| 206 |
|
cout.form("IF phase: nPC: %08X\n",nPC.get()); |
| 207 |
|
#endif |
| 208 |
|
|
| 209 |
phase_active[ID]=true; |
phase_active[ID]=true; |
| 210 |
} |
} |
| 211 |
|
|
| 214 |
nOP = instr_word( IR.get() ); |
nOP = instr_word( IR.get() ); |
| 215 |
|
|
| 216 |
IR.pass_through(); |
IR.pass_through(); |
| 217 |
|
PC.pass_through(); |
| 218 |
|
|
| 219 |
|
#ifdef VMDEBUG |
| 220 |
|
cout.form("ID phase: IR: %08X, PC: %08X\n",IR.get(), PC.get()); |
| 221 |
|
#endif |
| 222 |
|
|
| 223 |
Const.process(); |
Const.process(); |
| 224 |
Registers.process_out( psr.CWP ); |
Registers.process_out( psr.CWP ); |
| 255 |
else |
else |
| 256 |
Mpx1.set(1); |
Mpx1.set(1); |
| 257 |
|
|
|
OP = nOP; |
|
| 258 |
A1.remember(); |
A1.remember(); |
| 259 |
A2.remember(); |
A2.remember(); |
| 260 |
R.remember(); |
R.remember(); |
| 261 |
|
pPC.remember(); |
| 262 |
if ( nOP.instr == instr_word::call ) |
if ( nOP.instr == instr_word::call ) |
| 263 |
DR.remember(15); |
DR.remember(15); |
| 264 |
else |
else |
| 265 |
DR.remember(OP.dst); |
DR.remember(nOP.dst); |
| 266 |
|
|
| 267 |
phase_active[EX]=true; |
phase_active[EX]=true; |
| 268 |
} |
} |
| 272 |
A1.pass_through(); |
A1.pass_through(); |
| 273 |
A2.pass_through(); |
A2.pass_through(); |
| 274 |
R.pass_through(); |
R.pass_through(); |
| 275 |
|
pPC.pass_through(); |
| 276 |
DR.pass_through(); |
DR.pass_through(); |
| 277 |
|
|
| 278 |
|
#ifdef VMDEBUG |
| 279 |
|
cout.form("EX phase: A1: %08X, A2: %08X, R: %08X, DR: %08X\n", |
| 280 |
|
A1.get(), A2.get(),R.get(),DR.get()); |
| 281 |
|
#endif |
| 282 |
|
|
| 283 |
if ( phase_active[WB] && OP.is_arlog_src() && |
if ( phase_active[WB] && OP.is_arlog_src() && |
| 284 |
(ppOP.is_arlog_dst() || ppOP.group==instr_word::load) && |
(ppOP.is_arlog_dst() || ppOP.group==instr_word::load) && |
| 285 |
ppOP.dst == OP.src1 ) |
ppOP.dst == OP.src1 ) |
| 341 |
else if (OP.instr == instr_word::restore) |
else if (OP.instr == instr_word::restore) |
| 342 |
psr.CWP = Registers.inc_cwp( psr.CWP ); |
psr.CWP = Registers.inc_cwp( psr.CWP ); |
| 343 |
|
|
|
pOP = OP; |
|
| 344 |
T.remember(); |
T.remember(); |
| 345 |
pR.remember(); |
pR.remember(); |
| 346 |
pDR.remember(); |
pDR.remember(); |
| 347 |
|
|
| 348 |
|
ppPC.remember(); |
| 349 |
|
|
| 350 |
phase_active[MA]=true; |
phase_active[MA]=true; |
| 351 |
} |
} |
| 352 |
void vmachine::do_MA( void ) |
void vmachine::do_MA( void ) |
| 354 |
T.pass_through(); |
T.pass_through(); |
| 355 |
pR.pass_through(); |
pR.pass_through(); |
| 356 |
pDR.pass_through(); |
pDR.pass_through(); |
| 357 |
|
ppPC.pass_through(); |
| 358 |
|
|
| 359 |
|
#ifdef VMDEBUG |
| 360 |
|
cout.form("MA phase: T: %08X, pR: %08X, pDR: %08X\n", |
| 361 |
|
T.get(),pR.get(),pDR.get()); |
| 362 |
|
#endif |
| 363 |
|
|
| 364 |
if ( phase_active[WB] && pOP.group == instr_word::store && |
if ( phase_active[WB] && pOP.group == instr_word::store && |
| 365 |
(ppOP.is_arlog_dst() || ppOP.group==instr_word::load) && |
(ppOP.is_arlog_dst() || ppOP.group==instr_word::load) && |
| 385 |
else if ( pOP.instr == instr_word::stb ) |
else if ( pOP.instr == instr_word::stb ) |
| 386 |
DCache.process(cache::wr, cache::byte); |
DCache.process(cache::wr, cache::byte); |
| 387 |
|
|
| 388 |
ppOP = pOP; |
pT.remember(); |
| 389 |
D.remember(); |
D.remember(); |
| 390 |
ppDR.remember(); |
ppDR.remember(); |
| 391 |
|
pppPC.remember(); |
| 392 |
|
|
| 393 |
phase_active[MA]=true; |
phase_active[WB]=true; |
| 394 |
} |
} |
| 395 |
void vmachine::do_WB( void ) |
void vmachine::do_WB( void ) |
| 396 |
{ |
{ |
| 397 |
pT.pass_through(); |
pT.pass_through(); |
| 398 |
D.pass_through(); |
D.pass_through(); |
| 399 |
ppDR.pass_through(); |
ppDR.pass_through(); |
| 400 |
|
pppPC.pass_through(); |
| 401 |
|
|
| 402 |
|
#ifdef VMDEBUG |
| 403 |
|
cout.form("WB phase: pT: %08X, D: %08X, ppDR: %08X\n", |
| 404 |
|
pT.get(),D.get(),ppDR.get()); |
| 405 |
|
#endif |
| 406 |
|
|
| 407 |
if ( ppOP.group == instr_word::load ) |
if ( ppOP.group == instr_word::load ) |
| 408 |
Mpx9.process(2); |
Mpx9.process(2); |