⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 txcontroller.bsv

📁 MIT关于OFDM收发器、WIFI收发器的ASIC和 FPGA硬件开发源码及资料
💻 BSV
字号:
//----------------------------------------------------------------------//// The MIT License // // Copyright (c) 2007 Alfred Man Cheuk Ng, mcn02@mit.edu // // Permission is hereby granted, free of charge, to any person // obtaining a copy of this software and associated documentation // files (the "Software"), to deal in the Software without // restriction, including without limitation the rights to use,// copy, modify, merge, publish, distribute, sublicense, and/or sell// copies of the Software, and to permit persons to whom the// Software is furnished to do so, subject to the following conditions:// // The above copyright notice and this permission notice shall be// included in all copies or substantial portions of the Software.// // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES// OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT// HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,// WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR// OTHER DEALINGS IN THE SOFTWARE.//----------------------------------------------------------------------//import Connectable::*;import FIFO::*;import GetPut::*;import Vector::*;import Controls::*;import DataTypes::*;import Interfaces::*;import LibraryFunctions::*;import Parameters::*;import StreamFIFO::*;typedef struct{   Bit#(12) length;  // data to send in bytes   Rate     rate;    // data rate    Bit#(16) service; // service bits, should be all 0s   Bit#(3)  power;   // transmit power level (not affecting baseband)} TXVector deriving (Eq, Bits);typedef enum{ SendHeader, EnqService, SendData, SendPadding }        TXState deriving (Eq, Bits);interface TXController;   method Action txStart(TXVector txVec);   method Action txData(Bit#(8) inData);   method Action txEnd();   interface Get#(ScramblerMesg#(TXScramblerAndGlobalCtrl,				 ScramblerDataSz)) out;endinterface      function Bit#(24) makeHeader(TXVector txVec);      Bit#(4) translate_rate = case (txVec.rate)   //somehow checking rate directly doesn't work				  R0: 4'b1011;				  R1: 4'b1111;				  R2: 4'b1010; 				  R3: 4'b1110;				  R4: 4'b1001;				  R5: 4'b1101;				  R6: 4'b1000;				  R7: 4'b1100;			       endcase; // case(r)          Bit#(1)  parity = getParity({translate_rate,txVec.length});      Bit#(24) data = {6'b0,parity,txVec.length,1'b0,translate_rate};      return data;   endfunction// get maximum number of padding (basic unit is bit) required for each ratefunction Bit#(8) maxPadding(Rate rate);   Bit#(8) scramblerDataSz = fromInteger(valueOf(ScramblerDataSz)); // must be a factor of 12   return case (rate)	     R0: 24 - scramblerDataSz;	     R1: 36 - scramblerDataSz;	     R2: 48 - scramblerDataSz; 	     R3: 72 - scramblerDataSz;	     R4: 96 - scramblerDataSz;	     R5: 144 - scramblerDataSz;	     R6: 192 - scramblerDataSz;	     R7: 216 - scramblerDataSz;	  endcase;endfunction      function ScramblerMesg#(TXScramblerAndGlobalCtrl,ScramblerDataSz)   makeMesg(Bit#(ScramblerDataSz) bypass,	    Maybe#(Bit#(ScramblerShifterSz)) seed,	    Bool firstSymbol,	    Rate rate,	    Bit#(ScramblerDataSz) data);   let sCtrl = TXScramblerCtrl{bypass: bypass,			       seed: seed};   let gCtrl = TXGlobalCtrl{firstSymbol: firstSymbol,			    rate: rate};   let ctrl = TXScramblerAndGlobalCtrl{scramblerCtrl: sCtrl,				       globalCtrl: gCtrl};   let mesg = Mesg{control:ctrl, data:data};   return mesg;endfunction(* synthesize *)module mkTXController(TXController);      //state elements   Reg#(Bool)                 busy <- mkReg(False);   Reg#(TXState)           txState <- mkRegU;   Reg#(Bit#(5))          sfifoRem <- mkRegU;   Reg#(Bit#(8))             count <- mkRegU;   Reg#(Bool)              rstSeed <- mkRegU;   Reg#(Bool)              addTail <- mkRegU;   Reg#(Bool)              addZero <- mkRegU;   Reg#(TXVector)         txVector <- mkRegU;   StreamFIFO#(24,5,Bit#(1)) sfifo <- mkStreamLFIFO; // size >= 16   FIFO#(ScramblerMesg#(TXScramblerAndGlobalCtrl,ScramblerDataSz)) outQ;   outQ <- mkSizedFIFO(2);      // constants   let sfifo_usage = sfifo.usage;   let sfifo_free  = sfifo.free;   Bit#(5) scramblerDataSz = fromInteger(valueOf(ScramblerDataSz));   // rules   rule sendHeader(busy && txState == SendHeader && sfifo.usage >= scramblerDataSz);      Bit#(ScramblerDataSz) bypass = maxBound;       let seed = tagged Invalid;      let fstSym = True;      let rate = R0;      Bit#(ScramblerDataSz) data = pack(take(sfifo.first));      let mesg = makeMesg(bypass,seed,fstSym,rate,data);      outQ.enq(mesg);      sfifo.deq(scramblerDataSz);      if (sfifo.usage == scramblerDataSz)	 begin	    txState <= EnqService;	 end      rstSeed <= True;      addTail <= True;      addZero <= True;      $display("TXCtrl fires sendHeader");   endrule      rule enqService(busy && txState == EnqService);      sfifo.enq(16,append(unpack(txVector.service),replicate(0)));      rstSeed <= True;      txState <= SendData;      $display("TXCtrl fires enqService");   endrule      rule sendData(busy && txState == SendData && 		 sfifo_usage >= scramblerDataSz && 		 addZero);      Bit#(ScramblerDataSz) bypass = 0;      let seed = rstSeed ?                  tagged Valid 'b1101001 :                  tagged Invalid;      let fstSym = False;      let rate = txVector.rate;      Bit#(ScramblerDataSz) data = pack(take(sfifo.first));      let mesg = makeMesg(bypass,seed,fstSym,rate,data);      outQ.enq(mesg);      sfifo.deq(scramblerDataSz);      count <= (count == 0) ?                maxPadding(txVector.rate) :                count - zeroExtend(scramblerDataSz);      rstSeed <= False;      $display("TXCtrl fires sendData");   endrule        rule insTail(busy && txState == SendData &&		sfifo_usage < scramblerDataSz && 		txVector.length == 0 && addTail &&		addZero);       sfifo.enq(6,replicate(0));      addTail <= False;      $display("TXCtrl fires insTail");   endrule      rule insZero(busy && txState == SendData &&		sfifo_usage < scramblerDataSz && 		!addTail && addZero);       let enqSz = scramblerDataSz - sfifo_usage;      if (sfifo_usage > 0) // only add zero when usage > 0	 sfifo.enq(enqSz,replicate(0));      addZero <= False;      $display("TXCtrl fires insZero");   endrule         rule sendLast(busy && txState == SendData &&		 !addZero);      Bit#(ScramblerDataSz) bypass = 0;      let seed = tagged Invalid;      let fstSym = False;      let rate = txVector.rate;      Bit#(ScramblerDataSz) data = truncate(pack(sfifo.first));      let mesg = makeMesg(bypass,seed,fstSym,rate,data);      if (sfifo_usage > 0) // only send if usage > 0	 begin	    outQ.enq(mesg);	    sfifo.deq(sfifo_usage);	    count <= (count == 0) ?                      maxPadding(txVector.rate) : 		     count - zeroExtend(scramblerDataSz);	 end      txState <= SendPadding;      $display("TXCtrl fires sendLast");   endrule      rule sendPadding(busy && txState == SendPadding && count > 0);      Bit#(ScramblerDataSz) bypass = 0;      let seed = tagged Invalid;      let fstSym = False;      let rate = txVector.rate;      Bit#(ScramblerDataSz) data = 0;      let mesg = makeMesg(bypass,seed,fstSym,rate,data);      outQ.enq(mesg);      count <= count - zeroExtend(scramblerDataSz);      $display("TXCtrl fires sendPadding");         endrule      rule becomeIdle(busy && txState == SendPadding && count == 0);      busy <= False;      $display("TXCtrl fires becomeIdle");   endrule      // methods   method Action txStart(TXVector txVec) if (!busy);      txVector <= txVec;      busy <= True;      txState <= SendHeader;      count <= 0;      sfifo.enq(24,append(unpack(makeHeader(txVec)),replicate(0)));      $display("TXCtrl fires txStart");   endmethod      method Action txData(Bit#(8) inData)       if (busy && txState == SendData && sfifo_free >= 8 &&	  txVector.length > 0);      sfifo.enq(8,append(unpack(inData),replicate(0)));      txVector <= TXVector{rate: txVector.rate,			   length: txVector.length - 1,			   service: txVector.service,			   power: txVector.power};      $display("TXCtrl fires txData");   endmethod      method Action txEnd();      busy <= False;      sfifo.clear;   endmethod	       interface out = fifoToGet(outQ);   endmodule 

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -