diff modules/bluespec/Pygar/lab4/Proc.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/Proc.bsv	Fri Apr 23 02:32:05 2010 -0400
     1.3 @@ -0,0 +1,342 @@
     1.4 +import CBusUtils::*;
     1.5 +import Register::*;
     1.6 +
     1.7 +import Trace::*;
     1.8 +import MemTypes::*;
     1.9 +import IProc::*;
    1.10 +import ProcTypes::*;
    1.11 +import FPGATypes::*;
    1.12 +import RegFile::*;
    1.13 +import FIFO::*;
    1.14 +import BFIFO::*;
    1.15 +import Assert::*;
    1.16 +
    1.17 +import GetPut::*;
    1.18 +import GetPutExt::*;
    1.19 +import ClientServer::*;
    1.20 +import CBus::*;
    1.21 +
    1.22 +
    1.23 +interface IProc;
    1.24 +
    1.25 +  // Interface for testrig
    1.26 +  interface Put#(Bit#(8)) testrig_fromhost;
    1.27 +  interface Get#(Bit#(8)) testrig_tohost;
    1.28 +
    1.29 +  // Interface from processor to caches
    1.30 +  interface Client#(DataReq,DataResp) dmem_client;
    1.31 +  interface Client#(InstReq,InstResp) imem_client;
    1.32 +
    1.33 +  // Interface for enabling/disabling statistics on the rest of the core
    1.34 +  interface Get#(Bool) statsEn_get;
    1.35 +
    1.36 +endinterface
    1.37 +
    1.38 +
    1.39 +typedef enum { PCgen, Exec, Writeback } Stage deriving(Eq,Bits);
    1.40 +
    1.41 +//-----------------------------------------------------------
    1.42 +// Register file module
    1.43 +//-----------------------------------------------------------
    1.44 +
    1.45 +interface RFile;
    1.46 +   method Action   wr( Rindx rindx, Bit#(32) data );
    1.47 +   method Bit#(32) rd1( Rindx rindx );
    1.48 +   method Bit#(32) rd2( Rindx rindx );
    1.49 +endinterface
    1.50 +
    1.51 +module mkRFile( RFile );
    1.52 +   
    1.53 +   RegFile#(Rindx,Bit#(32)) rfile <- mkRegFileFull();
    1.54 +   
    1.55 +   method Action wr( Rindx rindx, Bit#(32) data );
    1.56 +      rfile.upd( rindx, data );
    1.57 +   endmethod
    1.58 +   
    1.59 +   method Bit#(32) rd1( Rindx rindx );
    1.60 +      return ( rindx == 0 ) ? 0 : rfile.sub(rindx);
    1.61 +   endmethod
    1.62 +   
    1.63 +   method Bit#(32) rd2( Rindx rindx );
    1.64 +      return ( rindx == 0 ) ? 0 : rfile.sub(rindx);
    1.65 +   endmethod
    1.66 +
    1.67 +endmodule
    1.68 +
    1.69 +//-----------------------------------------------------------
    1.70 +// Helper functions
    1.71 +//-----------------------------------------------------------
    1.72 +
    1.73 +function Bit#(32) slt( Bit#(32) val1, Bit#(32) val2 );
    1.74 +   return zeroExtend( pack( signedLT(val1,val2) ) );
    1.75 +endfunction
    1.76 +
    1.77 +function Bit#(32) sltu( Bit#(32) val1, Bit#(32) val2 );
    1.78 +   return zeroExtend( pack( val1 < val2 ) );
    1.79 +endfunction
    1.80 +
    1.81 +function Bit#(32) rshft( Bit#(32) val );
    1.82 +   return zeroExtend(val[4:0]);
    1.83 +endfunction
    1.84 +
    1.85 +//-----------------------------------------------------------
    1.86 +// Reference processor
    1.87 +//-----------------------------------------------------------
    1.88 +
    1.89 +
    1.90 +module  [ModWithCBus#(AvalonAddressWidth,AvalonDataWidth)] mkProc( IProc );
    1.91 +
    1.92 +   //-----------------------------------------------------------
    1.93 +   // State
    1.94 +
    1.95 +   // Standard processor state
    1.96 +   
    1.97 +   Reg#(Addr)  pc    <- mkReg(32'h00001000);
    1.98 +   Reg#(Stage) stage <- mkReg(PCgen);
    1.99 +   RFile       rf    <- mkRFile;
   1.100 +
   1.101 +   // Coprocessor state
   1.102 +   
   1.103 +   Reg#(Bit#(8)) cp0_tohost   <- mkReg(0);
   1.104 +   mkCBusWideRegRW(valueof(ToHostRegAddr),cp0_tohost);
   1.105 +   Reg#(Bit#(8)) cp0_fromhost <- mkReg(0);
   1.106 +   mkCBusWideRegRW(valueof(FromHostRegAddr),cp0_fromhost);
   1.107 +   Reg#(Bool)    cp0_statsEn  <- mkReg(False);
   1.108 +   mkCBusWideRegRW(valueof(StatsEnRegAddr),cp0_statsEn);
   1.109 +   // Memory request/response state
   1.110 +   
   1.111 +   FIFO#(InstReq)  instReqQ    <- mkBFIFO1();
   1.112 +   FIFO#(InstResp) instRespQ   <- mkFIFO();
   1.113 +
   1.114 +   FIFO#(DataReq)  dataReqQ    <- mkBFIFO1();
   1.115 +   FIFO#(DataResp) dataRespQ   <- mkFIFO();
   1.116 +
   1.117 +   // Statistics state
   1.118 +
   1.119 +   Reg#(Int#(25))  num_cycles  <- mkReg(25'h0);
   1.120 +   Reg#(Int#(25))  num_inst    <- mkReg(25'h0);
   1.121 +
   1.122 +   //-----------------------------------------------------------
   1.123 +   // Rules
   1.124 +
   1.125 +   let pc_plus4 = pc + 4;
   1.126 +
   1.127 +   rule pcgen ( stage == PCgen );
   1.128 +      traceTiny("pc",pc);
   1.129 +      traceTiny("stage","P");
   1.130 +      instReqQ.enq( LoadReq{ addr:pc, tag:0 } );
   1.131 +      stage   <= Exec;
   1.132 +   endrule
   1.133 +
   1.134 +   rule exec ( stage == Exec );
   1.135 +
   1.136 +      // Some abbreviations
   1.137 +      let sext = signExtend;
   1.138 +      let zext = zeroExtend;
   1.139 +      let sra  = signedShiftRight;
   1.140 +      
   1.141 +      // Get the instruction
   1.142 +      
   1.143 +      instRespQ.deq();
   1.144 +      Instr inst 
   1.145 +      = case ( instRespQ.first() ) matches
   1.146 +	   tagged LoadResp  .ld : return unpack(ld.data);
   1.147 +	   tagged StoreResp .st : return ?;
   1.148 +	endcase;
   1.149 +
   1.150 +      // Some default variables
   1.151 +      Stage next_stage = PCgen;
   1.152 +      Addr  next_pc    = pc_plus4;
   1.153 +
   1.154 +      // Tracing
   1.155 +      traceTiny("stage","X");
   1.156 +      traceTiny("exInstTiny",inst);
   1.157 +      traceFull("exInstFull",inst);
   1.158 +
   1.159 +      case ( inst ) matches
   1.160 +
   1.161 +	 // -- Memory Ops ------------------------------------------------      
   1.162 +
   1.163 +	 tagged LW .it : 
   1.164 +	    begin
   1.165 +               Addr addr = rf.rd1(it.rbase) + sext(it.offset);
   1.166 +               dataReqQ.enq( LoadReq{ addr:addr, tag:zeroExtend(it.rdst) } );
   1.167 +               next_stage = Writeback;
   1.168 +	    end
   1.169 +
   1.170 +	 tagged SW .it : 
   1.171 +	    begin
   1.172 +               Addr addr = rf.rd1(it.rbase) + sext(it.offset);
   1.173 +               dataReqQ.enq( StoreReq{ tag:0, addr:addr, data:rf.rd1(it.rsrc) } );
   1.174 +               next_stage = Writeback;
   1.175 +	    end
   1.176 +
   1.177 +	 // -- Simple Ops ------------------------------------------------      
   1.178 +
   1.179 +	 tagged ADDIU .it : rf.wr( it.rdst, rf.rd1(it.rsrc) + sext(it.imm) );
   1.180 +	 tagged SLTI  .it : rf.wr( it.rdst, slt( rf.rd1(it.rsrc), sext(it.imm) ) );
   1.181 +	 tagged SLTIU .it : rf.wr( it.rdst, sltu( rf.rd1(it.rsrc), sext(it.imm) ) );
   1.182 +	 tagged ANDI  .it : 
   1.183 +	    begin
   1.184 +	       Bit#(32) zext_it_imm = zext(it.imm);
   1.185 +	       rf.wr( it.rdst, rf.rd1(it.rsrc) & zext_it_imm );
   1.186 +	    end
   1.187 +	 tagged ORI   .it : 
   1.188 +	    begin
   1.189 +	       Bit#(32) zext_it_imm = zext(it.imm);
   1.190 +	       rf.wr( it.rdst, rf.rd1(it.rsrc) | zext_it_imm );
   1.191 +	    end
   1.192 +	 tagged XORI  .it : 
   1.193 +	    begin
   1.194 +	       Bit#(32) zext_it_imm = zext(it.imm);
   1.195 +	       rf.wr( it.rdst, rf.rd1(it.rsrc) ^ zext_it_imm );
   1.196 +	    end
   1.197 +	 tagged LUI   .it : 
   1.198 +	    begin
   1.199 +	       Bit#(32) zext_it_imm = zext(it.imm);
   1.200 +	       rf.wr( it.rdst, (zext_it_imm << 32'd16) );
   1.201 +	    end
   1.202 +	 
   1.203 +	 tagged SLL   .it : 
   1.204 +	    begin
   1.205 +	       Bit#(32) zext_it_shamt = zext(it.shamt);
   1.206 +	       rf.wr( it.rdst, rf.rd1(it.rsrc) << zext_it_shamt );
   1.207 +	    end
   1.208 +	 tagged SRL   .it : 
   1.209 +	    begin
   1.210 +	       Bit#(32) zext_it_shamt = zext(it.shamt);
   1.211 +	       rf.wr( it.rdst, rf.rd1(it.rsrc) >> zext_it_shamt );
   1.212 +	    end
   1.213 +	 tagged SRA   .it : 
   1.214 +	    begin
   1.215 +	       Bit#(32) zext_it_shamt = zext(it.shamt);
   1.216 +	       rf.wr( it.rdst, sra( rf.rd1(it.rsrc), zext_it_shamt ));
   1.217 +	    end
   1.218 +	 tagged SLLV  .it : rf.wr( it.rdst, rf.rd1(it.rsrc) << rshft(rf.rd2(it.rshamt)) );
   1.219 +	 tagged SRLV  .it : rf.wr( it.rdst, rf.rd1(it.rsrc) >> rshft(rf.rd2(it.rshamt)) );
   1.220 +	 tagged SRAV  .it : rf.wr( it.rdst, sra( rf.rd1(it.rsrc), rshft(rf.rd2(it.rshamt)) ) );
   1.221 +	 tagged ADDU  .it : rf.wr( it.rdst, rf.rd1(it.rsrc1) + rf.rd2(it.rsrc2) );
   1.222 +	 tagged SUBU  .it : rf.wr( it.rdst, rf.rd1(it.rsrc1) - rf.rd2(it.rsrc2) );
   1.223 +	 tagged AND   .it : rf.wr( it.rdst, rf.rd1(it.rsrc1) & rf.rd2(it.rsrc2) );
   1.224 +	 tagged OR    .it : rf.wr( it.rdst, rf.rd1(it.rsrc1) | rf.rd2(it.rsrc2) );
   1.225 +	 tagged XOR   .it : rf.wr( it.rdst, rf.rd1(it.rsrc1) ^ rf.rd2(it.rsrc2) );
   1.226 +	 tagged NOR   .it : rf.wr( it.rdst, ~(rf.rd1(it.rsrc1) | rf.rd2(it.rsrc2)) );
   1.227 +	 tagged SLT   .it : rf.wr( it.rdst, slt( rf.rd1(it.rsrc1), rf.rd2(it.rsrc2) ) );
   1.228 +	 tagged SLTU  .it : rf.wr( it.rdst, sltu( rf.rd1(it.rsrc1), rf.rd2(it.rsrc2) ) );
   1.229 +
   1.230 +	 // -- Branches --------------------------------------------------
   1.231 +
   1.232 +	 tagged BLEZ  .it : 
   1.233 +            if ( signedLE( rf.rd1(it.rsrc), 0 ) )
   1.234 +               next_pc = pc_plus4 + (sext(it.offset) << 2);
   1.235 +
   1.236 +	 tagged BGTZ  .it : 
   1.237 +            if ( signedGT( rf.rd1(it.rsrc), 0 ) ) 
   1.238 +               next_pc = pc_plus4 + (sext(it.offset) << 2);
   1.239 +
   1.240 +	 tagged BLTZ  .it : 
   1.241 +            if ( signedLT( rf.rd1(it.rsrc), 0 ) )
   1.242 +               next_pc = pc_plus4 + (sext(it.offset) << 2);
   1.243 +
   1.244 +	 tagged BGEZ  .it : 
   1.245 +            if ( signedGE( rf.rd1(it.rsrc), 0 ) )
   1.246 +               next_pc = pc_plus4 + (sext(it.offset) << 2);
   1.247 +
   1.248 +      tagged BEQ   .it : 
   1.249 +        if ( rf.rd1(it.rsrc1) == rf.rd2(it.rsrc2) )
   1.250 +          next_pc = pc_plus4 + (sext(it.offset) << 2);
   1.251 +
   1.252 +      tagged BNE   .it : 
   1.253 +        if ( rf.rd1(it.rsrc1) != rf.rd2(it.rsrc2) )
   1.254 +          next_pc = pc_plus4 + (sext(it.offset) << 2);
   1.255 +      
   1.256 +      // -- Jumps -----------------------------------------------------
   1.257 +      
   1.258 +      tagged J     .it : 
   1.259 +        next_pc = { pc_plus4[31:28], it.target, 2'b0 };
   1.260 +      
   1.261 +      tagged JR    .it : 
   1.262 +        next_pc = rf.rd1(it.rsrc);
   1.263 +
   1.264 +      tagged JAL   .it : 
   1.265 +       begin
   1.266 +        rf.wr( 31, pc_plus4 );
   1.267 +        next_pc = { pc_plus4[31:28], it.target, 2'b0 };
   1.268 +       end
   1.269 +
   1.270 +      tagged JALR  .it : 
   1.271 +       begin
   1.272 +        rf.wr( it.rdst, pc_plus4 );
   1.273 +        next_pc = rf.rd1(it.rsrc);
   1.274 +       end
   1.275 +
   1.276 +      // -- Cop0 ------------------------------------------------------
   1.277 +      
   1.278 +      tagged MTC0  .it : 
   1.279 +        case ( it.cop0dst )
   1.280 +          5'd10 : cp0_statsEn <= unpack(truncate(rf.rd1(it.rsrc)));
   1.281 +          5'd21 : cp0_tohost  <= truncate(rf.rd1(it.rsrc));
   1.282 +          default : 
   1.283 +            $display( " RTL-ERROR : %m : Illegal MTC0 cop0dst register!" );
   1.284 +        endcase
   1.285 +
   1.286 +      tagged MFC0  .it : 
   1.287 +        case ( it.cop0src )
   1.288 +          5'd10 : rf.wr( it.rdst, zext(pack(cp0_statsEn)) );
   1.289 +          5'd20 : rf.wr( it.rdst, zext(cp0_fromhost) );
   1.290 +          5'd21 : rf.wr( it.rdst, zext(cp0_tohost)   );
   1.291 +          default : 
   1.292 +            $display( " RTL-ERROR : %m : Illegal MFC0 cop0src register!" );
   1.293 +        endcase
   1.294 +
   1.295 +      // -- Illegal ---------------------------------------------------
   1.296 +
   1.297 +      default : 
   1.298 +        $display( " RTL-ERROR : %m : Illegal instruction !" );
   1.299 +
   1.300 +    endcase
   1.301 +
   1.302 +    stage    <= next_stage;
   1.303 +    pc       <= next_pc;
   1.304 +
   1.305 +    if ( cp0_statsEn )
   1.306 +      num_inst <= num_inst + 1;
   1.307 +
   1.308 +  endrule
   1.309 +
   1.310 +  rule writeback ( stage == Writeback );
   1.311 +    traceTiny("stage","W");
   1.312 +
   1.313 +    dataRespQ.deq();
   1.314 +    case ( dataRespQ.first() ) matches
   1.315 +      tagged LoadResp .ld  : rf.wr( truncate(ld.tag), ld.data );	
   1.316 +      tagged StoreResp .st : noAction;
   1.317 +    endcase
   1.318 +
   1.319 +    stage <= PCgen;
   1.320 +  endrule
   1.321 +
   1.322 +  rule inc_num_cycles;
   1.323 +    if ( cp0_statsEn )
   1.324 +      num_cycles <= num_cycles + 1;
   1.325 +  endrule
   1.326 +
   1.327 +  //-----------------------------------------------------------
   1.328 +  // Methods
   1.329 +
   1.330 +  interface Client imem_client;
   1.331 +    interface Get request  = fifoToGet(instReqQ);
   1.332 +    interface Put response = fifoToPut(instRespQ);
   1.333 +  endinterface
   1.334 +
   1.335 +  interface Client dmem_client;
   1.336 +    interface Get request  = fifoToGet(dataReqQ);
   1.337 +    interface Put response = fifoToPut(dataRespQ);
   1.338 +  endinterface
   1.339 +
   1.340 +  interface Get testrig_tohost   = regToGet(cp0_tohost);
   1.341 +  interface Put testrig_fromhost = regToPut(cp0_fromhost);
   1.342 +  interface Get statsEn_get      = regToGet(cp0_statsEn);
   1.343 +
   1.344 +endmodule
   1.345 +