Pipelines.bsv
上传用户:aoptech
上传日期:2014-09-22
资源大小:784k
文件大小:6k
源码类别:

3G开发

开发平台:

Others

  1. //----------------------------------------------------------------------//
  2. // The MIT License 
  3. // 
  4. // Copyright (c) 2007 Alfred Man Cheuk Ng, mcn02@mit.edu 
  5. // 
  6. // Permission is hereby granted, free of charge, to any person 
  7. // obtaining a copy of this software and associated documentation 
  8. // files (the "Software"), to deal in the Software without 
  9. // restriction, including without limitation the rights to use,
  10. // copy, modify, merge, publish, distribute, sublicense, and/or sell
  11. // copies of the Software, and to permit persons to whom the
  12. // Software is furnished to do so, subject to the following conditions:
  13. // 
  14. // The above copyright notice and this permission notice shall be
  15. // included in all copies or substantial portions of the Software.
  16. // 
  17. // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
  18. // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
  19. // OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
  20. // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
  21. // HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
  22. // WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
  23. // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
  24. // OTHER DEALINGS IN THE SOFTWARE.
  25. //----------------------------------------------------------------------//
  26. import FIFO::*;
  27. import FIFOF::*;
  28. import Vector::*;
  29. interface Pipeline#(type alpha);
  30.   method Action put(alpha x);
  31.   method ActionValue#(alpha) get();
  32. endinterface
  33. function alpha repeatfunction(Integer reps,  function alpha f(Bit#(b) stage, alpha fx),Bit#(b) stage, alpha in );
  34.       alpha new_in = in;
  35.       for (Integer i = 0 ; i < reps ; i = i + 1)
  36. new_in    = f(stage + fromInteger(i), new_in);
  37.       return new_in;
  38. endfunction // alpha
  39. // numStages = no of stages need to be executed, need to be multiple of step
  40. // step = no of stages perform per atomic action
  41. module mkPipeline_Circ#(Integer numStages,
  42.                         Integer step,
  43.                         function alpha sf(Bit#(b) s, alpha x))
  44.        (Pipeline#(alpha))
  45.     provisos
  46.        (Bits#(alpha, asz));
  47.   
  48.   
  49.   // input queue
  50.   FIFOF#(alpha)      inputQ <- mkLFIFOF();
  51.   
  52.   // internal state
  53.   Reg#(Bit#(b))       stage <- mkReg(0);
  54.   Reg#(alpha)             s <- mkRegU;  
  55.   
  56.   // output queue
  57.   FIFO#(alpha)      outputQ <- mkLFIFO();
  58.   
  59.   rule compute(True);
  60.       // get input (implicitly stalls if no input)
  61.       alpha s_in = s;
  62.       Bit#(b) maxStageIdx = fromInteger(numStages - 1);
  63.       Bit#(b) maxStepIdx  = fromInteger(step - 1);
  64.       
  65.       if (stage == 0)
  66.         begin    
  67.           s_in = inputQ.first();
  68.           inputQ.deq();
  69. end
  70.       //do stage
  71.       let s_out = repeatfunction(step, sf, stage, s_in);
  72.       // store output
  73.   
  74.       stage <= ((maxStageIdx - stage) <= maxStepIdx) ? 0 : stage + maxStepIdx + 1; // update stage to the starting index of the next stage
  75.       if((maxStageIdx - stage) <= maxStepIdx)
  76.         outputQ.enq(s_out);
  77.       else
  78.         s <= s_out;
  79.   endrule 
  80.   
  81. // The Interface
  82.   
  83.    method Action put(alpha x);
  84.      inputQ.enq(x);   
  85.    endmethod
  86.   
  87.    method ActionValue#(alpha) get();
  88.      outputQ.deq();
  89.      return outputQ.first();
  90.    endmethod
  91.   
  92. endmodule
  93.   
  94. // numStages = no of stages need to be executed, need to be multiple of step
  95. // step = no of stages perform per atomic action
  96. module mkPipeline_Sync#(Integer numStages,
  97.                         Integer step,
  98.                         function alpha sf(Bit#(b) s, alpha x))
  99.   (Pipeline#(alpha))
  100.   provisos
  101.     (Bits#(alpha, asz),Add#(b,k,32));
  102.       // input queue
  103.       FIFOF#(alpha)       inputQ <- mkLFIFOF();
  104.   
  105.       // internal state
  106.       // This is an over estimate of the space we need
  107.       // we're artificially restricted because there is no
  108.       // "reasonable way to pass a "static" parameter.
  109.       // We will only create/initialize the used registers though.
  110.       Vector#(TExp#(b), Reg#(Maybe#(alpha))) piperegs = newVector();
  111.       for(Integer i = 0; i < numStages - step; i = i + step) // don't need the last on
  112. begin
  113.    let pipereg <- mkReg(Nothing);
  114.    Bit#(b) idx = fromInteger(i);
  115.    piperegs[idx] = pipereg;
  116. end
  117.       
  118.       // output queue
  119.       FIFO#(alpha)        outputQ <- mkLFIFO();
  120.   
  121.       rule compute(True);
  122.      
  123.       for(Integer i = 0; i < numStages; i = i + step)
  124.         begin
  125.            //Determine Inputs
  126.    Bit#(b) lastStage = fromInteger(i - step); // index of last stage
  127.    Bit#(b) thisStage = fromInteger(i);        // index ot this stage
  128.            Maybe#(alpha)  in = Nothing; // Default Value Is Nothing
  129.   
  130.            if (i != 0)                         // Not-First Stage takes from reg
  131.              in = (piperegs[lastStage])._read;
  132.            else                                   
  133.        if(inputQ.notEmpty) // take from queue at stage 0
  134.                begin    
  135.                   in = Just(inputQ.first());
  136.                   inputQ.deq();
  137.        end
  138.   
  139.    alpha s_in = fromMaybe(?,in);
  140.    
  141.    //do stage
  142.    
  143.            alpha s_out = repeatfunction(step, sf, thisStage, s_in);
  144.    
  145.    //deal with outputs
  146.            if (i + step < numStages) // it's not the last stage
  147.              (piperegs[thisStage]) <= isJust(in) ? Just(s_out): Nothing;
  148.            else if(isValid(in)) // && stage == 2
  149.              outputQ.enq(s_out);
  150.    else
  151.      noAction;
  152.         end     
  153.       
  154.       endrule
  155.    
  156. // The Interface
  157.       method Action put(alpha x);
  158.          inputQ.enq(x);   
  159.       endmethod
  160.       method ActionValue#(alpha) get();
  161.          outputQ.deq();
  162.          return outputQ.first();
  163.       endmethod
  164. endmodule
  165.      
  166.      
  167. // maxStage = the index of the last stage (maxStage + 1 = num of stages need to be executed)
  168. module mkPipeline_Comb#(Integer numStages,
  169.                         function alpha sf(Bit#(b) s, alpha x))
  170.        (Pipeline#(alpha))
  171.     provisos
  172.        (Bits#(alpha, asz));
  173.   // input queue
  174.   FIFOF#(alpha)       inputQ <- mkLFIFOF();
  175.   
  176.   // output queue
  177.   FIFO#(alpha)        outputQ <- mkLFIFO();
  178.   
  179.  
  180.   rule compute(True);
  181.       alpha  stage_in, stage_out;
  182.       stage_in = inputQ.first();
  183.       stage_out = repeatfunction(numStages, sf, 0, stage_in);
  184.       inputQ.deq();
  185.       outputQ.enq(stage_out);
  186.       
  187.    endrule  
  188.    
  189. // The Interface
  190.   
  191.    method Action put(alpha x);
  192.      inputQ.enq(x);   
  193.    endmethod
  194.   
  195.    method ActionValue#(alpha) get();
  196.      outputQ.deq();
  197.      return outputQ.first();
  198.    endmethod
  199.   
  200. endmodule