📄 synchronizer.bsv
字号:
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 + -