Mercurial > pygar
view modules/bluespec/Pygar/core/Processor.bsv @ 71:86360c5ae9f2 pygar svn.72
[svn r72] added config for htg
author | punk |
---|---|
date | Wed, 12 May 2010 00:21:40 -0400 |
parents | 44cc00df1168 |
children |
line wrap: on
line source
1 // The MIT License3 // Copyright (c) 2009 Massachusetts Institute of Technology5 // Permission is hereby granted, free of charge, to any person obtaining a copy6 // of this software and associated documentation files (the "Software"), to deal7 // in the Software without restriction, including without limitation the rights8 // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell9 // copies of the Software, and to permit persons to whom the Software is10 // furnished to do so, subject to the following conditions:12 // The above copyright notice and this permission notice shall be included in13 // all copies or substantial portions of the Software.15 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR16 // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,17 // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE18 // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER19 // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,20 // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN21 // THE SOFTWARE.24 import Connectable::*;25 import GetPut::*;26 import ClientServer::*;27 import RegFile::*;29 import FIFO::*;30 import FIFOF::*;31 import SFIFO::*;32 import RWire::*;34 import Trace::*;35 import BFIFO::*;36 import MemTypes::*;37 import ProcTypes::*;38 import BRegFile::*;39 import BranchPred::*;41 //AWB includes42 `include "asim/provides/low_level_platform_interface.bsh"43 `include "asim/provides/soft_connections.bsh"44 `include "asim/provides/common_services.bsh"46 // Local includes47 //`include "asim/provides/processor_library.bsh" (included above directly)49 `include "asim/provides/common_services.bsh"50 `include "asim/provides/processor_library.bsh"52 // Local includes. Look for the correspondingly named .awb files53 // workspace/labs/src/mit-6.375/modules/bluespec/mit-6.375/common/54 // to find the actual Bluespec files which are used to generate55 // these includes. These files are specific to this audio processing56 // pipeline58 `include "asim/provides/audio_pipe_types.bsh"59 `include "asim/provides/path_types.bsh"61 //interface CPUToHost;62 // method Bit#(32) cpuToHost(int req);63 //endinterface65 interface Proc;67 // Interface from processor to caches68 interface Client#(DataReq,DataResp) dmem_client;69 interface Client#(InstReq,InstResp) imem_client;71 // Interface for enabling/disabling statistics on the rest of the core72 interface Get#(Bool) statsEn_get;74 // Interface to host75 interface Get#(Bit#(32)) pcCount;77 // Interface to Audio Pipeline78 interface Get#(AudioStream) sampleOutput;79 interface Put#(AudioStream) sampleInput;81 endinterface83 typedef enum { PCgen, Exec, Writeback } Stage deriving(Eq,Bits);85 //-----------------------------------------------------------86 // Helper functions87 //-----------------------------------------------------------89 function Bit#(32) slt( Bit#(32) val1, Bit#(32) val2 );90 return zeroExtend( pack( signedLT(val1,val2) ) );91 endfunction93 function Bit#(32) sltu( Bit#(32) val1, Bit#(32) val2 );94 return zeroExtend( pack( val1 < val2 ) );95 endfunction97 function Bit#(32) rshft( Bit#(32) val );98 return zeroExtend(val[4:0]);99 endfunction102 //-----------------------------------------------------------103 // Find funct for wbQ104 //-----------------------------------------------------------105 function Bool findwbf(Rindx fVal, WBResult cmpVal);106 case (cmpVal) matches107 tagged WB_ALU {data:.res, dest:.rd} :108 return (fVal == rd);109 tagged WB_Load .rd :110 return (fVal == rd);111 tagged WB_Store .st :112 return False;113 tagged WB_Host .x :114 return False;115 endcase116 endfunction119 //-----------------------------------------------------------120 // Stall funct for wbQ121 //-----------------------------------------------------------122 function Bool stall(Instr inst, SFIFO#(WBResult, Rindx) f);123 case (inst) matches124 // -- Memory Ops ------------------------------------------------125 tagged LW .it :126 return f.find(it.rbase);127 tagged SW {rsrc:.dreg, rbase:.addr, offset:.o} :128 return (f.find(addr) || f.find2(dreg));130 // -- Simple Ops ------------------------------------------------131 tagged ADDIU .it : return f.find(it.rsrc);132 tagged SLTI .it : return f.find(it.rsrc);133 tagged SLTIU .it : return f.find(it.rsrc);134 tagged ANDI .it : return f.find(it.rsrc);135 tagged ORI .it : return f.find(it.rsrc);136 tagged XORI .it : return f.find(it.rsrc);138 tagged LUI .it : return f.find(it.rdst); //this rds/wrs itself139 tagged SLL .it : return f.find(it.rsrc);140 tagged SRL .it : return f.find(it.rsrc);141 tagged SRA .it : return f.find(it.rsrc);142 tagged SLLV .it : return (f.find(it.rsrc) || f.find(it.rshamt));143 tagged SRLV .it : return (f.find(it.rsrc) || f.find(it.rshamt));144 tagged SRAV .it : return (f.find(it.rsrc) || f.find(it.rshamt));145 tagged ADDU .it : return (f.find(it.rsrc1) || f.find2(it.rsrc2));146 tagged SUBU .it : return (f.find(it.rsrc1) || f.find2(it.rsrc2));147 tagged AND .it : return (f.find(it.rsrc1) || f.find2(it.rsrc2));148 tagged OR .it : return (f.find(it.rsrc1) || f.find2(it.rsrc2));149 tagged XOR .it : return (f.find(it.rsrc1) || f.find2(it.rsrc2));150 tagged NOR .it : return (f.find(it.rsrc1) || f.find2(it.rsrc2));151 tagged SLT .it : return (f.find(it.rsrc1) || f.find2(it.rsrc2));152 tagged SLTU .it : return (f.find(it.rsrc1) || f.find2(it.rsrc2));155 // -- Branches --------------------------------------------------157 tagged BLEZ .it : return (f.find(it.rsrc));158 tagged BGTZ .it : return (f.find(it.rsrc));159 tagged BLTZ .it : return (f.find(it.rsrc));160 tagged BGEZ .it : return (f.find(it.rsrc));161 tagged BEQ .it : return (f.find(it.rsrc1) || f.find2(it.rsrc2));162 tagged BNE .it : return (f.find(it.rsrc1) || f.find2(it.rsrc2));164 // -- Jumps -----------------------------------------------------166 tagged J .it : return False;167 tagged JR .it : return f.find(it.rsrc);168 tagged JALR .it : return f.find(it.rsrc);169 tagged JAL .it : return False;171 // -- Cop0 ------------------------------------------------------173 tagged MTC0 .it : return f.find(it.rsrc);174 tagged MFC0 .it : return False;176 // -- Illegal ---------------------------------------------------178 default : return False;180 endcase181 endfunction184 //-----------------------------------------------------------185 // Reference processor186 //-----------------------------------------------------------189 //(* doc = "synthesis attribute ram_style mkProc distributed;" *)190 //(* synthesize *)192 module mkProc( Proc );194 //-----------------------------------------------------------195 // State197 // Standard processor state199 Reg#(Addr) pc <- mkReg(32'h00001000);200 Reg#(Epoch) epoch <- mkReg(0);201 Reg#(Stage) stage <- mkReg(PCgen);202 BRegFile rf <- mkBRegFile;204 // Branch Prediction205 BranchPred bp <- mkBranchPred();206 FIFO#(PCStat) execpc <- mkLFIFO();208 // Pipelines209 FIFO#(PCStat) pcQ <-mkSizedFIFO(3);210 SFIFO#(WBResult, Rindx) wbQ <-mkSFIFO(findwbf);212 // NEED TO ADD CAPABILITY FOR RESET (should be able to just say if I get valid in and these are flagged, clear them.213 Reg#(Bit#(32)) cp0_tohost <- mkReg(0);214 Reg#(Bit#(32)) cp0_fromhost <- mkReg(0);215 Reg#(Bool) cp0_statsEn <- mkReg(False);216 Reg#(Bool) cp0_audioEOF <- mkReg(False); // Register to let code that EOF is reached217 Reg#(Bool) cp0_progComp <- mkReg(False); // Register to let processor know that the program is complete (as this terminates)219 Reg#(Bool) code_bypass <- mkReg(True); // Register to enable passing invalid packets once all valid ones are passed OUT220 // (this becomes false at first valid packet)222 // Memory request/response state224 FIFO#(InstReq) instReqQ <- mkBFIFO1();225 FIFO#(InstResp) instRespQ <- mkFIFO();227 FIFO#(DataReq) dataReqQ <- mkBFIFO1();228 FIFO#(DataResp) dataRespQ <- mkFIFO();230 // Audio I/O231 FIFO#(AudioStream) inAudioFifo <- mkSizedFIFO(512);232 FIFO#(AudioStream) outAudioFifo <- mkFIFO;233 Reg#(VoiceId) channel <-mkReg(0); // Set based on the reading the incoming data. Not entirely sure I like this. What if the program generates samples?235 // Statistics state (2010)236 // Reg#(Stat) num_cycles <- mkReg(0);237 // Reg#(Stat) num_inst <- mkReg(0);239 //Or:240 // Statistics state242 //rlm: removing these to avoid their broken stupidness.243 //STAT num_cycles <- mkStatCounter(`STATS_PROCESSOR_CYCLE_COUNT);244 //STAT num_inst <- mkStatCounter(`STATS_PROCESSOR_INST_COUNT);246 //-----------------------------------------------------------247 // Internal Functions249 function Bool stallMTCO_MFCO(Instr inst);250 case(inst) matches251 tagged MTC0 .it :252 begin253 case (it.cop0dst)254 5'd26 : return cp0_progComp; // If true, processor service sendEnd which clears it.255 endcase256 end257 endcase258 endfunction260 //-----------------------------------------------------------261 // Rules263 (* descending_urgency = "exec, pcgen" *)264 rule pcgen; //( stage == PCgen );265 let pc_plus4 = pc + 4;267 traceTiny("mkProc", "pc",pc);268 traceTiny("mkProc", "pcgen","P");269 instReqQ.enq( LoadReq{ addr:pc, tag:epoch} );271 let next_pc = bp.get(pc);272 if (next_pc matches tagged Valid .npc)273 begin274 pcQ.enq(PCStat {qpc:pc, qnxtpc:npc, qepoch:epoch});275 pc <= npc;276 end277 else278 begin279 pcQ.enq(PCStat {qpc:pc, qnxtpc:pc_plus4, qepoch:epoch});280 pc <= pc_plus4;281 end283 endrule285 rule discard (instRespQ.first() matches tagged LoadResp .ld286 &&& ld.tag != epoch);287 traceTiny("mkProc", "stage", "D");288 instRespQ.deq();289 endrule291 (* conflict_free = "exec, writeback" *)292 rule exec (instRespQ.first() matches tagged LoadResp.ld293 &&& (ld.tag == epoch)294 &&& unpack(ld.data) matches .inst295 &&& !stall(inst, wbQ)296 &&& !stallMTCO_MFCO(inst));298 // Some abbreviations299 let sext = signExtend;300 let zext = zeroExtend;301 let sra = signedShiftRight;303 // Get the instruction305 instRespQ.deq();306 Instr inst307 = case ( instRespQ.first() ) matches308 tagged LoadResp .ld : return unpack(ld.data);309 tagged StoreResp .st : return ?;310 endcase;312 // Get the PC info313 let instrpc = pcQ.first().qpc;314 let pc_plus4 = instrpc + 4;316 Bool branchTaken = False;317 Addr newPC = pc_plus4;319 // Tracing320 traceTiny("mkProc", "exec","X");321 traceTiny("mkProc", "exInstTiny",inst);322 traceFull("mkProc", "exInstFull",inst);324 // $display("PROCESSOR: Exec Fires");325 case ( inst ) matches327 // -- Memory Ops ------------------------------------------------329 tagged LW .it :330 begin331 let val_rbase <- rf.rd1(it.rbase);332 Addr addr = val_rbase + sext(it.offset);333 dataReqQ.enq( LoadReq{ addr:addr, tag:zeroExtend(it.rdst) } );334 wbQ.enq(tagged WB_Load it.rdst);335 end337 tagged SW .it :338 begin339 let val_rbase <- rf.rd1(it.rbase);340 let val_rsrc2 <- rf.rd2(it.rsrc);341 Addr addr = val_rbase + sext(it.offset);342 dataReqQ.enq( StoreReq{ tag:0, addr:addr, data:val_rsrc2 } );343 wbQ.enq(tagged WB_Store);344 end346 // -- Simple Ops ------------------------------------------------348 tagged ADDIU .it :349 begin350 let val_rsrc1 <- rf.rd1(it.rsrc);351 Bit#(32) result = val_rsrc1 + sext(it.imm);352 wbQ.enq(tagged WB_ALU {data:result, dest:it.rdst});353 end354 tagged SLTI .it :355 begin356 let val_rsrc1 <- rf.rd1(it.rsrc);357 wbQ.enq(tagged WB_ALU {dest:it.rdst, data:slt( val_rsrc1, sext(it.imm) )});358 end359 tagged SLTIU .it :360 begin361 let val_rsrc1 <- rf.rd1(it.rsrc);362 wbQ.enq(tagged WB_ALU {dest:it.rdst, data:sltu( val_rsrc1, sext(it.imm) ) });363 end364 tagged ANDI .it :365 begin366 let val_rsrc1 <- rf.rd1(it.rsrc);367 Bit#(32) zext_it_imm = zext(it.imm);368 wbQ.enq(tagged WB_ALU {dest:it.rdst, data:(val_rsrc1 & zext_it_imm)} );369 end370 tagged ORI .it :371 begin372 let val_rsrc1 <- rf.rd1(it.rsrc);373 Bit#(32) zext_it_imm = zext(it.imm);374 wbQ.enq(tagged WB_ALU {dest:it.rdst, data:(val_rsrc1 | zext_it_imm)} );375 end376 tagged XORI .it :377 begin378 let val_rsrc1 <- rf.rd1(it.rsrc);379 Bit#(32) zext_it_imm = zext(it.imm);380 wbQ.enq(tagged WB_ALU {dest: it.rdst, data:(val_rsrc1 ^ zext_it_imm )});381 end382 tagged LUI .it :383 begin384 Bit#(32) zext_it_imm = zext(it.imm);385 wbQ.enq(tagged WB_ALU {dest: it.rdst, data:(zext_it_imm << 32'd16) });386 end388 tagged SLL .it :389 begin390 let val_rsrc1 <- rf.rd1(it.rsrc);391 Bit#(32) zext_it_shamt = zext(it.shamt);392 wbQ.enq(tagged WB_ALU {dest: it.rdst, data:(val_rsrc1 << zext_it_shamt )} );393 end394 tagged SRL .it :395 begin396 let val_rsrc1 <- rf.rd1(it.rsrc);397 Bit#(32) zext_it_shamt = zext(it.shamt);398 wbQ.enq(tagged WB_ALU {dest: it.rdst, data:(val_rsrc1 >> zext_it_shamt )});399 end400 tagged SRA .it :401 begin402 let val_rsrc1 <- rf.rd1(it.rsrc);403 Bit#(32) zext_it_shamt = zext(it.shamt);404 wbQ.enq(tagged WB_ALU {dest: it.rdst, data:sra( val_rsrc1, zext_it_shamt )});405 end406 tagged SLLV .it :407 begin408 let val_rsrc1 <- rf.rd1(it.rsrc);409 let val_rshamt <- rf.rd2(it.rshamt);410 wbQ.enq(tagged WB_ALU {dest: it.rdst, data:(val_rsrc1 << rshft(val_rshamt) )});411 end412 tagged SRLV .it :413 begin414 let val_rsrc1 <- rf.rd1(it.rsrc);415 let val_rshamt <- rf.rd2(it.rshamt);416 wbQ.enq(tagged WB_ALU {dest: it.rdst, data:(val_rsrc1 >> rshft(val_rshamt) )} );417 end418 tagged SRAV .it :419 begin420 let val_rsrc1 <- rf.rd1(it.rsrc);421 let val_rshamt <- rf.rd2(it.rshamt);422 wbQ.enq(tagged WB_ALU {dest: it.rdst, data:sra( val_rsrc1, rshft(val_rshamt) ) });423 end424 tagged ADDU .it :425 begin426 let val_rsrc11 <- rf.rd1(it.rsrc1);427 let val_rsrc22 <- rf.rd2(it.rsrc2);428 wbQ.enq(tagged WB_ALU {dest: it.rdst, data:(val_rsrc11 + val_rsrc22 )} );429 end430 tagged SUBU .it :431 begin432 let val_rsrc11 <- rf.rd1(it.rsrc1);433 let val_rsrc22 <- rf.rd2(it.rsrc2);434 wbQ.enq(tagged WB_ALU {dest: it.rdst, data:(val_rsrc11 - val_rsrc22 )} );435 end436 tagged AND .it :437 begin438 let val_rsrc11 <- rf.rd1(it.rsrc1);439 let val_rsrc22 <- rf.rd2(it.rsrc2);440 wbQ.enq(tagged WB_ALU {dest: it.rdst, data:(val_rsrc11 & val_rsrc22 )} );441 end442 tagged OR .it :443 begin444 let val_rsrc11 <- rf.rd1(it.rsrc1);445 let val_rsrc22 <- rf.rd2(it.rsrc2);446 wbQ.enq(tagged WB_ALU {dest: it.rdst, data:(val_rsrc11 | val_rsrc22 )} );447 end448 tagged XOR .it :449 begin450 let val_rsrc11 <- rf.rd1(it.rsrc1);451 let val_rsrc22 <- rf.rd2(it.rsrc2);452 wbQ.enq(tagged WB_ALU {dest: it.rdst, data:(val_rsrc11 ^ val_rsrc22 )} );453 end454 tagged NOR .it :455 begin456 let val_rsrc11 <- rf.rd1(it.rsrc1);457 let val_rsrc22 <- rf.rd2(it.rsrc2);458 wbQ.enq(tagged WB_ALU {dest: it.rdst, data:(~(val_rsrc11 | val_rsrc22) )} );459 end460 tagged SLT .it :461 begin462 let val_rsrc11 <- rf.rd1(it.rsrc1);463 let val_rsrc22 <- rf.rd2(it.rsrc2);464 wbQ.enq(tagged WB_ALU {dest: it.rdst, data:slt( val_rsrc11, val_rsrc22 ) });465 end466 tagged SLTU .it :467 begin468 let val_rsrc11 <- rf.rd1(it.rsrc1);469 let val_rsrc22 <- rf.rd2(it.rsrc2);470 wbQ.enq(tagged WB_ALU {dest: it.rdst, data:sltu( val_rsrc11, val_rsrc22 ) });471 end473 // -- Branches --------------------------------------------------475 tagged BLEZ .it :476 begin477 let val_rsrc1 <- rf.rd1(it.rsrc);478 if ( signedLE( val_rsrc1, 0 ) )479 begin480 newPC = pc_plus4 + (sext(it.offset) << 2);481 branchTaken = True;482 end483 end485 tagged BGTZ .it :486 begin487 let val_rsrc1 <- rf.rd1(it.rsrc);488 if ( signedGT( val_rsrc1, 0 ) )489 begin490 newPC = pc_plus4 + (sext(it.offset) << 2);491 branchTaken = True;492 end493 end495 tagged BLTZ .it :496 begin497 let val_rsrc1 <- rf.rd1(it.rsrc);498 if ( signedLT( val_rsrc1, 0 ) )499 begin500 newPC = pc_plus4 + (sext(it.offset) << 2);501 branchTaken = True;502 end503 end505 tagged BGEZ .it :506 begin507 let val_rsrc1 <- rf.rd1(it.rsrc);508 if ( signedGE( val_rsrc1, 0 ) )509 begin510 newPC = pc_plus4 + (sext(it.offset) << 2);511 branchTaken = True;512 end513 end515 tagged BEQ .it :516 begin517 let val_rsrc11 <- rf.rd1(it.rsrc1);518 let val_rsrc22 <- rf.rd2(it.rsrc2);519 if ( val_rsrc11 == val_rsrc22 )520 begin521 newPC = pc_plus4 + (sext(it.offset) << 2);522 branchTaken = True;523 end524 end526 tagged BNE .it :527 begin528 let val_rsrc11 <- rf.rd1(it.rsrc1);529 let val_rsrc22 <- rf.rd2(it.rsrc2);530 if ( val_rsrc11 != val_rsrc22 )531 begin532 newPC = pc_plus4 + (sext(it.offset) << 2);533 branchTaken = True;534 end535 end537 // -- Jumps -----------------------------------------------------539 tagged J .it :540 begin541 newPC = { pc_plus4[31:28], it.target, 2'b0 };542 branchTaken = True;543 end545 tagged JR .it :546 begin547 let val_rsrc1 <- rf.rd1(it.rsrc);548 newPC = val_rsrc1;549 branchTaken = True;550 end552 tagged JAL .it :553 begin554 wbQ.enq(tagged WB_ALU {dest:31, data:pc_plus4 });555 newPC = { pc_plus4[31:28], it.target, 2'b0 };556 branchTaken = True;557 end559 tagged JALR .it :560 begin561 let val_rsrc1 <- rf.rd1(it.rsrc);562 wbQ.enq(tagged WB_ALU {dest:it.rdst, data:pc_plus4 });563 newPC = val_rsrc1;564 branchTaken = True;565 end567 // -- Cop0 ------------------------------------------------------569 tagged MTC0 .it : //Recieve things from host computer570 begin571 let val_rsrc1 <- rf.rd1(it.rsrc);572 // $display( " PROCESSOR MTC0 call\n");573 case ( it.cop0dst )574 5'd10 : cp0_statsEn <= unpack(truncate(val_rsrc1));575 5'd21 : cp0_tohost <= truncate(val_rsrc1);576 5'd26 : cp0_progComp <= unpack(truncate(val_rsrc1)); //states audio program completed and termination okay577 5'd27 : outAudioFifo.enq(AudioStream {voice: channel, data: tagged Valid578 tagged Sample unpack(truncate(val_rsrc1)) }); //Bit size is 16 not 32579 default :580 $display( " RTL-ERROR : %m : Illegal MTC0 cop0dst register!" );581 endcase582 wbQ.enq(tagged WB_Host 0); //no idea wwhat this actually should be.583 end585 //this is host stuff?586 tagged MFC0 .it : //Things out587 begin588 case ( it.cop0src )589 // not actually an ALU instruction but don't have the format otherwise590 5'd10 : wbQ.enq(tagged WB_ALU {dest:it.rdst, data:zext(pack(cp0_statsEn)) });591 5'd20 : wbQ.enq(tagged WB_ALU {dest:it.rdst, data:cp0_fromhost });592 5'd21 : wbQ.enq(tagged WB_ALU {dest:it.rdst, data:cp0_tohost });593 5'd25 : begin594 // $display( "**** EOF Requested\n "); //Should never run if inAudioFifo.first not valid595 let stream = inAudioFifo.first();596 if (stream.data matches tagged Valid .sample)597 begin598 case (sample) matches599 tagged EndOfFile :600 begin601 $display("PROCESSOR sent toC EOF");602 wbQ.enq(tagged WB_ALU {dest:it.rdst, data:zext(pack(True)) }); // Reading clears bit603 inAudioFifo.deq;604 end605 tagged Sample .audio:606 wbQ.enq(tagged WB_ALU {dest:it.rdst, data:zext(pack(False)) }); // Reading clears bit607 endcase608 code_bypass <= False;609 end610 else $display("PROCESSOR code trying to read Invalid Audio Stream");611 end612 5'd28 : begin613 $display( "***** Reqesting Sample");614 let stream = inAudioFifo.first(); // is this going to cause perf. delay?615 if (stream.data matches tagged Valid .sample)616 begin617 if (sample matches tagged Sample .audio) // if it is EOF another rule sets the cp0_audioEOF618 wbQ.enq(tagged WB_ALU {dest:it.rdst, data:zext(pack(audio)) }); // do I need pack?619 else $display ( "Audio File EOF Reached. Invalid sample request.");620 inAudioFifo.deq();621 end622 else $display("PROCESSOR code trying to read Invalid Audio Stream");623 end624 default :625 $display( " RTL-ERROR : %m : Illegal MFC0 cop0src register!" );626 endcase627 end629 // -- Illegal ---------------------------------------------------631 default :632 $display( " RTL-ERROR : %m : Illegal instruction !" );634 endcase636 //evaluate branch prediction637 Addr ppc = pcQ.first().qnxtpc; //predicted branch638 if (ppc != newPC) //prediction wrong639 begin640 epoch <= pcQ.first().qepoch + 1;641 bp.upd(instrpc, newPC); //update branch predictor642 pcQ.clear();643 pc <= newPC;644 end645 else646 pcQ.deq();647 //rlm: removing648 // if ( cp0_statsEn )649 // num_inst.incr();651 endrule653 rule writeback; // ( stage == Writeback );654 traceTiny("mkProc", "writeback","W");657 // get what to do off the writeback queue658 wbQ.deq();659 case (wbQ.first()) matches660 tagged WB_ALU {data:.res, dest:.rdst} : rf.wr(rdst, res);661 tagged WB_Load .regWr :662 begin663 dataRespQ.deq();664 if (dataRespQ.first() matches tagged LoadResp .ld)665 rf.wr(truncate(ld.tag), ld.data); // no need to use Rindx from queue? Duplicate?666 end667 tagged WB_Store : dataRespQ.deq();668 tagged WB_Host .dat : noAction;669 endcase671 endrule673 //rlm remove674 // rule inc_num_cycles;675 // if ( cp0_statsEn )676 // num_cycles.incr();677 // endrule679 rule bypass (code_bypass &&&680 !cp0_progComp &&& //never fires at the same time as sendEnd where it is enabled681 inAudioFifo.first().data matches tagged Invalid) ;682 outAudioFifo.enq(inAudioFifo.first());683 inAudioFifo.deq;684 endrule686 /*687 rule flagAudioEnd (inAudioFifo.first() matches tagged EndOfFile);688 $display (" PROCESSOR End Audio Flag Set ");689 cp0_audioEOF <= True;690 inAudioFifo.deq;691 endrule692 */693 (* descending_urgency = "sendProcEnd, exec" *)694 rule sendProcEnd (cp0_progComp);695 $display (" PROCESSOR Says Program Complete ");696 outAudioFifo.enq(AudioStream {voice: channel, data: tagged Valid tagged EndOfFile }); // Only send one697 cp0_progComp <= False; // And functions to reset698 code_bypass <= True; // Enable Bypass so that invalids get thru699 endrule702 //-----------------------------------------------------------703 // Methods705 interface Client imem_client;706 interface Get request = fifoToGet(instReqQ);707 interface Put response = fifoToPut(instRespQ);708 endinterface710 interface Client dmem_client;711 interface Get request = fifoToGet(dataReqQ);712 interface Put response = fifoToPut(dataRespQ);713 endinterface715 interface Get statsEn_get = toGet(asReg(cp0_statsEn));717 /*718 interface CPUToHost tohost;719 method Bit#(32) cpuToHost(int req);720 return (case (req)721 0: cp0_tohost;722 1: pc;723 2: zeroExtend(pack(stage));724 endcase);725 endmethod726 endinterface727 */729 interface Get sampleOutput = fifoToGet(outAudioFifo);730 interface Put sampleInput = fifoToPut(inAudioFifo);731 interface Get pcCount = toGet(asReg(pc));733 endmodule