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

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 EHRReg::*;
  27. import Vector::*;
  28. /////////////////////////////////////////////////////////////
  29. // Interface
  30. // Name: StreamFIFO
  31. // Ptrs: sz, s_sz, data_t
  32. // Dscr: A fifo that can enq and deq arbitrary no. of 
  33. //       elements
  34. /////////////////////////////////////////////////////////////
  35. interface StreamFIFO#(numeric type sz,     // buffer sz
  36.       numeric type s_sz,   // shift sz
  37.       type data_t);        // basic data unit
  38.       method Action enq(Bit#(s_sz) i_s_sz, 
  39. Vector#(sz, data_t) i_msg);
  40.       method Vector#(sz, data_t) first();
  41.       method Action deq(Bit#(s_sz) o_s_sz); 
  42.       method Action clear();
  43.       method Bool notEmpty(Bit#(s_sz) o_s_sz); // canDeq?
  44.       method Bool notFull(Bit#(s_sz) i_s_sz);  // canEnq?
  45.       method Bit#(s_sz) usage(); // no of slots used
  46.       method Bit#(s_sz) free(); // no of slots unused
  47. endinterface
  48. //////////////////////////////////////////////////////////////
  49. // Functions
  50. /////////////////////////////////////////////////////////////
  51. // shift towards higher index
  52. function Vector#(sz,data_t) shiftLeftBy(Vector#(sz,data_t) inVec,
  53. Bit#(s_sz) shiftBy)
  54.    provisos (Add#(sz,1,szp1),
  55.      Log#(szp1,s_sz),
  56.      Bits#(data_t,data_sz));
  57.    
  58.    function Vector#(sz,data_t) stageFunc(Vector#(sz,data_t) iVec,
  59.  Tuple2#(Bit#(1),Nat) ctrl);
  60.       return (tpl_1(ctrl) == 1) ? 
  61.              unpack(pack(iVec) << tpl_2(ctrl)) : 
  62.              iVec;
  63.    endfunction
  64.    
  65.    Nat dataSz = fromInteger(valueOf(data_sz));
  66.    Vector#(s_sz,Bit#(1)) shiftVec = unpack(shiftBy);
  67.    Vector#(s_sz,Nat) natVec0 = genWith(fromInteger);
  68.    Vector#(s_sz,Nat) natVec1 = map(<< (1),natVec0);
  69.    Vector#(s_sz,Nat) natVec2 = map(* (dataSz),natVec1);
  70.    let ctrlVec = zip(shiftVec, natVec2);
  71.    return foldl(stageFunc,inVec,ctrlVec);
  72.    
  73. endfunction
  74. // shift towards lower index
  75. function Vector#(sz,data_t) shiftRightBy(Vector#(sz,data_t) inVec,
  76.  Bit#(s_sz) shiftBy)
  77.    provisos (Add#(sz,1,szp1),
  78.      Log#(szp1,s_sz),
  79.      Bits#(data_t,data_sz));
  80.    
  81.    function Vector#(sz,data_t) stageFunc(Vector#(sz,data_t) iVec,
  82.  Tuple2#(Bit#(1),Nat) ctrl);
  83.       return (tpl_1(ctrl) == 1) ? 
  84.              unpack(pack(iVec) >> tpl_2(ctrl)) : 
  85.              iVec;
  86.    endfunction
  87.    
  88.    Nat dataSz = fromInteger(valueOf(data_sz));
  89.    Vector#(s_sz,Bit#(1)) shiftVec = unpack(shiftBy);
  90.    Vector#(s_sz,Nat) natVec0 = genWith(fromInteger);
  91.    Vector#(s_sz,Nat) natVec1 = map(<< (1),natVec0);
  92.    Vector#(s_sz,Nat) natVec2 = map(* (dataSz),natVec1);
  93.    let ctrlVec = zip(shiftVec, natVec2);
  94.    return foldl(stageFunc,inVec,ctrlVec);
  95.    
  96. endfunction
  97. ////////////////////////////////////////////////////////////////////
  98. // Module
  99. // Name: mkStreamFIFO
  100. // Ptrs: 
  101. // Dscr: Create an instance of StreamFIFO which is implemented with
  102. //       shifting approach
  103. // Notes: To enq/deq, caller needs to check notFull/notEmpty 
  104. //        explicitly  
  105. ///////////////////////////////////////////////////////////////////
  106. module mkStreamFIFO(StreamFIFO#(sz, s_sz, data_t))
  107.    provisos (Add#(sz,1,szp1),
  108.      Log#(szp1,s_sz),
  109.      Bits#(data_t,data_sz));
  110.    
  111.    Bit#(s_sz) maxTail = fromInteger(valueOf(sz));
  112.    EHRReg#(2,Vector#(sz,data_t)) buffer <- mkEHRReg(newVector);       
  113.    EHRReg#(2,Bit#(s_sz)) tail <- mkEHRReg(0); // equal to usage
  114.    
  115.    function data_t selTuple(Tuple3#(Bool,data_t,data_t) tup);
  116.       return tpl_1(tup) ? tpl_2(tup) : tpl_3(tup);
  117.    endfunction
  118.    method Action enq(Bit#(s_sz) i_s_sz, 
  119.      Vector#(sz, data_t) i_msg);
  120.       let buffer0 = buffer[1];
  121.       let buffer1 = shiftLeftBy(i_msg, tail[1]);
  122.       Vector#(sz, Bit#(s_sz)) idxVec = genWith(fromInteger);
  123.       Vector#(sz, Bool) selBuffer = map(> (tail[1]), idxVec);
  124.       let zipBuffer = zip3(selBuffer,buffer0,buffer1);
  125.       let newBuffer = map(selTuple,zipBuffer);
  126.       buffer[1] <= newBuffer;
  127.       tail[1] <= tail[1] + i_s_sz;
  128.    endmethod
  129.    
  130.    method Vector#(sz, data_t) first(); 
  131.       return buffer[0];
  132.    endmethod
  133.    
  134.    method Action deq(Bit#(s_sz) o_s_sz);
  135.       buffer[0] <= shiftRightBy(buffer[0], o_s_sz);
  136.       tail[0] <= tail[0] - o_s_sz;
  137.    endmethod
  138.    
  139.    method Action clear();
  140.       tail[1] <= 0;
  141.    endmethod
  142.    
  143.    method Bool notEmpty(Bit#(s_sz) o_s_sz);
  144.       return tail[0] >= o_s_sz;
  145.    endmethod
  146.    
  147.    method Bool notFull(Bit#(s_sz) i_s_sz);
  148.       return tail[0] <= maxTail - i_s_sz;
  149.    endmethod
  150.    
  151.    method Bit#(s_sz) usage();
  152.       return tail[0];
  153.    endmethod
  154.    
  155.    method Bit#(s_sz) free();
  156.       return maxTail - tail[0];
  157.    endmethod
  158. endmodule
  159. ////////////////////////////////////////////////////////////////////
  160. // Module
  161. // Name: mkStreamLFIFO
  162. // Ptrs: 
  163. // Dscr: Create an instance of StreamFIFO which is implemented with
  164. //       shifting approach, can deq and enq parallelly when it is full
  165. // Notes: To enq/deq, caller needs to check notFull/notEmpty 
  166. //        explicitly  
  167. ///////////////////////////////////////////////////////////////////
  168. module mkStreamLFIFO(StreamFIFO#(sz, s_sz, data_t))
  169.    provisos (Add#(sz,1,szp1),
  170.      Log#(szp1,s_sz),
  171.      Bits#(data_t,data_sz));
  172.    
  173.    Bit#(s_sz) maxTail = fromInteger(valueOf(sz));
  174.    EHRReg#(2,Vector#(sz,data_t)) buffer <- mkEHRReg(newVector);       
  175.    EHRReg#(2,Bit#(s_sz)) tail <- mkEHRReg(0); // equal to usage
  176.    
  177.    function data_t selTuple(Tuple3#(Bool,data_t,data_t) tup);
  178.       return tpl_1(tup) ? tpl_2(tup) : tpl_3(tup);
  179.    endfunction
  180.    method Action enq(Bit#(s_sz) i_s_sz, 
  181.      Vector#(sz, data_t) i_msg);
  182.       let buffer0 = buffer[1];
  183.       let buffer1 = shiftLeftBy(i_msg, tail[1]);
  184.       Vector#(sz, Bit#(s_sz)) idxVec = genWith(fromInteger);
  185.       Vector#(sz, Bool) selBuffer = map(> (tail[1]), idxVec);
  186.       let zipBuffer = zip3(selBuffer,buffer0,buffer1);
  187.       let newBuffer = map(selTuple,zipBuffer);
  188.       buffer[1] <= newBuffer;
  189.       tail[1] <= tail[1] + i_s_sz;
  190.    endmethod
  191.    
  192.    method Vector#(sz, data_t) first(); 
  193.       return buffer[0];
  194.    endmethod
  195.    
  196.    method Action deq(Bit#(s_sz) o_s_sz);
  197.       buffer[0] <= shiftRightBy(buffer[0], o_s_sz);
  198.       tail[0] <= tail[0] - o_s_sz;
  199.    endmethod
  200.    
  201.    method Action clear();
  202.       tail[1] <= 0;
  203.    endmethod
  204.    
  205.    method Bool notEmpty(Bit#(s_sz) o_s_sz);
  206.       return tail[0] >= o_s_sz;
  207.    endmethod
  208.    
  209.    method Bool notFull(Bit#(s_sz) i_s_sz);
  210.       return tail[1] <= maxTail - i_s_sz; // slower ready signal 
  211.    endmethod
  212.    method Bit#(s_sz) usage();
  213.       return tail[0];
  214.    endmethod
  215.    
  216.    method Bit#(s_sz) free();
  217.       return maxTail - tail[1];
  218.    endmethod   
  219. endmodule