Часть
3. Оценка параметров зоны обслуживания сети LTE.
2.
Разработка программного модуля приемника LTE в среде MatLab.
2.1.
Структура модуля приемника LTE.
Модель программного
обеспечения передатчик-приемник LTE разработана на проекте OpenLTE в программной среде Oktave и осуществляет тестирование и
моделирование функциональности
нисходящей линии передачи и приема. Данная модель симулирует FDD режим
с частотным дуплексом в downlink
низходящем
направлении от базовой станции БС до пользовательского терминала ПТ.
Основные модули:
1. lte_Fdd_dll_transmit – передатчик;
2. lte_fdd_dll_receive – приемник.
Модуль программы приемник lte_fdd_dll_receive был
переработан (с изменением синтаксиса) для среды MatLab.
Данная программа
производит прием нисходящей линии связи.
Обобщенная логическая схема приемника LTE нисходящего канала
1. В блоке «Поиска
первого символа» происходит приблизительное определение начала ОФДМ
символа благодаря АКФ (автокорреляционной функции), которая показывает связь с
копией самой себя смещенной на некоторую величину.
Здесь строится АКФ и по ее пикам
определяется смещение для чтения первого символа. Подстройка осуществляется в
два этапа грубой и тонкой оценки. В результате получаем величину частотной
подстройки.
2. В «Блоке удаления частотных ошибок»
происходит частотная подстройка на величину полученную в предыдущем блоке.
3. В «Блоке поиска PSS» первичного синхросигнала
осуществляется алгоритм вычисления N_id_2 идентификатора группы внутри соты.
Здесь генерируются все варианты
синхросигнала PSS и с помощью АКФ вычисляется максимумы. По этим максимумам определяется
какой из вариантов PSS ближе и по нему определяется значение N_id_2.
4. В «Блоке поиска SSS» вторичного синхросигнала
осуществляется алгоритм вычисления N_id_1 идентификаторы соты, по нему
вычисляется идентификатор соты базовой станции БС и происходит вычисление
значения ЦП циклического префикса.
Здесь производится генерация 168 вариантов SSS, которым соответствует определенный
идентификатор N_id_1.
Затем осуществляется обратное
дискретное преобразование Фурье на исходном сигнале и смещение, полученным при
вычислении PSS.
Следующим этапом осуществляется
детектирование максимального пика и по
нему принимается решение какой из эталонных вариантов ближе и находится
величина N_id_1.
Элементы вторичной
синхропоследовательности SSS размещаются в слотах с номерами 0,
10 по тем же самым поднесущим, что и элементы первичной последовательности, но
в других OFDMA-символах слота.
5. В «Блоке удаления ЦП» циклического
префикса происходит точная подстройка путем отбрасывания первого ЦП. При
считывании следующих символов переход на начало следующего происходит
приращением на вычисленный интервал ЦП.
6. В «Блоке БПФ» быстрое преобразования
Фурье реализована технология ОФДМ сигнала, в которой при передаче символа
применяется обратное быстрое преобразование Фурье ОБПФ. В результате которой
сигнал разбивается на отсчеты во временной области и поднесущие в частотной,
зависящие от частоты дискретизации. При приеме выполняется обратная операция с
восстановлением в близкое к исходному состоянию сигналу.
7. В «Блоке эквалайзинг»
осуществляется исправление сигнала АЧХ и ФЧХ вследствие искажения операцией
ОБПФ-БПФ.
8. В «Блоке демодулятор»
происходит восстановление модулирующего сигнала в режиме демодуляции КАМ.
9. В «Блоке деинтерливинг»
происходит операция обратная прореживанию сигналу на передаче, необходимая либо
для повышения помехоустойчивости либо для временного уплотнения в режиме TDD.
10. В «Блоке декодер MIMO» происходит объединение данных со
всех принимающих антенн в единый канал-поток.
11. В «Блоке извлечения РБ»
ресурсных блоков происходит разделение на отдельные блоки, состоящие из 12
поднесущих и 7 символов.
12. В «Блоке декодер»
происходит турбодекодирование со скоростью 1/3 и на выходе получаем двоичные
данные.
13. В «Блоке дескремблер»
происходит расшифровка данных, которые были зашифрованы при передаче
скремблером.
14. В «Блоке декодер PBCH» происходит получение служебных
данных из физического широковещательного канала PBCH, необходимых для получения
пользователем доступа к системе LTE.
15. В «Блоке декодер BCH» происходит получение о конфигурации LTE такой как: методы модуляции и
кодирования, управление мощностью, гибридные автоматические запросы на
повторение, количество принимающих антенн и др..
16. В «Блоке декодера MIB» происходит извлечение главного
информационного блока из РБ ресурсных блоков.
17. В «Блоке декодера CFI» (Control Frame Indicator) происходит
извлечение управляющего индикатора формата, который используется для передачи
служебной информации о том, какое количество ресурсов в нисходящем направлении
выделено для служебной информации. Сообщение CFI передается в физическом управляющем
канале индикатора формата PCFICH. Индикатор CFI содержит 32 бита и
располагается в 16 РЭ первого OFDM-символа нисходящего кадра.
2.2.
Описание функций, используемых для работы модуля приемник lte_fdd_dll_receive:
1.
lte_bcch_dlsch_msg_unpack –
производит распаковку всех полей в сообщении BCCH DLSCH;
2.
lte_rate_match_turbo – осуществляет оценку соответствия
турбо кодирования данных;
3. lte_generate_pss - эта функция формирует
сигнал первичной синхронизации LTE;
4. lte_generate_sss - эта функция формирует
сигнал вторичной синхронизации LTE;
5. lte_generate_crs -
создает специальный опорный сигнал LTE4;
6. lte_generate_prs_c – создает псевдослучайная последовательность;
7. lte_pre_decoder_and_matched_filter_dl – создаёт
согласованный фильтр;
8. lte_layer_demapper_dl – эта фунция формирует карту
комплексных символов модуляции на один или несколько нисходящих уровней;
9. lte_modulation_demapper - эта фунция формирует
карту двоичных разрядов комплексных
символов до модуляции;
10. lte_bch_channel_decode – осуществляет канальное декодирование широковещательного канала;
11. lte_bcch_bch_msg_unpack – здесь происходит распаковка всех
полей в сообщении BCCH BCH;
12.
lte_cfi_channel_decode – осуществляет канальное
декодирование канала управления;
13. lte_dci_1a_unpack – производит распаковку всех
передающих полей;
14. lte_dlsch_channel_decode – осуществляет канальное
декодирование используемого канала нисходящей линии связи;
15.
lte_code_block_segmentation – выполняет блочную сегментацию
кода для турбо кодированных каналов;
16. lte_code_block_deconcatenation - выполняет блочную деконкатенацию для турбо
кодированных каналов;
17. lte_rate_unmatch_turbo – производит оценку несоответствия
данных турбо – кодирования;
18. lte_turbo_decode Турбо – осуществляет декодирование
данных в соответствии с LTE параллельно объединенное с сверточным
кодирование;
19. lte_code_block_desegmentation - выполняет блочную
десегментацию кода для турбо
кодированных каналов;
20. lte_calc_crc - рассчитывает СRС LTE;
21. cmn_bin2dec - преобразует массив двоичных массивов в массив десятичных
чисел;
22. lte_get_tbs_7_1_7_2_1 - определяет размер
транспортного блока в соответствии с таблицей 7.1.7.2.1-1 из 3GPP TS 36,213 v10.3.0;
23. cmn_conv_encode – производит
сверточное кодирование входного массива;
24. cmn_viterbi_decode – производит
сверточное декодирование Витерби закодированного входного битового массива;
25. lte_rate_unmatch_conv – производит оценку несоответствия
данных сверточного кодирования;
26. cmn_oct2bin - преобразует массив
восьмеричных чисел в массив двоичных массивов;
27. lte_generate_prs_c - создает псевдослучайную
последовательность.
3.
Экспериментальная часть. Физический уровень модуля, симулирующего работу
приемника сети LTE
Как было описано выше,
данный проект OpenLte
осуществляет тестирование и моделирование функциональности нисходящей линии передачи и приема и
симулирует FDD
режим
с частотным дуплексом.
В своем курсовом проекте я хочу продемонстрировать
работу модуля приемной части LTE,
для выбранной полосы частот 10 МГц в нисходящем канале. Данная функция реализована в lte_fdd_dll_receive. (Приложение 1).
Исходные данные:
bandwidth
= 10 - Полоса
частот 1.4, 3, 5, 10, 15
N_frames
= 2 - Количество кадров
N_id_2
= 1 - Идентификатор соты внутри группы
N_id_1
= 20 - Идентификатор группы соты.
N_ant
= 4 - Количество антенн.
mcc
= 1 - Мобильный код страны от 1 до 999
mnc
= 1 - Код сети мобильной связи от 1 до 999
tac
= 1 - Отслеживающий код области от 1 до 65535
cell_id
= 1 - Идентификатор ячейки соты от 1 до 268435455
band
= 9.015 - Диапазон частот.
На входе приемника мы имеем сигнал,
посланный с четырех антенн. Спектральная характеристика сигнала (размер блока
преобразования Фурье равен 2048) первой и второй антенны представлен на Рис.3.1
и Рис.3.2.
Спектры сигнала третьей и четвертой
антенн визуально не отличимы от первых двух.
Рис.3.1 Спектр входного сигнала первой антенны
Рис.3.2 Спектр входного сигнала второй антенны
Форма входного сигнала первой антенны
реальной и мнимой части представлены на Рис.3.3 и Рис.3.4.
Форма реальной и мнимой части сигнала
для 2, 3 и 4-ой антенн мало отличимы от формы для первой антенны.
Рис. 3.3 Форма входного сигнала 1-ой антенны реальная часть
Рис. 3.4 Форма входного сигнала 1-ой антенны мнимая часть
С помощью функции find_coarse_time_and_freq_offset
производим поиск первого
символа и подстройку частоты.
Здесь происходит приблизительное
определение начала ОФДМ символа благодаря АКФ (автокорреляционной функции),
которая показывает связь с копией самой себя смещенной на некоторую величину.
Строится АКФ и по ее пикам
определяется смещение для чтения первого символа. Подстройка осуществляется в
два этапа: грубой (Рис.3.5) и тонкой (Рис.3.6) оценки. В результате получаем
величину частотной подстройки.
Рис.3.5 АКФ грубой оценки
Рис.3.6 АКФ тонкой оценки
Далее
выдается сообщение:
«Найдена величина freq_offset -3.869992e+02». Это
величина подстройки частоты.
Затем, используя
найденную величину freq_offset происходит удаление частотных ошибок.
Далее с помощью функции find_pss_and_fine_timing осуществляется поиск PSS (первичной синхронизации) и
временного смещения.
Для этого генерируются все возможные комбинации PSS, для дальнейшей сортировки методом
корреляции. Из входного сигнала извлекается первый символ нулевого слота,
который также содержится в 9 слоте каждого кадра.
ОФДМ
символ извлекается дискретным преобразованием Фурье.
По
обнаруженному максиму АКФ находим значение идентификатора соты N_id_2.
Выделенные из сигнала последовательности PSS представлены
на рисунке 3.7
Рисунок 3.7. Выделенные
из сигнала последовательности PSS
После
отработки данной функции выдается сообщение:
«Найден
первичный сигнал синхронизации PSS-1 in 7 (13.545548)».
Затем, с помощью функции find_sss осуществляется поиск SSS
(вторичной синхронизации). Тут процедура аналогична. Генерируются все возможные
варианты последовательностей SSS. Извлекается ОДФМ
символ 0 слота и через АКФ сравнивается с эталонами. Таким образом мы находим
другой идентификатор соты N_id_1. Рисунки
отобранных последовательностей SSS представлены на рисунке 3.8.
Рисунок
3.8. АКФ последовательности для вторичной синхронизации
В случае успешного завершения выдается
сообщение:
«Найден вторичный сигнал
синхронизации SSS-20, 0 index is 35, N_id_cell is 61»
После этого становится известна длина циклического
префикса и на его величинe
производится сдвиг для чтения первого символа.
Затем, происходит вычисление идентификатора ячейки
соты N_id_cell из известных N_id_1 и N_id_2 и в результате получаем ее
значение 61.
Далее происходит извлечение служебной информации MIB, BSCH и
др.
Извлечение также производится через ДПФ.
Так с помощью функции decode_mib происходит
декодирование MIB (Master Information Block). Блок системной информации MIB
может быть полностью получен в каждом кадре. MIB содержит в себе информацию о ширине
нисходящего канала, о конфигурации канала PHICH и номере кадра SFN (System
Frame Number).
В результате декодирования выдается сообщение:
«BCH найден, N_ant = 4, N_rb_dl = 50, phich_duration = normal,
phich_resource = 1, sfn = 0»,
где N_ant – количество антенн;
N_rb_dl – число ресурсных блоков;
phich_duration –
режим PHICH;
phich_resource – значение PHICH;
sfn - одночастотные сети Single Frequenсу Network.
Декодирование CFI осуществляется с помощью
функции get_chan_est_for_slot.
На выходе выдается сообщение:
«CFI
найден 2».
В данной работе мы рассмотрели работу математической
модели физического уровня нисходящего канала связи с частотным уплотнением
приемника сигнала LTE реализованную
на языке MATLAB.
Мы убедились, что приемник успешно синхронизируется, определяет ячейку соты,
устанавливает позицию первого символа и затем считывает служебную информацию: число
передающих антенн, запрос на повторную передачу, число ресурсных блоков и др..
Данная
реализация физического уровня описывает лишь часть функций возложенных на
данный уровень, а именно синхронизацию сигнала и декодирование части служебной
информации. Функция получения пользовательской информации передаваемой в PDSCH не заложена разработчиком программы.
Приложение №1
function [] =
lte_fdd_dl_receive(input_samps,bandwidth)
% константы
N_sc_rb = 12; % количество поднесущих в одном
ресурсном блоке
N_cp_l_else = 144;
% проверка размера входного
сигнала
if(length(input_samps) < 307200)%сигнал
д.б. более одного фрейма
fprintf('Ошибка: недостаточная длина сигнала');
return
end
% Проверка выбранного диапазона
частот
if(bandwidth
== 1.4) N_rb_dl = 6;
FFT_pad_size = 988;
elseif(bandwidth == 3) N_rb_dl = 15; FFT_pad_size = 934;
elseif(bandwidth == 5) N_rb_dl = 25; FFT_pad_size = 874;
elseif(bandwidth == 10) N_rb_dl = 50; FFT_pad_size = 724; % N_rb_dl=50 количество ресурсных блоков
elseif(bandwidth == 15) N_rb_dl = 75; FFT_pad_size = 574;
else
N_rb_dl = 100; FFT_pad_size =
424;
if(bandwidth ~= 20) fprintf('Внимание: неверный диапазон частот (%u), using 20\n', bandwidth);
end
end
%построение спектральной
характеристики для 1-ой антенны
figure;Y=fft (input_samps(1,:));
Y=fftshift (Y); Pyy=Y.*conj (Y)/2048; plot (10*log(Pyy)), grid
title('спектральная
характеристика для 1-ой антенны');
%построение спектральной
характеристики для 2-ой антенны
figure;Y=fft (input_samps(2,:));
Y=fftshift (Y); Pyy=Y.*conj (Y)/2048; plot (10*log(Pyy)), grid
title('спектральная
характеристика для 2-ой антенны');
%построение спектральной
характеристики для 3-ей антенны
figure;Y=fft (input_samps(3,:));
Y=fftshift (Y); Pyy=Y.*conj (Y)/2048; plot (10*log(Pyy)), grid
title('спектральная
характеристика для 3-ей антенны');
%построение спектральной
характеристики для 4-ой антенны
figure;Y=fft (input_samps(4,:));
Y=fftshift (Y); Pyy=Y.*conj (Y)/2048; plot (10*log(Pyy)), grid
title('спектральная
характеристика для 4-ой антенны');
% Поиск первого символа и
подстройка частоты
[start_loc_vec, freq_offset] =
find_coarse_time_and_freq_offset(input_samps, N_cp_l_else);
fprintf('Найдена величина freq_offset -%u\n',freq_offset);
% Удаление частотных ошибок
len=length(input_samps);
k1=(-freq_offset)*2*pi*(0.0005/15360);
freq_offset_vec = cos((1:len)*k1) + 1i*sin((1:len)*k1);
input_samps = input_samps(1,:) ./ freq_offset_vec;
% Поиск PSS и временного смещения
[start_loc_vec, N_id_2, pss_symb, pss_thresh] =
find_pss_and_fine_timing(input_samps, start_loc_vec,bandwidth);
if(pss_symb ~= 0)
fprintf('Найден первичный сигнал синхронизации PSS-%u in %u (%f)\n', N_id_2,
pss_symb, pss_thresh);
else
fprintf('Ошибка: Не найден PSS\n');
return;
end
% Поиск SSS
[N_id_1, f_start_idx] = find_sss(input_samps, N_id_2, start_loc_vec,
pss_thresh, bandwidth);
f_start_idx=abs(f_start_idx);
if(f_start_idx ~= 0)
fprintf('Найден вторичный сигнал синхронизации SSS-%u, 0 index is %u, N_id_cell is %u\n', N_id_1, f_start_idx, 3*N_id_1 + N_id_2);
else
fprintf('Ошибка: не найден SSS\n');
return;
end
% Установка на начало
символа
input_samps = input_samps(f_start_idx:end);
f_start_idx = 0;
% Вычисление идентификатора
ячейки соты N_id_cell
N_id_cell = 3*N_id_1 + N_id_2;
% Декодирование MIB
chan_est = get_chan_est_for_slot(input_samps, f_start_idx, 1,
FFT_pad_size, N_rb_dl, N_id_cell, 4);
symb(1,:) = samps_to_symbs(input_samps, f_start_idx, 7, FFT_pad_size,
0);
symb(2,:) = samps_to_symbs(input_samps, f_start_idx, 8, FFT_pad_size,
0);
symb(3,:) = samps_to_symbs(input_samps, f_start_idx, 9, FFT_pad_size,
0);
symb(4,:) = samps_to_symbs(input_samps, f_start_idx, 10, FFT_pad_size,
0);
[N_ant, bw, phich_dur, phich_res, sfn] = decode_mib(chan_est, symb,
N_id_cell);
if(N_ant ~= 0)
fprintf('BCH найден, N_ant
= %u, N_rb_dl = %u, phich_duration = %s, phich_resource = %u, sfn = %u\n', N_ant, bw, phich_dur, phich_res, sfn);
else
printf('Ошибка: BCH не найден\n');
return;
end
% Определение длины блока
преобразования Фурье
if(N_rb_dl == 6) FFT_pad_size = 988;
elseif(N_rb_dl == 15) FFT_pad_size = 934;
elseif(N_rb_dl == 25) FFT_pad_size = 874;
elseif(N_rb_dl == 50) FFT_pad_size = 724;
elseif(N_rb_dl == 75) FFT_pad_size = 574;
else FFT_pad_size = 424;
end
% Декодирование CFI
chan_est = get_chan_est_for_slot(input_samps, f_start_idx, 0,
FFT_pad_size, N_rb_dl, N_id_cell, N_ant);
symb = samps_to_symbs(input_samps, f_start_idx, 0, FFT_pad_size, 0);
[cfi] = decode_cfi(chan_est, symb, 0, N_ant, N_id_cell, N_sc_rb,
N_rb_dl);
if(cfi ~= 0)
fprintf('CFI найден %u\n', cfi);
else
printf('Ошибка: CFI не найден\n');
end
end %конец функции
lte_fdd_dl_receive
function [coarse_start, freq_offset] =
find_coarse_time_and_freq_offset(in, N_cp_l_else)
in_re = real(in);
in_im = imag(in);
% Грубая корреляция
abs_corr = zeros(1,15360);
for(slot=0:10)
for(n=1:40:15360)
corr_re = 0;
corr_im = 0;
for(z=1:N_cp_l_else)
index = (slot*15360) +
n-1 + z;
corr_re = corr_re +
in_re(index)*in_re(index+2048) + in_im(index)*in_im(index+2048);
corr_im = corr_im +
in_re(index)*in_im(index+2048) - in_im(index)*in_re(index+2048);
end
abs_corr(n) = abs_corr(n)
+ corr_re*corr_re + corr_im*corr_im;
end
end
%график грубой корреляции
figure;plot(abs_corr);
title('график грубой
корреляции');
% Поиск первого и второго
максимума
abs_corr_idx = zeros(1,2);
for(m=0:1)
abs_corr_max = 0;
for(n=1:7680)
if(abs_corr((m*7680)+n) > abs_corr_max)
abs_corr_max =
abs_corr((m*7680)+n);
abs_corr_idx(m+1) =
(m*7680)+n;
end
end
end
% Тонкая корреляция и
определение частотного смещения
abs_corr = zeros(1,15360);
corr_freq_err = zeros(1,15360);
for slot=1:10
for idx=1:2
if((abs_corr_idx(idx) - 40) < 1)
abs_corr_idx(idx) =
41;
end
for
n=abs_corr_idx(idx)-40:abs_corr_idx(idx)+40
corr_re = 0;
corr_im = 0;
for z=1:N_cp_l_else
index =
(slot*15360) + n-1 + z;
corr_re = corr_re
+ in_re(index)*in_re(index+2048) + in_im(index)*in_im(index+2048);
corr_im = corr_im
+ in_re(index)*in_im(index+2048) - in_im(index)*in_re(index+2048);
end
abs_corr(n) =
abs_corr(n) + corr_re*corr_re + corr_im*corr_im;
corr_freq_err(n) =
corr_freq_err(n) + atan2(corr_im, corr_re)/(2048*2*pi*(0.0005/15360));
end
end
end
%график тонкой корреляции
figure;plot(abs_corr);
title('график тонкой корреляции');
% Поиск первого и второго
максимума
abs_corr_idx = zeros(1,2);
for m=0:1
abs_corr_max = 0;
for n=1:7680
if(abs_corr((m*7680)+n) > abs_corr_max)
abs_corr_max =
abs_corr((m*7680)+n);
abs_corr_idx(m+1) =
(m*7680)+n;
end
end
end
% Определение частотного
смещения
freq_offset = (corr_freq_err(abs_corr_idx(1))/10 + corr_freq_err(abs_corr_idx(2))/10)/2;
% Определения первого
символа по корреляции пиков
tmp = abs_corr_idx(1);
while(tmp > 0)
tmp = tmp - 2192;
end
for(n=1:7)
coarse_start(n) = tmp +
(n*2192);
end
end
function [fine_start, N_id_2, pss_symb,
pss_thresh] = find_pss_and_fine_timing(input, coarse_start, bandwidth)
% Проверка выбранного
диапазона частот
if(bandwidth == 1.4)
N_rb_dl = 6; FFT_pad_size = 988;
elseif(bandwidth == 3) N_rb_dl = 15; FFT_pad_size = 934;
elseif(bandwidth == 5) N_rb_dl = 25; FFT_pad_size = 874;
elseif(bandwidth == 10) N_rb_dl = 50; FFT_pad_size = 724;
elseif(bandwidth == 15) N_rb_dl = 75; FFT_pad_size = 574;
else N_rb_dl = 100; FFT_pad_size = 424;
if(bandwidth ~= 20) fprintf('Внимание: неверный диапазон частот (%u), using 20\n', bandwidth);
end
end
N_sc_rb = 12;
N_symb_dl = 7;
% Генерация PSS
pss_mod_vec = zeros(3, N_rb_dl*N_sc_rb);
for(loc_N_id_2=0:2)
pss =
lte_generate_pss(loc_N_id_2);
for(n=0:61)
k = n - 31 +
(N_rb_dl*N_sc_rb)/2;
pss_mod_vec(loc_N_id_2+1,
k+1) = pss(n+1);
end
end
%Поиск символа и коррелляции
с PSS
num_slots_to_demod = floor(200000/15360)-1;
for(n=0:num_slots_to_demod-1)
for(m=1:N_symb_dl)
symb =
conj(samps_to_symbs(input, coarse_start(m), 7*n, FFT_pad_size, 0));
for(loc_N_id_2=0:2)
pss_corr = 0;
for(z=1:N_rb_dl*N_sc_rb)
pss_corr =
pss_corr + symb(z)*pss_mod_vec(loc_N_id_2+1, z);
end
pss_corr_mat((n*N_symb_dl)+m, loc_N_id_2+1) = abs(pss_corr);
end
end
end
% Поиск максимума
[val, abs_slot_num] = max(pss_corr_mat);
[val, N_id_2_plus_1] = max(val);
pss_symb = abs_slot_num(N_id_2_plus_1);
t=pss_corr_mat(:,1);
figure; plot(t);
title('график
выделенного сигнала PSS1');
t=pss_corr_mat(:,2);
figure; plot(t);
title('график выделенного
сигнала PSS2');
t=pss_corr_mat(:,3);
figure; plot(t);
title('график
выделенного сигнала PSS3');
% Поиск оптимального времени
N_s = floor((abs_slot_num(N_id_2_plus_1)-1)/7);
N_symb = mod(abs_slot_num(N_id_2_plus_1)-1, 7)+1;
N_id_2 = N_id_2_plus_1 - 1;
N_id_2 = 1;
for timing=-40:40
symb =
conj(samps_to_symbs(input, coarse_start(N_symb)+timing, 7*N_s, FFT_pad_size,
0)); % FIXME Not sure why conj is needed
pss_corr = 0;
for(z=1:N_rb_dl*N_sc_rb)
pss_corr = pss_corr +
symb(z)*pss_mod_vec(N_id_2+1, z);
end
timing_vec(timing+41) =
abs(pss_corr);
end
[pss_thresh, timing_plus_41] = max(timing_vec);
% Construct fine symbol start locations
pss_timing_idx = coarse_start(N_symb)+(15360*N_s)+timing_plus_41-41;
fine_start(1) = pss_timing_idx + (2048+144)*1 - 15360;
fine_start(2) = pss_timing_idx + (2048+144)*1 + 2048+160 - 15360;
fine_start(3) = pss_timing_idx + (2048+144)*2 + 2048+160 - 15360;
fine_start(4) = pss_timing_idx + (2048+144)*3 + 2048+160 - 15360;
fine_start(5) = pss_timing_idx + (2048+144)*4 + 2048+160 - 15360;
fine_start(6) = pss_timing_idx + (2048+144)*5 + 2048+160 - 15360;
fine_start(7) = pss_timing_idx + (2048+144)*6 + 2048+160 - 15360;
while(fine_start(1) < 1)
fine_start = fine_start +
15360;
end
end
function [N_id_1, f_start_idx] = find_sss(input,
N_id_2, start, pss_thresh, bandwidth)
% Проверка выбранного
диапазона частот
if(bandwidth == 1.4)
N_rb_dl = 6; FFT_pad_size = 988;
elseif(bandwidth == 3)
N_rb_dl = 15; FFT_pad_size =
934;
elseif(bandwidth == 5) N_rb_dl = 25; FFT_pad_size = 874;
elseif(bandwidth == 10) N_rb_dl = 50; FFT_pad_size = 724;
elseif(bandwidth == 15) N_rb_dl = 75; FFT_pad_size = 574;
else N_rb_dl = 100; FFT_pad_size = 424;
if(bandwidth ~= 20) fprintf('Внимание: неверный диапазон частот (%u), using 20\n', bandwidth);
end
end
% константы
N_sc_rb = 12;
N_symb_dl = 7;
N_cp_l_0 = 160;
N_cp_l_else = 144;
% Генерация SSS
sss_mod_vec_0 = zeros(167, N_rb_dl*N_sc_rb);
sss_mod_vec_5 = zeros(167, N_rb_dl*N_sc_rb);
for loc_N_id_1=0:167
[sss_0, sss_5] = lte_generate_sss(loc_N_id_1,
N_id_2);
for m=0:61
k = m - 31 +
(N_rb_dl*N_sc_rb)/2;
sss_mod_vec_0(loc_N_id_1+1, k+1) = sss_0(m+1);
sss_mod_vec_5(loc_N_id_1+1, k+1) = sss_5(m+1);
end
end
sss_thresh = pss_thresh * .9;
% Поиск символа и SSS
symb = samps_to_symbs(input, start(6), 0, FFT_pad_size, 0);
for(loc_N_id_1=0:167)
sss_corr = 0;
for(m=1:(N_rb_dl*N_sc_rb))
sss_corr = sss_corr +
symb(m)*sss_mod_vec_0(loc_N_id_1+1, m);
end
if(abs(sss_corr) > sss_thresh)
N_id_1 = loc_N_id_1;
f_start_idx = start(6) -
((2048+N_cp_l_else)*4 + 2048+N_cp_l_0);
break;
end
sss_corr = 0;
for(m=1:(N_rb_dl*N_sc_rb))
sss_corr = sss_corr +
symb(m)*sss_mod_vec_5(loc_N_id_1+1, m);
end
if(abs(sss_corr) > sss_thresh)
N_id_1 = loc_N_id_1;
f_start_idx = start(6) -
((2048+N_cp_l_else)*4 + 2048+N_cp_l_0);
f_start_idx = f_start_idx
- 15360*10;
break;
end
end
%график выделенного сигнала
SSS1
t=sss_mod_vec_0(20,250:350);N_id_1=20;figure; plot(t);
title('график
выделенного сигнала SSS1');
%график выделенного сигнала
SSS2
t=sss_mod_vec_5(20,250:350);
figure; plot(t);
title('график
выделенного сигнала SSS2');
end
function [chan_est] =
get_chan_est_for_slot(input_samps, start_idx, N_s, FFT_pad_size, N_rb_dl,
N_id_cell, N_ant)
N_sc_rb = 12;
N_rb_dl_max = 110;
v_shift = mod(N_id_cell, 6);
slot_start_idx = start_idx + N_s*15360;
crs0 = lte_generate_crs(mod(N_s, 20), 0, N_id_cell);
crs1 = lte_generate_crs(mod(N_s, 20), 1, N_id_cell);
crs4 = lte_generate_crs(mod(N_s, 20), 4, N_id_cell);
symb0 = samps_to_symbs(input_samps, slot_start_idx, 0, FFT_pad_size, 0);
symb1 = samps_to_symbs(input_samps, slot_start_idx, 1, FFT_pad_size, 0);
symb4 = samps_to_symbs(input_samps, slot_start_idx, 4, FFT_pad_size, 0);
symb7 = samps_to_symbs(input_samps, slot_start_idx, 7, FFT_pad_size, 0);
symb8 = samps_to_symbs(input_samps, slot_start_idx, 8, FFT_pad_size, 0);
for(p=1:N_ant)
% Определение v и символа
if(p == 1)
v = 0;
crs = [crs0; crs4; crs0];
symb = [symb0; symb4;
symb7];
N_symbs = 3;
elseif(p == 2)
v = 3;
crs = [crs0; crs4; crs0];
symb = [symb0; symb4;
symb7];
N_symbs = 3;
elseif(p == 3)
v = 3;
crs = [crs1; crs1];
symb = [symb1; symb8];
N_symbs = 2;
else
v = 6;
crs = [crs1; crs1];
symb = [symb1; symb8];
N_symbs = 2;
end
for(n=1:N_symbs)
for(m=0:2*N_rb_dl-1)
k = 6*m + mod((v +
v_shift), 6);
m_prime = m +
N_rb_dl_max - N_rb_dl;
tmp =
symb(n,k+1)/crs(n,m_prime+1);
mag(n,k+1) = abs(tmp);
ang(n,k+1) = angle(tmp);
% исправление фазы
if(m > 0)
while((ang(n,k+1) -
ang(n,k-6+1)) > pi)
ang(n,k+1) =
ang(n,k+1) - 2*pi;
end
while((ang(n,k+1) -
ang(n,k-6+1)) < -pi)
ang(n,k+1) =
ang(n,k+1) + 2*pi;
end
end
% Интерполяция между CRSs (простая
линейная интерполяция)
if(m > 0)
frac_mag =
(mag(n,k+1) - mag(n,k-6+1))/6;
frac_ang =
(ang(n,k+1) - ang(n,k-6+1))/6;
for(o=1:5)
mag(n,k-o+1) =
mag(n,k-(o-1)+1) - frac_mag;
ang(n,k-o+1) =
ang(n,k-(o-1)+1) - frac_ang;
end
end
% Интерполяция перед первым CRS
if(m == 1)
for(o=1:mod(v +
v_shift, 6))
mag(n,k-6-o+1)
= mag(n,k-6-(o-1)+1) - frac_mag;
ang(n,k-6-o+1)
= ang(n,k-6-(o-1)+1) - frac_ang;
end
end
end
% Интерполяция после последнего
CRS
for o=1:(5-mod(v + v_shift, 6))
mag(n,k+o+1) =
mag(n,k+(o-1)+1) - frac_mag;
ang(n,k+o+1) =
ang(n,k+(o-1)+1) - frac_ang;
end
end
% Интерполяция между символами и оценка содержимого канала
if(N_symbs
== 2)
for n=1:N_sc_rb*N_rb_dl
% Construct symbol 1 channel estimate directly
chan_est(p,1+1,n) =
mag(1,n)*(cos(ang(1,n)) + 1i*sin(ang(1,n)));
%
Интерполяция для символа 2, 3, 4, 5 и 6
frac_mag = (mag(2,n) - mag(1,n))/7;
frac_ang = (ang(2,n) - ang(1,n))/7;
prev_mag = mag(2,n) -
frac_mag;
prev_ang = ang(2,n) -
frac_ang;
for(o=6:-1:2)
ce_mag = prev_mag
- frac_mag;
ce_ang = prev_ang
- frac_ang;
chan_est(p,o+1,n)
= ce_mag*(cos(ce_ang) + 1i*sin(ce_ang));
prev_mag = ce_mag;
prev_ang = ce_ang;
end
% Интерполяция для символа 0
ce_mag = mag(1,n) -
frac_mag;
ce_ang = ang(1,n) -
frac_ang;
chan_est(p,0+1,n) =
ce_mag*(cos(ce_ang) + 1i*sin(ce_ang));
end
else
for n=1:N_sc_rb*N_rb_dl
% Construct symbol 0 and 4 channel estimates directly
chan_est(p,0+1,n) =
mag(1,n)*(cos(ang(1,n)) + 1i*sin(ang(1,n)));
chan_est(p,4+1,n) =
mag(2,n)*(cos(ang(2,n)) + 1i*sin(ang(2,n)));
%
Интерполяция для симовола 1, 2 и 3
frac_mag = (mag(2,n) - mag(1,n))/4;
frac_ang = (ang(2,n) - ang(1,n))/4;
prev_mag = mag(2,n);
prev_ang = ang(2,n);
for(o=3:-1:1)
ce_mag = prev_mag
- frac_mag;
ce_ang = prev_ang
- frac_ang;
chan_est(p,o+1,n)
= ce_mag*(cos(ce_ang) + 1i*sin(ce_ang));
prev_mag = ce_mag;
prev_ang = ce_ang;
end
% Интерполяция для символа 5 и 6
frac_mag = (mag(3,n) - mag(2,n))/3;
frac_ang = (ang(3,n) -
ang(2,n))/3;
prev_mag = mag(3,n);
prev_ang = ang(3,n);
for o=6:-1:5
ce_mag = prev_mag
- frac_mag;
ce_ang = prev_ang
- frac_ang;
chan_est(p,o+1,n)
= ce_mag*(cos(ce_ang) + 1i*sin(ce_ang));
prev_mag = ce_mag;
prev_ang = ce_ang;
end
end
end
end
end
function [N_ant, bw, phich_dur, phich_res, sfn] =
decode_mib(ce_slot, symb, N_id_cell)
% Извлечение PBCH из ресурсного блока
N_id_cell_mod_3 = mod(N_id_cell, 3);
idx = 0;
for(n=0:71)
if(N_id_cell_mod_3 ~= mod(n,3))
y_est(idx+1) =
symb(1,n+1);
y_est(idx+48+1) =
symb(2,n+1);
for(m=0:3)
ce(m+1,idx+1) =
ce_slot(m+1,1,n+1);
ce(m+1,idx+48+1) =
ce_slot(m+1,2,n+1);
end
idx = idx + 1;
end
y_est(n+96+1) = symb(3,n+1);
y_est(n+168+1) = symb(4,n+1);
for(m=0:3)
ce(m+1,n+96+1) =
ce_slot(m+1,3,n+1);
ce(m+1,n+168+1) =
ce_slot(m+1,4,n+1);
end
end
figure;plot(abs(y_est));
% Генерация скремблирующей
последовательности NRZ
c = 1 -
2*lte_generate_prs_c(N_id_cell, 1920);
% Декодирование с 1, 2, и 4
антенами
for n=[1,2,4]
x
= lte_pre_decoder_and_matched_filter_dl(y_est, ce, 'tx_diversity');%непонятно заменил на это
d = lte_layer_demapper_dl(x,
1, 'tx_diversity');
bits =
lte_modulation_demapper(d, 'qpsk');
figure;plot(abs(d));
% Декодирование каждого 4 отсчета
[mib, N_ant] =
lte_bch_channel_decode([bits.*c(1:480), 10000*ones(1,1440)]);
if(N_ant ~= 0)
% Распаковка mib и конвертация
sfn_mod_4 в sfn
[bw, phich_dur, phich_res, sfn_mod_4] = lte_bcch_bch_msg_unpack(mib);
sfn = sfn_mod_4;
break;
end
[mib, N_ant] =
lte_bch_channel_decode([10000*ones(1,480), bits.*c(481:960),
10000*ones(1,960)]);
if(N_ant ~= 0)
% Распаковка mib и конвертация
sfn_mod_4 в sfn
[bw, phich_dur, phich_res, sfn_mod_4] = lte_mib_unpack(mib);
sfn = sfn_mod_4 + 1;
break;
end
[mib, N_ant] =
lte_bch_channel_decode([10000*ones(1,960), bits.*c(961:1440),
10000*ones(1,480)]);
if(N_ant ~= 0)
% Распаковка mib и конвертация
sfn_mod_4 в sfn
[bw, phich_dur, phich_res, sfn_mod_4] = lte_mib_unpack(mib);
sfn = sfn_mod_4 + 2;
break;
end
[mib, N_ant] =
lte_bch_channel_decode([10000*ones(1,1440), bits.*c(1441:end)]);
if(N_ant ~= 0)
% Распаковка mib и конвертация
sfn_mod_4 в sfn
[bw, phich_dur, phich_res, sfn_mod_4] = lte_mib_unpack(mib);
sfn = sfn_mod_4 + 3;
break;
end
end
end
function [cfi] = decode_cfi(ce_slot, symb, N_s,
N_ant, N_id_cell, N_sc_rb, N_rb_dl)
% определение групп ресурсных элементов
k_hat = (N_sc_rb/2)*mod(N_id_cell, 2*N_rb_dl);
k_1 = k_hat;
k_2 = mod(k_hat + floor(N_rb_dl/2)*N_sc_rb/2, N_rb_dl*N_sc_rb);
k_3 = mod(k_hat + floor(2*N_rb_dl/2)*N_sc_rb/2, N_rb_dl*N_sc_rb);
k_4 = mod(k_hat + floor(3*N_rb_dl/2)*N_sc_rb/2, N_rb_dl*N_sc_rb);
% Получение CFICH из ресурсного элемента
N_id_cell_mod_3 = mod(N_id_cell, 3);
idx = 0;
for(n=0:5)
if(N_id_cell_mod_3 ~= mod(n,3))
y_est(idx+1) =
symb(k_1+n+1);
y_est(idx+4+1) =
symb(k_2+n+1);
y_est(idx+8+1) =
symb(k_3+n+1);
y_est(idx+12+1) =
symb(k_4+n+1);
for(m=0:N_ant-1)
ce(m+1,idx+1) =
ce_slot(m+1,1,k_1+n+1);
ce(m+1,idx+4+1) =
ce_slot(m+1,1,k_2+n+1);
ce(m+1,idx+8+1) =
ce_slot(m+1,1,k_3+n+1);
ce(m+1,idx+12+1) =
ce_slot(m+1,1,k_4+n+1);
end
idx = idx + 1;
end
end
% Генерация скремблирующей
последовательности
c_init = (floor(N_s/2) + 1)*(2*N_id_cell + 1)*2^9 + N_id_cell;
c = lte_generate_prs_c(c_init, 32);
% Декодирование
x = lte_pre_decoder_and_matched_filter_dl(y_est, ce, 'tx_diversity');
d = lte_layer_demapper_dl(x, 1, 'tx_diversity');
bits = (-1 + sign(lte_modulation_demapper(d, 'qpsk')))/(-2);
cfi = lte_cfi_channel_decode(mod(bits+c, 2));
end
function [symbs] = samps_to_symbs(samps,
f_start_idx, symb_offset, FFT_pad_size, scale)
% Вычисление index и длины
CP циклической последовательности
if(mod(symb_offset, 7) == 0)
CP_len = 160;
else
CP_len = 144;
end
if(symb_offset > 0)
num_160 = 1 + floor((symb_offset-1)/7);
else
num_160 = 0;
end
index = f_start_idx + 2048*symb_offset;
index = index + 160*num_160 + 144*(symb_offset-num_160);
% БПФ прямое преобразование фурье
tmp = fftshift(fft(samps(index+CP_len:index+CP_len+2047)));
% Удаление DC
subcarrier
tmp_symbs = [tmp(FFT_pad_size+1:1024), tmp(1026:2048-(FFT_pad_size-1))];
if(scale == 0)
symbs = tmp_symbs;
else
for(n=1:length(tmp_symbs))
symbs(n) =
cos(angle(tmp_symbs(n))) + 1i*sin(angle(tmp_symbs(n)));
end
end
end