📄 iviterbi.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 FIFO::*;import Monad::*;import Traceback::*;import Vector::*;import VParams::*;import VRegFile::*;import Parameters::*;//`define isDebug True // uncomment this line to display error// useful integers definitionsInteger radix_sz = valueOf(RadixSz);Integer no_states = valueOf(VTotalStates);Integer fwd_steps = valueOf(FwdSteps);Integer fwd_entry_sz = valueOf(FwdEntrySz);Integer conv_in_sz = valueOf(ConvInSz);Integer conv_out_sz = valueOf(ConvOutSz);Integer vregs_out_sz = valueOf(VRegsOutSz);Integer half_max_metric_sum = valueOf(TExp#(TLog#(TAdd#(VMaxMetricSum,1))));Integer no_tbstage = valueOf(NoOfTBStage);//////////////////////////////////////////////////////////// begin of interface definitions/////////////////////////////////////////////////////////interface IViterbi; method Action putData (VInType dataIn); method ActionValue#(VOutType) getResult ();endinterface/////////////////////////////////////////////////////////// Begin of library functions and modules/////////////////////////////////////////////////////////function VState getNextState(VState state, Bit#(ConvInSz) nextBits); let tmp = {nextBits, state}; return tpl_1(split(tmp)); // drop LSBsendfunctionfunction VState getPrevState(VState state, Bit#(ConvInSz) prevBits); let tmp = {state, prevBits}; return tpl_2(split(tmp)); // drop MSBsendfunction // ViterbiStatefunction Vector#(ConvOutSz, Bit#(KSz)) getConvVec(); Vector#(ConvOutSz, Bit#(KSz)) outVec = newVector(); outVec[0] = convEncoderG1; outVec[1] = convEncoderG2; return outVec;endfunction // Vector// get the output of the convolutional encoder. convention is// {b, a} - meaning a is the low bit and b is the high bitfunction Vector#(ConvOutSz, Bit#(1)) getConvEncOutput (VState state, Bit#(ConvInSz) inBits); Vector#(ConvOutSz, Bit#(KSz)) convVec = getConvVec(); Bit#(KSz) temp = {inBits, state}; Vector#(ConvOutSz, Bit#(1)) outVec = replicate(0); for(Integer idx = 0; idx < valueOf(ConvOutSz); idx = idx + 1) for(Integer bitNum = 0; bitNum < valueOf (KSz); bitNum = bitNum + 1) outVec[idx] = outVec[idx] + (temp[bitNum] & convVec[idx][bitNum]); return outVec;endfunction// this is used to calculate the index of data that i need to readfunction Vector#(sz, Integer) getIdxLUT (Integer conv_in_sz, Integer stage); Integer v_sz = valueOf(sz); Integer shift_sz = conv_in_sz * stage; Integer mul_val = exp(2, shift_sz); Integer div_val = v_sz / mul_val; Vector#(sz, Integer) outVec = newVector; for (Integer i = 0; i < v_sz; i = i + 1) outVec[i] = ((i % div_val) * mul_val) + (i / div_val); // performing a circular right shift return outVec;endfunction// this actually perform the permutationfunction Vector#(sz, val_t) vPermute (Integer conv_in_sz, Integer stage, Vector#(sz, val_t) inVec); return map(select(inVec), getIdxLUT(conv_in_sz, stage));endfunction // Vector// this actually perform the reverse permutation function Vector#(sz, val_t) reverseVPermute (Integer conv_in_sz, Integer stage, Vector#(sz, val_t) inVec); Integer v_sz = valueOf(sz); Vector#(sz, val_t) outVec = newVector; Vector#(sz, Integer) lut = getIdxLUT(conv_in_sz, stage); for (Integer i = 0; i < v_sz; i = i + 1) outVec[lut[i]] = inVec[i]; return outVec;endfunction // Vector// this function is passed as a parameter to mkVRegFilefunction Vector#(out_sz, value_T) readSelect (Integer conv_in_sz, Integer stage, Bit#(sub_idx_sz) sidx, Vector#(row_sz, value_T) inVec) provisos (Log#(out_sz, out_idx_sz), Log#(row_sz, row_idx_sz), Add#(sub_idx_sz, out_idx_sz, row_idx_sz)); Vector#(out_sz, value_T) outVec = newVector; Vector#(row_sz, value_T) newInVec = vPermute(conv_in_sz, stage, inVec); Nat shiftN = fromInteger(valueOf(out_idx_sz)); for (Integer i = 0; i < valueOf(out_sz); i = i + 1) begin Bit#(out_idx_sz) idx1 = fromInteger(i); Bit#(row_idx_sz) idx2 = zeroExtend(idx1) + (zeroExtend(sidx) << shiftN); outVec[idx1] = newInVec[idx2]; end return outVec;endfunction// this function is passed as a parameter to mkVRegFilefunction Vector#(row_sz, value_T) reverseReadSelect (Integer conv_in_sz, Integer stage, Bit#(sub_idx_sz) sidx, Vector#(out_sz, value_T) inVec) provisos (Log#(out_sz, out_idx_sz), Log#(row_sz, row_idx_sz), Add#(sub_idx_sz, out_idx_sz, row_idx_sz)); Vector#(row_sz, value_T) outVec = newVector; Nat shiftN = fromInteger(valueOf(out_idx_sz)); for (Integer i = 0; i < valueOf(out_sz); i = i + 1) begin Bit#(out_idx_sz) idx1 = fromInteger(i); Bit#(row_idx_sz) idx2 = zeroExtend(idx1) + (zeroExtend(sidx) << shiftN); outVec[idx2] = inVec[idx1]; end outVec = reverseVPermute(conv_in_sz, stage, outVec); return outVec;endfunction// this function passed as a parameter to mkVRegFilefunction Vector#(row_sz, value_T) writeSelect (Bit#(sub_idx_sz) sidx, Vector#(row_sz, value_T) inVec1, Vector#(out_sz, value_T) inVec2) provisos (Log#(out_sz, out_idx_sz), Log#(row_sz, row_idx_sz), Add#(sub_idx_sz, out_idx_sz, row_idx_sz)); Vector#(row_sz, value_T) outVec = inVec1; Nat shiftN = fromInteger(valueOf(out_idx_sz)); for (Integer i = 0; i < valueOf(out_sz); i = i + 1) begin Bit#(out_idx_sz) idx1 = fromInteger(i); Bit#(row_idx_sz) idx2 = zeroExtend(idx1) + (zeroExtend(sidx) << shiftN); outVec[idx2] = inVec2[idx1]; end return outVec;endfunction (* synthesize *)module mkMetricSums (VRegFile#(VRegsSubIdxSz,VRegsOutSz,VMetricSum)); let vRegFile <- mkVRegFile(readSelect(conv_in_sz, fwd_steps),writeSelect, 0); return vRegFile;endmodule // mkVRegFileFull(* synthesize *)module mkTrellis (VRegFile#(VRegsSubIdxSz,VRegsOutSz,VTrellisEntry)); let vRegFile <- mkVRegFile(readSelect(conv_in_sz, fwd_steps),writeSelect, 0); return vRegFile;endmodule // mkVRegFileFullfunction VMetric getMetric(Bit#(1) in); return ((in == 0) ? 0 : maxBound);endfunction // Metric // generate the metric look up table// table index = {nextState, prevStateSuffix}(* noinline *)function MetricLUT getMetricLUT(); MetricLUT outVec = newVector; for (Integer next_state = 0; next_state < no_states; next_state = next_state + 1) begin VState nextState = fromInteger(next_state); Tuple2#(Bit#(ConvInSz), Bit#(TSub#(VStateSz, ConvInSz))) nsTup = split(nextState); Bit#(ConvInSz) inBits = tpl_1(nsTup); Bit#(TSub#(VStateSz, ConvInSz)) prevStatePrefix = tpl_2(nsTup); for (Integer prev_state_suffix = 0; prev_state_suffix < radix_sz; prev_state_suffix = prev_state_suffix + 1) begin Bit#(ConvInSz) prevStateSuffix = fromInteger(prev_state_suffix); VState prevState = {prevStatePrefix, prevStateSuffix}; Vector#(ConvOutSz, Bit#(1)) convOut = getConvEncOutput(prevState, inBits); outVec[next_state*radix_sz + prev_state_suffix] = map(getMetric, convOut); end end // for (Integer next_state = 0; next_state < no_states; next_state = next_state + 1) return outVec;endfunction function PrimEntry#(tEntry_T) chooseMin (PrimEntry#(tEntry_T) in1, PrimEntry#(tEntry_T) in2); return ((tpl_2(in1) - tpl_2(in2) < fromInteger(half_max_metric_sum)) ? in2 : in1); endfunction // Tuple3// used for create a TB pathfunction VTrellisEntry getNextTrellisEntry (VState prevState, VState nextState, VTrellisEntry oldTEntry); Bit#(ConvInSz) inBit = tpl_1(split(nextState)); return tpl_1(split({inBit, oldTEntry})); // shift out LSBsendfunction // VTrellisEntry// used for create a TB col, MSB = oldest columnfunction Bit#(VStateSuffixSz) getNextTB (VState prevState, VState nextState, Bit#(VStateSuffixSz) oldTEntry); Bit#(ConvInSz) inBit = tpl_2(split(prevState)); return tpl_1(split({inBit, oldTEntry})); // shift out LSBsendfunction // VTrellisEntryfunction RadixEntry#(tEntry_T) radixCompute(RadixEntry#(tEntry_T) inVec, Vector#(ConvOutSz, VMetric) inMetrics, function tEntry_T getNextTEntry(VState prevState, VState nextState, tEntry_T oldTEntry)); function VMetricSum calcVMetricSum (VMetricSum inSum, Vector#(ConvOutSz, Bit#(1)) expBits, Vector#(ConvOutSz, VMetric) recMetrics);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -