我正在测试约束长度 K = 7 和码率 = 1/2 的卷积码解码器的实现。
作为我的测试环境、发射器和接收器,我使用了 mathworks 的示例。
用于测试的发射器:
M = 2; % Modulation order
我决定用最简单的调制方案 BPSK 进行测试
bps = log2(M); % Bits per modulation symbol
numSymPerFrame = 1000;
dataIn = randi([0 1],K*bps*numSymPerFrame,1);
应用卷积编码输入数据。
codedout = convenc(dataIn,trellis);
对编码符号应用调制。
txSig = qammod(codedout,M,'InputType','bit');
将 Eb/No 转换为等效的 SNR 比率。通过 AWGN 通道传递信号。
EbNo = 9;
snr = EbNo + 10*log10(bps*coderate);
rxSig = awgn(txSig,snr,'measured');
解调接收信号:
demodSig = qamdemod(rxSig,M,'OutputType','bit');
为了解码二进制解调信号,我使用了我的 Viterbi 解码器实现vitdec_k_7(length (demodSig ),demodSig, 1 )
function [code, Minmetric, Maxmetric] = vitdec_k_7(len, Din, TraceBack)
out = Din;
MERGEDIST = 70; % Distance to trace back before decoding_ check = 64,32
TRACECHUNK = 58; % How many bits to decode on each traceback : check = 8
PATHMEM = MERGEDIST + TRACECHUNK; % PATHMEM must be equal or greater than MERGEDIST+TRACECHUNK, and for efficiency it should also be a power of 2.
if TraceBack == 1
NextTraceBack = PATHMEM;
elseif TraceBack == 2
TRACECHUNK = PATHMEM;
NextTraceBack = TRACECHUNK;
else
return;
end;
% states
for state = 1: 64
new = state - 1;
EncState(state, 7) = new;
% bits for each state
for i = 6: -1: 1
EncState(state, i) = rem(new, 2);
new = fix(new / 2);
end;
%% calculation encoder outputs
% ------------------------------------------------
% g0 = 171_8 = 1 1 1 1 0 0 1
% g1 = 133_8 = 1 0 1 1 0 1 1
% ------------------------------------------------
%% Depending on the current state for 0 as input
% g0(Din) = 1*Din + 1*S6 + 1*S5 + 1*S4 + 0*S3 + 0*S2 + 1*S1
EncState(state,10) = xor(EncState(state,6), xor(EncState(state,5), xor(EncState(state,4),EncState(state,1))));
% g1(Din) = 1*Din + 0*S6 + 1*S5 + 1*S4 + 0*S3 + 1*S2 + 1*S1
EncState(state,11) = xor(EncState(state,5),xor(EncState(state,4),xor(EncState(state,2),EncState(state,1))));
%% Depending on the current state for 0 as input
EncState(state, 12) = xor(1, EncState(state, 10));
EncState(state, 13) = xor(1, EncState(state, 11));
%% Branch Metric selA
if EncState(state,10) == 0
if EncState(state,11)== 0 EncState(state,14) = 4; % --
else EncState(state,14) = 3; % -+
end;
else
if EncState(state,11)== 0 EncState(state,14) = 2; % +-
else EncState(state,14) = 1; % ++
end;
end;
%% Branch Metric selB
if EncState(state,12)== 0
if EncState(state,13)== 0 EncState(state,15) = 4; %--
else EncState(state,15) = 3; %-+
end;
else
if EncState(state,13)== 0 EncState(state,15) = 2; %+-
else EncState(state,15) = 1; %++
end;
end;
end;
%% INitialisation of metric_A u. metric_B;
for state = 1: 64
metric_A(state) = 16; % K = 7
metric_B(state) = 16; % K = 7
end
Renorm = 0;
%% MAIN Path Metric Calculation
t = 1;
WritePos = 0;
% For all inputs; 4 input data Bits (2*Din[g0,g1]) per loop
while(1)
%% 1. -> loop first Din[g0,g1] READ from metric_A WRITE to metric_B
% Branch Metric Calculation: Soft Decision with 4 Bit (+7/-8): BranchMetric max. 16
D0P = out(1,t);
D1P = out(2,t);
D0N = -out(1,t);
D1N = -out(2,t);
BranchMetric(1) = (D0P + D1P) + Renorm; %++
BranchMetric(2) = (D0P + D1N) + Renorm; %+-
BranchMetric(3) = (D0N + D1P) + Renorm; %-+
BranchMetric(4) = (D0N + D1N) + Renorm; %--
Renorm = 0;
WritePos = WritePos + 1;
maxmetric = -32;
for state = 1: 32
% new state is a result of shifting the EncBits
newstate = (2 * (state - 1)) + 1;
% calculation of 2 possible "reasonable" distances for state(n); corresponding BranchMetric
a = BranchMetric(EncState(state,14)); % Branch Metric selA (Distance)
b = BranchMetric(EncState(state,15)); % Branch Metric selB (Distance)
% Assumtion: sent bits "0"
metric1 = metric_A(state) + a; % read old_metric (comming from first possible state with '0' to next state) and "add" corresponding BranchMetric
metric2 = metric_A(state + 32) + b; % read old_metric (comming from second possible state with '0' to next state) and "add" corresponding BranchMetric
% Define pathes (which with the biggest metric)
if t < 7
% Trellis is not complete: save metric1
metric_B(newstate) = metric1;
Dbgmetric(newstate, t) = metric1;
prev(newstate, WritePos) = 0; % notice the first best path (the biggest metric)
elseif metric2 > metric1
metric_B(newstate) = metric2;
Dbgmetric(newstate, t) = metric2;
prev(newstate, WritePos) = 1; % notice the 2nd best path (the biggest metric)
else
metric_B(newstate) = metric1;
Dbgmetric(newstate, t) = metric1;
prev(newstate, WritePos) = 0; % notice the first best path (the biggest metric)r
end;
if metric_B(newstate) > maxmetric
%notice the new beststate und maxmetric
maxmetric = metric_B(newstate);
beststate = newstate;
end;
% if we send 1
metric1 = metric_A(state) + b; % read old_metric (comming from first possible state with '1' to next state) and "add" corresponding BranchMetric
metric2 = metric_A(state + 32) + a; % read old_metric (comming from second possible state with '1' to next state) and "add" corresponding BranchMetric
% Define pathes (which with the biggest metric)
if t < 7
% Trellis is not complete: save metric1
metric_B(newstate + 1) = metric1;
Dbgmetric(newstate + 1, t) = metric1;
prev(newstate + 1,WritePos) = 0; % notice the first best path (the biggest metric)
elseif metric2 > metric1
metric_B(newstate + 1) = metric2;
Dbgmetric(newstate + 1, t) = metric2;
prev(newstate + 1,WritePos) = 1; % notice the 2nd best path (the biggest metric)
else
metric_B(newstate + 1) = metric1;
Dbgmetric(newstate + 1, t) = metric1;
prev(newstate + 1,WritePos) = 0; % notice the first best path (the biggest metric)
end;
if metric_B(newstate + 1) > maxmetric
% notice the new beststate und maxmetric
maxmetric = metric_B(newstate + 1);
beststate = newstate + 1;
end;
end;
t = t + 1;
if t > len break; end;
%% Renormalize metric_A to prevent overflow for this check read metric_B
for i = 1: 64
if metric_B(i) >= (16)
Renorm = -48;
end;
end;
%% 2. -> loop second Din[g0,g1] REAAD from metric_B WRITE to metric_A
% Branch Metric Calculation: Soft Decision with 4 Bit (+7/-8): BranchMetric max. 16
D0P = out(1,t);
D1P = out(2,t);
D0N = -out(1,t);
D1N = -out(2,t);
BranchMetric(1) = (D0P + D1P) + Renorm; %++
BranchMetric(2) = (D0P + D1N) + Renorm; %+-
BranchMetric(3) = (D0N + D1P) + Renorm; %-+
BranchMetric(4) = (D0N + D1N) + Renorm; %--
Renorm = 0;
WritePos = WritePos + 1;
maxmetric = -32;
for state = 1: 32
% new state is a result of shifting the EncBits
newstate = (2 * (state - 1)) + 1; % 1, 3, 5...63
% calculation of 2 possible "reasonable" distances for state(n); corresponding BranchMetric
a = BranchMetric(EncState(state,14)); % Branch Metric selA (Distance)
b = BranchMetric(EncState(state,15)); % Branch Metric selB (Distance)
% if we send "0"
metric1 = metric_B(state) + a; % read old_metric (comming from first possible state with '0' to next state) and "add" corresponding BranchMetric
metric2 = metric_B(state + 32) + b; % read old_metric (comming from second possible state with '0' to next state) and "add" corresponding BranchMetric
if t < 7
% Trellis is not complete: save metric1
metric_A(newstate) = metric1;
Dbgmetric(newstate, t) = metric1;
prev(newstate, WritePos) = 0;
elseif metric2 > metric1
metric_A(newstate) = metric2;
Dbgmetric(newstate, t) = metric2;
prev(newstate, WritePos) = 1;
else
metric_A(newstate) = metric1;
Dbgmetric(newstate, t) = metric1;
prev(newstate, WritePos) = 0;
end;
if metric_A(newstate) > maxmetric
maxmetric = metric_A(newstate);
beststate = newstate;
end;
% if we send 1
metric1 = metric_B(state) + b; % read old_metric (comming from first possible state with '1' to next state) and "add" corresponding BranchMetric
metric2 = metric_B(state + 32) + a; % read old_metric (comming from second possible state with '1' to next state) and "add" corresponding BranchMetric
if t < 7
% Trellis is not complete: save metric1
metric_A(newstate + 1) = metric1;
Dbgmetric(newstate + 1, t) = metric1;
prev(newstate + 1,WritePos) = 0;
elseif metric2 > metric1
metric_A(newstate + 1) = metric2;
Dbgmetric(newstate + 1, t) = metric2;
prev(newstate + 1,WritePos) = 1;
else
metric_A(newstate + 1) = metric1;
Dbgmetric(newstate + 1, t) = metric1;
prev(newstate + 1,WritePos) = 0;
end;
if metric_A(newstate + 1) > maxmetric
maxmetric = metric_A(newstate + 1);
beststate = newstate + 1;
end;
end;
if t == NextTraceBack
% partial Trace Back
NextTraceBack = NextTraceBack + TRACECHUNK;
ReadPos = WritePos;
if TraceBack == 1
% VARIANTE 1 --------------------------------------------------------------
% Start on an arbitrary path and trace it back until it's almost
% certain we've merged onto the best path -> aprox. 2*5*k (MERGEDIST 88)
beststate = 1;
for i = 1: PATHMEM
tmp = prev(beststate,ReadPos);
ReadPos = ReadPos - 1;
beststate = [tmp EncState(beststate, 1:5)];
beststate = beststate(1)*32 + beststate(2)*16 + beststate(3)*8 + beststate(4)*4 + beststate(5)*2 + beststate(6)*1 + 1;
if i > MERGEDIST
code((t + 1) - i) = tmp;
end;
end;
end;
if TraceBack == 2
% VARIANTE 2 --------------------------------------------------------------
% Start on the best state and trace back TRACECHUNK positions
for i = 1: TRACECHUNK
tmp = prev(beststate,ReadPos);
ReadPos = ReadPos - 1;
beststate = [tmp EncState(beststate, 1:5)];
beststate = beststate(1)*32 + beststate(2)*16 + beststate(3)*8 + beststate(4)*4 + beststate(5)*2 + beststate(6)*1 + 1;
code((t + 1) - i) = tmp;
end;
end;
end;
t = t + 1;
if t > len break; end;
end;
t = t - 1; % go back
beststate = 1; % beststate after 8 zeros
ReadPos = WritePos; % from the last WritePos we are going
if PATHMEM > t PATHMEM = t; end;
% TRACE BACK
for i = 1: PATHMEM
tmp = prev(beststate,ReadPos);
ReadPos = ReadPos - 1;
beststate = [tmp EncState(beststate, 1:5)];
beststate = beststate(1)*32 + beststate(2)*16 + beststate(3)*8 + beststate(4)*4 + beststate(5)*2 + beststate(6)*1 + 1;
code((t + 1) - i) = tmp;
end;
% the first 8bits are botched
code(1: len - 8) = code(9: len); % we advance all 8bits
code(len - 7: len) = 0; % and end with 8 zeros
Minmetric = min(min (Dbgmetric));
Maxmetric = max(max( Dbgmetric));
我已经计算了误码率,它是 30% 。这个数字告诉我有一个很大的错误。我检查了我的认识大约 100 次,但找不到我弄错的地方
有人可以帮我找到这个错误吗?