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