В этом примере показано, как спроектировать цифровой преобразователь частоты (DDC) для приложений радиосвязи, таких как LTE, и сгенерировать HDL-код с HDL- Coder™.
DDC широко используются в цифровых приемниках связи для преобразования сигналов радиочастоты (RF) или промежуточной частоты (IF) в полосу модулирующих частот. Операция DDC смещает сигнал на более низкую частоту и уменьшает его частоту дискретизации, чтобы облегчить последующие этапы обработки. Представленный здесь DDC выполняет комплексный преобразование частоты с последующим преобразованием частоты дискретизации с использованием 4-ступенчатого фильтрующей цепи. Пример начинается с разработки DDC с функциями DSP System Toolbox™ в плавающей точке. Затем каждый этап преобразуется в фиксированную точку, а затем используется в модели Simulink ®, которая генерирует синтезируемый HDL-код. Для демонстрации и проверки операции DDC используются два тестовых сигнала:
Синусоида, модулированная на несущей IF на 32 МГц.
Сигнал нисходящего канала LTE с шириной полосы 1,4 МГц, модулируемый на несущей IF на 32 МГц.
Пример измеряет качество сигнала на выходе DDC с плавающей и фиксированной точками и сравнивает эти два. Наконец, представлены результаты реализации ПЛИС.
Примечание: Этот пример использует DDCTestUtils
, класс helper, содержащий функции для генерации стимула и анализа выхода DDC. Смотрите DDCTestUtils.m
файл для получения дополнительной информации.
DDC состоит из численно управляемого генератора (NCO), смесителя и децимирующей цепи фильтра. Фильтрующая цепь состоит из CIC дециматора, коррекции усиления CIC, CIC компенсационного дециматора ( конечной импульсной характеристики), halfband конечной импульсной характеристики дециматора и конечной конечной импульсной характеристики дециматора. Общая реакция цепи фильтров эквивалентна реакции одного децимирующего фильтра с той же спецификацией, однако разделение фильтра на несколько каскадов десятикратного уменьшения приводит к более эффективному проекту, которая использует меньше аппаратных ресурсов. CIC дециматор обеспечивает большой начальный коэффициент десятикратного уменьшения, который позволяет последующим фильтрам работать с более низкими скоростями. CIC компенсационный дециматор улучшает спектральный ответ, компенсируя падение CIC при децимировании на два. Полуполоса является промежуточным дециматором, в то время как конечный дециматор реализует точное Fpass
и Fstop
характеристики DDC. Из-за более низких частот дискретизации фильтры ближе к концу цепи могут оптимизировать использование ресурсов путем совместного использования умножителей. Ниже приведен блок схема DDC.
Вход DDC дискретизируется на уровне 122,88 Msps, в то время как выходная частота выборки составляет 1,92 Msps. Поэтому общий коэффициент десятикратного уменьшения равен 64. 1.92 Msps является типовой частотой дискретизации, используемой приемниками LTE для выполнения поиска камеры и восстановления MIB (Master Information Block). Поэтому фильтры DDC были разработаны для этого приложения. DDC оптимизирован для работы с тактовой частотой 122,88 МГц.
В этом разделе описывается, как спроектировать DDC с использованием операций с плавающей точкой и функций filter-design в MATLAB ®.
Параметры постоянного тока
Желаемая характеристика DDC определяется входной частотой дискретизации, несущей частотой и характеристиками фильтра. Изменение этой желательной характеристики фильтра может потребовать изменений в свойствах HDL-блоков блоков фильтра в модели Simulink. Свойства блоков обсуждаются ниже в этом примере.
FsIn = 122.88e6; % Sampling rate at input to DDC Fc = 32e6; % Carrier frequency Fpass = 540e3; % Passband frequency, equivalent to 36x15kHz LTE subcarriers Fstop = 700e3; % Stopband frequency Ap = 0.1; % Passband ripple Ast = 60; % Stopband attenuation
В остальной части этого раздела показано, как проектировать каждый фильтр по очереди.
Каскадный интегратор-дециматор Comb (CIC)
Первый каскад фильтра реализован как CIC дециматор из-за его способности эффективно реализовывать большой коэффициент десятикратного уменьшения. Реакция CIC-фильтра подобна каскаду фильтров скользящего среднего значения, однако никакие умножения или деления не используются. В результате CIC-фильтра имеет большое усиление постоянного тока.
cicParams.DecimationFactor = 8; cicParams.DifferentialDelay = 1; cicParams.NumSections = 3; cicParams.FsOut = FsIn/cicParams.DecimationFactor; cicFilt = dsp.CICDecimator(cicParams.DecimationFactor,... cicParams.DifferentialDelay,cicParams.NumSections) %#ok<*NOPTS> cicGain = gain(cicFilt)
cicFilt = dsp.CICDecimator with properties: DecimationFactor: 8 DifferentialDelay: 1 NumSections: 3 FixedPointDataType: 'Full precision' cicGain = 512
Коэффициент усиления CIC является степенью двойки, поэтому его можно легко исправить в оборудовании со сдвигом операции. В целях анализа коррекция усиления представлена в MATLAB одним контактом dsp.FIRFilter
Системный объект.
cicGainCorr = dsp.FIRFilter('Numerator',1/cicGain)
cicGainCorr = dsp.FIRFilter with properties: Structure: 'Direct form' NumeratorSource: 'Property' Numerator: 0.0020 InitialConditions: 0 Use get to show all properties
Использование fvtool
отображение амплитудной характеристики CIC-фильтра с коррекцией усиления и без нее. Для анализа объедините CIC-фильтр и фильтр коррекции усиления в dsp.FilterCascade
Системный объект. CIC-фильтры всегда используют арифметику с фиксированной точкой внутри, поэтому fvtool
строит графики как квантованных, так и неквантованных ответов.
ddcPlots.cicDecim = fvtool(... cicFilt,... dsp.FilterCascade(cicFilt,cicGainCorr), ... 'Fs',[FsIn,FsIn]); DDCTestUtils.setPlotNameAndTitle('CIC Decimator'); legend(... 'CIC No Correction: Quantized', ... 'CIC No Correction: Reference', ... 'CIC With Gain Correction: Quantized', ... 'CIC With gain correction: Reference');
Фильтр компенсации падения CIC
Реакция величины CIC-фильтра имеет значительное падение в область полосы пропускания, поэтому для выравнивания полосы пропускания используется фильтр компенсации падения на основе КИХ. Компенсатор падения сконфигурирован с теми же параметрами, что и дециматор CIC. Этот фильтр также реализует десятикратное уменьшение в два раза, поэтому заданы его полосно-ограничительные характеристики. Задайте требования к фильтру и используйте design
функция для возврата Системного объекта фильтра с этими характеристиками.
compParams.R = 2; % CIC compensation decimation factor compParams.Fpass = Fstop; % CIC comp passband frequency compParams.FsOut = cicParams.FsOut/compParams.R; % New sampling rate compParams.Fstop = compParams.FsOut - Fstop; % CIC comp stopband frequency compParams.Ap = Ap; % Same Ap as overall filter compParams.Ast = Ast; % Same Ast as overall filter compSpec = fdesign.decimator(compParams.R,'ciccomp',... cicParams.DifferentialDelay,... cicParams.NumSections,... cicParams.DecimationFactor,... 'Fp,Fst,Ap,Ast',... compParams.Fpass,compParams.Fstop,compParams.Ap,compParams.Ast,... cicParams.FsOut); compFilt = design(compSpec,'SystemObject',true)
compFilt = dsp.FIRDecimator with properties: NumeratorSource: 'Property' Numerator: [-0.0398 -0.0126 0.2901 0.5258 0.2901 -0.0126 -0.0398] DecimationFactor: 2 Structure: 'Direct form' Use get to show all properties
Постройте график комбинированной характеристики CIC-фильтра (с коррекцией усиления) и уменьшите компенсацию.
ddcPlots.cicComp = fvtool(... dsp.FilterCascade(cicFilt,cicGainCorr,compFilt), ... 'Fs',FsIn,'Legend','off'); DDCTestUtils.setPlotNameAndTitle('CIC Decim + Droop Comp');
Halfband Decimator
Полудиапазонный фильтр обеспечивает эффективное десятикратное уменьшение на два. Полудиапазонные фильтры эффективны, потому что примерно половина их коэффициентов равна нулю.
hbParams.FsOut = compParams.FsOut/2; hbParams.TransitionWidth = hbParams.FsOut - 2*Fstop; hbParams.StopbandAttenuation = Ast; hbSpec = fdesign.decimator(2,'halfband',... 'Tw,Ast',... hbParams.TransitionWidth, ... hbParams.StopbandAttenuation,... compParams.FsOut); hbFilt = design(hbSpec,'SystemObject',true)
hbFilt = dsp.FIRDecimator with properties: NumeratorSource: 'Property' Numerator: [1x11 double] DecimationFactor: 2 Structure: 'Direct form' Use get to show all properties
Постройте график отклика DDC до выхода полуполосного фильтра.
ddcPlots.halfbandFIR = fvtool(... dsp.FilterCascade(cicFilt,cicGainCorr,compFilt,hbFilt), ... 'Fs',FsIn,'Legend','off'); DDCTestUtils.setPlotNameAndTitle('CIC Decim + Droop Comp + HB FIR');
Дециматор конечной импульсной характеристики завершения
Конечная конечная импульсная характеристика реализует подробные характеристики полосы пропускания и полосы остановки DDC. Этот фильтр имеет больше коэффициентов, чем предыдущие конечные импульсные характеристики фильтры, однако он работает с меньшей частотой дискретизации, что позволяет больше совместному использованию ресурсов на оборудовании.
% Add 3dB of headroom to the stopband attenuation so that the DDC still meets the % spec after fixed-point quantization. This value was determined by trial and error % with |fvtool|. finalSpec = fdesign.decimator(2,'lowpass',... 'Fp,Fst,Ap,Ast',Fpass,Fstop,Ap,Ast+3,hbParams.FsOut); finalFilt = design(finalSpec,'equiripple','SystemObject',true)
finalFilt = dsp.FIRDecimator with properties: NumeratorSource: 'Property' Numerator: [1x70 double] DecimationFactor: 2 Structure: 'Direct form' Use get to show all properties
Визуализируйте общую амплитудную характеристику DDC.
ddcFilterChain = dsp.FilterCascade(cicFilt,cicGainCorr,compFilt,hbFilt,finalFilt); ddcPlots.overallResponse = fvtool(ddcFilterChain,'Fs',FsIn,'Legend','off'); DDCTestUtils.setPlotNameAndTitle('Overall DDC Filter Chain');
Частотная характеристика цепи фильтров DDC с плавающей точкой теперь соответствует спецификации. Затем квантуйте каждую ступень фильтра, чтобы использовать фиксированные точки и анализируйте их, чтобы подтвердить, что цепь фильтров все еще соответствует спецификации.
Квантование фильтра
Этот пример использует 16-битные коэффициенты, которые достаточны для соответствия спецификации. Использование менее 18 бит для коэффициентов минимизирует количество блоков DSP, необходимых для реализации FPGA. Вход для цепи фильтров DDC является 16-битными данными с 15 дробными битами. Выходы фильтра являются 18-битными значениями, что обеспечивает дополнительный запас и точность в промежуточных сигналах.
Для дециматора CIC, выбирая Minimum section word lengths
опция типа данных с фиксированной точкой автоматически оптимизирует внутренние словосочетания на основе выхода словосочетания и других параметров CIC.
cicFilt.FixedPointDataType = 'Minimum section word lengths';
cicFilt.OutputWordLength = 18;
Сконфигурируйте параметры с фиксированной точкой объектов системы с коррекцией усиления и КИХ-базой. Хотя объект не показан явным образом, он использует значение по умолчанию RoundingMethod
и OverflowAction
настройки (Floor
и Wrap
соответственно).
% CIC Gain Correction cicGainCorr.FullPrecisionOverride = false; cicGainCorr.CoefficientsDataType = 'Custom'; cicGainCorr.CustomCoefficientsDataType = numerictype(fi(cicGainCorr.Numerator,1,16)); cicGainCorr.OutputDataType = 'Custom'; cicGainCorr.CustomOutputDataType = numerictype(1,18,16); % CIC Droop Compensation compFilt.FullPrecisionOverride = false; compFilt.CoefficientsDataType = 'Custom'; compFilt.CustomCoefficientsDataType = numerictype([],16,15); compFilt.ProductDataType = 'Full precision'; compFilt.AccumulatorDataType = 'Full precision'; compFilt.OutputDataType = 'Custom'; compFilt.CustomOutputDataType = numerictype([],18,16); % Halfband hbFilt.FullPrecisionOverride = false; hbFilt.CoefficientsDataType = 'Custom'; hbFilt.CustomCoefficientsDataType = numerictype([],16,15); hbFilt.ProductDataType = 'Full precision'; hbFilt.AccumulatorDataType = 'Full precision'; hbFilt.OutputDataType = 'Custom'; hbFilt.CustomOutputDataType = numerictype([],18,16); % FIR finalFilt.FullPrecisionOverride = false; finalFilt.CoefficientsDataType = 'Custom'; finalFilt.CustomCoefficientsDataType = numerictype([],16,15); finalFilt.ProductDataType = 'Full precision'; finalFilt.AccumulatorDataType = 'Full precision'; finalFilt.OutputDataType = 'Custom'; finalFilt.CustomOutputDataType = numerictype([],18,16);
Анализ с фиксированной точкой
Смотрите эффекты квантования с помощью fvtool
. Фильтры могут быть проанализированы индивидуально или в каскаде. fvtool
показывает квантованные и неквантованные (ссылочные) наложенные ответы. Для примера показан эффект квантования заключительной стадии конечной импульсной характеристики фильтра.
ddcPlots.quantizedFIR = fvtool(finalFilt,'Fs',hbParams.FsOut,'arithmetic','fixed'); DDCTestUtils.setPlotNameAndTitle('Quantized Final Filter');
Переопределите ddcFilterChain
каскадный объект, включающий свойства с фиксированной точкой отдельных фильтров. Затем используйте fvtool
анализ всей цепи фильтров и подтверждение того, что квантованный DDC все еще соответствует спецификации.
ddcFilterChain = dsp.FilterCascade(cicFilt,cicGainCorr,compFilt,hbFilt,finalFilt); ddcPlots.quantizedDDCResponse = fvtool(ddcFilterChain,'Fs',FsIn,'Arithmetic','fixed'); DDCTestUtils.setPlotNameAndTitle('Quantized DDC Filter Chain'); legend(... 'DDC filter chain: Quantized', ... 'DDC filter chain: Reference');
Следующим шагом в процессе проекта является реализация DDC в Simulink с использованием HDL Coder совместимых блоков.
Моделирование Строения
Модель полагается на переменные в рабочем пространстве MATLAB, чтобы сконфигурировать блоки и настройки. Он использует уже определенные переменные цепи фильтров. Затем задайте параметры Численно Управляемого Генератора (NCO) и входной сигнал. Эти параметры используются для настройки блока NCO.
Задайте желаемое разрешение частоты. Вычислите количество двоичных разрядов аккумулятора, необходимых для достижения желаемого разрешения, и определите количество квантованных двоичных разрядов аккумулятора. Квантованный выход аккумулятора используется для обращения к интерполяционной таблице синуса внутри NCO. Также вычислите шаг фазы, необходимый для генерации заданной несущей частоты. Фаза dither применяется к тем двоичным разрядам аккумулятора, которые удаляются во время квантования.
nco.Fd = 1; nco.AccWL = nextpow2(FsIn/nco.Fd) + 1; nco.QuantAccWL = 12; nco.PhaseInc = round((-Fc * 2^nco.AccWL)/FsIn); nco.NumDitherBits = nco.AccWL - nco.QuantAccWL;
Вход в DDC происходит от ddcIn
. Пока присвойте фиктивное значение для ddcIn
чтобы модель могла вычислять свои типы данных. Во время проверки, ddcIn
предоставляет входные данные в модель.
ddcIn = 0; %#ok<NASGU>
Показан верхний уровень модели DDC Simulink. Модель импортирует ddcIn
из рабочего пространства MATLAB с помощью блока Signal From Workspace преобразует его в 16-битные и затем применяет к DDC. HDL-код может быть сгенерирован из подсистемы HDL_DDC.
modelName = 'DDCHDLImplementation'; open_system(modelName); set_param(modelName,'SimulationCommand','Update'); set_param(modelName, 'Open','on');
Реализация DDC находится внутри подсистемы HDL_DDC. Блок NCO HDL Optimized генерирует комплексный фазор на несущей частоте. Этот сигнал поступает на смеситель, который умножает его на входной сигнал. Выход смесителя затем подается на цепь фильтра, где он децимируется до 1.92 Msps.
set_param([modelName '/HDL_DDC'],'Open','on');
Параметры блоков NCO
Блок NCO сконфигурирован с параметрами, определенными в nco
структура. Показаны обе вкладки диалогового окна параметров блока.
Коррекция Десятикратного уменьшения и усиления CIC
Первый каскад фильтра является Cascade Integrator-Comb (CIC) Decimator, реализованный с CIC Decimation HDL Optimized блоком. Параметры блоков устанавливаются в cicParams
структурные значения. Коррекция усиления реализована путем выбора параметра коррекции усиления.
Фильтрация Параметров блоков
Фильтры конфигурируются с помощью свойств соответствующих системных объектов. Фильтры CIC Reformation, Halfband Decimation и Final Decimation работают с эффективными скоростями дискретизации, которые ниже тактовой частоты (Fclk) на множители 8, 16 и 32, соответственно. Эти скорости дискретизации реализуются при помощи действительного сигнала, чтобы указать, какие выборки действительны с определенной скоростью. Все сигналы в цепи фильтров имеют одинаковый шаг расчета Simulink.
Каждый из Компенсаций CIC, Полуполосы Десятикратного уменьшения и Конечных Децимирующих фильтров реализован Блоком MATLAB function и двух Дискретных конечных импульсных характеристик в полифазу разложении. Полифазное разложение реализует функцию преобразования, где, и. Полифазное разложение является ресурсоэффективным способом реализации децимирующих фильтров. Function Block MATLAB содержит две входные выборки каждые два цикла и передает их одновременно в параллельную пару блоков дискретной конечной импульсной характеристики HDL Optimized и. Каждый нижний подфильтр и верхний подфильтр содержат половину коэффициентов фильтра и обрабатывают половину входных данных.
Для примера подсистема Десятикратного уменьшения компенсации CIC реализует 7
- фильтр коэффициентов. Верхний подфильтр,, имеет 4 коэффициенты и нижний подфильтр,, имеет 3
коэффициенты. Каждый фильтр получает выборку и генерирует выход каждый
16
циклы. Поскольку каждый фильтр обрабатывает одну выборку каждые 16 циклов, блоки подфильтра могут делиться аппаратными ресурсами во времени. Чтобы оптимизировать оборудование ресурсы таким образом, оба подфильтра имеют структуру Filter, набора параметров для Partly serial systolic
.
Схема показывает подсистему CIC Reformation Decimation. Полуполосы Decimation и Final Decimation используют одну и ту же структуру.
Все блоки фильтров сконфигурированы с параметрами, определенными в соответствующих структурах. Для примера на изображении показаны параметры блоков для блока CIC Compensation Десятикратного уменьшения. Параметр Number of Cycles является минимальным количеством циклов между входными выборками. Вход в блок CIC Compensation Decimation дискретизируется в cicParams.DecimationFactor*compParams.R
, что 16
циклы для обоих подфильтров.
Реализация последовательного фильтра повторно использует множители во времени в течение заданного количества тактов. Без этой оптимизации в фильтре CIC Compensation Decimation с комплексными входными данными будут использоваться 14 умножителей. После оптимизации каждый из и использует 2 умножители на общую сумму
4
. Точно так же подсистемы Halfband Decimation и Final Decimation используют 4
каждый умножитель.
Чтобы протестировать DDC, модулируйте 40kHz синусоиду на несущей частоте и передайте ее через DDC. Затем измерьте Ложную Свободную Динамическую Область значений (SFDR) полученного тонального сигнала и SFDR вывода NCO.
% Initialize random seed before executing any simulations. rng(0); % Generate a 40kHz test tone, modulated onto the carrier. ddcIn = DDCTestUtils.GenerateTestTone(40e3,Fc); % Demodulate the test signal with the floating point DDC. ddcOut = DDCTestUtils.DownConvert(ddcIn,FsIn,Fc,ddcFilterChain); release(ddcFilterChain); % Demodulate the test signal by executing the modified Simulink model with the sim function. out = sim(modelName); % Measure the SFDR of the NCO, floating point DDC and the fixed-point DDC outputs. results.sfdrNCO = sfdr(real(out.ncoOut),FsIn/64); results.sfdrFloatDDC = sfdr(real(ddcOut),FsIn/64); results.sfdrFixedDDC = sfdr(real(out.ddcOut),FsIn/64); disp('Spurious Free Dynamic Range (SFDR) Measurements'); disp([' Floating point DDC SFDR: ',num2str(results.sfdrFloatDDC) ' dB']); disp([' Fixed-point NCO SFDR: ',num2str(results.sfdrNCO) ' dB']); disp([' Optimized Fixed-point DDC SFDR: ',num2str(results.sfdrFixedDDC) ' dB']); fprintf(newline); % Plot the SFDR of the NCO and fixed-point DDC outputs. ddcPlots.ncoOutSDFR = figure; sfdr(real(out.ncoOut),FsIn/64); DDCTestUtils.setPlotNameAndTitle(['NCO Out ' get(gca,'Title').String]); ddcPlots.OptddcOutSFDR = figure; sfdr(real(out.ddcOut),FsIn/64); DDCTestUtils.setPlotNameAndTitle(['Optimized Fixed-Point DDC Out ' get(gca,'Title').String]);
Spurious Free Dynamic Range (SFDR) Measurements Floating point DDC SFDR: 291.3483 dB Fixed-point NCO SFDR: 83.0249 dB Optimized Fixed-point DDC SFDR: 108.8419 dB
rng(0); if license('test','LTE_Toolbox') % Generate a modulated LTE test signal with LTE Toolbox [ddcIn, sigInfo] = DDCTestUtils.GenerateLTETestSignal(Fc); % Downconvert with a MATLAB Floating Point Model ddcOut = DDCTestUtils.DownConvert(ddcIn,FsIn,Fc,ddcFilterChain); release(ddcFilterChain); % Downconvert using Simulink model ddcIn=[ddcIn;zeros(320,1)]; % Adding zeros to make up propagation latency to output complete result out = sim(modelName); results.evmFloat = DDCTestUtils.MeasureEVM(sigInfo,ddcOut); results.evmFixed = DDCTestUtils.MeasureEVM(sigInfo,out.ddcOut); disp('LTE Error Vector Magnitude (EVM) Measurements'); disp([' Floating point DDC RMS EVM: ' num2str(results.evmFloat.RMS*100,3) '%']); disp([' Floating point DDC Peak EVM: ' num2str(results.evmFloat.Peak*100,3) '%']); disp([' Fixed-point HDL Optimized DDC RMS EVM: ' num2str(results.evmFixed.RMS*100,3) '%']); disp([' Fixed-point HDL Optimized DDC Peak EVM: ' num2str(results.evmFixed.Peak*100,3) '%']); fprintf(newline); end
LTE Error Vector Magnitude (EVM) Measurements Floating point DDC RMS EVM: 0.633% Floating point DDC Peak EVM: 2.44% Fixed-point HDL Optimized DDC RMS EVM: 0.731% Fixed-point HDL Optimized DDC Peak EVM: 2.69%
Чтобы сгенерировать HDL-код для этого примера, у вас должен быть продукт HDL- Coder™. Используйте makehdl
и makehdltb
команды для генерации HDL-кода и HDL-теста для подсистемы HDL_DDC. DDC был синтезирован на доске оценки ZC706 Xilinx ® Zynq ® -7000. Результаты использования ресурсов после размещения и маршрутизации показаны в таблице. Тайминг проекта встретил с тактовой частотой 313 МГц.
T = table(... categorical({'LUT'; 'LUTRAM'; 'FF'; 'BRAM'; 'DSP'}),... categorical({'2660'; '318'; '5951'; '1.0'; '18'}),... 'VariableNames',{'Resource','Usage'})
T = 5x2 table Resource Usage ________ _____ LUT 2660 LUTRAM 318 FF 5951 BRAM 1.0 DSP 18