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

Subversion Repositories bluespec-h264

[/] [bluespec-h264/] [trunk/] [src_fpga/] [FIFO_2.bsv] - Rev 100

Compare with Previous | Blame | View Log


// The MIT License

// Copyright (c) 2006-2007 Massachusetts Institute of Technology

// 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.

package FIFO_2;
export FIFO_2(..);

export mkFIFO2;

import FIFOF::*;
import RWire::*;
import List::*;
import Monad::*;

interface FIFO_2 #(type t);
    method Bool has1i();
    method Bool has2i();
    method Bool space1i();
    method Bool space2i();
    method Action enq_1(t x1);
    method Action enq_2(t x1);
    method t first_1();
    method t first_2();
    method Action deq_1();
    method Action deq_2();
    method Action clear();
endinterface: FIFO_2


module mkFIFO2(FIFO_2#(t))
  provisos (Bits#(t, bt));

  function Bool pokeRWire(RWire#(z) x);
    begin
      case (x.wget) matches
           tagged Valid {.a}:  return(True);
           tagged Invalid  :  return(False);
      endcase
    end
  endfunction: pokeRWire

  List#(RWire#(t)) enq;
  enq <- mapM (constFn(mkRWire), upto(0, 1));

  List#(RWire#(Bit#(0))) deq;
  deq <- mapM (constFn(mkRWire), upto(0, 1));

  List#(FIFOF#(t)) fifos;
  fifos <- mapM (constFn(mkFIFOF), upto(0, 1));

  List#(RWire#(t)) fifosr;
  fifosr <- mapM (constFn(mkRWire), upto(0, 1));

  Reg#(Bit#(1)) head();
  mkReg#(0) the_head(head);

  Reg#(Bit#(1)) tail();
  mkReg#(0) the_tail(tail);

  rule doEnq (True);
     let predVals = map(pokeRWire, enq);
     Bit#(1) offset;
     function Bit#(1) foldfunc (Bit#(1) o, Bool x);
         return (x ? o+1 : o);
     endfunction: foldfunc

     offset = foldl(foldfunc, 0, predVals);

     function Action tryEnqr(RWire#(t) rf, RWire#(t) r);
       action
         case (r.wget) matches
              tagged Invalid : noAction;
              tagged Valid .v : rf.wset(v);
         endcase
       endaction
     endfunction: tryEnqr

     let efifo1r =  select(fifosr, ((Bit#(1))'(0)));
     let efifo2r =  select(fifosr, ((Bit#(1))'(1)));

     match {.enq1,.enq2} = tuple2(select(enq, tail + 0), select(enq, tail + 1));

     tryEnqr(efifo1r, enq1);
     tryEnqr(efifo2r, enq2);

     tail <= tail + offset;

  endrule: doEnq

  rule enq1(True);
    action
       let fifo1  = select(fifos , ((Bit#(1))'(0)));
       let fifo1r = select(fifosr, ((Bit#(1))'(0)));
       case (fifo1r.wget) matches
            tagged Invalid : noAction;
            tagged Valid .v : fifo1.enq (v);
       endcase
    endaction
  endrule: enq1

  rule enq2(True);
    action
       let fifo2  = select(fifos , ((Bit#(1))'(1)));
       let fifo2r = select(fifosr, ((Bit#(1))'(1)));
       case (fifo2r.wget) matches
            tagged Invalid : noAction;
            tagged Valid .v : fifo2.enq (v);
       endcase
    endaction
  endrule: enq2

  rule handle_Dequeues (True);
     let predVals =  map(pokeRWire, deq);
     Bit#(1) offset;

     function Bit#(1) foldfunc (Bit#(1) o, Bool x);
         return (x ? o+1 : o);
     endfunction: foldfunc

     offset = foldl(foldfunc, 0, predVals);

     function Action tryDeq(FIFOF#(t) f, RWire#(Bit#(0)) r);
       action
         case (r.wget) matches
              tagged Invalid : noAction;
              tagged Valid .a : f.deq();
        endcase
       endaction
     endfunction: tryDeq

     let dfifo1 =  select(fifos, ((Bit#(1))'(0)));
     let dfifo2 =  select(fifos, ((Bit#(1))'(1)));

     match {.deq1,.deq2} = tuple2(select(deq, head + 0), select(deq, head + 1));

     tryDeq(dfifo1, deq1);
     tryDeq(dfifo2, deq2);

     head <= head + offset;
  endrule: handle_Dequeues

  method enq_1(v) if (((select(fifos,0)).notFull) ||
                      ((select(fifos,1)).notFull)) ;
    action
      let enq1 = select(enq, ((Bit#(1))'(0)));
      enq1.wset(v);
    endaction 

  endmethod: enq_1

  method enq_2(v) if (((select(fifos,0)).notFull) && ((select(fifos,1)).notFull)) ;
    action
      let enq2 =  select(enq, ((Bit#(1))'(1)));
      enq2.wset(v);
    endaction
  endmethod: enq_2

  method deq_1() if (((select(fifos,0)).notEmpty) || ((select(fifos,1)).notEmpty)) ;
    action
      let deq1 =  select(deq, ((Bit#(1))'(0)));
      deq1.wset(?); // PrimUnit;
    endaction
  endmethod: deq_1

  method deq_2() if (((select(fifos,0)).notEmpty) && ((select(fifos,1)).notEmpty)) ;
    action
      let deq2 =  select(deq, ((Bit#(1))'(1)));
      deq2.wset (?); // Unit;
    endaction
  endmethod: deq_2

  method clear() ;
    action
      function Action clearfifo(FIFOF#(t) f);
        action
          f.clear();
        endaction
      endfunction: clearfifo
      List#(Action) lact;

      lact = map(clearfifo, fifos);
      head <= 0;
      tail <= 0;
      joinActions(lact);
    endaction
  endmethod: clear

  method first_1() if ((select(fifos, ((Bit#(1))'(0)))).notEmpty ||
                       (select(fifos, ((Bit#(1))'(1)))).notEmpty) ;
      let dfifo1 =  select(fifos, head + 0);
      return (dfifo1.first);
  endmethod: first_1

  method first_2() if ((select(fifos, ((Bit#(1))'(0)))).notEmpty &&
                      (select(fifos, ((Bit#(1))'(1)))).notEmpty) ;
      let dfifo2 =  select(fifos, head + 1);
      return (dfifo2.first);
  endmethod: first_2

  method has1i() ;
      return ((select(fifos, ((Bit#(1))'(0)))).notEmpty ||
              (select(fifos, ((Bit#(1))'(1)))).notEmpty);
  endmethod: has1i

  method has2i() ;
      return ((select(fifos, ((Bit#(1))'(0)))).notEmpty &&
              (select(fifos, ((Bit#(1))'(1)))).notEmpty);
  endmethod: has2i

  method space1i() ;
      return ((select(fifos, ((Bit#(1))'(0)))).notFull ||
              (select(fifos, ((Bit#(1))'(1)))).notFull);
  endmethod: space1i

  method space2i() ;
      return ((select(fifos, ((Bit#(1))'(0)))).notFull &&
              (select(fifos, ((Bit#(1))'(1)))).notFull);
  endmethod: space2i

endmodule: mkFIFO2


module mkTest(FIFO_2#(Bit#(2)));
  FIFO_2#(Bit#(2)) f();
  mkFIFO2 the_f(f);

  method enq_1();
     return (f.enq_1);
  endmethod: enq_1

  method enq_2();
     return (f.enq_2);
  endmethod: enq_2

  method first_1();
     return (f.first_1);
  endmethod: first_1

  method first_2();
     return (f.first_2);
  endmethod: first_2

  method deq_1();
     return (f.deq_1);
  endmethod: deq_1

  method deq_2();
     return (f.deq_2);
  endmethod: deq_2

  method clear();
     return (f.clear);
  endmethod: clear

  method has1i();
     return (f.has1i);
  endmethod: has1i

  method has2i();
     return (f.has2i);
  endmethod: has2i

  method space1i();
     return (f.space1i);
  endmethod: space1i

  method space2i();
     return (f.space2i);
  endmethod: space2i
endmodule: mkTest

endpackage: FIFO_2

Compare with Previous | Blame | View Log

powered by: WebSVN 2.1.0

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