В этом примере показано, как реализовать БПФ переменного размера с использованием одного ядра БПФ.
Этот пример включает две модели VariableSizeFFTHDLExample и VariableSizeFFTArbitraryValidPatternHDLExample, которые показывают реализации FFT переменного БПФ для различных входных допустимых шаблонов.
Многие популярные стандарты, такие как WLAN, WiMax, цифровая видеотрансляция (DVB), цифровая аудиотрансляция (DAB) и долгосрочная эволюция (LTE), обеспечивают несколько опции пропускной способности. Необходимая длина БПФ для модуляции OFDM и демодуляции для этих стандартов варьируется в зависимости от опции полосы пропускания. Например, LTE поддерживает различные опции пропускной способности канала от 1,4 МГц до 20 МГц, которые требуют длины БПФ от 128 до 2048 соответственно. Блок FFT HDL Optimized (DSP System Toolbox) генерирует HDL-код для определенной длины БПФ. Этот пример демонстрирует, как использовать блок FFT HDL Optimized для реализации БПФ переменного размера.
Этот пример генерирует входные данные в MATLAB ® и импортирует их в Simulink ® для симуляции. Импортированные данные подаются в реализации БПФ переменного размера с помощью одного БПФ и нескольких БПФ. Чтобы продемонстрировать, что реализация с одним FFT соответствует результатам использования нескольких FFT различных размеров, оба выходных потока из симуляции Simulink экспортируются в MATLAB и сравниваются.
Подсистема верхнего уровня в обеих моделях реализует БПФ переменного размера. Верхняя подсистема использует один блок FFT, а нижняя подсистема предоставляет справочные данные при помощи нескольких блоков FFT различных размеров.
Модель VariableSizeFFTHDLExample может обрабатывать данные с погрешностью между допустимыми выборками при условии, что погрешность зависит от длины БПФ.
modelname = 'VariableSizeFFTHDLExample';
open_system(modelname);
Длины БПФ заданы через переменную fftLenVecMulFFTs
. Самая большая из этих длин сохранена в переменной fftLenSinFFT
и используется в качестве длины БПФ для блока БПФ в 'Variable Size FFT using Single FFT'
подсистема.
Область входа fftLenIn
генерируется при помощи вектора длин БПФ, заданных в fftLenVecMulFFTs
.
fftLenVecMulFFTs = [128;256;512;1024;2048]; % Single FFT length used by variable size FFT. fftLenSinFFT = max(fftLenVecMulFFTs); % Generate |fftLenIn| by repeating each element of |fftLenVecMulFFTs| by % |fftLenSinFFT| times and arranging in a single column. fflen =repmat(fftLenVecMulFFTs.',fftLenSinFFT,1); fftLenIn = uint16(fflen(:));
dataIn
, validIn
, и fftLenIn
входы генерируются в MATLAB и импортируются в модель Simulink. Случайные комплексные входные данные randInputData
генерируется для каждой из длин БПФ, заданных в fftLenVecMulFFTs
. Различные длины БПФ соответствуют различным полосам пропускания и различным частотам дискретизации. Для образца в LTE длины БПФ 128, 256, 512, 1024 и 2048 соответствуют частотам дискретизации 1,92 МГ ц, 3,84 МГ ц, 7,68 МГ ц, 15,36 МГ ц и 30,72 МГ ц соответственно. Время символа для любой длины БПФ является. Пример работает с самой высокой частотой среди заданных длин БПФ.
The dataIn
сигнал генерируется путем заполнения нулями между randInputData
выборки. Рисунок ниже показывает входные данные и допустимые шаблоны для fftLenVecMulFFTs
256 и 512 и fftLenSinFFT
быть 2048. Для длины БПФ 256, пример вставляет 7 недопустимых выборок для каждой действительной выборки и для длины БПФ 512, код вставляет 3 недопустимых выборки для каждой действительной выборки.
Модель VariableSizeFFTHDLExample требует, чтобы входной допустимый шаблон имел разрыв между допустимыми выборками, как показано на рисунке ниже.
rng('default'); dataIn = zeros(length(fftLenVecMulFFTs)*fftLenSinFFT,1); validIn = false(length(fftLenVecMulFFTs)*fftLenSinFFT,1); % Loop over the FFT lengths for ind = 1:length(fftLenVecMulFFTs) % Generate data of FFT length samples randInputData = complex(randn(1,fftLenVecMulFFTs(ind)),randn(1,fftLenVecMulFFTs(ind))); % Zero padding in between input data samples upSamplingFac = fftLenSinFFT/fftLenVecMulFFTs(ind); dataIn((ind-1)*fftLenSinFFT+1:fftLenSinFFT*ind) = upsample(randInputData,upSamplingFac); % Valid corresponding to the generated data tempValid = true(1,fftLenVecMulFFTs(ind)); validIn((ind-1)*fftLenSinFFT+1:fftLenSinFFT*ind) = upsample(tempValid,upSamplingFac); end inputDataType = 'fixdt(1,16,14)'; % Input data type can be modified here set_param('VariableSizeFFTHDLExample/Data Type Conversion','OutDataTypeStr', inputDataType); % Get FFT latency fftObj = dsp.HDLFFT('FFTLength',fftLenSinFFT,... 'Architecture','Streaming Radix 2^2',... 'ComplexMultiplication','Use 3 multipliers and 5 adders',... 'BitReversedOutput',false,... 'BitReversedInput',false,... 'Normalize',false); latency=getLatency(fftObj); % Default latency is 4137 for 2048 point FFT. additionPipelineDelay = 6; % Number of additional pipeline delays % Simulink simulation end time Total Latency = Latency of FFT + Latency of % data controller (5 clock cycles). % Total simulation running time = Total % number of input samples + Total Latency + Pipeline delay. simTime = fftLenSinFFT*(length(fftLenVecMulFFTs) + 1) + latency + additionPipelineDelay ;
The 'Variable-Size FFT using Single FFT'
проект включает контроллер данных, блок FFT HDL Optimized и подсистему выбора интервал.
open_system([modelname '/Variable Size FFT using Single FFT']);
The Data Controller
подсистема управляет входными данными так, чтобы вход в блок FFT HDL Optimized имел выборки данных с заполненными между ними нулями. Блок FFT HDL Optimized сконфигурирован для длины FFT 2048, самой большой длины БПФ, требуемой стандартом LTE. Чтобы упростить выбор выходных интервалов, блок FFT сконфигурирован для вывода выборок в битовом естественном порядке. Длина БПФ задается через входной порт и дискретизируется в начале системы координат. Требуемая длина БПФ должна быть задержана, чтобы соответствовать задержке БПФ. Длина БПФ регистрируется с помощью начального выходного сигнала БПФ и сгенерированного конца системы координат. Этот способ избегает реализации большой памяти, соответствующей задержке. Поскольку входные данные имеют нули между выборками, выход большого БПФ содержит повторные копии выборок длины БПФ. Чтобы получить необходимый выход БПФ, первые выборки длины БПФ собираются с выхода БПФ. Эта операция выполняется путем изменения выхода допустимого сигнала БПФ с помощью Bin selection
подсистема.
Эта подсистема используется как ссылка для сравнения с выходами БПФ Переменного Размера с помощью Single FFT. Подсистема включает пять различных блоков БПФ (БПФ 128, БПФ 256, БПФ 512, БПФ 1024 и БПФ 2048) и один Блок MATLAB function. Входные данные будут поданы на все пять БПФ. В зависимости от требуемой длины БПФ активируется один из пяти блоков БПФ и выполняется операция БПФ. Область Блока MATLAB function pickFFTData
выбирает выход из соответствующего блока БПФ. Выходы сохраняются в MATLAB для сравнения с выходами БПФ Переменного размера с помощью Single FFT.
open_system([modelname '/Multiple FFTs for Reference']);
Скрипт MATLAB конфигурирует желаемый вектор длин БПФ, размер одинарного БПФ и генерирует входные данные с действительным сигналом. Затем он запускает модель и сравнивает выход двух подсистем в MATLAB.
Запустите модель с помощью sim
команда в командной строке MATLAB.
sim(modelname);
Выходы от обеих подсистем отправляются в рабочее пространство MATLAB, и выполняется построение графика различий. В этом случае выход двух подсистем идентичен, и ошибка между двумя множествами значений равна 0.
dataOut1 = out1(:); dataOut2 = out2(:); figVSF = figure('Visible', 'off'); plot(abs(dataOut1-dataOut2)); title('Difference between the two outputs for fixed valid pattern') xlabel('Sample Index'); ylabel('Error'); figVSF.Visible = 'on'; bdclose(modelname);
Вышеописанная модель VariableSizeFFTHDLExample имеет требование иметь минимальную погрешность между выборками входных данных. Погрешность зависит от заданной длины БПФ и самой большой длины БПФ, обрабатываемой проектом. Могут быть случаи, когда входные данные могут не соответствовать этому шаблону. Для примера данные могут быть непрерывными и заполнены нулями в конце выборок входных данных. Следующий рисунок показывает непрерывный входной допустимый шаблон с недопустимыми выборками, заполненными в конце выборки входных данных для длин БПФ 256 и 512. Длина одиночного БПФ устанавливается равной 2048. В этом случае за 256 действительными выборками следуют 1792 недействительных выборки, а за 512 действительными выборками следуют 1536 недействительных выборок.
В таком сценарии проект должен хранить входные выборки в ОЗУ и дополнять недопустимые выборки между допустимыми выборками перед отправкой их в БПФ. Модель VariableSizeFFTArbitraryValidPatternHDLExample может обрабатывать любой произвольный шаблон допустимого входа, пока зазор между системами координат составляет по крайней мере одну длину БПФ (2048 выборок для LTE). Эта модель аналогична модели VariableSizeFFTHDLExample, кроме подсистемы контроллера данных. Подсистема контроллера данных в модели использует ОЗУ размера 2*fftLenSinFFT
(как показано на рисунке ниже), чтобы сохранить входные выборки, считывает действительные выборки, заполняя нули между ними и затем передавая их в БПФ. В то время как входные данные записываются в одну половину памяти, данные считываются из другой половины памяти. В результате общая задержка увеличивается на fftLenSinFFT
.
modelname = 'VariableSizeFFTArbitraryValidPatternHDLExample'; load_system(modelname); open_system([modelname '/Variable Size FFT using Single FFT/Data Controller']);
Для генерации произвольных данных и допустимых входов пользователи могут выбрать любой из этих трёх опций: нулевое заполнение фиксированного размера между выборками данных, нулевое заполнение в конце выборки данных и нулевое заполнение случайного размера между выборками данных. Входные данные и действительная генерация для этих трех различных шаблонов нулевого заполнения показаны ниже. Модель VariableSizeFFTArbitraryValidPatternHDLExample использует сгенерированные данные и действительны для симуляции и верификации.
% Initialization of input data and valid dataIn = zeros(length(fftLenVecMulFFTs)*fftLenSinFFT,1); validIn = false(length(fftLenVecMulFFTs)*fftLenSinFFT,1); zeroPaddingPattern = 'InBetween'; %'AtEnd','Random' switch zeroPaddingPattern case 'InBetween' % Zero padding in between input data samples for ind = 1:length(fftLenVecMulFFTs) % Generate data of FFT length samples randInputData = complex(randn(1,fftLenVecMulFFTs(ind)),randn(1,fftLenVecMulFFTs(ind))); % Zero padding in between input data samples upSamplingFac = fftLenSinFFT/fftLenVecMulFFTs(ind); dataIn((ind-1)*fftLenSinFFT+1:fftLenSinFFT*ind) = upsample(randInputData,upSamplingFac); % Valid corresponding to the generated data validIn((ind-1)*fftLenSinFFT+1:upSamplingFac:fftLenSinFFT*ind) = true; end case 'AtEnd' % Zero padding at the end of input data samples for ind = 1:length(fftLenVecMulFFTs) % Generate data of FFT length samples randInputData = complex(randn(1,fftLenVecMulFFTs(ind)),randn(1,fftLenVecMulFFTs(ind))); % Zero padded data dataIn(((ind-1)*fftLenSinFFT+1):((ind-1)*fftLenSinFFT+fftLenVecMulFFTs(ind))) = randInputData; % Valid corresponding to data generated validIn(((ind-1)*fftLenSinFFT+1):((ind-1)*fftLenSinFFT+fftLenVecMulFFTs(ind))) = true; end otherwise % Random for ind =1:length(fftLenVecMulFFTs) % Zero padding at random randIndices = randperm(fftLenSinFFT); % Generate data of FFT length samples randInputData = complex(randn(1,fftLenVecMulFFTs(ind)),randn(1,fftLenVecMulFFTs(ind))); indices = randIndices(1:fftLenVecMulFFTs(ind)); % If the random indices does not have the first sample if(sum(indices==1)==0) indices(1) = 1; end % Zero padded data dataIn(indices+(ind-1)*fftLenSinFFT) = randInputData; % Valid corresponding to data generated validIn(indices+(ind-1)*fftLenSinFFT) = true; end end
Прежде чем запускать модель, убедитесь, что dataIn
, validIn
, fftLenIn
, и необходимые переменные инициализируются.
sim(modelname);
dataOut1 = out1(:); dataOut2 = out2(:); figVSFAIV = figure('Visible', 'off'); plot(abs(dataOut1-dataOut2)); title('Difference between the two outputs for arbitrary valid pattern') xlabel('Sample Index'); ylabel('Error'); figVSFAIV.Visible = 'on'; bdclose(modelname);
Чтобы сгенерировать HDL-код, на который ссылаются в этом примере, необходима HDL- Coder™ лицензия.
Можно использовать команды makehdl
и makehdltb
для генерации HDL-кода и тестового набора для подсистем.
HDL-код, сгенерированный для подсистем БПФ переменного размера, был синтезирован для ZC706 платы Xilinx ® Zynq ® -7000. Результаты синтеза показаны в следующей таблице.
В таблице выше показано, что реализация БПФ переменного размера с использованием одной БПФ использует меньше аппаратных ресурсов, чем использование нескольких решений. Чтобы поддержать произвольный входной допустимый шаблон, аппаратная реализация использует больше оперативной памяти.
FFT HDL Optimized (DSP System Toolbox)