annotate core/src/Processor.bsv @ 3:5e0595db14f6 pygar svn.4

[svn r4] added bluespec manual to documents
author rlm
date Tue, 20 Apr 2010 20:09:46 -0400
parents 91a1f76ddd62
children
rev   line source
punk@1 1 /// The MIT License
punk@1 2
punk@1 3 // Copyright (c) 2009 Massachusetts Institute of Technology
punk@1 4
punk@1 5 // Permission is hereby granted, free of charge, to any person obtaining a copy
punk@1 6 // of this software and associated documentation files (the "Software"), to deal
punk@1 7 // in the Software without restriction, including without limitation the rights
punk@1 8 // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
punk@1 9 // copies of the Software, and to permit persons to whom the Software is
punk@1 10 // furnished to do so, subject to the following conditions:
punk@1 11
punk@1 12 // The above copyright notice and this permission notice shall be included in
punk@1 13 // all copies or substantial portions of the Software.
punk@1 14
punk@1 15 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
punk@1 16 // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
punk@1 17 // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
punk@1 18 // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
punk@1 19 // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
punk@1 20 // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
punk@1 21 // THE SOFTWARE.
punk@1 22
punk@1 23 import Connectable::*;
punk@1 24 import GetPut::*;
punk@1 25 import ClientServer::*;
punk@1 26 import RegFile::*;
punk@1 27 import BRegFile::*;
punk@1 28 import FIFO::*;
punk@1 29 import FIFOF::*;
punk@1 30 import SFIFO::*;
punk@1 31 import RWire::*;
punk@1 32
punk@1 33 import BFIFO::*;
punk@1 34 import MemTypes::*;
punk@1 35 import ProcTypes::*;
punk@1 36 import BranchPred::*;
punk@1 37 import PathTypes::*;
punk@1 38
punk@1 39 import Trace::*;
punk@1 40
punk@1 41 interface ProcStats;
punk@1 42 interface Get#(Stat) num_cycles;
punk@1 43 interface Get#(Stat) num_inst;
punk@1 44 endinterface
punk@1 45
punk@1 46 interface CPUToHost;
punk@1 47 method Bit#(32) cpuToHost(int req);
punk@1 48 endinterface
punk@1 49
punk@1 50 interface Proc;
punk@1 51
punk@1 52 // Interface from processor to caches
punk@1 53 interface Client#(DataReq,DataResp) dmem_client;
punk@1 54 interface Client#(InstReq,InstResp) imem_client;
punk@1 55
punk@1 56 // Interface for enabling/disabling statistics on the rest of the core
punk@1 57 interface Get#(Bool) statsEn_get;
punk@1 58
punk@1 59 // Interface for collecting statistics.
punk@1 60 interface ProcStats stats;
punk@1 61
punk@1 62 // Interface to host
punk@1 63 interface CPUToHost tohost;
punk@1 64
punk@1 65 endinterface
punk@1 66
punk@1 67
punk@1 68 typedef enum { PCgen, Exec, Writeback } Stage deriving(Eq,Bits);
punk@1 69
punk@1 70 //-----------------------------------------------------------
punk@1 71 // Register file module
punk@1 72 //-----------------------------------------------------------
punk@1 73
punk@1 74 interface BRFile;
punk@1 75 method Action wr( Rindx rindx, Bit#(32) data );
punk@1 76 method Bit#(32) rd1( Rindx rindx );
punk@1 77 method Bit#(32) rd2( Rindx rindx );
punk@1 78 endinterface
punk@1 79
punk@1 80 module mkBRFile( BRFile );
punk@1 81
punk@1 82 RegFile#(Rindx,Bit#(32)) rfile <- mkBRegFile();
punk@1 83
punk@1 84 method Action wr( Rindx rindx, Bit#(32) data );
punk@1 85 rfile.upd( rindx, data );
punk@1 86 endmethod
punk@1 87
punk@1 88 method Bit#(32) rd1( Rindx rindx );
punk@1 89 return ( rindx == 0 ) ? 0 : rfile.sub(rindx);
punk@1 90 endmethod
punk@1 91
punk@1 92 method Bit#(32) rd2( Rindx rindx );
punk@1 93 return ( rindx == 0 ) ? 0 : rfile.sub(rindx);
punk@1 94 endmethod
punk@1 95
punk@1 96 endmodule
punk@1 97
punk@1 98 //-----------------------------------------------------------
punk@1 99 // Helper functions
punk@1 100 //-----------------------------------------------------------
punk@1 101
punk@1 102 function Bit#(32) slt( Bit#(32) val1, Bit#(32) val2 );
punk@1 103 return zeroExtend( pack( signedLT(val1,val2) ) );
punk@1 104 endfunction
punk@1 105
punk@1 106 function Bit#(32) sltu( Bit#(32) val1, Bit#(32) val2 );
punk@1 107 return zeroExtend( pack( val1 < val2 ) );
punk@1 108 endfunction
punk@1 109
punk@1 110 function Bit#(32) rshft( Bit#(32) val );
punk@1 111 return zeroExtend(val[4:0]);
punk@1 112 endfunction
punk@1 113
punk@1 114
punk@1 115 //-----------------------------------------------------------
punk@1 116 // Find funct for wbQ
punk@1 117 //-----------------------------------------------------------
punk@1 118 function Bool findwbf(Rindx fVal, WBResult cmpVal);
punk@1 119 case (cmpVal) matches
punk@1 120 tagged WB_ALU {data:.res, dest:.rd} :
punk@1 121 return (fVal == rd);
punk@1 122 tagged WB_Load .rd :
punk@1 123 return (fVal == rd);
punk@1 124 tagged WB_Store .st :
punk@1 125 return False;
punk@1 126 tagged WB_Host .x :
punk@1 127 return False;
punk@1 128 endcase
punk@1 129 endfunction
punk@1 130
punk@1 131
punk@1 132 //-----------------------------------------------------------
punk@1 133 // Stall funct for wbQ
punk@1 134 //-----------------------------------------------------------
punk@1 135 function Bool stall(Instr inst, SFIFO#(WBResult, Rindx) f);
punk@1 136 case (inst) matches
punk@1 137 // -- Memory Ops ------------------------------------------------
punk@1 138 tagged LW .it :
punk@1 139 return f.find(it.rbase);
punk@1 140 tagged SW {rsrc:.dreg, rbase:.addr, offset:.o} :
punk@1 141 return (f.find(addr) || f.find2(dreg));
punk@1 142
punk@1 143 // -- Simple Ops ------------------------------------------------
punk@1 144 tagged ADDIU .it : return f.find(it.rsrc);
punk@1 145 tagged SLTI .it : return f.find(it.rsrc);
punk@1 146 tagged SLTIU .it : return f.find(it.rsrc);
punk@1 147 tagged ANDI .it : return f.find(it.rsrc);
punk@1 148 tagged ORI .it : return f.find(it.rsrc);
punk@1 149 tagged XORI .it : return f.find(it.rsrc);
punk@1 150
punk@1 151 tagged LUI .it : return f.find(it.rdst); //this rds/wrs itself
punk@1 152 tagged SLL .it : return f.find(it.rsrc);
punk@1 153 tagged SRL .it : return f.find(it.rsrc);
punk@1 154 tagged SRA .it : return f.find(it.rsrc);
punk@1 155 tagged SLLV .it : return (f.find(it.rsrc) || f.find(it.rshamt));
punk@1 156 tagged SRLV .it : return (f.find(it.rsrc) || f.find(it.rshamt));
punk@1 157 tagged SRAV .it : return (f.find(it.rsrc) || f.find(it.rshamt));
punk@1 158 tagged ADDU .it : return (f.find(it.rsrc1) || f.find2(it.rsrc2));
punk@1 159 tagged SUBU .it : return (f.find(it.rsrc1) || f.find2(it.rsrc2));
punk@1 160 tagged AND .it : return (f.find(it.rsrc1) || f.find2(it.rsrc2));
punk@1 161 tagged OR .it : return (f.find(it.rsrc1) || f.find2(it.rsrc2));
punk@1 162 tagged XOR .it : return (f.find(it.rsrc1) || f.find2(it.rsrc2));
punk@1 163 tagged NOR .it : return (f.find(it.rsrc1) || f.find2(it.rsrc2));
punk@1 164 tagged SLT .it : return (f.find(it.rsrc1) || f.find2(it.rsrc2));
punk@1 165 tagged SLTU .it : return (f.find(it.rsrc1) || f.find2(it.rsrc2));
punk@1 166
punk@1 167
punk@1 168 // -- Branches --------------------------------------------------
punk@1 169
punk@1 170 tagged BLEZ .it : return (f.find(it.rsrc));
punk@1 171 tagged BGTZ .it : return (f.find(it.rsrc));
punk@1 172 tagged BLTZ .it : return (f.find(it.rsrc));
punk@1 173 tagged BGEZ .it : return (f.find(it.rsrc));
punk@1 174 tagged BEQ .it : return (f.find(it.rsrc1) || f.find2(it.rsrc2));
punk@1 175 tagged BNE .it : return (f.find(it.rsrc1) || f.find2(it.rsrc2));
punk@1 176
punk@1 177 // -- Jumps -----------------------------------------------------
punk@1 178
punk@1 179 tagged J .it : return False;
punk@1 180 tagged JR .it : return f.find(it.rsrc);
punk@1 181 tagged JALR .it : return f.find(it.rsrc);
punk@1 182 tagged JAL .it : return False;
punk@1 183
punk@1 184 // -- Cop0 ------------------------------------------------------
punk@1 185
punk@1 186 tagged MTC0 .it : return f.find(it.rsrc);
punk@1 187 tagged MFC0 .it : return False;
punk@1 188
punk@1 189 // -- Illegal ---------------------------------------------------
punk@1 190
punk@1 191 default : return False;
punk@1 192
punk@1 193 endcase
punk@1 194 endfunction
punk@1 195 //-----------------------------------------------------------
punk@1 196 // Reference processor
punk@1 197 //-----------------------------------------------------------
punk@1 198
punk@1 199
punk@1 200 (* doc = "synthesis attribute ram_style mkProc distributed;" *)
punk@1 201 (* synthesize *)
punk@1 202 module mkProc( Proc );
punk@1 203
punk@1 204 //-----------------------------------------------------------
punk@1 205 // State
punk@1 206
punk@1 207 // Standard processor state
punk@1 208
punk@1 209 Reg#(Addr) pc <- mkReg(32'h00001000);
punk@1 210 Reg#(Epoch) epoch <- mkReg(0);
punk@1 211 Reg#(Stage) stage <- mkReg(PCgen);
punk@1 212 BRFile rf <- mkBRFile;
punk@1 213
punk@1 214 // Branch Prediction
punk@1 215 BranchPred bp <- mkBranchPred();
punk@1 216 FIFO#(PCStat) execpc <- mkLFIFO();
punk@1 217
punk@1 218 // Pipelines
punk@1 219 FIFO#(PCStat) pcQ <-mkSizedFIFO(3);
punk@1 220 SFIFO#(WBResult, Rindx) wbQ <-mkSFIFO(findwbf);
punk@1 221
punk@1 222 Reg#(Bit#(32)) cp0_tohost <- mkReg(0);
punk@1 223 Reg#(Bit#(32)) cp0_fromhost <- mkReg(0);
punk@1 224 Reg#(Bool) cp0_statsEn <- mkReg(False);
punk@1 225
punk@1 226 // Memory request/response state
punk@1 227
punk@1 228 FIFO#(InstReq) instReqQ <- mkBFIFO1();
punk@1 229 FIFO#(InstResp) instRespQ <- mkFIFO();
punk@1 230
punk@1 231 FIFO#(DataReq) dataReqQ <- mkBFIFO1();
punk@1 232 FIFO#(DataResp) dataRespQ <- mkFIFO();
punk@1 233
punk@1 234 // Statistics state
punk@1 235 Reg#(Stat) num_cycles <- mkReg(0);
punk@1 236 Reg#(Stat) num_inst <- mkReg(0);
punk@1 237
punk@1 238 //-----------------------------------------------------------
punk@1 239 // Rules
punk@1 240
punk@1 241 (* descending_urgency = "exec, pcgen" *)
punk@1 242 rule pcgen; //( stage == PCgen );
punk@1 243 let pc_plus4 = pc + 4;
punk@1 244
punk@1 245 traceTiny("mkProc", "pc",pc);
punk@1 246 traceTiny("mkProc", "pcgen","P");
punk@1 247 instReqQ.enq( LoadReq{ addr:pc, tag:epoch} );
punk@1 248
punk@1 249 let next_pc = bp.get(pc);
punk@1 250 if (next_pc matches tagged Valid .npc)
punk@1 251 begin
punk@1 252 pcQ.enq(PCStat {qpc:pc, qnxtpc:npc, qepoch:epoch});
punk@1 253 pc <= npc;
punk@1 254 end
punk@1 255 else
punk@1 256 begin
punk@1 257 pcQ.enq(PCStat {qpc:pc, qnxtpc:pc_plus4, qepoch:epoch});
punk@1 258 pc <= pc_plus4;
punk@1 259 end
punk@1 260
punk@1 261 endrule
punk@1 262
punk@1 263 rule discard (instRespQ.first() matches tagged LoadResp .ld
punk@1 264 &&& ld.tag != epoch);
punk@1 265 traceTiny("mkProc", "stage", "D");
punk@1 266 instRespQ.deq();
punk@1 267 endrule
punk@1 268
punk@1 269 (* conflict_free = "exec, writeback" *)
punk@1 270 rule exec (instRespQ.first() matches tagged LoadResp.ld
punk@1 271 &&& (ld.tag == epoch)
punk@1 272 &&& unpack(ld.data) matches .inst
punk@1 273 &&& !stall(inst, wbQ));
punk@1 274
punk@1 275 // Some abbreviations
punk@1 276 let sext = signExtend;
punk@1 277 let zext = zeroExtend;
punk@1 278 let sra = signedShiftRight;
punk@1 279
punk@1 280 // Get the instruction
punk@1 281
punk@1 282 instRespQ.deq();
punk@1 283 Instr inst
punk@1 284 = case ( instRespQ.first() ) matches
punk@1 285 tagged LoadResp .ld : return unpack(ld.data);
punk@1 286 tagged StoreResp .st : return ?;
punk@1 287 endcase;
punk@1 288
punk@1 289 // Get the PC info
punk@1 290 let instrpc = pcQ.first().qpc;
punk@1 291 let pc_plus4 = instrpc + 4;
punk@1 292
punk@1 293 Bool branchTaken = False;
punk@1 294 Addr newPC = pc_plus4;
punk@1 295
punk@1 296 // Tracing
punk@1 297 traceTiny("mkProc", "exec","X");
punk@1 298 traceTiny("mkProc", "exInstTiny",inst);
punk@1 299 traceFull("mkProc", "exInstFull",inst);
punk@1 300
punk@1 301 case ( inst ) matches
punk@1 302
punk@1 303 // -- Memory Ops ------------------------------------------------
punk@1 304
punk@1 305 tagged LW .it :
punk@1 306 begin
punk@1 307 Addr addr = rf.rd1(it.rbase) + sext(it.offset);
punk@1 308 dataReqQ.enq( LoadReq{ addr:addr, tag:zeroExtend(it.rdst) } );
punk@1 309 wbQ.enq(tagged WB_Load it.rdst);
punk@1 310 end
punk@1 311
punk@1 312 tagged SW .it :
punk@1 313 begin
punk@1 314 Addr addr = rf.rd1(it.rbase) + sext(it.offset);
punk@1 315 dataReqQ.enq( StoreReq{ tag:0, addr:addr, data:rf.rd2(it.rsrc) } );
punk@1 316 wbQ.enq(tagged WB_Store);
punk@1 317 end
punk@1 318
punk@1 319 // -- Simple Ops ------------------------------------------------
punk@1 320
punk@1 321 tagged ADDIU .it :
punk@1 322 begin
punk@1 323 Bit#(32) result = rf.rd1(it.rsrc) + sext(it.imm);
punk@1 324 wbQ.enq(tagged WB_ALU {data:result, dest:it.rdst});
punk@1 325 end
punk@1 326 tagged SLTI .it : wbQ.enq(tagged WB_ALU {dest:it.rdst, data:slt( rf.rd1(it.rsrc), sext(it.imm) )});
punk@1 327 tagged SLTIU .it : wbQ.enq(tagged WB_ALU {dest:it.rdst, data:sltu( rf.rd1(it.rsrc), sext(it.imm) ) });
punk@1 328 tagged ANDI .it :
punk@1 329 begin
punk@1 330 Bit#(32) zext_it_imm = zext(it.imm);
punk@1 331 wbQ.enq(tagged WB_ALU {dest:it.rdst, data:(rf.rd1(it.rsrc) & zext_it_imm)} );
punk@1 332 end
punk@1 333 tagged ORI .it :
punk@1 334 begin
punk@1 335 Bit#(32) zext_it_imm = zext(it.imm);
punk@1 336 wbQ.enq(tagged WB_ALU {dest:it.rdst, data:(rf.rd1(it.rsrc) | zext_it_imm)} );
punk@1 337 end
punk@1 338 tagged XORI .it :
punk@1 339 begin
punk@1 340 Bit#(32) zext_it_imm = zext(it.imm);
punk@1 341 wbQ.enq(tagged WB_ALU {dest: it.rdst, data:(rf.rd1(it.rsrc) ^ zext_it_imm )});
punk@1 342 end
punk@1 343 tagged LUI .it :
punk@1 344 begin
punk@1 345 Bit#(32) zext_it_imm = zext(it.imm);
punk@1 346 wbQ.enq(tagged WB_ALU {dest: it.rdst, data:(zext_it_imm << 32'd16) });
punk@1 347 end
punk@1 348
punk@1 349 tagged SLL .it :
punk@1 350 begin
punk@1 351 Bit#(32) zext_it_shamt = zext(it.shamt);
punk@1 352 wbQ.enq(tagged WB_ALU {dest: it.rdst, data:(rf.rd1(it.rsrc) << zext_it_shamt )} );
punk@1 353 end
punk@1 354 tagged SRL .it :
punk@1 355 begin
punk@1 356 Bit#(32) zext_it_shamt = zext(it.shamt);
punk@1 357 wbQ.enq(tagged WB_ALU {dest: it.rdst, data:(rf.rd1(it.rsrc) >> zext_it_shamt )});
punk@1 358 end
punk@1 359 tagged SRA .it :
punk@1 360 begin
punk@1 361 Bit#(32) zext_it_shamt = zext(it.shamt);
punk@1 362 wbQ.enq(tagged WB_ALU {dest: it.rdst, data:sra( rf.rd1(it.rsrc), zext_it_shamt )});
punk@1 363 end
punk@1 364 tagged SLLV .it : wbQ.enq(tagged WB_ALU {dest: it.rdst, data:(rf.rd1(it.rsrc) << rshft(rf.rd2(it.rshamt)) )});
punk@1 365 tagged SRLV .it : wbQ.enq(tagged WB_ALU {dest: it.rdst, data:(rf.rd1(it.rsrc) >> rshft(rf.rd2(it.rshamt)) )} );
punk@1 366 tagged SRAV .it : wbQ.enq(tagged WB_ALU {dest: it.rdst, data:sra( rf.rd1(it.rsrc), rshft(rf.rd2(it.rshamt)) ) });
punk@1 367 tagged ADDU .it : wbQ.enq(tagged WB_ALU {dest: it.rdst, data:(rf.rd1(it.rsrc1) + rf.rd2(it.rsrc2) )} );
punk@1 368 tagged SUBU .it : wbQ.enq(tagged WB_ALU {dest: it.rdst, data:(rf.rd1(it.rsrc1) - rf.rd2(it.rsrc2) )} );
punk@1 369 tagged AND .it : wbQ.enq(tagged WB_ALU {dest: it.rdst, data:(rf.rd1(it.rsrc1) & rf.rd2(it.rsrc2) )} );
punk@1 370 tagged OR .it : wbQ.enq(tagged WB_ALU {dest: it.rdst, data:(rf.rd1(it.rsrc1) | rf.rd2(it.rsrc2) )} );
punk@1 371 tagged XOR .it : wbQ.enq(tagged WB_ALU {dest: it.rdst, data:(rf.rd1(it.rsrc1) ^ rf.rd2(it.rsrc2) )} );
punk@1 372 tagged NOR .it : wbQ.enq(tagged WB_ALU {dest: it.rdst, data:(~(rf.rd1(it.rsrc1) | rf.rd2(it.rsrc2)) )} );
punk@1 373 tagged SLT .it : wbQ.enq(tagged WB_ALU {dest: it.rdst, data:slt( rf.rd1(it.rsrc1), rf.rd2(it.rsrc2) ) });
punk@1 374 tagged SLTU .it : wbQ.enq(tagged WB_ALU {dest: it.rdst, data:sltu( rf.rd1(it.rsrc1), rf.rd2(it.rsrc2) ) });
punk@1 375
punk@1 376 // -- Branches --------------------------------------------------
punk@1 377
punk@1 378 tagged BLEZ .it :
punk@1 379 if ( signedLE( rf.rd1(it.rsrc), 0 ) )
punk@1 380 begin
punk@1 381 newPC = pc_plus4 + (sext(it.offset) << 2);
punk@1 382 branchTaken = True;
punk@1 383 end
punk@1 384
punk@1 385 tagged BGTZ .it :
punk@1 386 if ( signedGT( rf.rd1(it.rsrc), 0 ) )
punk@1 387 begin
punk@1 388 newPC = pc_plus4 + (sext(it.offset) << 2);
punk@1 389 branchTaken = True;
punk@1 390 end
punk@1 391
punk@1 392 tagged BLTZ .it :
punk@1 393 if ( signedLT( rf.rd1(it.rsrc), 0 ) )
punk@1 394 begin
punk@1 395 newPC = pc_plus4 + (sext(it.offset) << 2);
punk@1 396 branchTaken = True;
punk@1 397 end
punk@1 398
punk@1 399 tagged BGEZ .it :
punk@1 400 if ( signedGE( rf.rd1(it.rsrc), 0 ) )
punk@1 401 begin
punk@1 402 newPC = pc_plus4 + (sext(it.offset) << 2);
punk@1 403 branchTaken = True;
punk@1 404 end
punk@1 405
punk@1 406 tagged BEQ .it :
punk@1 407 if ( rf.rd1(it.rsrc1) == rf.rd2(it.rsrc2) )
punk@1 408 begin
punk@1 409 newPC = pc_plus4 + (sext(it.offset) << 2);
punk@1 410 branchTaken = True;
punk@1 411 end
punk@1 412
punk@1 413 tagged BNE .it :
punk@1 414 if ( rf.rd1(it.rsrc1) != rf.rd2(it.rsrc2) )
punk@1 415 begin
punk@1 416 newPC = pc_plus4 + (sext(it.offset) << 2);
punk@1 417 branchTaken = True;
punk@1 418 end
punk@1 419
punk@1 420 // -- Jumps -----------------------------------------------------
punk@1 421
punk@1 422 tagged J .it :
punk@1 423 begin
punk@1 424 newPC = { pc_plus4[31:28], it.target, 2'b0 };
punk@1 425 branchTaken = True;
punk@1 426 end
punk@1 427
punk@1 428 tagged JR .it :
punk@1 429 begin
punk@1 430 newPC = rf.rd1(it.rsrc);
punk@1 431 branchTaken = True;
punk@1 432 end
punk@1 433
punk@1 434 tagged JAL .it :
punk@1 435 begin
punk@1 436 wbQ.enq(tagged WB_ALU {dest:31, data:pc_plus4 });
punk@1 437 newPC = { pc_plus4[31:28], it.target, 2'b0 };
punk@1 438 branchTaken = True;
punk@1 439 end
punk@1 440
punk@1 441 tagged JALR .it :
punk@1 442 begin
punk@1 443 wbQ.enq(tagged WB_ALU {dest:it.rdst, data:pc_plus4 });
punk@1 444 newPC = rf.rd1(it.rsrc);
punk@1 445 branchTaken = True;
punk@1 446 end
punk@1 447
punk@1 448 // -- Cop0 ------------------------------------------------------
punk@1 449
punk@1 450 tagged MTC0 .it :
punk@1 451 begin
punk@1 452 case ( it.cop0dst )
punk@1 453 5'd10 : cp0_statsEn <= unpack(truncate(rf.rd1(it.rsrc)));
punk@1 454 5'd21 : cp0_tohost <= truncate(rf.rd1(it.rsrc));
punk@1 455 default :
punk@1 456 $display( " RTL-ERROR : %m : Illegal MTC0 cop0dst register!" );
punk@1 457 endcase
punk@1 458 wbQ.enq(tagged WB_Host 0); //no idea wwhat this actually should be.
punk@1 459 end
punk@1 460
punk@1 461 //this is host stuff?
punk@1 462 tagged MFC0 .it :
punk@1 463 begin
punk@1 464 case ( it.cop0src )
punk@1 465 // not actually an ALU instruction but don't have the format otherwise
punk@1 466 5'd10 : wbQ.enq(tagged WB_ALU {dest:it.rdst, data:zext(pack(cp0_statsEn)) });
punk@1 467 5'd20 : wbQ.enq(tagged WB_ALU {dest:it.rdst, data:cp0_fromhost });
punk@1 468 5'd21 : wbQ.enq(tagged WB_ALU {dest:it.rdst, data:cp0_tohost });
punk@1 469 default :
punk@1 470 $display( " RTL-ERROR : %m : Illegal MFC0 cop0src register!" );
punk@1 471 endcase
punk@1 472 end
punk@1 473
punk@1 474 // -- Illegal ---------------------------------------------------
punk@1 475
punk@1 476 default :
punk@1 477 $display( " RTL-ERROR : %m : Illegal instruction !" );
punk@1 478
punk@1 479 endcase
punk@1 480
punk@1 481 //evaluate branch prediction
punk@1 482 Addr ppc = pcQ.first().qnxtpc; //predicted branch
punk@1 483 if (ppc != newPC) //prediction wrong
punk@1 484 begin
punk@1 485 epoch <= pcQ.first().qepoch + 1;
punk@1 486 bp.upd(instrpc, newPC); //update branch predictor
punk@1 487 pcQ.clear();
punk@1 488 pc <= newPC;
punk@1 489 end
punk@1 490 else
punk@1 491 pcQ.deq();
punk@1 492
punk@1 493 if ( cp0_statsEn )
punk@1 494 num_inst <= num_inst+1;
punk@1 495
punk@1 496 endrule
punk@1 497
punk@1 498 rule writeback; // ( stage == Writeback );
punk@1 499 traceTiny("mkProc", "writeback","W");
punk@1 500
punk@1 501
punk@1 502 // get what to do off the writeback queue
punk@1 503 wbQ.deq();
punk@1 504 case (wbQ.first()) matches
punk@1 505 tagged WB_ALU {data:.res, dest:.rdst} : rf.wr(rdst, res);
punk@1 506 tagged WB_Load .regWr :
punk@1 507 begin
punk@1 508 dataRespQ.deq();
punk@1 509 if (dataRespQ.first() matches tagged LoadResp .ld)
punk@1 510 rf.wr(truncate(ld.tag), ld.data); // no need to use Rindx from queue? Duplicate?
punk@1 511 end
punk@1 512 tagged WB_Store : dataRespQ.deq();
punk@1 513 tagged WB_Host .dat : noAction;
punk@1 514 endcase
punk@1 515
punk@1 516 endrule
punk@1 517
punk@1 518 rule inc_num_cycles;
punk@1 519 if ( cp0_statsEn )
punk@1 520 num_cycles <= num_cycles+1;
punk@1 521 endrule
punk@1 522
punk@1 523
punk@1 524 //-----------------------------------------------------------
punk@1 525 // My Adds
punk@1 526 //-----------------------------------------------------------
punk@1 527
punk@1 528 //-----------------------------------------------------------
punk@1 529 // Methods
punk@1 530
punk@1 531 interface Client imem_client;
punk@1 532 interface Get request = toGet(instReqQ);
punk@1 533 interface Put response = toPut(instRespQ);
punk@1 534 endinterface
punk@1 535
punk@1 536 interface Client dmem_client;
punk@1 537 interface Get request = toGet(dataReqQ);
punk@1 538 interface Put response = toPut(dataRespQ);
punk@1 539 endinterface
punk@1 540
punk@1 541 interface Get statsEn_get = toGet(asReg(cp0_statsEn));
punk@1 542
punk@1 543 interface ProcStats stats;
punk@1 544 interface Get num_cycles = toGet(asReg(num_cycles));
punk@1 545 interface Get num_inst = toGet(asReg(num_inst));
punk@1 546 endinterface
punk@1 547
punk@1 548 interface CPUToHost tohost;
punk@1 549 method Bit#(32) cpuToHost(int req);
punk@1 550 return (case (req)
punk@1 551 0: cp0_tohost;
punk@1 552 1: pc;
punk@1 553 2: zeroExtend(pack(stage));
punk@1 554 endcase);
punk@1 555 endmethod
punk@1 556 endinterface
punk@1 557
punk@1 558 endmodule
punk@1 559