Compare commits

..

6 Commits

Author SHA1 Message Date
NCTU_CS_ISIP Terngyin&NY&GK&KM
44daf9cf64 NCTU OpinConnect 2020-04-08 15:37:29 +08:00
NCTU_CS_ISIP Terngyin&Weiying&NY
20133c819f parallel architecture of 5G NR by NCTU_CS_ISIP Terngyin&Weiying&NY 2020-03-01 20:24:39 +08:00
ISIP
7ce5066f86 parallel architecture of 5G NR 2020-03-01 20:11:30 +08:00
isip
10dd25b2bf remove debug message 2020-02-13 14:56:58 +08:00
isip
187b7b056c pipeline scrambling and modulaiton 2020-02-12 23:15:56 +08:00
root
99c5e1d272 parallel scrambling and modulation 2020-02-12 22:31:23 +08:00
9 changed files with 448 additions and 847 deletions

View File

@@ -31,6 +31,16 @@
* \warning
*/
/*!\file vcd_signal_dumper.c
* \brief Add some VCD signals of multi_ldpc_encoder
* \author Terngyin, NY, GK, KM (ISIP)
* \email tyhsu@cs.nctu.edu.tw
* \date 07-04-2020
* \version 1.0
* \note
* \warning
*/
#include <pthread.h>
#include <stdio.h>
#include <stdlib.h>

View File

@@ -32,6 +32,16 @@
* \warning
*/
/*!\file vcd_signal_dumper.h
* \brief Add some VCD signals of multi_ldpc_encoder
* \author Terngyin, NY, GK, KM (ISIP)
* \email tyhsu@cs.nctu.edu.tw
* \date 07-04-2020
* \version 1.0
* \note
* \warning
*/
#ifndef VCD_SIGNAL_DUMPER_H_
#define VCD_SIGNAL_DUMPER_H_

View File

@@ -19,6 +19,16 @@
* contact@openairinterface.org
*/
/*!\file T_defs.h
* \brief Update VCD_NUM_FUNCTIONS and VCD_NUM_VARIABLES
* \author Terngyin, NY, GK, KM (ISIP)
* \email tyhsu@cs.nctu.edu.tw
* \date 07-04-2020
* \version 1.0
* \note
* \warning
*/
#ifndef _T_defs_H_
#define _T_defs_H_

View File

@@ -103,16 +103,6 @@ uint16_t NB_UE_INST = 1;
short lift_size[51]= {2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,18,20,22,24,26,28,30,32,36,40,44,48,52,56,60,64,72,80,88,96,104,112,120,128,144,160,176,192,208,224,240,256,288,320,352,384};
/*! \file openair1/PHY/CODING/TESTBENCH/ldpctest.c
* \brief NCTU OpInConnect
* \author Terngyin Hsu, Sendren Xu, Nungyi Kuo, Kuankai Hsiung, Kaimi Yang (OpInConnect_NCTU)
* \email tyhsu@cs.nctu.edu.tw
* \date 13-05-2020
* \version 2.0
* \note
* \warning
*/
// ==[START]multi_lpdc_encoder
struct timespec start_ts, end_ts, start_per_ts, end_per_ts, start_enc_ts[thread_num_max], end_enc_ts[thread_num_max], start_perenc_ts[thread_num_max], end_perenc_ts[thread_num_max];
multi_ldpc_encoder ldpc_enc[thread_num_max];

View File

@@ -29,6 +29,16 @@
* \warning
*/
/*!\file defs.h
* \brief Declarations of parameters of multi_ldpc_encoder
* \author Terngyin, NY, GK, KM (ISIP)
* \email tyhsu@cs.nctu.edu.tw
* \date 07-04-2020
* \version 1.0
* \note
* \warning
*/
#include "PHY/TOOLS/time_meas.h"
// ==[START]multi_ldpc_encoder

View File

