5G NR PSS信号生成

5G NR PSS信号生成

  • IQ调制
  • OFDM过程
  • 5G协议
  • 代码解析

PSS的生成会用到几个概念,先介绍如下。

IQ调制

一个简化的发送端基带信号处理流程大概是下面这样的。
5G NR PSS信号生成_第1张图片
(在IFFT前后应该分别有串并转换和并串转换操作)
这里的Modulation部分一般就都是通过IQ调制完成的。
IQ调制是一种调制方式,通过这种方式可以实现PSK,QAM等各种调制方式。在通信系统中,对于需要发送的数据,首先需要按照对应的调制方式将输入数据分解到IQ分支上。
比如,如果使用的是16QAM,它的星座图是这样的:
5G NR PSS信号生成_第2张图片
那么输入数据就会4个一组,按照星座图的方式分别映射到I轴和Q轴。因为IQ默认是90度关系,所以只要知道I轴和Q轴的值就能够复原表示原来4位数据的向量,也就能知道原来的4位原始数据。原始数据与IQ值的对应关系如下:
5G NR PSS信号生成_第3张图片
把生成的IQ信号表示成复数的形式:I+jQ,然后再取N个复数做IFFT,对IFFT的结果取实部就得到一个OFDM符号在时域的采样点。其中N是当前带宽可用的子载波数。

OFDM过程

可以这么理解,对于单个子载波,IQ调制的过程是这样的:
5G NR PSS信号生成_第4张图片
其中a,b就是单个子载波对应的IQ信号。
而对于OFDM符号,它在时域上是多个频率信号的叠加,它的公式如下:
x ( t ) = ∑ k = − N / 2 N / 2 − 1 X [ k ] e j 2 π k t / N x(t)=\sum_{k=-N/2}^{N/2-1}X[k]e^{j2\pi kt/N} x(t)=k=N/2N/21X[k]ej2πkt/N
其中X[k]就相当于上面单载波中的IQ信号a+jb.

设IFFT的size为M,那么IFFT输出的M个时域离散值就是一个完整的OFDM符号时域所有的采样点。利用这些采样点就可以生成时域的OFDM基带信号。
在实际的通信系统中,IFFT的大小都是2的n次方,而子载波数却不一定是。因此通常M>N,那么在做IFFT的时候,是通过在N个IQ复数的基础上补零来完成M的IFFT。(待求证)
对于补零后的频域数据,在做IFFT之前通常会做循环移位,从而把零频分量移动到IFFT输入的中间。

5G协议

在38.211中,PSS序列被定义为一个m序列。m序列是一类特殊的LFSR序列。它的生成结构如下:
5G NR PSS信号生成_第5张图片
对应的生成公式是这样的:
5G NR PSS信号生成_第6张图片
然后是PSS所占用的时频资源的位置:
5G NR PSS信号生成_第7张图片
以上这些都是生成PSS所需要的参数。

代码解析

下面我们来看OAI中生成PSS的代码。
首先是函数定义及用到的变量的定义:


/*******************************************************************
*
* NAME :         generate_pss_nr
*
* PARAMETERS :   N_ID_2 : element 2 of physical layer cell identity
*                value : { 0, 1, 2}
*
* RETURN :       generate binary pss sequence (this is a m-sequence)
*
* DESCRIPTION :  3GPP TS 38.211 7.4.2.2 Primary synchronisation signal
*                Sequence generation
*
*********************************************************************/

