annotate modules/bluespec/Pygar/core/Processor.bsv @ 12:394aa40fd812 pygar svn.13

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