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

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 Controls::*;
  27. import DataTypes::*;
  28. import FIFO::*;
  29. import GetPut::*;
  30. import Interfaces::*;
  31. import StreamFIFO::*;
  32. import Vector::*;
  33. import VectorLibrary::*;
  34. typedef Vector#(r_sz,DepunctData#(c_sz))
  35.    Depunct2DVec#(numeric type r_sz,
  36.  numeric type c_sz);
  37. // for generating parallel functions
  38. function DepunctData#(fo_sz)
  39.    parDepunctFunc(function DepunctData#(o_sz) func(DepunctData#(i_sz) x),
  40.   DepunctData#(fi_sz) xs)
  41.    provisos (Mul#(f_sz,i_sz,fi_sz),
  42.      Mul#(f_sz,o_sz,fo_sz));
  43.    Integer fSz = valueOf(f_sz);
  44.    Depunct2DVec#(f_sz,i_sz) in2DVec = unpackVec(xs);
  45.    let out2DVec = map(func, in2DVec);
  46.    DepunctData#(fo_sz) outVec = packVec(out2DVec);
  47.    return outVec;
  48. endfunction   
  49.    
  50. // mkPuncturer using streamFIFO
  51. // in_buf_sz > in_sz + Max(in_sz mod {f1/f2/f3}_in_sz)
  52. // out_buf_sz > Max({f1/f2/f3}_out_sz + ({f1/f2/f3}_out_sz mod out_sz)) 
  53. module mkDepuncturer#(function PuncturerCtrl
  54.          depuncturerCtrl(ctrl_t rate),
  55.       function DepunctData#(f1_out_sz) 
  56.          twoThird(DepunctData#(f1_in_sz) x),
  57.       function DepunctData#(f2_out_sz)
  58.          threeFourth(DepunctData#(f2_in_sz) x),
  59.       function DepunctData#(f3_out_sz) 
  60.          fiveSixth(DepunctData#(f3_in_sz) x))
  61.    (Depuncturer#(ctrl_t, in_sz, out_sz, in_buf_sz, out_buf_sz))
  62.    provisos (Mul#(f1_sz,3,f1_in_sz),
  63.      Mul#(f2_sz,4,f2_in_sz),
  64.      Mul#(f3_sz,6,f3_in_sz),
  65.      Add#(xxA,in_sz,in_buf_sz),
  66.      Add#(xxB,f1_in_sz,in_buf_sz),
  67.      Add#(xxC,f2_in_sz,in_buf_sz),
  68.              Add#(xxD,f3_in_sz,in_buf_sz),
  69.      Mul#(f1_sz,4,f1_out_sz),
  70.      Mul#(f2_sz,6,f2_out_sz),
  71.      Mul#(f3_sz,10,f3_out_sz),
  72.      Add#(xxE,out_sz,out_buf_sz),
  73.      Add#(xxF,in_sz,out_buf_sz),
  74.      Add#(xxG,f1_out_sz,out_buf_sz),
  75.      Add#(xxH,f2_out_sz,out_buf_sz),
  76.      Add#(xxI,f3_out_sz,out_buf_sz),
  77.      Bits#(ctrl_t,ctrl_sz),
  78.      Add#(in_buf_sz,1,in_buf_sz_p_1),
  79.      Log#(in_buf_sz_p_1,in_s_sz),
  80.      Add#(out_buf_sz,1,out_buf_sz_p_1),
  81.      Log#(out_buf_sz_p_1,out_s_sz),
  82.      Eq#(ctrl_t));
  83.        
  84.    // constants
  85.    Bit#(in_s_sz) inSz = fromInteger(valueOf(in_sz));
  86.    Bit#(in_s_sz) f0InSz = inSz;
  87.    Bit#(in_s_sz) f1InSz = fromInteger(valueOf(f1_in_sz));
  88.    Bit#(in_s_sz) f2InSz = fromInteger(valueOf(f2_in_sz));
  89.    Bit#(in_s_sz) f3InSz = fromInteger(valueOf(f3_in_sz));
  90.    Bit#(out_s_sz) outSz = fromInteger(valueOf(out_sz));
  91.    Bit#(out_s_sz) f0OutSz = fromInteger(valueOf(in_sz));        
  92.    Bit#(out_s_sz) f1OutSz = fromInteger(valueOf(f1_out_sz));
  93.    Bit#(out_s_sz) f2OutSz = fromInteger(valueOf(f2_out_sz));
  94.    Bit#(out_s_sz) f3OutSz = fromInteger(valueOf(f3_out_sz));
  95.        
  96.    // state elements
  97.    Reg#(ctrl_t) lastCtrl <- mkRegU;
  98.    FIFO#(DecoderMesg#(ctrl_t,in_sz,ViterbiMetric)) inQ <- mkLFIFO;
  99.    FIFO#(DecoderMesg#(ctrl_t,out_sz,ViterbiMetric)) outQ <- mkSizedFIFO(2);
  100.    StreamFIFO#(in_buf_sz,in_s_sz,ViterbiMetric) inStreamQ <- mkStreamLFIFO;
  101.    StreamFIFO#(out_buf_sz,out_s_sz,ViterbiMetric) outStreamQ <- mkStreamLFIFO;
  102.       
  103.    let inMsg = inQ.first;
  104.    let inCtrl = inMsg.control;
  105.    let inData = inMsg.data;
  106.    let inPCtrl = depuncturerCtrl(inCtrl);   
  107.    let lastPCtrl = depuncturerCtrl(lastCtrl);
  108.    match {.fInSz, .fOutSz} = case (lastPCtrl)
  109. Half: tuple2(f0InSz, f0OutSz);
  110. TwoThird: tuple2(f1InSz,f1OutSz);
  111. ThreeFourth: tuple2(f2InSz,f2OutSz);
  112. FiveSixth: tuple2(f3InSz,f3OutSz);
  113.      endcase; 
  114.    let canEnqInStreamQ = inStreamQ.notFull(inSz);
  115.    let canDeqInStreamQ = inStreamQ.notEmpty(fInSz);
  116.    let canEnqOutStreamQ = outStreamQ.notFull(fOutSz);
  117.    let canDeqOutStreamQ = outStreamQ.notEmpty(outSz); 
  118.    
  119.    rule enqInStreamQ(canEnqInStreamQ && (lastCtrl == inCtrl || (!canDeqInStreamQ && !canDeqOutStreamQ)));
  120.       if (lastCtrl != inCtrl)
  121.  lastCtrl <= inCtrl;
  122.       inQ.deq;
  123.       inStreamQ.enq(inSz,append(inData,newVector));
  124.    endrule
  125.    rule puncture(canDeqInStreamQ && canEnqOutStreamQ);
  126.       let data = inStreamQ.first;
  127.       case (lastPCtrl)
  128.  Half:
  129.  begin
  130.     DepunctData#(in_sz) f0InData = take(data);
  131.     DepunctData#(out_buf_sz) f0OutData = append(f0InData,newVector);
  132.     inStreamQ.deq(f0InSz);
  133.     outStreamQ.enq(f0OutSz,f0OutData);
  134.  end
  135.  TwoThird:
  136.  begin
  137.     DepunctData#(f1_in_sz) f1InData = take(data);
  138.     DepunctData#(out_buf_sz) f1OutData = append(twoThird(f1InData),newVector);
  139.     inStreamQ.deq(f1InSz);
  140.     outStreamQ.enq(f1OutSz,f1OutData);
  141.  end
  142.  ThreeFourth:
  143.  begin
  144.     DepunctData#(f2_in_sz) f2InData = take(data);
  145.     DepunctData#(out_buf_sz) f2OutData = append(threeFourth(f2InData),newVector);
  146.     inStreamQ.deq(f2InSz);
  147.     outStreamQ.enq(f2OutSz,f2OutData);
  148.  end
  149.  FiveSixth:
  150.  begin
  151.     DepunctData#(f3_in_sz) f3InData = take(data);
  152.     DepunctData#(out_buf_sz) f3OutData = append(fiveSixth(f3InData),newVector);
  153.     inStreamQ.deq(f3InSz);
  154.     outStreamQ.enq(f3OutSz,f3OutData);
  155.  end
  156.       endcase
  157.    endrule
  158.        
  159.    rule deqOutStreamQ(canDeqOutStreamQ);
  160.       DepunctData#(out_sz) outData = take(outStreamQ.first);
  161.       let outMsg = Mesg { control: lastCtrl,
  162.   data: outData};
  163.       outStreamQ.deq(outSz);
  164.       outQ.enq(outMsg);
  165.    endrule
  166.    
  167.    interface Put in = fifoToPut(inQ);
  168.    interface Get out = fifoToGet(outQ);
  169.    
  170. endmodule   
  171.