void generate_pss_nr(NR_DL_FRAME_PARMS *fp,int N_ID_2)
{
  AssertFatal(fp->ofdm_symbol_size > 127,"Illegal ofdm_symbol_size %d\n",fp->ofdm_symbol_size);
  AssertFatal(N_ID_2>=0 && N_ID_2 <=2,"Illegal N_ID_2 %d\n",N_ID_2);
  int16_t d_pss[LENGTH_PSS_NR];
  int16_t x[LENGTH_PSS_NR];
  int16_t *primary_synchro_time = primary_synchro_time_nr[N_ID_2];   //存储三个PSS序列的数组
  unsigned int length = fp->ofdm_symbol_size;   //即IFFT size
  unsigned int size = length * IQ_SIZE; /* i & q */
  int16_t *primary_synchro = primary_synchro_nr[N_ID_2]; /* pss in complex with alternatively i then q */
  int16_t *primary_synchro2 = primary_synchro_nr2[N_ID_2]; /* pss in complex with alternatively i then q */
  void (*idft)(int16_t *,int16_t *, int);

初始化m序列的初始状态:

  //38.211中,m序列的初始状态
  #define INITIAL_PSS_NR    (7)
  const int x_initial[INITIAL_PSS_NR] = {0, 1, 1 , 0, 1, 1, 1};

然后按照协议公式计算出PSS序列中的127个值:

  //按照38.211的公式计算127位序列
  for (int i=0; i < INITIAL_PSS_NR; i++) {
    x[i] = x_initial[i];
  }

  for (int i=0; i < (LENGTH_PSS_NR - INITIAL_PSS_NR); i++) {
    x[i+INITIAL_PSS_NR] = (x[i + 4] + x[i])%(2);
  }

  for (int n=0; n < LENGTH_PSS_NR; n++) {
	int m = (n + 43*N_ID_2)%(LENGTH_PSS_NR);
    d_pss[n] = 1 - 2*x[m];   //这里相当于对PSS序列进行来BPSK的调制,由0,1序列调制为-1, 1
  }

根据生成的原始PSS序列生成对应的IQ数据:

  /* PSS is directly mapped to subcarrier without modulation 38.211 */
  for (int i=0; i < LENGTH_PSS_NR; i++) {
#if 1
    primary_synchro[2*i] = (d_pss[i] * SHRT_MAX)>>SCALING_PSS_NR; /* Maximum value for type short int ie int16_t */
    primary_synchro[2*i+1] = 0;   //按照实部虚部(I值Q值)的顺序以此存储IQ调制的结果
    primary_synchro2[i] = d_pss[i];
#else
    primary_synchro[2*i] = d_pss[i] * AMP;
    primary_synchro[2*i+1] = 0;
    primary_synchro2[i] = d_pss[i];
#endif
  }

根据输入输出的周期性,将IFFT的输入数据进行循环移位,将零频分量移动到中间位置。这正是由于我们之前说的FFT size比实际输入数据大造成的。也就是说时域的OFDM一个符号的采样点数比实际可用子载波数要大。

  /* call of IDFT should be done with ordered input as below
  *
  *                n input samples
  *  <------------------------------------------------>
  *  0                                                n
  *  are written into input buffer for IFFT
  *   -------------------------------------------------
  *  |xxxxxxx                       N/2       xxxxxxxx|
  *  --------------------------------------------------
  *  ^      ^                 ^               ^          ^
  *  |      |                 |               |          |
  * n/2    end of            n=0            start of    n/2-1
  *         pss                               pss
  *
  *                   Frequencies
  *      positives                   negatives
  * 0                 (+N/2)(-N/2)
  * |-----------------------><-------------------------|
  *
  * sample 0 is for continuous frequency which is used here
  */
  //k就是上面图中start of pss的位置
  unsigned int  k = fp->first_carrier_offset + fp->ssb_start_subcarrier + 56; //and
  if (k>= fp->ofdm_symbol_size) k-=fp->ofdm_symbol_size;



  for (int i=0; i < LENGTH_PSS_NR; i++) {
    synchroF_tmp[2*k] = primary_synchro[2*i];
    synchroF_tmp[2*k+1] = primary_synchro[2*i+1];

    k++;

    if (k == length) k=0;
    
  }

最后通过IFFT生成时域序列,注意这里时域的序列也是按照实部虚部的顺序存储的。

  /* IFFT will give temporal signal of Pss */

  idft = get_idft(length);

  idft(synchroF_tmp,          /* complex input */
       synchro_tmp,           /* complex output */
       1);                 /* scaling factor */

  /* then get final pss in time */
  for (unsigned int i=0; i<length; i++) {
    ((int32_t *)primary_synchro_time)[i] = ((int32_t *)synchro_tmp)[i];
  }

参考资料:
关于IQ调制的详细内容可以参考:
https://www.mobibrw.com/2018/12118
关于通信系统的完整流程可以参考:
https://zhuanlan.zhihu.com/p/25868603
关于OFDM调制可以参考:
https://www.csie.ntu.edu.tw/~hsinmu/courses/_media/wn_11fall/ofdm_new.pdf
https://zhuanlan.zhihu.com/p/57967971
https://blog.csdn.net/zzsfqiuyigui/article/details/9091363
关于5G PSS定义可以参考:
http://www.techplayon.com/nr-primary-synchronization-signal-pss/
http://www.dpi-proceedings.com/index.php/dtcse/article/viewFile/26293/25707
http://www.rfwireless-world.com/5G/5G-NR-m-sequence.html

你可能感兴趣的:(5G)