OpenCores
URL https://opencores.org/ocsvn/bluespec-80211atransmitter/bluespec-80211atransmitter/trunk

Subversion Repositories bluespec-80211atransmitter

[/] [bluespec-80211atransmitter/] [trunk/] [Pipelines.bsv] - Diff between revs 2 and 3

Show entire file | Details | Blame | View Log

Rev 2 Rev 3
?rev1line?
?rev2line?
 
// The MIT License
 
//
 
// Copyright (c) 2006 Nirav Dave (ndave@csail.mit.edu)
 
//
 
// Permission is hereby granted, free of charge, to any person obtaining a copy
 
// of this software and associated documentation files (the "Software"), to deal
 
// in the Software without restriction, including without limitation the rights
 
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
 
// copies of the Software, and to permit persons to whom the Software is
 
// furnished to do so, subject to the following conditions:
 
//
 
// The above copyright notice and this permission notice shall be included in
 
// all copies or substantial portions of the Software.
 
//
 
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
 
// THE SOFTWARE.
 
 
 
 
 
 
 
 
 
//////////////////////////////////////////////////////////////////////////////////
 
 
 
// Copyright (c) 2006 Nirav Dave (ndave@csail.mit.edu)
 
 
 
// Permission is hereby granted, free of charge, to any person obtaining
 
// a copy of this software and associated documentation files (the
 
// "Software"), to deal in the Software without restriction, including
 
// without limitation the rights to use, copy, modify, merge, publish,
 
// distribute, sublicense, and/or sell copies of the Software, and to
 
// permit persons to whom the Software is furnished to do so, subject to
 
// the following conditions:
 
 
 
// The above copyright notice and this permission notice shall be
 
// included in all copies or substantial portions of the Software.
 
 
 
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
 
// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
 
// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
 
// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
 
// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
 
// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
 
// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 
 
 
//////////////////////////////////////////////////////////////////////////////////
 
 
 
import FIFO::*;
 
import FIFOF::*;
 
import Vector::*;
 
 
 
interface Pipeline#(type alpha);
 
  method Action put(alpha x);
 
  method ActionValue#(alpha) get();
 
endinterface
 
 
 
