当前位置: 首页 > news >正文

phy_simulators之nr_pbchsim之PSS

phy_simulators之nr_pbchsim之PSS

Posted on 2026-03-12 08:06  普罗大众  阅读(0)  评论(0)    收藏  举报

nr_pbchsim

 

发端:

gNB_config->ssb_table.ssb_period.value = 1; //10ms

  mu: 0-> SCS15kHz, 1->SCS30kHz,默认30kHz

好像只装填了SSB的数据,共Lmax个可能的SSB,循环:

for (i=0; i<frame_parms->Lmax; i++) {

    if((SSB_positions >> i) & 0x01) //有SSB就加入

调用PHY_ofdm_mod:

装填第1个符号:

PHY_ofdm_mod((int *)gNB->common_vars.txdataF[0][aa],

                         (int*)&txdata[aa][samp],

                         frame_parms->ofdm_symbol_size,

                         1,

                         frame_parms->nb_prefix_samples0,

                         CYCLIC_PREFIX);

装填后面13个符号:

            PHY_ofdm_mod((int *)&gNB->common_vars.txdataF[0][aa][frame_parms->ofdm_symbol_size],

                         (int*)&txdata[aa][samp + frame_parms->nb_prefix_samples0 + frame_parms->ofdm_symbol_size],

                         frame_parms->ofdm_symbol_size,

                         13,

                         frame_parms->nb_prefix_samples,

                         CYCLIC_PREFIX);

输入跟gNB->common_vars有关

装填一次,接收就是不同snr的仿真

for (SNR = snr0; SNR < snr1 && !stop; SNR+=.2) {

    for (trial = 0; trial < n_trials && !stop; trial++) {

 

 

- I: 初始同步

调用:

nr_initial_sync_t nr_initial_sync(UE_nr_rxtx_proc_t *proc,

                                  PHY_VARS_NR_UE *ue,

                                  int n_frames,

                                  int sa,

                                  nr_gscn_info_t gscnInfo[MAX_GSCN_BAND],

                                  int numGscn)

逐个GSCN扫描:

for (int s = 0; s < numGscn; s++) {

    nr_ue_ssb_scan_t *ssbInfo = &ssb_info[s];

但因为是仿真,仅有一个GSCN

每次扫描,需要初始化ssbInfo结构,其会被装填上需要搜索的数据:

ssbInfo->rxdata[ant] = malloc16(sizeof(c16_t) * (fp->samples_per_frame * 2 + fp->ofdm_symbol_size));

其中,fp->samples_per_frame为614400=2048*300,fp->ofdm_symbol_size为2048

memcpy(ssbInfo->rxdata[ant], ue->common_vars.rxdata[ant], sizeof(c16_t) * fp->samples_per_frame * 2);

  ssbInfo->rxdata的前面数据来自ue->common_vars.rxdata,长度为sizeof(c16_t) * fp->samples_per_frame * 2

memset(ssbInfo->rxdata[ant] + fp->samples_per_frame * 2, 0, fp->ofdm_symbol_size * sizeof(c16_t));

  ssbInfo->rxdata后面数据设置为0,长度为fp->ofdm_symbol_size * sizeof(c16_t)

 

但是应该总共618496

 

=>单个GSCN的ssb搜索是用函数指针的方式来调用的:

task_t t = {.func = nr_scan_ssb, .args = ssbInfo}

其中:

typedef struct {

  void* args;

  void (*func)(void* args);

} task_t;

指向的函数是:

void nr_scan_ssb(void *arg)

{

  /*   Initial synchronisation

   *

   *                                 1 radio frame = 10 ms

   *     <--------------------------------------------------------------------------->

   *     -----------------------------------------------------------------------------

   *     |                                 Received UE data buffer                    |

   *     ----------------------------------------------------------------------------

   *                     --------------------------

   *     <-------------->| pss | pbch | sss | pbch |

   *                     --------------------------

   *          sync_pos            SS/PBCH block

   */

 

 

=> 调用nr_search_ssb_common

打印出来信息:

SSB extends beyond buffer boundary (sync_pos 614180, ssb_offset 614036, buffer_size 614400)

其中:

const int ssb_offset = sync_pos - fp->nb_prefix_samples;

可看出sync_pos - ssb_offset = 144,差了个CP,sync_pos是没有CP的ssb起点,而ssb_offset是带了CP的ssb起点?

sync_pos是变化的,例如614180

614400-614180=220

为什么找出来的sync_pos都是很大的值???612672是我看到的最小值了。。。

 

ssb_offset + NR_N_SYMBOLS_SSB * (fp->ofdm_symbol_size + fp->nb_prefix_samples) >= params->rxdata_size

NR_N_SYMBOLS_SSB * (fp->ofdm_symbol_size + fp->nb_prefix_samples) >= params->rxdata_size - ssb_offset

感觉是判断rxdata剩下的sample数量是否能包含4个符号的ssb的总的sample数量(8768),包括4个CP

但基本上不够。。。为什么只是1个10毫秒的sample呢?奇怪

来源于:

 

=> sync_pos的计算是调用pss_synchro_nr

const int sync_pos = pss_synchro_nr((const c16_t **)params->rxdata,

                                      fp,

                                      pssTime,

                                      params->search_frame_id,

                                      params->fo_flag,

                                      params->target_nid_cell,

                                      &nid2,

                                      &freq_offset_pss,

                                      &pss_peak,

                                      &pss_avg);

 

=> 调用pss_search_time_nr

长度:

if (is == 0)

      length = frame_parms->samples_per_frame + (2 * frame_parms->ofdm_symbol_size); //618496

    else

      length = frame_parms->samples_per_frame; //614400

相关:逐4点平移点乘,Search pss in the received buffer each 4 samples which ensures a memory alignment on 128 bits (32 bits x 4 ) 

for (n = start; n < start + length; n += 4) { //

……

        const c32_t result = dot_product(pssTime[pss_index],

                                         &(rxdata[ar][n + is * frame_parms->samples_per_frame]),

                                         frame_parms->ofdm_symbol_size,

                                         shift);

const c64_t r64 = {.r = result.r, .i = result.i};

        pss_corr_ue += squaredMod(r64); //相关值的能量

 

=> 调用dot_product

但是这个限制会导致“点乘”并没有真正执行:

#if defined(__x86_64__) || defined(__i386__)

  if (__builtin_cpu_supports("avx2")) {

 

 

一个奇怪的问题,随意的写printf,居然会导致Segmentation fault      (core dumped)的错误(程序崩掉),哎,c好脆弱的