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