function alpha repeatFN(Bit#(b) reps, function alpha f(Bit#(b) stage, alpha fx), Bit#(b) stage, alpha in);
 
  alpha new_in = f(stage, in);
 
  return (reps == 0) ? in : repeatFN(reps - 1, f, stage+1, new_in);
 
endfunction
 
 
 
module mkPipeline_Circ#(Bit#(b) numstages,
 
                        Bit#(b) step,
 
                        function alpha sf(Bit#(b) s, alpha x))
 
       (Pipeline#(alpha))
 
    provisos
 
       (Bits#(alpha, asz));
 
 
 
  // input queue
 
  FIFOF#(alpha)       inputQ <- mkLFIFOF();
 
 
 
  // internal state
 
  Reg#(Bit#(b))          stage <- mkReg(0);
 
  Reg#(alpha)             s <- mkRegU;
 
 
 
  // output queue
 
  FIFO#(alpha)        outputQ <- mkLFIFO();
 
 
 
  rule compute(True);
 
   // get input (implicitly stalls if no input)
 
 
 
   alpha s_in = s; // default is from register
 
   if (stage == 0)
 
     begin
 
       s_in = inputQ.first();
 
       inputQ.deq();
 
     end
 
 
 
   //do stage
 
   let s_out = repeatFN(step, sf, stage, s_in);
 
 
 
   // store output
 
   stage <= (stage + step == numstages) ? 0 : stage + step;
 
 
 
   if(stage + step == numstages)
 
     outputQ.enq(s_out);
 
   else
 
     s <= s_out;
 
  endrule
 
 
 
  // The Interface
 
 
 
  method Action put(alpha x);
 
    inputQ.enq(x);
 
  endmethod
 
 
 
  method ActionValue#(alpha) get();
 
    outputQ.deq();
 
    return outputQ.first();
 
  endmethod
 
 
 
endmodule
 
 
 
module mkPipeline_Sync#(Bit#(b) numstages,
 
                        Bit#(b) step,
 
                        function alpha sf(Bit#(b) s, alpha x))
 
       (Pipeline#(alpha))
 
    provisos
 
       (Bits#(alpha, asz),Add#(b,k,32));
 
 
 
  // input queue
 
  FIFOF#(alpha)       inputQ <- mkLFIFOF();
 
 
 
  // internal state
 
  // This is an over estimate of the space we need
 
  // we're artificially restricted because there is no
 
  // "reasonable way to pass a "static" parameter.
 
  // We will only create/initialize the used registers though.
 
 
 
  Vector#(TExp#(b), Reg#(Maybe#(alpha))) piperegs = newVector();
 
 
 
  for(Bit#(b) i = 0; i < numstages; i = i + step)
 
   begin
 
     let pipereg <- mkReg(Nothing);
 
     piperegs[i] = pipereg;
 
   end
 
 
 
  // output queue
 
  FIFO#(alpha)        outputQ <- mkLFIFO();
 
 
 
  rule compute(True);
 
    for(Bit#(b) stage = 0; stage < numstages; stage = stage + step)
 
      begin
 
        //Determine Inputs
 
 
 
        Maybe#(alpha) in = Nothing; // Default Value Is Nothing
 
 
 
        if (stage != 0)                         // Not-First Stage takes from reg
 
           in = (piperegs[stage - step])._read;
 
        else if(inputQ.notEmpty) // take from queue at stage 0
 
          begin
 
            in = Just(inputQ.first());
 
            inputQ.deq();
 
          end
 
        alpha s_in = fromMaybe(?,in);
 
 
 
        //do stage
 
 
 
        alpha s_out = repeatFN(step, sf, stage, s_in);
 
 
 
        //deal with outputs
 
        if (stage + step < numstages) // it's not the last stage
 
          (piperegs[stage]) <= isJust(in) ? Just(s_out): Nothing;
 
        else if(isValid(in)) // && stage == 2
 
          outputQ.enq(s_out);
 
        else
 
          noAction;
 
        end
 
  endrule
 
 
 
  // The Interface
 
  method Action put(alpha x);
 
    inputQ.enq(x);
 
  endmethod
 
 
 
  method ActionValue#(alpha) get();
 
    outputQ.deq();
 
    return outputQ.first();
 
  endmethod
 
 
 
endmodule
 
 
 
 
 
module mkPipeline_Comb#(Bit#(b) numstages,
 
                        Bit#(b) step,
 
                        function alpha sf(Bit#(b) s, alpha x))
 
       (Pipeline#(alpha))
 
    provisos
 
       (Bits#(alpha, asz));
 
 
 
  // input queue
 
  FIFOF#(alpha)       inputQ <- mkLFIFOF();
 
 
 
  // output queue
 
  FIFO#(alpha)        outputQ <- mkLFIFO();
 
 
 
  rule compute(True);
 
    alpha  stage_in, stage_out;
 
 
 
    stage_in = inputQ.first();
 
    inputQ.deq();
 
 
 
    for(Bit#(b) stage = 0; stage < numstages; stage = stage + step)
 
      begin
 
        //do stage
 
        stage_out = repeatFN(step, sf, stage, stage_in);
 
 
 
        //deal with outputs
 
        stage_in = stage_out;
 
      end
 
 
 
    outputQ.enq(stage_out);
 
  endrule
 
 
 
  // The Interface
 
  method Action put(alpha x);
 
    inputQ.enq(x);
 
  endmethod
 
 
 
  method ActionValue#(alpha) get();
 
    outputQ.deq();
 
    return outputQ.first();
 
  endmethod
 
 
 
endmodule
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.