annotate modules/bluespec/Pygar/lab4/Proc.bsv @ 16:7e1510b47336 pygar svn.17

[svn r17] added rest of items for core
author punk
date Tue, 27 Apr 2010 22:54:50 -0400
parents 74716e9a81cc
children
rev   line source
rlm@8 1 import CBusUtils::*;
rlm@8 2 import Register::*;
rlm@8 3
rlm@8 4 import Trace::*;
rlm@8 5 import MemTypes::*;
rlm@8 6 import IProc::*;
rlm@8 7 import ProcTypes::*;
rlm@8 8 import FPGATypes::*;
rlm@8 9 import RegFile::*;
rlm@8 10 import FIFO::*;
rlm@8 11 import BFIFO::*;
rlm@8 12 import Assert::*;
rlm@8 13
rlm@8 14 import GetPut::*;
rlm@8 15 import GetPutExt::*;
rlm@8 16 import ClientServer::*;
rlm@8 17 import CBus::*;
rlm@8 18
rlm@8 19
rlm@8 20 interface IProc;
rlm@8 21
rlm@8 22 // Interface for testrig
rlm@8 23 interface Put#(Bit#(8)) testrig_fromhost;
rlm@8 24 interface Get#(Bit#(8)) testrig_tohost;
rlm@8 25
rlm@8 26 // Interface from processor to caches
rlm@8 27 interface Client#(DataReq,DataResp) dmem_client;
rlm@8 28 interface Client#(InstReq,InstResp) imem_client;
rlm@8 29
rlm@8 30 // Interface for enabling/disabling statistics on the rest of the core
rlm@8 31 interface Get#(Bool) statsEn_get;
rlm@8 32
rlm@8 33 endinterface
rlm@8 34
rlm@8 35
rlm@8 36 typedef enum { PCgen, Exec, Writeback } Stage deriving(Eq,Bits);
rlm@8 37
rlm@8 38 //-----------------------------------------------------------
rlm@8 39 // Register file module
rlm@8 40 //-----------------------------------------------------------
rlm@8 41
rlm@8 42 interface RFile;
rlm@8 43 method Action wr( Rindx rindx, Bit#(32) data );
rlm@8 44 method Bit#(32) rd1( Rindx rindx );
rlm@8 45 method Bit#(32) rd2( Rindx rindx );
rlm@8 46 endinterface
rlm@8 47
rlm@8 48 module mkRFile( RFile );
rlm@8 49
rlm@8 50 RegFile#(Rindx,Bit#(32)) rfile <- mkRegFileFull();
rlm@8 51
rlm@8 52 method Action wr( Rindx rindx, Bit#(32) data );
rlm@8 53 rfile.upd( rindx, data );
rlm@8 54 endmethod
rlm@8 55
rlm@8 56 method Bit#(32) rd1( Rindx rindx );
rlm@8 57 return ( rindx == 0 ) ? 0 : rfile.sub(rindx);
rlm@8 58 endmethod
rlm@8 59
rlm@8 60 method Bit#(32) rd2( Rindx rindx );
rlm@8 61 return ( rindx == 0 ) ? 0 : rfile.sub(rindx);
rlm@8 62 endmethod
rlm@8 63
rlm@8 64 endmodule
rlm@8 65
rlm@8 66 //-----------------------------------------------------------
rlm@8 67 // Helper functions
rlm@8 68 //-----------------------------------------------------------
rlm@8 69
rlm@8 70 function Bit#(32) slt( Bit#(32) val1, Bit#(32) val2 );
rlm@8 71 return zeroExtend( pack( signedLT(val1,val2) ) );
rlm@8 72 endfunction
rlm@8 73
rlm@8 74 function Bit#(32) sltu( Bit#(32) val1, Bit#(32) val2 );
rlm@8 75 return zeroExtend( pack( val1 < val2 ) );
rlm@8 76 endfunction
rlm@8 77
rlm@8 78 function Bit#(32) rshft( Bit#(32) val );
rlm@8 79 return zeroExtend(val[4:0]);
rlm@8 80 endfunction
rlm@8 81
rlm@8 82 //-----------------------------------------------------------
rlm@8 83 // Reference processor
rlm@8 84 //-----------------------------------------------------------
rlm@8 85
rlm@8 86
rlm@8 87 module [ModWithCBus#(AvalonAddressWidth,AvalonDataWidth)] mkProc( IProc );
rlm@8 88
rlm@8 89 //-----------------------------------------------------------
rlm@8 90 // State
rlm@8 91
rlm@8 92 // Standard processor state
rlm@8 93
rlm@8 94 Reg#(Addr) pc <- mkReg(32'h00001000);
rlm@8 95 Reg#(Stage) stage <- mkReg(PCgen);
rlm@8 96 RFile rf <- mkRFile;
rlm@8 97
rlm@8 98 // Coprocessor state
rlm@8 99
rlm@8 100 Reg#(Bit#(8)) cp0_tohost <- mkReg(0);
rlm@8 101 mkCBusWideRegRW(valueof(ToHostRegAddr),cp0_tohost);
rlm@8 102 Reg#(Bit#(8)) cp0_fromhost <- mkReg(0);
rlm@8 103 mkCBusWideRegRW(valueof(FromHostRegAddr),cp0_fromhost);
rlm@8 104 Reg#(Bool) cp0_statsEn <- mkReg(False);
rlm@8 105 mkCBusWideRegRW(valueof(StatsEnRegAddr),cp0_statsEn);
rlm@8 106 // Memory request/response state
rlm@8 107
rlm@8 108 FIFO#(InstReq) instReqQ <- mkBFIFO1();
rlm@8 109 FIFO#(InstResp) instRespQ <- mkFIFO();
rlm@8 110
rlm@8 111 FIFO#(DataReq) dataReqQ <- mkBFIFO1();
rlm@8 112 FIFO#(DataResp) dataRespQ <- mkFIFO();
rlm@8 113
rlm@8 114 // Statistics state
rlm@8 115
rlm@8 116 Reg#(Int#(25)) num_cycles <- mkReg(25'h0);
rlm@8 117 Reg#(Int#(25)) num_inst <- mkReg(25'h0);
rlm@8 118
rlm@8 119 //-----------------------------------------------------------
rlm@8 120 // Rules
rlm@8 121
rlm@8 122 let pc_plus4 = pc + 4;
rlm@8 123
rlm@8 124 rule pcgen ( stage == PCgen );
rlm@8 125 traceTiny("pc",pc);
rlm@8 126 traceTiny("stage","P");
rlm@8 127 instReqQ.enq( LoadReq{ addr:pc, tag:0 } );
rlm@8 128 stage <= Exec;
rlm@8 129 endrule
rlm@8 130
rlm@8 131 rule exec ( stage == Exec );
rlm@8 132
rlm@8 133 // Some abbreviations
rlm@8 134 let sext = signExtend;
rlm@8 135 let zext = zeroExtend;
rlm@8 136 let sra = signedShiftRight;
rlm@8 137
rlm@8 138 // Get the instruction
rlm@8 139
rlm@8 140 instRespQ.deq();
rlm@8 141 Instr inst
rlm@8 142 = case ( instRespQ.first() ) matches
rlm@8 143 tagged LoadResp .ld : return unpack(ld.data);
rlm@8 144 tagged StoreResp .st : return ?;
rlm@8 145 endcase;
rlm@8 146
rlm@8 147 // Some default variables
rlm@8 148 Stage next_stage = PCgen;
rlm@8 149 Addr next_pc = pc_plus4;
rlm@8 150
rlm@8 151 // Tracing
rlm@8 152 traceTiny("stage","X");
rlm@8 153 traceTiny("exInstTiny",inst);
rlm@8 154 traceFull("exInstFull",inst);
rlm@8 155
rlm@8 156 case ( inst ) matches
rlm@8 157
rlm@8 158 // -- Memory Ops ------------------------------------------------
rlm@8 159
rlm@8 160 tagged LW .it :
rlm@8 161 begin
rlm@8 162 Addr addr = rf.rd1(it.rbase) + sext(it.offset);
rlm@8 163 dataReqQ.enq( LoadReq{ addr:addr, tag:zeroExtend(it.rdst) } );
rlm@8 164 next_stage = Writeback;
rlm@8 165 end
rlm@8 166
rlm@8 167 tagged SW .it :
rlm@8 168 begin
rlm@8 169 Addr addr = rf.rd1(it.rbase) + sext(it.offset);
rlm@8 170 dataReqQ.enq( StoreReq{ tag:0, addr:addr, data:rf.rd1(it.rsrc) } );
rlm@8 171 next_stage = Writeback;
rlm@8 172 end
rlm@8 173
rlm@8 174 // -- Simple Ops ------------------------------------------------
rlm@8 175
rlm@8 176 tagged ADDIU .it : rf.wr( it.rdst, rf.rd1(it.rsrc) + sext(it.imm) );
rlm@8 177 tagged SLTI .it : rf.wr( it.rdst, slt( rf.rd1(it.rsrc), sext(it.imm) ) );
rlm@8 178 tagged SLTIU .it : rf.wr( it.rdst, sltu( rf.rd1(it.rsrc), sext(it.imm) ) );
rlm@8 179 tagged ANDI .it :
rlm@8 180 begin
rlm@8 181 Bit#(32) zext_it_imm = zext(it.imm);
rlm@8 182 rf.wr( it.rdst, rf.rd1(it.rsrc) & zext_it_imm );
rlm@8 183 end
rlm@8 184 tagged ORI .it :
rlm@8 185 begin
rlm@8 186 Bit#(32) zext_it_imm = zext(it.imm);
rlm@8 187 rf.wr( it.rdst, rf.rd1(it.rsrc) | zext_it_imm );
rlm@8 188 end
rlm@8 189 tagged XORI .it :
rlm@8 190 begin
rlm@8 191 Bit#(32) zext_it_imm = zext(it.imm);
rlm@8 192 rf.wr( it.rdst, rf.rd1(it.rsrc) ^ zext_it_imm );
rlm@8 193 end
rlm@8 194 tagged LUI .it :
rlm@8 195 begin
rlm@8 196 Bit#(32) zext_it_imm = zext(it.imm);
rlm@8 197 rf.wr( it.rdst, (zext_it_imm << 32'd16) );
rlm@8 198 end
rlm@8 199
rlm@8 200 tagged SLL .it :
rlm@8 201 begin
rlm@8 202 Bit#(32) zext_it_shamt = zext(it.shamt);
rlm@8 203 rf.wr( it.rdst, rf.rd1(it.rsrc) << zext_it_shamt );
rlm@8 204 end
rlm@8 205 tagged SRL .it :
rlm@8 206 begin
rlm@8 207 Bit#(32) zext_it_shamt = zext(it.shamt);
rlm@8 208 rf.wr( it.rdst, rf.rd1(it.rsrc) >> zext_it_shamt );
rlm@8 209 end
rlm@8 210 tagged SRA .it :
rlm@8 211 begin
rlm@8 212 Bit#(32) zext_it_shamt = zext(it.shamt);
rlm@8 213 rf.wr( it.rdst, sra( rf.rd1(it.rsrc), zext_it_shamt ));
rlm@8 214 end
rlm@8 215 tagged SLLV .it : rf.wr( it.rdst, rf.rd1(it.rsrc) << rshft(rf.rd2(it.rshamt)) );
rlm@8 216 tagged SRLV .it : rf.wr( it.rdst, rf.rd1(it.rsrc) >> rshft(rf.rd2(it.rshamt)) );
rlm@8 217 tagged SRAV .it : rf.wr( it.rdst, sra( rf.rd1(it.rsrc), rshft(rf.rd2(it.rshamt)) ) );
rlm@8 218 tagged ADDU .it : rf.wr( it.rdst, rf.rd1(it.rsrc1) + rf.rd2(it.rsrc2) );
rlm@8 219 tagged SUBU .it : rf.wr( it.rdst, rf.rd1(it.rsrc1) - rf.rd2(it.rsrc2) );
rlm@8 220 tagged AND .it : rf.wr( it.rdst, rf.rd1(it.rsrc1) & rf.rd2(it.rsrc2) );
rlm@8 221 tagged OR .it : rf.wr( it.rdst, rf.rd1(it.rsrc1) | rf.rd2(it.rsrc2) );
rlm@8 222 tagged XOR .it : rf.wr( it.rdst, rf.rd1(it.rsrc1) ^ rf.rd2(it.rsrc2) );
rlm@8 223 tagged NOR .it : rf.wr( it.rdst, ~(rf.rd1(it.rsrc1) | rf.rd2(it.rsrc2)) );
rlm@8 224 tagged SLT .it : rf.wr( it.rdst, slt( rf.rd1(it.rsrc1), rf.rd2(it.rsrc2) ) );
rlm@8 225 tagged SLTU .it : rf.wr( it.rdst, sltu( rf.rd1(it.rsrc1), rf.rd2(it.rsrc2) ) );
rlm@8 226
rlm@8 227 // -- Branches --------------------------------------------------
rlm@8 228
rlm@8 229 tagged BLEZ .it :
rlm@8 230 if ( signedLE( rf.rd1(it.rsrc), 0 ) )
rlm@8 231 next_pc = pc_plus4 + (sext(it.offset) << 2);
rlm@8 232
rlm@8 233 tagged BGTZ .it :
rlm@8 234 if ( signedGT( rf.rd1(it.rsrc), 0 ) )
rlm@8 235 next_pc = pc_plus4 + (sext(it.offset) << 2);
rlm@8 236
rlm@8 237 tagged BLTZ .it :
rlm@8 238 if ( signedLT( rf.rd1(it.rsrc), 0 ) )
rlm@8 239 next_pc = pc_plus4 + (sext(it.offset) << 2);
rlm@8 240
rlm@8 241 tagged BGEZ .it :
rlm@8 242 if ( signedGE( rf.rd1(it.rsrc), 0 ) )
rlm@8 243 next_pc = pc_plus4 + (sext(it.offset) << 2);
rlm@8 244
rlm@8 245 tagged BEQ .it :
rlm@8 246 if ( rf.rd1(it.rsrc1) == rf.rd2(it.rsrc2) )
rlm@8 247 next_pc = pc_plus4 + (sext(it.offset) << 2);
rlm@8 248
rlm@8 249 tagged BNE .it :
rlm@8 250 if ( rf.rd1(it.rsrc1) != rf.rd2(it.rsrc2) )
rlm@8 251 next_pc = pc_plus4 + (sext(it.offset) << 2);
rlm@8 252
rlm@8 253 // -- Jumps -----------------------------------------------------
rlm@8 254
rlm@8 255 tagged J .it :
rlm@8 256 next_pc = { pc_plus4[31:28], it.target, 2'b0 };
rlm@8 257
rlm@8 258 tagged JR .it :
rlm@8 259 next_pc = rf.rd1(it.rsrc);
rlm@8 260
rlm@8 261 tagged JAL .it :
rlm@8 262 begin
rlm@8 263 rf.wr( 31, pc_plus4 );
rlm@8 264 next_pc = { pc_plus4[31:28], it.target, 2'b0 };
rlm@8 265 end
rlm@8 266
rlm@8 267 tagged JALR .it :
rlm@8 268 begin
rlm@8 269 rf.wr( it.rdst, pc_plus4 );
rlm@8 270 next_pc = rf.rd1(it.rsrc);
rlm@8 271 end
rlm@8 272
rlm@8 273 // -- Cop0 ------------------------------------------------------
rlm@8 274
rlm@8 275 tagged MTC0 .it :
rlm@8 276 case ( it.cop0dst )
rlm@8 277 5'd10 : cp0_statsEn <= unpack(truncate(rf.rd1(it.rsrc)));
rlm@8 278 5'd21 : cp0_tohost <= truncate(rf.rd1(it.rsrc));
rlm@8 279 default :
rlm@8 280 $display( " RTL-ERROR : %m : Illegal MTC0 cop0dst register!" );
rlm@8 281 endcase
rlm@8 282
rlm@8 283 tagged MFC0 .it :
rlm@8 284 case ( it.cop0src )
rlm@8 285 5'd10 : rf.wr( it.rdst, zext(pack(cp0_statsEn)) );
rlm@8 286 5'd20 : rf.wr( it.rdst, zext(cp0_fromhost) );
rlm@8 287 5'd21 : rf.wr( it.rdst, zext(cp0_tohost) );
rlm@8 288 default :
rlm@8 289 $display( " RTL-ERROR : %m : Illegal MFC0 cop0src register!" );
rlm@8 290 endcase
rlm@8 291
rlm@8 292 // -- Illegal ---------------------------------------------------
rlm@8 293
rlm@8 294 default :
rlm@8 295 $display( " RTL-ERROR : %m : Illegal instruction !" );
rlm@8 296
rlm@8 297 endcase
rlm@8 298
rlm@8 299 stage <= next_stage;
rlm@8 300 pc <= next_pc;
rlm@8 301
rlm@8 302 if ( cp0_statsEn )
rlm@8 303 num_inst <= num_inst + 1;
rlm@8 304
rlm@8 305 endrule
rlm@8 306
rlm@8 307 rule writeback ( stage == Writeback );
rlm@8 308 traceTiny("stage","W");
rlm@8 309
rlm@8 310 dataRespQ.deq();
rlm@8 311 case ( dataRespQ.first() ) matches
rlm@8 312 tagged LoadResp .ld : rf.wr( truncate(ld.tag), ld.data );
rlm@8 313 tagged StoreResp .st : noAction;
rlm@8 314 endcase
rlm@8 315
rlm@8 316 stage <= PCgen;
rlm@8 317 endrule
rlm@8 318
rlm@8 319 rule inc_num_cycles;
rlm@8 320 if ( cp0_statsEn )
rlm@8 321 num_cycles <= num_cycles + 1;
rlm@8 322 endrule
rlm@8 323
rlm@8 324 //-----------------------------------------------------------
rlm@8 325 // Methods
rlm@8 326
rlm@8 327 interface Client imem_client;
rlm@8 328 interface Get request = fifoToGet(instReqQ);
rlm@8 329 interface Put response = fifoToPut(instRespQ);
rlm@8 330 endinterface
rlm@8 331
rlm@8 332 interface Client dmem_client;
rlm@8 333 interface Get request = fifoToGet(dataReqQ);
rlm@8 334 interface Put response = fifoToPut(dataRespQ);
rlm@8 335 endinterface
rlm@8 336
rlm@8 337 interface Get testrig_tohost = regToGet(cp0_tohost);
rlm@8 338 interface Put testrig_fromhost = regToPut(cp0_fromhost);
rlm@8 339 interface Get statsEn_get = regToGet(cp0_statsEn);
rlm@8 340
rlm@8 341 endmodule
rlm@8 342