В этом примере показано, как проверить, сгенерировать и проверить HDL-код из кода MATLAB ®, который создает экземпляры объекта Viterbi Decoder System.
Код 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 есть три основных компонента. Они являются метрическими расчетами ветви (BMC), add-compare-select (ACS) и декодированием traceback. Следующая схема иллюстрирует три модулей измерения в алгоритме декодирования Viterbi.
Декодер Viterbi препятствует переполнению метрик состояния в компоненте ACS путем вычитания минимального значения метрик состояния на каждом временном шаге, как показано на следующем рисунке.
Получение минимального значения всех метрических элементов состояния в одном такте приводит к плохой тактовой частоте для схемы. Эффективность схемы может быть улучшена путем добавления регистров трубопровода. Однако простое вычитание минимального значения, задержанного регистрами конвейера, из метрик состояния все еще может привести к переполнению.
Аппаратная архитектура изменяет метод ренормализации и избегает переполнения метрики состояния в три этапа. Во-первых, архитектура вычисляет значения порога и параметров шага, основываясь на структуре решетки и количестве бит мягкого решения. Во-вторых, задержанное минимальное значение сравнивается с порогом. Наконец, если минимальное значение больше или равно порогу значению, реализация вычитает значение шага из метрики состояния; в противном случае регулировка не выполняется. Следующий рисунок иллюстрирует модифицированный метод ренормализации.
Чтобы создать новый проект, введите следующую команду:
coder -hdlcoder -new mlhdlc_viterbi
Затем добавьте файл 'mlhdlc _ sysobj _ viterbi.m' к проекту в качестве функции MATLAB и 'mlhdlc _ sysobj _ viterbi _ tb.m' в качестве испытательного стенда MATLAB.
Более полное руководство по созданию и заполнению проектов MATLAB HDL Coder см. в разделе «Начало работы с MATLAB в 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');