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

📄 synchronizer.bsv

📁 MIT编写的OFDM仿真程序
💻 BSV
📖 第 1 页 / 共 2 页
字号:
//----------------------------------------------------------------------//// 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 Controls::*;import Complex::*;import CORDIC::*;import DataTypes::*;import FIFO::*;import FIFOF::*;import FixedPoint::*;import FixedPointLibrary::*;import Interfaces::*;import Preambles::*;import ShiftRegs::*;import SParams::*;import SynchronizerLibrary::*;import Vector::*;import FPComplex::*;import GetPut::*;import Parameters::*;//`define debug_mode True // uncomment this line for displaying text typedef struct{  ctrlT   control;  // estimate postion  data1T  data1;     // data1  data2T  data2;     // data2} SyncData#(type ctrlT, type data1T, type data2T) deriving (Bits, Eq);typedef enum{  Dump = 0,          // useless data, don't output  Idle = 1,          // don't do estimation  Collect = 2,       // collect correlation and calculate moving average  ShortSync = 3,     // make coarse estimation  LongSync = 4,      // make fine estimation  TimeOut = 5        // timeout reset} ControlType deriving (Bits, Eq);typedef enum{  SNormal = 0,  STrans = 1,  LNormal = 2,  LTrans = 3} TimeState deriving (Bits, Eq);// type definitions for the input of timing and frequency synchronizer// defintion of CorrPipeT: control = tell timing sync what to do, data1 = original input, data2 = rotated inputtypedef SyncData#(TimeState, FPComplex#(SyncIntPrec,SyncFractPrec), FPComplex#(SyncIntPrec,SyncFractPrec)) CorrPipeT;// defintion of FineTimeInT: data1 = original input, data2 = rotated inputtypedef SyncData#(ControlType, FPComplex#(SyncIntPrec,SyncFractPrec), FPComplex#(SyncIntPrec,SyncFractPrec)) FineTimeInT;// definition of FreqEstInT: data1 = original input, data2 = auto correlation resulttypedef SyncData#(ControlType, FPComplex#(SyncIntPrec,SyncFractPrec), FPComplex#(CorrIntPrec, SyncFractPrec)) FreqEstInT;// definition of FreqRotInT: data1 = original input, data2 = angle to be rotatedtypedef SyncData#(ControlType, FPComplex#(SyncIntPrec,SyncFractPrec), FixedPoint#(SyncIntPrec, SyncFractPrec)) FreqRotInT;// timing synchronizer interface (used for both coarse and fine estimations)interface TimeEstimator;   // inputs   method Action putCoarTimeIn(FPComplex#(SyncIntPrec,SyncFractPrec) coarTimeIn);   method Action putFineTimeIn(FineTimeInT fineTimeIn);   // output   method ActionValue#(FreqEstInT) getFreqEstIn();endinterface// carrier frequency offset estimator (used for both coarse and fine estimations) interface FreqEstimator;   // inputs   method Action putFreqEstIn(FreqEstInT freqEstIn);   // output   method ActionValue#(FreqRotInT) getFreqRotIn();endinterface// carrier frequency offset compensatorinterface FreqRotator;   // inputs   method Action putFreqRotIn(FreqRotInT freqRotIn);   // output   method ActionValue#(FineTimeInT) getFineTimeIn();endinterfaceinterface AutoCorrelator;   // inputs   method Action putInput(FPComplex#(SyncIntPrec,SyncFractPrec) x);   method Action setMode(Bool isShortMode);   // outputs   method ActionValue#(CorrType) getCorrelation();endinterface(* synthesize *)module mkAutoCorrelator(AutoCorrelator);   // output buffer   FIFO#(CorrType) outQ <- mkFIFO;   // delay queues   ShiftRegs#(SSLen, FPComplex#(SyncIntPrec,SyncFractPrec))             delayIn <- mkAutoCorr_DelayIn;   ShiftRegs#(SSLen, FPComplex#(MulIntPrec,SyncFractPrec))              corrSub <- mkAutoCorr_CorrSub;      ShiftRegs#(LSLSSLen, FPComplex#(SyncIntPrec,SyncFractPrec))          extDelayIn <- mkAutoCorr_ExtDelayIn;   ShiftRegs#(LSLSSLen, FPComplex#(MulIntPrec,SyncFractPrec))           extCorrSub <- mkAutoCorr_ExtCorrSub;   // accumulator   Reg#(CorrType)                                          corr <- mkReg(cmplx(0,0));   // mode   Reg#(Bool) 						   isShort <- mkReg(True); 						      method Action putInput(FPComplex#(SyncIntPrec,SyncFractPrec) x);   begin      let conjDelayIn = cmplxConj(delayIn.first); // conjugate of delayed input      let curIn = x;      FPComplex#(MulIntPrec,SyncFractPrec) corrAdd = fpcmplxTruncate(fpcmplxMult(curIn,conjDelayIn));       let newCorr = corr + 		    fpcmplxSignExtend(corrAdd) - 		    fpcmplxSignExtend(corrSub.first);      corr <= newCorr;      outQ.enq(newCorr);      if (isShort)	begin	   delayIn.enq(curIn);	   corrSub.enq(corrAdd);	   `ifdef debug_mode	      $display("AutoCorr.putInput: isShort");	   `endif	end      else	begin	   extDelayIn.enq(curIn);	   delayIn.enq(extDelayIn.first);	   extCorrSub.enq(corrAdd);	   corrSub.enq(extCorrSub.first);	   `ifdef debug_mode	      $display("AutoCorr.putInput: isLong");	   `endif	end // else: !if(isShort)   end   endmethod   method Action setMode(Bool isShortMode);   begin      // reset accumulator and shiftregs      delayIn.clear;      corrSub.clear;      extDelayIn.clear;      extCorrSub.clear;      corr <= cmplx(0,0);      isShort <= isShortMode;      `ifdef debug_mode         $display("AutoCorr.setMode: %d",isShortMode);      `endif   end   endmethod   method ActionValue#(CorrType) getCorrelation();   begin      outQ.deq;      `ifdef debug_mode         $write("AutoCorr.getCorrelation:");         cmplxWrite("("," + ","i)",fxptWrite(7),outQ.first);         $display("");      `endif      return outQ.first;   end   endmethod     endmodule(* synthesize *)module mkTimeEstimator(TimeEstimator);   // constants   Integer lSStart = valueOf(LSStart);   Integer signalStart = valueOf(SignalStart);   Integer lSyncPos = valueOf(LSyncPos);   Integer freqMeanLen = valueOf(FreqMeanLen);   Integer coarTimeCorrPos = valueOf(CoarTimeCorrPos);   Integer coarResetPos = valueOf(TimeResetPos);   Integer coarTimeAccumDelaySz = valueOf(CoarTimeAccumDelaySz);   let fullLongPreambles = insertCP0(getLongPreSigns()); // constant known 160-long preambles   Vector#(FineTimeCorrSz, Complex#(Bit#(1))) longPreambles = take(fullLongPreambles);         Bit#(FineTimeCorrFullResSz)  maxFineTimePowSq = cmplxModSq(singleBitCrossCorrelation(longPreambles,longPreambles)) >> 1; // last maxFineTimeSignal       // states   // autocorrelator   AutoCorrelator          autoCorr <- mkAutoCorrelator;   // input buffers   FIFO#(FPComplex#(SyncIntPrec,SyncFractPrec)) coarTimeInQ <- mkFIFO; // the buffer should be large enough (> whole latency of synchronizer)   FIFOF#(FineTimeInT)     fineTimeInQ <- mkFIFOF;   FIFO#(TimeState) timeStatePipeQ <- mkSizedFIFO(2);   FIFO#(FPComplex#(SyncIntPrec,SyncFractPrec)) coarInPipeQ <- mkSizedFIFO(2);   FIFO#(FPComplex#(SyncIntPrec,SyncFractPrec)) fineInPipeQ <- mkSizedFIFO(2);   FIFO#(FixedPoint#(CoarTimeAccumIntPrec,SyncFractPrec)) coarPowQ <- mkSizedFIFO(2);   FIFO#(Bit#(FineTimeCorrFullResSz)) fineTimeCorrQ <- mkSizedFIFO(2);      // output buffer   FIFO#(FreqEstInT) outQ <- mkFIFO;   // delay queues   ShiftRegs#(SSLen, FixedPoint#(MulIntPrec,SyncFractPrec))             coarPowSub <- mkTimeEst_CoarPowSub;   ShiftRegs#(CoarTimeAccumDelaySz, Bool)                  coarTimeSub <- mkTimeEst_CoarTimeSub;      ShiftRegs#(FineTimeCorrDelaySz, Complex#(Bit#(1)))      fineDelaySign <- mkTimeEst_FineDelaySign;   //accumulators   Reg#(FixedPoint#(CoarTimeAccumIntPrec,SyncFractPrec))   coarPow <- mkReg(0);   Reg#(Bit#(CoarTimeAccumIdx))                            coarTime <- mkReg(0); // at most add up to 144   //other regs   Reg#(Bit#(CounterSz))                                   coarPos <- mkReg(0);   Reg#(Bool) 	                                           coarDet <- mkReg(False);      Reg#(Bit#(CounterSz))                                   finePos <- mkReg(0);   Reg#(Bool) 					           fineDet <- mkReg(False);   Reg#(Bool) 						   isProlog <- mkReg(True); // setup at the beginning   Reg#(TimeState) 					   status <- mkReg(SNormal);      rule procProlog(isProlog); // initial setup   begin      if (fineTimeInQ.notEmpty) // finish	begin	   isProlog <= False;	end      else // not yet fill up pipeline, keep sending	begin	   outQ.enq(FreqEstInT{control: Dump,			       data1: ?,			       data2: ?});	   	end      `ifdef debug_mode         $display("TimeEst.procProlog");      `endif   end   endrule   rule procAutoCorrSN(!isProlog && status == SNormal);   begin      let curIn = coarTimeInQ.first;      coarTimeInQ.deq;      fineTimeInQ.deq;      coarInPipeQ.enq(curIn);      if (fineTimeInQ.first.control == ShortSync)	begin	   status <= LNormal;	   autoCorr.setMode(False);	   timeStatePipeQ.enq(STrans);	end      else	begin	   FixedPoint#(MulIntPrec,SyncFractPrec) coarPowAdd = fxptTruncate(fpcmplxModSq(curIn));	   let newCoarPow = coarPow +			    fxptZeroExtend(coarPowAdd) -			    fxptZeroExtend(coarPowSub.first);	   coarPow <= newCoarPow;	   coarPowQ.enq(newCoarPow);	   coarPowSub.enq(coarPowAdd);	   autoCorr.putInput(curIn);	   timeStatePipeQ.enq(SNormal);	end // else: !if(fineTimeInQ.first.control == ShortSync)      `ifdef debug_mode         $display("TimeEst.procAutoCorrSN");      `endif   end   endrule   rule  procAutoCorrLN(!isProlog && status == LNormal);   begin      let fineSign = toSingleBitCmplx(fineTimeInQ.first.data2);      let fineTimeCorrIn = append(fineDelaySign.getVector(), cons(fineSign,nil));      let newFineTimeCorrPow = cmplxModSq(singleBitCrossCorrelation(fineTimeCorrIn, longPreambles));      fineDelaySign.enq(fineSign);      fineTimeCorrQ.enq(newFineTimeCorrPow);      coarTimeInQ.deq;      fineTimeInQ.deq;      autoCorr.putInput(fineTimeInQ.first.data2);	      timeStatePipeQ.enq(LNormal);      coarInPipeQ.enq(coarTimeInQ.first);      fineInPipeQ.enq(fineTimeInQ.first.data1);      `ifdef debug_mode         $write("TimeEst.procAutoCorrLN: fineSign: %d + %di,",fineSign.rel,fineSign.img);         $write("input: ");         cmplxWrite("("," + ","i), ",fxptWrite(7),fineTimeInQ.first.data2);         $display("");         $display("TimeEst.procAutoCorrLN: fineTimeCorrIn:%h, ",fineTimeCorrIn);         $display("TimeEst.procAutoCorrLN: longPreSigns:%h, ",longPreambles);      `endif   end   endrule   rule procAutoCorrLT(!isProlog && status == LTrans);   begin      fineTimeInQ.deq;      timeStatePipeQ.enq(LTrans);      fineInPipeQ.enq(fineTimeInQ.first.data1);      if (fineTimeInQ.first.control == LongSync || fineTimeInQ.first.control == TimeOut)	begin	   status <= SNormal;	   autoCorr.setMode(True);	end      `ifdef debug_mode         $display("TimeEst.procAutCorrLT");      `endif   end   endrule   rule procTimeEstSN(!isProlog && timeStatePipeQ.first == SNormal);   begin      //variables      ControlType outControl = Idle;      FPComplex#(SyncIntPrec,SyncFractPrec) outData = coarInPipeQ.first;      CorrType outCorr = ?;      Bit#(CounterSz) newCoarPos;      let newCorr <- autoCorr.getCorrelation;      let newCoarPow = coarPowQ.first;      if (coarDet)	begin	   newCoarPos = coarPos + 1;	end      else	begin	   FPComplex#(CoarTimeAccumIntPrec, SyncFractPrec) newCoarCorr = fpcmplxTruncate(newCorr);	   let newCoarCorrPow = fpcmplxModSq(newCoarCorr);	   let newCoarPowSq = fxptZeroExtend(fxptMult(newCoarPow,newCoarPow));	   let coarTimeAdd = newCoarCorrPow > (newCoarPowSq >> 1);	   let newCoarTime = coarTime +			     zeroExtend(pack(coarTimeAdd)) -			     zeroExtend(pack(coarTimeSub.first));	   newCoarPos = zeroExtend(newCoarTime) +	       		fromInteger(coarTimeCorrPos - 1);	   if (newCoarTime == fromInteger(coarTimeAccumDelaySz)) // coar detected	     begin		coarDet <= True;		coarTime <= 0;     // reset coarTime		coarTimeSub.clear; // clear coarTimeSub shiftreg	     end	   else	     begin		coarTimeSub.enq(coarTimeAdd);		coarTime <= newCoarTime;	     end	end // else: !if(coarDet)            // common state transitions      timeStatePipeQ.deq;      coarPowQ.deq;      coarInPipeQ.deq;

⌨️ 快捷键说明

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