view modules/bluespec/Pygar/core/Processor.bsv @ 31:f41eef1bebfc pygar svn.32

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