Mercurial > pygar
diff modules/bluespec/Pygar/core/Processor.bsv @ 8:74716e9a81cc pygar svn.9
[svn r9] Pygar now has the proper directory structure to play nicely with awb. Also, the apm file for audio-core willcompile successfully.
author | rlm |
---|---|
date | Fri, 23 Apr 2010 02:32:05 -0400 |
parents | |
children | 50af57801d6e |
line wrap: on
line diff
1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/modules/bluespec/Pygar/core/Processor.bsv Fri Apr 23 02:32:05 2010 -0400 1.3 @@ -0,0 +1,590 @@ 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 + 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 BRegFile::*; 1.40 +import BranchPred::*; 1.41 +//import PathTypes::*; This is only there to force the debugging 1.42 + 1.43 +import Trace::*; 1.44 + 1.45 +//AWB includes 1.46 +`include "asim/provides/low_level_platform_interface.bsh" 1.47 +`include "asim/provides/soft_connections.bsh" 1.48 +`include "asim/provides/common_services.bsh" 1.49 + 1.50 +// Local includes 1.51 +`include "asim/provides/processor_library.bsh" 1.52 +`include "asim/rrr/remote_server_stub_PROCESSORSYSTEMRRR.bsh" 1.53 +`include "asim/provides/common_services.bsh" 1.54 +`include "asim/dict/STATS_PROCESSOR.bsh" 1.55 + 1.56 +interface ProcStats; 1.57 + interface Get#(Stat) num_cycles; 1.58 + interface Get#(Stat) num_inst; 1.59 +endinterface 1.60 + 1.61 +interface CPUToHost; 1.62 + method Bit#(32) cpuToHost(int req); 1.63 +endinterface 1.64 + 1.65 +interface Proc; 1.66 + 1.67 + // Interface from processor to caches 1.68 + interface Client#(DataReq,DataResp) dmem_client; 1.69 + interface Client#(InstReq,InstResp) imem_client; 1.70 + 1.71 + // Interface for enabling/disabling statistics on the rest of the core 1.72 + interface Get#(Bool) statsEn_get; 1.73 + 1.74 + // Interface for collecting statistics. 1.75 + interface ProcStats stats; 1.76 + 1.77 + // Interface to host 1.78 + interface CPUToHost tohost; 1.79 + 1.80 +endinterface 1.81 + 1.82 + 1.83 +typedef enum { PCgen, Exec, Writeback } Stage deriving(Eq,Bits); 1.84 + 1.85 +//----------------------------------------------------------- 1.86 +// Register file module 1.87 +//----------------------------------------------------------- 1.88 + 1.89 +interface BRFile; 1.90 + method Action wr( Rindx rindx, Bit#(32) data ); 1.91 + method Bit#(32) rd1( Rindx rindx ); 1.92 + method Bit#(32) rd2( Rindx rindx ); 1.93 +endinterface 1.94 + 1.95 +module mkBRFile( BRFile ); 1.96 + 1.97 + RegFile#(Rindx,Bit#(32)) rfile <- mkBRegFile(); 1.98 + 1.99 + method Action wr( Rindx rindx, Bit#(32) data ); 1.100 + rfile.upd( rindx, data ); 1.101 + endmethod 1.102 + 1.103 + method Bit#(32) rd1( Rindx rindx ); 1.104 + return ( rindx == 0 ) ? 0 : rfile.sub(rindx); 1.105 + endmethod 1.106 + 1.107 + method Bit#(32) rd2( Rindx rindx ); 1.108 + return ( rindx == 0 ) ? 0 : rfile.sub(rindx); 1.109 + endmethod 1.110 + 1.111 +endmodule 1.112 + 1.113 +//----------------------------------------------------------- 1.114 +// Helper functions 1.115 +//----------------------------------------------------------- 1.116 + 1.117 +function Bit#(32) slt( Bit#(32) val1, Bit#(32) val2 ); 1.118 + return zeroExtend( pack( signedLT(val1,val2) ) ); 1.119 +endfunction 1.120 + 1.121 +function Bit#(32) sltu( Bit#(32) val1, Bit#(32) val2 ); 1.122 + return zeroExtend( pack( val1 < val2 ) ); 1.123 +endfunction 1.124 + 1.125 +function Bit#(32) rshft( Bit#(32) val ); 1.126 + return zeroExtend(val[4:0]); 1.127 +endfunction 1.128 + 1.129 + 1.130 +//----------------------------------------------------------- 1.131 +// Find funct for wbQ 1.132 +//----------------------------------------------------------- 1.133 +function Bool findwbf(Rindx fVal, WBResult cmpVal); 1.134 + case (cmpVal) matches 1.135 + tagged WB_ALU {data:.res, dest:.rd} : 1.136 + return (fVal == rd); 1.137 + tagged WB_Load .rd : 1.138 + return (fVal == rd); 1.139 + tagged WB_Store .st : 1.140 + return False; 1.141 + tagged WB_Host .x : 1.142 + return False; 1.143 + endcase 1.144 +endfunction 1.145 + 1.146 + 1.147 +//----------------------------------------------------------- 1.148 +// Stall funct for wbQ 1.149 +//----------------------------------------------------------- 1.150 +function Bool stall(Instr inst, SFIFO#(WBResult, Rindx) f); 1.151 + case (inst) matches 1.152 + // -- Memory Ops ------------------------------------------------ 1.153 + tagged LW .it : 1.154 + return f.find(it.rbase); 1.155 + tagged SW {rsrc:.dreg, rbase:.addr, offset:.o} : 1.156 + return (f.find(addr) || f.find2(dreg)); 1.157 + 1.158 + // -- Simple Ops ------------------------------------------------ 1.159 + tagged ADDIU .it : return f.find(it.rsrc); 1.160 + tagged SLTI .it : return f.find(it.rsrc); 1.161 + tagged SLTIU .it : return f.find(it.rsrc); 1.162 + tagged ANDI .it : return f.find(it.rsrc); 1.163 + tagged ORI .it : return f.find(it.rsrc); 1.164 + tagged XORI .it : return f.find(it.rsrc); 1.165 + 1.166 + tagged LUI .it : return f.find(it.rdst); //this rds/wrs itself 1.167 + tagged SLL .it : return f.find(it.rsrc); 1.168 + tagged SRL .it : return f.find(it.rsrc); 1.169 + tagged SRA .it : return f.find(it.rsrc); 1.170 + tagged SLLV .it : return (f.find(it.rsrc) || f.find(it.rshamt)); 1.171 + tagged SRLV .it : return (f.find(it.rsrc) || f.find(it.rshamt)); 1.172 + tagged SRAV .it : return (f.find(it.rsrc) || f.find(it.rshamt)); 1.173 + tagged ADDU .it : return (f.find(it.rsrc1) || f.find2(it.rsrc2)); 1.174 + tagged SUBU .it : return (f.find(it.rsrc1) || f.find2(it.rsrc2)); 1.175 + tagged AND .it : return (f.find(it.rsrc1) || f.find2(it.rsrc2)); 1.176 + tagged OR .it : return (f.find(it.rsrc1) || f.find2(it.rsrc2)); 1.177 + tagged XOR .it : return (f.find(it.rsrc1) || f.find2(it.rsrc2)); 1.178 + tagged NOR .it : return (f.find(it.rsrc1) || f.find2(it.rsrc2)); 1.179 + tagged SLT .it : return (f.find(it.rsrc1) || f.find2(it.rsrc2)); 1.180 + tagged SLTU .it : return (f.find(it.rsrc1) || f.find2(it.rsrc2)); 1.181 + 1.182 + 1.183 + // -- Branches -------------------------------------------------- 1.184 + 1.185 + tagged BLEZ .it : return (f.find(it.rsrc)); 1.186 + tagged BGTZ .it : return (f.find(it.rsrc)); 1.187 + tagged BLTZ .it : return (f.find(it.rsrc)); 1.188 + tagged BGEZ .it : return (f.find(it.rsrc)); 1.189 + tagged BEQ .it : return (f.find(it.rsrc1) || f.find2(it.rsrc2)); 1.190 + tagged BNE .it : return (f.find(it.rsrc1) || f.find2(it.rsrc2)); 1.191 + 1.192 + // -- Jumps ----------------------------------------------------- 1.193 + 1.194 + tagged J .it : return False; 1.195 + tagged JR .it : return f.find(it.rsrc); 1.196 + tagged JALR .it : return f.find(it.rsrc); 1.197 + tagged JAL .it : return False; 1.198 + 1.199 + // -- Cop0 ------------------------------------------------------ 1.200 + 1.201 + tagged MTC0 .it : return f.find(it.rsrc); 1.202 + tagged MFC0 .it : return False; 1.203 + 1.204 + // -- Illegal --------------------------------------------------- 1.205 + 1.206 + default : return False; 1.207 + 1.208 + endcase 1.209 +endfunction 1.210 +//----------------------------------------------------------- 1.211 +// Reference processor 1.212 +//----------------------------------------------------------- 1.213 + 1.214 + 1.215 +//(* doc = "synthesis attribute ram_style mkProc distributed;" *) 1.216 +//(* synthesize *) 1.217 + 1.218 +module [CONNECTED_MODULE] mkProc( Proc ); 1.219 + 1.220 + //----------------------------------------------------------- 1.221 + // Debug port 1.222 + 1.223 + ServerStub_PROCESSORSYSTEMRRR server_stub <- mkServerStub_PROCESSORSYSTEMRRR(); 1.224 + 1.225 + 1.226 + //----------------------------------------------------------- 1.227 + // State 1.228 + 1.229 + // Standard processor state 1.230 + 1.231 + Reg#(Addr) pc <- mkReg(32'h00001000); 1.232 + Reg#(Epoch) epoch <- mkReg(0); 1.233 + Reg#(Stage) stage <- mkReg(PCgen); 1.234 + BRFile rf <- mkBRFile; 1.235 + 1.236 + // Branch Prediction 1.237 + BranchPred bp <- mkBranchPred(); 1.238 + FIFO#(PCStat) execpc <- mkLFIFO(); 1.239 + 1.240 + // Pipelines 1.241 + FIFO#(PCStat) pcQ <-mkSizedFIFO(3); 1.242 + SFIFO#(WBResult, Rindx) wbQ <-mkSFIFO(findwbf); 1.243 + 1.244 + Reg#(Bit#(32)) cp0_tohost <- mkReg(0); 1.245 + Reg#(Bit#(32)) cp0_fromhost <- mkReg(0); 1.246 + Reg#(Bool) cp0_statsEn <- mkReg(False); 1.247 + 1.248 + // Memory request/response state 1.249 + 1.250 + FIFO#(InstReq) instReqQ <- mkBFIFO1(); 1.251 + FIFO#(InstResp) instRespQ <- mkFIFO(); 1.252 + 1.253 + FIFO#(DataReq) dataReqQ <- mkBFIFO1(); 1.254 + FIFO#(DataResp) dataRespQ <- mkFIFO(); 1.255 + 1.256 + // Statistics state 1.257 + Reg#(Stat) num_cycles <- mkReg(0); 1.258 + Reg#(Stat) num_inst <- mkReg(0); 1.259 + 1.260 + //Or: 1.261 + // Statistics state 1.262 + //STAT num_cycles <- mkStatCounter(`STATS_PROCESSOR_CYCLE_COUNT); 1.263 + //STAT num_inst <- mkStatCounter(`STATS_PROCESSOR_INST_COUNT); 1.264 + 1.265 + //----------------------------------------------------------- 1.266 + // Rules 1.267 + 1.268 + (* descending_urgency = "exec, pcgen" *) 1.269 + rule pcgen; //( stage == PCgen ); 1.270 + let pc_plus4 = pc + 4; 1.271 + 1.272 + traceTiny("mkProc", "pc",pc); 1.273 + traceTiny("mkProc", "pcgen","P"); 1.274 + instReqQ.enq( LoadReq{ addr:pc, tag:epoch} ); 1.275 + 1.276 + let next_pc = bp.get(pc); 1.277 + if (next_pc matches tagged Valid .npc) 1.278 + begin 1.279 + pcQ.enq(PCStat {qpc:pc, qnxtpc:npc, qepoch:epoch}); 1.280 + pc <= npc; 1.281 + end 1.282 + else 1.283 + begin 1.284 + pcQ.enq(PCStat {qpc:pc, qnxtpc:pc_plus4, qepoch:epoch}); 1.285 + pc <= pc_plus4; 1.286 + end 1.287 + 1.288 + endrule 1.289 + 1.290 + rule discard (instRespQ.first() matches tagged LoadResp .ld 1.291 + &&& ld.tag != epoch); 1.292 + traceTiny("mkProc", "stage", "D"); 1.293 + instRespQ.deq(); 1.294 + endrule 1.295 + 1.296 + (* conflict_free = "exec, writeback" *) 1.297 + rule exec (instRespQ.first() matches tagged LoadResp.ld 1.298 + &&& (ld.tag == epoch) 1.299 + &&& unpack(ld.data) matches .inst 1.300 + &&& !stall(inst, wbQ)); 1.301 + 1.302 + // Some abbreviations 1.303 + let sext = signExtend; 1.304 + let zext = zeroExtend; 1.305 + let sra = signedShiftRight; 1.306 + 1.307 + // Get the instruction 1.308 + 1.309 + instRespQ.deq(); 1.310 + Instr inst 1.311 + = case ( instRespQ.first() ) matches 1.312 + tagged LoadResp .ld : return unpack(ld.data); 1.313 + tagged StoreResp .st : return ?; 1.314 + endcase; 1.315 + 1.316 + // Get the PC info 1.317 + let instrpc = pcQ.first().qpc; 1.318 + let pc_plus4 = instrpc + 4; 1.319 + 1.320 + Bool branchTaken = False; 1.321 + Addr newPC = pc_plus4; 1.322 + 1.323 + // Tracing 1.324 + traceTiny("mkProc", "exec","X"); 1.325 + traceTiny("mkProc", "exInstTiny",inst); 1.326 + traceFull("mkProc", "exInstFull",inst); 1.327 + 1.328 + case ( inst ) matches 1.329 + 1.330 + // -- Memory Ops ------------------------------------------------ 1.331 + 1.332 + tagged LW .it : 1.333 + begin 1.334 + Addr addr = rf.rd1(it.rbase) + sext(it.offset); 1.335 + dataReqQ.enq( LoadReq{ addr:addr, tag:zeroExtend(it.rdst) } ); 1.336 + wbQ.enq(tagged WB_Load it.rdst); 1.337 + end 1.338 + 1.339 + tagged SW .it : 1.340 + begin 1.341 + Addr addr = rf.rd1(it.rbase) + sext(it.offset); 1.342 + dataReqQ.enq( StoreReq{ tag:0, addr:addr, data:rf.rd2(it.rsrc) } ); 1.343 + wbQ.enq(tagged WB_Store); 1.344 + end 1.345 + 1.346 + // -- Simple Ops ------------------------------------------------ 1.347 + 1.348 + tagged ADDIU .it : 1.349 + begin 1.350 + Bit#(32) result = rf.rd1(it.rsrc) + sext(it.imm); 1.351 + wbQ.enq(tagged WB_ALU {data:result, dest:it.rdst}); 1.352 + end 1.353 + tagged SLTI .it : wbQ.enq(tagged WB_ALU {dest:it.rdst, data:slt( rf.rd1(it.rsrc), sext(it.imm) )}); 1.354 + tagged SLTIU .it : wbQ.enq(tagged WB_ALU {dest:it.rdst, data:sltu( rf.rd1(it.rsrc), sext(it.imm) ) }); 1.355 + tagged ANDI .it : 1.356 + begin 1.357 + Bit#(32) zext_it_imm = zext(it.imm); 1.358 + wbQ.enq(tagged WB_ALU {dest:it.rdst, data:(rf.rd1(it.rsrc) & zext_it_imm)} ); 1.359 + end 1.360 + tagged ORI .it : 1.361 + begin 1.362 + Bit#(32) zext_it_imm = zext(it.imm); 1.363 + wbQ.enq(tagged WB_ALU {dest:it.rdst, data:(rf.rd1(it.rsrc) | zext_it_imm)} ); 1.364 + end 1.365 + tagged XORI .it : 1.366 + begin 1.367 + Bit#(32) zext_it_imm = zext(it.imm); 1.368 + wbQ.enq(tagged WB_ALU {dest: it.rdst, data:(rf.rd1(it.rsrc) ^ zext_it_imm )}); 1.369 + end 1.370 + tagged LUI .it : 1.371 + begin 1.372 + Bit#(32) zext_it_imm = zext(it.imm); 1.373 + wbQ.enq(tagged WB_ALU {dest: it.rdst, data:(zext_it_imm << 32'd16) }); 1.374 + end 1.375 + 1.376 + tagged SLL .it : 1.377 + begin 1.378 + Bit#(32) zext_it_shamt = zext(it.shamt); 1.379 + wbQ.enq(tagged WB_ALU {dest: it.rdst, data:(rf.rd1(it.rsrc) << zext_it_shamt )} ); 1.380 + end 1.381 + tagged SRL .it : 1.382 + begin 1.383 + Bit#(32) zext_it_shamt = zext(it.shamt); 1.384 + wbQ.enq(tagged WB_ALU {dest: it.rdst, data:(rf.rd1(it.rsrc) >> zext_it_shamt )}); 1.385 + end 1.386 + tagged SRA .it : 1.387 + begin 1.388 + Bit#(32) zext_it_shamt = zext(it.shamt); 1.389 + wbQ.enq(tagged WB_ALU {dest: it.rdst, data:sra( rf.rd1(it.rsrc), zext_it_shamt )}); 1.390 + end 1.391 + tagged SLLV .it : wbQ.enq(tagged WB_ALU {dest: it.rdst, data:(rf.rd1(it.rsrc) << rshft(rf.rd2(it.rshamt)) )}); 1.392 + tagged SRLV .it : wbQ.enq(tagged WB_ALU {dest: it.rdst, data:(rf.rd1(it.rsrc) >> rshft(rf.rd2(it.rshamt)) )} ); 1.393 + tagged SRAV .it : wbQ.enq(tagged WB_ALU {dest: it.rdst, data:sra( rf.rd1(it.rsrc), rshft(rf.rd2(it.rshamt)) ) }); 1.394 + tagged ADDU .it : wbQ.enq(tagged WB_ALU {dest: it.rdst, data:(rf.rd1(it.rsrc1) + rf.rd2(it.rsrc2) )} ); 1.395 + tagged SUBU .it : wbQ.enq(tagged WB_ALU {dest: it.rdst, data:(rf.rd1(it.rsrc1) - rf.rd2(it.rsrc2) )} ); 1.396 + tagged AND .it : wbQ.enq(tagged WB_ALU {dest: it.rdst, data:(rf.rd1(it.rsrc1) & rf.rd2(it.rsrc2) )} ); 1.397 + tagged OR .it : wbQ.enq(tagged WB_ALU {dest: it.rdst, data:(rf.rd1(it.rsrc1) | rf.rd2(it.rsrc2) )} ); 1.398 + tagged XOR .it : wbQ.enq(tagged WB_ALU {dest: it.rdst, data:(rf.rd1(it.rsrc1) ^ rf.rd2(it.rsrc2) )} ); 1.399 + tagged NOR .it : wbQ.enq(tagged WB_ALU {dest: it.rdst, data:(~(rf.rd1(it.rsrc1) | rf.rd2(it.rsrc2)) )} ); 1.400 + tagged SLT .it : wbQ.enq(tagged WB_ALU {dest: it.rdst, data:slt( rf.rd1(it.rsrc1), rf.rd2(it.rsrc2) ) }); 1.401 + tagged SLTU .it : wbQ.enq(tagged WB_ALU {dest: it.rdst, data:sltu( rf.rd1(it.rsrc1), rf.rd2(it.rsrc2) ) }); 1.402 + 1.403 + // -- Branches -------------------------------------------------- 1.404 + 1.405 + tagged BLEZ .it : 1.406 + if ( signedLE( rf.rd1(it.rsrc), 0 ) ) 1.407 + begin 1.408 + newPC = pc_plus4 + (sext(it.offset) << 2); 1.409 + branchTaken = True; 1.410 + end 1.411 + 1.412 + tagged BGTZ .it : 1.413 + if ( signedGT( rf.rd1(it.rsrc), 0 ) ) 1.414 + begin 1.415 + newPC = pc_plus4 + (sext(it.offset) << 2); 1.416 + branchTaken = True; 1.417 + end 1.418 + 1.419 + tagged BLTZ .it : 1.420 + if ( signedLT( rf.rd1(it.rsrc), 0 ) ) 1.421 + begin 1.422 + newPC = pc_plus4 + (sext(it.offset) << 2); 1.423 + branchTaken = True; 1.424 + end 1.425 + 1.426 + tagged BGEZ .it : 1.427 + if ( signedGE( rf.rd1(it.rsrc), 0 ) ) 1.428 + begin 1.429 + newPC = pc_plus4 + (sext(it.offset) << 2); 1.430 + branchTaken = True; 1.431 + end 1.432 + 1.433 + tagged BEQ .it : 1.434 + if ( rf.rd1(it.rsrc1) == rf.rd2(it.rsrc2) ) 1.435 + begin 1.436 + newPC = pc_plus4 + (sext(it.offset) << 2); 1.437 + branchTaken = True; 1.438 + end 1.439 + 1.440 + tagged BNE .it : 1.441 + if ( rf.rd1(it.rsrc1) != rf.rd2(it.rsrc2) ) 1.442 + begin 1.443 + newPC = pc_plus4 + (sext(it.offset) << 2); 1.444 + branchTaken = True; 1.445 + end 1.446 + 1.447 + // -- Jumps ----------------------------------------------------- 1.448 + 1.449 + tagged J .it : 1.450 + begin 1.451 + newPC = { pc_plus4[31:28], it.target, 2'b0 }; 1.452 + branchTaken = True; 1.453 + end 1.454 + 1.455 + tagged JR .it : 1.456 + begin 1.457 + newPC = rf.rd1(it.rsrc); 1.458 + branchTaken = True; 1.459 + end 1.460 + 1.461 + tagged JAL .it : 1.462 + begin 1.463 + wbQ.enq(tagged WB_ALU {dest:31, data:pc_plus4 }); 1.464 + newPC = { pc_plus4[31:28], it.target, 2'b0 }; 1.465 + branchTaken = True; 1.466 + end 1.467 + 1.468 + tagged JALR .it : 1.469 + begin 1.470 + wbQ.enq(tagged WB_ALU {dest:it.rdst, data:pc_plus4 }); 1.471 + newPC = rf.rd1(it.rsrc); 1.472 + branchTaken = True; 1.473 + end 1.474 + 1.475 + // -- Cop0 ------------------------------------------------------ 1.476 + 1.477 + tagged MTC0 .it : 1.478 + begin 1.479 + case ( it.cop0dst ) 1.480 + 5'd10 : cp0_statsEn <= unpack(truncate(rf.rd1(it.rsrc))); 1.481 + 5'd21 : cp0_tohost <= truncate(rf.rd1(it.rsrc)); 1.482 + default : 1.483 + $display( " RTL-ERROR : %m : Illegal MTC0 cop0dst register!" ); 1.484 + endcase 1.485 + wbQ.enq(tagged WB_Host 0); //no idea wwhat this actually should be. 1.486 + end 1.487 + 1.488 +//this is host stuff? 1.489 + tagged MFC0 .it : 1.490 + begin 1.491 + case ( it.cop0src ) 1.492 + // not actually an ALU instruction but don't have the format otherwise 1.493 + 5'd10 : wbQ.enq(tagged WB_ALU {dest:it.rdst, data:zext(pack(cp0_statsEn)) }); 1.494 + 5'd20 : wbQ.enq(tagged WB_ALU {dest:it.rdst, data:cp0_fromhost }); 1.495 + 5'd21 : wbQ.enq(tagged WB_ALU {dest:it.rdst, data:cp0_tohost }); 1.496 + default : 1.497 + $display( " RTL-ERROR : %m : Illegal MFC0 cop0src register!" ); 1.498 + endcase 1.499 + end 1.500 + 1.501 + // -- Illegal --------------------------------------------------- 1.502 + 1.503 + default : 1.504 + $display( " RTL-ERROR : %m : Illegal instruction !" ); 1.505 + 1.506 + endcase 1.507 + 1.508 +//evaluate branch prediction 1.509 + Addr ppc = pcQ.first().qnxtpc; //predicted branch 1.510 + if (ppc != newPC) //prediction wrong 1.511 + begin 1.512 + epoch <= pcQ.first().qepoch + 1; 1.513 + bp.upd(instrpc, newPC); //update branch predictor 1.514 + pcQ.clear(); 1.515 + pc <= newPC; 1.516 + end 1.517 + else 1.518 + pcQ.deq(); 1.519 + 1.520 + if ( cp0_statsEn ) 1.521 + num_inst <= num_inst+1; 1.522 + 1.523 + endrule 1.524 + 1.525 + rule writeback; // ( stage == Writeback ); 1.526 + traceTiny("mkProc", "writeback","W"); 1.527 + 1.528 + 1.529 + // get what to do off the writeback queue 1.530 + wbQ.deq(); 1.531 + case (wbQ.first()) matches 1.532 + tagged WB_ALU {data:.res, dest:.rdst} : rf.wr(rdst, res); 1.533 + tagged WB_Load .regWr : 1.534 + begin 1.535 + dataRespQ.deq(); 1.536 + if (dataRespQ.first() matches tagged LoadResp .ld) 1.537 + rf.wr(truncate(ld.tag), ld.data); // no need to use Rindx from queue? Duplicate? 1.538 + end 1.539 + tagged WB_Store : dataRespQ.deq(); 1.540 + tagged WB_Host .dat : noAction; 1.541 + endcase 1.542 + 1.543 + endrule 1.544 + 1.545 + rule inc_num_cycles; 1.546 + if ( cp0_statsEn ) 1.547 + num_cycles <= num_cycles+1; 1.548 + endrule 1.549 +// THis rule breaks things 1.550 +// rule handleCPUToHost; 1.551 +// let req <- server_stub.acceptRequest_ReadCPUToHost(); 1.552 +// case (req) 1.553 +// 0: server_stub.sendResponse_ReadCPUToHost(cp0_tohost); 1.554 +// 1: server_stub.sendResponse_ReadCPUToHost(pc); 1.555 +// 2: server_stub.sendResponse_ReadCPUToHost(zeroExtend(pack(stage))); 1.556 +// endcase 1.557 +// endrule 1.558 +//----------------------------------------------------------- 1.559 +// My Adds 1.560 +//----------------------------------------------------------- 1.561 + 1.562 + //----------------------------------------------------------- 1.563 + // Methods 1.564 + 1.565 + interface Client imem_client; 1.566 + interface Get request = toGet(instReqQ); 1.567 + interface Put response = toPut(instRespQ); 1.568 + endinterface 1.569 + 1.570 + interface Client dmem_client; 1.571 + interface Get request = toGet(dataReqQ); 1.572 + interface Put response = toPut(dataRespQ); 1.573 + endinterface 1.574 + 1.575 + interface Get statsEn_get = toGet(asReg(cp0_statsEn)); 1.576 + 1.577 + interface ProcStats stats; 1.578 + interface Get num_cycles = toGet(asReg(num_cycles)); 1.579 + interface Get num_inst = toGet(asReg(num_inst)); 1.580 + endinterface 1.581 + 1.582 + interface CPUToHost tohost; 1.583 + method Bit#(32) cpuToHost(int req); 1.584 + return (case (req) 1.585 + 0: cp0_tohost; 1.586 + 1: pc; 1.587 + 2: zeroExtend(pack(stage)); 1.588 + endcase); 1.589 + endmethod 1.590 + endinterface 1.591 + 1.592 +endmodule 1.593 +