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

📄 iviterbi.bsv

📁 MIT编写的OFDM仿真程序
💻 BSV
📖 第 1 页 / 共 2 页
字号:
           Vector#(ConvOutSz, VMetricSum) addMetrics = newVector;           for (Integer i = 0; i < conv_out_sz; i = i + 1)	     addMetrics[i] = zeroExtend(getMetric(expBits[i]) ^ recMetrics[i]); // |expMetric[i] - recMetrics[i]|           return inSum + fold(\+ , addMetrics);      endfunction            RadixEntry#(tEntry_T) outVec = newVector;//      MetricLUT metricLUT = getMetricLUT;      Bit#(TSub#(VStateSz, ConvInSz)) prevStatePrefix = tpl_1(split(tpl_1(inVec[0]))); // all input states must have the same prefix      RadixEntry#(tEntry_T) sumVec = newVector; // for calculating next result            for (Integer in_bits = 0; in_bits < radix_sz; in_bits = in_bits + 1)	begin	   Bit#(ConvInSz) inBits = fromInteger(in_bits);	   VState nextState = {inBits, prevStatePrefix};	   for (Integer prev_state_suffix = 0; prev_state_suffix < radix_sz; prev_state_suffix = prev_state_suffix + 1)	     begin//		Bit#(KSz) lutIdx = (zeroExtend(nextState) << fromInteger(conv_in_sz)) + fromInteger(prev_state_suffix);		sumVec[prev_state_suffix] = tuple3(tpl_1(inVec[prev_state_suffix]),  // same						   calcVMetricSum(tpl_2(inVec[prev_state_suffix]),								  getConvEncOutput(tpl_1(inVec[prev_state_suffix]), inBits),//								  metricLUT[lutIdx],								  inMetrics), // add 						   tpl_3(inVec[prev_state_suffix])); // same	     end	   let minRadix = fold(chooseMin, sumVec);	   let nextSum = tpl_2(minRadix);	   let nextT = getNextTEntry(tpl_1(minRadix), nextState, tpl_3(minRadix));	   outVec[in_bits] = tuple3(nextState, nextSum, nextT);	end // for (Integer in_bits = 0; in_bits < radix_sz; in_bits = in_bits + 1)      return outVec;endfunction // unmatched end(function|task|module|primitive)      function FwdEntry#(tEntry_T) fwdCompute(FwdEntry#(tEntry_T) inVec,					VInType inMetricsV,					function tEntry_T getNextTEntry(VState prevState,									VState nextState,									tEntry_T oldTEntry));            FwdEntry#(tEntry_T) outVec = inVec;      Integer no_radix = fwd_entry_sz / radix_sz;       for (Integer stage = 0; stage < fwd_steps; stage = stage + 1)	begin	   RadixEntry#(tEntry_T) radixVec = newVector;	   if (stage != 0)	     outVec = readSelect(conv_in_sz, stage, 0, outVec); // permute if not the first step	   for (Integer radix_idx = 0; radix_idx < no_radix; radix_idx = radix_idx + 1)	     begin		for (Integer k = 0; k < radix_sz; k = k + 1)		  radixVec[k] = outVec[radix_idx*radix_sz+k];	        radixVec = radixCompute(radixVec, inMetricsV[stage], getNextTEntry);		for (Integer k = 0; k < radix_sz; k = k + 1)		  outVec[radix_idx*radix_sz+k] = radixVec[k];	     end // for (Integer j = 0; j < noOfRadix; j = j + 1)	   if (stage != 0)	     outVec = reverseReadSelect(conv_in_sz, stage, 0, outVec); // reverse the permutation if not the first step	end // for (Integer i = 0; i < fwd_steps; i = i + 1)      return outVec;      endfunction // ForwardEntry// output the state with the minimum value and the new outentryfunction Tuple3#(VState, tEntry_T, VRegsOutEntry#(tEntry_T)) vRegsOutCompute(VRegsOutEntry#(tEntry_T) inVec,									     VInType inMetricsV,									     function tEntry_T getNextTEntry(VState prevState,													     VState nextState,													     tEntry_T oldTEntry));            VRegsOutEntry#(tEntry_T) outVec = newVector;      Integer no_fwd_unit = vregs_out_sz / fwd_entry_sz;      FwdEntry#(tEntry_T) fwdVec = newVector;      for (Integer fwd_idx = 0; fwd_idx < no_fwd_unit; fwd_idx = fwd_idx + 1)	begin	   for (Integer k = 0; k < fwd_entry_sz; k = k + 1)	     fwdVec[k] = inVec[fwd_idx * fwd_entry_sz + k];	   fwdVec = fwdCompute(fwdVec, inMetricsV, getNextTEntry);	   for (Integer k = 0; k < fwd_entry_sz; k = k + 1)	     outVec[fwd_idx * fwd_entry_sz + k] = fwdVec[k];	end // for (Integer j = 0; j < noOfRadix; j = j + 1)      let minPrimEntry = fold(chooseMin, outVec);      VState minState = tpl_1(minPrimEntry);      tEntry_T minTEntry = tpl_3(minPrimEntry);      return tuple3(minState, minTEntry, outVec);      endfunction // ForwardEntry(* noinline *)function Tuple3#(VState, VTrellisEntry, VRegsOutEntry#(VTrellisEntry)) vRegsOutComputeTBPath(VRegsOutEntry#(VTrellisEntry) inVec,											     VInType inMetricsV);            return vRegsOutCompute(inVec, inMetricsV, getNextTrellisEntry);      endfunction(* noinline *)function Tuple3#(VState, VTBEntry, VRegsOutEntry#(VTBEntry)) vRegsOutComputeTB(VRegsOutEntry#(VTBEntry) inVec,									       VInType inMetricsV);            return vRegsOutCompute(inVec, inMetricsV, getNextTB);      endfunctionfunction Vector#(VRegsOutSz, VState) getNextStates(Bit#(VRegsSubIdxSz) stage);      Vector#(VRegsOutSz, VState) outVec = newVector;      VState subIdx = zeroExtend(stage) << fromInteger(valueOf(VRegsOutIdxSz));      for (Integer i = 0; i < valueOf(VRegsOutSz); i = i + 1)	outVec[i] = subIdx + fromInteger(i);      return outVec;      endfunction // Vector            /////////////////////////////////////////////////////////// Begin of Viterbi Module /////////////////////////////////////////////////////////(*synthesize*)module mkIViterbiTBPath (IViterbi);   // states   FIFO#(VInType) inQ <- mkLFIFO;   FIFO#(VOutType) outQ <- mkSizedFIFO(2);   VRegFile#(VRegsSubIdxSz,VRegsOutSz,VMetricSum) metricSums <- mkMetricSums;   VRegFile#(VRegsSubIdxSz,VRegsOutSz,VTrellisEntry) trellis <- mkTrellis;   Reg#(Bit#(VRegsSubIdxSz)) stage <- mkReg(0);   Reg#(Bit#(1)) colIdx <- mkReg(0);   Reg#(VState)  curMinState <- mkReg(0);   Reg#(VTrellisEntry) curMinPath <- mkRegU;   Reg#(TBStageIdx)   tbStage <- mkReg(0); // keep track of whether we can output TB result yet      rule processInput(True);   begin      let nextMSums = metricSums.sub(colIdx, stage);      let nextTrellis = trellis.sub(colIdx, stage);      let nextStates = getNextStates(stage);      let vRegsOutEntry = zip3(nextStates, nextMSums, nextTrellis);      let vRegsOutNew = vRegsOutComputeTBPath(vRegsOutEntry, inQ.first);      let minState = tpl_1(vRegsOutNew);      let minPath = tpl_2(vRegsOutNew);      let newMinState = (stage == 0 || minState < curMinState) ? minState : curMinState;      let newMinPath = (stage == 0 || minState < curMinState) ? minPath : curMinPath;      let newMSums = map(tpl_2, tpl_3(vRegsOutNew));      let newTrellis = map(tpl_3, tpl_3(vRegsOutNew));      Bit#(VStateSuffixSz) out = tpl_2(split(newMinPath));      VOutType vOut = unpack(out);      curMinState <= newMinState; // new min      curMinPath <= newMinPath;      stage <= stage + 1;      metricSums.upd(colIdx+1, stage, newMSums);      trellis.upd(colIdx+1, stage, newTrellis);      `ifdef isDebug         $display ("viterbi return: colIdx=%d stage=%d newMinState=%d, newMinPath=%h", colIdx, stage, newMinState, newMinPath);         $write ("viterbi return: newMSums=");         for (Integer i = 0; i < no_states; i = i + 1)	   begin	      $write ("%d: %d ", tpl_1(tpl_3(vRegsOutNew)[i]), newMSums[i]);	   end         $display ("");         $write ("viterbi return: newTrellis=");	 for (Integer i = 0; i < no_states; i = i + 1)	   begin	      $write ("%d: %h ", tpl_1(tpl_3(vRegsOutNew)[i]), newTrellis[i]);	   end	 $display ("");      `endif      if (stage == maxBound) // last stage, output trace back	begin	   inQ.deq;	   if (tbStage == fromInteger(no_tbstage-1))	     outQ.enq(vOut);	   else	     tbStage <= tbStage + 1;	   colIdx <= colIdx + 1;	end   end   endrule      method Action putData (VInType dataIn);      inQ.enq(dataIn);   endmethod   method ActionValue#(VOutType) getResult ();      outQ.deq;      return outQ.first;   endmethod   endmodule(*synthesize*)module mkIViterbiTB (IViterbi);   // states   FIFO#(VInType) inQ <- mkLFIFO;   FIFO#(VOutType) outQ <- mkSizedFIFO(2);   VRegFile#(VRegsSubIdxSz,VRegsOutSz,VMetricSum) metricSums <- mkMetricSums;   Reg#(Vector#(VTotalStates, Bit#(1))) tbcol <- mkRegU; // save tb col   Reg#(Bit#(VRegsSubIdxSz)) stage <- mkReg(0);   Reg#(Bit#(1)) colIdx <- mkReg(0);   Reg#(VState)  curMinState <- mkReg(0);   Reg#(TBStageIdx)   tbStage <- mkReg(0); // keep track of whether we can output TB result yet   Traceback  tbu <- mkTraceback;   rule performACS(True);   begin      let nextMSums = metricSums.sub(colIdx, stage);      let nextTBEntry = newVector;      let nextStates = getNextStates(stage);      let vRegsOutEntry = zip3(nextStates, nextMSums, nextTBEntry);      let vRegsOutNew = vRegsOutComputeTB(vRegsOutEntry, inQ.first);      let minState = tpl_1(vRegsOutNew);      let newMinState = (stage == 0 || minState < curMinState) ? minState : curMinState;      let newMSums = map(tpl_2, tpl_3(vRegsOutNew));      let newTBEntry = map(tpl_3, tpl_3(vRegsOutNew));      let newTBCol = writeSelect(stage, tbcol, newTBEntry);      curMinState <= newMinState; // new min      stage <= stage + 1;      metricSums.upd(colIdx+1, stage, newMSums);      tbcol <= newTBCol;       `ifdef isDebug         $display ("viterbi return: colIdx=%d stage=%d newMinState=%d", colIdx, stage, newMinState);         $write ("viterbi return: newMSums=");         for (Integer i = 0; i < no_states; i = i + 1)	   begin	      $write ("%d: %d ", tpl_1(tpl_3(vRegsOutNew)[i]), newMSums[i]);	   end         $display ("");         $write ("viterbi return: newTBEntry=");	 for (Integer i = 0; i < no_states; i = i + 1)	   begin	      $write ("%d: %h ", tpl_1(tpl_3(vRegsOutNew)[i]), newTBEntry[i]);	   end	 $display ("");      `endif      if (stage == maxBound) // last stage, output trace back	begin	   inQ.deq;	   colIdx <= colIdx + 1;	   tbu.updateMemory(vPermute(conv_in_sz, fwd_steps, newTBCol), newMinState); // put to traceback	end   end   endrule   rule performTB(True);   begin      let result <- tbu.getDecodedOutput; //get result from tb      outQ.enq(unpack(pack(result)));   end   endrule      method Action putData (VInType dataIn);      inQ.enq(dataIn);   endmethod   method ActionValue#(VOutType) getResult ();      outQ.deq;      return outQ.first;   endmethod   endmodule

⌨️ 快捷键说明

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