Генерация HDL-кода из декодера Viterbi Системного объекта

В этом примере показано, как проверить, сгенерировать и проверить HDL-код из кода MATLAB ®, который создает экземпляры объекта Viterbi Decoder System.

MATLAB- Проекта

Код MATLAB, используемый в этом примере, является декодером Viterbi, используемым в сверточном декодировании с жестким решением, реализованным как системный объект. Этот пример также показывает испытательный стенд MATLAB, который тестирует декодер.

design_name = 'mlhdlc_sysobj_viterbi';
testbench_name = 'mlhdlc_sysobj_viterbi_tb';

Давайте рассмотрим проект MATLAB.

type(design_name);
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% MATLAB design: Viterbi Decoder 
% 
% Key Design pattern covered in this example: 
% (1) Using comm system toolbox ViterbiDecoder function
% (2) The 'step' method can be called only per system object in a design iteration
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

%   Copyright 2011-2015 The MathWorks, Inc.

function decodedBits = mlhdlc_sysobj_viterbi(inputSymbol)

persistent hVitDec;

if isempty(hVitDec)
    hVitDec = comm.ViterbiDecoder('InputFormat','Hard', 'OutputDataType', 'Logical');
end

decodedBits = step(hVitDec, inputSymbol);
type(testbench_name);
% Viterbi_tb - testbench for Viterbi_dut

%   Copyright 2011-2015 The MathWorks, Inc.

numErrors = 0;
% rand stream
original_rs = RandStream.getGlobalStream;
rs = RandStream.create('mrg32k3a', 'seed', 25);
%RandStream.getGlobalStream(rs);
rs.reset;
% convolutional encoder
hConvEnc = comm.ConvolutionalEncoder;
% BER
hBER = comm.ErrorRate;
hBER.ReceiveDelay = 34;
reset(hBER);

% clear persistent variables in the design between runs of the testbench
clear mlhdlc_msysobj_viterbi;

for numSymbols = 1:10000
    % generate a random bit
    inputBit = logical(randi([0 1], 1, 1));
        
    % encode it with the Convolutional Encoder - rate 1/2
    encodedSymbol = step(hConvEnc, inputBit);
    
    % optional - add noise
    
    %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
    % call Viterbi Decoder DUT to decode the symbol
    %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
    vitdecOut = mlhdlc_sysobj_viterbi(encodedSymbol);
    
    ber = step(hBER, inputBit, vitdecOut);
end

fprintf('%s\n', repmat('%', 1, 38));
fprintf('%%%%%%%%%%%%%% %s %%%%%%%%%%%%%%\n', 'Viterbi Decoder Output');
fprintf('%s\n', repmat('%', 1, 38));
fprintf('Number of bits %d, BER %g\n', numSymbols, ber(1));
fprintf('%s\n', repmat('%', 1, 38));

% EOF

Создайте новую папку и скопируйте соответствующие файлы

Выполните следующие строки кода, чтобы скопировать необходимые файлы примера во временную папку.

mlhdlc_demo_dir = fullfile(matlabroot, 'toolbox', 'hdlcoder', 'hdlcoderdemos', 'matlabhdlcoderdemos');
mlhdlc_temp_dir = [tempdir 'mlhdlc_so_viterbi'];

% Create a temporary folder and copy the MATLAB files.
cd(tempdir);
[~, ~, ~] = rmdir(mlhdlc_temp_dir, 's');
mkdir(mlhdlc_temp_dir);
cd(mlhdlc_temp_dir);

copyfile(fullfile(mlhdlc_demo_dir, [design_name,'.m*']), mlhdlc_temp_dir);
copyfile(fullfile(mlhdlc_demo_dir, [testbench_name,'.m*']), mlhdlc_temp_dir);

Моделируйте проект

Симулируйте проект с помощью тестбенча до генерации кода, чтобы убедиться, что нет ошибок во время выполнения.

mlhdlc_sysobj_viterbi_tb
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%%%%%%% Viterbi Decoder Output %%%%%%%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
Number of bits 10000, BER 0
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

Аппаратная реализация алгоритма декодирования Viterbi

В алгоритме декодирования Viterbi есть три основных компонента. Они являются метрическими расчетами ветви (BMC), add-compare-select (ACS) и декодированием traceback. Следующая схема иллюстрирует три модулей измерения в алгоритме декодирования Viterbi.

Метод ренормализации

Декодер Viterbi препятствует переполнению метрик состояния в компоненте ACS путем вычитания минимального значения метрик состояния на каждом временном шаге, как показано на следующем рисунке.

Получение минимального значения всех метрических элементов состояния в одном такте приводит к плохой тактовой частоте для схемы. Эффективность схемы может быть улучшена путем добавления регистров трубопровода. Однако простое вычитание минимального значения, задержанного регистрами конвейера, из метрик состояния все еще может привести к переполнению.

Аппаратная архитектура изменяет метод ренормализации и избегает переполнения метрики состояния в три этапа. Во-первых, архитектура вычисляет значения порога и параметров шага, основываясь на структуре решетки и количестве бит мягкого решения. Во-вторых, задержанное минимальное значение сравнивается с порогом. Наконец, если минимальное значение больше или равно порогу значению, реализация вычитает значение шага из метрики состояния; в противном случае регулировка не выполняется. Следующий рисунок иллюстрирует модифицированный метод ренормализации.

Создайте новый HDL Coder проект

Чтобы создать новый проект, введите следующую команду:

coder -hdlcoder -new mlhdlc_viterbi

Затем добавьте файл 'mlhdlc _ sysobj _ viterbi.m' к проекту в качестве функции MATLAB и 'mlhdlc _ sysobj _ viterbi _ tb.m' в качестве испытательного стенда MATLAB.

Более полное руководство по созданию и заполнению проектов MATLAB HDL Coder см. в разделе «Начало работы с MATLAB в HDL».

Запуск преобразования с фиксированной точкой и генерации HDL-кода

Запустите советник по рабочим процессам. В Workflow Advisor щелкните правой кнопкой мыши шаг 'Генерация Кода' и выберите опцию 'Run to selected task', чтобы запустить все шаги от начала до генерации HDL-кода.

Просмотрите сгенерированный HDL-код, щелкнув по ссылкам в окне журнала.

Поддерживаемые системные объекты

Список системных объектов, поддерживаемых для генерации HDL-кода, см. в разделе Предопределенные системные объекты, поддерживаемые для генерации HDL-кода.

Очистка сгенерированных файлов

Выполните следующие команды, чтобы очистить временную папку проекта.

mlhdlc_demo_dir = fullfile(matlabroot, 'toolbox', 'hdlcoder', 'hdlcoderdemos', 'matlabhdlcoderdemos');
mlhdlc_temp_dir = [tempdir 'mlhdlc_so_viterbi'];
clear mex;
cd (mlhdlc_demo_dir);
rmdir(mlhdlc_temp_dir, 's');