annotate modules/bluespec/Pygar/core/Processor.bsv~ @ 15:a1833d9f6e3d pygar svn.16

[svn r16] Recent
author punk
date Tue, 27 Apr 2010 13:11:45 -0400
parents 6d461680c6d9
children
rev   line source
punk@13 1 /// The MIT License
punk@13 2
punk@13 3 // Copyright (c) 2009 Massachusetts Institute of Technology
punk@13 4
punk@13 5 // Permission is hereby granted, free of charge, to any person obtaining a copy
punk@13 6 // of this software and associated documentation files (the "Software"), to deal
punk@13 7 // in the Software without restriction, including without limitation the rights
punk@13 8 // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
punk@13 9 // copies of the Software, and to permit persons to whom the Software is
punk@13 10 // furnished to do so, subject to the following conditions:
punk@13 11
punk@13 12 // The above copyright notice and this permission notice shall be included in
punk@13 13 // all copies or substantial portions of the Software.
punk@13 14
punk@13 15 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
punk@13 16 // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
punk@13 17 // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
punk@13 18 // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
punk@13 19 // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
punk@13 20 // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
punk@13 21 // THE SOFTWARE.
punk@13 22
punk@13 23 import Connectable::*;
punk@13 24 import GetPut::*;
punk@13 25 import ClientServer::*;
punk@13 26 import RegFile::*;
punk@13 27
punk@13 28 import FIFO::*;
punk@13 29 import FIFOF::*;
punk@13 30 import SFIFO::*;
punk@13 31 import RWire::*;
punk@13 32
punk@13 33 import Trace::*;
punk@13 34 import BFIFO::*;
punk@13 35 import MemTypes::*;
punk@13 36 import ProcTypes::*;
punk@13 37 import BRegFile::*;
punk@13 38 import BranchPred::*;
punk@13 39 //import PathTypes::*; This is only there to force the debugging
punk@13 40
punk@13 41 //AWB includes
punk@13 42 `include "asim/provides/low_level_platform_interface.bsh"
punk@13 43 `include "asim/provides/soft_connections.bsh"
punk@13 44 `include "asim/provides/common_services.bsh"
punk@13 45
punk@13 46 // Local includes
punk@13 47 //`include "asim/provides/processor_library.bsh" (included above directly)
punk@15 48 `include "asim/rrr/remote_server_stub_AUDIOCORERRR.bsh"
punk@13 49 `include "asim/provides/common_services.bsh"
punk@13 50 `include "asim/dict/STATS_PROCESSOR.bsh"
punk@13 51 `include "asim/provides/audio_pipe_types.bsh"
punk@13 52
punk@13 53 // Local includes. Look for the correspondingly named .awb files
punk@13 54 // workspace/labs/src/mit-6.375/modules/bluespec/mit-6.375/common/
punk@13 55 // to find the actual Bluespec files which are used to generate
punk@13 56 // these includes. These files are specific to this audio processing
punk@13 57 // pipeline
punk@13 58
punk@15 59 `include "asim/provides/audio_pipe_types.bsh"
punk@13 60
punk@13 61 //interface CPUToHost;
punk@13 62 // method Bit#(32) cpuToHost(int req);
punk@13 63 //endinterface
punk@13 64
punk@13 65 interface Proc;
punk@13 66
punk@13 67 // Interface from processor to caches
punk@13 68 interface Client#(DataReq,DataResp) dmem_client;
punk@13 69 interface Client#(InstReq,InstResp) imem_client;
punk@13 70
punk@13 71 // Interface for enabling/disabling statistics on the rest of the core
punk@13 72 interface Get#(Bool) statsEn_get;
punk@13 73
punk@13 74 // // Interface to host
punk@13 75 // interface CPUToHost tohost;
punk@13 76
punk@13 77 // Interface to Audio Pipeline
punk@13 78 interface AudioOut audioOut;
punk@13 79
punk@13 80 endinterface
punk@13 81
punk@13 82 //The full interface for this is as below in the common file for audioProcessorTypes.bsv
punk@13 83 interface AudioOut;
punk@13 84 interface Get#(AudioProcessorUnit) audioSampleOutput;
punk@13 85 endinterface
punk@13 86
punk@13 87 //interface AudioIn;
punk@13 88 // interface Put#(AudioProcessorUnit) audioSampleInput;
punk@13 89 //endinterface
punk@13 90
punk@13 91 typedef enum { PCgen, Exec, Writeback } Stage deriving(Eq,Bits);
punk@13 92
punk@13 93 //-----------------------------------------------------------
punk@13 94 // Register file module
punk@13 95 //-----------------------------------------------------------
punk@13 96
punk@13 97 interface BRFile;
punk@13 98 method Action wr( Rindx rindx, Bit#(32) data );
punk@13 99 method Bit#(32) rd1( Rindx rindx );
punk@13 100 method Bit#(32) rd2( Rindx rindx );
punk@13 101 endinterface
punk@13 102
punk@13 103 module mkBRFile( BRFile );
punk@13 104
punk@13 105 RegFile#(Rindx,Bit#(32)) rfile <- mkBRegFile();
punk@13 106
punk@13 107 method Action wr( Rindx rindx, Bit#(32) data );
punk@13 108 rfile.upd( rindx, data );
punk@13 109 endmethod
punk@13 110
punk@13 111 method Bit#(32) rd1( Rindx rindx );
punk@13 112 return ( rindx == 0 ) ? 0 : rfile.sub(rindx);
punk@13 113 endmethod
punk@13 114
punk@13 115 method Bit#(32) rd2( Rindx rindx );
punk@13 116 return ( rindx == 0 ) ? 0 : rfile.sub(rindx);
punk@13 117 endmethod
punk@13 118
punk@13 119 endmodule
punk@13 120
punk@13 121 //-----------------------------------------------------------
punk@13 122 // Helper functions
punk@13 123 //-----------------------------------------------------------
punk@13 124
punk@13 125 function Bit#(32) slt( Bit#(32) val1, Bit#(32) val2 );
punk@13 126 return zeroExtend( pack( signedLT(val1,val2) ) );
punk@13 127 endfunction
punk@13 128
punk@13 129 function Bit#(32) sltu( Bit#(32) val1, Bit#(32) val2 );
punk@13 130 return zeroExtend( pack( val1 < val2 ) );
punk@13 131 endfunction
punk@13 132
punk@13 133 function Bit#(32) rshft( Bit#(32) val );
punk@13 134 return zeroExtend(val[4:0]);
punk@13 135 endfunction
punk@13 136
punk@13 137
punk@13 138 //-----------------------------------------------------------
punk@13 139 // Find funct for wbQ
punk@13 140 //-----------------------------------------------------------
punk@13 141 function Bool findwbf(Rindx fVal, WBResult cmpVal);
punk@13 142 case (cmpVal) matches
punk@13 143 tagged WB_ALU {data:.res, dest:.rd} :
punk@13 144 return (fVal == rd);
punk@13 145 tagged WB_Load .rd :
punk@13 146 return (fVal == rd);
punk@13 147 tagged WB_Store .st :
punk@13 148 return False;
punk@13 149 tagged WB_Host .x :
punk@13 150 return False;
punk@13 151 endcase
punk@13 152 endfunction
punk@13 153
punk@13 154
punk@13 155 //-----------------------------------------------------------
punk@13 156 // Stall funct for wbQ
punk@13 157 //-----------------------------------------------------------
punk@13 158 function Bool stall(Instr inst, SFIFO#(WBResult, Rindx) f);
punk@13 159 case (inst) matches
punk@13 160 // -- Memory Ops ------------------------------------------------
punk@13 161 tagged LW .it :
punk@13 162 return f.find(it.rbase);
punk@13 163 tagged SW {rsrc:.dreg, rbase:.addr, offset:.o} :
punk@13 164 return (f.find(addr) || f.find2(dreg));
punk@13 165
punk@13 166 // -- Simple Ops ------------------------------------------------
punk@13 167 tagged ADDIU .it : return f.find(it.rsrc);
punk@13 168 tagged SLTI .it : return f.find(it.rsrc);
punk@13 169 tagged SLTIU .it : return f.find(it.rsrc);
punk@13 170 tagged ANDI .it : return f.find(it.rsrc);
punk@13 171 tagged ORI .it : return f.find(it.rsrc);
punk@13 172 tagged XORI .it : return f.find(it.rsrc);
punk@13 173
punk@13 174 tagged LUI .it : return f.find(it.rdst); //this rds/wrs itself
punk@13 175 tagged SLL .it : return f.find(it.rsrc);
punk@13 176 tagged SRL .it : return f.find(it.rsrc);
punk@13 177 tagged SRA .it : return f.find(it.rsrc);
punk@13 178 tagged SLLV .it : return (f.find(it.rsrc) || f.find(it.rshamt));
punk@13 179 tagged SRLV .it : return (f.find(it.rsrc) || f.find(it.rshamt));
punk@13 180 tagged SRAV .it : return (f.find(it.rsrc) || f.find(it.rshamt));
punk@13 181 tagged ADDU .it : return (f.find(it.rsrc1) || f.find2(it.rsrc2));
punk@13 182 tagged SUBU .it : return (f.find(it.rsrc1) || f.find2(it.rsrc2));
punk@13 183 tagged AND .it : return (f.find(it.rsrc1) || f.find2(it.rsrc2));
punk@13 184 tagged OR .it : return (f.find(it.rsrc1) || f.find2(it.rsrc2));
punk@13 185 tagged XOR .it : return (f.find(it.rsrc1) || f.find2(it.rsrc2));
punk@13 186 tagged NOR .it : return (f.find(it.rsrc1) || f.find2(it.rsrc2));
punk@13 187 tagged SLT .it : return (f.find(it.rsrc1) || f.find2(it.rsrc2));
punk@13 188 tagged SLTU .it : return (f.find(it.rsrc1) || f.find2(it.rsrc2));
punk@13 189
punk@13 190
punk@13 191 // -- Branches --------------------------------------------------
punk@13 192
punk@13 193 tagged BLEZ .it : return (f.find(it.rsrc));
punk@13 194 tagged BGTZ .it : return (f.find(it.rsrc));
punk@13 195 tagged BLTZ .it : return (f.find(it.rsrc));
punk@13 196 tagged BGEZ .it : return (f.find(it.rsrc));
punk@13 197 tagged BEQ .it : return (f.find(it.rsrc1) || f.find2(it.rsrc2));
punk@13 198 tagged BNE .it : return (f.find(it.rsrc1) || f.find2(it.rsrc2));
punk@13 199
punk@13 200 // -- Jumps -----------------------------------------------------
punk@13 201
punk@13 202 tagged J .it : return False;
punk@13 203 tagged JR .it : return f.find(it.rsrc);
punk@13 204 tagged JALR .it : return f.find(it.rsrc);
punk@13 205 tagged JAL .it : return False;
punk@13 206
punk@13 207 // -- Cop0 ------------------------------------------------------
punk@13 208
punk@13 209 tagged MTC0 .it : return f.find(it.rsrc);
punk@13 210 tagged MFC0 .it : return False;
punk@13 211
punk@13 212 // -- Illegal ---------------------------------------------------
punk@13 213
punk@13 214 default : return False;
punk@13 215
punk@13 216 endcase
punk@13 217 endfunction
punk@13 218 //-----------------------------------------------------------
punk@13 219 // Reference processor
punk@13 220 //-----------------------------------------------------------
punk@13 221
punk@13 222
punk@13 223 //(* doc = "synthesis attribute ram_style mkProc distributed;" *)
punk@13 224 //(* synthesize *)
punk@13 225
punk@13 226 module [CONNECTED_MODULE] mkProc( Proc );
punk@13 227
punk@13 228 //-----------------------------------------------------------
punk@13 229 // Debug port
punk@13 230
punk@15 231 ServerStub_AUDIOCORERRR server_stub <- mkServerStub_AUDIOCORERRR();
punk@13 232
punk@13 233
punk@13 234 //-----------------------------------------------------------
punk@13 235 // State
punk@13 236
punk@13 237 // Standard processor state
punk@13 238
punk@13 239 Reg#(Addr) pc <- mkReg(32'h00001000);
punk@13 240 Reg#(Epoch) epoch <- mkReg(0);
punk@13 241 Reg#(Stage) stage <- mkReg(PCgen);
punk@13 242 BRFile rf <- mkBRFile;
punk@13 243
punk@13 244 // Branch Prediction
punk@13 245 BranchPred bp <- mkBranchPred();
punk@13 246 FIFO#(PCStat) execpc <- mkLFIFO();
punk@13 247
punk@13 248 // Pipelines
punk@13 249 FIFO#(PCStat) pcQ <-mkSizedFIFO(3);
punk@13 250 SFIFO#(WBResult, Rindx) wbQ <-mkSFIFO(findwbf);
punk@13 251
punk@13 252 Reg#(Bit#(32)) cp0_tohost <- mkReg(0);
punk@13 253 Reg#(Bit#(32)) cp0_fromhost <- mkReg(0);
punk@13 254 Reg#(Bool) cp0_statsEn <- mkReg(False);
punk@13 255
punk@13 256 // Memory request/response state
punk@13 257
punk@13 258 FIFO#(InstReq) instReqQ <- mkBFIFO1();
punk@13 259 FIFO#(InstResp) instRespQ <- mkFIFO();
punk@13 260
punk@13 261 FIFO#(DataReq) dataReqQ <- mkBFIFO1();
punk@13 262 FIFO#(DataResp) dataRespQ <- mkFIFO();
punk@13 263
punk@13 264 // Audio I/O
punk@13 265 FIFO#(AudioProcessorUnit) inAudioFifo <- mkFIFO;
punk@13 266 FIFO#(AudioProcessorUnit) outAudioFifo <- mkFIFO;
punk@13 267
punk@13 268
punk@13 269 // Statistics state (2010)
punk@13 270 // Reg#(Stat) num_cycles <- mkReg(0);
punk@13 271 // Reg#(Stat) num_inst <- mkReg(0);
punk@13 272
punk@13 273 //Or:
punk@13 274 // Statistics state
punk@13 275 STAT num_cycles <- mkStatCounter(`STATS_PROCESSOR_CYCLE_COUNT);
punk@13 276 STAT num_inst <- mkStatCounter(`STATS_PROCESSOR_INST_COUNT);
punk@13 277
punk@13 278 //-----------------------------------------------------------
punk@13 279 // Rules
punk@13 280
punk@13 281 (* descending_urgency = "exec, pcgen" *)
punk@13 282 rule pcgen; //( stage == PCgen );
punk@13 283 let pc_plus4 = pc + 4;
punk@13 284
punk@13 285 traceTiny("mkProc", "pc",pc);
punk@13 286 traceTiny("mkProc", "pcgen","P");
punk@13 287 instReqQ.enq( LoadReq{ addr:pc, tag:epoch} );
punk@13 288
punk@13 289 let next_pc = bp.get(pc);
punk@13 290 if (next_pc matches tagged Valid .npc)
punk@13 291 begin
punk@13 292 pcQ.enq(PCStat {qpc:pc, qnxtpc:npc, qepoch:epoch});
punk@13 293 pc <= npc;
punk@13 294 end
punk@13 295 else
punk@13 296 begin
punk@13 297 pcQ.enq(PCStat {qpc:pc, qnxtpc:pc_plus4, qepoch:epoch});
punk@13 298 pc <= pc_plus4;
punk@13 299 end
punk@13 300
punk@13 301 endrule
punk@13 302
punk@13 303 rule discard (instRespQ.first() matches tagged LoadResp .ld
punk@13 304 &&& ld.tag != epoch);
punk@13 305 traceTiny("mkProc", "stage", "D");
punk@13 306 instRespQ.deq();
punk@13 307 endrule
punk@13 308
punk@13 309 (* conflict_free = "exec, writeback" *)
punk@13 310 rule exec (instRespQ.first() matches tagged LoadResp.ld
punk@13 311 &&& (ld.tag == epoch)
punk@13 312 &&& unpack(ld.data) matches .inst
punk@13 313 &&& !stall(inst, wbQ));
punk@13 314
punk@13 315 // Some abbreviations
punk@13 316 let sext = signExtend;
punk@13 317 let zext = zeroExtend;
punk@13 318 let sra = signedShiftRight;
punk@13 319
punk@13 320 // Get the instruction
punk@13 321
punk@13 322 instRespQ.deq();
punk@13 323 Instr inst
punk@13 324 = case ( instRespQ.first() ) matches
punk@13 325 tagged LoadResp .ld : return unpack(ld.data);
punk@13 326 tagged StoreResp .st : return ?;
punk@13 327 endcase;
punk@13 328
punk@13 329 // Get the PC info
punk@13 330 let instrpc = pcQ.first().qpc;
punk@13 331 let pc_plus4 = instrpc + 4;
punk@13 332
punk@13 333 Bool branchTaken = False;
punk@13 334 Addr newPC = pc_plus4;
punk@13 335
punk@13 336 // Tracing
punk@13 337 traceTiny("mkProc", "exec","X");
punk@13 338 traceTiny("mkProc", "exInstTiny",inst);
punk@13 339 traceFull("mkProc", "exInstFull",inst);
punk@13 340
punk@13 341 case ( inst ) matches
punk@13 342
punk@13 343 // -- Memory Ops ------------------------------------------------
punk@13 344
punk@13 345 tagged LW .it :
punk@13 346 begin
punk@13 347 Addr addr = rf.rd1(it.rbase) + sext(it.offset);
punk@13 348 dataReqQ.enq( LoadReq{ addr:addr, tag:zeroExtend(it.rdst) } );
punk@13 349 wbQ.enq(tagged WB_Load it.rdst);
punk@13 350 end
punk@13 351
punk@13 352 tagged SW .it :
punk@13 353 begin
punk@13 354 Addr addr = rf.rd1(it.rbase) + sext(it.offset);
punk@13 355 dataReqQ.enq( StoreReq{ tag:0, addr:addr, data:rf.rd2(it.rsrc) } );
punk@13 356 wbQ.enq(tagged WB_Store);
punk@13 357 end
punk@13 358
punk@13 359 // -- Simple Ops ------------------------------------------------
punk@13 360
punk@13 361 tagged ADDIU .it :
punk@13 362 begin
punk@13 363 Bit#(32) result = rf.rd1(it.rsrc) + sext(it.imm);
punk@13 364 wbQ.enq(tagged WB_ALU {data:result, dest:it.rdst});
punk@13 365 end
punk@13 366 tagged SLTI .it : wbQ.enq(tagged WB_ALU {dest:it.rdst, data:slt( rf.rd1(it.rsrc), sext(it.imm) )});
punk@13 367 tagged SLTIU .it : wbQ.enq(tagged WB_ALU {dest:it.rdst, data:sltu( rf.rd1(it.rsrc), sext(it.imm) ) });
punk@13 368 tagged ANDI .it :
punk@13 369 begin
punk@13 370 Bit#(32) zext_it_imm = zext(it.imm);
punk@13 371 wbQ.enq(tagged WB_ALU {dest:it.rdst, data:(rf.rd1(it.rsrc) & zext_it_imm)} );
punk@13 372 end
punk@13 373 tagged ORI .it :
punk@13 374 begin
punk@13 375 Bit#(32) zext_it_imm = zext(it.imm);
punk@13 376 wbQ.enq(tagged WB_ALU {dest:it.rdst, data:(rf.rd1(it.rsrc) | zext_it_imm)} );
punk@13 377 end
punk@13 378 tagged XORI .it :
punk@13 379 begin
punk@13 380 Bit#(32) zext_it_imm = zext(it.imm);
punk@13 381 wbQ.enq(tagged WB_ALU {dest: it.rdst, data:(rf.rd1(it.rsrc) ^ zext_it_imm )});
punk@13 382 end
punk@13 383 tagged LUI .it :
punk@13 384 begin
punk@13 385 Bit#(32) zext_it_imm = zext(it.imm);
punk@13 386 wbQ.enq(tagged WB_ALU {dest: it.rdst, data:(zext_it_imm << 32'd16) });
punk@13 387 end
punk@13 388
punk@13 389 tagged SLL .it :
punk@13 390 begin
punk@13 391 Bit#(32) zext_it_shamt = zext(it.shamt);
punk@13 392 wbQ.enq(tagged WB_ALU {dest: it.rdst, data:(rf.rd1(it.rsrc) << zext_it_shamt )} );
punk@13 393 end
punk@13 394 tagged SRL .it :
punk@13 395 begin
punk@13 396 Bit#(32) zext_it_shamt = zext(it.shamt);
punk@13 397 wbQ.enq(tagged WB_ALU {dest: it.rdst, data:(rf.rd1(it.rsrc) >> zext_it_shamt )});
punk@13 398 end
punk@13 399 tagged SRA .it :
punk@13 400 begin
punk@13 401 Bit#(32) zext_it_shamt = zext(it.shamt);
punk@13 402 wbQ.enq(tagged WB_ALU {dest: it.rdst, data:sra( rf.rd1(it.rsrc), zext_it_shamt )});
punk@13 403 end
punk@13 404 tagged SLLV .it : wbQ.enq(tagged WB_ALU {dest: it.rdst, data:(rf.rd1(it.rsrc) << rshft(rf.rd2(it.rshamt)) )});
punk@13 405 tagged SRLV .it : wbQ.enq(tagged WB_ALU {dest: it.rdst, data:(rf.rd1(it.rsrc) >> rshft(rf.rd2(it.rshamt)) )} );
punk@13 406 tagged SRAV .it : wbQ.enq(tagged WB_ALU {dest: it.rdst, data:sra( rf.rd1(it.rsrc), rshft(rf.rd2(it.rshamt)) ) });
punk@13 407 tagged ADDU .it : wbQ.enq(tagged WB_ALU {dest: it.rdst, data:(rf.rd1(it.rsrc1) + rf.rd2(it.rsrc2) )} );
punk@13 408 tagged SUBU .it : wbQ.enq(tagged WB_ALU {dest: it.rdst, data:(rf.rd1(it.rsrc1) - rf.rd2(it.rsrc2) )} );
punk@13 409 tagged AND .it : wbQ.enq(tagged WB_ALU {dest: it.rdst, data:(rf.rd1(it.rsrc1) & rf.rd2(it.rsrc2) )} );
punk@13 410 tagged OR .it : wbQ.enq(tagged WB_ALU {dest: it.rdst, data:(rf.rd1(it.rsrc1) | rf.rd2(it.rsrc2) )} );
punk@13 411 tagged XOR .it : wbQ.enq(tagged WB_ALU {dest: it.rdst, data:(rf.rd1(it.rsrc1) ^ rf.rd2(it.rsrc2) )} );
punk@13 412 tagged NOR .it : wbQ.enq(tagged WB_ALU {dest: it.rdst, data:(~(rf.rd1(it.rsrc1) | rf.rd2(it.rsrc2)) )} );
punk@13 413 tagged SLT .it : wbQ.enq(tagged WB_ALU {dest: it.rdst, data:slt( rf.rd1(it.rsrc1), rf.rd2(it.rsrc2) ) });
punk@13 414 tagged SLTU .it : wbQ.enq(tagged WB_ALU {dest: it.rdst, data:sltu( rf.rd1(it.rsrc1), rf.rd2(it.rsrc2) ) });
punk@13 415
punk@13 416 // -- Branches --------------------------------------------------
punk@13 417
punk@13 418 tagged BLEZ .it :
punk@13 419 if ( signedLE( rf.rd1(it.rsrc), 0 ) )
punk@13 420 begin
punk@13 421 newPC = pc_plus4 + (sext(it.offset) << 2);
punk@13 422 branchTaken = True;
punk@13 423 end
punk@13 424
punk@13 425 tagged BGTZ .it :
punk@13 426 if ( signedGT( rf.rd1(it.rsrc), 0 ) )
punk@13 427 begin
punk@13 428 newPC = pc_plus4 + (sext(it.offset) << 2);
punk@13 429 branchTaken = True;
punk@13 430 end
punk@13 431
punk@13 432 tagged BLTZ .it :
punk@13 433 if ( signedLT( rf.rd1(it.rsrc), 0 ) )
punk@13 434 begin
punk@13 435 newPC = pc_plus4 + (sext(it.offset) << 2);
punk@13 436 branchTaken = True;
punk@13 437 end
punk@13 438
punk@13 439 tagged BGEZ .it :
punk@13 440 if ( signedGE( rf.rd1(it.rsrc), 0 ) )
punk@13 441 begin
punk@13 442 newPC = pc_plus4 + (sext(it.offset) << 2);
punk@13 443 branchTaken = True;
punk@13 444 end
punk@13 445
punk@13 446 tagged BEQ .it :
punk@13 447 if ( rf.rd1(it.rsrc1) == rf.rd2(it.rsrc2) )
punk@13 448 begin
punk@13 449 newPC = pc_plus4 + (sext(it.offset) << 2);
punk@13 450 branchTaken = True;
punk@13 451 end
punk@13 452
punk@13 453 tagged BNE .it :
punk@13 454 if ( rf.rd1(it.rsrc1) != rf.rd2(it.rsrc2) )
punk@13 455 begin
punk@13 456 newPC = pc_plus4 + (sext(it.offset) << 2);
punk@13 457 branchTaken = True;
punk@13 458 end
punk@13 459
punk@13 460 // -- Jumps -----------------------------------------------------
punk@13 461
punk@13 462 tagged J .it :
punk@13 463 begin
punk@13 464 newPC = { pc_plus4[31:28], it.target, 2'b0 };
punk@13 465 branchTaken = True;
punk@13 466 end
punk@13 467
punk@13 468 tagged JR .it :
punk@13 469 begin
punk@13 470 newPC = rf.rd1(it.rsrc);
punk@13 471 branchTaken = True;
punk@13 472 end
punk@13 473
punk@13 474 tagged JAL .it :
punk@13 475 begin
punk@13 476 wbQ.enq(tagged WB_ALU {dest:31, data:pc_plus4 });
punk@13 477 newPC = { pc_plus4[31:28], it.target, 2'b0 };
punk@13 478 branchTaken = True;
punk@13 479 end
punk@13 480
punk@13 481 tagged JALR .it :
punk@13 482 begin
punk@13 483 wbQ.enq(tagged WB_ALU {dest:it.rdst, data:pc_plus4 });
punk@13 484 newPC = rf.rd1(it.rsrc);
punk@13 485 branchTaken = True;
punk@13 486 end
punk@13 487
punk@13 488 // -- Cop0 ------------------------------------------------------
punk@13 489
punk@13 490 tagged MTC0 .it :
punk@13 491 begin
punk@13 492 case ( it.cop0dst )
punk@13 493 5'd10 : cp0_statsEn <= unpack(truncate(rf.rd1(it.rsrc)));
punk@13 494 5'd21 : cp0_tohost <= truncate(rf.rd1(it.rsrc));
punk@13 495 default :
punk@13 496 $display( " RTL-ERROR : %m : Illegal MTC0 cop0dst register!" );
punk@13 497 endcase
punk@13 498 wbQ.enq(tagged WB_Host 0); //no idea wwhat this actually should be.
punk@13 499 end
punk@13 500
punk@13 501 //this is host stuff?
punk@13 502 tagged MFC0 .it :
punk@13 503 begin
punk@13 504 case ( it.cop0src )
punk@13 505 // not actually an ALU instruction but don't have the format otherwise
punk@13 506 5'd10 : wbQ.enq(tagged WB_ALU {dest:it.rdst, data:zext(pack(cp0_statsEn)) });
punk@13 507 5'd20 : wbQ.enq(tagged WB_ALU {dest:it.rdst, data:cp0_fromhost });
punk@13 508 5'd21 : wbQ.enq(tagged WB_ALU {dest:it.rdst, data:cp0_tohost });
punk@13 509 default :
punk@13 510 $display( " RTL-ERROR : %m : Illegal MFC0 cop0src register!" );
punk@13 511 endcase
punk@13 512 end
punk@13 513
punk@13 514 // -- Illegal ---------------------------------------------------
punk@13 515
punk@13 516 default :
punk@13 517 $display( " RTL-ERROR : %m : Illegal instruction !" );
punk@13 518
punk@13 519 endcase
punk@13 520
punk@13 521 //evaluate branch prediction
punk@13 522 Addr ppc = pcQ.first().qnxtpc; //predicted branch
punk@13 523 if (ppc != newPC) //prediction wrong
punk@13 524 begin
punk@13 525 epoch <= pcQ.first().qepoch + 1;
punk@13 526 bp.upd(instrpc, newPC); //update branch predictor
punk@13 527 pcQ.clear();
punk@13 528 pc <= newPC;
punk@13 529 end
punk@13 530 else
punk@13 531 pcQ.deq();
punk@13 532
punk@13 533 if ( cp0_statsEn )
punk@13 534 num_inst.incr();
punk@13 535
punk@13 536 endrule
punk@13 537
punk@13 538 rule writeback; // ( stage == Writeback );
punk@13 539 traceTiny("mkProc", "writeback","W");
punk@13 540
punk@13 541
punk@13 542 // get what to do off the writeback queue
punk@13 543 wbQ.deq();
punk@13 544 case (wbQ.first()) matches
punk@13 545 tagged WB_ALU {data:.res, dest:.rdst} : rf.wr(rdst, res);
punk@13 546 tagged WB_Load .regWr :
punk@13 547 begin
punk@13 548 dataRespQ.deq();
punk@13 549 if (dataRespQ.first() matches tagged LoadResp .ld)
punk@13 550 rf.wr(truncate(ld.tag), ld.data); // no need to use Rindx from queue? Duplicate?
punk@13 551 end
punk@13 552 tagged WB_Store : dataRespQ.deq();
punk@13 553 tagged WB_Host .dat : noAction;
punk@13 554 endcase
punk@13 555
punk@13 556 endrule
punk@13 557
punk@13 558 rule inc_num_cycles;
punk@13 559 if ( cp0_statsEn )
punk@13 560 num_cycles.incr();
punk@13 561 endrule
punk@13 562
punk@13 563 (* conservative_implicit_conditions *)
punk@13 564 rule handleCPUToHost;
punk@13 565 let req <- server_stub.acceptRequest_ReadCPUToHost();
punk@13 566 case (req)
punk@13 567 0: server_stub.sendResponse_ReadCPUToHost(cp0_tohost);
punk@13 568 1: server_stub.sendResponse_ReadCPUToHost(pc);
punk@13 569 2: server_stub.sendResponse_ReadCPUToHost(zeroExtend(pack(stage)));
punk@13 570 endcase
punk@13 571 endrule
punk@13 572
punk@13 573 // for now, we don't do anything.
punk@13 574 rule connectAudioReqResp;
punk@13 575 $display("FIR copies a data");
punk@13 576 outAudioFifo.enq(inAudioFifo.first);
punk@13 577 outAudioFifo.deq;
punk@13 578 endrule
punk@13 579
punk@13 580 // Server items & rules:
punk@13 581
punk@13 582 rule feedInput;
punk@13 583 let command <- server_stub.acceptRequest_SendUnprocessedStream();
punk@13 584 AudioProcessorControl ctrl = unpack(truncate(command.ctrl));
punk@13 585
punk@13 586 if(ctrl == EndOfFile)
punk@13 587 begin
punk@13 588 inAudioFifo.enq(tagged EndOfFile);
punk@13 589 end
punk@13 590 else
punk@13 591 begin
punk@13 592 inAudioFifo.enq(tagged Sample unpack(truncate(command.sample)));
punk@13 593 end
punk@13 594 endrule
punk@13 595
punk@13 596
punk@13 597 //-----------------------------------------------------------
punk@13 598 // Methods
punk@13 599
punk@13 600 interface Client imem_client;
punk@13 601 interface Get request = toGet(instReqQ);
punk@13 602 interface Put response = toPut(instRespQ);
punk@13 603 endinterface
punk@13 604
punk@13 605 interface Client dmem_client;
punk@13 606 interface Get request = toGet(dataReqQ);
punk@13 607 interface Put response = toPut(dataRespQ);
punk@13 608 endinterface
punk@13 609
punk@13 610 interface Get statsEn_get = toGet(asReg(cp0_statsEn));
punk@13 611
punk@13 612 // interface CPUToHost tohost;
punk@13 613 // method Bit#(32) cpuToHost(int req);
punk@13 614 // return (case (req)
punk@13 615 // 0: cp0_tohost;
punk@13 616 // 1: pc;
punk@13 617 // 2: zeroExtend(pack(stage));
punk@13 618 // endcase);
punk@13 619 // endmethod
punk@13 620 // endinterface
punk@13 621
punk@13 622 interface AudioOut audio;
punk@13 623 interface audioSampleOutput = fifoToGet(outAudioFifo);
punk@13 624 endinterface
punk@13 625
punk@13 626
punk@13 627 endmodule
punk@13 628