Mercurial > pygar
view modules/bluespec/Pygar/core/Processor.bsv @ 29:9830ff8fb0bd pygar svn.30
[svn r30] Forgot a file
author | punk |
---|---|
date | Fri, 30 Apr 2010 09:13:38 -0400 |
parents | f5dfbe28fa59 |
children | 2c8166d205d5 |
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::*;40 //import PathTypes::*; This is only there to force the debugging42 //AWB includes43 `include "asim/provides/low_level_platform_interface.bsh"44 `include "asim/provides/soft_connections.bsh"45 `include "asim/provides/common_services.bsh"47 // Local includes48 //`include "asim/provides/processor_library.bsh" (included above directly)49 `include "asim/rrr/remote_server_stub_AUDIOCORERRR.bsh"50 `include "asim/provides/common_services.bsh"51 `include "asim/dict/STATS_PROCESSOR.bsh"52 `include "asim/provides/processor_library.bsh"54 // Local includes. Look for the correspondingly named .awb files55 // workspace/labs/src/mit-6.375/modules/bluespec/mit-6.375/common/56 // to find the actual Bluespec files which are used to generate57 // these includes. These files are specific to this audio processing58 // pipeline60 `include "asim/provides/audio_pipe_types.bsh"62 //interface CPUToHost;63 // method Bit#(32) cpuToHost(int req);64 //endinterface66 interface Proc;68 // Interface from processor to caches69 interface Client#(DataReq,DataResp) dmem_client;70 interface Client#(InstReq,InstResp) imem_client;72 // Interface for enabling/disabling statistics on the rest of the core73 interface Get#(Bool) statsEn_get;75 // // Interface to host76 // interface CPUToHost tohost;78 // Interface to Audio Pipeline79 interface Get#(AudioProcessorUnit) sampleOutput;81 endinterface83 //The full interface for this is as below in the common file for audioProcessorTypes.bsv84 //interface AudioOut;85 // interface Get#(AudioProcessorUnit) audioSampleOutput;86 //endinterface88 //interface AudioIn;89 // interface Put#(AudioProcessorUnit) audioSampleInput;90 //endinterface92 typedef enum { PCgen, Exec, Writeback } Stage deriving(Eq,Bits);94 //-----------------------------------------------------------95 // Register file module96 //-----------------------------------------------------------98 interface BRFile;99 method Action wr( Rindx rindx, Bit#(32) data );100 method Bit#(32) rd1( Rindx rindx );101 method Bit#(32) rd2( Rindx rindx );102 endinterface104 module mkBRFile( BRFile );106 RegFile#(Rindx,Bit#(32)) rfile <- mkBRegFile();108 method Action wr( Rindx rindx, Bit#(32) data );109 rfile.upd( rindx, data );110 endmethod112 method Bit#(32) rd1( Rindx rindx );113 return ( rindx == 0 ) ? 0 : rfile.sub(rindx);114 endmethod116 method Bit#(32) rd2( Rindx rindx );117 return ( rindx == 0 ) ? 0 : rfile.sub(rindx);118 endmethod120 endmodule122 //-----------------------------------------------------------123 // Helper functions124 //-----------------------------------------------------------126 function Bit#(32) slt( Bit#(32) val1, Bit#(32) val2 );127 return zeroExtend( pack( signedLT(val1,val2) ) );128 endfunction130 function Bit#(32) sltu( Bit#(32) val1, Bit#(32) val2 );131 return zeroExtend( pack( val1 < val2 ) );132 endfunction134 function Bit#(32) rshft( Bit#(32) val );135 return zeroExtend(val[4:0]);136 endfunction139 //-----------------------------------------------------------140 // Find funct for wbQ141 //-----------------------------------------------------------142 function Bool findwbf(Rindx fVal, WBResult cmpVal);143 case (cmpVal) matches144 tagged WB_ALU {data:.res, dest:.rd} :145 return (fVal == rd);146 tagged WB_Load .rd :147 return (fVal == rd);148 tagged WB_Store .st :149 return False;150 tagged WB_Host .x :151 return False;152 endcase153 endfunction156 //-----------------------------------------------------------157 // Stall funct for wbQ158 //-----------------------------------------------------------159 function Bool stall(Instr inst, SFIFO#(WBResult, Rindx) f);160 case (inst) matches161 // -- Memory Ops ------------------------------------------------162 tagged LW .it :163 return f.find(it.rbase);164 tagged SW {rsrc:.dreg, rbase:.addr, offset:.o} :165 return (f.find(addr) || f.find2(dreg));167 // -- Simple Ops ------------------------------------------------168 tagged ADDIU .it : return f.find(it.rsrc);169 tagged SLTI .it : return f.find(it.rsrc);170 tagged SLTIU .it : return f.find(it.rsrc);171 tagged ANDI .it : return f.find(it.rsrc);172 tagged ORI .it : return f.find(it.rsrc);173 tagged XORI .it : return f.find(it.rsrc);175 tagged LUI .it : return f.find(it.rdst); //this rds/wrs itself176 tagged SLL .it : return f.find(it.rsrc);177 tagged SRL .it : return f.find(it.rsrc);178 tagged SRA .it : return f.find(it.rsrc);179 tagged SLLV .it : return (f.find(it.rsrc) || f.find(it.rshamt));180 tagged SRLV .it : return (f.find(it.rsrc) || f.find(it.rshamt));181 tagged SRAV .it : return (f.find(it.rsrc) || f.find(it.rshamt));182 tagged ADDU .it : return (f.find(it.rsrc1) || f.find2(it.rsrc2));183 tagged SUBU .it : return (f.find(it.rsrc1) || f.find2(it.rsrc2));184 tagged AND .it : return (f.find(it.rsrc1) || f.find2(it.rsrc2));185 tagged OR .it : return (f.find(it.rsrc1) || f.find2(it.rsrc2));186 tagged XOR .it : return (f.find(it.rsrc1) || f.find2(it.rsrc2));187 tagged NOR .it : return (f.find(it.rsrc1) || f.find2(it.rsrc2));188 tagged SLT .it : return (f.find(it.rsrc1) || f.find2(it.rsrc2));189 tagged SLTU .it : return (f.find(it.rsrc1) || f.find2(it.rsrc2));192 // -- Branches --------------------------------------------------194 tagged BLEZ .it : return (f.find(it.rsrc));195 tagged BGTZ .it : return (f.find(it.rsrc));196 tagged BLTZ .it : return (f.find(it.rsrc));197 tagged BGEZ .it : return (f.find(it.rsrc));198 tagged BEQ .it : return (f.find(it.rsrc1) || f.find2(it.rsrc2));199 tagged BNE .it : return (f.find(it.rsrc1) || f.find2(it.rsrc2));201 // -- Jumps -----------------------------------------------------203 tagged J .it : return False;204 tagged JR .it : return f.find(it.rsrc);205 tagged JALR .it : return f.find(it.rsrc);206 tagged JAL .it : return False;208 // -- Cop0 ------------------------------------------------------210 tagged MTC0 .it : return f.find(it.rsrc);211 tagged MFC0 .it : return False;213 // -- Illegal ---------------------------------------------------215 default : return False;217 endcase218 endfunction219 //-----------------------------------------------------------220 // Reference processor221 //-----------------------------------------------------------224 //(* doc = "synthesis attribute ram_style mkProc distributed;" *)225 //(* synthesize *)227 module [CONNECTED_MODULE] mkProc( Proc );229 //-----------------------------------------------------------230 // Debug port232 ServerStub_AUDIOCORERRR server_stub <- mkServerStub_AUDIOCORERRR();235 //-----------------------------------------------------------236 // State238 // Standard processor state240 Reg#(Addr) pc <- mkReg(32'h00001000);241 Reg#(Epoch) epoch <- mkReg(0);242 Reg#(Stage) stage <- mkReg(PCgen);243 BRFile rf <- mkBRFile;245 // Branch Prediction246 BranchPred bp <- mkBranchPred();247 FIFO#(PCStat) execpc <- mkLFIFO();249 // Pipelines250 FIFO#(PCStat) pcQ <-mkSizedFIFO(3);251 SFIFO#(WBResult, Rindx) wbQ <-mkSFIFO(findwbf);253 Reg#(Bit#(32)) cp0_tohost <- mkReg(0);254 Reg#(Bit#(32)) cp0_fromhost <- mkReg(0);255 Reg#(Bool) cp0_statsEn <- mkReg(False);257 // Memory request/response state259 FIFO#(InstReq) instReqQ <- mkBFIFO1();260 FIFO#(InstResp) instRespQ <- mkFIFO();262 FIFO#(DataReq) dataReqQ <- mkBFIFO1();263 FIFO#(DataResp) dataRespQ <- mkFIFO();265 // Audio I/O266 FIFO#(AudioProcessorUnit) inAudioFifo <- mkFIFO;267 FIFO#(AudioProcessorUnit) outAudioFifo <- mkFIFO;270 // Statistics state (2010)271 // Reg#(Stat) num_cycles <- mkReg(0);272 // Reg#(Stat) num_inst <- mkReg(0);274 //Or:275 // Statistics state276 STAT num_cycles <- mkStatCounter(`STATS_PROCESSOR_CYCLE_COUNT);277 STAT num_inst <- mkStatCounter(`STATS_PROCESSOR_INST_COUNT);279 //-----------------------------------------------------------280 // Rules282 (* descending_urgency = "exec, pcgen" *)283 rule pcgen; //( stage == PCgen );284 let pc_plus4 = pc + 4;286 traceTiny("mkProc", "pc",pc);287 traceTiny("mkProc", "pcgen","P");288 instReqQ.enq( LoadReq{ addr:pc, tag:epoch} );290 let next_pc = bp.get(pc);291 if (next_pc matches tagged Valid .npc)292 begin293 pcQ.enq(PCStat {qpc:pc, qnxtpc:npc, qepoch:epoch});294 pc <= npc;295 end296 else297 begin298 pcQ.enq(PCStat {qpc:pc, qnxtpc:pc_plus4, qepoch:epoch});299 pc <= pc_plus4;300 end302 endrule304 rule discard (instRespQ.first() matches tagged LoadResp .ld305 &&& ld.tag != epoch);306 traceTiny("mkProc", "stage", "D");307 instRespQ.deq();308 endrule310 (* conflict_free = "exec, writeback" *)311 rule exec (instRespQ.first() matches tagged LoadResp.ld312 &&& (ld.tag == epoch)313 &&& unpack(ld.data) matches .inst314 &&& !stall(inst, wbQ));316 // Some abbreviations317 let sext = signExtend;318 let zext = zeroExtend;319 let sra = signedShiftRight;321 // Get the instruction323 instRespQ.deq();324 Instr inst325 = case ( instRespQ.first() ) matches326 tagged LoadResp .ld : return unpack(ld.data);327 tagged StoreResp .st : return ?;328 endcase;330 // Get the PC info331 let instrpc = pcQ.first().qpc;332 let pc_plus4 = instrpc + 4;334 Bool branchTaken = False;335 Addr newPC = pc_plus4;337 // Tracing338 traceTiny("mkProc", "exec","X");339 traceTiny("mkProc", "exInstTiny",inst);340 traceFull("mkProc", "exInstFull",inst);342 case ( inst ) matches344 // -- Memory Ops ------------------------------------------------346 tagged LW .it :347 begin348 Addr addr = rf.rd1(it.rbase) + sext(it.offset);349 dataReqQ.enq( LoadReq{ addr:addr, tag:zeroExtend(it.rdst) } );350 wbQ.enq(tagged WB_Load it.rdst);351 end353 tagged SW .it :354 begin355 Addr addr = rf.rd1(it.rbase) + sext(it.offset);356 dataReqQ.enq( StoreReq{ tag:0, addr:addr, data:rf.rd2(it.rsrc) } );357 wbQ.enq(tagged WB_Store);358 end360 // -- Simple Ops ------------------------------------------------362 tagged ADDIU .it :363 begin364 Bit#(32) result = rf.rd1(it.rsrc) + sext(it.imm);365 wbQ.enq(tagged WB_ALU {data:result, dest:it.rdst});366 end367 tagged SLTI .it : wbQ.enq(tagged WB_ALU {dest:it.rdst, data:slt( rf.rd1(it.rsrc), sext(it.imm) )});368 tagged SLTIU .it : wbQ.enq(tagged WB_ALU {dest:it.rdst, data:sltu( rf.rd1(it.rsrc), sext(it.imm) ) });369 tagged ANDI .it :370 begin371 Bit#(32) zext_it_imm = zext(it.imm);372 wbQ.enq(tagged WB_ALU {dest:it.rdst, data:(rf.rd1(it.rsrc) & zext_it_imm)} );373 end374 tagged ORI .it :375 begin376 Bit#(32) zext_it_imm = zext(it.imm);377 wbQ.enq(tagged WB_ALU {dest:it.rdst, data:(rf.rd1(it.rsrc) | zext_it_imm)} );378 end379 tagged XORI .it :380 begin381 Bit#(32) zext_it_imm = zext(it.imm);382 wbQ.enq(tagged WB_ALU {dest: it.rdst, data:(rf.rd1(it.rsrc) ^ zext_it_imm )});383 end384 tagged LUI .it :385 begin386 Bit#(32) zext_it_imm = zext(it.imm);387 wbQ.enq(tagged WB_ALU {dest: it.rdst, data:(zext_it_imm << 32'd16) });388 end390 tagged SLL .it :391 begin392 Bit#(32) zext_it_shamt = zext(it.shamt);393 wbQ.enq(tagged WB_ALU {dest: it.rdst, data:(rf.rd1(it.rsrc) << zext_it_shamt )} );394 end395 tagged SRL .it :396 begin397 Bit#(32) zext_it_shamt = zext(it.shamt);398 wbQ.enq(tagged WB_ALU {dest: it.rdst, data:(rf.rd1(it.rsrc) >> zext_it_shamt )});399 end400 tagged SRA .it :401 begin402 Bit#(32) zext_it_shamt = zext(it.shamt);403 wbQ.enq(tagged WB_ALU {dest: it.rdst, data:sra( rf.rd1(it.rsrc), zext_it_shamt )});404 end405 tagged SLLV .it : wbQ.enq(tagged WB_ALU {dest: it.rdst, data:(rf.rd1(it.rsrc) << rshft(rf.rd2(it.rshamt)) )});406 tagged SRLV .it : wbQ.enq(tagged WB_ALU {dest: it.rdst, data:(rf.rd1(it.rsrc) >> rshft(rf.rd2(it.rshamt)) )} );407 tagged SRAV .it : wbQ.enq(tagged WB_ALU {dest: it.rdst, data:sra( rf.rd1(it.rsrc), rshft(rf.rd2(it.rshamt)) ) });408 tagged ADDU .it : wbQ.enq(tagged WB_ALU {dest: it.rdst, data:(rf.rd1(it.rsrc1) + rf.rd2(it.rsrc2) )} );409 tagged SUBU .it : wbQ.enq(tagged WB_ALU {dest: it.rdst, data:(rf.rd1(it.rsrc1) - rf.rd2(it.rsrc2) )} );410 tagged AND .it : wbQ.enq(tagged WB_ALU {dest: it.rdst, data:(rf.rd1(it.rsrc1) & rf.rd2(it.rsrc2) )} );411 tagged OR .it : wbQ.enq(tagged WB_ALU {dest: it.rdst, data:(rf.rd1(it.rsrc1) | rf.rd2(it.rsrc2) )} );412 tagged XOR .it : wbQ.enq(tagged WB_ALU {dest: it.rdst, data:(rf.rd1(it.rsrc1) ^ rf.rd2(it.rsrc2) )} );413 tagged NOR .it : wbQ.enq(tagged WB_ALU {dest: it.rdst, data:(~(rf.rd1(it.rsrc1) | rf.rd2(it.rsrc2)) )} );414 tagged SLT .it : wbQ.enq(tagged WB_ALU {dest: it.rdst, data:slt( rf.rd1(it.rsrc1), rf.rd2(it.rsrc2) ) });415 tagged SLTU .it : wbQ.enq(tagged WB_ALU {dest: it.rdst, data:sltu( rf.rd1(it.rsrc1), rf.rd2(it.rsrc2) ) });417 // -- Branches --------------------------------------------------419 tagged BLEZ .it :420 if ( signedLE( rf.rd1(it.rsrc), 0 ) )421 begin422 newPC = pc_plus4 + (sext(it.offset) << 2);423 branchTaken = True;424 end426 tagged BGTZ .it :427 if ( signedGT( rf.rd1(it.rsrc), 0 ) )428 begin429 newPC = pc_plus4 + (sext(it.offset) << 2);430 branchTaken = True;431 end433 tagged BLTZ .it :434 if ( signedLT( rf.rd1(it.rsrc), 0 ) )435 begin436 newPC = pc_plus4 + (sext(it.offset) << 2);437 branchTaken = True;438 end440 tagged BGEZ .it :441 if ( signedGE( rf.rd1(it.rsrc), 0 ) )442 begin443 newPC = pc_plus4 + (sext(it.offset) << 2);444 branchTaken = True;445 end447 tagged BEQ .it :448 if ( rf.rd1(it.rsrc1) == rf.rd2(it.rsrc2) )449 begin450 newPC = pc_plus4 + (sext(it.offset) << 2);451 branchTaken = True;452 end454 tagged BNE .it :455 if ( rf.rd1(it.rsrc1) != rf.rd2(it.rsrc2) )456 begin457 newPC = pc_plus4 + (sext(it.offset) << 2);458 branchTaken = True;459 end461 // -- Jumps -----------------------------------------------------463 tagged J .it :464 begin465 newPC = { pc_plus4[31:28], it.target, 2'b0 };466 branchTaken = True;467 end469 tagged JR .it :470 begin471 newPC = rf.rd1(it.rsrc);472 branchTaken = True;473 end475 tagged JAL .it :476 begin477 wbQ.enq(tagged WB_ALU {dest:31, data:pc_plus4 });478 newPC = { pc_plus4[31:28], it.target, 2'b0 };479 branchTaken = True;480 end482 tagged JALR .it :483 begin484 wbQ.enq(tagged WB_ALU {dest:it.rdst, data:pc_plus4 });485 newPC = rf.rd1(it.rsrc);486 branchTaken = True;487 end489 // -- Cop0 ------------------------------------------------------491 tagged MTC0 .it :492 begin493 case ( it.cop0dst )494 5'd10 : cp0_statsEn <= unpack(truncate(rf.rd1(it.rsrc)));495 5'd21 : cp0_tohost <= truncate(rf.rd1(it.rsrc));496 default :497 $display( " RTL-ERROR : %m : Illegal MTC0 cop0dst register!" );498 endcase499 wbQ.enq(tagged WB_Host 0); //no idea wwhat this actually should be.500 end502 //this is host stuff?503 tagged MFC0 .it :504 begin505 case ( it.cop0src )506 // not actually an ALU instruction but don't have the format otherwise507 5'd10 : wbQ.enq(tagged WB_ALU {dest:it.rdst, data:zext(pack(cp0_statsEn)) });508 5'd20 : wbQ.enq(tagged WB_ALU {dest:it.rdst, data:cp0_fromhost });509 5'd21 : wbQ.enq(tagged WB_ALU {dest:it.rdst, data:cp0_tohost });510 default :511 $display( " RTL-ERROR : %m : Illegal MFC0 cop0src register!" );512 endcase513 end515 // -- Illegal ---------------------------------------------------517 default :518 $display( " RTL-ERROR : %m : Illegal instruction !" );520 endcase522 //evaluate branch prediction523 Addr ppc = pcQ.first().qnxtpc; //predicted branch524 if (ppc != newPC) //prediction wrong525 begin526 epoch <= pcQ.first().qepoch + 1;527 bp.upd(instrpc, newPC); //update branch predictor528 pcQ.clear();529 pc <= newPC;530 end531 else532 pcQ.deq();534 if ( cp0_statsEn )535 num_inst.incr();537 endrule539 rule writeback; // ( stage == Writeback );540 traceTiny("mkProc", "writeback","W");543 // get what to do off the writeback queue544 wbQ.deq();545 case (wbQ.first()) matches546 tagged WB_ALU {data:.res, dest:.rdst} : rf.wr(rdst, res);547 tagged WB_Load .regWr :548 begin549 dataRespQ.deq();550 if (dataRespQ.first() matches tagged LoadResp .ld)551 rf.wr(truncate(ld.tag), ld.data); // no need to use Rindx from queue? Duplicate?552 end553 tagged WB_Store : dataRespQ.deq();554 tagged WB_Host .dat : noAction;555 endcase557 endrule559 rule inc_num_cycles;560 if ( cp0_statsEn )561 num_cycles.incr();562 endrule564 (* conservative_implicit_conditions *)565 rule handleCPUToHost;566 let req <- server_stub.acceptRequest_ReadCPUToHost();567 case (req)568 0: server_stub.sendResponse_ReadCPUToHost(cp0_tohost);569 1: server_stub.sendResponse_ReadCPUToHost(pc);570 2: server_stub.sendResponse_ReadCPUToHost(zeroExtend(pack(stage)));571 endcase572 endrule574 // for now, we don't do anything.575 rule connectAudioReqResp;576 // $display("rlm: PROCESSOR copies a datum\n");577 outAudioFifo.enq(inAudioFifo.first());578 inAudioFifo.deq;579 endrule581 // Server items & rules:583 rule feedInput;584 let command <- server_stub.acceptRequest_SendUnprocessedStream();585 AudioProcessorControl ctrl = unpack(truncate(command.ctrl));586 if(ctrl == EndOfFile)587 begin588 // $display("lsp: PROCESSOR received EOF ");589 inAudioFifo.enq(tagged EndOfFile);590 end591 else592 begin593 // $display("lsp: PROCESSOR received Data ");594 inAudioFifo.enq(tagged Sample unpack(truncate(command.sample)));595 end596 endrule599 //-----------------------------------------------------------600 // Methods602 interface Client imem_client;603 interface Get request = fifoToGet(instReqQ);604 interface Put response = fifoToPut(instRespQ);605 endinterface607 interface Client dmem_client;608 interface Get request = fifoToGet(dataReqQ);609 interface Put response = fifoToPut(dataRespQ);610 endinterface612 interface Get statsEn_get = toGet(asReg(cp0_statsEn));614 // interface CPUToHost tohost;615 // method Bit#(32) cpuToHost(int req);616 // return (case (req)617 // 0: cp0_tohost;618 // 1: pc;619 // 2: zeroExtend(pack(stage));620 // endcase);621 // endmethod622 // endinterface624 interface Get sampleOutput = fifoToGet(outAudioFifo);626 endmodule