Mercurial > pygar
comparison modules/bluespec/Pygar/core/Processor.bsv @ 68:44cc00df1168 pygar svn.69
[svn r69] runs separate eofs (I think)
author | punk |
---|---|
date | Wed, 12 May 2010 00:06:05 -0400 |
parents | cf8bb3038cbd |
children |
comparison
equal
deleted
inserted
replaced
67:0ede0715dbd6 | 68:44cc00df1168 |
---|---|
35 import BFIFO::*; | 35 import BFIFO::*; |
36 import MemTypes::*; | 36 import MemTypes::*; |
37 import ProcTypes::*; | 37 import ProcTypes::*; |
38 import BRegFile::*; | 38 import BRegFile::*; |
39 import BranchPred::*; | 39 import BranchPred::*; |
40 //import PathTypes::*; This is only there to force the debugging | |
41 | 40 |
42 //AWB includes | 41 //AWB includes |
43 `include "asim/provides/low_level_platform_interface.bsh" | 42 `include "asim/provides/low_level_platform_interface.bsh" |
44 `include "asim/provides/soft_connections.bsh" | 43 `include "asim/provides/soft_connections.bsh" |
45 `include "asim/provides/common_services.bsh" | 44 `include "asim/provides/common_services.bsh" |
55 // to find the actual Bluespec files which are used to generate | 54 // to find the actual Bluespec files which are used to generate |
56 // these includes. These files are specific to this audio processing | 55 // these includes. These files are specific to this audio processing |
57 // pipeline | 56 // pipeline |
58 | 57 |
59 `include "asim/provides/audio_pipe_types.bsh" | 58 `include "asim/provides/audio_pipe_types.bsh" |
59 `include "asim/provides/path_types.bsh" | |
60 | 60 |
61 //interface CPUToHost; | 61 //interface CPUToHost; |
62 // method Bit#(32) cpuToHost(int req); | 62 // method Bit#(32) cpuToHost(int req); |
63 //endinterface | 63 //endinterface |
64 | 64 |
69 interface Client#(InstReq,InstResp) imem_client; | 69 interface Client#(InstReq,InstResp) imem_client; |
70 | 70 |
71 // Interface for enabling/disabling statistics on the rest of the core | 71 // Interface for enabling/disabling statistics on the rest of the core |
72 interface Get#(Bool) statsEn_get; | 72 interface Get#(Bool) statsEn_get; |
73 | 73 |
74 // // Interface to host | 74 // Interface to host |
75 // interface CPUToHost tohost; | 75 interface Get#(Bit#(32)) pcCount; |
76 | 76 |
77 // Interface to Audio Pipeline | 77 // Interface to Audio Pipeline |
78 interface Get#(AudioProcessorUnit) sampleOutput; | 78 interface Get#(AudioStream) sampleOutput; |
79 interface Put#(AudioProcessorUnit) sampleInput; | 79 interface Put#(AudioStream) sampleInput; |
80 | 80 |
81 endinterface | 81 endinterface |
82 | 82 |
83 typedef enum { PCgen, Exec, Writeback } Stage deriving(Eq,Bits); | 83 typedef enum { PCgen, Exec, Writeback } Stage deriving(Eq,Bits); |
84 | 84 |
177 | 177 |
178 default : return False; | 178 default : return False; |
179 | 179 |
180 endcase | 180 endcase |
181 endfunction | 181 endfunction |
182 | |
183 | |
182 //----------------------------------------------------------- | 184 //----------------------------------------------------------- |
183 // Reference processor | 185 // Reference processor |
184 //----------------------------------------------------------- | 186 //----------------------------------------------------------- |
185 | 187 |
186 | 188 |
211 Reg#(Bit#(32)) cp0_tohost <- mkReg(0); | 213 Reg#(Bit#(32)) cp0_tohost <- mkReg(0); |
212 Reg#(Bit#(32)) cp0_fromhost <- mkReg(0); | 214 Reg#(Bit#(32)) cp0_fromhost <- mkReg(0); |
213 Reg#(Bool) cp0_statsEn <- mkReg(False); | 215 Reg#(Bool) cp0_statsEn <- mkReg(False); |
214 Reg#(Bool) cp0_audioEOF <- mkReg(False); // Register to let code that EOF is reached | 216 Reg#(Bool) cp0_audioEOF <- mkReg(False); // Register to let code that EOF is reached |
215 Reg#(Bool) cp0_progComp <- mkReg(False); // Register to let processor know that the program is complete (as this terminates) | 217 Reg#(Bool) cp0_progComp <- mkReg(False); // Register to let processor know that the program is complete (as this terminates) |
218 | |
219 Reg#(Bool) code_bypass <- mkReg(True); // Register to enable passing invalid packets once all valid ones are passed OUT | |
220 // (this becomes false at first valid packet) | |
216 | 221 |
217 // Memory request/response state | 222 // Memory request/response state |
218 | 223 |
219 FIFO#(InstReq) instReqQ <- mkBFIFO1(); | 224 FIFO#(InstReq) instReqQ <- mkBFIFO1(); |
220 FIFO#(InstResp) instRespQ <- mkFIFO(); | 225 FIFO#(InstResp) instRespQ <- mkFIFO(); |
221 | 226 |
222 FIFO#(DataReq) dataReqQ <- mkBFIFO1(); | 227 FIFO#(DataReq) dataReqQ <- mkBFIFO1(); |
223 FIFO#(DataResp) dataRespQ <- mkFIFO(); | 228 FIFO#(DataResp) dataRespQ <- mkFIFO(); |
224 | 229 |
225 // Audio I/O | 230 // Audio I/O |
226 FIFO#(AudioProcessorUnit) inAudioFifo <- mkSizedFIFO(512); | 231 FIFO#(AudioStream) inAudioFifo <- mkSizedFIFO(512); |
227 FIFO#(AudioProcessorUnit) outAudioFifo <- mkFIFO; | 232 FIFO#(AudioStream) outAudioFifo <- mkFIFO; |
228 | 233 Reg#(VoiceId) channel <-mkReg(0); // Set based on the reading the incoming data. Not entirely sure I like this. What if the program generates samples? |
229 | 234 |
230 // Statistics state (2010) | 235 // Statistics state (2010) |
231 // Reg#(Stat) num_cycles <- mkReg(0); | 236 // Reg#(Stat) num_cycles <- mkReg(0); |
232 // Reg#(Stat) num_inst <- mkReg(0); | 237 // Reg#(Stat) num_inst <- mkReg(0); |
233 | 238 |
236 | 241 |
237 //rlm: removing these to avoid their broken stupidness. | 242 //rlm: removing these to avoid their broken stupidness. |
238 //STAT num_cycles <- mkStatCounter(`STATS_PROCESSOR_CYCLE_COUNT); | 243 //STAT num_cycles <- mkStatCounter(`STATS_PROCESSOR_CYCLE_COUNT); |
239 //STAT num_inst <- mkStatCounter(`STATS_PROCESSOR_INST_COUNT); | 244 //STAT num_inst <- mkStatCounter(`STATS_PROCESSOR_INST_COUNT); |
240 | 245 |
246 //----------------------------------------------------------- | |
247 // Internal Functions | |
248 | |
249 function Bool stallMTCO_MFCO(Instr inst); | |
250 case(inst) matches | |
251 tagged MTC0 .it : | |
252 begin | |
253 case (it.cop0dst) | |
254 5'd26 : return cp0_progComp; // If true, processor service sendEnd which clears it. | |
255 endcase | |
256 end | |
257 endcase | |
258 endfunction | |
259 | |
241 //----------------------------------------------------------- | 260 //----------------------------------------------------------- |
242 // Rules | 261 // Rules |
243 | 262 |
244 (* descending_urgency = "exec, pcgen" *) | 263 (* descending_urgency = "exec, pcgen" *) |
245 rule pcgen; //( stage == PCgen ); | 264 rule pcgen; //( stage == PCgen ); |
271 | 290 |
272 (* conflict_free = "exec, writeback" *) | 291 (* conflict_free = "exec, writeback" *) |
273 rule exec (instRespQ.first() matches tagged LoadResp.ld | 292 rule exec (instRespQ.first() matches tagged LoadResp.ld |
274 &&& (ld.tag == epoch) | 293 &&& (ld.tag == epoch) |
275 &&& unpack(ld.data) matches .inst | 294 &&& unpack(ld.data) matches .inst |
276 &&& !stall(inst, wbQ)); | 295 &&& !stall(inst, wbQ) |
296 &&& !stallMTCO_MFCO(inst)); | |
277 | 297 |
278 // Some abbreviations | 298 // Some abbreviations |
279 let sext = signExtend; | 299 let sext = signExtend; |
280 let zext = zeroExtend; | 300 let zext = zeroExtend; |
281 let sra = signedShiftRight; | 301 let sra = signedShiftRight; |
299 // Tracing | 319 // Tracing |
300 traceTiny("mkProc", "exec","X"); | 320 traceTiny("mkProc", "exec","X"); |
301 traceTiny("mkProc", "exInstTiny",inst); | 321 traceTiny("mkProc", "exInstTiny",inst); |
302 traceFull("mkProc", "exInstFull",inst); | 322 traceFull("mkProc", "exInstFull",inst); |
303 | 323 |
324 // $display("PROCESSOR: Exec Fires"); | |
304 case ( inst ) matches | 325 case ( inst ) matches |
305 | 326 |
306 // -- Memory Ops ------------------------------------------------ | 327 // -- Memory Ops ------------------------------------------------ |
307 | 328 |
308 tagged LW .it : | 329 tagged LW .it : |
551 // $display( " PROCESSOR MTC0 call\n"); | 572 // $display( " PROCESSOR MTC0 call\n"); |
552 case ( it.cop0dst ) | 573 case ( it.cop0dst ) |
553 5'd10 : cp0_statsEn <= unpack(truncate(val_rsrc1)); | 574 5'd10 : cp0_statsEn <= unpack(truncate(val_rsrc1)); |
554 5'd21 : cp0_tohost <= truncate(val_rsrc1); | 575 5'd21 : cp0_tohost <= truncate(val_rsrc1); |
555 5'd26 : cp0_progComp <= unpack(truncate(val_rsrc1)); //states audio program completed and termination okay | 576 5'd26 : cp0_progComp <= unpack(truncate(val_rsrc1)); //states audio program completed and termination okay |
556 5'd27 : outAudioFifo.enq(tagged Sample unpack(truncate(val_rsrc1))); //Bit size is 16 not 32 | 577 5'd27 : outAudioFifo.enq(AudioStream {voice: channel, data: tagged Valid |
578 tagged Sample unpack(truncate(val_rsrc1)) }); //Bit size is 16 not 32 | |
557 default : | 579 default : |
558 $display( " RTL-ERROR : %m : Illegal MTC0 cop0dst register!" ); | 580 $display( " RTL-ERROR : %m : Illegal MTC0 cop0dst register!" ); |
559 endcase | 581 endcase |
560 wbQ.enq(tagged WB_Host 0); //no idea wwhat this actually should be. | 582 wbQ.enq(tagged WB_Host 0); //no idea wwhat this actually should be. |
561 end | 583 end |
567 // not actually an ALU instruction but don't have the format otherwise | 589 // not actually an ALU instruction but don't have the format otherwise |
568 5'd10 : wbQ.enq(tagged WB_ALU {dest:it.rdst, data:zext(pack(cp0_statsEn)) }); | 590 5'd10 : wbQ.enq(tagged WB_ALU {dest:it.rdst, data:zext(pack(cp0_statsEn)) }); |
569 5'd20 : wbQ.enq(tagged WB_ALU {dest:it.rdst, data:cp0_fromhost }); | 591 5'd20 : wbQ.enq(tagged WB_ALU {dest:it.rdst, data:cp0_fromhost }); |
570 5'd21 : wbQ.enq(tagged WB_ALU {dest:it.rdst, data:cp0_tohost }); | 592 5'd21 : wbQ.enq(tagged WB_ALU {dest:it.rdst, data:cp0_tohost }); |
571 5'd25 : begin | 593 5'd25 : begin |
572 // $display( "**** EOF Requested"); | 594 // $display( "**** EOF Requested\n "); //Should never run if inAudioFifo.first not valid |
573 let sample = inAudioFifo.first(); | 595 let stream = inAudioFifo.first(); |
574 case (sample) matches | 596 if (stream.data matches tagged Valid .sample) |
575 tagged EndOfFile : | 597 begin |
576 begin | 598 case (sample) matches |
577 $display("PROCESSOR sent toC EOF"); | 599 tagged EndOfFile : |
578 wbQ.enq(tagged WB_ALU {dest:it.rdst, data:zext(pack(True)) }); // Reading clears bit | 600 begin |
579 inAudioFifo.deq; | 601 $display("PROCESSOR sent toC EOF"); |
580 end | 602 wbQ.enq(tagged WB_ALU {dest:it.rdst, data:zext(pack(True)) }); // Reading clears bit |
581 tagged Sample .data: | 603 inAudioFifo.deq; |
582 wbQ.enq(tagged WB_ALU {dest:it.rdst, data:zext(pack(False)) }); // Reading clears bit | 604 end |
583 endcase | 605 tagged Sample .audio: |
606 wbQ.enq(tagged WB_ALU {dest:it.rdst, data:zext(pack(False)) }); // Reading clears bit | |
607 endcase | |
608 code_bypass <= False; | |
609 end | |
610 else $display("PROCESSOR code trying to read Invalid Audio Stream"); | |
584 end | 611 end |
585 5'd28 : begin | 612 5'd28 : begin |
586 $display( "***** Reqesting Sample"); | 613 $display( "***** Reqesting Sample"); |
587 let sample = inAudioFifo.first(); // is this going to cause perf. delay? | 614 let stream = inAudioFifo.first(); // is this going to cause perf. delay? |
588 if (sample matches tagged Sample .audio) // if it is EOF another rule sets the cp0_audioEOF | 615 if (stream.data matches tagged Valid .sample) |
589 wbQ.enq(tagged WB_ALU {dest:it.rdst, data:zext(pack(audio)) }); // do I need pack? | 616 begin |
590 else $display ( "Audio File EOF Reached. Invalid sample request."); | 617 if (sample matches tagged Sample .audio) // if it is EOF another rule sets the cp0_audioEOF |
591 inAudioFifo.deq(); | 618 wbQ.enq(tagged WB_ALU {dest:it.rdst, data:zext(pack(audio)) }); // do I need pack? |
619 else $display ( "Audio File EOF Reached. Invalid sample request."); | |
620 inAudioFifo.deq(); | |
621 end | |
622 else $display("PROCESSOR code trying to read Invalid Audio Stream"); | |
592 end | 623 end |
593 default : | 624 default : |
594 $display( " RTL-ERROR : %m : Illegal MFC0 cop0src register!" ); | 625 $display( " RTL-ERROR : %m : Illegal MFC0 cop0src register!" ); |
595 endcase | 626 endcase |
596 end | 627 end |
643 // rule inc_num_cycles; | 674 // rule inc_num_cycles; |
644 // if ( cp0_statsEn ) | 675 // if ( cp0_statsEn ) |
645 // num_cycles.incr(); | 676 // num_cycles.incr(); |
646 // endrule | 677 // endrule |
647 | 678 |
648 /* | 679 rule bypass (code_bypass &&& |
649 // for now, we don't do anything. | 680 !cp0_progComp &&& //never fires at the same time as sendEnd where it is enabled |
650 rule connectAudioReqResp; | 681 inAudioFifo.first().data matches tagged Invalid) ; |
651 $display("rlm: PROCESSOR copies a datum\n"); | |
652 outAudioFifo.enq(inAudioFifo.first()); | 682 outAudioFifo.enq(inAudioFifo.first()); |
653 inAudioFifo.deq; | 683 inAudioFifo.deq; |
654 endrule | 684 endrule |
655 */ | 685 |
656 /* | 686 /* |
657 rule flagAudioEnd (inAudioFifo.first() matches tagged EndOfFile); | 687 rule flagAudioEnd (inAudioFifo.first() matches tagged EndOfFile); |
658 $display (" PROCESSOR End Audio Flag Set "); | 688 $display (" PROCESSOR End Audio Flag Set "); |
659 cp0_audioEOF <= True; | 689 cp0_audioEOF <= True; |
660 inAudioFifo.deq; | 690 inAudioFifo.deq; |
661 endrule | 691 endrule |
662 */ | 692 */ |
693 (* descending_urgency = "sendProcEnd, exec" *) | |
663 rule sendProcEnd (cp0_progComp); | 694 rule sendProcEnd (cp0_progComp); |
664 $display (" PROCESSOR Says Program Complete "); | 695 $display (" PROCESSOR Says Program Complete "); |
665 outAudioFifo.enq(tagged EndOfFile); | 696 outAudioFifo.enq(AudioStream {voice: channel, data: tagged Valid tagged EndOfFile }); // Only send one |
666 cp0_progComp <= False; //only send one. And functions to reset | 697 cp0_progComp <= False; // And functions to reset |
698 code_bypass <= True; // Enable Bypass so that invalids get thru | |
667 endrule | 699 endrule |
668 | 700 |
669 | 701 |
670 //----------------------------------------------------------- | 702 //----------------------------------------------------------- |
671 // Methods | 703 // Methods |
694 endinterface | 726 endinterface |
695 */ | 727 */ |
696 | 728 |
697 interface Get sampleOutput = fifoToGet(outAudioFifo); | 729 interface Get sampleOutput = fifoToGet(outAudioFifo); |
698 interface Put sampleInput = fifoToPut(inAudioFifo); | 730 interface Put sampleInput = fifoToPut(inAudioFifo); |
731 interface Get pcCount = toGet(asReg(pc)); | |
699 | 732 |
700 endmodule | 733 endmodule |
701 | 734 |