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

📄 synchronizer.bsv

📁 MIT编写的OFDM仿真程序
💻 BSV
📖 第 1 页 / 共 2 页
字号:
      coarPos <= newCoarPos;      //setup output data      if (newCoarPos < fromInteger(lSStart - freqMeanLen) || newCoarPos > fromInteger(lSStart - 1))	begin	   outControl = Idle;	   outCorr = ?;	end      else	begin	   outControl = ((newCoarPos == fromInteger(lSStart - 1)) ? 			 ShortSync:			 Collect);	   outCorr = newCorr;	end // else: !if(newCoarPos < fromInteger(lSStart - freqMeanLen) || newCoarPos > fromInteger(lSStart - 1))      outQ.enq(FreqEstInT{control: outControl,			  data1: outData,			  data2: outCorr});      `ifdef debug_mode         $display("TimeEst.procTimeEstSN: coarPos:%d",newCoarPos);      `endif   end   endrule   rule procTimeEstST(!isProlog && timeStatePipeQ.first == STrans);   begin      timeStatePipeQ.deq;      coarInPipeQ.deq;      coarPos <= coarPos + 1;      outQ.enq(FreqEstInT{control: Idle,			  data1: coarInPipeQ.first,			  data2: ?});      `ifdef debug_mode         $display("TimeEst.procTimeEstST: coarPos:%d",coarPos + 1);      `endif   end   endrule   rule procTimeEstLN(!isProlog && timeStatePipeQ.first == LNormal);   begin      Bit#(CounterSz) newCoarPos = coarPos;      Bit#(CounterSz) newFinePos = finePos;      ControlType outControl = Idle;      FPComplex#(SyncIntPrec,SyncFractPrec) outData = ?;      CorrType outCorr = ?;      let newCorr <- autoCorr.getCorrelation;      let newFineTimeCorrPow = fineTimeCorrQ.first;      if (status == LTrans)	begin	   outControl = Idle;	   outData = fineInPipeQ.first; // send  outData as fineInPipeQ.first	   outCorr = ?;	end      else	begin	   if (fineDet)	     begin		newFinePos = finePos + 1; 	     end	   else	     begin		if (newFineTimeCorrPow > maxFineTimePowSq)		  begin		     newFinePos = fromInteger(lSyncPos); 		     fineDet <= True;		  end		else		  begin		     newCoarPos = coarPos + 1;		  end                `ifdef debug_mode		   $display("TimeEst.procTimeEstLN: newFineTimePowCorr:%d, maxFineTimePosSq:%d",newFineTimeCorrPow, maxFineTimePowSq);		`endif	     end // else: !if(fineDet)	   	   coarInPipeQ.deq;	   finePos <= newFinePos;	   coarPos <= newCoarPos;	   outData = coarInPipeQ.first;	   outCorr = newCorr;      	   if (newFinePos == fromInteger(signalStart - 1) || newCoarPos == fromInteger(coarResetPos))	     begin		status <= LTrans;		outControl = (newCoarPos == fromInteger(coarResetPos)) ? TimeOut : LongSync;		       	     end	   else	     begin		outControl = Collect;		       	     end	end            timeStatePipeQ.deq;      fineTimeCorrQ.deq;      fineInPipeQ.deq;            outQ.enq(FreqEstInT{control: outControl,			  data1: outData,			  data2: outCorr});      `ifdef debug_mode         $display("TimeEst.procTimeEstLN: coarPos:%d, finePos:%d",newCoarPos,newFinePos);      `endif   end // else: !if(status == LTrans)   endrule   rule procTimeEstLT(!isProlog && timeStatePipeQ.first == LTrans);   begin      coarPos <= 0;      finePos <= 0;      coarDet <= False;      fineDet <= False; // reset everything      fineInPipeQ.deq;      timeStatePipeQ.deq;      outQ.enq(FreqEstInT{control: Idle,			  data1: fineInPipeQ.first,			  data2: ?});      `ifdef debug_mode         $display("TimeEst.procTimeEstLT");      `endif   end // case: LTrans   endrule   method Action putCoarTimeIn(FPComplex#(SyncIntPrec,SyncFractPrec) coarTimeIn);   begin      coarTimeInQ.enq(coarTimeIn);      `ifdef debug_mode         $display("TimeEst.putCoarTimeIn");         `endif   end   endmethod   method Action putFineTimeIn(FineTimeInT fineTimeIn);   begin      fineTimeInQ.enq(fineTimeIn);      `ifdef debug_mode         $display("TimeEst.putFineTimeIn");      `endif   end   endmethod        method ActionValue#(FreqEstInT) getFreqEstIn();   begin      outQ.deq;      `ifdef debug_mode         $display("TimeEst.getFreqEstIn");      `endif      return outQ.first;   end   endmethod   endmodule   (* synthesize *)module [Module] mkFreqEstimator(FreqEstimator);   // Constants   Integer cordicPipe = valueOf(CORDICPipe);   Integer cordicIter = valueOf(CORDICIter);   Integer cordicStep = cordicIter/cordicPipe; // how many stages perform per cycle   Bit#(RotAngCounterSz) rotAngCounterReset = fromInteger(valueOf(SymbolLen) - 1);   Nat coarFreqOffAccumRShift = fromInteger(valueOf(CoarFreqOffAccumRShift));   Nat fineFreqOffAccumRShift = fromInteger(valueOf(FineFreqOffAccumRShift));      // states   // fifo buffer   FIFO#(FreqEstInT) pipeQ <- mkSizedFIFO(cordicPipe+2);   FIFO#(FreqRotInT) outQ <- mkFIFO;   // shift registers   ShiftRegs#(FreqMeanLen, FixedPoint#(SyncIntPrec,SyncFractPrec)) freqOffAccumSub <- mkFreqEst_FreqOffAccumSub;     // accumulators   Reg#(FixedPoint#(FreqOffAccumIntPrec,SyncFractPrec))   freqOffAccum <- mkReg(0);     // freq offset accumulators   Reg#(FixedPoint#(SyncIntPrec,SyncFractPrec))               freqOff <- mkReg(0);           // combined coar and fine freq off.   Reg#(FixedPoint#(SyncIntPrec,SyncFractPrec))               rotAng <- mkReg(0);            // the angle freq rot. should rotate for this sample   // counters   Reg#(Bit#(RotAngCounterSz))                        rotAngCounter <- mkReg(0);   // cordic   ArcTan#(CorrIntPrec,SyncFractPrec,SyncIntPrec,SyncFractPrec) cordic <- mkArcTan_Pipe(cordicIter,cordicStep); // cos and sin   rule procIdle(pipeQ.first.control == Idle || pipeQ.first.control == Dump);   begin      let reset = rotAngCounter == rotAngCounterReset;      let newRotAng = reset ? 0 : rotAng + freqOff;      pipeQ.deq;      rotAngCounter <= reset ? 0 : rotAngCounter +  1;      rotAng <= newRotAng;      outQ.enq(FreqRotInT{control: pipeQ.first.control,			  data1: pipeQ.first.data1,			  data2: rotAng});   end   endrule   rule procNotIdle(pipeQ.first.control != Idle && pipeQ.first.control != Dump);   begin      let cordicResult <- cordic.getArcTan;      let freqOffAccumAdd = negate(cordicResult); // get freq offset      let newFreqOffAccum = freqOffAccum + 			    fxptSignExtend(freqOffAccumAdd) -			    fxptSignExtend(freqOffAccumSub.first);      pipeQ.deq;      outQ.enq(FreqRotInT{control: pipeQ.first.control,			  data1: pipeQ.first.data1,			  data2: rotAng});      if (pipeQ.first.control != Collect)	begin	   let isShortSync = pipeQ.first.control == ShortSync;	   let newFreqOff = isShortSync ? 			    fxptTruncate(newFreqOffAccum >> coarFreqOffAccumRShift) : // reset to coar estimation			    freqOff + fxptTruncate(newFreqOffAccum >> fineFreqOffAccumRShift); // combine coar and fine estimation	   freqOff <= newFreqOff;	   rotAng <= 0; // next sample rotate by 0	   rotAngCounter <= 0;	   freqOffAccum <= 0;     // clear	   freqOffAccumSub.clear; // clear	end      else	begin	   freqOffAccumSub.enq(freqOffAccumAdd);	   rotAng <= rotAng + freqOff;	   freqOffAccum <= newFreqOffAccum;	end   end   endrule   method Action putFreqEstIn(FreqEstInT freqEstIn);   begin      pipeQ.enq(freqEstIn);      if (freqEstIn.control != Idle && freqEstIn.control != Dump)	cordic.putXY(freqEstIn.data2.rel, freqEstIn.data2.img); // use cordic   end   endmethod        method ActionValue#(FreqRotInT) getFreqRotIn;   begin      outQ.deq;      `ifdef debug_mode         $write("FreqEst.getFreqRotIn: control:%d, ",outQ.first.control);         cmplxWrite("data:("," + ","i), ",fxptWrite(7),outQ.first.data1);         $write("angle:");         fxptWrite(7, rotAng);         $display("");      `endif      return outQ.first;   end   endmethodendmodule(* synthesize *)module [Module] mkFreqRotator(FreqRotator);   // Integer constants   Integer cordicPipe = valueOf(CORDICPipe);   Integer cordicIter = valueOf(CORDICIter);   Integer cordicStep = cordicIter/cordicPipe; // how many stages perform per cycle      // states          // fifo buffers   FIFO#(FreqRotInT)  pipeQ <- mkSizedFIFO(cordicPipe+2);   FIFO#(FineTimeInT) outQ <- mkFIFO;   // cordic   CosAndSin#(SyncIntPrec,SyncFractPrec,SyncIntPrec,SyncFractPrec) cordic <- mkCosAndSin_Pipe(cordicIter,cordicStep); // cos and sin      rule procRot(True);   begin      let freqRotIn = pipeQ.first;      let control = freqRotIn.control;      let inCmplx = freqRotIn.data1;      let rotAng = freqRotIn.data2;      let rotCosSinPair <- cordic.getCosSinPair;      FPComplex#(SyncIntPrec,SyncFractPrec) rotCmplx = fpcmplxTruncate(cmplx(rotCosSinPair.cos, rotCosSinPair.sin));      FPComplex#(SyncIntPrec,SyncFractPrec) outCmplx = fpcmplxTruncate(fpcmplxMult(inCmplx, rotCmplx));      pipeQ.deq;      outQ.enq(FineTimeInT{control: control,			   data1: inCmplx,			   data2: outCmplx});      `ifdef debug_mode         $write("FreqRot.procRot:");         fxptWrite(7, rotAng);         $display("");      				           cmplxWrite("inputCmplx:("," + ","i)",fxptWrite(7),inCmplx);         $display("");         cmplxWrite("outCmplx:("," + ","i)",fxptWrite(7),outCmplx);         $display("");      `endif   end   endrule      method Action putFreqRotIn(FreqRotInT freqRotIn);   begin      pipeQ.enq(freqRotIn);      let rotAng = freqRotIn.data2;          cordic.putAngle(rotAng);   end   endmethod        method ActionValue#(FineTimeInT) getFineTimeIn();   begin      outQ.deq;      return outQ.first;   end   endmethod   endmodule   (* synthesize *)module [Module] mkSynchronizer(Synchronizer#(SyncIntPrec,SyncFractPrec));   //input and output buffers   FIFO#(SynchronizerMesg#(SyncIntPrec,SyncFractPrec)) inQ <- mkLFIFO;   FIFO#(UnserializerMesg#(SyncIntPrec,SyncFractPrec)) outQ <- mkSizedFIFO(2);   // modules   TimeEstimator      timeEst <- mkTimeEstimator;   FreqEstimator      freqEst <- mkFreqEstimator;   FreqRotator        freqRot <- mkFreqRotator;   // register   Reg#(Bool)    lastLongSync <- mkReg(False); // set if the last output is longsync   rule inQToTimeEst(True);   begin      inQ.deq;      timeEst.putCoarTimeIn(inQ.first);   end   endrule   rule timeEstToFreqEst(True);   begin      let freqEstIn <- timeEst.getFreqEstIn;      freqEst.putFreqEstIn(freqEstIn);   end   endrule   rule freqEstToFreqRot(True);   begin      let freqRotIn <- freqEst.getFreqRotIn;      freqRot.putFreqRotIn(freqRotIn);   end   endrule   rule freqRotToTimeEst(True);   begin      let fineTimeIn <- freqRot.getFineTimeIn;      timeEst.putFineTimeIn(fineTimeIn);      lastLongSync <= (fineTimeIn.control == LongSync);      if (fineTimeIn.control != Dump)	 begin	    let syncCtrl = SyncCtrl{isNewPacket: lastLongSync,				    cpSize: CP0};	    outQ.enq(UnserializerMesg{control: syncCtrl,				      data: fineTimeIn.data2});	 end   end   endrule      interface in = fifoToPut(inQ);   interface out = fifoToGet(outQ);endmodule

⌨️ 快捷键说明

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