Mercurial > pygar
view modules/bluespec/Pygar/lab4/Proc.bsv @ 60:6179c07c21d7 pygar svn.61
[svn r61] synthesis boundaries
author | punk |
---|---|
date | Mon, 10 May 2010 20:29:20 -0400 |
parents | 74716e9a81cc |
children |
line wrap: on
line source
1 import CBusUtils::*;2 import Register::*;4 import Trace::*;5 import MemTypes::*;6 import IProc::*;7 import ProcTypes::*;8 import FPGATypes::*;9 import RegFile::*;10 import FIFO::*;11 import BFIFO::*;12 import Assert::*;14 import GetPut::*;15 import GetPutExt::*;16 import ClientServer::*;17 import CBus::*;20 interface IProc;22 // Interface for testrig23 interface Put#(Bit#(8)) testrig_fromhost;24 interface Get#(Bit#(8)) testrig_tohost;26 // Interface from processor to caches27 interface Client#(DataReq,DataResp) dmem_client;28 interface Client#(InstReq,InstResp) imem_client;30 // Interface for enabling/disabling statistics on the rest of the core31 interface Get#(Bool) statsEn_get;33 endinterface36 typedef enum { PCgen, Exec, Writeback } Stage deriving(Eq,Bits);38 //-----------------------------------------------------------39 // Register file module40 //-----------------------------------------------------------42 interface RFile;43 method Action wr( Rindx rindx, Bit#(32) data );44 method Bit#(32) rd1( Rindx rindx );45 method Bit#(32) rd2( Rindx rindx );46 endinterface48 module mkRFile( RFile );50 RegFile#(Rindx,Bit#(32)) rfile <- mkRegFileFull();52 method Action wr( Rindx rindx, Bit#(32) data );53 rfile.upd( rindx, data );54 endmethod56 method Bit#(32) rd1( Rindx rindx );57 return ( rindx == 0 ) ? 0 : rfile.sub(rindx);58 endmethod60 method Bit#(32) rd2( Rindx rindx );61 return ( rindx == 0 ) ? 0 : rfile.sub(rindx);62 endmethod64 endmodule66 //-----------------------------------------------------------67 // Helper functions68 //-----------------------------------------------------------70 function Bit#(32) slt( Bit#(32) val1, Bit#(32) val2 );71 return zeroExtend( pack( signedLT(val1,val2) ) );72 endfunction74 function Bit#(32) sltu( Bit#(32) val1, Bit#(32) val2 );75 return zeroExtend( pack( val1 < val2 ) );76 endfunction78 function Bit#(32) rshft( Bit#(32) val );79 return zeroExtend(val[4:0]);80 endfunction82 //-----------------------------------------------------------83 // Reference processor84 //-----------------------------------------------------------87 module [ModWithCBus#(AvalonAddressWidth,AvalonDataWidth)] mkProc( IProc );89 //-----------------------------------------------------------90 // State92 // Standard processor state94 Reg#(Addr) pc <- mkReg(32'h00001000);95 Reg#(Stage) stage <- mkReg(PCgen);96 RFile rf <- mkRFile;98 // Coprocessor state100 Reg#(Bit#(8)) cp0_tohost <- mkReg(0);101 mkCBusWideRegRW(valueof(ToHostRegAddr),cp0_tohost);102 Reg#(Bit#(8)) cp0_fromhost <- mkReg(0);103 mkCBusWideRegRW(valueof(FromHostRegAddr),cp0_fromhost);104 Reg#(Bool) cp0_statsEn <- mkReg(False);105 mkCBusWideRegRW(valueof(StatsEnRegAddr),cp0_statsEn);106 // Memory request/response state108 FIFO#(InstReq) instReqQ <- mkBFIFO1();109 FIFO#(InstResp) instRespQ <- mkFIFO();111 FIFO#(DataReq) dataReqQ <- mkBFIFO1();112 FIFO#(DataResp) dataRespQ <- mkFIFO();114 // Statistics state116 Reg#(Int#(25)) num_cycles <- mkReg(25'h0);117 Reg#(Int#(25)) num_inst <- mkReg(25'h0);119 //-----------------------------------------------------------120 // Rules122 let pc_plus4 = pc + 4;124 rule pcgen ( stage == PCgen );125 traceTiny("pc",pc);126 traceTiny("stage","P");127 instReqQ.enq( LoadReq{ addr:pc, tag:0 } );128 stage <= Exec;129 endrule131 rule exec ( stage == Exec );133 // Some abbreviations134 let sext = signExtend;135 let zext = zeroExtend;136 let sra = signedShiftRight;138 // Get the instruction140 instRespQ.deq();141 Instr inst142 = case ( instRespQ.first() ) matches143 tagged LoadResp .ld : return unpack(ld.data);144 tagged StoreResp .st : return ?;145 endcase;147 // Some default variables148 Stage next_stage = PCgen;149 Addr next_pc = pc_plus4;151 // Tracing152 traceTiny("stage","X");153 traceTiny("exInstTiny",inst);154 traceFull("exInstFull",inst);156 case ( inst ) matches158 // -- Memory Ops ------------------------------------------------160 tagged LW .it :161 begin162 Addr addr = rf.rd1(it.rbase) + sext(it.offset);163 dataReqQ.enq( LoadReq{ addr:addr, tag:zeroExtend(it.rdst) } );164 next_stage = Writeback;165 end167 tagged SW .it :168 begin169 Addr addr = rf.rd1(it.rbase) + sext(it.offset);170 dataReqQ.enq( StoreReq{ tag:0, addr:addr, data:rf.rd1(it.rsrc) } );171 next_stage = Writeback;172 end174 // -- Simple Ops ------------------------------------------------176 tagged ADDIU .it : rf.wr( it.rdst, rf.rd1(it.rsrc) + sext(it.imm) );177 tagged SLTI .it : rf.wr( it.rdst, slt( rf.rd1(it.rsrc), sext(it.imm) ) );178 tagged SLTIU .it : rf.wr( it.rdst, sltu( rf.rd1(it.rsrc), sext(it.imm) ) );179 tagged ANDI .it :180 begin181 Bit#(32) zext_it_imm = zext(it.imm);182 rf.wr( it.rdst, rf.rd1(it.rsrc) & zext_it_imm );183 end184 tagged ORI .it :185 begin186 Bit#(32) zext_it_imm = zext(it.imm);187 rf.wr( it.rdst, rf.rd1(it.rsrc) | zext_it_imm );188 end189 tagged XORI .it :190 begin191 Bit#(32) zext_it_imm = zext(it.imm);192 rf.wr( it.rdst, rf.rd1(it.rsrc) ^ zext_it_imm );193 end194 tagged LUI .it :195 begin196 Bit#(32) zext_it_imm = zext(it.imm);197 rf.wr( it.rdst, (zext_it_imm << 32'd16) );198 end200 tagged SLL .it :201 begin202 Bit#(32) zext_it_shamt = zext(it.shamt);203 rf.wr( it.rdst, rf.rd1(it.rsrc) << zext_it_shamt );204 end205 tagged SRL .it :206 begin207 Bit#(32) zext_it_shamt = zext(it.shamt);208 rf.wr( it.rdst, rf.rd1(it.rsrc) >> zext_it_shamt );209 end210 tagged SRA .it :211 begin212 Bit#(32) zext_it_shamt = zext(it.shamt);213 rf.wr( it.rdst, sra( rf.rd1(it.rsrc), zext_it_shamt ));214 end215 tagged SLLV .it : rf.wr( it.rdst, rf.rd1(it.rsrc) << rshft(rf.rd2(it.rshamt)) );216 tagged SRLV .it : rf.wr( it.rdst, rf.rd1(it.rsrc) >> rshft(rf.rd2(it.rshamt)) );217 tagged SRAV .it : rf.wr( it.rdst, sra( rf.rd1(it.rsrc), rshft(rf.rd2(it.rshamt)) ) );218 tagged ADDU .it : rf.wr( it.rdst, rf.rd1(it.rsrc1) + rf.rd2(it.rsrc2) );219 tagged SUBU .it : rf.wr( it.rdst, rf.rd1(it.rsrc1) - rf.rd2(it.rsrc2) );220 tagged AND .it : rf.wr( it.rdst, rf.rd1(it.rsrc1) & rf.rd2(it.rsrc2) );221 tagged OR .it : rf.wr( it.rdst, rf.rd1(it.rsrc1) | rf.rd2(it.rsrc2) );222 tagged XOR .it : rf.wr( it.rdst, rf.rd1(it.rsrc1) ^ rf.rd2(it.rsrc2) );223 tagged NOR .it : rf.wr( it.rdst, ~(rf.rd1(it.rsrc1) | rf.rd2(it.rsrc2)) );224 tagged SLT .it : rf.wr( it.rdst, slt( rf.rd1(it.rsrc1), rf.rd2(it.rsrc2) ) );225 tagged SLTU .it : rf.wr( it.rdst, sltu( rf.rd1(it.rsrc1), rf.rd2(it.rsrc2) ) );227 // -- Branches --------------------------------------------------229 tagged BLEZ .it :230 if ( signedLE( rf.rd1(it.rsrc), 0 ) )231 next_pc = pc_plus4 + (sext(it.offset) << 2);233 tagged BGTZ .it :234 if ( signedGT( rf.rd1(it.rsrc), 0 ) )235 next_pc = pc_plus4 + (sext(it.offset) << 2);237 tagged BLTZ .it :238 if ( signedLT( rf.rd1(it.rsrc), 0 ) )239 next_pc = pc_plus4 + (sext(it.offset) << 2);241 tagged BGEZ .it :242 if ( signedGE( rf.rd1(it.rsrc), 0 ) )243 next_pc = pc_plus4 + (sext(it.offset) << 2);245 tagged BEQ .it :246 if ( rf.rd1(it.rsrc1) == rf.rd2(it.rsrc2) )247 next_pc = pc_plus4 + (sext(it.offset) << 2);249 tagged BNE .it :250 if ( rf.rd1(it.rsrc1) != rf.rd2(it.rsrc2) )251 next_pc = pc_plus4 + (sext(it.offset) << 2);253 // -- Jumps -----------------------------------------------------255 tagged J .it :256 next_pc = { pc_plus4[31:28], it.target, 2'b0 };258 tagged JR .it :259 next_pc = rf.rd1(it.rsrc);261 tagged JAL .it :262 begin263 rf.wr( 31, pc_plus4 );264 next_pc = { pc_plus4[31:28], it.target, 2'b0 };265 end267 tagged JALR .it :268 begin269 rf.wr( it.rdst, pc_plus4 );270 next_pc = rf.rd1(it.rsrc);271 end273 // -- Cop0 ------------------------------------------------------275 tagged MTC0 .it :276 case ( it.cop0dst )277 5'd10 : cp0_statsEn <= unpack(truncate(rf.rd1(it.rsrc)));278 5'd21 : cp0_tohost <= truncate(rf.rd1(it.rsrc));279 default :280 $display( " RTL-ERROR : %m : Illegal MTC0 cop0dst register!" );281 endcase283 tagged MFC0 .it :284 case ( it.cop0src )285 5'd10 : rf.wr( it.rdst, zext(pack(cp0_statsEn)) );286 5'd20 : rf.wr( it.rdst, zext(cp0_fromhost) );287 5'd21 : rf.wr( it.rdst, zext(cp0_tohost) );288 default :289 $display( " RTL-ERROR : %m : Illegal MFC0 cop0src register!" );290 endcase292 // -- Illegal ---------------------------------------------------294 default :295 $display( " RTL-ERROR : %m : Illegal instruction !" );297 endcase299 stage <= next_stage;300 pc <= next_pc;302 if ( cp0_statsEn )303 num_inst <= num_inst + 1;305 endrule307 rule writeback ( stage == Writeback );308 traceTiny("stage","W");310 dataRespQ.deq();311 case ( dataRespQ.first() ) matches312 tagged LoadResp .ld : rf.wr( truncate(ld.tag), ld.data );313 tagged StoreResp .st : noAction;314 endcase316 stage <= PCgen;317 endrule319 rule inc_num_cycles;320 if ( cp0_statsEn )321 num_cycles <= num_cycles + 1;322 endrule324 //-----------------------------------------------------------325 // Methods327 interface Client imem_client;328 interface Get request = fifoToGet(instReqQ);329 interface Put response = fifoToPut(instRespQ);330 endinterface332 interface Client dmem_client;333 interface Get request = fifoToGet(dataReqQ);334 interface Put response = fifoToPut(dataRespQ);335 endinterface337 interface Get testrig_tohost = regToGet(cp0_tohost);338 interface Put testrig_fromhost = regToPut(cp0_fromhost);339 interface Get statsEn_get = regToGet(cp0_statsEn);341 endmodule