annotate modules/bluespec/Pygar/lab4/#Processor.bsv# @ 42:ced2ebd41347 pygar svn.43

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