annotate modules/bluespec/Pygar/lab4/oProcessor.bsv @ 40:7ac38b0f93fa pygar svn.41

[svn r41] made perl build script automatically generate program.vmh
author rlm
date Tue, 04 May 2010 19:53:09 -0400
parents 74716e9a81cc
children
rev   line source
rlm@8 1 // The MIT License
rlm@8 2
rlm@8 3 // Copyright (c) 2009 Massachusetts Institute of Technology
rlm@8 4
rlm@8 5 // Permission is hereby granted, free of charge, to any person obtaining a copy
rlm@8 6 // of this software and associated documentation files (the "Software"), to deal
rlm@8 7 // in the Software without restriction, including without limitation the rights
rlm@8 8 // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
rlm@8 9 // copies of the Software, and to permit persons to whom the Software is
rlm@8 10 // furnished to do so, subject to the following conditions:
rlm@8 11
rlm@8 12 // The above copyright notice and this permission notice shall be included in
rlm@8 13 // all copies or substantial portions of the Software.
rlm@8 14
rlm@8 15 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
rlm@8 16 // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
rlm@8 17 // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
rlm@8 18 // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
rlm@8 19 // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
rlm@8 20 // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
rlm@8 21 // THE SOFTWARE.
rlm@8 22
rlm@8 23 import Connectable::*;
rlm@8 24 import GetPut::*;
rlm@8 25 import ClientServer::*;
rlm@8 26 import RegFile::*;
rlm@8 27 import FIFO::*;
rlm@8 28 import FIFOF::*;
rlm@8 29 import RWire::*;
rlm@8 30
rlm@8 31 //AWB includes
rlm@8 32 `include "asim/provides/low_level_platform_interface.bsh"
rlm@8 33 `include "asim/provides/soft_connections.bsh"
rlm@8 34 `include "asim/provides/common_services.bsh"
rlm@8 35
rlm@8 36 // Local includes
rlm@8 37 `include "asim/provides/processor_library.bsh"
rlm@8 38 `include "asim/rrr/remote_server_stub_PROCESSORSYSTEMRRR.bsh"
rlm@8 39 `include "asim/provides/common_services.bsh"
rlm@8 40 `include "asim/dict/STATS_PROCESSOR.bsh"
rlm@8 41
rlm@8 42 interface Proc;
rlm@8 43
rlm@8 44 // Interface from processor to caches
rlm@8 45 interface Client#(DataReq,DataResp) dmem_client;
rlm@8 46 interface Client#(InstReq,InstResp) imem_client;
rlm@8 47
rlm@8 48 // Interface for enabling/disabling statistics on the rest of the core
rlm@8 49 interface Get#(Bool) statsEn_get;
rlm@8 50
rlm@8 51 endinterface
rlm@8 52
rlm@8 53
rlm@8 54 typedef enum { PCgen, Exec, Writeback } Stage deriving(Eq,Bits);
rlm@8 55
rlm@8 56 //-----------------------------------------------------------
rlm@8 57 // Register file module
rlm@8 58 //-----------------------------------------------------------
rlm@8 59
rlm@8 60 interface RFile;
rlm@8 61 method Action wr( Rindx rindx, Bit#(32) data );
rlm@8 62 method Bit#(32) rd1( Rindx rindx );
rlm@8 63 method Bit#(32) rd2( Rindx rindx );
rlm@8 64 endinterface
rlm@8 65
rlm@8 66 module mkRFile( RFile );
rlm@8 67
rlm@8 68 RegFile#(Rindx,Bit#(32)) rfile <- mkRegFileFull();
rlm@8 69
rlm@8 70 method Action wr( Rindx rindx, Bit#(32) data );
rlm@8 71 rfile.upd( rindx, data );
rlm@8 72 endmethod
rlm@8 73
rlm@8 74 method Bit#(32) rd1( Rindx rindx );
rlm@8 75 return ( rindx == 0 ) ? 0 : rfile.sub(rindx);
rlm@8 76 endmethod
rlm@8 77
rlm@8 78 method Bit#(32) rd2( Rindx rindx );
rlm@8 79 return ( rindx == 0 ) ? 0 : rfile.sub(rindx);
rlm@8 80 endmethod
rlm@8 81
rlm@8 82 endmodule
rlm@8 83
rlm@8 84 //-----------------------------------------------------------
rlm@8 85 // Helper functions
rlm@8 86 //-----------------------------------------------------------
rlm@8 87
rlm@8 88 function Bit#(32) slt( Bit#(32) val1, Bit#(32) val2 );
rlm@8 89 return zeroExtend( pack( signedLT(val1,val2) ) );
rlm@8 90 endfunction
rlm@8 91
rlm@8 92 function Bit#(32) sltu( Bit#(32) val1, Bit#(32) val2 );
rlm@8 93 return zeroExtend( pack( val1 < val2 ) );
rlm@8 94 endfunction
rlm@8 95
rlm@8 96 function Bit#(32) rshft( Bit#(32) val );
rlm@8 97 return zeroExtend(val[4:0]);
rlm@8 98 endfunction
rlm@8 99
rlm@8 100 //-----------------------------------------------------------
rlm@8 101 // Reference processor
rlm@8 102 //-----------------------------------------------------------
rlm@8 103
rlm@8 104
rlm@8 105 module [CONNECTED_MODULE] mkProc( Proc );
rlm@8 106
rlm@8 107 //-----------------------------------------------------------
rlm@8 108 // Debug port
rlm@8 109
rlm@8 110 ServerStub_PROCESSORSYSTEMRRR server_stub <- mkServerStub_PROCESSORSYSTEMRRR();
rlm@8 111
rlm@8 112 //-----------------------------------------------------------
rlm@8 113 // State
rlm@8 114
rlm@8 115 // Standard processor state
rlm@8 116
rlm@8 117 Reg#(Addr) pc <- mkReg(32'h00001000);
rlm@8 118 Reg#(Stage) stage <- mkReg(PCgen);
rlm@8 119 RFile rf <- mkRFile;
rlm@8 120
rlm@8 121 // Coprocessor state - connected by way of RRR
rlm@8 122
rlm@8 123 Reg#(Bit#(32)) cp0_tohost <- mkReg(0);
rlm@8 124
rlm@8 125 Reg#(Bit#(32)) cp0_fromhost <- mkReg(0);
rlm@8 126
rlm@8 127 Reg#(Bool) cp0_statsEn <- mkReg(False);
rlm@8 128
rlm@8 129 // Memory request/response state
rlm@8 130
rlm@8 131 FIFO#(InstReq) instReqQ <- mkBFIFO1();
rlm@8 132 FIFO#(InstResp) instRespQ <- mkFIFO();
rlm@8 133
rlm@8 134 FIFO#(DataReq) dataReqQ <- mkBFIFO1();
rlm@8 135 FIFO#(DataResp) dataRespQ <- mkFIFO();
rlm@8 136
rlm@8 137 // Statistics state
rlm@8 138 STAT num_cycles <- mkStatCounter(`STATS_PROCESSOR_CYCLE_COUNT);
rlm@8 139 STAT num_inst <- mkStatCounter(`STATS_PROCESSOR_INST_COUNT);
rlm@8 140
rlm@8 141 //-----------------------------------------------------------
rlm@8 142 // Rules
rlm@8 143
rlm@8 144 let pc_plus4 = pc + 4;
rlm@8 145
rlm@8 146 rule pcgen ( stage == PCgen );
rlm@8 147 traceTiny("mkProc", "pc",pc);
rlm@8 148 traceTiny("mkProc", "pcgen","P");
rlm@8 149 instReqQ.enq( LoadReq{ addr:pc, tag:0 } );
rlm@8 150 stage <= Exec;
rlm@8 151 endrule
rlm@8 152
rlm@8 153 rule exec ( stage == Exec );
rlm@8 154
rlm@8 155 // Some abbreviations
rlm@8 156 let sext = signExtend;
rlm@8 157 let zext = zeroExtend;
rlm@8 158 let sra = signedShiftRight;
rlm@8 159
rlm@8 160 // Get the instruction
rlm@8 161
rlm@8 162 instRespQ.deq();
rlm@8 163 Instr inst
rlm@8 164 = case ( instRespQ.first() ) matches
rlm@8 165 tagged LoadResp .ld : return unpack(ld.data);
rlm@8 166 tagged StoreResp .st : return ?;
rlm@8 167 endcase;
rlm@8 168
rlm@8 169 // Some default variables
rlm@8 170 Stage next_stage = PCgen;
rlm@8 171 Addr next_pc = pc_plus4;
rlm@8 172
rlm@8 173 // Tracing
rlm@8 174 traceTiny("mkProc", "exec","X");
rlm@8 175 traceTiny("mkProc", "exInstTiny",inst);
rlm@8 176 traceFull("mkProc", "exInstFull",inst);
rlm@8 177
rlm@8 178 case ( inst ) matches
rlm@8 179
rlm@8 180 // -- Memory Ops ------------------------------------------------
rlm@8 181
rlm@8 182 tagged LW .it :
rlm@8 183 begin
rlm@8 184 Addr addr = rf.rd1(it.rbase) + sext(it.offset);
rlm@8 185 dataReqQ.enq( LoadReq{ addr:addr, tag:zeroExtend(it.rdst) } );
rlm@8 186 next_stage = Writeback;
rlm@8 187 end
rlm@8 188
rlm@8 189 tagged SW .it :
rlm@8 190 begin
rlm@8 191 Addr addr = rf.rd1(it.rbase) + sext(it.offset);
rlm@8 192 dataReqQ.enq( StoreReq{ tag:0, addr:addr, data:rf.rd1(it.rsrc) } );
rlm@8 193 next_stage = Writeback;
rlm@8 194 end
rlm@8 195
rlm@8 196 // -- Simple Ops ------------------------------------------------
rlm@8 197
rlm@8 198 tagged ADDIU .it : rf.wr( it.rdst, rf.rd1(it.rsrc) + sext(it.imm) );
rlm@8 199 tagged SLTI .it : rf.wr( it.rdst, slt( rf.rd1(it.rsrc), sext(it.imm) ) );
rlm@8 200 tagged SLTIU .it : rf.wr( it.rdst, sltu( rf.rd1(it.rsrc), sext(it.imm) ) );
rlm@8 201 tagged ANDI .it :
rlm@8 202 begin
rlm@8 203 Bit#(32) zext_it_imm = zext(it.imm);
rlm@8 204 rf.wr( it.rdst, rf.rd1(it.rsrc) & zext_it_imm );
rlm@8 205 end
rlm@8 206 tagged ORI .it :
rlm@8 207 begin
rlm@8 208 Bit#(32) zext_it_imm = zext(it.imm);
rlm@8 209 rf.wr( it.rdst, rf.rd1(it.rsrc) | zext_it_imm );
rlm@8 210 end
rlm@8 211 tagged XORI .it :
rlm@8 212 begin
rlm@8 213 Bit#(32) zext_it_imm = zext(it.imm);
rlm@8 214 rf.wr( it.rdst, rf.rd1(it.rsrc) ^ zext_it_imm );
rlm@8 215 end
rlm@8 216 tagged LUI .it :
rlm@8 217 begin
rlm@8 218 Bit#(32) zext_it_imm = zext(it.imm);
rlm@8 219 rf.wr( it.rdst, (zext_it_imm << 32'd16) );
rlm@8 220 end
rlm@8 221
rlm@8 222 tagged SLL .it :
rlm@8 223 begin
rlm@8 224 Bit#(32) zext_it_shamt = zext(it.shamt);
rlm@8 225 rf.wr( it.rdst, rf.rd1(it.rsrc) << zext_it_shamt );
rlm@8 226 end
rlm@8 227 tagged SRL .it :
rlm@8 228 begin
rlm@8 229 Bit#(32) zext_it_shamt = zext(it.shamt);
rlm@8 230 rf.wr( it.rdst, rf.rd1(it.rsrc) >> zext_it_shamt );
rlm@8 231 end
rlm@8 232 tagged SRA .it :
rlm@8 233 begin
rlm@8 234 Bit#(32) zext_it_shamt = zext(it.shamt);
rlm@8 235 rf.wr( it.rdst, sra( rf.rd1(it.rsrc), zext_it_shamt ));
rlm@8 236 end
rlm@8 237 tagged SLLV .it : rf.wr( it.rdst, rf.rd1(it.rsrc) << rshft(rf.rd2(it.rshamt)) );
rlm@8 238 tagged SRLV .it : rf.wr( it.rdst, rf.rd1(it.rsrc) >> rshft(rf.rd2(it.rshamt)) );
rlm@8 239 tagged SRAV .it : rf.wr( it.rdst, sra( rf.rd1(it.rsrc), rshft(rf.rd2(it.rshamt)) ) );
rlm@8 240 tagged ADDU .it : rf.wr( it.rdst, rf.rd1(it.rsrc1) + rf.rd2(it.rsrc2) );
rlm@8 241 tagged SUBU .it : rf.wr( it.rdst, rf.rd1(it.rsrc1) - rf.rd2(it.rsrc2) );
rlm@8 242 tagged AND .it : rf.wr( it.rdst, rf.rd1(it.rsrc1) & rf.rd2(it.rsrc2) );
rlm@8 243 tagged OR .it : rf.wr( it.rdst, rf.rd1(it.rsrc1) | rf.rd2(it.rsrc2) );
rlm@8 244 tagged XOR .it : rf.wr( it.rdst, rf.rd1(it.rsrc1) ^ rf.rd2(it.rsrc2) );
rlm@8 245 tagged NOR .it : rf.wr( it.rdst, ~(rf.rd1(it.rsrc1) | rf.rd2(it.rsrc2)) );
rlm@8 246 tagged SLT .it : rf.wr( it.rdst, slt( rf.rd1(it.rsrc1), rf.rd2(it.rsrc2) ) );
rlm@8 247 tagged SLTU .it : rf.wr( it.rdst, sltu( rf.rd1(it.rsrc1), rf.rd2(it.rsrc2) ) );
rlm@8 248
rlm@8 249 // -- Branches --------------------------------------------------
rlm@8 250
rlm@8 251 tagged BLEZ .it :
rlm@8 252 if ( signedLE( rf.rd1(it.rsrc), 0 ) )
rlm@8 253 next_pc = pc_plus4 + (sext(it.offset) << 2);
rlm@8 254
rlm@8 255 tagged BGTZ .it :
rlm@8 256 if ( signedGT( rf.rd1(it.rsrc), 0 ) )
rlm@8 257 next_pc = pc_plus4 + (sext(it.offset) << 2);
rlm@8 258
rlm@8 259 tagged BLTZ .it :
rlm@8 260 if ( signedLT( rf.rd1(it.rsrc), 0 ) )
rlm@8 261 next_pc = pc_plus4 + (sext(it.offset) << 2);
rlm@8 262
rlm@8 263 tagged BGEZ .it :
rlm@8 264 if ( signedGE( rf.rd1(it.rsrc), 0 ) )
rlm@8 265 next_pc = pc_plus4 + (sext(it.offset) << 2);
rlm@8 266
rlm@8 267 tagged BEQ .it :
rlm@8 268 if ( rf.rd1(it.rsrc1) == rf.rd2(it.rsrc2) )
rlm@8 269 next_pc = pc_plus4 + (sext(it.offset) << 2);
rlm@8 270
rlm@8 271 tagged BNE .it :
rlm@8 272 if ( rf.rd1(it.rsrc1) != rf.rd2(it.rsrc2) )
rlm@8 273 next_pc = pc_plus4 + (sext(it.offset) << 2);
rlm@8 274
rlm@8 275 // -- Jumps -----------------------------------------------------
rlm@8 276
rlm@8 277 tagged J .it :
rlm@8 278 next_pc = { pc_plus4[31:28], it.target, 2'b0 };
rlm@8 279
rlm@8 280 tagged JR .it :
rlm@8 281 next_pc = rf.rd1(it.rsrc);
rlm@8 282
rlm@8 283 tagged JAL .it :
rlm@8 284 begin
rlm@8 285 rf.wr( 31, pc_plus4 );
rlm@8 286 next_pc = { pc_plus4[31:28], it.target, 2'b0 };
rlm@8 287 end
rlm@8 288
rlm@8 289 tagged JALR .it :
rlm@8 290 begin
rlm@8 291 rf.wr( it.rdst, pc_plus4 );
rlm@8 292 next_pc = rf.rd1(it.rsrc);
rlm@8 293 end
rlm@8 294
rlm@8 295 // -- Cop0 ------------------------------------------------------
rlm@8 296
rlm@8 297 tagged MTC0 .it :
rlm@8 298 case ( it.cop0dst )
rlm@8 299 5'd10 : cp0_statsEn <= unpack(truncate(rf.rd1(it.rsrc)));
rlm@8 300 5'd21 : cp0_tohost <= truncate(rf.rd1(it.rsrc));
rlm@8 301 default :
rlm@8 302 $display( " RTL-ERROR : %m : Illegal MTC0 cop0dst register!" );
rlm@8 303 endcase
rlm@8 304
rlm@8 305 tagged MFC0 .it :
rlm@8 306 case ( it.cop0src )
rlm@8 307 5'd10 : rf.wr( it.rdst, zext(pack(cp0_statsEn)) );
rlm@8 308 5'd20 : rf.wr( it.rdst, cp0_fromhost );
rlm@8 309 5'd21 : rf.wr( it.rdst, cp0_tohost );
rlm@8 310 default :
rlm@8 311 $display( " RTL-ERROR : %m : Illegal MFC0 cop0src register!" );
rlm@8 312 endcase
rlm@8 313
rlm@8 314 // -- Illegal ---------------------------------------------------
rlm@8 315
rlm@8 316 default :
rlm@8 317 $display( " RTL-ERROR : %m : Illegal instruction !" );
rlm@8 318
rlm@8 319 endcase
rlm@8 320
rlm@8 321 stage <= next_stage;
rlm@8 322 pc <= next_pc;
rlm@8 323
rlm@8 324 if ( cp0_statsEn )
rlm@8 325 num_inst.incr();
rlm@8 326
rlm@8 327 endrule
rlm@8 328
rlm@8 329 rule writeback ( stage == Writeback );
rlm@8 330 traceTiny("mkProc", "writeback","W");
rlm@8 331
rlm@8 332 dataRespQ.deq();
rlm@8 333 case ( dataRespQ.first() ) matches
rlm@8 334 tagged LoadResp .ld : rf.wr( truncate(ld.tag), ld.data );
rlm@8 335 tagged StoreResp .st : noAction;
rlm@8 336 endcase
rlm@8 337
rlm@8 338 stage <= PCgen;
rlm@8 339 endrule
rlm@8 340
rlm@8 341 rule inc_num_cycles;
rlm@8 342 if ( cp0_statsEn )
rlm@8 343 num_cycles.incr();
rlm@8 344 endrule
rlm@8 345
rlm@8 346 rule handleCPUToHost;
rlm@8 347 let req <- server_stub.acceptRequest_ReadCPUToHost();
rlm@8 348 case (req)
rlm@8 349 0: server_stub.sendResponse_ReadCPUToHost(cp0_tohost);
rlm@8 350 1: server_stub.sendResponse_ReadCPUToHost(pc);
rlm@8 351 2: server_stub.sendResponse_ReadCPUToHost(zeroExtend(pack(stage)));
rlm@8 352 endcase
rlm@8 353 endrule
rlm@8 354
rlm@8 355
rlm@8 356
rlm@8 357 //-----------------------------------------------------------
rlm@8 358 // Methods
rlm@8 359
rlm@8 360 interface Client imem_client;
rlm@8 361 interface Get request = fifoToGet(instReqQ);
rlm@8 362 interface Put response = fifoToPut(instRespQ);
rlm@8 363 endinterface
rlm@8 364
rlm@8 365 interface Client dmem_client;
rlm@8 366 interface Get request = fifoToGet(dataReqQ);
rlm@8 367 interface Put response = fifoToPut(dataRespQ);
rlm@8 368 endinterface
rlm@8 369
rlm@8 370 interface Get statsEn_get = regToGet(cp0_statsEn);
rlm@8 371
rlm@8 372 endmodule
rlm@8 373