diff modules/bluespec/Pygar/lab4/oProcessor.bsv @ 8:74716e9a81cc pygar svn.9

[svn r9] Pygar now has the proper directory structure to play nicely with awb. Also, the apm file for audio-core willcompile successfully.
author rlm
date Fri, 23 Apr 2010 02:32:05 -0400
parents
children
line wrap: on
line diff
     1.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     1.2 +++ b/modules/bluespec/Pygar/lab4/oProcessor.bsv	Fri Apr 23 02:32:05 2010 -0400
     1.3 @@ -0,0 +1,373 @@
     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 +import FIFO::*;
    1.31 +import FIFOF::*;
    1.32 +import RWire::*;
    1.33 +
    1.34 +//AWB includes
    1.35 +`include "asim/provides/low_level_platform_interface.bsh"
    1.36 +`include "asim/provides/soft_connections.bsh"
    1.37 +`include "asim/provides/common_services.bsh"
    1.38 +
    1.39 +// Local includes
    1.40 +`include "asim/provides/processor_library.bsh"
    1.41 +`include "asim/rrr/remote_server_stub_PROCESSORSYSTEMRRR.bsh"
    1.42 +`include "asim/provides/common_services.bsh"
    1.43 +`include "asim/dict/STATS_PROCESSOR.bsh"
    1.44 +
    1.45 +interface Proc;
    1.46 +
    1.47 +  // Interface from processor to caches
    1.48 +  interface Client#(DataReq,DataResp) dmem_client;
    1.49 +  interface Client#(InstReq,InstResp) imem_client;
    1.50 +
    1.51 +  // Interface for enabling/disabling statistics on the rest of the core
    1.52 +  interface Get#(Bool) statsEn_get;
    1.53 +
    1.54 +endinterface
    1.55 +
    1.56 +
    1.57 +typedef enum { PCgen, Exec, Writeback } Stage deriving(Eq,Bits);
    1.58 +
    1.59 +//-----------------------------------------------------------
    1.60 +// Register file module
    1.61 +//-----------------------------------------------------------
    1.62 +
    1.63 +interface RFile;
    1.64 +   method Action   wr( Rindx rindx, Bit#(32) data );
    1.65 +   method Bit#(32) rd1( Rindx rindx );
    1.66 +   method Bit#(32) rd2( Rindx rindx );
    1.67 +endinterface
    1.68 +
    1.69 +module mkRFile( RFile );
    1.70 +   
    1.71 +   RegFile#(Rindx,Bit#(32)) rfile <- mkRegFileFull();
    1.72 +   
    1.73 +   method Action wr( Rindx rindx, Bit#(32) data );
    1.74 +      rfile.upd( rindx, data );
    1.75 +   endmethod
    1.76 +   
    1.77 +   method Bit#(32) rd1( Rindx rindx );
    1.78 +      return ( rindx == 0 ) ? 0 : rfile.sub(rindx);
    1.79 +   endmethod
    1.80 +   
    1.81 +   method Bit#(32) rd2( Rindx rindx );
    1.82 +      return ( rindx == 0 ) ? 0 : rfile.sub(rindx);
    1.83 +   endmethod
    1.84 +
    1.85 +endmodule
    1.86 +
    1.87 +//-----------------------------------------------------------
    1.88 +// Helper functions
    1.89 +//-----------------------------------------------------------
    1.90 +
    1.91 +function Bit#(32) slt( Bit#(32) val1, Bit#(32) val2 );
    1.92 +   return zeroExtend( pack( signedLT(val1,val2) ) );
    1.93 +endfunction
    1.94 +
    1.95 +function Bit#(32) sltu( Bit#(32) val1, Bit#(32) val2 );
    1.96 +   return zeroExtend( pack( val1 < val2 ) );
    1.97 +endfunction
    1.98 +
    1.99 +function Bit#(32) rshft( Bit#(32) val );
   1.100 +   return zeroExtend(val[4:0]);
   1.101 +endfunction
   1.102 +
   1.103 +//-----------------------------------------------------------
   1.104 +// Reference processor
   1.105 +//-----------------------------------------------------------
   1.106 +
   1.107 +
   1.108 +module  [CONNECTED_MODULE] mkProc( Proc );
   1.109 +
   1.110 +   //-----------------------------------------------------------
   1.111 +   // Debug port
   1.112 +   
   1.113 +   ServerStub_PROCESSORSYSTEMRRR server_stub <- mkServerStub_PROCESSORSYSTEMRRR();   
   1.114 +
   1.115 +   //-----------------------------------------------------------
   1.116 +   // State
   1.117 +
   1.118 +   // Standard processor state
   1.119 +   
   1.120 +   Reg#(Addr)  pc    <- mkReg(32'h00001000);
   1.121 +   Reg#(Stage) stage <- mkReg(PCgen);
   1.122 +   RFile       rf    <- mkRFile;
   1.123 +
   1.124 +   // Coprocessor state - connected by way of RRR
   1.125 +   
   1.126 +   Reg#(Bit#(32)) cp0_tohost   <- mkReg(0);
   1.127 +  
   1.128 +   Reg#(Bit#(32)) cp0_fromhost <- mkReg(0);
   1.129 +  
   1.130 +   Reg#(Bool)    cp0_statsEn  <- mkReg(False);
   1.131 +  
   1.132 +   // Memory request/response state
   1.133 +   
   1.134 +   FIFO#(InstReq)  instReqQ    <- mkBFIFO1();
   1.135 +   FIFO#(InstResp) instRespQ   <- mkFIFO();
   1.136 +
   1.137 +   FIFO#(DataReq)  dataReqQ    <- mkBFIFO1();
   1.138 +   FIFO#(DataResp) dataRespQ   <- mkFIFO();
   1.139 +
   1.140 +   // Statistics state
   1.141 +   STAT num_cycles <- mkStatCounter(`STATS_PROCESSOR_CYCLE_COUNT);
   1.142 +   STAT num_inst <- mkStatCounter(`STATS_PROCESSOR_INST_COUNT);
   1.143 +
   1.144 +   //-----------------------------------------------------------
   1.145 +   // Rules
   1.146 +
   1.147 +   let pc_plus4 = pc + 4;
   1.148 +
   1.149 +   rule pcgen ( stage == PCgen );
   1.150 +      traceTiny("mkProc", "pc",pc);
   1.151 +      traceTiny("mkProc", "pcgen","P");
   1.152 +      instReqQ.enq( LoadReq{ addr:pc, tag:0 } );
   1.153 +      stage   <= Exec;
   1.154 +   endrule
   1.155 +
   1.156 +   rule exec ( stage == Exec );
   1.157 +
   1.158 +      // Some abbreviations
   1.159 +      let sext = signExtend;
   1.160 +      let zext = zeroExtend;
   1.161 +      let sra  = signedShiftRight;
   1.162 +      
   1.163 +      // Get the instruction
   1.164 +      
   1.165 +      instRespQ.deq();
   1.166 +      Instr inst 
   1.167 +      = case ( instRespQ.first() ) matches
   1.168 +	   tagged LoadResp  .ld : return unpack(ld.data);
   1.169 +	   tagged StoreResp .st : return ?;
   1.170 +	endcase;
   1.171 +
   1.172 +      // Some default variables
   1.173 +      Stage next_stage = PCgen;
   1.174 +      Addr  next_pc    = pc_plus4;
   1.175 +
   1.176 +      // Tracing
   1.177 +      traceTiny("mkProc", "exec","X");
   1.178 +      traceTiny("mkProc", "exInstTiny",inst);
   1.179 +      traceFull("mkProc", "exInstFull",inst);
   1.180 +
   1.181 +      case ( inst ) matches
   1.182 +
   1.183 +	 // -- Memory Ops ------------------------------------------------      
   1.184 +
   1.185 +	 tagged LW .it : 
   1.186 +	    begin
   1.187 +               Addr addr = rf.rd1(it.rbase) + sext(it.offset);
   1.188 +               dataReqQ.enq( LoadReq{ addr:addr, tag:zeroExtend(it.rdst) } );
   1.189 +               next_stage = Writeback;
   1.190 +	    end
   1.191 +
   1.192 +	 tagged SW .it : 
   1.193 +	    begin
   1.194 +               Addr addr = rf.rd1(it.rbase) + sext(it.offset);
   1.195 +               dataReqQ.enq( StoreReq{ tag:0, addr:addr, data:rf.rd1(it.rsrc) } );
   1.196 +               next_stage = Writeback;
   1.197 +	    end
   1.198 +
   1.199 +	 // -- Simple Ops ------------------------------------------------      
   1.200 +
   1.201 +	 tagged ADDIU .it : rf.wr( it.rdst, rf.rd1(it.rsrc) + sext(it.imm) );
   1.202 +	 tagged SLTI  .it : rf.wr( it.rdst, slt( rf.rd1(it.rsrc), sext(it.imm) ) );
   1.203 +	 tagged SLTIU .it : rf.wr( it.rdst, sltu( rf.rd1(it.rsrc), sext(it.imm) ) );
   1.204 +	 tagged ANDI  .it : 
   1.205 +	    begin
   1.206 +	       Bit#(32) zext_it_imm = zext(it.imm);
   1.207 +	       rf.wr( it.rdst, rf.rd1(it.rsrc) & zext_it_imm );
   1.208 +	    end
   1.209 +	 tagged ORI   .it : 
   1.210 +	    begin
   1.211 +	       Bit#(32) zext_it_imm = zext(it.imm);
   1.212 +	       rf.wr( it.rdst, rf.rd1(it.rsrc) | zext_it_imm );
   1.213 +	    end
   1.214 +	 tagged XORI  .it : 
   1.215 +	    begin
   1.216 +	       Bit#(32) zext_it_imm = zext(it.imm);
   1.217 +	       rf.wr( it.rdst, rf.rd1(it.rsrc) ^ zext_it_imm );
   1.218 +	    end
   1.219 +	 tagged LUI   .it : 
   1.220 +	    begin
   1.221 +	       Bit#(32) zext_it_imm = zext(it.imm);
   1.222 +	       rf.wr( it.rdst, (zext_it_imm << 32'd16) );
   1.223 +	    end
   1.224 +	 
   1.225 +	 tagged SLL   .it : 
   1.226 +	    begin
   1.227 +	       Bit#(32) zext_it_shamt = zext(it.shamt);
   1.228 +	       rf.wr( it.rdst, rf.rd1(it.rsrc) << zext_it_shamt );
   1.229 +	    end
   1.230 +	 tagged SRL   .it : 
   1.231 +	    begin
   1.232 +	       Bit#(32) zext_it_shamt = zext(it.shamt);
   1.233 +	       rf.wr( it.rdst, rf.rd1(it.rsrc) >> zext_it_shamt );
   1.234 +	    end
   1.235 +	 tagged SRA   .it : 
   1.236 +	    begin
   1.237 +	       Bit#(32) zext_it_shamt = zext(it.shamt);
   1.238 +	       rf.wr( it.rdst, sra( rf.rd1(it.rsrc), zext_it_shamt ));
   1.239 +	    end
   1.240 +	 tagged SLLV  .it : rf.wr( it.rdst, rf.rd1(it.rsrc) << rshft(rf.rd2(it.rshamt)) );
   1.241 +	 tagged SRLV  .it : rf.wr( it.rdst, rf.rd1(it.rsrc) >> rshft(rf.rd2(it.rshamt)) );
   1.242 +	 tagged SRAV  .it : rf.wr( it.rdst, sra( rf.rd1(it.rsrc), rshft(rf.rd2(it.rshamt)) ) );
   1.243 +	 tagged ADDU  .it : rf.wr( it.rdst, rf.rd1(it.rsrc1) + rf.rd2(it.rsrc2) );
   1.244 +	 tagged SUBU  .it : rf.wr( it.rdst, rf.rd1(it.rsrc1) - rf.rd2(it.rsrc2) );
   1.245 +	 tagged AND   .it : rf.wr( it.rdst, rf.rd1(it.rsrc1) & rf.rd2(it.rsrc2) );
   1.246 +	 tagged OR    .it : rf.wr( it.rdst, rf.rd1(it.rsrc1) | rf.rd2(it.rsrc2) );
   1.247 +	 tagged XOR   .it : rf.wr( it.rdst, rf.rd1(it.rsrc1) ^ rf.rd2(it.rsrc2) );
   1.248 +	 tagged NOR   .it : rf.wr( it.rdst, ~(rf.rd1(it.rsrc1) | rf.rd2(it.rsrc2)) );
   1.249 +	 tagged SLT   .it : rf.wr( it.rdst, slt( rf.rd1(it.rsrc1), rf.rd2(it.rsrc2) ) );
   1.250 +	 tagged SLTU  .it : rf.wr( it.rdst, sltu( rf.rd1(it.rsrc1), rf.rd2(it.rsrc2) ) );
   1.251 +
   1.252 +	 // -- Branches --------------------------------------------------
   1.253 +
   1.254 +	 tagged BLEZ  .it : 
   1.255 +            if ( signedLE( rf.rd1(it.rsrc), 0 ) )
   1.256 +               next_pc = pc_plus4 + (sext(it.offset) << 2);
   1.257 +
   1.258 +	 tagged BGTZ  .it : 
   1.259 +            if ( signedGT( rf.rd1(it.rsrc), 0 ) ) 
   1.260 +               next_pc = pc_plus4 + (sext(it.offset) << 2);
   1.261 +
   1.262 +	 tagged BLTZ  .it : 
   1.263 +            if ( signedLT( rf.rd1(it.rsrc), 0 ) )
   1.264 +               next_pc = pc_plus4 + (sext(it.offset) << 2);
   1.265 +
   1.266 +	 tagged BGEZ  .it : 
   1.267 +            if ( signedGE( rf.rd1(it.rsrc), 0 ) )
   1.268 +               next_pc = pc_plus4 + (sext(it.offset) << 2);
   1.269 +
   1.270 +      tagged BEQ   .it : 
   1.271 +        if ( rf.rd1(it.rsrc1) == rf.rd2(it.rsrc2) )
   1.272 +          next_pc = pc_plus4 + (sext(it.offset) << 2);
   1.273 +
   1.274 +      tagged BNE   .it : 
   1.275 +        if ( rf.rd1(it.rsrc1) != rf.rd2(it.rsrc2) )
   1.276 +          next_pc = pc_plus4 + (sext(it.offset) << 2);
   1.277 +      
   1.278 +      // -- Jumps -----------------------------------------------------
   1.279 +      
   1.280 +      tagged J     .it : 
   1.281 +        next_pc = { pc_plus4[31:28], it.target, 2'b0 };
   1.282 +      
   1.283 +      tagged JR    .it : 
   1.284 +        next_pc = rf.rd1(it.rsrc);
   1.285 +
   1.286 +      tagged JAL   .it : 
   1.287 +       begin
   1.288 +        rf.wr( 31, pc_plus4 );
   1.289 +        next_pc = { pc_plus4[31:28], it.target, 2'b0 };
   1.290 +       end
   1.291 +
   1.292 +      tagged JALR  .it : 
   1.293 +       begin
   1.294 +        rf.wr( it.rdst, pc_plus4 );
   1.295 +        next_pc = rf.rd1(it.rsrc);
   1.296 +       end
   1.297 +
   1.298 +      // -- Cop0 ------------------------------------------------------
   1.299 +      
   1.300 +      tagged MTC0  .it : 
   1.301 +        case ( it.cop0dst )
   1.302 +          5'd10 : cp0_statsEn <= unpack(truncate(rf.rd1(it.rsrc))); 
   1.303 +          5'd21 : cp0_tohost  <= truncate(rf.rd1(it.rsrc));
   1.304 +          default : 
   1.305 +            $display( " RTL-ERROR : %m : Illegal MTC0 cop0dst register!" );
   1.306 +        endcase
   1.307 +
   1.308 +      tagged MFC0  .it : 
   1.309 +        case ( it.cop0src )
   1.310 +          5'd10 : rf.wr( it.rdst, zext(pack(cp0_statsEn)) );
   1.311 +          5'd20 : rf.wr( it.rdst, cp0_fromhost );
   1.312 +          5'd21 : rf.wr( it.rdst, cp0_tohost   );
   1.313 +          default : 
   1.314 +            $display( " RTL-ERROR : %m : Illegal MFC0 cop0src register!" );
   1.315 +        endcase
   1.316 +
   1.317 +      // -- Illegal ---------------------------------------------------
   1.318 +
   1.319 +      default : 
   1.320 +        $display( " RTL-ERROR : %m : Illegal instruction !" );
   1.321 +
   1.322 +    endcase
   1.323 +
   1.324 +    stage    <= next_stage;
   1.325 +    pc       <= next_pc;
   1.326 +
   1.327 +    if ( cp0_statsEn )
   1.328 +      num_inst.incr();
   1.329 +
   1.330 +  endrule
   1.331 +
   1.332 +  rule writeback ( stage == Writeback );
   1.333 +    traceTiny("mkProc", "writeback","W");
   1.334 +
   1.335 +    dataRespQ.deq();
   1.336 +    case ( dataRespQ.first() ) matches
   1.337 +      tagged LoadResp .ld  : rf.wr( truncate(ld.tag), ld.data );	
   1.338 +      tagged StoreResp .st : noAction;
   1.339 +    endcase
   1.340 +
   1.341 +    stage <= PCgen;
   1.342 +  endrule
   1.343 +
   1.344 +  rule inc_num_cycles;
   1.345 +    if ( cp0_statsEn )
   1.346 +      num_cycles.incr();
   1.347 +  endrule
   1.348 +
   1.349 +  rule handleCPUToHost;
   1.350 +    let req <- server_stub.acceptRequest_ReadCPUToHost();
   1.351 +    case (req)
   1.352 +     0: server_stub.sendResponse_ReadCPUToHost(cp0_tohost);
   1.353 +     1: server_stub.sendResponse_ReadCPUToHost(pc);
   1.354 +     2: server_stub.sendResponse_ReadCPUToHost(zeroExtend(pack(stage)));
   1.355 +    endcase
   1.356 +  endrule
   1.357 +
   1.358 +
   1.359 +
   1.360 +  //-----------------------------------------------------------
   1.361 +  // Methods
   1.362 +
   1.363 +  interface Client imem_client;
   1.364 +    interface Get request  = fifoToGet(instReqQ);
   1.365 +    interface Put response = fifoToPut(instRespQ);
   1.366 +  endinterface
   1.367 +
   1.368 +  interface Client dmem_client;
   1.369 +    interface Get request  = fifoToGet(dataReqQ);
   1.370 +    interface Put response = fifoToPut(dataRespQ);
   1.371 +  endinterface
   1.372 +
   1.373 +  interface Get statsEn_get      = regToGet(cp0_statsEn);
   1.374 +
   1.375 +endmodule
   1.376 +