Merge branch 'next' into novolk

master
Ismael Gomez 8 years ago
commit 94c7f56fbd

@ -39,7 +39,6 @@ MESSAGE( STATUS "CMAKE_CXX_COMPILER: " ${CMAKE_CXX_COMPILER} )
list(APPEND CMAKE_MODULE_PATH "${PROJECT_SOURCE_DIR}/cmake/modules") list(APPEND CMAKE_MODULE_PATH "${PROJECT_SOURCE_DIR}/cmake/modules")
include(SRSLTEVersion) #sets version information include(SRSLTEVersion) #sets version information
include(SRSLTEPackage) #setup cpack include(SRSLTEPackage) #setup cpack
include(BuildMex)
include(CTest) include(CTest)
set( CTEST_MEMORYCHECK_COMMAND valgrind ) set( CTEST_MEMORYCHECK_COMMAND valgrind )
@ -51,7 +50,6 @@ configure_file(
######################################################################## ########################################################################
# Options # Options
######################################################################## ########################################################################
option(DisableMEX "DisableMEX" ON)
option(StaticMKL "StaticMKL" OFF) option(StaticMKL "StaticMKL" OFF)
option(DisableBladeRF "DisableBladeRF" OFF) option(DisableBladeRF "DisableBladeRF" OFF)
set(GCC_ARCH native CACHE STRING "GCC compile for specific architecture.") set(GCC_ARCH native CACHE STRING "GCC compile for specific architecture.")
@ -72,7 +70,6 @@ endif()
set(RUNTIME_DIR bin) set(RUNTIME_DIR bin)
set(LIBRARY_DIR ${CMAKE_INSTALL_LIBDIR}) set(LIBRARY_DIR ${CMAKE_INSTALL_LIBDIR})
set(INCLUDE_DIR include) set(INCLUDE_DIR include)
set(MEX_DIR mex)
set(DOC_DIR "share/doc/${CPACK_PACKAGE_NAME}") set(DOC_DIR "share/doc/${CPACK_PACKAGE_NAME}")
set(DATA_DIR share/${CPACK_PACKAGE_NAME}) set(DATA_DIR share/${CPACK_PACKAGE_NAME})
@ -105,7 +102,8 @@ if(CMAKE_COMPILER_IS_GNUCC)
find_package(SSE) find_package(SSE)
if(${CMAKE_BUILD_TYPE} STREQUAL "Debug") if(${CMAKE_BUILD_TYPE} STREQUAL "Debug")
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -O0") find_package(SSE)
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -O0 -DDEBUG_MODE")
if(HAVE_AVX) if(HAVE_AVX)
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -march=${GCC_ARCH} -mfpmath=sse -mavx -DLV_HAVE_AVX -DLV_HAVE_SSE") set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -march=${GCC_ARCH} -mfpmath=sse -mavx -DLV_HAVE_AVX -DLV_HAVE_SSE")
elseif(HAVE_SSE) elseif(HAVE_SSE)
@ -125,6 +123,13 @@ if(CMAKE_COMPILER_IS_GNUCC)
endif(${CMAKE_BUILD_TYPE} STREQUAL "Debug") endif(${CMAKE_BUILD_TYPE} STREQUAL "Debug")
IF(${CMAKE_SYSTEM_PROCESSOR} MATCHES "arm")
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -mfpu=neon -march=native -DIS_ARM -DHAVE_NEON")
message(STATUS "have ARM")
ELSE(${CMAKE_SYSTEM_PROCESSOR} MATCHES "arm")
ENDIF(${CMAKE_SYSTEM_PROCESSOR} MATCHES "arm")
set(CMAKE_REQUIRED_FLAGS ${CMAKE_C_FLAGS})
if(NOT WIN32) if(NOT WIN32)
ADD_CXX_COMPILER_FLAG_IF_AVAILABLE(-fvisibility=hidden HAVE_VISIBILITY_HIDDEN) ADD_CXX_COMPILER_FLAG_IF_AVAILABLE(-fvisibility=hidden HAVE_VISIBILITY_HIDDEN)
@ -149,8 +154,6 @@ if(${CMAKE_SYSTEM_NAME} MATCHES "Darwin")
set(CMAKE_SHARED_LINKER_FLAGS "-undefined dynamic_lookup") set(CMAKE_SHARED_LINKER_FLAGS "-undefined dynamic_lookup")
endif(${CMAKE_SYSTEM_NAME} MATCHES "Darwin") endif(${CMAKE_SYSTEM_NAME} MATCHES "Darwin")
######################################################################## ########################################################################
# Create uninstall targets # Create uninstall targets
######################################################################## ########################################################################
@ -162,7 +165,6 @@ configure_file(
add_custom_target(uninstall add_custom_target(uninstall
COMMAND ${CMAKE_COMMAND} -P ${CMAKE_CURRENT_BINARY_DIR}/cmake_uninstall.cmake) COMMAND ${CMAKE_COMMAND} -P ${CMAKE_CURRENT_BINARY_DIR}/cmake_uninstall.cmake)
######################################################################## ########################################################################
# Macro to add -fPIC property to static libs # Macro to add -fPIC property to static libs
######################################################################## ########################################################################
@ -181,10 +183,8 @@ message(STATUS "Building for version: ${VERSION}")
######################################################################## ########################################################################
include_directories(${PROJECT_BINARY_DIR}/srslte/include/) include_directories(${PROJECT_BINARY_DIR}/srslte/include/)
include_directories(${PROJECT_SOURCE_DIR}/srslte/include/) include_directories(${PROJECT_SOURCE_DIR}/srslte/include/)
include_directories(${PROJECT_SOURCE_DIR}/mex/include)
######################################################################## ########################################################################
# Add the subdirectories # Add the subdirectories
######################################################################## ########################################################################
add_subdirectory(srslte) add_subdirectory(srslte)
add_subdirectory(mex)

@ -20,7 +20,6 @@ Current Features:
* All UL channels/signals are supported for UE side: PRACH, PUSCH, PUCCH, SRS * All UL channels/signals are supported for UE side: PRACH, PUSCH, PUCCH, SRS
* Frequency-based ZF and MMSE equalizer * Frequency-based ZF and MMSE equalizer
* Highly optimized Turbo Decoder available in Intel SSE4.1/AVX (+100 Mbps) and standard C (+25 Mbps) * Highly optimized Turbo Decoder available in Intel SSE4.1/AVX (+100 Mbps) and standard C (+25 Mbps)
* MATLAB and OCTAVE MEX library generation for many components
* UE receiver tested and verified with Amarisoft LTE 100 eNodeB and commercial LTE networks (Telefonica Spain, Three.ie and Eircom in Ireland) * UE receiver tested and verified with Amarisoft LTE 100 eNodeB and commercial LTE networks (Telefonica Spain, Three.ie and Eircom in Ireland)
Missing Features: Missing Features:
@ -45,7 +44,6 @@ Download & Install Instructions
* Optional requirements: * Optional requirements:
* srsgui: for real-time plotting. Download it here: https://github.com/srslte/srsgui * srsgui: for real-time plotting. Download it here: https://github.com/srslte/srsgui
* VOLK: if the VOLK library and headers are detected, they will be used for accelerating some signal processing functions. * VOLK: if the VOLK library and headers are detected, they will be used for accelerating some signal processing functions.
* Matlab/Octave: if found by CMake, MEX files will also be generated and installed. If you find any compilation issue with MEX and you don't need them, pass -DDisableMEX=ON to cmake to disable them.
Download and build srsLTE: Download and build srsLTE:
``` ```

@ -1,63 +0,0 @@
# BuildMex.cmake
# Author: Kent Williams norman-k-williams at uiowa.edu
# Modified by Ismael Gomez, 2014
include(CMakeParseArguments)
if(NOT DisableMEX)
if(NOT MATLAB_FOUND)
find_package(MATLAB)
endif()
if(NOT OCTAVE_FOUND)
find_package(OCTAVE)
endif()
# CMake 2.8.12 & earlier apparently don't define the
# Mex script path, so find it.
if(NOT MATLAB_MEX_PATH)
find_program( MATLAB_MEX_PATH mex
HINTS ${MATLAB_ROOT}/bin
PATHS ${MATLAB_ROOT}/bin
DOC "The mex program path"
)
endif()
endif()
#
# BuildMex -- arguments
# MEXNAME = root of mex library name
# SOURCE = list of source files
# LIBRARIES = libraries needed to link mex library
FUNCTION(BuildMex)
if(NOT DisableMEX)
set(oneValueArgs MEXNAME)
set(multiValueArgs SOURCES LIBRARIES)
cmake_parse_arguments(BuildMex "" "${oneValueArgs}" "${multiValueArgs}" ${ARGN})
if (MATLAB_FOUND)
add_library(${BuildMex_MEXNAME}-mat SHARED ${BuildMex_SOURCES})
#target_include_directories(${BuildMex_MEXNAME}-mat PUBLIC ${MATLAB_INCLUDE_DIR})
set_target_properties(${BuildMex_MEXNAME}-mat PROPERTIES
SUFFIX "${MATLAB_MEX_EXTENSION}"
PREFIX "srslte_"
OUTPUT_NAME "${BuildMex_MEXNAME}"
COMPILE_FLAGS "-fvisibility=default ${MATLAB_MEX_CFLAGS} -DFORCE_STANDARD_RATE -I${MATLAB_INCLUDE_DIR}"
)
target_link_libraries(${BuildMex_MEXNAME}-mat ${BuildMex_LIBRARIES} ${MATLAB_MEX_LIBRARY})
install(TARGETS ${BuildMex_MEXNAME}-mat DESTINATION "${MEX_DIR}/srslte/")
endif(MATLAB_FOUND)
if (OCTAVE_FOUND)
add_library(${BuildMex_MEXNAME}-oct SHARED ${BuildMex_SOURCES})
#target_include_directories(${BuildMex_MEXNAME}-oct PUBLIC ${OCTAVE_INCLUDE_DIR})
set_target_properties(${BuildMex_MEXNAME}-oct PROPERTIES
SUFFIX ".${OCTAVE_MEXFILE_EXT}"
PREFIX "srslte_"
OUTPUT_NAME "${BuildMex_MEXNAME}"
COMPILE_FLAGS "-fvisibility=default ${OCTAVE_MEX_CFLAGS} -DFORCE_STANDARD_RATE -DUNDEF_BOOL -I${OCTAVE_INCLUDE_DIR}"
)
target_link_libraries(${BuildMex_MEXNAME}-oct ${BuildMex_LIBRARIES} ${OCTAVE_LIBRARIES})
install(TARGETS ${BuildMex_MEXNAME}-oct DESTINATION "${MEX_DIR}/srslte/")
endif (OCTAVE_FOUND)
endif (NOT DisableMEX)
ENDFUNCTION(BuildMex)

@ -1,220 +0,0 @@
# - this module looks for Matlab
# Defines:
# MATLAB_INCLUDE_DIR: include path for mex.h, engine.h
# MATLAB_LIBRARIES: required libraries: libmex, etc
# MATLAB_MEX_LIBRARY: path to libmex.lib
# MATLAB_MX_LIBRARY: path to libmx.lib
# MATLAB_MAT_LIBRARY: path to libmat.lib # added
# MATLAB_ENG_LIBRARY: path to libeng.lib
# MATLAB_ROOT: path to Matlab's root directory
# This file is part of Gerardus
#
# This is a derivative work of file FindMatlab.cmake released with
# CMake v2.8, because the original seems to be a bit outdated and
# doesn't work with my Windows XP and Visual Studio 10 install
#
# (Note that the original file does work for Ubuntu Natty)
#
# Author: Ramon Casero <rcasero at gmail.com>, Tom Doel
# Version: 0.2.3
# $Rev$
# $Date$
#
# The original file was copied from an Ubuntu Linux install
# /usr/share/cmake-2.8/Modules/FindMatlab.cmake
set(MATLAB_FOUND FALSE)
if(WIN32)
# Search for a version of Matlab available, starting from the most modern one to older versions
foreach(MATVER "7.14" "7.11" "7.10" "7.9" "7.8" "7.7" "7.6" "7.5" "7.4")
if((NOT DEFINED MATLAB_ROOT)
OR ("${MATLAB_ROOT}" STREQUAL "")
OR ("${MATLAB_ROOT}" STREQUAL "/registry"))
get_filename_component(MATLAB_ROOT "[HKEY_LOCAL_MACHINE\\SOFTWARE\\MathWorks\\MATLAB\\${MATVER};MATLABROOT]"
ABSOLUTE)
set(MATLAB_VERSION ${MATVER})
endif()
endforeach()
# Directory name depending on whether the Windows architecture is 32
# bit or 64 bit
set(CMAKE_SIZEOF_VOID_P 8) # Note: For some wierd reason this variable is undefined in my system...
if(CMAKE_SIZEOF_VOID_P MATCHES "4")
set(WINDIR "win32")
elseif(CMAKE_SIZEOF_VOID_P MATCHES "8")
set(WINDIR "win64")
else()
message(FATAL_ERROR "CMAKE_SIZEOF_VOID_P (${CMAKE_SIZEOF_VOID_P}) doesn't indicate a valid platform")
endif()
# Folder where the MEX libraries are, depending of the Windows compiler
if(${CMAKE_GENERATOR} MATCHES "Visual Studio 6")
set(MATLAB_LIBRARIES_DIR "${MATLAB_ROOT}/extern/lib/${WINDIR}/microsoft/msvc60")
elseif(${CMAKE_GENERATOR} MATCHES "Visual Studio 7")
# Assume people are generally using Visual Studio 7.1,
# if using 7.0 need to link to: ../extern/lib/${WINDIR}/microsoft/msvc70
set(MATLAB_LIBRARIES_DIR "${MATLAB_ROOT}/extern/lib/${WINDIR}/microsoft/msvc71")
# set(MATLAB_LIBRARIES_DIR "${MATLAB_ROOT}/extern/lib/${WINDIR}/microsoft/msvc70")
elseif(${CMAKE_GENERATOR} MATCHES "Borland")
# Assume people are generally using Borland 5.4,
# if using 7.0 need to link to ../extern/lib/${WINDIR}/microsoft/msvc70
set(MATLAB_LIBRARIES_DIR "${MATLAB_ROOT}/extern/lib/${WINDIR}/microsoft/bcc54")
# set(MATLAB_LIBRARIES_DIR "${MATLAB_ROOT}/extern/lib/${WINDIR}/microsoft/bcc50")
# set(MATLAB_LIBRARIES_DIR "${MATLAB_ROOT}/extern/lib/${WINDIR}/microsoft/bcc51")
elseif(${CMAKE_GENERATOR} MATCHES "Visual Studio*")
# If the compiler is Visual Studio, but not any of the specific
# versions above, we try our luck with the microsoft directory
set(MATLAB_LIBRARIES_DIR "${MATLAB_ROOT}/extern/lib/${WINDIR}/microsoft/")
else()
message(FATAL_ERROR "Generator not compatible: ${CMAKE_GENERATOR}")
endif()
# Get paths to the Matlab MEX libraries
find_library(MATLAB_MEX_LIBRARY libmex ${MATLAB_LIBRARIES_DIR} )
find_library(MATLAB_MX_LIBRARY libm ${MATLAB_LIBRARIES_DIR} )
find_library(MATLAB_MAT_LIBRARY libmat ${MATLAB_LIBRARIES_DIR} )
find_library(MATLAB_ENG_LIBRARY libeng ${MATLAB_LIBRARIES_DIR} )
# Get path to the include directory
find_path(MATLAB_INCLUDE_DIR "mex.h" "${MATLAB_ROOT}/extern/include" )
else()
if((NOT DEFINED MATLAB_ROOT)
OR ("${MATLAB_ROOT}" STREQUAL ""))
# get path to the Matlab root directory
execute_process(
COMMAND which matlab
OUTPUT_VARIABLE MATLAB_BIN_EXISTS
)
IF (MATLAB_BIN_EXISTS)
execute_process(
COMMAND which matlab
COMMAND xargs realpath
COMMAND xargs dirname
COMMAND xargs dirname
COMMAND xargs echo -n
OUTPUT_VARIABLE MATLAB_ROOT
)
ENDIF (MATLAB_BIN_EXISTS)
endif()
# Check if this is a Mac
if(${CMAKE_SYSTEM_NAME} MATCHES "Darwin")
set(LIBRARY_EXTENSION .dylib)
# If this is a Mac and the attempts to find MATLAB_ROOT have so far failed,
# we look in the applications folder
if((NOT DEFINED MATLAB_ROOT) OR ("${MATLAB_ROOT}" STREQUAL ""))
# Search for a version of Matlab available, starting from the most modern one to older versions
foreach(MATVER "R2013b" "R2013a" "R2012b" "R2012a" "R2011b" "R2011a" "R2010b" "R2010a" "R2009b" "R2009a" "R2008b")
if((NOT DEFINED MATLAB_ROOT) OR ("${MATLAB_ROOT}" STREQUAL ""))
if(EXISTS /Applications/MATLAB_${MATVER}.app)
set(MATLAB_ROOT /Applications/MATLAB_${MATVER}.app)
endif()
endif()
endforeach()
endif()
else()
set(LIBRARY_EXTENSION .so)
endif()
# Get path to the MEX libraries
execute_process(
#COMMAND find "${MATLAB_ROOT}/extern/lib" -name libmex${LIBRARY_EXTENSION} # Peter
COMMAND find "${MATLAB_ROOT}/bin" -name libmex${LIBRARY_EXTENSION} # standard
COMMAND xargs echo -n
OUTPUT_VARIABLE MATLAB_MEX_LIBRARY
)
execute_process(
#COMMAND find "${MATLAB_ROOT}/extern/lib" -name libmx${LIBRARY_EXTENSION} # Peter
COMMAND find "${MATLAB_ROOT}/bin" -name libmx${LIBRARY_EXTENSION} # Standard
COMMAND xargs echo -n
OUTPUT_VARIABLE MATLAB_MX_LIBRARY
)
execute_process(
#COMMAND find "${MATLAB_ROOT}/extern/lib" -name libmat${LIBRARY_EXTENSION} # Peter
COMMAND find "${MATLAB_ROOT}/bin" -name libmat${LIBRARY_EXTENSION} # Standard
COMMAND xargs echo -n
OUTPUT_VARIABLE MATLAB_MAT_LIBRARY
)
execute_process(
#COMMAND find "${MATLAB_ROOT}/extern/lib" -name libeng${LIBRARY_EXTENSION} # Peter
COMMAND find "${MATLAB_ROOT}/bin" -name libeng${LIBRARY_EXTENSION} # Standard
COMMAND xargs echo -n
OUTPUT_VARIABLE MATLAB_ENG_LIBRARY
)
# Get path to the include directory
find_path(MATLAB_INCLUDE_DIR
"mex.h"
PATHS "${MATLAB_ROOT}/extern/include"
)
find_program( MATLAB_MEX_PATH mex
HINTS ${MATLAB_ROOT}/bin
PATHS ${MATLAB_ROOT}/bin
DOC "The mex program path"
)
find_program( MATLAB_MEXEXT_PATH mexext
HINTS ${MATLAB_ROOT}/bin
PATHS ${MATLAB_ROOT}/bin
DOC "The mexext program path"
)
execute_process(
COMMAND ${MATLAB_MEXEXT_PATH}
OUTPUT_STRIP_TRAILING_WHITESPACE
OUTPUT_VARIABLE MATLAB_MEX_EXT
)
endif()
# This is common to UNIX and Win32:
set(MATLAB_LIBRARIES
${MATLAB_MEX_LIBRARY}
${MATLAB_MX_LIBRARY}
${MATLAB_ENG_LIBRARY}
)
if(MATLAB_INCLUDE_DIR AND MATLAB_LIBRARIES)
set(MATLAB_FOUND TRUE)
endif()
# 32-bit or 64-bit mex
if(WIN32)
if (CMAKE_CL_64)
SET(MATLAB_MEX_EXTENSION .mexw64)
else(CMAKE_CL_64)
SET(MATLAB_MEX_EXTENSION .mexw32)
endif(CMAKE_CL_64)
else(WIN32)
if (CMAKE_SIZEOF_VOID_P MATCHES "8")
SET(MATLAB_MEX_EXTENSION .mexa64)
else(CMAKE_SIZEOF_VOID_P MATCHES "8")
SET(MATLAB_MEX_EXTENSION .mexglx)
endif (CMAKE_SIZEOF_VOID_P MATCHES "8")
endif(WIN32)
SET(MATLAB_MEX_CFLAGS "-DMATLAB_MEX_FILE -DMX_COMPAT_32")
mark_as_advanced(
MATLAB_LIBRARIES
MATLAB_MEX_LIBRARY
MATLAB_MX_LIBRARY
MATLAB_ENG_LIBRARY
MATLAB_INCLUDE_DIR
MATLAB_FOUND
MATLAB_ROOT
MATLAB_MEX_PATH
MATLAB_MEXEXT_PATH
MATLAB_MEX_EXT
)

@ -1,138 +0,0 @@
# - Try to find a version of Octave and headers/library required by the
# used compiler. It determines the right MEX-File extension and add
# a macro to help the build of MEX-functions.
#
# This module defines:
# OCTAVE_INCLUDE_DIR: include path for mex.h, mexproto.h
# OCTAVE_OCTINTERP_LIBRARY: path to the library octinterp
# OCTAVE_OCTAVE_LIBRARY: path to the library octave
# OCTAVE_CRUFT_LIBRARY: path to the library cruft
# OCTAVE_LIBRARIES: required libraries: octinterp, octave, cruft
# OCTAVE_CREATE_MEX: macro to build a MEX-file
#
# The macro OCTAVE_CREATE_MEX requires in this order:
# - function's name which will be called in Octave;
# - C/C++ source files;
# - third libraries required.
# Copyright (c) 2009-2013 Arnaud Barré <arnaud.barre@gmail.com>
# Redistribution and use is allowed according to the terms of the BSD license.
# For details see the accompanying COPYING-CMAKE-SCRIPTS file.
IF(OCTAVE_ROOT AND OCTAVE_INCLUDE_DIR AND OCTAVE_LIBRARIES)
STRING(COMPARE NOTEQUAL "${OCTAVE_ROOT}" "${OCTAVE_ROOT_LAST}" OCTAVE_CHANGED)
IF(OCTAVE_CHANGED)
SET(OCTAVE_USE_MINGW32 OCTAVE_USE_MINGW32-NOTFOUND CACHE INTERNAL "")
SET(OCTAVE_OCTAVE_LIBRARY OCTAVE_OCTAVE_LIBRARY-NOTFOUND CACHE INTERNAL "")
SET(OCTAVE_INCLUDE_DIR OCTAVE_INCLUDE_DIR-NOTFOUND CACHE INTERNAL "")
ELSE(OCTAVE_CHANGED)
# in cache already
SET(Octave_FIND_QUIETLY TRUE)
ENDIF(OCTAVE_CHANGED)
ENDIF(OCTAVE_ROOT AND OCTAVE_INCLUDE_DIR AND OCTAVE_LIBRARIES)
SET(OCTAVE_MEXFILE_EXT mex)
IF(WIN32)
SET(OCTAVE_PATHS_L1 )
SET(OCTAVE_PATHS_L2 )
# Level 0
FILE(GLOB OCTAVE_PATHS_L0 "c:/Octave*")
# Level 1
FOREACH(_file_ ${OCTAVE_PATHS_L0})
FILE(GLOB OCTAVE_PATHS_TEMP "${_file_}/*")
SET(OCTAVE_PATHS_L1 ${OCTAVE_PATHS_L1};${OCTAVE_PATHS_TEMP})
ENDFOREACH(_file_ OCTAVE_PATHS_L0)
# Level 2
FOREACH(_file_ ${OCTAVE_PATHS_L1})
FILE(GLOB OCTAVE_PATHS_TEMP "${_file_}/*")
SET(OCTAVE_PATHS_L2 ${OCTAVE_PATHS_L2};${OCTAVE_PATHS_TEMP})
ENDFOREACH(_file_ OCTAVE_PATHS_L1)
# Merge levels
SET(OCTAVE_PATHS ${OCTAVE_PATHS_L0} ${OCTAVE_PATHS_L1} ${OCTAVE_PATHS_L2})
FIND_PATH(OCTAVE_ROOT "bin/octave.exe" ${OCTAVE_PATHS})
FIND_PATH(OCTAVE_USE_MINGW32 "bin/mingw32-make.exe" "${OCTAVE_ROOT}/mingw32")
IF(MSVC AND OCTAVE_USE_MINGW32)
MESSAGE(FATAL_ERROR
"You must use the generator \"MinGW Makefiles\" as the "
"version of Octave installed on your computer was compiled "
"with MinGW. You should also specify the native compiler "
"(GCC, G++ and GFortan) and add the path of MinGW in the "
"environment variable PATH. Contact the developers of the "
"project for more details")
ENDIF(MSVC AND OCTAVE_USE_MINGW32)
FILE(GLOB OCTAVE_INCLUDE_PATHS "${OCTAVE_ROOT}/include/octave-*/octave")
FILE(GLOB OCTAVE_LIBRARIES_PATHS "${OCTAVE_ROOT}/lib/octave-*")
IF (NOT OCTAVE_LIBRARIES_PATHS)
FILE(GLOB OCTAVE_LIBRARIES_PATHS "${OCTAVE_ROOT}/lib/octave/*")
ENDIF (NOT OCTAVE_LIBRARIES_PATHS)
# LIBOCTINTERP, LIBOCTAVE, LIBCRUFT names
SET(LIBOCTAVE "liboctave")
ELSE(WIN32)
IF(APPLE)
FILE(GLOB OCTAVE_PATHS "/Applications/Octave*")
FIND_PATH(OCTAVE_ROOT "Contents/Resources/bin/octave" ${OCTAVE_PATHS})
FILE(GLOB OCTAVE_INCLUDE_PATHS "${OCTAVE_ROOT}/Contents/Resources/include/octave-*/octave")
FILE(GLOB OCTAVE_LIBRARIES_PATHS "${OCTAVE_ROOT}/Contents/Resources/lib/octave-*")
SET(LIBOCTAVE "liboctave.dylib")
ELSE(APPLE)
FILE(GLOB OCTAVE_LOCAL_PATHS "/usr/local/lib/octave-*")
FILE(GLOB OCTAVE_USR_PATHS "/usr/lib/octave-*")
FILE(GLOB OCTAVE_INCLUDE_PATHS "/usr/include/octave-*")
SET (OCTAVE_INCLUDE_PATHS
"/usr/local/include"
"/usr/local/include/octave"
"/usr/include"
"${OCTAVE_INCLUDE_PATHS}"
"${OCTAVE_INCLUDE_PATHS}/octave")
SET (OCTAVE_LIBRARIES_PATHS
"/usr/local/lib"
"/usr/local/lib/octave"
${OCTAVE_LOCAL_PATHS}
"/usr/lib"
"/usr/lib/octave"
${OCTAVE_USR_PATHS})
SET (LIBOCTAVE "octave")
ENDIF(APPLE)
ENDIF(WIN32)
FIND_LIBRARY(OCTAVE_OCTAVE_LIBRARY
${LIBOCTAVE}
${OCTAVE_LIBRARIES_PATHS}
)
FIND_PATH(OCTAVE_INCLUDE_DIR
"mex.h"
${OCTAVE_INCLUDE_PATHS}
)
SET(OCTAVE_ROOT_LAST "${OCTAVE_ROOT}" CACHE INTERNAL "" FORCE)
# This is common to UNIX and Win32:
SET(OCTAVE_LIBRARIES
${OCTAVE_OCTAVE_LIBRARY}
CACHE INTERNAL "Octave libraries" FORCE
)
INCLUDE(FindPackageHandleStandardArgs)
# The variable OCTAVE_ROOT is only relevant for WIN32
IF(WIN32)
FIND_PACKAGE_HANDLE_STANDARD_ARGS(Octave DEFAULT_MSG OCTAVE_ROOT OCTAVE_INCLUDE_DIR OCTAVE_OCTAVE_LIBRARY )
ELSE(WIN32)
FIND_PACKAGE_HANDLE_STANDARD_ARGS(Octave DEFAULT_MSG OCTAVE_INCLUDE_DIR OCTAVE_OCTAVE_LIBRARY )
ENDIF(WIN32)
MARK_AS_ADVANCED(
OCTAVE_OCTAVE_LIBRARY
OCTAVE_LIBRARIES
OCTAVE_INCLUDE_DIR
)

@ -1,3 +1,6 @@
#if (NOT CMAKE_SYSTEM_PROCESSOR MATCHES "x86_64|^i[3,9]86$")
# return()
#endif()
include(CheckCSourceRuns) include(CheckCSourceRuns)

@ -1,21 +0,0 @@
function [ s ] = bin2hex( in )
%BIN2HEX Summary of this function goes here
% Detailed explanation goes here
a=reshape(in,8,[]);
t=size(a);
s=cell(1,t(2));
nbit=2.^(7:-1:0);
for i=1:t(2)
s{i}=dec2hex(sum(nbit'.*double(a(:,i))));
end
for i=1:t(2)
if (length(s{i})==1)
fprintf('0%s ',s{i})
else
fprintf('%s ',s{i})
end
end
fprintf('\n');
end

@ -1,20 +0,0 @@
function [ out ] = read_complex( filename, count )
%READ_COMPLEX Summary of this function goes here
% Detailed explanation goes here
[tidin msg]=fopen(filename,'r');
if (tidin==-1)
fprintf('error opening %s: %s\n',filename, msg);
out=[];
return
end
if (nargin==1)
count=inf;
end
x=fread(tidin,2*count,'single');
i=1:2:length(x);
out=x(i)+x(i+1)*1i;
end

@ -1,18 +0,0 @@
function [ out ] = read_int16( filename, count )
%READ_COMPLEX Summary of this function goes here
% Detailed explanation goes here
[tidin msg]=fopen(filename,'r');
if (tidin==-1)
fprintf('error opening %s: %s\n',filename, msg);
out=[];
return
end
if (nargin==1)
count=inf;
end
out=fread(tidin,count,'int16');
end

@ -1,18 +0,0 @@
function [ out ] = read_real( filename, count )
%READ_COMPLEX Summary of this function goes here
% Detailed explanation goes here
[tidin msg]=fopen(filename,'r');
if (tidin==-1)
fprintf('error opening %s: %s\n',filename, msg);
out=[];
return
end
if (nargin==1)
count=inf;
end
out=fread(tidin,count,'single');
end

@ -1,19 +0,0 @@
function [ values, tti] = read_trace_uint( filename, count )
[tidin msg]=fopen(filename,'r');
if (tidin==-1)
fprintf('error opening %s: %s\n',filename, msg);
out=[];
return
end
if (nargin==1)
count=inf;
end
x=fread(tidin,2*count,'uint');
i=1:2:length(x);
tti=x(i);
values=x(i+1);
end

@ -1,18 +0,0 @@
function [ out ] = read_uchar( filename, count )
%READ_COMPLEX Summary of this function goes here
% Detailed explanation goes here
[tidin msg]=fopen(filename,'r');
if (tidin==-1)
fprintf('error opening %s: %s\n',filename, msg);
out=[];
return
end
if (nargin==1)
count=inf;
end
out=fread(tidin,count,'uint8');
end

@ -1,16 +0,0 @@
function [ out ] = write_c_struct_complex( filename, varname, x)
[tidin msg]=fopen(filename,'wt');
if (tidin==-1)
fprintf('error opening %s: %s\n',filename, msg);
out=[];
return
end
fprintf(tidin, 'float %s[%d]={%.9g,%.9g',varname,2*length(x),real(x(1)),imag(x(1)));
for i=2:length(x)
fprintf(tidin, ',\n %.9g,%.9g',real(x(i)),imag(x(i)));
end
fprintf(tidin, '};\n');
fclose(tidin);
end

@ -1,22 +0,0 @@
function [ out ] = write_complex( filename, x)
%READ_COMPLEX Summary of this function goes here
% Detailed explanation goes here
[tidin msg]=fopen(filename,'w');
if (tidin==-1)
fprintf('error opening %s: %s\n',filename, msg);
out=[];
return
end
if (isreal(x))
y=x;
else
i=1:2:2*length(x);
y(i)=real(x);
y(i+1)=imag(x);
end
fwrite(tidin,y,'single');
end

@ -1,14 +0,0 @@
function [ out ] = write_int16( filename, x)
%READ_COMPLEX Summary of this function goes here
% Detailed explanation goes here
[tidin msg]=fopen(filename,'w');
if (tidin==-1)
fprintf('error opening %s: %s\n',filename, msg);
out=[];
return
end
fwrite(tidin,x,'int16');
end

@ -1,14 +0,0 @@
function [ out ] = write_complex( filename, x)
%READ_COMPLEX Summary of this function goes here
% Detailed explanation goes here
[tidin msg]=fopen(filename,'w');
if (tidin==-1)
fprintf('error opening %s: %s\n',filename, msg);
out=[];
return
end
fwrite(tidin,x,'single');
end

@ -1,14 +0,0 @@
function [ out ] = write_uchar( filename, x)
%READ_COMPLEX Summary of this function goes here
% Detailed explanation goes here
[tidin msg]=fopen(filename,'w');
if (tidin==-1)
fprintf('error opening %s: %s\n',filename, msg);
out=[];
return
end
fwrite(tidin,x,'uint8');
end

@ -1,20 +0,0 @@
F=100000./(1:100);
PQ=(1:50);
PRB=50;
Mmax=1024;
N=PRB*12;
Fmin=N*15*1.1;
Fs=F(F>Fmin);
for i=length(Fs):-1:1
for p=PQ
for q=PQ
if (mod(p/q*Fs(i),15)==0 && p/q*Fs(i)/15<Mmax)
fprintf('found Fs=%f p=%d, q=%d, M=%d\n',Fs(i),p,q,p/q*Fs(i)/15);
return
end
end
end
end

Binary file not shown.

@ -1,46 +0,0 @@
function out = arb_resample_linear(sig, rate)
N = 32;
M = 8;
step = (1/rate)*N;
load('arb_filter.mat');
figure;plot(Num);title('Filter impulse response');
[h,w] = freqz(Num, 1);
figure;plot(20*log10(abs(h)));title('Filter freq response');
% Create polyphase partition
poly = reshape(Num, N, M);
% Filter
sig = [zeros(1,(M/2)-1) sig];
k=0;
acc=0;
index=0;
frac=0;
out = [];
while k < length(sig)-M
sig_reg = fliplr(sig(k+1:k+M));
filt_reg1 = poly(index+1, :);
filt_reg2 = poly(mod(index+1,N)+1, :);
res1 = sig_reg*filt_reg1';
res2 = sig_reg*filt_reg2';
if index+1 == 32
res = res1;
else
res = res1 + (res2-res1)*frac;
end
out = [out res];
acc = acc+step;
index = fix(acc);
while index >= N
acc = acc - N;
index = index - N;
k = k+1;
end
frac = abs(acc-index);
end

@ -1,37 +0,0 @@
function out = arb_resample_nearest(sig, rate)
N = 32;
M = 8;
step = (1/rate)*N;
load('arb_filter.mat');
figure;plot(Num);title('Filter impulse response');
[h,w] = freqz(Num, 1);
figure;plot(20*log10(abs(h)));title('Filter frequency response');
% Create polyphase partition
poly = reshape(Num, N, M);
% Filter
sig = [zeros(1,(M/2)-1) sig];
k=0;
acc=0;
index=0;
frac=0;
out = [];
while k < length(sig)-M
sig_reg = fliplr(sig(k+1:k+M));
filt_reg1 = poly(index+1, :);
res = sig_reg*filt_reg1';
out = [out res];
acc = acc+step;
index = round(acc);
while index >= N
acc = acc - N;
index = index - N;
k = k+1;
end
end

@ -1,33 +0,0 @@
close all
clear all
up = 24;
down = 25;
d_rate = up/down;
Fs = 100; % Arbitrary sample rate (used for displays)
Fsin = 1;
% Create a sine wave
t = 0:1/Fs:1-1/Fs;
sig = sin(2*pi*t);
out = arb_resample_nearest(sig,d_rate);
% matlab resample for comparison
out2 = resample(sig, up, down);
figure;hold on;title('Ours and matlabs');
l = min(length(out), length(out2));
stem(out(1:l));
stem(out2(1:l), 'r', 'filled');
diff = out2(1:l)-out(1:l);
figure;plot(diff);title('Difference between ours and matlabs');
figure; hold on;title('Original and resampled - no time scaling');
stem(sig);
stem(out, 'r', 'filled');
% Time align and plot
figure;hold on;title('Original and resampled - with time scaling');
stem((1:75)/Fs,real(sig(1:75)));
stem((1:72)/(Fs*d_rate),real(out(1:72)),'r','filled');
xlabel('Time (sec)');ylabel('Signal value');

@ -1,6 +0,0 @@
function [ y ] = addnoise( x, snr_db )
v = 10^(-snr_db/10);
y=x+sqrt(v)*(randn(size(x))+1i*randn(size(x)))/sqrt(2);
y=y/sqrt(mean(y.*conj(y)));
end

@ -1,18 +0,0 @@
function [cfo, r] = cfo_estimate_cp(input_slot, Nsyms, sym_len, cp0_len, cp_len)
% Start correlating from the end. Nsyms is the number of symbols to
% correlate starting from the end.
s=length(input_slot)-sym_len-cp_len;
e=length(input_slot)-sym_len;
for i=1:Nsyms
r(i)=sum(input_slot(s:e).*conj(input_slot(s+sym_len:e+sym_len)));
if (i < 7)
s=s-sym_len-cp_len;
e=e-sym_len-cp_len;
else
s=s-sym_len-cp0_len;
e=e-sym_len-cp0_len;
end
end
cfo=-angle(mean(r))/pi;

@ -1,42 +0,0 @@
clear;
sym_len=128;
hflen = (sym_len/128)*1920*5;
samp_rate = (sym_len/128)*1920000;
N_id_2=0;
input=read_complex('../../debug/lte_signal.dat', hflen*240);
addpath('../../debug/srslte/lib/sync/test')
off=100;
halfframes=reshape(input(hflen-off+1:end-hflen-off),hflen,[]);
[n m]=size(halfframes);
fo=linspace(-30000,30000,m);
nreal=1;
cfdl=struct('NDLRB',6,'CyclicPrefix','Normal','NCellID',0,'CellRefP',1,'DuplexMode','FDD');
cfo=zeros(m,3);
toffset=zeros(m,2);
for i=1:m
x = halfframes(:,i);
t = (0:n-1).'/samp_rate;
x = x .* exp(1i*2*pi*fo(i).*t);
cfo_=zeros(nreal,2);
idx_=zeros(nreal,2);
for j=1:nreal
y=awgn(x,5);
cfo_(j,1) = lteFrequencyOffset(cfdl,y)/15000;
[idx_(j,1), cfo_(j,2)] = find_pss(y,N_id_2);
[idx_(j,2), corr] = srslte_cp_synch(cfdl,y);
cfo_(j,3) = -angle(corr(idx_(j,2)+1))/2/pi;
idx_(j,1) = idx_(j,1)-961;
end
cfo(i,:)=mean(cfo_,1);
toffset(i,:)=mean(idx_,1);
end
error=abs(cfo-repmat(fo',1,3)/15000);
semilogy(fo/15000,error)
%plot(fo/15000,toffset)
legend('Matlab','PSS-based','CP-based')

@ -1,33 +0,0 @@
function [ fs ] = check_pss( x, N_id_2, threshold)
%CHECK_PSS Summary of this function goes here
% Detailed explanation goes here
flen=9600;
n=length(x);
nf=floor(n/flen);
xf=reshape(x(1:nf*flen),flen,[]);
fs=zeros(nf,1);
cfo=zeros(nf,1);
cfo2=zeros(nf,1);
m_p=zeros(nf,1);
for i=1:nf
[fs(i) cfo(i) m_p(i)]=find_pss(xf(:,i),N_id_2,false, threshold);
end
fs=fs+960;
[sfo sfo_v]=srslte_sfo_estimate(fs, 5/1000);
subplot(1,3,1)
plot(1:nf,fs)
subplot(1,3,2)
plot(1:nf, cfo)
if (nf > 0)
axis([0 nf -0.5 0.5])
end
subplot(1,3,3)
plot(m_p)
fprintf('cfo_mean=%g Hz, cfo_std=%g Hz, m_p=%g sfo=%g Hz\n',15000*nanmean(cfo),15000*nanstd(cfo), nanmean(m_p), sfo)
end

@ -1,14 +0,0 @@
function [ y eps] = correct_cfo( x )
xf=reshape(x,9600,[]);
yf=zeros(size(xf));
[m n]=size(xf);
for i=1:n
[fs eps(i)]=find_pss(xf(:,i),0,false);
yf(:,i)=xf(:,i).*exp(-1i.*(1:length(xf(:,i)))'.*2*pi*eps(i)/128);
end
y=reshape(yf,1,[]);
end

@ -1,9 +0,0 @@
function [ lambda ] = cp_corr( x, theta, N, L)
l0=sum(x(theta:theta+L-1).*conj(x(theta+N:theta+L+N-1)));
l1=0;
for i=theta:theta+L-1
l1=l1+abs(x(i))^2+abs(x(i+N))^2;
end
lambda=l1;%2*abs(l0)-rho*l1;

@ -1,8 +0,0 @@
function cp_pss_comp(x,N_id_2)
[ fs eps p_m w2] = find_pss( x, N_id_2);
lambda=zeros(1,length(x)-138);
for theta=1:length(lambda)
lambda(theta)=cp_corr(x,theta,128,9,0);
end
plot(1:length(w2),abs(w2)/max(abs(w2)),1:length(lambda),abs(lambda)/max(abs(lambda)))

@ -1,14 +0,0 @@
function [ eps fs] = epsilon( x )
xf=reshape(x,19200,[]);
[m n]=size(xf);
eps=zeros(n,1);
fs=zeros(n,1);
for i=1:n
[fs(i) eps(i)]=find_pss(xf(:,i),0,false);
end
end

@ -1,13 +0,0 @@
function [peaks] = find_peaks(x, N_id_2, fft_size)
flen=4800*(ceil(fft_size/64));
n=floor(length(x)/flen)*flen;
xf=reshape(x(1:n),flen,[]);
[n m] = size(xf);
peaks=zeros(m,1);
for i=1:m
[w, peaks(i)]= find_pss2(xf(:,i),N_id_2,fft_size);
end

@ -1,19 +0,0 @@
function [ fs, cfo, p_m, w2] = find_pss( x, N_id_2)
c=lte_pss_zc(N_id_2);
cc=[zeros(33,1); c; zeros(33,1)];
ccf=[0; cc(65:128); cc(2:64)];
ccf=sqrt(128)*conj(ifft(ccf));
w2=conv(x,ccf);
[m, fs]=max(abs(w2));
if (fs > 128 && fs < length(x))
y=ccf.*x(fs-128:fs-1);
y0=y(1:64);
y1=y(65:length(y));
cfo=angle(conj(sum(y0))*sum(y1))/pi;
p_m = m/mean(abs(w2));
end
end

@ -1,14 +0,0 @@
function [w2, m, idx] = find_pss2( x, N_id_2, fft_size)
c=lte_pss_zc(N_id_2);
cc=[zeros(fft_size/2-31,1); c; zeros(fft_size/2-31,1)];
ccd=[0; cc(fft_size/2+1:fft_size); cc(2:fft_size/2)];
ccf=sqrt(fft_size)*conj(ifft(ccd));
w2=abs(conv(x,ccf/62)).^2/var(x,1)/sqrt(2);
plot(w2)
[m, idx]=max(w2);
%fprintf('Frame starts at %d, energy=%g, p=%g, p/en=%g dB\n',i, ...
% en, m, m/en);
end

@ -1,7 +0,0 @@
function fs = find_pss_ac( x)
w2=xcorr(x,x);
[m, fs]=max(abs(w2));
fs=fs-1920;
end

@ -1,50 +0,0 @@
function [ m1 m2 out Zprod0 Zprod1] = find_sss( y, Nid_2,c0,c1)
y=y((960-2*137+1):(960-137-9));
yf=fft(y,128);
y=[yf(98:128) yf(2:32)];
n=length(y);
Y0=y(1:2:n);
Y1=y(2:2:n);
Z0=Y0.*c0;
nz=length(Z0);
sm0=zeros(31,31);
sm1=zeros(31,31);
zm0=zeros(31,31);
for i=1:31
[sm0(i,:) zm0(i,:)]=compute_m0(i-1);
end
Zprod0=Z0(2:nz).*conj(Z0(1:(nz-1)));
sum0=zeros(31,1);
for m=1:31
for i=2:31
sum0(m)=sum0(m)+Z0(i)*conj(Z0(i-1))*sm0(m,i)*conj(sm0(m,i-1));
end
end
[mi1 i1]=max(abs(sum0));
Z1=Y1.*c1.*zm0(i1,:);
Zprod1=Z1(2:nz).*conj(Z1(1:(nz-1)));
sum1=zeros(31,1);
for m=1:31
for i=2:31
sum1(m)=sum1(m)+Z1(i)*conj(Z1(i-1))*sm0(m,i)*conj(sm0(m,i-1));
end
end
[mi2 i2]=max(abs(sum1));
m1=i1;
m2=i2;
out=[sum0; sum1];
end

@ -1,13 +0,0 @@
function [ ifo ] = ifo_pss( r_pss, x_pss)
k=1;
v=-31:31;
c=zeros(length(v),1);
for i=v
c(k) = ifo_pss_corr(i, r_pss, x_pss);
k=k+1;
end
[m i]=max(c);
ifo=v(i);
plot(v,c);

@ -1,10 +0,0 @@
function [ corr ] = ifo_pss_corr( n, r_pss, x_pss)
x=0;
for i=1:length(x_pss)
x=x+r_pss(1+mod(i+n-1,length(r_pss)))*conj(x_pss(i));
end
corr=real(exp(1i*2*pi*9*n/128)*x);
% corr=abs(x);
end

@ -1,24 +0,0 @@
function[a]=lte_pss_zc(cell_id)
% Function returns 1 out of 3 possible Zadoff-Chu sequences used in LTE.
Nzc=62;
u=0;
if cell_id==0
u=25;
end
if cell_id==1
u=29;
end
if cell_id==2
u=34;
end
a = zeros(Nzc,1);
for n=0:30
a(n+1)=exp(complex(0,-1)*pi*u*n*(n+1)/63);
end
for n=31:61
a(n+1)=exp(complex(0,-1)*pi*u*(n+1)*(n+2)/63);
end
end

@ -1,18 +0,0 @@
function [ sfo sfo_v ] = srslte_sfo_estimate( fs, T )
nanfs=fs(~isnan(fs));
idx=find(~isnan(fs));
sfo_v = zeros(length(nanfs)-1,1);
for i=2:length(nanfs)
if (abs(nanfs(i)-nanfs(i-1))<9000)
sfo_v(i-1)=(nanfs(i)-nanfs(i-1))/T/(idx(i)-idx(i-1));
else
sfo_v(i-1)=sfo_v(i-2);
end
end
sfo = mean(sfo_v);

@ -1,13 +0,0 @@
function [ fs ] = sym_sync_cp( x, s )
lambda=zeros(1,length(x)-138);
for theta=1:length(lambda)
lambda(theta)=cp_corr(x,theta,128,9,s);
end
subplot(1,2,1)
plot(abs(lambda))
subplot(1,2,2)
plot(angle(lambda))
[m i] = max(abs(lambda))

@ -1,46 +0,0 @@
clear
addpath('../../build/srslte/lib/mimo/test')
enb = lteRMCDL('R.10');
cec = struct('FreqWindow',9,'TimeWindow',9,'InterpType','cubic');
cec.PilotAverage = 'UserDefined';
cec.InterpWinSize = 1;
cec.InterpWindow = 'Causal';
cfg.Seed = 1; % Random channel seed
cfg.NRxAnts = 1; % 1 receive antenna
cfg.DelayProfile = 'ETU'; % EVA delay spread
cfg.DopplerFreq = 100; % 120Hz Doppler frequency
cfg.MIMOCorrelation = 'Low'; % Low (no) MIMO correlation
cfg.InitTime = 0; % Initialize at time zero
cfg.NTerms = 16; % Oscillators used in fading model
cfg.ModelType = 'GMEDS'; % Rayleigh fading model type
cfg.InitPhase = 'Random'; % Random initial phases
cfg.NormalizePathGains = 'On'; % Normalize delay profile power
cfg.NormalizeTxAnts = 'On'; % Normalize for transmit antennas
[txWaveform, ~, info] = lteRMCDLTool(enb,[1;0;0;1]);
n = length(txWaveform);
cfg.SamplingRate = info.SamplingRate;
txWaveform = txWaveform+complex(randn(n,2),randn(n,2))*1e-3;
rxWaveform = lteFadingChannel(cfg,txWaveform);
rxGrid = lteOFDMDemodulate(enb,sum(rxWaveform,2));
[h,n0] = lteDLChannelEstimate(enb,cec,rxGrid);
signal=rxGrid(:,1);
hest(:,1,1)=reshape(h(:,1,1,1),[],1);
hest(:,1,2)=reshape(h(:,1,1,1),[],1);
output_mat = lteTransmitDiversityDecode(signal(, hest(1:598,1,:));
output_srs = srslte_diversitydecode(signal(1:598), hest(1:598,1,:));
plot(abs(output_mat-output_srs))
mean(abs(output_mat-output_srs).^2)

@ -1,285 +0,0 @@
%% PDSCH Transmit Diversity Throughput Conformance Test
% This example demonstrates the throughput performance under conformance
% test conditions as defined in TS36.101[ <#9 1> ]: single codeword,
% transmit diversity 4Tx-2Rx with medium correlation, EPA5 (Extended
% Pedestrian A) channel. The example also introduces the use of Parallel
% Computing Toolbox(TM) to provide improvements in the simulation time.
% Copyright 2009-2013 The MathWorks, Inc.
%% Introduction
% In this example, Hybrid Automatic Repeat Request(HARQ) is used in line
% with conformance test requirements. A total of 8 HARQ processes are used
% with a maximum of 4 retransmissions permitted. This example uses the R.12
% Reference Measurement Channel (RMC).
%
% This example also uses <matlab:doc('parfor') parfor> loop instead of the
% <matlab:doc('for') for> loop for SNR calculation. <matlab:doc('parfor')
% parfor>, as part of the Parallel Computing Toolbox, executes the SNR loop
% in parallel to reduce the total simulation time.
%% Simulation Settings
% The default simulation length is set to 10 frames at a number of |SNR|
% values including 0.2dB (as per TS36.101 (Section 8.2.1.2.2-Test1)[ <#9
% 1> ]).
NFrames = 50; % Number of frames
SNRdB = [4 5 6]; % SNR range
% eNodeB Configuration
enb = struct; % eNodeB config structure
enb.TotSubframes = 1; % Total subframes RMC will generate
enb.RC = 'R.10'; % RMC number
% Channel Configuration
channel = struct; % Channel config structure
channel.Seed = 2; % Random channel seed
channel.NRxAnts = 1; % 2 receive antennas
channel.DelayProfile ='EVA'; % Delay profile
channel.DopplerFreq = 5; % Doppler frequency
channel.MIMOCorrelation = 'Low'; % Multi-antenna correlation
channel.NTerms = 16; % Oscillators used in fading model
channel.ModelType = 'GMEDS'; % Rayleigh fading model type
channel.InitPhase = 'Random'; % Random initial phases
channel.NormalizePathGains = 'On'; % Normalize delay profile power
channel.NormalizeTxAnts = 'On'; % Normalize for transmit antennas
% Channel Estimator Configuration
cec = struct; % Channel estimation config structure
cec.PilotAverage = 'UserDefined'; % Type of pilot symbol averaging
cec.FreqWindow = 9; % Frequency window size
cec.TimeWindow = 9; % Time window size
cec.InterpType = 'Linear'; % 2D interpolation type
cec.InterpWindow = 'Centered'; % Interpolation window type
cec.InterpWinSize = 1; % Interpolation window size
% PDSCH Configuration
enb.PDSCH.TxScheme = 'TxDiversity'; % Transmission scheme
enb.PDSCH.RNTI = 1; % 16-bit User Equipment (UE) mask
enb.PDSCH.Rho = 0; % PDSCH RE power adjustment factor
enb.PDSCH.CSI = 'Off'; % No CSI scaling of soft bits
% Simulation Variables
totalBLKCRC = []; % Define total block CRC vector
bitThroughput = []; % Define total bit throughput vector
%% System Processing
% Working on a subframe by subframe basis and using the LTE System
% Toolbox(TM) a populated resource grid is generated and OFDM modulated to
% create a transmit waveform. The generated waveform is transmitted through
% a propagation channel and AWGN is added. Channel estimation, equalization
% and the inverse of transmission chain are performed at receiver. The
% throughput performance of the PDSCH is determined using the block CRC
% result.
% Generate the RMC configuration structure for RMC R.12
rmc = lteRMCDL(enb);
rvSeq = rmc.PDSCH.RVSeq;
% Transport block sizes for each subframe in a frame
trBlkSizes = rmc.PDSCH.TrBlkSizes;
codedTrBlkSizes = rmc.PDSCH.CodedTrBlkSizes;
% Determine resource grid dimensions
dims = lteDLResourceGridSize(rmc);
p = dims(3);
% Set up channel model sampling rate
ofdmInfo = lteOFDMInfo(rmc);
channel.SamplingRate = ofdmInfo.SamplingRate;
% Generation HARQ table for 8-HARQ processes
harqTable = hHARQTable();
% Initializing state of all HARQ processes
for i=1:9
harqProcess_init(i) = hTxDiversityNewHARQProcess ...
(trBlkSizes(i),codedTrBlkSizes(i),rvSeq); %#ok<SAGROW>
end
% Display the SNR points being simulated
for s=1:numel(SNRdB)
fprintf('\nSimulating at %gdB SNR for a total %d Frame(s)\n', ...
SNRdB(s),NFrames);
end
% The temporary variables 'rmc_init' and 'channel_init' are used to create
% the temporary variables 'rmc' and 'channel' within the SNR loop to create
% independent simulation loops for the parfor loop
rmc_init = rmc;
channel_init = channel;
% 'parfor' will default to the normal 'for' when executed without Parallel
% Computing Toolbox.
parfor index = 1:numel(SNRdB)
% Set the random number generator seed depending to the loop variable
% to ensure independent random streams
rng(index,'combRecursive');
% Set up variables for the SNR loop
offsets = 0; % Initialize overall frame offset value for the SNR
offset = 0; % Initialize frame offset value for the radio frame
rmc = rmc_init; % Initialize RMC configuration
channel = channel_init; % Initialize channel configuration
blkCRC = []; % Define intermediate block CRC vector
bitTput = []; % Intermediate bit throughput vector
% Initializing state of all HARQ processes
harqProcess = harqProcess_init;
for subframeNo = 0:(NFrames*10-1)
% Updating subframe number
rmc.NSubframe = subframeNo;
% HARQ index table
harqIdx = harqTable(mod(subframeNo,length(harqTable))+1); %#ok<PFBNS>
% Update HARQ process
harqProcess(harqIdx) = hTxDiversityHARQScheduling( ...
harqProcess(harqIdx));
% Updating the RV value for correct waveform generation
rmc.PDSCH.RV = harqProcess(harqIdx).rvSeq ...
(harqProcess(harqIdx).rvIdx);
rmc.PDSCH.RVSeq = harqProcess(harqIdx).rvSeq ...
(harqProcess(harqIdx).rvIdx);
[txWaveform txGrid] = lteRMCDLTool(rmc, ...
{harqProcess(harqIdx).dlschTransportBlk});
txWaveform = [txWaveform; zeros(25,p)];
% Initialize at time zero
channel.InitTime = subframeNo/1000;
% Pass data through the fading channel model
rxWaveform = lteFadingChannel(channel,txWaveform);
% Noise setup including compensation for downlink power allocation
SNR = 10^((SNRdB(index)-rmc.PDSCH.Rho)/20); % Linear SNR
% Normalize noise power to take account of sampling rate, which is
% a function of the IFFT size used in OFDM modulation, and the
% number of antennas
N0 = 1/(sqrt(2.0*rmc.CellRefP*double(ofdmInfo.Nfft))*SNR);
% Create additive white Gaussian noise
noise = N0*complex(randn(size(rxWaveform)), ...
randn(size(rxWaveform)));
% Add AWGN to the received time domain waveform
rxWaveform = rxWaveform + noise;
% Receiver
% Perform synchronization
% An offset within the range of delays expected from the channel
% modeling(a combination of implementation delay and channel delay
% spread) indicates success
if (mod(subframeNo,10)==0)
[offset] = lteDLFrameOffset(rmc,rxWaveform);
if (offset > 25)
offset = offsets(end);
end
offsets = [offsets offset];
end
rxWaveform = rxWaveform(1+offset:end,:);
% Perform OFDM demodulation on the received data to recreate the
% resource grid
rxSubframe = lteOFDMDemodulate(rmc,rxWaveform);
% Equalization and channel estimation
[estChannelGrid,noiseEst] = lteDLChannelEstimate(rmc,cec, ...
rxSubframe);
addpath('../../debug/lte/phy/lib/ch_estimation/test')
[est, ~, output] = srslte_chest(rmc.NCellID,rmc.CellRefP,rxSubframe,[0.25 0.5 0.25],[0.1 0.9],mod(rmc.NSubframe,10));
%estChannelGrid=reshape(est,size(estChannelGrid));
% Perform deprecoding, layer demapping, demodulation and
% descrambling on the received data using the estimate of
% the channel
rxEncodedBits = ltePDSCHDecode2(rmc,rmc.PDSCH,rxSubframe,estChannelGrid,noiseEst);
% Decode DownLink Shared Channel (DL-SCH)
[decbits,harqProcess(harqIdx).crc,harqProcess(harqIdx).decState] = ...
lteDLSCHDecode(rmc,rmc.PDSCH,harqProcess(harqIdx).trBlkSize, ...
rxEncodedBits{1},harqProcess(harqIdx).decState);
if(harqProcess(harqIdx).trBlkSize ~= 0)
blkCRC = [blkCRC harqProcess(harqIdx).crc];
bitTput = [bitTput harqProcess(harqIdx).trBlkSize.*(1- ...
harqProcess(harqIdx).crc)];
end
end
% Record the block CRC and bit throughput for the total number of
% frames simulated at a particular SNR
totalBLKCRC(index,:) = blkCRC;
bitThroughput(index,:) = bitTput;
end
%%
% |totalBLKCRC| is a matrix where each row contains the results of decoding
% the block CRC for a defined value of SNR. |bitThroughput| is a matrix
% containing the total number of bits per subframe at the different SNR
% points that have been successfully received and decoded.
%% Results
% First graph shows the throughput as total bits per second against the
% range of SNRs
% figure;
% plot(SNRdB,mean(bitThroughput,2),'-*');
% %axis([-5 3 200 400])
% title(['Throughput for ', num2str(NFrames) ' frame(s)'] );
% xlabel('SNRdB'); ylabel('Throughput (kbps)');
% grid on;
% hold on;
% plot(SNRdB,mean([trBlkSizes(1:5) trBlkSizes(7:10)])*0.7*ones ...
% (1,numel(SNRdB)),'--rs');
% legend('Simulation Result','70 Percent Throughput','Location','SouthEast');
%
% % Second graph shows the total throughput as a percentage of CRC passes
% % against SNR range
% figure;
plot(SNRdB,100*(1-mean(totalBLKCRC,2)),'-*');
%axis([-5 3 50 110])
title(['Throughput for ', num2str(NFrames) ' frame(s)'] );
xlabel('SNRdB'); ylabel('Throughput (%)');
grid on;
hold on;
plot(SNRdB,70*ones(1,numel(SNRdB)),'--rs');
legend('Simulation Result','70 Percent Throughput','Location','SouthEast');
%% Further Exploration
%
% You can modify parts of this example to experiment with different number
% of |NFrames| and different values of SNR. SNR can be a vector of
% values or a single value. Following scenarios can be simulated.
%%
% * Allows control over the total number of frames to run the demo at an
% SNR of 0.2dB (as per TS 36.101).
%
% * Allows control over the total number of frames to run the demo, as well
% as defining a set of desired SNR values. |SNRIn| can be a single value
% or a vector containing a range of values.
%
% * For simulations of multiple SNR points over a large number of frames,
% the use of Parallel Computing Toolbox provides significant improvement in
% the simulation time. This can be easily verified by changing the |parfor|
% in the SNR loop to |for| and re-running the example.
%% Appendix
% This example uses the following helper functions:
%
% * <matlab:edit('hHARQTable.m') hHARQTable.m>
% * <matlab:edit('hTxDiversityHARQScheduling.m') hTxDiversityHARQScheduling.m>
% * <matlab:edit('hTxDiversityNewHARQProcess.m') hTxDiversityNewHARQProcess.m>
%% Selected Bibliography
% # 3GPP TS 36.101
displayEndOfDemoMessage(mfilename)

@ -1,27 +0,0 @@
clear
enbConfig=struct('NCellID',0,'CyclicPrefix','Normal','CellRefP',1);
pdschConfig=struct('Modulation','64QAM','RV',1,'TxScheme','Port0','NTurboDecIts',10);
addpath('../../build/srslte/lib/phch/test')
TBs=18336;
i=1;
e_bits=3450*6;
error=zeros(size(TBs));
for i=1:length(TBs)
trblkin=randi(2,TBs(i),1)-1;
[mat, info]=lteDLSCH(enbConfig,pdschConfig,e_bits,trblkin);
lib=srslte_dlsch_encode(enbConfig,pdschConfig,e_bits,trblkin);
error(i)=mean(abs(double(mat)-double(lib)));
end
if (length(TBs) == 1)
disp(info)
disp(error)
n=1:length(mat);
plot(abs(double(mat)-double(lib)))
else
plot(error)
end

@ -1,184 +0,0 @@
%% LTE Downlink Channel Estimation and Equalization
%% Cell-Wide Settings
clear
plot_noise_estimation_only=false;
SNR_values_db=100;%linspace(0,30,5);
Nrealizations=1;
w1=1/3;
%% UE Configuration
ue = lteRMCUL('A3-5');
ue.TotSubframes = 2;
K=ue.NULRB*12;
P=K/6;
%% Channel Model Configuration
chs.Seed = 1; % Random channel seed
chs.InitTime = 0;
chs.NRxAnts = 1; % 1 receive antenna
chs.DelayProfile = 'EVA';
chs.DopplerFreq = 300; % 120Hz Doppler frequency
chs.MIMOCorrelation = 'Low'; % Low (no) MIMO correlation
chs.NTerms = 16; % Oscillators used in fading model
chs.ModelType = 'GMEDS'; % Rayleigh fading model type
chs.InitPhase = 'Random'; % Random initial phases
chs.NormalizePathGains = 'On'; % Normalize delay profile power
chs.NormalizeTxAnts = 'On'; % Normalize for transmit antennas
%% Channel Estimator Configuration
cec = struct; % Channel estimation config structure
cec.PilotAverage = 'UserDefined'; % Type of pilot symbol averaging
cec.FreqWindow = 9; % Frequency window size
cec.TimeWindow = 9; % Time window size
cec.InterpType = 'Linear'; % 2D interpolation type
cec.InterpWindow = 'Causal'; % Interpolation window type
cec.InterpWinSize = 1; % Interpolation window size
%% Allocate memory
Ntests=3;
hest=cell(1,Ntests);
for i=1:Ntests
hest{i}=zeros(K,14);
end
MSE=zeros(Ntests,Nrealizations,length(SNR_values_db));
noiseEst=zeros(Ntests,Nrealizations,length(SNR_values_db));
legends={'matlab','ls',num2str(w1)};
colors={'bo-','rx-','m*-','k+-','c+-'};
colors2={'b-','r-','m-','k-','c-'};
addpath('../../debug/srslte/lib/ch_estimation/test')
offset = -1;
for nreal=1:Nrealizations
%% Signal Generation
[txWaveform, txGrid, info] = lteRMCULTool(ue,[1;0;0;1]);
%% SNR Configuration
for snr_idx=1:length(SNR_values_db)
SNRdB = SNR_values_db(snr_idx); % Desired SNR in dB
SNR = 10^(SNRdB/20); % Linear SNR
fprintf('SNR=%.1f dB\n',SNRdB)
%% Fading Channel
chs.SamplingRate = info.SamplingRate;
[rxWaveform, chinfo] = lteFadingChannel(chs,txWaveform);
%% Additive Noise
% Calculate noise gain
N0 = 1/(sqrt(2.0*double(info.Nfft))*SNR);
% Create additive white Gaussian noise
noise = N0*complex(randn(size(rxWaveform)),randn(size(rxWaveform)));
% Add noise to the received time domain waveform
rxWaveform = rxWaveform + noise;
%% Synchronization
% Time offset estimation is done once because depends on channel
% model only
if (offset==-1)
offset = lteULFrameOffset(ue,ue.PUSCH,rxWaveform);
end
rxWaveform = rxWaveform(1+offset:end);
%% OFDM Demodulation
rxGrid = lteSCFDMADemodulate(ue,rxWaveform);
rxGrid = rxGrid(:,1:14);
%% Perfect channel estimate
h=lteULPerfectChannelEstimate(ue,chs,offset);
h=h(:,1:14);
%% Channel Estimation with Matlab
[hest{1}, noiseEst(1,nreal,snr_idx)] = lteULChannelEstimate(ue,ue.PUSCH,cec,rxGrid);
%% LS-Linear estimation with srsLTE
[hest{2}, noiseEst(2,nreal,snr_idx)] = srslte_chest_ul(ue,ue.PUSCH,rxGrid);
%% LS-Linear estimation + averaging with srsLTE
[hest{3}, noiseEst(3,nreal,snr_idx)] = srslte_chest_ul(ue,ue.PUSCH,rxGrid,w1);
%% Compute MSE
for i=1:Ntests
MSE(i,nreal,snr_idx)=mean(mean(abs(h-hest{i}).^2));
fprintf('MSE test %d: %f\n',i, 10*log10(MSE(i,nreal,snr_idx)));
end
%% Plot a single realization
if (length(SNR_values_db) == 1)
subplot(1,1,1)
sym=1;
n=1:(K*length(sym));
for i=1:Ntests
plot(n,abs(reshape(hest{i}(:,sym),1,[])),colors2{i});
hold on;
end
plot(n,abs(reshape(h(:,sym),1,[])),'k');
hold off;
tmp=cell(Ntests+1,1);
for i=1:Ntests
tmp{i}=legends{i};
end
tmp{Ntests+1}='Perfect';
legend(tmp)
xlabel('SNR (dB)')
ylabel('Channel Gain')
grid on;
end
end
end
%% Compute average MSE and noise estimation
mean_mse=mean(MSE,2);
mean_snr=10*log10(1./mean(noiseEst,2));
%disp(mean_snr(3)
%% Plot average over all SNR values
if (length(SNR_values_db) > 1)
subplot(1,2,1)
for i=1:Ntests
plot(SNR_values_db, 10*log10(mean_mse(i,:)),colors{i})
hold on;
end
hold off;
legend(legends);
grid on
xlabel('SNR (dB)')
ylabel('MSE (dB)')
subplot(1,2,2)
plot(SNR_values_db, SNR_values_db,'k:')
hold on;
for i=1:Ntests
plot(SNR_values_db, mean_snr(i,:), colors{i})
end
hold off
tmp=cell(Ntests+1,1);
tmp{1}='Theory';
for i=2:Ntests+1
tmp{i}=legends{i-1};
end
legend(tmp)
grid on
xlabel('SNR (dB)')
ylabel('Estimated SNR (dB)')
end

@ -1,52 +0,0 @@
ueConfig=struct('CyclicPrefixUL','Normal','NTxAnts',1,'NULRB',6);
puschConfig=struct('NLayers',1,'OrthCover','Off');
addpath('../../debug/lte/phy/lib/ch_estimation/test')
Hopping={'Off','Sequence','Group'};
k=1;
for prb=4
for ncell=1
for ns=8
for h=1
for sg=0
for cs=0
for ds=0
ueConfig.NCellID=ncell;
ueConfig.NSubframe=ns;
ueConfig.Hopping=Hopping{h};
ueConfig.SeqGroup=sg;
ueConfig.CyclicShift=cs;
puschConfig.PRBSet=(1:4)';
puschConfig.DynCyclicShift=ds;
[mat, info]=ltePUSCHDRS(ueConfig,puschConfig);
ind=ltePUSCHDRSIndices(ueConfig, puschConfig);
subframe_mat = lteULResourceGrid(ueConfig);
subframe_mat(ind)=mat;
subframe_lib=srslte_refsignal_pusch(ueConfig,puschConfig);
error(k)=mean(abs(subframe_mat(:)-subframe_lib(:)));
disp(error(k))
if (error(k) > 10^-3)
k=1;
end
k=k+1;
end
end
end
end
end
end
end
plot(error);
disp(info)
disp(length(subframe_mat))
n=1:length(subframe_mat(:));
%plot(n,real(subframe_mat(:)),n,real(subframe_lib(:)))
plot(abs(subframe_mat(:)-subframe_lib(:)))

@ -1,277 +0,0 @@
%% LTE Downlink Channel Estimation and Equalization
%% Cell-Wide Settings
clear
plot_noise_estimation_only=false;
SNR_values_db=linspace(0,30,8);
Nrealizations=10;
w1=0.1;
w2=0.2;
enb.NDLRB = 6; % Number of resource blocks
enb.CellRefP = 1; % One transmit antenna port
enb.NCellID = 0; % Cell ID
enb.CyclicPrefix = 'Normal'; % Normal cyclic prefix
enb.DuplexMode = 'FDD'; % FDD
K=enb.NDLRB*12;
P=K/6;
%% Channel Model Configuration
cfg.Seed = 0; % Random channel seed
cfg.InitTime = 0;
cfg.NRxAnts = 1; % 1 receive antenna
cfg.DelayProfile = 'EVA';
% doppler 5, 70 300
cfg.DopplerFreq = 5; % 120Hz Doppler frequency
cfg.MIMOCorrelation = 'Low'; % Low (no) MIMO correlation
cfg.NTerms = 16; % Oscillators used in fading model
cfg.ModelType = 'GMEDS'; % Rayleigh fading model type
cfg.InitPhase = 'Random'; % Random initial phases
cfg.NormalizePathGains = 'On'; % Normalize delay profile power
cfg.NormalizeTxAnts = 'On'; % Normalize for transmit antennas
%% Channel Estimator Configuration
cec = struct; % Channel estimation config structure
cec.PilotAverage = 'UserDefined'; % Type of pilot symbol averaging
cec.FreqWindow = 9; % Frequency window size
cec.TimeWindow = 9; % Time window size
cec.InterpType = 'Linear'; % 2D interpolation type
cec.InterpWindow = 'Causal'; % Interpolation window type
cec.InterpWinSize = 1; % Interpolation window size
%% Subframe Resource Grid Size
gridsize = lteDLResourceGridSize(enb);
Ks = gridsize(1); % Number of subcarriers
L = gridsize(2); % Number of OFDM symbols in one subframe
Ports = gridsize(3); % Number of transmit antenna ports
%% Allocate memory
Ntests=4;
hest=cell(1,Ntests);
tmpnoise=cell(1,Ntests);
for i=1:Ntests
hest{i}=zeros(K,140);
tmpnoise{i}=zeros(1,10);
end
hls=zeros(4,4*P*10);
MSE=zeros(Ntests,Nrealizations,length(SNR_values_db));
noiseEst=zeros(Ntests,Nrealizations,length(SNR_values_db));
legends={'matlab','ls',num2str(w1),num2str(w2)};
colors={'bo-','rx-','m*-','k+-','c+-'};
colors2={'b-','r-','m-','k-','c-'};
addpath('../../build/srslte/lib/ch_estimation/test')
offset=-1;
for nreal=1:Nrealizations
%% Transmit Resource Grid
txGrid = [];
%% Payload Data Generation
% Number of bits needed is size of resource grid (K*L*P) * number of bits
% per symbol (2 for QPSK)
numberOfBits = Ks*L*Ports*2;
% Create random bit stream
inputBits = randi([0 1], numberOfBits, 1);
% Modulate input bits
inputSym = lteSymbolModulate(inputBits,'QPSK');
%% Frame Generation
% For all subframes within the frame
for sf = 0:10
% Set subframe number
enb.NSubframe = mod(sf,10);
% Generate empty subframe
subframe = lteDLResourceGrid(enb);
% Map input symbols to grid
subframe(:) = inputSym;
% Generate synchronizing signals
pssSym = ltePSS(enb);
sssSym = lteSSS(enb);
pssInd = ltePSSIndices(enb);
sssInd = lteSSSIndices(enb);
% Map synchronizing signals to the grid
subframe(pssInd) = pssSym;
subframe(sssInd) = sssSym;
% Generate cell specific reference signal symbols and indices
cellRsSym = lteCellRS(enb);
cellRsInd = lteCellRSIndices(enb);
% Map cell specific reference signal to grid
subframe(cellRsInd) = cellRsSym;
% Append subframe to grid to be transmitted
txGrid = [txGrid subframe]; %#ok
end
txGrid([1:5 68:72],6:7) = ones(10,2);
%% OFDM Modulation
[txWaveform,info] = lteOFDMModulate(enb,txGrid);
txGrid = txGrid(:,1:140);
%% SNR Configuration
for snr_idx=1:length(SNR_values_db)
SNRdB = SNR_values_db(snr_idx); % Desired SNR in dB
SNR = 10^(SNRdB/20); % Linear SNR
fprintf('SNR=%.1f dB\n',SNRdB)
%% Fading Channel
cfg.SamplingRate = info.SamplingRate;
[rxWaveform, chinfo] = lteFadingChannel(cfg,txWaveform);
%% Additive Noise
% Calculate noise gain
N0 = 1/(sqrt(2.0*enb.CellRefP*double(info.Nfft))*SNR);
% Create additive white Gaussian noise
noise = N0*complex(randn(size(rxWaveform)),randn(size(rxWaveform)));
% Add noise to the received time domain waveform
rxWaveform_nonoise = rxWaveform;
rxWaveform = rxWaveform + noise;
%% Synchronization
if (offset==-1)
offset = lteDLFrameOffset(enb,rxWaveform);
end
rxWaveform = rxWaveform(1+offset:end,:);
rxWaveform_nonoise = rxWaveform_nonoise(1+offset:end,:);
%% OFDM Demodulation
rxGrid = lteOFDMDemodulate(enb,rxWaveform);
rxGrid = rxGrid(:,1:140);
rxGrid_nonoise = lteOFDMDemodulate(enb,rxWaveform_nonoise);
rxGrid_nonoise = rxGrid_nonoise(:,1:140);
% True channel
h=rxGrid_nonoise./(txGrid);
for i=1:10
enb.NSubframe=i-1;
rxGrid_sf = rxGrid(:,(i-1)*14+1:i*14);
%% Channel Estimation with Matlab
[hest{1}(:,(1:14)+(i-1)*14), tmpnoise{1}(i)] = ...
lteDLChannelEstimate(enb,cec,rxGrid_sf);
tmpnoise{1}(i)=tmpnoise{1}(i)*sqrt(2)*enb.CellRefP;
%% LS-Linear estimation with srsLTE
[hest{2}(:,(1:14)+(i-1)*14), tmpnoise{2}(i)] = srslte_chest_dl(enb,rxGrid_sf);
%% LS-Linear + averaging with srsLTE
[hest{3}(:,(1:14)+(i-1)*14), tmpnoise{3}(i)] = srslte_chest_dl(enb,rxGrid_sf,w1);
%% LS-Linear + more averaging with srsLTE
[hest{4}(:,(1:14)+(i-1)*14), tmpnoise{4}(i)] = srslte_chest_dl(enb,rxGrid_sf,w2);
end
%% Average noise estimates over all frame
for i=1:Ntests
noiseEst(i,nreal,snr_idx)=mean(tmpnoise{i});
end
%% Compute MSE
for i=1:Ntests
MSE(i,nreal,snr_idx)=mean(mean(abs(h-hest{i}).^2));
fprintf('MSE test %d: %f\n',i, 10*log10(MSE(i,nreal,snr_idx)));
end
%% Plot a single realization
if (length(SNR_values_db) == 1)
sym=1;
ref_idx=1:P;
ref_idx_x=[1:6:K];% (292:6:360)-216];% 577:6:648];
n=1:(K*length(sym));
for i=1:Ntests
plot(n,abs(reshape(hest{i}(:,sym),1,[])),colors2{i});
hold on;
end
plot(n, abs(h(:,sym)),'g-')
% plot(ref_idx_x,real(hls(3,ref_idx)),'ro');
hold off;
tmp=cell(Ntests+1,1);
for i=1:Ntests
tmp{i}=legends{i};
end
tmp{Ntests+1}='Real';
legend(tmp)
xlabel('SNR (dB)')
ylabel('Channel Gain')
grid on;
fprintf('Mean MMSE Robust %.2f dB\n', 10*log10(MSE(4,nreal,snr_idx)))
fprintf('Mean MMSE matlab %.2f dB\n', 10*log10(MSE(1,nreal,snr_idx)))
end
end
end
%% Compute average MSE and noise estimation
mean_mse=mean(MSE,2);
mean_snr=10*log10(1./mean(noiseEst,2));
%% Plot average over all SNR values
if (length(SNR_values_db) > 1)
subplot(1,2,1)
for i=1:Ntests
plot(SNR_values_db, 10*log10(mean_mse(i,:)),colors{i})
hold on;
end
hold off;
legend(legends);
grid on
xlabel('SNR (dB)')
ylabel('MSE (dB)')
subplot(1,2,2)
plot(SNR_values_db, SNR_values_db,'k:')
hold on;
for i=1:Ntests
plot(SNR_values_db, mean_snr(i,:), colors{i})
end
hold off
tmp=cell(Ntests+1,1);
tmp{1}='Theory';
for i=2:Ntests+1
tmp{i}=legends{i-1};
end
legend(tmp)
grid on
xlabel('SNR (dB)')
ylabel('Estimated SNR (dB)')
end

@ -1,111 +0,0 @@
function [ s, c0, c1 ] = get_sc( N_id_2 )
if (N_id_2 == 0)
s(1,:)=[1, 1, 1, 1, -1, 1, 1, -1, 1, -1, -1, 1, 1, -1, -1, -1, -1, -1, 1, 1, 1, -1, -1, 1, -1, -1, -1, 1, -1, 1, -1, ];
s(2,:)=[1, 1, 1, -1, 1, 1, -1, 1, -1, -1, 1, 1, -1, -1, -1, -1, -1, 1, 1, 1, -1, -1, 1, -1, -1, -1, 1, -1, 1, -1, 1, ];
s(3,:)=[1, 1, -1, 1, 1, -1, 1, -1, -1, 1, 1, -1, -1, -1, -1, -1, 1, 1, 1, -1, -1, 1, -1, -1, -1, 1, -1, 1, -1, 1, 1, ];
s(4,:)=[1, -1, 1, 1, -1, 1, -1, -1, 1, 1, -1, -1, -1, -1, -1, 1, 1, 1, -1, -1, 1, -1, -1, -1, 1, -1, 1, -1, 1, 1, 1, ];
s(5,:)=[-1, 1, 1, -1, 1, -1, -1, 1, 1, -1, -1, -1, -1, -1, 1, 1, 1, -1, -1, 1, -1, -1, -1, 1, -1, 1, -1, 1, 1, 1, 1, ];
s(6,:)=[1, 1, -1, 1, -1, -1, 1, 1, -1, -1, -1, -1, -1, 1, 1, 1, -1, -1, 1, -1, -1, -1, 1, -1, 1, -1, 1, 1, 1, 1, -1, ];
s(7,:)=[1, -1, 1, -1, -1, 1, 1, -1, -1, -1, -1, -1, 1, 1, 1, -1, -1, 1, -1, -1, -1, 1, -1, 1, -1, 1, 1, 1, 1, -1, 1, ];
s(8,:)=[-1, 1, -1, -1, 1, 1, -1, -1, -1, -1, -1, 1, 1, 1, -1, -1, 1, -1, -1, -1, 1, -1, 1, -1, 1, 1, 1, 1, -1, 1, 1, ];
s(9,:)=[1, -1, -1, 1, 1, -1, -1, -1, -1, -1, 1, 1, 1, -1, -1, 1, -1, -1, -1, 1, -1, 1, -1, 1, 1, 1, 1, -1, 1, 1, -1, ];
s(10,:)=[-1, -1, 1, 1, -1, -1, -1, -1, -1, 1, 1, 1, -1, -1, 1, -1, -1, -1, 1, -1, 1, -1, 1, 1, 1, 1, -1, 1, 1, -1, 1, ];
s(11,:)=[-1, 1, 1, -1, -1, -1, -1, -1, 1, 1, 1, -1, -1, 1, -1, -1, -1, 1, -1, 1, -1, 1, 1, 1, 1, -1, 1, 1, -1, 1, -1, ];
s(12,:)=[1, 1, -1, -1, -1, -1, -1, 1, 1, 1, -1, -1, 1, -1, -1, -1, 1, -1, 1, -1, 1, 1, 1, 1, -1, 1, 1, -1, 1, -1, -1, ];
s(13,:)=[1, -1, -1, -1, -1, -1, 1, 1, 1, -1, -1, 1, -1, -1, -1, 1, -1, 1, -1, 1, 1, 1, 1, -1, 1, 1, -1, 1, -1, -1, 1, ];
s(14,:)=[-1, -1, -1, -1, -1, 1, 1, 1, -1, -1, 1, -1, -1, -1, 1, -1, 1, -1, 1, 1, 1, 1, -1, 1, 1, -1, 1, -1, -1, 1, 1, ];
s(15,:)=[-1, -1, -1, -1, 1, 1, 1, -1, -1, 1, -1, -1, -1, 1, -1, 1, -1, 1, 1, 1, 1, -1, 1, 1, -1, 1, -1, -1, 1, 1, -1, ];
s(16,:)=[-1, -1, -1, 1, 1, 1, -1, -1, 1, -1, -1, -1, 1, -1, 1, -1, 1, 1, 1, 1, -1, 1, 1, -1, 1, -1, -1, 1, 1, -1, -1, ];
s(17,:)=[-1, -1, 1, 1, 1, -1, -1, 1, -1, -1, -1, 1, -1, 1, -1, 1, 1, 1, 1, -1, 1, 1, -1, 1, -1, -1, 1, 1, -1, -1, -1, ];
s(18,:)=[-1, 1, 1, 1, -1, -1, 1, -1, -1, -1, 1, -1, 1, -1, 1, 1, 1, 1, -1, 1, 1, -1, 1, -1, -1, 1, 1, -1, -1, -1, -1, ];
s(19,:)=[1, 1, 1, -1, -1, 1, -1, -1, -1, 1, -1, 1, -1, 1, 1, 1, 1, -1, 1, 1, -1, 1, -1, -1, 1, 1, -1, -1, -1, -1, -1, ];
s(20,:)=[1, 1, -1, -1, 1, -1, -1, -1, 1, -1, 1, -1, 1, 1, 1, 1, -1, 1, 1, -1, 1, -1, -1, 1, 1, -1, -1, -1, -1, -1, 1, ];
s(21,:)=[1, -1, -1, 1, -1, -1, -1, 1, -1, 1, -1, 1, 1, 1, 1, -1, 1, 1, -1, 1, -1, -1, 1, 1, -1, -1, -1, -1, -1, 1, 1, ];
s(22,:)=[-1, -1, 1, -1, -1, -1, 1, -1, 1, -1, 1, 1, 1, 1, -1, 1, 1, -1, 1, -1, -1, 1, 1, -1, -1, -1, -1, -1, 1, 1, 1, ];
s(23,:)=[-1, 1, -1, -1, -1, 1, -1, 1, -1, 1, 1, 1, 1, -1, 1, 1, -1, 1, -1, -1, 1, 1, -1, -1, -1, -1, -1, 1, 1, 1, -1, ];
s(24,:)=[1, -1, -1, -1, 1, -1, 1, -1, 1, 1, 1, 1, -1, 1, 1, -1, 1, -1, -1, 1, 1, -1, -1, -1, -1, -1, 1, 1, 1, -1, -1, ];
s(25,:)=[-1, -1, -1, 1, -1, 1, -1, 1, 1, 1, 1, -1, 1, 1, -1, 1, -1, -1, 1, 1, -1, -1, -1, -1, -1, 1, 1, 1, -1, -1, 1, ];
s(26,:)=[-1, -1, 1, -1, 1, -1, 1, 1, 1, 1, -1, 1, 1, -1, 1, -1, -1, 1, 1, -1, -1, -1, -1, -1, 1, 1, 1, -1, -1, 1, -1, ];
s(27,:)=[-1, 1, -1, 1, -1, 1, 1, 1, 1, -1, 1, 1, -1, 1, -1, -1, 1, 1, -1, -1, -1, -1, -1, 1, 1, 1, -1, -1, 1, -1, -1, ];
s(28,:)=[1, -1, 1, -1, 1, 1, 1, 1, -1, 1, 1, -1, 1, -1, -1, 1, 1, -1, -1, -1, -1, -1, 1, 1, 1, -1, -1, 1, -1, -1, -1, ];
s(29,:)=[-1, 1, -1, 1, 1, 1, 1, -1, 1, 1, -1, 1, -1, -1, 1, 1, -1, -1, -1, -1, -1, 1, 1, 1, -1, -1, 1, -1, -1, -1, 1, ];
s(30,:)=[1, -1, 1, 1, 1, 1, -1, 1, 1, -1, 1, -1, -1, 1, 1, -1, -1, -1, -1, -1, 1, 1, 1, -1, -1, 1, -1, -1, -1, 1, -1, ];
s(31,:)=[-1, 1, 1, 1, 1, -1, 1, 1, -1, 1, -1, -1, 1, 1, -1, -1, -1, -1, -1, 1, 1, 1, -1, -1, 1, -1, -1, -1, 1, -1, 1, ];
c0=[1, 1, 1, 1, -1, 1, -1, 1, -1, -1, -1, 1, -1, -1, 1, 1, 1, -1, -1, -1, -1, -1, 1, 1, -1, -1, 1, -1, 1, 1, -1, ];
c1=[1, -1, 1, -1, 1, -1, -1, -1, 1, -1, -1, 1, 1, 1, -1, -1, -1, -1, -1, 1, 1, -1, -1, 1, -1, 1, 1, -1, 1, 1, 1, ];
elseif (N_id_2 == 1)
s(1,:)=[1, 1, 1, 1, -1, 1, 1, -1, 1, -1, -1, 1, 1, -1, -1, -1, -1, -1, 1, 1, 1, -1, -1, 1, -1, -1, -1, 1, -1, 1, -1, ];
s(2,:)=[1, 1, 1, -1, 1, 1, -1, 1, -1, -1, 1, 1, -1, -1, -1, -1, -1, 1, 1, 1, -1, -1, 1, -1, -1, -1, 1, -1, 1, -1, 1, ];
s(3,:)=[1, 1, -1, 1, 1, -1, 1, -1, -1, 1, 1, -1, -1, -1, -1, -1, 1, 1, 1, -1, -1, 1, -1, -1, -1, 1, -1, 1, -1, 1, 1, ];
s(4,:)=[1, -1, 1, 1, -1, 1, -1, -1, 1, 1, -1, -1, -1, -1, -1, 1, 1, 1, -1, -1, 1, -1, -1, -1, 1, -1, 1, -1, 1, 1, 1, ];
s(5,:)=[-1, 1, 1, -1, 1, -1, -1, 1, 1, -1, -1, -1, -1, -1, 1, 1, 1, -1, -1, 1, -1, -1, -1, 1, -1, 1, -1, 1, 1, 1, 1, ];
s(6,:)=[1, 1, -1, 1, -1, -1, 1, 1, -1, -1, -1, -1, -1, 1, 1, 1, -1, -1, 1, -1, -1, -1, 1, -1, 1, -1, 1, 1, 1, 1, -1, ];
s(7,:)=[1, -1, 1, -1, -1, 1, 1, -1, -1, -1, -1, -1, 1, 1, 1, -1, -1, 1, -1, -1, -1, 1, -1, 1, -1, 1, 1, 1, 1, -1, 1, ];
s(8,:)=[-1, 1, -1, -1, 1, 1, -1, -1, -1, -1, -1, 1, 1, 1, -1, -1, 1, -1, -1, -1, 1, -1, 1, -1, 1, 1, 1, 1, -1, 1, 1, ];
s(9,:)=[1, -1, -1, 1, 1, -1, -1, -1, -1, -1, 1, 1, 1, -1, -1, 1, -1, -1, -1, 1, -1, 1, -1, 1, 1, 1, 1, -1, 1, 1, -1, ];
s(10,:)=[-1, -1, 1, 1, -1, -1, -1, -1, -1, 1, 1, 1, -1, -1, 1, -1, -1, -1, 1, -1, 1, -1, 1, 1, 1, 1, -1, 1, 1, -1, 1, ];
s(11,:)=[-1, 1, 1, -1, -1, -1, -1, -1, 1, 1, 1, -1, -1, 1, -1, -1, -1, 1, -1, 1, -1, 1, 1, 1, 1, -1, 1, 1, -1, 1, -1, ];
s(12,:)=[1, 1, -1, -1, -1, -1, -1, 1, 1, 1, -1, -1, 1, -1, -1, -1, 1, -1, 1, -1, 1, 1, 1, 1, -1, 1, 1, -1, 1, -1, -1, ];
s(13,:)=[1, -1, -1, -1, -1, -1, 1, 1, 1, -1, -1, 1, -1, -1, -1, 1, -1, 1, -1, 1, 1, 1, 1, -1, 1, 1, -1, 1, -1, -1, 1, ];
s(14,:)=[-1, -1, -1, -1, -1, 1, 1, 1, -1, -1, 1, -1, -1, -1, 1, -1, 1, -1, 1, 1, 1, 1, -1, 1, 1, -1, 1, -1, -1, 1, 1, ];
s(15,:)=[-1, -1, -1, -1, 1, 1, 1, -1, -1, 1, -1, -1, -1, 1, -1, 1, -1, 1, 1, 1, 1, -1, 1, 1, -1, 1, -1, -1, 1, 1, -1, ];
s(16,:)=[-1, -1, -1, 1, 1, 1, -1, -1, 1, -1, -1, -1, 1, -1, 1, -1, 1, 1, 1, 1, -1, 1, 1, -1, 1, -1, -1, 1, 1, -1, -1, ];
s(17,:)=[-1, -1, 1, 1, 1, -1, -1, 1, -1, -1, -1, 1, -1, 1, -1, 1, 1, 1, 1, -1, 1, 1, -1, 1, -1, -1, 1, 1, -1, -1, -1, ];
s(18,:)=[-1, 1, 1, 1, -1, -1, 1, -1, -1, -1, 1, -1, 1, -1, 1, 1, 1, 1, -1, 1, 1, -1, 1, -1, -1, 1, 1, -1, -1, -1, -1, ];
s(19,:)=[1, 1, 1, -1, -1, 1, -1, -1, -1, 1, -1, 1, -1, 1, 1, 1, 1, -1, 1, 1, -1, 1, -1, -1, 1, 1, -1, -1, -1, -1, -1, ];
s(20,:)=[1, 1, -1, -1, 1, -1, -1, -1, 1, -1, 1, -1, 1, 1, 1, 1, -1, 1, 1, -1, 1, -1, -1, 1, 1, -1, -1, -1, -1, -1, 1, ];
s(21,:)=[1, -1, -1, 1, -1, -1, -1, 1, -1, 1, -1, 1, 1, 1, 1, -1, 1, 1, -1, 1, -1, -1, 1, 1, -1, -1, -1, -1, -1, 1, 1, ];
s(22,:)=[-1, -1, 1, -1, -1, -1, 1, -1, 1, -1, 1, 1, 1, 1, -1, 1, 1, -1, 1, -1, -1, 1, 1, -1, -1, -1, -1, -1, 1, 1, 1, ];
s(23,:)=[-1, 1, -1, -1, -1, 1, -1, 1, -1, 1, 1, 1, 1, -1, 1, 1, -1, 1, -1, -1, 1, 1, -1, -1, -1, -1, -1, 1, 1, 1, -1, ];
s(24,:)=[1, -1, -1, -1, 1, -1, 1, -1, 1, 1, 1, 1, -1, 1, 1, -1, 1, -1, -1, 1, 1, -1, -1, -1, -1, -1, 1, 1, 1, -1, -1, ];
s(25,:)=[-1, -1, -1, 1, -1, 1, -1, 1, 1, 1, 1, -1, 1, 1, -1, 1, -1, -1, 1, 1, -1, -1, -1, -1, -1, 1, 1, 1, -1, -1, 1, ];
s(26,:)=[-1, -1, 1, -1, 1, -1, 1, 1, 1, 1, -1, 1, 1, -1, 1, -1, -1, 1, 1, -1, -1, -1, -1, -1, 1, 1, 1, -1, -1, 1, -1, ];
s(27,:)=[-1, 1, -1, 1, -1, 1, 1, 1, 1, -1, 1, 1, -1, 1, -1, -1, 1, 1, -1, -1, -1, -1, -1, 1, 1, 1, -1, -1, 1, -1, -1, ];
s(28,:)=[1, -1, 1, -1, 1, 1, 1, 1, -1, 1, 1, -1, 1, -1, -1, 1, 1, -1, -1, -1, -1, -1, 1, 1, 1, -1, -1, 1, -1, -1, -1, ];
s(29,:)=[-1, 1, -1, 1, 1, 1, 1, -1, 1, 1, -1, 1, -1, -1, 1, 1, -1, -1, -1, -1, -1, 1, 1, 1, -1, -1, 1, -1, -1, -1, 1, ];
s(30,:)=[1, -1, 1, 1, 1, 1, -1, 1, 1, -1, 1, -1, -1, 1, 1, -1, -1, -1, -1, -1, 1, 1, 1, -1, -1, 1, -1, -1, -1, 1, -1, ];
s(31,:)=[-1, 1, 1, 1, 1, -1, 1, 1, -1, 1, -1, -1, 1, 1, -1, -1, -1, -1, -1, 1, 1, 1, -1, -1, 1, -1, -1, -1, 1, -1, 1, ];
c0=[1, 1, 1, -1, 1, -1, 1, -1, -1, -1, 1, -1, -1, 1, 1, 1, -1, -1, -1, -1, -1, 1, 1, -1, -1, 1, -1, 1, 1, -1, 1, ];
c1=[-1, 1, -1, 1, -1, -1, -1, 1, -1, -1, 1, 1, 1, -1, -1, -1, -1, -1, 1, 1, -1, -1, 1, -1, 1, 1, -1, 1, 1, 1, 1, ];
else
s(1,:)=[1, 1, 1, 1, -1, 1, 1, -1, 1, -1, -1, 1, 1, -1, -1, -1, -1, -1, 1, 1, 1, -1, -1, 1, -1, -1, -1, 1, -1, 1, -1, ];
s(2,:)=[1, 1, 1, -1, 1, 1, -1, 1, -1, -1, 1, 1, -1, -1, -1, -1, -1, 1, 1, 1, -1, -1, 1, -1, -1, -1, 1, -1, 1, -1, 1, ];
s(3,:)=[1, 1, -1, 1, 1, -1, 1, -1, -1, 1, 1, -1, -1, -1, -1, -1, 1, 1, 1, -1, -1, 1, -1, -1, -1, 1, -1, 1, -1, 1, 1, ];
s(4,:)=[1, -1, 1, 1, -1, 1, -1, -1, 1, 1, -1, -1, -1, -1, -1, 1, 1, 1, -1, -1, 1, -1, -1, -1, 1, -1, 1, -1, 1, 1, 1, ];
s(5,:)=[-1, 1, 1, -1, 1, -1, -1, 1, 1, -1, -1, -1, -1, -1, 1, 1, 1, -1, -1, 1, -1, -1, -1, 1, -1, 1, -1, 1, 1, 1, 1, ];
s(6,:)=[1, 1, -1, 1, -1, -1, 1, 1, -1, -1, -1, -1, -1, 1, 1, 1, -1, -1, 1, -1, -1, -1, 1, -1, 1, -1, 1, 1, 1, 1, -1, ];
s(7,:)=[1, -1, 1, -1, -1, 1, 1, -1, -1, -1, -1, -1, 1, 1, 1, -1, -1, 1, -1, -1, -1, 1, -1, 1, -1, 1, 1, 1, 1, -1, 1, ];
s(8,:)=[-1, 1, -1, -1, 1, 1, -1, -1, -1, -1, -1, 1, 1, 1, -1, -1, 1, -1, -1, -1, 1, -1, 1, -1, 1, 1, 1, 1, -1, 1, 1, ];
s(9,:)=[1, -1, -1, 1, 1, -1, -1, -1, -1, -1, 1, 1, 1, -1, -1, 1, -1, -1, -1, 1, -1, 1, -1, 1, 1, 1, 1, -1, 1, 1, -1, ];
s(10,:)=[-1, -1, 1, 1, -1, -1, -1, -1, -1, 1, 1, 1, -1, -1, 1, -1, -1, -1, 1, -1, 1, -1, 1, 1, 1, 1, -1, 1, 1, -1, 1, ];
s(11,:)=[-1, 1, 1, -1, -1, -1, -1, -1, 1, 1, 1, -1, -1, 1, -1, -1, -1, 1, -1, 1, -1, 1, 1, 1, 1, -1, 1, 1, -1, 1, -1, ];
s(12,:)=[1, 1, -1, -1, -1, -1, -1, 1, 1, 1, -1, -1, 1, -1, -1, -1, 1, -1, 1, -1, 1, 1, 1, 1, -1, 1, 1, -1, 1, -1, -1, ];
s(13,:)=[1, -1, -1, -1, -1, -1, 1, 1, 1, -1, -1, 1, -1, -1, -1, 1, -1, 1, -1, 1, 1, 1, 1, -1, 1, 1, -1, 1, -1, -1, 1, ];
s(14,:)=[-1, -1, -1, -1, -1, 1, 1, 1, -1, -1, 1, -1, -1, -1, 1, -1, 1, -1, 1, 1, 1, 1, -1, 1, 1, -1, 1, -1, -1, 1, 1, ];
s(15,:)=[-1, -1, -1, -1, 1, 1, 1, -1, -1, 1, -1, -1, -1, 1, -1, 1, -1, 1, 1, 1, 1, -1, 1, 1, -1, 1, -1, -1, 1, 1, -1, ];
s(16,:)=[-1, -1, -1, 1, 1, 1, -1, -1, 1, -1, -1, -1, 1, -1, 1, -1, 1, 1, 1, 1, -1, 1, 1, -1, 1, -1, -1, 1, 1, -1, -1, ];
s(17,:)=[-1, -1, 1, 1, 1, -1, -1, 1, -1, -1, -1, 1, -1, 1, -1, 1, 1, 1, 1, -1, 1, 1, -1, 1, -1, -1, 1, 1, -1, -1, -1, ];
s(18,:)=[-1, 1, 1, 1, -1, -1, 1, -1, -1, -1, 1, -1, 1, -1, 1, 1, 1, 1, -1, 1, 1, -1, 1, -1, -1, 1, 1, -1, -1, -1, -1, ];
s(19,:)=[1, 1, 1, -1, -1, 1, -1, -1, -1, 1, -1, 1, -1, 1, 1, 1, 1, -1, 1, 1, -1, 1, -1, -1, 1, 1, -1, -1, -1, -1, -1, ];
s(20,:)=[1, 1, -1, -1, 1, -1, -1, -1, 1, -1, 1, -1, 1, 1, 1, 1, -1, 1, 1, -1, 1, -1, -1, 1, 1, -1, -1, -1, -1, -1, 1, ];
s(21,:)=[1, -1, -1, 1, -1, -1, -1, 1, -1, 1, -1, 1, 1, 1, 1, -1, 1, 1, -1, 1, -1, -1, 1, 1, -1, -1, -1, -1, -1, 1, 1, ];
s(22,:)=[-1, -1, 1, -1, -1, -1, 1, -1, 1, -1, 1, 1, 1, 1, -1, 1, 1, -1, 1, -1, -1, 1, 1, -1, -1, -1, -1, -1, 1, 1, 1, ];
s(23,:)=[-1, 1, -1, -1, -1, 1, -1, 1, -1, 1, 1, 1, 1, -1, 1, 1, -1, 1, -1, -1, 1, 1, -1, -1, -1, -1, -1, 1, 1, 1, -1, ];
s(24,:)=[1, -1, -1, -1, 1, -1, 1, -1, 1, 1, 1, 1, -1, 1, 1, -1, 1, -1, -1, 1, 1, -1, -1, -1, -1, -1, 1, 1, 1, -1, -1, ];
s(25,:)=[-1, -1, -1, 1, -1, 1, -1, 1, 1, 1, 1, -1, 1, 1, -1, 1, -1, -1, 1, 1, -1, -1, -1, -1, -1, 1, 1, 1, -1, -1, 1, ];
s(26,:)=[-1, -1, 1, -1, 1, -1, 1, 1, 1, 1, -1, 1, 1, -1, 1, -1, -1, 1, 1, -1, -1, -1, -1, -1, 1, 1, 1, -1, -1, 1, -1, ];
s(27,:)=[-1, 1, -1, 1, -1, 1, 1, 1, 1, -1, 1, 1, -1, 1, -1, -1, 1, 1, -1, -1, -1, -1, -1, 1, 1, 1, -1, -1, 1, -1, -1, ];
s(28,:)=[1, -1, 1, -1, 1, 1, 1, 1, -1, 1, 1, -1, 1, -1, -1, 1, 1, -1, -1, -1, -1, -1, 1, 1, 1, -1, -1, 1, -1, -1, -1, ];
s(29,:)=[-1, 1, -1, 1, 1, 1, 1, -1, 1, 1, -1, 1, -1, -1, 1, 1, -1, -1, -1, -1, -1, 1, 1, 1, -1, -1, 1, -1, -1, -1, 1, ];
s(30,:)=[1, -1, 1, 1, 1, 1, -1, 1, 1, -1, 1, -1, -1, 1, 1, -1, -1, -1, -1, -1, 1, 1, 1, -1, -1, 1, -1, -1, -1, 1, -1, ];
s(31,:)=[-1, 1, 1, 1, 1, -1, 1, 1, -1, 1, -1, -1, 1, 1, -1, -1, -1, -1, -1, 1, 1, 1, -1, -1, 1, -1, -1, -1, 1, -1, 1, ];
c0=[1, 1, -1, 1, -1, 1, -1, -1, -1, 1, -1, -1, 1, 1, 1, -1, -1, -1, -1, -1, 1, 1, -1, -1, 1, -1, 1, 1, -1, 1, 1, ];
c1=[1, -1, 1, -1, -1, -1, 1, -1, -1, 1, 1, 1, -1, -1, -1, -1, -1, 1, 1, -1, -1, 1, -1, 1, 1, -1, 1, 1, 1, 1, -1, ];
end
end

@ -0,0 +1,84 @@
clear
addpath('../../debug/srslte/lib/mimo/test')
Nt=1;
Nr=1;
Nl=1;
Ncw=1;
txscheme='Port0';
codebook=0;
enb.NDLRB=6;
Ns=enb.NDLRB*12*14;
enb.CyclicPrefix='Normal';
enb.CellRefP=Nt;
enb.TotSubframes=1;
cfg.Seed = 1; % Random channel seed
cfg.NRxAnts = Nr; % 1 receive antenna
cfg.DelayProfile = 'ETU'; % EVA delay spread
cfg.DopplerFreq = 100; % 120Hz Doppler frequency
cfg.MIMOCorrelation = 'Low'; % Low (no) MIMO correlation
cfg.InitTime = 0; % Initialize at time zero
cfg.NTerms = 16; % Oscillators used in fading model
cfg.ModelType = 'GMEDS'; % Rayleigh fading model type
cfg.InitPhase = 'Random'; % Random initial phases
cfg.NormalizePathGains = 'On'; % Normalize delay profile power
cfg.NormalizeTxAnts = 'On'; % Normalize for transmit antennas
cec = struct('FreqWindow',9,'TimeWindow',9,'InterpType','cubic');
cec.PilotAverage = 'UserDefined';
cec.InterpWinSize = 1;
cec.InterpWindow = 'Causal';
sym = 2*rand(Ns*Nl,1)-1;
layermap = lteLayerMap(sym, Nl, txscheme);
tx = lteDLPrecode(layermap, Nt, txscheme, codebook);
tx_srs = srslte_precoder(sym, Nl, Nt, txscheme);
err_tx=mean(abs(tx_srs-tx).^2)
[txwaveform, info] = lteOFDMModulate(enb, reshape(tx,enb.NDLRB*12,[],Nt));
cfg.SamplingRate = info.SamplingRate;
rxwaveform = lteFadingChannel(cfg, txwaveform);
rxGrid = lteOFDMDemodulate(enb, rxwaveform);
h=lteDLPerfectChannelEstimate(enb, cfg);
hp=reshape(h,Ns,Nr,Nt);
rx=reshape(rxGrid,Ns,Nr);
if (Nt > 1)
if (strcmp(txscheme,'TxDiversity')==1)
output_mat = lteTransmitDiversityDecode(rx, hp);
elseif (strcmp(txscheme,'CDD')==1 || strcmp(txscheme,'SpatialMux')==1)
pdsch.NLayers=Nl;
pdsch.RNTI=0;
pdsch.TxScheme=txscheme;
pdsch.PMISet=codebook;
pdsch.NCodewords=Ncw;
deprecoded = lteEqualizeMIMO(enb,pdsch,rx,hp,0);
out_cw = lteLayerDemap(pdsch,deprecoded);
output_mat = [];
for i=1:Ncw
output_mat = [output_mat out_cw{i}];
end
else
error('Unsupported txscheme')
end
else
output_mat = lteEqualizeMMSE(rx, hp, 0);
end
output_srs = srslte_predecoder(rx, hp, 0, txscheme);
plot(abs(output_mat(:)-output_srs(:)))
mean(abs(output_mat(:)-output_srs(:)).^2)
t=1:100;
plot(t,real(output_mat(t)),t,real(output_srs(t)))

@ -1,130 +0,0 @@
clear
Nblock=[3];
SNR_values_db=100;%linspace(-4,0,6);
Nrealizations=1;
enb = struct('NCellID',62,'NDLRB',50,'CellRefP',2,'CyclicPrefix','Normal','DuplexMode','FDD',...
'NSubframe',0,'PHICHDuration','Normal','Ng','One','NFrame',101,'TotSubframes',40);
cfg.Seed = 8; % Random channel seed
cfg.NRxAnts = 1; % 1 receive antenna
cfg.DelayProfile = 'EPA'; % EVA delay spread
cfg.DopplerFreq = 5; % 120Hz Doppler frequency
cfg.MIMOCorrelation = 'Low'; % Low (no) MIMO correlation
cfg.InitTime = 0; % Initialize at time zero
cfg.NTerms = 16; % Oscillators used in fading model
cfg.ModelType = 'GMEDS'; % Rayleigh fading model type
cfg.InitPhase = 'Random'; % Random initial phases
cfg.NormalizePathGains = 'On'; % Normalize delay profile power
cfg.NormalizeTxAnts = 'On'; % Normalize for transmit antennas
cec.PilotAverage = 'UserDefined'; % Type of pilot averaging
cec.FreqWindow = 9; % Frequency window size
cec.TimeWindow = 9; % Time window size
cec.InterpType = 'linear'; % 2D interpolation type
cec.InterpWindow = 'Centered'; % Interpolation window type
cec.InterpWinSize = 1; % Interpolation window size
griddims = lteResourceGridSize(enb); % Resource grid dimensions
L = griddims(2);
% Generate signal
mib = lteMIB(enb);
bchCoded = lteBCH(enb,mib);
mibCRC = lteCRCEncode(mib,'16');
mibCoded = lteConvolutionalEncode(mibCRC);
pbchSymbolsTx = ltePBCH(enb,bchCoded);
pbchIndtx = ltePBCHIndices(enb);
subframe_tx = lteDLResourceGrid(enb);
rs = lteCellRS(enb);
rsind = lteCellRSIndices(enb);
subframe_tx(rsind)=rs;
NofPortsTx=enb.CellRefP;
addpath('../../build/srslte/lib/phch/test')
txWaveform=cell(length(Nblock));
rxWaveform=cell(length(Nblock));
for n=1:length(Nblock)
subframe_tx2=subframe_tx;
subframe_tx2(pbchIndtx)=pbchSymbolsTx(Nblock(n)*240+1:(Nblock(n)+1)*240,:);
[txWaveform{n},info] = lteOFDMModulate(enb, subframe_tx2, 0);
cfg.SamplingRate = info.SamplingRate;
end
error=zeros(length(SNR_values_db),2);
for snr_idx=1:length(SNR_values_db)
SNRdB = SNR_values_db(snr_idx); % Desired SNR in dB
SNR = 10^(SNRdB/10); % Linear SNR
errorReal = zeros(Nrealizations,2);
for i=1:Nrealizations
for n=1:length(Nblock)
%rxWaveform = lteFadingChannel(cfg,sum(txWaveform,2));
rxWaveform{n} = sum(txWaveform{n},2);
%% Additive Noise
N0 = 1/(sqrt(2.0*double(enb.CellRefP)*double(info.Nfft))*SNR);
% Create additive white Gaussian noise
noise = N0*complex(randn(size(rxWaveform{n})),randn(size(rxWaveform{n})));
rxWaveform{n} = noise + rxWaveform{n};
% Number of OFDM symbols in a subframe
% OFDM demodulate signal
rxgrid = lteOFDMDemodulate(enb, rxWaveform{n}, 0);
% Perform channel estimation
%enb.CellRefP=2;
[hest, nest] = lteDLChannelEstimate(enb, cec, rxgrid(:,1:L,:));
pbchIndices = ltePBCHIndices(enb);
[pbchRx, pbchHest] = lteExtractResources(pbchIndices, rxgrid(:,1:L,:), ...
hest(:,1:L,:,:));
% Decode PBCH
[bchBits, pbchSymbols, nfmod4, mib, nof_ports] = ltePBCHDecode(enb, pbchRx, pbchHest, nest);
if (nof_ports ~= NofPortsTx)
errorReal(i,1)=1;
end
end
%enb.CellRefP=NofPortsTx;
[nof_ports2, pbchSymbols2, pbchBits, ce, ce2, pbchRx2, pbchHest2, mod2, codedbits]= ...
srslte_pbch(enb, rxWaveform);
subplot(2,1,1)
plot(abs((bchCoded(1:960)>0)-(pbchBits(1:960)>0)))
subplot(2,1,2)
codedbits2 = reshape(reshape(codedbits,3,[])',1,[]);
plot(abs((codedbits2'>0)-(mibCoded>0)))
%decodedData = lteConvolutionalDecode(noisysymbols);
%[decodedData2, quant] = srslte_viterbi(interleavedSymbols);
if (nof_ports2 ~= NofPortsTx)
errorReal(i,2)=1;
end
end
error(snr_idx,:) = sum(errorReal);
fprintf('SNR: %.2f dB\n', SNR_values_db(snr_idx));
end
if (length(SNR_values_db) > 1)
semilogy(SNR_values_db, error/Nrealizations)
grid on
xlabel('SNR (dB)');
ylabel('BLER')
legend('Matlab','srsLTE')
axis([min(SNR_values_db) max(SNR_values_db) 1/Nrealizations/10 1])
else
disp(error)
disp(nfmod4)
disp(mod2)
end

@ -1,189 +0,0 @@
%% PDCCH Blind Search and DCI Decoding + PCFICH encoding/decoding
%% Cell-Wide Settings
% A structure |enbConfig| is used to configure the eNodeB.
clear
Npackets = 60;
SNR_values = linspace(2,6,6);
txCFI = 3;
enbConfig.NDLRB = 15; % No of Downlink RBs in total BW
enbConfig.CyclicPrefix = 'Normal'; % CP length
enbConfig.CFI = txCFI; % 4 PDCCH symbols as NDLRB <= 10
enbConfig.Ng = 'One'; % HICH groups
enbConfig.CellRefP = 1; % 1-antenna ports
enbConfig.NCellID = 0; % Physical layer cell identity
enbConfig.NSubframe = 5; % Subframe number 0
enbConfig.DuplexMode = 'FDD'; % Frame structure
enbConfig.PHICHDuration = 'Normal';
C_RNTI = 1; % 16-bit UE-specific mask
%% Setup Fading channel model
cfg.Seed = 8; % Random channel seed
cfg.NRxAnts = 1; % 1 receive antenna
cfg.DelayProfile = 'EPA'; % EVA delay spread
cfg.DopplerFreq = 5; % 120Hz Doppler frequency
cfg.MIMOCorrelation = 'Low'; % Low (no) MIMO correlation
cfg.InitTime = 0; % Initialize at time zero
cfg.NTerms = 16; % Oscillators used in fading model
cfg.ModelType = 'GMEDS'; % Rayleigh fading model type
cfg.InitPhase = 'Random'; % Random initial phases
cfg.NormalizePathGains = 'On'; % Normalize delay profile power
cfg.NormalizeTxAnts = 'On'; % Normalize for transmit antennas
% Setup channel equalizer
cec.PilotAverage = 'UserDefined'; % Type of pilot averaging
cec.FreqWindow = 9; % Frequency window size
cec.TimeWindow = 9; % Time window size
cec.InterpType = 'linear'; % 2D interpolation type
cec.InterpWindow = 'Causal'; % Interpolation window type
cec.InterpWinSize = 1; % Interpolation window size
%% DCI Message Generation
% Generate a DCI message to be mapped to the PDCCH.
dciConfig.DCIFormat = 'Format1A'; % DCI message format
dciConfig.Allocation.RIV = 26; % Resource indication value
% Create DCI message for given configuration
[dciMessage, dciMessageBits] = lteDCI(enbConfig, dciConfig);
%% DCI Channel Coding
% Do not include RNTI if Common Search space
if C_RNTI<65535
pdcchConfig.RNTI = C_RNTI; % Radio network temporary identifier
end
pdcchConfig.PDCCHFormat = 3; % PDCCH format
ueConfig.RNTI = C_RNTI;
candidates = ltePDCCHSpace(enbConfig, pdcchConfig, {'bits', '1based'});
% Include now RNTI in pdcch
pdcchConfig.RNTI = C_RNTI;
% DCI message bits coding to form coded DCI bits
codedDciBits = lteDCIEncode(pdcchConfig, dciMessageBits);
%% PDCCH Bits Generation
pdcchDims = ltePDCCHInfo(enbConfig);
% Initialize elements with -1 to indicate that all the bits are unused
pdcchBitsTx = -1*ones(pdcchDims.MTot, 1);
Ncad=1;
% Map PDCCH payload on available UE-specific candidate. In this example the
% first available candidate is used to map the coded DCI bits.
pdcchBitsTx ( candidates(Ncad, 1) : candidates(Ncad, 2) ) = codedDciBits;
%% PDCCH Complex-Valued Modulated Symbol Generation
pdcchSymbolsTx = ltePDCCH(enbConfig, pdcchBitsTx);
pdcchIndices = ltePDCCHIndices(enbConfig,{'1based'});
subframe_tx = lteDLResourceGrid(enbConfig);
subframe_tx(pdcchIndices) = pdcchSymbolsTx;
%% PCFICH
cfiCodeword = lteCFI(enbConfig);
pcfichSymbols = ltePCFICH(enbConfig,cfiCodeword);
pcfichIndices = ltePCFICHIndices(enbConfig,'1based');
subframe_tx(pcfichIndices) = pcfichSymbols;
%% Add references
cellRsSym = lteCellRS(enbConfig);
cellRsInd = lteCellRSIndices(enbConfig);
subframe_tx(cellRsInd) = cellRsSym;
[txWaveform, info] = lteOFDMModulate(enbConfig,subframe_tx);
cfg.SamplingRate = info.SamplingRate;
addpath('../../build/srslte/lib/phch/test')
decoded = zeros(size(SNR_values));
decoded_cfi = zeros(size(SNR_values));
decoded_srslte = zeros(size(SNR_values));
decoded_cfi_srslte = zeros(size(SNR_values));
for snr_idx=1:length(SNR_values)
SNRdB = SNR_values(snr_idx);
SNR = 10^(SNRdB/10); % Linear SNR
N0 = 1/(sqrt(2.0*enbConfig.CellRefP*double(info.Nfft))*SNR);
for i=1:Npackets
enbConfigRx=enbConfig;
rxWaveform = sum(txWaveform,2);
%% Fading
rxWaveform = lteFadingChannel(cfg,rxWaveform);
%% Noise Addition
noise = N0*complex(randn(size(rxWaveform)), randn(size(rxWaveform))); % Generate noise
rxWaveform = rxWaveform + noise;
%% Demodulate
subframe_rx = lteOFDMDemodulate(enbConfigRx, rxWaveform);
% Perform channel estimation
[hest, nest] = lteDLChannelEstimate(enbConfigRx, cec, subframe_rx);
[pcfichSymbolsRx, pcfichSymbolsHest] = lteExtractResources(pcfichIndices(:,1), subframe_rx, hest);
%% PCFICH decoding
[pcfichBits, pcfichSymbols] = ltePCFICHDecode(enbConfigRx,pcfichSymbolsRx, pcfichSymbolsHest, nest);
rxCFI = lteCFIDecode(pcfichBits);
decoded_cfi(snr_idx) = decoded_cfi(snr_idx) + (rxCFI == txCFI);
%% PDCCH Decoding
enbConfigRx.CFI = rxCFI;
pdcchIndicesRx = ltePDCCHIndices(enbConfigRx,{'1based'});
[pdcchRx, pdcchHest] = lteExtractResources(pdcchIndicesRx(:,1), subframe_rx, hest);
[pdcchBits, pdcchSymbols] = ltePDCCHDecode(enbConfigRx, pdcchRx, pdcchHest, nest);
%% Blind Decoding using DCI Search
[rxDCI, rxDCIBits] = ltePDCCHSearch(enbConfigRx, ueConfig, pdcchBits);
decoded(snr_idx) = decoded(snr_idx) + (length(rxDCI)>0);
%% Same with srsLTE
[rxCFI_srslte, pcfichRx2, pcfichSymbols2] = srslte_pcfich(enbConfigRx, subframe_rx);
decoded_cfi_srslte(snr_idx) = decoded_cfi_srslte(snr_idx) + (rxCFI_srslte == txCFI);
enbConfigRx.CFI = txCFI;
[found_srslte, pdcchBits2, pdcchRx2, pdcchSymbols2, hest2] = srslte_pdcch(enbConfigRx, ueConfig.RNTI, subframe_rx, hest, nest);
decoded_srslte(snr_idx) = decoded_srslte(snr_idx)+found_srslte;
end
fprintf('SNR: %.1f\n',SNRdB)
end
if (Npackets>1)
semilogy(SNR_values,1-decoded/Npackets,'bo-',...
SNR_values,1-decoded_cfi/Npackets,'bx:',...
SNR_values,1-decoded_srslte/Npackets, 'ro-',...
SNR_values,1-decoded_cfi_srslte/Npackets,'rx:')
grid on
legend('Matlab all','Matlab cfi', 'srsLTE all', 'srsLTE cfi')
xlabel('SNR (dB)')
ylabel('BLER')
axis([min(SNR_values) max(SNR_values) 1/Npackets/10 1])
else
n=min(length(pdcchSymbols),length(pdcchSymbols2));
subplot(2,1,1)
plot(abs(pdcchSymbols(1:n)-pdcchSymbols2(1:n)))
n=min(length(pdcchBits),length(pdcchBits2));
subplot(2,1,2)
pdcchBitsTx(pdcchBitsTx==-1)=0;
plot(abs((pdcchBitsTx(1:n)>0.1)-(pdcchBits2(1:n)>0.1)))
subplot(1,1,1)
plot(1:180,real(hest(:,1,1,1)),1:180,real(hest2(1:180)))
disp(decoded)
disp(decoded_srslte)
end

@ -1,108 +0,0 @@
%% Plot PDSCH BLER vs SNR for PDSCH without equalization
clear
transportBlkSize=75376;
modulation='64QAM';
rvValues=[0 2 3 1];
SNR=linspace(-2.9,-2.0,8);
Nblocks=30;
addpath('../../build/srslte/lib/phch/test')
% Subframe configuration
enbConfig.NCellID = 100;
enbConfig.CyclicPrefix = 'Normal';
enbConfig.NSubframe = 1;
enbConfig.CellRefP = 1;
enbConfig.NDLRB = 100;
enbConfig.CFI = 1;
enbConfig.DuplexMode='FDD';
% Transmission mode configuration for PDSCH
pdschConfig.NLayers = 1;
pdschConfig.TxScheme = 'Port0';
pdschConfig.Modulation = {modulation};
pdschConfig.RNTI = 100;
pdschConfig.NTurboDecIts = 5;
pdschConfig.PRBSet = (0:enbConfig.NDLRB-1)';
switch (modulation)
case 'QPSK'
bitsPerSym = 2;
case '16QAM'
bitsPerSym = 4;
case '64QAM'
bitsPerSym = 6;
end
noiseVarfactor = sqrt(2*bitsPerSym);
snr = 10.^(SNR/10);
nErrors_mat = zeros(length(SNR),length(rvValues));
nErrors_srs = zeros(length(SNR),length(rvValues));
for k = 1:length(SNR);
subframe=cell(length(rvValues));
pdschIdx=ltePDSCHIndices(enbConfig,pdschConfig,pdschConfig.PRBSet);
for i=1:length(rvValues)
subframe{i} = lteDLResourceGrid(enbConfig);
end
blkCounter = 0;
for l = 1:Nblocks;
% DL-SCH data bits
dlschBits = randi([0 1],transportBlkSize,1);
softBuffer = {};
for rvIndex = 1:length(rvValues)
% DLSCH transport channel
pdschConfig.RV = rvValues(rvIndex);
pdschPayload = lteDLSCH(enbConfig, pdschConfig, length(pdschIdx)*bitsPerSym, dlschBits);
% PDSCH modulated symbols
pdschSymbols = ltePDSCH(enbConfig, pdschConfig, pdschPayload);
pdschSize = size(pdschSymbols);
% Addition of noise
noise = (1/noiseVarfactor)*sqrt(1/snr(k))*complex(randn(pdschSize),randn(pdschSize));
noisySymbols = pdschSymbols + noise;
subframe{rvIndex}(pdschIdx)=noisySymbols;
% PDSCH Rx-side
rxCW = ltePDSCHDecode(enbConfig, pdschConfig, noisySymbols);
% DL-SCH turbo decoding
[rxBits, blkCRCerr, softBuffer] = lteDLSCHDecode(enbConfig, pdschConfig, transportBlkSize, rxCW{1}, softBuffer);
% Add errors to previous error counts
nErrors_mat(k,rvIndex) = nErrors_mat(k,rvIndex)+blkCRCerr;
end
% Same with srsLTE
[okSRSLTE, data, pdschRx, pdschSymbols, cws] = srslte_pdsch(enbConfig, pdschConfig, ...
transportBlkSize, subframe, ones(size(subframe{1})), 0);
nErrors_srs(k,rvIndex) = nErrors_srs(k,rvIndex)+~okSRSLTE;
end
fprintf('SNR=%.1f dB, BLER_mat=%f, BLER_srs=%f\n',SNR(k),nErrors_mat(k,rvIndex)/Nblocks, nErrors_srs(k,rvIndex)/Nblocks);
end
PDSCHBLER_MAT = nErrors_mat./Nblocks;
PDSCHBLER_MAT(PDSCHBLER_MAT==0)=10^-10;
PDSCHBLER_SRS = nErrors_srs./Nblocks;
PDSCHBLER_SRS(PDSCHBLER_SRS==0)=10^-10;
if (Nblocks == 1 && length(SNR) == 1)
else
semilogy(SNR,PDSCHBLER_MAT,SNR,PDSCHBLER_SRS)
grid on
xlabel('Eb/No (dB)')
ylabel('BLER')
leg=[];
for rvIndex = 1:length(rvValues)
leg=strvcat(leg,sprintf('Matlab rv=%d',rvValues(rvIndex)));
end
for rvIndex = 1:length(rvValues)
leg=strvcat(leg,sprintf('srsLTE rv=%d',rvValues(rvIndex)));
end
legend(leg);
axis([min(SNR) max(SNR) 10^-4 1])
end

@ -1,76 +0,0 @@
enb=struct('NCellID',313,'NDLRB',75,'NSubframe',5,'CFI',1,'CyclicPrefix','Normal','CellRefP',2,'Ng','One','PHICHDuration','Normal','DuplexMode','FDD');
RNTI=65535;
addpath('../../build/srslte/lib/phch/test')
cec.PilotAverage = 'UserDefined'; % Type of pilot averaging
cec.FreqWindow = 1; % Frequency window size
cec.TimeWindow = 1; % Time window size
cec.InterpType = 'linear'; % 2D interpolation type
cec.InterpWindow = 'Causal'; % Interpolation window type
cec.InterpWinSize = 1; % Interpolation window size
%subframe_rx=lteOFDMDemodulate(enb,x);
subframe_rx=reshape(x,[],14);
[hest,nest] = lteDLChannelEstimate(enb, cec, subframe_rx);
% Search PDCCH
pdcchIndices = ltePDCCHIndices(enb);
[pdcchRx, pdcchHest] = lteExtractResources(pdcchIndices, subframe_rx, hest);
[dciBits, pdcchSymbols] = ltePDCCHDecode(enb, pdcchRx, pdcchHest, nest);
pdcch = struct('RNTI', RNTI);
[dci, dcidecBits] = ltePDCCHSearch(enb, pdcch, dciBits); % Search PDCCH for DCI
if ~isempty(dci)
dci = dci{1};
disp(dci);
% Get the PDSCH configuration from the DCI
[pdsch, trblklen] = hPDSCHConfiguration(enb, dci, pdcch.RNTI);
pdsch.NTurboDecIts = 16;
%pdsch.Modulation = {'64QAM'};
pdsch.RV=0;
fprintf('PDSCH settings after DCI decoding:\n');
disp(pdsch);
fprintf('Decoding PDSCH...\n\n');
% Get PDSCH indices
[pdschIndices,pdschIndicesInfo] = ltePDSCHIndices(enb, pdsch, pdsch.PRBSet);
[pdschRx, pdschHest] = lteExtractResources(pdschIndices, subframe_rx, hest);
% Decode PDSCH
[dlschBits,pdschSymbols] = ltePDSCHDecode(enb, pdsch, pdschRx, pdschHest, 0);
[sib1, crc] = lteDLSCHDecode(enb, pdsch, trblklen, dlschBits);
[dec2, data, pdschRx2, pdschSymbols2, e_bits, ce] = srslte_pdsch(enb, pdsch, ...
trblklen, ...
subframe_rx);
subplot(2,1,1)
scatter(real(pdschSymbols{1}),imag(pdschSymbols{1}))
subplot(2,1,2)
scatter(real(pdschSymbols2),imag(pdschSymbols2))
if crc == 0
fprintf('PDSCH Matlab OK.\n\n');
else
fprintf('PDSCH Matlab ERROR.\n\n');
end
if dec2 == 1
fprintf('PDSCH srsLTE OK.\n\n');
else
fprintf('PDSCH srsLTE ERROR.\n\n');
end
else
% indicate that DCI decoding failed
fprintf('DCI decoding failed.\n\n');
end
%indices=indices+1;
%plot(t,indices(t),t,pdschIndices(t))

@ -1,166 +0,0 @@
%% PDSCH decoding based on RMC channels
%% Cell-Wide Settings
% A structure |enbConfig| is used to configure the eNodeB.
%clear12
recordedSignal=[];
Npackets = 1;
SNR_values = 56;%linspace(2,6,10);
Lp=12;
N=256;
K=180;
rstart=(N-K)/2;
P=K/6;
Rhphp=zeros(P,P);
Rhhp=zeros(K,P);
Rhh=zeros(K,K);
t=0:Lp-1;
alfa=log(2*Lp)/Lp;
c_l=exp(-t*alfa);
c_l=c_l/sum(c_l);
C_l=diag(1./c_l);
prows=rstart+(1:6:K);
F=dftmtx(N);
F_p=F(prows,1:Lp);
F_l=F((rstart+1):(K+rstart),1:Lp);
Wi=(F_p'*F_p+C_l*0.01)^(-1);
W2=F_l*Wi*F_p';
w2=reshape(transpose(W2),1,[]);
%% Choose RMC
[waveform,rgrid,rmccFgOut] = lteRMCDLTool('R.5',[1;0;0;1]);
waveform = sum(waveform,2);
if ~isempty(recordedSignal)
rmccFgOut = struct('CellRefP',1,'NDLRB',25,'DuplexMode','FDD','CyclicPrefix','Normal');
rmccFgOut.PDSCH.RNTI = 1234;
rmccFgOut.PDSCH.PRBSet = repmat(transpose(0:rmccFgOut.NDLRB-1),1,2);
rmccFgOut.PDSCH.TxScheme = 'Port0';
rmccFgOut.PDSCH.NLayers = 1;
rmccFgOut.PDSCH.NTurboDecIts = 5;
rmccFgOut.PDSCH.Modulation = {'64QAM'};
trblklen=75376;
rmccFgOut.PDSCH.TrBlkSizes = trblklen*ones(10,1);
rmccFgOut.PDSCH.RV = 0;
end
flen=rmccFgOut.SamplingRate/1000;
Nsf = 2;
%% Setup Fading channel model
cfg.Seed = 0; % Random channel seed
cfg.NRxAnts = 1; % 1 receive antenna
cfg.DelayProfile = 'EPA'; % EVA delay spread
cfg.DopplerFreq = 5; % 120Hz Doppler frequency
cfg.MIMOCorrelation = 'Low'; % Low (no) MIMO correlation
cfg.InitTime = 0; % Initialize at time zero
cfg.NTerms = 16; % Oscillators used in fading model
cfg.ModelType = 'GMEDS'; % Rayleigh fading model type
cfg.InitPhase = 'Random'; % Random initial phases
cfg.NormalizePathGains = 'On'; % Normalize delay profile power
cfg.NormalizeTxAnts = 'On'; % Normalize for transmit antennas
cfg.SamplingRate = rmccFgOut.SamplingRate;
% Setup channel equalizer
cec.PilotAverage = 'UserDefined'; % Type of pilot averaging
cec.FreqWindow = 1; % Frequency window size
cec.TimeWindow = 1; % Time window size
cec.InterpType = 'linear'; % 2D interpolation type
cec.InterpWindow = 'Causal'; % Interpolation window type
cec.InterpWinSize = 1; % Interpolation window size
addpath('../../build/srslte/lib/phch/test')
decoded = zeros(size(SNR_values));
decoded_srslte = zeros(size(SNR_values));
for snr_idx=1:length(SNR_values)
SNRdB = SNR_values(snr_idx);
SNR = 10^(SNRdB/10); % Linear SNR
N0 = 1/(sqrt(2.0*rmccFgOut.CellRefP*double(rmccFgOut.Nfft))*SNR);
Rhphp=zeros(30,30);
Rhhp=zeros(180,30);
for i=1:Npackets
if isempty(recordedSignal)
%% Fading
[rxWaveform, chinfo] = lteFadingChannel(cfg,waveform);
rxWaveform = rxWaveform(chinfo.ChannelFilterDelay+1:end);
%rxWaveform = waveform;
%% Noise Addition
noise = N0*complex(randn(size(rxWaveform)), randn(size(rxWaveform))); % Generate noise
rxWaveform = rxWaveform + noise;
else
rxWaveform = recordedSignal;
end
%% Demodulate
frame_rx = lteOFDMDemodulate(rmccFgOut, rxWaveform);
for sf_idx=0:Nsf-1
% sf_idx=9;
subframe_rx=frame_rx(:,sf_idx*14+1:(sf_idx+1)*14);
rmccFgOut.NSubframe=sf_idx;
rmccFgOut.TotSubframes=1;
% Perform channel estimation
[hest, nest] = lteDLChannelEstimate(rmccFgOut, cec, subframe_rx);
[cws,symbols] = ltePDSCHDecode(rmccFgOut,rmccFgOut.PDSCH,subframe_rx,hest,nest);
[trblkout,blkcrc,dstate] = lteDLSCHDecode(rmccFgOut,rmccFgOut.PDSCH, ...
rmccFgOut.PDSCH.TrBlkSizes(sf_idx+1),cws);
decoded(snr_idx) = decoded(snr_idx) + ~blkcrc;
%% Same with srsLTE
if (rmccFgOut.PDSCH.TrBlkSizes(sf_idx+1) > 0)
[dec2, data, pdschRx, pdschSymbols2, cws2, ce] = srslte_pdsch(rmccFgOut, rmccFgOut.PDSCH, ...
rmccFgOut.PDSCH.TrBlkSizes(sf_idx+1), ...
subframe_rx);
else
dec2 = 1;
end
if (~dec2)
fprintf('Error in sf=%d\n',sf_idx);
end
decoded_srslte(snr_idx) = decoded_srslte(snr_idx)+dec2;
end
if ~isempty(recordedSignal)
recordedSignal = recordedSignal(flen*10+1:end);
end
end
fprintf('SNR: %.1f. Decoded: %d-%d\n',SNRdB, decoded(snr_idx), decoded_srslte(snr_idx))
end
if (length(SNR_values)>1)
semilogy(SNR_values,1-decoded/Npackets/(Nsf),'bo-',...
SNR_values,1-decoded_srslte/Npackets/(Nsf), 'ro-')
grid on;
legend('Matlab','srsLTE')
xlabel('SNR (dB)')
ylabel('BLER')
axis([min(SNR_values) max(SNR_values) 1/Npackets/(Nsf+1) 1])
else
subplot(2,1,1)
scatter(real(pdschSymbols2),imag(pdschSymbols2))
%plot(real(hest))
subplot(2,1,2)
%plot(1:180,angle(ce(1:180)),1:180,angle(hest(:,1)))
plot(abs(ce-hest(:)))
fprintf('Matlab: %d OK\nsrsLTE: %d OK\n',decoded, decoded_srslte);
end

@ -1,76 +0,0 @@
filename='../../debug/dist_ra.dat';
enb.NDLRB = 50;
enb.CyclicPrefix = 'Normal';
enb.PHICHDuration = 'Normal';
enb.CFI = 2;
enb.Ng = 'Sixth';
enb.CellRefP = 1;
enb.NCellID = 196;
enb.NSubframe = 5;
enb.NTotalSubframes=1;
enb.DuplexMode = 'FDD';
dci.NDLRB = enb.NDLRB;
dci.DCIFormat = 'SRSLTE_DCI_FORMAT1C';
dci.AllocationType=1;
%dci.Allocation.Bitmap='01111000011110000';
%dci.Allocation.Subset=3;
dci.Allocation.RIV = 33;
dci.Allocation.Gap = 0;
dci.ModCoding=6;
dci.RV=0;
dci.DuplexMode = enb.DuplexMode;
dci.NTxAnts = enb.CellRefP;
pdcch.RNTI = 65535;
pdcch.PDCCHFormat = 3;
pdsch.Modulation='QPSK';
pdsch.RNTI=pdcch.RNTI;
if (enb.CellRefP == 1)
pdsch.TxScheme='Port0';
else
pdsch.TxScheme='TxDiversity';
end
pdsch.NLayers=enb.CellRefP;
pdsch.trblklen=176;
pdsch.RV=dci.RV;
% Begin frame generation
subframe = lteDLResourceGrid(enb);
%%% Create Reference Signals
rsAnt = lteCellRS(enb);
indAnt = lteCellRSIndices(enb);
subframe(indAnt) = rsAnt;
%%% Create PDCCH
[dciMessage,dciMessageBits] = lteDCI(enb,dci);
codedDciBits = lteDCIEncode(pdcch,dciMessageBits);
pdcchInfo = ltePDCCHInfo(enb);
pdcchBits = -1*ones(1,pdcchInfo.MTot);
candidates = ltePDCCHSpace(enb,pdcch,{'bits','1based'});
pdcchBits (candidates(1,1):candidates(1,2)) = codedDciBits;
pdcchSymbols = ltePDCCH(enb, pdcchBits);
pdcchIndices = ltePDCCHIndices(enb,{'1based'});
subframe(pdcchIndices) = pdcchSymbols;
% Create PDSCH
pdsch.prbset = lteDCIResourceAllocation(enb,dci);
[pdschIndices,pdschInfo] = ltePDSCHIndices(enb,pdsch,pdsch.prbset);
dlschTransportBlk=randi([0 1],pdsch.trblklen,1);
pdschcodeword = lteDLSCH(enb,pdsch,pdschInfo.G,dlschTransportBlk);
%crced = lteCRCEncode(dlschTransportBlk, '24A');
%encoded = lteTurboEncode(crced);
%pdschcodeword2 = lteRateMatchTurbo(encoded,pdschInfo.G,pdsch.RV);
pdschSymbols = ltePDSCH(enb,pdsch,pdschcodeword);
subframe(pdschIndices) = pdschSymbols;
txwaveform = lteOFDMModulate(enb,subframe);
write_complex(filename,sum(txwaveform,2));
fprintf('Written signal to %s\n',filename);

@ -1,39 +0,0 @@
clear
% Run pdsch_test with -vv to generate files. Then run this script to check
% rate matching and demodulation
% Need to change soft demodulator output to +-10
enbConfig=struct('NCellID',0,'CyclicPrefix','Normal','CellRefP',1,'DuplexMode','FDD');
pdschConfig=struct('Modulation','64QAM','RV',3,'TxScheme','Port0','NTurboDecIts',10,...
'NSoftbits',0,'DuplexMode','FDD');
addpath('../../build/srslte/lib/phch/test')
cbidx_v=0:12;
e_bits=90000;
trblkin=read_uchar('../../build/data_in');
[mat, info]=lteDLSCH(enbConfig,pdschConfig,e_bits,trblkin);
mat(mat==0)=-1;
mat=mat*10;
rec = lteRateRecoverTurbo(mat,length(trblkin),pdschConfig.RV,pdschConfig);
rec2=cell(size(rec));
srs=cell(size(rec));
for cbidx=cbidx_v
rec2{cbidx+1} = reshape(reshape(rec{cbidx+1},[],3)',[],1);
srs{cbidx+1}=read_int16(sprintf('../../build/rmout_%d.dat',cbidx));
end
subplot(2,1,1)
plot(abs(double(reshape(cell2mat(srs),1,[]))-double(reshape(cell2mat(rec2),1,[]))));
subplot(2,1,2)
llr=read_int16('../../build/llr.dat');
plot(abs(double(mat)-double(llr)))
[data, crc,state] = lteDLSCHDecode(enbConfig, pdschConfig, length(trblkin), mat);
disp(crc)

@ -1,132 +0,0 @@
clear
%% PHICH encoding/decoding
%% Setup simulation
Npackets = 80;
SNR_values = linspace(-6,0,6);
enable_fading=false;
addpath('../../debug/srslte/lib/phch/test')
%% Cell-Wide Settings
enbConfig.NDLRB = 50; % No of Downlink RBs in total BW
enbConfig.CyclicPrefix = 'Normal'; % CP length
enbConfig.Ng = 'One'; % HICH groups
enbConfig.CellRefP = 1; % 1-antenna ports
enbConfig.NCellID = 36; % Physical layer cell identity
enbConfig.NSubframe = 5; % Subframe number 0
enbConfig.DuplexMode = 'FDD'; % Frame structure
enbConfig.PHICHDuration = 'Normal';
%% Define HI resource
hi_res = [1 1];
ack_bit = 1;
%% Setup Fading channel model
if (enable_fading)
cfg.Seed = 8; % Random channel seed
cfg.NRxAnts = 1; % 1 receive antenna
cfg.DelayProfile = 'EPA'; % EVA delay spread
cfg.DopplerFreq = 5; % 120Hz Doppler frequency
cfg.MIMOCorrelation = 'Low'; % Low (no) MIMO correlation
cfg.InitTime = 0; % Initialize at time zero
cfg.NTerms = 16; % Oscillators used in fading model
cfg.ModelType = 'GMEDS'; % Rayleigh fading model type
cfg.InitPhase = 'Random'; % Random initial phases
cfg.NormalizePathGains = 'On'; % Normalize delay profile power
cfg.NormalizeTxAnts = 'On'; % Normalize for transmit antennas
end
% Setup channel equalizer
cec.PilotAverage = 'UserDefined'; % Type of pilot averaging
cec.FreqWindow = 9; % Frequency window size
cec.TimeWindow = 9; % Time window size
cec.InterpType = 'linear'; % 2D interpolation type
cec.InterpWindow = 'Causal'; % Interpolation window type
cec.InterpWinSize = 1; % Interpolation window size
%% Generate TX subframe
subframe_tx = lteDLResourceGrid(enbConfig);
%% Genearte PHICH signal
hi_sym_tx = ltePHICH(enbConfig, [hi_res ack_bit]);
hi_indices = ltePHICHIndices(enbConfig);
subframe_tx(hi_indices)=hi_sym_tx;
%% Add references to subframe
cellRsSym = lteCellRS(enbConfig);
cellRsInd = lteCellRSIndices(enbConfig);
subframe_tx(cellRsInd) = cellRsSym;
%% Modulate signal
[txWaveform, info] = lteOFDMModulate(enbConfig,subframe_tx);
cfg.SamplingRate = info.SamplingRate;
%% Start simulation
decoded = zeros(size(SNR_values));
decoded_srslte = zeros(size(SNR_values));
for snr_idx=1:length(SNR_values)
SNRdB = SNR_values(snr_idx);
SNR = 10^(SNRdB/10); % Linear SNR
N0 = 1/(sqrt(2.0*enbConfig.CellRefP*double(info.Nfft))*SNR);
for i=1:Npackets
%% Fading
rxWaveform = sum(txWaveform,2);
if (enable_fading)
rxWaveform = lteFadingChannel(cfg,rxWaveform);
end
%% Noise Addition
noise = N0*complex(randn(size(rxWaveform)), randn(size(rxWaveform)));
rxWaveform = rxWaveform + noise;
%% Demodulate
subframe_rx = lteOFDMDemodulate(enbConfig, rxWaveform);
%% Channel estimation
if (enable_fading)
[hest, nest] = lteDLChannelEstimate(enbConfig, cec, subframe_rx);
else
hest=ones(size(subframe_rx));
nest=0;
end
%% Extract resources
phichSymbolsRx = subframe_rx(hi_indices);
phichSymbolsHest = hest(hi_indices);
%% PHICH decoding
[hi, hi_symbols] = ltePHICHDecode(enbConfig,hi_res, phichSymbolsRx, phichSymbolsHest, nest);
decoded(snr_idx) = decoded(snr_idx) + (hi == ack_bit);
%% Same with srsLTE
[hi_srslte, hi_symbols_srslte] = srslte_phich(enbConfig, hi_res, subframe_rx, hest, nest);
decoded_srslte(snr_idx) = decoded_srslte(snr_idx) + (hi_srslte == ack_bit);
end
fprintf('SNR: %.1f\n',SNRdB)
end
if (Npackets>1)
semilogy(SNR_values,1-decoded/Npackets,'bo-',...
SNR_values,1-decoded_srslte/Npackets, 'ro-')
grid on
legend('Matlab','srsLTE')
xlabel('SNR (dB)')
ylabel('BLER')
axis([min(SNR_values) max(SNR_values) 1/Npackets/10 1])
else
scatter(real(hi_symbols),imag(hi_symbols))
hold on
scatter(real(hi_symbols_srslte),imag(hi_symbols_srslte))
hold off
grid on;
axis([-2 2 -2 2])
disp(hi)
disp(hi_srslte)
end

@ -1,200 +0,0 @@
%% PRACH Detection Conformance Test
%clear
d=80;%linspace(4,14,6);
pDetection2 = zeros(2,length(d));
for dd=1:length(d)
detect_factor=d(dd);
numSubframes = 1; % Number of subframes frames to simulate at each SNR
SNRdB = 50;%linspace(-14,10,8); % SNR points to simulate
foffset = 0.0; % Frequency offset in Hertz
delay=0;
add_fading=false;
addpath('../../build/srslte/lib/phch/test')
%% UE Configuration
% User Equipment (UE) settings are specified in the structure |ue|.
ue.NULRB = 15; % 6 Resource Blocks
ue.DuplexMode = 'FDD'; % Frequency Division Duplexing (FDD)
ue.CyclicPrefixUL = 'Normal'; % Normal cyclic prefix length
ue.NTxAnts = 1; % Number of transmission antennas
%% PRACH Configuration
prach.Format = 0; % PRACH format: TS36.104, Table 8.4.2.1-1
prach.HighSpeed = 0; % Normal mode: TS36.104, Table 8.4.2.1-1
prach.FreqOffset = 2; % Default frequency location
info = ltePRACHInfo(ue, prach); % PRACH information
%% Propagation Channel Configuration
% Configure the propagation channel model using a structure |chcfg| as per
% TS36.104, Table 8.4.2.1-1 [ <#9 1> ].
chcfg.NRxAnts = 1; % Number of receive antenna
chcfg.DelayProfile = 'ETU'; % Delay profile
chcfg.DopplerFreq = 70.0; % Doppler frequency
chcfg.MIMOCorrelation = 'Low'; % MIMO correlation
chcfg.Seed = 1; % Channel seed
chcfg.NTerms = 16; % Oscillators used in fading model
chcfg.ModelType = 'GMEDS'; % Rayleigh fading model type
chcfg.InitPhase = 'Random'; % Random initial phases
chcfg.NormalizePathGains = 'On'; % Normalize delay profile power
chcfg.NormalizeTxAnts = 'On'; % Normalize for transmit antennas
chcfg.SamplingRate = info.SamplingRate; % Sampling rate
%% Loop for SNR Values
% Initialize the random number generator stream
rng('default');
% Initialize variables storing probability of detection at each SNR
pDetection = zeros(2,length(SNRdB));
for nSNR = 1:length(SNRdB)
% Scale noise to ensure the desired SNR after SC-FDMA demodulation
ulinfo = lteSCFDMAInfo(ue);
SNR = 10^(SNRdB(nSNR)/20);
N = 1/(SNR*sqrt(double(ulinfo.Nfft)))/sqrt(2.0);
% Detected preamble count
detectedCount = 0;
detectedCount_srs = 0;
% Loop for each subframe
for nsf = 1:numSubframes
prach.SeqIdx = 41;%randi(838,1,1)-1; % Logical sequence index: TS36.141, Table A.6-1
prach.CyclicShiftIdx = 11;%randi(16,1,1)-1; % Cyclic shift index: TS36.141, Table A.6-1
prach.PreambleIdx = 1;%randi(64,1,1)-1; % Preamble index: TS36.141, Table A.6-1
prach.TimingOffset = 0;
info = ltePRACHInfo(ue, prach); % PRACH information
% PRACH transmission
ue.NSubframe = mod(nsf-1, 10);
ue.NFrame = fix((nsf-1)/10);
% Set PRACH timing offset in us as per TS36.141, Figure 8.4.1.4.2-2
%prach.TimingOffset = info.BaseOffset + ue.NSubframe/10.0;
prach.TimingOffset = 0;
% Generate transmit wave
[txwave,prachinfo] = ltePRACH(ue, prach);
% Channel modeling
if (add_fading)
chcfg.InitTime = (nsf-1)/1000;
[rxwave, fadinginfo] = lteFadingChannel(chcfg, ...
[txwave; zeros(25, 1)]);
else
rxwave = txwave;
end
% Add noise
%noise = N*complex(randn(size(rxwave)), randn(size(rxwave)));
%rxwave = rxwave + noise;
% Remove the implementation delay of the channel modeling
if (add_fading)
rxwave = rxwave((fadinginfo.ChannelFilterDelay + 1):end, :);
end
rxwave=lteFrequencyCorrect(ue, x, -20);
% rxwave=[zeros(delay,1); txwave(1:end-delay)];
% Apply frequency offset
t = ((0:size(rxwave, 1)-1)/chcfg.SamplingRate).';
rxwave = rxwave .* repmat(exp(1i*2*pi*foffset*t), ...
1, size(rxwave, 2));
% PRACH detection for all cell preamble indices
[detected, offsets] = ltePRACHDetect(ue, prach, rxwave, (0:63).');
[detected_srs, offsets_srs, corrout] = srslte_prach_detect(ue, prach, rxwave, detect_factor);
disp(detected)
disp(detected_srs)
disp(offsets_srs*1e6)
% Test for preamble detection
if (length(detected)==1)
% Test for correct preamble detection
if (detected==prach.PreambleIdx)
% Calculate timing estimation error. The true offset is
% PRACH offset plus channel delay
trueOffset = prach.TimingOffset/1e6 + 310e-9;
measuredOffset = offsets(1)/chcfg.SamplingRate;
timingerror = abs(measuredOffset-trueOffset);
% Test for acceptable timing error
if (timingerror<=2.08e-6)
detectedCount = detectedCount + 1; % Detected preamble
else
disp('Timing error');
end
else
disp('Detected incorrect preamble');
end
else
disp('Detected multiple or zero preambles');
end
% Test for preamble detection
if (length(detected_srs)==1)
% Test for correct preamble detection
if (detected_srs==prach.PreambleIdx)
% Calculate timing estimation error. The true offset is
% PRACH offset plus channel delay
trueOffset = prach.TimingOffset/1e6 + 310e-9;
measuredOffset = offsets_srs(1);
timingerror = abs(measuredOffset-trueOffset);
% Test for acceptable timing error
if (timingerror<=2.08e-6)
detectedCount_srs = detectedCount_srs + 1; % Detected preamble
else
disp('SRS: Timing error');
end
else
disp('SRS: Detected incorrect preamble');
end
else
fprintf('SRS: Detected %d preambles. D=%.1f, Seq=%3d, NCS=%2d, Idx=%2d\n', ...
length(detected_srs),detect_factor, prach.SeqIdx, prach.CyclicShiftIdx, prach.PreambleIdx);
end
end % of subframe loop
% Compute final detection probability for this SNR
pDetection(1,nSNR) = detectedCount/numSubframes;
pDetection(2,nSNR) = detectedCount_srs/numSubframes;
end % of SNR loop
pDetection2(1,dd)=pDetection(1,1);
pDetection2(2,dd)=pDetection(2,1);
end
%% Analysis
if (length(SNRdB)>1)
plot(SNRdB, pDetection)
legend('Matlab','srsLTE')
grid on
xlabel('SNR (dB)')
ylabel('Pdet')
else
plot(d,pDetection2)
legend('Matlab','srsLTE')
grid on
xlabel('d')
ylabel('Pdet')
fprintf('Pdet=%.4f%%, Pdet_srs=%.4f%%\n',pDetection(1,nSNR),pDetection(2,nSNR))
end
plot(corrout)

@ -1,83 +0,0 @@
%% PRACH False Alarm Probability Conformance Test
clear
detect_factor=5;
ue.NULRB = 6; % Number of resource blocks
ue.DuplexMode = 'FDD'; % FDD duplexing mode
%% PRACH Configuration
prach.Format = 0; % Preamble format
prach.SeqIdx = 2; % Logical root sequence index
prach.CyclicShiftIdx = 1; % Cyclic shift configuration index
prach.HighSpeed = 0; % High speed flag
prach.FreqOffset = 0; % Use default frequency resource index
prach.PreambleIdx = []; % Empty since no preamble is transmitted
%% Establish PRACH Generator Output Length for this Configuration
info = ltePRACHInfo(ue, prach);
nSamples = info.SamplingRate*info.TotSubframes*0.001;
%% Loop for Detection in Each Subframe
numTrials = 2000;
falseCount = 0; % Initialize false detection counter
falseCount_srs = 0; % Initialize false detection counter
rng('default'); % Random number generator to default state
runningP=zeros(1, numTrials);
runningP_srs=zeros(1, numTrials);
for nt = 1:numTrials
% Create noise
noise = complex(randn(nSamples, 1), randn(nSamples, 1));
% Attempt detection for all cell preamble indices (0...63)
[detected,offset] = ltePRACHDetect(ue, prach, noise, 0:63);
[detected_srs] = srslte_prach_detect(ue, prach, noise, detect_factor);
% Record false alarm
if (~isempty(detected))
falseCount = falseCount+1;
end
if (~isempty(detected_srs))
falseCount_srs = falseCount_srs+1;
end
% Calculate running false alarm probability
runningP(nt) = falseCount/nt*100;
runningP_srs(nt) = falseCount_srs/nt*100;
% Plot information about false alarm (if applicable)
if (~isempty(detected))
plot(nt,runningP(nt),'ro','LineWidth',2,'MarkerSize',7);
hold on;
text(nt,runningP(nt), sprintf(['Preamble index = %d' ...
' \nTiming offset = %0.2f samples '],detected,offset), ...
'HorizontalAlignment','right');
end
if (~isempty(detected_srs))
plot(nt,runningP(nt),'mx','LineWidth',2,'MarkerSize',7);
hold on;
text(nt,runningP(nt), sprintf(['SRS index = %d' ...
' \nTiming offset = %0.2f samples '],detected,offset), ...
'HorizontalAlignment','right');
end
end
%% Compute Final False Alarm Probability
P = falseCount / numTrials;
P_srs = falseCount_srs / numTrials;
plot(1:numTrials,runningP,'b','LineWidth',2);
plot(1:numTrials,runningP_srs,'k','LineWidth',2);
hold off
axis([0 numTrials+1 -0.1 0.2]);
xlabel('Trials');
ylabel('Running false alarm probability (%)');
title('PRACH False Alarm Detection Probability');
fprintf('\nFalse alarm probability = %0.4f%% - %.04f%%\n',P*100, P_srs*100);

@ -1,51 +0,0 @@
clear
ueConfig=struct('NULRB',6,'DuplexMode','FDD','CyclicPrefix','Normal');
prachConfig=struct('Format',0,'SeqIdx',0,'PreambleIdx',0,'CyclicShiftIdx',0,'HighSpeed',0,'TimingOffset',0,'FreqIdx',0,'FreqOffset',8);
addpath('../../build/srslte/lib/phch/test')
NULRB=[100];
% FreqIdx, FreqOffset and TimeOffset need to be tested
for n_rb=1:length(NULRB)
for format=0;
for seqIdx=7:17:237
for preambleIdx=0:23:63
for CyclicShift=1:3:15
fprintf('RB: %d, format %d, seqIdx: %d, Cyc=%d Idx=%d\n',NULRB(n_rb),format,seqIdx, CyclicShift, preambleIdx);
%for hs=0:1
hs=0;
ueConfig.NULRB=NULRB(n_rb);
prachConfig.Format=format;
prachConfig.SeqIdx=seqIdx;
prachConfig.PreambleIdx=preambleIdx;
prachConfig.CyclicShiftIdx=CyclicShift;
prachConfig.HighSpeed=hs;
prachConfig.FreqIdx=0;
prachConfig.FreqOffset=0;
lib=srslte_prach(ueConfig,prachConfig);
[mat, info]=ltePRACH(ueConfig,prachConfig);
err=max(abs(mat-lib));
if (err > 2*10^-3)
disp(err)
a=1:100;
plot(a,real(lib(a)),a,real(mat(a)))
error('Error!');
end
%end
end
end
end
end
end
%
% disp(info)
n=1:length(mat);
% plot(abs(double(mat)-double(lib)))
flib=fft(lib(199:end),1536);
fmat=fft(mat(199:end),1536);
n=1:1536;
plot(n,real(flib(n)),n,real(fmat(n)))

@ -1,9 +0,0 @@
fprintf('static uint8_t M_basis_seq_pucch[20][13]={\n');
for i=1:20
fprintf('\t\t{');
for j=1:12
fprintf('%d, ',y(i,j));
end
fprintf('%d},\n',y(i,13));
end
fprintf('\t\t};\n');

@ -1,79 +0,0 @@
clear
ueConfig=struct('NCellID',1,'RNTI',11,'NULRB',25,'NSubframe',0,'CyclicPrefixUL','Normal','NTxAnts',1,'Hopping','Off');
pucchConfig=struct('NLayers',1,'OrthCover','Off','Shortened',0,'ResourceSize',2);
addpath('../../build/srslte/lib/phch/test')
format_str={'1','1a','1b','2','2a','2b'};
k=1;
for f=0:5
for n=0:7:130
for d=1:3
for ncs=0:d:7
for nsf=0:9
pucchConfig.ResourceIdx= n;
pucchConfig.DeltaShift = d;
pucchConfig.CyclicShifts = ncs;
ueConfig.NSubframe=nsf;
if (f >= 3)
nb=20;
nb_ack=f-3;
else
nb=f;
nb_ack=0;
end
bits=mod(0:nb-1,2);
bits_ack=randi(2,nb_ack,1)-1;
fprintf('Testing PUCCH Format: %s, n_pucch=%d, DeltaShift=%d, CyclicShift=%d, Nsf=%d\n',format_str{f+1},n,d,ncs,nsf);
if (f >= 3)
[sym_mat, info]=ltePUCCH2(ueConfig,pucchConfig,bits);
idx=ltePUCCH2Indices(ueConfig,pucchConfig);
[dmrs_mat, info_dmrs]=ltePUCCH2DRS(ueConfig,pucchConfig,bits_ack);
idx_dmrs=ltePUCCH2DRSIndices(ueConfig,pucchConfig);
else
[sym_mat, info]=ltePUCCH1(ueConfig,pucchConfig,bits);
idx=ltePUCCH1Indices(ueConfig,pucchConfig);
[dmrs_mat, info_dmrs]=ltePUCCH1DRS(ueConfig,pucchConfig);
idx_dmrs=ltePUCCH1DRSIndices(ueConfig,pucchConfig);
end
subframe_mat = lteULResourceGrid(ueConfig);
subframe_mat(idx)=sym_mat;
subframe_mat(idx_dmrs)=dmrs_mat;
[sym, dmrs, subframe]=srslte_pucch_encode(ueConfig,pucchConfig,[bits; bits_ack]);
error_sym=max(abs(sym-sym_mat));
error_dmrs=max(abs(dmrs-dmrs_mat));
error_sf=max(abs(subframe_mat(:)-subframe));
k=k+1;
if (error_sym > 1e-5)
disp(info)
plot(1:length(sym),sym,1:length(sym_mat),sym_mat)
legend('srsLTE','Matlab')
error('Error in symbols');
end
if (error_dmrs > 1e-5)
disp(info_dmrs)
plot(angle(dmrs)-angle(dmrs_mat))
error('Error in DMRS');
end
if (error_sf > 1e-5)
disp(info)
plot(abs(subframe-subframe_mat(:)))
error('Error in subframe');
end
end
end
end
end
end
if (k == 2)
disp(info)
disp(error_sym)
disp(error_sf)
n=1:length(sym);
plot(n,real(sym(n)),n,real(sym_mat(n)))
end

@ -1,188 +0,0 @@
%% Plot PUSCH BLER vs SNR for PUSCH without equalization
clear
transportBlkSize=904;
modulation='64QAM';
rvValues=0;
SNR=linspace(-5,0.0,8);
Nblocks=30;
addpath('../../build/srslte/lib/phch/test')
% Subframe configuration
ueConfig.NCellID = 100;
ueConfig.CyclicPrefixUL = 'Normal';
ueConfig.NSubframe = 0;
ueConfig.NULRB = 6;
ueConfig.Shortened = 0;
ueConfig.NTxAnts = 1;
ueConfig.RNTI = 1;
ueConfig.DuplexMode='FDD';
ueConfig.Hopping = 'Off';
ueConfig.SeqGroup = 0;
ueConfig.CyclicShift = 0;
ueConfig.Shortened = 0;
% Transmission mode configuration for PUSCH
puschConfig.NLayers = 1;
puschConfig.TxScheme = 'Port0';
puschConfig.Modulation = modulation;
puschConfig.NTurboDecIts = 5;
puschConfig.PRBSet = (0:ueConfig.NULRB-1)';
puschConfig.NBundled = 0;
% Configure control channels
puschConfig.OCQI = 0;
puschConfig.ORI = 0;
puschConfig.OACK = 0;
puschConfig.BetaCQI = 2;
puschConfig.BetaRI = 3;
puschConfig.BetaACK = 1;
info=lteULSCHInfo(ueConfig,puschConfig,transportBlkSize,puschConfig.OCQI,puschConfig.ORI,puschConfig.OACK);
puschConfig.QdACK=info.QdACK;
puschConfig.QdRI=info.QdRI;
puschConfig.QdCQI=info.QdCQI;
switch (modulation)
case 'QPSK'
bitsPerSym = 2;
case '16QAM'
bitsPerSym = 4;
case '64QAM'
bitsPerSym = 6;
end
noiseVarfactor = sqrt(2*bitsPerSym);
snr = 10.^(SNR/10);
nErrors_mat = zeros(length(SNR),length(rvValues));
nErrorsCtrl_mat = zeros(length(SNR),3);
nErrors_srs = zeros(length(SNR),length(rvValues));
nErrorsCtrl_srs = zeros(length(SNR),3);
for k = 1:length(SNR);
subframe=cell(length(rvValues));
puschIdx=ltePUSCHIndices(ueConfig,puschConfig);
for i=1:length(rvValues)
subframe{i} = lteULResourceGrid(ueConfig);
end
blkCounter = 0;
for l = 1:Nblocks;
% UL-SCH data bits
ulschBits = randi([0 1],transportBlkSize,1);
softBuffer = {};
% Control bits
cqi = randi([0 1], puschConfig.OCQI,1);
ri = randi([0 1], puschConfig.ORI,1);
ack = randi([0 1], puschConfig.OACK,1);
for rvIndex = 1:length(rvValues)
% ULSCH transport channel
puschConfig.RV = rvValues(rvIndex);
puschPayload = lteULSCH(ueConfig, puschConfig, ulschBits, cqi, ri, ack);
% PUSCH modulated symbols
puschSymbols = ltePUSCH(ueConfig, puschConfig, puschPayload);
puschSize = size(puschSymbols);
% Addition of noise
noise = (1/noiseVarfactor)*sqrt(1/snr(k))*complex(randn(puschSize),randn(puschSize));
noisySymbols = puschSymbols + noise;
subframe{rvIndex}(puschIdx)=noisySymbols;
% PUSCH Rx-side
[rxCW, puschSymbolsRx] = ltePUSCHDecode(ueConfig, puschConfig, noisySymbols);
if (iscell(rxCW))
rxCW_=rxCW{1};
else
rxCW_=rxCW;
end
% UL-SCH turbo decoding
[rxBits, blkCRCerr, softBuffer,ccqi,cri,cack] = lteULSCHDecode2(ueConfig, puschConfig, ...
transportBlkSize, rxCW_, softBuffer);
% Add errors to previous error counts
nErrors_mat(k,rvIndex) = nErrors_mat(k,rvIndex)+blkCRCerr;
if (rvIndex==1)
ack_rx=lteACKDecode(puschConfig,cack);
ri_rx=lteRIDecode(puschConfig,cri);
cqi_rx=lteCQIDecode(puschConfig,ccqi);
nErrorsCtrl_mat(k,1) = nErrorsCtrl_mat(k,1)+(sum(ack_rx~=ack)>0);
nErrorsCtrl_mat(k,2) = nErrorsCtrl_mat(k,2)+(sum(ri_rx~=ri)>0);
nErrorsCtrl_mat(k,3) = nErrorsCtrl_mat(k,3)+(sum(cqi_rx~=cqi)>0);
end
end
% Same with srsLTE
[okSRSLTE, cqi_rx_srs, ri_rx_srs, ack_rx_srs] = srslte_puscht(ueConfig, puschConfig, ...
transportBlkSize, subframe, ones(size(subframe{1})), 0);
nErrors_srs(k,rvIndex) = nErrors_srs(k,rvIndex)+~okSRSLTE;
if (rvIndex==1)
nErrorsCtrl_srs(k,1) = nErrorsCtrl_srs(k,1)+(sum(ack_rx_srs~=ack)>0);
nErrorsCtrl_srs(k,2) = nErrorsCtrl_srs(k,2)+(sum(ri_rx_srs~=ri)>0);
nErrorsCtrl_srs(k,3) = nErrorsCtrl_srs(k,3)+(sum(cqi_rx_srs~=cqi)>0);
end
end
fprintf('SNR=%.1f dB, BLER_mat=%.2f, BLER_srs=%.2f, BLER_ack=%.2f/%.2f, BLER_ri=%.2f/%.2f, BLER_cqi=%.2f/%.2f\n',...
SNR(k),nErrors_mat(k,rvIndex)/Nblocks, nErrors_srs(k,rvIndex)/Nblocks, ...
nErrorsCtrl_mat(k,1)/Nblocks, nErrorsCtrl_srs(k,1)/Nblocks, ...
nErrorsCtrl_mat(k,3)/Nblocks, nErrorsCtrl_srs(k,2)/Nblocks, ...
nErrorsCtrl_mat(k,2)/Nblocks, nErrorsCtrl_srs(k,3)/Nblocks);
end
puschBLER_mat = nErrors_mat./Nblocks;
puschBLER_mat(puschBLER_mat==0)=10^-10;
puschBLER_srs = nErrors_srs./Nblocks;
puschBLER_srs(puschBLER_srs==0)=10^-10;
puschCtrlBLER_mat = nErrorsCtrl_mat./Nblocks;
puschCtrlBLER_mat(puschCtrlBLER_mat==0)=10^-10;
puschCtrlBLER_srs = nErrorsCtrl_srs./Nblocks;
puschCtrlBLER_srs(puschCtrlBLER_srs==0)=10^-10;
if (Nblocks == 1 && length(SNR) == 1)
else
ctrlplot=1;
if (puschConfig.OCQI+puschConfig.ORI+puschConfig.OACK>0)
ctrlplot=2;
end
subplot(ctrlplot,1,1)
semilogy(SNR,puschBLER_mat,SNR,puschBLER_srs);
grid on
xlabel('Eb/No (dB)')
ylabel('BLER')
leg=[];
for rvIndex = 1:length(rvValues)
leg=strvcat(leg,sprintf('Matlab rv=%d',rvValues(rvIndex)));
end
for rvIndex = 1:length(rvValues)
leg=strvcat(leg,sprintf('srsLTE rv=%d',rvValues(rvIndex)));
end
axis([min(SNR) max(SNR) 10^-4 1])
if (ctrlplot==2)
subplot(2,1,2)
semilogy(SNR,puschCtrlBLER_mat,SNR,puschCtrlBLER_srs)
grid on
xlabel('Eb/No (dB)')
ylabel('BLER')
leg=[];
leg=strvcat(leg,'Matlab ACK','Matlab RI', 'Matlab CQI');
leg=strvcat(leg,'srsLTE ACK','srsLTE RI', 'srsLTE CQI');
legend(leg);
axis([min(SNR) max(SNR) 10^-4 1])
end
end

@ -1,20 +0,0 @@
ueConfig=struct('NCellID',1,'NULRB',15,'NSubframe',0,'RNTI',30,'CyclicPrefixUL','Normal','NTxAnts',1,'Shortened',0);
puschConfig=struct('NTurboDecIts',5,'NLayers',1,'OrthCover','Off','PRBSet',(0:14)','Modulation','QPSK','RV',0);
TBS=392;
cfo=0;
t0=1;
x=[rx(t0:end); zeros(t0-1,1)];
x=lteFrequencyCorrect(ueConfig,x,cfo);
subframe_rx=lteSCFDMADemodulate(ueConfig,x);
idx=ltePUSCHIndices(ueConfig,puschConfig);
pusch_rx=subframe_rx(idx);
dmrs_rx=subframe_rx(ltePUSCHDRSIndices(ueConfig,puschConfig));
[hest, noiseest] = lteULChannelEstimate(ueConfig,puschConfig,subframe_rx);
ce=hest(idx);
[cws,symbols] = ltePUSCHDecode(ueConfig,puschConfig,pusch_rx,ce,noiseest);
[trblkout,blkcrc,stateout] = lteULSCHDecode(ueConfig,puschConfig,TBS,cws);
disp(blkcrc)
scatter(real(symbols),imag(symbols))
%plot(angle(hest(:,1)))

@ -1,67 +0,0 @@
ueConfig=struct('NCellID',1,'NULRB',6,'CyclicPrefixUL','Normal','NTxAnts',1,'RNTI',64);
puschConfig=struct('NLayers',1,'OrthCover','Off','Shortened',0,'NBundled',0);
addpath('../../build//srslte/lib/phch/test')
cqilen=0;%[0 4 20];
mods={'64QAM'};
rvs=0;
betas=0;%[0 5.0, 20.0];
for p=1
for i=0:26
for m=1:length(mods)
for r=1:length(rvs)
for bri=1:length(betas)
for back=1:length(betas)
for c=1:length(cqilen)
for s=0:9
ueConfig.NSubframe=s;
puschConfig.PRBSet=(0:p-1)';
TBs=lteTBS(length(puschConfig.PRBSet),i);
%TBs=256;
%trblkin=randi(2,TBs,1)-1;
trblkin=ones(1,TBs);
puschConfig.Modulation = mods{m};
puschConfig.RV = rvs(r);
puschConfig.BetaCQI = 5;
puschConfig.BetaRI = betas(bri);
puschConfig.BetaACK = betas(back);
if (betas(bri)>0)
ri_bit=randi(2,1,1)-1;
else
ri_bit=[];
end
if (betas(back)>0)
ack_bit=randi(2,1,1)-1;
else
ack_bit=[];
end
if (cqilen(c)>0 || TBs>0)
[enc, info]=lteULSCH(ueConfig,puschConfig,trblkin,ones(1,cqilen(c)),ri_bit,ack_bit);
cw_mat=ltePUSCH(ueConfig,puschConfig,enc);
%[drs, infodrs]=ltePUSCHDRS(ueConfig,puschConfig);
idx=ltePUSCHIndices(ueConfig,puschConfig);
%drs_idx=ltePUSCHDRSIndices(ueConfig,puschConfig);
subframe_mat = lteULResourceGrid(ueConfig);
subframe_mat(idx)=cw_mat;
[~, subframe_lib, cwlib, bits]=srslte_pusch_encode(ueConfig,puschConfig,trblkin,ones(1,cqilen(c)),ri_bit,ack_bit);
err=max(abs(subframe_mat(:)-subframe_lib));
if (err > 10^-5)
plot(abs(subframe_mat(:)-subframe_lib))
error('Error!');
end
end
end
end
end
end
end
end
end
end

@ -1,43 +0,0 @@
clear
enbConfig=struct('NCellID',1,'CyclicPrefix','Normal','CellRefP',1);
pdschConfig=struct('Modulation','QPSK','RV',0,'TxScheme','Port0');
addpath('../../build/srslte/lib/fec/test')
codewordLen = 12000;
trBlkLenVec = 6201;
error=zeros(size(trBlkLenVec));
for i=1:length(trBlkLenVec)
trBlkLen=trBlkLenVec(i);
in=randi(2,trBlkLen,1)-1;
RV = 0;
trblockwithcrc = lteCRCEncode(in,'24A');
codeblocks = lteCodeBlockSegment(trblockwithcrc);
turbocodedblocks = lteTurboEncode(codeblocks);
codeword = lteRateMatchTurbo(turbocodedblocks,codewordLen,RV);
info = lteDLSCHInfo(trBlkLen);
mat = lteRateRecoverTurbo(codeword,trBlkLen,RV);
mat2 = reshape(reshape(mat{1},[],3)',[],1);
out = lteTurboDecode(mat{1});
lib=srslte_rm_turbo_rx(double(codeword),trBlkLen,RV);
[outLib] = srslte_turbodecoder(lib);
if (length(trBlkLenVec) == 1)
% fprintf('Err mat: %d. Err lib: %d\n',sum(out(1+info.F:trBlkLen+info.F)~=in),sum(outLib(1+info.F:trBlkLen+info.F)~=in));
end
error(i)=mean(abs(double(mat2)-double(lib)));
end
if (length(trBlkLenVec) == 1)
n=1:length(mat{1});
plot(abs(double(mat2)-double(lib)))
%plot(n,mat{1},n,lib)
else
plot(error)
end

@ -1,47 +0,0 @@
clear
ueConfig=struct('NCellID',1,'NULRB',100,'DuplexMode','FDD','NSubframe',0,'CyclicPrefixUL','Normal','NTxAnts',1);
srsConfig=struct('NTxAnts',1,'ConfigIdx',317,'SeqGroup',1,'SeqIdx',0,'TxComb',0);
addpath('../../build/srslte/lib/ch_estimation/test')
for k=0:50
for csbw=0:7
for uebw=0:3
for hop=0:3
for ncs=0
for n_rrc=1:5:20
ueConfig.NFrame=mod(32*k,1024);
srsConfig.BWConfig = csbw;
srsConfig.BW = uebw;
srsConfig.CyclicShift = ncs;
srsConfig.HoppingBW = hop;
srsConfig.FreqPosition = n_rrc;
fprintf('Testing SRS: Nframe=%d, CSBW=%d, UEBW=%d, b_hop=%d n_rrc=%d\n',ueConfig.NFrame, csbw, uebw, hop, n_rrc);
[sym_mat, info]=lteSRS(ueConfig,srsConfig);
[idx, info2]=lteSRSIndices(ueConfig,srsConfig);
subframe_mat = lteULResourceGrid(ueConfig);
subframe_mat(idx)=sym_mat;
[sym, subframe]=srslte_refsignal_srs(ueConfig,srsConfig);
error_sym=max(abs(sym-sym_mat));
error_sf=max(abs(subframe_mat(:)-subframe));
if (error_sym > 3.5e-3)
disp(info)
plot(abs(sym-sym_mat))
legend('srsLTE','Matlab')
error('Error in symbols');
end
if (error_sf > 3.5e-3)
disp(info2)
plot(abs(subframe-subframe_mat(:)))
error('Error in subframe');
end
end
end
end
end
end
end

@ -1,144 +0,0 @@
SNR_values = linspace(-6,4,10);
Npackets = 200;
CFO=4/15;
m0=7;
m1=10;
%m0=26;
%m1=21;
recordedWaveform = x;
if (~isempty(recordedWaveform))
Npackets = floor(length(recordedWaveform)/19200)-1;
SNR_values = 0;
end
error = zeros(6,length(SNR_values));
enb = struct('NCellID',2,'NSubframe',0,'NDLRB',6,'CellRefP',1,'CyclicPrefix','Normal','DuplexMode','FDD');
sss=lteSSS(enb);
cfg.Seed = 2; % Random channel seed
cfg.NRxAnts = 1; % 1 receive antenna
cfg.DelayProfile = 'ETU'; % EVA delay spread
cfg.DopplerFreq = 144; % 120Hz Doppler frequency
cfg.MIMOCorrelation = 'Low'; % Low (no) MIMO correlation
cfg.NTerms = 16; % Oscillators used in fading model
cfg.ModelType = 'GMEDS'; % Rayleigh fading model type
cfg.InitPhase = 'Random'; % Random initial phases
cfg.NormalizePathGains = 'On'; % Normalize delay profile power
cfg.NormalizeTxAnts = 'On'; % Normalize for transmit antennas % Initialize at time zero
[s, c0, c1] = get_sc(mod(enb.NCellID,3));
subframe = lteDLResourceGrid(enb);
sssSym = lteSSS(enb);
sssInd = lteSSSIndices(enb);
subframe(sssInd) = sssSym;
N_id_1 = floor(enb.NCellID/3);
[txWaveform,info] = lteOFDMModulate(enb,subframe);
cfg.SamplingRate = info.SamplingRate;
fftSize = info.Nfft;
addpath('../../debug/lte/phy/lib/sync/test')
for snr_idx=1:length(SNR_values)
SNRdB = SNR_values(snr_idx);
for i=1:Npackets
%% Noise Addition
SNR = 10^(SNRdB/10); % Linear SNR
if (isempty(recordedWaveform))
cfg.InitTime = i*(10^-3);
[rxWaveform, info]= lteFadingChannel(cfg,txWaveform);
rxWaveform = txWaveform;
% Add CFO
freq = CFO/double(fftSize);
rxWaveform = rxWaveform.*exp(1i*2*pi*freq*(1:length(txWaveform))');
N0 = 1/(sqrt(2.0*enb.CellRefP*double(fftSize))*SNR);
noise = N0*complex(randn(size(rxWaveform)), randn(size(rxWaveform))); % Generate noise
rxWaveform = rxWaveform + noise;
else
rxWaveform = recordedWaveform(i*19200+1:(i+1)*19200);
end
offset = lteDLFrameOffset(enb,rxWaveform);
offsetVec(i)=offset;
rxWaveform = [rxWaveform(1+offset:end,:); zeros(offset,1)];
subframe_rx = lteOFDMDemodulate(enb,rxWaveform,1);
sss_rx = subframe_rx(lteSSSIndices(enb));
sss0=sss_rx(1:2:end);
sss1=sss_rx(2:2:end);
beta0=sss0.*c0';
beta1=sss1.*c1';
corr0=zeros(31,1);
for m=1:31
corr0(m)=sum(beta0.*s(m,:)');
end
corr0=abs(corr0).^2;
[m, idx]=max(corr0);
error(1,snr_idx) = error(1,snr_idx) + ((idx ~= m0 && idx ~= m1));
M=2;
Nm=10;
corr2=zeros(31,1);
for m=1:31
for j=0:M
idx=1+j*Nm:(j+1)*Nm;
corr2(m)=corr2(m)+abs(sum(beta0(idx).*s(m,idx)')).^2;
end
end
[m, idx]=max(corr2);
error(2,snr_idx) = error(2,snr_idx) + ((idx ~= m0 && idx ~= m1));
corr3=zeros(31,1);
for m=1:31
corr3(m)=abs(sum(beta0(2:end).*conj(beta0(1:end-1)).*transpose(s(m,2:end).*conj(s(m,1:end-1))))).^2;
end
[m, idx]=max(corr3);
error(3,snr_idx) = error(3,snr_idx) + ((idx ~= m0 && idx ~= m1));
% srsLTE results
[n,sf_idx,lt_corr0]=srslte_sss(enb,rxWaveform,'full');
[m, idx]=max(lt_corr0);
error(4,snr_idx) = error(4,snr_idx) + ((idx ~= m0 && idx ~= m1));
[n,sf_idx,lt_corr2]=srslte_sss(enb,rxWaveform,'partial');
[m, idx]=max(lt_corr2);
error(5,snr_idx) = error(5,snr_idx) + ((idx ~= m0 && idx ~= m1));
[n,sf_idx,lt_corr3]=srslte_sss(enb,rxWaveform,'diff');
[m, idx]=max(lt_corr3);
error(6,snr_idx) = error(6,snr_idx) + ((idx ~= m0 && idx ~= m1));
end
end
if (length(SNR_values) > 1)
plot(SNR_values,1-error/Npackets)
legend('Full','Partial','Differential','Full-lt','Partial-lt','Differential-lt')
grid on
else
e=error/Npackets;
fprintf('Full (mt/lt): \t%f/%f\n',e(1),e(4));
fprintf('Partial (mt/lt):%f/%f\n',e(2),e(5));
fprintf('Diff (mt/lt): \t%f/%f\n',e(3),e(6));
end

@ -1,96 +0,0 @@
clear
enb = lteTestModel('1.1','1.4MHz');
Ntrials = 1;
SNR_values = 100;%linspace(-8,0,6);
flen=1920;
fft_size=128;
fading_enabled = true;
tx_offset = 10;%randi(50,1,Ntrials);
tx_signal = lteTestModelTool(enb);
pss_idx = flen/2-fft_size+1:flen/2;
pss_signal=tx_signal(pss_idx);
tx_power = mean(pss_signal.*conj(pss_signal));
corrcfg.PSS='On';
corrcfg.SSS='On';
corrcfg.CellRS='Off';
cfg.Seed = 0; % Random channel seed
cfg.NRxAnts = 1; % 1 receive antenna
cfg.DelayProfile = 'ETU'; % EVA delay spread
cfg.DopplerFreq = 120; % 120Hz Doppler frequency
cfg.MIMOCorrelation = 'Low'; % Low (no) MIMO correlation
cfg.InitTime = 0; % Initialize at time zero
cfg.NTerms = 16; % Oscillators used in fading model
cfg.ModelType = 'GMEDS'; % Rayleigh fading model type
cfg.InitPhase = 'Random'; % Random initial phases
cfg.NormalizePathGains = 'On'; % Normalize delay profile power
cfg.NormalizeTxAnts = 'On'; % Normalize for transmit antennas
cfg.SamplingRate = flen*1000;
addpath('../../build/srslte/lib/sync/test')
addpath('../sync/')
t = (0:length(tx_signal)-1).'/fft_size;
L=fft_size;
M=4;
diff=zeros(length(SNR_values),M);
for snr_idx=1:length(SNR_values)
fprintf('SNR=%.1f dB\n', SNR_values(snr_idx));
SNRdB = SNR_values(snr_idx);
rx_offset = zeros(M,length(tx_offset));
for i=1:Ntrials
if fading_enabled
[rx_signal, chinfo] = lteFadingChannel(cfg,tx_signal);
else
rx_signal = tx_signal;
end
SNR = 10^(SNRdB/10); % Linear SNR
rx = [zeros(tx_offset(i),1); rx_signal];
N0 = tx_power/(sqrt(2.0)*SNR);
noise = N0*complex(randn(size(rx)), randn(size(rx))); % Generate noise
rx=noise+rx;
[rx_offset(1,i),corr_res] = lteDLFrameOffset(enb,rx(1:flen),corrcfg);
% srsLTE in find mode
[rx_offset(2,i),corr_lt] = srslte_pss(enb,rx(1:flen));
rx_offset(2,i) = rx_offset(2,i) - flen/2;
% srsLTE in tracking mode
track_offset=2+rx_offset(2,i)+flen/2-fft_size-L/2;
[rx_offset(3,i),corr_lt_track] = srslte_pss(enb,rx(track_offset:end),L);
rx_offset(3,i) = rx_offset(2,i) + (rx_offset(3,i) - L/2) + 1;
% CP based
[rx_offset(4,i), corr_lt_cp] = srslte_cp_synch(enb, rx);
end
if fading_enabled
ch_delay = chinfo.ChannelFilterDelay;
else
ch_delay = 0;
end
diff(snr_idx,:)=mean(abs(rx_offset-repmat(tx_offset,M,1) - ch_delay),2);
end
if (Ntrials == 1)
disp(rx_offset)
disp(diff)
%plot(1:flen,abs(corr_res(1:flen)),1:flen,abs(corr_lt(1:flen)));
t=1:L;
plot(t,abs(corr_lt_track(t)));
%plot(lambda)
%plot(1:L,abs(corr_lt_track),[L/2, L/2], [0 max(abs(corr_lt_track))])
grid on
else
plot(SNR_values,diff);
legend('Matlab','srs find','srs tracking','srs cp')
grid on
xlabel('SNR (dB)')
ylabel('Avg time offset')
end

@ -1,32 +0,0 @@
clear
enbConfig=struct('NCellID',0,'DuplexMode','TDD','CyclicPrefix','Normal','CellRefP',1,'CFI',2,'NDLRB',25,'NSubframe',4,'CyclicPrefixUL','Normal','NTxAnts',1);
pdschConfig=struct('NLayers',1,'TxScheme','Port0','OrthCover','Off','PRBSet',0,'RNTI',82,'Modulation','QPSK','RV',0,'Shortened',0);
addpath('../../debug/lte/phy/lib/phch/test')
NDLRB=[6 15 25 50 100];
Peak=[];
k=1;
for r=1:length(NDLRB)
fprintf('NDLRB: %d\n',NDLRB(r));
for l=1:NDLRB(r)
trblkin=randi(2,l*5,1)-1;
enbConfig.NDLRB=NDLRB(r);
pdschConfig.PRBSet=(0:(l-1))';
idx=ltePDSCHIndices(enbConfig,pdschConfig,pdschConfig.PRBSet);
[cw, info]=lteDLSCH(enbConfig,pdschConfig,2*length(idx),trblkin);
cw_mat=ltePDSCH(enbConfig,pdschConfig,cw);
subframe_mat = lteDLResourceGrid(enbConfig);
subframe_mat(idx)=cw_mat;
waveform = lteOFDMModulate(enbConfig,subframe_mat,0);
waveform = waveform*sqrt(512)/sqrt(l)*NDLRB(r)/15;
Peak(k)=max(max(abs(real(waveform))),max(abs(imag(waveform))));
k=k+1;
end
end
plot(Peak(:)')

@ -1,26 +0,0 @@
clear
ue = struct('NULRB',6,'NDLRB',6);
d = lteULResourceGridSize(ue);
rgrid = complex(rand(d)-0.5,rand(d)-0.5);
waveform = lteSCFDMAModulate(ue,rgrid,0);
wave = [];
freq_correct=[];
for i=1:14
symbol = ifft(ifftshift([zeros(28,1); rgrid(:,i); zeros(28,1)]),128);
if (i==1 || i==8)
cp_len=10;
else
cp_len=9;
end
symbol_cp=[symbol((128-cp_len+1):128); symbol(1:128)];
freq_correct=[freq_correct; exp(1i*pi*(-cp_len:127)'/128)];
wave = [wave; symbol_cp];
end
wave=wave.*freq_correct;
%wave=transpose(wave);
%plot(1:138,fftshift(fft(waveform(1:138))),1:138,fftshift(fft(wave(1:138))))
plot(abs(wave(1:138)-waveform(1:138)))
mean(abs(wave-waveform))

@ -1,32 +0,0 @@
clear
ueConfig=struct('NCellID',0,'NULRB',25,'NSubframe',4,'RNTI',82,'CyclicPrefixUL','Normal','NTxAnts',1);
puschConfig=struct('NLayers',1,'OrthCover','Off','PRBSet',0,'Modulation','QPSK','RV',0,'Shortened',0);
addpath('../../debug/lte/phy/lib/phch/test')
NULRB=[6 15 25 50 100];
Peak=[];
k=1;
for r=1:length(NULRB)
fprintf('NULRB: %d\n',NULRB(r));
for l=1:NULRB(r)
trblkin=randi(2,l*5,1)-1;
ueConfig.NULRB=NULRB(r);
puschConfig.PRBSet=(0:(l-1))';
[cw, info]=lteULSCH(ueConfig,puschConfig,trblkin);
cw_mat=ltePUSCH(ueConfig,puschConfig,cw);
idx=ltePUSCHIndices(ueConfig,puschConfig);
subframe_mat = lteULResourceGrid(ueConfig);
subframe_mat(idx)=cw_mat;
waveform = lteSCFDMAModulate(ueConfig,subframe_mat,0);
waveform = waveform*sqrt(512)/sqrt(l)*NULRB(r)/10;
Peak(k)=max(max(abs(real(waveform))),max(abs(imag(waveform))));
k=k+1;
end
end
plot(Peak(:)')

@ -1,51 +0,0 @@
clear
blen=5184;
SNR_values_db=linspace(-1.3,-0.7,6);
Nrealizations=600;
addpath('../../build/srslte/lib/fec/test')
errors1=zeros(1,length(SNR_values_db));
errors2=zeros(1,length(SNR_values_db));
for snr_idx=1:length(SNR_values_db)
SNRdB = SNR_values_db(snr_idx); % Desired SNR in dB
SNR = 10^(SNRdB/20); % Linear SNR
for i=1:Nrealizations
Data = randi(2,blen,1)==1;
codedData = lteTurboEncode(Data);
codedsymbols = 2*double(codedData)-1;
%% Additive Noise
N0 = 1/SNR;
% Create additive white Gaussian noise
noise = N0*randn(size(codedsymbols));
noisysymbols = noise + codedsymbols;
decodedData = lteTurboDecode(noisysymbols);
interleavedSymbols = reshape(reshape(noisysymbols,[],3)',1,[]);
[decodedData2] = srslte_turbodecoder(interleavedSymbols);
errors1(snr_idx) = errors1(snr_idx) + any(decodedData ~= Data);
errors2(snr_idx) = errors2(snr_idx) + any(decodedData2 ~= Data);
end
fprintf('SNR: %.2f BLER: %f-%f\n', SNR_values_db(snr_idx), ...
errors1(snr_idx)/Nrealizations, errors2(snr_idx)/Nrealizations);
end
if (length(SNR_values_db) > 1)
semilogy(SNR_values_db, errors1/Nrealizations, ...
SNR_values_db, errors2/Nrealizations)
grid on
xlabel('SNR (dB)')
ylabel('BLER')
legend('Matlab','srsLTE');
else
disp(errors1);
disp(errors2);
end

@ -1,67 +0,0 @@
clear
ueConfig=struct('NCellID',1,'CyclicPrefixUL','Normal','NTxAnts',1);
puschConfig=struct('NLayers',1,'OrthCover','Off','Shortened',0);
addpath('/home/ismael/work/srsLTE/debug/srslte/lib/phch/test')
cqilen=[0 20];
mods={'QPSK','16QAM', '64QAM'};
rvs=0;
betas=[0 2.0 2.5 5.0, 20.0];
for p=1:100
for i=0:26
for m=1:length(mods)
for r=1:length(rvs)
for bri=1:length(betas)
for back=1:length(betas)
for c=1:length(cqilen)
puschConfig.PRBSet=(0:p-1)';
TBs=lteTBS(length(puschConfig.PRBSet),i);
%TBs=256;
%trblkin=randi(2,TBs,1)-1;
trblkin=ones(1,TBs);
puschConfig.Modulation = mods{m};
puschConfig.RV = rvs(r);
puschConfig.BetaCQI = 5;
puschConfig.BetaRI = betas(bri);
puschConfig.BetaACK = betas(back);
if (betas(bri)>0)
ri_bit=randi(2,1,1)-1;
else
ri_bit=[];
end
if (betas(back)>0)
ack_bit=randi(2,1,1)-1;
else
ack_bit=[];
end
if (cqilen(c)>0 || TBs>0)
[lib]=srslte_ulsch_encode(ueConfig,puschConfig,trblkin,ones(1,cqilen(c)),ri_bit,ack_bit);
[mat, info]=lteULSCH(ueConfig,puschConfig,trblkin,ones(1,cqilen(c)),ri_bit,ack_bit,[]);
mat(mat==-2)=0;
mat(mat==-1)=0;
err=sum(abs(double(mat)-double(lib)));
if (err > 0)
disp(err)
plot(abs(double(mat)-double(lib)))
error('Error!');
end
end
end
end
end
end
end
end
end
if (length(TBs) == 1)
%disp(info)
n=1:length(mat);
%plot(abs(double(mat)-double(lib)))
plot(n,lib(n),n,mat(n))
end

@ -1,49 +0,0 @@
clear
blen=40;
SNR_values_db=linspace(-3,4,8);
Nrealizations=50000;
addpath('../../build/srslte/lib/fec/test')
errors1=zeros(1,length(SNR_values_db));
errors2=zeros(1,length(SNR_values_db));
for snr_idx=1:length(SNR_values_db)
SNRdB = SNR_values_db(snr_idx); % Desired SNR in dB
SNR = 10^(SNRdB/20); % Linear SNR
for i=1:Nrealizations
Data = randi(2,blen,1)==1;
codedData = lteConvolutionalEncode(Data);
codedsymbols = 2*double(codedData)-1;
%% Additive Noise
N0 = 1/SNR;
% Create additive white Gaussian noise
noise = N0*randn(size(codedsymbols));
noisysymbols = noise + codedsymbols;
decodedData = lteConvolutionalDecode(noisysymbols);
interleavedSymbols = reshape(reshape(noisysymbols,[],3)',1,[]);
[decodedData2, quant] = srslte_viterbi(interleavedSymbols, 32);
errors1(snr_idx) = errors1(snr_idx) + any(decodedData ~= Data);
errors2(snr_idx) = errors2(snr_idx) + any(decodedData2 ~= Data);
end
end
if (length(SNR_values_db) > 1)
semilogy(SNR_values_db, errors1/Nrealizations, ...
SNR_values_db, errors2/Nrealizations)
grid on
xlabel('SNR (dB)')
ylabel('BLER')
legend('Matlab','srsLTE');
else
disp(errors1);
disp(errors2);
disp(errors3);
end

@ -1,49 +0,0 @@
#
# Copyright 2013-2015 Software Radio Systems Limited
#
# This file is part of the srsLTE library.
#
# srsLTE is free software: you can redistribute it and/or modify
# it under the terms of the GNU Affero General Public License as
# published by the Free Software Foundation, either version 3 of
# the License, or (at your option) any later version.
#
# srsLTE is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU Affero General Public License for more details.
#
# A copy of the GNU Affero General Public License can be found in
# the LICENSE file in the top-level directory of this distribution
# and at http://www.gnu.org/licenses/.
#
if(NOT DisableMEX)
########################################################################
# Install headers
########################################################################
INSTALL(DIRECTORY include/
DESTINATION "${INCLUDE_DIR}"
FILES_MATCHING PATTERN "*.h"
PATTERN ".svn" EXCLUDE
)
########################################################################
# Add headers to cmake project (useful for IDEs)
########################################################################
set(HEADERS_ALL "")
file(GLOB headers *)
FOREACH (_header ${headers})
if(IS_DIRECTORY ${_header})
file(GLOB_RECURSE tmp "${_header}/*.h")
list(APPEND HEADERS_ALL ${tmp})
endif(IS_DIRECTORY ${_header})
ENDFOREACH()
add_custom_target (add_mex_headers SOURCES ${HEADERS_ALL})
########################################################################
# Add the subdirectories
########################################################################
add_subdirectory(lib)
endif()

@ -1,103 +0,0 @@
/**
*
* \section COPYRIGHT
*
* Copyright 2013-2015 Software Radio Systems Limited
*
* \section LICENSE
*
* This file is part of the srsLTE library.
*
* srsLTE is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as
* published by the Free Software Foundation, either version 3 of
* the License, or (at your option) any later version.
*
* srsLTE is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* A copy of the GNU Affero General Public License can be found in
* the LICENSE file in the top-level directory of this distribution
* and at http://www.gnu.org/licenses/.
*
*/
#ifndef MEXUTILS_
#define MEXUTILS_
#ifdef UNDEF_BOOL
#undef bool
#endif
#include "mex.h"
#include <stdbool.h>
#include "srslte/config.h"
#include "srslte/common/phy_common.h"
SRSLTE_API bool mexutils_isScalar(const mxArray *ptr);
SRSLTE_API bool mexutils_isCell(const mxArray *ptr);
SRSLTE_API int mexutils_getLength(const mxArray *ptr);
SRSLTE_API mxArray* mexutils_getCellArray(const mxArray *ptr, int idx);
SRSLTE_API int mexutils_read_cell(const mxArray *ptr,
srslte_cell_t *cell);
SRSLTE_API char *mexutils_get_char_struct(const mxArray *ptr,
const char *field_name);
SRSLTE_API int mexutils_read_uint32_struct(const mxArray *ptr,
const char *field_name,
uint32_t *value);
SRSLTE_API int mexutils_read_float_struct(const mxArray *ptr,
const char *field_name,
float *value);
SRSLTE_API int mexutils_write_f(float *buffer,
mxArray **ptr,
uint32_t nr,
uint32_t nc);
SRSLTE_API int mexutils_write_s(short *buffer,
mxArray **ptr,
uint32_t nr,
uint32_t nc);
SRSLTE_API int mexutils_write_cf(cf_t *buffer,
mxArray **ptr,
uint32_t nr,
uint32_t nc);
SRSLTE_API int mexutils_write_uint8(uint8_t *buffer,
mxArray **ptr,
uint32_t nr,
uint32_t nc);
SRSLTE_API int mexutils_write_int(int *buffer,
mxArray **ptr,
uint32_t nr,
uint32_t nc);
SRSLTE_API int mexutils_read_uint8(const mxArray *ptr,
uint8_t **buffer);
SRSLTE_API int mexutils_read_uint64(const mxArray *ptr,
uint64_t **buffer);
SRSLTE_API int mexutils_read_f(const mxArray *ptr,
float **buffer);
SRSLTE_API int mexutils_read_cf(const mxArray *ptr,
cf_t **buffer);
#endif

@ -1,63 +0,0 @@
#
# Copyright 2013-2015 Software Radio Systems Limited
#
# This file is part of the srsLTE library.
#
# srsLTE is free software: you can redistribute it and/or modify
# it under the terms of the GNU Affero General Public License as
# published by the Free Software Foundation, either version 3 of
# the License, or (at your option) any later version.
#
# srsLTE is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU Affero General Public License for more details.
#
# A copy of the GNU Affero General Public License can be found in
# the LICENSE file in the top-level directory of this distribution
# and at http://www.gnu.org/licenses/.
#
if(NOT MATLAB_FOUND)
find_package(MATLAB)
endif()
if(NOT OCTAVE_FOUND)
find_package(OCTAVE)
endif()
# CMake 2.8.12 & earlier apparently don't define the
# Mex script path, so find it.
if(NOT MATLAB_MEX_PATH)
find_program( MATLAB_MEX_PATH mex
HINTS ${MATLAB_ROOT}/bin
PATHS ${MATLAB_ROOT}/bin
DOC "The mex program path"
)
endif()
if(MATLAB_FOUND)
message(STATUS "Found MATLAB in ${MATLAB_ROOT}")
add_library(srslte_mex SHARED mexutils.c)
install(TARGETS srslte_mex DESTINATION ${LIBRARY_DIR})
SRSLTE_SET_PIC(srslte_mex)
include_directories(${MATLAB_INCLUDE_DIR})
endif(MATLAB_FOUND)
if(OCTAVE_FOUND)
message(STATUS "Found OCTAVE in ${OCTAVE_INCLUDE_PATHS}")
if (NOT MATLAB_FOUND)
add_library(srslte_mex SHARED mexutils.c)
install(TARGETS srslte_mex DESTINATION ${LIBRARY_DIR})
SRSLTE_SET_PIC(srslte_mex)
endif (NOT MATLAB_FOUND)
include_directories(${OCTAVE_INCLUDE_DIR})
endif(OCTAVE_FOUND)
if(NOT MATLAB_FOUND)
if(NOT OCTAVE_FOUND)
message(STATUS "Could NOT find OCTAVE or MATLAB. MEX files won't be compiled")
endif(NOT OCTAVE_FOUND)
endif(NOT MATLAB_FOUND)

@ -1,249 +0,0 @@
/**
*
* \section COPYRIGHT
*
* Copyright 2013-2015 Software Radio Systems Limited
*
* \section LICENSE
*
* This file is part of the srsLTE library.
*
* srsLTE is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as
* published by the Free Software Foundation, either version 3 of
* the License, or (at your option) any later version.
*
* srsLTE is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* A copy of the GNU Affero General Public License can be found in
* the LICENSE file in the top-level directory of this distribution
* and at http://www.gnu.org/licenses/.
*
*/
#include <string.h>
#include <complex.h>
#include "srslte/mex/mexutils.h"
#include "srslte/utils/vector.h"
#include "srslte/common/phy_common.h"
bool mexutils_isScalar(const mxArray *ptr) {
return mxGetM(ptr) == 1 && mxGetN(ptr) == 1;
}
bool mexutils_isCell(const mxArray *ptr) {
return mxIsCell(ptr);
}
int mexutils_getLength(const mxArray *ptr) {
const mwSize *dims;
dims = mxGetDimensions(ptr);
return dims[0];
}
mxArray* mexutils_getCellArray(const mxArray *ptr, int idx) {
return mxGetCell(ptr, idx);
}
char *mexutils_get_char_struct(const mxArray *ptr, const char *field_name) {
mxArray *p;
p = mxGetField(ptr, 0, field_name);
if (!p) {
return "";
}
if (mxIsCell(p)) {
return mxArrayToString(mxGetCell(p,0));
} else {
return mxArrayToString(p);
}
}
int mexutils_read_uint32_struct(const mxArray *ptr, const char *field_name, uint32_t *value)
{
mxArray *p;
p = mxGetField(ptr, 0, field_name);
if (!p) {
return -1;
}
*value = (uint32_t) mxGetScalar(p);
return 0;
}
int mexutils_read_float_struct(const mxArray *ptr, const char *field_name, float *value)
{
mxArray *p;
p = mxGetField(ptr, 0, field_name);
if (!p) {
return -1;
}
*value = (float) mxGetScalar(p);
return 0;
}
int mexutils_read_cell(const mxArray *ptr, srslte_cell_t *cell) {
if (mexutils_read_uint32_struct(ptr, "NCellID", &cell->id)) {
return -1;
}
if (mexutils_read_uint32_struct(ptr, "CellRefP", &cell->nof_ports)) {
return -1;
}
if (mexutils_read_uint32_struct(ptr, "NDLRB", &cell->nof_prb)) {
return -1;
}
if (!strcmp(mexutils_get_char_struct(ptr, "CyclicPrefix"), "Extended")) {
cell->cp = SRSLTE_CP_EXT;
} else {
cell->cp = SRSLTE_CP_NORM;
}
if (!strcmp(mexutils_get_char_struct(ptr, "PHICHDuration"), "Extended")) {
cell->phich_length = SRSLTE_PHICH_EXT;
} else {
cell->phich_length = SRSLTE_PHICH_NORM;
}
if (!strcmp(mexutils_get_char_struct(ptr, "Ng"), "Sixth")) {
cell->phich_resources = SRSLTE_PHICH_R_1_6;
} else if (!strcmp(mexutils_get_char_struct(ptr, "Ng"), "Half")) {
cell->phich_resources = SRSLTE_PHICH_R_1_2;
} else if (!strcmp(mexutils_get_char_struct(ptr, "Ng"), "Two")) {
cell->phich_resources = SRSLTE_PHICH_R_2;
} else {
cell->phich_resources = SRSLTE_PHICH_R_1;
}
return 0;
}
int mexutils_read_cf(const mxArray *ptr, cf_t **buffer) {
int numelems = mxGetNumberOfElements(ptr);
cf_t *tmp = srslte_vec_malloc(numelems * sizeof(cf_t));
if (tmp) {
double *inr=mxGetPr(ptr);
double *ini=mxGetPi(ptr);
for (int i=0;i<numelems;i++) {
__real__ tmp[i] = (float) inr[i];
if (ini) {
__imag__ tmp[i] = (float) ini[i];
} else {
__imag__ tmp[i] = 0;
}
}
*buffer = tmp;
return numelems;
} else {
return -1;
}
}
int mexutils_read_f(const mxArray *ptr, float **buffer) {
int numelems = mxGetNumberOfElements(ptr);
float *tmp = srslte_vec_malloc(numelems * sizeof(float));
if (tmp) {
double *inr=mxGetPr(ptr);
for (int i=0;i<numelems;i++) {
tmp[i] = (float) inr[i];
}
*buffer = tmp;
return numelems;
} else {
return -1;
}
}
int mexutils_read_uint8(const mxArray *ptr, uint8_t **buffer) {
int numelems = mxGetNumberOfElements(ptr);
uint8_t *tmp = srslte_vec_malloc(numelems * sizeof(uint8_t));
if (tmp) {
double *inr=mxGetPr(ptr);
for (int i=0;i<numelems;i++) {
tmp[i] = (uint8_t) inr[i];
}
*buffer = tmp;
return numelems;
} else {
return -1;
}
}
int mexutils_read_uint64(const mxArray *ptr, uint64_t **buffer) {
int numelems = mxGetNumberOfElements(ptr);
uint64_t *tmp = srslte_vec_malloc(numelems * sizeof(uint64_t));
if (tmp) {
uint64_t *inr=(uint64_t*) mxGetPr(ptr);
for (int i=0;i<numelems;i++) {
tmp[i] = (uint64_t) inr[i];
}
*buffer = tmp;
return numelems;
} else {
return -1;
}
}
int mexutils_write_cf(cf_t *buffer, mxArray **ptr, uint32_t nr, uint32_t nc) {
*ptr = mxCreateDoubleMatrix(nr, nc, mxCOMPLEX);
if (*ptr) {
double *outr = mxGetPr(*ptr);
double *outi = mxGetPi(*ptr);
for (int i=0;i<nr*nc;i++) {
outr[i] = (double) crealf(buffer[i]);
outi[i] = (double) cimagf(buffer[i]);
}
return nc*nr;
} else {
return -1;
}
}
int mexutils_write_f(float *buffer, mxArray **ptr, uint32_t nr, uint32_t nc) {
*ptr = mxCreateDoubleMatrix(nr, nc, mxREAL);
if (*ptr) {
double *outr = mxGetPr(*ptr);
for (int i=0;i<nr*nc;i++) {
outr[i] = (double) buffer[i];
}
return nc*nr;
} else {
return -1;
}
}
int mexutils_write_s(short *buffer, mxArray **ptr, uint32_t nr, uint32_t nc) {
*ptr = mxCreateDoubleMatrix(nr, nc, mxREAL);
if (*ptr) {
double *outr = mxGetPr(*ptr);
for (int i=0;i<nr*nc;i++) {
outr[i] = (double) buffer[i];
}
return nc*nr;
} else {
return -1;
}
}
int mexutils_write_uint8(uint8_t *buffer, mxArray **ptr, uint32_t nr, uint32_t nc) {
*ptr = mxCreateNumericMatrix(nr, nc, mxUINT8_CLASS, mxREAL);
if (*ptr) {
uint8_t *outr = (uint8_t*) mxGetPr(*ptr);
memcpy(outr, buffer, nr*nc*sizeof(uint8_t));
return nc*nr;
} else {
return -1;
}
}
int mexutils_write_int(int *buffer, mxArray **ptr, uint32_t nr, uint32_t nc) {
*ptr = mxCreateNumericMatrix(nr, nc, mxINT32_CLASS, mxREAL);
if (*ptr) {
int *outr = (int*) mxGetPr(*ptr);
memcpy(outr, buffer, nr*nc*sizeof(int));
return nc*nr;
} else {
return -1;
}
}

@ -129,9 +129,10 @@ void sig_int_handler(int signo)
} }
} }
int srslte_rf_recv_wrapper(void *h, void *data, uint32_t nsamples, srslte_timestamp_t *q) { int srslte_rf_recv_wrapper(void *h, cf_t *data[SRSLTE_MAX_PORTS], uint32_t nsamples, srslte_timestamp_t *q) {
DEBUG(" ---- Receive %d samples ---- \n", nsamples); DEBUG(" ---- Receive %d samples ---- \n", nsamples);
return srslte_rf_recv(h, data, nsamples, 1);
return srslte_rf_recv(h, data[0], nsamples, 1);
} }
enum receiver_state { DECODE_MIB, DECODE_SIB, MEASURE} state; enum receiver_state { DECODE_MIB, DECODE_SIB, MEASURE} state;
@ -141,7 +142,7 @@ enum receiver_state { DECODE_MIB, DECODE_SIB, MEASURE} state;
int main(int argc, char **argv) { int main(int argc, char **argv) {
int ret; int ret;
cf_t *sf_buffer; cf_t *sf_buffer[SRSLTE_MAX_PORTS] = {NULL, NULL};
prog_args_t prog_args; prog_args_t prog_args;
srslte_cell_t cell; srslte_cell_t cell;
int64_t sf_cnt; int64_t sf_cnt;
@ -181,6 +182,8 @@ int main(int argc, char **argv) {
srslte_rf_set_rx_gain(&rf, 50); srslte_rf_set_rx_gain(&rf, 50);
} }
sf_buffer[0] = srslte_vec_malloc(3*sizeof(cf_t)*SRSLTE_SF_LEN_PRB(100));
sigset_t sigset; sigset_t sigset;
sigemptyset(&sigset); sigemptyset(&sigset);
sigaddset(&sigset, SIGINT); sigaddset(&sigset, SIGINT);
@ -198,7 +201,7 @@ int main(int argc, char **argv) {
uint32_t ntrial=0; uint32_t ntrial=0;
do { do {
ret = rf_search_and_decode_mib(&rf, &cell_detect_config, prog_args.force_N_id_2, &cell, &cfo); ret = rf_search_and_decode_mib(&rf, 1, &cell_detect_config, prog_args.force_N_id_2, &cell, &cfo);
if (ret < 0) { if (ret < 0) {
fprintf(stderr, "Error searching for cell\n"); fprintf(stderr, "Error searching for cell\n");
exit(-1); exit(-1);
@ -234,11 +237,11 @@ int main(int argc, char **argv) {
srslte_rf_stop_rx_stream(&rf); srslte_rf_stop_rx_stream(&rf);
srslte_rf_flush_buffer(&rf); srslte_rf_flush_buffer(&rf);
if (srslte_ue_sync_init(&ue_sync, cell, srslte_rf_recv_wrapper, (void*) &rf)) { if (srslte_ue_sync_init_multi(&ue_sync, cell, srslte_rf_recv_wrapper, 1, (void*) &rf)) {
fprintf(stderr, "Error initiating ue_sync\n"); fprintf(stderr, "Error initiating ue_sync\n");
return -1; return -1;
} }
if (srslte_ue_dl_init(&ue_dl, cell)) { if (srslte_ue_dl_init_multi(&ue_dl, cell, 1)) {
fprintf(stderr, "Error initiating UE downlink processing module\n"); fprintf(stderr, "Error initiating UE downlink processing module\n");
return -1; return -1;
} }
@ -280,7 +283,7 @@ int main(int argc, char **argv) {
/* Main loop */ /* Main loop */
while ((sf_cnt < prog_args.nof_subframes || prog_args.nof_subframes == -1) && !go_exit) { while ((sf_cnt < prog_args.nof_subframes || prog_args.nof_subframes == -1) && !go_exit) {
ret = srslte_ue_sync_get_buffer(&ue_sync, &sf_buffer); ret = srslte_ue_sync_zerocopy_multi(&ue_sync, sf_buffer);
if (ret < 0) { if (ret < 0) {
fprintf(stderr, "Error calling srslte_ue_sync_work()\n"); fprintf(stderr, "Error calling srslte_ue_sync_work()\n");
} }
@ -292,7 +295,7 @@ int main(int argc, char **argv) {
case DECODE_MIB: case DECODE_MIB:
if (srslte_ue_sync_get_sfidx(&ue_sync) == 0) { if (srslte_ue_sync_get_sfidx(&ue_sync) == 0) {
srslte_pbch_decode_reset(&ue_mib.pbch); srslte_pbch_decode_reset(&ue_mib.pbch);
n = srslte_ue_mib_decode(&ue_mib, sf_buffer, bch_payload, NULL, &sfn_offset); n = srslte_ue_mib_decode(&ue_mib, sf_buffer[0], bch_payload, NULL, &sfn_offset);
if (n < 0) { if (n < 0) {
fprintf(stderr, "Error decoding UE MIB\n"); fprintf(stderr, "Error decoding UE MIB\n");
return -1; return -1;
@ -307,7 +310,7 @@ int main(int argc, char **argv) {
case DECODE_SIB: case DECODE_SIB:
/* We are looking for SI Blocks, search only in appropiate places */ /* We are looking for SI Blocks, search only in appropiate places */
if ((srslte_ue_sync_get_sfidx(&ue_sync) == 5 && (sfn%2)==0)) { if ((srslte_ue_sync_get_sfidx(&ue_sync) == 5 && (sfn%2)==0)) {
n = srslte_ue_dl_decode(&ue_dl, sf_buffer, data, sfn*10+srslte_ue_sync_get_sfidx(&ue_sync)); n = srslte_ue_dl_decode_multi(&ue_dl, sf_buffer, data, sfn*10+srslte_ue_sync_get_sfidx(&ue_sync));
if (n < 0) { if (n < 0) {
fprintf(stderr, "Error decoding UE DL\n");fflush(stdout); fprintf(stderr, "Error decoding UE DL\n");fflush(stdout);
return -1; return -1;
@ -329,11 +332,11 @@ int main(int argc, char **argv) {
if (srslte_ue_sync_get_sfidx(&ue_sync) == 5) { if (srslte_ue_sync_get_sfidx(&ue_sync) == 5) {
/* Run FFT for all subframe data */ /* Run FFT for all subframe data */
srslte_ofdm_rx_sf(&fft, sf_buffer, sf_symbols); srslte_ofdm_rx_sf(&fft, sf_buffer[0], sf_symbols);
srslte_chest_dl_estimate(&chest, sf_symbols, ce, srslte_ue_sync_get_sfidx(&ue_sync)); srslte_chest_dl_estimate(&chest, sf_symbols, ce, srslte_ue_sync_get_sfidx(&ue_sync));
rssi = SRSLTE_VEC_EMA(srslte_vec_avg_power_cf(sf_buffer,SRSLTE_SF_LEN(srslte_symbol_sz(cell.nof_prb))),rssi,0.05); rssi = SRSLTE_VEC_EMA(srslte_vec_avg_power_cf(sf_buffer[0],SRSLTE_SF_LEN(srslte_symbol_sz(cell.nof_prb))),rssi,0.05);
rssi_utra = SRSLTE_VEC_EMA(srslte_chest_dl_get_rssi(&chest),rssi_utra,0.05); rssi_utra = SRSLTE_VEC_EMA(srslte_chest_dl_get_rssi(&chest),rssi_utra,0.05);
rsrq = SRSLTE_VEC_EMA(srslte_chest_dl_get_rsrq(&chest),rsrq,0.05); rsrq = SRSLTE_VEC_EMA(srslte_chest_dl_get_rsrq(&chest),rsrq,0.05);
rsrp = SRSLTE_VEC_EMA(srslte_chest_dl_get_rsrp(&chest),rsrp,0.05); rsrp = SRSLTE_VEC_EMA(srslte_chest_dl_get_rsrp(&chest),rsrp,0.05);

@ -120,9 +120,13 @@ void parse_args(int argc, char **argv) {
} }
} }
int srslte_rf_recv_wrapper(void *h, void *data, uint32_t nsamples, srslte_timestamp_t *t) { int srslte_rf_recv_wrapper(void *h, cf_t *data[SRSLTE_MAX_PORTS], uint32_t nsamples, srslte_timestamp_t *t) {
DEBUG(" ---- Receive %d samples ---- \n", nsamples); DEBUG(" ---- Receive %d samples ---- \n", nsamples);
return srslte_rf_recv((srslte_rf_t*) h, data, nsamples, 1); void *ptr[SRSLTE_MAX_PORTS];
for (int i=0;i<SRSLTE_MAX_PORTS;i++) {
ptr[i] = data[i];
}
return srslte_rf_recv_with_time_multi((srslte_rf_t*) h, ptr, nsamples, 1, NULL, NULL);
} }
bool go_exit = false; bool go_exit = false;
@ -200,7 +204,7 @@ int main(int argc, char **argv) {
bzero(found_cells, 3*sizeof(srslte_ue_cellsearch_result_t)); bzero(found_cells, 3*sizeof(srslte_ue_cellsearch_result_t));
if (srslte_ue_cellsearch_init(&cs, cell_detect_config.max_frames_pss, srslte_rf_recv_wrapper, (void*) &rf)) { if (srslte_ue_cellsearch_init_multi(&cs, cell_detect_config.max_frames_pss, srslte_rf_recv_wrapper, 1, (void*) &rf)) {
fprintf(stderr, "Error initiating UE cell detect\n"); fprintf(stderr, "Error initiating UE cell detect\n");
exit(-1); exit(-1);
} }
@ -228,7 +232,7 @@ int main(int argc, char **argv) {
srslte_cell_t cell; srslte_cell_t cell;
cell.id = found_cells[i].cell_id; cell.id = found_cells[i].cell_id;
cell.cp = found_cells[i].cp; cell.cp = found_cells[i].cp;
int ret = rf_mib_decoder(&rf, &cell_detect_config, &cell, NULL); int ret = rf_mib_decoder(&rf, 1, &cell_detect_config, &cell, NULL);
if (ret < 0) { if (ret < 0) {
fprintf(stderr, "Error decoding MIB\n"); fprintf(stderr, "Error decoding MIB\n");
exit(-1); exit(-1);

@ -340,6 +340,7 @@ int update_radl() {
ra_dl.rv_idx = 0; ra_dl.rv_idx = 0;
ra_dl.alloc_type = SRSLTE_RA_ALLOC_TYPE0; ra_dl.alloc_type = SRSLTE_RA_ALLOC_TYPE0;
ra_dl.type0_alloc.rbg_bitmask = prbset_to_bitmask(); ra_dl.type0_alloc.rbg_bitmask = prbset_to_bitmask();
ra_dl.tb_en[0] = 1;
srslte_ra_pdsch_fprint(stdout, &ra_dl, cell.nof_prb); srslte_ra_pdsch_fprint(stdout, &ra_dl, cell.nof_prb);
srslte_ra_dl_grant_t dummy_grant; srslte_ra_dl_grant_t dummy_grant;

@ -89,6 +89,7 @@ typedef struct {
uint32_t file_nof_ports; uint32_t file_nof_ports;
uint32_t file_cell_id; uint32_t file_cell_id;
char *rf_args; char *rf_args;
uint32_t rf_nof_rx_ant;
double rf_freq; double rf_freq;
float rf_gain; float rf_gain;
int net_port; int net_port;
@ -113,6 +114,7 @@ void args_default(prog_args_t *args) {
args->file_offset_freq = 0; args->file_offset_freq = 0;
args->rf_args = ""; args->rf_args = "";
args->rf_freq = -1.0; args->rf_freq = -1.0;
args->rf_nof_rx_ant = 1;
#ifdef ENABLE_AGC_DEFAULT #ifdef ENABLE_AGC_DEFAULT
args->rf_gain = -1.0; args->rf_gain = -1.0;
#else #else
@ -128,6 +130,7 @@ void usage(prog_args_t *args, char *prog) {
printf("Usage: %s [agpPoOcildDnruv] -f rx_frequency (in Hz) | -i input_file\n", prog); printf("Usage: %s [agpPoOcildDnruv] -f rx_frequency (in Hz) | -i input_file\n", prog);
#ifndef DISABLE_RF #ifndef DISABLE_RF
printf("\t-a RF args [Default %s]\n", args->rf_args); printf("\t-a RF args [Default %s]\n", args->rf_args);
printf("\t-A Number of RX antennas [Default %d]\n", args->rf_nof_rx_ant);
#ifdef ENABLE_AGC_DEFAULT #ifdef ENABLE_AGC_DEFAULT
printf("\t-g RF fix RX gain [Default AGC]\n"); printf("\t-g RF fix RX gain [Default AGC]\n");
#else #else
@ -163,7 +166,7 @@ void usage(prog_args_t *args, char *prog) {
void parse_args(prog_args_t *args, int argc, char **argv) { void parse_args(prog_args_t *args, int argc, char **argv) {
int opt; int opt;
args_default(args); args_default(args);
while ((opt = getopt(argc, argv, "aoglipPcOCtdDnvrfuUsS")) != -1) { while ((opt = getopt(argc, argv, "aAoglipPcOCtdDnvrfuUsS")) != -1) {
switch (opt) { switch (opt) {
case 'i': case 'i':
args->input_file_name = argv[optind]; args->input_file_name = argv[optind];
@ -186,6 +189,9 @@ void parse_args(prog_args_t *args, int argc, char **argv) {
case 'a': case 'a':
args->rf_args = argv[optind]; args->rf_args = argv[optind];
break; break;
case 'A':
args->rf_nof_rx_ant = atoi(argv[optind]);
break;
case 'g': case 'g':
args->rf_gain = atof(argv[optind]); args->rf_gain = atof(argv[optind]);
break; break;
@ -252,10 +258,16 @@ void sig_int_handler(int signo)
} }
} }
cf_t *sf_buffer[2] = {NULL, NULL};
#ifndef DISABLE_RF #ifndef DISABLE_RF
int srslte_rf_recv_wrapper(void *h, void *data, uint32_t nsamples, srslte_timestamp_t *t) { int srslte_rf_recv_wrapper(void *h, cf_t *data[SRSLTE_MAX_PORTS], uint32_t nsamples, srslte_timestamp_t *t) {
DEBUG(" ---- Receive %d samples ---- \n", nsamples); DEBUG(" ---- Receive %d samples ---- \n", nsamples);
return srslte_rf_recv(h, data, nsamples, 1); void *ptr[SRSLTE_MAX_PORTS];
for (int i=0;i<SRSLTE_MAX_PORTS;i++) {
ptr[i] = data[i];
}
return srslte_rf_recv_with_time_multi(h, ptr, nsamples, true, NULL, NULL);
} }
double srslte_rf_set_rx_gain_th_wrapper_(void *h, double f) { double srslte_rf_set_rx_gain_th_wrapper_(void *h, double f) {
@ -273,7 +285,6 @@ srslte_ue_sync_t ue_sync;
prog_args_t prog_args; prog_args_t prog_args;
uint32_t sfn = 0; // system frame number uint32_t sfn = 0; // system frame number
cf_t *sf_buffer = NULL;
srslte_netsink_t net_sink, net_sink_signal; srslte_netsink_t net_sink, net_sink_signal;
int main(int argc, char **argv) { int main(int argc, char **argv) {
@ -311,8 +322,8 @@ int main(int argc, char **argv) {
#ifndef DISABLE_RF #ifndef DISABLE_RF
if (!prog_args.input_file_name) { if (!prog_args.input_file_name) {
printf("Opening RF device...\n"); printf("Opening RF device with %d RX antennas...\n", prog_args.rf_nof_rx_ant);
if (srslte_rf_open(&rf, prog_args.rf_args)) { if (srslte_rf_open_multi(&rf, prog_args.rf_args, prog_args.rf_nof_rx_ant)) {
fprintf(stderr, "Error opening rf\n"); fprintf(stderr, "Error opening rf\n");
exit(-1); exit(-1);
} }
@ -344,7 +355,7 @@ int main(int argc, char **argv) {
uint32_t ntrial=0; uint32_t ntrial=0;
do { do {
ret = rf_search_and_decode_mib(&rf, &cell_detect_config, prog_args.force_N_id_2, &cell, &cfo); ret = rf_search_and_decode_mib(&rf, prog_args.rf_nof_rx_ant, &cell_detect_config, prog_args.force_N_id_2, &cell, &cfo);
if (ret < 0) { if (ret < 0) {
fprintf(stderr, "Error searching for cell\n"); fprintf(stderr, "Error searching for cell\n");
exit(-1); exit(-1);
@ -356,6 +367,10 @@ int main(int argc, char **argv) {
if (go_exit) { if (go_exit) {
exit(0); exit(0);
} }
srslte_rf_stop_rx_stream(&rf);
srslte_rf_flush_buffer(&rf);
/* set sampling frequency */ /* set sampling frequency */
int srate = srslte_sampling_freq_hz(cell.nof_prb); int srate = srslte_sampling_freq_hz(cell.nof_prb);
if (srate != -1) { if (srate != -1) {
@ -376,8 +391,6 @@ int main(int argc, char **argv) {
} }
INFO("Stopping RF and flushing buffer...\r",0); INFO("Stopping RF and flushing buffer...\r",0);
srslte_rf_stop_rx_stream(&rf);
srslte_rf_flush_buffer(&rf);
} }
#endif #endif
@ -399,7 +412,7 @@ int main(int argc, char **argv) {
} else { } else {
#ifndef DISABLE_RF #ifndef DISABLE_RF
if (srslte_ue_sync_init(&ue_sync, cell, srslte_rf_recv_wrapper, (void*) &rf)) { if (srslte_ue_sync_init_multi(&ue_sync, cell, srslte_rf_recv_wrapper, prog_args.rf_nof_rx_ant, (void*) &rf)) {
fprintf(stderr, "Error initiating ue_sync\n"); fprintf(stderr, "Error initiating ue_sync\n");
exit(-1); exit(-1);
} }
@ -411,11 +424,15 @@ int main(int argc, char **argv) {
exit(-1); exit(-1);
} }
if (srslte_ue_dl_init(&ue_dl, cell)) { // This is the User RNTI if (srslte_ue_dl_init_multi(&ue_dl, cell, prog_args.rf_nof_rx_ant)) { // This is the User RNTI
fprintf(stderr, "Error initiating UE downlink processing module\n"); fprintf(stderr, "Error initiating UE downlink processing module\n");
exit(-1); exit(-1);
} }
for (int i=0;i<prog_args.rf_nof_rx_ant;i++) {
sf_buffer[i] = srslte_vec_malloc(3*sizeof(cf_t)*SRSLTE_SF_LEN_PRB(cell.nof_prb));
}
/* Configure downlink receiver for the SI-RNTI since will be the only one we'll use */ /* Configure downlink receiver for the SI-RNTI since will be the only one we'll use */
srslte_ue_dl_set_rnti(&ue_dl, prog_args.rnti); srslte_ue_dl_set_rnti(&ue_dl, prog_args.rnti);
@ -462,7 +479,7 @@ int main(int argc, char **argv) {
/* Main loop */ /* Main loop */
while (!go_exit && (sf_cnt < prog_args.nof_subframes || prog_args.nof_subframes == -1)) { while (!go_exit && (sf_cnt < prog_args.nof_subframes || prog_args.nof_subframes == -1)) {
ret = srslte_ue_sync_get_buffer(&ue_sync, &sf_buffer); ret = srslte_ue_sync_zerocopy_multi(&ue_sync, sf_buffer);
if (ret < 0) { if (ret < 0) {
fprintf(stderr, "Error calling srslte_ue_sync_work()\n"); fprintf(stderr, "Error calling srslte_ue_sync_work()\n");
} }
@ -477,7 +494,7 @@ int main(int argc, char **argv) {
switch (state) { switch (state) {
case DECODE_MIB: case DECODE_MIB:
if (srslte_ue_sync_get_sfidx(&ue_sync) == 0) { if (srslte_ue_sync_get_sfidx(&ue_sync) == 0) {
n = srslte_ue_mib_decode(&ue_mib, sf_buffer, bch_payload, NULL, &sfn_offset); n = srslte_ue_mib_decode(&ue_mib, sf_buffer[0], bch_payload, NULL, &sfn_offset);
if (n < 0) { if (n < 0) {
fprintf(stderr, "Error decoding UE MIB\n"); fprintf(stderr, "Error decoding UE MIB\n");
exit(-1); exit(-1);
@ -503,10 +520,10 @@ int main(int argc, char **argv) {
} }
if (decode_pdsch) { if (decode_pdsch) {
INFO("Attempting DL decode SFN=%d\n", sfn); INFO("Attempting DL decode SFN=%d\n", sfn);
n = srslte_ue_dl_decode(&ue_dl, n = srslte_ue_dl_decode_multi(&ue_dl,
&sf_buffer[prog_args.time_offset], sf_buffer,
data, data,
sfn*10+srslte_ue_sync_get_sfidx(&ue_sync)); sfn*10+srslte_ue_sync_get_sfidx(&ue_sync));
if (n < 0) { if (n < 0) {
// fprintf(stderr, "Error decoding UE DL\n");fflush(stdout); // fprintf(stderr, "Error decoding UE DL\n");fflush(stdout);

@ -182,7 +182,7 @@ int main(int argc, char **argv) {
} }
gettimeofday(&tdata[2], NULL); gettimeofday(&tdata[2], NULL);
get_time_interval(tdata); get_time_interval(tdata);
printf("done in %ld s %ld ms\n", (int) tdata[0].tv_sec, (int) tdata[0].tv_usec/1000); printf("done in %ld s %ld ms\n", tdata[0].tv_sec, tdata[0].tv_usec/1000);
printf("\n\tFr.Cnt\tN_id_2\tN_id_1\tSubf\tPSS Peak/Avg\tIdx\tm0\tm1\tCFO\n"); printf("\n\tFr.Cnt\tN_id_2\tN_id_1\tSubf\tPSS Peak/Avg\tIdx\tm0\tm1\tCFO\n");
printf("\t===============================================================================\n"); printf("\t===============================================================================\n");

@ -98,13 +98,13 @@ void parse_args(int argc, char **argv) {
} }
} }
int srslte_rf_recv_wrapper(void *h, void *data, uint32_t nsamples, srslte_timestamp_t *t) { int srslte_rf_recv_wrapper(void *h, cf_t *data[SRSLTE_MAX_PORTS], uint32_t nsamples, srslte_timestamp_t *t) {
DEBUG(" ---- Receive %d samples ---- \n", nsamples); DEBUG(" ---- Receive %d samples ---- \n", nsamples);
return srslte_rf_recv(h, data, nsamples, 1); return srslte_rf_recv(h, data[2], nsamples, 1);
} }
int main(int argc, char **argv) { int main(int argc, char **argv) {
cf_t *buffer; cf_t *buffer[SRSLTE_MAX_PORTS] = {NULL, NULL};
int n; int n;
srslte_rf_t rf; srslte_rf_t rf;
srslte_filesink_t sink; srslte_filesink_t sink;
@ -124,6 +124,8 @@ int main(int argc, char **argv) {
} }
srslte_rf_set_master_clock_rate(&rf, 30.72e6); srslte_rf_set_master_clock_rate(&rf, 30.72e6);
buffer[0] = srslte_vec_malloc(3*sizeof(cf_t)*SRSLTE_SF_LEN_PRB(100));
sigset_t sigset; sigset_t sigset;
sigemptyset(&sigset); sigemptyset(&sigset);
sigaddset(&sigset, SIGINT); sigaddset(&sigset, SIGINT);
@ -156,7 +158,7 @@ int main(int argc, char **argv) {
cell.nof_prb = nof_prb; cell.nof_prb = nof_prb;
cell.nof_ports = 1; cell.nof_ports = 1;
if (srslte_ue_sync_init(&ue_sync, cell, srslte_rf_recv_wrapper, (void*) &rf)) { if (srslte_ue_sync_init_multi(&ue_sync, cell, srslte_rf_recv_wrapper, 1, (void*) &rf)) {
fprintf(stderr, "Error initiating ue_sync\n"); fprintf(stderr, "Error initiating ue_sync\n");
exit(-1); exit(-1);
} }
@ -167,7 +169,7 @@ int main(int argc, char **argv) {
while((subframe_count < nof_subframes || nof_subframes == -1) while((subframe_count < nof_subframes || nof_subframes == -1)
&& !stop_capture) && !stop_capture)
{ {
n = srslte_ue_sync_get_buffer(&ue_sync, &buffer); n = srslte_ue_sync_zerocopy_multi(&ue_sync, buffer);
if (n < 0) { if (n < 0) {
fprintf(stderr, "Error receiving samples\n"); fprintf(stderr, "Error receiving samples\n");
exit(-1); exit(-1);
@ -179,7 +181,7 @@ int main(int argc, char **argv) {
} }
} else { } else {
printf("Writing to file %6d subframes...\r", subframe_count); printf("Writing to file %6d subframes...\r", subframe_count);
srslte_filesink_write(&sink, buffer, SRSLTE_SF_LEN_PRB(nof_prb)); srslte_filesink_write(&sink, buffer[0], SRSLTE_SF_LEN_PRB(nof_prb));
subframe_count++; subframe_count++;
} }
} }

@ -76,9 +76,9 @@ typedef struct {
srslte_interp_linsrslte_vec_t srslte_interp_linvec; srslte_interp_linsrslte_vec_t srslte_interp_linvec;
srslte_interp_lin_t srslte_interp_lin; srslte_interp_lin_t srslte_interp_lin;
float rssi[SRSLTE_MAX_PORTS]; float rssi[SRSLTE_MAX_PORTS][SRSLTE_MAX_PORTS];
float rsrp[SRSLTE_MAX_PORTS]; float rsrp[SRSLTE_MAX_PORTS][SRSLTE_MAX_PORTS];
float noise_estimate[SRSLTE_MAX_PORTS]; float noise_estimate[SRSLTE_MAX_PORTS][SRSLTE_MAX_PORTS];
/* Use PSS for noise estimation in LS linear interpolation mode */ /* Use PSS for noise estimation in LS linear interpolation mode */
cf_t pss_signal[SRSLTE_PSS_LEN]; cf_t pss_signal[SRSLTE_PSS_LEN];
@ -86,6 +86,7 @@ typedef struct {
cf_t tmp_pss_noisy[SRSLTE_PSS_LEN]; cf_t tmp_pss_noisy[SRSLTE_PSS_LEN];
srslte_chest_dl_noise_alg_t noise_alg; srslte_chest_dl_noise_alg_t noise_alg;
int last_nof_antennas;
} srslte_chest_dl_t; } srslte_chest_dl_t;
@ -105,6 +106,12 @@ SRSLTE_API void srslte_chest_dl_set_smooth_filter3_coeff(srslte_chest_dl_t* q,
SRSLTE_API void srslte_chest_dl_set_noise_alg(srslte_chest_dl_t *q, SRSLTE_API void srslte_chest_dl_set_noise_alg(srslte_chest_dl_t *q,
srslte_chest_dl_noise_alg_t noise_estimation_alg); srslte_chest_dl_noise_alg_t noise_estimation_alg);
SRSLTE_API int srslte_chest_dl_estimate_multi(srslte_chest_dl_t *q,
cf_t *input[SRSLTE_MAX_PORTS],
cf_t *ce[SRSLTE_MAX_PORTS][SRSLTE_MAX_PORTS],
uint32_t sf_idx,
uint32_t nof_rx_antennas);
SRSLTE_API int srslte_chest_dl_estimate(srslte_chest_dl_t *q, SRSLTE_API int srslte_chest_dl_estimate(srslte_chest_dl_t *q,
cf_t *input, cf_t *input,
cf_t *ce[SRSLTE_MAX_PORTS], cf_t *ce[SRSLTE_MAX_PORTS],
@ -114,7 +121,8 @@ SRSLTE_API int srslte_chest_dl_estimate_port(srslte_chest_dl_t *q,
cf_t *input, cf_t *input,
cf_t *ce, cf_t *ce,
uint32_t sf_idx, uint32_t sf_idx,
uint32_t port_id); uint32_t port_id,
uint32_t rxant_id);
SRSLTE_API float srslte_chest_dl_get_noise_estimate(srslte_chest_dl_t *q); SRSLTE_API float srslte_chest_dl_get_noise_estimate(srslte_chest_dl_t *q);

@ -50,7 +50,7 @@
#define SRSLTE_PC_MAX 23 // Maximum TX power for Category 1 UE (in dBm) #define SRSLTE_PC_MAX 23 // Maximum TX power for Category 1 UE (in dBm)
#define SRSLTE_MAX_PORTS 4 #define SRSLTE_MAX_PORTS 4
#define SRSLTE_MAX_LAYERS 8 #define SRSLTE_MAX_LAYERS 4
#define SRSLTE_MAX_CODEWORDS 2 #define SRSLTE_MAX_CODEWORDS 2
#define SRSLTE_LTE_CRC24A 0x1864CFB #define SRSLTE_LTE_CRC24A 0x1864CFB
@ -167,7 +167,8 @@ typedef struct SRSLTE_API {
typedef enum SRSLTE_API { typedef enum SRSLTE_API {
SRSLTE_MIMO_TYPE_SINGLE_ANTENNA, SRSLTE_MIMO_TYPE_SINGLE_ANTENNA,
SRSLTE_MIMO_TYPE_TX_DIVERSITY, SRSLTE_MIMO_TYPE_TX_DIVERSITY,
SRSLTE_MIMO_TYPE_SPATIAL_MULTIPLEX SRSLTE_MIMO_TYPE_SPATIAL_MULTIPLEX,
SRSLTE_MIMO_TYPE_CDD
} srslte_mimo_type_t; } srslte_mimo_type_t;
typedef enum SRSLTE_API { typedef enum SRSLTE_API {

@ -70,12 +70,26 @@ SRSLTE_API int srslte_predecoding_single(cf_t *y,
int nof_symbols, int nof_symbols,
float noise_estimate); float noise_estimate);
SRSLTE_API int srslte_predecoding_single_multi(cf_t *y[SRSLTE_MAX_PORTS],
cf_t *h[SRSLTE_MAX_PORTS],
cf_t *x,
int nof_rxant,
int nof_symbols,
float noise_estimate);
SRSLTE_API int srslte_predecoding_diversity(cf_t *y, SRSLTE_API int srslte_predecoding_diversity(cf_t *y,
cf_t *h[SRSLTE_MAX_PORTS], cf_t *h[SRSLTE_MAX_PORTS],
cf_t *x[SRSLTE_MAX_LAYERS], cf_t *x[SRSLTE_MAX_LAYERS],
int nof_ports, int nof_ports,
int nof_symbols); int nof_symbols);
SRSLTE_API int srslte_predecoding_diversity_multi(cf_t *y[SRSLTE_MAX_PORTS],
cf_t *h[SRSLTE_MAX_PORTS][SRSLTE_MAX_PORTS],
cf_t *x[SRSLTE_MAX_LAYERS],
int nof_rxant,
int nof_ports,
int nof_symbols);
SRSLTE_API int srslte_predecoding_type(cf_t *y, SRSLTE_API int srslte_predecoding_type(cf_t *y,
cf_t *h[SRSLTE_MAX_PORTS], cf_t *h[SRSLTE_MAX_PORTS],
cf_t *x[SRSLTE_MAX_LAYERS], cf_t *x[SRSLTE_MAX_LAYERS],

@ -52,11 +52,13 @@ typedef struct SRSLTE_API {
srslte_cell_t cell; srslte_cell_t cell;
int nof_symbols; int nof_symbols;
uint32_t nof_rx_antennas;
/* handler to REGs resource mapper */ /* handler to REGs resource mapper */
srslte_regs_t *regs; srslte_regs_t *regs;
/* buffers */ /* buffers */
cf_t ce[SRSLTE_MAX_PORTS][PCFICH_RE]; cf_t ce[SRSLTE_MAX_PORTS][SRSLTE_MAX_PORTS][PCFICH_RE];
cf_t symbols[SRSLTE_MAX_PORTS][PCFICH_RE]; cf_t symbols[SRSLTE_MAX_PORTS][PCFICH_RE];
cf_t x[SRSLTE_MAX_PORTS][PCFICH_RE]; cf_t x[SRSLTE_MAX_PORTS][PCFICH_RE];
cf_t d[PCFICH_RE]; cf_t d[PCFICH_RE];
@ -80,6 +82,11 @@ SRSLTE_API int srslte_pcfich_init(srslte_pcfich_t *q,
srslte_regs_t *regs, srslte_regs_t *regs,
srslte_cell_t cell); srslte_cell_t cell);
SRSLTE_API int srslte_pcfich_init_multi(srslte_pcfich_t *q,
srslte_regs_t *regs,
srslte_cell_t cell,
uint32_t nof_rx_antennas);
SRSLTE_API void srslte_pcfich_free(srslte_pcfich_t *q); SRSLTE_API void srslte_pcfich_free(srslte_pcfich_t *q);
SRSLTE_API int srslte_pcfich_decode(srslte_pcfich_t *q, SRSLTE_API int srslte_pcfich_decode(srslte_pcfich_t *q,
@ -90,6 +97,14 @@ SRSLTE_API int srslte_pcfich_decode(srslte_pcfich_t *q,
uint32_t *cfi, uint32_t *cfi,
float *corr_result); float *corr_result);
SRSLTE_API int srslte_pcfich_decode_multi(srslte_pcfich_t *q,
cf_t *sf_symbols[SRSLTE_MAX_PORTS],
cf_t *ce[SRSLTE_MAX_PORTS][SRSLTE_MAX_PORTS],
float noise_estimate,
uint32_t subframe,
uint32_t *cfi,
float *corr_result);
SRSLTE_API int srslte_pcfich_encode(srslte_pcfich_t *q, SRSLTE_API int srslte_pcfich_encode(srslte_pcfich_t *q,
uint32_t cfi, uint32_t cfi,
cf_t *sf_symbols[SRSLTE_MAX_PORTS], cf_t *sf_symbols[SRSLTE_MAX_PORTS],

@ -63,11 +63,12 @@ typedef struct SRSLTE_API {
uint32_t nof_regs; uint32_t nof_regs;
uint32_t nof_cce; uint32_t nof_cce;
uint32_t max_bits; uint32_t max_bits;
uint32_t nof_rx_antennas;
srslte_regs_t *regs; srslte_regs_t *regs;
/* buffers */ /* buffers */
cf_t *ce[SRSLTE_MAX_PORTS]; cf_t *ce[SRSLTE_MAX_PORTS][SRSLTE_MAX_PORTS];
cf_t *symbols[SRSLTE_MAX_PORTS]; cf_t *symbols[SRSLTE_MAX_PORTS];
cf_t *x[SRSLTE_MAX_PORTS]; cf_t *x[SRSLTE_MAX_PORTS];
cf_t *d; cf_t *d;
@ -87,6 +88,11 @@ SRSLTE_API int srslte_pdcch_init(srslte_pdcch_t *q,
srslte_regs_t *regs, srslte_regs_t *regs,
srslte_cell_t cell); srslte_cell_t cell);
SRSLTE_API int srslte_pdcch_init_multi(srslte_pdcch_t *q,
srslte_regs_t *regs,
srslte_cell_t cell,
uint32_t nof_rx_antennas);
SRSLTE_API void srslte_pdcch_free(srslte_pdcch_t *q); SRSLTE_API void srslte_pdcch_free(srslte_pdcch_t *q);
@ -113,6 +119,13 @@ SRSLTE_API int srslte_pdcch_extract_llr(srslte_pdcch_t *q,
uint32_t nsubframe, uint32_t nsubframe,
uint32_t cfi); uint32_t cfi);
SRSLTE_API int srslte_pdcch_extract_llr_multi(srslte_pdcch_t *q,
cf_t *sf_symbols[SRSLTE_MAX_PORTS],
cf_t *ce[SRSLTE_MAX_PORTS][SRSLTE_MAX_PORTS],
float noise_estimate,
uint32_t nsubframe,
uint32_t cfi);
/* Decoding functions: Try to decode a DCI message after calling srslte_pdcch_extract_llr */ /* Decoding functions: Try to decode a DCI message after calling srslte_pdcch_extract_llr */
SRSLTE_API int srslte_pdcch_decode_msg(srslte_pdcch_t *q, SRSLTE_API int srslte_pdcch_decode_msg(srslte_pdcch_t *q,
srslte_dci_msg_t *msg, srslte_dci_msg_t *msg,

@ -55,11 +55,13 @@ typedef struct {
typedef struct SRSLTE_API { typedef struct SRSLTE_API {
srslte_cell_t cell; srslte_cell_t cell;
uint32_t nof_rx_antennas;
uint32_t max_re; uint32_t max_re;
/* buffers */ /* buffers */
// void buffers are shared for tx and rx // void buffers are shared for tx and rx
cf_t *ce[SRSLTE_MAX_PORTS]; cf_t *ce[SRSLTE_MAX_PORTS][SRSLTE_MAX_PORTS];
cf_t *symbols[SRSLTE_MAX_PORTS]; cf_t *symbols[SRSLTE_MAX_PORTS];
cf_t *x[SRSLTE_MAX_PORTS]; cf_t *x[SRSLTE_MAX_PORTS];
cf_t *d; cf_t *d;
@ -78,6 +80,10 @@ typedef struct SRSLTE_API {
SRSLTE_API int srslte_pdsch_init(srslte_pdsch_t *q, SRSLTE_API int srslte_pdsch_init(srslte_pdsch_t *q,
srslte_cell_t cell); srslte_cell_t cell);
SRSLTE_API int srslte_pdsch_init_multi(srslte_pdsch_t *q,
srslte_cell_t cell,
uint32_t nof_rx_antennas);
SRSLTE_API void srslte_pdsch_free(srslte_pdsch_t *q); SRSLTE_API void srslte_pdsch_free(srslte_pdsch_t *q);
SRSLTE_API int srslte_pdsch_set_rnti(srslte_pdsch_t *q, SRSLTE_API int srslte_pdsch_set_rnti(srslte_pdsch_t *q,
@ -112,6 +118,15 @@ SRSLTE_API int srslte_pdsch_decode(srslte_pdsch_t *q,
uint16_t rnti, uint16_t rnti,
uint8_t *data); uint8_t *data);
SRSLTE_API int srslte_pdsch_decode_multi(srslte_pdsch_t *q,
srslte_pdsch_cfg_t *cfg,
srslte_softbuffer_rx_t *softbuffer,
cf_t *sf_symbols[SRSLTE_MAX_PORTS],
cf_t *ce[SRSLTE_MAX_PORTS][SRSLTE_MAX_PORTS],
float noise_estimate,
uint16_t rnti,
uint8_t *data);
SRSLTE_API float srslte_pdsch_average_noi(srslte_pdsch_t *q); SRSLTE_API float srslte_pdsch_average_noi(srslte_pdsch_t *q);
SRSLTE_API uint32_t srslte_pdsch_last_noi(srslte_pdsch_t *q); SRSLTE_API uint32_t srslte_pdsch_last_noi(srslte_pdsch_t *q);

@ -62,12 +62,14 @@
typedef struct SRSLTE_API { typedef struct SRSLTE_API {
srslte_cell_t cell; srslte_cell_t cell;
uint32_t nof_rx_antennas;
/* handler to REGs resource mapper */ /* handler to REGs resource mapper */
srslte_regs_t *regs; srslte_regs_t *regs;
/* buffers */ /* buffers */
cf_t ce[SRSLTE_MAX_PORTS][SRSLTE_PHICH_MAX_NSYMB]; cf_t ce[SRSLTE_MAX_PORTS][SRSLTE_MAX_PORTS][SRSLTE_PHICH_MAX_NSYMB];
cf_t symbols[SRSLTE_MAX_PORTS][SRSLTE_PHICH_MAX_NSYMB]; cf_t sf_symbols[SRSLTE_MAX_PORTS][SRSLTE_PHICH_MAX_NSYMB];
cf_t x[SRSLTE_MAX_PORTS][SRSLTE_PHICH_MAX_NSYMB]; cf_t x[SRSLTE_MAX_PORTS][SRSLTE_PHICH_MAX_NSYMB];
cf_t d[SRSLTE_PHICH_MAX_NSYMB]; cf_t d[SRSLTE_PHICH_MAX_NSYMB];
cf_t d0[SRSLTE_PHICH_MAX_NSYMB]; cf_t d0[SRSLTE_PHICH_MAX_NSYMB];
@ -87,6 +89,11 @@ SRSLTE_API int srslte_phich_init(srslte_phich_t *q,
srslte_regs_t *regs, srslte_regs_t *regs,
srslte_cell_t cell); srslte_cell_t cell);
SRSLTE_API int srslte_phich_init_multi(srslte_phich_t *q,
srslte_regs_t *regs,
srslte_cell_t cell,
uint32_t nof_rx_antennas);
SRSLTE_API void srslte_phich_free(srslte_phich_t *q); SRSLTE_API void srslte_phich_free(srslte_phich_t *q);
SRSLTE_API void srslte_phich_calc(srslte_phich_t *q, SRSLTE_API void srslte_phich_calc(srslte_phich_t *q,
@ -105,6 +112,16 @@ SRSLTE_API int srslte_phich_decode(srslte_phich_t *q,
uint8_t *ack, uint8_t *ack,
float *distance); float *distance);
SRSLTE_API int srslte_phich_decode_multi(srslte_phich_t *q,
cf_t *slot_symbols[SRSLTE_MAX_PORTS],
cf_t *ce[SRSLTE_MAX_PORTS][SRSLTE_MAX_PORTS],
float noise_estimate,
uint32_t ngroup,
uint32_t nseq,
uint32_t nsubframe,
uint8_t *ack,
float *distance);
SRSLTE_API int srslte_phich_encode(srslte_phich_t *q, SRSLTE_API int srslte_phich_encode(srslte_phich_t *q,
uint8_t ack, uint8_t ack,
uint32_t ngroup, uint32_t ngroup,

@ -71,9 +71,18 @@ typedef void (*srslte_rf_error_handler_t)(srslte_rf_error_t error);
SRSLTE_API int srslte_rf_open(srslte_rf_t *h, SRSLTE_API int srslte_rf_open(srslte_rf_t *h,
char *args); char *args);
SRSLTE_API int srslte_rf_open_multi(srslte_rf_t *h,
char *args,
uint32_t nof_rx_antennas);
SRSLTE_API int srslte_rf_open_devname(srslte_rf_t *h, SRSLTE_API int srslte_rf_open_devname(srslte_rf_t *h,
char *devname, char *devname,
char *args); char *args);
SRSLTE_API int srslte_rf_open_devname_multi(srslte_rf_t *h,
char *devname,
char *args,
uint32_t nof_rx_antennas);
SRSLTE_API const char *srslte_rf_name(srslte_rf_t *h); SRSLTE_API const char *srslte_rf_name(srslte_rf_t *h);
@ -139,6 +148,13 @@ SRSLTE_API int srslte_rf_recv_with_time(srslte_rf_t *h,
time_t *secs, time_t *secs,
double *frac_secs); double *frac_secs);
SRSLTE_API int srslte_rf_recv_with_time_multi(srslte_rf_t *h,
void **data,
uint32_t nsamples,
bool blocking,
time_t *secs,
double *frac_secs);
SRSLTE_API double srslte_rf_set_tx_srate(srslte_rf_t *h, SRSLTE_API double srslte_rf_set_tx_srate(srslte_rf_t *h,
double freq); double freq);

@ -43,17 +43,20 @@ SRSLTE_API int rf_rssi_scan(srslte_rf_t *rf,
int nsamp); int nsamp);
SRSLTE_API int rf_mib_decoder(srslte_rf_t *rf, SRSLTE_API int rf_mib_decoder(srslte_rf_t *rf,
uint32_t nof_rx_antennas,
cell_search_cfg_t *config, cell_search_cfg_t *config,
srslte_cell_t *cell, srslte_cell_t *cell,
float *cfo); float *cfo);
SRSLTE_API int rf_cell_search(srslte_rf_t *rf, SRSLTE_API int rf_cell_search(srslte_rf_t *rf,
uint32_t nof_rx_antennas,
cell_search_cfg_t *config, cell_search_cfg_t *config,
int force_N_id_2, int force_N_id_2,
srslte_cell_t *cell, srslte_cell_t *cell,
float *cfo); float *cfo);
SRSLTE_API int rf_search_and_decode_mib(srslte_rf_t *rf, SRSLTE_API int rf_search_and_decode_mib(srslte_rf_t *rf,
uint32_t nof_rx_antennas,
cell_search_cfg_t *config, cell_search_cfg_t *config,
int force_N_id_2, int force_N_id_2,
srslte_cell_t *cell, srslte_cell_t *cell,

@ -69,6 +69,9 @@ typedef struct SRSLTE_API {
typedef struct SRSLTE_API { typedef struct SRSLTE_API {
srslte_ue_sync_t ue_sync; srslte_ue_sync_t ue_sync;
cf_t *sf_buffer[SRSLTE_MAX_PORTS];
uint32_t nof_rx_antennas;
uint32_t max_frames; uint32_t max_frames;
uint32_t nof_valid_frames; // number of 5 ms frames to scan uint32_t nof_valid_frames; // number of 5 ms frames to scan
@ -83,6 +86,12 @@ SRSLTE_API int srslte_ue_cellsearch_init(srslte_ue_cellsearch_t *q,
int (recv_callback)(void*, void*, uint32_t,srslte_timestamp_t*), int (recv_callback)(void*, void*, uint32_t,srslte_timestamp_t*),
void *stream_handler); void *stream_handler);
SRSLTE_API int srslte_ue_cellsearch_init_multi(srslte_ue_cellsearch_t *q,
uint32_t max_frames_total,
int (recv_callback)(void*, cf_t*[SRSLTE_MAX_PORTS], uint32_t,srslte_timestamp_t*),
uint32_t nof_rx_antennas,
void *stream_handler);
SRSLTE_API void srslte_ue_cellsearch_free(srslte_ue_cellsearch_t *q); SRSLTE_API void srslte_ue_cellsearch_free(srslte_ue_cellsearch_t *q);
SRSLTE_API int srslte_ue_cellsearch_scan_N_id_2(srslte_ue_cellsearch_t *q, SRSLTE_API int srslte_ue_cellsearch_scan_N_id_2(srslte_ue_cellsearch_t *q,

@ -88,8 +88,12 @@ typedef struct SRSLTE_API {
srslte_ra_dl_dci_t dl_dci; srslte_ra_dl_dci_t dl_dci;
srslte_cell_t cell; srslte_cell_t cell;
cf_t *sf_symbols; uint32_t nof_rx_antennas;
cf_t *ce[SRSLTE_MAX_PORTS];
cf_t *sf_symbols; // this is for backwards compatibility
cf_t *sf_symbols_m[SRSLTE_MAX_PORTS];
cf_t *ce[SRSLTE_MAX_PORTS]; // compatibility
cf_t *ce_m[SRSLTE_MAX_PORTS][SRSLTE_MAX_PORTS];
srslte_dci_format_t dci_format; srslte_dci_format_t dci_format;
uint64_t pkt_errors; uint64_t pkt_errors;
@ -112,6 +116,10 @@ typedef struct SRSLTE_API {
SRSLTE_API int srslte_ue_dl_init(srslte_ue_dl_t *q, SRSLTE_API int srslte_ue_dl_init(srslte_ue_dl_t *q,
srslte_cell_t cell); srslte_cell_t cell);
SRSLTE_API int srslte_ue_dl_init_multi(srslte_ue_dl_t *q,
srslte_cell_t cell,
uint32_t nof_rx_antennas);
SRSLTE_API void srslte_ue_dl_free(srslte_ue_dl_t *q); SRSLTE_API void srslte_ue_dl_free(srslte_ue_dl_t *q);
SRSLTE_API int srslte_ue_dl_decode_fft_estimate(srslte_ue_dl_t *q, SRSLTE_API int srslte_ue_dl_decode_fft_estimate(srslte_ue_dl_t *q,
@ -119,6 +127,11 @@ SRSLTE_API int srslte_ue_dl_decode_fft_estimate(srslte_ue_dl_t *q,
uint32_t sf_idx, uint32_t sf_idx,
uint32_t *cfi); uint32_t *cfi);
SRSLTE_API int srslte_ue_dl_decode_fft_estimate_multi(srslte_ue_dl_t *q,
cf_t *input[SRSLTE_MAX_PORTS],
uint32_t sf_idx,
uint32_t *cfi);
SRSLTE_API int srslte_ue_dl_decode_estimate(srslte_ue_dl_t *q, SRSLTE_API int srslte_ue_dl_decode_estimate(srslte_ue_dl_t *q,
uint32_t sf_idx, uint32_t sf_idx,
uint32_t *cfi); uint32_t *cfi);
@ -158,12 +171,23 @@ SRSLTE_API int srslte_ue_dl_decode(srslte_ue_dl_t * q,
uint8_t *data, uint8_t *data,
uint32_t tti); uint32_t tti);
SRSLTE_API int srslte_ue_dl_decode_multi(srslte_ue_dl_t * q,
cf_t *input[SRSLTE_MAX_PORTS],
uint8_t *data,
uint32_t tti);
SRSLTE_API int srslte_ue_dl_decode_rnti(srslte_ue_dl_t * q, SRSLTE_API int srslte_ue_dl_decode_rnti(srslte_ue_dl_t * q,
cf_t *input, cf_t *input,
uint8_t *data, uint8_t *data,
uint32_t tti, uint32_t tti,
uint16_t rnti); uint16_t rnti);
SRSLTE_API int srslte_ue_dl_decode_rnti_multi(srslte_ue_dl_t * q,
cf_t *input[SRSLTE_MAX_PORTS],
uint8_t *data,
uint32_t tti,
uint16_t rnti);
SRSLTE_API bool srslte_ue_dl_decode_phich(srslte_ue_dl_t *q, SRSLTE_API bool srslte_ue_dl_decode_phich(srslte_ue_dl_t *q,
uint32_t sf_idx, uint32_t sf_idx,
uint32_t n_prb_lowest, uint32_t n_prb_lowest,

@ -100,6 +100,8 @@ SRSLTE_API int srslte_ue_mib_decode(srslte_ue_mib_t * q,
typedef struct { typedef struct {
srslte_ue_mib_t ue_mib; srslte_ue_mib_t ue_mib;
srslte_ue_sync_t ue_sync; srslte_ue_sync_t ue_sync;
cf_t *sf_buffer[SRSLTE_MAX_PORTS];
uint32_t nof_rx_antennas;
} srslte_ue_mib_sync_t; } srslte_ue_mib_sync_t;
SRSLTE_API int srslte_ue_mib_sync_init(srslte_ue_mib_sync_t *q, SRSLTE_API int srslte_ue_mib_sync_init(srslte_ue_mib_sync_t *q,
@ -108,6 +110,13 @@ SRSLTE_API int srslte_ue_mib_sync_init(srslte_ue_mib_sync_t *q,
int (recv_callback)(void*, void*, uint32_t, srslte_timestamp_t *), int (recv_callback)(void*, void*, uint32_t, srslte_timestamp_t *),
void *stream_handler); void *stream_handler);
SRSLTE_API int srslte_ue_mib_sync_init_multi(srslte_ue_mib_sync_t *q,
uint32_t cell_id,
srslte_cp_t cp,
int (recv_callback)(void*, cf_t*[SRSLTE_MAX_PORTS], uint32_t, srslte_timestamp_t *),
uint32_t nof_rx_antennas,
void *stream_handler);
SRSLTE_API void srslte_ue_mib_sync_free(srslte_ue_mib_sync_t *q); SRSLTE_API void srslte_ue_mib_sync_free(srslte_ue_mib_sync_t *q);
SRSLTE_API void srslte_ue_mib_sync_reset(srslte_ue_mib_sync_t * q); SRSLTE_API void srslte_ue_mib_sync_reset(srslte_ue_mib_sync_t * q);

@ -75,9 +75,13 @@ typedef struct SRSLTE_API {
uint32_t agc_period; uint32_t agc_period;
void *stream; void *stream;
int (*recv_callback)(void*, void*, uint32_t, srslte_timestamp_t*); void *stream_single;
int (*recv_callback)(void*, cf_t*[SRSLTE_MAX_PORTS], uint32_t, srslte_timestamp_t*);
int (*recv_callback_single)(void*, void*, uint32_t, srslte_timestamp_t*);
srslte_timestamp_t last_timestamp; srslte_timestamp_t last_timestamp;
uint32_t nof_rx_antennas;
srslte_filesource_t file_source; srslte_filesource_t file_source;
bool file_mode; bool file_mode;
float file_cfo; float file_cfo;
@ -85,8 +89,6 @@ typedef struct SRSLTE_API {
srslte_ue_sync_state_t state; srslte_ue_sync_state_t state;
cf_t *input_buffer;
uint32_t frame_len; uint32_t frame_len;
uint32_t fft_size; uint32_t fft_size;
uint32_t nof_recv_sf; // Number of subframes received each call to srslte_ue_sync_get_buffer uint32_t nof_recv_sf; // Number of subframes received each call to srslte_ue_sync_get_buffer
@ -116,17 +118,23 @@ typedef struct SRSLTE_API {
uint32_t sample_offset_correct_period; uint32_t sample_offset_correct_period;
float sfo_ema; float sfo_ema;
#ifdef MEASURE_EXEC_TIME #ifdef MEASURE_EXEC_TIME
float mean_exec_time; float mean_exec_time;
#endif #endif
} srslte_ue_sync_t; } srslte_ue_sync_t;
SRSLTE_API int srslte_ue_sync_init(srslte_ue_sync_t *q, SRSLTE_API int srslte_ue_sync_init(srslte_ue_sync_t *q,
srslte_cell_t cell, srslte_cell_t cell,
int (recv_callback)(void*, void*, uint32_t, srslte_timestamp_t*), int (recv_callback)(void*, void*, uint32_t, srslte_timestamp_t*),
void *stream_handler); void *stream_handler);
SRSLTE_API int srslte_ue_sync_init_multi(srslte_ue_sync_t *q,
srslte_cell_t cell,
int (recv_callback)(void*, cf_t*[SRSLTE_MAX_PORTS], uint32_t, srslte_timestamp_t*),
uint32_t nof_rx_antennas,
void *stream_handler);
SRSLTE_API int srslte_ue_sync_init_file(srslte_ue_sync_t *q, SRSLTE_API int srslte_ue_sync_init_file(srslte_ue_sync_t *q,
uint32_t nof_prb, uint32_t nof_prb,
char *file_name, char *file_name,
@ -141,9 +149,6 @@ SRSLTE_API int srslte_ue_sync_start_agc(srslte_ue_sync_t *q,
SRSLTE_API uint32_t srslte_ue_sync_sf_len(srslte_ue_sync_t *q); SRSLTE_API uint32_t srslte_ue_sync_sf_len(srslte_ue_sync_t *q);
SRSLTE_API int srslte_ue_sync_get_buffer(srslte_ue_sync_t *q,
cf_t **sf_symbols);
SRSLTE_API void srslte_ue_sync_set_agc_period(srslte_ue_sync_t *q, SRSLTE_API void srslte_ue_sync_set_agc_period(srslte_ue_sync_t *q,
uint32_t period); uint32_t period);
@ -151,6 +156,9 @@ SRSLTE_API void srslte_ue_sync_set_agc_period(srslte_ue_sync_t *q,
SRSLTE_API int srslte_ue_sync_zerocopy(srslte_ue_sync_t *q, SRSLTE_API int srslte_ue_sync_zerocopy(srslte_ue_sync_t *q,
cf_t *input_buffer); cf_t *input_buffer);
SRSLTE_API int srslte_ue_sync_zerocopy_multi(srslte_ue_sync_t *q,
cf_t *input_buffer[SRSLTE_MAX_PORTS]);
SRSLTE_API void srslte_ue_sync_set_cfo(srslte_ue_sync_t *q, SRSLTE_API void srslte_ue_sync_set_cfo(srslte_ue_sync_t *q,
float cfo); float cfo);

@ -311,7 +311,7 @@ float srslte_chest_dl_rssi(srslte_chest_dl_t *q, cf_t *input, uint32_t port_id)
return rssi/nsymbols; return rssi/nsymbols;
} }
int srslte_chest_dl_estimate_port(srslte_chest_dl_t *q, cf_t *input, cf_t *ce, uint32_t sf_idx, uint32_t port_id) int srslte_chest_dl_estimate_port(srslte_chest_dl_t *q, cf_t *input, cf_t *ce, uint32_t sf_idx, uint32_t port_id, uint32_t rxant_id)
{ {
/* Get references from the input signal */ /* Get references from the input signal */
srslte_refsignal_cs_get_sf(q->cell, port_id, input, q->pilot_recv_signal); srslte_refsignal_cs_get_sf(q->cell, port_id, input, q->pilot_recv_signal);
@ -331,41 +331,61 @@ int srslte_chest_dl_estimate_port(srslte_chest_dl_t *q, cf_t *input, cf_t *ce, u
/* Estimate noise power */ /* Estimate noise power */
if (q->noise_alg == SRSLTE_NOISE_ALG_REFS && q->smooth_filter_len > 0) { if (q->noise_alg == SRSLTE_NOISE_ALG_REFS && q->smooth_filter_len > 0) {
q->noise_estimate[port_id] = estimate_noise_pilots(q, port_id); q->noise_estimate[rxant_id][port_id] = estimate_noise_pilots(q, port_id);
} else if (q->noise_alg == SRSLTE_NOISE_ALG_PSS) { } else if (q->noise_alg == SRSLTE_NOISE_ALG_PSS) {
if (sf_idx == 0 || sf_idx == 5) { if (sf_idx == 0 || sf_idx == 5) {
q->noise_estimate[port_id] = estimate_noise_pss(q, input, ce); q->noise_estimate[rxant_id][port_id] = estimate_noise_pss(q, input, ce);
} }
} else { } else {
if (sf_idx == 0 || sf_idx == 5) { if (sf_idx == 0 || sf_idx == 5) {
q->noise_estimate[port_id] = estimate_noise_empty_sc(q, input); q->noise_estimate[rxant_id][port_id] = estimate_noise_empty_sc(q, input);
} }
} }
} }
/* Compute RSRP for the channel estimates in this port */ /* Compute RSRP for the channel estimates in this port */
q->rsrp[port_id] = srslte_vec_avg_power_cf(q->pilot_recv_signal, SRSLTE_REFSIGNAL_NUM_SF(q->cell.nof_prb, port_id)); q->rsrp[rxant_id][port_id] = srslte_vec_avg_power_cf(q->pilot_recv_signal, SRSLTE_REFSIGNAL_NUM_SF(q->cell.nof_prb, port_id));
if (port_id == 0) { if (port_id == 0) {
/* compute rssi only for port 0 */ /* compute rssi only for port 0 */
q->rssi[port_id] = srslte_chest_dl_rssi(q, input, port_id); q->rssi[rxant_id][port_id] = srslte_chest_dl_rssi(q, input, port_id);
} }
return 0; return 0;
} }
int srslte_chest_dl_estimate_multi(srslte_chest_dl_t *q, cf_t *input[SRSLTE_MAX_PORTS], cf_t *ce[SRSLTE_MAX_PORTS][SRSLTE_MAX_PORTS], uint32_t sf_idx, uint32_t nof_rx_antennas)
{
for (uint32_t rxant_id=0;rxant_id<nof_rx_antennas;rxant_id++) {
for (uint32_t port_id=0;port_id<q->cell.nof_ports;port_id++) {
if (srslte_chest_dl_estimate_port(q, input[rxant_id], ce[port_id][rxant_id], sf_idx, port_id, rxant_id)) {
return SRSLTE_ERROR;
}
}
}
q->last_nof_antennas = nof_rx_antennas;
return SRSLTE_SUCCESS;
}
int srslte_chest_dl_estimate(srslte_chest_dl_t *q, cf_t *input, cf_t *ce[SRSLTE_MAX_PORTS], uint32_t sf_idx) int srslte_chest_dl_estimate(srslte_chest_dl_t *q, cf_t *input, cf_t *ce[SRSLTE_MAX_PORTS], uint32_t sf_idx)
{ {
uint32_t port_id; uint32_t port_id;
for (port_id=0;port_id<q->cell.nof_ports;port_id++) { for (port_id=0;port_id<q->cell.nof_ports;port_id++) {
srslte_chest_dl_estimate_port(q, input, ce[port_id], sf_idx, port_id); if (srslte_chest_dl_estimate_port(q, input, ce[port_id], sf_idx, port_id, 0)) {
return SRSLTE_ERROR;
}
} }
q->last_nof_antennas = 1;
return SRSLTE_SUCCESS; return SRSLTE_SUCCESS;
} }
float srslte_chest_dl_get_noise_estimate(srslte_chest_dl_t *q) { float srslte_chest_dl_get_noise_estimate(srslte_chest_dl_t *q) {
return srslte_vec_acc_ff(q->noise_estimate, q->cell.nof_ports)/q->cell.nof_ports; float n = 0;
for (int i=0;i<q->last_nof_antennas;i++) {
n += srslte_vec_acc_ff(q->noise_estimate[i], q->cell.nof_ports)/q->cell.nof_ports;
}
return n/q->last_nof_antennas;
} }
float srslte_chest_dl_get_snr(srslte_chest_dl_t *q) { float srslte_chest_dl_get_snr(srslte_chest_dl_t *q) {
@ -378,20 +398,31 @@ float srslte_chest_dl_get_snr(srslte_chest_dl_t *q) {
} }
float srslte_chest_dl_get_rssi(srslte_chest_dl_t *q) { float srslte_chest_dl_get_rssi(srslte_chest_dl_t *q) {
return 4*q->rssi[0]/q->cell.nof_prb/SRSLTE_NRE; float n = 0;
for (int i=0;i<q->last_nof_antennas;i++) {
n += 4*q->rssi[i][0]/q->cell.nof_prb/SRSLTE_NRE;
}
return n/q->last_nof_antennas;
} }
/* q->rssi[0] is the average power in all RE in all symbol containing references for port 0 . q->rssi[0]/q->cell.nof_prb is the average power per PRB /* q->rssi[0] is the average power in all RE in all symbol containing references for port 0 . q->rssi[0]/q->cell.nof_prb is the average power per PRB
* q->rsrp[0] is the average power of RE containing references only (for port 0). * q->rsrp[0] is the average power of RE containing references only (for port 0).
*/ */
float srslte_chest_dl_get_rsrq(srslte_chest_dl_t *q) { float srslte_chest_dl_get_rsrq(srslte_chest_dl_t *q) {
return q->cell.nof_prb*q->rsrp[0] / q->rssi[0]; float n = 0;
for (int i=0;i<q->last_nof_antennas;i++) {
n += q->cell.nof_prb*q->rsrp[i][0] / q->rssi[i][0];
}
return n/q->last_nof_antennas;
} }
float srslte_chest_dl_get_rsrp(srslte_chest_dl_t *q) { float srslte_chest_dl_get_rsrp(srslte_chest_dl_t *q) {
// return sum of power received from all tx ports // return sum of power received from all tx ports
return srslte_vec_acc_ff(q->rsrp, q->cell.nof_ports); float n = 0;
for (int i=0;i<q->last_nof_antennas;i++) {
n += srslte_vec_acc_ff(q->rsrp[i], q->cell.nof_ports);
}
return n/q->last_nof_antennas;
} }

@ -33,8 +33,6 @@ add_test(chest_test_dl_cellid0 chest_test_dl -c 0 -r 50)
add_test(chest_test_dl_cellid1 chest_test_dl -c 1 -r 50) add_test(chest_test_dl_cellid1 chest_test_dl -c 1 -r 50)
add_test(chest_test_dl_cellid2 chest_test_dl -c 2 -r 50) add_test(chest_test_dl_cellid2 chest_test_dl -c 2 -r 50)
BuildMex(MEXNAME chest_dl SOURCES chest_test_dl_mex.c LIBRARIES srslte_static srslte_mex)
######################################################################## ########################################################################
# Uplink Channel Estimation TEST # Uplink Channel Estimation TEST
@ -50,10 +48,6 @@ add_test(chest_test_ul_cellid0 chest_test_ul -c 0 -r 50)
add_test(chest_test_ul_cellid1 chest_test_ul -c 1 -r 50) add_test(chest_test_ul_cellid1 chest_test_ul -c 1 -r 50)
add_test(chest_test_ul_cellid1 chest_test_ul -c 2 -r 50) add_test(chest_test_ul_cellid1 chest_test_ul -c 2 -r 50)
BuildMex(MEXNAME chest_ul SOURCES chest_test_ul_mex.c LIBRARIES srslte_static srslte_mex)
BuildMex(MEXNAME refsignal_pusch SOURCES refsignal_pusch_mex.c LIBRARIES srslte_static srslte_mex)
BuildMex(MEXNAME refsignal_srs SOURCES refsignal_srs_mex.c LIBRARIES srslte_static srslte_mex)

@ -161,7 +161,7 @@ int main(int argc, char **argv) {
struct timeval t[3]; struct timeval t[3];
gettimeofday(&t[1], NULL); gettimeofday(&t[1], NULL);
for (int j=0;j<100;j++) { for (int j=0;j<100;j++) {
srslte_chest_dl_estimate_port(&est, input, ce, sf_idx, n_port); srslte_chest_dl_estimate_port(&est, input, ce, sf_idx, n_port, 0);
} }
gettimeofday(&t[2], NULL); gettimeofday(&t[2], NULL);
get_time_interval(t); get_time_interval(t);

Some files were not shown because too many files have changed in this diff Show More

Loading…
Cancel
Save