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

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. /////////////////////////////////////////////////////////////
  27. // Interface and Implementation of BitStreamFIFO
  28. // Description: BitStreamFIFO is a fifo that can enq and deq 
  29. //              arbitrary no. bits
  30. /////////////////////////////////////////////////////////////
  31. import Vector::*;
  32. /////////////////////////////////////////////////////////////
  33. // Interface
  34. // Name: BitStreamFIFO
  35. // Description: A fifo that can enq and deq arbitrary no. elements
  36. // Parameters: buf_sz    : FIFO buffer size
  37. //             buf_bsz   : buffer index size in no. bits
  38. //             io_sz     : max no. io_sz data element can be enq/deq at one time
  39. //             io_bsz    : no. bits to specify the element to be enq/deq at one time
  40. //             io_data_sz: data element size in no. bits
  41. // Methods: enq  : enqueue the first i_b elements in i_data to 
  42. //                 the end of the fifo
  43. //          first: read o_sz elements from the start of fifo
  44. //          deq  : dequeue the o_b elements from the start of fifo
  45. //          clear: clear the fifo
  46. //          usage: return no. buffer used in the fifo
  47. //          free:  return no. buffer free in the fifo          
  48. /////////////////////////////////////////////////////////////
  49. interface BitStreamFIFO#(numeric type buf_sz,
  50.                          numeric type buf_bsz,
  51.                          numeric type io_sz,
  52.                          numeric type io_bsz,
  53.                          numeric type io_data_sz);
  54.    method Action enq(Bit#(io_bsz) i_sz,    
  55.                      Vector#(io_sz,Bit#(io_data_sz))  i_data);
  56.    method Vector#(io_sz,Bit#(io_data_sz)) first();            
  57.    method Action deq(Bit#(io_bsz) o_sz);   
  58.    method Action clear();                
  59.    method Bit#(buf_bsz) usage();            
  60.    method Bit#(buf_bsz) free();            
  61. endinterface
  62. //////////////////////////////////////////////////////////////
  63. // Auxiliary Functions
  64. /////////////////////////////////////////////////////////////
  65. // dynamic left shifter using barrel shifter
  66. function Vector#(sz,Bit#(data_sz)) shiftLeft(Vector#(sz,Bit#(data_sz)) i_data, // input data
  67.                                              Bit#(s_sz) shift); // left shift amount
  68.    
  69.    function Tuple2#(Bit#(a),Nat) 
  70.       stageFunc(Tuple2#(Bit#(a),Nat) in, Bool ctrl);
  71.       let in_data      = tpl_1(in);
  72.       let in_shift     = tpl_2(in);
  73.       let new_in_data  = ctrl ? in_data << in_shift : in_data;
  74.       let new_in_shift = in_shift << 1;
  75.       return tuple2(new_in_data,new_in_shift);
  76.    endfunction
  77.    Vector#(s_sz,Bool) ctrlVec = unpack(pack(shift));
  78.    Nat seed = fromInteger(valueOf(data_sz));
  79.    let i_data_b = pack(i_data);
  80.    let resTpl = foldl(stageFunc,tuple2(i_data_b,seed),ctrlVec);
  81.    return unpack(tpl_1(resTpl));
  82.       
  83. endfunction
  84. // dynamic right shifter using barrel shifter
  85. function Vector#(sz,Bit#(data_sz)) shiftRight(Vector#(sz,Bit#(data_sz)) i_data, // input data
  86.                                               Bit#(s_sz) shift); // right shift amount
  87.    
  88.    function Tuple2#(Bit#(a),Nat) 
  89.       stageFunc(Tuple2#(Bit#(a),Nat) in, Bool ctrl);
  90.       let in_data      = tpl_1(in);
  91.       let in_shift     = tpl_2(in);
  92.       let new_in_data  = ctrl ? in_data >> in_shift : in_data;
  93.       let new_in_shift = in_shift << 1;
  94.       return tuple2(new_in_data,new_in_shift);
  95.    endfunction
  96.    Vector#(s_sz,Bool) ctrlVec = unpack(pack(shift));
  97.    Nat seed = fromInteger(valueOf(data_sz));
  98.    let i_data_b = pack(i_data);
  99.    let resTpl = foldl(stageFunc,tuple2(i_data_b,seed),ctrlVec);
  100.    return unpack(tpl_1(resTpl));
  101.       
  102. endfunction
  103. ////////////////////////////////////////////////////////////////////
  104. // Module Defintion
  105. // Name: mkUGBitStreamFIFO
  106. // Description: Implementation of BitStreamFIFO interface
  107. //              with shifters, methods enq/deq are unguarded, 
  108. //              user of this module needs to check usage and free 
  109. //              explicitly to guarantee correctness
  110. // Schedule: enq CF {first, deq, usage, free}
  111. //           enq SB clear
  112. //           enq C  enq
  113. //           first CF {enq, first, deq, usage ,free}
  114. //           first SB clear
  115. //           deq CF {enq, first, usage, free}
  116. //           deq SB clear
  117. //           deq C  deq
  118. //           clear SB clear
  119. //           clear SA {enq, first, deq, usage, free}
  120. //           usage CF {enq, first, deq, usage, free}
  121. //           usage SB clear
  122. //           free CF {enq, first, deq, usage, free}
  123. //           free SB clear
  124. ///////////////////////////////////////////////////////////////////
  125. module mkUGBitStreamFIFO(BitStreamFIFO#(buf_sz,buf_bsz,io_sz,io_bsz,io_data_sz))
  126.    provisos (Add#(buf_sz,1,buf_szp1),
  127.              Log#(buf_szp1,buf_bsz),    // Bit#(buf_bsz) ranges 0-buf_sz
  128.              Add#(io_sz,1,io_szp1),
  129.              Log#(io_szp1,io_bsz),      // Bit#(io_bsz) ranges 0-io_sz
  130.              Add#(xxA,io_bsz,buf_bsz),  // io_bsz < buf_bsz
  131.              Add#(io_sz,xxB,buf_sz));   // io_sz < buf_sz 
  132.    
  133.    Bit#(buf_bsz) maxIdx = fromInteger(valueOf(buf_sz));
  134.    Reg#(Vector#(buf_sz,Bit#(io_data_sz))) buffers <- mkReg(newVector);
  135.    Reg#(Bit#(buf_bsz)) freeNo <- mkReg(maxIdx);
  136.    Reg#(Bit#(buf_bsz)) useNo  <- mkReg(0);
  137.    Wire#(Bit#(io_bsz)) subFree <- mkDWire(0);
  138.    Wire#(Bit#(io_bsz)) addFree <- mkDWire(0);
  139.    Bit#(io_bsz) addUse = subFree;
  140.    Bit#(io_bsz) subUse = addFree;
  141.    Wire#(Vector#(buf_sz,Bit#(io_data_sz))) newBuffers <- mkDWire(buffers);
  142.    
  143.    // adjust the freeNo/ussNo/buffers dependings on whether enq/deq has been called
  144.    rule updateState(True);
  145.       freeNo <= freeNo + zeroExtend(addFree) - zeroExtend(subFree);
  146.       useNo  <= useNo + zeroExtend(addUse) - zeroExtend(subUse);
  147.       buffers <= newBuffers;
  148.    endrule
  149.    
  150.    method Action enq(Bit#(io_bsz) i_b,Vector#(io_sz,Bit#(io_data_sz)) i_data);
  151.       let extBuffers  = append(buffers,i_data);     // append i_data at the end of buffers
  152.       let shftBuffers = shiftRight(extBuffers,i_b); // shift the extended buffers by i_b elements    
  153.       newBuffers <= take(shftBuffers);              // save back the data
  154.       subFree <= i_b;                               // add i_b to freeNo
  155.    endmethod
  156.    
  157.    method Vector#(io_sz,Bit#(io_data_sz)) first(); 
  158.       // shift the data so that first element at lsbs
  159.       let shftBuffers = shiftRight(buffers,freeNo);
  160.       return take(shftBuffers);
  161.    endmethod
  162.    
  163.    method Action deq(Bit#(io_bsz) o_b);
  164.       addFree <= o_b; // sub o_b to freeNo
  165.    endmethod
  166.    
  167.    method Action clear();
  168.       freeNo <= maxIdx;   // reset freeNo
  169.       useNo <= 0;
  170.    endmethod
  171.    
  172.    method Bit#(buf_bsz) usage();
  173.       return useNo;
  174.    endmethod
  175.    
  176.    method Bit#(buf_bsz) free();
  177.       return freeNo;
  178.    endmethod
  179.    
  180. endmodule
  181. ////////////////////////////////////////////////////////////////////
  182. // Module Defintion
  183. // Name: mkUGBitStreamLFIFO
  184. // Description: Implementation of BitStreamFIFO interface
  185. //              with shifters, methods enq/deq are unguarded, 
  186. //              user of this module needs to check usage and free 
  187. //              explicitly to guarantee correctness, free returns
  188. //              the value after deq  
  189. // Schedule: enq CF {first, deq, usage, free}
  190. //           enq SB clear
  191. //           enq C  enq
  192. //           first CF {enq, first, deq, usage ,free}
  193. //           first SB clear
  194. //           deq CF {enq, first, usage}
  195. //           deq SB {free, clear}
  196. //           deq C  deq
  197. //           clear SB clear
  198. //           clear SA {enq, first, deq, usage, free}
  199. //           usage CF {enq, first, deq, usage, free}
  200. //           usage SB clear
  201. //           free CF {enq, first, usage, free}
  202. //           free SB clear
  203. //           free SA deq              
  204. ///////////////////////////////////////////////////////////////////
  205. module mkUGBitStreamLFIFO(BitStreamFIFO#(buf_sz,buf_bsz,io_sz,io_bsz,io_data_sz))
  206.    provisos (Add#(buf_sz,1,buf_szp1),
  207.              Log#(buf_szp1,buf_bsz),   // Bit#(buf_bsz) ranges 0-buf_sz
  208.              Add#(io_sz,1,io_szp1),
  209.              Log#(io_szp1,io_bsz),     // Bit#(io_bsz) ranges 0-io_sz
  210.              Add#(xxA,io_bsz,buf_bsz), // io_bsz < buf_bsz
  211.              Add#(io_sz,xxB,buf_sz));  // io_sz < buf_sz 
  212.    
  213.    Bit#(buf_bsz) maxIdx = fromInteger(valueOf(buf_sz));
  214.    Reg#(Vector#(buf_sz,Bit#(io_data_sz))) buffers <- mkReg(newVector);
  215.    Reg#(Bit#(buf_bsz)) freeNo <- mkReg(maxIdx);
  216.    Reg#(Bit#(buf_bsz)) useNo  <- mkReg(0);
  217.    Wire#(Bit#(io_bsz)) subFree <- mkDWire(0);
  218.    Wire#(Bit#(io_bsz)) addFree <- mkDWire(0);
  219.    Bit#(io_bsz) addUse = subFree;
  220.    Bit#(io_bsz) subUse = addFree;
  221.    Wire#(Vector#(buf_sz,Bit#(io_data_sz))) newBuffers <- mkDWire(buffers);
  222.    
  223.    // adjust the freeNo dependings on whether enq/deq has been called
  224.    rule updateFreeNo(True);
  225.       freeNo <= freeNo + zeroExtend(addFree) - zeroExtend(subFree);
  226.       useNo <= useNo + zeroExtend(addUse) - zeroExtend(subUse);
  227.       buffers <= newBuffers;
  228.    endrule
  229.    
  230.    method Action enq(Bit#(io_bsz) i_b,Vector#(io_sz,Bit#(io_data_sz)) i_data);
  231.       let extBuffers  = append(buffers,i_data);     // append i_data at the end of buffers
  232.       let shftBuffers = shiftRight(extBuffers,i_b); // shift the extended buffers by i_b elements    
  233.       newBuffers <= take(shftBuffers);              // save back the data
  234.       subFree <= i_b;                               // add i_b to freeNo
  235.    endmethod
  236.    
  237.    method Vector#(io_sz,Bit#(io_data_sz)) first(); 
  238.       // shift the data so that first bit at lsb
  239.       let shftBuffers = shiftRight(buffers,freeNo);
  240.       return take(shftBuffers);
  241.    endmethod
  242.    
  243.    method Action deq(Bit#(io_bsz) o_b);
  244.       addFree <= o_b; // add o_b to freeNo
  245.    endmethod
  246.    
  247.    method Action clear();
  248.       freeNo <= maxIdx;   // reset freeNo
  249.    endmethod
  250.    
  251.    method Bit#(buf_bsz) usage();
  252.       return useNo;
  253.    endmethod
  254.    
  255.    method Bit#(buf_bsz) free();
  256.       return freeNo + zeroExtend(addFree);
  257.    endmethod
  258.    
  259. endmodule