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

📄 rxcontroller.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 Complex::*;import Connectable::*;import FIFO::*;import GetPut::*;import Vector::*;import Controls::*;import DataTypes::*;import Interfaces::*;import LibraryFunctions::*;import Parameters::*;import StreamFIFO::*;typedef struct{   Rate     rate;   Bit#(12) length;} RXFeedback deriving (Bits, Eq);interface PreFFTRXController;   interface Put#(SPMesgFromSync#(UnserialOutDataSz,RXFPIPrec,RXFPFPrec))       inFromPreFFT;   interface Get#(FFTMesg#(RXGlobalCtrl,FFTIFFTSz,RXFPIPrec,RXFPFPrec))         outToPreDescrambler;   interface Put#(Maybe#(RXFeedback)) inFeedback;endinterfaceinterface PreDescramblerRXController;   interface Put#(DecoderMesg#(RXGlobalCtrl,ViterbiOutDataSz,Bit#(1)))          inFromPreDescrambler;   interface Get#(DescramblerMesg#(RXDescramblerAndGlobalCtrl,DescramblerDataSz))       outToDescrambler;   interface Get#(Maybe#(RXFeedback)) outFeedback;   interface Get#(Bit#(12))   outLength;endinterfaceinterface PostDescramblerRXController;   interface Put#(EncoderMesg#(RXDescramblerAndGlobalCtrl,DescramblerDataSz))                      inFromDescrambler;   interface Get#(Bit#(8))  outData;endinterface      interface RXController;   interface Put#(SPMesgFromSync#(UnserialOutDataSz,RXFPIPrec,RXFPFPrec))       inFromPreFFT;   interface Get#(FFTMesg#(RXGlobalCtrl,FFTIFFTSz,RXFPIPrec,RXFPFPrec))         outToPreDescrambler;   interface Put#(DecoderMesg#(RXGlobalCtrl,ViterbiOutDataSz,Bit#(1)))          inFromPreDescrambler;   interface Get#(DescramblerMesg#(RXDescramblerAndGlobalCtrl,DescramblerDataSz))       outToDescrambler;   interface Put#(EncoderMesg#(RXDescramblerAndGlobalCtrl,DescramblerDataSz))                      inFromDescrambler;   interface Get#(Bit#(12)) outLength;   interface Get#(Bit#(8))  outData;endinterface      typedef enum{   RX_IDLE,     // idle   RX_HEADER,   // decoding header   RX_HTAIL,    // sending zeros after header   RX_FEEDBACK, // waiting for feedback   RX_DATA,     // decoding data   RX_DTAIL     // sending zeros after data} RXCtrlState deriving(Eq,Bits);(* synthesize *)module mkPreFFTRXController(PreFFTRXController);   // state elements   FIFO#(FFTMesg#(RXGlobalCtrl,FFTIFFTSz,RXFPIPrec,RXFPFPrec)) outQ <- mkLFIFO;   Reg#(RXCtrlState) rxState <- mkReg(RX_IDLE); // the current state   Reg#(Bit#(3))     zeroCount <- mkRegU;       // count no of zeros symbol sent   Reg#(Rate)        rxRate <- mkRegU;          // the packet rate for receiving   Reg#(Bit#(16))    rxLength <- mkRegU;        // the remaining of data to be received (in terms of bits)      // constants   // data bis per ofdm symbol    Bit#(16) dbps = case (rxRate)		      R0: 24;		      R1: 36;		      R2: 48;		      R3: 72;		      R4: 96;		      R5: 144;		      R6: 192;		      R7: 216;		   endcase;      // rules   // send 2 extra symbol of zeros to push out data from vitebri (also reset the viterbi state)   rule sendZeros(rxState == RX_HTAIL || rxState == RX_DTAIL);      RXGlobalCtrl rxCtrl = RXGlobalCtrl{firstSymbol: False, 					 rate: R0};      Symbol#(FFTIFFTSz,RXFPIPrec,RXFPFPrec) zeroSymbol = replicate(cmplx(0,0));      outQ.enq(FFTMesg{control:rxCtrl, data: zeroSymbol});      if (zeroCount < 4)	 begin	    zeroCount <= zeroCount + 1;	 end      else	 begin	    rxState <= (rxState == RX_HTAIL) ? RX_FEEDBACK : RX_IDLE;	 end      $display("PreFFTRXCtrllr sendZeros rxState:%d rxLength:%d",rxState,rxLength);   endrule       // interface methods   interface Put inFromPreFFT;      method Action put(SPMesgFromSync#(UnserialOutDataSz,RXFPIPrec,RXFPFPrec) mesg) 	 if (rxState != RX_HTAIL && rxState != RX_DTAIL && rxState != RX_FEEDBACK);	 case (rxState)	    RX_IDLE: 	    begin	       if (mesg.control) // only process if it is a new packet, otherwise, drop it		  begin			     zeroCount <= 0;		     RXGlobalCtrl rxCtrl = RXGlobalCtrl{firstSymbol: True, 							rate: R0};		     outQ.enq(FFTMesg{control:rxCtrl, data: mesg.data});		     rxState <= RX_HTAIL;		  end  	       end	    RX_DATA:	    begin	       RXGlobalCtrl rxCtrl = RXGlobalCtrl{firstSymbol: False, 						  rate: rxRate};	       outQ.enq(FFTMesg{control:rxCtrl, data: mesg.data});	       if (rxLength <= dbps) // last symbol		  begin		     rxState <= RX_DTAIL;		     zeroCount <= 0;		  end	       else		  begin		     rxLength <= rxLength - dbps;		  end	    end	 endcase	 $display("PreFFTRXCtrllr inFromPreFFT rxState:%d rxLength:%d",rxState,rxLength);      endmethod   endinterface    interface Put inFeedback;      method Action put(Maybe#(RXFeedback) feedback) if (rxState == RX_FEEDBACK);	 if (isValid(feedback)) // set the packet parameter	    begin	       let packetInfo = fromMaybe(?,feedback);	       rxState <= RX_DATA;	       rxRate  <= packetInfo.rate; 	       rxLength <= ((zeroExtend(packetInfo.length) + 2) << 3) + 6; // no of bits to be received = (16+8*length+6) 	    end	 else // error in decoding package, return to idle	    begin	       rxState <= RX_IDLE; 	    end	 $display("PreFFTRXCtrllr inFeedback rxState:%d rxLength:%d",rxState,rxLength);      endmethod   endinterface   interface outToPreDescrambler = fifoToGet(outQ);endmodule(* synthesize *)module mkPreDescramblerRXController(PreDescramblerRXController);   // state elements   FIFO#(DecoderMesg#(RXGlobalCtrl,ViterbiOutDataSz,Bit#(1))) inMesgQ <- mkLFIFO;   FIFO#(DescramblerMesg#(RXDescramblerAndGlobalCtrl,DescramblerDataSz)) outMesgQ <- mkLFIFO;   FIFO#(Maybe#(RXFeedback)) outFeedbackQ <- mkLFIFO;   FIFO#(Bit#(12))           outLengthQ <- mkLFIFO;   StreamFIFO#(24,5,Bit#(1)) streamQ <- mkStreamLFIFO;   Reg#(RXCtrlState)         rxState <- mkReg(RX_DATA);   Reg#(Bit#(3))             zeroCount <- mkReg(0);   Reg#(Bool)                isGetSeed <- mkReg(False);   Reg#(Maybe#(Bit#(ScramblerShifterSz))) seed <- mkReg(tagged Invalid);   Reg#(Bit#(12))            rxLength <- mkRegU;   // constants   Bit#(5) vOutSz = fromInteger(valueOf(ViterbiOutDataSz));   Bit#(5) dInSz  = fromInteger(valueOf(DescramblerDataSz));   let streamQ_usage = streamQ.usage;   let streamQ_free  = streamQ.free;      // functions   function Rate getRate(Bit#(24) header);      return case (header[3:0])		4'b1011: R0;		4'b1111: R1;		4'b1010: R2; 		4'b1110: R3;		4'b1001: R4;		4'b1101: R5;		4'b1000: R6;		4'b1100: R7;		default: R0;	     endcase;   endfunction      function Bit#(12) getLength(Bit#(24) header);      return header[16:5];   endfunction      function Bool checkParity(Bit#(24) header);      return header[17:17] == getParity(header[16:0]);   endfunction      // rules   rule decodeHeader(rxState == RX_HEADER && streamQ_usage >= 24);      let header = pack(streamQ.first);      if (checkParity(header))	 begin	    let rate = getRate(header);	    let length = getLength(header);	    outFeedbackQ.enq(tagged Valid RXFeedback{rate:rate,						     length:length});	    outLengthQ.enq(length);	    isGetSeed <= True;	    rxLength <= length;	 end      else	 begin	    outFeedbackQ.enq(tagged Invalid);	 end      rxState <= RX_HTAIL;      streamQ.deq(24);      $display("PreDescramblerRXCtrllr decodeHeader rxState:%d rxLength:%d",rxState,rxLength);   endrule      // skip 2 symbols of zeros   rule skipZeros(rxState == RX_HTAIL && streamQ_usage >= 24);      streamQ.deq(24);      if (zeroCount < 4)	 begin	    zeroCount <= zeroCount + 1;	 end      else	 begin	    rxState <= RX_DATA;	 end      $display("PreDescramblerRXCtrllr skipZeros rxState:%d rxLength:%d",rxState,rxLength);   endrule      rule getSeed(rxState == RX_DATA && isGetSeed && streamQ_usage >= 12);      seed <= tagged Valid (reverseBits((pack(streamQ.first))[11:5]));      isGetSeed <= False;      streamQ.deq(12);      $display("PreDescramblerRXCtrllr getSeed rxState:%d rxLength:%d",rxState,rxLength);         endrule      rule sendData(rxState == RX_DATA && !isGetSeed && streamQ_usage >= dInSz);      let rxDCtrl = RXDescramblerCtrl{seed: seed, bypass: 0}; // descrambler ctrl, no bypass      let rxGCtrl = RXGlobalCtrl{firstSymbol: isValid(seed), rate: ?};      let rxCtrl = RXDescramblerAndGlobalCtrl{descramblerCtrl: rxDCtrl, length: rxLength, globalCtrl: rxGCtrl};      seed <= tagged Invalid;      outMesgQ.enq(DescramblerMesg{control: rxCtrl, data: pack(take(streamQ.first))});      streamQ.deq(dInSz);      $display("PreDescramblerRXCtrllr sendData rxState:%d rxLength:%d",rxState,rxLength);   endrule      rule processInMesgQ(streamQ_free >= vOutSz);      let mesg = inMesgQ.first;      if (rxState == RX_DATA && mesg.control.firstSymbol)	 begin	    if (streamQ_usage == 0) // all date from last packet has been processed	       begin		  rxState <= RX_HEADER;		  zeroCount <= 0;		  inMesgQ.deq;		  streamQ.enq(vOutSz,append(mesg.data,replicate(0)));	       end	 end      else	 begin	    inMesgQ.deq;	    streamQ.enq(vOutSz,append(mesg.data,replicate(0)));	 end      $display("PreDescramblerRXCtrll processInMsgQ rxState:%d rxLength:%d",rxState,rxLength);         endrule   // interface methods   interface inFromPreDescrambler = fifoToPut(inMesgQ);        interface outToDescrambler = fifoToGet(outMesgQ);      interface outLength = fifoToGet(outLengthQ);      interface outFeedback = fifoToGet(outFeedbackQ);endmodule (* synthesize *)module mkPostDescramblerRXController(PostDescramblerRXController);   // state elements   FIFO#(EncoderMesg#(RXDescramblerAndGlobalCtrl,DescramblerDataSz)) inMesgQ <- mkLFIFO;   FIFO#(Bit#(8)) outDataQ <- mkLFIFO;   StreamFIFO#(24,5,Bit#(1)) streamQ <- mkStreamLFIFO; // descramblerdatasz must be factor of 12   Reg#(Bit#(12)) rxLength <- mkRegU; // no of bytes remains to be received   Reg#(Bool)     drop4b   <- mkRegU; // drop the first 4 bits?   Reg#(RXCtrlState) rxState <- mkReg(RX_IDLE);      // constants   Bit#(5) dInSz = fromInteger(valueOf(DescramblerDataSz));   let streamQ_usage = streamQ.usage;   let streamQ_free  = streamQ.free;      // rules   rule processInMesgQ(streamQ_free >= dInSz);      let mesg = inMesgQ.first;      inMesgQ.deq;      if ((rxState == RX_IDLE && mesg.control.globalCtrl.firstSymbol) || rxState != RX_IDLE)	 begin	    if (rxState == RX_IDLE)	       begin		  rxState <= RX_DATA;		  drop4b <= True;		  rxLength <= mesg.control.length;	       end	    streamQ.enq(dInSz,append(unpack(mesg.data),replicate(0)));	 end      else	 begin	    streamQ.clear;	 end      $display("PostDescramblerRXCtrllr processInMesgQ rxState:%d rxLength:%d",rxState,rxLength);         endrule      rule processStreamQ(streamQ_usage >= 8);      Bit#(8) outData = truncate(pack(streamQ.first));      Bit#(5) deqSz = drop4b ? 4 : 8;      drop4b <= False;      streamQ.deq(deqSz);      if (!drop4b)	 begin	    outDataQ.enq(outData);	    if (rxLength > 1)	       begin		  rxLength <= rxLength - 1;	       end	    else	       begin		  rxState <= RX_IDLE;	       end	 end      $display("PostDescramblerRXCtrllr processStreamQ rxState:%d rxLength:%d",rxState,rxLength);         endrule      // interface methods   interface inFromDescrambler = fifoToPut(inMesgQ);   interface outData = fifoToGet(outDataQ);endmodule(* synthesize *)module mkRXController(RXController);   // state elements   let preFFTCtrllr          <- mkPreFFTRXController;   let preDescramblerCtrllr  <- mkPreDescramblerRXController;   let postDescramblerCtrllr <- mkPostDescramblerRXController;      // mkConnections   mkConnection(preDescramblerCtrllr.outFeedback,preFFTCtrllr.inFeedback);      // methods   interface inFromPreFFT = preFFTCtrllr.inFromPreFFT;   interface outToPreDescrambler = preFFTCtrllr.outToPreDescrambler;   interface inFromPreDescrambler = preDescramblerCtrllr.inFromPreDescrambler;   interface outToDescrambler = preDescramblerCtrllr.outToDescrambler;   interface inFromDescrambler = postDescramblerCtrllr.inFromDescrambler;   interface outLength = preDescramblerCtrllr.outLength;   interface outData   = postDescramblerCtrllr.outData;endmodule

⌨️ 快捷键说明

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