@@ -29,7 +29,6 @@
* \note
* \warning
*/
//pipeline scrambling and modulation from Ian
#include "PHY/phy_extern.h"
#include "PHY/defs_gNB.h"
@@ -44,10 +43,10 @@
void nr_pdsch_codeword_scrambling(uint8_t *in,
uint32_t size,
uint8_t q, //use q
uint8_t q,
uint32_t Nid,
uint32_t n_RNTI,
uint32_t* out) { //use q => scrambled_output[q]
uint32_t* out) {
uint8_t reset, b_idx;
uint32_t x1, x2, s=0;
@@ -90,7 +89,7 @@ uint8_t nr_generate_pdsch(NR_gNB_DLSCH_t *dlsch,
NR_DL_gNB_HARQ_t *harq = dlsch->harq_processes[dci_alloc->harq_pid];
nfapi_nr_dl_config_dlsch_pdu_rel15_t *rel15 = &harq->dlsch_pdu.dlsch_pdu_rel15;
nfapi_nr_dl_config_pdcch_parameters_rel15_t pdcch_params = dci_alloc->pdcch_params;
uint32_t scrambled_output[NR_MAX_NB_CODEWORDS][NR_MAX_PDSCH_ENCODED_LENGTH>>5]; //NR_MAX_NB_CODEWORDS 2
uint32_t scrambled_output[NR_MAX_NB_CODEWORDS][NR_MAX_PDSCH_ENCODED_LENGTH>>5];
int16_t **mod_symbs = (int16_t**)dlsch->mod_symbs;
int16_t **tx_layers = (int16_t**)dlsch->txdataF;
int8_t Wf[2], Wt[2], l0, l_prime[2], delta;
@@ -109,11 +108,11 @@ uint8_t nr_generate_pdsch(NR_gNB_DLSCH_t *dlsch,
/// CRC, coding, interleaving and rate matching
AssertFatal(harq->pdu!=NULL,"harq->pdu is null\n");
start_meas(dlsch_encoding_stats);
nr_dlsch_encoding(harq->pdu, frame, slot, dlsch, frame_parms); //the way to encoder
nr_dlsch_encoding(harq->pdu, frame, slot, dlsch, frame_parms);
stop_meas(dlsch_encoding_stats);
//printf("rel15->nb_codewords : %d\n", rel15->nb_codewords);
#ifdef DEBUG_DLSCH // ==Show original payload & encoded payload ==***
#ifdef DEBUG_DLSCH
printf("PDSCH encoding:\nPayload:\n");
uint32_t encoded_length = nb_symbols*Qm;
for (int i=0; i<harq->B>>7; i++) {
for (int j=0; j<16; j++)
printf("0x%02x\t", harq->pdu[(i<<4)+j]);
@@ -128,8 +127,7 @@ for (int i=0; i<encoded_length>>3; i++) {
printf("\n");
#endif
long sum = 0;
#if 0
//#ifdef thread_for_scrambling_modulation //the way to scrambling & modulation
#ifdef thread_for_scrambling_modulation
// for(int j = 0;j<100;j++){
gNB->complete_scrambling_and_modulation = 0;
gNB->complete_modulation = 0;
@@ -152,7 +150,7 @@ printf("\n");
// }
// printf("averge time = %ld\n",sum/100);
#elseif 0//original
#else
/// scrambling
start_meas(dlsch_scrambling_stats);
//printf("nb_codewords = %d encoded_length = %d\n",rel15->nb_codewords,encoded_length);
@@ -197,132 +195,8 @@ for (int i=0; i<nb_symbols>>3; i++) {
printf("\n");
}
#endif
#endif
//[START]multi_genetate_pdsch_proc
struct timespec start_ts, end_ts;
for (int q=0; q<rel15->nb_codewords; q++) // ==Look out!NR_MAX_NB_CODEWORDS is 2!So we can't let q>2 until spec change
memset((void*)scrambled_output[q], 0, (encoded_length>>5)*sizeof(uint32_t));
uint16_t n_RNTI = (pdcch_params.search_space_type == NFAPI_NR_SEARCH_SPACE_TYPE_UE_SPECIFIC) ? ((pdcch_params.scrambling_id==0)?pdcch_params.rnti:0) : 0;
uint16_t Nid = (pdcch_params.search_space_type == NFAPI_NR_SEARCH_SPACE_TYPE_UE_SPECIFIC) ? pdcch_params.scrambling_id : config->sch_config.physical_cell_id.value;
printf("==================[Scr]==================\n");
printf(" [Movement] [No.] [Round] [Cost time] \n");
//Get value for dual thread
for (int q=0; q<thread_num_pdsch; q++){
gNB->multi_encoder[q].f = harq->f;
gNB->multi_encoder[q].encoded_length = encoded_length;
gNB->multi_encoder[q].Nid = Nid;
gNB->multi_encoder[q].n_RNTI = n_RNTI;
gNB->multi_encoder[q].scrambled_output = scrambled_output[q]; // ==Need to change ==***
gNB->multi_encoder[q].Qm = Qm;
gNB->multi_encoder[q].mod_symbs = mod_symbs[q]; // ==Need to change ==***
}
//Get value for pressure
for (int q=0; q<thread_num_pressure; q++){
//gNB->pressure_test[q].f = harq->f;
gNB->pressure_test[q].encoded_length = encoded_length;
gNB->pressure_test[q].Nid = Nid;
gNB->pressure_test[q].n_RNTI = n_RNTI;
//gNB->pressure_test[q].scrambled_output = scrambled_output[q]; // ==Need to change ==***
gNB->pressure_test[q].Qm = Qm;
//gNB->pressure_test[q].mod_symbs = mod_symbs[q]; // ==Need to change ==***
}
for(int th=0;th<thread_num_pressure;th++){
for (int q=0; q<NR_MAX_NB_CODEWORDS; q++){
gNB->pressure_test[th].mod_symbs_test[q] = (int32_t *)malloc16(NR_MAX_PDSCH_ENCODED_LENGTH*sizeof(int32_t));
}
for (int i=0; i<encoded_length>>3; i++) {
for (int j=0; j<8; j++)
gNB->pressure_test[th].f_test[(i<<3)+j] = harq->f[(i<<3)+j];
}
for (int q=0; q<rel15->nb_codewords; q++) // ==Look out!NR_MAX_NB_CODEWORDS is 2!So we can't let q>2 until spec change
memset((void*)gNB->pressure_test[th].scrambled_output_test[q], 0, (encoded_length>>5)*sizeof(uint32_t));
}
//Get value for multi pdsch
//scrambling
for (int th=0; th<thread_num_scrambling; th++){
if(th == 0){ // ==copy original memory space for check ==
gNB->multi_pdsch.f_first = harq->f;
gNB->multi_pdsch.scrambled_output_first = scrambled_output[0]; // ==Need to change ==***
}
for (int i=0; i<encoded_length>>3; i++) {
for (int j=0; j<8; j++)
gNB->multi_pdsch.f[th][(i<<3)+j] = harq->f[(i<<3)+j];
}
for (int q=0; q<rel15->nb_codewords; q++) // ==Look out!NR_MAX_NB_CODEWORDS is 2!So we can't let q>2 until spec change
memset((void*)gNB->multi_pdsch.scrambled_output_scr[th][q], 0, (encoded_length>>5)*sizeof(uint32_t));
gNB->multi_pdsch.encoded_length_scr[th] = encoded_length;
gNB->multi_pdsch.Nid[th] = Nid;
gNB->multi_pdsch.n_RNTI[th] = n_RNTI;
}
//modulation
for (int th=0; th<thread_num_modulation; th++){
if(th == 0){ // ==copy original memory space for check ==
gNB->multi_pdsch.mod_symbs_first = mod_symbs[0]; // ==Need to change ==***
}
for (int q=0; q<rel15->nb_codewords; q++) // ==Look out!NR_MAX_NB_CODEWORDS is 2!So we can't let q>2 until spec change
memset((void*)gNB->multi_pdsch.scrambled_output_mod[th][q], 0, (encoded_length>>5)*sizeof(uint32_t));
for (int q=0; q<NR_MAX_NB_CODEWORDS; q++){
gNB->multi_pdsch.mod_symbs[th][q] = (int32_t *)malloc16(NR_MAX_PDSCH_ENCODED_LENGTH*sizeof(int32_t));
}
gNB->multi_pdsch.encoded_length_mod[th] = encoded_length;
gNB->multi_pdsch.Qm[th] = Qm;
}
//Show value for pressure
// printf("\nEncoded payload:\n");
// for (int i=0; i<10; i++) {
// for (int j=0; j<3; j++)
// printf("%d", harq->f[(i<<3)+j]);
// printf("\t");
// }
// printf("\nEncoded payload:\n");
// for (int i=0; i<10; i++) {
// for (int j=0; j<3; j++)
// printf("%d", gNB->pressure_test[0].f_test[(i<<3)+j]);
// printf("\t");
// }
//Awake scrambling threads(or scr_mod threads)
VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_MULTI_ENC,1);
clock_gettime(CLOCK_MONOTONIC, &start_ts); //timing
for (int q=0; q<thread_num_pdsch; q++){
pthread_cond_signal(&(gNB->multi_encoder[q].cond_scr_mod));
}
for (int q=0; q<thread_num_pressure; q++){
pthread_cond_signal(&(gNB->pressure_test[q].cond_scr_mod));
}
for (int th=0; th<thread_num_scrambling; th++){
pthread_cond_signal(&(gNB->multi_pdsch.cond_scr[th]));
}
//Wait scrambling threads(or scr_mod threads)
for (int q=0; q<thread_num_pdsch; q++){
while(gNB->multi_encoder[q].complete_scr_mod!=1);
}
for (int q=0; q<thread_num_pressure; q++){
while(gNB->pressure_test[q].complete_scr_mod!=1);
}
for (int th=0; th<thread_num_scrambling; th++){
while(gNB->multi_pdsch.complete_scr[th]!=1);
}
clock_gettime(CLOCK_MONOTONIC, &end_ts); //timing
printf(" Total %.2f usec\n", (end_ts.tv_nsec - start_ts.tv_nsec) *1.0 / 1000);
printf("==================[Mod]==================\n");
printf(" [Movement] [No.] [Round] [Cost time] \n");
clock_gettime(CLOCK_MONOTONIC, &start_ts); //timing
//Awake modulation threads
for (int th=0; th<thread_num_modulation; th++){
pthread_cond_signal(&(gNB->multi_pdsch.cond_mod[th]));
}
//Wait modulation threads
for (int th=0; th<thread_num_modulation; th++){
while(gNB->multi_pdsch.complete_mod[th]!=1);
}
clock_gettime(CLOCK_MONOTONIC, &end_ts); //timing
VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_MULTI_ENC,0);
//printf(" Movement No. Round Cost time \n");
printf(" Total %.2f usec\n", (end_ts.tv_nsec - start_ts.tv_nsec) *1.0 / 1000);
//[END]multi_genetate_pdsch_proc
/// Layer mapping
nr_layer_mapping(mod_symbs,
rel15->nb_layers,

View File

@@ -44,9 +44,6 @@
#include "common/utils/LOG/vcd_signal_dumper.h"
#include "common/utils/LOG/log.h"
#include <syscall.h>
#include <time.h>
//multi_ldpc_encoder ldpc_enc[thread_num_max]; //things in ldpc_encoder
//#define DEBUG_DLSCH_CODING
//#define DEBUG_DLSCH_FREE 1
@@ -276,30 +273,22 @@ void clean_gNB_dlsch(NR_gNB_DLSCH_t *dlsch)
}
}
int nr_dlsch_encoding(unsigned char *a, //harq->pdu => dlsch->harq_processes[harq_pid]->b
int nr_dlsch_encoding(unsigned char *a,
int frame,
uint8_t slot,
NR_gNB_DLSCH_t *dlsch,
NR_DL_FRAME_PARMS* frame_parms)
{
/*
PHY_VARS_gNB *gNB = RC.gNB[0][0];
gNB->complete_encode[0] = 0;
gNB->complete_encode[1] = 0;
gNB->complete_encode[2] = 0;
gNB->complete_encode[3] = 0;
clock_gettime(CLOCK_MONOTONIC, &start_ts);//timing
for (int t = 0; t < 4; t++){
pthread_cond_signal(&gNB->thread_encode[t].cond_encode);
}
while((gNB->complete_encode[0] != 1) || (gNB->complete_encode[1] != 1) || (gNB->complete_encode[2] != 1) || (gNB->complete_encode[3] != 1));
clock_gettime(CLOCK_MONOTONIC, &end_ts);//timing
printf("%.2f usec\n", (end_ts.tv_nsec - start_ts.tv_nsec) *1.0 / 1000);
*/
PHY_VARS_gNB *gNB = RC.gNB[0][0]; // ==check it! ==***
struct timespec start_ts, end_ts;
/*
unsigned int G;
unsigned int crc=1;
uint8_t harq_pid = dlsch->harq_ids[frame&2][slot];
@@ -322,14 +311,14 @@ int nr_dlsch_encoding(unsigned char *a, //harq->pdu => dlsch->harq_processes[har
uint16_t length_dmrs = 1;
float Coderate = 0.0;
uint8_t Nl = 4;
*/
/*
uint8_t *channel_input[MAX_NUM_DLSCH_SEGMENTS]; //unsigned char
for(j=0;j<MAX_NUM_DLSCH_SEGMENTS;j++) {
channel_input[j] = (unsigned char *)malloc16(sizeof(unsigned char) * 68*384);
}
*/
/*
VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_ENB_DLSCH_ENCODING, VCD_FUNCTION_IN);
A = rel15.transport_block_size;
@@ -343,7 +332,7 @@ int nr_dlsch_encoding(unsigned char *a, //harq->pdu => dlsch->harq_processes[har
#ifdef DEBUG_DLSCH_CODING
printf("encoding thinks this is a new packet \n");
#endif
*/
/*
int i;
printf("dlsch (tx): \n");
@@ -351,7 +340,7 @@ int nr_dlsch_encoding(unsigned char *a, //harq->pdu => dlsch->harq_processes[har
printf("%02x.",a[i]);
printf("\n");
*/
/*
if (A > 3824) {
// Add 24-bit crc (polynomial A) to payload
crc = crc24a(a,A)>>8;
@@ -429,110 +418,9 @@ int nr_dlsch_encoding(unsigned char *a, //harq->pdu => dlsch->harq_processes[har
//ldpc_encoder_optim((unsigned char*)dlsch->harq_processes[harq_pid]->c[r],(unsigned char*)&dlsch->harq_processes[harq_pid]->d[r][0],*Zc,Kb,Kr,BG,NULL,NULL,NULL,NULL);
}
//[START]Get value & Awake threads & Wait threads finish
// clock_gettime(CLOCK_MONOTONIC, &start_ts); //timing
// for(int i=0;i<2;i++)
// for(int j=0;j<(dlsch->harq_processes[harq_pid]->C/8+1);j++) {
// ldpc_encoder_optim_8seg_multi(dlsch->harq_processes[harq_pid]->c,dlsch->harq_processes[harq_pid]->d,*Zc,Kb,Kr,BG,dlsch->harq_processes[harq_pid]->C,j,NULL,NULL,NULL,NULL);
// }
// clock_gettime(CLOCK_MONOTONIC, &end_ts); //timing
// //printf(" Movement No. Round Cost time \n");
// printf(" Total Single %.2f usec\n", (end_ts.tv_nsec - start_ts.tv_nsec) *1.0 / 1000);
/*get value*/
for(int th=0;th<thread_num_pdsch;th++){
gNB->multi_encoder[th].test_input = dlsch->harq_processes[harq_pid]->c;
gNB->multi_encoder[th].channel_input_optim = dlsch->harq_processes[harq_pid]->d;
gNB->multi_encoder[th].Zc = *Zc;
gNB->multi_encoder[th].Kb = Kb;
gNB->multi_encoder[th].block_length = Kr;
gNB->multi_encoder[th].BG = BG;
gNB->multi_encoder[th].n_segments = dlsch->harq_processes[harq_pid]->C;
for(int j=0;j<(dlsch->harq_processes[harq_pid]->C/8+1);j++) {
ldpc_encoder_optim_8seg_multi(dlsch->harq_processes[harq_pid]->c,dlsch->harq_processes[harq_pid]->d,*Zc,Kb,Kr,BG,dlsch->harq_processes[harq_pid]->C,j,NULL,NULL,NULL,NULL);
}
/*cpy original data to pressure data*/
unsigned char bw_scaling =2; // ==Need to change ==***
// for(int r=0;r<MAX_NUM_NR_DLSCH_SEGMENTS/bw_scaling;r++){
// dlsch->harq_processes[i]->c[r] = (uint8_t*)malloc16(8448);
// dlsch->harq_processes[i]->d[r] = (uint8_t*)malloc16(68*384); //max size for coded output
// }
for(int th=0;th<thread_num_pressure;th++){
for(int j=0;j<MAX_NUM_NR_DLSCH_SEGMENTS/bw_scaling;j++){ // ==Why can not just be MAX_NUM_NR_DLSCH_SEGMENTS ==???
gNB->pressure_test[th].c_test[j]=(uint8_t*)malloc16(8448);//(unsigned char *)malloc16(sizeof(unsigned char) * Kr/8);
gNB->pressure_test[th].d_test[j]=(uint8_t*)malloc16(68*384);//(unsigned char *)malloc16(sizeof(unsigned char) * 68*384);
memcpy(gNB->pressure_test[th].c_test[j], dlsch->harq_processes[harq_pid]->c[j], 8448); // ==Check 8448 ==***
}
}
for(int th=0;th<thread_num_pressure;th++){
//gNB->pressure_test[th].test_input = dlsch->harq_processes[harq_pid]->c;
//gNB->pressure_test[th].channel_input_optim = dlsch->harq_processes[harq_pid]->d;
gNB->pressure_test[th].Zc = *Zc;
gNB->pressure_test[th].Kb = Kb;
gNB->pressure_test[th].block_length = Kr;
gNB->pressure_test[th].BG = BG;
gNB->pressure_test[th].n_segments = dlsch->harq_processes[harq_pid]->C;
}
/*cpy original data to multi pdsch*/
for(int th=0;th<thread_num_ldpc_encoder;th++){
if(th == 0){ // ==copy original memory space for check ==
gNB->multi_pdsch.test_input_first = dlsch->harq_processes[harq_pid]->c;
gNB->multi_pdsch.channel_input_optim_first = dlsch->harq_processes[harq_pid]->d;
}
for(int j=0;j<MAX_NUM_NR_DLSCH_SEGMENTS/bw_scaling;j++){ // ==Why can not just be MAX_NUM_NR_DLSCH_SEGMENTS ==???
gNB->multi_pdsch.c[th][j]=(uint8_t*)malloc16(8448);//(unsigned char *)malloc16(sizeof(unsigned char) * Kr/8);
gNB->multi_pdsch.d[th][j]=(uint8_t*)malloc16(68*384);//(unsigned char *)malloc16(sizeof(unsigned char) * 68*384);
memcpy(gNB->multi_pdsch.c[th][j], dlsch->harq_processes[harq_pid]->c[j], 8448); // ==Check 8448 ==***
}
gNB->multi_pdsch.Zc[th] = *Zc;
gNB->multi_pdsch.Kb[th] = Kb;
gNB->multi_pdsch.block_length[th] = Kr;
gNB->multi_pdsch.BG[th] = BG;
gNB->multi_pdsch.n_segments[th] = dlsch->harq_processes[harq_pid]->C;
}
/*Show c_test*/
// printf("c_test :\n");
// for (int i=0; i<3; i++){
// printf("%d", dlsch->harq_processes[harq_pid]->c[0][i]);
// printf("/%d\n", gNB->multi_encoder[0].c_test[0][i]);
// }
// printf("c_test ptr :\n");
// for (int i=0; i<3; i++){
// printf("%p", &dlsch->harq_processes[harq_pid]->c[0][i]);
// printf("/%p\n", &gNB->multi_encoder[0].c_test[0][i]);
// }
//Awake threads & Wait threads finish
printf("================[Encoder]================\n");
printf(" [Movement] [No.] [Round] [Cost time] \n");
VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_MULTI_ENC,1);
clock_gettime(CLOCK_MONOTONIC, &start_ts); //timing
for(int th=0;th<thread_num_pdsch;th++){
pthread_cond_signal(&(gNB->multi_encoder[th].cond));
}
for(int th=0;th<thread_num_pressure;th++){
pthread_cond_signal(&(gNB->pressure_test[th].cond));
}
for(int th=0;th<thread_num_ldpc_encoder;th++){
pthread_cond_signal(&(gNB->multi_pdsch.cond_enc[th]));
}
for(int th = 0;th<thread_num_pdsch;th++){
while(gNB->multi_encoder[th].complete!=1); // ==check if multi_ldpc_enc done ==
}
for(int th = 0;th<thread_num_pressure;th++){
while(gNB->pressure_test[th].complete!=1); // ==check if multi_ldpc_enc done ==
}
for(int th = 0;th<thread_num_ldpc_encoder;th++){
while(gNB->multi_pdsch.complete_enc[th]!=1); // ==check if multi_ldpc_enc done ==
}
clock_gettime(CLOCK_MONOTONIC, &end_ts); //timing
VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_MULTI_ENC,0);
//printf(" Movement No. Round Cost time \n");
printf(" Total %.2f usec\n", (end_ts.tv_nsec - start_ts.tv_nsec) *1.0 / 1000);
// for(int th = 0;th<thread_num_pdsch;th++){
// pthread_mutex_destroy(&gNB->multi_encoder[th].mutex);
// pthread_join(gNB->multi_encoder[th].pthread, NULL);
// }
//[END]Get value & Awake threads & Wait threads finish
#ifdef DEBUG_DLSCH_CODING
@@ -605,6 +493,6 @@ int nr_dlsch_encoding(unsigned char *a, //harq->pdu => dlsch->harq_processes[har
}
VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_ENB_DLSCH_ENCODING, VCD_FUNCTION_OUT);
*/
return 0;
}

View File

@@ -43,99 +43,7 @@
#include "PHY/CODING/nrLDPC_decoder/nrLDPC_decoder.h"
#include "PHY/CODING/nrLDPC_decoder/nrLDPC_types.h"
#include "common/utils/LOG/vcd_signal_dumper.h" //VCD
#define MAX_NUM_RU_PER_gNB MAX_NUM_RU_PER_eNB
#define thread_num_pdsch 0 // ==Change thread_num_pdsch here. Don't greater than 2 ==
#define thread_num_pressure 0 // ==Change thread_num_pressure here ==
#define thread_num_ldpc_encoder 2
#define thread_num_scrambling 3
#define thread_num_modulation 4
#define check_time 0 // ==Change if you wnat to check time of threads ==
typedef struct{
/*params of thread*/
int id;
volatile int flag_wait;
pthread_t pthread;
pthread_cond_t cond;
pthread_cond_t cond_scr_mod;
pthread_mutex_t mutex;
pthread_mutex_t mutex_scr_mod;
pthread_attr_t attr;
volatile uint8_t complete;
volatile uint8_t complete_scr_mod;
/*encoder*/
unsigned char **test_input;
unsigned char **channel_input_optim;
int Zc;
int Kb;
short block_length;
short BG;
int n_segments;
//unsigned int macro_num; //Not necessary to do
/*scrambling & modulation*/
uint8_t *f;
uint32_t *scrambled_output;
int16_t *mod_symbs;
uint32_t encoded_length;
uint16_t Nid;
uint16_t n_RNTI;
uint8_t Qm;
/*pressure test*/
uint8_t *c_test[MAX_NUM_NR_DLSCH_SEGMENTS];
uint8_t *d_test[MAX_NUM_NR_DLSCH_SEGMENTS];
uint8_t f_test[MAX_NUM_NR_CHANNEL_BITS] __attribute__((aligned(32)));
int32_t *mod_symbs_test[NR_MAX_NB_CODEWORDS];
uint32_t scrambled_output_test[NR_MAX_NB_CODEWORDS][NR_MAX_PDSCH_ENCODED_LENGTH>>5];
}multi_ldpc_encoder_gNB;
typedef struct{
/*params of thread*/
int id_enc[thread_num_ldpc_encoder];
int id_scr[thread_num_scrambling];
int id_mod[thread_num_modulation];
pthread_t pthread_enc[thread_num_ldpc_encoder];
pthread_t pthread_scr[thread_num_scrambling];
pthread_t pthread_mod[thread_num_modulation];
pthread_cond_t cond_enc[thread_num_ldpc_encoder];
pthread_cond_t cond_scr[thread_num_scrambling];
pthread_cond_t cond_mod[thread_num_modulation];
pthread_mutex_t mutex_enc[thread_num_ldpc_encoder];
pthread_mutex_t mutex_scr[thread_num_scrambling];
pthread_mutex_t mutex_mod[thread_num_modulation];
pthread_attr_t attr_enc[thread_num_ldpc_encoder];
pthread_attr_t attr_scr[thread_num_scrambling];
pthread_attr_t attr_mod[thread_num_modulation];
volatile uint8_t complete_enc[thread_num_ldpc_encoder];
volatile uint8_t complete_scr[thread_num_scrambling];
volatile uint8_t complete_mod[thread_num_modulation];
/*memorys of the first thread*/
unsigned char **test_input_first;
unsigned char **channel_input_optim_first;
uint8_t *f_first;
uint32_t *scrambled_output_first;
int16_t *mod_symbs_first;
/*encoder*/
uint8_t *c[thread_num_ldpc_encoder][MAX_NUM_NR_DLSCH_SEGMENTS];
uint8_t *d[thread_num_ldpc_encoder][MAX_NUM_NR_DLSCH_SEGMENTS];
int Zc[thread_num_ldpc_encoder];
int Kb[thread_num_ldpc_encoder];
short block_length[thread_num_ldpc_encoder];
short BG[thread_num_ldpc_encoder];
int n_segments[thread_num_ldpc_encoder];
/*scrambling*/
uint8_t f[thread_num_scrambling][MAX_NUM_NR_CHANNEL_BITS] __attribute__((aligned(32)));
uint32_t scrambled_output_scr[thread_num_scrambling][NR_MAX_NB_CODEWORDS][NR_MAX_PDSCH_ENCODED_LENGTH>>5]; // ==use thread_num_scrambling or thread_num_modulation ==???
uint32_t encoded_length_scr[thread_num_scrambling]; // ==use thread_num_scrambling or thread_num_modulation ==???
uint16_t Nid[thread_num_scrambling];
uint16_t n_RNTI[thread_num_scrambling];
/*modulation*/
uint32_t scrambled_output_mod[thread_num_modulation][NR_MAX_NB_CODEWORDS][NR_MAX_PDSCH_ENCODED_LENGTH>>5]; // ==use thread_num_scrambling or thread_num_modulation ==???
int32_t *mod_symbs[thread_num_modulation][NR_MAX_NB_CODEWORDS];
uint32_t encoded_length_mod[thread_num_modulation]; // ==use thread_num_scrambling or thread_num_modulation ==???
uint8_t Qm[thread_num_modulation];
}multi_pdsch_gNB;
typedef struct {
uint32_t pbch_a;
@@ -966,9 +874,6 @@ typedef struct PHY_VARS_gNB_s {
//**************************DLSCH ENCODING**************************//
dlsch_encoding_ISIP thread_encode[4];
ldpc_encoding_ISIP ldpc_encode;
multi_ldpc_encoder_gNB multi_encoder[thread_num_pdsch];
multi_ldpc_encoder_gNB pressure_test[thread_num_pressure];
multi_pdsch_gNB multi_pdsch;
volatile uint8_t complete_encode[4];

View File

@@ -18,7 +18,6 @@
* For more information about the OpenAirInterface (OAI) Software Alliance:
* contact@openairinterface.org
*/
#define _GNU_SOURCE
#include <sched.h>
#include <time.h>
@@ -61,9 +60,6 @@
#include "openair1/SIMULATION/NR_PHY/nr_unitary_defs.h"
#include "openair1/SIMULATION/NR_PHY/nr_dummy_functions.c"
#define CPU_AFF
#include "PHY/CODING/nrLDPC_encoder/defs.h"
PHY_VARS_gNB *gNB;
PHY_VARS_NR_UE *UE;
RAN_CONTEXT_t RC;
@@ -140,374 +136,382 @@ int nr_rate_matching_ldpc(uint8_t Ilbrm, uint32_t Tbslbrm, uint8_t BG, uint16_t
int32_t nr_segmentation(unsigned char *input_buffer, unsigned char **output_buffers, unsigned int B, unsigned int *C, unsigned int *K, unsigned int *Zout, unsigned int *F, uint8_t BG);
int ldpc_encoder_optim_8seg_multi(unsigned char **test_input,unsigned char **channel_input,int Zc,int Kb,short block_length, short BG, int n_segments,unsigned int macro_num, time_stats_t *tinput,time_stats_t *tprep,time_stats_t *tparity,time_stats_t *toutput);
/*! \file openair1/SIMULATION/NR_PHY/dlsim.c
* \brief Integration of dual thread and multi-parallelism threads
* \author Terngyin Hsu, Sendren Xu, Nungyi Kuo, Kuankai Hsiung, Kaimi Yang (OpInConnect_NCTU)
* \email tyhsu@cs.nctu.edu.tw
* \date 04-06-2020
* \version 3.2
* \note
* \warning
*/
static void *dlsch_encoding_proc(void *ptr){
dlsch_encoding_ISIP *test = (dlsch_encoding_ISIP*) ptr;
int num = test->id;
static int encode_status = 0;
uint8_t Nl = 4, Ilbrm = 1, BG = 1;
uint16_t r, Kr = 0, R;
uint32_t A, E, Z, Kb;
uint32_t *Zc = &Z, Tbslbrm = 950984, r_offset = 0, F = 0;
int frame = 0, slot = 1;
float Coderate = 0.0;
unsigned int crc = 1;
while(!oai_exit){
while(pthread_cond_wait(&gNB->thread_encode[num].cond_encode, &gNB->thread_encode[num].mutex_encode) != 0);
// TICK(TIME_DLSCH_ENCODING_THREAD);
test->flag_wait = 0;
uint8_t num_pdsch_rnti = gNB->pdcch_vars.num_pdsch_rnti;
for (int i = 0; i < num_pdsch_rnti; i++) {
NR_gNB_DLSCH_t *nr_gnb_dlsch = gNB->dlsch[i][0];
NR_gNB_DCI_ALLOC_t *dci_alloc = &gNB->pdcch_vars.dci_alloc[i];
NR_DL_gNB_HARQ_t *harq = nr_gnb_dlsch->harq_processes[dci_alloc->harq_pid];
uint8_t harq_pid = nr_gnb_dlsch->harq_ids[frame&2][slot];
nfapi_nr_dl_config_dlsch_pdu_rel15_t rel15 = nr_gnb_dlsch->harq_processes[harq_pid]->dlsch_pdu.dlsch_pdu_rel15;
uint16_t nb_rb = rel15.n_prb;
uint8_t nb_symb_sch = rel15.nb_symbols;
uint8_t mod_order = rel15.modulation_order;
uint8_t nb_re_dmrs = rel15.nb_re_dmrs;
uint16_t length_dmrs = 1;
unsigned int G = nr_get_G(nb_rb, nb_symb_sch, nb_re_dmrs, length_dmrs, mod_order, rel15.nb_layers);
unsigned char *a = harq->pdu;
A = rel15.transport_block_size;
R = rel15.coding_rate;
if (A > 3824) {
// Add 24-bit crc (polynomial A) to payload
crc = crc24a(a,A)>>8;
a[A>>3] = ((uint8_t*)&crc)[2];
a[1+(A>>3)] = ((uint8_t*)&crc)[1];
a[2+(A>>3)] = ((uint8_t*)&crc)[0];
//printf("CRC %x (A %d)\n",crc,A);
//printf("a0 %d a1 %d a2 %d\n", a[A>>3], a[1+(A>>3)], a[2+(A>>3)]);
nr_gnb_dlsch->harq_processes[harq_pid]->B = A+24;
// nr_gnb_dlsch->harq_processes[harq_pid]->b = a;
AssertFatal((A/8)+4 <= MAX_DLSCH_PAYLOAD_BYTES,"A %d is too big (A/8+4 = %d > %d)\n",A,(A/8)+4,MAX_DLSCH_PAYLOAD_BYTES);
//[START]multi_genetate_pdsch_proc
struct timespec start_encoder_ts[thread_num_pdsch], end_encoder_ts[thread_num_pdsch], start_perenc_ts[thread_num_pdsch], end_perenc_ts[thread_num_pdsch], start_pressure_ts[thread_num_pressure], end_pressure_ts[thread_num_pressure], start_perpre_ts[thread_num_pressure], end_perpre_ts[thread_num_pressure];
struct timespec start_multi_enc_ts[thread_num_ldpc_encoder], end_multi_enc_ts[thread_num_ldpc_encoder], start_multi_scr_ts[thread_num_scrambling], end_multi_scr_ts[thread_num_scrambling], start_multi_mod_ts[thread_num_modulation], end_multi_mod_ts[thread_num_modulation];
int vcd = 0; //default : 0
/*original genetate_pdsch for multi threads*/
static void *multi_genetate_pdsch_proc(void *ptr){
//ldpc_encoder_optim_8seg_multi(dlsch->harq_processes[harq_pid]->c,dlsch->harq_processes[harq_pid]->d,*Zc,Kb,Kr,BG,dlsch->harq_processes[harq_pid]->C,j,NULL,NULL,NULL,NULL);
//ldpc_encoder_optim_8seg_multi(unsigned char **test_input,unsigned char **channel_input,int Zc,int Kb,short block_length, short BG, int n_segments,unsigned int macro_num, time_stats_t *tinput,time_stats_t *tprep,time_stats_t *tparity,time_stats_t *toutput)
multi_ldpc_encoder_gNB *test =(multi_ldpc_encoder_gNB*) ptr;
printf("[READY] : %d\n", test->id);
while(!oai_exit){
while(pthread_cond_wait(&(gNB->multi_encoder[test->id].cond),&(gNB->multi_encoder[test->id].mutex))!=0);
if(oai_exit){ //If oai_exit, KILL this thread!
pthread_mutex_destroy(&gNB->multi_encoder[test->id].mutex);
pthread_mutex_destroy(&gNB->multi_encoder[test->id].mutex_scr_mod);
pthread_join(gNB->multi_encoder[test->id].pthread, NULL);
return 0;
}
//Print params of multi_ldpc_enc
// printf("[b]ldpc_encoder_optim_8seg: BG %d, Zc %d, Kb %d, block_length %d, segments %d\n",
// ldpc_enc[test->id].BG,
// ldpc_enc[test->id].Zc,
// ldpc_enc[test->id].Kb,
// ldpc_enc[test->id].block_length,
// ldpc_enc[test->id].n_segments);
memcpy(nr_gnb_dlsch->harq_processes[harq_pid]->b,a,(A/8)+4); // why is this +4 if the CRC is only 3 bytes?
}
else {
// Add 16-bit crc (polynomial A) to payload
crc = crc16(a,A)>>16;
a[A>>3] = ((uint8_t*)&crc)[1];
a[1+(A>>3)] = ((uint8_t*)&crc)[0];
//printf("CRC %x (A %d)\n",crc,A);
//printf("a0 %d a1 %d \n", a[A>>3], a[1+(A>>3)]);
nr_gnb_dlsch->harq_processes[harq_pid]->B = A+16;
// nr_gnb_dlsch->harq_processes[harq_pid]->b = a;
AssertFatal((A/8)+3 <= MAX_DLSCH_PAYLOAD_BYTES,"A %d is too big (A/8+3 = %d > %d)\n",A,(A/8)+3,MAX_DLSCH_PAYLOAD_BYTES);
int j_start, j_end; //Check if our situation((n_segments > 7)&(thread_num_pdsch == 2))
if((gNB->multi_encoder[test->id].n_segments > 7)&&(thread_num_pdsch == 2)){
j_start = test->id;
j_end = j_start + 1;
}else{
j_start = 0;
j_end = (gNB->multi_encoder[test->id].n_segments/8+1);
}
int offset = test->id>7?7:test->id;
//printf("[OFFSET] : %d %d\n", offset, test->id);
VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_MULTI_ENC_0 + offset,1);
if(check_time)
clock_gettime(CLOCK_MONOTONIC, &start_encoder_ts[test->id]); //timing
for(int j=j_start;j<j_end;j++){
if(check_time){
printf(" Active %d %d\n", test->id, j);
clock_gettime(CLOCK_MONOTONIC, &start_perenc_ts[test->id]); //timing
}
ldpc_encoder_optim_8seg_multi(gNB->multi_encoder[test->id].test_input,//gNB->multi_encoder[0].c_test,
gNB->multi_encoder[test->id].channel_input_optim,//gNB->multi_encoder[0].d_test,
gNB->multi_encoder[test->id].Zc,
gNB->multi_encoder[test->id].Kb,
gNB->multi_encoder[test->id].block_length,
gNB->multi_encoder[test->id].BG,
gNB->multi_encoder[test->id].n_segments,
j,
NULL, NULL, NULL, NULL);
if(check_time){
clock_gettime(CLOCK_MONOTONIC, &end_perenc_ts[test->id]); //timing
printf(" Done %d %d %.2f usec\n", test->id, j, (end_perenc_ts[test->id].tv_nsec - start_perenc_ts[test->id].tv_nsec) *1.0 / 1000);
}
}
if(check_time){
clock_gettime(CLOCK_MONOTONIC, &end_encoder_ts[test->id]); //timing
printf(" All done %d %.2f usec\n", test->id, (end_encoder_ts[test->id].tv_nsec - start_encoder_ts[test->id].tv_nsec) *1.0 / 1000);
}
VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_MULTI_ENC_0 + offset,0);
gNB->multi_encoder[test->id].complete = 1;
//==================================================
while(pthread_cond_wait(&(gNB->multi_encoder[test->id].cond_scr_mod),&(gNB->multi_encoder[test->id].mutex_scr_mod))!=0);
VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_MULTI_ENC_0 + offset,1);
if(check_time)
clock_gettime(CLOCK_MONOTONIC, &start_encoder_ts[test->id]); //timing
for (int q=0; q<1; q++){ //Need to change by codewords
if(check_time){
printf(" Active %d %d\n", test->id, q);
clock_gettime(CLOCK_MONOTONIC, &start_perenc_ts[test->id]); //timing
}
nr_pdsch_codeword_scrambling(gNB->multi_encoder[test->id].f,
gNB->multi_encoder[test->id].encoded_length,
q,
gNB->multi_encoder[test->id].Nid,
gNB->multi_encoder[test->id].n_RNTI,
gNB->multi_encoder[test->id].scrambled_output);
nr_modulation(gNB->multi_encoder[test->id].scrambled_output,
gNB->multi_encoder[test->id].encoded_length,
gNB->multi_encoder[test->id].Qm,
gNB->multi_encoder[test->id].mod_symbs);
if(check_time){
clock_gettime(CLOCK_MONOTONIC, &end_perenc_ts[test->id]); //timing
printf(" Done %d %d %.2f usec\n", test->id, q, (end_perenc_ts[test->id].tv_nsec - start_perenc_ts[test->id].tv_nsec) *1.0 / 1000);
}
memcpy(nr_gnb_dlsch->harq_processes[harq_pid]->b,a,(A/8)+3); // using 3 bytes to mimic the case of 24 bit crc
}
if (R < 1000)
Coderate = (float) R /(float) 1024;
else // to scale for mcs 20 and 26 in table 5.1.3.1-2 which are decimal and input 2* in nr_tbs_tools
Coderate = (float) R /(float) 2048;
if ((A <=292) || ((A<=3824) && (Coderate <= 0.6667)) || Coderate <= 0.25)
BG = 2;
else
BG = 1;
Kb = nr_segmentation(nr_gnb_dlsch->harq_processes[harq_pid]->b,
nr_gnb_dlsch->harq_processes[harq_pid]->c,
nr_gnb_dlsch->harq_processes[harq_pid]->B,
&nr_gnb_dlsch->harq_processes[harq_pid]->C,
&nr_gnb_dlsch->harq_processes[harq_pid]->K,
Zc,
&nr_gnb_dlsch->harq_processes[harq_pid]->F,
BG);
F = nr_gnb_dlsch->harq_processes[harq_pid]->F;
Kr = nr_gnb_dlsch->harq_processes[harq_pid]->K;
//for(int j = 0; j < (nr_gnb_dlsch->harq_processes[harq_pid]->C/8 + 1); j++) {
//ldpc_encoder_optim_8seg_multi(nr_gnb_dlsch->harq_processes[harq_pid]->c,nr_gnb_dlsch->harq_processes[harq_pid]->d,*Zc,Kb,Kr,BG,nr_gnb_dlsch->harq_processes[harq_pid]->C,(gNB->ldpc_encode).seg,NULL,NULL,NULL,NULL);
ldpc_encoder_optim_8seg_multi(nr_gnb_dlsch->harq_processes[harq_pid]->c,nr_gnb_dlsch->harq_processes[harq_pid]->d,*Zc,Kb,Kr,BG,nr_gnb_dlsch->harq_processes[harq_pid]->C,0,NULL,NULL,NULL,NULL);
//}
for (r = 0; r < nr_gnb_dlsch->harq_processes[harq_pid]->C; r++) {
if (nr_gnb_dlsch->harq_processes[harq_pid]->F > 0) {
for (int k=(Kr-F-2*(*Zc)); k<Kr-2*(*Zc); k++) {
nr_gnb_dlsch->harq_processes[harq_pid]->d[r][k] = NR_NULL;
}
}
E = nr_get_E(G, nr_gnb_dlsch->harq_processes[harq_pid]->C, mod_order, rel15.nb_layers, r);
// for tbslbrm calculation according to 5.4.2.1 of 38.212
if (rel15.nb_layers < Nl)
Nl = rel15.nb_layers;
Tbslbrm = nr_compute_tbslbrm(rel15.mcs_table, nb_rb, Nl, nr_gnb_dlsch->harq_processes[harq_pid]->C);
//TICK(TIME_NR_RATE_MATCH_LDPC);
nr_rate_matching_ldpc(Ilbrm,
Tbslbrm,
BG,
*Zc,
nr_gnb_dlsch->harq_processes[harq_pid]->d[r],
nr_gnb_dlsch->harq_processes[harq_pid]->e + r_offset,
nr_gnb_dlsch->harq_processes[harq_pid]->C,
rel15.redundancy_version,
E);
//TOCK(TIME_NR_RATE_MATCH_LDPC);
//TICK(TIME_NR_INTERLEAVING_LDPC);
nr_interleaving_ldpc(E,
mod_order,
nr_gnb_dlsch->harq_processes[harq_pid]->e + r_offset,
nr_gnb_dlsch->harq_processes[harq_pid]->f + r_offset);
//TOCK(TIME_NR_INTERLEAVING_LDPC);
r_offset += E;
}
}
gNB->complete_encode[num] = 1;
// TOCK(TIME_DLSCH_ENCODING_THREAD);
}
if(check_time){
clock_gettime(CLOCK_MONOTONIC, &end_encoder_ts[test->id]); //timing
printf(" All done %d %.2f usec\n", test->id, (end_encoder_ts[test->id].tv_nsec - start_encoder_ts[test->id].tv_nsec) *1.0 / 1000);
}
VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_MULTI_ENC_0 + offset,0);
gNB->multi_encoder[test->id].complete_scr_mod = 1;
}
return 0;
encode_status = 0;
return &encode_status;
}
/*pressure test*/
static void *multi_genetate_pdsch_pressure(void *ptr){
//ldpc_encoder_optim_8seg_multi(dlsch->harq_processes[harq_pid]->c,dlsch->harq_processes[harq_pid]->d,*Zc,Kb,Kr,BG,dlsch->harq_processes[harq_pid]->C,j,NULL,NULL,NULL,NULL);
//ldpc_encoder_optim_8seg_multi(unsigned char **test_input,unsigned char **channel_input,int Zc,int Kb,short block_length, short BG, int n_segments,unsigned int macro_num, time_stats_t *tinput,time_stats_t *tprep,time_stats_t *tparity,time_stats_t *toutput)
multi_ldpc_encoder_gNB *test =(multi_ldpc_encoder_gNB*) ptr;
printf("[READY] : %d(p)\n", test->id);
while(!oai_exit){
while(pthread_cond_wait(&(gNB->pressure_test[test->id].cond),&(gNB->pressure_test[test->id].mutex))!=0);
if(oai_exit){ //If oai_exit, KILL this thread!
pthread_mutex_destroy(&gNB->pressure_test[test->id].mutex);
pthread_mutex_destroy(&gNB->pressure_test[test->id].mutex_scr_mod);
pthread_join(gNB->pressure_test[test->id].pthread, NULL);
return 0;
}
//Print params of multi_ldpc_enc
// printf("[b]ldpc_encoder_optim_8seg: BG %d, Zc %d, Kb %d, block_length %d, segments %d\n",
// ldpc_enc[test->id].BG,
// ldpc_enc[test->id].Zc,
// ldpc_enc[test->id].Kb,
// ldpc_enc[test->id].block_length,
// ldpc_enc[test->id].n_segments);
int j_start, j_end; //Check if our situation((n_segments > 7)&(thread_num_pdsch == 2))
if((gNB->pressure_test[test->id].n_segments > 7)&&(thread_num_pdsch == 2)){
j_start = test->id;
j_end = j_start + 1;
}else{
j_start = 0;
j_end = (gNB->pressure_test[test->id].n_segments/8+1);
}
int offset = test->id+thread_num_pdsch;
if(offset>7){
offset = 7;
}
//printf("[OFFSET] : %d %d\n", offset, test->id);
VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_MULTI_ENC_0 + offset,1);
if(check_time)
clock_gettime(CLOCK_MONOTONIC, &start_pressure_ts[test->id]); //timing
for(int j=j_start;j<j_end;j++){
if(check_time){
printf(" Active %d(p) %d\n", test->id, j);
clock_gettime(CLOCK_MONOTONIC, &start_perpre_ts[test->id]); //timing
}
ldpc_encoder_optim_8seg_multi(gNB->pressure_test[test->id].c_test,
gNB->pressure_test[test->id].d_test,
gNB->pressure_test[test->id].Zc,
gNB->pressure_test[test->id].Kb,
gNB->pressure_test[test->id].block_length,
gNB->pressure_test[test->id].BG,
gNB->pressure_test[test->id].n_segments,
j,
NULL, NULL, NULL, NULL);
if(check_time){
clock_gettime(CLOCK_MONOTONIC, &end_perpre_ts[test->id]); //timing
printf(" Done %d(p) %d %.2f usec\n", test->id, j, (end_perpre_ts[test->id].tv_nsec - start_perpre_ts[test->id].tv_nsec) *1.0 / 1000);
}
}
if(check_time){
clock_gettime(CLOCK_MONOTONIC, &end_pressure_ts[test->id]); //timing
printf(" All done %d(p) %.2f usec\n", test->id, (end_pressure_ts[test->id].tv_nsec - start_pressure_ts[test->id].tv_nsec) *1.0 / 1000);
}
VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_MULTI_ENC_0 + offset,0);
gNB->pressure_test[test->id].complete = 1;
//==================================================
while(pthread_cond_wait(&(gNB->pressure_test[test->id].cond_scr_mod),&(gNB->pressure_test[test->id].mutex_scr_mod))!=0);
VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_MULTI_ENC_0 + offset,1);
if(check_time)
clock_gettime(CLOCK_MONOTONIC, &start_pressure_ts[test->id]); //timing
for (int q=0; q<1; q++){ //Need to change by codewords
if(check_time){
printf(" Active %d(p) %d\n", test->id, q);
clock_gettime(CLOCK_MONOTONIC, &start_perpre_ts[test->id]); //timing
}
nr_pdsch_codeword_scrambling(gNB->pressure_test[test->id].f_test,
gNB->pressure_test[test->id].encoded_length,
q,
gNB->pressure_test[test->id].Nid,
gNB->pressure_test[test->id].n_RNTI,
gNB->pressure_test[test->id].scrambled_output_test);
nr_modulation(gNB->pressure_test[test->id].scrambled_output_test,
gNB->pressure_test[test->id].encoded_length,
gNB->pressure_test[test->id].Qm,
gNB->pressure_test[test->id].mod_symbs_test);
if(check_time){
clock_gettime(CLOCK_MONOTONIC, &end_perpre_ts[test->id]); //timing
printf(" Done %d(p) %d %.2f usec\n", test->id, q, (end_perpre_ts[test->id].tv_nsec - start_perpre_ts[test->id].tv_nsec) *1.0 / 1000);
}
}
if(check_time){
clock_gettime(CLOCK_MONOTONIC, &end_pressure_ts[test->id]); //timing
printf(" All done %d(p) %.2f usec\n", test->id, (end_pressure_ts[test->id].tv_nsec - start_pressure_ts[test->id].tv_nsec) *1.0 / 1000);
}
VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_MULTI_ENC_0 + offset,0);
gNB->pressure_test[test->id].complete_scr_mod = 1;
}
return 0;
}
/*ldpc_encoder*/
static void *multi_ldpc_encoder_proc(int id){
//ldpc_encoder_optim_8seg_multi(dlsch->harq_processes[harq_pid]->c,dlsch->harq_processes[harq_pid]->d,*Zc,Kb,Kr,BG,dlsch->harq_processes[harq_pid]->C,j,NULL,NULL,NULL,NULL);
//ldpc_encoder_optim_8seg_multi(unsigned char **test_input,unsigned char **channel_input,int Zc,int Kb,short block_length, short BG, int n_segments,unsigned int macro_num, time_stats_t *tinput,time_stats_t *tprep,time_stats_t *tparity,time_stats_t *toutput)
printf("[READY] : %d(e)\n", id);
while(!oai_exit){
while(pthread_cond_wait(&(gNB->multi_pdsch.cond_enc[id]),&(gNB->multi_pdsch.mutex_enc[id]))!=0);
if(oai_exit){ //If oai_exit, KILL this thread!
pthread_mutex_destroy(&gNB->multi_pdsch.mutex_enc[id]);
pthread_join(gNB->multi_pdsch.pthread_enc[id], NULL);
return 0;
}
// int offset = id+thread_num_pdsch;
// if(offset>7){
// offset = 7;
// }
//printf("[OFFSET] : %d %d\n", offset, id);
static void *scrambling_proc(void *ptr){
scrambling_channel *test =(scrambling_channel*) ptr;
int q_id = test->q_id;
struct timespec tt1, tt2, tt3, tt4;
//clock_gettime(CLOCK_REALTIME, &eNB->tt17);
//printf("cch_proc consumes %ld nanoseconds!\n",eNB->tt17.tv_nsec-eNB->tt13.tv_nsec);
static int scrambling_channel_status;
scrambling_channel_status=0;
//scrambling_channel *scrambling_proc=(scrambling_channel*)ptr;
//PHY_VARS_eNB *eNB = PHY_vars_eNB_g[0][0];
/**********************************************************************/
#ifdef CPU_AFF
cpu_set_t cpuset;
int cpu = 0;
int s;
CPU_ZERO(&cpuset); //clears the cpuset
CPU_SET( cpu , &cpuset); //set CPU 0~7 on cpuset
s = pthread_setaffinity_np(pthread_self(), sizeof(cpu_set_t), &cpuset);
if (s != 0)
{
perror( "pthread_setaffinity_np");
exit_fun("Error setting processor affinity");
}
s = pthread_getaffinity_np(pthread_self(), sizeof(cpu_set_t), &cpuset);
if (s != 0) {
perror( "pthread_getaffinity_np");
exit_fun("Error getting processor affinity ");
}
printf("[SCHED][gNB] scrambling_proc scheduler thread started on CPU %d TID %ld\n",sched_getcpu(),gettid());
#endif
/**********************************************************************/
while(!oai_exit)
{
while(pthread_cond_wait(&gNB->thread_scrambling[test->q_id].cond_tx, &gNB->thread_scrambling[test->q_id].mutex_tx)!=0);
//VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_ENB_CONTROL_CHANNEL_THREAD_TX,1);
//clock_gettime(CLOCK_REALTIME, &tt1);
PHY_VARS_gNB *gNB = RC.gNB[0][0];
NR_gNB_DLSCH_t *dlsch =gNB->dlsch[0][0];
NR_gNB_DCI_ALLOC_t *dci_alloc = &gNB->pdcch_vars.dci_alloc[0];
NR_DL_gNB_HARQ_t *harq = dlsch->harq_processes[dci_alloc->harq_pid];
nfapi_nr_dl_config_dlsch_pdu_rel15_t *rel15 = &harq->dlsch_pdu.dlsch_pdu_rel15;
nfapi_nr_config_request_t *config = &gNB->gNB_config;
nfapi_nr_dl_config_pdcch_parameters_rel15_t pdcch_params = dci_alloc->pdcch_params;
uint32_t scrambled_output[NR_MAX_NB_CODEWORDS][NR_MAX_PDSCH_ENCODED_LENGTH>>5];
int16_t **mod_symbs = (int16_t**)dlsch->mod_symbs;
//int16_t **tx_layers = (int16_t**)dlsch->txdataF;
//int8_t Wf[2], Wt[2], l0, l_prime[2], delta;
uint16_t nb_symbols = rel15->nb_mod_symbols;
uint8_t Qm = rel15->modulation_order;
uint32_t encoded_length = nb_symbols*Qm;
//clock_gettime(CLOCK_REALTIME, &tt2);
//printf("scrambling_proc initial for q = %d consumes %ld nanoseconds!!!!!!!!!!!\n", q_id,tt2.tv_nsec - tt1.tv_nsec);
//VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_ENB_PMCH_PBCH_TX,1);
/// scrambling
clock_gettime(CLOCK_REALTIME, &tt3);
clock_gettime(CLOCK_REALTIME, &tt1);
for (int q=0; q<rel15->nb_codewords; q++)
memset((void*)(scrambled_output[q]), 0, (encoded_length>>5)*sizeof(uint32_t));
uint16_t n_RNTI = (pdcch_params.search_space_type == NFAPI_NR_SEARCH_SPACE_TYPE_UE_SPECIFIC)? \
((pdcch_params.scrambling_id==0)?pdcch_params.rnti:0) : 0;
uint16_t Nid = (pdcch_params.search_space_type == NFAPI_NR_SEARCH_SPACE_TYPE_UE_SPECIFIC)? \
pdcch_params.scrambling_id : config->sch_config.physical_cell_id.value;
nr_pdsch_codeword_scrambling(harq->f,
encoded_length,
q_id,
Nid,
n_RNTI,
scrambled_output[q_id]);
clock_gettime(CLOCK_REALTIME, &tt2);
// printf("scrambling for q = %d consumes %ld nanoseconds!\n", q_id,tt2.tv_nsec - tt1.tv_nsec);
#ifdef DEBUG_DLSCH
printf("PDSCH scrambling:\n");
for (int i=0; i<encoded_length>>8; i++) {
for (int j=0; j<8; j++)
printf("0x%08x\t", scrambled_output[0][(i<<3)+j]);
printf("\n");
}
#endif
clock_gettime(CLOCK_REALTIME, &tt1);
nr_modulation(scrambled_output[q_id],
encoded_length,
Qm,
mod_symbs[q_id]);
//gNB->q_scrambling[q] = 0;
clock_gettime(CLOCK_REALTIME, &tt2);
// printf("modulation for q = %d consumes %ld nanoseconds!\n", q_id,tt2.tv_nsec - tt1.tv_nsec);
//stop_meas(dlsch_modulation_stats);
#ifdef DEBUG_DLSCH
printf("PDSCH Modulation: Qm %d(%d)\n", Qm, nb_symbols);
for (int i=0; i<nb_symbols>>3; i++) {
for (int j=0; j<8; j++) {
printf("%d %d\t", mod_symbs[0][((i<<3)+j)<<1], mod_symbs[0][(((i<<3)+j)<<1)+1]);
}
printf("\n");
}
#endif
int j_start, j_end; // ==Wait for n_segments increasing ==***
j_start = 0;
j_end = 1;
//VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_MULTI_ENC_0 + offset,1);
if(check_time)
clock_gettime(CLOCK_MONOTONIC, &start_multi_enc_ts[id]); //timing
for(int j=j_start;j<j_end;j++){
if(check_time){
printf(" Active %d(e) %d\n", id, j);
//clock_gettime(CLOCK_MONOTONIC, &start_perpre_ts[id]); //timing
}
if(id == 0){ // ==deal with original memory space for check ==
ldpc_encoder_optim_8seg_multi(gNB->multi_pdsch.test_input_first,
gNB->multi_pdsch.channel_input_optim_first,
gNB->multi_pdsch.Zc[id],
gNB->multi_pdsch.Kb[id],
gNB->multi_pdsch.block_length[id],
gNB->multi_pdsch.BG[id],
gNB->multi_pdsch.n_segments[id],
j,
NULL, NULL, NULL, NULL);
}else{
ldpc_encoder_optim_8seg_multi(gNB->multi_pdsch.c[id],
gNB->multi_pdsch.d[id],
gNB->multi_pdsch.Zc[id],
gNB->multi_pdsch.Kb[id],
gNB->multi_pdsch.block_length[id],
gNB->multi_pdsch.BG[id],
gNB->multi_pdsch.n_segments[id],
j,
NULL, NULL, NULL, NULL);
}
if(check_time){
// clock_gettime(CLOCK_MONOTONIC, &end_perpre_ts[id]); //timing
// printf(" Done %d(e) %d %.2f usec\n", id, j, (end_perpre_ts[id].tv_nsec - start_perpre_ts[id].tv_nsec) *1.0 / 1000);
}
}
if(check_time){
clock_gettime(CLOCK_MONOTONIC, &end_multi_enc_ts[id]); //timing
printf(" All done %d(e) %.2f usec\n", id, (end_multi_enc_ts[id].tv_nsec - start_multi_enc_ts[id].tv_nsec) *1.0 / 1000);
}
//VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_MULTI_ENC_0 + offset,0);
gNB->multi_pdsch.complete_enc[id] = 1;
}
return 0;
}
/*scrambling*/
static void *multi_scrambling_proc(int id){
//ldpc_encoder_optim_8seg_multi(dlsch->harq_processes[harq_pid]->c,dlsch->harq_processes[harq_pid]->d,*Zc,Kb,Kr,BG,dlsch->harq_processes[harq_pid]->C,j,NULL,NULL,NULL,NULL);
//ldpc_encoder_optim_8seg_multi(unsigned char **test_input,unsigned char **channel_input,int Zc,int Kb,short block_length, short BG, int n_segments,unsigned int macro_num, time_stats_t *tinput,time_stats_t *tprep,time_stats_t *tparity,time_stats_t *toutput)
printf("[READY] : %d(s)\n", id);
while(!oai_exit){
while(pthread_cond_wait(&(gNB->multi_pdsch.cond_scr[id]),&(gNB->multi_pdsch.mutex_scr[id]))!=0);
if(oai_exit){ //If oai_exit, KILL this thread!
pthread_mutex_destroy(&gNB->multi_pdsch.mutex_scr[id]);
pthread_join(gNB->multi_pdsch.pthread_scr[id], NULL);
return 0;
}
//VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_MULTI_ENC_0 + offset,1);
if(check_time)
clock_gettime(CLOCK_MONOTONIC, &start_multi_scr_ts[id]); //timing
for (int q=0; q<1; q++){ //Need to change by codewords
if(check_time){
printf(" Active %d(s) %d\n", id, q);
// clock_gettime(CLOCK_MONOTONIC, &start_perpre_ts[id]); //timing
}
//if(0){
if(id == 0){ // ==deal with original memory space for check ==
nr_pdsch_codeword_scrambling(gNB->multi_pdsch.f_first,
gNB->multi_pdsch.encoded_length_scr[id],
q,
gNB->multi_pdsch.Nid[id],
gNB->multi_pdsch.n_RNTI[id],
gNB->multi_pdsch.scrambled_output_first);
}else{
nr_pdsch_codeword_scrambling(gNB->multi_pdsch.f[id],
gNB->multi_pdsch.encoded_length_scr[id],
q,
gNB->multi_pdsch.Nid[id],
gNB->multi_pdsch.n_RNTI[id],
gNB->multi_pdsch.scrambled_output_scr[id]);
}
if(check_time){
// clock_gettime(CLOCK_MONOTONIC, &end_perpre_ts[id]); //timing
// printf(" Done %d(p) %d %.2f usec\n", id, q, (end_perpre_ts[id].tv_nsec - start_perpre_ts[id].tv_nsec) *1.0 / 1000);
}
//printf("complete_scrambling\n");
//pthread_mutex_lock(&gNB->complete_scrambling_modulation_mutex);
//gNB->complete_scrambling_and_modulation++;
//pthread_mutex_unlock(&gNB->complete_scrambling_modulation_mutex);
clock_gettime(CLOCK_REALTIME, &tt4);
// printf("scrambling&modulation for q = %d consumes %ld nanoseconds!\n", q_id,tt4.tv_nsec - tt3.tv_nsec);
gNB->complete_scrambling_and_modulation++;
}
if(check_time){
clock_gettime(CLOCK_MONOTONIC, &end_multi_scr_ts[id]); //timing
printf(" All done %d(s) %.2f usec\n", id, (end_multi_scr_ts[id].tv_nsec - start_multi_scr_ts[id].tv_nsec) *1.0 / 1000);
}
//VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_MULTI_ENC_0 + offset,0);
gNB->multi_pdsch.complete_scr[id] = 1;
}
return 0;
printf( "Exiting gNB thread scrambling_channel\n");
return &scrambling_channel_status;
}
/*modulation*/
static void *multi_modulation_proc(int id){
//ldpc_encoder_optim_8seg_multi(dlsch->harq_processes[harq_pid]->c,dlsch->harq_processes[harq_pid]->d,*Zc,Kb,Kr,BG,dlsch->harq_processes[harq_pid]->C,j,NULL,NULL,NULL,NULL);
//ldpc_encoder_optim_8seg_multi(unsigned char **test_input,unsigned char **channel_input,int Zc,int Kb,short block_length, short BG, int n_segments,unsigned int macro_num, time_stats_t *tinput,time_stats_t *tprep,time_stats_t *tparity,time_stats_t *toutput)
printf("[READY] : %d(m)\n", id);
while(!oai_exit){
while(pthread_cond_wait(&(gNB->multi_pdsch.cond_mod[id]),&(gNB->multi_pdsch.mutex_mod[id]))!=0);
if(oai_exit){ //If oai_exit, KILL this thread!
pthread_mutex_destroy(&gNB->multi_pdsch.mutex_mod[id]);
pthread_join(gNB->multi_pdsch.pthread_mod[id], NULL);
return 0;
}
//VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_MULTI_ENC_0 + offset,1);
if(check_time)
clock_gettime(CLOCK_MONOTONIC, &start_multi_mod_ts[id]); //timing
//printf("%d, %p\n", id, gNB->multi_pdsch.mod_symbs[id]);
//printf("%d, %p\n", id, *gNB->multi_pdsch.mod_symbs[id]);
for (int q=0; q<1; q++){ //Need to change by codewords
if(check_time){
printf(" Active %d(m) %d\n", id, q);
// clock_gettime(CLOCK_MONOTONIC, &start_perpre_ts[id]); //timing
}
if(id == 0){ // ==deal with original memory space for check ==
nr_modulation(gNB->multi_pdsch.scrambled_output_first,
gNB->multi_pdsch.encoded_length_mod[id],
gNB->multi_pdsch.Qm[id],
gNB->multi_pdsch.mod_symbs_first);
}else{
nr_modulation(gNB->multi_pdsch.scrambled_output_mod[id],
gNB->multi_pdsch.encoded_length_mod[id],
gNB->multi_pdsch.Qm[id],
*gNB->multi_pdsch.mod_symbs[id]);//gNB->pressure_test[id].mod_symbs_test);
}
if(check_time){
// clock_gettime(CLOCK_MONOTONIC, &end_perpre_ts[id]); //timing
// printf(" Done %d(p) %d %.2f usec\n", id, q, (end_perpre_ts[id].tv_nsec - start_perpre_ts[id].tv_nsec) *1.0 / 1000);
}
static void *modulation_proc(void *ptr){
// PHY_VARS_gNB *gNB = RC.gNB[0][0];
// NR_gNB_DLSCH_t *dlsch = gNB->dlsch[0][0];
//clock_gettime(CLOCK_REALTIME, &eNB->tt17);
//printf("cch_proc consumes %ld nanoseconds!\n",eNB->tt17.tv_nsec-eNB->tt13.tv_nsec);
static int modulation_channel_status;
modulation_channel_status=0;
struct timespec tt1, tt2;
PHY_VARS_gNB *gNB = RC.gNB[0][0];
NR_gNB_DLSCH_t *dlsch = gNB->dlsch[0][0];
/**********************************************************************/
#ifdef CPU_AFF
cpu_set_t cpuset;
int cpu = 1;
int s;
CPU_ZERO(&cpuset); //clears the cpuset
CPU_SET( cpu , &cpuset); //set CPU 0~7 on cpuset
s = pthread_setaffinity_np(pthread_self(), sizeof(cpu_set_t), &cpuset);
if (s != 0)
{
perror( "pthread_setaffinity_np");
exit_fun("Error setting processor affinity");
}
if(check_time){
clock_gettime(CLOCK_MONOTONIC, &end_multi_mod_ts[id]); //timing
printf(" All done %d(m) %.2f usec\n", id, (end_multi_mod_ts[id].tv_nsec - start_multi_mod_ts[id].tv_nsec) *1.0 / 1000);
}
//VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_MULTI_ENC_0 + offset,0);
gNB->multi_pdsch.complete_mod[id] = 1;
}
return 0;
s = pthread_getaffinity_np(pthread_self(), sizeof(cpu_set_t), &cpuset);
if (s != 0) {
perror( "pthread_getaffinity_np");
exit_fun("Error getting processor affinity ");
}
printf("[SCHED][gNB] scrambling_proc scheduler thread started on CPU %d TID %ld\n",sched_getcpu(),gettid());
#endif
/*
NR_gNB_DCI_ALLOC_t *dci_alloc = &gNB->pdcch_vars.dci_alloc[0];
NR_DL_gNB_HARQ_t *harq = dlsch->harq_processes[dci_alloc->harq_pid];
nfapi_nr_dl_config_dlsch_pdu_rel15_t *rel15 = &harq->dlsch_pdu.dlsch_pdu_rel15;
nfapi_nr_config_request_t *config = &gNB->gNB_config;
nfapi_nr_dl_config_pdcch_parameters_rel15_t pdcch_params = dci_alloc->pdcch_params;
uint32_t scrambled_output[NR_MAX_NB_CODEWORDS][NR_MAX_PDSCH_ENCODED_LENGTH>>5];
*/
while(!oai_exit)
{
while(pthread_cond_wait(&gNB->thread_modulation.cond_tx, &gNB->thread_modulation.mutex_tx)!=0);
clock_gettime(CLOCK_REALTIME, &tt1);
//VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_ENB_CONTROL_CHANNEL_THREAD_TX,1);
gNB->complete_modulation = 0;
NR_gNB_DCI_ALLOC_t *dci_alloc = &gNB->pdcch_vars.dci_alloc[0];
NR_DL_gNB_HARQ_t *harq = dlsch->harq_processes[dci_alloc->harq_pid];
nfapi_nr_dl_config_dlsch_pdu_rel15_t *rel15 = &harq->dlsch_pdu.dlsch_pdu_rel15;
nfapi_nr_config_request_t *config = &gNB->gNB_config;
nfapi_nr_dl_config_pdcch_parameters_rel15_t pdcch_params = dci_alloc->pdcch_params;
uint32_t scrambled_output[NR_MAX_NB_CODEWORDS][NR_MAX_PDSCH_ENCODED_LENGTH>>5];
int16_t **mod_symbs = (int16_t**)dlsch->mod_symbs_test;
//int16_t **mod_symbs ;/*= (int16_t**)dlsch->mod_symbs;*/
uint16_t nb_symbols = rel15->nb_mod_symbols;
uint8_t Qm = rel15->modulation_order;
uint32_t encoded_length = nb_symbols*Qm;
//VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_ENB_PMCH_PBCH_TX,1);
/// scrambling
for (int q=0; q<rel15->nb_codewords; q++)
memset((void*)(scrambled_output[q]), 0, (encoded_length>>5)*sizeof(uint32_t));
uint16_t n_RNTI = (pdcch_params.search_space_type == NFAPI_NR_SEARCH_SPACE_TYPE_UE_SPECIFIC)? \
((pdcch_params.scrambling_id==0)?pdcch_params.rnti:0) : 0;
uint16_t Nid = (pdcch_params.search_space_type == NFAPI_NR_SEARCH_SPACE_TYPE_UE_SPECIFIC)? \
pdcch_params.scrambling_id : config->sch_config.physical_cell_id.value;
nr_pdsch_codeword_scrambling(harq->f,
encoded_length,
0,
Nid,
n_RNTI,
scrambled_output[0]);
printf("nr_pdsch_codeword_scrambling in test\n");
#ifdef DEBUG_DLSCH
printf("PDSCH scrambling:\n");
for (int i=0; i<encoded_length>>8; i++) {
for (int j=0; j<8; j++)
printf("0x%08x\t", scrambled_output[0][(i<<3)+j]);
printf("\n");
}
#endif
/// Modulation
//start_meas(dlsch_modulation_stats);
nr_modulation(gNB->scrambled_output[0],
encoded_length,
Qm,
mod_symbs[0]);
//printf("nr_modulation in test\n");
//stop_meas(dlsch_modulation_stats);
#ifdef DEBUG_DLSCH
printf("PDSCH Modulation: Qm %d(%d)\n", Qm, nb_symbols);
for (int i=0; i<nb_symbols>>3; i++) {
for (int j=0; j<8; j++) {
printf("%d %d\t", mod_symbs[0][((i<<3)+j)<<1], mod_symbs[0][(((i<<3)+j)<<1)+1]);
}
printf("\n");
}
#endif
//printf("complete_modulation\n");
gNB->complete_modulation ++;
//printf("complete_modulation = %d\n",gNB->complete_modulation);
clock_gettime(CLOCK_REALTIME, &tt2);
//printf("scrambling_proc for test consumes %ld nanoseconds!\n",tt2.tv_nsec - tt1.tv_nsec);
}
printf( "Exiting gNB thread modulation_channel\n");
return &modulation_channel_status;
}
//[END]multi_genetate_pdsch_proc
int main(int argc, char **argv)
{
@@ -590,7 +594,7 @@ int main(int argc, char **argv)
randominit(0);
while ((c = getopt (argc, argv, "f:hA:pf:g:i:j:n:s:S:t:x:y:z:M:N:F:GR:dP:IL:o:a:b:c:j:e:V:")) != -1) {
while ((c = getopt (argc, argv, "f:hA:pf:g:i:j:n:s:S:t:x:y:z:M:N:F:GR:dP:IL:o:a:b:c:j:e:")) != -1) {
switch (c) {
/*case 'f':
write_output_file=1;
@@ -779,12 +783,6 @@ int main(int argc, char **argv)
dlsch_config.mcs_idx = atoi(optarg);
break;
case 'V':
vcd = atoi(optarg);
if(vcd)
T_init(2021, 1, 0); //VCD init
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 -t Delayspread -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",
@@ -812,14 +810,14 @@ int main(int argc, char **argv)
printf("-F Input filename (.txt format) for RX conformance testing\n");
printf("-o CORESET offset\n");
printf("-a Start PRB for PDSCH\n");
printf("-b Number of PRB for PDSCH, default : 50\n");
printf("-b Number of PRB for PDSCH\n");
printf("-c Start symbol for PDSCH (fixed for now)\n");
printf("-j Number of symbols for PDSCH (fixed for now)\n");
printf("-e MSC index\n");
exit (-1);
break;
}
}
}
logInit();
set_glog(loglvl);
@@ -937,87 +935,28 @@ int main(int argc, char **argv)
exit(-1);
}
// for (int t = 0; t < 4; t++){ //create threads
// gNB->thread_encode[t].id = t;
// gNB->thread_encode[t].flag_wait = 1;
// pthread_mutex_init( &(gNB->thread_encode[t].mutex_encode), NULL);
// pthread_cond_init( &(gNB->thread_encode[t].cond_encode), NULL);
// pthread_create(&(gNB->thread_encode[t].pthread_encode),&gNB->thread_encode[t].attr_encode,dlsch_encoding_proc,&gNB->thread_encode[t]);
// printf("[CREATE] DLSCH ENCODER Thread %d\n", gNB->thread_encode[t].id);
// }
// for(int aa = 0;aa<1;aa++){
// pthread_attr_init( &gNB->thread_scrambling[aa].attr_scrambling);
// pthread_mutex_init(&(gNB->thread_scrambling[aa].mutex_tx), NULL);
// pthread_cond_init(&(gNB->thread_scrambling[aa].cond_tx), NULL);
// gNB->thread_scrambling[aa].q_id = aa;
// pthread_create(&(gNB->thread_scrambling[aa].pthread_scrambling),&gNB->thread_scrambling[aa].attr_scrambling,scrambling_proc,&gNB->thread_scrambling[aa]);
// printf("[CREATE] scrambling_channel thread[%d] \n",aa);
// }
for (int t = 0; t < 4; t++){
gNB->thread_encode[t].id = t;
gNB->thread_encode[t].flag_wait = 1;
pthread_mutex_init( &(gNB->thread_encode[t].mutex_encode), NULL);
pthread_cond_init( &(gNB->thread_encode[t].cond_encode), NULL);
pthread_create(&(gNB->thread_encode[t].pthread_encode),&gNB->thread_encode[t].attr_encode,dlsch_encoding_proc,&gNB->thread_encode[t]);
printf("[CREATE] DLSCH ENCODER Thread %d\n", gNB->thread_encode[t].id);
}
for(int aa = 0;aa<1;aa++){
pthread_attr_init( &gNB->thread_scrambling[aa].attr_scrambling);
pthread_mutex_init(&(gNB->thread_scrambling[aa].mutex_tx), NULL);
pthread_cond_init(&(gNB->thread_scrambling[aa].cond_tx), NULL);
gNB->thread_scrambling[aa].q_id = aa;
pthread_create(&(gNB->thread_scrambling[aa].pthread_scrambling),&gNB->thread_scrambling[aa].attr_scrambling,scrambling_proc,&gNB->thread_scrambling[aa]);
printf("[CREATE] scrambling_channel thread[%d] \n",aa);
}
// pthread_mutex_init( &(gNB->thread_modulation.mutex_tx), NULL);
// pthread_cond_init( &(gNB->thread_modulation.cond_tx), NULL);
// pthread_create(&(gNB->thread_modulation.pthread_modulation),&gNB->thread_modulation.attr_modulation,modulation_proc,&gNB->thread_modulation);
// printf("[CREATE] modulation_channel thread \n");
//[START]multi_genetate_pdsch_proc:create thread
for(int th=0;th<thread_num_pdsch;th++){
pthread_attr_init(&(gNB->multi_encoder[th].attr));
pthread_mutex_init(&(gNB->multi_encoder[th].mutex), NULL);
pthread_mutex_init(&(gNB->multi_encoder[th].mutex_scr_mod), NULL);
pthread_cond_init(&(gNB->multi_encoder[th].cond), NULL);
pthread_cond_init(&(gNB->multi_encoder[th].cond_scr_mod), NULL);
gNB->multi_encoder[th].id = th;
gNB->multi_encoder[th].flag_wait = 1;
gNB->multi_encoder[th].complete = 0;
gNB->multi_encoder[th].complete_scr_mod = 0;
pthread_create(&(gNB->multi_encoder[th].pthread), &(gNB->multi_encoder[th].attr), multi_genetate_pdsch_proc, &(gNB->multi_encoder[th]));
printf("[CREATE] LDPC encoder thread %d \n",gNB->multi_encoder[th].id);
}
for(int th=0;th<thread_num_pressure;th++){
pthread_attr_init(&(gNB->pressure_test[th].attr));
pthread_mutex_init(&(gNB->pressure_test[th].mutex), NULL);
pthread_mutex_init(&(gNB->pressure_test[th].mutex_scr_mod), NULL);
pthread_cond_init(&(gNB->pressure_test[th].cond), NULL);
pthread_cond_init(&(gNB->pressure_test[th].cond_scr_mod), NULL);
gNB->pressure_test[th].id = th;
gNB->pressure_test[th].flag_wait = 1;
gNB->pressure_test[th].complete = 0;
gNB->pressure_test[th].complete_scr_mod = 0;
pthread_create(&(gNB->pressure_test[th].pthread), &(gNB->pressure_test[th].attr), multi_genetate_pdsch_pressure, &(gNB->pressure_test[th]));
printf("[CREATE] LDPC encoder thread %d(p) \n",gNB->pressure_test[th].id);
}
/*multi pdsch*/
for(int th=0;th<thread_num_ldpc_encoder;th++){
pthread_attr_init(&(gNB->multi_pdsch.attr_enc[th]));
pthread_mutex_init(&(gNB->multi_pdsch.mutex_enc[th]), NULL);
pthread_cond_init(&(gNB->multi_pdsch.cond_enc[th]), NULL);
gNB->multi_pdsch.id_enc[th] = th;
gNB->multi_pdsch.complete_enc[th] = 0;
pthread_create(&(gNB->multi_pdsch.pthread_enc[th]), &(gNB->multi_pdsch.attr_enc[th]), multi_ldpc_encoder_proc, gNB->multi_pdsch.id_enc[th]);
printf("[CREATE] multi_ldpc_encoder_proc %d \n",gNB->multi_pdsch.id_enc[th]);
}
for(int th=0;th<thread_num_scrambling;th++){
pthread_attr_init(&(gNB->multi_pdsch.attr_scr[th]));
pthread_mutex_init(&(gNB->multi_pdsch.mutex_scr[th]), NULL);
pthread_cond_init(&(gNB->multi_pdsch.cond_scr[th]), NULL);
gNB->multi_pdsch.id_scr[th] = th;
gNB->multi_pdsch.complete_scr[th] = 0;
pthread_create(&(gNB->multi_pdsch.pthread_scr[th]), &(gNB->multi_pdsch.attr_scr[th]), multi_scrambling_proc, gNB->multi_pdsch.id_scr[th]);
printf("[CREATE] multi_scrambling_proc %d \n",gNB->multi_pdsch.id_scr[th]);
}
//for(int th=0;th<0;th++){
for(int th=0;th<thread_num_modulation;th++){
pthread_attr_init(&(gNB->multi_pdsch.attr_mod[th]));
pthread_mutex_init(&(gNB->multi_pdsch.mutex_mod[th]), NULL);
pthread_cond_init(&(gNB->multi_pdsch.cond_mod[th]), NULL);
gNB->multi_pdsch.id_mod[th] = th;
gNB->multi_pdsch.complete_mod[th] = 0;
pthread_create(&(gNB->multi_pdsch.pthread_mod[th]), &(gNB->multi_pdsch.attr_mod[th]), multi_modulation_proc, gNB->multi_pdsch.id_mod[th]);
printf("[CREATE] multi_modulation_proc %d \n",gNB->multi_pdsch.id_mod[th]);
}
//[END]multi_genetate_pdsch_proc:create thread
pthread_mutex_init( &(gNB->thread_modulation.mutex_tx), NULL);
pthread_cond_init( &(gNB->thread_modulation.cond_tx), NULL);
pthread_create(&(gNB->thread_modulation.pthread_modulation),&gNB->thread_modulation.attr_modulation,modulation_proc,&gNB->thread_modulation);
printf("[CREATE] modulation_channel thread \n");
init_nr_ue_transport(UE,0);
usleep(1000000);
nr_gold_pbch(UE);
@@ -1071,7 +1010,7 @@ int main(int argc, char **argv)
Sched_INFO.TX_req = &gNB_mac->TX_req[0];
nr_schedule_response(&Sched_INFO);
phy_procedures_gNB_TX(gNB,frame,slot,0); // ==the way to downlink ==
phy_procedures_gNB_TX(gNB,frame,slot,0);
//nr_common_signal_procedures (gNB,frame,subframe);
int txdataF_offset = (slot%2) * frame_parms->samples_per_slot_wCP;
@@ -1365,41 +1304,6 @@ int main(int argc, char **argv)
} // NSR
//[START]Send Kill massage
oai_exit = 1; //set oai status oai_exit = 1
printf("Kill them all!\n");
for(int th=0; th<thread_num_pdsch; th++){
pthread_cond_signal(&(gNB->multi_encoder[th].cond));
}
for(int th=0; th<thread_num_pressure; th++){
pthread_cond_signal(&(gNB->pressure_test[th].cond));
}
//free pressure memorys
unsigned char bw_scaling =2; // ==Need to change ==***
for(int th=0;th<thread_num_pressure;th++){
for(int j=0;j<MAX_NUM_NR_DLSCH_SEGMENTS/bw_scaling;j++){
free(gNB->pressure_test[th].c_test[j]);
free(gNB->pressure_test[th].d_test[j]);
}
// ==We have some problom here ==???
// for (int q=0; q<NR_MAX_NB_CODEWORDS; q++){
// free(*gNB->pressure_test[th].mod_symbs_test[q]);
// }
}
//free multi_pdsch memorys
for(int th=0;th<thread_num_ldpc_encoder;th++){
for(int j=0;j<MAX_NUM_NR_DLSCH_SEGMENTS/bw_scaling;j++){
free(gNB->multi_pdsch.c[th][j]);
free(gNB->multi_pdsch.d[th][j]);
}
}
for(int th=0;th<thread_num_modulation;th++){
for (int q=0; q<NR_MAX_NB_CODEWORDS; q++){
free(gNB->multi_pdsch.mod_symbs[th][q]);
}
}
//[END]Send Kill massage
for (i = 0; i < 2; i++) {
free(s_re[i]);
free(s_im[i]);