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

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 Vector::*;
  27. interface ShiftRegs#(numeric type size, type data_t);
  28.   method Action enq(data_t x);              // put the element at the last position of the queue 
  29.   method data_t first();                    // get the first element of the queue
  30.   method Action clear();                    // clear all elements in the queue
  31.   method Vector#(size, data_t) getVector(); // return a snapshot of the queue
  32. endinterface
  33. // shift reg approach 
  34. module mkShiftRegs (ShiftRegs#(size,data_t))
  35.   provisos (Bits#(data_t,data_w));
  36.    // states
  37.    Vector#(size, Reg#(data_t)) vRegs <- Vector::replicateM(mkReg(unpack(0)));
  38.    // constants
  39.    let maxIndex = valueOf(size) - 1;
  40.    method Action enq(x);
  41.    begin
  42.       (vRegs[maxIndex])._write(x);
  43.       for (Integer i = 0; i < maxIndex; i = i + 1)
  44. (vRegs[fromInteger(i)])._write((vRegs[fromInteger(i)+1])._read);
  45.    end
  46.    endmethod
  47.      
  48.    method data_t first();
  49.    begin
  50.       return (vRegs[0])._read;
  51.    end
  52.    endmethod
  53.    
  54.    method Action clear();
  55.    begin
  56.       for (Integer i = 0; i <= maxIndex; i = i + 1)
  57. (vRegs[fromInteger(i)])._write(unpack(0));
  58.    end
  59.    endmethod
  60.    method Vector#(size, data_t) getVector();
  61.    begin
  62.       Vector#(size, data_t) resultV = newVector();
  63.       for (Integer i = 0; i <= maxIndex; i = i + 1)
  64. resultV[fromInteger(i)] = (vRegs[fromInteger(i)])._read(); // oldest element come first
  65.       return resultV;
  66.    end
  67.    endmethod
  68.       
  69. endmodule // mkDelay
  70. // circular pointer approach, note that getVector doesn't work correctly in this design
  71. module mkCirShiftRegs (ShiftRegs#(size,data_t))
  72.   provisos (Bits#(data_t,data_w), 
  73.     Log#(size, index_w));   
  74.    // states
  75.    Vector#(size, Reg#(data_t)) vRegs <- Vector::replicateM(mkReg(unpack(0)));
  76.    Reg#(Bit#(index_w))   nextToWrite <- mkRegU;
  77.    
  78.    // constants
  79.    Integer maxIndex = valueOf(size) - 1;
  80.    Bit#(index_w) maxIdx = fromInteger(maxIndex);
  81.    Bit#(index_w) nextToRead = nextToWrite;
  82.    
  83.    // functions
  84.    function Bit#(index_w) incr (Bit#(index_w) n);
  85.       let result = (n == maxIdx) ? 0 : n + 1;
  86.       return result;
  87.    endfunction // Bit
  88.    method Action enq(x);
  89.       (vRegs[nextToWrite])._write(x);
  90.       nextToWrite <= incr(nextToWrite);
  91.    endmethod
  92.      
  93.    method data_t first();
  94.       return (vRegs[nextToRead])._read;
  95.    endmethod
  96.    
  97.    method Action clear();
  98.       for (Integer i = 0; i <= maxIndex; i = i + 1)
  99. (vRegs[fromInteger(i)])._write(unpack(0));
  100.    endmethod
  101.    method Vector#(size, data_t) getVector();
  102.       Vector#(size, data_t) outVec = newVector;
  103.       Bit#(index_w) idx = nextToWrite;
  104.       for (Integer i = 0; i <= maxIndex; i = i + 1)
  105. begin
  106.    outVec[i] = (vRegs[idx])._read;
  107.    idx = incr(idx);
  108. end
  109.       return outVec;
  110.    endmethod
  111.       
  112. endmodule // mkDelay
  113. // circular pointer approach, note that getVector doesn't work correctly in this design
  114. module mkCirShiftRegsNoGetVec (ShiftRegs#(size,data_t))
  115.   provisos (Bits#(data_t,data_w), 
  116.     Log#(size, index_w));   
  117.    // states
  118.    Vector#(size, Reg#(data_t)) vRegs <- Vector::replicateM(mkReg(unpack(0)));
  119.    Reg#(Bit#(index_w))   nextToWrite <- mkRegU;
  120.    
  121.    // constants
  122.    Integer maxIndex = valueOf(size) - 1;
  123.    Bit#(index_w) maxIdx = fromInteger(maxIndex);
  124.    Bit#(index_w) nextToRead = nextToWrite;
  125.    // functions
  126.    function Bit#(index_w) incr (Bit#(index_w) n);
  127.       let result = (n == maxIdx) ? 0 : n + 1;
  128.       return result;
  129.    endfunction // Bit
  130.    
  131.    method Action enq(x);
  132.       (vRegs[nextToWrite])._write(x);
  133.       nextToWrite <= incr(nextToWrite);
  134.    endmethod
  135.      
  136.    method data_t first();
  137.       return (vRegs[nextToRead])._read;
  138.    endmethod
  139.    
  140.    method Action clear();
  141.       for (Integer i = 0; i <= maxIndex; i = i + 1)
  142. (vRegs[fromInteger(i)])._write(unpack(0));
  143.    endmethod
  144.    method Vector#(size, data_t) getVector();
  145.       return newVector;
  146.    endmethod
  147.       
  148. endmodule // mkDelay