Commit e74fd5a0 authored by Александр Мудрик's avatar Александр Мудрик
Browse files

Delete ViterbiDecoderMatlab.m

parent c8c2bd00
No related merge requests found
Showing with 0 additions and 271 deletions
+0 -271
function decodedStream2 = ViterbiDecoderMatlab(inputBits, rate, decType) %#codegen
% Function ViterbiDecoder decodes BCC encoded bits
% with Hard or Soft Viterbi algorithm
% a lot of variables like bits->bits1 are needed for C code
% Input:
% inputBits - input sequence of bits
% rate - puncturing rate (1/2, 2/3, 3/4, 5/6)
% decType - type of decoder ('hard' / 'soft')
% Output:
% decodedStream2 - decoded bits
% initial variable to copy input bits
bits1 = zeros(length(inputBits), 1);
% if Soft decoder is used, -1*LLR should be used
if strcmp(decType, "soft")
bits1 = -inputBits;
elseif strcmp(decType, "hard")
bits1 = inputBits;
end
% Reversed puncturing
bitsPunctured = (RePuncturing(bits1, rate))';
% Initialisation of variable for decoded bits
decodedStream = zeros(1, length(bitsPunctured)/2 + 1);
% Polynom for BCC encoding
% IEEE 802.11-2020 17.3.5.6
G = [1 0 1 1 0 1 1; ...
1 1 1 1 0 0 1];
[numPolynom, lenPolynom] = size(G);
% A matrix of all possible register states
states = utils.int2bit(0:(2^(lenPolynom-1))-1, (lenPolynom-1))';
% Possible output when sending zero or one to the register for each state
outputForZero = zeros(2^(lenPolynom-1), numPolynom);
outputForOne = zeros(2^(lenPolynom-1), numPolynom);
% All possible transitions between states when transmitting 0 and 1
transitSubmit0 = zeros(64, 1);
transitSubmit1 = zeros(64, 1);
% shows previous metric
prevMetricPath1 = [0 0];
prevMetricPath2 = [0 0];
% Fills tables with transitions to 0 or 1
for i = 1:size(states, 1)
sumBitPolynom = sum(G.*[0 states(i, :)], 2);
outputForZero(i,:) = rem(sumBitPolynom',2);
transitSubmit0(i,:)= bit2Int2([0 states(i, 1:end-1)])+1;
sumBitPolynom = sum(G .* [1 states(i, :)], 2);
outputForOne(i, :) = rem(sumBitPolynom',2);
transitSubmit1(i,:)= bit2Int2([1 states(i, 1:end-1)])+1;
end
% The transition table shows where each state can go and what we get at the output
transitTabl = zeros(64, 6);
switch decType
case 'hard'
transitTabl = [transitSubmit0 outputForZero transitSubmit1 outputForOne];
case 'soft'
outputForZero(find(outputForZero(:,:)==0))=-1;
outputForOne(find(outputForOne(:,:)==0))=-1;
transitTabl = [transitSubmit0 outputForZero transitSubmit1 outputForOne];
end
row = length(bitsPunctured)/numPolynom;
col = numPolynom;
% Group input bits by 2
bitsAsMatrix = reshape(bitsPunctured, col, row);
% An array of metrics that contains metrics with possible short paths
pathMetric = zeros(2^(lenPolynom-1), size(bitsAsMatrix, 2)+1);
pathMetric(2:end) = 1e4;
branchMetric0 = zeros(64, 2);
branchMetric1 = zeros(64, 2);
% Decoding
for i = 1:size(pathMetric, 2)-1
rcvd = bitsAsMatrix(:, i)'; % first 2 bits of message
switch decType
case 'hard'
% Metric of 1st path
branchMetric0 = abs(outputForZero(:,:) - rcvd);
branchMetric0(find(branchMetric0>4)) = 0;
branchMetric0 = sum(branchMetric0,2);
% Metric of 2nd path
branchMetric1 = abs(outputForOne(:,:) - rcvd);
branchMetric1(find(branchMetric1>4)) = 0;
branchMetric1 = sum(branchMetric1,2);
case 'soft'
flag = find(rcvd==1e4);
if flag == 1
branchMetric0 = ((rcvd(2)-transitTabl(:,3)).^2);
branchMetric1 = ((rcvd(2)-transitTabl(:,6)).^2);
elseif flag == 2
branchMetric0 = ((rcvd(1)-transitTabl(:,2)).^2);
branchMetric1 = ((rcvd(1)-transitTabl(:,5)).^2);
else
branchMetric0 = ((rcvd(1)-transitTabl(:,2)).^2) + ((rcvd(2)-transitTabl(:,3)).^2);
branchMetric1 = ((rcvd(1)-transitTabl(:,5)).^2) + ((rcvd(2)-transitTabl(:,6)).^2);
end
end
% The matrix contains the indicators that we will get when moving from one state to another when transferring 0 or 1
matrixMetricTransit = [transitSubmit0 branchMetric0 transitSubmit1 branchMetric1];
for j = 1:2:size(states, 1)
pathMetric(matrixMetricTransit(j,1),i+1) = min(matrixMetricTransit(j,2)...
+ pathMetric(j, i), matrixMetricTransit(j+1,2) + pathMetric(j+1, i));
pathMetric(matrixMetricTransit(j,3),i+1) = min(matrixMetricTransit(j,4)...
+ pathMetric(j, i), matrixMetricTransit(j+1,4) + pathMetric(j+1, i));
end
end
[~, minInd] = min(pathMetric(:, size(pathMetric, 2)));
minVal = min(pathMetric(:, size(pathMetric, 2)));
% Going back through the metric matrix
for i = size(pathMetric, 2):-1:2
[row,col] = find(transitTabl == minInd);
row = row(1:2);
rcvd = bitsAsMatrix(:, i-1)';
switch decType
case 'hard'
% Search for the previous metric for the 1st path
prevMetricPath1 = abs(transitTabl(row(1),(col(1)+1):(col(1)+2)) - rcvd);
prevMetricPath1(find(prevMetricPath1>4)) = 0;
prevMetricPath1 = sum(prevMetricPath1,2);
% Search for the previous metric for the 2nd path
prevMetricPath2 = abs(transitTabl(row(2),(col(2)+1):(col(2)+2)) - rcvd);
prevMetricPath2(find(prevMetricPath2>4)) = 0;
prevMetricPath2 = sum(prevMetricPath2,2);
case 'soft'
flag = find(rcvd==1e4);
if flag == 1
prevMetricPath1 = ((rcvd(2)-transitTabl(row(1),(col(1)+2))).^2);
prevMetricPath2 = ((rcvd(2)-transitTabl(row(2),(col(2)+2))).^2);
elseif flag == 2
prevMetricPath1 = ((rcvd(1)-transitTabl(row(1),(col(1)+1))).^2);
prevMetricPath2 = ((rcvd(1)-transitTabl(row(2),(col(2)+1))).^2);
else
prevMetricPath1 = ((rcvd(1)-transitTabl(row(1),(col(1)+1))).^2) ...
+ ((rcvd(2)-transitTabl(row(1),(col(1)+2))).^2);
prevMetricPath2 = ((rcvd(1)-transitTabl(row(2),(col(2)+1))).^2) ...
+ ((rcvd(2)-transitTabl(row(2),(col(2)+2))).^2);
end
end
% The metric for the first and second paths at the end of the path
path1 = pathMetric(row(1),i-1);
path2 = pathMetric(row(2),i-1);
if path1+prevMetricPath1 == minVal
minVal = path1;
minInd = row(1);
else
minVal = path2;
minInd = row(2);
end
if transitTabl(row(1),col(1))<=(2^(lenPolynom-1))/2
outputBit = 0;
else
outputBit = 1;
end
decodedStream(i) = outputBit;
end
decodedStream1 = decodedStream(2:length(bitsPunctured)/2+1);
decodedStream2 = int8(decodedStream1');
coder.varsize('decodedStream2', [1000000 1]);
end
function rePunctured = RePuncturing(inputBits, rate)
% Func RePuncturing reverses puncturing, executed during encoding
% Input:
% bits and rate are the same as in ViterbiDecoder
% Output:
% rePunctured - bits after reversed puncturing
switch rate % choosing puncturing rate
case 1/2
% rate 1/2 - no puncturing
puncPat = 0;
case 2/3
puncPat = [1 1 1 0]';
case 3/4
puncPat = [1 1 1 0 0 1]';
otherwise % 5/6
puncPat = [1 1 1 0 0 1 1 0 0 1]';
end
% reverse puncturing is executed if rate~=1/2
msg = zeros(0, 1);
j = 0;
i = 0;
if rate ~= 1/2
for k = 1:size(inputBits, 2)
while size(inputBits, 1)+1 ~= i
i = i + 1;
j = j + 1;
if puncPat(j, 1) == 1 && size(inputBits, 1)+1 ~= i
msg = [msg; inputBits(i, k)];
end
if puncPat(j, 1) == 0
if mod(j,2)==0
msg = [msg; 1e4];
i = i - 1;
elseif mod(j,2)==1 && i < size(inputBits, 1)+1
msg = [msg; 1e4];
i = i - 1;
end
end
if j == length(puncPat)
j = 0;
end
end
end
rePunctured = msg;
else
rePunctured = inputBits;
end
end
function int = bit2Int2(bins)
% The function converts a sequence of bits into a number
% Input:
% bits
% Output:
% int - an integer
int = 0;
len = length(bins);
for i = 1:len
number = 2^(len-1)*bins(i);
len = len-1;
int = int + number;
end
end
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment