Mercurial > pygar
view modules/bluespec/Pygar/lab4/oProcessor.bsv @ 62:90fa9b289aab pygar svn.63
[svn r63] synthesis boundaries
author | punk |
---|---|
date | Mon, 10 May 2010 21:00:49 -0400 |
parents | 74716e9a81cc |
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.23 import Connectable::*;24 import GetPut::*;25 import ClientServer::*;26 import RegFile::*;27 import FIFO::*;28 import FIFOF::*;29 import RWire::*;31 //AWB includes32 `include "asim/provides/low_level_platform_interface.bsh"33 `include "asim/provides/soft_connections.bsh"34 `include "asim/provides/common_services.bsh"36 // Local includes37 `include "asim/provides/processor_library.bsh"38 `include "asim/rrr/remote_server_stub_PROCESSORSYSTEMRRR.bsh"39 `include "asim/provides/common_services.bsh"40 `include "asim/dict/STATS_PROCESSOR.bsh"42 interface Proc;44 // Interface from processor to caches45 interface Client#(DataReq,DataResp) dmem_client;46 interface Client#(InstReq,InstResp) imem_client;48 // Interface for enabling/disabling statistics on the rest of the core49 interface Get#(Bool) statsEn_get;51 endinterface54 typedef enum { PCgen, Exec, Writeback } Stage deriving(Eq,Bits);56 //-----------------------------------------------------------57 // Register file module58 //-----------------------------------------------------------60 interface RFile;61 method Action wr( Rindx rindx, Bit#(32) data );62 method Bit#(32) rd1( Rindx rindx );63 method Bit#(32) rd2( Rindx rindx );64 endinterface66 module mkRFile( RFile );68 RegFile#(Rindx,Bit#(32)) rfile <- mkRegFileFull();70 method Action wr( Rindx rindx, Bit#(32) data );71 rfile.upd( rindx, data );72 endmethod74 method Bit#(32) rd1( Rindx rindx );75 return ( rindx == 0 ) ? 0 : rfile.sub(rindx);76 endmethod78 method Bit#(32) rd2( Rindx rindx );79 return ( rindx == 0 ) ? 0 : rfile.sub(rindx);80 endmethod82 endmodule84 //-----------------------------------------------------------85 // Helper functions86 //-----------------------------------------------------------88 function Bit#(32) slt( Bit#(32) val1, Bit#(32) val2 );89 return zeroExtend( pack( signedLT(val1,val2) ) );90 endfunction92 function Bit#(32) sltu( Bit#(32) val1, Bit#(32) val2 );93 return zeroExtend( pack( val1 < val2 ) );94 endfunction96 function Bit#(32) rshft( Bit#(32) val );97 return zeroExtend(val[4:0]);98 endfunction100 //-----------------------------------------------------------101 // Reference processor102 //-----------------------------------------------------------105 module [CONNECTED_MODULE] mkProc( Proc );107 //-----------------------------------------------------------108 // Debug port110 ServerStub_PROCESSORSYSTEMRRR server_stub <- mkServerStub_PROCESSORSYSTEMRRR();112 //-----------------------------------------------------------113 // State115 // Standard processor state117 Reg#(Addr) pc <- mkReg(32'h00001000);118 Reg#(Stage) stage <- mkReg(PCgen);119 RFile rf <- mkRFile;121 // Coprocessor state - connected by way of RRR123 Reg#(Bit#(32)) cp0_tohost <- mkReg(0);125 Reg#(Bit#(32)) cp0_fromhost <- mkReg(0);127 Reg#(Bool) cp0_statsEn <- mkReg(False);129 // Memory request/response state131 FIFO#(InstReq) instReqQ <- mkBFIFO1();132 FIFO#(InstResp) instRespQ <- mkFIFO();134 FIFO#(DataReq) dataReqQ <- mkBFIFO1();135 FIFO#(DataResp) dataRespQ <- mkFIFO();137 // Statistics state138 STAT num_cycles <- mkStatCounter(`STATS_PROCESSOR_CYCLE_COUNT);139 STAT num_inst <- mkStatCounter(`STATS_PROCESSOR_INST_COUNT);141 //-----------------------------------------------------------142 // Rules144 let pc_plus4 = pc + 4;146 rule pcgen ( stage == PCgen );147 traceTiny("mkProc", "pc",pc);148 traceTiny("mkProc", "pcgen","P");149 instReqQ.enq( LoadReq{ addr:pc, tag:0 } );150 stage <= Exec;151 endrule153 rule exec ( stage == Exec );155 // Some abbreviations156 let sext = signExtend;157 let zext = zeroExtend;158 let sra = signedShiftRight;160 // Get the instruction162 instRespQ.deq();163 Instr inst164 = case ( instRespQ.first() ) matches165 tagged LoadResp .ld : return unpack(ld.data);166 tagged StoreResp .st : return ?;167 endcase;169 // Some default variables170 Stage next_stage = PCgen;171 Addr next_pc = pc_plus4;173 // Tracing174 traceTiny("mkProc", "exec","X");175 traceTiny("mkProc", "exInstTiny",inst);176 traceFull("mkProc", "exInstFull",inst);178 case ( inst ) matches180 // -- Memory Ops ------------------------------------------------182 tagged LW .it :183 begin184 Addr addr = rf.rd1(it.rbase) + sext(it.offset);185 dataReqQ.enq( LoadReq{ addr:addr, tag:zeroExtend(it.rdst) } );186 next_stage = Writeback;187 end189 tagged SW .it :190 begin191 Addr addr = rf.rd1(it.rbase) + sext(it.offset);192 dataReqQ.enq( StoreReq{ tag:0, addr:addr, data:rf.rd1(it.rsrc) } );193 next_stage = Writeback;194 end196 // -- Simple Ops ------------------------------------------------198 tagged ADDIU .it : rf.wr( it.rdst, rf.rd1(it.rsrc) + sext(it.imm) );199 tagged SLTI .it : rf.wr( it.rdst, slt( rf.rd1(it.rsrc), sext(it.imm) ) );200 tagged SLTIU .it : rf.wr( it.rdst, sltu( rf.rd1(it.rsrc), sext(it.imm) ) );201 tagged ANDI .it :202 begin203 Bit#(32) zext_it_imm = zext(it.imm);204 rf.wr( it.rdst, rf.rd1(it.rsrc) & zext_it_imm );205 end206 tagged ORI .it :207 begin208 Bit#(32) zext_it_imm = zext(it.imm);209 rf.wr( it.rdst, rf.rd1(it.rsrc) | zext_it_imm );210 end211 tagged XORI .it :212 begin213 Bit#(32) zext_it_imm = zext(it.imm);214 rf.wr( it.rdst, rf.rd1(it.rsrc) ^ zext_it_imm );215 end216 tagged LUI .it :217 begin218 Bit#(32) zext_it_imm = zext(it.imm);219 rf.wr( it.rdst, (zext_it_imm << 32'd16) );220 end222 tagged SLL .it :223 begin224 Bit#(32) zext_it_shamt = zext(it.shamt);225 rf.wr( it.rdst, rf.rd1(it.rsrc) << zext_it_shamt );226 end227 tagged SRL .it :228 begin229 Bit#(32) zext_it_shamt = zext(it.shamt);230 rf.wr( it.rdst, rf.rd1(it.rsrc) >> zext_it_shamt );231 end232 tagged SRA .it :233 begin234 Bit#(32) zext_it_shamt = zext(it.shamt);235 rf.wr( it.rdst, sra( rf.rd1(it.rsrc), zext_it_shamt ));236 end237 tagged SLLV .it : rf.wr( it.rdst, rf.rd1(it.rsrc) << rshft(rf.rd2(it.rshamt)) );238 tagged SRLV .it : rf.wr( it.rdst, rf.rd1(it.rsrc) >> rshft(rf.rd2(it.rshamt)) );239 tagged SRAV .it : rf.wr( it.rdst, sra( rf.rd1(it.rsrc), rshft(rf.rd2(it.rshamt)) ) );240 tagged ADDU .it : rf.wr( it.rdst, rf.rd1(it.rsrc1) + rf.rd2(it.rsrc2) );241 tagged SUBU .it : rf.wr( it.rdst, rf.rd1(it.rsrc1) - rf.rd2(it.rsrc2) );242 tagged AND .it : rf.wr( it.rdst, rf.rd1(it.rsrc1) & rf.rd2(it.rsrc2) );243 tagged OR .it : rf.wr( it.rdst, rf.rd1(it.rsrc1) | rf.rd2(it.rsrc2) );244 tagged XOR .it : rf.wr( it.rdst, rf.rd1(it.rsrc1) ^ rf.rd2(it.rsrc2) );245 tagged NOR .it : rf.wr( it.rdst, ~(rf.rd1(it.rsrc1) | rf.rd2(it.rsrc2)) );246 tagged SLT .it : rf.wr( it.rdst, slt( rf.rd1(it.rsrc1), rf.rd2(it.rsrc2) ) );247 tagged SLTU .it : rf.wr( it.rdst, sltu( rf.rd1(it.rsrc1), rf.rd2(it.rsrc2) ) );249 // -- Branches --------------------------------------------------251 tagged BLEZ .it :252 if ( signedLE( rf.rd1(it.rsrc), 0 ) )253 next_pc = pc_plus4 + (sext(it.offset) << 2);255 tagged BGTZ .it :256 if ( signedGT( rf.rd1(it.rsrc), 0 ) )257 next_pc = pc_plus4 + (sext(it.offset) << 2);259 tagged BLTZ .it :260 if ( signedLT( rf.rd1(it.rsrc), 0 ) )261 next_pc = pc_plus4 + (sext(it.offset) << 2);263 tagged BGEZ .it :264 if ( signedGE( rf.rd1(it.rsrc), 0 ) )265 next_pc = pc_plus4 + (sext(it.offset) << 2);267 tagged BEQ .it :268 if ( rf.rd1(it.rsrc1) == rf.rd2(it.rsrc2) )269 next_pc = pc_plus4 + (sext(it.offset) << 2);271 tagged BNE .it :272 if ( rf.rd1(it.rsrc1) != rf.rd2(it.rsrc2) )273 next_pc = pc_plus4 + (sext(it.offset) << 2);275 // -- Jumps -----------------------------------------------------277 tagged J .it :278 next_pc = { pc_plus4[31:28], it.target, 2'b0 };280 tagged JR .it :281 next_pc = rf.rd1(it.rsrc);283 tagged JAL .it :284 begin285 rf.wr( 31, pc_plus4 );286 next_pc = { pc_plus4[31:28], it.target, 2'b0 };287 end289 tagged JALR .it :290 begin291 rf.wr( it.rdst, pc_plus4 );292 next_pc = rf.rd1(it.rsrc);293 end295 // -- Cop0 ------------------------------------------------------297 tagged MTC0 .it :298 case ( it.cop0dst )299 5'd10 : cp0_statsEn <= unpack(truncate(rf.rd1(it.rsrc)));300 5'd21 : cp0_tohost <= truncate(rf.rd1(it.rsrc));301 default :302 $display( " RTL-ERROR : %m : Illegal MTC0 cop0dst register!" );303 endcase305 tagged MFC0 .it :306 case ( it.cop0src )307 5'd10 : rf.wr( it.rdst, zext(pack(cp0_statsEn)) );308 5'd20 : rf.wr( it.rdst, cp0_fromhost );309 5'd21 : rf.wr( it.rdst, cp0_tohost );310 default :311 $display( " RTL-ERROR : %m : Illegal MFC0 cop0src register!" );312 endcase314 // -- Illegal ---------------------------------------------------316 default :317 $display( " RTL-ERROR : %m : Illegal instruction !" );319 endcase321 stage <= next_stage;322 pc <= next_pc;324 if ( cp0_statsEn )325 num_inst.incr();327 endrule329 rule writeback ( stage == Writeback );330 traceTiny("mkProc", "writeback","W");332 dataRespQ.deq();333 case ( dataRespQ.first() ) matches334 tagged LoadResp .ld : rf.wr( truncate(ld.tag), ld.data );335 tagged StoreResp .st : noAction;336 endcase338 stage <= PCgen;339 endrule341 rule inc_num_cycles;342 if ( cp0_statsEn )343 num_cycles.incr();344 endrule346 rule handleCPUToHost;347 let req <- server_stub.acceptRequest_ReadCPUToHost();348 case (req)349 0: server_stub.sendResponse_ReadCPUToHost(cp0_tohost);350 1: server_stub.sendResponse_ReadCPUToHost(pc);351 2: server_stub.sendResponse_ReadCPUToHost(zeroExtend(pack(stage)));352 endcase353 endrule357 //-----------------------------------------------------------358 // Methods360 interface Client imem_client;361 interface Get request = fifoToGet(instReqQ);362 interface Put response = fifoToPut(instRespQ);363 endinterface365 interface Client dmem_client;366 interface Get request = fifoToGet(dataReqQ);367 interface Put response = fifoToPut(dataRespQ);368 endinterface370 interface Get statsEn_get = regToGet(cp0_statsEn);372 endmodule