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

Subversion Repositories bluespec-h264

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

Go to most recent revision | Compare with Previous | Blame | View Log

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

Go to most recent revision | 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.