Merge remote-tracking branch 'origin/develop' into NR_remove_ssb_offset_from_configfile
This commit is contained in:
@@ -38,7 +38,6 @@
|
||||
#define MAX_TURBO_ITERATIONS_MBSFN 8
|
||||
#define MAX_TURBO_ITERATIONS max_turbo_iterations
|
||||
|
||||
#define MAX_LDPC_ITERATIONS 5
|
||||
#define MAX_LDPC_ITERATIONS_MBSFN 4
|
||||
|
||||
#define LTE_NULL 2
|
||||
|
||||
Binary file not shown.
|
Before Width: | Height: | Size: 3.6 KiB |
Binary file not shown.
@@ -1,960 +0,0 @@
|
||||
%
|
||||
% Licensed to the OpenAirInterface (OAI) Software Alliance under one or more
|
||||
% contributor license agreements. See the NOTICE file distributed with
|
||||
% this work for additional information regarding copyright ownership.
|
||||
% The OpenAirInterface Software Alliance licenses this file to You under
|
||||
% the OAI Public License, Version 1.1 (the "License"); you may not use this file
|
||||
% except in compliance with the License.
|
||||
% You may obtain a copy of the License at
|
||||
%
|
||||
% http://www.openairinterface.org/?page_id=698
|
||||
%
|
||||
% Unless required by applicable law or agreed to in writing, software
|
||||
% distributed under the License is distributed on an "AS IS" BASIS,
|
||||
% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
% See the License for the specific language governing permissions and
|
||||
% limitations under the License.
|
||||
%-------------------------------------------------------------------------------
|
||||
% For more information about the OpenAirInterface (OAI) Software Alliance:
|
||||
% contact@openairinterface.org
|
||||
%
|
||||
|
||||
\documentclass{article}
|
||||
|
||||
\usepackage[a4paper, total={6in, 8in}]{geometry}
|
||||
|
||||
\usepackage{amsmath}
|
||||
\usepackage{amsfonts}
|
||||
\usepackage{amssymb}
|
||||
\usepackage{booktabs}
|
||||
\usepackage{url}
|
||||
\usepackage{tcolorbox}
|
||||
|
||||
\usepackage{tikz}
|
||||
\usetikzlibrary{arrows,decorations,shapes,backgrounds,patterns}
|
||||
\usepackage{pgfplots}
|
||||
\pgfplotsset{compat=newest}
|
||||
\definecolor{green}{RGB}{32,127,43}
|
||||
\usetikzlibrary{calc}
|
||||
|
||||
\usepackage{listings}
|
||||
\lstdefinestyle{customc}{
|
||||
belowcaptionskip=1\baselineskip,
|
||||
breaklines=true,
|
||||
frame=L,
|
||||
xleftmargin=\parindent,
|
||||
language=C,
|
||||
showstringspaces=false,
|
||||
basicstyle=\footnotesize\ttfamily,
|
||||
keywordstyle=\bfseries\color{green!40!black},
|
||||
commentstyle=\itshape\color{purple!40!black},
|
||||
identifierstyle=\color{blue},
|
||||
stringstyle=\color{orange},
|
||||
}
|
||||
\lstset{escapechar=@,style=customc}
|
||||
|
||||
\title{NR LDPC Decoder}
|
||||
\author{Sebastian Wagner (TCL)}
|
||||
\date{\today}
|
||||
|
||||
\def\0{\mathbf{0}}
|
||||
\def\b{\mathbf{b}}
|
||||
\def\Bbb{\mathbb{B}}
|
||||
\def\Bcal{\mathcal{B}}
|
||||
\def\c{\mathbf{c}}
|
||||
\def\C{\mathbf{C}}
|
||||
\def\Cbb{\mathbb{C}}
|
||||
\def\Ccal{\mathcal{C}}
|
||||
\def\eqdef{\triangleq}
|
||||
\def\g{\mathbf{g}}
|
||||
\def\G{\mathbf{G}}
|
||||
\def\Gcal{\mathcal{G}}
|
||||
\def\h{\mathbf{h}}
|
||||
\def\H{\mathbf{H}}
|
||||
\def\Hbg{\mathbf{H}_\mathrm{BG}}
|
||||
\def\Hbgo{\mathbf{H}_\mathrm{BG1}}
|
||||
\def\Hbgt{\mathbf{H}_\mathrm{BG2}}
|
||||
\def\I{\mathbf{I}}
|
||||
\def\Kb{{K_b}}
|
||||
\def\m{\mathbf{m}}
|
||||
\def\Mb{{M_b}}
|
||||
\def\Nb{{N_b}}
|
||||
\def\Nbb{\mathbb{N}}
|
||||
\def\n{\mathbf{n}}
|
||||
\def\nr{{n_{\rm r}}}
|
||||
\def\nt{{n_{\rm t}}}
|
||||
\def\s{\mathbf{s}}
|
||||
\def\SNR{\mathsf{SNR}}
|
||||
\def\y{\mathbf{y}}
|
||||
\def\z{\mathbf{z}}
|
||||
\def\Z{\mathbf{Z}}
|
||||
\def\Zc{{Z_c}}
|
||||
|
||||
|
||||
\def\herm{\mathsf{H}}
|
||||
\def\trans{\mathsf{T}}
|
||||
\def\EE{\mathsf{E}}
|
||||
\newcommand{\sgn}{\operatorname{sgn}}
|
||||
|
||||
\begin{document}
|
||||
|
||||
\maketitle
|
||||
|
||||
\begin{tikzpicture}[remember picture,overlay]
|
||||
\node[anchor=north west,inner sep=0pt] at (current page.north west)
|
||||
{\includegraphics[scale=0.5]{logo.png}};
|
||||
\end{tikzpicture}
|
||||
|
||||
|
||||
\begin{center}Currently Supported:\end{center}
|
||||
\tcbox[center]{
|
||||
\begin{tabular}{lll}
|
||||
\toprule
|
||||
\textbf{BG} & \textbf{Lifting Size Z} & \textbf{Code Rate R} \\
|
||||
\midrule
|
||||
1 & all & 1/3, 2/3, 8/9 \\
|
||||
2 & all & 1/5, 1/3, 2/3 \\
|
||||
\bottomrule
|
||||
\end{tabular}
|
||||
}
|
||||
|
||||
\paragraph{Version 1.0:}
|
||||
\begin{itemize}
|
||||
\item Initial version
|
||||
\end{itemize}
|
||||
|
||||
\paragraph{Version 2.0:}
|
||||
\begin{itemize}
|
||||
\item Enhancements in message passing:
|
||||
\begin{itemize}
|
||||
\item LUTs replaced by smaller BG-specific parameters
|
||||
\item Inefficient load/store replaced by circular memcpy
|
||||
\end{itemize}
|
||||
\item Bug fixes:
|
||||
\begin{itemize}
|
||||
\item Fixed bug in function \texttt{llr2CnProcBuf}
|
||||
\item Corrected input LLR dynamic range in BLER simulations
|
||||
\end{itemize}
|
||||
\item Results:
|
||||
\begin{itemize}
|
||||
\item Size of LUTs reduced significantly (60MB to 200KB)
|
||||
\item Siginifcantly enhances execution time (factor 3.5)
|
||||
\item Improved BLER performance (all simulation results have been updated)
|
||||
\end{itemize}
|
||||
\end{itemize}
|
||||
|
||||
|
||||
\newpage
|
||||
\tableofcontents
|
||||
|
||||
\newpage
|
||||
\section{Introduction}
|
||||
\label{sec:introduction}
|
||||
|
||||
Low Density Parity Check (LDPC) codes have been developed by Gallager in 1963 \cite{gallager1962low}. They are linear error correcting codes that are capacity-achieving for large block length and are completely described by their Parity Check Matrix (PCM) $\H^{M\times N}$. The PCM $\H$ defines $M$ constraints on the codeword $\c$ of length $N$ such that
|
||||
\begin{equation}
|
||||
\label{eq:29}
|
||||
\H\c = \0.
|
||||
\end{equation}
|
||||
The number of information bits $B$ that can be encoded with $\H$ is given by $B=N-M$. Hence the code rate $R$ of $\H$ reads
|
||||
\begin{equation}
|
||||
\label{eq:37}
|
||||
R = \frac{B}{N} = 1-\frac{M}{N}.
|
||||
\end{equation}
|
||||
|
||||
|
||||
\subsection{LDPC in NR}
|
||||
\label{sec:ldpc-nr}
|
||||
|
||||
NR uses quasi-cyclic (QC) Protograph LDPC codes, i.e. a smaller graph, called Base Graph (BG), is defined and utilized to construct the larger PCM. This has the advantage that the large PCM does not have to be stored in memory and allows for a more efficient implementation while maintaining good decoding properties.
|
||||
Two BGs $\Hbg\in\Nbb^{\Mb\times \Nb}$ are defined in NR:
|
||||
\begin{enumerate}
|
||||
\item $\Hbgo\in\Nbb^{46\times 68}$
|
||||
\item $\Hbgt\in\Nbb^{42\times 52}$
|
||||
\end{enumerate}
|
||||
where $\Nbb$ is the set of integers. For instance the first 3 rows and 13 columns of BG2 are given by
|
||||
|
||||
\setcounter{MaxMatrixCols}{30}
|
||||
\begin{equation*}
|
||||
\label{eq:33}
|
||||
\Hbgt =
|
||||
\begin{bmatrix}
|
||||
9 & 117 & 204 & 26 & \emptyset & \emptyset & 189 & \emptyset & \emptyset & 205 & 0 & 0 & \emptyset & \emptyset \\
|
||||
127 & \emptyset & \emptyset & 166 & 253 & 125 & 226 & 156 & 224 & 252 & \emptyset & 0 & 0 & \emptyset \\
|
||||
81 & 114 & \emptyset & 44 & 52 & \emptyset & \emptyset & \emptyset & 240 & \emptyset & 1 & \emptyset & 0 & 0
|
||||
\end{bmatrix}.
|
||||
\end{equation*}
|
||||
|
||||
To obtain the PCM $\H$ from the BG $\Hbg$, each element $\Hbg(i,j)$ in the BG is replaced by a lifting matrix of size $\Zc\times \Zc$ according to
|
||||
\begin{equation}
|
||||
\label{eq:35}
|
||||
\Hbg(i,j) =
|
||||
\begin{cases}
|
||||
\0 & \textrm{if}~ \Hbg(i,j)=\emptyset \\
|
||||
\I_{P_{ij}} & \textrm{otherwise}
|
||||
\end{cases}
|
||||
\end{equation}
|
||||
where $\I_{P_{ij}}$ is the identity matrix circularly shifted to the right by $P_{ij} = \Hbg(i,j)\mod \Zc$. Hence, the resulting PCM $\H$ will be of size $\Mb\Zc\times\Nb\Zc$.
|
||||
|
||||
The lifting size $\Zc$ depends on the number of bits to encode. To limit the complexity, a discrete set $\mathcal{Z}$ of possible values of $\Zc$ has been defined in \cite{3gpp2017_38212} and the optimal value $\Zc$ is calculated according to
|
||||
\begin{equation}
|
||||
\label{eq:36}
|
||||
\Zc = \min_{\Z\in\mathcal{Z}}\left[Z\geq\frac{B}{\Nb}\right].
|
||||
\end{equation}
|
||||
|
||||
The base rate of the two BGs is $1/3$ and $1/5$ for BG1 and BG2, respectively. That is, BG1 encodes $K=22\Zc$ bits and BG2 encodes $K=10\Zc$ bits. Note that the first 2 columns of BG 1 and 2 are always punctured, that is after encoding, the first $2\Zc$ bits are discarded and not transmitted.
|
||||
For instance, consider $B=500$ information bits to encode using BG2, \eqref{eq:36} yields $\Zc=64$ hence $K=640$. Since $K>B$, $K-B=140$ filler bits are appended to the information bits. The PCM $\Hbgt$ is of size $2688\times 3328$ and the $640$ bits $\b$ are encoded according to \eqref{eq:29} at a rate $R \approx 0.192$. To achieve the higher base rate of $0.2$, the first $128$ are punctured, i.e. instead of transmitting all $3328$ bits, only $3200$ are transmitted resulting in the desired rate $R=640/3200=0.2$.
|
||||
|
||||
\subsection{LDPC Decoding}
|
||||
\label{sec:ldpc-decoding}
|
||||
|
||||
The decoding of codeword $\c$ can be achieved via the classical message passing algorithm. This algorithm can be illustrated best using the Tanner graph of the PCM. The rows of the PCM are called check nodes (CN) since they represent the parity check equations. The parity check equation of each of these check nodes involves various bits in the codeword. Similarly, every column of the PCM corresponds to a bit and each bit is involved in several parity check equations. In the Tanner graph representation, the bits are called bit nodes (BN). Let's go back to the previous example of BG2 and assume $\Zc=2$, hence the first 3 rows and 13 columns of BG2 $\Hbgt$ read
|
||||
\begin{equation*}
|
||||
\label{eq:36}
|
||||
\Hbgt =
|
||||
\begin{bmatrix}
|
||||
1 & 1 & 0 & 0 & \emptyset & \emptyset & 1 & \emptyset & \emptyset & 1 & 0 & 0 & \emptyset & \emptyset \\
|
||||
1 & \emptyset & \emptyset & 0 & 1 & 1 & 0 & 0 & 0 & 0 & \emptyset & 0 & 0 & \emptyset \\
|
||||
1 & 0 & \emptyset & 0 & 0 & \emptyset & \emptyset & \emptyset & 0 & \emptyset & 1 & \emptyset & 0 & 0
|
||||
\end{bmatrix}.
|
||||
\end{equation*}
|
||||
Replacing the elements according to \eqref{eq:35}, we obtain the first 6 rows and 26 columns of the PCM as
|
||||
\begin{equation*}
|
||||
\label{eq:39}
|
||||
\H =
|
||||
\begin{bmatrix}
|
||||
0 & 1 & 0 & 1 & 1 & 0 & 1 & 0 & 0 & 0 & 0 & 0 & 0 & 1 & 0 & 0 & 0 & 0 & 0 & 1 & 1 & 0 & 1 & 0 & 0 & 0 & 0 & 0\\
|
||||
1 & 0 & 1 & 0 & 0 & 1 & 0 & 1 & 0 & 0 & 0 & 0 & 1 & 0 & 0 & 0 & 0 & 0 & 1 & 0 & 0 & 1 & 0 & 1 & 0 & 0 & 0 & 0\\
|
||||
0 & 1 & 0 & 0 & 0 & 0 & 1 & 0 & 0 & 1 & 0 & 1 & 1 & 0 & 1 & 0 & 1 & 0 & 1 & 0 & 0 & 0 & 1 & 0 & 1 & 0 & 0 & 0\\
|
||||
1 & 0 & 0 & 0 & 0 & 0 & 0 & 1 & 1 & 0 & 1 & 0 & 0 & 1 & 0 & 1 & 0 & 1 & 0 & 1 & 0 & 0 & 0 & 1 & 0 & 1 & 0 & 0\\
|
||||
0 & 1 & 1 & 0 & 0 & 0 & 1 & 0 & 1 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 1 & 0 & 0 & 0 & 0 & 1 & 0 & 0 & 1 & 0 & 1 & 0\\
|
||||
1 & 0 & 0 & 1 & 0 & 0 & 0 & 1 & 0 & 1 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 1 & 0 & 0 & 1 & 0 & 0 & 0 & 0 & 1 & 0 & 1
|
||||
\end{bmatrix}.
|
||||
\end{equation*}
|
||||
|
||||
The Tanner graph of the first 8 BNs is shown in Figure \ref{fig:tannergraph}.
|
||||
|
||||
\begin{figure}[ht]
|
||||
\label{fig:tannergraph}
|
||||
\centering
|
||||
\def\ww{0.3cm}
|
||||
\def\hh{0.3cm}
|
||||
\tikzstyle{cnode}=[fill=white,rectangle,draw=black,thick,inner sep=2pt, minimum height=\hh,minimum width=\ww, rounded corners=1pt,text width=\ww]
|
||||
\tikzstyle{vnode}=[fill=white,circle,draw=black,thick,inner sep=2pt, minimum height=\hh,minimum width=\ww, rounded corners=1pt,text width=\ww]
|
||||
\tikzstyle{connector}=[<->,>=latex',semithick]
|
||||
|
||||
\begin{tikzpicture}
|
||||
\tikzstyle{every node}=[node distance=1.5cm,text centered]
|
||||
% Check nodes
|
||||
\node[cnode, label=above:$v_0$] (v0) {};
|
||||
\node[cnode, label=above:$v_1$, right of=v0] (v1) {};
|
||||
\node[cnode, label=above:$v_2$, right of=v1] (v2) {};
|
||||
% Variable nodes
|
||||
\node[vnode, label=below:$c_3$, below of=v1, node distance=1.5cm] (c3) {};
|
||||
\node[vnode, label=below:$c_2$, left of=c3, node distance=1.5cm] (c2) {};
|
||||
\node[vnode, label=below:$c_1$, left of=c2, node distance=1.5cm] (c1) {};
|
||||
\node[vnode, label=below:$c_0$, left of=c1, node distance=1.5cm] (c0) {};
|
||||
\node[vnode, label=below:$c_4$, right of=c3, node distance=1.5cm] (c4) {};
|
||||
\node[vnode, label=below:$c_5$, right of=c4, node distance=1.5cm] (c5) {};
|
||||
\node[vnode, label=below:$c_6$, right of=c5, node distance=1.5cm] (c6) {};
|
||||
|
||||
% Draw edges
|
||||
\draw (c0) edge[connector] (v1);
|
||||
\draw (c1) edge[connector] (v0);
|
||||
\draw (c1) edge[connector] (v2);
|
||||
\draw (c2) edge[connector] (v1);
|
||||
\draw (c3) edge[connector] (v0);
|
||||
\draw (c4) edge[connector] (v0);
|
||||
\draw (c4) edge[connector] (v2);
|
||||
\draw (c5) edge[connector] (v1);
|
||||
\draw (c6) edge[connector] (v0);
|
||||
\draw (c6) edge[connector] (v2);
|
||||
|
||||
\end{tikzpicture}
|
||||
|
||||
\caption{Tanner graph for first 7 bits nodes and 3 check nodes from \eqref{eq:39}.}
|
||||
\end{figure}
|
||||
|
||||
The message passing algorithm is an iterative algorithm where probabilities of the bits (being either 0 or 1) are exchanged between the BNs and CNs. After sufficient iterations, the probabilities will have either converged to either 0 or 1 and the parity check equations will be satisfied, at this point, the codeword has been decoded correctly.
|
||||
|
||||
\newpage
|
||||
\section{LDPC Decoder Implementation}
|
||||
\label{sec:ldpc-implementation}
|
||||
|
||||
The implementation on a general purpose processor (GPP) has to take advantage of potential instruction extension of the processor architecture. We focus on the Intel x86 instruction set architecture (ISA) and its advanced vector extension (AVX). In particular, we utilize AVX2 with its 256-bit single instruction multiple data (SIMD) format. In order to utilize AVX2 to speed up the processing at the CNs and BNs, the corresponding data has to be ordered/aligned in a specific way. The processing flow of the LDPC decoder is depicted in \ref{fig:ldpc_decoder_flow}.
|
||||
|
||||
\begin{figure}[ht]
|
||||
\label{fig:ldpc_decoder_flow}
|
||||
\centering
|
||||
\def\ww{0.3cm}
|
||||
\def\hh{0.3cm}
|
||||
\tikzstyle{func}=[,draw=none]
|
||||
\tikzstyle{connector}=[->,>=latex',semithick]
|
||||
|
||||
\begin{tikzpicture}
|
||||
\tikzstyle{every node}=[node distance=2.5cm,text centered]
|
||||
% Check nodes
|
||||
% First iteration
|
||||
\node[func] (llr2llrProcBuf) {\texttt{llr2llrProcBuf}};
|
||||
\node[func, above of=llr2llrProcBuf] (llr2CnProcBuf) {\texttt{llr2CnProcBuf}};
|
||||
\node[func, above right of=llr2CnProcBuf] (cnProc1) {\texttt{cnProc}};
|
||||
\node[func, below right of=cnProc1] (cn2bnProcBuf1) {\texttt{cn2bnProcBuf}};
|
||||
\node[func, below of=cn2bnProcBuf1] (bnProcPc1) {\texttt{bnProcPc}};
|
||||
|
||||
% Iterations
|
||||
\node[func, right of=cnProc1, node distance=7cm] (cnProc) {\texttt{cnProc}};
|
||||
\node[func, below right of=cnProc] (cn2bnProcBuf) {\texttt{cn2bnProcBuf}};
|
||||
\node[func, below of=cn2bnProcBuf] (bnProcPc) {\texttt{bnProcPc}};
|
||||
\node[func, below left of=cnProc] (bn2cnProcBuf) {\texttt{bn2cnProcBuf}};
|
||||
\node[func, below of=bn2cnProcBuf] (bnProc) {\texttt{bnProc}};
|
||||
|
||||
% Post processing
|
||||
\node[func, below of=bnProcPc] (llrRes2llrOut) {\texttt{llrRes2llrOut}};
|
||||
\node[func, below of=llrRes2llrOut, node distance=1cm] (llr2bit) {\texttt{llr2bit}};
|
||||
|
||||
% Draw edges
|
||||
\draw (llr2llrProcBuf) edge[connector] (llr2CnProcBuf);
|
||||
\draw (llr2CnProcBuf) edge[connector] (cnProc1);
|
||||
\draw (cnProc1) edge[connector] (cn2bnProcBuf1);
|
||||
\draw (cn2bnProcBuf1) edge[connector] (bnProcPc1);
|
||||
|
||||
\draw (bnProcPc) edge[connector] (bnProc);
|
||||
\draw (bnProc) edge[connector] (bn2cnProcBuf);
|
||||
\draw (bn2cnProcBuf) edge[connector] node[above left] {\texttt{cnProcPc}} (cnProc);
|
||||
\draw (cnProc) edge[connector] (cn2bnProcBuf);
|
||||
\draw (cn2bnProcBuf) edge[connector] (bnProcPc);
|
||||
|
||||
\draw (bnProcPc1) edge[connector] (bnProc);
|
||||
|
||||
\draw (bnProcPc) edge[connector] node[left] {iterations done} (llrRes2llrOut);
|
||||
\draw (llrRes2llrOut) edge[connector] (llr2bit);
|
||||
|
||||
% Boxes
|
||||
\node[inner sep=0pt,above right of=cn2bnProcBuf1, node distance = 2.5cm] (ref) {};
|
||||
|
||||
\draw[fill=black,opacity=.2, rounded corners] (llr2llrProcBuf.south west) rectangle ($(ref) + (-.5cm,.5cm)$);
|
||||
\draw[fill=black,opacity=.2, rounded corners] ($(ref) + (.5cm,.5cm)$) rectangle ($(bnProcPc.south east) + (.4cm,0)$);
|
||||
|
||||
\node[func, above of=cnProc1, node distance=.8cm] (iter1) {\textbf{First Iteration}};
|
||||
\node[func, above of=cnProc , node distance=.8cm] (iterX) {\textbf{Subsequent Iterations}};
|
||||
|
||||
\end{tikzpicture}
|
||||
|
||||
\caption{LDPC Decoder processing flow.}
|
||||
\end{figure}
|
||||
|
||||
The functions involved are described in more detail in Table \ref{tab:sum_func}.
|
||||
|
||||
\begin{table}[ht]
|
||||
\centering
|
||||
\begin{tabular}{ll}
|
||||
\toprule
|
||||
\textbf{Function} & \textbf{Description} \\
|
||||
\midrule
|
||||
\texttt{llr2llrProcBuf} & Copies input LLRs to LLR processing buffer \\
|
||||
\texttt{llr2CnProcBuf} & Copies input LLRs to CN processing buffer \\
|
||||
\texttt{cnProc} & Performs CN signal processing \\
|
||||
\texttt{cnProcPc} & Performs parity check \\
|
||||
\texttt{cn2bnProcBuf} & Copies the CN results to the BN processing buffer \\
|
||||
\texttt{bnProcPc} & Performs BN processing for parity check and/or hard-decision \\
|
||||
\texttt{bnProc} & Utilizes the results of \texttt{bnProcPc} to compute LLRs for CN processing \\
|
||||
\texttt{bn2cnProcBuf} & Copies the BN results to the CN processing buffer \\
|
||||
\texttt{llrRes2llrOut} & Copies the results of \texttt{bnProcPc} to output LLRs \\
|
||||
\texttt{llr2bit} & Performs hard-decision on the output LLRs \\
|
||||
\bottomrule
|
||||
\end{tabular}
|
||||
\caption{Summary of the LDPC decoder functions.}
|
||||
\label{tab:sum_func}
|
||||
\end{table}
|
||||
|
||||
The input LLRs are assumed to be 8-bit and aligned on 32 bytes. CN processing is carried out in 8-bit whereas BN processing is done in 16 bit. Subsequently, the processing tasks at the CNs and BNs are explained in more detail.
|
||||
|
||||
\newpage
|
||||
\subsection{Check Node Processing}
|
||||
\label{sec:check-node-proc}
|
||||
|
||||
Denote $q_{ij}$ the value from BN $j$ to CN $i$ and let $\Bcal_i$ be the set of connected BNs to the $i$th CN. Then, using the min-sum approximation, CN $i$ has to carry out the following operation for each connected BN.
|
||||
\begin{equation}
|
||||
\label{eq:40}
|
||||
r_{ji} = \prod_{j'\in\Bcal_i\setminus j}\sgn q_{ij'}\min_{j'\in\Bcal_i\setminus j} |q_{ij'}|
|
||||
\end{equation}
|
||||
where $r_{ji}$ is the value returned to BN $j$ from CN $i$. There are $\Mb = \{46,42\}$ CNs in BG 1 and BG 2, respectively. Each of these CNs is connected to only a small number of BNs. The number of connected BNs to CN $i$ is $|\Bcal_i|$. In BG1 and BG2, $|\Bcal_i|=\{3,4,5,6,7,8,9,10,19\}$ and $|\Bcal_i|=\{3,4,5,6,8,10\}$, respectively. The following tables show the number of CNs $M_{|\Bcal_i|}$ that are connected to the same number of BNs.
|
||||
|
||||
\begin{table}[ht]
|
||||
\centering
|
||||
\begin{tabular}{llllllllll}
|
||||
\toprule
|
||||
$|\Bcal_i|$ & 3 & 4 & 5 & 6 & 7 & 8 & 9 & 10 & 19 \\
|
||||
\midrule
|
||||
$M_{|\Bcal_i|}^\mathrm{BG1}$ & 1 & 5 &18 & 8 & 5 & 2 & 2 & 1 & 4 \\
|
||||
$M_{|\Bcal_i|}^\mathrm{BG2}$ & 6 & 20 & 9 & 3 & 0 & 2 & 0 & 2 & 0 \\
|
||||
\bottomrule
|
||||
\end{tabular}
|
||||
\caption{Ceck node groups for BG1 and BG2.}
|
||||
\label{tab:checkNodeGroups}
|
||||
\end{table}
|
||||
|
||||
It can be observed that each CN is at least connected to 3 BNs and there are 9 groups and 5 groups in BG1 and BG2, respectively. Denote the set of CN groups as $\Gcal$ and $M_k$ the number of CNs in group $k\in\Gcal$, e.g. for BG2 $M_4=20\Zc$. Each CN group will be processed separately. The CN processing buffer $p_C^k$ of group $k$ is defined as
|
||||
\begin{equation}
|
||||
\label{eq:44}
|
||||
p_C^k = \{\underbrace{q_{11}q_{21}\dots q_{M_k 1}}_{\text 1. BN},\underbrace{q_{12}q_{22}\dots q_{M_k 2}}_{\text 2. BN},\dots,\underbrace{q_{12}q_{22}\dots q_{M_k k}}_{\text last BN}\}
|
||||
\end{equation}
|
||||
Hence, $|p_C^k| = kM_k$, e.g, $\Zc=128$, $|p_C^4| = 4\cdot 20\cdot 128 = 10240$.
|
||||
|
||||
\begin{lstlisting}[frame=single,caption={Example of CN processing for group 3 from \texttt{cnProc}.},label=code_cnproc] % Start your code-block
|
||||
|
||||
const uint8_t lut_idxCnProcG3[3][2] = {{72,144}, {0,144}, {0,72}};
|
||||
|
||||
// =====================================================================
|
||||
// Process group with 3 BNs
|
||||
|
||||
// Number of groups of 32 CNs for parallel processing
|
||||
M = (lut_numCnInCnGroups[0]*Z)>>5;
|
||||
// Set the offset to each bit within a group in terms of 32 Byte
|
||||
bitOffsetInGroup = (lut_numCnInCnGroups_BG2_R15[0]*NR_LDPC_ZMAX)>>5;
|
||||
|
||||
// Set pointers to start of group 3
|
||||
p_cnProcBuf = (__m256i*) &cnProcBuf [lut_startAddrCnGroups[0]];
|
||||
p_cnProcBufRes = (__m256i*) &cnProcBufRes[lut_startAddrCnGroups[0]];
|
||||
|
||||
// Loop over every BN
|
||||
for (j=0; j<3; j++)
|
||||
{
|
||||
// Set of results pointer to correct BN address
|
||||
p_cnProcBufResBit = p_cnProcBufRes + (j*bitOffsetInGroup);
|
||||
|
||||
// Loop over CNs
|
||||
for (i=0; i<M; i++)
|
||||
{
|
||||
// Abs and sign of 32 CNs (first BN)
|
||||
ymm0 = p_cnProcBuf[lut_idxCnProcG3[j][0] + i];
|
||||
sgn = _mm256_sign_epi8(*p_ones, ymm0);
|
||||
min = _mm256_abs_epi8(ymm0);
|
||||
|
||||
// 32 CNs of second BN
|
||||
ymm0 = p_cnProcBuf[lut_idxCnProcG3[j][1] + i];
|
||||
min = _mm256_min_epu8(min, _mm256_abs_epi8(ymm0));
|
||||
sgn = _mm256_sign_epi8(sgn, ymm0);
|
||||
|
||||
// Store result
|
||||
min = _mm256_min_epu8(min, *p_maxLLR); // 128 in epi8 is -127
|
||||
*p_cnProcBufResBit = _mm256_sign_epi8(min, sgn);
|
||||
p_cnProcBufResBit++;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
\end{lstlisting}
|
||||
|
||||
Once all results of the check node processing $r_{ji}$ have been calculated, they are copied to the bit node processing buffer.
|
||||
|
||||
\subsection{Bit Node Processing}
|
||||
\label{sec:bit-node-processing}
|
||||
|
||||
Denote $r_{ji}$ the value from CN $i$ to BN $j$ and let $\Ccal_j$ be the set of connected CNs to the $j$th BN. Each BN $j$ has to carry out the following operation for every connected CN $i\in\Ccal_j$.
|
||||
\begin{equation}
|
||||
\label{eq:46}
|
||||
q_{ij} = \Lambda_j + \sum_{i'\in\Ccal_j\setminus i}r_{ji'}
|
||||
\end{equation}
|
||||
|
||||
There are $\Nb = \{68,52\}$ BNs in BG 1 and BG 2, respectively. Each of these BNs is connected to only a small number of CNs. The number of connected CNs to BN $j$ is $|\Ccal_j|$. In BG1 and BG2, $|\Ccal_j|=\{1,4,7,8,9,10,11,12,28,30\}$ and $|\Ccal_j|=\{1,5,6,7,8,9,10,12,13,14,16,22,23\}$, respectively. The following tables show the number of BNs $K_{|\Ccal_j|}$ that are connected to the same number of CNs.
|
||||
|
||||
\begin{table}[ht]
|
||||
\centering
|
||||
\begin{tabular}{lllllllllllllllllll}
|
||||
\toprule
|
||||
$|\Ccal_j|$ & 1&4&5&6&7&8&9&10&11&12&13 & 14 & 15 & 16 & 22 & 23 &28&30 \\
|
||||
\midrule
|
||||
$K_{|\Ccal_j|}^\mathrm{BG1}$ & 42 & 1 & 1 & 2 & 4 & 3 & 1 & 4 & 3 & 4 & 1 & 0 & 0 & 0 & 0 & 0 & 1 & 1 \\
|
||||
$K_{|\Ccal_j|}^\mathrm{BG2}$ & 38 & 0 & 2 & 1 & 1 & 1 & 2 & 1 & 0 & 1 & 1 & 1 & 0 & 1 & 1 & 1 & 0 & 0\\
|
||||
\bottomrule
|
||||
\end{tabular}
|
||||
\caption{Bit node groups for BG1 and BG2 for base rates 1/3 and 1/5, respectively.}
|
||||
\label{tab:bitNodeGroups}
|
||||
\end{table}
|
||||
|
||||
The BNs that are connected to a single CN do not need to be considered in the BN processing since \eqref{eq:46} yields $q_{ij} = \Lambda_j$. It can be observed that the grouping is less compact, i.e. there are many groups with only a small number of elements.
|
||||
|
||||
Denote the set of BN groups as $\Bcal$ and $K_k$ the number of BNs in group $k\in\Bcal$, e.g. for BG2 $K_5=2\Zc$. Each BN group will be processed separately. The BN processing buffer $p_B^k$ of group $k$ is defined as
|
||||
\begin{equation}
|
||||
\label{eq:47}
|
||||
p_B^k = \{\underbrace{r_{11}r_{21}\dots r_{K_k 1}}_{\text 1. CN},\underbrace{r_{12}r_{22}\dots r_{K_k 2}}_{\text 2. CN},\dots,\underbrace{r_{12}r_{22}\dots r_{K_k k}}_{\text last CN}\}
|
||||
\end{equation}
|
||||
Hence, $|p_B^k| = kK_k$, e.g, $\Zc=128$, $|p_B^5| = 5\cdot 2\cdot 128 = 1024$.
|
||||
|
||||
Depending on the code rate, some parity bits are not being transmitted. For instance, for BG2 with code rate $R = 1/3$ the last $20\Zc$ bits are discarded. Therefore, the last 20 columns or the last $20\Zc$ parity check equation are not required for decoding. This means that the BN groups shown in table \ref{tab:bitNodeGroups} are depending on the rate.
|
||||
|
||||
\begin{lstlisting}[frame=single,caption={Example of BN processing for group 3 from \texttt{bnProcPc}.},label=code_bnproc] % Start your code-block
|
||||
|
||||
// If elements in group move to next address
|
||||
idxBnGroup++;
|
||||
|
||||
// Number of groups of 32 BNs for parallel processing
|
||||
M = (lut_numBnInBnGroups[2]*Z)>>5;
|
||||
|
||||
// Set the offset to each CN within a group in terms of 16 Byte
|
||||
cnOffsetInGroup = (lut_numBnInBnGroups[2]*NR_LDPC_ZMAX)>>4;
|
||||
|
||||
// Set pointers to start of group 3
|
||||
p_bnProcBuf = (__m128i*) &bnProcBuf [lut_startAddrBnGroups [idxBnGroup]];
|
||||
p_llrProcBuf = (__m128i*) &llrProcBuf [lut_startAddrBnGroupsLlr[idxBnGroup]];
|
||||
p_llrRes = (__m256i*) &llrRes [lut_startAddrBnGroupsLlr[idxBnGroup]];
|
||||
|
||||
// Loop over BNs
|
||||
for (i=0,j=0; i<M; i++,j+=2)
|
||||
{
|
||||
// First 16 LLRs of first CN
|
||||
ymmRes0 = _mm256_cvtepi8_epi16(p_bnProcBuf[j]);
|
||||
ymmRes1 = _mm256_cvtepi8_epi16(p_bnProcBuf[j+1]);
|
||||
|
||||
// Loop over CNs
|
||||
for (k=1; k<3; k++)
|
||||
{
|
||||
ymm0 = _mm256_cvtepi8_epi16(p_bnProcBuf[k*cnOffsetInGroup + j]);
|
||||
ymmRes0 = _mm256_adds_epi16(ymmRes0, ymm0);
|
||||
|
||||
ymm1 = _mm256_cvtepi8_epi16(p_bnProcBuf[k*cnOffsetInGroup + j+1]);
|
||||
ymmRes1 = _mm256_adds_epi16(ymmRes1, ymm1);
|
||||
}
|
||||
|
||||
// Add LLR from receiver input
|
||||
ymm0 = _mm256_cvtepi8_epi16(p_llrProcBuf[j]);
|
||||
ymmRes0 = _mm256_adds_epi16(ymmRes0, ymm0);
|
||||
|
||||
ymm1 = _mm256_cvtepi8_epi16(p_llrProcBuf[j+1]);
|
||||
ymmRes1 = _mm256_adds_epi16(ymmRes1, ymm1);
|
||||
|
||||
// Pack results back to epi8
|
||||
ymm0 = _mm256_packs_epi16(ymmRes0, ymmRes1);
|
||||
// ymm0 = [ymmRes1[255:128] ymmRes0[255:128] ymmRes1[127:0] ymmRes0[127:0]]
|
||||
// p_llrRes = [ymmRes1[255:128] ymmRes1[127:0] ymmRes0[255:128] ymmRes0[127:0]]
|
||||
*p_llrRes = _mm256_permute4x64_epi64(ymm0, 0xD8);
|
||||
|
||||
// Next result
|
||||
p_llrRes++;
|
||||
}
|
||||
}
|
||||
|
||||
\end{lstlisting}
|
||||
|
||||
The sum of the LLRs is carried out in 16 bit for accuracy and is then saturated to 8 bit for CN processing. Saturation after each addition results in significant loss of sensitivity for low code rates.
|
||||
|
||||
\subsection{Mapping to the Processing Buffers}
|
||||
\label{sec:mapp-cn-proc}
|
||||
|
||||
For efficient processing with the AVX instructions, the data is required to be aligned in a certain manner. That is the reason why processing buffers have been introduced. The drawback is that the results of the processing need to copied every time to the processing buffer of the next task. However, the speed up in computation with AVX more than makes up for the time wasted in copying data. The copying is implemented as a circular memcpy because every edge in the BG is a circular shift of a $Z\times Z$ identity matrix. Hence, a circular mempcy consists of two regular memcpys each copying a part of the $Z$ values depending on the circular shift in the BG definition. The circular shifts are stored in \texttt{nrLDPC\_lut.h} in arrays \texttt{circShift\_BGX\_ZX\_CNGX}. In the specification there are only 8 sets of cirular shifts defined. However, the applied circular shift depends on $Z$, i.e. modulo $Z$. To avoid inefficient modulo operations in loops, we store the the circular shift values for every $Z$. Moreover, for convinience the arrays are already arranged depending on the CN group (CNG).
|
||||
|
||||
\newpage
|
||||
\section{Performance Results}
|
||||
\label{sec:performance-results}
|
||||
|
||||
In this section, the performance in terms of BLER and decoding latency of the current LDPC decoder implementation is verified.
|
||||
|
||||
\subsection{BLER Performance}
|
||||
\label{sec:bler-performance}
|
||||
|
||||
In all simulations, we assume AWGN, QPSK modulation and 8-bit input LLRs, i.e. $-127$ until $+127$. The DLSCH coding procedure in 38.212 is used to encode/decode the TB and an error is declared if the TB CRC check failed. Results are averaged over at least $10\,000$ channel realizations.
|
||||
|
||||
The first set of simulations in Figure \ref{fig:bler-bg2-15} compares the current LDPC decoder implementation to the reference implementation developed by Kien. This reference implementation is called \textit{LDPC Ref} and uses the min-sum algorithm with 2 layers and 16 bit for processing. Our current optimized decoder implementation is referred to as \textit{LDPC OAI}. Moreover, reference results provided by Huawei are also shown.
|
||||
|
||||
\begin{figure}[ht]
|
||||
\centering
|
||||
\begin{tikzpicture}
|
||||
\tikzstyle{every pin}=[fill=white,draw=black]
|
||||
\pgfplotsset{every axis legend/.append style={
|
||||
cells={anchor=west}, at={(1.05,1)}, anchor=north west}}
|
||||
% \pgfplotsset{every axis plot/.append style={smooth}}
|
||||
\pgfplotsset{every axis/.append style={line width=0.5pt}}
|
||||
\pgfplotsset{every axis/.append style={mark options=solid, mark size=2.5pt}}
|
||||
|
||||
\begin{semilogyaxis}[title={}, xlabel={$\SNR$ [dB]}, ylabel={BLER},
|
||||
grid={both}, xmin=-4, xmax=2, xtick={-4,-3.5,...,2}, ymin=0,
|
||||
ymax=1,ytickten={-5,-4,-3,-2,-1,0},legend columns=1]
|
||||
|
||||
% HUAWEI merged BG2 2017-06-15
|
||||
\addplot[black, solid] plot coordinates { (-3.91839,0.01) (-3.5567,0.0001) };
|
||||
|
||||
% 5 iterations
|
||||
% LDPC Ref
|
||||
\addplot[red, solid, mark=o] plot coordinates {(-1.250000,0.781300) (-1.000000,0.421000) (-0.750000,0.140400) (-0.500000,0.028900) (-0.250000,0.003300) (0.000000,0.000300) (0.250000,0.000000) (0.500000,0.000000)};
|
||||
% LDPC OAI
|
||||
\addplot[blue, solid, mark=square] plot coordinates {(-1.000000,0.693730) (-0.750000,0.370190) (-0.500000,0.137260) (-0.250000,0.038850) (0.000000,0.009740) (0.250000,0.002510) (0.500000,0.000730) (0.750000,0.000180) };
|
||||
% Matlab layered min-sum with scaling factor 1
|
||||
\addplot[green, solid, mark=triangle] plot coordinates {(-1.750000,0.709000) (-1.500000,0.360600) (-1.250000,0.105500) (-1.000000,0.015700) (-0.750000,0.001300) (-0.500000,0.000100) (-0.250000,0.000000) (0.000000,0.000000) };
|
||||
% Matlab layered min-sum with scaling factor 0.8
|
||||
%\addplot[green, solid, mark=triangle] plot coordinates {(-2.750000,0.982300) (-2.500000,0.882200) (-2.250000,0.573100) (-2.000000,0.214100) (-1.750000,0.041300) (-1.500000,0.003800) (-1.250000,0.000000) (-1.000000,0.000000) };
|
||||
|
||||
% 10 iterations
|
||||
% Kien's 2-layer 16bit code
|
||||
\addplot[red, solid, mark=o] plot coordinates { (-2.750000,0.915500) (-2.500000,0.576000) (-2.250000,0.165000) (-2.000000,0.017100) (-1.750000,0.000600) (-1.500000,0.000000) (-1.250000,0.000000) (-1.000000,0.000000)};
|
||||
% LDPC OAI
|
||||
\addplot[blue, solid, mark=square] plot coordinates { (-2.750000,0.997200) (-2.500000,0.955000) (-2.250000,0.710900) (-2.000000,0.270400) (-1.750000,0.042400) (-1.500000,0.002200) (-1.250000,0.000000) (-1.000000,0.000000)};
|
||||
% Matlab layered min-sum with scaling factor 1
|
||||
\addplot[green, solid, mark=triangle] plot coordinates {(-2.750000,0.942900) (-2.500000,0.723200) (-2.250000,0.362300) (-2.000000,0.098400) (-1.750000,0.014500) (-1.500000,0.001100) (-1.250000,0.000000) (-1.000000,0.000000) };
|
||||
% Matlab layered min-sum with scaling factor 0.8
|
||||
%\addplot[green, solid, mark=triangle] plot coordinates {(-3.750000,0.994300) (-3.500000,0.927200) (-3.250000,0.651100) (-3.000000,0.252000) (-2.750000,0.042500) (-2.500000,0.002700) (-2.250000,0.000000) (-2.000000,0.000000) (-1.750000,0.000000) (-1.500000,0.000000) };
|
||||
|
||||
|
||||
% 20 iterations
|
||||
% Kien's 2-layer 16bit code
|
||||
\addplot[red, solid, mark=o] plot coordinates { (-2.750000,0.330300) (-2.500000,0.067800) (-2.250000,0.006000) (-2.000000,0.000100) (-1.750000,0.000000) (-1.500000,0.000000) (-1.250000,0.000000) (-1.000000,0.000000)};
|
||||
% LDPC OAI
|
||||
\addplot[blue, solid, mark=square] plot coordinates {(-2.750000,0.337900) (-2.500000,0.058300) (-2.250000,0.004000) (-2.000000,0.000200) (-1.750000,0.000000) (-1.500000,0.000000) };
|
||||
% Matlab layered min-sum with scaling factor 1
|
||||
%\addplot[green, solid, mark=triangle] plot coordinates {(-2.750000,0.843200) (-2.500000,0.524600) (-2.250000,0.198100) (-2.000000,0.037300) (-1.750000,0.003200) (-1.500000,0.000000) };
|
||||
% Matlab layered min-sum with scaling factor 0.8
|
||||
%\addplot[green, solid, mark=triangle] plot coordinates {(-3.750000,0.872300) (-3.500000,0.544600) (-3.250000,0.186400) (-3.000000,0.027500) (-2.750000,0.001900) (-2.500000,0.000000) };
|
||||
|
||||
|
||||
|
||||
% Parity check 50 iterations
|
||||
%\addplot[blue, solid, mark=square] plot coordinates {(-2.750000,0.214600) (-2.500000,0.029200) (-2.250000,0.001500) (-2.000000,0.000100) (-1.750000,0.000000) (-1.500000,0.000000) };
|
||||
|
||||
|
||||
\draw (axis cs:-3.3,0.1) node[fill=white,draw=black] (pint0) {20 iter};
|
||||
\draw (axis cs:-2.3,0.01) node[draw,black,thick,ellipse,minimum height=0.3cm] (ell0) {}; \draw[black,thick] (pint0) -- (ell0);
|
||||
|
||||
\draw (axis cs:-1.2,0.0001) node[fill=white,draw=black] (pint1) {10 iter};
|
||||
\draw (axis cs:-1.6,0.002) node[draw,black,thick,ellipse,minimum width=0.8cm] (ell1) {}; \draw[black,thick] (pint1) -- (ell1);
|
||||
|
||||
\draw (axis cs:1.3,0.2) node[fill=white,draw=black] (pint2) {5 iter};
|
||||
\draw (axis cs:-0.4,0.01) node[draw,black,thick,ellipse,minimum width=2cm] (ell2) {}; \draw[black,thick] (pint2) -- (ell2);
|
||||
|
||||
|
||||
\legend{ {Huawei 2017-06-15}\\
|
||||
{LDPC Ref}\\
|
||||
{LDPC OAI}\\
|
||||
{MATLAB NMS SF=1}\\};
|
||||
|
||||
\end{semilogyaxis}
|
||||
\end{tikzpicture}
|
||||
\caption{BLER vs. SNR, BG2, Rate=1/5, \{5,10,20\} Iterations, B=1280.}
|
||||
\label{fig:bler-bg2-15}
|
||||
\end{figure}
|
||||
|
||||
From Figure \ref{fig:bler-bg2-15} it can be observed that the reference decoder outperforms the current implementation significantly for low to medium number of iterations. The reason is the implementation of 2 layers in the reference decoder, which results in faster convergence for punctured codes and hence requires less iterations to achieve a given BLER target. Note that there is a large performance loss of about 4 dB at BLER $10^{-2}$ between the Huawei reference and the current optimized decoder implementation with 5 iterations.
|
||||
|
||||
Moreover, there is a gap of about 1.5 dB between the results provided by Huawei and the current decoder with 20 iterations. The reason is the min-sum approximation algorithm used in both the reference decoder and the current implementation. The gap can be closed by using a tighter approximation like the min-sum with normalization or the lambda-min approach. Moreover, the gap closes for higher code rates which can be observed from Figure \ref{fig:bler-bg2-r23}. The gap is only about 0.6 dB for 50 iterations.
|
||||
|
||||
The Matlab results denoted \texttt{MATLAB NMS} are obtained with the function \texttt{nrLDPCDecode} provided by the MATLAB 5G Toolbox R2019b. The following options are provided to the function: \texttt{'Termination','max','Algorithm','Normalized min-sum','ScalingFactor',1}. Furthermore, the 8-bit input LLRs are adapted to fit the dynamic range of \texttt{nrLDPCDecode} which is shown in Listing \ref{ldpc_matlab}.
|
||||
|
||||
\begin{lstlisting}[frame=single,caption={Input adaptation for MATLAB LDPC Decoder},label=ldpc_matlab]
|
||||
maxLLR = max(abs(softbits));
|
||||
rxLLRs = round((softbits/maxLLR)*127);
|
||||
// adjust range to fit tanh use in decoder code
|
||||
softbits = rxLLRs/3.4;
|
||||
\end{lstlisting}
|
||||
|
||||
A scaling factor (SF) of 1 has been chosen to compare the results more easily with the \textit{LDPC OAI} since the resulting check node processing is the same. However, the Matlab normelized min-sum algorithm uses layered processing and floating point operations. Thus, for the same number of iterations, the performance is significantly better than \textit{LDPC OAI}, especially for small a number of iterations.
|
||||
|
||||
\begin{figure}[ht]
|
||||
\centering
|
||||
\begin{tikzpicture}
|
||||
\tikzstyle{every pin}=[fill=white,draw=black]
|
||||
\pgfplotsset{every axis legend/.append style={
|
||||
cells={anchor=west}, at={(1.05,1)}, anchor=north west}}
|
||||
% \pgfplotsset{every axis plot/.append style={smooth}}
|
||||
\pgfplotsset{every axis/.append style={line width=0.5pt}}
|
||||
\pgfplotsset{every axis/.append style={mark options=solid, mark size=2.5pt}}
|
||||
|
||||
\begin{semilogyaxis}[title={}, xlabel={$\SNR$ [dB]}, ylabel={BLER},
|
||||
grid={both}, xmin=3, xmax=6.5, xtick={3,3.5,...,6.5}, ymin=0,
|
||||
ymax=1,ytickten={-5,-4,-3,-2,-1,0},legend columns=1]
|
||||
|
||||
% Kien's 2-layer 16bit code
|
||||
%\addplot[red, solid] plot coordinates { (-2.750000,0.915500) (-2.500000,0.576000) (-2.250000,0.165000) (-2.000000,0.017100) (-1.750000,0.000600) (-1.500000,0.000000) (-1.250000,0.000000) (-1.000000,0.000000)};
|
||||
|
||||
% Huawei
|
||||
\addplot[black, solid] plot coordinates { (3.28392,0.01) (3.73319,0.0001) };
|
||||
|
||||
% LDPC opt with 16bit BN processing
|
||||
%\addplot[blue, solid, mark=square] plot coordinates {(4.000000,0.487500) (4.250000,0.163400) (4.500000,0.029800) (4.750000,0.002700) (5.000000,0.000100)};
|
||||
\addplot[blue, solid, mark=square] plot coordinates {(5.000000,0.439600) (5.250000,0.185800) (5.500000,0.062100) (5.750000,0.015000) (6.000000,0.003900)};
|
||||
|
||||
|
||||
%\addplot[blue, dashed, mark=triangle] plot coordinates {(4.000000,0.487500) (4.250000,0.163700) (4.500000,0.030000) (4.750000,0.002900) (5.000000,0.000100)};
|
||||
|
||||
%\addplot[blue, dashed, mark=square] plot coordinates {(3.000000,0.911600) (3.250000,0.614100) (3.500000,0.230100) (3.750000,0.036900) (4.000000,0.001100) (4.250000,0.000000) (4.500000,0.000000)};
|
||||
\addplot[blue, dashed, mark=square] plot coordinates {(3.000000,0.900400) (3.250000,0.600000) (3.500000,0.216400) (3.750000,0.036000) (4.000000,0.002600) (4.250000,0.000000) };
|
||||
|
||||
|
||||
\legend{ {Huawei 2017-06-15}\\
|
||||
{LDPC OAI 5 iter}\\
|
||||
{LDPC OAI 50 iter}\\};
|
||||
|
||||
\end{semilogyaxis}
|
||||
\end{tikzpicture}
|
||||
\caption{BLER vs. SNR, BG2, Rate=2/3, \{5,50\} Iterations, B=1280.}
|
||||
\label{fig:bler-bg2-r23}
|
||||
\end{figure}
|
||||
|
||||
In Figure \ref{fig:bler-bg2-15-2} we compare the performance of different algorithms using at most 50 iterations with early stopping if the parity check passes. The Matlab layered believe propagation (LBP) is used with unquantized input LLRs and performs the best since no approximation is done in the processing. Both NMS and offset min-sum (OMS) use a scaling factor and offset, respectively, that has been empirically found to perform best in this simulation setting. Theirs performance is very close to the BLP and OMS is slightly better than NMS. The performance of \textit{LDPC OAI} is more than 1 dB worse mainly because of the looser approximation. Moreover, the NMS algorithm with SF=1 performs worst probably because the SF is not optimized for the input LLRs. From the results in Figure \ref{fig:bler-bg2-15-2} we can conclude that the performance of the \textit{LDPC OAI} can be significantly improved by adopting an offset min-sum approximation improving the performance to within 0.3dB of the Huawei reference curve.
|
||||
|
||||
\begin{figure}[ht]
|
||||
\centering
|
||||
\begin{tikzpicture}
|
||||
\tikzstyle{every pin}=[fill=white,draw=black]
|
||||
\pgfplotsset{every axis legend/.append style={
|
||||
cells={anchor=west}, at={(1.05,1)}, anchor=north west}}
|
||||
% \pgfplotsset{every axis plot/.append style={smooth}}
|
||||
\pgfplotsset{every axis/.append style={line width=0.5pt}}
|
||||
\pgfplotsset{every axis/.append style={mark options=solid, mark size=2.5pt}}
|
||||
|
||||
\begin{semilogyaxis}[title={}, xlabel={$\SNR$ [dB]}, ylabel={BLER},
|
||||
grid={both}, xmin=-4, xmax=-1, xtick={-4,-3.5,...,-1}, ymin=0,
|
||||
ymax=1,ytickten={-5,-4,-3,-2,-1,0},legend columns=1]
|
||||
|
||||
% HUAWEI merged BG2 2017-06-15
|
||||
\addplot[black, solid] plot coordinates { (-3.91839,0.01) (-3.5567,0.0001) };
|
||||
|
||||
% Parity check 50 iterations
|
||||
\addplot[blue, solid, mark=square] plot coordinates {(-2.750000,0.214600) (-2.500000,0.029200) (-2.250000,0.001500) (-2.000000,0.000100) (-1.750000,0.000000) (-1.500000,0.000000) };
|
||||
|
||||
% Matlab layered believe propagation
|
||||
\addplot[red, solid, mark=diamond] plot coordinates {(-4.500000,0.854200) (-4.250000,0.495800) (-4.000000,0.147700) (-3.750000,0.016100) (-3.500000,0.000800) (-3.250000,0.000200) (-3.000000,0.000000) };
|
||||
|
||||
% Matlab layered min-sum with scaling factor 1
|
||||
\addplot[green, dashed, mark=triangle] plot coordinates {(-2.750000,0.830100) (-2.500000,0.497700) (-2.250000,0.165800) (-2.000000,0.024000) (-1.750000,0.001900) (-1.500000,0.000000) };
|
||||
% Matlab layered min-sum with scaling factor 0.8
|
||||
%\addplot[green, solid, mark=triangle] plot coordinates {(-3.750000,0.734800) (-3.500000,0.353800) (-3.250000,0.084300) (-3.000000,0.008000) (-2.750000,0.000400) };
|
||||
\addplot[green, solid, mark=triangle] plot coordinates {(-4.500000,0.964400) (-4.250000,0.748200) (-4.000000,0.333600) (-3.750000,0.057700) (-3.500000,0.004400) (-3.250000,0.000400) };
|
||||
|
||||
% Matlab layered offset min-sum with offset 0.025
|
||||
\addplot[brown, solid, mark=asterisk] plot coordinates {(-4.250000,0.688800) (-4.000000,0.253800) (-3.750000,0.035600) (-3.500000,0.002000) (-3.250000,0.000000) (-3.000000,0.000000) };
|
||||
|
||||
|
||||
|
||||
\legend{ {Huawei 2017-06-15}\\
|
||||
{LDPC OAI}\\
|
||||
{MATLAB LBP}\\
|
||||
{MATLAB NMS SF=1}\\
|
||||
{MATLAB NMS SF=0.65}\\
|
||||
{MATLAB OMS OS=0.025}\\};
|
||||
|
||||
\end{semilogyaxis}
|
||||
\end{tikzpicture}
|
||||
\caption{BLER vs. SNR, BG2, Rate=1/5, max iterations = 50, B=1280.}
|
||||
\label{fig:bler-bg2-15-2}
|
||||
\end{figure}
|
||||
|
||||
|
||||
Figure \ref{fig:bler-bg1-r89} shows the performance of BG1 with largest block size of $B=8448$ and highest code rate $R=8/9$. From Figure \ref{fig:bler-bg1-r89} it can be observed that the performance gap is only about 0.3 dB if 50 iterations are used. However, for 5 iterations there is still a significant performance loss of about 2.3 dB at BLER $10^{-2}$.
|
||||
|
||||
\begin{figure}[ht]
|
||||
\centering
|
||||
\begin{tikzpicture}
|
||||
\tikzstyle{every pin}=[fill=white,draw=black]
|
||||
\pgfplotsset{every axis legend/.append style={
|
||||
cells={anchor=west}, at={(1.05,1)}, anchor=north west}}
|
||||
% \pgfplotsset{every axis plot/.append style={smooth}}
|
||||
\pgfplotsset{every axis/.append style={line width=0.5pt}}
|
||||
\pgfplotsset{every axis/.append style={mark options=solid, mark size=2.5pt}}
|
||||
|
||||
\begin{semilogyaxis}[title={}, xlabel={$\SNR$ [dB]}, ylabel={BLER},
|
||||
grid={both}, xmin=6, xmax=9, xtick={6,6.5,...,9}, ymin=0,
|
||||
ymax=1,ytickten={-5,-4,-3,-2,-1,0},legend columns=1]
|
||||
|
||||
% Huawei
|
||||
\addplot[black, solid] plot coordinates { (6.118717,0.01) (6.291449,0.0001) };
|
||||
|
||||
% LDPC opt 5 iter
|
||||
%\addplot[blue, solid, mark=square] plot coordinates {(8.500000,0.350000) (8.750000,0.155100) (9.000000,0.062400) (9.250000,0.023000) (9.500000,0.008700) (9.750000,0.003500) (10.000000,0.000900) (10.250000,0.000300) };
|
||||
\addplot[blue, solid, mark=square] plot coordinates {(7.500000,0.858900) (7.750000,0.449500) (8.000000,0.129700) (8.250000,0.025500) (8.500000,0.002300) (8.750000,0.000300) (9.000000,0.000000) };
|
||||
|
||||
% LDPC opt 50 iter
|
||||
%\addplot[blue, dashed, mark=square] plot coordinates {(6.000000,0.705333) (6.100000,0.353367) (6.200000,0.102100) (6.300000,0.015133) (6.400000,0.000967) (6.500000,0.000000)};
|
||||
\addplot[blue, dashed, mark=square] plot coordinates {(6.000000,0.970000) (6.100000,0.830800) (6.200000,0.527300) (6.300000,0.216900) (6.400000,0.045500) (6.500000,0.005600) (6.600000,0.000300) (6.700000,0.000000) (6.800000,0.000000) };
|
||||
|
||||
\legend{ {Huawei}\\
|
||||
{LDPC OAI 5 iter}\\
|
||||
{LDPC OAI 50 iter}\\};
|
||||
|
||||
\end{semilogyaxis}
|
||||
\end{tikzpicture}
|
||||
\caption{BLER vs. SNR, BG1, Rate=8/9 \{5,50\} Iterations, B=8448.}
|
||||
\label{fig:bler-bg1-r89}
|
||||
\end{figure}
|
||||
|
||||
\newpage
|
||||
\subsection{Decoding Latency}
|
||||
\label{sec:decoding-time}
|
||||
|
||||
This section provides results in terms of decoding latency. That is, the time it takes the decoder to to finish decoding for a given number of iterations. To measure the run time of the decoder we use the OAI tool \texttt{time\_meas.h}. The clock frequency is about 2.9 GHZ, decoder is run on a single core and the results are averaged over $10\,000$ blocks.
|
||||
|
||||
The results in Table \ref{tab:lat-bg2-r15} show the impact of the number of iterations on the decoding latency. It can be observed that the latency roughly doubles if the number of iterations are doubled.
|
||||
|
||||
\begin{table}[ht]
|
||||
\centering
|
||||
\begin{tabular}{lrrr}
|
||||
\toprule
|
||||
\textbf{Function} & \textbf{Time [$\mu s$] (5 it)} & \textbf{Time [$\mu s$] (10 it)} & \textbf{Time [$\mu s$] (20 it)}\\
|
||||
\midrule
|
||||
% \texttt{llr2llrProcBuf} & 1.1 & 1.1 & 1.1 \\
|
||||
% \texttt{llr2CnProcBuf} & 12.4 & 12.0 & 12.0 \\
|
||||
% \texttt{cnProc} & 11.7 & 22.1 & 43.5 \\
|
||||
% \texttt{bnProcPc} & 6.6 & 12.1 & 23.8 \\
|
||||
% \texttt{bnProc} & 4.2 & 8.1 & 16.2 \\
|
||||
% \texttt{cn2bnProcBuf} & 61.3 & 118.3 & 234.9 \\
|
||||
% \texttt{bn2cnProcBuf} & 38.1 & 82.5 & 172.3 \\
|
||||
% \texttt{llrRes2llrOut} & 3.5 & 3.4 & 3.4 \\
|
||||
% \texttt{llr2bit} & 0.2 & 0.1 & 0.1 \\
|
||||
\texttt{llr2llrProcBuf} & 0.5 & 0.5 & 0.5 \\
|
||||
\texttt{llr2CnProcBuf} & 5.0 & 4.8 & 4.9 \\
|
||||
\texttt{cnProc} & 12.4 & 23.0 & 42.7 \\
|
||||
\texttt{bnProcPc} & 8.4 & 14.8 & 27.0 \\
|
||||
\texttt{bnProc} & 5.5 & 10.1 & 19.0 \\
|
||||
\texttt{cn2bnProcBuf} & 14.9 & 24.4 & 44.0 \\
|
||||
\texttt{bn2cnProcBuf} & 10.5 & 17.8 & 31.8 \\
|
||||
\texttt{llrRes2llrOut} & 0.3 & 0.3 & 0.3 \\
|
||||
\texttt{llr2bit} & 0.2 & 0.2 & 0.2 \\
|
||||
\midrule
|
||||
% \textbf{Total} & \textbf{139.4} & \textbf{260.3} & \textbf{508.4} \\
|
||||
\textbf{Total} & \textbf{58.5} & \textbf{97.1} & \textbf{172.6} \\
|
||||
\bottomrule
|
||||
\end{tabular}
|
||||
\caption{BG2, Z=128, R=1/5, B=1280, LDPC OAI}
|
||||
\label{tab:lat-bg2-r15}
|
||||
\end{table}
|
||||
|
||||
Table \ref{tab:lat-bg2-i5} shows the impact of the code rate on the latency for a given block size and 5 iterations. It can be observed that the performance gain from code rate 1/3 to 2/3 is about a factor 2.
|
||||
|
||||
\begin{table}[ht]
|
||||
\centering
|
||||
\begin{tabular}{lrrr}
|
||||
\toprule
|
||||
\textbf{Function} & \textbf{Time [$\mu s$] (R=1/5)} & \textbf{Time [$\mu s$] (R=1/3)} & \textbf{Time [$\mu s$] (R=2/3)}\\
|
||||
\midrule
|
||||
% \texttt{llr2llrProcBuf} & 3.2 & 2.9 & 2.6 \\
|
||||
% \texttt{llr2CnProcBuf} & 36.5 & 25.4 & 14.8 \\
|
||||
% \texttt{cnProc} & 33.6 & 25.2 & 13.3 \\
|
||||
% \texttt{bnProcPc} & 17.6 & 10.2 & 4.5 \\
|
||||
% \texttt{bnProc} & 8.5 & 5.4 & 2.5 \\
|
||||
% \texttt{cn2bnProcBuf} & 175.3 & 110.6 & 50.7 \\
|
||||
% \texttt{bn2cnProcBuf} & 106.6 & 71.2 & 36.1 \\
|
||||
% \texttt{llrRes2llrOut} & 10.2 & 6.3 & 3.3 \\
|
||||
% \texttt{llr2bit} & 0.4 & 0.2 & 0.1 \\
|
||||
\texttt{llr2llrProcBuf} & 1.5 & 0.9 & 0.5 \\
|
||||
\texttt{llr2CnProcBuf} & 6.0 & 4.1 & 2.2 \\
|
||||
\texttt{cnProc} & 32.2 & 23.7 & 14.4 \\
|
||||
\texttt{bnProcPc} & 21.2 & 12.1 & 5.5 \\
|
||||
\texttt{bnProc} & 9.8 & 5.9 & 2.9 \\
|
||||
\texttt{cn2bnProcBuf} & 23.3 & 13.9 & 6.8 \\
|
||||
\texttt{bn2cnProcBuf} & 14.8 & 9.7 & 5.0 \\
|
||||
\texttt{llrRes2llrOut} & 0.6 & 0.4 & 0.3 \\
|
||||
\texttt{llr2bit} & 0.7 & 0.4 & 0.2 \\
|
||||
\midrule
|
||||
% \textbf{Total} & \textbf{392.4} & \textbf{258.0} & \textbf{128.2} \\
|
||||
\textbf{Total} & \textbf{111.0} & \textbf{71.8} & \textbf{38.5} \\
|
||||
\bottomrule
|
||||
\end{tabular}
|
||||
\caption{BG2, Z=384, B=3840, LDPC OAI, 5 iterations}
|
||||
\label{tab:lat-bg2-i5}
|
||||
\end{table}
|
||||
|
||||
Table \ref{tab:lat-bg1-i5} shows the results for BG1, larges block size and different code rates. The latency difference betwee code rate 1/3 and code rate 2/3 is less than half because upper left corner of the PCM is more dense than the rest of the PCM.
|
||||
|
||||
\begin{table}[ht]
|
||||
\centering
|
||||
\begin{tabular}{lrrr}
|
||||
\toprule
|
||||
\textbf{Function} & \textbf{Time [$\mu s$] (R=1/3)} & \textbf{Time [$\mu s$] (R=2/3)} & \textbf{Time [$\mu s$] (R=8/9)}\\
|
||||
\midrule
|
||||
% \texttt{llr2llrProcBuf} & 5.5 & 4.9 & 4.6 \\
|
||||
% \texttt{llr2CnProcBuf} & 60.6 & 34.1 & 24.4 \\
|
||||
% \texttt{cnProc} & 102.0 & 74.1 & 56.0 \\
|
||||
% \texttt{bnProcPc} & 26.0 & 11.0 & 6.4 \\
|
||||
% \texttt{bnProc} & 15.7 & 7.4 & 4.5 \\
|
||||
% \texttt{cn2bnProcBuf} & 291.0 & 140.8 & 83.1 \\
|
||||
% \texttt{bn2cnProcBuf} & 193.6 & 100.5 & 63.0 \\
|
||||
% \texttt{llrRes2llrOut} & 13.3 & 6.9 & 5.2 \\
|
||||
% \texttt{llr2bit} & 0.4 & 0.2 & 0.2 \\
|
||||
\texttt{llr2llrProcBuf} & 2.1 & 1.2 & 0.9 \\
|
||||
\texttt{llr2CnProcBuf} & 10.6 & 5.4 & 2.9 \\
|
||||
\texttt{cnProc} & 89.8 & 66.3 & 50.0 \\
|
||||
\texttt{bnProcPc} & 28.1 & 12.4 & 7.1 \\
|
||||
\texttt{bnProc} & 17.1 & 8.1 & 4.8 \\
|
||||
\texttt{cn2bnProcBuf} & 38.7 & 17.1 & 9.3 \\
|
||||
\texttt{bn2cnProcBuf} & 25.6 & 12.7 & 7.2 \\
|
||||
\texttt{llrRes2llrOut} & 0.8 & 0.4 & 0.3 \\
|
||||
\texttt{llr2bit} & 0.9 & 0.4 & 0.3 \\
|
||||
\midrule
|
||||
% \textbf{Total} & \textbf{708.9} & \textbf{380.6} & \textbf{248.1}\\
|
||||
\textbf{Total} & \textbf{214.6} & \textbf{124.6} & \textbf{83.6}\\
|
||||
\bottomrule
|
||||
\end{tabular}
|
||||
\caption{BG1, Z=384, B=8448, LDPC OAI, 5 iterations}
|
||||
\label{tab:lat-bg1-i5}
|
||||
\end{table}
|
||||
|
||||
From the above results it can be observed that the data transfer between CNs and BNs takes up a significant amount of the run time. However, the performance gain due to AVX instructions in both CN and BN processing is significantly larger than the penalty incurred by the data transfers.
|
||||
|
||||
\section{Parity Check and Early Stopping Criteria}
|
||||
It is often unnecessary to carry out the maximum number of iterations. After each iteration a parity check (PC) \eqref{eq:29} can be computed and if a valid code word is found the decoder can stop. This functionality has been implemented and the additional overhead is reasonable. The PC is carried out in the CN processing buffer and the calculation complexity itself is negligible. However, for the processing it is necessary to move the BN results to the CN buffer which takes time, the overall overhead is at most $10\%$ compared to an algorithm without early stopping criteria with the same number of iterations. The PC has to be activated via the define \texttt{NR\_LDPC\_ENABLE\_PARITY\_CHECK}.
|
||||
|
||||
|
||||
\section{Conclusion}
|
||||
\label{sec:conclusion}
|
||||
|
||||
The results in the previous sections show that the current optimized LDPC implementation full-fills the requirements in terms of decoding latency for low to medium number of iterations at the expense of a loss in BLER performance. To improve BLER performance, it is recommended to implement a layered algorithm and a min-sum algorithm with normalization. Further improvements upon the current implementation are detailed in the next section.
|
||||
|
||||
\newpage
|
||||
\section{Future Work}
|
||||
\label{sec:future-work}
|
||||
|
||||
The improvements upon the current LDPC decoder implementation can be divided into two categories:
|
||||
\begin{enumerate}
|
||||
\item Improved BLER performance
|
||||
\item Reduced decoding latency
|
||||
\end{enumerate}
|
||||
|
||||
\subsection{Improved BLER Performance}
|
||||
\label{sec:impr-bler-perf}
|
||||
|
||||
The BLER performance can be improved by using a tighter approximation than the min-sum approximation. For instance, the min-sum algorithm can be improved by adding a correction factor in the CN processing . The min-sum approximation in \eqref{eq:40} is modified as
|
||||
\begin{equation}
|
||||
\label{eq:50}
|
||||
r_{ji} = \prod_{j'\in\Bcal_i\setminus j}\sgn q_{ij'}\min_{j'\in\Bcal_i\setminus j} |q_{ij'}| + w(q_{ij'})
|
||||
\end{equation}
|
||||
The correction term $w(q_{ij'})$ is defined as
|
||||
\begin{equation}
|
||||
\label{eq:51}
|
||||
w(q_{ij'}) =
|
||||
\begin{cases}
|
||||
c & \textrm{if}~ \\
|
||||
-c & \textrm{if}~ \\
|
||||
0 & \textrm{otherwise}
|
||||
\end{cases}
|
||||
\end{equation}
|
||||
where the constant $c$ is of order $0.5$ typically.
|
||||
|
||||
\subsection{Reduced Decoding Latency}
|
||||
\label{sec:reduc-decod-latency}
|
||||
|
||||
The following improvements will reduce the decoding latency:
|
||||
|
||||
\begin{itemize}
|
||||
\item Adapt to AVX512
|
||||
\item Optimization of CN processing
|
||||
\item Implement 2/3-layers for faster convergence
|
||||
\end{itemize}
|
||||
|
||||
\paragraph{AVX512:}
|
||||
The computations in the CN and BN processing can be further accelerated by using AVX512 instructions. This improvement will speed-up the CN and BN processing by a approximately a factor of 2.
|
||||
|
||||
\paragraph{Optimization of CN Processing:}
|
||||
It can be investigated if CN processing can be improved by computing two minima regardless of the number of BNs. Susequently, the (absolute) value fed back to the BN is one of those minima.
|
||||
|
||||
\paragraph{Layered processing:}
|
||||
The LDPC code in NR always punctures the first 2 columns of the base graph. Hence, the decoder inserts LLRs with value 0 at their place and needs to retrieve those bits during the decoding process. Instead of computing all the parity equations and then passing the results to the BN processing, it is beneficial to first compute parity equations where at most one punctured BN is connected to that CN. If two punctured BNs are connected than according to \eqref{eq:40}, the result will be again 0. Thus in a first sub-iteration those parity equation are computed and the results are send to BN processing which calculates the results using only those rows in the PCM. In the second sub-iteration the remaining check equation are used.
|
||||
The convergence of this layered approach is much fast since the bit can be retrieved more quickly while the decoding complexity remains the same. Therefore, for a fixed number of iterations the layered algorithm will have a significantly better performance.
|
||||
|
||||
\newpage
|
||||
\bibliographystyle{IEEEtran}
|
||||
\bibliography{./references}
|
||||
|
||||
\end{document}
|
||||
|
||||
%%% Local Variables:
|
||||
%%% mode: latex
|
||||
%%% TeX-master: t
|
||||
%%% End:
|
||||
@@ -1,105 +0,0 @@
|
||||
%
|
||||
% Licensed to the OpenAirInterface (OAI) Software Alliance under one or more
|
||||
% contributor license agreements. See the NOTICE file distributed with
|
||||
% this work for additional information regarding copyright ownership.
|
||||
% The OpenAirInterface Software Alliance licenses this file to You under
|
||||
% the OAI Public License, Version 1.1 (the "License"); you may not use this file
|
||||
% except in compliance with the License.
|
||||
% You may obtain a copy of the License at
|
||||
%
|
||||
% http://www.openairinterface.org/?page_id=698
|
||||
%
|
||||
% Unless required by applicable law or agreed to in writing, software
|
||||
% distributed under the License is distributed on an "AS IS" BASIS,
|
||||
% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
% See the License for the specific language governing permissions and
|
||||
% limitations under the License.
|
||||
%-------------------------------------------------------------------------------
|
||||
% For more information about the OpenAirInterface (OAI) Software Alliance:
|
||||
% contact@openairinterface.org
|
||||
%
|
||||
@online{3gpp5gTimeline,
|
||||
author = {3GPP},
|
||||
title = {{3GPP 5G Timeline}},
|
||||
year = 2016,
|
||||
urldate = {2017-06-14},
|
||||
url = {http://www.3gpp.org/images/articleimages/5g_timeline.jpg}
|
||||
}
|
||||
|
||||
@techreport{3gppTR38913,
|
||||
author = "{Technical Specification Group Radio Access Network}",
|
||||
title = "{Study on Scenarios and Requirements for Next Generation Access Technologies}",
|
||||
institution = "{3GPP TR 38.913 V14.2.0}",
|
||||
month = mar,
|
||||
year = 2017,
|
||||
};
|
||||
|
||||
@techreport{iturM2038,
|
||||
author = "{ITU-R}",
|
||||
title = "{IMT Vision -- Framework and overall objectives of the future development of IMT for 2020 and beyond}",
|
||||
institution = "{Radiocommunication Sector of ITU}",
|
||||
month = sep,
|
||||
year = 2015,
|
||||
};
|
||||
|
||||
@techreport{3gpp2014seb,
|
||||
author = "{Samsung, Nokia Networks}",
|
||||
title = "{New SID Proposal: Study on Elevation Beamforming/Full-Dimension (FD) MIMO for LTE}",
|
||||
institution = "3GPP",
|
||||
month = sep,
|
||||
year = 2014,
|
||||
};
|
||||
|
||||
@techreport{3gpp2015fdm,
|
||||
author = "{Technical Specification Group Radio Access Network}",
|
||||
title = "{Study on elevation beamforming / Full-Dimension (FD) Multiple Input Multiple Output (MIMO) for LTE}",
|
||||
institution = "3GPP TR 36.897 V13.0.0",
|
||||
month = jun,
|
||||
year = 2015,
|
||||
};
|
||||
|
||||
|
||||
@techreport{3gpp2008tsg,
|
||||
author = "{Technical Specification Group Radio Access Network;
|
||||
Evolved Universal Terrestrial Radio Access (E-UTRA)}",
|
||||
title = "{Further advancements for E-UTRA physical layer aspects (Release 9)}",
|
||||
institution = "{3GPP TR 36.814 V9.0.0}",
|
||||
month = mar,
|
||||
year = 2010,
|
||||
};
|
||||
|
||||
@techreport{3gpp2011uer,
|
||||
author = "{Technical Specification Group Radio Access Network;
|
||||
Evolved Universal Terrestrial Radio Access (E-UTRA)}",
|
||||
title = "{User Equipment (UE) Radio Transmission and Reception}",
|
||||
institution = "{3GPP TR 36.101 V10.3.0}",
|
||||
month = jun,
|
||||
year = 2011,
|
||||
};
|
||||
|
||||
@techreport{3gpp2009_36211,
|
||||
author = "{3rd Generation Partnership Project}",
|
||||
title = "{Physical Channels and Modulation (Release 8)}",
|
||||
institution = "{3GPP TS 36.211 V8.6.0}",
|
||||
month = mar,
|
||||
year = 2009,
|
||||
};
|
||||
|
||||
@techreport{3gpp2017_38212,
|
||||
author = "{3rd Generation Partnership Project}",
|
||||
title = "{Multiplexing and channel coding (Release 15)}",
|
||||
institution = "{3GPP TS 38.212 V15.0.1}",
|
||||
month = mar,
|
||||
year = 2018,
|
||||
};
|
||||
|
||||
@article{gallager1962low,
|
||||
title={Low-density parity-check codes},
|
||||
author={Gallager, Robert},
|
||||
journal={IRE Transactions on information theory},
|
||||
volume={8},
|
||||
number={1},
|
||||
pages={21--28},
|
||||
year={1962},
|
||||
publisher={IEEE}
|
||||
}
|
||||
File diff suppressed because it is too large
Load Diff
@@ -30,7 +30,7 @@
|
||||
|
||||
#ifndef __NR_LDPC_BNPROC__H__
|
||||
#define __NR_LDPC_BNPROC__H__
|
||||
|
||||
#include <immintrin.h>
|
||||
/**
|
||||
\brief Performs first part of BN processing on the BN processing buffer and stores the results in the LLR results buffer.
|
||||
At every BN, the sum of the returned LLRs from the connected CNs and the LLR of the receiver input is computed.
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
|
||||
/*
|
||||
* Licensed to the OpenAirInterface (OAI) Software Alliance under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with
|
||||
@@ -28,8 +29,8 @@
|
||||
* \warning
|
||||
*/
|
||||
|
||||
#ifndef __NR_LDPC_CNPROC__H__
|
||||
#define __NR_LDPC_CNPROC__H__
|
||||
#ifndef __NR_LDPC_DECODER_CNPROC__H__
|
||||
#define __NR_LDPC_DECODER_CNPROC__H__
|
||||
|
||||
/**
|
||||
\brief Performs CN processing for BG2 on the CN processing buffer and stores the results in the CN processing results buffer.
|
||||
@@ -37,6 +38,13 @@
|
||||
\param p_procBuf Pointer to processing buffers
|
||||
\param Z Lifting size
|
||||
*/
|
||||
|
||||
|
||||
#ifdef __AVX512BW__
|
||||
#include "nrLDPC_cnProc_avx512.h"
|
||||
|
||||
#else
|
||||
|
||||
static inline void nrLDPC_cnProc_BG2(t_nrLDPC_lut* p_lut, int8_t* cnProcBuf, int8_t* cnProcBufRes, uint16_t Z)
|
||||
{
|
||||
const uint8_t* lut_numCnInCnGroups = p_lut->numCnInCnGroups;
|
||||
@@ -92,14 +100,14 @@ static inline void nrLDPC_cnProc_BG2(t_nrLDPC_lut* p_lut, int8_t* cnProcBuf, int
|
||||
for (i=0; i<M; i++)
|
||||
{
|
||||
// Abs and sign of 32 CNs (first BN)
|
||||
// ymm0 = p_cnProcBuf[lut_idxCnProcG3[j][0] + i];
|
||||
ymm0 = pj0[i];
|
||||
// ymm0 = p_cnProcBuf[lut_idxCnProcG3[j][0] + i];
|
||||
ymm0 = pj0[i];
|
||||
sgn = _mm256_sign_epi8(*p_ones, ymm0);
|
||||
min = _mm256_abs_epi8(ymm0);
|
||||
|
||||
// 32 CNs of second BN
|
||||
// ymm0 = p_cnProcBuf[lut_idxCnProcG3[j][1] + i];
|
||||
ymm0 = pj1[i];
|
||||
// ymm0 = p_cnProcBuf[lut_idxCnProcG3[j][1] + i];
|
||||
ymm0 = pj1[i];
|
||||
min = _mm256_min_epu8(min, _mm256_abs_epi8(ymm0));
|
||||
sgn = _mm256_sign_epi8(sgn, ymm0);
|
||||
|
||||
@@ -107,7 +115,7 @@ static inline void nrLDPC_cnProc_BG2(t_nrLDPC_lut* p_lut, int8_t* cnProcBuf, int
|
||||
min = _mm256_min_epu8(min, *p_maxLLR); // 128 in epi8 is -127
|
||||
//*p_cnProcBufResBit = _mm256_sign_epi8(min, sgn);
|
||||
//p_cnProcBufResBit++;
|
||||
p_cnProcBufResBit[i]=_mm256_sign_epi8(min, sgn);
|
||||
p_cnProcBufResBit[i]=_mm256_sign_epi8(min, sgn);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -364,6 +372,15 @@ static inline void nrLDPC_cnProc_BG2(t_nrLDPC_lut* p_lut, int8_t* cnProcBuf, int
|
||||
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
\brief Performs CN processing for BG1 on the CN processing buffer and stores the results in the CN processing results buffer.
|
||||
\param p_lut Pointer to decoder LUTs
|
||||
\param Z Lifting size
|
||||
*/
|
||||
|
||||
|
||||
|
||||
/**
|
||||
\brief Performs CN processing for BG1 on the CN processing buffer and stores the results in the CN processing results buffer.
|
||||
\param p_lut Pointer to decoder LUTs
|
||||
@@ -431,6 +448,7 @@ static inline void nrLDPC_cnProc_BG1(t_nrLDPC_lut* p_lut, int8_t* cnProcBuf, int
|
||||
min = _mm256_min_epu8(min, _mm256_abs_epi8(ymm0));
|
||||
sgn = _mm256_sign_epi8(sgn, ymm0);
|
||||
|
||||
|
||||
// Store result
|
||||
min = _mm256_min_epu8(min, *p_maxLLR); // 128 in epi8 is -127
|
||||
*p_cnProcBufResBit = _mm256_sign_epi8(min, sgn);
|
||||
@@ -859,6 +877,7 @@ static inline void nrLDPC_cnProc_BG1(t_nrLDPC_lut* p_lut, int8_t* cnProcBuf, int
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
/**
|
||||
\brief Performs parity check for BG1 on the CN processing buffer. Stops as soon as error is detected.
|
||||
\param p_lut Pointer to decoder LUTs
|
||||
@@ -1922,3 +1941,6 @@ static inline uint32_t nrLDPC_cnProcPc_BG2(t_nrLDPC_lut* p_lut, int8_t* cnProcBu
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -0,0 +1,865 @@
|
||||
|
||||
/*
|
||||
* Licensed to the OpenAirInterface (OAI) Software Alliance under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright ownership.
|
||||
* The OpenAirInterface Software Alliance licenses this file to You under
|
||||
* the OAI Public License, Version 1.1 (the "License"); you may not use this file
|
||||
* except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.openairinterface.org/?page_id=698
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*-------------------------------------------------------------------------------
|
||||
* For more information about the OpenAirInterface (OAI) Software Alliance:
|
||||
* contact@openairinterface.org
|
||||
*/
|
||||
|
||||
/*!\file nrLDPC_cnProc_avx512.h
|
||||
* \brief Defines the functions for check node processing
|
||||
* \author Sebastian Wagner (TCL Communications) Email: <mailto:sebastian.wagner@tcl.com>
|
||||
* \date 30-09-2021
|
||||
* \version 1.0
|
||||
* \note
|
||||
* \warning
|
||||
*/
|
||||
|
||||
#ifndef __NR_LDPC_CNPROC__H__
|
||||
#define __NR_LDPC_CNPROC__H__
|
||||
|
||||
#define conditional_negate(a,b,z) _mm512_mask_sub_epi8(a,_mm512_movepi8_mask(b),z,a)
|
||||
static inline void nrLDPC_cnProc_BG2_AVX512(t_nrLDPC_lut* p_lut, int8_t* cnProcBuf, int8_t* cnProcBufRes, uint16_t Z)
|
||||
{
|
||||
const uint8_t* lut_numCnInCnGroups = p_lut->numCnInCnGroups;
|
||||
const uint32_t* lut_startAddrCnGroups = p_lut->startAddrCnGroups;
|
||||
|
||||
__m512i* p_cnProcBuf;
|
||||
__m512i* p_cnProcBufRes;
|
||||
|
||||
// Number of CNs in Groups
|
||||
uint32_t M;
|
||||
uint32_t i;
|
||||
uint32_t j;
|
||||
uint32_t k;
|
||||
// Offset to each bit within a group in terms of 32 Byte
|
||||
uint32_t bitOffsetInGroup;
|
||||
|
||||
__m512i zmm0, min, sgn, zeros;
|
||||
zeros = _mm512_setzero_si512();
|
||||
// maxLLR = _mm512_set1_epi8((char)127);
|
||||
__m512i* p_cnProcBufResBit;
|
||||
|
||||
const __m512i* p_ones = (__m512i*) ones512_epi8;
|
||||
const __m512i* p_maxLLR = (__m512i*) maxLLR512_epi8;
|
||||
|
||||
// LUT with offsets for bits that need to be processed
|
||||
// 1. bit proc requires LLRs of 2. and 3. bit, 2.bits of 1. and 3. etc.
|
||||
// Offsets are in units of bitOffsetInGroup
|
||||
const uint8_t lut_idxCnProcG3[3][2] = {{72,144}, {0,144}, {0,72}};
|
||||
|
||||
// =====================================================================
|
||||
// Process group with 3 BNs
|
||||
|
||||
if (lut_numCnInCnGroups[0] > 0)
|
||||
{
|
||||
// Number of groups of 32 CNs for parallel processing
|
||||
// Ceil for values not divisible by 32
|
||||
M = (lut_numCnInCnGroups[0]*Z + 63)>>6;
|
||||
// Set the offset to each bit within a group in terms of 32 Byte
|
||||
bitOffsetInGroup = (lut_numCnInCnGroups_BG2_R15[0]*NR_LDPC_ZMAX)>>6;
|
||||
|
||||
// Set pointers to start of group 3
|
||||
p_cnProcBuf = (__m512i*) &cnProcBuf [lut_startAddrCnGroups[0]];
|
||||
p_cnProcBufRes = (__m512i*) &cnProcBufRes[lut_startAddrCnGroups[0]];
|
||||
|
||||
// Loop over every BN
|
||||
for (j=0; j<3; j++)
|
||||
{
|
||||
// Set of results pointer to correct BN address
|
||||
p_cnProcBufResBit = p_cnProcBufRes + (j*bitOffsetInGroup);
|
||||
|
||||
__m512i *pj0 = &p_cnProcBuf[(lut_idxCnProcG3[j][0]/2)];
|
||||
__m512i *pj1 = &p_cnProcBuf[(lut_idxCnProcG3[j][1]/2)];
|
||||
|
||||
// Loop over CNs
|
||||
for (i=0; i<M; i++)
|
||||
{
|
||||
// Abs and sign of 32 CNs (first BN)
|
||||
// zmm0 = p_cnProcBuf[lut_idxCnProcG3[j][0] + i];
|
||||
zmm0 = pj0[i];
|
||||
sgn = _mm512_xor_si512(*p_ones, zmm0);
|
||||
min = _mm512_abs_epi8(zmm0);
|
||||
|
||||
// 32 CNs of second BN
|
||||
// zmm0 = p_cnProcBuf[(lut_idxCnProcG3[j][1]/2) + i];
|
||||
zmm0 = pj1[i];
|
||||
min = _mm512_min_epu8(min, _mm512_abs_epi8(zmm0));
|
||||
sgn = _mm512_xor_si512(sgn, zmm0);
|
||||
|
||||
// Store result
|
||||
min = _mm512_min_epu8(min, *p_maxLLR); // 128 in epi8 is -127
|
||||
*p_cnProcBufResBit = conditional_negate(min, sgn,zeros);
|
||||
p_cnProcBufResBit++;
|
||||
//p_cnProcBufResBit[i]=_mm512_sign_epi8(min, sgn);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// =====================================================================
|
||||
// Process group with 4 BNs
|
||||
|
||||
// Offset is 20*384/32 = 240
|
||||
const uint16_t lut_idxCnProcG4[4][3] = {{240,480,720}, {0,480,720}, {0,240,720}, {0,240,480}};
|
||||
|
||||
if (lut_numCnInCnGroups[1] > 0)
|
||||
{
|
||||
// Number of groups of 32 CNs for parallel processing
|
||||
// Ceil for values not divisible by 32
|
||||
M = (lut_numCnInCnGroups[1]*Z + 63)>>6;
|
||||
// Set the offset to each bit within a group in terms of 32 Byte
|
||||
bitOffsetInGroup = (lut_numCnInCnGroups_BG2_R15[1]*NR_LDPC_ZMAX)>>6;
|
||||
|
||||
// Set pointers to start of group 4
|
||||
p_cnProcBuf = (__m512i*) &cnProcBuf [lut_startAddrCnGroups[1]];
|
||||
p_cnProcBufRes = (__m512i*) &cnProcBufRes[lut_startAddrCnGroups[1]];
|
||||
|
||||
// Loop over every BN
|
||||
for (j=0; j<4; j++)
|
||||
{
|
||||
// Set of results pointer to correct BN address
|
||||
p_cnProcBufResBit = p_cnProcBufRes + (j*bitOffsetInGroup);
|
||||
|
||||
// Loop over CNs
|
||||
for (i=0; i<M; i++)
|
||||
{
|
||||
// Abs and sign of 32 CNs (first BN)
|
||||
zmm0 = p_cnProcBuf[(lut_idxCnProcG4[j][0]/2) + i];
|
||||
sgn = _mm512_xor_si512(*p_ones, zmm0);
|
||||
min = _mm512_abs_epi8(zmm0);
|
||||
|
||||
// Loop over BNs
|
||||
for (k=1; k<3; k++)
|
||||
{
|
||||
zmm0 = p_cnProcBuf[(lut_idxCnProcG4[j][k]/2) + i];
|
||||
min = _mm512_min_epu8(min, _mm512_abs_epi8(zmm0));
|
||||
sgn = _mm512_xor_si512(sgn, zmm0);
|
||||
}
|
||||
|
||||
// Store result
|
||||
min = _mm512_min_epu8(min, *p_maxLLR); // 128 in epi8 is -127
|
||||
*p_cnProcBufResBit = conditional_negate(min, sgn,zeros);
|
||||
p_cnProcBufResBit++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// =====================================================================
|
||||
// Process group with 5 BNs
|
||||
|
||||
// Offset is 9*384/32 = 108
|
||||
const uint16_t lut_idxCnProcG5[5][4] = {{108,216,324,432}, {0,216,324,432},
|
||||
{0,108,324,432}, {0,108,216,432}, {0,108,216,324}};
|
||||
|
||||
if (lut_numCnInCnGroups[2] > 0)
|
||||
{
|
||||
// Number of groups of 32 CNs for parallel processing
|
||||
// Ceil for values not divisible by 32
|
||||
M = (lut_numCnInCnGroups[2]*Z + 63)>>6;
|
||||
// Set the offset to each bit within a group in terms of 32 Byte
|
||||
bitOffsetInGroup = (lut_numCnInCnGroups_BG2_R15[2]*NR_LDPC_ZMAX)>>6;
|
||||
|
||||
// Set pointers to start of group 5
|
||||
p_cnProcBuf = (__m512i*) &cnProcBuf [lut_startAddrCnGroups[2]];
|
||||
p_cnProcBufRes = (__m512i*) &cnProcBufRes[lut_startAddrCnGroups[2]];
|
||||
|
||||
// Loop over every BN
|
||||
for (j=0; j<5; j++)
|
||||
{
|
||||
// Set of results pointer to correct BN address
|
||||
p_cnProcBufResBit = p_cnProcBufRes + (j*bitOffsetInGroup);
|
||||
|
||||
// Loop over CNs
|
||||
for (i=0; i<M; i++)
|
||||
{
|
||||
// Abs and sign of 32 CNs (first BN)
|
||||
zmm0 = p_cnProcBuf[(lut_idxCnProcG5[j][0]/2) + i];
|
||||
sgn = _mm512_xor_si512(*p_ones, zmm0);
|
||||
min = _mm512_abs_epi8(zmm0);
|
||||
|
||||
// Loop over BNs
|
||||
for (k=1; k<4; k++)
|
||||
{
|
||||
zmm0 = p_cnProcBuf[(lut_idxCnProcG5[j][k]/2) + i];
|
||||
min = _mm512_min_epu8(min, _mm512_abs_epi8(zmm0));
|
||||
sgn = _mm512_xor_si512(sgn, zmm0);
|
||||
}
|
||||
|
||||
// Store result
|
||||
min = _mm512_min_epu8(min, *p_maxLLR); // 128 in epi8 is -127
|
||||
*p_cnProcBufResBit = conditional_negate(min, sgn,zeros);
|
||||
p_cnProcBufResBit++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// =====================================================================
|
||||
// Process group with 6 BNs
|
||||
|
||||
// Offset is 3*384/32 = 36
|
||||
const uint16_t lut_idxCnProcG6[6][5] = {{36,72,108,144,180}, {0,72,108,144,180},
|
||||
{0,36,108,144,180}, {0,36,72,144,180},
|
||||
{0,36,72,108,180}, {0,36,72,108,144}};
|
||||
|
||||
if (lut_numCnInCnGroups[3] > 0)
|
||||
{
|
||||
// Number of groups of 32 CNs for parallel processing
|
||||
// Ceil for values not divisible by 32
|
||||
M = (lut_numCnInCnGroups[3]*Z + 63)>>6;
|
||||
// Set the offset to each bit within a group in terms of 32 Byte
|
||||
bitOffsetInGroup = (lut_numCnInCnGroups_BG2_R15[3]*NR_LDPC_ZMAX)>>6;
|
||||
|
||||
// Set pointers to start of group 6
|
||||
p_cnProcBuf = (__m512i*) &cnProcBuf [lut_startAddrCnGroups[3]];
|
||||
p_cnProcBufRes = (__m512i*) &cnProcBufRes[lut_startAddrCnGroups[3]];
|
||||
|
||||
// Loop over every BN
|
||||
for (j=0; j<6; j++)
|
||||
{
|
||||
// Set of results pointer to correct BN address
|
||||
p_cnProcBufResBit = p_cnProcBufRes + (j*bitOffsetInGroup);
|
||||
|
||||
// Loop over CNs
|
||||
for (i=0; i<M; i++)
|
||||
{
|
||||
// Abs and sign of 32 CNs (first BN)
|
||||
zmm0 = p_cnProcBuf[(lut_idxCnProcG6[j][0]/2) + i];
|
||||
sgn = _mm512_xor_si512(*p_ones, zmm0);
|
||||
min = _mm512_abs_epi8(zmm0);
|
||||
|
||||
// Loop over BNs
|
||||
for (k=1; k<5; k++)
|
||||
{
|
||||
zmm0 = p_cnProcBuf[(lut_idxCnProcG6[j][k]/2) + i];
|
||||
min = _mm512_min_epu8(min, _mm512_abs_epi8(zmm0));
|
||||
sgn = _mm512_xor_si512(sgn, zmm0);
|
||||
}
|
||||
|
||||
// Store result
|
||||
min = _mm512_min_epu8(min, *p_maxLLR); // 128 in epi8 is -127
|
||||
*p_cnProcBufResBit = conditional_negate(min, sgn,zeros);
|
||||
p_cnProcBufResBit++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// =====================================================================
|
||||
// Process group with 8 BNs
|
||||
|
||||
// Offset is 2*384/32 = 24
|
||||
const uint8_t lut_idxCnProcG8[8][7] = {{24,48,72,96,120,144,168}, {0,48,72,96,120,144,168},
|
||||
{0,24,72,96,120,144,168}, {0,24,48,96,120,144,168},
|
||||
{0,24,48,72,120,144,168}, {0,24,48,72,96,144,168},
|
||||
{0,24,48,72,96,120,168}, {0,24,48,72,96,120,144}};
|
||||
|
||||
if (lut_numCnInCnGroups[4] > 0)
|
||||
{
|
||||
// Number of groups of 32 CNs for parallel processing
|
||||
// Ceil for values not divisible by 32
|
||||
M = (lut_numCnInCnGroups[4]*Z + 63)>>6;
|
||||
// Set the offset to each bit within a group in terms of 32 Byte
|
||||
bitOffsetInGroup = (lut_numCnInCnGroups_BG2_R15[4]*NR_LDPC_ZMAX)>>6;
|
||||
|
||||
// Set pointers to start of group 8
|
||||
p_cnProcBuf = (__m512i*) &cnProcBuf [lut_startAddrCnGroups[4]];
|
||||
p_cnProcBufRes = (__m512i*) &cnProcBufRes[lut_startAddrCnGroups[4]];
|
||||
|
||||
// Loop over every BN
|
||||
for (j=0; j<8; j++)
|
||||
{
|
||||
// Set of results pointer to correct BN address
|
||||
p_cnProcBufResBit = p_cnProcBufRes + (j*bitOffsetInGroup);
|
||||
|
||||
// Loop over CNs
|
||||
for (i=0; i<M; i++)
|
||||
{
|
||||
// Abs and sign of 32 CNs (first BN)
|
||||
zmm0 = p_cnProcBuf[(lut_idxCnProcG8[j][0]/2) + i];
|
||||
sgn = _mm512_xor_si512(*p_ones, zmm0);
|
||||
min = _mm512_abs_epi8(zmm0);
|
||||
|
||||
// Loop over BNs
|
||||
for (k=1; k<7; k++)
|
||||
{
|
||||
zmm0 = p_cnProcBuf[(lut_idxCnProcG8[j][k]/2) + i];
|
||||
min = _mm512_min_epu8(min, _mm512_abs_epi8(zmm0));
|
||||
sgn = _mm512_xor_si512(sgn, zmm0);
|
||||
}
|
||||
|
||||
// Store result
|
||||
min = _mm512_min_epu8(min, *p_maxLLR); // 128 in epi8 is -127
|
||||
*p_cnProcBufResBit = conditional_negate(min, sgn,zeros);
|
||||
p_cnProcBufResBit++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// =====================================================================
|
||||
// Process group with 10 BNs
|
||||
|
||||
// Offset is 2*384/32 = 24
|
||||
const uint8_t lut_idxCnProcG10[10][9] = {{24,48,72,96,120,144,168,192,216}, {0,48,72,96,120,144,168,192,216},
|
||||
{0,24,72,96,120,144,168,192,216}, {0,24,48,96,120,144,168,192,216},
|
||||
{0,24,48,72,120,144,168,192,216}, {0,24,48,72,96,144,168,192,216},
|
||||
{0,24,48,72,96,120,168,192,216}, {0,24,48,72,96,120,144,192,216},
|
||||
{0,24,48,72,96,120,144,168,216}, {0,24,48,72,96,120,144,168,192}};
|
||||
|
||||
if (lut_numCnInCnGroups[5] > 0)
|
||||
{
|
||||
// Number of groups of 32 CNs for parallel processing
|
||||
// Ceil for values not divisible by 32
|
||||
M = (lut_numCnInCnGroups[5]*Z + 63)>>6;
|
||||
// Set the offset to each bit within a group in terms of 32 Byte
|
||||
bitOffsetInGroup = (lut_numCnInCnGroups_BG2_R15[5]*NR_LDPC_ZMAX)>>6;
|
||||
|
||||
// Set pointers to start of group 10
|
||||
p_cnProcBuf = (__m512i*) &cnProcBuf [lut_startAddrCnGroups[5]];
|
||||
p_cnProcBufRes = (__m512i*) &cnProcBufRes[lut_startAddrCnGroups[5]];
|
||||
|
||||
// Loop over every BN
|
||||
for (j=0; j<10; j++)
|
||||
{
|
||||
// Set of results pointer to correct BN address
|
||||
p_cnProcBufResBit = p_cnProcBufRes + (j*bitOffsetInGroup);
|
||||
|
||||
// Loop over CNs
|
||||
for (i=0; i<M; i++)
|
||||
{
|
||||
// Abs and sign of 32 CNs (first BN)
|
||||
zmm0 = p_cnProcBuf[(lut_idxCnProcG10[j][0]/2) + i];
|
||||
sgn = _mm512_xor_si512(*p_ones, zmm0);
|
||||
min = _mm512_abs_epi8(zmm0);
|
||||
|
||||
// Loop over BNs
|
||||
for (k=1; k<9; k++)
|
||||
{
|
||||
zmm0 = p_cnProcBuf[(lut_idxCnProcG10[j][k]/2) + i];
|
||||
min = _mm512_min_epu8(min, _mm512_abs_epi8(zmm0));
|
||||
sgn = _mm512_xor_si512(sgn, zmm0);
|
||||
}
|
||||
|
||||
// Store result
|
||||
min = _mm512_min_epu8(min, *p_maxLLR); // 128 in epi8 is -127
|
||||
*p_cnProcBufResBit = conditional_negate(min, sgn,zeros);
|
||||
p_cnProcBufResBit++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
static inline void nrLDPC_cnProc_BG1_AVX512(t_nrLDPC_lut* p_lut, t_nrLDPC_procBuf* p_procBuf, uint16_t Z)
|
||||
{
|
||||
const uint8_t* lut_numCnInCnGroups = p_lut->numCnInCnGroups;
|
||||
const uint32_t* lut_startAddrCnGroups = p_lut->startAddrCnGroups;
|
||||
|
||||
int8_t* cnProcBuf = p_procBuf->cnProcBuf;
|
||||
int8_t* cnProcBufRes = p_procBuf->cnProcBufRes;
|
||||
|
||||
__m512i* p_cnProcBuf;
|
||||
__m512i* p_cnProcBufRes;
|
||||
|
||||
// Number of CNs in Groups
|
||||
uint32_t M;
|
||||
uint32_t i;
|
||||
uint32_t j;
|
||||
uint32_t k;
|
||||
// Offset to each bit within a group in terms of 32 Byte
|
||||
uint32_t bitOffsetInGroup;
|
||||
|
||||
__m512i zmm0, min, sgn, zeros;
|
||||
|
||||
zeros = _mm512_setzero_si512();
|
||||
// maxLLR = _mm512_set1_epi8((char)127);
|
||||
__m512i* p_cnProcBufResBit;
|
||||
|
||||
|
||||
const __m512i* p_ones = (__m512i*) ones512_epi8;
|
||||
const __m512i* p_maxLLR = (__m512i*) maxLLR512_epi8;
|
||||
|
||||
|
||||
|
||||
|
||||
// LUT with offsets for bits that need to be processed
|
||||
// 1. bit proc requires LLRs of 2. and 3. bit, 2.bits of 1. and 3. etc.
|
||||
// Offsets are in units of bitOffsetInGroup (1*384/32)
|
||||
const uint8_t lut_idxCnProcG3[3][2] = {{12,24}, {0,24}, {0,12}};
|
||||
|
||||
// =====================================================================
|
||||
// Process group with 3 BNs
|
||||
|
||||
if (lut_numCnInCnGroups[0] > 0)
|
||||
{
|
||||
// Number of groups of 32 CNs for parallel processing
|
||||
// Ceil for values not divisible by 32
|
||||
M = (lut_numCnInCnGroups[0]*Z + 63)>>6;
|
||||
|
||||
// Set the offset to each bit within a group in terms of 32 Byte
|
||||
bitOffsetInGroup = (lut_numCnInCnGroups_BG1_R13[0]*NR_LDPC_ZMAX)>>6;
|
||||
|
||||
// Set pointers to start of group 3
|
||||
p_cnProcBuf = (__m512i*) &cnProcBuf [lut_startAddrCnGroups[0]];
|
||||
p_cnProcBufRes = (__m512i*) &cnProcBufRes[lut_startAddrCnGroups[0]];
|
||||
|
||||
// Loop over every BN
|
||||
for (j=0; j<3; j++)
|
||||
{
|
||||
// Set of results pointer to correct BN address
|
||||
p_cnProcBufResBit = p_cnProcBufRes + (j*bitOffsetInGroup);
|
||||
|
||||
// Loop over CNs
|
||||
for (i=0; i<M; i++)
|
||||
{
|
||||
// Abs and sign of 32 CNs (first BN)
|
||||
zmm0 = p_cnProcBuf[(lut_idxCnProcG3[j][0]/2) + i];
|
||||
sgn = _mm512_xor_si512(*p_ones, zmm0);
|
||||
min = _mm512_abs_epi8(zmm0);
|
||||
|
||||
// 32 CNs of second BN
|
||||
zmm0 = p_cnProcBuf[(lut_idxCnProcG3[j][1]/2) + i];
|
||||
min = _mm512_min_epu8(min, _mm512_abs_epi8(zmm0));
|
||||
sgn = _mm512_xor_si512(sgn, zmm0);
|
||||
|
||||
|
||||
// Store result
|
||||
min = _mm512_min_epu8(min, *p_maxLLR); // 128 in epi8 is -127
|
||||
*p_cnProcBufResBit = conditional_negate(min, sgn,zeros);
|
||||
p_cnProcBufResBit++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// =====================================================================
|
||||
// Process group with 4 BNs
|
||||
|
||||
// Offset is 5*384/32 = 60
|
||||
const uint8_t lut_idxCnProcG4[4][3] = {{60,120,180}, {0,120,180}, {0,60,180}, {0,60,120}};
|
||||
|
||||
if (lut_numCnInCnGroups[1] > 0)
|
||||
{
|
||||
// Number of groups of 32 CNs for parallel processing
|
||||
// Ceil for values not divisible by 32
|
||||
M = (lut_numCnInCnGroups[1]*Z + 63)>>6;
|
||||
|
||||
// Set the offset to each bit within a group in terms of 32 Byte
|
||||
bitOffsetInGroup = (lut_numCnInCnGroups_BG1_R13[1]*NR_LDPC_ZMAX)>>6;
|
||||
|
||||
// Set pointers to start of group 4
|
||||
p_cnProcBuf = (__m512i*) &cnProcBuf [lut_startAddrCnGroups[1]];
|
||||
p_cnProcBufRes = (__m512i*) &cnProcBufRes[lut_startAddrCnGroups[1]];
|
||||
|
||||
// Loop over every BN
|
||||
for (j=0; j<4; j++)
|
||||
{
|
||||
// Set of results pointer to correct BN address
|
||||
p_cnProcBufResBit = p_cnProcBufRes + (j*bitOffsetInGroup);
|
||||
|
||||
// Loop over CNs
|
||||
for (i=0; i<M; i++)
|
||||
{
|
||||
// Abs and sign of 32 CNs (first BN)
|
||||
zmm0 = p_cnProcBuf[(lut_idxCnProcG4[j][0]/2) + i];
|
||||
sgn = _mm512_xor_si512(*p_ones, zmm0);
|
||||
min = _mm512_abs_epi8(zmm0);
|
||||
|
||||
// Loop over BNs
|
||||
for (k=1; k<3; k++)
|
||||
{
|
||||
zmm0 = p_cnProcBuf[(lut_idxCnProcG4[j][k]/2) + i];
|
||||
min = _mm512_min_epu8(min, _mm512_abs_epi8(zmm0));
|
||||
sgn = _mm512_xor_si512(sgn, zmm0);
|
||||
}
|
||||
|
||||
// Store result
|
||||
min = _mm512_min_epu8(min, *p_maxLLR); // 128 in epi8 is -127
|
||||
*p_cnProcBufResBit = conditional_negate(min, sgn,zeros);
|
||||
p_cnProcBufResBit++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// =====================================================================
|
||||
// Process group with 5 BNs
|
||||
|
||||
// Offset is 18*384/32 = 216
|
||||
const uint16_t lut_idxCnProcG5[5][4] = {{216,432,648,864}, {0,432,648,864},
|
||||
{0,216,648,864}, {0,216,432,864}, {0,216,432,648}};
|
||||
|
||||
if (lut_numCnInCnGroups[2] > 0)
|
||||
{
|
||||
// Number of groups of 32 CNs for parallel processing
|
||||
// Ceil for values not divisible by 32
|
||||
M = (lut_numCnInCnGroups[2]*Z + 63)>>6;
|
||||
|
||||
// Set the offset to each bit within a group in terms of 32 Byte
|
||||
bitOffsetInGroup = (lut_numCnInCnGroups_BG1_R13[2]*NR_LDPC_ZMAX)>>6;
|
||||
|
||||
// Set pointers to start of group 5
|
||||
p_cnProcBuf = (__m512i*) &cnProcBuf [lut_startAddrCnGroups[2]];
|
||||
p_cnProcBufRes = (__m512i*) &cnProcBufRes[lut_startAddrCnGroups[2]];
|
||||
|
||||
// Loop over every BN
|
||||
for (j=0; j<5; j++)
|
||||
{
|
||||
// Set of results pointer to correct BN address
|
||||
p_cnProcBufResBit = p_cnProcBufRes + (j*bitOffsetInGroup);
|
||||
|
||||
// Loop over CNs
|
||||
for (i=0; i<M; i++)
|
||||
{
|
||||
// Abs and sign of 32 CNs (first BN)
|
||||
zmm0 = p_cnProcBuf[(lut_idxCnProcG5[j][0]/2) + i];
|
||||
sgn = _mm512_xor_si512(*p_ones, zmm0);
|
||||
min = _mm512_abs_epi8(zmm0);
|
||||
|
||||
// Loop over BNs
|
||||
for (k=1; k<4; k++)
|
||||
{
|
||||
zmm0 = p_cnProcBuf[(lut_idxCnProcG5[j][k]/2) + i];
|
||||
min = _mm512_min_epu8(min, _mm512_abs_epi8(zmm0));
|
||||
sgn = _mm512_xor_si512(sgn, zmm0);
|
||||
}
|
||||
|
||||
// Store result
|
||||
min = _mm512_min_epu8(min, *p_maxLLR); // 128 in epi8 is -127
|
||||
*p_cnProcBufResBit = conditional_negate(min, sgn,zeros);
|
||||
p_cnProcBufResBit++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// =====================================================================
|
||||
// Process group with 6 BNs
|
||||
|
||||
// Offset is 8*384/32 = 96
|
||||
const uint16_t lut_idxCnProcG6[6][5] = {{96,192,288,384,480}, {0,192,288,384,480},
|
||||
{0,96,288,384,480}, {0,96,192,384,480},
|
||||
{0,96,192,288,480}, {0,96,192,288,384}};
|
||||
|
||||
if (lut_numCnInCnGroups[3] > 0)
|
||||
{
|
||||
// Number of groups of 32 CNs for parallel processing
|
||||
// Ceil for values not divisible by 32
|
||||
M = (lut_numCnInCnGroups[3]*Z + 63)>>6;
|
||||
|
||||
// Set the offset to each bit within a group in terms of 32 Byte
|
||||
bitOffsetInGroup = (lut_numCnInCnGroups_BG1_R13[3]*NR_LDPC_ZMAX)>>6;
|
||||
|
||||
// Set pointers to start of group 6
|
||||
p_cnProcBuf = (__m512i*) &cnProcBuf [lut_startAddrCnGroups[3]];
|
||||
p_cnProcBufRes = (__m512i*) &cnProcBufRes[lut_startAddrCnGroups[3]];
|
||||
|
||||
// Loop over every BN
|
||||
for (j=0; j<6; j++)
|
||||
{
|
||||
// Set of results pointer to correct BN address
|
||||
p_cnProcBufResBit = p_cnProcBufRes + (j*bitOffsetInGroup);
|
||||
|
||||
// Loop over CNs
|
||||
for (i=0; i<M; i++)
|
||||
{
|
||||
// Abs and sign of 32 CNs (first BN)
|
||||
zmm0 = p_cnProcBuf[(lut_idxCnProcG6[j][0]/2) + i];
|
||||
sgn = _mm512_xor_si512(*p_ones, zmm0);
|
||||
min = _mm512_abs_epi8(zmm0);
|
||||
|
||||
// Loop over BNs
|
||||
for (k=1; k<5; k++)
|
||||
{
|
||||
zmm0 = p_cnProcBuf[(lut_idxCnProcG6[j][k]/2) + i];
|
||||
min = _mm512_min_epu8(min, _mm512_abs_epi8(zmm0));
|
||||
sgn = _mm512_xor_si512(sgn, zmm0);
|
||||
}
|
||||
|
||||
// Store result
|
||||
min = _mm512_min_epu8(min, *p_maxLLR); // 128 in epi8 is -127
|
||||
*p_cnProcBufResBit = conditional_negate(min, sgn,zeros);
|
||||
p_cnProcBufResBit++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// =====================================================================
|
||||
// Process group with 7 BNs
|
||||
|
||||
// Offset is 5*384/32 = 60
|
||||
const uint16_t lut_idxCnProcG7[7][6] = {{60,120,180,240,300,360}, {0,120,180,240,300,360},
|
||||
{0,60,180,240,300,360}, {0,60,120,240,300,360},
|
||||
{0,60,120,180,300,360}, {0,60,120,180,240,360},
|
||||
{0,60,120,180,240,300}};
|
||||
|
||||
if (lut_numCnInCnGroups[4] > 0)
|
||||
{
|
||||
// Number of groups of 32 CNs for parallel processing
|
||||
// Ceil for values not divisible by 32
|
||||
M = (lut_numCnInCnGroups[4]*Z + 63)>>6;
|
||||
|
||||
// Set the offset to each bit within a group in terms of 32 Byte
|
||||
bitOffsetInGroup = (lut_numCnInCnGroups_BG1_R13[4]*NR_LDPC_ZMAX)>>6;
|
||||
|
||||
// Set pointers to start of group 7
|
||||
p_cnProcBuf = (__m512i*) &cnProcBuf [lut_startAddrCnGroups[4]];
|
||||
p_cnProcBufRes = (__m512i*) &cnProcBufRes[lut_startAddrCnGroups[4]];
|
||||
|
||||
// Loop over every BN
|
||||
for (j=0; j<7; j++)
|
||||
{
|
||||
// Set of results pointer to correct BN address
|
||||
p_cnProcBufResBit = p_cnProcBufRes + (j*bitOffsetInGroup);
|
||||
|
||||
// Loop over CNs
|
||||
for (i=0; i<M; i++)
|
||||
{
|
||||
// Abs and sign of 32 CNs (first BN)
|
||||
zmm0 = p_cnProcBuf[(lut_idxCnProcG7[j][0]/2) + i];
|
||||
sgn = _mm512_xor_si512(*p_ones, zmm0);
|
||||
min = _mm512_abs_epi8(zmm0);
|
||||
|
||||
// Loop over BNs
|
||||
for (k=1; k<6; k++)
|
||||
{
|
||||
zmm0 = p_cnProcBuf[(lut_idxCnProcG7[j][k]/2) + i];
|
||||
min = _mm512_min_epu8(min, _mm512_abs_epi8(zmm0));
|
||||
sgn = _mm512_xor_si512(sgn, zmm0);
|
||||
}
|
||||
|
||||
// Store result
|
||||
min = _mm512_min_epu8(min, *p_maxLLR); // 128 in epi8 is -127
|
||||
*p_cnProcBufResBit = conditional_negate(min, sgn,zeros);
|
||||
p_cnProcBufResBit++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// =====================================================================
|
||||
// Process group with 8 BNs
|
||||
|
||||
// Offset is 2*384/32 = 24
|
||||
const uint8_t lut_idxCnProcG8[8][7] = {{24,48,72,96,120,144,168}, {0,48,72,96,120,144,168},
|
||||
{0,24,72,96,120,144,168}, {0,24,48,96,120,144,168},
|
||||
{0,24,48,72,120,144,168}, {0,24,48,72,96,144,168},
|
||||
{0,24,48,72,96,120,168}, {0,24,48,72,96,120,144}};
|
||||
|
||||
if (lut_numCnInCnGroups[5] > 0)
|
||||
{
|
||||
// Number of groups of 32 CNs for parallel processing
|
||||
// Ceil for values not divisible by 32
|
||||
M = (lut_numCnInCnGroups[5]*Z + 63)>>6;
|
||||
|
||||
// Set the offset to each bit within a group in terms of 32 Byte
|
||||
bitOffsetInGroup = (lut_numCnInCnGroups_BG1_R13[5]*NR_LDPC_ZMAX)>>6;
|
||||
|
||||
// Set pointers to start of group 8
|
||||
p_cnProcBuf = (__m512i*) &cnProcBuf [lut_startAddrCnGroups[5]];
|
||||
p_cnProcBufRes = (__m512i*) &cnProcBufRes[lut_startAddrCnGroups[5]];
|
||||
|
||||
// Loop over every BN
|
||||
for (j=0; j<8; j++)
|
||||
{
|
||||
// Set of results pointer to correct BN address
|
||||
p_cnProcBufResBit = p_cnProcBufRes + (j*bitOffsetInGroup);
|
||||
|
||||
// Loop over CNs
|
||||
for (i=0; i<M; i++)
|
||||
{
|
||||
// Abs and sign of 32 CNs (first BN)
|
||||
zmm0 = p_cnProcBuf[(lut_idxCnProcG8[j][0]/2) + i];
|
||||
sgn = _mm512_xor_si512(*p_ones, zmm0);
|
||||
min = _mm512_abs_epi8(zmm0);
|
||||
|
||||
// Loop over BNs
|
||||
for (k=1; k<7; k++)
|
||||
{
|
||||
zmm0 = p_cnProcBuf[(lut_idxCnProcG8[j][k]/2) + i];
|
||||
min = _mm512_min_epu8(min, _mm512_abs_epi8(zmm0));
|
||||
sgn = _mm512_xor_si512(sgn, zmm0);
|
||||
}
|
||||
|
||||
// Store result
|
||||
min = _mm512_min_epu8(min, *p_maxLLR); // 128 in epi8 is -127
|
||||
*p_cnProcBufResBit = conditional_negate(min, sgn,zeros);
|
||||
p_cnProcBufResBit++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// =====================================================================
|
||||
// Process group with 9 BNs
|
||||
|
||||
// Offset is 2*384/32 = 24
|
||||
const uint8_t lut_idxCnProcG9[9][8] = {{24,48,72,96,120,144,168,192}, {0,48,72,96,120,144,168,192},
|
||||
{0,24,72,96,120,144,168,192}, {0,24,48,96,120,144,168,192},
|
||||
{0,24,48,72,120,144,168,192}, {0,24,48,72,96,144,168,192},
|
||||
{0,24,48,72,96,120,168,192}, {0,24,48,72,96,120,144,192},
|
||||
{0,24,48,72,96,120,144,168}};
|
||||
|
||||
if (lut_numCnInCnGroups[6] > 0)
|
||||
{
|
||||
// Number of groups of 32 CNs for parallel processing
|
||||
// Ceil for values not divisible by 32
|
||||
M = (lut_numCnInCnGroups[6]*Z + 63)>>6;
|
||||
|
||||
// Set the offset to each bit within a group in terms of 32 Byte
|
||||
bitOffsetInGroup = (lut_numCnInCnGroups_BG1_R13[6]*NR_LDPC_ZMAX)>>6;
|
||||
|
||||
// Set pointers to start of group 9
|
||||
p_cnProcBuf = (__m512i*) &cnProcBuf [lut_startAddrCnGroups[6]];
|
||||
p_cnProcBufRes = (__m512i*) &cnProcBufRes[lut_startAddrCnGroups[6]];
|
||||
|
||||
// Loop over every BN
|
||||
for (j=0; j<9; j++)
|
||||
{
|
||||
// Set of results pointer to correct BN address
|
||||
p_cnProcBufResBit = p_cnProcBufRes + (j*bitOffsetInGroup);
|
||||
|
||||
// Loop over CNs
|
||||
for (i=0; i<M; i++)
|
||||
{
|
||||
// Abs and sign of 32 CNs (first BN)
|
||||
zmm0 = p_cnProcBuf[(lut_idxCnProcG9[j][0]/2) + i];
|
||||
sgn = _mm512_xor_si512(*p_ones, zmm0);
|
||||
min = _mm512_abs_epi8(zmm0);
|
||||
|
||||
// Loop over BNs
|
||||
for (k=1; k<8; k++)
|
||||
{
|
||||
zmm0 = p_cnProcBuf[(lut_idxCnProcG9[j][k]/2) + i];
|
||||
min = _mm512_min_epu8(min, _mm512_abs_epi8(zmm0));
|
||||
sgn = _mm512_xor_si512(sgn, zmm0);
|
||||
}
|
||||
|
||||
// Store result
|
||||
min = _mm512_min_epu8(min, *p_maxLLR); // 128 in epi8 is -127
|
||||
*p_cnProcBufResBit = conditional_negate(min, sgn,zeros);
|
||||
p_cnProcBufResBit++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// =====================================================================
|
||||
// Process group with 10 BNs
|
||||
|
||||
// Offset is 1*384/32 = 12
|
||||
const uint8_t lut_idxCnProcG10[10][9] = {{12,24,36,48,60,72,84,96,108}, {0,24,36,48,60,72,84,96,108},
|
||||
{0,12,36,48,60,72,84,96,108}, {0,12,24,48,60,72,84,96,108},
|
||||
{0,12,24,36,60,72,84,96,108}, {0,12,24,36,48,72,84,96,108},
|
||||
{0,12,24,36,48,60,84,96,108}, {0,12,24,36,48,60,72,96,108},
|
||||
{0,12,24,36,48,60,72,84,108}, {0,12,24,36,48,60,72,84,96}};
|
||||
|
||||
if (lut_numCnInCnGroups[7] > 0)
|
||||
{
|
||||
// Number of groups of 32 CNs for parallel processing
|
||||
// Ceil for values not divisible by 32
|
||||
M = (lut_numCnInCnGroups[7]*Z + 63)>>6;
|
||||
|
||||
// Set the offset to each bit within a group in terms of 32 Byte
|
||||
bitOffsetInGroup = (lut_numCnInCnGroups_BG1_R13[7]*NR_LDPC_ZMAX)>>6;
|
||||
|
||||
// Set pointers to start of group 10
|
||||
p_cnProcBuf = (__m512i*) &cnProcBuf [lut_startAddrCnGroups[7]];
|
||||
p_cnProcBufRes = (__m512i*) &cnProcBufRes[lut_startAddrCnGroups[7]];
|
||||
|
||||
// Loop over every BN
|
||||
for (j=0; j<10; j++)
|
||||
{
|
||||
// Set of results pointer to correct BN address
|
||||
p_cnProcBufResBit = p_cnProcBufRes + (j*bitOffsetInGroup);
|
||||
|
||||
// Loop over CNs
|
||||
for (i=0; i<M; i++)
|
||||
{
|
||||
// Abs and sign of 32 CNs (first BN)
|
||||
zmm0 = p_cnProcBuf[(lut_idxCnProcG10[j][0]/2) + i];
|
||||
sgn = _mm512_xor_si512(*p_ones, zmm0);
|
||||
min = _mm512_abs_epi8(zmm0);
|
||||
|
||||
// Loop over BNs
|
||||
for (k=1; k<9; k++)
|
||||
{
|
||||
zmm0 = p_cnProcBuf[(lut_idxCnProcG10[j][k]/2) + i];
|
||||
min = _mm512_min_epu8(min, _mm512_abs_epi8(zmm0));
|
||||
sgn = _mm512_xor_si512(sgn, zmm0);
|
||||
}
|
||||
|
||||
// Store result
|
||||
min = _mm512_min_epu8(min, *p_maxLLR); // 128 in epi8 is -127
|
||||
*p_cnProcBufResBit = conditional_negate(min, sgn,zeros);
|
||||
p_cnProcBufResBit++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// =====================================================================
|
||||
// Process group with 19 BNs
|
||||
|
||||
// Offset is 4*384/32 = 12
|
||||
const uint16_t lut_idxCnProcG19[19][18] = {{48,96,144,192,240,288,336,384,432,480,528,576,624,672,720,768,816,864}, {0,96,144,192,240,288,336,384,432,480,528,576,624,672,720,768,816,864},
|
||||
{0,48,144,192,240,288,336,384,432,480,528,576,624,672,720,768,816,864}, {0,48,96,192,240,288,336,384,432,480,528,576,624,672,720,768,816,864},
|
||||
{0,48,96,144,240,288,336,384,432,480,528,576,624,672,720,768,816,864}, {0,48,96,144,192,288,336,384,432,480,528,576,624,672,720,768,816,864},
|
||||
{0,48,96,144,192,240,336,384,432,480,528,576,624,672,720,768,816,864}, {0,48,96,144,192,240,288,384,432,480,528,576,624,672,720,768,816,864},
|
||||
{0,48,96,144,192,240,288,336,432,480,528,576,624,672,720,768,816,864}, {0,48,96,144,192,240,288,336,384,480,528,576,624,672,720,768,816,864},
|
||||
{0,48,96,144,192,240,288,336,384,432,528,576,624,672,720,768,816,864}, {0,48,96,144,192,240,288,336,384,432,480,576,624,672,720,768,816,864},
|
||||
{0,48,96,144,192,240,288,336,384,432,480,528,624,672,720,768,816,864}, {0,48,96,144,192,240,288,336,384,432,480,528,576,672,720,768,816,864},
|
||||
{0,48,96,144,192,240,288,336,384,432,480,528,576,624,720,768,816,864}, {0,48,96,144,192,240,288,336,384,432,480,528,576,624,672,768,816,864},
|
||||
{0,48,96,144,192,240,288,336,384,432,480,528,576,624,672,720,816,864}, {0,48,96,144,192,240,288,336,384,432,480,528,576,624,672,720,768,864},
|
||||
{0,48,96,144,192,240,288,336,384,432,480,528,576,624,672,720,768,816}};
|
||||
|
||||
if (lut_numCnInCnGroups[8] > 0)
|
||||
{
|
||||
// Number of groups of 32 CNs for parallel processing
|
||||
// Ceil for values not divisible by 32
|
||||
M = (lut_numCnInCnGroups[8]*Z + 63)>>6;
|
||||
|
||||
// Set the offset to each bit within a group in terms of 32 Byte
|
||||
bitOffsetInGroup = (lut_numCnInCnGroups_BG1_R13[8]*NR_LDPC_ZMAX)>>6;
|
||||
|
||||
// Set pointers to start of group 19
|
||||
p_cnProcBuf = (__m512i*) &cnProcBuf [lut_startAddrCnGroups[8]];
|
||||
p_cnProcBufRes = (__m512i*) &cnProcBufRes[lut_startAddrCnGroups[8]];
|
||||
|
||||
// Loop over every BN
|
||||
for (j=0; j<19; j++)
|
||||
{
|
||||
// Set of results pointer to correct BN address
|
||||
p_cnProcBufResBit = p_cnProcBufRes + (j*bitOffsetInGroup);
|
||||
|
||||
// Loop over CNs
|
||||
for (i=0; i<M; i++)
|
||||
{
|
||||
// Abs and sign of 32 CNs (first BN)
|
||||
zmm0 = p_cnProcBuf[(lut_idxCnProcG19[j][0]/2) + i];
|
||||
sgn = _mm512_xor_si512(*p_ones, zmm0);
|
||||
min = _mm512_abs_epi8(zmm0);
|
||||
|
||||
// Loop over BNs
|
||||
for (k=1; k<18; k++)
|
||||
{
|
||||
zmm0 = p_cnProcBuf[(lut_idxCnProcG19[j][k]/2) + i];
|
||||
min = _mm512_min_epu8(min, _mm512_abs_epi8(zmm0));
|
||||
sgn = _mm512_xor_si512(sgn, zmm0);
|
||||
}
|
||||
|
||||
// Store result
|
||||
min = _mm512_min_epu8(min, *p_maxLLR); // 128 in epi8 is -127
|
||||
*p_cnProcBufResBit = conditional_negate(min, sgn,zeros);
|
||||
p_cnProcBufResBit++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
#endif
|
||||
@@ -1,3 +1,5 @@
|
||||
|
||||
|
||||
/*
|
||||
* Licensed to the OpenAirInterface (OAI) Software Alliance under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with
|
||||
@@ -20,14 +22,8 @@
|
||||
*/
|
||||
|
||||
/*!\file nrLDPC_decoder.c
|
||||
* \brief Defines the LDPC decoder
|
||||
* \author Sebastian Wagner (TCL Communications) Email: <mailto:sebastian.wagner@tcl.com>
|
||||
* \date 30-09-2019
|
||||
* \version 2.0
|
||||
* \note
|
||||
* \warning
|
||||
*/
|
||||
|
||||
* \brief Defines thenrLDPC decoder
|
||||
*/
|
||||
|
||||
#include <stdint.h>
|
||||
#include <immintrin.h>
|
||||
@@ -37,6 +33,83 @@
|
||||
#include "nrLDPC_mPass.h"
|
||||
#include "nrLDPC_cnProc.h"
|
||||
#include "nrLDPC_bnProc.h"
|
||||
#define UNROLL_CN_PROC 1
|
||||
#define UNROLL_BN_PROC 1
|
||||
#define UNROLL_BN_PROC_PC 1
|
||||
#define UNROLL_BN2CN_PROC 1
|
||||
/*----------------------------------------------------------------------
|
||||
| cn processing files -->AVX512
|
||||
/----------------------------------------------------------------------*/
|
||||
|
||||
//BG1-------------------------------------------------------------------
|
||||
#ifdef __AVX512BW__
|
||||
|
||||
#include "cnProc_avx512/nrLDPC_cnProc_BG1_R13_AVX512.h"
|
||||
#include "cnProc_avx512/nrLDPC_cnProc_BG1_R23_AVX512.h"
|
||||
#include "cnProc_avx512/nrLDPC_cnProc_BG1_R89_AVX512.h"
|
||||
//BG2-------------------------------------------------------------------
|
||||
#include "cnProc_avx512/nrLDPC_cnProc_BG2_R15_AVX512.h"
|
||||
#include "cnProc_avx512/nrLDPC_cnProc_BG2_R13_AVX512.h"
|
||||
#include "cnProc_avx512/nrLDPC_cnProc_BG2_R23_AVX512.h"
|
||||
|
||||
#else
|
||||
|
||||
/*----------------------------------------------------------------------
|
||||
| cn Processing files -->AVX2
|
||||
/----------------------------------------------------------------------*/
|
||||
|
||||
//BG1------------------------------------------------------------------
|
||||
#include "cnProc/nrLDPC_cnProc_BG1_R13_AVX2.h"
|
||||
#include "cnProc/nrLDPC_cnProc_BG1_R23_AVX2.h"
|
||||
#include "cnProc/nrLDPC_cnProc_BG1_R89_AVX2.h"
|
||||
//BG2 --------------------------------------------------------------------
|
||||
#include "cnProc/nrLDPC_cnProc_BG2_R15_AVX2.h"
|
||||
#include "cnProc/nrLDPC_cnProc_BG2_R13_AVX2.h"
|
||||
#include "cnProc/nrLDPC_cnProc_BG2_R23_AVX2.h"
|
||||
|
||||
#endif
|
||||
|
||||
/*----------------------------------------------------------------------
|
||||
| bn Processing files -->AVX2
|
||||
/----------------------------------------------------------------------*/
|
||||
|
||||
//bnProcPc-------------------------------------------------------------
|
||||
//BG1------------------------------------------------------------------
|
||||
#include "bnProcPc/nrLDPC_bnProcPc_BG1_R13_AVX2.h"
|
||||
#include "bnProcPc/nrLDPC_bnProcPc_BG1_R23_AVX2.h"
|
||||
#include "bnProcPc/nrLDPC_bnProcPc_BG1_R89_AVX2.h"
|
||||
//BG2 --------------------------------------------------------------------
|
||||
#include "bnProcPc/nrLDPC_bnProcPc_BG2_R15_AVX2.h"
|
||||
#include "bnProcPc/nrLDPC_bnProcPc_BG2_R13_AVX2.h"
|
||||
#include "bnProcPc/nrLDPC_bnProcPc_BG2_R23_AVX2.h"
|
||||
|
||||
//bnProc----------------------------------------------------------------
|
||||
|
||||
#ifdef __AVX512BW__
|
||||
//BG1-------------------------------------------------------------------
|
||||
#include "bnProc_avx512/nrLDPC_bnProc_BG1_R13_AVX512.h"
|
||||
#include "bnProc_avx512/nrLDPC_bnProc_BG1_R23_AVX512.h"
|
||||
#include "bnProc_avx512/nrLDPC_bnProc_BG1_R89_AVX512.h"
|
||||
//BG2 --------------------------------------------------------------------
|
||||
#include "bnProc_avx512/nrLDPC_bnProc_BG2_R15_AVX512.h"
|
||||
#include "bnProc_avx512/nrLDPC_bnProc_BG2_R13_AVX512.h"
|
||||
#include "bnProc_avx512/nrLDPC_bnProc_BG2_R23_AVX512.h"
|
||||
|
||||
#else
|
||||
#include "bnProc/nrLDPC_bnProc_BG1_R13_AVX2.h"
|
||||
#include "bnProc/nrLDPC_bnProc_BG1_R23_AVX2.h"
|
||||
#include "bnProc/nrLDPC_bnProc_BG1_R89_AVX2.h"
|
||||
//BG2 --------------------------------------------------------------------
|
||||
#include "bnProc/nrLDPC_bnProc_BG2_R15_AVX2.h"
|
||||
#include "bnProc/nrLDPC_bnProc_BG2_R13_AVX2.h"
|
||||
#include "bnProc/nrLDPC_bnProc_BG2_R23_AVX2.h"
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
#define NR_LDPC_ENABLE_PARITY_CHECK
|
||||
//#define NR_LDPC_PROFILER_DETAIL
|
||||
@@ -66,28 +139,31 @@ int32_t nrLDPC_decod(t_nrLDPC_dec_params* p_decParams, int8_t* p_llr, int8_t* p_
|
||||
}
|
||||
|
||||
/**
|
||||
\brief Performs LDPC decoding of one code block
|
||||
\brief PerformsnrLDPC decoding of one code block
|
||||
\param p_llr Input LLRs
|
||||
\param p_out Output vector
|
||||
\param numLLR Number of LLRs
|
||||
\param p_lut Pointer to decoder LUTs
|
||||
\param p_decParams LDPC decoder parameters
|
||||
\param p_profiler LDPC profiler statistics
|
||||
\param p_decParamsnrLDPC decoder parameters
|
||||
\param p_profilernrLDPC profiler statistics
|
||||
*/
|
||||
static inline uint32_t nrLDPC_decoder_core(int8_t* p_llr, int8_t* p_out, uint32_t numLLR, t_nrLDPC_lut* p_lut, t_nrLDPC_dec_params* p_decParams, t_nrLDPC_time_stats* p_profiler)
|
||||
{
|
||||
uint16_t Z = p_decParams->Z;
|
||||
uint8_t BG = p_decParams->BG;
|
||||
uint8_t R = p_decParams->R; //Decoding rate: Format 15,13,... for code rates 1/5, 1/3,... */
|
||||
uint8_t numMaxIter = p_decParams->numMaxIter;
|
||||
e_nrLDPC_outMode outMode = p_decParams->outMode;
|
||||
// int8_t* cnProcBuf= cnProcBuf;
|
||||
// int8_t* cnProcBufRes= cnProcBufRes;
|
||||
|
||||
int8_t cnProcBuf[NR_LDPC_SIZE_CN_PROC_BUF] __attribute__ ((aligned(32))) = {0};
|
||||
int8_t cnProcBufRes[NR_LDPC_SIZE_CN_PROC_BUF] __attribute__ ((aligned(32))) = {0};
|
||||
int8_t bnProcBuf[NR_LDPC_SIZE_BN_PROC_BUF] __attribute__ ((aligned(32))) = {0};
|
||||
int8_t bnProcBufRes[NR_LDPC_SIZE_BN_PROC_BUF] __attribute__ ((aligned(32))) = {0};
|
||||
int8_t llrRes[NR_LDPC_MAX_NUM_LLR] __attribute__ ((aligned(32))) = {0};
|
||||
int8_t llrProcBuf[NR_LDPC_MAX_NUM_LLR] __attribute__ ((aligned(32))) = {0};
|
||||
int8_t llrOut[NR_LDPC_MAX_NUM_LLR] __attribute__ ((aligned(32))) = {0};
|
||||
int8_t cnProcBuf[NR_LDPC_SIZE_CN_PROC_BUF] __attribute__ ((aligned(64))) = {0};
|
||||
int8_t cnProcBufRes[NR_LDPC_SIZE_CN_PROC_BUF] __attribute__ ((aligned(64))) = {0};
|
||||
int8_t bnProcBuf[NR_LDPC_SIZE_BN_PROC_BUF] __attribute__ ((aligned(64))) = {0};
|
||||
int8_t bnProcBufRes[NR_LDPC_SIZE_BN_PROC_BUF] __attribute__ ((aligned(64))) = {0};
|
||||
int8_t llrRes[NR_LDPC_MAX_NUM_LLR] __attribute__ ((aligned(64))) = {0};
|
||||
int8_t llrProcBuf[NR_LDPC_MAX_NUM_LLR] __attribute__ ((aligned(64))) = {0};
|
||||
int8_t llrOut[NR_LDPC_MAX_NUM_LLR] __attribute__ ((aligned(64))) = {0};
|
||||
// Minimum number of iterations is 1
|
||||
// 0 iterations means hard-decision on input LLRs
|
||||
uint32_t i = 1;
|
||||
@@ -123,14 +199,8 @@ static inline uint32_t nrLDPC_decoder_core(int8_t* p_llr, int8_t* p_out, uint32_
|
||||
#ifdef NR_LDPC_PROFILER_DETAIL
|
||||
start_meas(&p_profiler->llr2CnProcBuf);
|
||||
#endif
|
||||
if (BG == 1)
|
||||
{
|
||||
nrLDPC_llr2CnProcBuf_BG1(p_lut, p_llr, cnProcBuf, Z);
|
||||
}
|
||||
else
|
||||
{
|
||||
nrLDPC_llr2CnProcBuf_BG2(p_lut, p_llr, cnProcBuf, Z);
|
||||
}
|
||||
if (BG == 1) nrLDPC_llr2CnProcBuf_BG1(p_lut, p_llr, cnProcBuf, Z);
|
||||
else nrLDPC_llr2CnProcBuf_BG2(p_lut, p_llr, cnProcBuf, Z);
|
||||
#ifdef NR_LDPC_PROFILER_DETAIL
|
||||
stop_meas(&p_profiler->llr2CnProcBuf);
|
||||
#endif
|
||||
@@ -146,13 +216,79 @@ static inline uint32_t nrLDPC_decoder_core(int8_t* p_llr, int8_t* p_out, uint32_
|
||||
#ifdef NR_LDPC_PROFILER_DETAIL
|
||||
start_meas(&p_profiler->cnProc);
|
||||
#endif
|
||||
if (BG == 1)
|
||||
{
|
||||
if (BG==1) {
|
||||
#ifndef UNROLL_CN_PROC
|
||||
nrLDPC_cnProc_BG1(p_lut, cnProcBuf, cnProcBufRes, Z);
|
||||
}
|
||||
else
|
||||
{
|
||||
#else
|
||||
switch (R)
|
||||
{
|
||||
case 13:
|
||||
{
|
||||
#ifdef __AVX512BW__
|
||||
nrLDPC_cnProc_BG1_R13_AVX512(cnProcBuf, cnProcBufRes, Z);
|
||||
#else
|
||||
nrLDPC_cnProc_BG1_R13_AVX2(cnProcBuf, cnProcBufRes, Z);
|
||||
#endif
|
||||
break;
|
||||
}
|
||||
|
||||
case 23:
|
||||
{
|
||||
#ifdef __AVX512BW__
|
||||
nrLDPC_cnProc_BG1_R23_AVX512(cnProcBuf,cnProcBufRes, Z);
|
||||
#else
|
||||
nrLDPC_cnProc_BG1_R23_AVX2(cnProcBuf, cnProcBufRes, Z);
|
||||
#endif
|
||||
break;
|
||||
}
|
||||
|
||||
case 89:
|
||||
{
|
||||
#ifdef __AVX512BW__
|
||||
nrLDPC_cnProc_BG1_R89_AVX512(cnProcBuf, cnProcBufRes, Z);
|
||||
#else
|
||||
nrLDPC_cnProc_BG1_R89_AVX2(cnProcBuf, cnProcBufRes, Z);
|
||||
#endif
|
||||
break;
|
||||
}
|
||||
|
||||
}
|
||||
#endif
|
||||
} else {
|
||||
#ifndef UNROLL_CN_PROC
|
||||
nrLDPC_cnProc_BG2(p_lut, cnProcBuf, cnProcBufRes, Z);
|
||||
#else
|
||||
switch (R) {
|
||||
case 15:
|
||||
{
|
||||
#ifdef __AVX512BW__
|
||||
nrLDPC_cnProc_BG2_R15_AVX512(cnProcBuf, cnProcBufRes, Z);
|
||||
#else
|
||||
nrLDPC_cnProc_BG2_R15_AVX2(cnProcBuf, cnProcBufRes, Z);
|
||||
#endif
|
||||
break;
|
||||
}
|
||||
case 13:
|
||||
{
|
||||
#ifdef __AVX512BW__
|
||||
nrLDPC_cnProc_BG2_R13_AVX512(cnProcBuf, cnProcBufRes, Z);
|
||||
#else
|
||||
nrLDPC_cnProc_BG2_R13_AVX2(cnProcBuf, cnProcBufRes, Z);
|
||||
#endif
|
||||
break;
|
||||
}
|
||||
case 23:
|
||||
{
|
||||
#ifdef __AVX512BW__
|
||||
nrLDPC_cnProc_BG2_R23_AVX512(cnProcBuf, cnProcBufRes, Z);
|
||||
#else
|
||||
nrLDPC_cnProc_BG2_R23_AVX2(cnProcBuf, cnProcBufRes, Z);
|
||||
#endif
|
||||
break;
|
||||
}
|
||||
|
||||
}
|
||||
#endif
|
||||
}
|
||||
#ifdef NR_LDPC_PROFILER_DETAIL
|
||||
stop_meas(&p_profiler->cnProc);
|
||||
@@ -166,14 +302,8 @@ static inline uint32_t nrLDPC_decoder_core(int8_t* p_llr, int8_t* p_out, uint32_
|
||||
#ifdef NR_LDPC_PROFILER_DETAIL
|
||||
start_meas(&p_profiler->cn2bnProcBuf);
|
||||
#endif
|
||||
if (BG == 1)
|
||||
{
|
||||
nrLDPC_cn2bnProcBuf_BG1(p_lut, cnProcBufRes, bnProcBuf, Z);
|
||||
}
|
||||
else
|
||||
{
|
||||
nrLDPC_cn2bnProcBuf_BG2(p_lut, cnProcBufRes, bnProcBuf, Z);
|
||||
}
|
||||
if (BG == 1) nrLDPC_cn2bnProcBuf_BG1(p_lut, cnProcBufRes, bnProcBuf, Z);
|
||||
else nrLDPC_cn2bnProcBuf_BG2(p_lut, cnProcBufRes, bnProcBuf, Z);
|
||||
#ifdef NR_LDPC_PROFILER_DETAIL
|
||||
stop_meas(&p_profiler->cn2bnProcBuf);
|
||||
#endif
|
||||
@@ -187,7 +317,51 @@ static inline uint32_t nrLDPC_decoder_core(int8_t* p_llr, int8_t* p_out, uint32_
|
||||
#ifdef NR_LDPC_PROFILER_DETAIL
|
||||
start_meas(&p_profiler->bnProcPc);
|
||||
#endif
|
||||
|
||||
|
||||
#ifndef UNROLL_BN_PROC_PC
|
||||
nrLDPC_bnProcPc(p_lut, bnProcBuf, bnProcBufRes, llrProcBuf, llrRes, Z);
|
||||
#else
|
||||
if (BG==1) {
|
||||
switch (R) {
|
||||
case 13:
|
||||
{
|
||||
nrLDPC_bnProcPc_BG1_R13_AVX2(bnProcBuf,bnProcBufRes,llrRes, llrProcBuf, Z);
|
||||
break;
|
||||
}
|
||||
case 23:
|
||||
{
|
||||
nrLDPC_bnProcPc_BG1_R23_AVX2(bnProcBuf,bnProcBufRes, llrRes, llrProcBuf, Z);
|
||||
break;
|
||||
}
|
||||
case 89:
|
||||
{
|
||||
nrLDPC_bnProcPc_BG1_R89_AVX2(bnProcBuf,bnProcBufRes, llrRes, llrProcBuf, Z);
|
||||
break;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
switch (R) {
|
||||
case 15:
|
||||
{
|
||||
nrLDPC_bnProcPc_BG2_R15_AVX2(bnProcBuf,bnProcBufRes, llrRes, llrProcBuf, Z);
|
||||
break;
|
||||
}
|
||||
case 13:
|
||||
{
|
||||
nrLDPC_bnProcPc_BG2_R13_AVX2(bnProcBuf,bnProcBufRes,llrRes,llrProcBuf, Z);
|
||||
break;
|
||||
}
|
||||
|
||||
case 23:
|
||||
{
|
||||
nrLDPC_bnProcPc_BG2_R23_AVX2(bnProcBuf,bnProcBufRes,llrRes, llrProcBuf, Z);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef NR_LDPC_PROFILER_DETAIL
|
||||
stop_meas(&p_profiler->bnProcPc);
|
||||
#endif
|
||||
@@ -200,7 +374,78 @@ static inline uint32_t nrLDPC_decoder_core(int8_t* p_llr, int8_t* p_out, uint32_
|
||||
#ifdef NR_LDPC_PROFILER_DETAIL
|
||||
start_meas(&p_profiler->bnProc);
|
||||
#endif
|
||||
nrLDPC_bnProc(p_lut, bnProcBuf, bnProcBufRes, llrRes, Z);
|
||||
|
||||
if (BG==1) {
|
||||
#ifndef UNROLL_BN_PROC
|
||||
nrLDPC_bnProc(p_lut, bnProcBuf, bnProcBufRes, llrRes, Z);
|
||||
#else
|
||||
switch (R) {
|
||||
case 13:
|
||||
{
|
||||
#ifdef __AVX512BW__
|
||||
nrLDPC_bnProc_BG1_R13_AVX512(bnProcBuf, bnProcBufRes,llrRes, Z);
|
||||
#else
|
||||
nrLDPC_bnProc_BG1_R13_AVX2(bnProcBuf, bnProcBufRes,llrRes, Z);
|
||||
#endif
|
||||
break;
|
||||
}
|
||||
case 23:
|
||||
{
|
||||
#ifdef __AVX512BW__
|
||||
nrLDPC_bnProc_BG1_R23_AVX512(bnProcBuf, bnProcBufRes,llrRes, Z);
|
||||
#else
|
||||
nrLDPC_bnProc_BG1_R23_AVX2(bnProcBuf, bnProcBufRes,llrRes, Z);
|
||||
#endif
|
||||
break;
|
||||
}
|
||||
case 89:
|
||||
{
|
||||
#ifdef __AVX512BW__
|
||||
nrLDPC_bnProc_BG1_R89_AVX512(bnProcBuf, bnProcBufRes,llrRes, Z);
|
||||
#else
|
||||
nrLDPC_bnProc_BG1_R89_AVX2(bnProcBuf, bnProcBufRes,llrRes, Z);
|
||||
#endif
|
||||
break;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
} else {
|
||||
#ifndef UNROLL_BN2CN_PROC
|
||||
nrLDPC_bn2cnProcBuf_BG2(p_lut, bnProcBufRes, cnProcBuf, Z);
|
||||
#else
|
||||
switch (R) {
|
||||
case 15:
|
||||
{
|
||||
#ifdef __AVX512BW__
|
||||
nrLDPC_bnProc_BG2_R15_AVX512(bnProcBuf, bnProcBufRes,llrRes, Z);
|
||||
#else
|
||||
nrLDPC_bnProc_BG2_R15_AVX2(bnProcBuf, bnProcBufRes,llrRes, Z);
|
||||
#endif
|
||||
break;
|
||||
}
|
||||
case 13:
|
||||
{
|
||||
#ifdef __AVX512BW__
|
||||
nrLDPC_bnProc_BG2_R13_AVX512(bnProcBuf, bnProcBufRes,llrRes, Z);
|
||||
#else
|
||||
nrLDPC_bnProc_BG2_R13_AVX2(bnProcBuf, bnProcBufRes,llrRes, Z);
|
||||
#endif
|
||||
break;
|
||||
}
|
||||
|
||||
case 23:
|
||||
{
|
||||
#ifdef __AVX512BW__
|
||||
nrLDPC_bnProc_BG2_R23_AVX512(bnProcBuf, bnProcBufRes,llrRes, Z);
|
||||
#else
|
||||
nrLDPC_bnProc_BG2_R23_AVX2(bnProcBuf, bnProcBufRes,llrRes, Z);
|
||||
#endif
|
||||
break;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
#ifdef NR_LDPC_PROFILER_DETAIL
|
||||
stop_meas(&p_profiler->bnProc);
|
||||
#endif
|
||||
@@ -214,14 +459,8 @@ static inline uint32_t nrLDPC_decoder_core(int8_t* p_llr, int8_t* p_out, uint32_
|
||||
#ifdef NR_LDPC_PROFILER_DETAIL
|
||||
start_meas(&p_profiler->bn2cnProcBuf);
|
||||
#endif
|
||||
if (BG == 1)
|
||||
{
|
||||
nrLDPC_bn2cnProcBuf_BG1(p_lut, bnProcBufRes, cnProcBuf, Z);
|
||||
}
|
||||
else
|
||||
{
|
||||
nrLDPC_bn2cnProcBuf_BG2(p_lut, bnProcBufRes, cnProcBuf, Z);
|
||||
}
|
||||
if (BG == 1) nrLDPC_bn2cnProcBuf_BG1(p_lut, bnProcBufRes, cnProcBuf, Z);
|
||||
else nrLDPC_bn2cnProcBuf_BG2(p_lut, bnProcBufRes, cnProcBuf, Z);
|
||||
#ifdef NR_LDPC_PROFILER_DETAIL
|
||||
stop_meas(&p_profiler->bn2cnProcBuf);
|
||||
#endif
|
||||
@@ -236,8 +475,7 @@ static inline uint32_t nrLDPC_decoder_core(int8_t* p_llr, int8_t* p_out, uint32_
|
||||
|
||||
// First iteration finished
|
||||
|
||||
while ( (i < numMaxIter) && (pcRes != 0) )
|
||||
{
|
||||
while ( (i < numMaxIter) && (pcRes != 0) ) {
|
||||
// Increase iteration counter
|
||||
i++;
|
||||
|
||||
@@ -245,13 +483,74 @@ static inline uint32_t nrLDPC_decoder_core(int8_t* p_llr, int8_t* p_out, uint32_
|
||||
#ifdef NR_LDPC_PROFILER_DETAIL
|
||||
start_meas(&p_profiler->cnProc);
|
||||
#endif
|
||||
if (BG == 1)
|
||||
{
|
||||
nrLDPC_cnProc_BG1(p_lut, cnProcBuf, cnProcBufRes, Z);
|
||||
}
|
||||
else
|
||||
{
|
||||
nrLDPC_cnProc_BG2(p_lut, cnProcBuf, cnProcBufRes, Z);
|
||||
if (BG==1) {
|
||||
#ifndef UNROLL_CN_PROC
|
||||
nrLDPC_cnProc_BG1(p_lut, cnProcBuf, cnProcBufRes, Z);
|
||||
#else
|
||||
switch (R) {
|
||||
case 13:
|
||||
{
|
||||
#ifdef __AVX512BW__
|
||||
nrLDPC_cnProc_BG1_R13_AVX512(cnProcBuf, cnProcBufRes, Z);
|
||||
#else
|
||||
nrLDPC_cnProc_BG1_R13_AVX2(cnProcBuf, cnProcBufRes, Z);
|
||||
#endif
|
||||
break;
|
||||
}
|
||||
case 23:
|
||||
{
|
||||
#ifdef __AVX512BW__
|
||||
nrLDPC_cnProc_BG1_R23_AVX512(cnProcBuf, cnProcBufRes, Z);
|
||||
#else
|
||||
nrLDPC_cnProc_BG1_R23_AVX2(cnProcBuf, cnProcBufRes, Z);
|
||||
#endif
|
||||
break;
|
||||
}
|
||||
case 89:
|
||||
{
|
||||
#ifdef __AVX512BW__
|
||||
nrLDPC_cnProc_BG1_R89_AVX512(cnProcBuf, cnProcBufRes, Z);
|
||||
#else
|
||||
nrLDPC_cnProc_BG1_R89_AVX2(cnProcBuf, cnProcBufRes, Z);
|
||||
#endif
|
||||
break;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
} else {
|
||||
#ifndef UNROLL_CN_PROC
|
||||
nrLDPC_cnProc_BG2(p_lut, cnProcBuf, cnProcBufRes, Z);
|
||||
#else
|
||||
switch (R) {
|
||||
case 15:
|
||||
{
|
||||
#ifdef __AVX512BW__
|
||||
nrLDPC_cnProc_BG2_R15_AVX512(cnProcBuf,cnProcBufRes, Z);
|
||||
#else
|
||||
nrLDPC_cnProc_BG2_R15_AVX2(cnProcBuf, cnProcBufRes, Z);
|
||||
#endif
|
||||
break;
|
||||
}
|
||||
case 13:
|
||||
{
|
||||
#ifdef __AVX512BW__
|
||||
nrLDPC_cnProc_BG2_R13_AVX512(cnProcBuf, cnProcBufRes, Z);
|
||||
#else
|
||||
nrLDPC_cnProc_BG2_R13_AVX2(cnProcBuf, cnProcBufRes, Z);
|
||||
#endif
|
||||
break;
|
||||
}
|
||||
case 23:
|
||||
{
|
||||
#ifdef __AVX512BW__
|
||||
nrLDPC_cnProc_BG2_R23_AVX512(cnProcBuf, cnProcBufRes, Z);
|
||||
#else
|
||||
nrLDPC_cnProc_BG2_R23_AVX2(cnProcBuf, cnProcBufRes, Z);
|
||||
#endif
|
||||
break;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
}
|
||||
#ifdef NR_LDPC_PROFILER_DETAIL
|
||||
stop_meas(&p_profiler->cnProc);
|
||||
@@ -265,14 +564,8 @@ static inline uint32_t nrLDPC_decoder_core(int8_t* p_llr, int8_t* p_out, uint32_
|
||||
#ifdef NR_LDPC_PROFILER_DETAIL
|
||||
start_meas(&p_profiler->cn2bnProcBuf);
|
||||
#endif
|
||||
if (BG == 1)
|
||||
{
|
||||
nrLDPC_cn2bnProcBuf_BG1(p_lut, cnProcBufRes, bnProcBuf, Z);
|
||||
}
|
||||
else
|
||||
{
|
||||
nrLDPC_cn2bnProcBuf_BG2(p_lut, cnProcBufRes, bnProcBuf, Z);
|
||||
}
|
||||
if (BG == 1) nrLDPC_cn2bnProcBuf_BG1(p_lut, cnProcBufRes, bnProcBuf, Z);
|
||||
else nrLDPC_cn2bnProcBuf_BG2(p_lut, cnProcBufRes, bnProcBuf, Z);
|
||||
#ifdef NR_LDPC_PROFILER_DETAIL
|
||||
stop_meas(&p_profiler->cn2bnProcBuf);
|
||||
#endif
|
||||
@@ -285,7 +578,49 @@ static inline uint32_t nrLDPC_decoder_core(int8_t* p_llr, int8_t* p_out, uint32_
|
||||
#ifdef NR_LDPC_PROFILER_DETAIL
|
||||
start_meas(&p_profiler->bnProcPc);
|
||||
#endif
|
||||
|
||||
#ifndef UNROLL_BN_PROC_PC
|
||||
nrLDPC_bnProcPc(p_lut, bnProcBuf, bnProcBufRes, llrProcBuf, llrRes, Z);
|
||||
#else
|
||||
if (BG==1) {
|
||||
switch (R) {
|
||||
case 13:
|
||||
{
|
||||
nrLDPC_bnProcPc_BG1_R13_AVX2(bnProcBuf,bnProcBufRes,llrRes, llrProcBuf, Z);
|
||||
break;
|
||||
}
|
||||
case 23:
|
||||
{
|
||||
nrLDPC_bnProcPc_BG1_R23_AVX2(bnProcBuf,bnProcBufRes, llrRes, llrProcBuf, Z);
|
||||
break;
|
||||
}
|
||||
case 89:
|
||||
{
|
||||
nrLDPC_bnProcPc_BG1_R89_AVX2(bnProcBuf,bnProcBufRes, llrRes, llrProcBuf, Z);
|
||||
break;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
switch (R)
|
||||
{
|
||||
case 15:
|
||||
{
|
||||
nrLDPC_bnProcPc_BG2_R15_AVX2(bnProcBuf,bnProcBufRes,llrRes, llrProcBuf, Z);
|
||||
break;
|
||||
}
|
||||
case 13:
|
||||
{
|
||||
nrLDPC_bnProcPc_BG2_R13_AVX2(bnProcBuf,bnProcBufRes,llrRes, llrProcBuf, Z);
|
||||
break;
|
||||
}
|
||||
case 23:
|
||||
{
|
||||
nrLDPC_bnProcPc_BG2_R23_AVX2(bnProcBuf,bnProcBufRes,llrRes, llrProcBuf, Z);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
#ifdef NR_LDPC_PROFILER_DETAIL
|
||||
stop_meas(&p_profiler->bnProcPc);
|
||||
#endif
|
||||
@@ -297,7 +632,75 @@ static inline uint32_t nrLDPC_decoder_core(int8_t* p_llr, int8_t* p_out, uint32_
|
||||
#ifdef NR_LDPC_PROFILER_DETAIL
|
||||
start_meas(&p_profiler->bnProc);
|
||||
#endif
|
||||
#ifndef UNROLL_BN_PROC
|
||||
nrLDPC_bnProc(p_lut, bnProcBuf, bnProcBufRes, llrRes, Z);
|
||||
#else
|
||||
if (BG==1) {
|
||||
switch (R) {
|
||||
case 13:
|
||||
{
|
||||
#ifdef __AVX512BW__
|
||||
nrLDPC_bnProc_BG1_R13_AVX512(bnProcBuf, bnProcBufRes,llrRes, Z);
|
||||
#else
|
||||
nrLDPC_bnProc_BG1_R13_AVX2(bnProcBuf, bnProcBufRes,llrRes, Z);
|
||||
#endif
|
||||
break;
|
||||
}
|
||||
case 23:
|
||||
{
|
||||
#ifdef __AVX512BW__
|
||||
nrLDPC_bnProc_BG1_R23_AVX512(bnProcBuf, bnProcBufRes,llrRes, Z);
|
||||
#else
|
||||
nrLDPC_bnProc_BG1_R23_AVX2(bnProcBuf,bnProcBufRes,llrRes, Z);
|
||||
#endif
|
||||
break;
|
||||
}
|
||||
case 89:
|
||||
{
|
||||
#ifdef __AVX512BW__
|
||||
nrLDPC_bnProc_BG1_R89_AVX512(bnProcBuf, bnProcBufRes,llrRes, Z);
|
||||
#else
|
||||
nrLDPC_bnProc_BG1_R89_AVX2(bnProcBuf, bnProcBufRes,llrRes, Z);
|
||||
#endif
|
||||
break;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
switch (R)
|
||||
{
|
||||
case 15:
|
||||
{
|
||||
#ifdef __AVX512BW__
|
||||
nrLDPC_bnProc_BG2_R15_AVX512(bnProcBuf, bnProcBufRes,llrRes, Z);
|
||||
#else
|
||||
nrLDPC_bnProc_BG2_R15_AVX2(bnProcBuf, bnProcBufRes,llrRes, Z);
|
||||
#endif
|
||||
break;
|
||||
}
|
||||
case 13:
|
||||
{
|
||||
#ifdef __AVX512BW__
|
||||
nrLDPC_bnProc_BG2_R13_AVX512(bnProcBuf, bnProcBufRes,llrRes, Z);
|
||||
#else
|
||||
nrLDPC_bnProc_BG2_R13_AVX2(bnProcBuf, bnProcBufRes,llrRes, Z);
|
||||
#endif
|
||||
break;
|
||||
}
|
||||
case 23:
|
||||
{
|
||||
#ifdef __AVX512BW__
|
||||
nrLDPC_bnProc_BG2_R23_AVX512(bnProcBuf, bnProcBufRes,llrRes, Z);
|
||||
#else
|
||||
nrLDPC_bnProc_BG2_R23_AVX2(bnProcBuf, bnProcBufRes,llrRes, Z);
|
||||
#endif
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
#ifdef NR_LDPC_PROFILER_DETAIL
|
||||
stop_meas(&p_profiler->bnProc);
|
||||
#endif
|
||||
@@ -310,14 +713,8 @@ static inline uint32_t nrLDPC_decoder_core(int8_t* p_llr, int8_t* p_out, uint32_
|
||||
#ifdef NR_LDPC_PROFILER_DETAIL
|
||||
start_meas(&p_profiler->bn2cnProcBuf);
|
||||
#endif
|
||||
if (BG == 1)
|
||||
{
|
||||
nrLDPC_bn2cnProcBuf_BG1(p_lut, bnProcBufRes, cnProcBuf, Z);
|
||||
}
|
||||
else
|
||||
{
|
||||
nrLDPC_bn2cnProcBuf_BG2(p_lut, bnProcBufRes, cnProcBuf, Z);
|
||||
}
|
||||
if (BG == 1) nrLDPC_bn2cnProcBuf_BG1(p_lut, bnProcBufRes, cnProcBuf, Z);
|
||||
else nrLDPC_bn2cnProcBuf_BG2(p_lut, bnProcBufRes, cnProcBuf, Z);
|
||||
#ifdef NR_LDPC_PROFILER_DETAIL
|
||||
stop_meas(&p_profiler->bn2cnProcBuf);
|
||||
#endif
|
||||
@@ -326,60 +723,44 @@ static inline uint32_t nrLDPC_decoder_core(int8_t* p_llr, int8_t* p_out, uint32_
|
||||
nrLDPC_debug_writeBuffer2File(nrLDPC_buffers_CN_PROC, cnProcBuf);
|
||||
#endif
|
||||
|
||||
// Parity Check
|
||||
// Parity Check
|
||||
#ifdef NR_LDPC_ENABLE_PARITY_CHECK
|
||||
#ifdef NR_LDPC_PROFILER_DETAIL
|
||||
start_meas(&p_profiler->cnProcPc);
|
||||
start_meas(&p_profiler->cnProcPc);
|
||||
#endif
|
||||
if (BG == 1)
|
||||
{
|
||||
pcRes = nrLDPC_cnProcPc_BG1(p_lut, cnProcBuf, cnProcBufRes, Z);
|
||||
}
|
||||
else
|
||||
{
|
||||
pcRes = nrLDPC_cnProcPc_BG2(p_lut, cnProcBuf, cnProcBufRes, Z);
|
||||
}
|
||||
if (BG == 1) pcRes = nrLDPC_cnProcPc_BG1(p_lut, cnProcBuf, cnProcBufRes, Z);
|
||||
else pcRes = nrLDPC_cnProcPc_BG2(p_lut, cnProcBuf, cnProcBufRes, Z);
|
||||
#ifdef NR_LDPC_PROFILER_DETAIL
|
||||
stop_meas(&p_profiler->cnProcPc);
|
||||
stop_meas(&p_profiler->cnProcPc);
|
||||
#endif
|
||||
#endif
|
||||
}
|
||||
|
||||
// If maximum number of iterations reached an PC still fails increase number of iterations
|
||||
// Thus, i > numMaxIter indicates that PC has failed
|
||||
|
||||
#ifdef NR_LDPC_ENABLE_PARITY_CHECK
|
||||
if (pcRes != 0)
|
||||
{
|
||||
i++;
|
||||
}
|
||||
#endif
|
||||
} // end while
|
||||
|
||||
// Last iteration
|
||||
if (pcRes != 0) i++;
|
||||
// Assign results from processing buffer to output
|
||||
#ifdef NR_LDPC_PROFILER_DETAIL
|
||||
start_meas(&p_profiler->llrRes2llrOut);
|
||||
start_meas(&p_profiler->llrRes2llrOut);
|
||||
#endif
|
||||
nrLDPC_llrRes2llrOut(p_lut, p_llrOut, llrRes, Z, BG);
|
||||
nrLDPC_llrRes2llrOut(p_lut, p_llrOut, llrRes, Z, BG);
|
||||
#ifdef NR_LDPC_PROFILER_DETAIL
|
||||
stop_meas(&p_profiler->llrRes2llrOut);
|
||||
stop_meas(&p_profiler->llrRes2llrOut);
|
||||
#endif
|
||||
|
||||
// Hard-decision
|
||||
#ifdef NR_LDPC_PROFILER_DETAIL
|
||||
start_meas(&p_profiler->llr2bit);
|
||||
start_meas(&p_profiler->llr2bit);
|
||||
#endif
|
||||
if (outMode == nrLDPC_outMode_BIT)
|
||||
{
|
||||
nrLDPC_llr2bitPacked(p_out, p_llrOut, numLLR);
|
||||
}
|
||||
else if (outMode == nrLDPC_outMode_BITINT8)
|
||||
{
|
||||
nrLDPC_llr2bit(p_out, p_llrOut, numLLR);
|
||||
}
|
||||
|
||||
if (outMode == nrLDPC_outMode_BIT) nrLDPC_llr2bitPacked(p_out, p_llrOut, numLLR);
|
||||
else //if (outMode == nrLDPC_outMode_BITINT8)
|
||||
nrLDPC_llr2bit(p_out, p_llrOut, numLLR);
|
||||
#ifdef NR_LDPC_PROFILER_DETAIL
|
||||
stop_meas(&p_profiler->llr2bit);
|
||||
#endif
|
||||
|
||||
return i;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -0,0 +1,83 @@
|
||||
/*
|
||||
* Licensed to the OpenAirInterface (OAI) Software Alliance under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright ownership.
|
||||
* The OpenAirInterface Software Alliance licenses this file to You under
|
||||
* the OAI Public License, Version 1.1 (the "License"); you may not use this file
|
||||
* except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.openairinterface.org/?page_id=698
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*-------------------------------------------------------------------------------
|
||||
* For more information about the OpenAirInterface (OAI) Software Alliance:
|
||||
* contact@openairinterface.org
|
||||
*/
|
||||
|
||||
/*!\file nrLDPC_init_mem.h
|
||||
* \brief Defines the function to initialize the LDPC decoder and sets correct LUTs.
|
||||
* \author Sebastian Wagner (TCL Communications) Email: <mailto:sebastian.wagner@tcl.com>
|
||||
* \date 07-12-2018
|
||||
* \version 1.0
|
||||
* \note
|
||||
* \warning
|
||||
*/
|
||||
|
||||
#ifndef __NR_LDPC_INIT_MEM__H__
|
||||
#define __NR_LDPC_INIT_MEM__H__
|
||||
|
||||
#include <stdlib.h>
|
||||
#include "nrLDPC_types.h"
|
||||
|
||||
/**
|
||||
\brief Allocates 32 byte aligned memory and initializes to zero
|
||||
\param size Input size in bytes
|
||||
\return Pointer to memory
|
||||
*/
|
||||
static inline void* malloc32_clear(size_t size)
|
||||
{
|
||||
void* ptr = (void*) memalign(64, size+64);
|
||||
memset(ptr, 0, size);
|
||||
return ptr;
|
||||
}
|
||||
|
||||
/**
|
||||
\brief Allocates and initializes the internal decoder processing buffers
|
||||
\param p_decParams Pointer to decoder parameters
|
||||
\param p_lut Pointer to decoder LUTs
|
||||
\return Number of LLR values
|
||||
*/
|
||||
static inline t_nrLDPC_procBuf* nrLDPC_init_mem(void)
|
||||
{
|
||||
t_nrLDPC_procBuf* p_procBuf = (t_nrLDPC_procBuf*) malloc32_clear(sizeof(t_nrLDPC_procBuf));
|
||||
|
||||
if (p_procBuf)
|
||||
{
|
||||
p_procBuf->cnProcBuf = (int8_t*) malloc32_clear(NR_LDPC_SIZE_CN_PROC_BUF*sizeof(int8_t));
|
||||
p_procBuf->cnProcBufRes = (int8_t*) malloc32_clear(NR_LDPC_SIZE_CN_PROC_BUF*sizeof(int8_t));
|
||||
p_procBuf->bnProcBuf = (int8_t*) malloc32_clear(NR_LDPC_SIZE_BN_PROC_BUF*sizeof(int8_t));
|
||||
p_procBuf->bnProcBufRes = (int8_t*) malloc32_clear(NR_LDPC_SIZE_BN_PROC_BUF*sizeof(int8_t));
|
||||
p_procBuf->llrRes = (int8_t*) malloc32_clear(NR_LDPC_MAX_NUM_LLR *sizeof(int8_t));
|
||||
p_procBuf->llrProcBuf = (int8_t*) malloc32_clear(NR_LDPC_MAX_NUM_LLR *sizeof(int8_t));
|
||||
}
|
||||
|
||||
return(p_procBuf);
|
||||
}
|
||||
|
||||
static inline void nrLDPC_free_mem(t_nrLDPC_procBuf* p_procBuf)
|
||||
{
|
||||
free(p_procBuf->cnProcBuf);
|
||||
free(p_procBuf->cnProcBufRes);
|
||||
free(p_procBuf->bnProcBuf);
|
||||
free(p_procBuf->bnProcBufRes);
|
||||
free(p_procBuf->llrRes);
|
||||
free(p_procBuf->llrProcBuf);
|
||||
|
||||
free(p_procBuf);
|
||||
}
|
||||
#endif
|
||||
@@ -21,21 +21,16 @@
|
||||
|
||||
/*!\file nrLDPC_mPass.h
|
||||
* \brief Defines the functions for message passing
|
||||
* \author Sebastian Wagner (TCL Communications) Email: <mailto:sebastian.wagner@tcl.com>
|
||||
* \date 30-09-2019
|
||||
* \version 2.0
|
||||
* \note
|
||||
* \warning
|
||||
*/
|
||||
|
||||
*
|
||||
*/
|
||||
#ifndef __NR_LDPC_MPASS__H__
|
||||
#define __NR_LDPC_MPASS__H__
|
||||
|
||||
#include <string.h>
|
||||
#include "nrLDPCdecoder_defs.h"
|
||||
|
||||
//#include <omp.h>
|
||||
/**
|
||||
\brief Circular memcpy
|
||||
\brief Circular memcpy1
|
||||
|<- rem->|<- circular shift ->|
|
||||
(src) str2 = |--------xxxxxxxxxxxxxxxxxxxxx|
|
||||
\_______________
|
||||
@@ -46,6 +41,7 @@
|
||||
\param Z Lifting size
|
||||
\param cshift Circular shift
|
||||
*/
|
||||
|
||||
static inline void *nrLDPC_inv_circ_memcpy(int8_t *str1, const int8_t *str2, uint16_t Z, uint16_t cshift)
|
||||
{
|
||||
uint16_t rem = Z - cshift;
|
||||
@@ -169,6 +165,8 @@ static inline void nrLDPC_llr2CnProcBuf_BG1(t_nrLDPC_lut* p_lut, int8_t* llr, in
|
||||
|
||||
bitOffsetInGroup = lut_numCnInCnGroups_BG1_R13[0]*NR_LDPC_ZMAX;
|
||||
|
||||
|
||||
|
||||
for (j=0; j<3; j++)
|
||||
{
|
||||
p_cnProcBuf = &cnProcBuf[lut_startAddrCnGroups[0] + j*bitOffsetInGroup];
|
||||
@@ -200,8 +198,10 @@ static inline void nrLDPC_llr2CnProcBuf_BG1(t_nrLDPC_lut* p_lut, int8_t* llr, in
|
||||
// =====================================================================
|
||||
// CN group with 5 BNs
|
||||
|
||||
|
||||
bitOffsetInGroup = lut_numCnInCnGroups_BG1_R13[2]*NR_LDPC_ZMAX;
|
||||
|
||||
|
||||
for (j=0; j<5; j++)
|
||||
{
|
||||
p_cnProcBuf = &cnProcBuf[lut_startAddrCnGroups[2] + j*bitOffsetInGroup];
|
||||
@@ -234,8 +234,10 @@ static inline void nrLDPC_llr2CnProcBuf_BG1(t_nrLDPC_lut* p_lut, int8_t* llr, in
|
||||
// =====================================================================
|
||||
// CN group with 7 BNs
|
||||
|
||||
|
||||
bitOffsetInGroup = lut_numCnInCnGroups_BG1_R13[4]*NR_LDPC_ZMAX;
|
||||
|
||||
|
||||
for (j=0; j<7; j++)
|
||||
{
|
||||
p_cnProcBuf = &cnProcBuf[lut_startAddrCnGroups[4] + j*bitOffsetInGroup];
|
||||
@@ -253,6 +255,7 @@ static inline void nrLDPC_llr2CnProcBuf_BG1(t_nrLDPC_lut* p_lut, int8_t* llr, in
|
||||
|
||||
bitOffsetInGroup = lut_numCnInCnGroups_BG1_R13[5]*NR_LDPC_ZMAX;
|
||||
|
||||
|
||||
for (j=0; j<8; j++)
|
||||
{
|
||||
p_cnProcBuf = &cnProcBuf[lut_startAddrCnGroups[5] + j*bitOffsetInGroup];
|
||||
@@ -302,6 +305,7 @@ static inline void nrLDPC_llr2CnProcBuf_BG1(t_nrLDPC_lut* p_lut, int8_t* llr, in
|
||||
// =====================================================================
|
||||
// CN group with 19 BNs
|
||||
|
||||
|
||||
bitOffsetInGroup = lut_numCnInCnGroups_BG1_R13[8]*NR_LDPC_ZMAX;
|
||||
|
||||
for (j=0; j<19; j++)
|
||||
@@ -1007,18 +1011,18 @@ static inline void nrLDPC_bn2cnProcBuf_BG1(t_nrLDPC_lut* p_lut, int8_t* bnProcBu
|
||||
// CN group with 4 BNs
|
||||
|
||||
bitOffsetInGroup = lut_numCnInCnGroups_BG1_R13[1]*NR_LDPC_ZMAX;
|
||||
|
||||
|
||||
for (j=0; j<3; j++)
|
||||
{
|
||||
p_cnProcBuf = &cnProcBuf[lut_startAddrCnGroups[1] + j*bitOffsetInGroup];
|
||||
|
||||
for (i=0; i<lut_numCnInCnGroups[1]; i++)
|
||||
{
|
||||
idxBn = lut_startAddrBnProcBuf_CNG4[j][i] + lut_bnPosBnProcBuf_CNG4[j][i]*Z;
|
||||
nrLDPC_circ_memcpy(p_cnProcBuf, &bnProcBufRes[idxBn], Z, lut_circShift_CNG4[j][i]);
|
||||
p_cnProcBuf += Z;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// =====================================================================
|
||||
// CN group with 5 BNs
|
||||
|
||||
@@ -1027,6 +1031,7 @@ static inline void nrLDPC_bn2cnProcBuf_BG1(t_nrLDPC_lut* p_lut, int8_t* bnProcBu
|
||||
for (j=0; j<4; j++)
|
||||
{
|
||||
p_cnProcBuf = &cnProcBuf[lut_startAddrCnGroups[2] + j*bitOffsetInGroup];
|
||||
|
||||
for (i=0; i<lut_numCnInCnGroups[2]; i++)
|
||||
{
|
||||
idxBn = lut_startAddrBnProcBuf_CNG5[j][i] + lut_bnPosBnProcBuf_CNG5[j][i]*Z;
|
||||
@@ -1039,10 +1044,11 @@ static inline void nrLDPC_bn2cnProcBuf_BG1(t_nrLDPC_lut* p_lut, int8_t* bnProcBu
|
||||
// CN group with 6 BNs
|
||||
|
||||
bitOffsetInGroup = lut_numCnInCnGroups_BG1_R13[3]*NR_LDPC_ZMAX;
|
||||
|
||||
|
||||
for (j=0; j<5; j++)
|
||||
{
|
||||
p_cnProcBuf = &cnProcBuf[lut_startAddrCnGroups[3] + j*bitOffsetInGroup];
|
||||
|
||||
for (i=0; i<lut_numCnInCnGroups[3]; i++)
|
||||
{
|
||||
idxBn = lut_startAddrBnProcBuf_CNG6[j][i] + lut_bnPosBnProcBuf_CNG6[j][i]*Z;
|
||||
@@ -1055,11 +1061,12 @@ static inline void nrLDPC_bn2cnProcBuf_BG1(t_nrLDPC_lut* p_lut, int8_t* bnProcBu
|
||||
// CN group with 7 BNs
|
||||
|
||||
bitOffsetInGroup = lut_numCnInCnGroups_BG1_R13[4]*NR_LDPC_ZMAX;
|
||||
|
||||
|
||||
for (j=0; j<6; j++)
|
||||
{
|
||||
p_cnProcBuf = &cnProcBuf[lut_startAddrCnGroups[4] + j*bitOffsetInGroup];
|
||||
|
||||
|
||||
for (i=0; i<lut_numCnInCnGroups[4]; i++)
|
||||
{
|
||||
idxBn = lut_startAddrBnProcBuf_CNG7[j][i] + lut_bnPosBnProcBuf_CNG7[j][i]*Z;
|
||||
@@ -1092,6 +1099,7 @@ static inline void nrLDPC_bn2cnProcBuf_BG1(t_nrLDPC_lut* p_lut, int8_t* bnProcBu
|
||||
for (j=0; j<8; j++)
|
||||
{
|
||||
p_cnProcBuf = &cnProcBuf[lut_startAddrCnGroups[6] + j*bitOffsetInGroup];
|
||||
|
||||
for (i=0; i<lut_numCnInCnGroups[6]; i++)
|
||||
{
|
||||
idxBn = lut_startAddrBnProcBuf_CNG9[j][i] + lut_bnPosBnProcBuf_CNG9[j][i]*Z;
|
||||
@@ -1104,10 +1112,11 @@ static inline void nrLDPC_bn2cnProcBuf_BG1(t_nrLDPC_lut* p_lut, int8_t* bnProcBu
|
||||
// CN group with 10 BNs
|
||||
|
||||
bitOffsetInGroup = lut_numCnInCnGroups_BG1_R13[7]*NR_LDPC_ZMAX;
|
||||
|
||||
|
||||
for (j=0; j<9; j++)
|
||||
{
|
||||
p_cnProcBuf = &cnProcBuf[lut_startAddrCnGroups[7] + j*bitOffsetInGroup];
|
||||
|
||||
for (i=0; i<lut_numCnInCnGroups[7]; i++)
|
||||
{
|
||||
idxBn = lut_startAddrBnProcBuf_CNG10[j][i] + lut_bnPosBnProcBuf_CNG10[j][i]*Z;
|
||||
@@ -1120,10 +1129,11 @@ static inline void nrLDPC_bn2cnProcBuf_BG1(t_nrLDPC_lut* p_lut, int8_t* bnProcBu
|
||||
// CN group with 19 BNs
|
||||
|
||||
bitOffsetInGroup = lut_numCnInCnGroups_BG1_R13[8]*NR_LDPC_ZMAX;
|
||||
|
||||
|
||||
for (j=0; j<19; j++)
|
||||
{
|
||||
p_cnProcBuf = &cnProcBuf[lut_startAddrCnGroups[8] + j*bitOffsetInGroup];
|
||||
|
||||
for (i=0; i<lut_numCnInCnGroups[8]; i++)
|
||||
{
|
||||
idxBn = lut_startAddrBnProcBuf_CNG19[j][i] + lut_bnPosBnProcBuf_CNG19[j][i]*Z;
|
||||
@@ -1172,3 +1182,7 @@ static inline void nrLDPC_llrRes2llrOut(t_nrLDPC_lut* p_lut, int8_t* llrOut, int
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -0,0 +1,19 @@
|
||||
add_subdirectory(${CMAKE_CURRENT_LIST_DIR}/generator_bnProc ldpc/generator_bnProc)
|
||||
add_subdirectory(${CMAKE_CURRENT_LIST_DIR}/generator_bnProc_avx512 ldpc/generator_bnProc_avx512)
|
||||
add_subdirectory(${CMAKE_CURRENT_LIST_DIR}/generator_cnProc ldpc/generator_cnProc)
|
||||
add_subdirectory(${CMAKE_CURRENT_LIST_DIR}/generator_cnProc_avx512 ldpc/generator_cnProc_avx512)
|
||||
|
||||
# custom target to build all generators
|
||||
add_custom_target(ldpc_generators)
|
||||
add_dependencies(ldpc_generators
|
||||
bnProc_gen_avx2
|
||||
bnProc_gen_avx512
|
||||
cnProc_gen_avx2
|
||||
cnProc_gen_avx512)
|
||||
|
||||
add_library(ldpc_gen_HEADERS INTERFACE)
|
||||
target_link_libraries(ldpc_gen_HEADERS INTERFACE
|
||||
bnProc_gen_avx2_HEADERS
|
||||
bnProc_gen_avx512_HEADERS
|
||||
cnProc_gen_avx2_HEADERS
|
||||
cnProc_gen_avx512_HEADERS)
|
||||
@@ -0,0 +1,36 @@
|
||||
add_executable(bnProc_gen_avx2
|
||||
bnProc_gen_BG1_avx2.c
|
||||
bnProc_gen_BG2_avx2.c
|
||||
bnProcPc_gen_BG1_avx2.c
|
||||
bnProcPc_gen_BG2_avx2.c
|
||||
main.c)
|
||||
target_compile_options(bnProc_gen_avx2 PRIVATE -W -Wall -mavx2)
|
||||
|
||||
#set(bnProc_headers
|
||||
# bnProc/nrLDPC_bnProc_BG1_R13_AVX2.h
|
||||
# bnProc/nrLDPC_bnProc_BG1_R23_AVX2.h
|
||||
# bnProc/nrLDPC_bnProc_BG1_R89_AVX2.h
|
||||
# bnProc/rLDPC_bnProc_BG2_R13_AVX2.h
|
||||
# bnProc/rLDPC_bnProc_BG2_R15_AVX2.h
|
||||
# bnProc/rLDPC_bnProc_BG2_R23_AVX2.h)
|
||||
#
|
||||
#set(bnProcPc_headers
|
||||
# bnProcPc/rLDPC_bnProcPc_BG1_R13_AVX2.h
|
||||
# bnProcPc/rLDPC_bnProcPc_BG1_R23_AVX2.h
|
||||
# bnProcPc/rLDPC_bnProcPc_BG1_R89_AVX2.h
|
||||
# bnProcPc/rLDPC_bnProcPc_BG2_R13_AVX2.h
|
||||
# bnProcPc/rLDPC_bnProcPc_BG2_R15_AVX2.h
|
||||
# bnProcPc/rLDPC_bnProcPc_BG2_R23_AVX2.h)
|
||||
|
||||
add_custom_command(TARGET bnProc_gen_avx2 POST_BUILD
|
||||
#OUTPUT ${bnProc_headers} ${bnProcPc_headers}
|
||||
COMMAND ${CMAKE_COMMAND} -E make_directory bnProc
|
||||
COMMAND ${CMAKE_COMMAND} -E make_directory bnProcPc
|
||||
COMMAND bnProc_gen_avx2 .
|
||||
DEPENDS bnProc_gen_avx2
|
||||
COMMENT "Generating LDPC bnProc header files for AVX2"
|
||||
)
|
||||
|
||||
add_library(bnProc_gen_avx2_HEADERS INTERFACE)
|
||||
target_include_directories(bnProc_gen_avx2_HEADERS INTERFACE ${CMAKE_CURRENT_BINARY_DIR})
|
||||
add_dependencies(bnProc_gen_avx2_HEADERS bnProc_gen_avx2)
|
||||
+1789
File diff suppressed because it is too large
Load Diff
+1789
File diff suppressed because it is too large
Load Diff
+1112
File diff suppressed because it is too large
Load Diff
+1108
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,55 @@
|
||||
/*
|
||||
* Licensed to the OpenAirInterface (OAI) Software Alliance under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright ownership.
|
||||
* The OpenAirInterface Software Alliance licenses this file to You under
|
||||
* the OAI Public License, Version 1.1 (the "License"); you may not use this file
|
||||
* except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.openairinterface.org/?page_id=698
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*-------------------------------------------------------------------------------
|
||||
* For more information about the OpenAirInterface (OAI) Software Alliance:
|
||||
* contact@openairinterface.org
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdint.h>
|
||||
#define NB_R 3
|
||||
void nrLDPC_bnProc_BG1_generator_AVX2(const char*, int);
|
||||
void nrLDPC_bnProc_BG2_generator_AVX2(const char*, int);
|
||||
void nrLDPC_bnProcPc_BG1_generator_AVX2(const char*, int);
|
||||
void nrLDPC_bnProcPc_BG2_generator_AVX2(const char*, int);
|
||||
|
||||
const char *__asan_default_options()
|
||||
{
|
||||
/* don't do leak checking in nr_ulsim, creates problems in the CI */
|
||||
return "detect_leaks=0";
|
||||
}
|
||||
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
if (argc != 2) {
|
||||
fprintf(stderr, "usage: %s <output-dir>\n", argv[0]);
|
||||
return 1;
|
||||
}
|
||||
const char *dir = argv[1];
|
||||
|
||||
int R[NB_R]={0,1,2};
|
||||
for(int i=0; i<NB_R;i++){
|
||||
nrLDPC_bnProc_BG1_generator_AVX2(dir, R[i]);
|
||||
nrLDPC_bnProc_BG2_generator_AVX2(dir, R[i]);
|
||||
|
||||
nrLDPC_bnProcPc_BG1_generator_AVX2(dir, R[i]);
|
||||
nrLDPC_bnProcPc_BG2_generator_AVX2(dir, R[i]);
|
||||
}
|
||||
|
||||
return(0);
|
||||
}
|
||||
|
||||
+36
@@ -0,0 +1,36 @@
|
||||
add_executable(bnProc_gen_avx512
|
||||
bnProc_gen_BG1_avx512.c
|
||||
bnProc_gen_BG2_avx512.c
|
||||
bnProcPc_gen_BG1_avx512.c
|
||||
bnProcPc_gen_BG2_avx512.c
|
||||
main.c)
|
||||
target_compile_options(bnProc_gen_avx512 PRIVATE -W -Wall -mavx2)
|
||||
|
||||
#set(bnProc_avx512_headers
|
||||
# bnProc_avx512/rLDPC_bnProc_BG1_R13_AVX512.h
|
||||
# bnProc_avx512/rLDPC_bnProc_BG1_R23_AVX512.h
|
||||
# bnProc_avx512/rLDPC_bnProc_BG1_R89_AVX512.h
|
||||
# bnProc_avx512/rLDPC_bnProc_BG2_R13_AVX512.h
|
||||
# bnProc_avx512/rLDPC_bnProc_BG2_R15_AVX512.h
|
||||
# bnProc_avx512/rLDPC_bnProc_BG2_R23_AVX512.h)
|
||||
#
|
||||
#set(bnProcPc_avx512_headers
|
||||
# bnProcPc_avx512/rLDPC_bnProcPc_BG1_R13_AVX512.h
|
||||
# bnProcPc_avx512/rLDPC_bnProcPc_BG1_R23_AVX512.h
|
||||
# bnProcPc_avx512/rLDPC_bnProcPc_BG1_R89_AVX512.h
|
||||
# bnProcPc_avx512/rLDPC_bnProcPc_BG2_R13_AVX512.h
|
||||
# bnProcPc_avx512/rLDPC_bnProcPc_BG2_R15_AVX512.h
|
||||
# bnProcPc_avx512/rLDPC_bnProcPc_BG2_R23_AVX512.h)
|
||||
|
||||
add_custom_command(TARGET bnProc_gen_avx512 POST_BUILD
|
||||
#OUTPUT ${bnProc_avx512_headers} ${bnProcPc_avx512_headers}
|
||||
COMMAND ${CMAKE_COMMAND} -E make_directory bnProc_avx512
|
||||
COMMAND ${CMAKE_COMMAND} -E make_directory bnProcPc_avx512
|
||||
COMMAND bnProc_gen_avx512 .
|
||||
DEPENDS bnProc_gen_avx512
|
||||
COMMENT "Generating LDPC bnProc header files for AVX512"
|
||||
)
|
||||
|
||||
add_library(bnProc_gen_avx512_HEADERS INTERFACE)
|
||||
target_include_directories(bnProc_gen_avx512_HEADERS INTERFACE ${CMAKE_CURRENT_BINARY_DIR})
|
||||
add_dependencies(bnProc_gen_avx512_HEADERS bnProc_gen_avx512)
|
||||
+1790
File diff suppressed because it is too large
Load Diff
+1793
File diff suppressed because it is too large
Load Diff
+1112
File diff suppressed because it is too large
Load Diff
+1108
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,56 @@
|
||||
/*
|
||||
* Licensed to the OpenAirInterface (OAI) Software Alliance under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright ownership.
|
||||
* The OpenAirInterface Software Alliance licenses this file to You under
|
||||
* the OAI Public License, Version 1.1 (the "License"); you may not use this file
|
||||
* except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.openairinterface.org/?page_id=698
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*-------------------------------------------------------------------------------
|
||||
* For more information about the OpenAirInterface (OAI) Software Alliance:
|
||||
* contact@openairinterface.org
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdint.h>
|
||||
#include <stdlib.h>
|
||||
#define NB_R 3
|
||||
void nrLDPC_bnProc_BG1_generator_AVX512(const char *, int);
|
||||
void nrLDPC_bnProc_BG2_generator_AVX512(const char *, int);
|
||||
void nrLDPC_bnProcPc_BG1_generator_AVX512(const char *, int);
|
||||
void nrLDPC_bnProcPc_BG2_generator_AVX512(const char *, int);
|
||||
|
||||
const char *__asan_default_options()
|
||||
{
|
||||
/* don't do leak checking in nr_ulsim, creates problems in the CI */
|
||||
return "detect_leaks=0";
|
||||
}
|
||||
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
if (argc != 2) {
|
||||
fprintf(stderr, "usage: %s <output-dir>\n", argv[0]);
|
||||
return 1;
|
||||
}
|
||||
const char *dir = argv[1];
|
||||
|
||||
int R[NB_R]={0,1,2};
|
||||
for(int i=0; i<NB_R;i++){
|
||||
nrLDPC_bnProc_BG1_generator_AVX512(dir, R[i]);
|
||||
nrLDPC_bnProc_BG2_generator_AVX512(dir, R[i]);
|
||||
|
||||
nrLDPC_bnProcPc_BG1_generator_AVX512(dir, R[i]);
|
||||
nrLDPC_bnProcPc_BG2_generator_AVX512(dir, R[i]);
|
||||
}
|
||||
|
||||
return(0);
|
||||
}
|
||||
|
||||
@@ -0,0 +1,25 @@
|
||||
add_executable(cnProc_gen_avx2
|
||||
cnProc_gen_BG1_avx2.c
|
||||
cnProc_gen_BG2_avx2.c
|
||||
main.c)
|
||||
target_compile_options(cnProc_gen_avx2 PRIVATE -W -Wall -mavx2)
|
||||
|
||||
#set(cnProc_headers
|
||||
# cnProc/rLDPC_cnProc_BG1_R13_AVX2.h
|
||||
# cnProc/rLDPC_cnProc_BG1_R23_AVX2.h
|
||||
# cnProc/rLDPC_cnProc_BG1_R89_AVX2.h
|
||||
# cnProc/rLDPC_cnProc_BG2_R13_AVX2.h
|
||||
# cnProc/rLDPC_cnProc_BG2_R15_AVX2.h
|
||||
# cnProc/rLDPC_cnProc_BG2_R23_AVX2.h)
|
||||
|
||||
add_custom_command(TARGET cnProc_gen_avx2 POST_BUILD
|
||||
#OUTPUT ${cnProc_headers}
|
||||
COMMAND ${CMAKE_COMMAND} -E make_directory cnProc
|
||||
COMMAND cnProc_gen_avx2 .
|
||||
DEPENDS cnProc_gen_avx2
|
||||
COMMENT "Generating LDPC cnProc header files for AVX2"
|
||||
)
|
||||
|
||||
add_library(cnProc_gen_avx2_HEADERS INTERFACE)
|
||||
target_include_directories(cnProc_gen_avx2_HEADERS INTERFACE ${CMAKE_CURRENT_BINARY_DIR})
|
||||
add_dependencies(cnProc_gen_avx2_HEADERS cnProc_gen_avx2)
|
||||
+693
@@ -0,0 +1,693 @@
|
||||
/*
|
||||
* Licensed to the OpenAirInterface (OAI) Software Alliance under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright ownership.
|
||||
* The OpenAirInterface Software Alliance licenses this file to You under
|
||||
* the OAI Public License, Version 1.1 (the "License"); you may not use this file
|
||||
* except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.openairinterface.org/?page_id=698
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*-------------------------------------------------------------------------------
|
||||
* For more information about the OpenAirInterface (OAI) Software Alliance:
|
||||
* contact@openairinterface.org
|
||||
*/
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include <stdint.h>
|
||||
#include "../../nrLDPCdecoder_defs.h"
|
||||
|
||||
void nrLDPC_cnProc_BG1_generator_AVX2(const char* dir, int R)
|
||||
{
|
||||
const char *ratestr[3]={"13","23","89"};
|
||||
|
||||
if (R<0 || R>2) {printf("Illegal R %d\n",R); abort();}
|
||||
|
||||
|
||||
// system("mkdir -p ../ldpc_gen_files");
|
||||
|
||||
char fname[FILENAME_MAX+1];
|
||||
snprintf(fname, sizeof(fname), "%s/cnProc/nrLDPC_cnProc_BG1_R%s_AVX2.h", dir, ratestr[R]);
|
||||
FILE *fd=fopen(fname,"w");
|
||||
if (fd == NULL) {
|
||||
printf("Cannot create file %s\n", fname);
|
||||
abort();
|
||||
}
|
||||
|
||||
fprintf(fd,"#include <stdint.h>\n");
|
||||
fprintf(fd,"#include <immintrin.h>\n");
|
||||
|
||||
|
||||
fprintf(fd,"static inline void nrLDPC_cnProc_BG1_R%s_AVX2(int8_t* cnProcBuf, int8_t* cnProcBufRes, uint16_t Z) {\n",ratestr[R]);
|
||||
|
||||
const uint8_t* lut_numCnInCnGroups;
|
||||
const uint32_t* lut_startAddrCnGroups = lut_startAddrCnGroups_BG1;
|
||||
|
||||
if (R==0) lut_numCnInCnGroups = lut_numCnInCnGroups_BG1_R13;
|
||||
else if (R==1) lut_numCnInCnGroups = lut_numCnInCnGroups_BG1_R23;
|
||||
else if (R==2) lut_numCnInCnGroups = lut_numCnInCnGroups_BG1_R89;
|
||||
else { printf("aborting, illegal R %d\n",R); fclose(fd);abort();}
|
||||
|
||||
|
||||
|
||||
//__m256i* p_cnProcBuf;
|
||||
//__m256i* p_cnProcBufRes;
|
||||
|
||||
// Number of CNs in Groups
|
||||
//uint32_t M;
|
||||
uint32_t j;
|
||||
uint32_t k;
|
||||
// Offset to each bit within a group in terms of 32 Byte
|
||||
uint32_t bitOffsetInGroup;
|
||||
|
||||
//__m256i ymm0, min, sgn;
|
||||
//__m256i* p_cnProcBufResBit;
|
||||
|
||||
// const __m256i* p_ones = (__m256i*) ones256_epi8;
|
||||
// const __m256i* p_maxLLR = (__m256i*) maxLLR256_epi8;
|
||||
|
||||
// LUT with offsets for bits that need to be processed
|
||||
// 1. bit proc requires LLRs of 2. and 3. bit, 2.bits of 1. and 3. etc.
|
||||
// Offsets are in units of bitOffsetInGroup (1*384/32)
|
||||
// const uint8_t lut_idxCnProcG3[3][2] = {{12,24}, {0,24}, {0,12}};
|
||||
|
||||
// =====================================================================
|
||||
// Process group with 3 BNs
|
||||
fprintf(fd,"//Process group with 3 BNs\n");
|
||||
// LUT with offsets for bits that need to be processed
|
||||
// 1. bit proc requires LLRs of 2. and 3. bit, 2.bits of 1. and 3. etc.
|
||||
// Offsets are in units of bitOffsetInGroup (1*384/32)
|
||||
const uint8_t lut_idxCnProcG3[3][2] = {{12,24}, {0,24}, {0,12}};
|
||||
|
||||
fprintf(fd," __m256i ymm0, min, sgn,ones,maxLLR;\n");
|
||||
fprintf(fd," ones = _mm256_set1_epi8((char)1);\n");
|
||||
fprintf(fd," maxLLR = _mm256_set1_epi8((char)127);\n");
|
||||
|
||||
fprintf(fd," uint32_t M;\n");
|
||||
|
||||
if (lut_numCnInCnGroups[0] > 0)
|
||||
{
|
||||
// Number of groups of 32 CNs for parallel processing
|
||||
// Ceil for values not divisible by 32
|
||||
fprintf(fd," M = (%d*Z + 31)>>5;\n",lut_numCnInCnGroups[0] );
|
||||
|
||||
// Set the offset to each bit within a group in terms of 32 Byte
|
||||
bitOffsetInGroup = (lut_numCnInCnGroups_BG1_R13[0]*NR_LDPC_ZMAX)>>5;
|
||||
|
||||
|
||||
// Set pointers to start of group 3
|
||||
//p_cnProcBuf = (__m256i*) &cnProcBuf [lut_startAddrCnGroups[0]];
|
||||
//p_cnProcBufRes = (__m256i*) &cnProcBufRes[lut_startAddrCnGroups[0]];
|
||||
|
||||
// Loop over every BN
|
||||
|
||||
for (j=0; j<3; j++)
|
||||
{
|
||||
// Set of results pointer to correct BN address
|
||||
//p_cnProcBufResBit = p_cnProcBufRes + (j*bitOffsetInGroup);
|
||||
|
||||
// Loop over CNs
|
||||
// for (i=0; i<M; i++,iprime++)
|
||||
// {
|
||||
|
||||
fprintf(fd," for (int i=0;i<M;i++) {\n");
|
||||
// Abs and sign of 32 CNs (first BN)
|
||||
// ymm0 = p_cnProcBuf[lut_idxCnProcG3[j][0] + i];
|
||||
fprintf(fd," ymm0 = ((__m256i*)cnProcBuf)[%d+i];\n",(lut_startAddrCnGroups[0]>>5)+lut_idxCnProcG3[j][0]);
|
||||
// sgn = _mm256_sign_epi8(ones, ymm0);
|
||||
fprintf(fd," sgn = _mm256_sign_epi8(ones, ymm0);\n");
|
||||
// min = _mm256_abs_epi8(ymm0);
|
||||
fprintf(fd," min = _mm256_abs_epi8(ymm0);\n");
|
||||
|
||||
// 32 CNs of second BN
|
||||
// ymm0 = p_cnProcBuf[lut_idxCnProcG3[j][1] + i];
|
||||
fprintf(fd," ymm0 = ((__m256i*)cnProcBuf)[%d+i];\n",(lut_startAddrCnGroups[0]>>5)+lut_idxCnProcG3[j][1]);
|
||||
|
||||
// min = _mm256_min_epu8(min, _mm256_abs_epi8(ymm0));
|
||||
fprintf(fd," min = _mm256_min_epu8(min, _mm256_abs_epi8(ymm0));\n");
|
||||
|
||||
// sgn = _mm256_sign_epi8(sgn, ymm0);
|
||||
fprintf(fd," sgn = _mm256_sign_epi8(sgn, ymm0);\n");
|
||||
|
||||
// Store result
|
||||
// min = _mm256_min_epu8(min, maxLLR); // 128 in epi8 is -127
|
||||
fprintf(fd," min = _mm256_min_epu8(min, maxLLR);\n");
|
||||
// *p_cnProcBufResBit = _mm256_sign_epi8(min, sgn);
|
||||
// p_cnProcBufResBit++;
|
||||
fprintf(fd," ((__m256i*)cnProcBufRes)[%d+i] = _mm256_sign_epi8(min, sgn);\n",(lut_startAddrCnGroups[0]>>5)+(j*bitOffsetInGroup));
|
||||
fprintf(fd," }\n");
|
||||
}
|
||||
}
|
||||
|
||||
// =====================================================================
|
||||
// Process group with 4 BNs
|
||||
fprintf(fd,"//Process group with 4 BNs\n");
|
||||
// Offset is 5*384/32 = 60
|
||||
const uint8_t lut_idxCnProcG4[4][3] = {{60,120,180}, {0,120,180}, {0,60,180}, {0,60,120}};
|
||||
|
||||
if (lut_numCnInCnGroups[1] > 0)
|
||||
{
|
||||
// Number of groups of 32 CNs for parallel processing
|
||||
// Ceil for values not divisible by 32
|
||||
fprintf(fd," M = (%d*Z + 31)>>5;\n",lut_numCnInCnGroups[1] );
|
||||
|
||||
// Set the offset to each bit within a group in terms of 32 Byte
|
||||
bitOffsetInGroup = (lut_numCnInCnGroups_BG1_R13[1]*NR_LDPC_ZMAX)>>5;
|
||||
|
||||
|
||||
// Set pointers to start of group 4
|
||||
//p_cnProcBuf = (__m256i*) &cnProcBuf [lut_startAddrCnGroups[1]];
|
||||
//p_cnProcBufRes = (__m256i*) &cnProcBufRes[lut_startAddrCnGroups[1]];
|
||||
|
||||
// Loop over every BN
|
||||
|
||||
for (j=0; j<4; j++)
|
||||
{
|
||||
// Set of results pointer to correct BN address
|
||||
//p_cnProcBufResBit = p_cnProcBufRes + (j*bitOffsetInGroup);
|
||||
|
||||
// Loop over CNs
|
||||
// for (i=0; i<M; i++,iprime++)
|
||||
// {
|
||||
fprintf(fd," for (int i=0;i<M;i++) {\n");
|
||||
// Abs and sign of 32 CNs (first BN)
|
||||
// ymm0 = p_cnProcBuf[lut_idxCnProcG3[j][0] + i];
|
||||
fprintf(fd," ymm0 = ((__m256i*)cnProcBuf)[%d+i];\n",(lut_startAddrCnGroups[1]>>5)+lut_idxCnProcG4[j][0]);
|
||||
// sgn = _mm256_sign_epi8(ones, ymm0);
|
||||
fprintf(fd," sgn = _mm256_sign_epi8(ones, ymm0);\n");
|
||||
// min = _mm256_abs_epi8(ymm0);
|
||||
fprintf(fd," min = _mm256_abs_epi8(ymm0);\n");
|
||||
|
||||
|
||||
// Loop over BNs
|
||||
for (k=1; k<3; k++)
|
||||
{
|
||||
fprintf(fd," ymm0 = ((__m256i*)cnProcBuf)[%d+i];\n",(lut_startAddrCnGroups[1]>>5)+lut_idxCnProcG4[j][k]);
|
||||
|
||||
// min = _mm256_min_epu8(min, _mm256_abs_epi8(ymm0));
|
||||
fprintf(fd," min = _mm256_min_epu8(min, _mm256_abs_epi8(ymm0));\n");
|
||||
|
||||
// sgn = _mm256_sign_epi8(sgn, ymm0);
|
||||
fprintf(fd," sgn = _mm256_sign_epi8(sgn, ymm0);\n");
|
||||
}
|
||||
|
||||
// Store result
|
||||
// min = _mm256_min_epu8(min, maxLLR); // 128 in epi8 is -127
|
||||
fprintf(fd," min = _mm256_min_epu8(min, maxLLR);\n");
|
||||
// *p_cnProcBufResBit = _mm256_sign_epi8(min, sgn);
|
||||
// p_cnProcBufResBit++;
|
||||
fprintf(fd," ((__m256i*)cnProcBufRes)[%d+i] = _mm256_sign_epi8(min, sgn);\n",(lut_startAddrCnGroups[1]>>5)+(j*bitOffsetInGroup));
|
||||
fprintf(fd," }\n");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// =====================================================================
|
||||
// Process group with 5 BNs
|
||||
fprintf(fd,"//Process group with 5 BNs\n");
|
||||
// Offset is 18*384/32 = 216
|
||||
const uint16_t lut_idxCnProcG5[5][4] = {{216,432,648,864}, {0,432,648,864},
|
||||
{0,216,648,864}, {0,216,432,864}, {0,216,432,648}};
|
||||
|
||||
|
||||
if (lut_numCnInCnGroups[2] > 0)
|
||||
{
|
||||
// Number of groups of 32 CNs for parallel processing
|
||||
// Ceil for values not divisible by 32
|
||||
fprintf(fd," M = (%d*Z + 31)>>5;\n",lut_numCnInCnGroups[2] );
|
||||
|
||||
// Set the offset to each bit within a group in terms of 32 Byte
|
||||
bitOffsetInGroup = (lut_numCnInCnGroups_BG1_R13[2]*NR_LDPC_ZMAX)>>5;
|
||||
|
||||
|
||||
// Set pointers to start of group 4
|
||||
//p_cnProcBuf = (__m256i*) &cnProcBuf [lut_startAddrCnGroups[1]];
|
||||
//p_cnProcBufRes = (__m256i*) &cnProcBufRes[lut_startAddrCnGroups[1]];
|
||||
|
||||
// Loop over every BN
|
||||
|
||||
for (j=0; j<5; j++)
|
||||
{
|
||||
// Set of results pointer to correct BN address
|
||||
//p_cnProcBufResBit = p_cnProcBufRes + (j*bitOffsetInGroup);
|
||||
|
||||
// Loop over CNs
|
||||
// for (i=0; i<M; i++,iprime++)
|
||||
// {
|
||||
fprintf(fd," for (int i=0;i<M;i++) {\n");
|
||||
// Abs and sign of 32 CNs (first BN)
|
||||
// ymm0 = p_cnProcBuf[lut_idxCnProcG3[j][0] + i];
|
||||
fprintf(fd," ymm0 = ((__m256i*)cnProcBuf)[%d+i];\n",(lut_startAddrCnGroups[2]>>5)+lut_idxCnProcG5[j][0]);
|
||||
// sgn = _mm256_sign_epi8(ones, ymm0);
|
||||
fprintf(fd," sgn = _mm256_sign_epi8(ones, ymm0);\n");
|
||||
// min = _mm256_abs_epi8(ymm0);
|
||||
fprintf(fd," min = _mm256_abs_epi8(ymm0);\n");
|
||||
|
||||
|
||||
// Loop over BNs
|
||||
for (k=1; k<4; k++)
|
||||
{
|
||||
fprintf(fd," ymm0 = ((__m256i*)cnProcBuf)[%d+i];\n",(lut_startAddrCnGroups[2]>>5)+lut_idxCnProcG5[j][k]);
|
||||
|
||||
// min = _mm256_min_epu8(min, _mm256_abs_epi8(ymm0));
|
||||
fprintf(fd," min = _mm256_min_epu8(min, _mm256_abs_epi8(ymm0));\n");
|
||||
|
||||
// sgn = _mm256_sign_epi8(sgn, ymm0);
|
||||
fprintf(fd," sgn = _mm256_sign_epi8(sgn, ymm0);\n");
|
||||
}
|
||||
|
||||
// Store result
|
||||
// min = _mm256_min_epu8(min, maxLLR); // 128 in epi8 is -127
|
||||
fprintf(fd," min = _mm256_min_epu8(min, maxLLR);\n");
|
||||
// *p_cnProcBufResBit = _mm256_sign_epi8(min, sgn);
|
||||
// p_cnProcBufResBit++;
|
||||
fprintf(fd," ((__m256i*)cnProcBufRes)[%d+i] = _mm256_sign_epi8(min, sgn);\n",(lut_startAddrCnGroups[2]>>5)+(j*bitOffsetInGroup));
|
||||
fprintf(fd," }\n");
|
||||
}
|
||||
}
|
||||
|
||||
// =====================================================================
|
||||
// Process group with 6 BNs
|
||||
fprintf(fd,"//Process group with 6 BNs\n");
|
||||
// Offset is 8*384/32 = 96
|
||||
const uint16_t lut_idxCnProcG6[6][5] = {{96,192,288,384,480}, {0,192,288,384,480},
|
||||
{0,96,288,384,480}, {0,96,192,384,480},
|
||||
{0,96,192,288,480}, {0,96,192,288,384}};
|
||||
|
||||
|
||||
if (lut_numCnInCnGroups[3] > 0)
|
||||
{
|
||||
// Number of groups of 32 CNs for parallel processing
|
||||
// Ceil for values not divisible by 32
|
||||
fprintf(fd, "M = (%d*Z + 31)>>5;\n",lut_numCnInCnGroups[3] );
|
||||
|
||||
// Set the offset to each bit within a group in terms of 32 Byte
|
||||
bitOffsetInGroup = (lut_numCnInCnGroups_BG1_R13[3]*NR_LDPC_ZMAX)>>5;
|
||||
|
||||
|
||||
// Set pointers to start of group 4
|
||||
//p_cnProcBuf = (__m256i*) &cnProcBuf [lut_startAddrCnGroups[1]];
|
||||
//p_cnProcBufRes = (__m256i*) &cnProcBufRes[lut_startAddrCnGroups[1]];
|
||||
|
||||
// Loop over every BN
|
||||
|
||||
for (j=0; j<6; j++)
|
||||
{
|
||||
// Set of results pointer to correct BN address
|
||||
//p_cnProcBufResBit = p_cnProcBufRes + (j*bitOffsetInGroup);
|
||||
|
||||
// Loop over CNs
|
||||
// for (i=0; i<M; i++,iprime++)
|
||||
// {
|
||||
fprintf(fd," for (int i=0;i<M;i++) {\n");
|
||||
// Abs and sign of 32 CNs (first BN)
|
||||
// ymm0 = p_cnProcBuf[lut_idxCnProcG3[j][0] + i];
|
||||
fprintf(fd," ymm0 = ((__m256i*)cnProcBuf)[%d+i];\n",(lut_startAddrCnGroups[3]>>5)+lut_idxCnProcG6[j][0]);
|
||||
// sgn = _mm256_sign_epi8(ones, ymm0);
|
||||
fprintf(fd," sgn = _mm256_sign_epi8(ones, ymm0);\n");
|
||||
// min = _mm256_abs_epi8(ymm0);
|
||||
fprintf(fd," min = _mm256_abs_epi8(ymm0);\n");
|
||||
|
||||
|
||||
// Loop over BNs
|
||||
for (k=1; k<5; k++)
|
||||
{
|
||||
fprintf(fd," ymm0 = ((__m256i*)cnProcBuf)[%d+i];\n",(lut_startAddrCnGroups[3]>>5)+lut_idxCnProcG6[j][k]);
|
||||
|
||||
// min = _mm256_min_epu8(min, _mm256_abs_epi8(ymm0));
|
||||
fprintf(fd," min = _mm256_min_epu8(min, _mm256_abs_epi8(ymm0));\n");
|
||||
|
||||
// sgn = _mm256_sign_epi8(sgn, ymm0);
|
||||
fprintf(fd," sgn = _mm256_sign_epi8(sgn, ymm0);\n");
|
||||
}
|
||||
|
||||
// Store result
|
||||
// min = _mm256_min_epu8(min, maxLLR); // 128 in epi8 is -127
|
||||
fprintf(fd," min = _mm256_min_epu8(min, maxLLR);\n");
|
||||
// *p_cnProcBufResBit = _mm256_sign_epi8(min, sgn);
|
||||
// p_cnProcBufResBit++;
|
||||
fprintf(fd," ((__m256i*)cnProcBufRes)[%d+i] = _mm256_sign_epi8(min, sgn);\n",(lut_startAddrCnGroups[3]>>5)+(j*bitOffsetInGroup));
|
||||
fprintf(fd," }\n");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// =====================================================================
|
||||
// Process group with 7 BNs
|
||||
fprintf(fd,"//Process group with 7 BNs\n");
|
||||
// Offset is 5*384/32 = 60
|
||||
const uint16_t lut_idxCnProcG7[7][6] = {{60,120,180,240,300,360}, {0,120,180,240,300,360},
|
||||
{0,60,180,240,300,360}, {0,60,120,240,300,360},
|
||||
{0,60,120,180,300,360}, {0,60,120,180,240,360},
|
||||
{0,60,120,180,240,300}};
|
||||
|
||||
|
||||
|
||||
if (lut_numCnInCnGroups[4] > 0)
|
||||
{
|
||||
// Number of groups of 32 CNs for parallel processing
|
||||
// Ceil for values not divisible by 32
|
||||
fprintf(fd, "M = (%d*Z + 31)>>5;\n",lut_numCnInCnGroups[4] );
|
||||
|
||||
// Set the offset to each bit within a group in terms of 32 Byte
|
||||
bitOffsetInGroup = (lut_numCnInCnGroups_BG1_R13[4]*NR_LDPC_ZMAX)>>5;
|
||||
|
||||
|
||||
// Set pointers to start of group 4
|
||||
//p_cnProcBuf = (__m256i*) &cnProcBuf [lut_startAddrCnGroups[1]];
|
||||
//p_cnProcBufRes = (__m256i*) &cnProcBufRes[lut_startAddrCnGroups[1]];
|
||||
|
||||
// Loop over every BN
|
||||
|
||||
for (j=0; j<7; j++)
|
||||
{
|
||||
// Set of results pointer to correct BN address
|
||||
//p_cnProcBufResBit = p_cnProcBufRes + (j*bitOffsetInGroup);
|
||||
|
||||
// Loop over CNs
|
||||
// for (i=0; i<M; i++,iprime++)
|
||||
// {
|
||||
fprintf(fd," for (int i=0;i<M;i++) {\n");
|
||||
// Abs and sign of 32 CNs (first BN)
|
||||
// ymm0 = p_cnProcBuf[lut_idxCnProcG3[j][0] + i];
|
||||
fprintf(fd," ymm0 = ((__m256i*)cnProcBuf)[%d+i];\n",(lut_startAddrCnGroups[4]>>5)+lut_idxCnProcG7[j][0]);
|
||||
// sgn = _mm256_sign_epi8(ones, ymm0);
|
||||
fprintf(fd," sgn = _mm256_sign_epi8(ones, ymm0);\n");
|
||||
// min = _mm256_abs_epi8(ymm0);
|
||||
fprintf(fd," min = _mm256_abs_epi8(ymm0);\n");
|
||||
|
||||
|
||||
// Loop over BNs
|
||||
for (k=1; k<6; k++)
|
||||
{
|
||||
fprintf(fd," ymm0 = ((__m256i*)cnProcBuf)[%d+i];\n",(lut_startAddrCnGroups[4]>>5)+lut_idxCnProcG7[j][k]);
|
||||
|
||||
// min = _mm256_min_epu8(min, _mm256_abs_epi8(ymm0));
|
||||
fprintf(fd," min = _mm256_min_epu8(min, _mm256_abs_epi8(ymm0));\n");
|
||||
|
||||
// sgn = _mm256_sign_epi8(sgn, ymm0);
|
||||
fprintf(fd," sgn = _mm256_sign_epi8(sgn, ymm0);\n");
|
||||
}
|
||||
|
||||
// Store result
|
||||
// min = _mm256_min_epu8(min, maxLLR); // 128 in epi8 is -127
|
||||
fprintf(fd," min = _mm256_min_epu8(min, maxLLR);\n");
|
||||
// *p_cnProcBufResBit = _mm256_sign_epi8(min, sgn);
|
||||
// p_cnProcBufResBit++;
|
||||
fprintf(fd," ((__m256i*)cnProcBufRes)[%d+i] = _mm256_sign_epi8(min, sgn);\n",(lut_startAddrCnGroups[4]>>5)+(j*bitOffsetInGroup));
|
||||
fprintf(fd," }\n");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// =====================================================================
|
||||
// Process group with 8 BNs
|
||||
fprintf(fd,"//Process group with 8 BNs\n");
|
||||
// Offset is 2*384/32 = 24
|
||||
const uint8_t lut_idxCnProcG8[8][7] = {{24,48,72,96,120,144,168}, {0,48,72,96,120,144,168},
|
||||
{0,24,72,96,120,144,168}, {0,24,48,96,120,144,168},
|
||||
{0,24,48,72,120,144,168}, {0,24,48,72,96,144,168},
|
||||
{0,24,48,72,96,120,168}, {0,24,48,72,96,120,144}};
|
||||
|
||||
|
||||
|
||||
|
||||
if (lut_numCnInCnGroups[5] > 0)
|
||||
{
|
||||
// Number of groups of 32 CNs for parallel processing
|
||||
// Ceil for values not divisible by 32
|
||||
fprintf(fd, "M = (%d*Z + 31)>>5;\n",lut_numCnInCnGroups[5] );
|
||||
|
||||
// Set the offset to each bit within a group in terms of 32 Byte
|
||||
bitOffsetInGroup = (lut_numCnInCnGroups_BG1_R13[5]*NR_LDPC_ZMAX)>>5;
|
||||
|
||||
|
||||
// Set pointers to start of group 4
|
||||
//p_cnProcBuf = (__m256i*) &cnProcBuf [lut_startAddrCnGroups[1]];
|
||||
//p_cnProcBufRes = (__m256i*) &cnProcBufRes[lut_startAddrCnGroups[1]];
|
||||
|
||||
// Loop over every BN
|
||||
|
||||
for (j=0; j<8; j++)
|
||||
{
|
||||
// Set of results pointer to correct BN address
|
||||
//p_cnProcBufResBit = p_cnProcBufRes + (j*bitOffsetInGroup);
|
||||
|
||||
// Loop over CNs
|
||||
// for (i=0; i<M; i++,iprime++)
|
||||
// {
|
||||
fprintf(fd," for (int i=0;i<M;i++) {\n");
|
||||
// Abs and sign of 32 CNs (first BN)
|
||||
// ymm0 = p_cnProcBuf[lut_idxCnProcG3[j][0] + i];
|
||||
fprintf(fd," ymm0 = ((__m256i*)cnProcBuf)[%d+i];\n",(lut_startAddrCnGroups[5]>>5)+lut_idxCnProcG8[j][0]);
|
||||
// sgn = _mm256_sign_epi8(ones, ymm0);
|
||||
fprintf(fd," sgn = _mm256_sign_epi8(ones, ymm0);\n");
|
||||
// min = _mm256_abs_epi8(ymm0);
|
||||
fprintf(fd," min = _mm256_abs_epi8(ymm0);\n");
|
||||
|
||||
|
||||
// Loop over BNs
|
||||
for (k=1; k<7; k++)
|
||||
{
|
||||
fprintf(fd," ymm0 = ((__m256i*)cnProcBuf)[%d+i];\n",(lut_startAddrCnGroups[5]>>5)+lut_idxCnProcG8[j][k]);
|
||||
|
||||
// min = _mm256_min_epu8(min, _mm256_abs_epi8(ymm0));
|
||||
fprintf(fd," min = _mm256_min_epu8(min, _mm256_abs_epi8(ymm0));\n");
|
||||
|
||||
// sgn = _mm256_sign_epi8(sgn, ymm0);
|
||||
fprintf(fd," sgn = _mm256_sign_epi8(sgn, ymm0);\n");
|
||||
}
|
||||
|
||||
// Store result
|
||||
// min = _mm256_min_epu8(min, maxLLR); // 128 in epi8 is -127
|
||||
fprintf(fd," min = _mm256_min_epu8(min, maxLLR);\n");
|
||||
// *p_cnProcBufResBit = _mm256_sign_epi8(min, sgn);
|
||||
// p_cnProcBufResBit++;
|
||||
fprintf(fd," ((__m256i*)cnProcBufRes)[%d+i] = _mm256_sign_epi8(min, sgn);\n",(lut_startAddrCnGroups[5]>>5)+(j*bitOffsetInGroup));
|
||||
fprintf(fd," }\n");
|
||||
}
|
||||
}
|
||||
|
||||
// =====================================================================
|
||||
// Process group with 9 BNs
|
||||
fprintf(fd,"//Process group with 9 BNs\n");
|
||||
// Offset is 2*384/32 = 24
|
||||
const uint8_t lut_idxCnProcG9[9][8] = {{24,48,72,96,120,144,168,192}, {0,48,72,96,120,144,168,192},
|
||||
{0,24,72,96,120,144,168,192}, {0,24,48,96,120,144,168,192},
|
||||
{0,24,48,72,120,144,168,192}, {0,24,48,72,96,144,168,192},
|
||||
{0,24,48,72,96,120,168,192}, {0,24,48,72,96,120,144,192},
|
||||
{0,24,48,72,96,120,144,168}};
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
if (lut_numCnInCnGroups[6] > 0)
|
||||
{
|
||||
// Number of groups of 32 CNs for parallel processing
|
||||
// Ceil for values not divisible by 32
|
||||
fprintf(fd, "M = (%d*Z + 31)>>5;\n",lut_numCnInCnGroups[6] );
|
||||
// Set the offset to each bit within a group in terms of 32 Byte
|
||||
bitOffsetInGroup = (lut_numCnInCnGroups_BG1_R13[6]*NR_LDPC_ZMAX)>>5;
|
||||
|
||||
|
||||
// Set pointers to start of group 9
|
||||
//p_cnProcBuf = (__m256i*) &cnProcBuf [lut_startAddrCnGroups[1]];
|
||||
//p_cnProcBufRes = (__m256i*) &cnProcBufRes[lut_startAddrCnGroups[1]];
|
||||
|
||||
// Loop over every BN
|
||||
|
||||
for (j=0; j<9; j++)
|
||||
{
|
||||
// Set of results pointer to correct BN address
|
||||
//p_cnProcBufResBit = p_cnProcBufRes + (j*bitOffsetInGroup);
|
||||
|
||||
// Loop over CNs
|
||||
// for (i=0; i<M; i++,iprime++)
|
||||
// {
|
||||
fprintf(fd," for (int i=0;i<M;i++) {\n");
|
||||
// Abs and sign of 32 CNs (first BN)
|
||||
// ymm0 = p_cnProcBuf[lut_idxCnProcG3[j][0] + i];
|
||||
fprintf(fd," ymm0 = ((__m256i*)cnProcBuf)[%d+i];\n",(lut_startAddrCnGroups[6]>>5)+lut_idxCnProcG9[j][0]);
|
||||
// sgn = _mm256_sign_epi8(ones, ymm0);
|
||||
fprintf(fd," sgn = _mm256_sign_epi8(ones, ymm0);\n");
|
||||
// min = _mm256_abs_epi8(ymm0);
|
||||
fprintf(fd," min = _mm256_abs_epi8(ymm0);\n");
|
||||
|
||||
|
||||
// Loop over BNs
|
||||
for (k=1; k<8; k++)
|
||||
{
|
||||
fprintf(fd," ymm0 = ((__m256i*)cnProcBuf)[%d+i];\n",(lut_startAddrCnGroups[6]>>5)+lut_idxCnProcG9[j][k]);
|
||||
|
||||
// min = _mm256_min_epu8(min, _mm256_abs_epi8(ymm0));
|
||||
fprintf(fd," min = _mm256_min_epu8(min, _mm256_abs_epi8(ymm0));\n");
|
||||
|
||||
// sgn = _mm256_sign_epi8(sgn, ymm0);
|
||||
fprintf(fd," sgn = _mm256_sign_epi8(sgn, ymm0);\n");
|
||||
}
|
||||
|
||||
// Store result
|
||||
// min = _mm256_min_epu8(min, maxLLR); // 128 in epi8 is -127
|
||||
fprintf(fd," min = _mm256_min_epu8(min, maxLLR);\n");
|
||||
// *p_cnProcBufResBit = _mm256_sign_epi8(min, sgn);
|
||||
// p_cnProcBufResBit++;
|
||||
fprintf(fd," ((__m256i*)cnProcBufRes)[%d+i] = _mm256_sign_epi8(min, sgn);\n",(lut_startAddrCnGroups[6]>>5)+(j*bitOffsetInGroup));
|
||||
fprintf(fd," }\n");
|
||||
}
|
||||
}
|
||||
|
||||
// =====================================================================
|
||||
// Process group with 10 BNs
|
||||
fprintf(fd,"//Process group with 10 BNs\n");
|
||||
// Offset is 1*384/32 = 12
|
||||
const uint8_t lut_idxCnProcG10[10][9] = {{12,24,36,48,60,72,84,96,108}, {0,24,36,48,60,72,84,96,108},
|
||||
{0,12,36,48,60,72,84,96,108}, {0,12,24,48,60,72,84,96,108},
|
||||
{0,12,24,36,60,72,84,96,108}, {0,12,24,36,48,72,84,96,108},
|
||||
{0,12,24,36,48,60,84,96,108}, {0,12,24,36,48,60,72,96,108},
|
||||
{0,12,24,36,48,60,72,84,108}, {0,12,24,36,48,60,72,84,96}};
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
if (lut_numCnInCnGroups[7] > 0)
|
||||
{
|
||||
// Number of groups of 32 CNs for parallel processing
|
||||
// Ceil for values not divisible by 32
|
||||
fprintf(fd, " M = (%d*Z + 31)>>5;\n",lut_numCnInCnGroups[7] );
|
||||
|
||||
// Set the offset to each bit within a group in terms of 32 Byte
|
||||
bitOffsetInGroup = (lut_numCnInCnGroups_BG1_R13[7]*NR_LDPC_ZMAX)>>5;
|
||||
|
||||
|
||||
// Set pointers to start of group 10
|
||||
//p_cnProcBuf = (__m256i*) &cnProcBuf [lut_startAddrCnGroups[1]];
|
||||
//p_cnProcBufRes = (__m256i*) &cnProcBufRes[lut_startAddrCnGroups[1]];
|
||||
|
||||
// Loop over every BN
|
||||
|
||||
for (j=0; j<10; j++)
|
||||
{
|
||||
// Set of results pointer to correct BN address
|
||||
//p_cnProcBufResBit = p_cnProcBufRes + (j*bitOffsetInGroup);
|
||||
|
||||
// Loop over CNs
|
||||
// for (i=0; i<M; i++,iprime++)
|
||||
// {
|
||||
fprintf(fd," for (int i=0;i<M;i++) {\n");
|
||||
// Abs and sign of 32 CNs (first BN)
|
||||
// ymm0 = p_cnProcBuf[lut_idxCnProcG3[j][0] + i];
|
||||
fprintf(fd," ymm0 = ((__m256i*)cnProcBuf)[%d+i];\n",(lut_startAddrCnGroups[7]>>5)+lut_idxCnProcG10[j][0]);
|
||||
// sgn = _mm256_sign_epi8(ones, ymm0);
|
||||
fprintf(fd," sgn = _mm256_sign_epi8(ones, ymm0);\n");
|
||||
// min = _mm256_abs_epi8(ymm0);
|
||||
fprintf(fd," min = _mm256_abs_epi8(ymm0);\n");
|
||||
|
||||
|
||||
// Loop over BNs
|
||||
for (k=1; k<9; k++)
|
||||
{
|
||||
fprintf(fd," ymm0 = ((__m256i*)cnProcBuf)[%d+i];\n",(lut_startAddrCnGroups[7]>>5)+lut_idxCnProcG10[j][k]);
|
||||
|
||||
// min = _mm256_min_epu8(min, _mm256_abs_epi8(ymm0));
|
||||
fprintf(fd," min = _mm256_min_epu8(min, _mm256_abs_epi8(ymm0));\n");
|
||||
|
||||
// sgn = _mm256_sign_epi8(sgn, ymm0);
|
||||
fprintf(fd," sgn = _mm256_sign_epi8(sgn, ymm0);\n");
|
||||
}
|
||||
|
||||
// Store result
|
||||
// min = _mm256_min_epu8(min, maxLLR); // 128 in epi8 is -127
|
||||
fprintf(fd," min = _mm256_min_epu8(min, maxLLR);\n");
|
||||
// *p_cnProcBufResBit = _mm256_sign_epi8(min, sgn);
|
||||
// p_cnProcBufResBit++;
|
||||
fprintf(fd," ((__m256i*)cnProcBufRes)[%d+i] = _mm256_sign_epi8(min, sgn);\n",(lut_startAddrCnGroups[7]>>5)+(j*bitOffsetInGroup));
|
||||
fprintf(fd," }\n");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// =====================================================================
|
||||
// Process group with 19 BNs
|
||||
fprintf(fd,"//Process group with 19 BNs\n");
|
||||
// Offset is 4*384/32 = 12
|
||||
const uint16_t lut_idxCnProcG19[19][18] = {{48,96,144,192,240,288,336,384,432,480,528,576,624,672,720,768,816,864}, {0,96,144,192,240,288,336,384,432,480,528,576,624,672,720,768,816,864},
|
||||
{0,48,144,192,240,288,336,384,432,480,528,576,624,672,720,768,816,864}, {0,48,96,192,240,288,336,384,432,480,528,576,624,672,720,768,816,864},
|
||||
{0,48,96,144,240,288,336,384,432,480,528,576,624,672,720,768,816,864}, {0,48,96,144,192,288,336,384,432,480,528,576,624,672,720,768,816,864},
|
||||
{0,48,96,144,192,240,336,384,432,480,528,576,624,672,720,768,816,864}, {0,48,96,144,192,240,288,384,432,480,528,576,624,672,720,768,816,864},
|
||||
{0,48,96,144,192,240,288,336,432,480,528,576,624,672,720,768,816,864}, {0,48,96,144,192,240,288,336,384,480,528,576,624,672,720,768,816,864},
|
||||
{0,48,96,144,192,240,288,336,384,432,528,576,624,672,720,768,816,864}, {0,48,96,144,192,240,288,336,384,432,480,576,624,672,720,768,816,864},
|
||||
{0,48,96,144,192,240,288,336,384,432,480,528,624,672,720,768,816,864}, {0,48,96,144,192,240,288,336,384,432,480,528,576,672,720,768,816,864},
|
||||
{0,48,96,144,192,240,288,336,384,432,480,528,576,624,720,768,816,864}, {0,48,96,144,192,240,288,336,384,432,480,528,576,624,672,768,816,864},
|
||||
{0,48,96,144,192,240,288,336,384,432,480,528,576,624,672,720,816,864}, {0,48,96,144,192,240,288,336,384,432,480,528,576,624,672,720,768,864},
|
||||
{0,48,96,144,192,240,288,336,384,432,480,528,576,624,672,720,768,816}};
|
||||
|
||||
|
||||
if (lut_numCnInCnGroups[8] > 0)
|
||||
{
|
||||
// Number of groups of 32 CNs for parallel processing
|
||||
// Ceil for values not divisible by 32
|
||||
fprintf(fd, " M = (%d*Z + 31)>>5;\n",lut_numCnInCnGroups[8] );
|
||||
|
||||
// Set the offset to each bit within a group in terms of 32 Byte
|
||||
bitOffsetInGroup = (lut_numCnInCnGroups_BG1_R13[8]*NR_LDPC_ZMAX)>>5;
|
||||
|
||||
|
||||
// Set pointers to start of group 19
|
||||
//p_cnProcBuf = (__m256i*) &cnProcBuf [lut_startAddrCnGroups[1]];
|
||||
//p_cnProcBufRes = (__m256i*) &cnProcBufRes[lut_startAddrCnGroups[1]];
|
||||
|
||||
// Loop over every BN
|
||||
|
||||
for (j=0; j<19; j++)
|
||||
{
|
||||
// Set of results pointer to correct BN address
|
||||
//p_cnProcBufResBit = p_cnProcBufRes + (j*bitOffsetInGroup);
|
||||
|
||||
// Loop over CNs
|
||||
// for (i=0; i<M; i++,iprime++)
|
||||
// {
|
||||
fprintf(fd," for (int i=0;i<M;i++) {\n");
|
||||
// Abs and sign of 32 CNs (first BN)
|
||||
// ymm0 = p_cnProcBuf[lut_idxCnProcG3[j][0] + i];
|
||||
fprintf(fd," ymm0 = ((__m256i*)cnProcBuf)[%d+i];\n",(lut_startAddrCnGroups[8]>>5)+lut_idxCnProcG19[j][0]);
|
||||
// sgn = _mm256_sign_epi8(ones, ymm0);
|
||||
fprintf(fd," sgn = _mm256_sign_epi8(ones, ymm0);\n");
|
||||
// min = _mm256_abs_epi8(ymm0);
|
||||
fprintf(fd," min = _mm256_abs_epi8(ymm0);\n");
|
||||
|
||||
|
||||
// Loop over BNs
|
||||
for (k=1; k<18; k++)
|
||||
{
|
||||
fprintf(fd," ymm0 = ((__m256i*)cnProcBuf)[%d+i];\n",(lut_startAddrCnGroups[8]>>5)+lut_idxCnProcG19[j][k]);
|
||||
|
||||
// min = _mm256_min_epu8(min, _mm256_abs_epi8(ymm0));
|
||||
fprintf(fd," min = _mm256_min_epu8(min, _mm256_abs_epi8(ymm0));\n");
|
||||
|
||||
// sgn = _mm256_sign_epi8(sgn, ymm0);
|
||||
fprintf(fd," sgn = _mm256_sign_epi8(sgn, ymm0);\n");
|
||||
}
|
||||
|
||||
// Store result
|
||||
// min = _mm256_min_epu8(min, maxLLR); // 128 in epi8 is -127
|
||||
fprintf(fd," min = _mm256_min_epu8(min, maxLLR);\n");
|
||||
// *p_cnProcBufResBit = _mm256_sign_epi8(min, sgn);
|
||||
// p_cnProcBufResBit++;
|
||||
fprintf(fd," ((__m256i*)cnProcBufRes)[%d+i] = _mm256_sign_epi8(min, sgn);\n",(lut_startAddrCnGroups[8]>>5)+(j*bitOffsetInGroup));
|
||||
fprintf(fd," }\n");
|
||||
}
|
||||
}
|
||||
|
||||
fprintf(fd,"}\n");
|
||||
fclose(fd);
|
||||
}//end of the function nrLDPC_cnProc_BG1
|
||||
|
||||
+436
@@ -0,0 +1,436 @@
|
||||
/*
|
||||
* Licensed to the OpenAirInterface (OAI) Software Alliance under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright ownership.
|
||||
* The OpenAirInterface Software Alliance licenses this file to You under
|
||||
* the OAI Public License, Version 1.1 (the "License"); you may not use this file
|
||||
* except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.openairinterface.org/?page_id=698
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*-------------------------------------------------------------------------------
|
||||
* For more information about the OpenAirInterface (OAI) Software Alliance:
|
||||
* contact@openairinterface.org
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdint.h>
|
||||
#include <stdlib.h>
|
||||
#include "../../nrLDPCdecoder_defs.h"
|
||||
#include "../../nrLDPC_types.h"
|
||||
#include "../../nrLDPC_bnProc.h"
|
||||
|
||||
|
||||
void nrLDPC_cnProc_BG2_generator_AVX2(const char* dir, int R)
|
||||
{
|
||||
const char *ratestr[3]={"15","13","23"};
|
||||
|
||||
if (R<0 || R>2) {printf("Illegal R %d\n",R); abort();}
|
||||
|
||||
|
||||
// system("mkdir -p ldpc_gen_files/avx2");
|
||||
|
||||
char fname[FILENAME_MAX+1];
|
||||
snprintf(fname, sizeof(fname), "%s/cnProc/nrLDPC_cnProc_BG2_R%s_AVX2.h", dir, ratestr[R]);
|
||||
FILE *fd=fopen(fname,"w");
|
||||
if (fd == NULL) {
|
||||
printf("Cannot create file %s\n", fname);
|
||||
abort();
|
||||
}
|
||||
|
||||
fprintf(fd,"#include <stdint.h>\n");
|
||||
fprintf(fd,"#include <immintrin.h>\n");
|
||||
fprintf(fd,"static inline void nrLDPC_cnProc_BG2_R%s_AVX2(int8_t* cnProcBuf, int8_t* cnProcBufRes, uint16_t Z) {\n",ratestr[R]);
|
||||
|
||||
const uint8_t* lut_numCnInCnGroups;
|
||||
const uint32_t* lut_startAddrCnGroups = lut_startAddrCnGroups_BG2;
|
||||
|
||||
if (R==0) lut_numCnInCnGroups = lut_numCnInCnGroups_BG2_R15;
|
||||
else if (R==1) lut_numCnInCnGroups = lut_numCnInCnGroups_BG2_R13;
|
||||
else if (R==2) lut_numCnInCnGroups = lut_numCnInCnGroups_BG2_R23;
|
||||
else { printf("aborting, illegal R %d\n",R); fclose(fd);abort();}
|
||||
|
||||
|
||||
// Number of CNs in Groups
|
||||
//uint32_t M;
|
||||
uint32_t j;
|
||||
uint32_t k;
|
||||
// Offset to each bit within a group in terms of 32 byte
|
||||
uint32_t bitOffsetInGroup;
|
||||
|
||||
// Offsets are in units of bitOffsetInGroup (1*384/32)
|
||||
// const uint8_t lut_idxCnProcG3[3][2] = {{12,24}, {0,24}, {0,12}};
|
||||
|
||||
// =====================================================================
|
||||
// Process group with 3 BNs
|
||||
fprintf(fd,"//Process group with 3 BNs\n");
|
||||
// LUT with offsets for bits that need to be processed
|
||||
// 1. bit proc requires LLRs of 2. and 3. bit, 2.bits of 1. and 3. etc.
|
||||
// Offsets are in units of bitOffsetInGroup
|
||||
const uint8_t lut_idxCnProcG3[3][2] = {{72,144}, {0,144}, {0,72}};
|
||||
|
||||
|
||||
fprintf(fd," __m256i ymm0, min, sgn,ones,maxLLR;\n");
|
||||
fprintf(fd," ones = _mm256_set1_epi8((char)1);\n");
|
||||
fprintf(fd," maxLLR = _mm256_set1_epi8((char)127);\n");
|
||||
fprintf(fd," uint32_t M;\n");
|
||||
|
||||
|
||||
if (lut_numCnInCnGroups[0] > 0)
|
||||
{
|
||||
// Number of groups of 32 CNs for parallel processing
|
||||
// Ceil for values not divisible by 32
|
||||
fprintf(fd," M = (%d*Z + 31)>>5;\n",lut_numCnInCnGroups[0] );
|
||||
|
||||
// Set the offset to each bit within a group in terms of 32 byte
|
||||
bitOffsetInGroup = (lut_numCnInCnGroups_BG2_R15[0]*NR_LDPC_ZMAX)>>5;
|
||||
|
||||
// Loop over every BN
|
||||
|
||||
for (j=0; j<3; j++)
|
||||
{
|
||||
|
||||
fprintf(fd," for (int i=0;i<M;i+=2) {\n");
|
||||
// Abs and sign of 32 CNs (first BN)
|
||||
// ymm0 = p_cnProcBuf[lut_idxCnProcG3[j][0] + i];
|
||||
fprintf(fd," ymm0 = ((__m256i*)cnProcBuf)[%d+i];\n",(lut_startAddrCnGroups[0]>>5)+lut_idxCnProcG3[j][0]);
|
||||
// sgn = _mm256_sign_epi8(ones, ymm0);
|
||||
fprintf(fd," sgn = _mm256_sign_epi8(ones, ymm0);\n");
|
||||
// min = _mm256_abs_epi8(ymm0);
|
||||
fprintf(fd," min = _mm256_abs_epi8(ymm0);\n");
|
||||
|
||||
// 32 CNs of second BN
|
||||
// ymm0 = p_cnProcBuf[lut_idxCnProcG3[j][1] + i];
|
||||
fprintf(fd," ymm0 = ((__m256i*)cnProcBuf)[%d+i];\n",(lut_startAddrCnGroups[0]>>5)+lut_idxCnProcG3[j][1]);
|
||||
|
||||
// min = _mm256_min_epu8(min, _mm256_abs_epi8(ymm0));
|
||||
fprintf(fd," min = _mm256_min_epu8(min, _mm256_abs_epi8(ymm0));\n");
|
||||
|
||||
// sgn = _mm256_sign_epi8(sgn, ymm0);
|
||||
fprintf(fd," sgn = _mm256_sign_epi8(sgn, ymm0);\n");
|
||||
|
||||
// Store result
|
||||
// min = _mm256_min_epu8(min, maxLLR); // 128 in epi8 is -127
|
||||
fprintf(fd," min = _mm256_min_epu8(min, maxLLR);\n");
|
||||
// *p_cnProcBufResBit = _mm256_sign_epi8(min, sgn);
|
||||
// p_cnProcBufResBit++;
|
||||
fprintf(fd," ((__m256i*)cnProcBufRes)[%d+i] = _mm256_sign_epi8(min, sgn);\n",(lut_startAddrCnGroups[0]>>5)+(j*bitOffsetInGroup));
|
||||
|
||||
// Abs and sign of 32 CNs (first BN)
|
||||
// ymm0 = p_cnProcBuf[lut_idxCnProcG3[j][0] + i];
|
||||
fprintf(fd," ymm0 = ((__m256i*)cnProcBuf)[%d+i];\n",(lut_startAddrCnGroups[0]>>5)+lut_idxCnProcG3[j][0]+1);
|
||||
// sgn = _mm256_sign_epi8(ones, ymm0);
|
||||
fprintf(fd," sgn = _mm256_sign_epi8(ones, ymm0);\n");
|
||||
// min = _mm256_abs_epi8(ymm0);
|
||||
fprintf(fd," min = _mm256_abs_epi8(ymm0);\n");
|
||||
|
||||
fprintf(fd," }\n");
|
||||
}
|
||||
}
|
||||
|
||||
// =====================================================================
|
||||
// Process group with 4 BNs
|
||||
fprintf(fd,"//Process group with 4 BNs\n");
|
||||
|
||||
// Offset is 20*384/32 = 240
|
||||
const uint16_t lut_idxCnProcG4[4][3] = {{240,480,720}, {0,480,720}, {0,240,720}, {0,240,480}};
|
||||
|
||||
if (lut_numCnInCnGroups[1] > 0)
|
||||
{
|
||||
// Number of groups of 32 CNs for parallel processing
|
||||
// Ceil for values not divisible by 32
|
||||
fprintf(fd," M = (%d*Z + 31)>>5;\n",lut_numCnInCnGroups[1] );
|
||||
|
||||
// Set the offset to each bit within a group in terms of 32 byte
|
||||
bitOffsetInGroup = (lut_numCnInCnGroups_BG2_R15[1]*NR_LDPC_ZMAX)>>5;
|
||||
|
||||
// Loop over every BN
|
||||
|
||||
for (j=0; j<4; j++)
|
||||
{
|
||||
|
||||
// Loop over CNs
|
||||
|
||||
fprintf(fd," for (int i=0;i<M;i++) {\n");
|
||||
// Abs and sign of 32 CNs (first BN)
|
||||
// ymm0 = p_cnProcBuf[lut_idxCnProcG3[j][0] + i];
|
||||
fprintf(fd," ymm0 = ((__m256i*)cnProcBuf)[%d+i];\n",(lut_startAddrCnGroups[1]>>5)+lut_idxCnProcG4[j][0]);
|
||||
// sgn = _mm256_sign_epi8(ones, ymm0);
|
||||
fprintf(fd," sgn = _mm256_sign_epi8(ones, ymm0);\n");
|
||||
// min = _mm256_abs_epi8(ymm0);
|
||||
fprintf(fd," min = _mm256_abs_epi8(ymm0);\n");
|
||||
|
||||
|
||||
// Loop over BNs
|
||||
for (k=1; k<3; k++)
|
||||
{
|
||||
fprintf(fd," ymm0 = ((__m256i*)cnProcBuf)[%d+i];\n",(lut_startAddrCnGroups[1]>>5)+lut_idxCnProcG4[j][k]);
|
||||
|
||||
// min = _mm256_min_epu8(min, _mm256_abs_epi8(ymm0));
|
||||
fprintf(fd," min = _mm256_min_epu8(min, _mm256_abs_epi8(ymm0));\n");
|
||||
|
||||
// sgn = _mm256_sign_epi8(sgn, ymm0);
|
||||
fprintf(fd," sgn = _mm256_sign_epi8(sgn, ymm0);\n");
|
||||
}
|
||||
|
||||
// Store result
|
||||
// min = _mm256_min_epu8(min, maxLLR); // 128 in epi8 is -127
|
||||
fprintf(fd," min = _mm256_min_epu8(min, maxLLR);\n");
|
||||
// *p_cnProcBufResBit = _mm256_sign_epi8(min, sgn);
|
||||
// p_cnProcBufResBit++;
|
||||
fprintf(fd," ((__m256i*)cnProcBufRes)[%d+i] = _mm256_sign_epi8(min, sgn);\n",(lut_startAddrCnGroups[1]>>5)+(j*bitOffsetInGroup));
|
||||
fprintf(fd," }\n");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// =====================================================================
|
||||
// Process group with 5 BNs
|
||||
fprintf(fd,"//Process group with 5 BNs\n");
|
||||
|
||||
// Offset is 9*384/32 = 108
|
||||
const uint16_t lut_idxCnProcG5[5][4] = {{108,216,324,432}, {0,216,324,432},
|
||||
{0,108,324,432}, {0,108,216,432}, {0,108,216,324}};
|
||||
|
||||
|
||||
|
||||
if (lut_numCnInCnGroups[2] > 0)
|
||||
{
|
||||
// Number of groups of 32 CNs for parallel processing
|
||||
// Ceil for values not divisible by 32
|
||||
fprintf(fd," M = (%d*Z + 31)>>5;\n",lut_numCnInCnGroups[2] );
|
||||
// Set the offset to each bit within a group in terms of 32 byte
|
||||
bitOffsetInGroup = (lut_numCnInCnGroups_BG2_R15[2]*NR_LDPC_ZMAX)>>5;
|
||||
|
||||
// Loop over every BN
|
||||
|
||||
for (j=0; j<5; j++)
|
||||
{
|
||||
|
||||
|
||||
fprintf(fd," for (int i=0;i<M;i++) {\n");
|
||||
// Abs and sign of 32 CNs (first BN)
|
||||
// ymm0 = p_cnProcBuf[lut_idxCnProcG3[j][0] + i];
|
||||
fprintf(fd," ymm0 = ((__m256i*)cnProcBuf)[%d+i];\n",(lut_startAddrCnGroups[2]>>5)+lut_idxCnProcG5[j][0]);
|
||||
// sgn = _mm256_sign_epi8(ones, ymm0);
|
||||
fprintf(fd," sgn = _mm256_sign_epi8(ones, ymm0);\n");
|
||||
// min = _mm256_abs_epi8(ymm0);
|
||||
fprintf(fd," min = _mm256_abs_epi8(ymm0);\n");
|
||||
|
||||
|
||||
// Loop over BNs
|
||||
for (k=1; k<4; k++)
|
||||
{
|
||||
fprintf(fd," ymm0 = ((__m256i*)cnProcBuf)[%d+i];\n",(lut_startAddrCnGroups[2]>>5)+lut_idxCnProcG5[j][k]);
|
||||
|
||||
// min = _mm256_min_epu8(min, _mm256_abs_epi8(ymm0));
|
||||
fprintf(fd," min = _mm256_min_epu8(min, _mm256_abs_epi8(ymm0));\n");
|
||||
|
||||
// sgn = _mm256_sign_epi8(sgn, ymm0);
|
||||
fprintf(fd," sgn = _mm256_sign_epi8(sgn, ymm0);\n");
|
||||
}
|
||||
|
||||
// Store result
|
||||
// min = _mm256_min_epu8(min, maxLLR); // 128 in epi8 is -127
|
||||
fprintf(fd," min = _mm256_min_epu8(min, maxLLR);\n");
|
||||
// *p_cnProcBufResBit = _mm256_sign_epi8(min, sgn);
|
||||
fprintf(fd," ((__m256i*)cnProcBufRes)[%d+i] = _mm256_sign_epi8(min, sgn);\n",(lut_startAddrCnGroups[2]>>5)+(j*bitOffsetInGroup));
|
||||
fprintf(fd," }\n");
|
||||
}
|
||||
}
|
||||
|
||||
// =====================================================================
|
||||
// Process group with 6 BNs
|
||||
fprintf(fd,"//Process group with 6 BNs\n");
|
||||
// Offset is 3*384/32 = 36
|
||||
const uint16_t lut_idxCnProcG6[6][5] = {{36,72,108,144,180}, {0,72,108,144,180},
|
||||
{0,36,108,144,180}, {0,36,72,144,180},
|
||||
{0,36,72,108,180}, {0,36,72,108,144}};
|
||||
|
||||
|
||||
if (lut_numCnInCnGroups[3] > 0)
|
||||
{
|
||||
// Number of groups of 32 CNs for parallel processing
|
||||
// Ceil for values not divisible by 32
|
||||
fprintf(fd, "M = (%d*Z + 31)>>5;\n",lut_numCnInCnGroups[3] );
|
||||
|
||||
// Set the offset to each bit within a group in terms of 32 byte
|
||||
bitOffsetInGroup = (lut_numCnInCnGroups_BG2_R15[3]*NR_LDPC_ZMAX)>>5;
|
||||
|
||||
// Loop over every BN
|
||||
|
||||
for (j=0; j<6; j++)
|
||||
{
|
||||
|
||||
|
||||
// Loop over CNs
|
||||
|
||||
fprintf(fd," for (int i=0;i<M;i++) {\n");
|
||||
// Abs and sign of 32 CNs (first BN)
|
||||
// ymm0 = p_cnProcBuf[lut_idxCnProcG3[j][0] + i];
|
||||
fprintf(fd," ymm0 = ((__m256i*)cnProcBuf)[%d+i];\n",(lut_startAddrCnGroups[3]>>5)+lut_idxCnProcG6[j][0]);
|
||||
// sgn = _mm256_sign_epi8(ones, ymm0);
|
||||
fprintf(fd," sgn = _mm256_sign_epi8(ones, ymm0);\n");
|
||||
// min = _mm256_abs_epi8(ymm0);
|
||||
fprintf(fd," min = _mm256_abs_epi8(ymm0);\n");
|
||||
|
||||
|
||||
// Loop over BNs
|
||||
for (k=1; k<5; k++)
|
||||
{
|
||||
fprintf(fd," ymm0 = ((__m256i*)cnProcBuf)[%d+i];\n",(lut_startAddrCnGroups[3]>>5)+lut_idxCnProcG6[j][k]);
|
||||
|
||||
// min = _mm256_min_epu8(min, _mm256_abs_epi8(ymm0));
|
||||
fprintf(fd," min = _mm256_min_epu8(min, _mm256_abs_epi8(ymm0));\n");
|
||||
|
||||
// sgn = _mm256_sign_epi8(sgn, ymm0);
|
||||
fprintf(fd," sgn = _mm256_sign_epi8(sgn, ymm0);\n");
|
||||
}
|
||||
|
||||
// Store result
|
||||
// min = _mm256_min_epu8(min, maxLLR); // 128 in epi8 is -127
|
||||
fprintf(fd," min = _mm256_min_epu8(min, maxLLR);\n");
|
||||
// *p_cnProcBufResBit = _mm256_sign_epi8(min, sgn);
|
||||
// p_cnProcBufResBit++;
|
||||
fprintf(fd," ((__m256i*)cnProcBufRes)[%d+i] = _mm256_sign_epi8(min, sgn);\n",(lut_startAddrCnGroups[3]>>5)+(j*bitOffsetInGroup));
|
||||
fprintf(fd," }\n");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
// =====================================================================
|
||||
// Process group with 8 BNs
|
||||
fprintf(fd,"//Process group with 8 BNs\n");
|
||||
// Offset is 2*384/32 = 24
|
||||
const uint8_t lut_idxCnProcG8[8][7] = {{24,48,72,96,120,144,168}, {0,48,72,96,120,144,168},
|
||||
{0,24,72,96,120,144,168}, {0,24,48,96,120,144,168},
|
||||
{0,24,48,72,120,144,168}, {0,24,48,72,96,144,168},
|
||||
{0,24,48,72,96,120,168}, {0,24,48,72,96,120,144}};
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
if (lut_numCnInCnGroups[4] > 0)
|
||||
{
|
||||
// Number of groups of 32 CNs for parallel processing
|
||||
// Ceil for values not divisible by 32
|
||||
fprintf(fd, "M = (%d*Z + 31)>>5;\n",lut_numCnInCnGroups[4] );
|
||||
|
||||
// Set the offset to each bit within a group in terms of 32 byte
|
||||
bitOffsetInGroup = (lut_numCnInCnGroups_BG2_R15[4]*NR_LDPC_ZMAX)>>5;
|
||||
|
||||
// Loop over every BN
|
||||
|
||||
for (j=0; j<8; j++)
|
||||
{
|
||||
|
||||
// Loop over CNs
|
||||
fprintf(fd," for (int i=0;i<M;i++) {\n");
|
||||
// Abs and sign of 32 CNs (first BN)
|
||||
// ymm0 = p_cnProcBuf[lut_idxCnProcG3[j][0] + i];
|
||||
fprintf(fd," ymm0 = ((__m256i*)cnProcBuf)[%d+i];\n",(lut_startAddrCnGroups[4]>>5)+lut_idxCnProcG8[j][0]);
|
||||
// sgn = _mm256_sign_epi8(ones, ymm0);
|
||||
fprintf(fd," sgn = _mm256_sign_epi8(ones, ymm0);\n");
|
||||
// min = _mm256_abs_epi8(ymm0);
|
||||
fprintf(fd," min = _mm256_abs_epi8(ymm0);\n");
|
||||
|
||||
// Loop over BNs
|
||||
for (k=1; k<7; k++)
|
||||
{
|
||||
fprintf(fd," ymm0 = ((__m256i*)cnProcBuf)[%d+i];\n",(lut_startAddrCnGroups[4]>>5)+lut_idxCnProcG8[j][k]);
|
||||
|
||||
// min = _mm256_min_epu8(min, _mm256_abs_epi8(ymm0));
|
||||
fprintf(fd," min = _mm256_min_epu8(min, _mm256_abs_epi8(ymm0));\n");
|
||||
|
||||
// sgn = _mm256_sign_epi8(sgn, ymm0);
|
||||
fprintf(fd," sgn = _mm256_sign_epi8(sgn, ymm0);\n");
|
||||
|
||||
}
|
||||
|
||||
// Store result
|
||||
// min = _mm256_min_epu8(min, maxLLR); // 128 in epi8 is -127
|
||||
fprintf(fd," min = _mm256_min_epu8(min, maxLLR);\n");
|
||||
// *p_cnProcBufResBit = _mm256_sign_epi8(min, sgn);
|
||||
// p_cnProcBufResBit++;
|
||||
fprintf(fd," ((__m256i*)cnProcBufRes)[%d+i] = _mm256_sign_epi8(min, sgn);\n",(lut_startAddrCnGroups[4]>>5)+(j*bitOffsetInGroup));
|
||||
fprintf(fd," }\n");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// =====================================================================
|
||||
// Process group with 10 BNs
|
||||
fprintf(fd,"//Process group with 10 BNs\n");
|
||||
|
||||
const uint8_t lut_idxCnProcG10[10][9] = {{24,48,72,96,120,144,168,192,216}, {0,48,72,96,120,144,168,192,216},
|
||||
{0,24,72,96,120,144,168,192,216}, {0,24,48,96,120,144,168,192,216},
|
||||
{0,24,48,72,120,144,168,192,216}, {0,24,48,72,96,144,168,192,216},
|
||||
{0,24,48,72,96,120,168,192,216}, {0,24,48,72,96,120,144,192,216},
|
||||
{0,24,48,72,96,120,144,168,216}, {0,24,48,72,96,120,144,168,192}};
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
if (lut_numCnInCnGroups[5] > 0)
|
||||
{
|
||||
// Number of groups of 32 CNs for parallel processing
|
||||
// Ceil for values not divisible by 32
|
||||
fprintf(fd, "M = (%d*Z + 31)>>5;\n",lut_numCnInCnGroups[5] );
|
||||
|
||||
// Set the offset to each bit within a group in terms of 32 byte
|
||||
bitOffsetInGroup = (lut_numCnInCnGroups_BG2_R15[5]*NR_LDPC_ZMAX)>>5;
|
||||
|
||||
// Loop over every BN
|
||||
|
||||
for (j=0; j<10; j++)
|
||||
{
|
||||
|
||||
// Loop over CNs
|
||||
|
||||
fprintf(fd," for (int i=0;i<M;i++) {\n");
|
||||
// Abs and sign of 32 CNs (first BN)
|
||||
// ymm0 = p_cnProcBuf[lut_idxCnProcG3[j][0] + i];
|
||||
fprintf(fd," ymm0 = ((__m256i*)cnProcBuf)[%d+i];\n",(lut_startAddrCnGroups[5]>>5)+lut_idxCnProcG10[j][0]);
|
||||
// sgn = _mm256_sign_epi8(ones, ymm0);
|
||||
fprintf(fd," sgn = _mm256_sign_epi8(ones, ymm0);\n");
|
||||
// min = _mm256_abs_epi8(ymm0);
|
||||
fprintf(fd," min = _mm256_abs_epi8(ymm0);\n");
|
||||
|
||||
|
||||
// Loop over BNs
|
||||
for (k=1; k<9; k++)
|
||||
{
|
||||
fprintf(fd," ymm0 = ((__m256i*)cnProcBuf)[%d+i];\n",(lut_startAddrCnGroups[5]>>5)+lut_idxCnProcG10[j][k]);
|
||||
|
||||
// min = _mm256_min_epu8(min, _mm256_abs_epi8(ymm0));
|
||||
fprintf(fd," min = _mm256_min_epu8(min, _mm256_abs_epi8(ymm0));\n");
|
||||
|
||||
// sgn = _mm256_sign_epi8(sgn, ymm0);
|
||||
fprintf(fd," sgn = _mm256_sign_epi8(sgn, ymm0);\n");
|
||||
}
|
||||
|
||||
// Store result
|
||||
// min = _mm256_min_epu8(min, maxLLR); // 128 in epi8 is -127
|
||||
fprintf(fd," min = _mm256_min_epu8(min, maxLLR);\n");
|
||||
// *p_cnProcBufResBit = _mm256_sign_epi8(min, sgn);
|
||||
// p_cnProcBufResBit++;
|
||||
fprintf(fd," ((__m256i*)cnProcBufRes)[%d+i] = _mm256_sign_epi8(min, sgn);\n",(lut_startAddrCnGroups[5]>>5)+(j*bitOffsetInGroup));
|
||||
fprintf(fd," }\n");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
fprintf(fd,"}\n");
|
||||
fclose(fd);
|
||||
}//end of the function nrLDPC_cnProc_BG2
|
||||
|
||||
@@ -0,0 +1,50 @@
|
||||
/*
|
||||
* Licensed to the OpenAirInterface (OAI) Software Alliance under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright ownership.
|
||||
* The OpenAirInterface Software Alliance licenses this file to You under
|
||||
* the OAI Public License, Version 1.1 (the "License"); you may not use this file
|
||||
* except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.openairinterface.org/?page_id=698
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*-------------------------------------------------------------------------------
|
||||
* For more information about the OpenAirInterface (OAI) Software Alliance:
|
||||
* contact@openairinterface.org
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdint.h>
|
||||
#define NB_R 3
|
||||
void nrLDPC_cnProc_BG1_generator_AVX2(const char*, int);
|
||||
void nrLDPC_cnProc_BG2_generator_AVX2(const char*, int);
|
||||
|
||||
const char *__asan_default_options()
|
||||
{
|
||||
/* don't do leak checking in nr_ulsim, creates problems in the CI */
|
||||
return "detect_leaks=0";
|
||||
}
|
||||
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
if (argc != 2) {
|
||||
fprintf(stderr, "usage: %s <output-dir>\n", argv[0]);
|
||||
return 1;
|
||||
}
|
||||
const char *dir = argv[1];
|
||||
|
||||
int R[NB_R]={0,1,2};
|
||||
for(int i=0; i<NB_R;i++) {
|
||||
nrLDPC_cnProc_BG1_generator_AVX2(dir, R[i]);
|
||||
nrLDPC_cnProc_BG2_generator_AVX2(dir, R[i]);
|
||||
}
|
||||
|
||||
return(0);
|
||||
}
|
||||
|
||||
+25
@@ -0,0 +1,25 @@
|
||||
add_executable(cnProc_gen_avx512
|
||||
cnProc_gen_BG1_avx512.c
|
||||
cnProc_gen_BG2_avx512.c
|
||||
main.c)
|
||||
target_compile_options(cnProc_gen_avx512 PRIVATE -W -Wall -mavx2)
|
||||
|
||||
#set(cnProc_avx512_headers
|
||||
# cnProc_avx512/nrLDPC_cnProc_BG1_R13_AVX512.h
|
||||
# cnProc_avx512/nrLDPC_cnProc_BG1_R23_AVX512.h
|
||||
# cnProc_avx512/nrLDPC_cnProc_BG1_R89_AVX512.h
|
||||
# cnProc_avx512/nrLDPC_cnProc_BG2_R13_AVX512.h
|
||||
# cnProc_avx512/nrLDPC_cnProc_BG2_R15_AVX512.h
|
||||
# cnProc_avx512/nrLDPC_cnProc_BG2_R23_AVX512.h)
|
||||
|
||||
add_custom_command(TARGET cnProc_gen_avx512 POST_BUILD
|
||||
#OUTPUT ${cnProc_avx512_headers}
|
||||
COMMAND ${CMAKE_COMMAND} -E make_directory cnProc_avx512
|
||||
COMMAND cnProc_gen_avx512 .
|
||||
DEPENDS cnProc_gen_avx512
|
||||
COMMENT "Generating LDPC cnProc header files for AVX512"
|
||||
)
|
||||
|
||||
add_library(cnProc_gen_avx512_HEADERS INTERFACE)
|
||||
target_include_directories(cnProc_gen_avx512_HEADERS INTERFACE ${CMAKE_CURRENT_BINARY_DIR})
|
||||
add_dependencies(cnProc_gen_avx512_HEADERS cnProc_gen_avx512)
|
||||
+597
@@ -0,0 +1,597 @@
|
||||
/*
|
||||
* Licensed to the OpenAirInterface (OAI) Software Alliance under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright ownership.
|
||||
* The OpenAirInterface Software Alliance licenses this file to You under
|
||||
* the OAI Public License, Version 1.1 (the "License"); you may not use this file
|
||||
* except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.openairinterface.org/?page_id=698
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*-------------------------------------------------------------------------------
|
||||
* For more information about the OpenAirInterface (OAI) Software Alliance:
|
||||
* contact@openairinterface.org
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdint.h>
|
||||
#include <stdlib.h>
|
||||
#include "../../nrLDPCdecoder_defs.h"
|
||||
|
||||
void nrLDPC_cnProc_BG1_generator_AVX512(const char *dir, int R)
|
||||
{
|
||||
const char *ratestr[3]={"13","23","89"};
|
||||
|
||||
if (R<0 || R>2) {printf("Illegal R %d\n",R); abort();}
|
||||
|
||||
|
||||
// system("mkdir -p ../ldpc_gen_files");
|
||||
|
||||
char fname[FILENAME_MAX+1];
|
||||
snprintf(fname, sizeof(fname), "%s/cnProc_avx512/nrLDPC_cnProc_BG1_R%s_AVX512.h", dir, ratestr[R]);
|
||||
FILE *fd=fopen(fname,"w");
|
||||
if (fd == NULL) {
|
||||
printf("Cannot create file %s\n", fname);
|
||||
abort();
|
||||
}
|
||||
|
||||
// fprintf(fd,"#include <stdint.h>\n");
|
||||
// fprintf(fd,"#include <immintrin.h>\n");
|
||||
|
||||
|
||||
fprintf(fd, "#define conditional_negate(a,b,z) _mm512_mask_sub_epi8(a,_mm512_movepi8_mask(b),z,a)\n");
|
||||
|
||||
|
||||
fprintf(fd,"static inline void nrLDPC_cnProc_BG1_R%s_AVX512(int8_t* cnProcBuf, int8_t* cnProcBufRes, uint16_t Z) {\n",ratestr[R]);
|
||||
|
||||
const uint8_t* lut_numCnInCnGroups;
|
||||
const uint32_t* lut_startAddrCnGroups = lut_startAddrCnGroups_BG1;
|
||||
|
||||
if (R==0) lut_numCnInCnGroups = lut_numCnInCnGroups_BG1_R13;
|
||||
else if (R==1) lut_numCnInCnGroups = lut_numCnInCnGroups_BG1_R23;
|
||||
else if (R==2) lut_numCnInCnGroups = lut_numCnInCnGroups_BG1_R89;
|
||||
else { printf("aborting, illegal R %d\n",R); fclose(fd);abort();}
|
||||
|
||||
|
||||
|
||||
uint32_t j;
|
||||
uint32_t k;
|
||||
// Offset to each bit within a group in terms of 64 Byte
|
||||
uint32_t bitOffsetInGroup;
|
||||
|
||||
|
||||
fprintf(fd," uint32_t M, i;\n");
|
||||
fprintf(fd," __m512i zmm0, min, sgn,zeros,maxLLR, ones;\n");
|
||||
|
||||
fprintf(fd," zeros = _mm512_setzero_si512();\n");
|
||||
fprintf(fd," maxLLR = _mm512_set1_epi8((char)127);\n");
|
||||
fprintf(fd," ones = _mm512_set1_epi8((char)1);\n");
|
||||
|
||||
|
||||
|
||||
// =====================================================================
|
||||
// Process group with 3 BNs
|
||||
fprintf(fd,"//Process group with 3 BNs\n");
|
||||
// LUT with offsets for bits that need to be processed
|
||||
// 1. bit proc requires LLRs of 2. and 3. bit, 2.bits of 1. and 3. etc.
|
||||
// Offsets are in units of bitOffsetInGroup (1*384/32)12
|
||||
// Offsets are in units of bitOffsetInGroup (1*384/32)12
|
||||
|
||||
const uint8_t lut_idxCnProcG3[3][2] = {{12,24}, {0,24}, {0,12}};
|
||||
|
||||
if (lut_numCnInCnGroups[0] > 0)
|
||||
{
|
||||
// Number of groups of 64 CNs for parallel processing
|
||||
// Ceil for values not divisible by 64
|
||||
//M = (lut_numCnInCnGroups[0]*Z + 63)>>6;
|
||||
|
||||
fprintf(fd," M = (%d*Z + 63)>>6;\n",lut_numCnInCnGroups[0] );
|
||||
|
||||
// Set the offset to each bit within a group in terms of 64 Byte
|
||||
bitOffsetInGroup = (lut_numCnInCnGroups_BG1_R13[0]*NR_LDPC_ZMAX)>>6;
|
||||
|
||||
// Loop over every BN
|
||||
|
||||
for (j=0; j<3; j++)
|
||||
{
|
||||
|
||||
fprintf(fd," for (i=0;i<M;i++) {\n");
|
||||
// Abs and sign of 64 CNs (first BN)
|
||||
// zmm0 = p_cnProcBuf[lut_idxCnProcG3[j][0] + i];
|
||||
fprintf(fd," zmm0 = ((__m512i*)cnProcBuf)[%d+i];\n",(lut_startAddrCnGroups[0]>>6)+lut_idxCnProcG3[j][0]/2);
|
||||
fprintf(fd," sgn = _mm512_xor_si512(ones, zmm0);\n");
|
||||
fprintf(fd," min = _mm512_abs_epi8(zmm0);\n");
|
||||
|
||||
|
||||
// for (k=1; k<2; k++)
|
||||
//{
|
||||
fprintf(fd," zmm0 = ((__m512i*)cnProcBuf)[%d+i];\n",(lut_startAddrCnGroups[0]>>6)+lut_idxCnProcG3[j][1]/2);
|
||||
|
||||
// min = _mm512_min_epu8(min, _mm512_abs_epi8(zmm0));
|
||||
fprintf(fd," min = _mm512_min_epu8(min, _mm512_abs_epi8(zmm0));\n");
|
||||
|
||||
// sgn = _mm512_sign_epi8(*p_ones, zmm0);
|
||||
fprintf(fd," sgn = _mm512_xor_si512(sgn, zmm0);\n");
|
||||
// }
|
||||
|
||||
// Store result
|
||||
// min = _mm512_min_epu8(min, *maxLLR); // 128 in epi8 is -127
|
||||
fprintf(fd," min = _mm512_min_epu8(min, maxLLR);\n");
|
||||
// *p_cnProcBufResBit = _mm512_sign_epi8(min, sgn);
|
||||
// p_cnProcBufResBit++;
|
||||
fprintf(fd," ((__m512i*)cnProcBufRes)[%d+i] = conditional_negate(min, sgn,zeros);\n",(lut_startAddrCnGroups[0]>>6)+(j*bitOffsetInGroup));
|
||||
fprintf(fd," }\n");
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// =====================================================================
|
||||
// Process group with 4 BNs
|
||||
fprintf(fd,"//Process group with 4 BNs\n");
|
||||
// Offset is 5*384/32 = 30
|
||||
const uint8_t lut_idxCnProcG4[4][3] = {{60,120,180}, {0,120,180}, {0,60,180}, {0,60,120}};
|
||||
|
||||
if (lut_numCnInCnGroups[1] > 0)
|
||||
{
|
||||
// Number of groups of 64 CNs for parallel processing
|
||||
// Ceil for values not divisible by 64
|
||||
//M = (lut_numCnInCnGroups[1]*Z + 63)>>6;
|
||||
fprintf(fd," M = (%d*Z + 63)>>6;\n",lut_numCnInCnGroups[1] );
|
||||
// Set the offset to each bit within a group in terms of 64 Byte
|
||||
bitOffsetInGroup = (lut_numCnInCnGroups_BG1_R13[1]*NR_LDPC_ZMAX)>>6;
|
||||
|
||||
// Loop over every BN
|
||||
for (j=0; j<4; j++)
|
||||
{
|
||||
// Loop over CNs
|
||||
// for (i=0; i<M; i++,iprime++)
|
||||
// {
|
||||
fprintf(fd," for (i=0;i<M;i++) {\n");
|
||||
// Abs and sign of 64 CNs (first BN)
|
||||
// zmm0 = p_cnProcBuf[lut_idxCnProcG3[j][0] + i];
|
||||
fprintf(fd," zmm0 = ((__m512i*)cnProcBuf)[%d+i];\n",(lut_startAddrCnGroups[1]>>6)+lut_idxCnProcG4[j][0]/2);
|
||||
fprintf(fd," sgn = _mm512_xor_si512(ones, zmm0);\n");
|
||||
fprintf(fd," min = _mm512_abs_epi8(zmm0);\n");
|
||||
|
||||
|
||||
// Loop over BNs
|
||||
for (k=1; k<3; k++)
|
||||
{
|
||||
fprintf(fd," zmm0 = ((__m512i*)cnProcBuf)[%d+i];\n",(lut_startAddrCnGroups[1]>>6)+lut_idxCnProcG4[j][k]/2);
|
||||
|
||||
// min = _mm512_min_epu8(min, _mm512_abs_epi8(zmm0));
|
||||
fprintf(fd," min = _mm512_min_epu8(min, _mm512_abs_epi8(zmm0));\n");
|
||||
|
||||
// sgn = _mm512_sign_epi8(*p_ones, zmm0);
|
||||
fprintf(fd," sgn = _mm512_xor_si512(sgn, zmm0);\n");
|
||||
}
|
||||
|
||||
// Store result
|
||||
// min = _mm512_min_epu8(min, maxLLR); // 128 in epi8 is -127
|
||||
fprintf(fd," min = _mm512_min_epu8(min, maxLLR);\n");
|
||||
// *p_cnProcBufResBit = _mm512_sign_epi8(min, sgn);
|
||||
// p_cnProcBufResBit++;
|
||||
fprintf(fd," ((__m512i*)cnProcBufRes)[%d+i] = conditional_negate(min, sgn,zeros);\n",(lut_startAddrCnGroups[1]>>6)+(j*bitOffsetInGroup));
|
||||
fprintf(fd," }\n");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// =====================================================================
|
||||
// Process group with 5 BNs
|
||||
fprintf(fd,"//Process group with 5 BNs\n");
|
||||
// Offset is 18*384/32 = 216
|
||||
const uint16_t lut_idxCnProcG5[5][4] = {{216,432,648,864}, {0,432,648,864},
|
||||
{0,216,648,864}, {0,216,432,864}, {0,216,432,648}};
|
||||
|
||||
|
||||
if (lut_numCnInCnGroups[2] > 0)
|
||||
{
|
||||
// Number of groups of 64 CNs for parallel processing
|
||||
// Ceil for values not divisible by 64
|
||||
//M = (lut_numCnInCnGroups[2]*Z + 63)>>6;
|
||||
fprintf(fd," M = (%d*Z + 63)>>6;\n",lut_numCnInCnGroups[2] );
|
||||
|
||||
// Set the offset to each bit within a group in terms of 64 Byte
|
||||
bitOffsetInGroup = (lut_numCnInCnGroups_BG1_R13[2]*NR_LDPC_ZMAX)>>6;
|
||||
|
||||
// Loop over every BN
|
||||
|
||||
for (j=0; j<5; j++)
|
||||
{
|
||||
|
||||
fprintf(fd," for (i=0;i<M;i++) {\n");
|
||||
// Abs and sign of 64 CNs (first BN)
|
||||
// zmm0 = p_cnProcBuf[lut_idxCnProcG3[j][0] + i];
|
||||
fprintf(fd," zmm0 = ((__m512i*)cnProcBuf)[%d+i];\n",(lut_startAddrCnGroups[2]>>6)+lut_idxCnProcG5[j][0]/2);
|
||||
fprintf(fd," sgn = _mm512_xor_si512(ones, zmm0);\n");
|
||||
fprintf(fd," min = _mm512_abs_epi8(zmm0);\n");
|
||||
|
||||
|
||||
// Loop over BNs
|
||||
for (k=1; k<4; k++)
|
||||
{
|
||||
fprintf(fd," zmm0 = ((__m512i*)cnProcBuf)[%d+i];\n",(lut_startAddrCnGroups[2]>>6)+lut_idxCnProcG5[j][k]/2);
|
||||
|
||||
// min = _mm512_min_epu8(min, _mm512_abs_epi8(zmm0));
|
||||
fprintf(fd," min = _mm512_min_epu8(min, _mm512_abs_epi8(zmm0));\n");
|
||||
|
||||
// sgn = _mm512_sign_epi8(*p_ones, zmm0);
|
||||
fprintf(fd," sgn = _mm512_xor_si512(sgn, zmm0);\n");
|
||||
}
|
||||
|
||||
// Store result
|
||||
// min = _mm512_min_epu8(min, maxLLR); // 128 in epi8 is -127
|
||||
fprintf(fd," min = _mm512_min_epu8(min, maxLLR);\n");
|
||||
|
||||
fprintf(fd," ((__m512i*)cnProcBufRes)[%d+i] = conditional_negate(min, sgn,zeros);\n",(lut_startAddrCnGroups[2]>>6)+(j*bitOffsetInGroup));
|
||||
fprintf(fd," }\n");
|
||||
}
|
||||
}
|
||||
|
||||
// =====================================================================
|
||||
// Process group with 6 BNs
|
||||
fprintf(fd,"//Process group with 6 BNs\n");
|
||||
// Offset is 8*384/32 = 48
|
||||
const uint16_t lut_idxCnProcG6[6][5] = {{96,192,288,384,480}, {0,192,288,384,480},
|
||||
{0,96,288,384,480}, {0,96,192,384,480},
|
||||
{0,96,192,288,480}, {0,96,192,288,384}};
|
||||
|
||||
|
||||
if (lut_numCnInCnGroups[3] > 0)
|
||||
{
|
||||
// Number of groups of 64 CNs for parallel processing
|
||||
// Ceil for values not divisible by 64
|
||||
//M = (lut_numCnInCnGroups[3]*Z + 63)>>6;
|
||||
|
||||
fprintf(fd, "M = (%d*Z + 63)>>6;\n",lut_numCnInCnGroups[3] );
|
||||
|
||||
// Set the offset to each bit within a group in terms of 64 Byte
|
||||
bitOffsetInGroup = (lut_numCnInCnGroups_BG1_R13[3]*NR_LDPC_ZMAX)>>6;
|
||||
|
||||
// Loop over every BN
|
||||
|
||||
for (j=0; j<6; j++)
|
||||
{
|
||||
|
||||
fprintf(fd," for (i=0;i<M;i++) {\n");
|
||||
// Abs and sign of 64 CNs (first BN)
|
||||
// zmm0 = p_cnProcBuf[lut_idxCnProcG3[j][0] + i];
|
||||
fprintf(fd," zmm0 = ((__m512i*)cnProcBuf)[%d+i];\n",(lut_startAddrCnGroups[3]>>6)+lut_idxCnProcG6[j][0]/2);
|
||||
fprintf(fd," sgn = _mm512_xor_si512(ones, zmm0);\n");
|
||||
fprintf(fd," min = _mm512_abs_epi8(zmm0);\n");
|
||||
|
||||
|
||||
// Loop over BNs
|
||||
for (k=1; k<5; k++)
|
||||
{
|
||||
fprintf(fd," zmm0 = ((__m512i*)cnProcBuf)[%d+i];\n",(lut_startAddrCnGroups[3]>>6)+lut_idxCnProcG6[j][k]/2);
|
||||
|
||||
// min = _mm512_min_epu8(min, _mm512_abs_epi8(zmm0));
|
||||
fprintf(fd," min = _mm512_min_epu8(min, _mm512_abs_epi8(zmm0));\n");
|
||||
|
||||
// sgn = _mm512_sign_epi8(*p_ones, zmm0);
|
||||
fprintf(fd," sgn = _mm512_xor_si512(sgn, zmm0);\n");
|
||||
}
|
||||
|
||||
// Store result
|
||||
// min = _mm512_min_epu8(min, maxLLR); // 128 in epi8 is -127
|
||||
fprintf(fd," min = _mm512_min_epu8(min, maxLLR);\n");
|
||||
|
||||
fprintf(fd," ((__m512i*)cnProcBufRes)[%d+i] = conditional_negate(min, sgn,zeros);\n",(lut_startAddrCnGroups[3]>>6)+(j*bitOffsetInGroup));
|
||||
fprintf(fd," }\n");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// =====================================================================
|
||||
// Process group with 7 BNs
|
||||
fprintf(fd,"//Process group with 7 BNs\n");
|
||||
// Offset is 5*384/32 = 30
|
||||
const uint16_t lut_idxCnProcG7[7][6] = {{60,120,180,240,300,360}, {0,120,180,240,300,360},
|
||||
{0,60,180,240,300,360}, {0,60,120,240,300,360},
|
||||
{0,60,120,180,300,360}, {0,60,120,180,240,360},
|
||||
{0,60,120,180,240,300}};
|
||||
|
||||
|
||||
if (lut_numCnInCnGroups[4] > 0)
|
||||
{
|
||||
// Number of groups of 64 CNs for parallel processing
|
||||
// Ceil for values not divisible by 64
|
||||
// M = (lut_numCnInCnGroups[4]*Z + 63)>>6;
|
||||
fprintf(fd, "M = (%d*Z + 63)>>6;\n",lut_numCnInCnGroups[4] );
|
||||
|
||||
// Set the offset to each bit within a group in terms of 64 Byte
|
||||
bitOffsetInGroup = (lut_numCnInCnGroups_BG1_R13[4]*NR_LDPC_ZMAX)>>6;
|
||||
|
||||
// Loop over every BN
|
||||
|
||||
for (j=0; j<7; j++)
|
||||
{
|
||||
// Loop over CNs
|
||||
// for (i=0; i<M; i++,iprime++)
|
||||
// {
|
||||
fprintf(fd," for (i=0;i<M;i++) {\n");
|
||||
// Abs and sign of 64 CNs (first BN)
|
||||
// zmm0 = p_cnProcBuf[lut_idxCnProcG3[j][0] + i];
|
||||
fprintf(fd," zmm0= ((__m512i*)cnProcBuf)[%d+i];\n",(lut_startAddrCnGroups[4]>>6)+lut_idxCnProcG7[j][0]/2);
|
||||
fprintf(fd," sgn = _mm512_xor_si512(ones, zmm0);\n");
|
||||
fprintf(fd," min = _mm512_abs_epi8(zmm0);\n");
|
||||
|
||||
|
||||
// Loop over BNs
|
||||
for (k=1; k<6; k++)
|
||||
{
|
||||
fprintf(fd," zmm0 = ((__m512i*)cnProcBuf)[%d+i];\n",(lut_startAddrCnGroups[4]>>6)+lut_idxCnProcG7[j][k]/2);
|
||||
|
||||
// min = _mm512_min_epu8(min, _mm512_abs_epi8(zmm0));
|
||||
fprintf(fd," min = _mm512_min_epu8(min, _mm512_abs_epi8(zmm0));\n");
|
||||
|
||||
// sgn = _mm512_sign_epi8(*p_ones, zmm0);
|
||||
fprintf(fd," sgn = _mm512_xor_si512(sgn, zmm0);\n");
|
||||
}
|
||||
|
||||
// Store result
|
||||
// min = _mm512_min_epu8(min, maxLLR); // 128 in epi8 is -127
|
||||
fprintf(fd," min = _mm512_min_epu8(min, maxLLR);\n");
|
||||
|
||||
fprintf(fd," ((__m512i*)cnProcBufRes)[%d+i] = conditional_negate(min, sgn,zeros);\n",(lut_startAddrCnGroups[4]>>6)+(j*bitOffsetInGroup));
|
||||
fprintf(fd," }\n");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// =====================================================================
|
||||
// Process group with 8 BNs
|
||||
fprintf(fd,"//Process group with 8 BNs\n");
|
||||
// Offset is 2*384/32 = 24
|
||||
const uint8_t lut_idxCnProcG8[8][7] = {{24,48,72,96,120,144,168}, {0,48,72,96,120,144,168},
|
||||
{0,24,72,96,120,144,168}, {0,24,48,96,120,144,168},
|
||||
{0,24,48,72,120,144,168}, {0,24,48,72,96,144,168},
|
||||
{0,24,48,72,96,120,168}, {0,24,48,72,96,120,144}};
|
||||
|
||||
|
||||
if (lut_numCnInCnGroups[5] > 0)
|
||||
{
|
||||
// Number of groups of 64 CNs for parallel processing
|
||||
// Ceil for values not divisible by 64
|
||||
// M = (lut_numCnInCnGroups[5]*Z + 63)>>6;
|
||||
fprintf(fd, "M = (%d*Z + 63)>>6;\n",lut_numCnInCnGroups[5] );
|
||||
|
||||
// Set the offset to each bit within a group in terms of 64 Byte
|
||||
bitOffsetInGroup = (lut_numCnInCnGroups_BG1_R13[5]*NR_LDPC_ZMAX)>>6;
|
||||
|
||||
// Loop over every BN
|
||||
|
||||
for (j=0; j<8; j++)
|
||||
{
|
||||
// Loop over CNs
|
||||
// for (i=0; i<M; i++,iprime++)
|
||||
// {
|
||||
fprintf(fd," for (i=0;i<M;i++) {\n");
|
||||
// Abs and sign of 64 CNs (first BN)
|
||||
// zmm0 = p_cnProcBuf[lut_idxCnProcG3[j][0] + i];
|
||||
fprintf(fd," zmm0 = ((__m512i*)cnProcBuf)[%d+i];\n",(lut_startAddrCnGroups[5]>>6)+lut_idxCnProcG8[j][0]/2);
|
||||
fprintf(fd," sgn = _mm512_xor_si512(ones, zmm0);\n");
|
||||
fprintf(fd," min = _mm512_abs_epi8(zmm0);\n");
|
||||
|
||||
|
||||
// Loop over BNs
|
||||
for (k=1; k<7; k++)
|
||||
{
|
||||
fprintf(fd," zmm0 = ((__m512i*)cnProcBuf)[%d+i];\n",(lut_startAddrCnGroups[5]>>6)+lut_idxCnProcG8[j][k]/2);
|
||||
|
||||
// min = _mm512_min_epu8(min, _mm512_abs_epi8(zmm0));
|
||||
fprintf(fd," min = _mm512_min_epu8(min, _mm512_abs_epi8(zmm0));\n");
|
||||
|
||||
// sgn = _mm512_sign_epi8(*p_ones, zmm0);
|
||||
fprintf(fd," sgn = _mm512_xor_si512(sgn, zmm0);\n");
|
||||
}
|
||||
|
||||
// Store result
|
||||
// min = _mm512_min_epu8(min, maxLLR); // 128 in epi8 is -127
|
||||
fprintf(fd," min = _mm512_min_epu8(min, maxLLR);\n");
|
||||
|
||||
fprintf(fd," ((__m512i*)cnProcBufRes)[%d+i] = conditional_negate(min, sgn,zeros);\n",(lut_startAddrCnGroups[5]>>6)+(j*bitOffsetInGroup));
|
||||
fprintf(fd," }\n");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// =====================================================================
|
||||
// Process group with 9 BNs
|
||||
|
||||
fprintf(fd,"//Process group with 9 BNs\n");
|
||||
// Offset is 2*384/32 = 12
|
||||
const uint8_t lut_idxCnProcG9[9][8] = {{24,48,72,96,120,144,168,192}, {0,48,72,96,120,144,168,192},
|
||||
{0,24,72,96,120,144,168,192}, {0,24,48,96,120,144,168,192},
|
||||
{0,24,48,72,120,144,168,192}, {0,24,48,72,96,144,168,192},
|
||||
{0,24,48,72,96,120,168,192}, {0,24,48,72,96,120,144,192},
|
||||
{0,24,48,72,96,120,144,168}};
|
||||
|
||||
|
||||
if (lut_numCnInCnGroups[6] > 0)
|
||||
{
|
||||
// Number of groups of 64 CNs for parallel processing
|
||||
// Ceil for values not divisible by 64
|
||||
// M = (lut_numCnInCnGroups[5]*Z + 63)>>6;
|
||||
fprintf(fd, "M = (%d*Z + 63)>>6;\n",lut_numCnInCnGroups[6] );
|
||||
|
||||
// Set the offset to each bit within a group in terms of 64 Byte
|
||||
bitOffsetInGroup = (lut_numCnInCnGroups_BG1_R13[6]*NR_LDPC_ZMAX)>>6;
|
||||
|
||||
// Loop over every BN
|
||||
|
||||
for (j=0; j<9; j++)
|
||||
{
|
||||
// Loop over CNs
|
||||
// for (i=0; i<M; i++,iprime++)
|
||||
// {
|
||||
fprintf(fd," for (i=0;i<M;i++) {\n");
|
||||
// Abs and sign of 64 CNs (first BN)
|
||||
// zmm0 = p_cnProcBuf[lut_idxCnProcG3[j][0] + i];
|
||||
fprintf(fd," zmm0 = ((__m512i*)cnProcBuf)[%d+i];\n",(lut_startAddrCnGroups[6]>>6)+lut_idxCnProcG9[j][0]/2);
|
||||
fprintf(fd," sgn = _mm512_xor_si512(ones, zmm0);\n");
|
||||
fprintf(fd," min = _mm512_abs_epi8(zmm0);\n");
|
||||
|
||||
|
||||
// Loop over BNs
|
||||
for (k=1; k<8; k++)
|
||||
{
|
||||
fprintf(fd," zmm0 = ((__m512i*)cnProcBuf)[%d+i];\n",(lut_startAddrCnGroups[6]>>6)+lut_idxCnProcG9[j][k]/2);
|
||||
|
||||
// min = _mm512_min_epu8(min, _mm512_abs_epi8(zmm0));
|
||||
fprintf(fd," min = _mm512_min_epu8(min, _mm512_abs_epi8(zmm0));\n");
|
||||
|
||||
// sgn = _mm512_sign_epi8(*p_ones, zmm0);
|
||||
fprintf(fd," sgn = _mm512_xor_si512(sgn, zmm0);\n");
|
||||
}
|
||||
|
||||
// Store result
|
||||
// min = _mm512_min_epu8(min, maxLLR); // 128 in epi8 is -127
|
||||
fprintf(fd," min = _mm512_min_epu8(min, maxLLR);\n");
|
||||
|
||||
fprintf(fd," ((__m512i*)cnProcBufRes)[%d+i] = conditional_negate(min, sgn,zeros);\n",(lut_startAddrCnGroups[6]>>6)+(j*bitOffsetInGroup));
|
||||
fprintf(fd," }\n");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
// =====================================================================
|
||||
// Process group with 10 BNs
|
||||
fprintf(fd,"//Process group with 10 BNs\n");
|
||||
// Offset is 1*384/32 = 6
|
||||
const uint8_t lut_idxCnProcG10[10][9] = {{12,24,36,48,60,72,84,96,108}, {0,24,36,48,60,72,84,96,108},
|
||||
{0,12,36,48,60,72,84,96,108}, {0,12,24,48,60,72,84,96,108},
|
||||
{0,12,24,36,60,72,84,96,108}, {0,12,24,36,48,72,84,96,108},
|
||||
{0,12,24,36,48,60,84,96,108}, {0,12,24,36,48,60,72,96,108},
|
||||
{0,12,24,36,48,60,72,84,108}, {0,12,24,36,48,60,72,84,96}};
|
||||
|
||||
if (lut_numCnInCnGroups[7] > 0)
|
||||
{
|
||||
// Number of groups of 64 CNs for parallel processing
|
||||
// Ceil for values not divisible by 64
|
||||
//M = (lut_numCnInCnGroups[7]*Z + 63)>>6;
|
||||
fprintf(fd, " M = (%d*Z + 63)>>6;\n",lut_numCnInCnGroups[7] );
|
||||
|
||||
// Set the offset to each bit within a group in terms of 64 Byte
|
||||
bitOffsetInGroup = (lut_numCnInCnGroups_BG1_R13[7]*NR_LDPC_ZMAX)>>6;
|
||||
|
||||
|
||||
// Loop over every BN
|
||||
|
||||
for (j=0; j<10; j++)
|
||||
{
|
||||
// Loop over CNs
|
||||
// for (i=0; i<M; i++,iprime++)
|
||||
// {
|
||||
fprintf(fd," for (i=0;i<M;i++) {\n");
|
||||
// Abs and sign of 64 CNs (first BN)
|
||||
// zmm0 = p_cnProcBuf[lut_idxCnProcG3[j][0] + i];
|
||||
fprintf(fd," zmm0 = ((__m512i*)cnProcBuf)[%d+i];\n",(lut_startAddrCnGroups[7]>>6)+lut_idxCnProcG10[j][0]/2);
|
||||
fprintf(fd," sgn = _mm512_xor_si512(ones, zmm0);\n");
|
||||
fprintf(fd," min = _mm512_abs_epi8(zmm0);\n");
|
||||
|
||||
|
||||
// Loop over BNs
|
||||
for (k=1; k<9; k++)
|
||||
{
|
||||
fprintf(fd," zmm0 = ((__m512i*)cnProcBuf)[%d+i];\n",(lut_startAddrCnGroups[7]>>6)+lut_idxCnProcG10[j][k]/2);
|
||||
|
||||
// min = _mm512_min_epu8(min, _mm512_abs_epi8(zmm0));
|
||||
fprintf(fd," min = _mm512_min_epu8(min, _mm512_abs_epi8(zmm0));\n");
|
||||
|
||||
// sgn = _mm512_sign_epi8(*p_ones, zmm0);
|
||||
fprintf(fd," sgn = _mm512_xor_si512(sgn, zmm0);\n");
|
||||
}
|
||||
|
||||
// Store result
|
||||
// min = _mm512_min_epu8(min, maxLLR); // 128 in epi8 is -127
|
||||
fprintf(fd," min = _mm512_min_epu8(min, maxLLR);\n");
|
||||
|
||||
fprintf(fd," ((__m512i*)cnProcBufRes)[%d+i] = conditional_negate(min,sgn,zeros);\n",(lut_startAddrCnGroups[7]>>6)+(j*bitOffsetInGroup));
|
||||
fprintf(fd," }\n");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// =====================================================================
|
||||
// Process group with 19 BNs
|
||||
fprintf(fd,"//Process group with 19 BNs\n");
|
||||
// Offset is 4*384/32 = 24
|
||||
const uint16_t lut_idxCnProcG19[19][18] = {{48,96,144,192,240,288,336,384,432,480,528,576,624,672,720,768,816,864}, {0,96,144,192,240,288,336,384,432,480,528,576,624,672,720,768,816,864},
|
||||
{0,48,144,192,240,288,336,384,432,480,528,576,624,672,720,768,816,864}, {0,48,96,192,240,288,336,384,432,480,528,576,624,672,720,768,816,864},
|
||||
{0,48,96,144,240,288,336,384,432,480,528,576,624,672,720,768,816,864}, {0,48,96,144,192,288,336,384,432,480,528,576,624,672,720,768,816,864},
|
||||
{0,48,96,144,192,240,336,384,432,480,528,576,624,672,720,768,816,864}, {0,48,96,144,192,240,288,384,432,480,528,576,624,672,720,768,816,864},
|
||||
{0,48,96,144,192,240,288,336,432,480,528,576,624,672,720,768,816,864}, {0,48,96,144,192,240,288,336,384,480,528,576,624,672,720,768,816,864},
|
||||
{0,48,96,144,192,240,288,336,384,432,528,576,624,672,720,768,816,864}, {0,48,96,144,192,240,288,336,384,432,480,576,624,672,720,768,816,864},
|
||||
{0,48,96,144,192,240,288,336,384,432,480,528,624,672,720,768,816,864}, {0,48,96,144,192,240,288,336,384,432,480,528,576,672,720,768,816,864},
|
||||
{0,48,96,144,192,240,288,336,384,432,480,528,576,624,720,768,816,864}, {0,48,96,144,192,240,288,336,384,432,480,528,576,624,672,768,816,864},
|
||||
{0,48,96,144,192,240,288,336,384,432,480,528,576,624,672,720,816,864}, {0,48,96,144,192,240,288,336,384,432,480,528,576,624,672,720,768,864},
|
||||
{0,48,96,144,192,240,288,336,384,432,480,528,576,624,672,720,768,816}};
|
||||
|
||||
|
||||
if (lut_numCnInCnGroups[8] > 0)
|
||||
{
|
||||
// Number of groups of 64 CNs for parallel processing
|
||||
// Ceil for values not divisible by 64
|
||||
// M = (lut_numCnInCnGroups[8]*Z + 63)>>6;
|
||||
fprintf(fd, " M = (%d*Z + 63)>>6;\n",lut_numCnInCnGroups[8] );
|
||||
|
||||
// Set the offset to each bit within a group in terms of 64 Byte
|
||||
bitOffsetInGroup = (lut_numCnInCnGroups_BG1_R13[8]*NR_LDPC_ZMAX)>>6;
|
||||
|
||||
// Loop over every BN
|
||||
|
||||
for (j=0; j<19; j++)
|
||||
{
|
||||
// Loop over CNs
|
||||
// for (i=0; i<M; i++,iprime++)
|
||||
// {
|
||||
fprintf(fd," for (i=0;i<M;i++) {\n");
|
||||
// Abs and sign of 64 CNs (first BN)
|
||||
// zmm0 = p_cnProcBuf[lut_idxCnProcG3[j][0] + i];
|
||||
fprintf(fd," zmm0 = ((__m512i*)cnProcBuf)[%d+i];\n",(lut_startAddrCnGroups[8]>>6)+lut_idxCnProcG19[j][0]/2);
|
||||
fprintf(fd," sgn = _mm512_xor_si512(ones, zmm0);\n");
|
||||
fprintf(fd," min = _mm512_abs_epi8(zmm0);\n");
|
||||
|
||||
|
||||
// Loop over BNs
|
||||
for (k=1; k<18; k++)
|
||||
{
|
||||
fprintf(fd," zmm0 = ((__m512i*)cnProcBuf)[%d+i];\n",(lut_startAddrCnGroups[8]>>6)+lut_idxCnProcG19[j][k]/2);
|
||||
|
||||
// min = _mm512_min_epu8(min, _mm512_abs_epi8(zmm0));
|
||||
fprintf(fd," min = _mm512_min_epu8(min, _mm512_abs_epi8(zmm0));\n");
|
||||
|
||||
// sgn = _mm512_sign_epi8(*p_ones, zmm0);
|
||||
fprintf(fd," sgn = _mm512_xor_si512(sgn, zmm0);\n");
|
||||
}
|
||||
|
||||
// Store result
|
||||
// min = _mm512_min_epu8(min, maxLLR); // 128 in epi8 is -127
|
||||
fprintf(fd," min = _mm512_min_epu8(min, maxLLR);\n");
|
||||
|
||||
fprintf(fd," ((__m512i*)cnProcBufRes)[%d+i] = conditional_negate(min, sgn,zeros);\n",(lut_startAddrCnGroups[8]>>6)+(j*bitOffsetInGroup));
|
||||
fprintf(fd," }\n");
|
||||
}
|
||||
}
|
||||
|
||||
fprintf(fd,"}\n");
|
||||
fclose(fd);
|
||||
}//end of the function nrLDPC_cnProc_BG1
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
+414
@@ -0,0 +1,414 @@
|
||||
/*
|
||||
* Licensed to the OpenAirInterface (OAI) Software Alliance under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright ownership.
|
||||
* The OpenAirInterface Software Alliance licenses this file to You under
|
||||
* the OAI Public License, Version 1.1 (the "License"); you may not use this file
|
||||
* except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.openairinterface.org/?page_id=698
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*-------------------------------------------------------------------------------
|
||||
* For more information about the OpenAirInterface (OAI) Software Alliance:
|
||||
* contact@openairinterface.org
|
||||
*/
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include <stdint.h>
|
||||
#include "../../nrLDPCdecoder_defs.h"
|
||||
|
||||
void nrLDPC_cnProc_BG2_generator_AVX512(const char *dir, int R)
|
||||
{
|
||||
const char *ratestr[3]={"15","13","23"};
|
||||
|
||||
if (R<0 || R>2) {printf("Illegal R %d\n",R); abort();}
|
||||
|
||||
|
||||
// system("mkdir -p ../ldpc_gen_files");
|
||||
|
||||
char fname[FILENAME_MAX+1];
|
||||
snprintf(fname, sizeof(fname), "%s/cnProc_avx512/nrLDPC_cnProc_BG2_R%s_AVX512.h", dir, ratestr[R]);
|
||||
FILE *fd=fopen(fname,"w");
|
||||
if (fd == NULL) {
|
||||
printf("Cannot create file %s\n", fname);
|
||||
abort();
|
||||
}
|
||||
|
||||
//fprintf(fd,"#include <stdint.h>\n");
|
||||
// fprintf(fd,"#include <immintrin.h>\n");
|
||||
|
||||
|
||||
fprintf(fd, "#define conditional_negate(a,b,z) _mm512_mask_sub_epi8(a,_mm512_movepi8_mask(b),z,a)\n");
|
||||
|
||||
|
||||
|
||||
fprintf(fd,"static inline void nrLDPC_cnProc_BG2_R%s_AVX512(int8_t* cnProcBuf, int8_t* cnProcBufRes, uint16_t Z) {\n",ratestr[R]);
|
||||
const uint8_t* lut_numCnInCnGroups;
|
||||
const uint32_t* lut_startAddrCnGroups = lut_startAddrCnGroups_BG2;
|
||||
|
||||
if (R==0) lut_numCnInCnGroups = lut_numCnInCnGroups_BG2_R15;
|
||||
else if (R==1) lut_numCnInCnGroups = lut_numCnInCnGroups_BG2_R13;
|
||||
else if (R==2) lut_numCnInCnGroups = lut_numCnInCnGroups_BG2_R23;
|
||||
else { printf("aborting, illegal R %d\n",R); fclose(fd);abort();}
|
||||
|
||||
|
||||
// Number of CNs in Groups
|
||||
//uint32_t M;
|
||||
uint32_t j;
|
||||
uint32_t k;
|
||||
// Offset to each bit within a group in terms of 64 Byte
|
||||
uint32_t bitOffsetInGroup;
|
||||
|
||||
fprintf(fd," uint32_t M;\n");
|
||||
fprintf(fd," __m512i zmm0, min, sgn,zeros,ones,maxLLR;\n");
|
||||
fprintf(fd," zeros = _mm512_setzero_si512();\n");
|
||||
fprintf(fd," maxLLR = _mm512_set1_epi8((char)127);\n");
|
||||
fprintf(fd," ones = _mm512_set1_epi8((char)1);\n");
|
||||
// =====================================================================
|
||||
// Process group with 3 BNs
|
||||
fprintf(fd,"//Process group with 3 BNs\n");
|
||||
// LUT with offsets for bits that need to be processed
|
||||
// 1. bit proc requires LLRs of 2. and 3. bit, 2.bits of 1. and 3. etc.
|
||||
// Offsets are in units of bitOffsetInGroup
|
||||
const uint8_t lut_idxCnProcG3[3][2] = {{72,144}, {0,144}, {0,72}};
|
||||
|
||||
|
||||
if (lut_numCnInCnGroups[0] > 0)
|
||||
{
|
||||
// Number of groups of 64 CNs for parallel processing
|
||||
// Ceil for values not divisible by 64
|
||||
fprintf(fd," M = (%d*Z + 63)>>6;\n",lut_numCnInCnGroups[0] );
|
||||
|
||||
// Set the offset to each bit within a group in terms of 64 Byte
|
||||
bitOffsetInGroup = (lut_numCnInCnGroups_BG2_R15[0]*NR_LDPC_ZMAX)>>6;
|
||||
|
||||
|
||||
// Loop over every BN
|
||||
|
||||
for (j=0; j<3; j++)
|
||||
{
|
||||
|
||||
|
||||
|
||||
fprintf(fd," for (int i=0;i<M;i++) {\n");
|
||||
// Abs and sign of 64 CNs (first BN)
|
||||
// zmm0 = p_cnProcBuf[lut_idxCnProcG3[j][0] + i];
|
||||
fprintf(fd," zmm0 = ((__m512i*)cnProcBuf)[%d+i];\n",(lut_startAddrCnGroups[0]>>6)+lut_idxCnProcG3[j][0]/2);
|
||||
fprintf(fd," sgn = _mm512_xor_si512(ones, zmm0);\n");
|
||||
fprintf(fd," min = _mm512_abs_epi8(zmm0);\n");
|
||||
|
||||
|
||||
// for (k=1; k<2; k++)
|
||||
//{
|
||||
fprintf(fd," zmm0 = ((__m512i*)cnProcBuf)[%d+i];\n",(lut_startAddrCnGroups[0]>>6)+lut_idxCnProcG3[j][1]/2);
|
||||
|
||||
// min = _mm512_min_epu8(min, _mm512_abs_epi8(zmm0));
|
||||
fprintf(fd," min = _mm512_min_epu8(min, _mm512_abs_epi8(zmm0));\n");
|
||||
|
||||
// sgn = _mm512_sign_epi8(*p_ones, zmm0);
|
||||
fprintf(fd," sgn = _mm512_xor_si512(sgn, zmm0);\n");
|
||||
// }
|
||||
|
||||
// Store result
|
||||
// min = _mm512_min_epu8(min, *maxLLR); // 128 in epi8 is -127
|
||||
fprintf(fd," min = _mm512_min_epu8(min, maxLLR);\n");
|
||||
// *p_cnProcBufResBit = _mm512_sign_epi8(min, sgn);
|
||||
// p_cnProcBufResBit++;
|
||||
fprintf(fd," ((__m512i*)cnProcBufRes)[%d+i] = conditional_negate(min, sgn,zeros);\n",(lut_startAddrCnGroups[0]>>6)+(j*bitOffsetInGroup));
|
||||
fprintf(fd," }\n");
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
// =====================================================================
|
||||
// Process group with 4 BNs
|
||||
fprintf(fd,"//Process group with 4 BNs\n");
|
||||
// Offset is 20*384/32 = 240
|
||||
const uint16_t lut_idxCnProcG4[4][3] = {{240,480,720}, {0,480,720}, {0,240,720}, {0,240,480}};
|
||||
|
||||
|
||||
if (lut_numCnInCnGroups[1] > 0)
|
||||
{
|
||||
// Number of groups of 64 CNs for parallel processing
|
||||
// Ceil for values not divisible by 64
|
||||
fprintf(fd," M = (%d*Z + 63)>>6;\n",lut_numCnInCnGroups[1] );
|
||||
|
||||
// Set the offset to each bit within a group in terms of 64 Byte
|
||||
bitOffsetInGroup = (lut_numCnInCnGroups_BG2_R15[1]*NR_LDPC_ZMAX)>>6;
|
||||
|
||||
// Loop over every BN
|
||||
for (j=0; j<4; j++)
|
||||
{
|
||||
fprintf(fd," for (int i=0;i<M;i++) {\n");
|
||||
// Abs and sign of 64 CNs (first BN)
|
||||
// zmm0 = p_cnProcBuf[lut_idxCnProcG3[j][0] + i];
|
||||
fprintf(fd," zmm0 = ((__m512i*)cnProcBuf)[%d+i];\n",(lut_startAddrCnGroups[1]>>6)+lut_idxCnProcG4[j][0]/2);
|
||||
fprintf(fd," sgn = _mm512_xor_si512(ones, zmm0);\n");
|
||||
fprintf(fd," min = _mm512_abs_epi8(zmm0);\n");
|
||||
|
||||
|
||||
// Loop over BNs
|
||||
for (k=1; k<3; k++)
|
||||
{
|
||||
fprintf(fd," zmm0 = ((__m512i*)cnProcBuf)[%d+i];\n",(lut_startAddrCnGroups[1]>>6)+lut_idxCnProcG4[j][k]/2);
|
||||
|
||||
// min = _mm512_min_epu8(min, _mm512_abs_epi8(zmm0));
|
||||
fprintf(fd," min = _mm512_min_epu8(min, _mm512_abs_epi8(zmm0));\n");
|
||||
|
||||
// sgn = _mm512_sign_epi8(sgn, zmm0);
|
||||
fprintf(fd," sgn = _mm512_xor_si512(sgn, zmm0);\n");
|
||||
}
|
||||
|
||||
// Store result
|
||||
// min = _mm512_min_epu8(min, maxLLR); // 128 in epi8 is -127
|
||||
fprintf(fd," min = _mm512_min_epu8(min, maxLLR);\n");
|
||||
// *p_cnProcBufResBit = _mm512_sign_epi8(min, sgn);
|
||||
// p_cnProcBufResBit++;
|
||||
fprintf(fd," ((__m512i*)cnProcBufRes)[%d+i] = conditional_negate(min, sgn,zeros);\n",(lut_startAddrCnGroups[1]>>6)+(j*bitOffsetInGroup));
|
||||
fprintf(fd," }\n");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// =====================================================================
|
||||
// Process group with 5 BNs
|
||||
fprintf(fd,"//Process group with 5 BNs\n");
|
||||
// Offset is 9*384/32 = 108
|
||||
const uint16_t lut_idxCnProcG5[5][4] = {{108,216,324,432}, {0,216,324,432},
|
||||
{0,108,324,432}, {0,108,216,432}, {0,108,216,324}};
|
||||
|
||||
|
||||
|
||||
|
||||
if (lut_numCnInCnGroups[2] > 0)
|
||||
{
|
||||
// Number of groups of 64 CNs for parallel processing
|
||||
// Ceil for values not divisible by 64
|
||||
fprintf(fd," M = (%d*Z + 63)>>6;\n",lut_numCnInCnGroups[2] );
|
||||
|
||||
// Set the offset to each bit within a group in terms of 64 Byte
|
||||
bitOffsetInGroup = (lut_numCnInCnGroups_BG2_R15[2]*NR_LDPC_ZMAX)>>6;
|
||||
|
||||
// Loop over every BN
|
||||
|
||||
for (j=0; j<5; j++)
|
||||
{
|
||||
|
||||
fprintf(fd," for (int i=0;i<M;i++) {\n");
|
||||
// Abs and sign of 64 CNs (first BN)
|
||||
// zmm0 = p_cnProcBuf[lut_idxCnProcG3[j][0] + i];
|
||||
fprintf(fd," zmm0 = ((__m512i*)cnProcBuf)[%d+i];\n",(lut_startAddrCnGroups[2]>>6)+lut_idxCnProcG5[j][0]/2);
|
||||
fprintf(fd," sgn = _mm512_xor_si512(ones, zmm0);\n");
|
||||
fprintf(fd," min = _mm512_abs_epi8(zmm0);\n");
|
||||
|
||||
|
||||
// Loop over BNs
|
||||
for (k=1; k<4; k++)
|
||||
{
|
||||
fprintf(fd," zmm0 = ((__m512i*)cnProcBuf)[%d+i];\n",(lut_startAddrCnGroups[2]>>6)+lut_idxCnProcG5[j][k]/2);
|
||||
|
||||
// min = _mm512_min_epu8(min, _mm512_abs_epi8(zmm0));
|
||||
fprintf(fd," min = _mm512_min_epu8(min, _mm512_abs_epi8(zmm0));\n");
|
||||
|
||||
// sgn = _mm512_sign_epi8(sgn, zmm0);
|
||||
fprintf(fd," sgn = _mm512_xor_si512(sgn, zmm0);\n");
|
||||
}
|
||||
|
||||
// Store result
|
||||
// min = _mm512_min_epu8(min, maxLLR); // 128 in epi8 is -127
|
||||
fprintf(fd," min = _mm512_min_epu8(min, maxLLR);\n");
|
||||
|
||||
fprintf(fd," ((__m512i*)cnProcBufRes)[%d+i] = conditional_negate(min, sgn,zeros);\n",(lut_startAddrCnGroups[2]>>6)+(j*bitOffsetInGroup));
|
||||
fprintf(fd," }\n");
|
||||
}
|
||||
}
|
||||
|
||||
// =====================================================================
|
||||
// Process group with 6 BNs
|
||||
fprintf(fd,"//Process group with 6 BNs\n");
|
||||
// Offset is 3*384/32 = 36
|
||||
const uint16_t lut_idxCnProcG6[6][5] = {{36,72,108,144,180}, {0,72,108,144,180},
|
||||
{0,36,108,144,180}, {0,36,72,144,180},
|
||||
{0,36,72,108,180}, {0,36,72,108,144}};
|
||||
|
||||
|
||||
|
||||
|
||||
if (lut_numCnInCnGroups[3] > 0)
|
||||
{
|
||||
// Number of groups of 64 CNs for parallel processing
|
||||
// Ceil for values not divisible by 64
|
||||
fprintf(fd," M = (%d*Z + 63)>>6;\n",lut_numCnInCnGroups[3] );
|
||||
|
||||
// Set the offset to each bit within a group in terms of 64 Byte
|
||||
bitOffsetInGroup = (lut_numCnInCnGroups_BG2_R15[3]*NR_LDPC_ZMAX)>>6;
|
||||
|
||||
// Loop over every BN
|
||||
|
||||
for (j=0; j<6; j++)
|
||||
{
|
||||
|
||||
fprintf(fd," for (int i=0;i<M;i++) {\n");
|
||||
// Abs and sign of 64 CNs (first BN)
|
||||
// zmm0 = p_cnProcBuf[lut_idxCnProcG3[j][0] + i];
|
||||
fprintf(fd," zmm0 = ((__m512i*)cnProcBuf)[%d+i];\n",(lut_startAddrCnGroups[3]>>6)+lut_idxCnProcG6[j][0]/2);
|
||||
fprintf(fd," sgn = _mm512_xor_si512(ones, zmm0);\n");
|
||||
fprintf(fd," min = _mm512_abs_epi8(zmm0);\n");
|
||||
|
||||
|
||||
// Loop over BNs
|
||||
for (k=1; k<5; k++)
|
||||
{
|
||||
fprintf(fd," zmm0 = ((__m512i*)cnProcBuf)[%d+i];\n",(lut_startAddrCnGroups[3]>>6)+lut_idxCnProcG6[j][k]/2);
|
||||
|
||||
// min = _mm512_min_epu8(min, _mm512_abs_epi8(zmm0));
|
||||
fprintf(fd," min = _mm512_min_epu8(min, _mm512_abs_epi8(zmm0));\n");
|
||||
|
||||
// sgn = _mm512_sign_epi8(sgn, zmm0);
|
||||
fprintf(fd," sgn = _mm512_xor_si512(sgn, zmm0);\n");
|
||||
}
|
||||
|
||||
// Store result
|
||||
// min = _mm512_min_epu8(min, maxLLR); // 128 in epi8 is -127
|
||||
fprintf(fd," min = _mm512_min_epu8(min, maxLLR);\n");
|
||||
|
||||
fprintf(fd," ((__m512i*)cnProcBufRes)[%d+i] = conditional_negate(min, sgn,zeros);\n",(lut_startAddrCnGroups[3]>>6)+(j*bitOffsetInGroup));
|
||||
fprintf(fd," }\n");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
// =====================================================================
|
||||
// Process group with 8 BNs
|
||||
fprintf(fd,"//Process group with 8 BNs\n");
|
||||
// Offset is 2*384/32 = 24
|
||||
const uint8_t lut_idxCnProcG8[8][7] = {{24,48,72,96,120,144,168}, {0,48,72,96,120,144,168},
|
||||
{0,24,72,96,120,144,168}, {0,24,48,96,120,144,168},
|
||||
{0,24,48,72,120,144,168}, {0,24,48,72,96,144,168},
|
||||
{0,24,48,72,96,120,168}, {0,24,48,72,96,120,144}};
|
||||
|
||||
|
||||
|
||||
|
||||
if (lut_numCnInCnGroups[4] > 0)
|
||||
{
|
||||
// Number of groups of 64 CNs for parallel processing
|
||||
// Ceil for values not divisible by 64
|
||||
fprintf(fd," M = (%d*Z + 63)>>6;\n",lut_numCnInCnGroups[4] );
|
||||
|
||||
// Set the offset to each bit within a group in terms of 64 Byte
|
||||
bitOffsetInGroup = (lut_numCnInCnGroups_BG2_R15[4]*NR_LDPC_ZMAX)>>6;
|
||||
|
||||
// Loop over every BN
|
||||
|
||||
for (j=0; j<8; j++)
|
||||
{
|
||||
|
||||
fprintf(fd," for (int i=0;i<M;i++) {\n");
|
||||
// Abs and sign of 64 CNs (first BN)
|
||||
// zmm0 = p_cnProcBuf[lut_idxCnProcG3[j][0] + i];
|
||||
fprintf(fd," zmm0 = ((__m512i*)cnProcBuf)[%d+i];\n",(lut_startAddrCnGroups[4]>>6)+lut_idxCnProcG8[j][0]/2);
|
||||
fprintf(fd," sgn = _mm512_xor_si512(ones, zmm0);\n");
|
||||
fprintf(fd," min = _mm512_abs_epi8(zmm0);\n");
|
||||
|
||||
|
||||
// Loop over BNs
|
||||
for (k=1; k<7; k++)
|
||||
{
|
||||
fprintf(fd," zmm0 = ((__m512i*)cnProcBuf)[%d+i];\n",(lut_startAddrCnGroups[4]>>6)+lut_idxCnProcG8[j][k]/2);
|
||||
|
||||
// min = _mm512_min_epu8(min, _mm512_abs_epi8(zmm0));
|
||||
fprintf(fd," min = _mm512_min_epu8(min, _mm512_abs_epi8(zmm0));\n");
|
||||
|
||||
// sgn = _mm512_sign_epi8(sgn, zmm0);
|
||||
fprintf(fd," sgn = _mm512_xor_si512(sgn, zmm0);\n");
|
||||
}
|
||||
|
||||
// Store result
|
||||
// min = _mm512_min_epu8(min, maxLLR); // 128 in epi8 is -127
|
||||
fprintf(fd," min = _mm512_min_epu8(min, maxLLR);\n");
|
||||
|
||||
fprintf(fd," ((__m512i*)cnProcBufRes)[%d+i] = conditional_negate(min, sgn,zeros);\n",(lut_startAddrCnGroups[4]>>6)+(j*bitOffsetInGroup));
|
||||
fprintf(fd," }\n");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// =====================================================================
|
||||
// Process group with 10 BNs
|
||||
fprintf(fd,"//Process group with 10 BNs\n");
|
||||
|
||||
const uint8_t lut_idxCnProcG10[10][9] = {{24,48,72,96,120,144,168,192,216}, {0,48,72,96,120,144,168,192,216},
|
||||
{0,24,72,96,120,144,168,192,216}, {0,24,48,96,120,144,168,192,216},
|
||||
{0,24,48,72,120,144,168,192,216}, {0,24,48,72,96,144,168,192,216},
|
||||
{0,24,48,72,96,120,168,192,216}, {0,24,48,72,96,120,144,192,216},
|
||||
{0,24,48,72,96,120,144,168,216}, {0,24,48,72,96,120,144,168,192}};
|
||||
|
||||
|
||||
|
||||
|
||||
if (lut_numCnInCnGroups[5] > 0)
|
||||
{
|
||||
// Number of groups of 64 CNs for parallel processing
|
||||
// Ceil for values not divisible by 64
|
||||
fprintf(fd," M = (%d*Z + 63)>>6;\n",lut_numCnInCnGroups[5] );
|
||||
|
||||
// Set the offset to each bit within a group in terms of 64 Byte
|
||||
bitOffsetInGroup = (lut_numCnInCnGroups_BG2_R15[5]*NR_LDPC_ZMAX)>>6;
|
||||
|
||||
// Loop over every BN
|
||||
|
||||
for (j=0; j<10; j++)
|
||||
{
|
||||
|
||||
fprintf(fd," for (int i=0;i<M;i++) {\n");
|
||||
// Abs and sign of 64 CNs (first BN)
|
||||
// zmm0 = p_cnProcBuf[lut_idxCnProcG3[j][0] + i];
|
||||
fprintf(fd," zmm0 = ((__m512i*)cnProcBuf)[%d+i];\n",(lut_startAddrCnGroups[5]>>6)+lut_idxCnProcG10[j][0]/2);
|
||||
fprintf(fd," sgn = _mm512_xor_si512(ones, zmm0);\n");
|
||||
fprintf(fd," min = _mm512_abs_epi8(zmm0);\n");
|
||||
|
||||
|
||||
// Loop over BNs
|
||||
for (k=1; k<9; k++)
|
||||
{
|
||||
fprintf(fd," zmm0 = ((__m512i*)cnProcBuf)[%d+i];\n",(lut_startAddrCnGroups[5]>>6)+lut_idxCnProcG10[j][k]/2);
|
||||
|
||||
// min = _mm512_min_epu8(min, _mm512_abs_epi8(zmm0));
|
||||
fprintf(fd," min = _mm512_min_epu8(min, _mm512_abs_epi8(zmm0));\n");
|
||||
|
||||
// sgn = _mm512_sign_epi8(sgn, zmm0);
|
||||
fprintf(fd," sgn = _mm512_xor_si512(sgn, zmm0);\n");
|
||||
}
|
||||
|
||||
// Store result
|
||||
// min = _mm512_min_epu8(min, maxLLR); // 128 in epi8 is -127
|
||||
fprintf(fd," min = _mm512_min_epu8(min, maxLLR);\n");
|
||||
|
||||
fprintf(fd," ((__m512i*)cnProcBufRes)[%d+i] = conditional_negate(min,sgn,zeros);\n",(lut_startAddrCnGroups[5]>>6)+(j*bitOffsetInGroup));
|
||||
fprintf(fd," }\n");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
fprintf(fd,"}\n");
|
||||
fclose(fd);
|
||||
}//end of the function nrLDPC_cnProc_BG2
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -0,0 +1,50 @@
|
||||
/*
|
||||
* Licensed to the OpenAirInterface (OAI) Software Alliance under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright ownership.
|
||||
* The OpenAirInterface Software Alliance licenses this file to You under
|
||||
* the OAI Public License, Version 1.1 (the "License"); you may not use this file
|
||||
* except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.openairinterface.org/?page_id=698
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*-------------------------------------------------------------------------------
|
||||
* For more information about the OpenAirInterface (OAI) Software Alliance:
|
||||
* contact@openairinterface.org
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdint.h>
|
||||
#define NB_R 3
|
||||
void nrLDPC_cnProc_BG1_generator_AVX512(const char *, int);
|
||||
void nrLDPC_cnProc_BG2_generator_AVX512(const char *, int);
|
||||
|
||||
const char *__asan_default_options()
|
||||
{
|
||||
/* don't do leak checking in nr_ulsim, creates problems in the CI */
|
||||
return "detect_leaks=0";
|
||||
}
|
||||
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
if (argc != 2) {
|
||||
fprintf(stderr, "usage: %s <output-dir>\n", argv[0]);
|
||||
return 1;
|
||||
}
|
||||
const char *dir = argv[1];
|
||||
|
||||
int R[NB_R]={0,1,2};
|
||||
for(int i=0; i<NB_R;i++){
|
||||
nrLDPC_cnProc_BG1_generator_AVX512(dir, R[i]);
|
||||
nrLDPC_cnProc_BG2_generator_AVX512(dir, R[i]);
|
||||
}
|
||||
|
||||
return(0);
|
||||
}
|
||||
|
||||
@@ -0,0 +1,11 @@
|
||||
#!/bin/bash
|
||||
|
||||
echo "to build the LDPC decoder headers: go to the build directory, and type"
|
||||
echo "make/ninja ldpc_generators"
|
||||
echo
|
||||
echo "assuming your build directory is ran_build/build, I trigger building for"
|
||||
echo "you now. The generated headers will be in ran_build/build/ldpc/generator_*/"
|
||||
echo
|
||||
|
||||
cd $OPENAIR_HOME/cmake_targets/ran_build/build
|
||||
make ldpc_generators || ninja ldpc_generators
|
||||
@@ -30,8 +30,9 @@
|
||||
|
||||
#ifndef __NR_LDPC_TYPES__H__
|
||||
#define __NR_LDPC_TYPES__H__
|
||||
|
||||
#ifndef CODEGEN
|
||||
#include "time_meas.h"
|
||||
#endif
|
||||
#include "nrLDPCdecoder_defs.h"
|
||||
// ==============================================================================
|
||||
// TYPES
|
||||
@@ -77,6 +78,7 @@ typedef struct nrLDPC_dec_params {
|
||||
/**
|
||||
Structure containing LDPC decoder processing time statistics.
|
||||
*/
|
||||
#ifndef CODEGEN
|
||||
typedef struct nrLDPC_time_stats {
|
||||
time_stats_t llr2llrProcBuf; /**< Statistics for function llr2llrProcBuf */
|
||||
time_stats_t llr2CnProcBuf; /**< Statistics for function llr2CnProcBuf */
|
||||
@@ -90,7 +92,7 @@ typedef struct nrLDPC_time_stats {
|
||||
time_stats_t llr2bit; /**< Statistics for function llr2bit */
|
||||
time_stats_t total; /**< Statistics for total processing time */
|
||||
} t_nrLDPC_time_stats;
|
||||
|
||||
#endif
|
||||
/**
|
||||
Structure containing the processing buffers
|
||||
*/
|
||||
|
||||
@@ -198,4 +198,14 @@ static const int8_t zeros256_epi8[32] __attribute__ ((aligned(32))) = {0,0,0,0,0
|
||||
/** Vector of 32 '127' in int8 for application with AVX2 */
|
||||
static const int8_t maxLLR256_epi8[32] __attribute__ ((aligned(32))) = {127,127,127,127,127,127,127,127,127,127,127,127,127,127,127,127,127,127,127,127,127,127,127,127,127,127,127,127,127,127,127,127};
|
||||
|
||||
/** Vector of 64 '1' in int8 for application with AVX512 */
|
||||
static const int8_t ones512_epi8[64] __attribute__ ((aligned(64))) = {1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1};
|
||||
/** Vector of 64 '0' in int8 for application with AVX512 */
|
||||
static const int8_t zeros512_epi8[64] __attribute__ ((aligned(64))) = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0};
|
||||
/** Vector of 64 '127' in int8 for application with AVX512 */
|
||||
static const int8_t maxLLR512_epi8[64] __attribute__ ((aligned(64))) = {127,127,127,127,127,127,127,127,127,127,127,127,127,127,127,127,127,127,127,127,127,127,127,127,127,127,127,127,127,127,127,127,127,127,127,127,127,127,127,127,127,127,127,127,127,127,127,127,127,127,127,127,127,127,127,127,127,127,127,127,127,127,127,127};
|
||||
|
||||
|
||||
|
||||
|
||||
#endif
|
||||
|
||||
@@ -544,8 +544,8 @@ int phy_init_nr_gNB(PHY_VARS_gNB *gNB,
|
||||
gNB->nr_gold_pdsch_dmrs = (uint32_t ****)malloc16(fp->slots_per_frame*sizeof(uint32_t ***));
|
||||
uint32_t ****pdsch_dmrs = gNB->nr_gold_pdsch_dmrs;
|
||||
|
||||
// ceil(((NB_RB*6(k)*2(QPSK)/32) // 3 RE *2(QPSK)
|
||||
int pdsch_dmrs_init_length = ((fp->N_RB_DL*12)>>5)+1;
|
||||
// ceil(((NB_RB*12(k)*2(QPSK)/32) // 3 RE *2(QPSK)
|
||||
const int pdsch_dmrs_init_length = ((fp->N_RB_DL*24)>>5)+1;
|
||||
for (int slot=0; slot<fp->slots_per_frame; slot++) {
|
||||
pdsch_dmrs[slot] = (uint32_t ***)malloc16(fp->symbols_per_slot*sizeof(uint32_t **));
|
||||
AssertFatal(pdsch_dmrs[slot]!=NULL, "NR init: pdsch_dmrs for slot %d - malloc failed\n", slot);
|
||||
@@ -1050,7 +1050,7 @@ void init_nr_transport(PHY_VARS_gNB *gNB) {
|
||||
|
||||
LOG_I(PHY,"Allocating Transport Channel Buffers for ULSCH %d/%d\n",i,gNB->number_of_nr_ulsch_max);
|
||||
|
||||
gNB->ulsch[i] = new_gNB_ulsch(MAX_LDPC_ITERATIONS, fp->N_RB_UL);
|
||||
gNB->ulsch[i] = new_gNB_ulsch(gNB->max_ldpc_iterations, fp->N_RB_UL);
|
||||
|
||||
if (!gNB->ulsch[i]) {
|
||||
LOG_E(PHY,"Can't get gNB ulsch structures\n");
|
||||
|
||||
@@ -60,7 +60,7 @@ int nr_phy_init_RU(RU_t *ru) {
|
||||
|
||||
for (i=0; i<ru->nb_tx; i++) {
|
||||
// Allocate 10 subframes of I/Q TX signal data (time) if not
|
||||
ru->common.txdata[i] = (int32_t*)malloc16_clear( ru->sf_extension + (fp->samples_per_frame*sizeof(int32_t) ));
|
||||
ru->common.txdata[i] = (int32_t*)malloc16_clear((ru->sf_extension +fp->samples_per_frame) *sizeof(int32_t));
|
||||
LOG_I(PHY,"[INIT] common.txdata[%d] = %p (%lu bytes,sf_extension %d)\n",i,ru->common.txdata[i],
|
||||
(ru->sf_extension + fp->samples_per_frame)*sizeof(int32_t),ru->sf_extension);
|
||||
ru->common.txdata[i] = &ru->common.txdata[i][ru->sf_extension];
|
||||
|
||||
@@ -577,7 +577,7 @@ void init_nr_ue_transport(PHY_VARS_NR_UE *ue) {
|
||||
for (int i = 0; i < NUMBER_OF_CONNECTED_gNB_MAX; i++) {
|
||||
for (int j=0; j<num_codeword; j++) {
|
||||
for (int k=0; k<RX_NB_TH_MAX; k++) {
|
||||
AssertFatal((ue->dlsch[k][i][j] = new_nr_ue_dlsch(1,NR_MAX_DLSCH_HARQ_PROCESSES,NSOFT,MAX_LDPC_ITERATIONS,ue->frame_parms.N_RB_DL))!=NULL,"Can't get ue dlsch structures\n");
|
||||
AssertFatal((ue->dlsch[k][i][j] = new_nr_ue_dlsch(1,NR_MAX_DLSCH_HARQ_PROCESSES,NSOFT,ue->max_ldpc_iterations,ue->frame_parms.N_RB_DL))!=NULL,"Can't get ue dlsch structures\n");
|
||||
LOG_D(PHY,"dlsch[%d][%d][%d] => %p\n",k,i,j,ue->dlsch[k][i][j]);
|
||||
if (j==0) {
|
||||
AssertFatal((ue->ulsch[k][i] = new_nr_ue_ulsch(ue->frame_parms.N_RB_UL, NR_MAX_ULSCH_HARQ_PROCESSES,&ue->frame_parms))!=NULL,"Can't get ue ulsch structures\n");
|
||||
@@ -586,8 +586,8 @@ void init_nr_ue_transport(PHY_VARS_NR_UE *ue) {
|
||||
}
|
||||
}
|
||||
|
||||
ue->dlsch_SI[i] = new_nr_ue_dlsch(1,1,NSOFT,MAX_LDPC_ITERATIONS,ue->frame_parms.N_RB_DL);
|
||||
ue->dlsch_ra[i] = new_nr_ue_dlsch(1,1,NSOFT,MAX_LDPC_ITERATIONS,ue->frame_parms.N_RB_DL);
|
||||
ue->dlsch_SI[i] = new_nr_ue_dlsch(1,1,NSOFT,ue->max_ldpc_iterations,ue->frame_parms.N_RB_DL);
|
||||
ue->dlsch_ra[i] = new_nr_ue_dlsch(1,1,NSOFT,ue->max_ldpc_iterations,ue->frame_parms.N_RB_DL);
|
||||
ue->transmission_mode[i] = ue->frame_parms.nb_antenna_ports_gNB==1 ? 1 : 2;
|
||||
}
|
||||
|
||||
|
||||
@@ -92,6 +92,7 @@ int nr_pusch_channel_estimation(PHY_VARS_gNB *gNB,
|
||||
int16_t *fl,*fm,*fr,*fml,*fmr,*fmm,*fdcl,*fdcr,*fdclh,*fdcrh;
|
||||
int ch_offset,symbol_offset ;
|
||||
int32_t **ul_ch_estimates_time = gNB->pusch_vars[ul_id]->ul_ch_estimates_time;
|
||||
int chest_freq = gNB->chest_freq;
|
||||
__m128i *ul_ch_128;
|
||||
|
||||
#ifdef DEBUG_CH
|
||||
@@ -225,8 +226,7 @@ int nr_pusch_channel_estimation(PHY_VARS_gNB *gNB,
|
||||
LOG_I(PHY, "In %s ul_ch addr %p nushift %d\n", __FUNCTION__, ul_ch, nushift);
|
||||
#endif
|
||||
|
||||
if (pusch_pdu->dmrs_config_type == pusch_dmrs_type1 && gNB->prb_interpolation == 0) {
|
||||
|
||||
if (pusch_pdu->dmrs_config_type == pusch_dmrs_type1 && chest_freq == 0){
|
||||
LOG_D(PHY,"PUSCH estimation DMRS type 1, Freq-domain interpolation");
|
||||
|
||||
// For configuration type 1: k = 4*n + 2*k' + delta,
|
||||
@@ -329,7 +329,7 @@ int nr_pusch_channel_estimation(PHY_VARS_gNB *gNB,
|
||||
}
|
||||
#endif
|
||||
}
|
||||
else if (pusch_pdu->dmrs_config_type == pusch_dmrs_type2 && gNB->prb_interpolation == 0) { //pusch_dmrs_type2 |p_r,p_l,d,d,d,d,p_r,p_l,d,d,d,d|
|
||||
else if (pusch_pdu->dmrs_config_type == pusch_dmrs_type2 && chest_freq == 0) { //pusch_dmrs_type2 |p_r,p_l,d,d,d,d,p_r,p_l,d,d,d,d|
|
||||
LOG_D(PHY,"PUSCH estimation DMRS type 2, Freq-domain interpolation");
|
||||
// Treat first DMRS specially (left edge)
|
||||
|
||||
|
||||
@@ -338,3 +338,81 @@ int8_t get_valid_dmrs_idx_for_channel_est(uint16_t dmrs_symb_pos, uint8_t count
|
||||
}
|
||||
return symbIdx;
|
||||
}
|
||||
|
||||
/* perform averaging of channel estimates and store result in first symbol buffer */
|
||||
void nr_chest_time_domain_avg(NR_DL_FRAME_PARMS *frame_parms,
|
||||
int **ch_est,
|
||||
uint8_t num_symbols,
|
||||
uint8_t start_symbol,
|
||||
uint16_t dmrs_bitmap,
|
||||
uint16_t num_rbs)
|
||||
{
|
||||
__m128i *ul_ch128_0;
|
||||
__m128i *ul_ch128_1;
|
||||
int16_t *ul_ch16_0;
|
||||
int total_symbols = start_symbol + num_symbols;
|
||||
int num_dmrs_symb = get_dmrs_symbols_in_slot(dmrs_bitmap, total_symbols);
|
||||
int first_dmrs_symb = get_next_dmrs_symbol_in_slot(dmrs_bitmap, start_symbol, total_symbols);
|
||||
AssertFatal(first_dmrs_symb > -1, "No DMRS symbol present in this slot\n");
|
||||
for (int aarx = 0; aarx < frame_parms->nb_antennas_rx; aarx++) {
|
||||
for (int symb = first_dmrs_symb+1; symb < total_symbols; symb++) {
|
||||
ul_ch128_0 = (__m128i *)&ch_est[aarx][first_dmrs_symb*frame_parms->ofdm_symbol_size];
|
||||
if ((dmrs_bitmap >> symb) & 0x01) {
|
||||
ul_ch128_1 = (__m128i *)&ch_est[aarx][symb*frame_parms->ofdm_symbol_size];
|
||||
for (int rbIdx = 0; rbIdx < num_rbs; rbIdx++) {
|
||||
ul_ch128_0[0] = _mm_adds_epi16(ul_ch128_0[0], ul_ch128_1[0]);
|
||||
ul_ch128_0[1] = _mm_adds_epi16(ul_ch128_0[1], ul_ch128_1[1]);
|
||||
ul_ch128_0[2] = _mm_adds_epi16(ul_ch128_0[2], ul_ch128_1[2]);
|
||||
ul_ch128_0 += 3;
|
||||
ul_ch128_1 += 3;
|
||||
}
|
||||
}
|
||||
}
|
||||
ul_ch128_0 = (__m128i *)&ch_est[aarx][first_dmrs_symb*frame_parms->ofdm_symbol_size];
|
||||
if (num_dmrs_symb == 2) {
|
||||
for (int rbIdx = 0; rbIdx < num_rbs; rbIdx++) {
|
||||
ul_ch128_0[0] = _mm_srai_epi16(ul_ch128_0[0], 1);
|
||||
ul_ch128_0[1] = _mm_srai_epi16(ul_ch128_0[1], 1);
|
||||
ul_ch128_0[2] = _mm_srai_epi16(ul_ch128_0[2], 1);
|
||||
ul_ch128_0 += 3;
|
||||
}
|
||||
} else if (num_dmrs_symb == 4) {
|
||||
for (int rbIdx = 0; rbIdx < num_rbs; rbIdx++) {
|
||||
ul_ch128_0[0] = _mm_srai_epi16(ul_ch128_0[0], 2);
|
||||
ul_ch128_0[1] = _mm_srai_epi16(ul_ch128_0[1], 2);
|
||||
ul_ch128_0[2] = _mm_srai_epi16(ul_ch128_0[2], 2);
|
||||
ul_ch128_0 += 3;
|
||||
}
|
||||
} else if (num_dmrs_symb == 3) {
|
||||
ul_ch16_0 = (int16_t *)&ch_est[aarx][first_dmrs_symb*frame_parms->ofdm_symbol_size];
|
||||
for (int rbIdx = 0; rbIdx < num_rbs; rbIdx++) {
|
||||
ul_ch16_0[0] /= 3;
|
||||
ul_ch16_0[1] /= 3;
|
||||
ul_ch16_0[2] /= 3;
|
||||
ul_ch16_0[3] /= 3;
|
||||
ul_ch16_0[4] /= 3;
|
||||
ul_ch16_0[5] /= 3;
|
||||
ul_ch16_0[6] /= 3;
|
||||
ul_ch16_0[7] /= 3;
|
||||
ul_ch16_0[8] /= 3;
|
||||
ul_ch16_0[9] /= 3;
|
||||
ul_ch16_0[10] /= 3;
|
||||
ul_ch16_0[11] /= 3;
|
||||
ul_ch16_0[12] /= 3;
|
||||
ul_ch16_0[13] /= 3;
|
||||
ul_ch16_0[14] /= 3;
|
||||
ul_ch16_0[15] /= 3;
|
||||
ul_ch16_0[16] /= 3;
|
||||
ul_ch16_0[17] /= 3;
|
||||
ul_ch16_0[18] /= 3;
|
||||
ul_ch16_0[19] /= 3;
|
||||
ul_ch16_0[20] /= 3;
|
||||
ul_ch16_0[21] /= 3;
|
||||
ul_ch16_0[22] /= 3;
|
||||
ul_ch16_0[23] /= 3;
|
||||
ul_ch16_0 += 24;
|
||||
}
|
||||
} else AssertFatal((num_dmrs_symb < 5) && (num_dmrs_symb > 0), "Illegal number of DMRS symbols in the slot\n");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -65,6 +65,12 @@ void nr_gen_ref_conj_symbols(uint32_t *in, uint32_t length, int16_t *output, uin
|
||||
int8_t get_next_dmrs_symbol_in_slot(uint16_t ul_dmrs_symb_pos, uint8_t counter, uint8_t end_symbol);
|
||||
uint8_t get_dmrs_symbols_in_slot(uint16_t l_prime_mask, uint16_t nb_symb);
|
||||
int8_t get_valid_dmrs_idx_for_channel_est(uint16_t dmrs_symb_pos, uint8_t counter);
|
||||
void nr_chest_time_domain_avg(NR_DL_FRAME_PARMS *frame_parms,
|
||||
int **ch_est,
|
||||
uint8_t num_symbols,
|
||||
uint8_t start_symbol,
|
||||
uint16_t dmrs_bitmap,
|
||||
uint16_t num_rbs);
|
||||
|
||||
static inline uint8_t is_dmrs_symbol(uint8_t l, uint16_t dmrsSymbMask ) { return ((dmrsSymbMask >> l) & 0x1); }
|
||||
#undef EXTERN
|
||||
|
||||
@@ -73,7 +73,6 @@ void nr_generate_dci(PHY_VARS_gNB *gNB,
|
||||
NR_DL_FRAME_PARMS *frame_parms,
|
||||
int slot) {
|
||||
|
||||
int16_t mod_dmrs[NR_MAX_CSET_DURATION][NR_MAX_PDCCH_DMRS_LENGTH>>1] __attribute__((aligned(16))); // 3 for the max coreset duration
|
||||
uint16_t cset_start_sc;
|
||||
uint8_t cset_start_symb, cset_nsymb;
|
||||
int k,l,k_prime,dci_idx, dmrs_idx;
|
||||
@@ -82,13 +81,14 @@ void nr_generate_dci(PHY_VARS_gNB *gNB,
|
||||
|
||||
int rb_offset;
|
||||
int n_rb;
|
||||
|
||||
// compute rb_offset and n_prb based on frequency allocation
|
||||
nr_cce_t cce_list[MAX_DCI_CORESET][NR_MAX_PDCCH_AGG_LEVEL];
|
||||
nr_fill_cce_list(cce_list,0,pdcch_pdu_rel15);
|
||||
nr_fill_cce_list(cce_list, pdcch_pdu_rel15);
|
||||
get_coreset_rballoc(pdcch_pdu_rel15->FreqDomainResource,&n_rb,&rb_offset);
|
||||
cset_start_sc = frame_parms->first_carrier_offset + (pdcch_pdu_rel15->BWPStart + rb_offset) * NR_NB_SC_PER_RB;
|
||||
|
||||
int16_t mod_dmrs[pdcch_pdu_rel15->StartSymbolIndex+pdcch_pdu_rel15->DurationSymbols][(n_rb+rb_offset)*6] __attribute__((aligned(16))); // 3 for the max coreset duration
|
||||
|
||||
for (int d=0;d<pdcch_pdu_rel15->numDlDci;d++) {
|
||||
/*The coreset is initialised
|
||||
* in frequency: the first subcarrier is obtained by adding the first CRB overlapping the SSB and the rb_offset for coreset 0
|
||||
@@ -118,7 +118,7 @@ void nr_generate_dci(PHY_VARS_gNB *gNB,
|
||||
|
||||
/// DMRS QPSK modulation
|
||||
for (int symb=cset_start_symb; symb<cset_start_symb + pdcch_pdu_rel15->DurationSymbols; symb++) {
|
||||
|
||||
|
||||
nr_modulation(gold_pdcch_dmrs[symb], dmrs_length, DMRS_MOD_ORDER, mod_dmrs[symb]); //Qm = 2 as DMRS is QPSK modulated
|
||||
|
||||
#ifdef DEBUG_PDCCH_DMRS
|
||||
@@ -178,8 +178,10 @@ void nr_generate_dci(PHY_VARS_gNB *gNB,
|
||||
|
||||
// Get cce_list indices by reg_idx in ascending order
|
||||
int reg_list_index = 0;
|
||||
int N_regs = n_rb*pdcch_pdu_rel15->DurationSymbols; // nb of REGs per coreset
|
||||
int N_cces = N_regs / NR_NB_REG_PER_CCE; // nb of cces in coreset
|
||||
int reg_list_order[NR_MAX_PDCCH_AGG_LEVEL] = {};
|
||||
for (int p = 0; p < NR_MAX_PDCCH_AGG_LEVEL; p++) {
|
||||
for (int p = 0; p < N_cces; p++) {
|
||||
for(int p2 = 0; p2 < dci_pdu->AggregationLevel; p2++) {
|
||||
if(cce_list[d][p2].reg_list[0].reg_idx == p * NR_NB_REG_PER_CCE) {
|
||||
reg_list_order[reg_list_index] = p2;
|
||||
@@ -191,24 +193,25 @@ void nr_generate_dci(PHY_VARS_gNB *gNB,
|
||||
|
||||
/*Mapping the encoded DCI along with the DMRS */
|
||||
for(int symbol_idx = 0; symbol_idx < pdcch_pdu_rel15->DurationSymbols; symbol_idx++) {
|
||||
for (int cce_count = 0; cce_count < dci_pdu->AggregationLevel; cce_count+=pdcch_pdu_rel15->DurationSymbols) {
|
||||
for (int cce_count = 0; cce_count < dci_pdu->AggregationLevel; cce_count++) {
|
||||
|
||||
int8_t cce_idx = reg_list_order[cce_count];
|
||||
|
||||
for (int reg_in_cce_idx = 0; reg_in_cce_idx < NR_NB_REG_PER_CCE; reg_in_cce_idx++) {
|
||||
for (int reg_in_cce_idx = 0; reg_in_cce_idx < NR_NB_REG_PER_CCE; reg_in_cce_idx+=pdcch_pdu_rel15->DurationSymbols) {
|
||||
|
||||
k = cset_start_sc + cce_list[d][cce_idx].reg_list[reg_in_cce_idx].start_sc_idx;
|
||||
|
||||
LOG_D(PHY,"CCE %d REG %d k %d\n",cce_idx,reg_in_cce_idx+symbol_idx,k);
|
||||
if (k >= frame_parms->ofdm_symbol_size)
|
||||
k -= frame_parms->ofdm_symbol_size;
|
||||
|
||||
l = cset_start_symb + symbol_idx;
|
||||
|
||||
// dmrs index depends on reference point for k according to 38.211 7.4.1.3.2
|
||||
int eff_reg_idx = cce_list[d][cce_idx].reg_list[reg_in_cce_idx].reg_idx/pdcch_pdu_rel15->DurationSymbols;
|
||||
if (pdcch_pdu_rel15->CoreSetType == NFAPI_NR_CSET_CONFIG_PDCCH_CONFIG)
|
||||
dmrs_idx = (cce_list[d][cce_idx].reg_list[reg_in_cce_idx].reg_idx) * 3;
|
||||
dmrs_idx = eff_reg_idx * 3;
|
||||
else
|
||||
dmrs_idx = (cce_list[d][cce_idx].reg_list[reg_in_cce_idx].reg_idx + rb_offset) * 3;
|
||||
dmrs_idx = (eff_reg_idx + rb_offset) * 3;
|
||||
|
||||
k_prime = 0;
|
||||
|
||||
|
||||
@@ -55,6 +55,6 @@ void nr_fill_ul_dci(PHY_VARS_gNB *gNB,
|
||||
int slot,
|
||||
nfapi_nr_ul_dci_request_pdus_t *pdcch_pdu);
|
||||
|
||||
void nr_fill_cce_list(nr_cce_t cce_list[MAX_DCI_CORESET][NR_MAX_PDCCH_AGG_LEVEL], uint8_t m,nfapi_nr_dl_tti_pdcch_pdu_rel15_t *pdcch_pdu_rel15);
|
||||
void nr_fill_cce_list(nr_cce_t cce_list[MAX_DCI_CORESET][NR_MAX_PDCCH_AGG_LEVEL], nfapi_nr_dl_tti_pdcch_pdu_rel15_t *pdcch_pdu_rel15);
|
||||
|
||||
#endif //__PHY_NR_TRANSPORT_DCI__H
|
||||
|
||||
@@ -37,89 +37,8 @@
|
||||
|
||||
#include "nr_dlsch.h"
|
||||
|
||||
/*
|
||||
Original version to keep code for Y that needs to be moved to MAC
|
||||
|
||||
void nr_fill_cce_list(PHY_VARS_gNB *gNB, uint16_t n_shift, uint8_t m) {
|
||||
|
||||
nr_cce_t* cce;
|
||||
nr_reg_t* reg;
|
||||
nfapi_nr_dl_config_pdcch_pdu_rel15_t* pdcch_pdu = gNB->pdcch_pdu.pdcch;
|
||||
|
||||
uint8_t L = dci_alloc->L;
|
||||
uint8_t bsize = pdcch_params->reg_bundle_size;
|
||||
uint8_t R = pdcch_params->interleaver_size;
|
||||
uint16_t N_reg = pdcch_params->n_rb * pdcch_params->n_symb;
|
||||
uint16_t Y, N_cce, M_s_max, n_CI=0, tmp, C=0;
|
||||
uint16_t n_RNTI = (pdcch_params->search_space_type == NFAPI_NR_SEARCH_SPACE_TYPE_UE_SPECIFIC)? pdcch_params->rnti:0;
|
||||
uint32_t A[3]={39827,39829,39839};
|
||||
|
||||
if (pdcch_params->config_type == NFAPI_NR_CSET_CONFIG_MIB_SIB1)
|
||||
AssertFatal(L>=4, "Invalid aggregation level for SIB1 configured PDCCH %d\n", L);
|
||||
|
||||
N_cce = N_reg / NR_NB_REG_PER_CCE;
|
||||
//Max number of candidates per aggregation level -- SIB1 configured search space only
|
||||
M_s_max = (L==4)?4:(L==8)?2:1;
|
||||
|
||||
if (pdcch_params->search_space_type == NFAPI_NR_SEARCH_SPACE_TYPE_COMMON)
|
||||
Y = 0;
|
||||
else { //NFAPI_NR_SEARCH_SPACE_TYPE_UE_SPECIFIC
|
||||
Y = (A[0]*n_RNTI)%65537; // Candidate 0, antenna port 0
|
||||
}
|
||||
|
||||
if (pdcch_params->cr_mapping_type == NFAPI_NR_CCE_REG_MAPPING_INTERLEAVED) {
|
||||
uint16_t assertFatalCond = (N_reg%(bsize*R));
|
||||
AssertFatal(assertFatalCond == 0,"CCE to REG interleaving: Invalid configuration leading to non integer C (N_reg %us, bsize %d R %d)\n",N_reg, bsize, R);
|
||||
C = N_reg/(bsize*R);
|
||||
}
|
||||
|
||||
tmp = L * (( Y + (m*N_cce)/(L*M_s_max) + n_CI ) % CEILIDIV(N_cce,L));
|
||||
|
||||
LOG_D(PHY, "CCE list generation for candidate %d: bundle size %d ilv size %d tmp %d\n", m, bsize, R, tmp);
|
||||
for (uint8_t cce_idx=0; cce_idx<L; cce_idx++) {
|
||||
cce = &dci_alloc->cce_list[cce_idx];
|
||||
cce->cce_idx = tmp + cce_idx;
|
||||
LOG_D(PHY, "cce_idx %d\n", cce->cce_idx);
|
||||
|
||||
if (pdcch_params->cr_mapping_type == NFAPI_NR_CCE_REG_MAPPING_INTERLEAVED) {
|
||||
LOG_D(PHY, "Interleaved CCE to REG mapping\n");
|
||||
uint8_t j = cce->cce_idx, j_prime;
|
||||
uint8_t r,c,idx;
|
||||
|
||||
for (uint8_t bundle_idx=0; bundle_idx<NR_NB_REG_PER_CCE/bsize; bundle_idx++) {
|
||||
j_prime = 6*j/bsize + bundle_idx;
|
||||
r = j_prime%R;
|
||||
c = (j_prime-r)/R;
|
||||
idx = (r*C + c + n_shift)%(N_reg/bsize);
|
||||
LOG_D(PHY, "bundle idx = %d \n j = %d \t j_prime = %d \t r = %d \t c = %d\n", idx, j , j_prime, r, c);
|
||||
|
||||
for (uint8_t reg_idx=0; reg_idx<bsize; reg_idx++) {
|
||||
reg = &cce->reg_list[reg_idx];
|
||||
reg->reg_idx = bsize*idx + reg_idx;
|
||||
reg->start_sc_idx = (reg->reg_idx/pdcch_params->n_symb) * NR_NB_SC_PER_RB;
|
||||
reg->symb_idx = reg->reg_idx % pdcch_params->n_symb;
|
||||
LOG_D(PHY, "reg %d symbol %d start subcarrier %d\n", reg->reg_idx, reg->symb_idx, reg->start_sc_idx);
|
||||
}
|
||||
}
|
||||
}
|
||||
else { // NFAPI_NR_CCE_REG_MAPPING_NON_INTERLEAVED
|
||||
LOG_D(PHY, "Non interleaved CCE to REG mapping\n");
|
||||
for (uint8_t reg_idx=0; reg_idx<NR_NB_REG_PER_CCE; reg_idx++) {
|
||||
reg = &cce->reg_list[reg_idx];
|
||||
reg->reg_idx = cce->cce_idx*NR_NB_REG_PER_CCE + reg_idx;
|
||||
reg->start_sc_idx = (reg->reg_idx/pdcch_params->n_symb) * NR_NB_SC_PER_RB;
|
||||
reg->symb_idx = reg->reg_idx % pdcch_params->n_symb;
|
||||
LOG_D(PHY, "reg %d symbol %d start subcarrier %d\n", reg->reg_idx, reg->symb_idx, reg->start_sc_idx);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
*/
|
||||
|
||||
void nr_fill_cce_list(nr_cce_t cce_list[MAX_DCI_CORESET][NR_MAX_PDCCH_AGG_LEVEL], uint8_t m, nfapi_nr_dl_tti_pdcch_pdu_rel15_t *pdcch_pdu_rel15) {
|
||||
void nr_fill_cce_list(nr_cce_t cce_list[MAX_DCI_CORESET][NR_MAX_PDCCH_AGG_LEVEL], nfapi_nr_dl_tti_pdcch_pdu_rel15_t *pdcch_pdu_rel15) {
|
||||
|
||||
nr_cce_t* cce;
|
||||
nr_reg_t* reg;
|
||||
@@ -128,71 +47,51 @@ void nr_fill_cce_list(nr_cce_t cce_list[MAX_DCI_CORESET][NR_MAX_PDCCH_AGG_LEVEL]
|
||||
int R = pdcch_pdu_rel15->InterleaverSize;
|
||||
int n_shift = pdcch_pdu_rel15->ShiftIndex;
|
||||
|
||||
|
||||
//Max number of candidates per aggregation level -- SIB1 configured search space only
|
||||
|
||||
|
||||
int n_rb,rb_offset;
|
||||
|
||||
get_coreset_rballoc(pdcch_pdu_rel15->FreqDomainResource,&n_rb,&rb_offset);
|
||||
|
||||
|
||||
int N_reg = n_rb;
|
||||
int C=-1;
|
||||
|
||||
AssertFatal(N_reg > 0,"N_reg cannot be 0\n");
|
||||
|
||||
for (int d=0;d<pdcch_pdu_rel15->numDlDci;d++) {
|
||||
|
||||
int L = pdcch_pdu_rel15->dci_pdu[d].AggregationLevel;
|
||||
int dur = pdcch_pdu_rel15->DurationSymbols;
|
||||
int N_regs = n_rb*dur; // nb of REGs per coreset
|
||||
AssertFatal(N_regs > 0,"N_reg cannot be 0\n");
|
||||
|
||||
if (pdcch_pdu_rel15->CoreSetType == NFAPI_NR_CSET_CONFIG_MIB_SIB1)
|
||||
AssertFatal(L>=4, "Invalid aggregation level for SIB1 configured PDCCH %d\n", L);
|
||||
|
||||
|
||||
int C = 0;
|
||||
|
||||
if (pdcch_pdu_rel15->CceRegMappingType == NFAPI_NR_CCE_REG_MAPPING_INTERLEAVED) {
|
||||
uint16_t assertFatalCond = (N_reg%(bsize*R));
|
||||
AssertFatal(assertFatalCond == 0,"CCE to REG interleaving: Invalid configuration leading to non integer C (N_reg %us, bsize %d R %d)\n",N_reg, bsize, R);
|
||||
C = N_reg/(bsize*R);
|
||||
uint16_t assertFatalCond = (N_regs%(bsize*R));
|
||||
AssertFatal(assertFatalCond == 0,"CCE to REG interleaving: Invalid configuration leading to non integer C (N_reg %us, bsize %d R %d)\n",N_regs, bsize, R);
|
||||
C = N_regs/(bsize*R);
|
||||
}
|
||||
|
||||
if (pdcch_pdu_rel15->dci_pdu[d].RNTI != 0xFFFF) LOG_D(PHY, "CCE list generation for candidate %d: bundle size %d ilv size %d CceIndex %d\n", m, bsize, R, pdcch_pdu_rel15->dci_pdu[d].CceIndex);
|
||||
|
||||
if (pdcch_pdu_rel15->dci_pdu[d].RNTI != 0xFFFF)
|
||||
LOG_D(PHY, "CCE list generation for candidate %d: bundle size %d ilv size %d CceIndex %d\n", d, bsize, R, pdcch_pdu_rel15->dci_pdu[d].CceIndex);
|
||||
|
||||
for (uint8_t cce_idx=0; cce_idx<L; cce_idx++) {
|
||||
cce = &cce_list[d][cce_idx];
|
||||
cce->cce_idx = pdcch_pdu_rel15->dci_pdu[d].CceIndex + cce_idx;
|
||||
LOG_D(PHY, "cce_idx %d\n", cce->cce_idx);
|
||||
|
||||
if (pdcch_pdu_rel15->CceRegMappingType == NFAPI_NR_CCE_REG_MAPPING_INTERLEAVED) {
|
||||
LOG_D(PHY, "Interleaved CCE to REG mapping\n");
|
||||
uint8_t j = cce->cce_idx, j_prime;
|
||||
uint8_t r,c,idx;
|
||||
|
||||
for (uint8_t bundle_idx=0; bundle_idx<NR_NB_REG_PER_CCE/bsize; bundle_idx++) {
|
||||
j_prime = 6*j/bsize + bundle_idx;
|
||||
r = j_prime%R;
|
||||
c = (j_prime-r)/R;
|
||||
idx = (r*C + c + n_shift)%(N_reg/bsize);
|
||||
LOG_D(PHY, "bundle idx = %d \n j = %d \t j_prime = %d \t r = %d \t c = %d\n", idx, j , j_prime, r, c);
|
||||
|
||||
for (uint8_t reg_idx=0; reg_idx<bsize; reg_idx++) {
|
||||
reg = &cce->reg_list[reg_idx];
|
||||
reg->reg_idx = bsize*idx + reg_idx;
|
||||
reg->start_sc_idx = reg->reg_idx * NR_NB_SC_PER_RB;
|
||||
reg->symb_idx = 0;
|
||||
LOG_D(PHY, "reg %d symbol %d start subcarrier %d\n", reg->reg_idx, reg->symb_idx, reg->start_sc_idx);
|
||||
}
|
||||
}
|
||||
}
|
||||
else { // NFAPI_NR_CCE_REG_MAPPING_NON_INTERLEAVED
|
||||
LOG_D(PHY, "Non interleaved CCE to REG mapping\n");
|
||||
for (uint8_t reg_idx=0; reg_idx<NR_NB_REG_PER_CCE; reg_idx++) {
|
||||
|
||||
uint8_t j = cce->cce_idx;
|
||||
for (int k=6*j/bsize; k<(6*j/bsize+6/bsize); k++) { // loop over REG bundles
|
||||
|
||||
int f = cce_to_reg_interleaving(R, k, n_shift, C, bsize, N_regs);
|
||||
|
||||
for (uint8_t reg_idx=0; reg_idx<bsize; reg_idx++) {
|
||||
reg = &cce->reg_list[reg_idx];
|
||||
reg->reg_idx = cce->cce_idx*NR_NB_REG_PER_CCE + reg_idx;
|
||||
reg->start_sc_idx = reg->reg_idx * NR_NB_SC_PER_RB;
|
||||
reg->symb_idx = 0;
|
||||
reg->reg_idx = bsize*f + reg_idx;
|
||||
reg->start_sc_idx = (reg->reg_idx/dur) * NR_NB_SC_PER_RB;
|
||||
reg->symb_idx = reg_idx%dur;
|
||||
LOG_D(PHY, "reg %d symbol %d start subcarrier %d\n", reg->reg_idx, reg->symb_idx, reg->start_sc_idx);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -38,6 +38,7 @@
|
||||
#include "PHY/NR_REFSIG/ptrs_nr.h"
|
||||
#include "common/utils/LOG/vcd_signal_dumper.h"
|
||||
#include "common/utils/nr/nr_common.h"
|
||||
#include "executables/softmodem-common.h"
|
||||
|
||||
//#define DEBUG_DLSCH
|
||||
//#define DEBUG_DLSCH_MAPPING
|
||||
@@ -153,6 +154,9 @@ void nr_generate_pdsch(processingData_L1tx_t *msgTx,
|
||||
printf("\n");
|
||||
#endif
|
||||
|
||||
if (IS_SOFTMODEM_DLSIM)
|
||||
memcpy(harq->f, output, encoded_length);
|
||||
|
||||
for (int q=0; q<rel15->NrOfCodewords; q++) {
|
||||
/// scrambling
|
||||
start_meas(dlsch_scrambling_stats);
|
||||
|
||||
@@ -69,6 +69,10 @@ void free_gNB_dlsch(NR_gNB_DLSCH_t **dlschptr,
|
||||
free16(harq->b, a_segments * 1056);
|
||||
harq->b = NULL;
|
||||
}
|
||||
if (harq->f) {
|
||||
free16(harq->f, N_RB * NR_SYMBOLS_PER_SLOT * NR_NB_SC_PER_RB * 8 * NR_MAX_NB_LAYERS);
|
||||
harq->f = NULL;
|
||||
}
|
||||
for (int r = 0; r < a_segments; r++) {
|
||||
free(harq->c[r]);
|
||||
harq->c[r] = NULL;
|
||||
@@ -177,6 +181,10 @@ NR_gNB_DLSCH_t *new_gNB_dlsch(NR_DL_FRAME_PARMS *frame_parms,
|
||||
bzero(harq->c[r], 8448);
|
||||
}
|
||||
|
||||
harq->f = malloc16(N_RB * NR_SYMBOLS_PER_SLOT * NR_NB_SC_PER_RB * 8 * NR_MAX_NB_LAYERS);
|
||||
AssertFatal(harq->f, "cannot allocate harq->f\n");
|
||||
bzero(harq->f, N_RB * NR_SYMBOLS_PER_SLOT * NR_NB_SC_PER_RB * 8 * NR_MAX_NB_LAYERS);
|
||||
|
||||
return(dlsch);
|
||||
}
|
||||
|
||||
|
||||
@@ -1963,6 +1963,17 @@ int nr_rx_pusch(PHY_VARS_gNB *gNB,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (gNB->chest_time == 1) { // averaging time domain channel estimates
|
||||
nr_chest_time_domain_avg(frame_parms,
|
||||
gNB->pusch_vars[ulsch_id]->ul_ch_estimates,
|
||||
rel15_ul->nr_of_symbols,
|
||||
rel15_ul->start_symbol_index,
|
||||
rel15_ul->ul_dmrs_symb_pos,
|
||||
rel15_ul->rb_size);
|
||||
|
||||
gNB->pusch_vars[ulsch_id]->dmrs_symbol = get_next_dmrs_symbol_in_slot(rel15_ul->ul_dmrs_symb_pos, rel15_ul->start_symbol_index, rel15_ul->nr_of_symbols);
|
||||
}
|
||||
stop_meas(&gNB->ulsch_channel_estimation_stats);
|
||||
|
||||
#ifdef __AVX2__
|
||||
@@ -1978,7 +1989,8 @@ int nr_rx_pusch(PHY_VARS_gNB *gNB,
|
||||
if ((rel15_ul->ul_dmrs_symb_pos >> ((symbol + 1) % frame_parms->symbols_per_slot)) & 0x01)
|
||||
AssertFatal(1==0,"Double DMRS configuration is not yet supported\n");
|
||||
|
||||
gNB->pusch_vars[ulsch_id]->dmrs_symbol = symbol;
|
||||
if (gNB->chest_time == 0) // Non averaging time domain channel estimates
|
||||
gNB->pusch_vars[ulsch_id]->dmrs_symbol = symbol;
|
||||
|
||||
if (rel15_ul->dmrs_config_type == 0) {
|
||||
// if no data in dmrs cdm group is 1 only even REs have no data
|
||||
|
||||
@@ -44,19 +44,19 @@ void nr_ulsch_qpsk_llr(int32_t *rxdataF_comp,
|
||||
uint32_t nb_re,
|
||||
uint8_t symbol)
|
||||
{
|
||||
uint32_t *rxF = (uint32_t*)rxdataF_comp;
|
||||
uint32_t *llr32 = (uint32_t*)ulsch_llr;
|
||||
c16_t *rxF = (c16_t *)rxdataF_comp;
|
||||
c16_t *llr32 = (c16_t *)ulsch_llr;
|
||||
|
||||
if (!llr32) {
|
||||
LOG_E(PHY,"nr_ulsch_qpsk_llr: llr is null, symbol %d, llr32 = %p\n",symbol, llr32);
|
||||
}
|
||||
/*
|
||||
for (i = 0; i < nb_re; i++) {
|
||||
*llr32 = *rxF;
|
||||
for (int i = 0; i < nb_re; i++) {
|
||||
//*llr32 = *rxF;
|
||||
llr32->r = rxF->r >> 3;
|
||||
llr32->i = rxF->i >> 3;
|
||||
rxF++;
|
||||
llr32++;
|
||||
}*/
|
||||
memcpy1((void*)llr32,(void*)rxF,nb_re<<2);
|
||||
}
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------------------------
|
||||
|
||||
@@ -93,7 +93,7 @@ short filt16a_m3_dc[16] = {
|
||||
-9831,-6554,-3277,0,3276,6553,9830,16384,12288,8192,4096,0,0,0,0,0};
|
||||
|
||||
short filt16a_1[16] = {
|
||||
16384,16384,16384,16384,16384,16384,16384,16384,16384,16384,16384,16384};
|
||||
16384,16384,16384,16384,16384,16384,16384,16384,16384,16384,16384,16384,0,0,0,0};
|
||||
|
||||
short filt16a_2l0[16] = {
|
||||
16384,12288,8192,4096,-4096,0,0,0,0,0,0,0,0,0,0,0};
|
||||
@@ -295,4 +295,4 @@ short filt24_end[24] = {
|
||||
|
||||
short filt24_middle[24] = {
|
||||
4096,4779,5461,6144,6827,7509,8192,8875,9557,10240,10923,11605,
|
||||
12288,11605,10923,10240,9557,8875,8192,7509,6827,6144,5461,4779};
|
||||
12288,11605,10923,10240,9557,8875,8192,7509,6827,6144,5461,4779};
|
||||
|
||||
@@ -34,6 +34,7 @@
|
||||
//#define DEBUG_PDSCH
|
||||
//#define DEBUG_PDCCH
|
||||
|
||||
#define CH_INTERP 0
|
||||
#define NO_INTERP 1
|
||||
|
||||
int nr_pbch_dmrs_correlation(PHY_VARS_NR_UE *ue,
|
||||
@@ -477,7 +478,7 @@ int nr_pdcch_channel_estimation(PHY_VARS_NR_UE *ue,
|
||||
unsigned char aarx;
|
||||
unsigned short k;
|
||||
unsigned int pilot_cnt;
|
||||
int16_t ch[2],*pil,*rxF,*dl_ch,*fl,*fm,*fr;
|
||||
int16_t ch[2],*pil,*rxF,*dl_ch;
|
||||
int ch_offset,symbol_offset;
|
||||
|
||||
int **rxdataF=ue->common_vars.common_vars_rx_data_per_thread[proc->thread_id].rxdataF;
|
||||
@@ -492,9 +493,11 @@ int nr_pdcch_channel_estimation(PHY_VARS_NR_UE *ue,
|
||||
proc->thread_id, gNB_id,ch_offset,ue->frame_parms.ofdm_symbol_size,ue->frame_parms.Ncp,Ns,symbol);
|
||||
#endif
|
||||
|
||||
fl = filt16a_l1;
|
||||
fm = filt16a_m1;
|
||||
fr = filt16a_r1;
|
||||
#if CH_INTERP
|
||||
int16_t *fl = filt16a_l1;
|
||||
int16_t *fm = filt16a_m1;
|
||||
int16_t *fr = filt16a_r1;
|
||||
#endif
|
||||
|
||||
// checking if re-initialization of scrambling IDs is needed (should be done here but scrambling ID for PDCCH is not taken from RRC)
|
||||
if (scrambling_id != ue->scramblingID_pdcch){
|
||||
@@ -523,6 +526,7 @@ int nr_pdcch_channel_estimation(PHY_VARS_NR_UE *ue,
|
||||
|
||||
printf("dl_ch addr %p\n",dl_ch);
|
||||
#endif
|
||||
#if CH_INTERP
|
||||
// if ((ue->frame_parms.N_RB_DL&1)==0) {
|
||||
// Treat first 2 pilots specially (left edge)
|
||||
ch[0] = (int16_t)(((int32_t)pil[0]*rxF[0] - (int32_t)pil[1]*rxF[1])>>15);
|
||||
@@ -651,6 +655,33 @@ int nr_pdcch_channel_estimation(PHY_VARS_NR_UE *ue,
|
||||
rxF += 8;
|
||||
k += 4;
|
||||
}
|
||||
#else //ELSE CH_INTERP
|
||||
int ch_sum[2] = {0, 0};
|
||||
|
||||
for (pilot_cnt = 0; pilot_cnt < 3*nb_rb_coreset; pilot_cnt++) {
|
||||
if (k >= ue->frame_parms.ofdm_symbol_size) {
|
||||
k -= ue->frame_parms.ofdm_symbol_size;
|
||||
rxF = (int16_t *)&rxdataF[aarx][(symbol_offset+k+1)];
|
||||
}
|
||||
#ifdef DEBUG_PDCCH
|
||||
printf("pilot[%d] = (%d, %d)\trxF[%d] = (%d, %d)\n", pilot_cnt, pil[0], pil[1], k+1, rxF[0], rxF[1]);
|
||||
#endif
|
||||
ch_sum[0] += (int16_t)(((int32_t)pil[0]*rxF[0] - (int32_t)pil[1]*rxF[1])>>15);
|
||||
ch_sum[1] += (int16_t)(((int32_t)pil[0]*rxF[1] + (int32_t)pil[1]*rxF[0])>>15);
|
||||
pil += 2;
|
||||
rxF += 8;
|
||||
k += 4;
|
||||
|
||||
if (pilot_cnt % 3 == 2) {
|
||||
ch[0] = ch_sum[0] / 3;
|
||||
ch[1] = ch_sum[1] / 3;
|
||||
multadd_real_vector_complex_scalar(filt16a_1, ch, dl_ch, 16);
|
||||
dl_ch += 24;
|
||||
ch_sum[0] = 0;
|
||||
ch_sum[1] = 0;
|
||||
}
|
||||
}
|
||||
#endif //END CH_INTERP
|
||||
|
||||
|
||||
//}
|
||||
@@ -683,7 +714,7 @@ int nr_pdsch_channel_estimation(PHY_VARS_NR_UE *ue,
|
||||
int ch_offset,symbol_offset;
|
||||
|
||||
uint8_t nushift;
|
||||
int **dl_ch_estimates =ue->pdsch_vars[proc->thread_id][gNB_id]->dl_ch_estimates;
|
||||
int **dl_ch_estimates = ue->pdsch_vars[proc->thread_id][gNB_id]->dl_ch_estimates;
|
||||
int **rxdataF=ue->common_vars.common_vars_rx_data_per_thread[proc->thread_id].rxdataF;
|
||||
|
||||
ch_offset = ue->frame_parms.ofdm_symbol_size*symbol;
|
||||
@@ -808,7 +839,7 @@ int nr_pdsch_channel_estimation(PHY_VARS_NR_UE *ue,
|
||||
printf("rxF addr %p p %d\n", rxF,p);
|
||||
printf("dl_ch addr %p nushift %d\n",dl_ch,nushift);
|
||||
#endif
|
||||
if (config_type == NFAPI_NR_DMRS_TYPE1 && ue->prb_interpolation == 0) {
|
||||
if (config_type == NFAPI_NR_DMRS_TYPE1 && ue->chest_freq == 0) {
|
||||
|
||||
// Treat first 2 pilots specially (left edge)
|
||||
ch[0] = (int16_t)(((int32_t)pil[0]*rxF[0] - (int32_t)pil[1]*rxF[1])>>15);
|
||||
@@ -985,7 +1016,7 @@ int nr_pdsch_channel_estimation(PHY_VARS_NR_UE *ue,
|
||||
8);
|
||||
}
|
||||
}
|
||||
} else if (config_type == NFAPI_NR_DMRS_TYPE2 && ue->prb_interpolation == 0){ //pdsch_dmrs_type2 |dmrs_r,dmrs_l,0,0,0,0,dmrs_r,dmrs_l,0,0,0,0|
|
||||
} else if (config_type == NFAPI_NR_DMRS_TYPE2 && ue->chest_freq == 0){ //pdsch_dmrs_type2 |dmrs_r,dmrs_l,0,0,0,0,dmrs_r,dmrs_l,0,0,0,0|
|
||||
|
||||
// Treat first 4 pilots specially (left edge)
|
||||
ch_l[0] = (int16_t)(((int32_t)pil[0]*rxF[0] - (int32_t)pil[1]*rxF[1])>>15);
|
||||
|
||||
@@ -142,7 +142,8 @@ static void nr_pdcch_demapping_deinterleaving(uint32_t *llr,
|
||||
|
||||
int B_rb = reg_bundle_size_L/coreset_time_dur; // nb of RBs occupied by each REG bundle
|
||||
int num_bundles_per_cce = 6/reg_bundle_size_L;
|
||||
int max_bundles = NR_MAX_PDCCH_AGG_LEVEL*num_bundles_per_cce;
|
||||
int n_cce = N_regs/6;
|
||||
int max_bundles = n_cce*num_bundles_per_cce;
|
||||
int f_bundle_j_list[max_bundles];
|
||||
|
||||
// for each bundle
|
||||
@@ -359,10 +360,7 @@ void nr_pdcch_extract_rbs_single(int32_t **rxdataF,
|
||||
* According to this equations, DM-RS PDCCH are mapped on k where k%12==1 || k%12==5 || k%12==9
|
||||
*
|
||||
*/
|
||||
// the bitmap coreset_frq_domain contains 45 bits
|
||||
#define CORESET_FREQ_DOMAIN_BITMAP_SIZE 45
|
||||
// each bit is associated to 6 RBs
|
||||
#define BIT_TO_NBR_RB_CORESET_FREQ_DOMAIN 6
|
||||
|
||||
#define NBR_RE_PER_RB_WITH_DMRS 12
|
||||
// after removing the 3 DMRS RE, the RB contains 9 RE with PDCCH
|
||||
#define NBR_RE_PER_RB_WITHOUT_DMRS 9
|
||||
@@ -686,9 +684,9 @@ int32_t nr_rx_pdcch(PHY_VARS_NR_UE *ue,
|
||||
|
||||
// Pointers to extracted PDCCH symbols in frequency-domain.
|
||||
int32_t rx_size = 4*273*12;
|
||||
int32_t rxdataF_ext[4*frame_parms->nb_antennas_rx][rx_size];
|
||||
int32_t rxdataF_comp[4*frame_parms->nb_antennas_rx][rx_size];
|
||||
int32_t pdcch_dl_ch_estimates_ext[4*frame_parms->nb_antennas_rx][rx_size];
|
||||
__attribute__ ((aligned(32))) int32_t rxdataF_ext[4*frame_parms->nb_antennas_rx][rx_size];
|
||||
__attribute__ ((aligned(32))) int32_t rxdataF_comp[4*frame_parms->nb_antennas_rx][rx_size];
|
||||
__attribute__ ((aligned(32))) int32_t pdcch_dl_ch_estimates_ext[4*frame_parms->nb_antennas_rx][rx_size];
|
||||
|
||||
// Pointer to llrs, 4-bit resolution.
|
||||
int32_t llr_size = 2*4*100*12;
|
||||
@@ -920,7 +918,7 @@ uint8_t nr_dci_decoding_procedure(PHY_VARS_NR_UE *ue,
|
||||
proc->frame_rx, proc->nr_slot_rx,n_rnti,nr_dci_format_string[rel15->dci_format_options[k]],CCEind,dci_length,*(unsigned long long*)dci_estimation);
|
||||
uint16_t mb = nr_dci_false_detection(dci_estimation,tmp_e,L*108,n_rnti, NR_POLAR_DCI_MESSAGE_TYPE, dci_length, L);
|
||||
ue->dci_thres = (ue->dci_thres + mb) / 2;
|
||||
if (mb > (ue->dci_thres+20)) {
|
||||
if (mb > (ue->dci_thres+30)) {
|
||||
LOG_W(PHY,"DCI false positive. Dropping DCI index %d. Mismatched bits: %d/%d. Current DCI threshold: %d\n",j,mb,L*108,ue->dci_thres);
|
||||
continue;
|
||||
}
|
||||
|
||||
@@ -319,7 +319,8 @@ int nr_rx_pdsch(PHY_VARS_NR_UE *ue,
|
||||
dlsch0_harq->n_dmrs_cdm_groups,
|
||||
dlsch0_harq->Nl,
|
||||
frame_parms,
|
||||
dlsch0_harq->dlDmrsSymbPos);
|
||||
dlsch0_harq->dlDmrsSymbPos,
|
||||
ue->chest_time);
|
||||
stop_meas(&ue->generic_stat_bis[proc->thread_id][slot]);
|
||||
if (cpumeas(CPUMEAS_GETSTATE))
|
||||
LOG_D(PHY, "[AbsSFN %u.%d] Slot%d Symbol %d type %d: Pilot/Data extraction %5.2f \n",
|
||||
@@ -1610,7 +1611,8 @@ unsigned short nr_dlsch_extract_rbs_single(int **rxdataF,
|
||||
unsigned short nb_rb_pdsch,
|
||||
uint8_t n_dmrs_cdm_groups,
|
||||
NR_DL_FRAME_PARMS *frame_parms,
|
||||
uint16_t dlDmrsSymbPos)
|
||||
uint16_t dlDmrsSymbPos,
|
||||
int chest_time_type)
|
||||
{
|
||||
if (config_type == NFAPI_NR_DMRS_TYPE1) {
|
||||
AssertFatal(n_dmrs_cdm_groups == 1 || n_dmrs_cdm_groups == 2,
|
||||
@@ -1621,7 +1623,12 @@ unsigned short nr_dlsch_extract_rbs_single(int **rxdataF,
|
||||
}
|
||||
|
||||
const unsigned short start_re = (frame_parms->first_carrier_offset + start_rb * NR_NB_SC_PER_RB) % frame_parms->ofdm_symbol_size;
|
||||
const int8_t validDmrsEst = get_valid_dmrs_idx_for_channel_est(dlDmrsSymbPos, symbol);
|
||||
int8_t validDmrsEst;
|
||||
|
||||
if (chest_time_type == 0)
|
||||
validDmrsEst = get_valid_dmrs_idx_for_channel_est(dlDmrsSymbPos,symbol);
|
||||
else
|
||||
validDmrsEst = get_next_dmrs_symbol_in_slot(dlDmrsSymbPos,0,14); // get first dmrs symbol index
|
||||
|
||||
for (unsigned char aarx = 0; aarx < frame_parms->nb_antennas_rx; aarx++) {
|
||||
|
||||
@@ -1708,7 +1715,8 @@ void nr_dlsch_extract_rbs(int **rxdataF,
|
||||
uint8_t n_dmrs_cdm_groups,
|
||||
uint8_t Nl,
|
||||
NR_DL_FRAME_PARMS *frame_parms,
|
||||
uint16_t dlDmrsSymbPos)
|
||||
uint16_t dlDmrsSymbPos,
|
||||
int chest_time_type)
|
||||
{
|
||||
|
||||
unsigned short k,rb;
|
||||
@@ -1726,7 +1734,10 @@ void nr_dlsch_extract_rbs(int **rxdataF,
|
||||
nushift = (n_dmrs_cdm_groups -1)<<1;//delta in Table 7.4.1.1.2-2
|
||||
}
|
||||
|
||||
validDmrsEst = get_valid_dmrs_idx_for_channel_est(dlDmrsSymbPos,symbol);
|
||||
if (chest_time_type == 0)
|
||||
validDmrsEst = get_valid_dmrs_idx_for_channel_est(dlDmrsSymbPos,symbol);
|
||||
else
|
||||
validDmrsEst = get_next_dmrs_symbol_in_slot(dlDmrsSymbPos,0,14); // get first dmrs symbol index
|
||||
|
||||
for (aarx=0; aarx<frame_parms->nb_antennas_rx; aarx++) {
|
||||
|
||||
|
||||
@@ -638,11 +638,10 @@ int nr_dlsch_qpsk_llr(NR_DL_FRAME_PARMS *frame_parms,
|
||||
uint8_t beamforming_mode)
|
||||
{
|
||||
|
||||
uint32_t *rxF = (uint32_t *)&rxdataF_comp[((int32_t)symbol*nb_rb*12)];
|
||||
uint32_t *llr32;
|
||||
c16_t *rxF = (c16_t *)&rxdataF_comp[((int32_t)symbol*nb_rb*12)];
|
||||
c16_t *llr32 = (c16_t *)dlsch_llr;
|
||||
int i;
|
||||
|
||||
llr32 = (uint32_t*)dlsch_llr;
|
||||
if (!llr32) {
|
||||
LOG_E(PHY,"nr_dlsch_qpsk_llr: llr is null, symbol %d, llr32=%p\n",symbol, llr32);
|
||||
return(-1);
|
||||
@@ -656,8 +655,10 @@ int nr_dlsch_qpsk_llr(NR_DL_FRAME_PARMS *frame_parms,
|
||||
llr32);
|
||||
*/
|
||||
for (i=0; i<len; i++) {
|
||||
*llr32 = *rxF;
|
||||
//printf("dlsch_qpsk_llr %d : (%d,%d)\n",i,((int16_t*)llr32)[0],((int16_t*)llr32)[1]);
|
||||
//*llr32 = *rxF;
|
||||
llr32->r = rxF->r >> 3;
|
||||
llr32->i = rxF->i >> 3;
|
||||
//printf("dlsch_qpsk_llr %d : (%d,%d)\n", i, llr32->r, llr32->i);
|
||||
rxF++;
|
||||
llr32++;
|
||||
}
|
||||
|
||||
@@ -430,8 +430,8 @@ int nr_rx_pbch( PHY_VARS_NR_UE *ue,
|
||||
|
||||
for (symbol=1; symbol<4; symbol++) {
|
||||
const uint16_t nb_re=symbol == 2 ? 72 : 180;
|
||||
struct complex16 rxdataF_ext[frame_parms->nb_antennas_rx][PBCH_MAX_RE_PER_SYMBOL];
|
||||
struct complex16 dl_ch_estimates_ext[frame_parms->nb_antennas_rx][PBCH_MAX_RE_PER_SYMBOL];
|
||||
__attribute__ ((aligned(32))) struct complex16 rxdataF_ext[frame_parms->nb_antennas_rx][PBCH_MAX_RE_PER_SYMBOL];
|
||||
__attribute__ ((aligned(32))) struct complex16 dl_ch_estimates_ext[frame_parms->nb_antennas_rx][PBCH_MAX_RE_PER_SYMBOL];
|
||||
memset(dl_ch_estimates_ext,0, sizeof dl_ch_estimates_ext);
|
||||
nr_pbch_extract(nr_ue_common_vars->common_vars_rx_data_per_thread[proc->thread_id].rxdataF,
|
||||
estimateSz,
|
||||
@@ -456,7 +456,7 @@ int nr_rx_pbch( PHY_VARS_NR_UE *ue,
|
||||
#ifdef DEBUG_PBCH
|
||||
LOG_I(PHY,"[PHY] PBCH log2_maxh = %d (%d)\n",nr_ue_pbch_vars->log2_maxh,max_h);
|
||||
#endif
|
||||
struct complex16 rxdataF_comp[frame_parms->nb_antennas_rx][PBCH_MAX_RE_PER_SYMBOL];
|
||||
__attribute__ ((aligned(32))) struct complex16 rxdataF_comp[frame_parms->nb_antennas_rx][PBCH_MAX_RE_PER_SYMBOL];
|
||||
nr_pbch_channel_compensation(rxdataF_ext,
|
||||
dl_ch_estimates_ext,
|
||||
nb_re,
|
||||
|
||||
@@ -709,7 +709,8 @@ unsigned short nr_dlsch_extract_rbs_single(int **rxdataF,
|
||||
unsigned short nb_rb_pdsch,
|
||||
uint8_t n_dmrs_cdm_groups,
|
||||
NR_DL_FRAME_PARMS *frame_parms,
|
||||
uint16_t dlDmrsSymbPos);
|
||||
uint16_t dlDmrsSymbPos,
|
||||
int chest_time_type);
|
||||
|
||||
/** \fn dlsch_extract_rbs_multiple(int32_t **rxdataF,
|
||||
int32_t **dl_ch_estimates,
|
||||
@@ -747,7 +748,8 @@ void nr_dlsch_extract_rbs(int **rxdataF,
|
||||
uint8_t n_dmrs_cdm_groups,
|
||||
uint8_t Nl,
|
||||
NR_DL_FRAME_PARMS *frame_parms,
|
||||
uint16_t dlDmrsSymbPos);
|
||||
uint16_t dlDmrsSymbPos,
|
||||
int chest_time_type);
|
||||
|
||||
/** \fn dlsch_extract_rbs_TM7(int32_t **rxdataF,
|
||||
int32_t **dl_bf_ch_estimates,
|
||||
|
||||
@@ -96,6 +96,8 @@ typedef struct {
|
||||
uint32_t subframe;
|
||||
/// MIMO mode for this DLSCH
|
||||
MIMO_mode_t mimo_mode;
|
||||
/// Interleaver outputs
|
||||
uint8_t *f;
|
||||
/// LDPC lifting size
|
||||
uint32_t Z;
|
||||
} NR_DL_gNB_HARQ_t;
|
||||
@@ -826,7 +828,11 @@ typedef struct PHY_VARS_gNB_s {
|
||||
int **dl_precoder_SgNB[3];
|
||||
char log2_maxp; /// holds the maximum channel/precoder coefficient
|
||||
|
||||
int prb_interpolation;
|
||||
int max_ldpc_iterations;
|
||||
/// indicate the channel estimation technique in time domain
|
||||
int chest_time;
|
||||
/// indicate the channel estimation technique in freq domain
|
||||
int chest_freq;
|
||||
|
||||
/// if ==0 enables phy only test mode
|
||||
int mac_enabled;
|
||||
|
||||
@@ -773,11 +773,10 @@ typedef struct {
|
||||
|
||||
uint32_t X_u[64][839];
|
||||
|
||||
|
||||
uint32_t perfect_ce;
|
||||
// flag to activate PRB based averaging of channel estimates
|
||||
// when off, defaults to frequency domain interpolation
|
||||
int prb_interpolation;
|
||||
int chest_freq;
|
||||
int chest_time;
|
||||
int generate_ul_signal[NUMBER_OF_CONNECTED_gNB_MAX];
|
||||
|
||||
UE_NR_SCAN_INFO_t scan_info[NB_BANDS_MAX];
|
||||
@@ -865,6 +864,8 @@ typedef struct {
|
||||
/// N0 (used for abstraction)
|
||||
double N0;
|
||||
|
||||
uint8_t max_ldpc_iterations;
|
||||
|
||||
/// PDSCH Varaibles
|
||||
PDSCH_CONFIG_DEDICATED pdsch_config_dedicated[NUMBER_OF_CONNECTED_gNB_MAX];
|
||||
|
||||
|
||||
@@ -782,10 +782,14 @@ int phy_procedures_gNB_uespec_RX(PHY_VARS_gNB *gNB, int frame_rx, int slot_rx) {
|
||||
dB_fixed_x10(gNB->pusch_vars[ULSCH_id]->ulsch_power_tot),
|
||||
dB_fixed_x10(gNB->pusch_vars[ULSCH_id]->ulsch_noise_power_tot),gNB->pusch_thres);
|
||||
gNB->pusch_vars[ULSCH_id]->ulsch_power_tot = gNB->pusch_vars[ULSCH_id]->ulsch_noise_power_tot;
|
||||
nr_fill_indication(gNB,frame_rx, slot_rx, ULSCH_id, harq_pid, 1,1);
|
||||
gNB->pusch_vars[ULSCH_id]->DTX=1;
|
||||
if (stats) stats->DTX++;
|
||||
return 1;
|
||||
if (!get_softmodem_params()->phy_test) {
|
||||
/* in case of phy_test mode, we still want to decode to measure execution time.
|
||||
Therefore, we don't yet call nr_fill_indication, it will be called later */
|
||||
nr_fill_indication(gNB,frame_rx, slot_rx, ULSCH_id, harq_pid, 1,1);
|
||||
return 1;
|
||||
}
|
||||
} else {
|
||||
LOG_D(PHY, "PUSCH detected in %d.%d (%d,%d,%d)\n",frame_rx,slot_rx,
|
||||
dB_fixed_x10(gNB->pusch_vars[ULSCH_id]->ulsch_power_tot),
|
||||
@@ -845,10 +849,6 @@ int phy_procedures_gNB_uespec_RX(PHY_VARS_gNB *gNB, int frame_rx, int slot_rx) {
|
||||
}
|
||||
|
||||
stop_meas(&gNB->phy_proc_rx);
|
||||
// figure out a better way to choose slot_rx, 19 is ok for a particular TDD configuration with 30kHz SCS
|
||||
if ((frame_rx&127) == 0 && slot_rx==19) {
|
||||
LOG_I(NR_PHY, "Number of bad PUCCH received: %lu\n", gNB->bad_pucch);
|
||||
}
|
||||
|
||||
if (pucch_decode_done || pusch_decode_done) {
|
||||
T(T_GNB_PHY_PUCCH_PUSCH_IQ, T_INT(frame_rx), T_INT(slot_rx), T_BUFFER(&gNB->common_vars.rxdataF[0][0], gNB->frame_parms.symbols_per_slot * gNB->frame_parms.ofdm_symbol_size * 4));
|
||||
|
||||
@@ -36,6 +36,7 @@
|
||||
#include "assertions.h"
|
||||
#include "defs.h"
|
||||
#include "PHY/defs_nr_UE.h"
|
||||
#include "PHY/NR_REFSIG/dmrs_nr.h"
|
||||
#include "PHY/phy_extern_nr_ue.h"
|
||||
#include "PHY/MODULATION/modulation_UE.h"
|
||||
#include "PHY/NR_UE_TRANSPORT/nr_transport_ue.h"
|
||||
@@ -611,6 +612,15 @@ int nr_ue_pdsch_procedures(PHY_VARS_NR_UE *ue, UE_nr_rxtx_proc_t *proc, int gNB_
|
||||
}
|
||||
}
|
||||
|
||||
if (ue->chest_time == 1) { // averaging time domain channel estimates
|
||||
nr_chest_time_domain_avg(&ue->frame_parms,
|
||||
ue->pdsch_vars[proc->thread_id][gNB_id]->dl_ch_estimates,
|
||||
dlsch0_harq->nb_symbols,
|
||||
dlsch0_harq->start_symbol,
|
||||
dlsch0_harq->dlDmrsSymbPos,
|
||||
pdsch_nb_rb);
|
||||
}
|
||||
|
||||
uint16_t first_symbol_with_data = s0;
|
||||
uint32_t dmrs_data_re;
|
||||
|
||||
|
||||
@@ -1338,20 +1338,16 @@ int main(int argc, char **argv) {
|
||||
break;
|
||||
}
|
||||
|
||||
for (k=0; k<NUMBER_OF_UE_MAX; k++) {
|
||||
// Create transport channel structures for 2 transport blocks (MIMO)
|
||||
for (i=0; i<2; i++) {
|
||||
eNB->dlsch[k][i] = new_eNB_dlsch(Kmimo,8,Nsoft,N_RB_DL,0,&eNB->frame_parms);
|
||||
// Create transport channel structures for 1 transport block
|
||||
eNB->dlsch[0][0] = new_eNB_dlsch(Kmimo,8,Nsoft,N_RB_DL,0,&eNB->frame_parms);
|
||||
|
||||
if (!eNB->dlsch[k][i]) {
|
||||
printf("Can't get eNB dlsch structures\n");
|
||||
exit(-1);
|
||||
}
|
||||
|
||||
eNB->dlsch[k][i]->rnti = n_rnti+k;
|
||||
}
|
||||
if (!eNB->dlsch[0][0]) {
|
||||
printf("Can't get eNB dlsch structures\n");
|
||||
exit(-1);
|
||||
}
|
||||
|
||||
eNB->dlsch[0][0]->rnti = n_rnti+k;
|
||||
|
||||
#ifdef ENABLE_MBMS_SIM
|
||||
eNB->dlsch_MCH = new_eNB_dlsch(1,8,Nsoft,N_RB_DL, 0, &eNB->frame_parms);
|
||||
#endif
|
||||
|
||||
@@ -358,7 +358,7 @@ int main(int argc, char **argv) {
|
||||
unsigned short input_buffer_length;
|
||||
unsigned int ret;
|
||||
unsigned int coded_bits_per_codeword,nsymb;
|
||||
unsigned int tx_lev=0,tx_lev_dB,trials,errs[5]= {0,0,0,0,0},round_trials[4]= {0,0,0,0};
|
||||
unsigned int tx_lev=0,tx_lev_dB=0,trials,errs[5]= {0,0,0,0,0},round_trials[4]= {0,0,0,0};
|
||||
FILE *bler_fd=NULL;
|
||||
char bler_fname[512];
|
||||
FILE *time_meas_fd=NULL;
|
||||
|
||||
@@ -66,6 +66,7 @@
|
||||
#include "NR_RRCReconfiguration.h"
|
||||
#define inMicroS(a) (((double)(a))/(get_cpu_freq_GHz()*1000.0))
|
||||
#include "SIMULATION/LTE_PHY/common_sim.h"
|
||||
#include "PHY/NR_REFSIG/dmrs_nr.h"
|
||||
|
||||
#include <openair2/LAYER2/MAC/mac_vars.h>
|
||||
#include <openair2/RRC/LTE/rrc_vars.h>
|
||||
@@ -262,26 +263,41 @@ void update_ptrs_config(NR_CellGroupConfig_t *secondaryCellGroup, uint16_t *rbSi
|
||||
void update_dmrs_config(NR_CellGroupConfig_t *scg, int8_t* dmrs_arg);
|
||||
extern void fix_scd(NR_ServingCellConfig_t *scd);// forward declaration
|
||||
|
||||
/* specific dlsim DL preprocessor: uses rbStart/rbSize/mcs/nrOfLayers from command line of
|
||||
dlsim, does not search for CCE/PUCCH occasion but simply sets to 0 */
|
||||
/* specific dlsim DL preprocessor: uses rbStart/rbSize/mcs/nrOfLayers from command line of dlsim */
|
||||
int g_mcsIndex = -1, g_mcsTableIdx = 0, g_rbStart = -1, g_rbSize = -1, g_nrOfLayers = 1;
|
||||
void nr_dlsim_preprocessor(module_id_t module_id,
|
||||
frame_t frame,
|
||||
sub_frame_t slot) {
|
||||
|
||||
NR_UE_info_t *UE_info = RC.nrmac[module_id]->UE_info.list[0];
|
||||
AssertFatal(RC.nrmac[module_id]->UE_info.list[1]==NULL, "can have only a single UE\n");
|
||||
NR_UE_sched_ctrl_t *sched_ctrl = &UE_info->UE_sched_ctrl;
|
||||
NR_ServingCellConfigCommon_t *scc = RC.nrmac[0]->common_channels[0].ServingCellConfigCommon;
|
||||
|
||||
/* manually set free CCE to 0 */
|
||||
const int target_ss = NR_SearchSpace__searchSpaceType_PR_ue_Specific;
|
||||
sched_ctrl->search_space = get_searchspace(NULL, scc, sched_ctrl->active_bwp ? sched_ctrl->active_bwp->bwp_Dedicated : NULL, target_ss);
|
||||
uint8_t nr_of_candidates;
|
||||
find_aggregation_candidates(&sched_ctrl->aggregation_level,
|
||||
&nr_of_candidates,
|
||||
sched_ctrl->search_space,4);
|
||||
uint8_t nr_of_candidates = 0;
|
||||
if (g_mcsIndex < 4) {
|
||||
find_aggregation_candidates(&sched_ctrl->aggregation_level,
|
||||
&nr_of_candidates,
|
||||
sched_ctrl->search_space,8);
|
||||
}
|
||||
if (nr_of_candidates == 0) {
|
||||
find_aggregation_candidates(&sched_ctrl->aggregation_level,
|
||||
&nr_of_candidates,
|
||||
sched_ctrl->search_space,4);
|
||||
}
|
||||
sched_ctrl->coreset = get_coreset(RC.nrmac[module_id], scc, sched_ctrl->active_bwp->bwp_Dedicated, sched_ctrl->search_space, target_ss);
|
||||
sched_ctrl->cce_index = 0;
|
||||
uint32_t Y = get_Y(sched_ctrl->search_space, slot, UE_info->rnti);
|
||||
int CCEIndex = find_pdcch_candidate(RC.nrmac[module_id],
|
||||
/* CC_id = */ 0,
|
||||
sched_ctrl->aggregation_level,
|
||||
nr_of_candidates,
|
||||
&sched_ctrl->sched_pdcch,
|
||||
sched_ctrl->coreset,
|
||||
Y);
|
||||
AssertFatal(CCEIndex>=0, "%4d.%2d could not find CCE for DL DCI UE %d/RNTI %04x\n", frame, slot, 0, UE_info->rnti);
|
||||
sched_ctrl->cce_index = CCEIndex;
|
||||
|
||||
NR_pdsch_semi_static_t *ps = &sched_ctrl->pdsch_semi_static;
|
||||
|
||||
@@ -356,10 +372,13 @@ int main(int argc, char **argv)
|
||||
int i,aa;//,l;
|
||||
double sigma2, sigma2_dB=10, SNR, snr0=-2.0, snr1=2.0;
|
||||
uint8_t snr1set=0;
|
||||
double roundStats[500] = {0};
|
||||
double blerStats[500] = {0};
|
||||
double berStats[500] = {0};
|
||||
double snrStats[500] = {0};
|
||||
uint32_t errors_scrambling[4][100] = {{0}};
|
||||
int n_errors[4][100] = {{0}};
|
||||
int round_trials[4][100] = {{0}};
|
||||
double roundStats[100] = {0};
|
||||
double blerStats[4][100] = {{0}};
|
||||
double berStats[4][100] = {{0}};
|
||||
double snrStats[100] = {0};
|
||||
float effRate;
|
||||
//float psnr;
|
||||
float eff_tp_check = 0.7;
|
||||
@@ -377,7 +396,7 @@ int main(int argc, char **argv)
|
||||
//int freq_offset;
|
||||
// int subframe_offset;
|
||||
// char fname[40], vname[40];
|
||||
int trial, n_trials = 1, n_errors = 0, n_false_positive = 0;
|
||||
int trial, n_trials = 1, n_false_positive = 0;
|
||||
//int n_errors2, n_alamouti;
|
||||
uint8_t n_tx=1,n_rx=1;
|
||||
uint8_t round;
|
||||
@@ -433,7 +452,8 @@ int main(int argc, char **argv)
|
||||
uint16_t rbSize = 106;
|
||||
uint8_t mcsIndex = 9;
|
||||
uint8_t dlsch_threads = 0;
|
||||
int prb_inter = 0;
|
||||
int chest_type[2] = {0};
|
||||
uint8_t max_ldpc_iterations = 5;
|
||||
if ( load_configmodule(argc,argv,CONFIG_ENABLECMDLINEONLY) == 0) {
|
||||
exit_fun("[NR_DLSIM] Error, configuration module init failed\n");
|
||||
}
|
||||
@@ -444,7 +464,7 @@ int main(int argc, char **argv)
|
||||
|
||||
FILE *scg_fd=NULL;
|
||||
|
||||
while ((c = getopt (argc, argv, "f:hA:pf:g:in:s:S:t:x:y:z:M:N:F:GR:dPIL:Ea:b:d:e:q:m:w:T:U:X:")) != -1) {
|
||||
while ((c = getopt (argc, argv, "f:hA:pf:g:i:n:s:S:t:x:y:z:M:N:F:GR:dPI:L:Ea:b:d:e:m:w:T:U:q:X:Y")) != -1) {
|
||||
switch (c) {
|
||||
case 'f':
|
||||
scg_fd = fopen(optarg,"r");
|
||||
@@ -501,7 +521,9 @@ int main(int argc, char **argv)
|
||||
break;
|
||||
|
||||
case 'i':
|
||||
prb_inter=1;
|
||||
for(i=0; i < atoi(optarg); i++){
|
||||
chest_type[i] = atoi(argv[optind++]);
|
||||
}
|
||||
break;
|
||||
|
||||
case 'n':
|
||||
@@ -588,9 +610,7 @@ int main(int argc, char **argv)
|
||||
break;
|
||||
|
||||
case 'I':
|
||||
run_initial_sync=1;
|
||||
//target_error_rate=0.1;
|
||||
slot = 0;
|
||||
max_ldpc_iterations = atoi(optarg);
|
||||
break;
|
||||
|
||||
case 'L':
|
||||
@@ -654,6 +674,12 @@ int main(int argc, char **argv)
|
||||
gNBthreads[sizeof(gNBthreads)-1]=0;
|
||||
break;
|
||||
|
||||
case 'Y':
|
||||
run_initial_sync=1;
|
||||
//target_error_rate=0.1;
|
||||
slot = 0;
|
||||
break;
|
||||
|
||||
default:
|
||||
case 'h':
|
||||
printf("%s -h(elp) -p(extended_prefix) -N cell_id -f output_filename -F input_filename -g channel_model -n n_frames -s snr0 -S snr1 -x transmission_mode -y TXant -z RXant -i Intefrence0 -j Interference1 -A interpolation_file -C(alibration offset dB) -N CellId\n",
|
||||
@@ -669,7 +695,7 @@ int main(int argc, char **argv)
|
||||
printf("-g [A,B,C,D,E,F,G,R] Use 3GPP SCM (A,B,C,D) or 36-101 (E-EPA,F-EVA,G-ETU) models or R for MIMO model (ignores delay spread and Ricean factor)\n");
|
||||
printf("-y Number of TX antennas used in gNB\n");
|
||||
printf("-z Number of RX antennas used in UE\n");
|
||||
printf("-i Activate PRB based averaging for channel estimation. Frequncy domain interpolation by default.\n");
|
||||
printf("-i Change channel estimation technique. Arguments list: Frequency domain {0:Linear interpolation, 1:PRB based averaging}, Time domain {0:Estimates of last DMRS symbol, 1:Average of DMRS symbols}\n");
|
||||
//printf("-j Relative strength of second intefering gNB (in dB) - cell_id mod 3 = 2\n");
|
||||
printf("-R N_RB_DL\n");
|
||||
printf("-O oversampling factor (1,2,4,8,16)\n");
|
||||
@@ -686,12 +712,14 @@ int main(int argc, char **argv)
|
||||
printf("-e MSC index\n");
|
||||
printf("-q MCS Table index\n");
|
||||
printf("-t Acceptable effective throughput (in percentage)\n");
|
||||
printf("-I Maximum LDPC decoder iterations\n");
|
||||
printf("-T Enable PTRS, arguments list L_PTRS{0,1,2} K_PTRS{2,4}, e.g. -T 2 0 2 \n");
|
||||
printf("-U Change DMRS Config, arguments list DMRS TYPE{0=A,1=B} DMRS AddPos{0:2} DMRS ConfType{1:2}, e.g. -U 3 0 2 1 \n");
|
||||
printf("-P Print DLSCH performances\n");
|
||||
printf("-w Write txdata to binary file (one frame)\n");
|
||||
printf("-d number of dlsch threads, 0: no dlsch parallelization\n");
|
||||
printf("-X gNB thread pool configuration, n => no threads");
|
||||
printf("-X gNB thread pool configuration, n => no threads\n");
|
||||
printf("-Y Run initial sync in UE\n");
|
||||
exit (-1);
|
||||
break;
|
||||
}
|
||||
@@ -705,6 +733,7 @@ int main(int argc, char **argv)
|
||||
|
||||
get_softmodem_params()->phy_test = 1;
|
||||
get_softmodem_params()->do_ra = 0;
|
||||
set_softmodem_optmask(SOFTMODEM_DLSIM_BIT);
|
||||
|
||||
if (snr1set==0)
|
||||
snr1 = snr0+10;
|
||||
@@ -947,11 +976,10 @@ int main(int argc, char **argv)
|
||||
PHY_vars_UE_g[0][0] = UE;
|
||||
memcpy(&UE->frame_parms,frame_parms,sizeof(NR_DL_FRAME_PARMS));
|
||||
UE->frame_parms.nb_antennas_rx = n_rx;
|
||||
UE->max_ldpc_iterations = max_ldpc_iterations;
|
||||
|
||||
if (run_initial_sync==1) UE->is_synchronized = 0;
|
||||
else {UE->is_synchronized = 1; UE->UE_mode[0]=PUSCH;}
|
||||
|
||||
UE->perfect_ce = 0;
|
||||
|
||||
if (init_nr_ue_signal(UE, 1) != 0)
|
||||
{
|
||||
@@ -981,8 +1009,8 @@ int main(int argc, char **argv)
|
||||
UE->if_inst->phy_config_request = nr_ue_phy_config_request;
|
||||
UE->if_inst->dl_indication = nr_ue_dl_indication;
|
||||
UE->if_inst->ul_indication = dummy_nr_ue_ul_indication;
|
||||
UE->prb_interpolation = prb_inter;
|
||||
|
||||
UE->chest_freq = chest_type[0];
|
||||
UE->chest_time = chest_type[1];
|
||||
|
||||
UE_mac->if_module = nr_ue_if_module_init(0);
|
||||
|
||||
@@ -990,7 +1018,6 @@ int main(int argc, char **argv)
|
||||
unsigned char *estimated_output_bit;
|
||||
unsigned char *test_input_bit;
|
||||
unsigned int errors_bit = 0;
|
||||
uint32_t errors_scrambling = 0;
|
||||
|
||||
initTpool("N", &(nrUE_params.Tpool), false);
|
||||
|
||||
@@ -1031,6 +1058,7 @@ int main(int argc, char **argv)
|
||||
nr_ue_phy_config_request(&UE_mac->phy_config);
|
||||
//NR_COMMON_channels_t *cc = RC.nrmac[0]->common_channels;
|
||||
snrRun = 0;
|
||||
int n_errs = 0;
|
||||
|
||||
gNB->threadPool = (tpool_t*)malloc(sizeof(tpool_t));
|
||||
initTpool(gNBthreads, gNB->threadPool, true);
|
||||
@@ -1064,11 +1092,9 @@ int main(int argc, char **argv)
|
||||
|
||||
clear_pdsch_stats(gNB);
|
||||
|
||||
n_errors = 0;
|
||||
effRate = 0;
|
||||
//n_errors2 = 0;
|
||||
//n_alamouti = 0;
|
||||
errors_scrambling=0;
|
||||
n_false_positive = 0;
|
||||
if (n_trials== 1) num_rounds = 1;
|
||||
|
||||
@@ -1100,16 +1126,12 @@ int main(int argc, char **argv)
|
||||
UE_harq_process->first_rx = 1;
|
||||
|
||||
while ((round<num_rounds) && (UE_harq_process->ack==0)) {
|
||||
round_trials[round][snrRun]++;
|
||||
|
||||
clear_nr_nfapi_information(RC.nrmac[0], 0, frame, slot);
|
||||
|
||||
UE_info->UE_sched_ctrl.harq_processes[harq_pid].ndi = !(trial&1);
|
||||
|
||||
|
||||
UE_info->UE_sched_ctrl.harq_processes[harq_pid].round = round;
|
||||
for (int i=0; i<MAX_NUM_CORESET; i++)
|
||||
gNB_mac->pdcch_cand[i] = 0;
|
||||
|
||||
|
||||
if (css_flag == 0) {
|
||||
nr_schedule_ue_spec(0, frame, slot);
|
||||
} else {
|
||||
@@ -1272,49 +1294,45 @@ int main(int argc, char **argv)
|
||||
&phy_pdcch_config,
|
||||
NULL);
|
||||
|
||||
//----------------------------------------------------------
|
||||
//---------------------- count errors ----------------------
|
||||
//----------------------------------------------------------
|
||||
|
||||
if (UE->dlsch[UE_proc.thread_id][0][0]->last_iteration_cnt >=
|
||||
UE->dlsch[UE_proc.thread_id][0][0]->max_ldpc_iterations+1)
|
||||
n_errors[round][snrRun]++;
|
||||
|
||||
NR_UE_PDSCH **pdsch_vars = UE->pdsch_vars[UE_proc.thread_id];
|
||||
int16_t *UE_llr = pdsch_vars[0]->llr[0];
|
||||
|
||||
TBS = UE_harq_process->TBS;//rel15->TBSize[0];
|
||||
uint16_t length_dmrs = get_num_dmrs(rel15->dlDmrsSymbPos);
|
||||
uint16_t nb_rb = rel15->rbSize;
|
||||
uint8_t nb_re_dmrs = rel15->dmrsConfigType == NFAPI_NR_DMRS_TYPE1 ? 6*UE_harq_process->n_dmrs_cdm_groups : 4*UE_harq_process->n_dmrs_cdm_groups;
|
||||
uint8_t mod_order = rel15->qamModOrder[0];
|
||||
uint8_t nb_symb_sch = rel15->NrOfSymbols;
|
||||
|
||||
available_bits = nr_get_G(nb_rb, nb_symb_sch, nb_re_dmrs, length_dmrs, mod_order, rel15->nrOfLayers);
|
||||
if(pdu_bit_map & 0x1) {
|
||||
available_bits-= (ptrsSymbPerSlot * ptrsRePerSymb *rel15->nrOfLayers* 2);
|
||||
printf("[DLSIM][PTRS] Available bits are: %5u, removed PTRS bits are: %5u \n",available_bits, (ptrsSymbPerSlot * ptrsRePerSymb *rel15->nrOfLayers* 2) );
|
||||
}
|
||||
|
||||
for (i = 0; i < available_bits; i++) {
|
||||
if(((gNB_dlsch->harq_process.f[i] == 0) && (UE_llr[i] <= 0)) ||
|
||||
((gNB_dlsch->harq_process.f[i] == 1) && (UE_llr[i] >= 0)))
|
||||
{
|
||||
if(errors_scrambling[round][snrRun] == 0) {
|
||||
LOG_D(PHY,"First bit in error in unscrambling = %d\n",i);
|
||||
}
|
||||
errors_scrambling[round][snrRun]++;
|
||||
}
|
||||
}
|
||||
|
||||
//printf("dlsim round %d ends\n",round);
|
||||
round++;
|
||||
} // round
|
||||
|
||||
//----------------------------------------------------------
|
||||
//---------------------- count errors ----------------------
|
||||
//----------------------------------------------------------
|
||||
|
||||
if (UE->dlsch[UE_proc.thread_id][0][0]->last_iteration_cnt >=
|
||||
UE->dlsch[UE_proc.thread_id][0][0]->max_ldpc_iterations+1)
|
||||
n_errors++;
|
||||
|
||||
//NR_UE_PDSCH **pdsch_vars = UE->pdsch_vars[UE_proc.thread_id];
|
||||
//int16_t *UE_llr = pdsch_vars[0]->llr[0];
|
||||
|
||||
TBS = UE_harq_process->TBS;//rel15->TBSize[0];
|
||||
uint16_t length_dmrs = get_num_dmrs(rel15->dlDmrsSymbPos);
|
||||
uint16_t nb_rb = rel15->rbSize;
|
||||
uint8_t nb_re_dmrs = rel15->dmrsConfigType == NFAPI_NR_DMRS_TYPE1 ? 6*UE_harq_process->n_dmrs_cdm_groups : 4*UE_harq_process->n_dmrs_cdm_groups;
|
||||
uint8_t mod_order = rel15->qamModOrder[0];
|
||||
uint8_t nb_symb_sch = rel15->NrOfSymbols;
|
||||
|
||||
available_bits = nr_get_G(nb_rb, nb_symb_sch, nb_re_dmrs, length_dmrs, mod_order, rel15->nrOfLayers);
|
||||
if(pdu_bit_map & 0x1) {
|
||||
available_bits-= (ptrsSymbPerSlot * ptrsRePerSymb *rel15->nrOfLayers* 2);
|
||||
LOG_D(PHY,"[DLSIM][PTRS] Available bits are: %5u, removed PTRS bits are: %5u \n",available_bits, (ptrsSymbPerSlot * ptrsRePerSymb *rel15->nrOfLayers* 2) );
|
||||
}
|
||||
|
||||
/*
|
||||
for (i = 0; i < available_bits; i++) {
|
||||
|
||||
if(((gNB_dlsch->harq_process.f[i] == 0) && (UE_llr[i] <= 0)) ||
|
||||
((gNB_dlsch->harq_process.f[i] == 1) && (UE_llr[i] >= 0)))
|
||||
{
|
||||
if(errors_scrambling == 0) {
|
||||
LOG_D(PHY,"\n");
|
||||
LOG_D(PHY,"First bit in error in unscrambling = %d\n",i);
|
||||
}
|
||||
errors_scrambling++;
|
||||
}
|
||||
|
||||
}
|
||||
*/
|
||||
for (i = 0; i < TBS; i++) {
|
||||
|
||||
estimated_output_bit[i] = (UE_harq_process->b[i/8] & (1 << (i & 7))) >> (i & 7);
|
||||
@@ -1322,19 +1340,14 @@ int main(int argc, char **argv)
|
||||
|
||||
if (estimated_output_bit[i] != test_input_bit[i]) {
|
||||
if(errors_bit == 0)
|
||||
LOG_D(PHY,"First bit in error in decoding = %d (errors scrambling %d)\n",i,errors_scrambling);
|
||||
LOG_D(PHY,"First bit in error in decoding = %d\n",i);
|
||||
errors_bit++;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
|
||||
if (errors_scrambling > 0) {
|
||||
if (n_trials == 1)
|
||||
printf("errors_scrambling = %u/%u (trial %d)\n", errors_scrambling, available_bits,trial);
|
||||
}
|
||||
|
||||
|
||||
if (errors_bit > 0) {
|
||||
n_false_positive++;
|
||||
if (n_trials == 1)
|
||||
@@ -1344,18 +1357,48 @@ int main(int argc, char **argv)
|
||||
if (UE_harq_process->ack==1) effRate += ((float)TBS)/round;
|
||||
} // noise trials
|
||||
|
||||
blerStats[snrRun] = (float) n_errors / (float) n_trials;
|
||||
roundStats[snrRun]/=((float)n_trials);
|
||||
berStats[snrRun] = (double)errors_scrambling/available_bits/n_trials;
|
||||
|
||||
blerStats[0][snrRun] = (double)n_errors[0][snrRun]/round_trials[0][snrRun];
|
||||
blerStats[1][snrRun] = (double)n_errors[1][snrRun]/round_trials[1][snrRun];
|
||||
blerStats[2][snrRun] = (double)n_errors[2][snrRun]/round_trials[2][snrRun];
|
||||
blerStats[3][snrRun] = (double)n_errors[3][snrRun]/round_trials[3][snrRun];
|
||||
|
||||
berStats[0][snrRun] = (double)errors_scrambling[0][snrRun]/available_bits/round_trials[0][snrRun];
|
||||
berStats[1][snrRun] = (double)errors_scrambling[1][snrRun]/available_bits/round_trials[1][snrRun];
|
||||
berStats[2][snrRun] = (double)errors_scrambling[2][snrRun]/available_bits/round_trials[2][snrRun];
|
||||
berStats[3][snrRun] = (double)errors_scrambling[3][snrRun]/available_bits/round_trials[3][snrRun];
|
||||
|
||||
effRate /= n_trials;
|
||||
printf("*****************************************\n");
|
||||
printf("SNR %f, (false positive %f)\n", SNR,
|
||||
(float) n_errors / (float) n_trials);
|
||||
printf("*****************************************\n");
|
||||
printf("SNR %f: n_errors (%d/%d,%d/%d,%d/%d,%d/%d) (negative CRC), false_positive %d/%d, errors_scrambling (%u/%u,%u/%u,%u/%u,%u/%u\n",
|
||||
SNR,
|
||||
n_errors[0][snrRun], round_trials[0][snrRun],
|
||||
n_errors[1][snrRun], round_trials[1][snrRun],
|
||||
n_errors[2][snrRun], round_trials[2][snrRun],
|
||||
n_errors[3][snrRun], round_trials[3][snrRun],
|
||||
n_false_positive, n_trials,
|
||||
errors_scrambling[0][snrRun], available_bits*round_trials[0][snrRun],
|
||||
errors_scrambling[1][snrRun], available_bits*round_trials[1][snrRun],
|
||||
errors_scrambling[2][snrRun], available_bits*round_trials[2][snrRun],
|
||||
errors_scrambling[3][snrRun], available_bits*round_trials[3][snrRun]);
|
||||
printf("\n");
|
||||
dump_pdsch_stats(stdout,gNB);
|
||||
printf("SNR %f : n_errors (negative CRC) = %d/%d, Avg round %.2f, Channel BER %e, BLER %.2f, Eff Rate %.4f bits/slot, Eff Throughput %.2f, TBS %u bits/slot\n",
|
||||
SNR, n_errors, n_trials,roundStats[snrRun],berStats[snrRun],blerStats[snrRun],effRate,effRate/TBS*100,TBS);
|
||||
printf("SNR %f: Channel BLER (%e,%e,%e,%e), Channel BER (%e,%e,%e,%e) Avg round %.2f, Eff Rate %.4f bits/slot, Eff Throughput %.2f, TBS %u bits/slot\n",
|
||||
SNR,
|
||||
blerStats[0][snrRun],
|
||||
blerStats[1][snrRun],
|
||||
blerStats[2][snrRun],
|
||||
blerStats[3][snrRun],
|
||||
berStats[0][snrRun],
|
||||
berStats[1][snrRun],
|
||||
berStats[2][snrRun],
|
||||
berStats[3][snrRun],
|
||||
roundStats[snrRun],
|
||||
effRate,
|
||||
effRate/TBS*100,
|
||||
TBS);
|
||||
printf("*****************************************\n");
|
||||
printf("\n");
|
||||
|
||||
if (print_perf==1) {
|
||||
@@ -1415,6 +1458,7 @@ int main(int argc, char **argv)
|
||||
LOG_M("rxsig0.m","rxs0", UE->common_vars.rxdata[0], frame_length_complex_samples, 1, 1);
|
||||
if (UE->frame_parms.nb_antennas_rx>1)
|
||||
LOG_M("rxsig1.m","rxs1", UE->common_vars.rxdata[1], frame_length_complex_samples, 1, 1);
|
||||
LOG_M("rxF0.m","rxF0", UE->common_vars.common_vars_rx_data_per_thread[UE_proc.thread_id].rxdataF[0], frame_parms->samples_per_slot_wCP, 1, 1);
|
||||
LOG_M("chestF0.m","chF0",&UE->pdsch_vars[0][0]->dl_ch_estimates_ext[0][0],g_rbSize*12*14,1,1);
|
||||
write_output("rxF_comp.m","rxFc",&UE->pdsch_vars[0][0]->rxdataF_comp0[0][0],N_RB_DL*12*14,1,1);
|
||||
LOG_M("rxF_llr.m","rxFllr",UE->pdsch_vars[UE_proc.thread_id][0]->llr[0],available_bits,1,0);
|
||||
@@ -1428,6 +1472,7 @@ int main(int argc, char **argv)
|
||||
|
||||
snrStats[snrRun] = SNR;
|
||||
snrRun++;
|
||||
n_errs = n_errors[0][snrRun];
|
||||
} // NSR
|
||||
|
||||
LOG_M("dlsimStats.m","SNR",snrStats,snrRun,1,7);
|
||||
@@ -1471,8 +1516,8 @@ int main(int argc, char **argv)
|
||||
|
||||
if (scg_fd)
|
||||
fclose(scg_fd);
|
||||
return(n_errors);
|
||||
|
||||
|
||||
return n_errs;
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -567,8 +567,6 @@ int main(int argc, char **argv)
|
||||
if (run_initial_sync==1) UE->is_synchronized = 0;
|
||||
else UE->is_synchronized = 1;
|
||||
|
||||
UE->perfect_ce = 0;
|
||||
|
||||
if(eps!=0.0)
|
||||
UE->UE_fo_compensation = 1; // if a frequency offset is set then perform fo estimation and compensation
|
||||
|
||||
|
||||
@@ -476,7 +476,6 @@ int main(int argc, char **argv)
|
||||
UE = calloc(1,sizeof(PHY_VARS_NR_UE));
|
||||
memcpy(&UE->frame_parms,frame_parms,sizeof(NR_DL_FRAME_PARMS));
|
||||
UE->frame_parms.nb_antennas_rx=1;
|
||||
UE->perfect_ce = 0;
|
||||
|
||||
if(eps!=0.0)
|
||||
UE->UE_fo_compensation = 1; // if a frequency offset is set then perform fo estimation and compensation
|
||||
|
||||
@@ -141,6 +141,7 @@ int main(int argc, char **argv)
|
||||
uint16_t nb_rb = 50;
|
||||
uint8_t Imcs = 9;
|
||||
uint8_t Nl = 1;
|
||||
uint8_t max_ldpc_iterations = 5;
|
||||
|
||||
double DS_TDL = .03;
|
||||
|
||||
@@ -395,6 +396,8 @@ int main(int argc, char **argv)
|
||||
frame_parms->N_RB_DL = N_RB_DL;
|
||||
frame_parms->N_RB_UL = N_RB_UL;
|
||||
frame_parms->Ncp = extended_prefix_flag ? EXTENDED : NORMAL;
|
||||
gNB->max_ldpc_iterations = max_ldpc_iterations;
|
||||
|
||||
crcTableInit();
|
||||
|
||||
memcpy(&gNB->frame_parms, frame_parms, sizeof(NR_DL_FRAME_PARMS));
|
||||
|
||||
@@ -312,16 +312,15 @@ int main(int argc, char **argv)
|
||||
float roundStats[100];
|
||||
double effRate[100];
|
||||
double effTP[100];
|
||||
float eff_tp_check = 0.7;
|
||||
float eff_tp_check = 100;
|
||||
uint8_t snrRun;
|
||||
int prb_inter = 0;
|
||||
int chest_type[2] = {0};
|
||||
|
||||
int enable_ptrs = 0;
|
||||
int modify_dmrs = 0;
|
||||
/* L_PTRS = ptrs_arg[0], K_PTRS = ptrs_arg[1] */
|
||||
int ptrs_arg[2] = {-1,-1};// Invalid values
|
||||
/* mapping type = dmrs_arg[0], Add Pos = dmrs_arg[1], dmrs config type = dmrs_arg[2] */
|
||||
int dmrs_arg[3] = {-1,-1,-1};// Invalid values
|
||||
int dmrs_arg[4] = {-1,-1,-1,-1};// Invalid values
|
||||
uint16_t ptrsSymPos = 0;
|
||||
uint16_t ptrsSymbPerSlot = 0;
|
||||
uint16_t ptrsRePerSymb = 0;
|
||||
@@ -338,6 +337,8 @@ int main(int argc, char **argv)
|
||||
int ibwps=24;
|
||||
int ibwp_rboffset=41;
|
||||
int params_from_file = 0;
|
||||
int threadCnt=0;
|
||||
int max_ldpc_iterations = 5;
|
||||
if ( load_configmodule(argc,argv,CONFIG_ENABLECMDLINEONLY) == 0 ) {
|
||||
exit_fun("[NR_ULSIM] Error, configuration module init failed\n");
|
||||
}
|
||||
@@ -348,7 +349,7 @@ int main(int argc, char **argv)
|
||||
/* initialize the sin-cos table */
|
||||
InitSinLUT();
|
||||
|
||||
while ((c = getopt(argc, argv, "a:b:c:d:ef:g:h:ikl:m:n:p:r:s:t:u:w:y:z:F:G:H:M:N:PR:S:T:U:L:Z:W:")) != -1) {
|
||||
while ((c = getopt(argc, argv, "a:b:c:d:ef:g:h:i:kl:m:n:p:q:r:s:t:u:w:y:z:C:F:G:H:I:M:N:PR:S:T:U:L:ZW:")) != -1) {
|
||||
printf("handling optarg %c\n",c);
|
||||
switch (c) {
|
||||
|
||||
@@ -441,7 +442,9 @@ int main(int argc, char **argv)
|
||||
break;
|
||||
|
||||
case 'i':
|
||||
prb_inter=1;
|
||||
for(i=0; i < atoi(optarg); i++){
|
||||
chest_type[i] = atoi(argv[optind++]);
|
||||
}
|
||||
break;
|
||||
|
||||
case 'k':
|
||||
@@ -468,7 +471,11 @@ int main(int argc, char **argv)
|
||||
case 'p':
|
||||
extended_prefix_flag = 1;
|
||||
break;
|
||||
|
||||
|
||||
case 'q':
|
||||
mcs_table = atoi(optarg);
|
||||
break;
|
||||
|
||||
case 'r':
|
||||
nb_rb = atoi(optarg);
|
||||
break;
|
||||
@@ -478,6 +485,10 @@ int main(int argc, char **argv)
|
||||
printf("Setting SNR0 to %f\n", snr0);
|
||||
break;
|
||||
|
||||
case 'C':
|
||||
threadCnt = atoi(optarg);
|
||||
break;
|
||||
|
||||
case 'u':
|
||||
mu = atoi(optarg);
|
||||
break;
|
||||
@@ -487,7 +498,7 @@ int main(int argc, char **argv)
|
||||
break;
|
||||
|
||||
case 't':
|
||||
eff_tp_check = (float)atoi(optarg)/100;
|
||||
eff_tp_check = (float)atoi(optarg);
|
||||
break;
|
||||
|
||||
/*
|
||||
@@ -519,7 +530,7 @@ int main(int argc, char **argv)
|
||||
exit(-1);
|
||||
}
|
||||
break;
|
||||
|
||||
|
||||
case 'F':
|
||||
input_fd = fopen(optarg, "r");
|
||||
if (input_fd == NULL) {
|
||||
@@ -536,6 +547,10 @@ int main(int argc, char **argv)
|
||||
slot = atoi(optarg);
|
||||
break;
|
||||
|
||||
case 'I':
|
||||
max_ldpc_iterations = atoi(optarg);
|
||||
break;
|
||||
|
||||
case 'M':
|
||||
// SSB_positions = atoi(optarg);
|
||||
break;
|
||||
@@ -591,19 +606,20 @@ int main(int argc, char **argv)
|
||||
|
||||
default:
|
||||
case 'h':
|
||||
printf("%s -h(elp) -p(extended_prefix) -N cell_id -f output_filename -F input_filename -g channel_model -n n_frames -s snr0 -S snr1 -x transmission_mode -y TXant -z RXant -i Intefrence0 -j Interference1 -A interpolation_file -C(alibration offset dB) -N CellId -Z Enable SC-FDMA in Uplink \n", argv[0]);
|
||||
printf("%s -h(elp) -p(extended_prefix) -N cell_id -f output_filename -F input_filename -g channel_model -i Intefrence0 -j Interference1 -n n_frames -s snr0 -S snr1 -t Delayspread -x transmission_mode -y TXant -z RXant -A interpolation_file -C(alibration offset dB) -N CellId -Z Enable SC-FDMA in Uplink \n", argv[0]);
|
||||
//printf("-d Use TDD\n");
|
||||
printf("-d Introduce delay in terms of number of samples\n");
|
||||
printf("-f Number of frames to simulate\n");
|
||||
printf("-g [A,B,C,D,E,F,G] Use 3GPP SCM (A,B,C,D) or 36-101 (E-EPA,F-EVA,G-ETU) models (ignores delay spread and Ricean factor)\n");
|
||||
printf("-h This message\n");
|
||||
printf("-i Activate PRB based averaging for channel estimation. Frequncy domain interpolation by default.\n");
|
||||
printf("-i Change channel estimation technique. Arguments list: Number of arguments=2, Frequency domain {0:Linear interpolation, 1:PRB based averaging}, Time domain {0:Estimates of last DMRS symbol, 1:Average of DMRS symbols}. e.g. -i 2 1 0\n");
|
||||
//printf("-j Relative strength of second intefering eNB (in dB) - cell_id mod 3 = 2\n");
|
||||
printf("-s Starting SNR, runs from SNR0 to SNR0 + 10 dB if ending SNR isn't given\n");
|
||||
printf("-m MCS value\n");
|
||||
printf("-n Number of trials to simulate\n");
|
||||
printf("-p Use extended prefix mode\n");
|
||||
//printf("-t Delay spread for multipath channel\n");
|
||||
printf("-q MCS table\n");
|
||||
printf("-t Delay spread for multipath channel\n");
|
||||
printf("-u Set the numerology\n");
|
||||
printf("-w Start PRB for PUSCH\n");
|
||||
//printf("-x Transmission mode (1,2,6 for the moment)\n");
|
||||
@@ -614,6 +630,7 @@ int main(int argc, char **argv)
|
||||
printf("-F Input filename (.txt format) for RX conformance testing\n");
|
||||
printf("-G Offset of samples to read from file (0 default)\n");
|
||||
printf("-L <log level, 0(errors), 1(warning), 2(info) 3(debug) 4 (trace)>\n");
|
||||
printf("-I Maximum LDPC decoder iterations\n");
|
||||
printf("-M Multiple SSB positions in burst\n");
|
||||
printf("-N Nid_cell\n");
|
||||
printf("-O oversampling factor (1,2,4,8,16)\n");
|
||||
@@ -621,8 +638,8 @@ int main(int argc, char **argv)
|
||||
printf("-t Acceptable effective throughput (in percentage)\n");
|
||||
printf("-S Ending SNR, runs from SNR0 to SNR1\n");
|
||||
printf("-P Print ULSCH performances\n");
|
||||
printf("-T Enable PTRS, arguments list L_PTRS{0,1,2} K_PTRS{2,4}, e.g. -T 2 0 2 \n");
|
||||
printf("-U Change DMRS Config, arguments list DMRS TYPE{0=A,1=B} DMRS AddPos{0:3}, e.g. -U 2 0 2 \n");
|
||||
printf("-T Enable PTRS, arguments list: Number of arguments=2 L_PTRS{0,1,2} K_PTRS{2,4}, e.g. -T 2 0 2 \n");
|
||||
printf("-U Change DMRS Config, arguments list: Number of arguments=4, DMRS Mapping Type{0=A,1=B}, DMRS AddPos{0:3}, DMRS Config Type{1,2}, Number of CDM groups without data{1,2,3} e.g. -U 4 0 2 0 1 \n");
|
||||
printf("-Q If -F used, read parameters from file\n");
|
||||
printf("-Z If -Z is used, SC-FDMA or transform precoding is enabled in Uplink \n");
|
||||
printf("-W Num of layer for PUSCH\n");
|
||||
@@ -698,7 +715,18 @@ int main(int argc, char **argv)
|
||||
gNB->ofdm_offset_divisor = UINT_MAX;
|
||||
gNB->threadPool = (tpool_t*)malloc(sizeof(tpool_t));
|
||||
gNB->respDecode = (notifiedFIFO_t*) malloc(sizeof(notifiedFIFO_t));
|
||||
char tp_param[] = "n";
|
||||
initNotifiedFIFO(gNB->respDecode);
|
||||
char tp_param[80];
|
||||
if (threadCnt>0)
|
||||
sprintf(tp_param,"-1");
|
||||
else
|
||||
tp_param[0]='n';
|
||||
int s_offset = 0;
|
||||
for (int icpu=1; icpu<threadCnt; icpu++) {
|
||||
sprintf(tp_param+2+s_offset,",-1");
|
||||
s_offset += 3;
|
||||
}
|
||||
|
||||
initTpool(tp_param, gNB->threadPool, false);
|
||||
initNotifiedFIFO(gNB->respDecode);
|
||||
gNB->L1_tx_free = (notifiedFIFO_t*) malloc(sizeof(notifiedFIFO_t));
|
||||
@@ -717,7 +745,8 @@ int main(int argc, char **argv)
|
||||
gNB->UL_INFO.crc_ind.crc_list = (nfapi_nr_crc_t *)malloc(NB_UE_INST*sizeof(nfapi_nr_crc_t));
|
||||
gNB->UL_INFO.rx_ind.number_of_pdus = 0;
|
||||
gNB->UL_INFO.crc_ind.number_crcs = 0;
|
||||
gNB->prb_interpolation = prb_inter;
|
||||
gNB->max_ldpc_iterations = max_ldpc_iterations;
|
||||
gNB->pusch_thres = -20;
|
||||
frame_parms = &gNB->frame_parms; //to be initialized I suppose (maybe not necessary for PBCH)
|
||||
|
||||
frame_parms->N_RB_DL = N_RB_DL;
|
||||
@@ -781,6 +810,8 @@ int main(int argc, char **argv)
|
||||
cfg->carrier_config.num_tx_ant.value = 1;
|
||||
cfg->carrier_config.num_rx_ant.value = n_rx;
|
||||
// nr_phy_config_request_sim(gNB,N_RB_DL,N_RB_DL,mu,0,0x01);
|
||||
gNB->chest_freq = chest_type[0];
|
||||
gNB->chest_time = chest_type[1];
|
||||
phy_init_nr_gNB(gNB,0,1);
|
||||
N_RB_DL = gNB->frame_parms.N_RB_DL;
|
||||
|
||||
@@ -796,7 +827,7 @@ int main(int argc, char **argv)
|
||||
PHY_vars_UE_g[0][0] = UE;
|
||||
memcpy(&UE->frame_parms, frame_parms, sizeof(NR_DL_FRAME_PARMS));
|
||||
UE->frame_parms.nb_antennas_tx = n_tx;
|
||||
UE->frame_parms.nb_antennas_rx = 1;
|
||||
UE->frame_parms.nb_antennas_rx = 0;
|
||||
|
||||
if (init_nr_ue_signal(UE, 1) != 0) {
|
||||
printf("Error at UE NR initialisation\n");
|
||||
@@ -895,6 +926,7 @@ int main(int argc, char **argv)
|
||||
dmrs_config_type = pusch_dmrs_type1;
|
||||
else if(dmrs_arg[2] == 2)
|
||||
dmrs_config_type = pusch_dmrs_type2;
|
||||
num_dmrs_cdm_grps_no_data = dmrs_arg[3];
|
||||
}
|
||||
|
||||
uint8_t length_dmrs = pusch_len1;
|
||||
@@ -983,7 +1015,6 @@ int main(int argc, char **argv)
|
||||
int slot_length = slot_offset - frame_parms->get_samples_slot_timestamp(slot-1,frame_parms,0);
|
||||
|
||||
if (input_fd != NULL) {
|
||||
AssertFatal(frame_parms->nb_antennas_rx == 1, "nb_ant != 1\n");
|
||||
// 800 samples is N_TA_OFFSET for FR1 @ 30.72 Ms/s,
|
||||
AssertFatal(frame_parms->subcarrier_spacing==30000,"only 30 kHz for file input for now (%d)\n",frame_parms->subcarrier_spacing);
|
||||
|
||||
@@ -1011,18 +1042,21 @@ int main(int argc, char **argv)
|
||||
printf("harq_pid %d\n",harq_pid);
|
||||
}
|
||||
fseek(input_fd,file_offset*sizeof(int16_t)*2,SEEK_SET);
|
||||
read_errors+=fread((void*)&gNB->common_vars.rxdata[0][slot_offset-delay],
|
||||
sizeof(int16_t),
|
||||
slot_length<<1,
|
||||
input_fd);
|
||||
if (read_errors==0) {
|
||||
printf("error reading file\n");
|
||||
exit(1);
|
||||
for (int irx=0; irx<frame_parms->nb_antennas_rx; irx++) {
|
||||
fseek(input_fd,irx*(slot_length+15)*sizeof(int16_t)*2,SEEK_SET); // matlab adds samlples to the end to emulate channel delay
|
||||
read_errors+=fread((void*)&gNB->common_vars.rxdata[irx][slot_offset-delay],
|
||||
sizeof(int16_t),
|
||||
slot_length<<1,
|
||||
input_fd);
|
||||
if (read_errors==0) {
|
||||
printf("error reading file\n");
|
||||
exit(1);
|
||||
}
|
||||
for (int i=0;i<16;i+=2) printf("slot_offset %d : %d,%d\n",
|
||||
slot_offset,
|
||||
((int16_t*)&gNB->common_vars.rxdata[irx][slot_offset])[i],
|
||||
((int16_t*)&gNB->common_vars.rxdata[irx][slot_offset])[1+i]);
|
||||
}
|
||||
for (int i=0;i<16;i+=2) printf("slot_offset %d : %d,%d\n",
|
||||
slot_offset,
|
||||
((int16_t*)&gNB->common_vars.rxdata[0][slot_offset])[i],
|
||||
((int16_t*)&gNB->common_vars.rxdata[0][slot_offset])[1+i]);
|
||||
|
||||
mod_order = nr_get_Qm_ul(Imcs, mcs_table);
|
||||
code_rate = nr_get_code_rate_ul(Imcs, mcs_table);
|
||||
@@ -1389,11 +1423,11 @@ int main(int argc, char **argv)
|
||||
&gNB->pusch_vars[0]->llr_layers[0][0],(nb_symb_sch-1)*NR_NB_SC_PER_RB * pusch_pdu->rb_size * mod_order,1,0);
|
||||
|
||||
if (precod_nbr_layers==2) {
|
||||
LOG_M("rxsigF1_ext.m","rxsF1_ext",
|
||||
&gNB->pusch_vars[0]->rxdataF_ext[1][start_symbol*NR_NB_SC_PER_RB * pusch_pdu->rb_size],nb_symb_sch*(off+(NR_NB_SC_PER_RB * pusch_pdu->rb_size)),1,1);
|
||||
LOG_M("rxsigF1_ext.m","rxsF1_ext",
|
||||
&gNB->pusch_vars[0]->rxdataF_ext[1][start_symbol*NR_NB_SC_PER_RB * pusch_pdu->rb_size],nb_symb_sch*(off+(NR_NB_SC_PER_RB * pusch_pdu->rb_size)),1,1);
|
||||
|
||||
LOG_M("chestF3.m","chF3",
|
||||
&gNB->pusch_vars[0]->ul_ch_estimates[3][start_symbol*frame_parms->ofdm_symbol_size],frame_parms->ofdm_symbol_size,1,1);
|
||||
&gNB->pusch_vars[0]->ul_ch_estimates[3][start_symbol*frame_parms->ofdm_symbol_size],frame_parms->ofdm_symbol_size,1,1);
|
||||
|
||||
LOG_M("chestF3_ext.m","chF3_ext",
|
||||
&gNB->pusch_vars[0]->ul_ch_estimates_ext[3][(start_symbol+1)*(off+(NR_NB_SC_PER_RB * pusch_pdu->rb_size))],
|
||||
@@ -1553,7 +1587,12 @@ int main(int argc, char **argv)
|
||||
roundStats[snrRun],effRate[snrRun],effTP[snrRun],TBS);
|
||||
|
||||
FILE *fd=fopen("nr_ulsim.log","w");
|
||||
if (fd == NULL) {
|
||||
printf("Problem with filename %s\n", "nr_ulsim.log");
|
||||
exit(-1);
|
||||
}
|
||||
dump_pusch_stats(fd,gNB);
|
||||
fclose(fd);
|
||||
|
||||
printf("*****************************************\n");
|
||||
printf("\n");
|
||||
@@ -1583,7 +1622,7 @@ int main(int argc, char **argv)
|
||||
if(n_trials==1)
|
||||
break;
|
||||
|
||||
if (effRate[snrRun] > (eff_tp_check*TBS)) {
|
||||
if ((float)effTP[snrRun] >= eff_tp_check) {
|
||||
printf("*************\n");
|
||||
printf("PUSCH test OK\n");
|
||||
printf("*************\n");
|
||||
@@ -1613,17 +1652,19 @@ int main(int argc, char **argv)
|
||||
length_dmrs,
|
||||
num_dmrs_cdm_grps_no_data);
|
||||
|
||||
LOG_M("ulsimStats.m","SNR",snrStats,snrRun,1,7);
|
||||
LOG_MM("ulsimStats.m","BLER_round0",blerStats[0],snrRun,1,7);
|
||||
LOG_MM("ulsimStats.m","BLER_round1",blerStats[1],snrRun,1,7);
|
||||
LOG_MM("ulsimStats.m","BLER_round2",blerStats[2],snrRun,1,7);
|
||||
LOG_MM("ulsimStats.m","BLER_round3",blerStats[3],snrRun,1,7);
|
||||
LOG_MM("ulsimStats.m","BER_round0",berStats[0],snrRun,1,7);
|
||||
LOG_MM("ulsimStats.m","BER_round1",berStats[1],snrRun,1,7);
|
||||
LOG_MM("ulsimStats.m","BER_round2",berStats[2],snrRun,1,7);
|
||||
LOG_MM("ulsimStats.m","BER_round3",berStats[3],snrRun,1,7);
|
||||
LOG_MM("ulsimStats.m","EffRate",effRate,snrRun,1,7);
|
||||
LOG_MM("ulsimStats.m","EffTP",effTP,snrRun,1,7);
|
||||
char opStatsFile[50];
|
||||
sprintf(opStatsFile, "ulsimStats_z%d.m", n_rx);
|
||||
LOG_M(opStatsFile,"SNR",snrStats,snrRun,1,7);
|
||||
LOG_MM(opStatsFile,"BLER_round0",blerStats[0],snrRun,1,7);
|
||||
LOG_MM(opStatsFile,"BLER_round1",blerStats[1],snrRun,1,7);
|
||||
LOG_MM(opStatsFile,"BLER_round2",blerStats[2],snrRun,1,7);
|
||||
LOG_MM(opStatsFile,"BLER_round3",blerStats[3],snrRun,1,7);
|
||||
LOG_MM(opStatsFile,"BER_round0",berStats[0],snrRun,1,7);
|
||||
LOG_MM(opStatsFile,"BER_round1",berStats[1],snrRun,1,7);
|
||||
LOG_MM(opStatsFile,"BER_round2",berStats[2],snrRun,1,7);
|
||||
LOG_MM(opStatsFile,"BER_round3",berStats[3],snrRun,1,7);
|
||||
LOG_MM(opStatsFile,"EffRate",effRate,snrRun,1,7);
|
||||
LOG_MM(opStatsFile,"EffTP",effTP,snrRun,1,7);
|
||||
free(test_input_bit);
|
||||
free(estimated_output_bit);
|
||||
|
||||
|
||||
@@ -0,0 +1,313 @@
|
||||
# This is the CMakeCache file.
|
||||
# For build in directory: /home/sy/openairinterface5g/openair1/SIMULATION/NR_UE_PHY/unit_tests/build
|
||||
# It was generated by CMake: /usr/bin/cmake
|
||||
# You can edit this file to change values found and used by cmake.
|
||||
# If you do not want to change any of the values, simply exit the editor.
|
||||
# If you do want to change a value, simply edit, save, and exit the editor.
|
||||
# The syntax for the file is as follows:
|
||||
# KEY:TYPE=VALUE
|
||||
# KEY is the name of a variable in the cache.
|
||||
# TYPE is a hint to GUIs for the type of VALUE, DO NOT EDIT TYPE!.
|
||||
# VALUE is the current value for the KEY.
|
||||
|
||||
########################
|
||||
# EXTERNAL cache entries
|
||||
########################
|
||||
|
||||
//Path to a program.
|
||||
CMAKE_AR:FILEPATH=/usr/bin/ar
|
||||
|
||||
//Choose the type of build, options are: None(CMAKE_CXX_FLAGS or
|
||||
// CMAKE_C_FLAGS used) Debug Release RelWithDebInfo MinSizeRel.
|
||||
CMAKE_BUILD_TYPE:STRING=
|
||||
|
||||
//Enable/Disable color output during build.
|
||||
CMAKE_COLOR_MAKEFILE:BOOL=ON
|
||||
|
||||
//CXX compiler.
|
||||
CMAKE_CXX_COMPILER:FILEPATH=/usr/bin/c++
|
||||
|
||||
//Flags used by the compiler during all build types.
|
||||
CMAKE_CXX_FLAGS:STRING=
|
||||
|
||||
//Flags used by the compiler during debug builds.
|
||||
CMAKE_CXX_FLAGS_DEBUG:STRING=-g
|
||||
|
||||
//Flags used by the compiler during release minsize builds.
|
||||
CMAKE_CXX_FLAGS_MINSIZEREL:STRING=-Os -DNDEBUG
|
||||
|
||||
//Flags used by the compiler during release builds (/MD /Ob1 /Oi
|
||||
// /Ot /Oy /Gs will produce slightly less optimized but smaller
|
||||
// files).
|
||||
CMAKE_CXX_FLAGS_RELEASE:STRING=-O3 -DNDEBUG
|
||||
|
||||
//Flags used by the compiler during Release with Debug Info builds.
|
||||
CMAKE_CXX_FLAGS_RELWITHDEBINFO:STRING=-O2 -g -DNDEBUG
|
||||
|
||||
//C compiler.
|
||||
CMAKE_C_COMPILER:FILEPATH=/usr/bin/cc
|
||||
|
||||
//Flags used by the compiler during all build types.
|
||||
CMAKE_C_FLAGS:STRING=
|
||||
|
||||
//Flags used by the compiler during debug builds.
|
||||
CMAKE_C_FLAGS_DEBUG:STRING=-g
|
||||
|
||||
//Flags used by the compiler during release minsize builds.
|
||||
CMAKE_C_FLAGS_MINSIZEREL:STRING=-Os -DNDEBUG
|
||||
|
||||
//Flags used by the compiler during release builds (/MD /Ob1 /Oi
|
||||
// /Ot /Oy /Gs will produce slightly less optimized but smaller
|
||||
// files).
|
||||
CMAKE_C_FLAGS_RELEASE:STRING=-O3 -DNDEBUG
|
||||
|
||||
//Flags used by the compiler during Release with Debug Info builds.
|
||||
CMAKE_C_FLAGS_RELWITHDEBINFO:STRING=-O2 -g -DNDEBUG
|
||||
|
||||
//Flags used by the linker.
|
||||
CMAKE_EXE_LINKER_FLAGS:STRING=' '
|
||||
|
||||
//Flags used by the linker during debug builds.
|
||||
CMAKE_EXE_LINKER_FLAGS_DEBUG:STRING=
|
||||
|
||||
//Flags used by the linker during release minsize builds.
|
||||
CMAKE_EXE_LINKER_FLAGS_MINSIZEREL:STRING=
|
||||
|
||||
//Flags used by the linker during release builds.
|
||||
CMAKE_EXE_LINKER_FLAGS_RELEASE:STRING=
|
||||
|
||||
//Flags used by the linker during Release with Debug Info builds.
|
||||
CMAKE_EXE_LINKER_FLAGS_RELWITHDEBINFO:STRING=
|
||||
|
||||
//Enable/Disable output of compile commands during generation.
|
||||
CMAKE_EXPORT_COMPILE_COMMANDS:BOOL=OFF
|
||||
|
||||
//Install path prefix, prepended onto install directories.
|
||||
CMAKE_INSTALL_PREFIX:PATH=/usr/local
|
||||
|
||||
//Path to a program.
|
||||
CMAKE_LINKER:FILEPATH=/usr/bin/ld
|
||||
|
||||
//Path to a program.
|
||||
CMAKE_MAKE_PROGRAM:FILEPATH=/usr/bin/gmake
|
||||
|
||||
//Flags used by the linker during the creation of modules.
|
||||
CMAKE_MODULE_LINKER_FLAGS:STRING=' '
|
||||
|
||||
//Flags used by the linker during debug builds.
|
||||
CMAKE_MODULE_LINKER_FLAGS_DEBUG:STRING=
|
||||
|
||||
//Flags used by the linker during release minsize builds.
|
||||
CMAKE_MODULE_LINKER_FLAGS_MINSIZEREL:STRING=
|
||||
|
||||
//Flags used by the linker during release builds.
|
||||
CMAKE_MODULE_LINKER_FLAGS_RELEASE:STRING=
|
||||
|
||||
//Flags used by the linker during Release with Debug Info builds.
|
||||
CMAKE_MODULE_LINKER_FLAGS_RELWITHDEBINFO:STRING=
|
||||
|
||||
//Path to a program.
|
||||
CMAKE_NM:FILEPATH=/usr/bin/nm
|
||||
|
||||
//Path to a program.
|
||||
CMAKE_OBJCOPY:FILEPATH=/usr/bin/objcopy
|
||||
|
||||
//Path to a program.
|
||||
CMAKE_OBJDUMP:FILEPATH=/usr/bin/objdump
|
||||
|
||||
//Value Computed by CMake
|
||||
CMAKE_PROJECT_NAME:STATIC=Project
|
||||
|
||||
//Path to a program.
|
||||
CMAKE_RANLIB:FILEPATH=/usr/bin/ranlib
|
||||
|
||||
//Flags used by the linker during the creation of dll's.
|
||||
CMAKE_SHARED_LINKER_FLAGS:STRING=' '
|
||||
|
||||
//Flags used by the linker during debug builds.
|
||||
CMAKE_SHARED_LINKER_FLAGS_DEBUG:STRING=
|
||||
|
||||
//Flags used by the linker during release minsize builds.
|
||||
CMAKE_SHARED_LINKER_FLAGS_MINSIZEREL:STRING=
|
||||
|
||||
//Flags used by the linker during release builds.
|
||||
CMAKE_SHARED_LINKER_FLAGS_RELEASE:STRING=
|
||||
|
||||
//Flags used by the linker during Release with Debug Info builds.
|
||||
CMAKE_SHARED_LINKER_FLAGS_RELWITHDEBINFO:STRING=
|
||||
|
||||
//If set, runtime paths are not added when installing shared libraries,
|
||||
// but are added when building.
|
||||
CMAKE_SKIP_INSTALL_RPATH:BOOL=NO
|
||||
|
||||
//If set, runtime paths are not added when using shared libraries.
|
||||
CMAKE_SKIP_RPATH:BOOL=NO
|
||||
|
||||
//Flags used by the linker during the creation of static libraries.
|
||||
CMAKE_STATIC_LINKER_FLAGS:STRING=
|
||||
|
||||
//Flags used by the linker during debug builds.
|
||||
CMAKE_STATIC_LINKER_FLAGS_DEBUG:STRING=
|
||||
|
||||
//Flags used by the linker during release minsize builds.
|
||||
CMAKE_STATIC_LINKER_FLAGS_MINSIZEREL:STRING=
|
||||
|
||||
//Flags used by the linker during release builds.
|
||||
CMAKE_STATIC_LINKER_FLAGS_RELEASE:STRING=
|
||||
|
||||
//Flags used by the linker during Release with Debug Info builds.
|
||||
CMAKE_STATIC_LINKER_FLAGS_RELWITHDEBINFO:STRING=
|
||||
|
||||
//Path to a program.
|
||||
CMAKE_STRIP:FILEPATH=/usr/bin/strip
|
||||
|
||||
//If true, cmake will use relative paths in makefiles and projects.
|
||||
CMAKE_USE_RELATIVE_PATHS:BOOL=OFF
|
||||
|
||||
//If this value is on, makefiles will be generated without the
|
||||
// .SILENT directive, and all commands will be echoed to the console
|
||||
// during the make. This is useful for debugging only. With Visual
|
||||
// Studio IDE projects all commands are done without /nologo.
|
||||
CMAKE_VERBOSE_MAKEFILE:BOOL=FALSE
|
||||
|
||||
//Value Computed by CMake
|
||||
Project_BINARY_DIR:STATIC=/home/sy/openairinterface5g/openair1/SIMULATION/NR_UE_PHY/unit_tests/build
|
||||
|
||||
//Value Computed by CMake
|
||||
Project_SOURCE_DIR:STATIC=/home/sy/openairinterface5g/openair1/SIMULATION/NR_UE_PHY/unit_tests/build
|
||||
|
||||
|
||||
########################
|
||||
# INTERNAL cache entries
|
||||
########################
|
||||
|
||||
//ADVANCED property for variable: CMAKE_AR
|
||||
CMAKE_AR-ADVANCED:INTERNAL=1
|
||||
//ADVANCED property for variable: CMAKE_BUILD_TOOL
|
||||
CMAKE_BUILD_TOOL-ADVANCED:INTERNAL=1
|
||||
//What is the target build tool cmake is generating for.
|
||||
CMAKE_BUILD_TOOL:INTERNAL=/usr/bin/gmake
|
||||
//This is the directory where this CMakeCache.txt was created
|
||||
CMAKE_CACHEFILE_DIR:INTERNAL=/home/sy/openairinterface5g/openair1/SIMULATION/NR_UE_PHY/unit_tests/build
|
||||
//Major version of cmake used to create the current loaded cache
|
||||
CMAKE_CACHE_MAJOR_VERSION:INTERNAL=2
|
||||
//Minor version of cmake used to create the current loaded cache
|
||||
CMAKE_CACHE_MINOR_VERSION:INTERNAL=8
|
||||
//Patch version of cmake used to create the current loaded cache
|
||||
CMAKE_CACHE_PATCH_VERSION:INTERNAL=12
|
||||
//ADVANCED property for variable: CMAKE_COLOR_MAKEFILE
|
||||
CMAKE_COLOR_MAKEFILE-ADVANCED:INTERNAL=1
|
||||
//Path to CMake executable.
|
||||
CMAKE_COMMAND:INTERNAL=/usr/bin/cmake
|
||||
//Path to cpack program executable.
|
||||
CMAKE_CPACK_COMMAND:INTERNAL=/usr/bin/cpack
|
||||
//Path to ctest program executable.
|
||||
CMAKE_CTEST_COMMAND:INTERNAL=/usr/bin/ctest
|
||||
//ADVANCED property for variable: CMAKE_CXX_COMPILER
|
||||
CMAKE_CXX_COMPILER-ADVANCED:INTERNAL=1
|
||||
//ADVANCED property for variable: CMAKE_CXX_FLAGS
|
||||
CMAKE_CXX_FLAGS-ADVANCED:INTERNAL=1
|
||||
//ADVANCED property for variable: CMAKE_CXX_FLAGS_DEBUG
|
||||
CMAKE_CXX_FLAGS_DEBUG-ADVANCED:INTERNAL=1
|
||||
//ADVANCED property for variable: CMAKE_CXX_FLAGS_MINSIZEREL
|
||||
CMAKE_CXX_FLAGS_MINSIZEREL-ADVANCED:INTERNAL=1
|
||||
//ADVANCED property for variable: CMAKE_CXX_FLAGS_RELEASE
|
||||
CMAKE_CXX_FLAGS_RELEASE-ADVANCED:INTERNAL=1
|
||||
//ADVANCED property for variable: CMAKE_CXX_FLAGS_RELWITHDEBINFO
|
||||
CMAKE_CXX_FLAGS_RELWITHDEBINFO-ADVANCED:INTERNAL=1
|
||||
//ADVANCED property for variable: CMAKE_C_COMPILER
|
||||
CMAKE_C_COMPILER-ADVANCED:INTERNAL=1
|
||||
//ADVANCED property for variable: CMAKE_C_FLAGS
|
||||
CMAKE_C_FLAGS-ADVANCED:INTERNAL=1
|
||||
//ADVANCED property for variable: CMAKE_C_FLAGS_DEBUG
|
||||
CMAKE_C_FLAGS_DEBUG-ADVANCED:INTERNAL=1
|
||||
//ADVANCED property for variable: CMAKE_C_FLAGS_MINSIZEREL
|
||||
CMAKE_C_FLAGS_MINSIZEREL-ADVANCED:INTERNAL=1
|
||||
//ADVANCED property for variable: CMAKE_C_FLAGS_RELEASE
|
||||
CMAKE_C_FLAGS_RELEASE-ADVANCED:INTERNAL=1
|
||||
//ADVANCED property for variable: CMAKE_C_FLAGS_RELWITHDEBINFO
|
||||
CMAKE_C_FLAGS_RELWITHDEBINFO-ADVANCED:INTERNAL=1
|
||||
//Path to cache edit program executable.
|
||||
CMAKE_EDIT_COMMAND:INTERNAL=/usr/bin/ccmake
|
||||
//Executable file format
|
||||
CMAKE_EXECUTABLE_FORMAT:INTERNAL=ELF
|
||||
//ADVANCED property for variable: CMAKE_EXE_LINKER_FLAGS
|
||||
CMAKE_EXE_LINKER_FLAGS-ADVANCED:INTERNAL=1
|
||||
//ADVANCED property for variable: CMAKE_EXE_LINKER_FLAGS_DEBUG
|
||||
CMAKE_EXE_LINKER_FLAGS_DEBUG-ADVANCED:INTERNAL=1
|
||||
//ADVANCED property for variable: CMAKE_EXE_LINKER_FLAGS_MINSIZEREL
|
||||
CMAKE_EXE_LINKER_FLAGS_MINSIZEREL-ADVANCED:INTERNAL=1
|
||||
//ADVANCED property for variable: CMAKE_EXE_LINKER_FLAGS_RELEASE
|
||||
CMAKE_EXE_LINKER_FLAGS_RELEASE-ADVANCED:INTERNAL=1
|
||||
//ADVANCED property for variable: CMAKE_EXE_LINKER_FLAGS_RELWITHDEBINFO
|
||||
CMAKE_EXE_LINKER_FLAGS_RELWITHDEBINFO-ADVANCED:INTERNAL=1
|
||||
//ADVANCED property for variable: CMAKE_EXPORT_COMPILE_COMMANDS
|
||||
CMAKE_EXPORT_COMPILE_COMMANDS-ADVANCED:INTERNAL=1
|
||||
//Name of generator.
|
||||
CMAKE_GENERATOR:INTERNAL=Unix Makefiles
|
||||
//Name of generator toolset.
|
||||
CMAKE_GENERATOR_TOOLSET:INTERNAL=
|
||||
//Start directory with the top level CMakeLists.txt file for this
|
||||
// project
|
||||
CMAKE_HOME_DIRECTORY:INTERNAL=/home/sy/openairinterface5g/openair1/SIMULATION/NR_UE_PHY/unit_tests/build
|
||||
//Install .so files without execute permission.
|
||||
CMAKE_INSTALL_SO_NO_EXE:INTERNAL=0
|
||||
//ADVANCED property for variable: CMAKE_LINKER
|
||||
CMAKE_LINKER-ADVANCED:INTERNAL=1
|
||||
//ADVANCED property for variable: CMAKE_MAKE_PROGRAM
|
||||
CMAKE_MAKE_PROGRAM-ADVANCED:INTERNAL=1
|
||||
//ADVANCED property for variable: CMAKE_MODULE_LINKER_FLAGS
|
||||
CMAKE_MODULE_LINKER_FLAGS-ADVANCED:INTERNAL=1
|
||||
//ADVANCED property for variable: CMAKE_MODULE_LINKER_FLAGS_DEBUG
|
||||
CMAKE_MODULE_LINKER_FLAGS_DEBUG-ADVANCED:INTERNAL=1
|
||||
//ADVANCED property for variable: CMAKE_MODULE_LINKER_FLAGS_MINSIZEREL
|
||||
CMAKE_MODULE_LINKER_FLAGS_MINSIZEREL-ADVANCED:INTERNAL=1
|
||||
//ADVANCED property for variable: CMAKE_MODULE_LINKER_FLAGS_RELEASE
|
||||
CMAKE_MODULE_LINKER_FLAGS_RELEASE-ADVANCED:INTERNAL=1
|
||||
//ADVANCED property for variable: CMAKE_MODULE_LINKER_FLAGS_RELWITHDEBINFO
|
||||
CMAKE_MODULE_LINKER_FLAGS_RELWITHDEBINFO-ADVANCED:INTERNAL=1
|
||||
//ADVANCED property for variable: CMAKE_NM
|
||||
CMAKE_NM-ADVANCED:INTERNAL=1
|
||||
//number of local generators
|
||||
CMAKE_NUMBER_OF_LOCAL_GENERATORS:INTERNAL=1
|
||||
//ADVANCED property for variable: CMAKE_OBJCOPY
|
||||
CMAKE_OBJCOPY-ADVANCED:INTERNAL=1
|
||||
//ADVANCED property for variable: CMAKE_OBJDUMP
|
||||
CMAKE_OBJDUMP-ADVANCED:INTERNAL=1
|
||||
//ADVANCED property for variable: CMAKE_RANLIB
|
||||
CMAKE_RANLIB-ADVANCED:INTERNAL=1
|
||||
//Path to CMake installation.
|
||||
CMAKE_ROOT:INTERNAL=/usr/share/cmake
|
||||
//ADVANCED property for variable: CMAKE_SHARED_LINKER_FLAGS
|
||||
CMAKE_SHARED_LINKER_FLAGS-ADVANCED:INTERNAL=1
|
||||
//ADVANCED property for variable: CMAKE_SHARED_LINKER_FLAGS_DEBUG
|
||||
CMAKE_SHARED_LINKER_FLAGS_DEBUG-ADVANCED:INTERNAL=1
|
||||
//ADVANCED property for variable: CMAKE_SHARED_LINKER_FLAGS_MINSIZEREL
|
||||
CMAKE_SHARED_LINKER_FLAGS_MINSIZEREL-ADVANCED:INTERNAL=1
|
||||
//ADVANCED property for variable: CMAKE_SHARED_LINKER_FLAGS_RELEASE
|
||||
CMAKE_SHARED_LINKER_FLAGS_RELEASE-ADVANCED:INTERNAL=1
|
||||
//ADVANCED property for variable: CMAKE_SHARED_LINKER_FLAGS_RELWITHDEBINFO
|
||||
CMAKE_SHARED_LINKER_FLAGS_RELWITHDEBINFO-ADVANCED:INTERNAL=1
|
||||
//ADVANCED property for variable: CMAKE_SKIP_INSTALL_RPATH
|
||||
CMAKE_SKIP_INSTALL_RPATH-ADVANCED:INTERNAL=1
|
||||
//ADVANCED property for variable: CMAKE_SKIP_RPATH
|
||||
CMAKE_SKIP_RPATH-ADVANCED:INTERNAL=1
|
||||
//ADVANCED property for variable: CMAKE_STATIC_LINKER_FLAGS
|
||||
CMAKE_STATIC_LINKER_FLAGS-ADVANCED:INTERNAL=1
|
||||
//ADVANCED property for variable: CMAKE_STATIC_LINKER_FLAGS_DEBUG
|
||||
CMAKE_STATIC_LINKER_FLAGS_DEBUG-ADVANCED:INTERNAL=1
|
||||
//ADVANCED property for variable: CMAKE_STATIC_LINKER_FLAGS_MINSIZEREL
|
||||
CMAKE_STATIC_LINKER_FLAGS_MINSIZEREL-ADVANCED:INTERNAL=1
|
||||
//ADVANCED property for variable: CMAKE_STATIC_LINKER_FLAGS_RELEASE
|
||||
CMAKE_STATIC_LINKER_FLAGS_RELEASE-ADVANCED:INTERNAL=1
|
||||
//ADVANCED property for variable: CMAKE_STATIC_LINKER_FLAGS_RELWITHDEBINFO
|
||||
CMAKE_STATIC_LINKER_FLAGS_RELWITHDEBINFO-ADVANCED:INTERNAL=1
|
||||
//ADVANCED property for variable: CMAKE_STRIP
|
||||
CMAKE_STRIP-ADVANCED:INTERNAL=1
|
||||
//uname command
|
||||
CMAKE_UNAME:INTERNAL=/usr/bin/uname
|
||||
//ADVANCED property for variable: CMAKE_USE_RELATIVE_PATHS
|
||||
CMAKE_USE_RELATIVE_PATHS-ADVANCED:INTERNAL=1
|
||||
//ADVANCED property for variable: CMAKE_VERBOSE_MAKEFILE
|
||||
CMAKE_VERBOSE_MAKEFILE-ADVANCED:INTERNAL=1
|
||||
|
||||
+56
@@ -0,0 +1,56 @@
|
||||
set(CMAKE_C_COMPILER "/usr/bin/cc")
|
||||
set(CMAKE_C_COMPILER_ARG1 "")
|
||||
set(CMAKE_C_COMPILER_ID "GNU")
|
||||
set(CMAKE_C_COMPILER_VERSION "4.8.5")
|
||||
set(CMAKE_C_PLATFORM_ID "Linux")
|
||||
|
||||
set(CMAKE_AR "/usr/bin/ar")
|
||||
set(CMAKE_RANLIB "/usr/bin/ranlib")
|
||||
set(CMAKE_LINKER "/usr/bin/ld")
|
||||
set(CMAKE_COMPILER_IS_GNUCC 1)
|
||||
set(CMAKE_C_COMPILER_LOADED 1)
|
||||
set(CMAKE_C_COMPILER_WORKS TRUE)
|
||||
set(CMAKE_C_ABI_COMPILED TRUE)
|
||||
set(CMAKE_COMPILER_IS_MINGW )
|
||||
set(CMAKE_COMPILER_IS_CYGWIN )
|
||||
if(CMAKE_COMPILER_IS_CYGWIN)
|
||||
set(CYGWIN 1)
|
||||
set(UNIX 1)
|
||||
endif()
|
||||
|
||||
set(CMAKE_C_COMPILER_ENV_VAR "CC")
|
||||
|
||||
if(CMAKE_COMPILER_IS_MINGW)
|
||||
set(MINGW 1)
|
||||
endif()
|
||||
set(CMAKE_C_COMPILER_ID_RUN 1)
|
||||
set(CMAKE_C_SOURCE_FILE_EXTENSIONS c)
|
||||
set(CMAKE_C_IGNORE_EXTENSIONS h;H;o;O;obj;OBJ;def;DEF;rc;RC)
|
||||
set(CMAKE_C_LINKER_PREFERENCE 10)
|
||||
|
||||
# Save compiler ABI information.
|
||||
set(CMAKE_C_SIZEOF_DATA_PTR "8")
|
||||
set(CMAKE_C_COMPILER_ABI "ELF")
|
||||
set(CMAKE_C_LIBRARY_ARCHITECTURE "")
|
||||
|
||||
if(CMAKE_C_SIZEOF_DATA_PTR)
|
||||
set(CMAKE_SIZEOF_VOID_P "${CMAKE_C_SIZEOF_DATA_PTR}")
|
||||
endif()
|
||||
|
||||
if(CMAKE_C_COMPILER_ABI)
|
||||
set(CMAKE_INTERNAL_PLATFORM_ABI "${CMAKE_C_COMPILER_ABI}")
|
||||
endif()
|
||||
|
||||
if(CMAKE_C_LIBRARY_ARCHITECTURE)
|
||||
set(CMAKE_LIBRARY_ARCHITECTURE "")
|
||||
endif()
|
||||
|
||||
|
||||
|
||||
|
||||
set(CMAKE_C_IMPLICIT_LINK_LIBRARIES "c")
|
||||
set(CMAKE_C_IMPLICIT_LINK_DIRECTORIES "/usr/lib/gcc/x86_64-redhat-linux/4.8.5;/usr/lib64;/lib64;/usr/lib")
|
||||
set(CMAKE_C_IMPLICIT_LINK_FRAMEWORK_DIRECTORIES "")
|
||||
|
||||
|
||||
|
||||
+57
@@ -0,0 +1,57 @@
|
||||
set(CMAKE_CXX_COMPILER "/usr/bin/c++")
|
||||
set(CMAKE_CXX_COMPILER_ARG1 "")
|
||||
set(CMAKE_CXX_COMPILER_ID "GNU")
|
||||
set(CMAKE_CXX_COMPILER_VERSION "4.8.5")
|
||||
set(CMAKE_CXX_PLATFORM_ID "Linux")
|
||||
|
||||
set(CMAKE_AR "/usr/bin/ar")
|
||||
set(CMAKE_RANLIB "/usr/bin/ranlib")
|
||||
set(CMAKE_LINKER "/usr/bin/ld")
|
||||
set(CMAKE_COMPILER_IS_GNUCXX 1)
|
||||
set(CMAKE_CXX_COMPILER_LOADED 1)
|
||||
set(CMAKE_CXX_COMPILER_WORKS TRUE)
|
||||
set(CMAKE_CXX_ABI_COMPILED TRUE)
|
||||
set(CMAKE_COMPILER_IS_MINGW )
|
||||
set(CMAKE_COMPILER_IS_CYGWIN )
|
||||
if(CMAKE_COMPILER_IS_CYGWIN)
|
||||
set(CYGWIN 1)
|
||||
set(UNIX 1)
|
||||
endif()
|
||||
|
||||
set(CMAKE_CXX_COMPILER_ENV_VAR "CXX")
|
||||
|
||||
if(CMAKE_COMPILER_IS_MINGW)
|
||||
set(MINGW 1)
|
||||
endif()
|
||||
set(CMAKE_CXX_COMPILER_ID_RUN 1)
|
||||
set(CMAKE_CXX_IGNORE_EXTENSIONS inl;h;hpp;HPP;H;o;O;obj;OBJ;def;DEF;rc;RC)
|
||||
set(CMAKE_CXX_SOURCE_FILE_EXTENSIONS C;M;c++;cc;cpp;cxx;m;mm;CPP)
|
||||
set(CMAKE_CXX_LINKER_PREFERENCE 30)
|
||||
set(CMAKE_CXX_LINKER_PREFERENCE_PROPAGATES 1)
|
||||
|
||||
# Save compiler ABI information.
|
||||
set(CMAKE_CXX_SIZEOF_DATA_PTR "8")
|
||||
set(CMAKE_CXX_COMPILER_ABI "ELF")
|
||||
set(CMAKE_CXX_LIBRARY_ARCHITECTURE "")
|
||||
|
||||
if(CMAKE_CXX_SIZEOF_DATA_PTR)
|
||||
set(CMAKE_SIZEOF_VOID_P "${CMAKE_CXX_SIZEOF_DATA_PTR}")
|
||||
endif()
|
||||
|
||||
if(CMAKE_CXX_COMPILER_ABI)
|
||||
set(CMAKE_INTERNAL_PLATFORM_ABI "${CMAKE_CXX_COMPILER_ABI}")
|
||||
endif()
|
||||
|
||||
if(CMAKE_CXX_LIBRARY_ARCHITECTURE)
|
||||
set(CMAKE_LIBRARY_ARCHITECTURE "")
|
||||
endif()
|
||||
|
||||
|
||||
|
||||
|
||||
set(CMAKE_CXX_IMPLICIT_LINK_LIBRARIES "stdc++;m;c")
|
||||
set(CMAKE_CXX_IMPLICIT_LINK_DIRECTORIES "/usr/lib/gcc/x86_64-redhat-linux/4.8.5;/usr/lib64;/lib64;/usr/lib")
|
||||
set(CMAKE_CXX_IMPLICIT_LINK_FRAMEWORK_DIRECTORIES "")
|
||||
|
||||
|
||||
|
||||
Executable
BIN
Binary file not shown.
openair1/SIMULATION/NR_UE_PHY/unit_tests/build/CMakeFiles/2.8.12.2/CMakeDetermineCompilerABI_CXX.bin
Executable
BIN
Binary file not shown.
@@ -0,0 +1,15 @@
|
||||
set(CMAKE_HOST_SYSTEM "Linux-3.10.0-957.21.3.rt56.935.el7.x86_64")
|
||||
set(CMAKE_HOST_SYSTEM_NAME "Linux")
|
||||
set(CMAKE_HOST_SYSTEM_VERSION "3.10.0-957.21.3.rt56.935.el7.x86_64")
|
||||
set(CMAKE_HOST_SYSTEM_PROCESSOR "x86_64")
|
||||
|
||||
|
||||
|
||||
set(CMAKE_SYSTEM "Linux-3.10.0-957.21.3.rt56.935.el7.x86_64")
|
||||
set(CMAKE_SYSTEM_NAME "Linux")
|
||||
set(CMAKE_SYSTEM_VERSION "3.10.0-957.21.3.rt56.935.el7.x86_64")
|
||||
set(CMAKE_SYSTEM_PROCESSOR "x86_64")
|
||||
|
||||
set(CMAKE_CROSSCOMPILING "FALSE")
|
||||
|
||||
set(CMAKE_SYSTEM_LOADED 1)
|
||||
+389
@@ -0,0 +1,389 @@
|
||||
#ifdef __cplusplus
|
||||
# error "A C++ compiler has been selected for C."
|
||||
#endif
|
||||
|
||||
/* Version number components: V=Version, R=Revision, P=Patch
|
||||
Version date components: YYYY=Year, MM=Month, DD=Day */
|
||||
|
||||
#if defined(__18CXX)
|
||||
# define ID_VOID_MAIN
|
||||
#endif
|
||||
|
||||
#if defined(__INTEL_COMPILER) || defined(__ICC)
|
||||
# define COMPILER_ID "Intel"
|
||||
/* __INTEL_COMPILER = VRP */
|
||||
# define COMPILER_VERSION_MAJOR DEC(__INTEL_COMPILER/100)
|
||||
# define COMPILER_VERSION_MINOR DEC(__INTEL_COMPILER/10 % 10)
|
||||
# define COMPILER_VERSION_PATCH DEC(__INTEL_COMPILER % 10)
|
||||
# if defined(__INTEL_COMPILER_BUILD_DATE)
|
||||
/* __INTEL_COMPILER_BUILD_DATE = YYYYMMDD */
|
||||
# define COMPILER_VERSION_TWEAK DEC(__INTEL_COMPILER_BUILD_DATE)
|
||||
# endif
|
||||
|
||||
#elif defined(__PATHCC__)
|
||||
# define COMPILER_ID "PathScale"
|
||||
# define COMPILER_VERSION_MAJOR DEC(__PATHCC__)
|
||||
# define COMPILER_VERSION_MINOR DEC(__PATHCC_MINOR__)
|
||||
# if defined(__PATHCC_PATCHLEVEL__)
|
||||
# define COMPILER_VERSION_PATCH DEC(__PATHCC_PATCHLEVEL__)
|
||||
# endif
|
||||
|
||||
#elif defined(__clang__)
|
||||
# define COMPILER_ID "Clang"
|
||||
# define COMPILER_VERSION_MAJOR DEC(__clang_major__)
|
||||
# define COMPILER_VERSION_MINOR DEC(__clang_minor__)
|
||||
# define COMPILER_VERSION_PATCH DEC(__clang_patchlevel__)
|
||||
|
||||
#elif defined(__BORLANDC__) && defined(__CODEGEARC_VERSION__)
|
||||
# define COMPILER_ID "Embarcadero"
|
||||
# define COMPILER_VERSION_MAJOR HEX(__CODEGEARC_VERSION__>>24 & 0x00FF)
|
||||
# define COMPILER_VERSION_MINOR HEX(__CODEGEARC_VERSION__>>16 & 0x00FF)
|
||||
# define COMPILER_VERSION_PATCH HEX(__CODEGEARC_VERSION__ & 0xFFFF)
|
||||
|
||||
#elif defined(__BORLANDC__)
|
||||
# define COMPILER_ID "Borland"
|
||||
/* __BORLANDC__ = 0xVRR */
|
||||
# define COMPILER_VERSION_MAJOR HEX(__BORLANDC__>>8)
|
||||
# define COMPILER_VERSION_MINOR HEX(__BORLANDC__ & 0xFF)
|
||||
|
||||
#elif defined(__WATCOMC__)
|
||||
# define COMPILER_ID "Watcom"
|
||||
/* __WATCOMC__ = VVRR */
|
||||
# define COMPILER_VERSION_MAJOR DEC(__WATCOMC__ / 100)
|
||||
# define COMPILER_VERSION_MINOR DEC(__WATCOMC__ % 100)
|
||||
|
||||
#elif defined(__SUNPRO_C)
|
||||
# define COMPILER_ID "SunPro"
|
||||
# if __SUNPRO_C >= 0x5100
|
||||
/* __SUNPRO_C = 0xVRRP */
|
||||
# define COMPILER_VERSION_MAJOR HEX(__SUNPRO_C>>12)
|
||||
# define COMPILER_VERSION_MINOR HEX(__SUNPRO_C>>4 & 0xFF)
|
||||
# define COMPILER_VERSION_PATCH HEX(__SUNPRO_C & 0xF)
|
||||
# else
|
||||
/* __SUNPRO_C = 0xVRP */
|
||||
# define COMPILER_VERSION_MAJOR HEX(__SUNPRO_C>>8)
|
||||
# define COMPILER_VERSION_MINOR HEX(__SUNPRO_C>>4 & 0xF)
|
||||
# define COMPILER_VERSION_PATCH HEX(__SUNPRO_C & 0xF)
|
||||
# endif
|
||||
|
||||
#elif defined(__HP_cc)
|
||||
# define COMPILER_ID "HP"
|
||||
/* __HP_cc = VVRRPP */
|
||||
# define COMPILER_VERSION_MAJOR DEC(__HP_cc/10000)
|
||||
# define COMPILER_VERSION_MINOR DEC(__HP_cc/100 % 100)
|
||||
# define COMPILER_VERSION_PATCH DEC(__HP_cc % 100)
|
||||
|
||||
#elif defined(__DECC)
|
||||
# define COMPILER_ID "Compaq"
|
||||
/* __DECC_VER = VVRRTPPPP */
|
||||
# define COMPILER_VERSION_MAJOR DEC(__DECC_VER/10000000)
|
||||
# define COMPILER_VERSION_MINOR DEC(__DECC_VER/100000 % 100)
|
||||
# define COMPILER_VERSION_PATCH DEC(__DECC_VER % 10000)
|
||||
|
||||
#elif defined(__IBMC__)
|
||||
# if defined(__COMPILER_VER__)
|
||||
# define COMPILER_ID "zOS"
|
||||
# else
|
||||
# if __IBMC__ >= 800
|
||||
# define COMPILER_ID "XL"
|
||||
# else
|
||||
# define COMPILER_ID "VisualAge"
|
||||
# endif
|
||||
/* __IBMC__ = VRP */
|
||||
# define COMPILER_VERSION_MAJOR DEC(__IBMC__/100)
|
||||
# define COMPILER_VERSION_MINOR DEC(__IBMC__/10 % 10)
|
||||
# define COMPILER_VERSION_PATCH DEC(__IBMC__ % 10)
|
||||
# endif
|
||||
|
||||
#elif defined(__PGI)
|
||||
# define COMPILER_ID "PGI"
|
||||
# define COMPILER_VERSION_MAJOR DEC(__PGIC__)
|
||||
# define COMPILER_VERSION_MINOR DEC(__PGIC_MINOR__)
|
||||
# if defined(__PGIC_PATCHLEVEL__)
|
||||
# define COMPILER_VERSION_PATCH DEC(__PGIC_PATCHLEVEL__)
|
||||
# endif
|
||||
|
||||
#elif defined(_CRAYC)
|
||||
# define COMPILER_ID "Cray"
|
||||
# define COMPILER_VERSION_MAJOR DEC(_RELEASE)
|
||||
# define COMPILER_VERSION_MINOR DEC(_RELEASE_MINOR)
|
||||
|
||||
#elif defined(__TI_COMPILER_VERSION__)
|
||||
# define COMPILER_ID "TI"
|
||||
/* __TI_COMPILER_VERSION__ = VVVRRRPPP */
|
||||
# define COMPILER_VERSION_MAJOR DEC(__TI_COMPILER_VERSION__/1000000)
|
||||
# define COMPILER_VERSION_MINOR DEC(__TI_COMPILER_VERSION__/1000 % 1000)
|
||||
# define COMPILER_VERSION_PATCH DEC(__TI_COMPILER_VERSION__ % 1000)
|
||||
|
||||
#elif defined(__TINYC__)
|
||||
# define COMPILER_ID "TinyCC"
|
||||
|
||||
#elif defined(__SCO_VERSION__)
|
||||
# define COMPILER_ID "SCO"
|
||||
|
||||
#elif defined(__GNUC__)
|
||||
# define COMPILER_ID "GNU"
|
||||
# define COMPILER_VERSION_MAJOR DEC(__GNUC__)
|
||||
# define COMPILER_VERSION_MINOR DEC(__GNUC_MINOR__)
|
||||
# if defined(__GNUC_PATCHLEVEL__)
|
||||
# define COMPILER_VERSION_PATCH DEC(__GNUC_PATCHLEVEL__)
|
||||
# endif
|
||||
|
||||
#elif defined(_MSC_VER)
|
||||
# define COMPILER_ID "MSVC"
|
||||
/* _MSC_VER = VVRR */
|
||||
# define COMPILER_VERSION_MAJOR DEC(_MSC_VER / 100)
|
||||
# define COMPILER_VERSION_MINOR DEC(_MSC_VER % 100)
|
||||
# if defined(_MSC_FULL_VER)
|
||||
# if _MSC_VER >= 1400
|
||||
/* _MSC_FULL_VER = VVRRPPPPP */
|
||||
# define COMPILER_VERSION_PATCH DEC(_MSC_FULL_VER % 100000)
|
||||
# else
|
||||
/* _MSC_FULL_VER = VVRRPPPP */
|
||||
# define COMPILER_VERSION_PATCH DEC(_MSC_FULL_VER % 10000)
|
||||
# endif
|
||||
# endif
|
||||
# if defined(_MSC_BUILD)
|
||||
# define COMPILER_VERSION_TWEAK DEC(_MSC_BUILD)
|
||||
# endif
|
||||
|
||||
/* Analog VisualDSP++ >= 4.5.6 */
|
||||
#elif defined(__VISUALDSPVERSION__)
|
||||
# define COMPILER_ID "ADSP"
|
||||
/* __VISUALDSPVERSION__ = 0xVVRRPP00 */
|
||||
# define COMPILER_VERSION_MAJOR HEX(__VISUALDSPVERSION__>>24)
|
||||
# define COMPILER_VERSION_MINOR HEX(__VISUALDSPVERSION__>>16 & 0xFF)
|
||||
# define COMPILER_VERSION_PATCH HEX(__VISUALDSPVERSION__>>8 & 0xFF)
|
||||
|
||||
/* Analog VisualDSP++ < 4.5.6 */
|
||||
#elif defined(__ADSPBLACKFIN__) || defined(__ADSPTS__) || defined(__ADSP21000__)
|
||||
# define COMPILER_ID "ADSP"
|
||||
|
||||
/* IAR Systems compiler for embedded systems.
|
||||
http://www.iar.com */
|
||||
#elif defined(__IAR_SYSTEMS_ICC__ ) || defined(__IAR_SYSTEMS_ICC)
|
||||
# define COMPILER_ID "IAR"
|
||||
|
||||
/* sdcc, the small devices C compiler for embedded systems,
|
||||
http://sdcc.sourceforge.net */
|
||||
#elif defined(SDCC)
|
||||
# define COMPILER_ID "SDCC"
|
||||
/* SDCC = VRP */
|
||||
# define COMPILER_VERSION_MAJOR DEC(SDCC/100)
|
||||
# define COMPILER_VERSION_MINOR DEC(SDCC/10 % 10)
|
||||
# define COMPILER_VERSION_PATCH DEC(SDCC % 10)
|
||||
|
||||
#elif defined(_SGI_COMPILER_VERSION) || defined(_COMPILER_VERSION)
|
||||
# define COMPILER_ID "MIPSpro"
|
||||
# if defined(_SGI_COMPILER_VERSION)
|
||||
/* _SGI_COMPILER_VERSION = VRP */
|
||||
# define COMPILER_VERSION_MAJOR DEC(_SGI_COMPILER_VERSION/100)
|
||||
# define COMPILER_VERSION_MINOR DEC(_SGI_COMPILER_VERSION/10 % 10)
|
||||
# define COMPILER_VERSION_PATCH DEC(_SGI_COMPILER_VERSION % 10)
|
||||
# else
|
||||
/* _COMPILER_VERSION = VRP */
|
||||
# define COMPILER_VERSION_MAJOR DEC(_COMPILER_VERSION/100)
|
||||
# define COMPILER_VERSION_MINOR DEC(_COMPILER_VERSION/10 % 10)
|
||||
# define COMPILER_VERSION_PATCH DEC(_COMPILER_VERSION % 10)
|
||||
# endif
|
||||
|
||||
/* This compiler is either not known or is too old to define an
|
||||
identification macro. Try to identify the platform and guess that
|
||||
it is the native compiler. */
|
||||
#elif defined(__sgi)
|
||||
# define COMPILER_ID "MIPSpro"
|
||||
|
||||
#elif defined(__hpux) || defined(__hpua)
|
||||
# define COMPILER_ID "HP"
|
||||
|
||||
#else /* unknown compiler */
|
||||
# define COMPILER_ID ""
|
||||
|
||||
#endif
|
||||
|
||||
/* Construct the string literal in pieces to prevent the source from
|
||||
getting matched. Store it in a pointer rather than an array
|
||||
because some compilers will just produce instructions to fill the
|
||||
array rather than assigning a pointer to a static array. */
|
||||
char const* info_compiler = "INFO" ":" "compiler[" COMPILER_ID "]";
|
||||
|
||||
/* Identify known platforms by name. */
|
||||
#if defined(__linux) || defined(__linux__) || defined(linux)
|
||||
# define PLATFORM_ID "Linux"
|
||||
|
||||
#elif defined(__CYGWIN__)
|
||||
# define PLATFORM_ID "Cygwin"
|
||||
|
||||
#elif defined(__MINGW32__)
|
||||
# define PLATFORM_ID "MinGW"
|
||||
|
||||
#elif defined(__APPLE__)
|
||||
# define PLATFORM_ID "Darwin"
|
||||
|
||||
#elif defined(_WIN32) || defined(__WIN32__) || defined(WIN32)
|
||||
# define PLATFORM_ID "Windows"
|
||||
|
||||
#elif defined(__FreeBSD__) || defined(__FreeBSD)
|
||||
# define PLATFORM_ID "FreeBSD"
|
||||
|
||||
#elif defined(__NetBSD__) || defined(__NetBSD)
|
||||
# define PLATFORM_ID "NetBSD"
|
||||
|
||||
#elif defined(__OpenBSD__) || defined(__OPENBSD)
|
||||
# define PLATFORM_ID "OpenBSD"
|
||||
|
||||
#elif defined(__sun) || defined(sun)
|
||||
# define PLATFORM_ID "SunOS"
|
||||
|
||||
#elif defined(_AIX) || defined(__AIX) || defined(__AIX__) || defined(__aix) || defined(__aix__)
|
||||
# define PLATFORM_ID "AIX"
|
||||
|
||||
#elif defined(__sgi) || defined(__sgi__) || defined(_SGI)
|
||||
# define PLATFORM_ID "IRIX"
|
||||
|
||||
#elif defined(__hpux) || defined(__hpux__)
|
||||
# define PLATFORM_ID "HP-UX"
|
||||
|
||||
#elif defined(__HAIKU__)
|
||||
# define PLATFORM_ID "Haiku"
|
||||
|
||||
#elif defined(__BeOS) || defined(__BEOS__) || defined(_BEOS)
|
||||
# define PLATFORM_ID "BeOS"
|
||||
|
||||
#elif defined(__QNX__) || defined(__QNXNTO__)
|
||||
# define PLATFORM_ID "QNX"
|
||||
|
||||
#elif defined(__tru64) || defined(_tru64) || defined(__TRU64__)
|
||||
# define PLATFORM_ID "Tru64"
|
||||
|
||||
#elif defined(__riscos) || defined(__riscos__)
|
||||
# define PLATFORM_ID "RISCos"
|
||||
|
||||
#elif defined(__sinix) || defined(__sinix__) || defined(__SINIX__)
|
||||
# define PLATFORM_ID "SINIX"
|
||||
|
||||
#elif defined(__UNIX_SV__)
|
||||
# define PLATFORM_ID "UNIX_SV"
|
||||
|
||||
#elif defined(__bsdos__)
|
||||
# define PLATFORM_ID "BSDOS"
|
||||
|
||||
#elif defined(_MPRAS) || defined(MPRAS)
|
||||
# define PLATFORM_ID "MP-RAS"
|
||||
|
||||
#elif defined(__osf) || defined(__osf__)
|
||||
# define PLATFORM_ID "OSF1"
|
||||
|
||||
#elif defined(_SCO_SV) || defined(SCO_SV) || defined(sco_sv)
|
||||
# define PLATFORM_ID "SCO_SV"
|
||||
|
||||
#elif defined(__ultrix) || defined(__ultrix__) || defined(_ULTRIX)
|
||||
# define PLATFORM_ID "ULTRIX"
|
||||
|
||||
#elif defined(__XENIX__) || defined(_XENIX) || defined(XENIX)
|
||||
# define PLATFORM_ID "Xenix"
|
||||
|
||||
#else /* unknown platform */
|
||||
# define PLATFORM_ID ""
|
||||
|
||||
#endif
|
||||
|
||||
/* For windows compilers MSVC and Intel we can determine
|
||||
the architecture of the compiler being used. This is because
|
||||
the compilers do not have flags that can change the architecture,
|
||||
but rather depend on which compiler is being used
|
||||
*/
|
||||
#if defined(_WIN32) && defined(_MSC_VER)
|
||||
# if defined(_M_IA64)
|
||||
# define ARCHITECTURE_ID "IA64"
|
||||
|
||||
# elif defined(_M_X64) || defined(_M_AMD64)
|
||||
# define ARCHITECTURE_ID "x64"
|
||||
|
||||
# elif defined(_M_IX86)
|
||||
# define ARCHITECTURE_ID "X86"
|
||||
|
||||
# elif defined(_M_ARM)
|
||||
# define ARCHITECTURE_ID "ARM"
|
||||
|
||||
# elif defined(_M_MIPS)
|
||||
# define ARCHITECTURE_ID "MIPS"
|
||||
|
||||
# elif defined(_M_SH)
|
||||
# define ARCHITECTURE_ID "SHx"
|
||||
|
||||
# else /* unknown architecture */
|
||||
# define ARCHITECTURE_ID ""
|
||||
# endif
|
||||
|
||||
#else
|
||||
# define ARCHITECTURE_ID ""
|
||||
#endif
|
||||
|
||||
/* Convert integer to decimal digit literals. */
|
||||
#define DEC(n) \
|
||||
('0' + (((n) / 10000000)%10)), \
|
||||
('0' + (((n) / 1000000)%10)), \
|
||||
('0' + (((n) / 100000)%10)), \
|
||||
('0' + (((n) / 10000)%10)), \
|
||||
('0' + (((n) / 1000)%10)), \
|
||||
('0' + (((n) / 100)%10)), \
|
||||
('0' + (((n) / 10)%10)), \
|
||||
('0' + ((n) % 10))
|
||||
|
||||
/* Convert integer to hex digit literals. */
|
||||
#define HEX(n) \
|
||||
('0' + ((n)>>28 & 0xF)), \
|
||||
('0' + ((n)>>24 & 0xF)), \
|
||||
('0' + ((n)>>20 & 0xF)), \
|
||||
('0' + ((n)>>16 & 0xF)), \
|
||||
('0' + ((n)>>12 & 0xF)), \
|
||||
('0' + ((n)>>8 & 0xF)), \
|
||||
('0' + ((n)>>4 & 0xF)), \
|
||||
('0' + ((n) & 0xF))
|
||||
|
||||
/* Construct a string literal encoding the version number components. */
|
||||
#ifdef COMPILER_VERSION_MAJOR
|
||||
char const info_version[] = {
|
||||
'I', 'N', 'F', 'O', ':',
|
||||
'c','o','m','p','i','l','e','r','_','v','e','r','s','i','o','n','[',
|
||||
COMPILER_VERSION_MAJOR,
|
||||
# ifdef COMPILER_VERSION_MINOR
|
||||
'.', COMPILER_VERSION_MINOR,
|
||||
# ifdef COMPILER_VERSION_PATCH
|
||||
'.', COMPILER_VERSION_PATCH,
|
||||
# ifdef COMPILER_VERSION_TWEAK
|
||||
'.', COMPILER_VERSION_TWEAK,
|
||||
# endif
|
||||
# endif
|
||||
# endif
|
||||
']','\0'};
|
||||
#endif
|
||||
|
||||
/* Construct the string literal in pieces to prevent the source from
|
||||
getting matched. Store it in a pointer rather than an array
|
||||
because some compilers will just produce instructions to fill the
|
||||
array rather than assigning a pointer to a static array. */
|
||||
char const* info_platform = "INFO" ":" "platform[" PLATFORM_ID "]";
|
||||
char const* info_arch = "INFO" ":" "arch[" ARCHITECTURE_ID "]";
|
||||
|
||||
|
||||
|
||||
/*--------------------------------------------------------------------------*/
|
||||
|
||||
#ifdef ID_VOID_MAIN
|
||||
void main() {}
|
||||
#else
|
||||
int main(int argc, char* argv[])
|
||||
{
|
||||
int require = 0;
|
||||
require += info_compiler[argc];
|
||||
require += info_platform[argc];
|
||||
require += info_arch[argc];
|
||||
#ifdef COMPILER_VERSION_MAJOR
|
||||
require += info_version[argc];
|
||||
#endif
|
||||
(void)argv;
|
||||
return require;
|
||||
}
|
||||
#endif
|
||||
BIN
Binary file not shown.
+377
@@ -0,0 +1,377 @@
|
||||
/* This source file must have a .cpp extension so that all C++ compilers
|
||||
recognize the extension without flags. Borland does not know .cxx for
|
||||
example. */
|
||||
#ifndef __cplusplus
|
||||
# error "A C compiler has been selected for C++."
|
||||
#endif
|
||||
|
||||
/* Version number components: V=Version, R=Revision, P=Patch
|
||||
Version date components: YYYY=Year, MM=Month, DD=Day */
|
||||
|
||||
#if defined(__COMO__)
|
||||
# define COMPILER_ID "Comeau"
|
||||
/* __COMO_VERSION__ = VRR */
|
||||
# define COMPILER_VERSION_MAJOR DEC(__COMO_VERSION__ / 100)
|
||||
# define COMPILER_VERSION_MINOR DEC(__COMO_VERSION__ % 100)
|
||||
|
||||
#elif defined(__INTEL_COMPILER) || defined(__ICC)
|
||||
# define COMPILER_ID "Intel"
|
||||
/* __INTEL_COMPILER = VRP */
|
||||
# define COMPILER_VERSION_MAJOR DEC(__INTEL_COMPILER/100)
|
||||
# define COMPILER_VERSION_MINOR DEC(__INTEL_COMPILER/10 % 10)
|
||||
# define COMPILER_VERSION_PATCH DEC(__INTEL_COMPILER % 10)
|
||||
# if defined(__INTEL_COMPILER_BUILD_DATE)
|
||||
/* __INTEL_COMPILER_BUILD_DATE = YYYYMMDD */
|
||||
# define COMPILER_VERSION_TWEAK DEC(__INTEL_COMPILER_BUILD_DATE)
|
||||
# endif
|
||||
|
||||
#elif defined(__PATHCC__)
|
||||
# define COMPILER_ID "PathScale"
|
||||
# define COMPILER_VERSION_MAJOR DEC(__PATHCC__)
|
||||
# define COMPILER_VERSION_MINOR DEC(__PATHCC_MINOR__)
|
||||
# if defined(__PATHCC_PATCHLEVEL__)
|
||||
# define COMPILER_VERSION_PATCH DEC(__PATHCC_PATCHLEVEL__)
|
||||
# endif
|
||||
|
||||
#elif defined(__clang__)
|
||||
# define COMPILER_ID "Clang"
|
||||
# define COMPILER_VERSION_MAJOR DEC(__clang_major__)
|
||||
# define COMPILER_VERSION_MINOR DEC(__clang_minor__)
|
||||
# define COMPILER_VERSION_PATCH DEC(__clang_patchlevel__)
|
||||
|
||||
#elif defined(__BORLANDC__) && defined(__CODEGEARC_VERSION__)
|
||||
# define COMPILER_ID "Embarcadero"
|
||||
# define COMPILER_VERSION_MAJOR HEX(__CODEGEARC_VERSION__>>24 & 0x00FF)
|
||||
# define COMPILER_VERSION_MINOR HEX(__CODEGEARC_VERSION__>>16 & 0x00FF)
|
||||
# define COMPILER_VERSION_PATCH HEX(__CODEGEARC_VERSION__ & 0xFFFF)
|
||||
|
||||
#elif defined(__BORLANDC__)
|
||||
# define COMPILER_ID "Borland"
|
||||
/* __BORLANDC__ = 0xVRR */
|
||||
# define COMPILER_VERSION_MAJOR HEX(__BORLANDC__>>8)
|
||||
# define COMPILER_VERSION_MINOR HEX(__BORLANDC__ & 0xFF)
|
||||
|
||||
#elif defined(__WATCOMC__)
|
||||
# define COMPILER_ID "Watcom"
|
||||
/* __WATCOMC__ = VVRR */
|
||||
# define COMPILER_VERSION_MAJOR DEC(__WATCOMC__ / 100)
|
||||
# define COMPILER_VERSION_MINOR DEC(__WATCOMC__ % 100)
|
||||
|
||||
#elif defined(__SUNPRO_CC)
|
||||
# define COMPILER_ID "SunPro"
|
||||
# if __SUNPRO_CC >= 0x5100
|
||||
/* __SUNPRO_CC = 0xVRRP */
|
||||
# define COMPILER_VERSION_MAJOR HEX(__SUNPRO_CC>>12)
|
||||
# define COMPILER_VERSION_MINOR HEX(__SUNPRO_CC>>4 & 0xFF)
|
||||
# define COMPILER_VERSION_PATCH HEX(__SUNPRO_CC & 0xF)
|
||||
# else
|
||||
/* __SUNPRO_CC = 0xVRP */
|
||||
# define COMPILER_VERSION_MAJOR HEX(__SUNPRO_CC>>8)
|
||||
# define COMPILER_VERSION_MINOR HEX(__SUNPRO_CC>>4 & 0xF)
|
||||
# define COMPILER_VERSION_PATCH HEX(__SUNPRO_CC & 0xF)
|
||||
# endif
|
||||
|
||||
#elif defined(__HP_aCC)
|
||||
# define COMPILER_ID "HP"
|
||||
/* __HP_aCC = VVRRPP */
|
||||
# define COMPILER_VERSION_MAJOR DEC(__HP_aCC/10000)
|
||||
# define COMPILER_VERSION_MINOR DEC(__HP_aCC/100 % 100)
|
||||
# define COMPILER_VERSION_PATCH DEC(__HP_aCC % 100)
|
||||
|
||||
#elif defined(__DECCXX)
|
||||
# define COMPILER_ID "Compaq"
|
||||
/* __DECCXX_VER = VVRRTPPPP */
|
||||
# define COMPILER_VERSION_MAJOR DEC(__DECCXX_VER/10000000)
|
||||
# define COMPILER_VERSION_MINOR DEC(__DECCXX_VER/100000 % 100)
|
||||
# define COMPILER_VERSION_PATCH DEC(__DECCXX_VER % 10000)
|
||||
|
||||
#elif defined(__IBMCPP__)
|
||||
# if defined(__COMPILER_VER__)
|
||||
# define COMPILER_ID "zOS"
|
||||
# else
|
||||
# if __IBMCPP__ >= 800
|
||||
# define COMPILER_ID "XL"
|
||||
# else
|
||||
# define COMPILER_ID "VisualAge"
|
||||
# endif
|
||||
/* __IBMCPP__ = VRP */
|
||||
# define COMPILER_VERSION_MAJOR DEC(__IBMCPP__/100)
|
||||
# define COMPILER_VERSION_MINOR DEC(__IBMCPP__/10 % 10)
|
||||
# define COMPILER_VERSION_PATCH DEC(__IBMCPP__ % 10)
|
||||
# endif
|
||||
|
||||
#elif defined(__PGI)
|
||||
# define COMPILER_ID "PGI"
|
||||
# define COMPILER_VERSION_MAJOR DEC(__PGIC__)
|
||||
# define COMPILER_VERSION_MINOR DEC(__PGIC_MINOR__)
|
||||
# if defined(__PGIC_PATCHLEVEL__)
|
||||
# define COMPILER_VERSION_PATCH DEC(__PGIC_PATCHLEVEL__)
|
||||
# endif
|
||||
|
||||
#elif defined(_CRAYC)
|
||||
# define COMPILER_ID "Cray"
|
||||
# define COMPILER_VERSION_MAJOR DEC(_RELEASE)
|
||||
# define COMPILER_VERSION_MINOR DEC(_RELEASE_MINOR)
|
||||
|
||||
#elif defined(__TI_COMPILER_VERSION__)
|
||||
# define COMPILER_ID "TI"
|
||||
/* __TI_COMPILER_VERSION__ = VVVRRRPPP */
|
||||
# define COMPILER_VERSION_MAJOR DEC(__TI_COMPILER_VERSION__/1000000)
|
||||
# define COMPILER_VERSION_MINOR DEC(__TI_COMPILER_VERSION__/1000 % 1000)
|
||||
# define COMPILER_VERSION_PATCH DEC(__TI_COMPILER_VERSION__ % 1000)
|
||||
|
||||
#elif defined(__SCO_VERSION__)
|
||||
# define COMPILER_ID "SCO"
|
||||
|
||||
#elif defined(__GNUC__)
|
||||
# define COMPILER_ID "GNU"
|
||||
# define COMPILER_VERSION_MAJOR DEC(__GNUC__)
|
||||
# define COMPILER_VERSION_MINOR DEC(__GNUC_MINOR__)
|
||||
# if defined(__GNUC_PATCHLEVEL__)
|
||||
# define COMPILER_VERSION_PATCH DEC(__GNUC_PATCHLEVEL__)
|
||||
# endif
|
||||
|
||||
#elif defined(_MSC_VER)
|
||||
# define COMPILER_ID "MSVC"
|
||||
/* _MSC_VER = VVRR */
|
||||
# define COMPILER_VERSION_MAJOR DEC(_MSC_VER / 100)
|
||||
# define COMPILER_VERSION_MINOR DEC(_MSC_VER % 100)
|
||||
# if defined(_MSC_FULL_VER)
|
||||
# if _MSC_VER >= 1400
|
||||
/* _MSC_FULL_VER = VVRRPPPPP */
|
||||
# define COMPILER_VERSION_PATCH DEC(_MSC_FULL_VER % 100000)
|
||||
# else
|
||||
/* _MSC_FULL_VER = VVRRPPPP */
|
||||
# define COMPILER_VERSION_PATCH DEC(_MSC_FULL_VER % 10000)
|
||||
# endif
|
||||
# endif
|
||||
# if defined(_MSC_BUILD)
|
||||
# define COMPILER_VERSION_TWEAK DEC(_MSC_BUILD)
|
||||
# endif
|
||||
|
||||
/* Analog VisualDSP++ >= 4.5.6 */
|
||||
#elif defined(__VISUALDSPVERSION__)
|
||||
# define COMPILER_ID "ADSP"
|
||||
/* __VISUALDSPVERSION__ = 0xVVRRPP00 */
|
||||
# define COMPILER_VERSION_MAJOR HEX(__VISUALDSPVERSION__>>24)
|
||||
# define COMPILER_VERSION_MINOR HEX(__VISUALDSPVERSION__>>16 & 0xFF)
|
||||
# define COMPILER_VERSION_PATCH HEX(__VISUALDSPVERSION__>>8 & 0xFF)
|
||||
|
||||
/* Analog VisualDSP++ < 4.5.6 */
|
||||
#elif defined(__ADSPBLACKFIN__) || defined(__ADSPTS__) || defined(__ADSP21000__)
|
||||
# define COMPILER_ID "ADSP"
|
||||
|
||||
/* IAR Systems compiler for embedded systems.
|
||||
http://www.iar.com */
|
||||
#elif defined(__IAR_SYSTEMS_ICC__ ) || defined(__IAR_SYSTEMS_ICC)
|
||||
# define COMPILER_ID "IAR"
|
||||
|
||||
#elif defined(_SGI_COMPILER_VERSION) || defined(_COMPILER_VERSION)
|
||||
# define COMPILER_ID "MIPSpro"
|
||||
# if defined(_SGI_COMPILER_VERSION)
|
||||
/* _SGI_COMPILER_VERSION = VRP */
|
||||
# define COMPILER_VERSION_MAJOR DEC(_SGI_COMPILER_VERSION/100)
|
||||
# define COMPILER_VERSION_MINOR DEC(_SGI_COMPILER_VERSION/10 % 10)
|
||||
# define COMPILER_VERSION_PATCH DEC(_SGI_COMPILER_VERSION % 10)
|
||||
# else
|
||||
/* _COMPILER_VERSION = VRP */
|
||||
# define COMPILER_VERSION_MAJOR DEC(_COMPILER_VERSION/100)
|
||||
# define COMPILER_VERSION_MINOR DEC(_COMPILER_VERSION/10 % 10)
|
||||
# define COMPILER_VERSION_PATCH DEC(_COMPILER_VERSION % 10)
|
||||
# endif
|
||||
|
||||
/* This compiler is either not known or is too old to define an
|
||||
identification macro. Try to identify the platform and guess that
|
||||
it is the native compiler. */
|
||||
#elif defined(__sgi)
|
||||
# define COMPILER_ID "MIPSpro"
|
||||
|
||||
#elif defined(__hpux) || defined(__hpua)
|
||||
# define COMPILER_ID "HP"
|
||||
|
||||
#else /* unknown compiler */
|
||||
# define COMPILER_ID ""
|
||||
|
||||
#endif
|
||||
|
||||
/* Construct the string literal in pieces to prevent the source from
|
||||
getting matched. Store it in a pointer rather than an array
|
||||
because some compilers will just produce instructions to fill the
|
||||
array rather than assigning a pointer to a static array. */
|
||||
char const* info_compiler = "INFO" ":" "compiler[" COMPILER_ID "]";
|
||||
|
||||
/* Identify known platforms by name. */
|
||||
#if defined(__linux) || defined(__linux__) || defined(linux)
|
||||
# define PLATFORM_ID "Linux"
|
||||
|
||||
#elif defined(__CYGWIN__)
|
||||
# define PLATFORM_ID "Cygwin"
|
||||
|
||||
#elif defined(__MINGW32__)
|
||||
# define PLATFORM_ID "MinGW"
|
||||
|
||||
#elif defined(__APPLE__)
|
||||
# define PLATFORM_ID "Darwin"
|
||||
|
||||
#elif defined(_WIN32) || defined(__WIN32__) || defined(WIN32)
|
||||
# define PLATFORM_ID "Windows"
|
||||
|
||||
#elif defined(__FreeBSD__) || defined(__FreeBSD)
|
||||
# define PLATFORM_ID "FreeBSD"
|
||||
|
||||
#elif defined(__NetBSD__) || defined(__NetBSD)
|
||||
# define PLATFORM_ID "NetBSD"
|
||||
|
||||
#elif defined(__OpenBSD__) || defined(__OPENBSD)
|
||||
# define PLATFORM_ID "OpenBSD"
|
||||
|
||||
#elif defined(__sun) || defined(sun)
|
||||
# define PLATFORM_ID "SunOS"
|
||||
|
||||
#elif defined(_AIX) || defined(__AIX) || defined(__AIX__) || defined(__aix) || defined(__aix__)
|
||||
# define PLATFORM_ID "AIX"
|
||||
|
||||
#elif defined(__sgi) || defined(__sgi__) || defined(_SGI)
|
||||
# define PLATFORM_ID "IRIX"
|
||||
|
||||
#elif defined(__hpux) || defined(__hpux__)
|
||||
# define PLATFORM_ID "HP-UX"
|
||||
|
||||
#elif defined(__HAIKU__)
|
||||
# define PLATFORM_ID "Haiku"
|
||||
|
||||
#elif defined(__BeOS) || defined(__BEOS__) || defined(_BEOS)
|
||||
# define PLATFORM_ID "BeOS"
|
||||
|
||||
#elif defined(__QNX__) || defined(__QNXNTO__)
|
||||
# define PLATFORM_ID "QNX"
|
||||
|
||||
#elif defined(__tru64) || defined(_tru64) || defined(__TRU64__)
|
||||
# define PLATFORM_ID "Tru64"
|
||||
|
||||
#elif defined(__riscos) || defined(__riscos__)
|
||||
# define PLATFORM_ID "RISCos"
|
||||
|
||||
#elif defined(__sinix) || defined(__sinix__) || defined(__SINIX__)
|
||||
# define PLATFORM_ID "SINIX"
|
||||
|
||||
#elif defined(__UNIX_SV__)
|
||||
# define PLATFORM_ID "UNIX_SV"
|
||||
|
||||
#elif defined(__bsdos__)
|
||||
# define PLATFORM_ID "BSDOS"
|
||||
|
||||
#elif defined(_MPRAS) || defined(MPRAS)
|
||||
# define PLATFORM_ID "MP-RAS"
|
||||
|
||||
#elif defined(__osf) || defined(__osf__)
|
||||
# define PLATFORM_ID "OSF1"
|
||||
|
||||
#elif defined(_SCO_SV) || defined(SCO_SV) || defined(sco_sv)
|
||||
# define PLATFORM_ID "SCO_SV"
|
||||
|
||||
#elif defined(__ultrix) || defined(__ultrix__) || defined(_ULTRIX)
|
||||
# define PLATFORM_ID "ULTRIX"
|
||||
|
||||
#elif defined(__XENIX__) || defined(_XENIX) || defined(XENIX)
|
||||
# define PLATFORM_ID "Xenix"
|
||||
|
||||
#else /* unknown platform */
|
||||
# define PLATFORM_ID ""
|
||||
|
||||
#endif
|
||||
|
||||
/* For windows compilers MSVC and Intel we can determine
|
||||
the architecture of the compiler being used. This is because
|
||||
the compilers do not have flags that can change the architecture,
|
||||
but rather depend on which compiler is being used
|
||||
*/
|
||||
#if defined(_WIN32) && defined(_MSC_VER)
|
||||
# if defined(_M_IA64)
|
||||
# define ARCHITECTURE_ID "IA64"
|
||||
|
||||
# elif defined(_M_X64) || defined(_M_AMD64)
|
||||
# define ARCHITECTURE_ID "x64"
|
||||
|
||||
# elif defined(_M_IX86)
|
||||
# define ARCHITECTURE_ID "X86"
|
||||
|
||||
# elif defined(_M_ARM)
|
||||
# define ARCHITECTURE_ID "ARM"
|
||||
|
||||
# elif defined(_M_MIPS)
|
||||
# define ARCHITECTURE_ID "MIPS"
|
||||
|
||||
# elif defined(_M_SH)
|
||||
# define ARCHITECTURE_ID "SHx"
|
||||
|
||||
# else /* unknown architecture */
|
||||
# define ARCHITECTURE_ID ""
|
||||
# endif
|
||||
|
||||
#else
|
||||
# define ARCHITECTURE_ID ""
|
||||
#endif
|
||||
|
||||
/* Convert integer to decimal digit literals. */
|
||||
#define DEC(n) \
|
||||
('0' + (((n) / 10000000)%10)), \
|
||||
('0' + (((n) / 1000000)%10)), \
|
||||
('0' + (((n) / 100000)%10)), \
|
||||
('0' + (((n) / 10000)%10)), \
|
||||
('0' + (((n) / 1000)%10)), \
|
||||
('0' + (((n) / 100)%10)), \
|
||||
('0' + (((n) / 10)%10)), \
|
||||
('0' + ((n) % 10))
|
||||
|
||||
/* Convert integer to hex digit literals. */
|
||||
#define HEX(n) \
|
||||
('0' + ((n)>>28 & 0xF)), \
|
||||
('0' + ((n)>>24 & 0xF)), \
|
||||
('0' + ((n)>>20 & 0xF)), \
|
||||
('0' + ((n)>>16 & 0xF)), \
|
||||
('0' + ((n)>>12 & 0xF)), \
|
||||
('0' + ((n)>>8 & 0xF)), \
|
||||
('0' + ((n)>>4 & 0xF)), \
|
||||
('0' + ((n) & 0xF))
|
||||
|
||||
/* Construct a string literal encoding the version number components. */
|
||||
#ifdef COMPILER_VERSION_MAJOR
|
||||
char const info_version[] = {
|
||||
'I', 'N', 'F', 'O', ':',
|
||||
'c','o','m','p','i','l','e','r','_','v','e','r','s','i','o','n','[',
|
||||
COMPILER_VERSION_MAJOR,
|
||||
# ifdef COMPILER_VERSION_MINOR
|
||||
'.', COMPILER_VERSION_MINOR,
|
||||
# ifdef COMPILER_VERSION_PATCH
|
||||
'.', COMPILER_VERSION_PATCH,
|
||||
# ifdef COMPILER_VERSION_TWEAK
|
||||
'.', COMPILER_VERSION_TWEAK,
|
||||
# endif
|
||||
# endif
|
||||
# endif
|
||||
']','\0'};
|
||||
#endif
|
||||
|
||||
/* Construct the string literal in pieces to prevent the source from
|
||||
getting matched. Store it in a pointer rather than an array
|
||||
because some compilers will just produce instructions to fill the
|
||||
array rather than assigning a pointer to a static array. */
|
||||
char const* info_platform = "INFO" ":" "platform[" PLATFORM_ID "]";
|
||||
char const* info_arch = "INFO" ":" "arch[" ARCHITECTURE_ID "]";
|
||||
|
||||
|
||||
|
||||
/*--------------------------------------------------------------------------*/
|
||||
|
||||
int main(int argc, char* argv[])
|
||||
{
|
||||
int require = 0;
|
||||
require += info_compiler[argc];
|
||||
require += info_platform[argc];
|
||||
#ifdef COMPILER_VERSION_MAJOR
|
||||
require += info_version[argc];
|
||||
#endif
|
||||
(void)argv;
|
||||
return require;
|
||||
}
|
||||
BIN
Binary file not shown.
@@ -0,0 +1,247 @@
|
||||
The system is: Linux - 3.10.0-957.21.3.rt56.935.el7.x86_64 - x86_64
|
||||
Compiling the C compiler identification source file "CMakeCCompilerId.c" succeeded.
|
||||
Compiler: /usr/bin/cc
|
||||
Build flags:
|
||||
Id flags:
|
||||
|
||||
The output was:
|
||||
0
|
||||
|
||||
|
||||
Compilation of the C compiler identification source "CMakeCCompilerId.c" produced "a.out"
|
||||
|
||||
The C compiler identification is GNU, found in "/home/sy/openairinterface5g/openair1/SIMULATION/NR_UE_PHY/unit_tests/build/CMakeFiles/2.8.12.2/CompilerIdC/a.out"
|
||||
|
||||
Compiling the CXX compiler identification source file "CMakeCXXCompilerId.cpp" succeeded.
|
||||
Compiler: /usr/bin/c++
|
||||
Build flags:
|
||||
Id flags:
|
||||
|
||||
The output was:
|
||||
0
|
||||
|
||||
|
||||
Compilation of the CXX compiler identification source "CMakeCXXCompilerId.cpp" produced "a.out"
|
||||
|
||||
The CXX compiler identification is GNU, found in "/home/sy/openairinterface5g/openair1/SIMULATION/NR_UE_PHY/unit_tests/build/CMakeFiles/2.8.12.2/CompilerIdCXX/a.out"
|
||||
|
||||
Determining if the C compiler works passed with the following output:
|
||||
Change Dir: /home/sy/openairinterface5g/openair1/SIMULATION/NR_UE_PHY/unit_tests/build/CMakeFiles/CMakeTmp
|
||||
|
||||
Run Build Command:/usr/bin/gmake "cmTryCompileExec2388936454/fast"
|
||||
/usr/bin/gmake -f CMakeFiles/cmTryCompileExec2388936454.dir/build.make CMakeFiles/cmTryCompileExec2388936454.dir/build
|
||||
gmake[1]: Entering directory `/home/sy/openairinterface5g/openair1/SIMULATION/NR_UE_PHY/unit_tests/build/CMakeFiles/CMakeTmp'
|
||||
/usr/bin/cmake -E cmake_progress_report /home/sy/openairinterface5g/openair1/SIMULATION/NR_UE_PHY/unit_tests/build/CMakeFiles/CMakeTmp/CMakeFiles 1
|
||||
Building C object CMakeFiles/cmTryCompileExec2388936454.dir/testCCompiler.c.o
|
||||
/usr/bin/cc -o CMakeFiles/cmTryCompileExec2388936454.dir/testCCompiler.c.o -c /home/sy/openairinterface5g/openair1/SIMULATION/NR_UE_PHY/unit_tests/build/CMakeFiles/CMakeTmp/testCCompiler.c
|
||||
Linking C executable cmTryCompileExec2388936454
|
||||
/usr/bin/cmake -E cmake_link_script CMakeFiles/cmTryCompileExec2388936454.dir/link.txt --verbose=1
|
||||
/usr/bin/cc CMakeFiles/cmTryCompileExec2388936454.dir/testCCompiler.c.o -o cmTryCompileExec2388936454 -rdynamic
|
||||
gmake[1]: Leaving directory `/home/sy/openairinterface5g/openair1/SIMULATION/NR_UE_PHY/unit_tests/build/CMakeFiles/CMakeTmp'
|
||||
|
||||
|
||||
Detecting C compiler ABI info compiled with the following output:
|
||||
Change Dir: /home/sy/openairinterface5g/openair1/SIMULATION/NR_UE_PHY/unit_tests/build/CMakeFiles/CMakeTmp
|
||||
|
||||
Run Build Command:/usr/bin/gmake "cmTryCompileExec602265197/fast"
|
||||
/usr/bin/gmake -f CMakeFiles/cmTryCompileExec602265197.dir/build.make CMakeFiles/cmTryCompileExec602265197.dir/build
|
||||
gmake[1]: Entering directory `/home/sy/openairinterface5g/openair1/SIMULATION/NR_UE_PHY/unit_tests/build/CMakeFiles/CMakeTmp'
|
||||
/usr/bin/cmake -E cmake_progress_report /home/sy/openairinterface5g/openair1/SIMULATION/NR_UE_PHY/unit_tests/build/CMakeFiles/CMakeTmp/CMakeFiles 1
|
||||
Building C object CMakeFiles/cmTryCompileExec602265197.dir/CMakeCCompilerABI.c.o
|
||||
/usr/bin/cc -o CMakeFiles/cmTryCompileExec602265197.dir/CMakeCCompilerABI.c.o -c /usr/share/cmake/Modules/CMakeCCompilerABI.c
|
||||
Linking C executable cmTryCompileExec602265197
|
||||
/usr/bin/cmake -E cmake_link_script CMakeFiles/cmTryCompileExec602265197.dir/link.txt --verbose=1
|
||||
/usr/bin/cc -v CMakeFiles/cmTryCompileExec602265197.dir/CMakeCCompilerABI.c.o -o cmTryCompileExec602265197 -rdynamic
|
||||
Using built-in specs.
|
||||
COLLECT_GCC=/usr/bin/cc
|
||||
COLLECT_LTO_WRAPPER=/usr/libexec/gcc/x86_64-redhat-linux/4.8.5/lto-wrapper
|
||||
Target: x86_64-redhat-linux
|
||||
Configured with: ../configure --prefix=/usr --mandir=/usr/share/man --infodir=/usr/share/info --with-bugurl=http://bugzilla.redhat.com/bugzilla --enable-bootstrap --enable-shared --enable-threads=posix --enable-checking=release --with-system-zlib --enable-__cxa_atexit --disable-libunwind-exceptions --enable-gnu-unique-object --enable-linker-build-id --with-linker-hash-style=gnu --enable-languages=c,c++,objc,obj-c++,java,fortran,ada,go,lto --enable-plugin --enable-initfini-array --disable-libgcj --with-isl=/builddir/build/BUILD/gcc-4.8.5-20150702/obj-x86_64-redhat-linux/isl-install --with-cloog=/builddir/build/BUILD/gcc-4.8.5-20150702/obj-x86_64-redhat-linux/cloog-install --enable-gnu-indirect-function --with-tune=generic --with-arch_32=x86-64 --build=x86_64-redhat-linux
|
||||
Thread model: posix
|
||||
gcc version 4.8.5 20150623 (Red Hat 4.8.5-39) (GCC)
|
||||
COMPILER_PATH=/usr/libexec/gcc/x86_64-redhat-linux/4.8.5/:/usr/libexec/gcc/x86_64-redhat-linux/4.8.5/:/usr/libexec/gcc/x86_64-redhat-linux/:/usr/lib/gcc/x86_64-redhat-linux/4.8.5/:/usr/lib/gcc/x86_64-redhat-linux/
|
||||
LIBRARY_PATH=/usr/lib/gcc/x86_64-redhat-linux/4.8.5/:/usr/lib/gcc/x86_64-redhat-linux/4.8.5/../../../../lib64/:/lib/../lib64/:/usr/lib/../lib64/:/usr/lib/gcc/x86_64-redhat-linux/4.8.5/../../../:/lib/:/usr/lib/
|
||||
COLLECT_GCC_OPTIONS='-v' '-o' 'cmTryCompileExec602265197' '-rdynamic' '-mtune=generic' '-march=x86-64'
|
||||
/usr/libexec/gcc/x86_64-redhat-linux/4.8.5/collect2 --build-id --no-add-needed --eh-frame-hdr --hash-style=gnu -m elf_x86_64 -export-dynamic -dynamic-linker /lib64/ld-linux-x86-64.so.2 -o cmTryCompileExec602265197 /usr/lib/gcc/x86_64-redhat-linux/4.8.5/../../../../lib64/crt1.o /usr/lib/gcc/x86_64-redhat-linux/4.8.5/../../../../lib64/crti.o /usr/lib/gcc/x86_64-redhat-linux/4.8.5/crtbegin.o -L/usr/lib/gcc/x86_64-redhat-linux/4.8.5 -L/usr/lib/gcc/x86_64-redhat-linux/4.8.5/../../../../lib64 -L/lib/../lib64 -L/usr/lib/../lib64 -L/usr/lib/gcc/x86_64-redhat-linux/4.8.5/../../.. CMakeFiles/cmTryCompileExec602265197.dir/CMakeCCompilerABI.c.o -lgcc --as-needed -lgcc_s --no-as-needed -lc -lgcc --as-needed -lgcc_s --no-as-needed /usr/lib/gcc/x86_64-redhat-linux/4.8.5/crtend.o /usr/lib/gcc/x86_64-redhat-linux/4.8.5/../../../../lib64/crtn.o
|
||||
gmake[1]: Leaving directory `/home/sy/openairinterface5g/openair1/SIMULATION/NR_UE_PHY/unit_tests/build/CMakeFiles/CMakeTmp'
|
||||
|
||||
|
||||
Parsed C implicit link information from above output:
|
||||
link line regex: [^( *|.*[/\])(ld|([^/\]+-)?ld|collect2)[^/\]*( |$)]
|
||||
ignore line: [Change Dir: /home/sy/openairinterface5g/openair1/SIMULATION/NR_UE_PHY/unit_tests/build/CMakeFiles/CMakeTmp]
|
||||
ignore line: []
|
||||
ignore line: [Run Build Command:/usr/bin/gmake "cmTryCompileExec602265197/fast"]
|
||||
ignore line: [/usr/bin/gmake -f CMakeFiles/cmTryCompileExec602265197.dir/build.make CMakeFiles/cmTryCompileExec602265197.dir/build]
|
||||
ignore line: [gmake[1]: Entering directory `/home/sy/openairinterface5g/openair1/SIMULATION/NR_UE_PHY/unit_tests/build/CMakeFiles/CMakeTmp']
|
||||
ignore line: [/usr/bin/cmake -E cmake_progress_report /home/sy/openairinterface5g/openair1/SIMULATION/NR_UE_PHY/unit_tests/build/CMakeFiles/CMakeTmp/CMakeFiles 1]
|
||||
ignore line: [Building C object CMakeFiles/cmTryCompileExec602265197.dir/CMakeCCompilerABI.c.o]
|
||||
ignore line: [/usr/bin/cc -o CMakeFiles/cmTryCompileExec602265197.dir/CMakeCCompilerABI.c.o -c /usr/share/cmake/Modules/CMakeCCompilerABI.c]
|
||||
ignore line: [Linking C executable cmTryCompileExec602265197]
|
||||
ignore line: [/usr/bin/cmake -E cmake_link_script CMakeFiles/cmTryCompileExec602265197.dir/link.txt --verbose=1]
|
||||
ignore line: [/usr/bin/cc -v CMakeFiles/cmTryCompileExec602265197.dir/CMakeCCompilerABI.c.o -o cmTryCompileExec602265197 -rdynamic ]
|
||||
ignore line: [Using built-in specs.]
|
||||
ignore line: [COLLECT_GCC=/usr/bin/cc]
|
||||
ignore line: [COLLECT_LTO_WRAPPER=/usr/libexec/gcc/x86_64-redhat-linux/4.8.5/lto-wrapper]
|
||||
ignore line: [Target: x86_64-redhat-linux]
|
||||
ignore line: [Configured with: ../configure --prefix=/usr --mandir=/usr/share/man --infodir=/usr/share/info --with-bugurl=http://bugzilla.redhat.com/bugzilla --enable-bootstrap --enable-shared --enable-threads=posix --enable-checking=release --with-system-zlib --enable-__cxa_atexit --disable-libunwind-exceptions --enable-gnu-unique-object --enable-linker-build-id --with-linker-hash-style=gnu --enable-languages=c,c++,objc,obj-c++,java,fortran,ada,go,lto --enable-plugin --enable-initfini-array --disable-libgcj --with-isl=/builddir/build/BUILD/gcc-4.8.5-20150702/obj-x86_64-redhat-linux/isl-install --with-cloog=/builddir/build/BUILD/gcc-4.8.5-20150702/obj-x86_64-redhat-linux/cloog-install --enable-gnu-indirect-function --with-tune=generic --with-arch_32=x86-64 --build=x86_64-redhat-linux]
|
||||
ignore line: [Thread model: posix]
|
||||
ignore line: [gcc version 4.8.5 20150623 (Red Hat 4.8.5-39) (GCC) ]
|
||||
ignore line: [COMPILER_PATH=/usr/libexec/gcc/x86_64-redhat-linux/4.8.5/:/usr/libexec/gcc/x86_64-redhat-linux/4.8.5/:/usr/libexec/gcc/x86_64-redhat-linux/:/usr/lib/gcc/x86_64-redhat-linux/4.8.5/:/usr/lib/gcc/x86_64-redhat-linux/]
|
||||
ignore line: [LIBRARY_PATH=/usr/lib/gcc/x86_64-redhat-linux/4.8.5/:/usr/lib/gcc/x86_64-redhat-linux/4.8.5/../../../../lib64/:/lib/../lib64/:/usr/lib/../lib64/:/usr/lib/gcc/x86_64-redhat-linux/4.8.5/../../../:/lib/:/usr/lib/]
|
||||
ignore line: [COLLECT_GCC_OPTIONS='-v' '-o' 'cmTryCompileExec602265197' '-rdynamic' '-mtune=generic' '-march=x86-64']
|
||||
link line: [ /usr/libexec/gcc/x86_64-redhat-linux/4.8.5/collect2 --build-id --no-add-needed --eh-frame-hdr --hash-style=gnu -m elf_x86_64 -export-dynamic -dynamic-linker /lib64/ld-linux-x86-64.so.2 -o cmTryCompileExec602265197 /usr/lib/gcc/x86_64-redhat-linux/4.8.5/../../../../lib64/crt1.o /usr/lib/gcc/x86_64-redhat-linux/4.8.5/../../../../lib64/crti.o /usr/lib/gcc/x86_64-redhat-linux/4.8.5/crtbegin.o -L/usr/lib/gcc/x86_64-redhat-linux/4.8.5 -L/usr/lib/gcc/x86_64-redhat-linux/4.8.5/../../../../lib64 -L/lib/../lib64 -L/usr/lib/../lib64 -L/usr/lib/gcc/x86_64-redhat-linux/4.8.5/../../.. CMakeFiles/cmTryCompileExec602265197.dir/CMakeCCompilerABI.c.o -lgcc --as-needed -lgcc_s --no-as-needed -lc -lgcc --as-needed -lgcc_s --no-as-needed /usr/lib/gcc/x86_64-redhat-linux/4.8.5/crtend.o /usr/lib/gcc/x86_64-redhat-linux/4.8.5/../../../../lib64/crtn.o]
|
||||
arg [/usr/libexec/gcc/x86_64-redhat-linux/4.8.5/collect2] ==> ignore
|
||||
arg [--build-id] ==> ignore
|
||||
arg [--no-add-needed] ==> ignore
|
||||
arg [--eh-frame-hdr] ==> ignore
|
||||
arg [--hash-style=gnu] ==> ignore
|
||||
arg [-m] ==> ignore
|
||||
arg [elf_x86_64] ==> ignore
|
||||
arg [-export-dynamic] ==> ignore
|
||||
arg [-dynamic-linker] ==> ignore
|
||||
arg [/lib64/ld-linux-x86-64.so.2] ==> ignore
|
||||
arg [-o] ==> ignore
|
||||
arg [cmTryCompileExec602265197] ==> ignore
|
||||
arg [/usr/lib/gcc/x86_64-redhat-linux/4.8.5/../../../../lib64/crt1.o] ==> ignore
|
||||
arg [/usr/lib/gcc/x86_64-redhat-linux/4.8.5/../../../../lib64/crti.o] ==> ignore
|
||||
arg [/usr/lib/gcc/x86_64-redhat-linux/4.8.5/crtbegin.o] ==> ignore
|
||||
arg [-L/usr/lib/gcc/x86_64-redhat-linux/4.8.5] ==> dir [/usr/lib/gcc/x86_64-redhat-linux/4.8.5]
|
||||
arg [-L/usr/lib/gcc/x86_64-redhat-linux/4.8.5/../../../../lib64] ==> dir [/usr/lib/gcc/x86_64-redhat-linux/4.8.5/../../../../lib64]
|
||||
arg [-L/lib/../lib64] ==> dir [/lib/../lib64]
|
||||
arg [-L/usr/lib/../lib64] ==> dir [/usr/lib/../lib64]
|
||||
arg [-L/usr/lib/gcc/x86_64-redhat-linux/4.8.5/../../..] ==> dir [/usr/lib/gcc/x86_64-redhat-linux/4.8.5/../../..]
|
||||
arg [CMakeFiles/cmTryCompileExec602265197.dir/CMakeCCompilerABI.c.o] ==> ignore
|
||||
arg [-lgcc] ==> lib [gcc]
|
||||
arg [--as-needed] ==> ignore
|
||||
arg [-lgcc_s] ==> lib [gcc_s]
|
||||
arg [--no-as-needed] ==> ignore
|
||||
arg [-lc] ==> lib [c]
|
||||
arg [-lgcc] ==> lib [gcc]
|
||||
arg [--as-needed] ==> ignore
|
||||
arg [-lgcc_s] ==> lib [gcc_s]
|
||||
arg [--no-as-needed] ==> ignore
|
||||
arg [/usr/lib/gcc/x86_64-redhat-linux/4.8.5/crtend.o] ==> ignore
|
||||
arg [/usr/lib/gcc/x86_64-redhat-linux/4.8.5/../../../../lib64/crtn.o] ==> ignore
|
||||
remove lib [gcc]
|
||||
remove lib [gcc_s]
|
||||
remove lib [gcc]
|
||||
remove lib [gcc_s]
|
||||
collapse library dir [/usr/lib/gcc/x86_64-redhat-linux/4.8.5] ==> [/usr/lib/gcc/x86_64-redhat-linux/4.8.5]
|
||||
collapse library dir [/usr/lib/gcc/x86_64-redhat-linux/4.8.5/../../../../lib64] ==> [/usr/lib64]
|
||||
collapse library dir [/lib/../lib64] ==> [/lib64]
|
||||
collapse library dir [/usr/lib/../lib64] ==> [/usr/lib64]
|
||||
collapse library dir [/usr/lib/gcc/x86_64-redhat-linux/4.8.5/../../..] ==> [/usr/lib]
|
||||
implicit libs: [c]
|
||||
implicit dirs: [/usr/lib/gcc/x86_64-redhat-linux/4.8.5;/usr/lib64;/lib64;/usr/lib]
|
||||
implicit fwks: []
|
||||
|
||||
|
||||
Determining if the CXX compiler works passed with the following output:
|
||||
Change Dir: /home/sy/openairinterface5g/openair1/SIMULATION/NR_UE_PHY/unit_tests/build/CMakeFiles/CMakeTmp
|
||||
|
||||
Run Build Command:/usr/bin/gmake "cmTryCompileExec3828041398/fast"
|
||||
/usr/bin/gmake -f CMakeFiles/cmTryCompileExec3828041398.dir/build.make CMakeFiles/cmTryCompileExec3828041398.dir/build
|
||||
gmake[1]: Entering directory `/home/sy/openairinterface5g/openair1/SIMULATION/NR_UE_PHY/unit_tests/build/CMakeFiles/CMakeTmp'
|
||||
/usr/bin/cmake -E cmake_progress_report /home/sy/openairinterface5g/openair1/SIMULATION/NR_UE_PHY/unit_tests/build/CMakeFiles/CMakeTmp/CMakeFiles 1
|
||||
Building CXX object CMakeFiles/cmTryCompileExec3828041398.dir/testCXXCompiler.cxx.o
|
||||
/usr/bin/c++ -o CMakeFiles/cmTryCompileExec3828041398.dir/testCXXCompiler.cxx.o -c /home/sy/openairinterface5g/openair1/SIMULATION/NR_UE_PHY/unit_tests/build/CMakeFiles/CMakeTmp/testCXXCompiler.cxx
|
||||
Linking CXX executable cmTryCompileExec3828041398
|
||||
/usr/bin/cmake -E cmake_link_script CMakeFiles/cmTryCompileExec3828041398.dir/link.txt --verbose=1
|
||||
/usr/bin/c++ CMakeFiles/cmTryCompileExec3828041398.dir/testCXXCompiler.cxx.o -o cmTryCompileExec3828041398 -rdynamic
|
||||
gmake[1]: Leaving directory `/home/sy/openairinterface5g/openair1/SIMULATION/NR_UE_PHY/unit_tests/build/CMakeFiles/CMakeTmp'
|
||||
|
||||
|
||||
Detecting CXX compiler ABI info compiled with the following output:
|
||||
Change Dir: /home/sy/openairinterface5g/openair1/SIMULATION/NR_UE_PHY/unit_tests/build/CMakeFiles/CMakeTmp
|
||||
|
||||
Run Build Command:/usr/bin/gmake "cmTryCompileExec1700914889/fast"
|
||||
/usr/bin/gmake -f CMakeFiles/cmTryCompileExec1700914889.dir/build.make CMakeFiles/cmTryCompileExec1700914889.dir/build
|
||||
gmake[1]: Entering directory `/home/sy/openairinterface5g/openair1/SIMULATION/NR_UE_PHY/unit_tests/build/CMakeFiles/CMakeTmp'
|
||||
/usr/bin/cmake -E cmake_progress_report /home/sy/openairinterface5g/openair1/SIMULATION/NR_UE_PHY/unit_tests/build/CMakeFiles/CMakeTmp/CMakeFiles 1
|
||||
Building CXX object CMakeFiles/cmTryCompileExec1700914889.dir/CMakeCXXCompilerABI.cpp.o
|
||||
/usr/bin/c++ -o CMakeFiles/cmTryCompileExec1700914889.dir/CMakeCXXCompilerABI.cpp.o -c /usr/share/cmake/Modules/CMakeCXXCompilerABI.cpp
|
||||
Linking CXX executable cmTryCompileExec1700914889
|
||||
/usr/bin/cmake -E cmake_link_script CMakeFiles/cmTryCompileExec1700914889.dir/link.txt --verbose=1
|
||||
/usr/bin/c++ -v CMakeFiles/cmTryCompileExec1700914889.dir/CMakeCXXCompilerABI.cpp.o -o cmTryCompileExec1700914889 -rdynamic
|
||||
Using built-in specs.
|
||||
COLLECT_GCC=/usr/bin/c++
|
||||
COLLECT_LTO_WRAPPER=/usr/libexec/gcc/x86_64-redhat-linux/4.8.5/lto-wrapper
|
||||
Target: x86_64-redhat-linux
|
||||
Configured with: ../configure --prefix=/usr --mandir=/usr/share/man --infodir=/usr/share/info --with-bugurl=http://bugzilla.redhat.com/bugzilla --enable-bootstrap --enable-shared --enable-threads=posix --enable-checking=release --with-system-zlib --enable-__cxa_atexit --disable-libunwind-exceptions --enable-gnu-unique-object --enable-linker-build-id --with-linker-hash-style=gnu --enable-languages=c,c++,objc,obj-c++,java,fortran,ada,go,lto --enable-plugin --enable-initfini-array --disable-libgcj --with-isl=/builddir/build/BUILD/gcc-4.8.5-20150702/obj-x86_64-redhat-linux/isl-install --with-cloog=/builddir/build/BUILD/gcc-4.8.5-20150702/obj-x86_64-redhat-linux/cloog-install --enable-gnu-indirect-function --with-tune=generic --with-arch_32=x86-64 --build=x86_64-redhat-linux
|
||||
Thread model: posix
|
||||
gcc version 4.8.5 20150623 (Red Hat 4.8.5-39) (GCC)
|
||||
COMPILER_PATH=/usr/libexec/gcc/x86_64-redhat-linux/4.8.5/:/usr/libexec/gcc/x86_64-redhat-linux/4.8.5/:/usr/libexec/gcc/x86_64-redhat-linux/:/usr/lib/gcc/x86_64-redhat-linux/4.8.5/:/usr/lib/gcc/x86_64-redhat-linux/
|
||||
LIBRARY_PATH=/usr/lib/gcc/x86_64-redhat-linux/4.8.5/:/usr/lib/gcc/x86_64-redhat-linux/4.8.5/../../../../lib64/:/lib/../lib64/:/usr/lib/../lib64/:/usr/lib/gcc/x86_64-redhat-linux/4.8.5/../../../:/lib/:/usr/lib/
|
||||
COLLECT_GCC_OPTIONS='-v' '-o' 'cmTryCompileExec1700914889' '-rdynamic' '-shared-libgcc' '-mtune=generic' '-march=x86-64'
|
||||
/usr/libexec/gcc/x86_64-redhat-linux/4.8.5/collect2 --build-id --no-add-needed --eh-frame-hdr --hash-style=gnu -m elf_x86_64 -export-dynamic -dynamic-linker /lib64/ld-linux-x86-64.so.2 -o cmTryCompileExec1700914889 /usr/lib/gcc/x86_64-redhat-linux/4.8.5/../../../../lib64/crt1.o /usr/lib/gcc/x86_64-redhat-linux/4.8.5/../../../../lib64/crti.o /usr/lib/gcc/x86_64-redhat-linux/4.8.5/crtbegin.o -L/usr/lib/gcc/x86_64-redhat-linux/4.8.5 -L/usr/lib/gcc/x86_64-redhat-linux/4.8.5/../../../../lib64 -L/lib/../lib64 -L/usr/lib/../lib64 -L/usr/lib/gcc/x86_64-redhat-linux/4.8.5/../../.. CMakeFiles/cmTryCompileExec1700914889.dir/CMakeCXXCompilerABI.cpp.o -lstdc++ -lm -lgcc_s -lgcc -lc -lgcc_s -lgcc /usr/lib/gcc/x86_64-redhat-linux/4.8.5/crtend.o /usr/lib/gcc/x86_64-redhat-linux/4.8.5/../../../../lib64/crtn.o
|
||||
gmake[1]: Leaving directory `/home/sy/openairinterface5g/openair1/SIMULATION/NR_UE_PHY/unit_tests/build/CMakeFiles/CMakeTmp'
|
||||
|
||||
|
||||
Parsed CXX implicit link information from above output:
|
||||
link line regex: [^( *|.*[/\])(ld|([^/\]+-)?ld|collect2)[^/\]*( |$)]
|
||||
ignore line: [Change Dir: /home/sy/openairinterface5g/openair1/SIMULATION/NR_UE_PHY/unit_tests/build/CMakeFiles/CMakeTmp]
|
||||
ignore line: []
|
||||
ignore line: [Run Build Command:/usr/bin/gmake "cmTryCompileExec1700914889/fast"]
|
||||
ignore line: [/usr/bin/gmake -f CMakeFiles/cmTryCompileExec1700914889.dir/build.make CMakeFiles/cmTryCompileExec1700914889.dir/build]
|
||||
ignore line: [gmake[1]: Entering directory `/home/sy/openairinterface5g/openair1/SIMULATION/NR_UE_PHY/unit_tests/build/CMakeFiles/CMakeTmp']
|
||||
ignore line: [/usr/bin/cmake -E cmake_progress_report /home/sy/openairinterface5g/openair1/SIMULATION/NR_UE_PHY/unit_tests/build/CMakeFiles/CMakeTmp/CMakeFiles 1]
|
||||
ignore line: [Building CXX object CMakeFiles/cmTryCompileExec1700914889.dir/CMakeCXXCompilerABI.cpp.o]
|
||||
ignore line: [/usr/bin/c++ -o CMakeFiles/cmTryCompileExec1700914889.dir/CMakeCXXCompilerABI.cpp.o -c /usr/share/cmake/Modules/CMakeCXXCompilerABI.cpp]
|
||||
ignore line: [Linking CXX executable cmTryCompileExec1700914889]
|
||||
ignore line: [/usr/bin/cmake -E cmake_link_script CMakeFiles/cmTryCompileExec1700914889.dir/link.txt --verbose=1]
|
||||
ignore line: [/usr/bin/c++ -v CMakeFiles/cmTryCompileExec1700914889.dir/CMakeCXXCompilerABI.cpp.o -o cmTryCompileExec1700914889 -rdynamic ]
|
||||
ignore line: [Using built-in specs.]
|
||||
ignore line: [COLLECT_GCC=/usr/bin/c++]
|
||||
ignore line: [COLLECT_LTO_WRAPPER=/usr/libexec/gcc/x86_64-redhat-linux/4.8.5/lto-wrapper]
|
||||
ignore line: [Target: x86_64-redhat-linux]
|
||||
ignore line: [Configured with: ../configure --prefix=/usr --mandir=/usr/share/man --infodir=/usr/share/info --with-bugurl=http://bugzilla.redhat.com/bugzilla --enable-bootstrap --enable-shared --enable-threads=posix --enable-checking=release --with-system-zlib --enable-__cxa_atexit --disable-libunwind-exceptions --enable-gnu-unique-object --enable-linker-build-id --with-linker-hash-style=gnu --enable-languages=c,c++,objc,obj-c++,java,fortran,ada,go,lto --enable-plugin --enable-initfini-array --disable-libgcj --with-isl=/builddir/build/BUILD/gcc-4.8.5-20150702/obj-x86_64-redhat-linux/isl-install --with-cloog=/builddir/build/BUILD/gcc-4.8.5-20150702/obj-x86_64-redhat-linux/cloog-install --enable-gnu-indirect-function --with-tune=generic --with-arch_32=x86-64 --build=x86_64-redhat-linux]
|
||||
ignore line: [Thread model: posix]
|
||||
ignore line: [gcc version 4.8.5 20150623 (Red Hat 4.8.5-39) (GCC) ]
|
||||
ignore line: [COMPILER_PATH=/usr/libexec/gcc/x86_64-redhat-linux/4.8.5/:/usr/libexec/gcc/x86_64-redhat-linux/4.8.5/:/usr/libexec/gcc/x86_64-redhat-linux/:/usr/lib/gcc/x86_64-redhat-linux/4.8.5/:/usr/lib/gcc/x86_64-redhat-linux/]
|
||||
ignore line: [LIBRARY_PATH=/usr/lib/gcc/x86_64-redhat-linux/4.8.5/:/usr/lib/gcc/x86_64-redhat-linux/4.8.5/../../../../lib64/:/lib/../lib64/:/usr/lib/../lib64/:/usr/lib/gcc/x86_64-redhat-linux/4.8.5/../../../:/lib/:/usr/lib/]
|
||||
ignore line: [COLLECT_GCC_OPTIONS='-v' '-o' 'cmTryCompileExec1700914889' '-rdynamic' '-shared-libgcc' '-mtune=generic' '-march=x86-64']
|
||||
link line: [ /usr/libexec/gcc/x86_64-redhat-linux/4.8.5/collect2 --build-id --no-add-needed --eh-frame-hdr --hash-style=gnu -m elf_x86_64 -export-dynamic -dynamic-linker /lib64/ld-linux-x86-64.so.2 -o cmTryCompileExec1700914889 /usr/lib/gcc/x86_64-redhat-linux/4.8.5/../../../../lib64/crt1.o /usr/lib/gcc/x86_64-redhat-linux/4.8.5/../../../../lib64/crti.o /usr/lib/gcc/x86_64-redhat-linux/4.8.5/crtbegin.o -L/usr/lib/gcc/x86_64-redhat-linux/4.8.5 -L/usr/lib/gcc/x86_64-redhat-linux/4.8.5/../../../../lib64 -L/lib/../lib64 -L/usr/lib/../lib64 -L/usr/lib/gcc/x86_64-redhat-linux/4.8.5/../../.. CMakeFiles/cmTryCompileExec1700914889.dir/CMakeCXXCompilerABI.cpp.o -lstdc++ -lm -lgcc_s -lgcc -lc -lgcc_s -lgcc /usr/lib/gcc/x86_64-redhat-linux/4.8.5/crtend.o /usr/lib/gcc/x86_64-redhat-linux/4.8.5/../../../../lib64/crtn.o]
|
||||
arg [/usr/libexec/gcc/x86_64-redhat-linux/4.8.5/collect2] ==> ignore
|
||||
arg [--build-id] ==> ignore
|
||||
arg [--no-add-needed] ==> ignore
|
||||
arg [--eh-frame-hdr] ==> ignore
|
||||
arg [--hash-style=gnu] ==> ignore
|
||||
arg [-m] ==> ignore
|
||||
arg [elf_x86_64] ==> ignore
|
||||
arg [-export-dynamic] ==> ignore
|
||||
arg [-dynamic-linker] ==> ignore
|
||||
arg [/lib64/ld-linux-x86-64.so.2] ==> ignore
|
||||
arg [-o] ==> ignore
|
||||
arg [cmTryCompileExec1700914889] ==> ignore
|
||||
arg [/usr/lib/gcc/x86_64-redhat-linux/4.8.5/../../../../lib64/crt1.o] ==> ignore
|
||||
arg [/usr/lib/gcc/x86_64-redhat-linux/4.8.5/../../../../lib64/crti.o] ==> ignore
|
||||
arg [/usr/lib/gcc/x86_64-redhat-linux/4.8.5/crtbegin.o] ==> ignore
|
||||
arg [-L/usr/lib/gcc/x86_64-redhat-linux/4.8.5] ==> dir [/usr/lib/gcc/x86_64-redhat-linux/4.8.5]
|
||||
arg [-L/usr/lib/gcc/x86_64-redhat-linux/4.8.5/../../../../lib64] ==> dir [/usr/lib/gcc/x86_64-redhat-linux/4.8.5/../../../../lib64]
|
||||
arg [-L/lib/../lib64] ==> dir [/lib/../lib64]
|
||||
arg [-L/usr/lib/../lib64] ==> dir [/usr/lib/../lib64]
|
||||
arg [-L/usr/lib/gcc/x86_64-redhat-linux/4.8.5/../../..] ==> dir [/usr/lib/gcc/x86_64-redhat-linux/4.8.5/../../..]
|
||||
arg [CMakeFiles/cmTryCompileExec1700914889.dir/CMakeCXXCompilerABI.cpp.o] ==> ignore
|
||||
arg [-lstdc++] ==> lib [stdc++]
|
||||
arg [-lm] ==> lib [m]
|
||||
arg [-lgcc_s] ==> lib [gcc_s]
|
||||
arg [-lgcc] ==> lib [gcc]
|
||||
arg [-lc] ==> lib [c]
|
||||
arg [-lgcc_s] ==> lib [gcc_s]
|
||||
arg [-lgcc] ==> lib [gcc]
|
||||
arg [/usr/lib/gcc/x86_64-redhat-linux/4.8.5/crtend.o] ==> ignore
|
||||
arg [/usr/lib/gcc/x86_64-redhat-linux/4.8.5/../../../../lib64/crtn.o] ==> ignore
|
||||
remove lib [gcc_s]
|
||||
remove lib [gcc]
|
||||
remove lib [gcc_s]
|
||||
remove lib [gcc]
|
||||
collapse library dir [/usr/lib/gcc/x86_64-redhat-linux/4.8.5] ==> [/usr/lib/gcc/x86_64-redhat-linux/4.8.5]
|
||||
collapse library dir [/usr/lib/gcc/x86_64-redhat-linux/4.8.5/../../../../lib64] ==> [/usr/lib64]
|
||||
collapse library dir [/lib/../lib64] ==> [/lib64]
|
||||
collapse library dir [/usr/lib/../lib64] ==> [/usr/lib64]
|
||||
collapse library dir [/usr/lib/gcc/x86_64-redhat-linux/4.8.5/../../..] ==> [/usr/lib]
|
||||
implicit libs: [stdc++;m;c]
|
||||
implicit dirs: [/usr/lib/gcc/x86_64-redhat-linux/4.8.5;/usr/lib64;/lib64;/usr/lib]
|
||||
implicit fwks: []
|
||||
|
||||
|
||||
@@ -0,0 +1 @@
|
||||
# This file is generated by cmake for dependency checking of the CMakeCache.txt file
|
||||
Reference in New Issue
Block a user