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