TXController.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 Connectable::*;
  27. import FIFO::*;
  28. import GetPut::*;
  29. import Vector::*;
  30. import Controls::*;
  31. import DataTypes::*;
  32. import Interfaces::*;
  33. import LibraryFunctions::*;
  34. import Parameters::*;
  35. import StreamFIFO::*;
  36. typedef struct{
  37.    Bit#(12) length;  // data to send in bytes
  38.    Rate     rate;    // data rate 
  39.    Bit#(16) service; // service bits, should be all 0s
  40.    Bit#(3)  power;   // transmit power level (not affecting baseband)
  41. } TXVector deriving (Eq, Bits);
  42. typedef enum{ SendHeader, EnqService, SendData, SendPadding }
  43.         TXState deriving (Eq, Bits);
  44. interface TXController;
  45.    method Action txStart(TXVector txVec);
  46.    method Action txData(Bit#(8) inData);
  47.    method Action txEnd();
  48.    interface Get#(ScramblerMesg#(TXScramblerAndGlobalCtrl,
  49.  ScramblerDataSz)) out;
  50. endinterface
  51.       
  52. function Bit#(24) makeHeader(TXVector txVec);
  53.       Bit#(4) translate_rate = case (txVec.rate)   //somehow checking rate directly doesn't work
  54.   R0: 4'b1011;
  55.   R1: 4'b1111;
  56.   R2: 4'b1010; 
  57.   R3: 4'b1110;
  58.   R4: 4'b1001;
  59.   R5: 4'b1101;
  60.   R6: 4'b1000;
  61.   R7: 4'b1100;
  62.        endcase; // case(r)    
  63.       Bit#(1)  parity = getParity({translate_rate,txVec.length});
  64.       Bit#(24) data = {6'b0,parity,txVec.length,1'b0,translate_rate};
  65.       return data;   
  66. endfunction
  67. // get maximum number of padding (basic unit is bit) required for each rate
  68. function Bit#(8) maxPadding(Rate rate);
  69.    Bit#(8) scramblerDataSz = fromInteger(valueOf(ScramblerDataSz)); // must be a factor of 12
  70.    return case (rate)
  71.      R0: 24 - scramblerDataSz;
  72.      R1: 36 - scramblerDataSz;
  73.      R2: 48 - scramblerDataSz; 
  74.      R3: 72 - scramblerDataSz;
  75.      R4: 96 - scramblerDataSz;
  76.      R5: 144 - scramblerDataSz;
  77.      R6: 192 - scramblerDataSz;
  78.      R7: 216 - scramblerDataSz;
  79.   endcase;
  80. endfunction      
  81. function ScramblerMesg#(TXScramblerAndGlobalCtrl,ScramblerDataSz)
  82.    makeMesg(Bit#(ScramblerDataSz) bypass,
  83.     Maybe#(Bit#(ScramblerShifterSz)) seed,
  84.     Bool firstSymbol,
  85.     Rate rate,
  86.     Bit#(ScramblerDataSz) data);
  87.    let sCtrl = TXScramblerCtrl{bypass: bypass,
  88.        seed: seed};
  89.    let gCtrl = TXGlobalCtrl{firstSymbol: firstSymbol,
  90.     rate: rate};
  91.    let ctrl = TXScramblerAndGlobalCtrl{scramblerCtrl: sCtrl,
  92.        globalCtrl: gCtrl};
  93.    let mesg = Mesg{control:ctrl, data:data};
  94.    return mesg;
  95. endfunction
  96. (* synthesize *)
  97. module mkTXController(TXController);
  98.    
  99.    //state elements
  100.    Reg#(Bool)                 busy <- mkReg(False);
  101.    Reg#(TXState)           txState <- mkRegU;
  102.    Reg#(Bit#(5))          sfifoRem <- mkRegU;
  103.    Reg#(Bit#(8))             count <- mkRegU;
  104.    Reg#(Bool)              rstSeed <- mkRegU;
  105.    Reg#(Bool)              addTail <- mkRegU;
  106.    Reg#(Bool)              addZero <- mkRegU;
  107.    Reg#(TXVector)         txVector <- mkRegU;
  108.    StreamFIFO#(24,5,Bit#(1)) sfifo <- mkStreamLFIFO; // size >= 16
  109.    FIFO#(ScramblerMesg#(TXScramblerAndGlobalCtrl,ScramblerDataSz)) outQ;
  110.    outQ <- mkSizedFIFO(2);
  111.    
  112.    // constants
  113.    let sfifo_usage = sfifo.usage;
  114.    let sfifo_free  = sfifo.free;
  115.    Bit#(5) scramblerDataSz = fromInteger(valueOf(ScramblerDataSz));
  116.    // rules
  117.    rule sendHeader(busy && txState == SendHeader && sfifo.usage >= scramblerDataSz);
  118.       Bit#(ScramblerDataSz) bypass = maxBound; 
  119.       let seed = tagged Invalid;
  120.       let fstSym = True;
  121.       let rate = R0;
  122.       Bit#(ScramblerDataSz) data = pack(take(sfifo.first));
  123.       let mesg = makeMesg(bypass,seed,fstSym,rate,data);
  124.       outQ.enq(mesg);
  125.       sfifo.deq(scramblerDataSz);
  126.       if (sfifo.usage == scramblerDataSz)
  127.  begin
  128.     txState <= EnqService;
  129.  end
  130.       rstSeed <= True;
  131.       addTail <= True;
  132.       addZero <= True;
  133.       $display("TXCtrl fires sendHeader");
  134.    endrule
  135.    
  136.    rule enqService(busy && txState == EnqService);
  137.       sfifo.enq(16,append(unpack(txVector.service),replicate(0)));
  138.       rstSeed <= True;
  139.       txState <= SendData;
  140.       $display("TXCtrl fires enqService");
  141.    endrule
  142.    
  143.    rule sendData(busy && txState == SendData && 
  144.  sfifo_usage >= scramblerDataSz && 
  145.  addZero);
  146.       Bit#(ScramblerDataSz) bypass = 0;
  147.       let seed = rstSeed ? 
  148.                  tagged Valid 'b1101001 : 
  149.                  tagged Invalid;
  150.       let fstSym = False;
  151.       let rate = txVector.rate;
  152.       Bit#(ScramblerDataSz) data = pack(take(sfifo.first));
  153.       let mesg = makeMesg(bypass,seed,fstSym,rate,data);
  154.       outQ.enq(mesg);
  155.       sfifo.deq(scramblerDataSz);
  156.       count <= (count == 0) ? 
  157.                maxPadding(txVector.rate) : 
  158.                count - zeroExtend(scramblerDataSz);
  159.       rstSeed <= False;
  160.       $display("TXCtrl fires sendData");
  161.    endrule
  162.      
  163.    rule insTail(busy && txState == SendData &&
  164. sfifo_usage < scramblerDataSz && 
  165. txVector.length == 0 && addTail &&
  166. addZero); 
  167.       sfifo.enq(6,replicate(0));
  168.       addTail <= False;
  169.       $display("TXCtrl fires insTail");
  170.    endrule
  171.    
  172.    rule insZero(busy && txState == SendData &&
  173. sfifo_usage < scramblerDataSz && 
  174. !addTail && addZero); 
  175.       let enqSz = scramblerDataSz - sfifo_usage;
  176.       if (sfifo_usage > 0) // only add zero when usage > 0
  177.  sfifo.enq(enqSz,replicate(0));
  178.       addZero <= False;
  179.       $display("TXCtrl fires insZero");
  180.    endrule   
  181.    
  182.    rule sendLast(busy && txState == SendData &&
  183.  !addZero);
  184.       Bit#(ScramblerDataSz) bypass = 0;
  185.       let seed = tagged Invalid;
  186.       let fstSym = False;
  187.       let rate = txVector.rate;
  188.       Bit#(ScramblerDataSz) data = truncate(pack(sfifo.first));
  189.       let mesg = makeMesg(bypass,seed,fstSym,rate,data);
  190.       if (sfifo_usage > 0) // only send if usage > 0
  191.  begin
  192.     outQ.enq(mesg);
  193.     sfifo.deq(sfifo_usage);
  194.     count <= (count == 0) ? 
  195.                      maxPadding(txVector.rate) : 
  196.      count - zeroExtend(scramblerDataSz);
  197.  end
  198.       txState <= SendPadding;
  199.       $display("TXCtrl fires sendLast");
  200.    endrule
  201.    
  202.    rule sendPadding(busy && txState == SendPadding && count > 0);
  203.       Bit#(ScramblerDataSz) bypass = 0;
  204.       let seed = tagged Invalid;
  205.       let fstSym = False;
  206.       let rate = txVector.rate;
  207.       Bit#(ScramblerDataSz) data = 0;
  208.       let mesg = makeMesg(bypass,seed,fstSym,rate,data);
  209.       outQ.enq(mesg);
  210.       count <= count - zeroExtend(scramblerDataSz);
  211.       $display("TXCtrl fires sendPadding");      
  212.    endrule
  213.    
  214.    rule becomeIdle(busy && txState == SendPadding && count == 0);
  215.       busy <= False;
  216.       $display("TXCtrl fires becomeIdle");
  217.    endrule
  218.    
  219.    // methods
  220.    method Action txStart(TXVector txVec) if (!busy);
  221.       txVector <= txVec;
  222.       busy <= True;
  223.       txState <= SendHeader;
  224.       count <= 0;
  225.       sfifo.enq(24,append(unpack(makeHeader(txVec)),replicate(0)));
  226.       $display("TXCtrl fires txStart");
  227.    endmethod
  228.    
  229.    method Action txData(Bit#(8) inData) 
  230.       if (busy && txState == SendData && sfifo_free >= 8 &&
  231.   txVector.length > 0);
  232.       sfifo.enq(8,append(unpack(inData),replicate(0)));
  233.       txVector <= TXVector{rate: txVector.rate,
  234.    length: txVector.length - 1,
  235.    service: txVector.service,
  236.    power: txVector.power};
  237.       $display("TXCtrl fires txData");
  238.    endmethod
  239.    
  240.    method Action txEnd();
  241.       busy <= False;
  242.       sfifo.clear;
  243.    endmethod
  244.     
  245.    interface out = fifoToGet(outQ);   
  246. endmodule