Mercurial > pygar
diff core/src/Processor.bsv @ 1:91a1f76ddd62 pygar svn.2
[svn r2] Adding initial lab 5 source
author | punk |
---|---|
date | Tue, 13 Apr 2010 17:34:33 -0400 |
parents | |
children |
line wrap: on
line diff
1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/core/src/Processor.bsv Tue Apr 13 17:34:33 2010 -0400 1.3 @@ -0,0 +1,559 @@ 1.4 +/// The MIT License 1.5 + 1.6 +// Copyright (c) 2009 Massachusetts Institute of Technology 1.7 + 1.8 +// Permission is hereby granted, free of charge, to any person obtaining a copy 1.9 +// of this software and associated documentation files (the "Software"), to deal 1.10 +// in the Software without restriction, including without limitation the rights 1.11 +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 1.12 +// copies of the Software, and to permit persons to whom the Software is 1.13 +// furnished to do so, subject to the following conditions: 1.14 + 1.15 +// The above copyright notice and this permission notice shall be included in 1.16 +// all copies or substantial portions of the Software. 1.17 + 1.18 +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 1.19 +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 1.20 +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 1.21 +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 1.22 +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 1.23 +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 1.24 +// THE SOFTWARE. 1.25 + 1.26 +import Connectable::*; 1.27 +import GetPut::*; 1.28 +import ClientServer::*; 1.29 +import RegFile::*; 1.30 +import BRegFile::*; 1.31 +import FIFO::*; 1.32 +import FIFOF::*; 1.33 +import SFIFO::*; 1.34 +import RWire::*; 1.35 + 1.36 +import BFIFO::*; 1.37 +import MemTypes::*; 1.38 +import ProcTypes::*; 1.39 +import BranchPred::*; 1.40 +import PathTypes::*; 1.41 + 1.42 +import Trace::*; 1.43 + 1.44 +interface ProcStats; 1.45 + interface Get#(Stat) num_cycles; 1.46 + interface Get#(Stat) num_inst; 1.47 +endinterface 1.48 + 1.49 +interface CPUToHost; 1.50 + method Bit#(32) cpuToHost(int req); 1.51 +endinterface 1.52 + 1.53 +interface Proc; 1.54 + 1.55 + // Interface from processor to caches 1.56 + interface Client#(DataReq,DataResp) dmem_client; 1.57 + interface Client#(InstReq,InstResp) imem_client; 1.58 + 1.59 + // Interface for enabling/disabling statistics on the rest of the core 1.60 + interface Get#(Bool) statsEn_get; 1.61 + 1.62 + // Interface for collecting statistics. 1.63 + interface ProcStats stats; 1.64 + 1.65 + // Interface to host 1.66 + interface CPUToHost tohost; 1.67 + 1.68 +endinterface 1.69 + 1.70 + 1.71 +typedef enum { PCgen, Exec, Writeback } Stage deriving(Eq,Bits); 1.72 + 1.73 +//----------------------------------------------------------- 1.74 +// Register file module 1.75 +//----------------------------------------------------------- 1.76 + 1.77 +interface BRFile; 1.78 + method Action wr( Rindx rindx, Bit#(32) data ); 1.79 + method Bit#(32) rd1( Rindx rindx ); 1.80 + method Bit#(32) rd2( Rindx rindx ); 1.81 +endinterface 1.82 + 1.83 +module mkBRFile( BRFile ); 1.84 + 1.85 + RegFile#(Rindx,Bit#(32)) rfile <- mkBRegFile(); 1.86 + 1.87 + method Action wr( Rindx rindx, Bit#(32) data ); 1.88 + rfile.upd( rindx, data ); 1.89 + endmethod 1.90 + 1.91 + method Bit#(32) rd1( Rindx rindx ); 1.92 + return ( rindx == 0 ) ? 0 : rfile.sub(rindx); 1.93 + endmethod 1.94 + 1.95 + method Bit#(32) rd2( Rindx rindx ); 1.96 + return ( rindx == 0 ) ? 0 : rfile.sub(rindx); 1.97 + endmethod 1.98 + 1.99 +endmodule 1.100 + 1.101 +//----------------------------------------------------------- 1.102 +// Helper functions 1.103 +//----------------------------------------------------------- 1.104 + 1.105 +function Bit#(32) slt( Bit#(32) val1, Bit#(32) val2 ); 1.106 + return zeroExtend( pack( signedLT(val1,val2) ) ); 1.107 +endfunction 1.108 + 1.109 +function Bit#(32) sltu( Bit#(32) val1, Bit#(32) val2 ); 1.110 + return zeroExtend( pack( val1 < val2 ) ); 1.111 +endfunction 1.112 + 1.113 +function Bit#(32) rshft( Bit#(32) val ); 1.114 + return zeroExtend(val[4:0]); 1.115 +endfunction 1.116 + 1.117 + 1.118 +//----------------------------------------------------------- 1.119 +// Find funct for wbQ 1.120 +//----------------------------------------------------------- 1.121 +function Bool findwbf(Rindx fVal, WBResult cmpVal); 1.122 + case (cmpVal) matches 1.123 + tagged WB_ALU {data:.res, dest:.rd} : 1.124 + return (fVal == rd); 1.125 + tagged WB_Load .rd : 1.126 + return (fVal == rd); 1.127 + tagged WB_Store .st : 1.128 + return False; 1.129 + tagged WB_Host .x : 1.130 + return False; 1.131 + endcase 1.132 +endfunction 1.133 + 1.134 + 1.135 +//----------------------------------------------------------- 1.136 +// Stall funct for wbQ 1.137 +//----------------------------------------------------------- 1.138 +function Bool stall(Instr inst, SFIFO#(WBResult, Rindx) f); 1.139 + case (inst) matches 1.140 + // -- Memory Ops ------------------------------------------------ 1.141 + tagged LW .it : 1.142 + return f.find(it.rbase); 1.143 + tagged SW {rsrc:.dreg, rbase:.addr, offset:.o} : 1.144 + return (f.find(addr) || f.find2(dreg)); 1.145 + 1.146 + // -- Simple Ops ------------------------------------------------ 1.147 + tagged ADDIU .it : return f.find(it.rsrc); 1.148 + tagged SLTI .it : return f.find(it.rsrc); 1.149 + tagged SLTIU .it : return f.find(it.rsrc); 1.150 + tagged ANDI .it : return f.find(it.rsrc); 1.151 + tagged ORI .it : return f.find(it.rsrc); 1.152 + tagged XORI .it : return f.find(it.rsrc); 1.153 + 1.154 + tagged LUI .it : return f.find(it.rdst); //this rds/wrs itself 1.155 + tagged SLL .it : return f.find(it.rsrc); 1.156 + tagged SRL .it : return f.find(it.rsrc); 1.157 + tagged SRA .it : return f.find(it.rsrc); 1.158 + tagged SLLV .it : return (f.find(it.rsrc) || f.find(it.rshamt)); 1.159 + tagged SRLV .it : return (f.find(it.rsrc) || f.find(it.rshamt)); 1.160 + tagged SRAV .it : return (f.find(it.rsrc) || f.find(it.rshamt)); 1.161 + tagged ADDU .it : return (f.find(it.rsrc1) || f.find2(it.rsrc2)); 1.162 + tagged SUBU .it : return (f.find(it.rsrc1) || f.find2(it.rsrc2)); 1.163 + tagged AND .it : return (f.find(it.rsrc1) || f.find2(it.rsrc2)); 1.164 + tagged OR .it : return (f.find(it.rsrc1) || f.find2(it.rsrc2)); 1.165 + tagged XOR .it : return (f.find(it.rsrc1) || f.find2(it.rsrc2)); 1.166 + tagged NOR .it : return (f.find(it.rsrc1) || f.find2(it.rsrc2)); 1.167 + tagged SLT .it : return (f.find(it.rsrc1) || f.find2(it.rsrc2)); 1.168 + tagged SLTU .it : return (f.find(it.rsrc1) || f.find2(it.rsrc2)); 1.169 + 1.170 + 1.171 + // -- Branches -------------------------------------------------- 1.172 + 1.173 + tagged BLEZ .it : return (f.find(it.rsrc)); 1.174 + tagged BGTZ .it : return (f.find(it.rsrc)); 1.175 + tagged BLTZ .it : return (f.find(it.rsrc)); 1.176 + tagged BGEZ .it : return (f.find(it.rsrc)); 1.177 + tagged BEQ .it : return (f.find(it.rsrc1) || f.find2(it.rsrc2)); 1.178 + tagged BNE .it : return (f.find(it.rsrc1) || f.find2(it.rsrc2)); 1.179 + 1.180 + // -- Jumps ----------------------------------------------------- 1.181 + 1.182 + tagged J .it : return False; 1.183 + tagged JR .it : return f.find(it.rsrc); 1.184 + tagged JALR .it : return f.find(it.rsrc); 1.185 + tagged JAL .it : return False; 1.186 + 1.187 + // -- Cop0 ------------------------------------------------------ 1.188 + 1.189 + tagged MTC0 .it : return f.find(it.rsrc); 1.190 + tagged MFC0 .it : return False; 1.191 + 1.192 + // -- Illegal --------------------------------------------------- 1.193 + 1.194 + default : return False; 1.195 + 1.196 + endcase 1.197 +endfunction 1.198 +//----------------------------------------------------------- 1.199 +// Reference processor 1.200 +//----------------------------------------------------------- 1.201 + 1.202 + 1.203 +(* doc = "synthesis attribute ram_style mkProc distributed;" *) 1.204 +(* synthesize *) 1.205 +module mkProc( Proc ); 1.206 + 1.207 + //----------------------------------------------------------- 1.208 + // State 1.209 + 1.210 + // Standard processor state 1.211 + 1.212 + Reg#(Addr) pc <- mkReg(32'h00001000); 1.213 + Reg#(Epoch) epoch <- mkReg(0); 1.214 + Reg#(Stage) stage <- mkReg(PCgen); 1.215 + BRFile rf <- mkBRFile; 1.216 + 1.217 + // Branch Prediction 1.218 + BranchPred bp <- mkBranchPred(); 1.219 + FIFO#(PCStat) execpc <- mkLFIFO(); 1.220 + 1.221 + // Pipelines 1.222 + FIFO#(PCStat) pcQ <-mkSizedFIFO(3); 1.223 + SFIFO#(WBResult, Rindx) wbQ <-mkSFIFO(findwbf); 1.224 + 1.225 + Reg#(Bit#(32)) cp0_tohost <- mkReg(0); 1.226 + Reg#(Bit#(32)) cp0_fromhost <- mkReg(0); 1.227 + Reg#(Bool) cp0_statsEn <- mkReg(False); 1.228 + 1.229 + // Memory request/response state 1.230 + 1.231 + FIFO#(InstReq) instReqQ <- mkBFIFO1(); 1.232 + FIFO#(InstResp) instRespQ <- mkFIFO(); 1.233 + 1.234 + FIFO#(DataReq) dataReqQ <- mkBFIFO1(); 1.235 + FIFO#(DataResp) dataRespQ <- mkFIFO(); 1.236 + 1.237 + // Statistics state 1.238 + Reg#(Stat) num_cycles <- mkReg(0); 1.239 + Reg#(Stat) num_inst <- mkReg(0); 1.240 + 1.241 + //----------------------------------------------------------- 1.242 + // Rules 1.243 + 1.244 + (* descending_urgency = "exec, pcgen" *) 1.245 + rule pcgen; //( stage == PCgen ); 1.246 + let pc_plus4 = pc + 4; 1.247 + 1.248 + traceTiny("mkProc", "pc",pc); 1.249 + traceTiny("mkProc", "pcgen","P"); 1.250 + instReqQ.enq( LoadReq{ addr:pc, tag:epoch} ); 1.251 + 1.252 + let next_pc = bp.get(pc); 1.253 + if (next_pc matches tagged Valid .npc) 1.254 + begin 1.255 + pcQ.enq(PCStat {qpc:pc, qnxtpc:npc, qepoch:epoch}); 1.256 + pc <= npc; 1.257 + end 1.258 + else 1.259 + begin 1.260 + pcQ.enq(PCStat {qpc:pc, qnxtpc:pc_plus4, qepoch:epoch}); 1.261 + pc <= pc_plus4; 1.262 + end 1.263 + 1.264 + endrule 1.265 + 1.266 + rule discard (instRespQ.first() matches tagged LoadResp .ld 1.267 + &&& ld.tag != epoch); 1.268 + traceTiny("mkProc", "stage", "D"); 1.269 + instRespQ.deq(); 1.270 + endrule 1.271 + 1.272 + (* conflict_free = "exec, writeback" *) 1.273 + rule exec (instRespQ.first() matches tagged LoadResp.ld 1.274 + &&& (ld.tag == epoch) 1.275 + &&& unpack(ld.data) matches .inst 1.276 + &&& !stall(inst, wbQ)); 1.277 + 1.278 + // Some abbreviations 1.279 + let sext = signExtend; 1.280 + let zext = zeroExtend; 1.281 + let sra = signedShiftRight; 1.282 + 1.283 + // Get the instruction 1.284 + 1.285 + instRespQ.deq(); 1.286 + Instr inst 1.287 + = case ( instRespQ.first() ) matches 1.288 + tagged LoadResp .ld : return unpack(ld.data); 1.289 + tagged StoreResp .st : return ?; 1.290 + endcase; 1.291 + 1.292 + // Get the PC info 1.293 + let instrpc = pcQ.first().qpc; 1.294 + let pc_plus4 = instrpc + 4; 1.295 + 1.296 + Bool branchTaken = False; 1.297 + Addr newPC = pc_plus4; 1.298 + 1.299 + // Tracing 1.300 + traceTiny("mkProc", "exec","X"); 1.301 + traceTiny("mkProc", "exInstTiny",inst); 1.302 + traceFull("mkProc", "exInstFull",inst); 1.303 + 1.304 + case ( inst ) matches 1.305 + 1.306 + // -- Memory Ops ------------------------------------------------ 1.307 + 1.308 + tagged LW .it : 1.309 + begin 1.310 + Addr addr = rf.rd1(it.rbase) + sext(it.offset); 1.311 + dataReqQ.enq( LoadReq{ addr:addr, tag:zeroExtend(it.rdst) } ); 1.312 + wbQ.enq(tagged WB_Load it.rdst); 1.313 + end 1.314 + 1.315 + tagged SW .it : 1.316 + begin 1.317 + Addr addr = rf.rd1(it.rbase) + sext(it.offset); 1.318 + dataReqQ.enq( StoreReq{ tag:0, addr:addr, data:rf.rd2(it.rsrc) } ); 1.319 + wbQ.enq(tagged WB_Store); 1.320 + end 1.321 + 1.322 + // -- Simple Ops ------------------------------------------------ 1.323 + 1.324 + tagged ADDIU .it : 1.325 + begin 1.326 + Bit#(32) result = rf.rd1(it.rsrc) + sext(it.imm); 1.327 + wbQ.enq(tagged WB_ALU {data:result, dest:it.rdst}); 1.328 + end 1.329 + tagged SLTI .it : wbQ.enq(tagged WB_ALU {dest:it.rdst, data:slt( rf.rd1(it.rsrc), sext(it.imm) )}); 1.330 + tagged SLTIU .it : wbQ.enq(tagged WB_ALU {dest:it.rdst, data:sltu( rf.rd1(it.rsrc), sext(it.imm) ) }); 1.331 + tagged ANDI .it : 1.332 + begin 1.333 + Bit#(32) zext_it_imm = zext(it.imm); 1.334 + wbQ.enq(tagged WB_ALU {dest:it.rdst, data:(rf.rd1(it.rsrc) & zext_it_imm)} ); 1.335 + end 1.336 + tagged ORI .it : 1.337 + begin 1.338 + Bit#(32) zext_it_imm = zext(it.imm); 1.339 + wbQ.enq(tagged WB_ALU {dest:it.rdst, data:(rf.rd1(it.rsrc) | zext_it_imm)} ); 1.340 + end 1.341 + tagged XORI .it : 1.342 + begin 1.343 + Bit#(32) zext_it_imm = zext(it.imm); 1.344 + wbQ.enq(tagged WB_ALU {dest: it.rdst, data:(rf.rd1(it.rsrc) ^ zext_it_imm )}); 1.345 + end 1.346 + tagged LUI .it : 1.347 + begin 1.348 + Bit#(32) zext_it_imm = zext(it.imm); 1.349 + wbQ.enq(tagged WB_ALU {dest: it.rdst, data:(zext_it_imm << 32'd16) }); 1.350 + end 1.351 + 1.352 + tagged SLL .it : 1.353 + begin 1.354 + Bit#(32) zext_it_shamt = zext(it.shamt); 1.355 + wbQ.enq(tagged WB_ALU {dest: it.rdst, data:(rf.rd1(it.rsrc) << zext_it_shamt )} ); 1.356 + end 1.357 + tagged SRL .it : 1.358 + begin 1.359 + Bit#(32) zext_it_shamt = zext(it.shamt); 1.360 + wbQ.enq(tagged WB_ALU {dest: it.rdst, data:(rf.rd1(it.rsrc) >> zext_it_shamt )}); 1.361 + end 1.362 + tagged SRA .it : 1.363 + begin 1.364 + Bit#(32) zext_it_shamt = zext(it.shamt); 1.365 + wbQ.enq(tagged WB_ALU {dest: it.rdst, data:sra( rf.rd1(it.rsrc), zext_it_shamt )}); 1.366 + end 1.367 + tagged SLLV .it : wbQ.enq(tagged WB_ALU {dest: it.rdst, data:(rf.rd1(it.rsrc) << rshft(rf.rd2(it.rshamt)) )}); 1.368 + tagged SRLV .it : wbQ.enq(tagged WB_ALU {dest: it.rdst, data:(rf.rd1(it.rsrc) >> rshft(rf.rd2(it.rshamt)) )} ); 1.369 + tagged SRAV .it : wbQ.enq(tagged WB_ALU {dest: it.rdst, data:sra( rf.rd1(it.rsrc), rshft(rf.rd2(it.rshamt)) ) }); 1.370 + tagged ADDU .it : wbQ.enq(tagged WB_ALU {dest: it.rdst, data:(rf.rd1(it.rsrc1) + rf.rd2(it.rsrc2) )} ); 1.371 + tagged SUBU .it : wbQ.enq(tagged WB_ALU {dest: it.rdst, data:(rf.rd1(it.rsrc1) - rf.rd2(it.rsrc2) )} ); 1.372 + tagged AND .it : wbQ.enq(tagged WB_ALU {dest: it.rdst, data:(rf.rd1(it.rsrc1) & rf.rd2(it.rsrc2) )} ); 1.373 + tagged OR .it : wbQ.enq(tagged WB_ALU {dest: it.rdst, data:(rf.rd1(it.rsrc1) | rf.rd2(it.rsrc2) )} ); 1.374 + tagged XOR .it : wbQ.enq(tagged WB_ALU {dest: it.rdst, data:(rf.rd1(it.rsrc1) ^ rf.rd2(it.rsrc2) )} ); 1.375 + tagged NOR .it : wbQ.enq(tagged WB_ALU {dest: it.rdst, data:(~(rf.rd1(it.rsrc1) | rf.rd2(it.rsrc2)) )} ); 1.376 + tagged SLT .it : wbQ.enq(tagged WB_ALU {dest: it.rdst, data:slt( rf.rd1(it.rsrc1), rf.rd2(it.rsrc2) ) }); 1.377 + tagged SLTU .it : wbQ.enq(tagged WB_ALU {dest: it.rdst, data:sltu( rf.rd1(it.rsrc1), rf.rd2(it.rsrc2) ) }); 1.378 + 1.379 + // -- Branches -------------------------------------------------- 1.380 + 1.381 + tagged BLEZ .it : 1.382 + if ( signedLE( rf.rd1(it.rsrc), 0 ) ) 1.383 + begin 1.384 + newPC = pc_plus4 + (sext(it.offset) << 2); 1.385 + branchTaken = True; 1.386 + end 1.387 + 1.388 + tagged BGTZ .it : 1.389 + if ( signedGT( rf.rd1(it.rsrc), 0 ) ) 1.390 + begin 1.391 + newPC = pc_plus4 + (sext(it.offset) << 2); 1.392 + branchTaken = True; 1.393 + end 1.394 + 1.395 + tagged BLTZ .it : 1.396 + if ( signedLT( rf.rd1(it.rsrc), 0 ) ) 1.397 + begin 1.398 + newPC = pc_plus4 + (sext(it.offset) << 2); 1.399 + branchTaken = True; 1.400 + end 1.401 + 1.402 + tagged BGEZ .it : 1.403 + if ( signedGE( rf.rd1(it.rsrc), 0 ) ) 1.404 + begin 1.405 + newPC = pc_plus4 + (sext(it.offset) << 2); 1.406 + branchTaken = True; 1.407 + end 1.408 + 1.409 + tagged BEQ .it : 1.410 + if ( rf.rd1(it.rsrc1) == rf.rd2(it.rsrc2) ) 1.411 + begin 1.412 + newPC = pc_plus4 + (sext(it.offset) << 2); 1.413 + branchTaken = True; 1.414 + end 1.415 + 1.416 + tagged BNE .it : 1.417 + if ( rf.rd1(it.rsrc1) != rf.rd2(it.rsrc2) ) 1.418 + begin 1.419 + newPC = pc_plus4 + (sext(it.offset) << 2); 1.420 + branchTaken = True; 1.421 + end 1.422 + 1.423 + // -- Jumps ----------------------------------------------------- 1.424 + 1.425 + tagged J .it : 1.426 + begin 1.427 + newPC = { pc_plus4[31:28], it.target, 2'b0 }; 1.428 + branchTaken = True; 1.429 + end 1.430 + 1.431 + tagged JR .it : 1.432 + begin 1.433 + newPC = rf.rd1(it.rsrc); 1.434 + branchTaken = True; 1.435 + end 1.436 + 1.437 + tagged JAL .it : 1.438 + begin 1.439 + wbQ.enq(tagged WB_ALU {dest:31, data:pc_plus4 }); 1.440 + newPC = { pc_plus4[31:28], it.target, 2'b0 }; 1.441 + branchTaken = True; 1.442 + end 1.443 + 1.444 + tagged JALR .it : 1.445 + begin 1.446 + wbQ.enq(tagged WB_ALU {dest:it.rdst, data:pc_plus4 }); 1.447 + newPC = rf.rd1(it.rsrc); 1.448 + branchTaken = True; 1.449 + end 1.450 + 1.451 + // -- Cop0 ------------------------------------------------------ 1.452 + 1.453 + tagged MTC0 .it : 1.454 + begin 1.455 + case ( it.cop0dst ) 1.456 + 5'd10 : cp0_statsEn <= unpack(truncate(rf.rd1(it.rsrc))); 1.457 + 5'd21 : cp0_tohost <= truncate(rf.rd1(it.rsrc)); 1.458 + default : 1.459 + $display( " RTL-ERROR : %m : Illegal MTC0 cop0dst register!" ); 1.460 + endcase 1.461 + wbQ.enq(tagged WB_Host 0); //no idea wwhat this actually should be. 1.462 + end 1.463 + 1.464 +//this is host stuff? 1.465 + tagged MFC0 .it : 1.466 + begin 1.467 + case ( it.cop0src ) 1.468 + // not actually an ALU instruction but don't have the format otherwise 1.469 + 5'd10 : wbQ.enq(tagged WB_ALU {dest:it.rdst, data:zext(pack(cp0_statsEn)) }); 1.470 + 5'd20 : wbQ.enq(tagged WB_ALU {dest:it.rdst, data:cp0_fromhost }); 1.471 + 5'd21 : wbQ.enq(tagged WB_ALU {dest:it.rdst, data:cp0_tohost }); 1.472 + default : 1.473 + $display( " RTL-ERROR : %m : Illegal MFC0 cop0src register!" ); 1.474 + endcase 1.475 + end 1.476 + 1.477 + // -- Illegal --------------------------------------------------- 1.478 + 1.479 + default : 1.480 + $display( " RTL-ERROR : %m : Illegal instruction !" ); 1.481 + 1.482 + endcase 1.483 + 1.484 +//evaluate branch prediction 1.485 + Addr ppc = pcQ.first().qnxtpc; //predicted branch 1.486 + if (ppc != newPC) //prediction wrong 1.487 + begin 1.488 + epoch <= pcQ.first().qepoch + 1; 1.489 + bp.upd(instrpc, newPC); //update branch predictor 1.490 + pcQ.clear(); 1.491 + pc <= newPC; 1.492 + end 1.493 + else 1.494 + pcQ.deq(); 1.495 + 1.496 + if ( cp0_statsEn ) 1.497 + num_inst <= num_inst+1; 1.498 + 1.499 + endrule 1.500 + 1.501 + rule writeback; // ( stage == Writeback ); 1.502 + traceTiny("mkProc", "writeback","W"); 1.503 + 1.504 + 1.505 + // get what to do off the writeback queue 1.506 + wbQ.deq(); 1.507 + case (wbQ.first()) matches 1.508 + tagged WB_ALU {data:.res, dest:.rdst} : rf.wr(rdst, res); 1.509 + tagged WB_Load .regWr : 1.510 + begin 1.511 + dataRespQ.deq(); 1.512 + if (dataRespQ.first() matches tagged LoadResp .ld) 1.513 + rf.wr(truncate(ld.tag), ld.data); // no need to use Rindx from queue? Duplicate? 1.514 + end 1.515 + tagged WB_Store : dataRespQ.deq(); 1.516 + tagged WB_Host .dat : noAction; 1.517 + endcase 1.518 + 1.519 + endrule 1.520 + 1.521 + rule inc_num_cycles; 1.522 + if ( cp0_statsEn ) 1.523 + num_cycles <= num_cycles+1; 1.524 + endrule 1.525 + 1.526 + 1.527 +//----------------------------------------------------------- 1.528 +// My Adds 1.529 +//----------------------------------------------------------- 1.530 + 1.531 + //----------------------------------------------------------- 1.532 + // Methods 1.533 + 1.534 + interface Client imem_client; 1.535 + interface Get request = toGet(instReqQ); 1.536 + interface Put response = toPut(instRespQ); 1.537 + endinterface 1.538 + 1.539 + interface Client dmem_client; 1.540 + interface Get request = toGet(dataReqQ); 1.541 + interface Put response = toPut(dataRespQ); 1.542 + endinterface 1.543 + 1.544 + interface Get statsEn_get = toGet(asReg(cp0_statsEn)); 1.545 + 1.546 + interface ProcStats stats; 1.547 + interface Get num_cycles = toGet(asReg(num_cycles)); 1.548 + interface Get num_inst = toGet(asReg(num_inst)); 1.549 + endinterface 1.550 + 1.551 + interface CPUToHost tohost; 1.552 + method Bit#(32) cpuToHost(int req); 1.553 + return (case (req) 1.554 + 0: cp0_tohost; 1.555 + 1: pc; 1.556 + 2: zeroExtend(pack(stage)); 1.557 + endcase); 1.558 + endmethod 1.559 + endinterface 1.560 + 1.561 +endmodule 1.562 +