Commit d2febea8 authored by Melissa's avatar Melissa

Merge branch 'episys/david/sl-tb-update' into 'episys/master-sl'

Transport block size update per mcs value for sidelink.

See merge request aburger/openairinterface5g!241
parents 0f6043d8 75afd14b
#!/bin/bash
remote_host_ip=10.1.1.61
remote_host_ip=10.1.1.80 # to test on N310
user_id=$USER
message_to_send=EpiScience
num_repeat=1
atten_list=(21) #(0 5 10 15 20 25 30 35 39 40)
atten_list=(0) #(0 5 10 15 20 25 30 35 39 40)
mcs_list=(9)
repeat=1
TEST_FOLDER=$HOME/test_usrp
[ -d $TEST_FOLDER ] || mkdir $TEST_FOLDER
for i in ${!atten_list[@]}; do
python3 run_sl_test.py -m $message_to_send -r $num_repeat \
-u $user_id --host $remote_host_ip \
--att ${atten_list[$i]} \
--save test_att_${atten_list[$i]}.txt
for j in ${!mcs_list[@]}; do
python3 run_sl_test.py --repeat $repeat \
-u $user_id --host $remote_host_ip \
--att ${atten_list[$i]} \
--mcs ${mcs_list[$j]} \
--save $TEST_FOLDER/att_${atten_list[$i]}_mcs_${mcs_list[$j]}.txt \
# -m $message_to_send
done
done
......@@ -28,6 +28,7 @@ import re
import glob
import subprocess
from subprocess import Popen
from subprocess import check_output
import threading
from typing import Dict
from queue import Queue
......@@ -74,6 +75,10 @@ parser.add_argument('--message', '-m', type=str, default='EpiScience', help="""
The message to send from SyncRef UE to Nearby UE
""")
parser.add_argument('--mcs', default=9, type=int, help="""
The default mcs value (default: %(default)s)
""")
parser.add_argument('--commands', default='sl_cmds.txt', help="""
The USRP Commands .txt file (default: %(default)s)
""")
......@@ -112,14 +117,14 @@ Enable debug logging (for this script only)
""")
parser.add_argument('--save', default=None, help="""
The default Python log result with .txt extention (default: %(default)s)
The default Python log result with .txt extension (default: %(default)s)
""")
parser.add_argument('--sci2', action='store_true', help="""
Enable SCI2 log parsing (this will grep the logs for the SCI2 payload)
""")
parser.add_argument('--test', '-t', default='usrp_b210', choices='psbchsim psschsim rfsim usrp_b210 usrp_n310'.split(), help="""
parser.add_argument('--test', '-t', default='usrp_n310', choices='psbchsim psschsim rfsim usrp_b210 usrp_n310'.split(), help="""
The kind of test scenario to run. The options include psbchsim, psschsim, rfsim, or usrp_b210 usrp_n310. (default: %(default)s)
""")
......@@ -244,7 +249,7 @@ class TestThread(threading.Thread):
while not self.queue.empty():
job = self.queue.get()
if "nearby" == job:
thread_delay(delay = 3)
thread_delay(delay = 5)
self.launch_nearby(job)
if "syncref" == job and not OPTS.no_run:
thread_delay(delay = self.delay)
......@@ -257,21 +262,21 @@ class TestThread(threading.Thread):
LOGGER.info('Launching SyncRef UE')
if OPTS.basic: cmd = redirect_output('uname -a', self.log_file)
else: cmd = self.commands.launch_cmds[job]
cmd = cmd[:-1] + f' --message {OPTS.message}'
cmd = cmd[:-1] + f' --message {OPTS.message}' + f' --mcs {OPTS.mcs}'
proc = Popen(cmd, shell=True)
LOGGER.info(f"syncref_proc = {proc}")
if not OPTS.basic and not OPTS.no_run:
LOGGER.info("Process running... %s", job)
time.sleep(OPTS.duration)
time.sleep(OPTS.duration + 10)
self.kill_process("syncref", proc)
def launch_nearby(self, job, host=OPTS.host, user=OPTS.user) -> Popen:
LOGGER.info('#' * 42)
LOGGER.info('Launching Nearby UE')
if OPTS.basic: cmd = redirect_output('uname -a', self.log_file)
else: cmd = self.commands.launch_cmds[job]
if 'usrp' in OPTS.test:
cmd = cmd[:-1] + f' -d {OPTS.duration} --nid1 {OPTS.nid1} --nid2 {OPTS.nid2}'
cmd = cmd[:-2] + f' --mcs {OPTS.mcs}' + cmd[-2] # cmd[-2] is ' (end of cmd)
cmd = cmd + f' -d {OPTS.duration} --nid1 {OPTS.nid1} --nid2 {OPTS.nid2}'
proc = Popen(["ssh", f"{user}@{host}", cmd],
shell=False,
stdout=subprocess.PIPE,
......@@ -333,12 +338,15 @@ class TestThread(threading.Thread):
# ----------------------------------------------------------------------------
def set_attenuation(attenuation, host, user) -> Popen:
def set_attenuation(attenuation, atten_host, user) -> Popen:
if OPTS.att >= 0:
LOGGER.info('Setting attenuation')
cmd = f'curl http://169.254.10.10/:CHAN:3:SETATT:{attenuation}'
Popen(["ssh", f"{user}@{host}", cmd],
shell=False,
atten_cmd = f"curl http://169.254.10.10/:CHAN:3:SETATT:{attenuation}"
LOCAL_IP = check_output(['hostname', '-I']).decode().strip().split()[0]
cmd = [atten_cmd] if atten_host == LOCAL_IP else ["ssh", f"{user}@{atten_host}", atten_cmd]
shell_flag = True if atten_host == LOCAL_IP else False
Popen(cmd,
shell=shell_flag,
stdout=subprocess.PIPE,
stderr=subprocess.PIPE)
LOGGER.info(f"attenuation value = {attenuation}")
......@@ -366,6 +374,7 @@ def main() -> int:
sync_duration_list = []
set_attenuation(OPTS.att, OPTS.att_host, OPTS.att_user)
for i in range(OPTS.repeat):
LOGGER.info('-' * 42)
threads = []
queue = Queue()
for job in jobs:
......@@ -391,24 +400,27 @@ def main() -> int:
else:
LOGGER.info(f"Failure detected during {i+1}/{OPTS.repeat} trial(s).")
num_passed = len(passed_metric)
LOGGER.info('#' * 42)
if 'nearby' in jobs:
LOGGER.info(f"Number of passed = {len(passed_metric)}/{OPTS.repeat}")
if len(num_tx_ssb) > 0:
LOGGER.info(f"Avg number of SSB = {sum(num_tx_ssb) / len(num_tx_ssb)} ({num_tx_ssb})")
if len(passed_metric) > 0:
sum_nb_decoded, sum_total_rx = sum(nb_decoded_list), sum(total_rx_list)
avg_bler = (float) (sum_total_rx - sum_nb_decoded) / sum_total_rx if sum_total_rx > 0 else 1
LOGGER.info(f"Avg PSSCH RSRP = {sum(pssch_rsrp_list) / len(passed_metric):.2f}")
LOGGER.info(f"Avg SSB RSRP = {sum(ssb_rsrp_list) / len(passed_metric):.2f}")
LOGGER.info(f"Avg BLER = {avg_bler:.2f} with {sum_nb_decoded} / {sum_total_rx}")
LOGGER.info(f"Avg Sync duration (seconds) = {sum(sync_duration_list) / len(passed_metric):.2f}")
LOGGER.info(f"pssch_rsrp_list = {pssch_rsrp_list}")
LOGGER.info(f"ssb_rsrp_list = {ssb_rsrp_list}")
LOGGER.info(f"nb_decoded_list = {nb_decoded_list}")
LOGGER.info(f"total_rx_list = {total_rx_list}")
LOGGER.info('-' * 42)
return 0
LOGGER.info('#' * 42)
LOGGER.info(f"Attenuation value {OPTS.att}, MCS value {OPTS.mcs}")
if 'nearby' in jobs:
LOGGER.info(f"Number of synced = {len(passed_metric)}/{OPTS.repeat}")
if len(num_tx_ssb) > 0:
LOGGER.info(f"Avg number of SSB = {sum(num_tx_ssb) / len(num_tx_ssb)} ({num_tx_ssb})")
if len(passed_metric) > 0:
sum_nb_decoded, sum_total_rx = sum(nb_decoded_list), sum(total_rx_list)
avg_bler = (float) (sum_total_rx - sum_nb_decoded) / sum_total_rx if sum_total_rx > 0 else 1
avg_bldr = (float) (sum_nb_decoded) / sum_total_rx if sum_total_rx > 0 else 1
LOGGER.info(f"Avg PSSCH RSRP = {sum(pssch_rsrp_list) / len(passed_metric):.2f}")
LOGGER.info(f"Avg SSB RSRP = {sum(ssb_rsrp_list) / len(passed_metric):.2f}")
LOGGER.info(f"Avg BLER = {avg_bler:.3f} with {sum_total_rx - sum_nb_decoded} / {sum_total_rx}")
LOGGER.info(f"Avg BLDecodedRate = {avg_bldr:.3f} with {sum_nb_decoded} / {sum_total_rx}")
LOGGER.info(f"Avg Sync duration (seconds) = {sum(sync_duration_list) / len(passed_metric):.2f}")
LOGGER.info(f"pssch_rsrp_list = {pssch_rsrp_list}")
LOGGER.info(f"ssb_rsrp_list = {ssb_rsrp_list}")
LOGGER.info(f"nb_decoded_list = {nb_decoded_list}")
LOGGER.info(f"total_rx_list = {total_rx_list}")
LOGGER.info('-' * 42)
time.sleep(10)
return 0
sys.exit(main())
......@@ -33,7 +33,7 @@ nearby_usrp_n310_cmd = cd $HOME/openairinterface5g/ci-scripts; \
python3 sl_rx_agent.py --cmd \
'sudo -E LD_LIBRARY_PATH=$HOME/openairinterface5g/cmake_targets/ran_build/build:$LD_LIBRARY_PATH \
$HOME/openairinterface5g/cmake_targets/ran_build/build/nr-uesoftmodem \
--sl-mode 2 --rbsl 106 --numerology 1 --band 38 --SLC 2600000000 --ue-rxgain 70 \
--sl-mode 2 --rbsl 52 --numerology 1 --band 38 --SLC 2600000000 --ue-rxgain 20 \
--usrp-args "type=n3xx,addr=192.168.20.2,subdev=A:0,master_clock_rate=122.88e6" \
--log_config.global_log_options time,nocolor \
> ~/rx.log 2>&1'
......@@ -42,9 +42,9 @@ $HOME/openairinterface5g/cmake_targets/ran_build/build/nr-uesoftmodem \
syncref_usrp_n310_cmd = \
sudo -E LD_LIBRARY_PATH=$HOME/openairinterface5g/cmake_targets/ran_build/build:$LD_LIBRARY_PATH \
$HOME/openairinterface5g/cmake_targets/ran_build/build/nr-uesoftmodem \
--sl-mode 2 --sync-ref --rbsl 106 --numerology 1 --band 38 --SLC 2600000000 --ue-txgain 8 \
--sl-mode 2 --sync-ref --rbsl 52 --numerology 1 --band 38 --SLC 2600000000 --ue-txgain 0 \
--usrp-args "type=n3xx,addr=192.168.10.2,subdev=A:0,master_clock_rate=122.88e6" \
--log_config.global_log_options time,nocolor\
--log_config.global_log_options time,nocolor \
> ~/tx.log 2>&1
......
......@@ -6,7 +6,7 @@
# python3 sl_rx_agent.py \
# --cmd 'sudo -E LD_LIBRARY_PATH=$HOME/openairinterface5g/cmake_targets/ran_build/build:$LD_LIBRARY_PATH \
# $HOME/openairinterface5g/cmake_targets/ran_build/build/nr-uesoftmodem \
# --sl-mode 2 -r 106 --numerology 1 --band 38 -C 2600000000 --ue-rxgain 90 \
# --sl-mode 2 -r 52 --numerology 1 --band 38 -C 2600000000 --ue-rxgain 20 \
# --usrp-args "type=n3xx,addr=192.168.20.2,subdev=A:0,master_clock_rate=122.88e6" \
# > ~/rx.log 2>&1' \
# --nid1 10 --nid2 1
......
......@@ -74,6 +74,7 @@
#define CONFIG_HLP_ULBW_PHYTEST "Set the number of PRBs used for ULSCH in PHYTEST mode\n"
#define CONFIG_HLP_PRB_SA "Set the number of PRBs for SA\n"
#define CONFIG_HLP_PRB_SL "Set the number of PRBs for Sidelink\n"
#define CONFIG_HLP_PRB_IMCS "Set the index of default MCS for Sidelink\n"
#define CONFIG_HLP_DLBM_PHYTEST "Bitmap for DLSCH slots (slot 0 starts at LSB)\n"
#define CONFIG_HLP_ULBM_PHYTEST "Bitmap for ULSCH slots (slot 0 starts at LSB)\n"
#define CONFIG_HLP_SSC "Set the start subcarrier \n"
......
......@@ -833,19 +833,20 @@ int computeSamplesShift(PHY_VARS_NR_UE *UE) {
return samples_shift;
}
static inline int get_firstSymSamp(uint16_t slot, NR_DL_FRAME_PARMS *fp) {
static inline int get_firstSymSamp(uint16_t slot, NR_DL_FRAME_PARMS *fp, bool sync) {
uint16_t nb_prefix_samples0 = sync ? fp->nb_prefix_samples0 : fp->nb_prefix_samples;
if (fp->numerology_index == 0)
return fp->nb_prefix_samples0 + fp->ofdm_symbol_size;
int num_samples = (slot % (fp->slots_per_subframe / 2)) ? fp->nb_prefix_samples : fp->nb_prefix_samples0;
int num_samples = (slot % (fp->slots_per_subframe / 2)) ? fp->nb_prefix_samples : nb_prefix_samples0;
num_samples += fp->ofdm_symbol_size;
return num_samples;
}
static inline int get_readBlockSize(uint16_t slot, NR_DL_FRAME_PARMS *fp) {
int rem_samples = fp->get_samples_per_slot(slot, fp) - get_firstSymSamp(slot, fp);
static inline int get_readBlockSize(uint16_t slot, NR_DL_FRAME_PARMS *fp, bool sync) {
int rem_samples = fp->get_samples_per_slot(slot, fp) - get_firstSymSamp(slot, fp, sync);
int next_slot_first_symbol = 0;
if (slot < (fp->slots_per_frame-1))
next_slot_first_symbol = get_firstSymSamp(slot+1, fp);
next_slot_first_symbol = get_firstSymSamp(slot+1, fp, sync);
return rem_samples + next_slot_first_symbol;
}
......@@ -898,7 +899,6 @@ void *UE_thread_SL(void *arg) {
int nbSlotProcessing = 0;
int thread_idx = 0;
NR_UE_MAC_INST_t *mac = get_mac_inst(0);
int timing_advance = UE->timing_advance;
UE->lost_sync_sl = 0;
......@@ -972,11 +972,13 @@ void *UE_thread_SL(void *arg) {
syncInFrame(UE, &timestamp);
UE->rx_offset_sl = 0;
UE->time_sync_cell = 0;
AssertFatal (UE->frame_parms.ofdm_symbol_size + UE->frame_parms.nb_prefix_samples0 ==
uint16_t nb_prefix_samples0 = UE->is_synchronized_sl ? UE->frame_parms.nb_prefix_samples0 :
UE->frame_parms.nb_prefix_samples;
AssertFatal (UE->frame_parms.ofdm_symbol_size + nb_prefix_samples0 ==
UE->rfdevice.trx_read_func(&UE->rfdevice,
&timestamp,
(void **)UE->common_vars.rxdata,
UE->frame_parms.ofdm_symbol_size + UE->frame_parms.nb_prefix_samples0,
UE->frame_parms.ofdm_symbol_size + nb_prefix_samples0,
UE->frame_parms.nb_antennas_rx), "Could not read in first symbol");
// we have the decoded frame index in the return of the synch process
// and we shifted above to the first slot of next frame
......@@ -1011,7 +1013,7 @@ void *UE_thread_SL(void *arg) {
curMsg->proc.frame_tx = ((absolute_slot+DURATION_RX_TO_TX)/nb_slot_frame) % MAX_FRAME_NUMBER;
curMsg->proc.decoded_frame_rx=-1;
int firstSymSamp = get_firstSymSamp(slot_nr, &UE->frame_parms);
int firstSymSamp = get_firstSymSamp(slot_nr, &UE->frame_parms, UE->is_synchronized_sl);
uint64_t write_time_stamp = UE->frame_parms.get_samples_slot_timestamp(slot_nr, &UE->frame_parms, 0);
uint64_t read_time_stamp = UE->frame_parms.get_samples_slot_timestamp(slot_nr, &UE->frame_parms, 0);
for (int i = 0; i<UE->frame_parms.nb_antennas_rx; i++)
......@@ -1021,11 +1023,11 @@ void *UE_thread_SL(void *arg) {
int readBlockSize, writeBlockSize;
if (slot_nr < (nb_slot_frame - 1)) {
readBlockSize = get_readBlockSize(slot_nr, &UE->frame_parms);
readBlockSize = get_readBlockSize(slot_nr, &UE->frame_parms, UE->is_synchronized_sl);
writeBlockSize = UE->frame_parms.get_samples_per_slot(slot_nr, &UE->frame_parms);
} else {
UE->rx_offset_diff = computeSamplesShift(UE);
readBlockSize = get_readBlockSize(slot_nr, &UE->frame_parms) - UE->rx_offset_diff;
readBlockSize = get_readBlockSize(slot_nr, &UE->frame_parms, UE->is_synchronized_sl) - UE->rx_offset_diff;
writeBlockSize = UE->frame_parms.get_samples_per_slot(slot_nr, &UE->frame_parms) - UE->rx_offset_diff;
}
......@@ -1038,7 +1040,10 @@ void *UE_thread_SL(void *arg) {
if (slot_nr == (nb_slot_frame - 1)) {
// read in first symbol of next frame and adjust for timing drift
int first_symbols = UE->frame_parms.ofdm_symbol_size + UE->frame_parms.nb_prefix_samples0;
uint16_t nb_prefix_samples0 = UE->is_synchronized_sl ? UE->frame_parms.nb_prefix_samples0 :
UE->frame_parms.nb_prefix_samples;
int first_symbols = UE->frame_parms.ofdm_symbol_size + nb_prefix_samples0;
if (first_symbols > 0) {
openair0_timestamp ignore_timestamp;
AssertFatal(first_symbols ==
......@@ -1242,7 +1247,7 @@ void *UE_thread(void *arg) {
}*/
#endif
int firstSymSamp = get_firstSymSamp(slot_nr, &UE->frame_parms);
int firstSymSamp = get_firstSymSamp(slot_nr, &UE->frame_parms, UE->is_synchronized_sl);
for (int i=0; i<UE->frame_parms.nb_antennas_rx; i++)
rxp[i] = (void *)&UE->common_vars.rxdata[i][firstSymSamp+
UE->frame_parms.get_samples_slot_timestamp(slot_nr,&UE->frame_parms,0)];
......@@ -1254,11 +1259,11 @@ void *UE_thread(void *arg) {
int readBlockSize, writeBlockSize;
if (slot_nr<(nb_slot_frame - 1)) {
readBlockSize=get_readBlockSize(slot_nr, &UE->frame_parms);
readBlockSize=get_readBlockSize(slot_nr, &UE->frame_parms, UE->is_synchronized);
writeBlockSize=UE->frame_parms.get_samples_per_slot((slot_nr + DURATION_RX_TO_TX - NR_RX_NB_TH) % nb_slot_frame, &UE->frame_parms);
} else {
UE->rx_offset_diff = computeSamplesShift(UE);
readBlockSize=get_readBlockSize(slot_nr, &UE->frame_parms) -
readBlockSize=get_readBlockSize(slot_nr, &UE->frame_parms, UE->is_synchronized) -
UE->rx_offset_diff;
writeBlockSize=UE->frame_parms.get_samples_per_slot((slot_nr + DURATION_RX_TO_TX - NR_RX_NB_TH) % nb_slot_frame, &UE->frame_parms)- UE->rx_offset_diff;
}
......
......@@ -39,7 +39,7 @@
{"uecap_file", CONFIG_HLP_UECAP_FILE, 0, strptr:&uecap_file, defstrval:"./uecap.xml", TYPE_STRING, 0}, \
{"rrc_config_path", CONFIG_HLP_RRC_CFG_PATH,0, strptr:&rrc_config_path, defstrval:"./", TYPE_STRING, 0}, \
{"ue-idx-standalone", NULL, 0, u16ptr:&ue_idx_standalone, defuintval:0xFFFF, TYPE_UINT16, 0}, \
{"SLC", CONFIG_HLP_SLF, 0, u64ptr:&(sidelink_frequency[0][0]), defuintval:2600000000, TYPE_UINT64, 0}, \
{"SLC", CONFIG_HLP_SLF, 0, u64ptr:&(sidelink_frequency[0][0]), defuintval:2570000000, TYPE_UINT64, 0}, \
}
......@@ -67,6 +67,7 @@
{"E" , CONFIG_HLP_TQFS, PARAMFLAG_BOOL, u8ptr:&(fp->threequarter_fs), defintval:0, TYPE_UINT8, 0}, \
{"r" , CONFIG_HLP_PRB_SA, 0, iptr:&(fp->N_RB_DL), defintval:106, TYPE_UINT, 0}, \
{"rbsl", CONFIG_HLP_PRB_SL, 0, iptr:&(fp->N_RB_SL), defintval:106, TYPE_UINT, 0}, \
{"mcs", CONFIG_HLP_PRB_IMCS, 0, uptr:&(fp->Imcs), defintval:9, TYPE_UINT, 0}, \
{"ssb", CONFIG_HLP_SSC, 0, u16ptr:&(fp->ssb_start_subcarrier), defintval:516, TYPE_UINT16,0}, \
{"T" , CONFIG_HLP_TDD, PARAMFLAG_BOOL, iptr:&tddflag, defintval:0, TYPE_INT, 0}, \
{"if_freq" , CONFIG_HLP_IF_FREQ, 0, u64ptr:&(UE->if_freq), defuintval:0, TYPE_UINT64,0}, \
......
......@@ -47,18 +47,37 @@ int nr_slot_fep(PHY_VARS_NR_UE *ue,
AssertFatal(symbol < frame_parms->symbols_per_slot, "slot_fep: symbol must be between 0 and %d\n", frame_parms->symbols_per_slot-1);
AssertFatal(Ns < frame_parms->slots_per_frame, "slot_fep: Ns must be between 0 and %d\n", frame_parms->slots_per_frame-1);
unsigned int nb_prefix_samples;
unsigned int nb_prefix_samples0;
bool is_synced = ue->is_synchronized;
if(get_softmodem_params()->sl_mode == 2) {
is_synced = ue->is_synchronized_sl;
}
if (is_synced) {
nb_prefix_samples = frame_parms->nb_prefix_samples;
nb_prefix_samples0 = frame_parms->nb_prefix_samples0;
} else {
nb_prefix_samples = frame_parms->nb_prefix_samples;
nb_prefix_samples0 = frame_parms->nb_prefix_samples;
}
dft_size_idx_t dftsize = get_dft(frame_parms->ofdm_symbol_size);
// This is for misalignment issues
int32_t tmp_dft_in[8192] __attribute__ ((aligned (32)));
unsigned int rx_offset = frame_parms->get_samples_slot_timestamp(Ns,frame_parms,0);
rx_offset += frame_parms->nb_prefix_samples0;
rx_offset += (frame_parms->ofdm_symbol_size + frame_parms->nb_prefix_samples) * symbol;
unsigned int abs_symbol = Ns * frame_parms->symbols_per_slot + symbol;
for (int idx_symb = Ns*frame_parms->symbols_per_slot; idx_symb <= abs_symbol; idx_symb++)
rx_offset += (idx_symb%(0x7<<frame_parms->numerology_index)) ? nb_prefix_samples : nb_prefix_samples0;
rx_offset += frame_parms->ofdm_symbol_size * symbol;
// use OFDM symbol from within 1/8th of the CP to avoid ISI
rx_offset -= (nb_prefix_samples / frame_parms->ofdm_offset_divisor);
//#ifdef DEBUG_FEP
// if (ue->frame <100)
LOG_D(PHY,"slot_fep: slot %d, symbol %d, nb_prefix_samples %u, nb_prefix_samples0 %u, rx_offset %u energy %d\n",
Ns, symbol, frame_parms->nb_prefix_samples, frame_parms->nb_prefix_samples0, rx_offset, dB_fixed(signal_energy(&common_vars->rxdata[0][rx_offset],frame_parms->ofdm_symbol_size)));
Ns, symbol, nb_prefix_samples, nb_prefix_samples0, rx_offset, dB_fixed(signal_energy(&common_vars->rxdata[0][rx_offset],frame_parms->ofdm_symbol_size)));
//#endif
for (unsigned char aa=0; aa<frame_parms->nb_antennas_rx; aa++) {
......@@ -146,8 +165,20 @@ int nr_slot_fep_init_sync(PHY_VARS_NR_UE *ue,
AssertFatal(symbol < frame_parms->symbols_per_slot, "slot_fep: symbol must be between 0 and %d\n", frame_parms->symbols_per_slot-1);
AssertFatal(Ns < frame_parms->slots_per_frame, "slot_fep: Ns must be between 0 and %d\n", frame_parms->slots_per_frame-1);
unsigned int nb_prefix_samples = frame_parms->nb_prefix_samples;
unsigned int nb_prefix_samples0 = frame_parms->nb_prefix_samples0;
unsigned int nb_prefix_samples;
unsigned int nb_prefix_samples0;
bool is_synced = ue->is_synchronized;
if(get_softmodem_params()->sl_mode == 2) {
is_synced = ue->is_synchronized_sl;
}
if (is_synced) {
nb_prefix_samples = frame_parms->nb_prefix_samples;
nb_prefix_samples0 = frame_parms->nb_prefix_samples0;
}
else {
nb_prefix_samples = frame_parms->nb_prefix_samples;
nb_prefix_samples0 = frame_parms->nb_prefix_samples;
}
unsigned int frame_length_samples = frame_parms->samples_per_frame;
dft_size_idx_t dftsize = get_dft(frame_parms->ofdm_symbol_size);
......@@ -156,8 +187,10 @@ int nr_slot_fep_init_sync(PHY_VARS_NR_UE *ue,
unsigned int slot_offset = frame_parms->get_samples_slot_timestamp(Ns,frame_parms,0);
unsigned int rx_offset = sample_offset + slot_offset;
rx_offset += nb_prefix_samples0;
rx_offset += (frame_parms->ofdm_symbol_size + nb_prefix_samples) * symbol;
unsigned int abs_symbol = Ns * frame_parms->symbols_per_slot + symbol;
for (int idx_symb = Ns*frame_parms->symbols_per_slot; idx_symb <= abs_symbol; idx_symb++)
rx_offset += (abs_symbol%(0x7<<frame_parms->numerology_index)) ? nb_prefix_samples : nb_prefix_samples0;
rx_offset += frame_parms->ofdm_symbol_size * symbol;
#ifdef DEBUG_FEP
LOG_I(NR_PHY, "slot_fep: slot %d, symbol %d, nb_prefix_samples %u, nb_prefix_samples0 %u, slot_offset %u, sample_offset %d,rx_offset %u, frame_length_samples %u\n",
......@@ -303,7 +336,7 @@ void apply_nr_rotation_ul(NR_DL_FRAME_PARMS *frame_parms,
c16_t rot2 = frame_parms->symbol_rotation[link_type][symbol + symb_offset];
rot2.i=-rot2.i;
LOG_D(PHY,"slot %d, symb_offset %d rotating by %d.%d\n",slot,symb_offset,rot2.r,rot2.i);
LOG_I(PHY,"slot %d, symb_offset %d rotating by %d.%d\n",slot,symb_offset,rot2.r,rot2.i);
c16_t *shift_rot = frame_parms->timeshift_symbol_rotation;
c16_t *this_symbol = (c16_t *)&rxdataF[soffset+(frame_parms->ofdm_symbol_size*symbol)];
......@@ -336,4 +369,5 @@ void apply_nr_rotation_ul(NR_DL_FRAME_PARMS *frame_parms,
1, N_RB * 6, 15);
}
}
}
......@@ -70,7 +70,7 @@
#define SSS_SYMBOL_NB ((2) + OFFSET_SS_PBCH)
#define PBCH_LAST_SYMBOL_NB ((3) + OFFSET_SS_PBCH)
#define OFFSET_SS_PSBCH 0
#define OFFSET_SS_PSBCH -1
#define PSS0_SL_SYMBOL_NB ((1) + OFFSET_SS_PSBCH)
#define PSS1_SL_SYMBOL_NB ((2) + OFFSET_SS_PSBCH)
#define SSS0_SL_SYMBOL_NB ((3) + OFFSET_SS_PSBCH)
......
......@@ -278,25 +278,25 @@ int nr_sl_initial_sync(UE_nr_rxtx_proc_t *proc,
int32_t sync_pos = 0, sync_pos_frame;
for (int is = 0; is < n_frames; is++) {
sync_pos = pss_synchro_nr(ue, is, NO_RATE_CHANGE);
// In 5G SL, the first SSB symbol is the PSBCH, so we need adjust the SSB
// offset accordingly (psbch_plus_prefix_size). Additionally, there are 2
// PSS symbols.
// However, if we correlated on the second PSS, we do not need to include an offset
// the size of the first PSS0, becasue the correlation occurs on each individual PSS.
// The sync_pos will ALWAYS point at the start of the first PSS (PSS0) becasue
// it is just the peak position in the correlation related to the ref symbols.
// PSBCH PREFIX | PSBCH 0 | PSS 0 PREFIX | PSS 0 | PSS 1 PREFIX | PSS 1 |
// 176 | 2048 | 144 | 2048 | 144 | 2048 |
// 176 | 2048 | 144 | - | - | X | SSB Start = X - (176 + 2048 + 144)
// 176 | 2048 | 144 | X | 144 | 2048 | SSB Start = X - (176 + 2048 + 144)
uint32_t psbch_plus_prefix_size = fp->ofdm_symbol_size + fp->nb_prefix_samples0;
uint32_t pss_plus_prefix_size = fp->nb_prefix_samples;
if (sync_pos >= psbch_plus_prefix_size + pss_plus_prefix_size) {
LOG_I(NR_PHY, "This is pss_plus_prefix_size %d, psbch_plus_prefix_size %d, sync_pos %d, N2_id %d\n",
pss_plus_prefix_size, psbch_plus_prefix_size, sync_pos, ue->common_vars.N2_id);
ue->ssb_offset = sync_pos - (pss_plus_prefix_size + psbch_plus_prefix_size);
if (sync_pos >= fp->nb_prefix_samples) {
// In 5G SL, the first SSB symbol is the PSBCH, so we need adjust the SSB
// offset accordingly (psbch_plus_prefix_size). Additionally, there are 2
// PSS symbols. So in the case where we correlate on the second PSS,
// we need to adjust the SSB offset accordingly (subtracting first PSS prefix).
// However, if we correlated on the second PSS, we do not need to include
// the size of the first PSS0, becasue the correlation occurs on each individual PSS.
// The sync position (sync_pos) is the start of the found PSS + nb_prefix_samples.
// PSBCH PREFIX | PSBCH 0 | PSS 0 PREFIX | PSS 0 | PSS 1 PREFIX | PSS 1 |
// 144 | 2048 | 144 | 2048 | 144 | 2048 |
// 144 | 2048 | 144 | - | 144 | X | SSB Start = X - (144 + 144 + 2048 + 144)
// 144 | 2048 | 144 | X | 144 | 2048 | SSB Start = X - (144 + 2048 + 144)
uint32_t psbch_plus_prefix_size = fp->ofdm_symbol_size + fp->nb_prefix_samples;
uint32_t num_pss_prefix_samples_size = (ue->common_vars.N2_id + 1) * fp->nb_prefix_samples;
LOG_I(NR_PHY, "This is num_pss_prefix_samples_size %d, psbch_plus_prefix_size %d, sync_pos %d, N2_id %d\n",
num_pss_prefix_samples_size, psbch_plus_prefix_size, sync_pos, ue->common_vars.N2_id);
ue->ssb_offset = sync_pos - num_pss_prefix_samples_size - psbch_plus_prefix_size;
} else {
ue->ssb_offset = sync_pos + fp->samples_per_frame - (pss_plus_prefix_size + psbch_plus_prefix_size);
ue->ssb_offset = sync_pos + (fp->samples_per_subframe * 10) - fp->nb_prefix_samples;
}
LOG_I(NR_PHY, "[UE%d] Initial sync : n_frames %d Estimated PSS position %d, Nid2 %d ssb_offset %d\n",
ue->Mod_id, n_frames, sync_pos, ue->common_vars.N2_id, ue->ssb_offset);
......
......@@ -300,7 +300,7 @@ void nr_sl_common_signal_procedures(PHY_VARS_NR_UE *ue, int frame, int slot)
NR_DL_FRAME_PARMS *fp = &ue->frame_parms;
int **txdataF = ue->common_vars.txdataF;
uint8_t ssb_index = 0; //TODO: Need update to get 0 or 1 from parameter in case of mu = 1.
const int txdataF_offset = slot * ue->frame_parms.get_samples_per_slot(slot, &ue->frame_parms);
int txdataF_offset = slot * fp->samples_per_slot_wCP;
uint16_t ssb_start_symbol = 0;
LOG_D(NR_PHY, "common_signal_procedures: frame %d, slot %d ssb index %d, ssb_start_symbol %d, txdataF_offset %d\n",
......
......@@ -30,6 +30,7 @@
#include "common/utils/LOG/vcd_signal_dumper.h"
#include <openair2/UTIL/OPT/opt.h>
#include <inttypes.h>
#include "executables/softmodem-common.h"
//#define DEBUG_SLSCH_CODING
#define NR_POLAR_SCI2_MESSAGE_TYPE 4
......@@ -167,14 +168,14 @@ NR_UE_ULSCH_t *new_nr_ue_slsch(uint16_t N_RB_UL, int number_of_harq_pids, NR_DL_
return(slsch);
}
uint16_t polar_encoder_output_length(NR_UL_UE_HARQ_t *harq_process) {
uint16_t polar_encoder_output_length(uint16_t target_code_rate, uint32_t num_of_mod_symbols) {
// calculating length of sequence comming out of rate matching for SCI2 based on 8.4.4 TS38212
uint8_t Osci2 = NR_POLAR_SCI2_PAYLOAD_BITS;
uint8_t Lsci2 = 24;
uint8_t Qmsci2 = 2; //modulation order of SCI2
double beta = 1.125; // harq_process->pssch_pdu.sci1.beta_offset;
double alpha = 1; // hardcoded for now
float R = (float)harq_process->pssch_pdu.target_code_rate / (1024*10);
double beta = 1.125; // TODO: harq_process->pssch_pdu.sci1.beta_offset;
double alpha = 1; // hardcoded sl-Scaling-r16 for now among {f0p5, f0p65, f0p8, f1}
float R = (float)target_code_rate / (1024 * 10);
double tmp1 = (Osci2 + Lsci2) * beta / (Qmsci2 * R);
/*
......@@ -184,9 +185,10 @@ uint16_t polar_encoder_output_length(NR_UL_UE_HARQ_t *harq_process) {
uint8_t N_pssch_symb = N_sh_sym - N_psfch_symb;
*/
double tmp2 = alpha * harq_process->num_of_mod_symbols; // it is assumed that number of RB for PSCCH is 0.
int gamma = 461;
uint16_t Qprime = min(ceil(tmp1), ceil(tmp2)) + gamma;
double tmp2 = alpha * num_of_mod_symbols; // it is assumed that number of RB for PSCCH is NB_RB_SCI1.
uint16_t Qprime = min(ceil(tmp1), ceil(tmp2));
int spare = 16 - Qprime % 16;
Qprime += spare;
uint16_t Gsci2 = Qprime * Qmsci2;
return Gsci2;
}
......@@ -201,6 +203,41 @@ void byte2bit(uint8_t *in_bytes, uint8_t *out_bits, uint16_t num_bytes) {
return;
}
static void check_Nidx_value(uint32_t nidx, NR_DL_FRAME_PARMS* fp) {
switch(fp->Imcs) {
case 0:
AssertFatal(nidx == 45727, "Invalid nidx size %d for MCS %d!\n", nidx, fp->Imcs);
break;
case 1:
AssertFatal(nidx == 45727, "Invalid nidx size %d for MCS %d!\n", nidx, fp->Imcs);
break;
case 2:
AssertFatal(nidx == 45727, "Invalid nidx size %d for MCS %d!\n", nidx, fp->Imcs);
break;
case 3:
AssertFatal(nidx == 45727, "Invalid nidx size %d for MCS %d!\n", nidx, fp->Imcs);
break;
case 4:
AssertFatal(nidx == 45727, "Invalid nidx size %d for MCS %d!\n", nidx, fp->Imcs);
break;
case 5:
AssertFatal(nidx == 45727, "Invalid nidx size %d for MCS %d!\n", nidx, fp->Imcs);
break;
case 6:
AssertFatal(nidx == 45727, "Invalid nidx size %d for MCS %d!\n", nidx, fp->Imcs);
break;
case 7:
AssertFatal(nidx == 45727, "Invalid nidx size %d for MCS %d!\n", nidx, fp->Imcs);
break;
case 8:
AssertFatal(nidx == 45727, "Invalid nidx size %d for MCS %d!\n", nidx, fp->Imcs);
break;
case 9:
AssertFatal(nidx == 45727, "Invalid nidx size %d for MCS %d!\n", nidx, fp->Imcs);
break;
}
}
int nr_slsch_encoding(PHY_VARS_NR_UE *ue,
NR_UE_ULSCH_t *slsch,
NR_DL_FRAME_PARMS* frame_parms,
......@@ -237,7 +274,7 @@ int nr_slsch_encoding(PHY_VARS_NR_UE *ue,
LOG_D(NR_PHY, "encoding thinks this is a new packet \n");
#endif
int max_payload_bytes = MAX_NUM_NR_SLSCH_SEGMENTS_PER_LAYER * harq_process->pssch_pdu.nrOfLayers * 1056;
uint16_t polar_encoder_output_len = polar_encoder_output_length(harq_process);
uint16_t polar_encoder_output_len = polar_encoder_output_length(harq_process->pssch_pdu.target_code_rate, harq_process->num_of_mod_symbols);
polar_encoder_fast(harq_process->a_sci2, (void*)harq_process->b_sci2, 0, 0,
NR_POLAR_SCI2_MESSAGE_TYPE,
polar_encoder_output_len,
......@@ -246,6 +283,7 @@ int nr_slsch_encoding(PHY_VARS_NR_UE *ue,
NR_POLAR_SCI2_MESSAGE_TYPE,
polar_encoder_output_len,
NR_POLAR_SCI2_AGGREGATION_LEVEL);
check_Nidx_value(slsch->Nidx, frame_parms);
harq_process->B_sci2 = polar_encoder_output_len;
byte2bit(harq_process->b_sci2, harq_process->f_sci2, polar_encoder_output_len>>3);
/*
......
......@@ -90,6 +90,7 @@ bool nr_ue_sl_postDecode(PHY_VARS_NR_UE *phy_vars_ue, notifiedFIFO_elt_t *req, b
merge_meas(&phy_vars_ue->dlsch_ldpc_decoding_stats, &rdata->ts_ldpc_decode);
bool decodeSuccess = (rdata->decodeIterations < (1+dlsch->max_ldpc_iterations));
LOG_D(PHY, "rdata->decodeIterations %d\n", rdata->decodeIterations);
if (1) {
memcpy(harq_process->b+rdata->offset,
......
......@@ -146,29 +146,55 @@ void nr_pssch_data_control_multiplexing(uint8_t *in_slssh,
}
}
uint32_t get_B_multiplexed_value(NR_DL_FRAME_PARMS* fp, NR_DL_UE_HARQ_t *harq) {
uint8_t number_of_symbols = harq->nb_symbols ;
uint16_t nb_rb = harq->nb_rb;
uint8_t Nl = harq->Nl;
uint8_t mod_order = harq->Qm ;
uint16_t dmrs_pos = harq->dlDmrsSymbPos ;
uint16_t length_dmrs = get_num_dmrs(dmrs_pos);
uint8_t nb_dmrs_re_per_rb = 6 * harq->n_dmrs_cdm_groups;
unsigned int G_slsch_bits = nr_get_G(nb_rb, number_of_symbols, nb_dmrs_re_per_rb, length_dmrs, mod_order, Nl);
uint32_t B_mul = G_slsch_bits + harq->B_sci2 * Nl;
return B_mul;
}
static int get_PRB(int nb_rb) {
if (nb_rb > 25)
return (nb_rb / 25) * 25;
if (nb_rb > 9)
return (nb_rb / 5) * 5;
else
AssertFatal(1 == 0, "Not supported PRB");
}
void nr_ue_set_slsch_rx(PHY_VARS_NR_UE *ue, unsigned char harq_pid)
{
int nb_rb = ue->frame_parms.N_RB_SL;
int nb_rb = get_PRB(ue->frame_parms.N_RB_SL);
uint16_t nb_symb_sch = 12;
uint16_t nb_symb_cch = 3; // Assumption there are three SLCCH symbols
uint8_t dmrsConfigType = 0;
uint8_t nb_re_dmrs = 6;
uint8_t Nl = 1; // number of layers
uint8_t Imcs = 9;
uint8_t Imcs = ue->frame_parms.Imcs;
uint16_t dmrsSymbPos = 16 + 1024; // symbol 4 and 10
uint8_t length_dmrs = get_num_dmrs(dmrsSymbPos);
uint16_t start_symbol = 1; // start from 0
uint8_t SCI2_mod_order = 2;
uint8_t mod_order = nr_get_Qm_ul(Imcs, 0);
uint16_t code_rate = nr_get_code_rate_ul(Imcs, 0);
unsigned int TBS = 2048;//nr_compute_tbs(mod_order, code_rate, nb_rb, nb_symb_sch, nb_re_dmrs * length_dmrs, 0, 0, Nl);
LOG_D(NR_PHY, "\nTBS %u mod_order %d\n", TBS, mod_order);
LOG_D(NR_PHY, "\ncode_rate %u mod_order %d\n", code_rate, mod_order);
NR_UE_DLSCH_t *slsch_ue_rx = ue->slsch_rx[0][0][0];
NR_DL_UE_HARQ_t *harq = slsch_ue_rx->harq_processes[harq_pid];
harq->Nl = Nl;
harq->Qm = mod_order;
harq->nb_rb = nb_rb;
harq->TBS = TBS >> 3;
harq->n_dmrs_cdm_groups = 1;
harq->dlDmrsSymbPos = dmrsSymbPos;
harq->mcs = Imcs;
......@@ -177,14 +203,25 @@ void nr_ue_set_slsch_rx(PHY_VARS_NR_UE *ue, unsigned char harq_pid)
harq->nb_symbols = nb_symb_sch;
harq->codeword = 0;
harq->start_symbol = start_symbol;
harq->B_sci2 = 1024; // This should be updated from SCI1 parameter.
uint16_t nb_re_sci1 = nb_symb_cch * NB_RB_SCI1 * NR_NB_SC_PER_RB;
uint8_t N_PRB_oh = 0;
uint16_t nb_symb_psfch = 0;
uint8_t nb_codewords = 1;
uint16_t N_RE_prime = NR_NB_SC_PER_RB * (nb_symb_sch - nb_symb_psfch) - nb_re_dmrs - N_PRB_oh;
uint16_t num_of_mod_symbols = N_RE_prime * nb_rb * nb_codewords - nb_re_sci1;
harq->B_sci2 = polar_encoder_output_length(code_rate, num_of_mod_symbols);
uint16_t nb_re_sci2 = harq->B_sci2 / SCI2_mod_order;
unsigned int TBS = nr_compute_tbs_sl(mod_order, code_rate, nb_rb, nb_re_sci1, nb_re_sci2, nb_symb_sch, nb_re_dmrs * length_dmrs, 0, 0, Nl);
harq->TBS = TBS >> 3;
LOG_I(NR_PHY, "mcs %u polar_encoder_output_len %u, code_rate %d, TBS %d\n", Imcs, harq->B_sci2, code_rate, TBS);
harq->status = ACTIVE;
nfapi_nr_pssch_pdu_t *rel16_sl_rx = &harq->pssch_pdu;
rel16_sl_rx->mcs_index = Imcs;
rel16_sl_rx->pssch_data.rv_index = 0;
rel16_sl_rx->target_code_rate = code_rate;
rel16_sl_rx->pssch_data.tb_size = TBS >> 3; // bytes
rel16_sl_rx->pssch_data.sci2_size = SCI2_LEN_SIZE >> 3;
rel16_sl_rx->maintenance_parms_v3.ldpcBaseGraph = get_BG(TBS, code_rate);
rel16_sl_rx->nr_of_symbols = nb_symb_sch; // number of symbols per slot
......@@ -196,6 +233,7 @@ void nr_ue_set_slsch_rx(PHY_VARS_NR_UE *ue, unsigned char harq_pid)
rel16_sl_rx->bwp_start = 0;
rel16_sl_rx->rb_start = 0;
rel16_sl_rx->dmrs_config_type = dmrsConfigType;
rel16_sl_rx->pssch_data.tb_size = TBS >> 3;
}
void nr_ue_set_slsch(NR_DL_FRAME_PARMS *fp,
......@@ -207,9 +245,10 @@ void nr_ue_set_slsch(NR_DL_FRAME_PARMS *fp,
uint8_t nb_codewords = 1;
uint8_t N_PRB_oh = 0;
uint16_t nb_symb_sch = 12;
uint16_t nb_symb_cch = 3; // Assumption there are three SLCCH symbols
uint8_t nb_re_dmrs = 6;
int nb_rb = fp->N_RB_SL;
uint8_t Imcs = 9;
int nb_rb = get_PRB(fp->N_RB_SL);
uint8_t Imcs = fp->Imcs;
uint8_t Nl = 1; // number of layers
uint16_t start_symbol = 1; // start from 0
SCI_1_A *sci1 = &harq->pssch_pdu.sci1;
......@@ -226,8 +265,9 @@ void nr_ue_set_slsch(NR_DL_FRAME_PARMS *fp,
uint8_t length_dmrs = get_num_dmrs(dmrsSymbPos);
uint16_t code_rate = nr_get_code_rate_ul(Imcs, 0);
uint8_t mod_order = nr_get_Qm_ul(Imcs, 0);
uint16_t N_RE_prime = NR_NB_SC_PER_RB * nb_symb_sch - nb_re_dmrs - N_PRB_oh;
unsigned int TBS = 2048;//nr_compute_tbs(mod_order, code_rate, nb_rb, nb_symb_sch, nb_re_dmrs * length_dmrs, 0, 0, Nl);
uint16_t nb_symb_psfch = 0;
uint16_t N_RE_prime = NR_NB_SC_PER_RB * (nb_symb_sch - nb_symb_psfch) - nb_re_dmrs - N_PRB_oh;
uint16_t nb_re_sci1 = nb_symb_cch * NB_RB_SCI1 * NR_NB_SC_PER_RB;
harq->pssch_pdu.mcs_index = Imcs;
harq->pssch_pdu.nrOfLayers = Nl;
......@@ -236,7 +276,6 @@ void nr_ue_set_slsch(NR_DL_FRAME_PARMS *fp,
harq->pssch_pdu.dmrs_config_type = dmrsConfigType;
harq->num_of_mod_symbols = N_RE_prime * nb_rb * nb_codewords;
harq->pssch_pdu.pssch_data.rv_index = 0;
harq->pssch_pdu.pssch_data.tb_size = TBS >> 3;
harq->pssch_pdu.pssch_data.sci2_size = SCI2_LEN_SIZE >> 3;
harq->pssch_pdu.target_code_rate = code_rate;
harq->pssch_pdu.qam_mod_order = mod_order;
......@@ -246,6 +285,13 @@ void nr_ue_set_slsch(NR_DL_FRAME_PARMS *fp,
harq->pssch_pdu.transform_precoding = transformPrecoder_disabled;
harq->first_tx = 1;
uint16_t polar_encoder_output_len = polar_encoder_output_length(code_rate, harq->num_of_mod_symbols);
uint8_t SCI2_mod_order = 2;
uint16_t nb_re_sci2 = polar_encoder_output_len / SCI2_mod_order;
unsigned int TBS = nr_compute_tbs_sl(mod_order, code_rate, nb_rb, nb_re_sci1, nb_re_sci2, nb_symb_sch, nb_re_dmrs * length_dmrs, 0, 0, Nl);
LOG_D(NR_PHY, "mcs %u polar_encoder_output_len %u, code_rate %d, TBS %d\n", Imcs, polar_encoder_output_len, code_rate, TBS);
harq->pssch_pdu.pssch_data.tb_size = TBS >> 3;
harq->status = ACTIVE;
unsigned char *test_input = harq->a;
uint64_t *sci_input = harq->a_sci2;
......
......@@ -77,6 +77,8 @@ NR_UE_ULSCH_t *new_nr_ue_ulsch(uint16_t N_RB_UL, int number_of_harq_pids, NR_DL_
NR_UE_ULSCH_t *new_nr_ue_slsch(uint16_t N_RB_UL, int number_of_harq_pids, NR_DL_FRAME_PARMS* frame_parms);
uint16_t polar_encoder_output_length(uint16_t target_code_rate, uint32_t num_of_mod_symbols);
/** \brief This function computes the LLRs for ML (max-logsum approximation) dual-stream QPSK/QPSK reception.
@param stream0_in Input from channel compensated (MR combined) stream 0
@param stream1_in Input from channel compensated (MR combined) stream 1
......@@ -1869,6 +1871,7 @@ void nr_pssch_data_control_multiplexing(uint8_t *in_slssh,
uint8_t Q_SCI2,
uint8_t* out);
uint32_t get_B_multiplexed_value(NR_DL_FRAME_PARMS* fp, NR_DL_UE_HARQ_t *harq);
/**@}*/
#endif
......@@ -95,7 +95,8 @@
/// suppress compiler warning for unused arguments
#define UNUSED(x) (void)x;
#define NB_RB_SCI1 20
// Based on sl-FreqResourcePSCCH TS 138331, it is one of {n10, n12, n15, n20, n25}.
#define NB_RB_SCI1 10
#include "impl_defs_top.h"
#include "impl_defs_nr.h"
#include "time_meas.h"
......
......@@ -401,6 +401,7 @@ struct NR_DL_FRAME_PARMS {
uint8_t ssb_index;
/// OFDM symbol offset divisor for UL
uint32_t ofdm_offset_divisor;
uint32_t Imcs;
};
/* NR Sidelink PSBCH payload fields */
......
......@@ -159,9 +159,9 @@ int phy_procedures_nrUE_SL_RX(PHY_VARS_NR_UE *ue,
uint8_t synchRefUE_id,
notifiedFIFO_t *txFifo);
void validate_rx_payload(NR_DL_UE_HARQ_t *harq, int frame_rx, int slot_rx);
void validate_rx_payload(NR_DL_UE_HARQ_t *harq, int frame_rx, int slot_rx, bool polar_decoded);
void validate_rx_payload_str(NR_DL_UE_HARQ_t *harq, int slot);
void validate_rx_payload_str(NR_DL_UE_HARQ_t *harq, int slot, bool polar_decoded);
int phy_procedures_slot_parallelization_nrUE_RX(PHY_VARS_NR_UE *ue, UE_nr_rxtx_proc_t *proc, uint8_t eNB_id, uint8_t abstraction_flag, uint8_t do_pdcch_flag, relaying_type_t r_type);
......
This diff is collapsed.
......@@ -34,6 +34,68 @@ uint16_t Tbstable_nr[INDEX_MAX_TBS_TABLE] = {24,32,40,48,56,64,72,80,88,96,104,1
uint16_t NPRB_LBRM[7] = {32,66,107,135,162,217,273};
// Transport block size determination according to 8.1.3.2 of TS 38.214
// returns the TBS in bits
uint32_t nr_compute_tbs_sl(uint16_t Qm,
uint16_t R,
uint16_t nb_rb,
uint16_t nb_re_sci1,
uint16_t nb_re_sci2,
uint16_t nb_symb_sch,
uint16_t nb_dmrs_prb,
uint16_t nb_rb_oh,
uint8_t tb_scaling,
uint8_t Nl)
{
LOG_D(NR_MAC, "In %s: nb_symb_sch %d, nb_dmrs_prb %d, nb_rb %d, nb_rb_oh %d, tb_scaling %d Nl %d\n", __FUNCTION__, nb_symb_sch, nb_dmrs_prb, nb_rb, nb_rb_oh, tb_scaling, Nl);
uint16_t nb_symb_psfch = 0;
uint16_t nb_symb = nb_symb_sch - nb_symb_psfch;
const uint32_t nbp_re = NR_NB_SC_PER_RB * nb_symb - nb_dmrs_prb - nb_rb_oh;
const uint32_t nb_re = nbp_re * nb_rb - nb_re_sci1 - nb_re_sci2;
// Intermediate number of information bits
// Rx1024 is tabulated as 10 times the actual code rate
const uint32_t R_5 = R / 5; // R can be fractional so we can't divide by 10
// So we ned to right shift by 11 (10 for x1024 and 1 additional as above)
const uint32_t Ninfo = ((nb_re * R_5 * Qm * Nl) >> 11) >> tb_scaling;
uint32_t nr_tbs = 0;
uint32_t Np_info, C, n;
if (Ninfo <= 3824) {
n = max(3, floor(log2(Ninfo)) - 6);
Np_info = max(24, (Ninfo>>n)<<n);
for (int i = 0; i < INDEX_MAX_TBS_TABLE; i++) {
if (Tbstable_nr[i] >= Np_info){
nr_tbs = Tbstable_nr[i];
break;
}
}
} else {
n = log2(Ninfo - 24) - 5;
Np_info = max(3840, (ROUNDIDIV((Ninfo - 24), (1 << n))) << n);
if (R <= 2560) {
C = CEILIDIV((Np_info + 24), 3816);
nr_tbs = (C << 3) * CEILIDIV((Np_info + 24), (C << 3)) - 24;
} else {
if (Np_info > 8424){
C = CEILIDIV((Np_info + 24), 8424);
nr_tbs = (C << 3)*CEILIDIV((Np_info + 24), (C << 3)) - 24;
} else {
nr_tbs = ((CEILIDIV((Np_info + 24), 8)) << 3) - 24;
}
}
}
LOG_D(NR_MAC, "In %s: Ninfo %u nbp_re %d nb_re %d Qm %d, R %d, tbs %d bits\n", __FUNCTION__, Ninfo, nbp_re, nb_re, Qm, R, nr_tbs);
return nr_tbs;
}
// Transport block size determination according to 6.1.4.2 of TS 38.214
// returns the TBS in bits
uint32_t nr_compute_tbs(uint16_t Qm,
......
......@@ -147,6 +147,17 @@ uint32_t nr_compute_tbs(uint16_t Qm,
uint8_t tb_scaling,
uint8_t Nl);
uint32_t nr_compute_tbs_sl(uint16_t Qm,
uint16_t R,
uint16_t nb_rb,
uint16_t nb_re_sci1,
uint16_t nb_re_sci2,
uint16_t nb_symb_sch,
uint16_t nb_dmrs_prb,
uint16_t nb_rb_oh,
uint8_t tb_scaling,
uint8_t Nl);
/** \brief Computes Q based on I_MCS PDSCH and table_idx for downlink. Implements MCS Tables from 38.214. */
uint8_t nr_get_Qm_dl(uint8_t Imcs, uint8_t table_idx);
uint32_t nr_get_code_rate_dl(uint8_t Imcs, uint8_t table_idx);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment