0

我正在测试约束长度 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 次,但找不到我弄错的地方

有人可以帮我找到这个错误吗?

4

0 回答 0