Merge remote-tracking branch 'origin/develop-nr' into nr_prach
Conflicts: cmake_targets/build_oai executables/nr-gnb.c openair1/PHY/INIT/nr_init.c openair1/PHY/defs_gNB.h openair1/SCHED_NR/fapi_nr_l1.c openair2/LAYER2/NR_MAC_gNB/config.c openair2/LAYER2/NR_MAC_gNB/mac_proto.h openair2/RRC/NR/rrc_gNB.c
This commit is contained in:
@@ -98,6 +98,7 @@ typedef struct {
|
||||
int64_t rx_count;
|
||||
int wait_for_first_pps;
|
||||
int use_gps;
|
||||
int first_tx;
|
||||
//! timestamp of RX packet
|
||||
openair0_timestamp rx_timestamp;
|
||||
|
||||
@@ -323,10 +324,10 @@ static int trx_usrp_start(openair0_device *device) {
|
||||
|
||||
cmd.stream_now = false; // start at constant delay
|
||||
s->rx_stream->issue_stream_cmd(cmd);
|
||||
s->tx_md.time_spec = cmd.time_spec + uhd::time_spec_t(1-(double)s->tx_forward_nsamps/s->sample_rate);
|
||||
/*s->tx_md.time_spec = cmd.time_spec + uhd::time_spec_t(1-(double)s->tx_forward_nsamps/s->sample_rate);
|
||||
s->tx_md.has_time_spec = true;
|
||||
s->tx_md.start_of_burst = true;
|
||||
s->tx_md.end_of_burst = false;
|
||||
s->tx_md.end_of_burst = false;*/
|
||||
s->rx_count = 0;
|
||||
s->tx_count = 0;
|
||||
s->rx_timestamp = 0;
|
||||
@@ -435,6 +436,7 @@ static int trx_usrp_write(openair0_device *device, openair0_timestamp timestamp,
|
||||
if (u_sf_mode != 2) { // not replay mode
|
||||
#endif
|
||||
usrp_state_t *s = (usrp_state_t *)device->priv;
|
||||
|
||||
int nsamps2; // aligned to upper 32 or 16 byte boundary
|
||||
#if defined(__x86_64) || defined(__i386__)
|
||||
#ifdef __AVX2__
|
||||
@@ -464,47 +466,54 @@ static int trx_usrp_write(openair0_device *device, openair0_timestamp timestamp,
|
||||
}
|
||||
}
|
||||
|
||||
s->tx_md.time_spec = uhd::time_spec_t::from_ticks(timestamp, s->sample_rate);
|
||||
s->tx_md.has_time_spec = flags;
|
||||
|
||||
if(flags>0)
|
||||
s->tx_md.has_time_spec = true;
|
||||
else
|
||||
s->tx_md.has_time_spec = false;
|
||||
boolean_t first_packet_state=false,last_packet_state=false;
|
||||
|
||||
if (flags == 2) { // start of burst
|
||||
s->tx_md.start_of_burst = true;
|
||||
s->tx_md.end_of_burst = false;
|
||||
// s->tx_md.start_of_burst = true;
|
||||
// s->tx_md.end_of_burst = false;
|
||||
first_packet_state = true;
|
||||
last_packet_state = false;
|
||||
} else if (flags == 3) { // end of burst
|
||||
s->tx_md.start_of_burst = false;
|
||||
s->tx_md.end_of_burst = true;
|
||||
//s->tx_md.start_of_burst = false;
|
||||
//s->tx_md.end_of_burst = true;
|
||||
first_packet_state = false;
|
||||
last_packet_state - true;
|
||||
} else if (flags == 4) { // start and end
|
||||
s->tx_md.start_of_burst = true;
|
||||
s->tx_md.end_of_burst = true;
|
||||
// s->tx_md.start_of_burst = true;
|
||||
// s->tx_md.end_of_burst = true;
|
||||
first_packet_state = true;
|
||||
last_packet_state = true;
|
||||
} else if (flags==1) { // middle of burst
|
||||
s->tx_md.start_of_burst = false;
|
||||
s->tx_md.end_of_burst = false;
|
||||
// s->tx_md.start_of_burst = false;
|
||||
// s->tx_md.end_of_burst = false;
|
||||
first_packet_state = false;
|
||||
last_packet_state = false;
|
||||
}
|
||||
else if (flags==10) { // fail safe mode
|
||||
// s->tx_md.has_time_spec = false;
|
||||
// s->tx_md.start_of_burst = false;
|
||||
// s->tx_md.end_of_burst = true;
|
||||
first_packet_state=false;
|
||||
last_packet_state=true;
|
||||
}
|
||||
s->tx_md.has_time_spec = true;
|
||||
s->tx_md.start_of_burst = (s->tx_count==0) ? true : first_packet_state;
|
||||
s->tx_md.end_of_burst = last_packet_state;
|
||||
s->tx_md.time_spec = uhd::time_spec_t::from_ticks(timestamp, s->sample_rate);
|
||||
|
||||
if(flags==10) { // fail safe mode
|
||||
s->tx_md.has_time_spec = false;
|
||||
s->tx_md.start_of_burst = false;
|
||||
s->tx_md.end_of_burst = true;
|
||||
}
|
||||
s->tx_count++;
|
||||
|
||||
if (cc>1) {
|
||||
std::vector<void *> buff_ptrs;
|
||||
std::vector<void *> buff_ptrs;
|
||||
|
||||
for (int i=0; i<cc; i++)
|
||||
buff_ptrs.push_back(buff_tx[i]);
|
||||
for (int i=0; i<cc; i++)
|
||||
buff_ptrs.push_back(&(((int16_t*)buff_tx[i])[0]));
|
||||
|
||||
ret = (int)s->tx_stream->send(buff_ptrs, nsamps, s->tx_md,1e-3);
|
||||
} else
|
||||
ret = (int)s->tx_stream->send(buff_tx[0], nsamps, s->tx_md,1e-3);
|
||||
|
||||
if (ret != nsamps)
|
||||
LOG_E(PHY,"[xmit] tx samples %d != %d\n",ret,nsamps);
|
||||
ret = (int)s->tx_stream->send(buff_ptrs, nsamps, s->tx_md);
|
||||
} else ret = (int)s->tx_stream->send(&(((int16_t *)buff_tx[0])[0]), nsamps, s->tx_md);
|
||||
|
||||
if (ret != nsamps) LOG_E(PHY,"[xmit] tx samples %d != %d\n",ret,nsamps);
|
||||
|
||||
#if defined(USRP_REC_PLAY)
|
||||
} else {
|
||||
struct timespec req;
|
||||
@@ -1087,7 +1096,7 @@ extern "C" {
|
||||
device->type = USRP_B200_DEV;
|
||||
usrp_master_clock = 30.72e6;
|
||||
args += boost::str(boost::format(",master_clock_rate=%f") % usrp_master_clock);
|
||||
args += ",num_send_frames=256,num_recv_frames=256, send_frame_size=15360, recv_frame_size=15360" ;
|
||||
args += ",num_send_frames=256,num_recv_frames=256, send_frame_size=7680, recv_frame_size=7680" ;
|
||||
}
|
||||
|
||||
if (device_adds[0].get("type") == "n3xx") {
|
||||
@@ -1095,6 +1104,7 @@ extern "C" {
|
||||
device->type=USRP_X300_DEV; //treat it as X300 for now
|
||||
usrp_master_clock = 122.88e6;
|
||||
args += boost::str(boost::format(",master_clock_rate=%f") % usrp_master_clock);
|
||||
//args += ", send_buff_size=33554432";
|
||||
}
|
||||
|
||||
if (device_adds[0].get("type") == "x300") {
|
||||
@@ -1115,6 +1125,7 @@ extern "C" {
|
||||
else
|
||||
s->usrp->set_clock_source("external");
|
||||
|
||||
|
||||
if (device->type==USRP_X300_DEV) {
|
||||
openair0_cfg[0].rx_gain_calib_table = calib_table_x310;
|
||||
#if defined(USRP_REC_PLAY)
|
||||
@@ -1335,6 +1346,7 @@ extern "C" {
|
||||
LOG_I(PHY," Actual TX gain: %f...\n", s->usrp->get_tx_gain(i));
|
||||
LOG_I(PHY," Actual TX bandwidth: %fM...\n", s->usrp->get_tx_bandwidth(i)/1e6);
|
||||
LOG_I(PHY," Actual TX antenna: %s...\n", s->usrp->get_tx_antenna(i).c_str());
|
||||
LOG_I(PHY," Actual TX packet size: %lu\n",s->tx_stream->get_max_num_samps());
|
||||
}
|
||||
|
||||
LOG_I(PHY,"Device timestamp: %f...\n", s->usrp->get_time_now().get_real_secs());
|
||||
|
||||
@@ -3,6 +3,12 @@
|
||||
copyleft: OpenAirInterface Software Alliance and it's licence
|
||||
*/
|
||||
|
||||
/*
|
||||
* Open issues and limitations
|
||||
* The read and write should be called in the same thread, that is not new USRP UHD design
|
||||
* When the opposite side switch from passive reading to active R+Write, the synchro is not fully deterministic
|
||||
*/
|
||||
|
||||
#include <sys/socket.h>
|
||||
#include <netinet/in.h>
|
||||
#include <netinet/tcp.h>
|
||||
@@ -28,7 +34,7 @@
|
||||
#define sampleToByte(a,b) ((a)*(b)*sizeof(sample_t))
|
||||
#define byteToSample(a,b) ((a)/(sizeof(sample_t)*(b)))
|
||||
|
||||
#define sample_t uint32_t // 2*16 bits complex number
|
||||
#define sample_t uint32_t //2*16 bits complex number
|
||||
|
||||
typedef struct buffer_s {
|
||||
int conn_sock;
|
||||
@@ -111,7 +117,7 @@ void setblocking(int sock, enum blocking_t active) {
|
||||
AssertFatal(fcntl(sock, F_SETFL, opts) >= 0, "");
|
||||
}
|
||||
|
||||
static bool flushInput(rfsimulator_state_t *t);
|
||||
static bool flushInput(rfsimulator_state_t *t, int timeout);
|
||||
|
||||
void fullwrite(int fd, void *_buf, ssize_t count, rfsimulator_state_t *t) {
|
||||
if (t->saveIQfile != -1) {
|
||||
@@ -134,7 +140,9 @@ void fullwrite(int fd, void *_buf, ssize_t count, rfsimulator_state_t *t) {
|
||||
continue;
|
||||
|
||||
if(errno==EAGAIN) {
|
||||
flushInput(t);
|
||||
// The opposite side is saturated
|
||||
// we read incoming sockets meawhile waiting
|
||||
flushInput(t, 5);
|
||||
continue;
|
||||
} else
|
||||
return;
|
||||
@@ -229,14 +237,17 @@ int rfsimulator_write(openair0_device *device, openair0_timestamp timestamp, voi
|
||||
lastW=timestamp;
|
||||
LOG_D(HW,"sent %d samples at time: %ld->%ld, energy in first antenna: %d\n",
|
||||
nsamps, timestamp, timestamp+nsamps, signal_energy(samplesVoid[0], nsamps) );
|
||||
// Let's verify we don't have incoming data
|
||||
// This is mandatory when the opposite side don't transmit
|
||||
flushInput(t, 0);
|
||||
return nsamps;
|
||||
}
|
||||
|
||||
static bool flushInput(rfsimulator_state_t *t) {
|
||||
static bool flushInput(rfsimulator_state_t *t, int timeout) {
|
||||
// Process all incoming events on sockets
|
||||
// store the data in lists
|
||||
struct epoll_event events[FD_SETSIZE]= {0};
|
||||
int nfds = epoll_wait(t->epollfd, events, FD_SETSIZE, 20);
|
||||
int nfds = epoll_wait(t->epollfd, events, FD_SETSIZE, timeout);
|
||||
|
||||
if ( nfds==-1 ) {
|
||||
if ( errno==EINTR || errno==EAGAIN )
|
||||
@@ -356,7 +367,7 @@ int rfsimulator_read(openair0_device *device, openair0_timestamp *ptimestamp, vo
|
||||
|
||||
if ( first_sock == FD_SETSIZE ) {
|
||||
// no connected device (we are eNB, no UE is connected)
|
||||
if (!flushInput(t)) {
|
||||
if (!flushInput(t, 10)) {
|
||||
for (int x=0; x < nbAnt; x++)
|
||||
memset(samplesVoid[x],0,sampleToByte(nsamps,1));
|
||||
|
||||
@@ -385,7 +396,7 @@ int rfsimulator_read(openair0_device *device, openair0_timestamp *ptimestamp, vo
|
||||
ptr->lastReceivedTS,
|
||||
t->nextTimestamp+nsamps);
|
||||
*/
|
||||
flushInput(t);
|
||||
flushInput(t, 3);
|
||||
} while (have_to_wait);
|
||||
}
|
||||
|
||||
|
||||
@@ -6,6 +6,8 @@
|
||||
# define NUMBER_OF_gNB_MAX 1
|
||||
# define NUMBER_OF_RU_MAX 2
|
||||
# define NUMBER_OF_NR_RU_MAX 2
|
||||
# define NUMBER_OF_NR_DLSCH_MAX 16
|
||||
# define NUMBER_OF_NR_ULSCH_MAX 16
|
||||
# ifndef PHYSIM
|
||||
# ifndef UE_EXPANSION
|
||||
# define NUMBER_OF_UE_MAX 4
|
||||
|
||||
@@ -1,13 +1,13 @@
|
||||
[*]
|
||||
[*] GTKWave Analyzer v3.3.66 (w)1999-2015 BSI
|
||||
[*] Mon Oct 29 17:36:13 2018
|
||||
[*] Sun May 19 21:39:57 2019
|
||||
[*]
|
||||
[dumpfile] "/mnt/hgfs/Documents/Devel/openair_dump_eNB.vcd"
|
||||
[dumpfile_mtime] "Mon Oct 29 17:34:25 2018"
|
||||
[dumpfile_size] 4559568
|
||||
[savefile] "/home/kaltenbe/Devel/openairinterface5g/targets/RT/USER/eNB_usrp.gtkw"
|
||||
[timestart] 7635200000
|
||||
[size] 1535 780
|
||||
[dumpfile] "/tmp/openair_dump_eNB.vcd"
|
||||
[dumpfile_mtime] "Sun May 19 21:30:25 2019"
|
||||
[dumpfile_size] 11590554
|
||||
[savefile] "/home/sphex/raymond/openairinterface5g/targets/RT/USER/eNB_usrp.gtkw"
|
||||
[timestart] 7629910000
|
||||
[size] 1840 795
|
||||
[pos] -1 -1
|
||||
*-21.832302 7639830000 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1
|
||||
[sst_width] 386
|
||||
@@ -24,9 +24,11 @@ variables.trx_tst[63:0]
|
||||
functions.eNB_thread_rxtx0
|
||||
@24
|
||||
variables.frame_number_RX0_RU[63:0]
|
||||
variables.subframe_number_RX0_RU[63:0]
|
||||
@25
|
||||
variables.tti_number_RX0_RU[63:0]
|
||||
@24
|
||||
variables.frame_number_TX0_RU[63:0]
|
||||
variables.subframe_number_TX0_RU[63:0]
|
||||
variables.tti_number_TX0_RU[63:0]
|
||||
@28
|
||||
functions.mac_schedule_dlsch
|
||||
functions.macxface_eNB_dlsch_ulsch_scheduler
|
||||
@@ -54,9 +56,7 @@ functions.phy_procedures_eNb_rx_uespec1
|
||||
functions.phy_enb_sfgen
|
||||
functions.phy_procedures_eNb_tx0
|
||||
functions.phy_procedures_eNb_tx1
|
||||
@29
|
||||
functions.phy_procedures_ru_feprx0
|
||||
@28
|
||||
functions.phy_procedures_ru_feprx1
|
||||
functions.phy_procedures_ru_feptx_ofdm0
|
||||
functions.phy_procedures_ru_feptx_ofdm1
|
||||
|
||||
@@ -1,28 +1,34 @@
|
||||
[*]
|
||||
[*] GTKWave Analyzer v3.3.58 (w)1999-2014 BSI
|
||||
[*] Tue Nov 6 14:54:14 2018
|
||||
[*] GTKWave Analyzer v3.3.61 (w)1999-2014 BSI
|
||||
[*] Sat May 18 17:25:11 2019
|
||||
[*]
|
||||
[dumpfile] "/tmp/openair_dump_eNB.vcd"
|
||||
[dumpfile_mtime] "Tue Nov 6 14:50:45 2018"
|
||||
[dumpfile_size] 1894074
|
||||
[savefile] "/homes/wangts/openairinterface5g/targets/RT/USER/gNB_usrp.gtkw"
|
||||
[timestart] 1238454000
|
||||
[size] 1920 1018
|
||||
[pos] -159 -155
|
||||
*-20.848083 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1
|
||||
[dumpfile] "/tmp/openair_dump_gNB40.vcd"
|
||||
[dumpfile_mtime] "Sat May 18 17:11:31 2019"
|
||||
[dumpfile_size] 53148516
|
||||
[savefile] "/home/caracal/raymond/openairinterface5g/targets/RT/USER/gNB_usrp.gtkw"
|
||||
[timestart] 11552775390
|
||||
[size] 1840 795
|
||||
[pos] -1 -1
|
||||
*-13.848083 11552814436 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1
|
||||
[sst_width] 386
|
||||
[signals_width] 344
|
||||
[sst_expanded] 1
|
||||
[sst_vpaned_height] 421
|
||||
[sst_vpaned_height] 197
|
||||
@28
|
||||
functions.trx_read
|
||||
functions.trx_write
|
||||
@420
|
||||
variables.frame_number_TX0_UE[63:0]
|
||||
variables.frame_number_TX1_UE[63:0]
|
||||
@28
|
||||
functions.ue_gain_control
|
||||
@420
|
||||
variables.frame_number_RX1_UE[63:0]
|
||||
@25
|
||||
variables.trx_ts_ue[63:0]
|
||||
@24
|
||||
variables.trx_ts[63:0]
|
||||
variables.trx_tst[63:0]
|
||||
@28
|
||||
functions.eNB_thread_rxtx0
|
||||
@24
|
||||
variables.frame_number_RX0_RU[63:0]
|
||||
variables.tti_number_RX0_RU[63:0]
|
||||
variables.frame_number_TX0_RU[63:0]
|
||||
@@ -30,8 +36,6 @@ variables.tti_number_TX0_RU[63:0]
|
||||
@28
|
||||
functions.mac_schedule_dlsch
|
||||
functions.macxface_eNB_dlsch_ulsch_scheduler
|
||||
functions.macxface_ue_scheduler
|
||||
functions.phy_eNB_ofdm_mod_l
|
||||
@24
|
||||
variables.frame_number_RX0_gNB[63:0]
|
||||
variables.slot_number_RX0_gNB[63:0]
|
||||
@@ -46,7 +50,13 @@ variables.frame_number_TX1_gNB[63:0]
|
||||
variables.slot_number_TX1_gNB[63:0]
|
||||
@28
|
||||
functions.gNB_thread_rxtx1
|
||||
functions.phy_procedures_ru_feprx0
|
||||
functions.phy_enb_pdcch_tx
|
||||
functions.phy_eNB_dlsch_encoding
|
||||
functions.phy_eNB_dlsch_encoding_w
|
||||
functions.generate_dlsch
|
||||
@420
|
||||
variables.frame_number_RX0_UE[63:0]
|
||||
@28
|
||||
functions.phy_procedures_ru_feprx0
|
||||
functions.phy_procedures_ru_feprx1
|
||||
functions.phy_procedures_ru_feptx_ofdm0
|
||||
|
||||
+39
-39
@@ -309,23 +309,23 @@ int connect_rau(RU_t *ru) {
|
||||
/* Southbound Fronthaul functions, RCC/RAU */
|
||||
|
||||
// southbound IF5 fronthaul for 16-bit OAI format
|
||||
static inline void fh_if5_south_out(RU_t *ru) {
|
||||
static inline void fh_if5_south_out(RU_t *ru,int frame, int subframe, uint64_t timestamp) {
|
||||
if (ru == RC.ru[0]) VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME( VCD_SIGNAL_DUMPER_VARIABLES_TRX_TST, ru->proc.timestamp_tx&0xffffffff );
|
||||
send_IF5(ru, ru->proc.timestamp_tx, ru->proc.tti_tx, &ru->seqno, IF5_RRH_GW_DL);
|
||||
send_IF5(ru, timestamp, subframe, &ru->seqno, IF5_RRH_GW_DL);
|
||||
}
|
||||
|
||||
// southbound IF5 fronthaul for Mobipass packet format
|
||||
static inline void fh_if5_mobipass_south_out(RU_t *ru) {
|
||||
static inline void fh_if5_mobipass_south_out(RU_t *ru,int frame, int subframe, uint64_t timestamp) {
|
||||
if (ru == RC.ru[0]) VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME( VCD_SIGNAL_DUMPER_VARIABLES_TRX_TST, ru->proc.timestamp_tx&0xffffffff );
|
||||
send_IF5(ru, ru->proc.timestamp_tx, ru->proc.tti_tx, &ru->seqno, IF5_MOBIPASS);
|
||||
send_IF5(ru, timestamp, subframe, &ru->seqno, IF5_MOBIPASS);
|
||||
}
|
||||
|
||||
// southbound IF4p5 fronthaul
|
||||
static inline void fh_if4p5_south_out(RU_t *ru) {
|
||||
static inline void fh_if4p5_south_out(RU_t *ru,int frame, int subframe, uint64_t timestamp) {
|
||||
if (ru == RC.ru[0]) VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME( VCD_SIGNAL_DUMPER_VARIABLES_TRX_TST, ru->proc.timestamp_tx&0xffffffff );
|
||||
LOG_D(PHY,"Sending IF4p5 for frame %d subframe %d\n",ru->proc.frame_tx,ru->proc.tti_tx);
|
||||
if (subframe_select(ru->frame_parms,ru->proc.tti_tx)!=SF_UL)
|
||||
send_IF4p5(ru,ru->proc.frame_tx, ru->proc.tti_tx, IF4p5_PDLFFT);
|
||||
if (subframe_select(ru->frame_parms,subframe)!=SF_UL)
|
||||
send_IF4p5(ru,frame, subframe, IF4p5_PDLFFT);
|
||||
}
|
||||
|
||||
/*************************************************************/
|
||||
@@ -646,8 +646,8 @@ void fh_if4p5_north_asynch_in(RU_t *ru,int *frame,int *subframe) {
|
||||
VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME( VCD_SIGNAL_DUMPER_VARIABLES_TTI_NUMBER_TX0_RU, tti_tx );
|
||||
}
|
||||
|
||||
if (ru->feptx_ofdm) ru->feptx_ofdm(ru);
|
||||
if (ru->fh_south_out) ru->fh_south_out(ru);
|
||||
if (ru->feptx_ofdm) ru->feptx_ofdm(ru,frame_tx,tti_tx);
|
||||
if (ru->fh_south_out) ru->fh_south_out(ru,frame_tx,tti_tx,proc->timestamp_tx);
|
||||
}
|
||||
|
||||
void fh_if5_north_out(RU_t *ru) {
|
||||
@@ -841,7 +841,7 @@ void rx_rf(RU_t *ru,int *frame,int *subframe) {
|
||||
}
|
||||
|
||||
|
||||
void tx_rf(RU_t *ru) {
|
||||
void tx_rf(RU_t *ru,int frame,int subframe,uint64_t timestamp) {
|
||||
|
||||
RU_proc_t *proc = &ru->proc;
|
||||
LTE_DL_FRAME_PARMS *fp = ru->frame_parms;
|
||||
@@ -849,12 +849,12 @@ void tx_rf(RU_t *ru) {
|
||||
unsigned int txs;
|
||||
int i;
|
||||
|
||||
T(T_ENB_PHY_OUTPUT_SIGNAL, T_INT(0), T_INT(0), T_INT(proc->frame_tx), T_INT(proc->tti_tx),
|
||||
T_INT(0), T_BUFFER(&ru->common.txdata[0][proc->tti_tx * fp->samples_per_tti], fp->samples_per_tti * 4));
|
||||
T(T_ENB_PHY_OUTPUT_SIGNAL, T_INT(0), T_INT(0), T_INT(frame), T_INT(subframe),
|
||||
T_INT(0), T_BUFFER(&ru->common.txdata[0][subframe * fp->samples_per_tti], fp->samples_per_tti * 4));
|
||||
|
||||
lte_subframe_t SF_type = subframe_select(fp,proc->tti_tx%10);
|
||||
lte_subframe_t prevSF_type = subframe_select(fp,(proc->tti_tx+9)%10);
|
||||
lte_subframe_t nextSF_type = subframe_select(fp,(proc->tti_tx+1)%10);
|
||||
lte_subframe_t SF_type = subframe_select(fp,subframe%10);
|
||||
lte_subframe_t prevSF_type = subframe_select(fp,(subframe+9)%10);
|
||||
lte_subframe_t nextSF_type = subframe_select(fp,(subframe+1)%10);
|
||||
int sf_extension = 0;
|
||||
|
||||
if ((SF_type == SF_DL) ||
|
||||
@@ -892,7 +892,7 @@ void tx_rf(RU_t *ru) {
|
||||
#endif
|
||||
|
||||
for (i=0; i<ru->nb_tx; i++)
|
||||
txp[i] = (void*)&ru->common.txdata[i][(proc->tti_tx*fp->samples_per_tti)-sf_extension];
|
||||
txp[i] = (void*)&ru->common.txdata[i][(subframe*fp->samples_per_tti)-sf_extension];
|
||||
|
||||
/* add fail safe for late command */
|
||||
if(late_control!=STATE_BURST_NORMAL){//stop burst
|
||||
@@ -925,22 +925,22 @@ void tx_rf(RU_t *ru) {
|
||||
}
|
||||
/* add fail safe for late command end */
|
||||
|
||||
VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME( VCD_SIGNAL_DUMPER_VARIABLES_FRAME_NUMBER_TX0_RU, proc->frame_tx );
|
||||
VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME( VCD_SIGNAL_DUMPER_VARIABLES_TTI_NUMBER_TX0_RU, proc->tti_tx );
|
||||
VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME( VCD_SIGNAL_DUMPER_VARIABLES_FRAME_NUMBER_TX0_RU, frame);
|
||||
VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME( VCD_SIGNAL_DUMPER_VARIABLES_TTI_NUMBER_TX0_RU, subframe);
|
||||
|
||||
VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME( VCD_SIGNAL_DUMPER_VARIABLES_TRX_TST, (proc->timestamp_tx-ru->openair0_cfg.tx_sample_advance)&0xffffffff );
|
||||
VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME( VCD_SIGNAL_DUMPER_VARIABLES_TRX_TST, (timestamp-ru->openair0_cfg.tx_sample_advance)&0xffffffff );
|
||||
VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_TRX_WRITE, 1 );
|
||||
// prepare tx buffer pointers
|
||||
|
||||
txs = ru->rfdevice.trx_write_func(&ru->rfdevice,
|
||||
proc->timestamp_tx+ru->ts_offset-ru->openair0_cfg.tx_sample_advance-sf_extension,
|
||||
timestamp+ru->ts_offset-ru->openair0_cfg.tx_sample_advance-sf_extension,
|
||||
txp,
|
||||
siglen+sf_extension,
|
||||
ru->nb_tx,
|
||||
flags);
|
||||
|
||||
LOG_D(PHY,"[TXPATH] RU %d tx_rf, writing to TS %llu, frame %d, unwrapped_frame %d, subframe %d\n",ru->idx,
|
||||
(long long unsigned int)proc->timestamp_tx,proc->frame_tx,proc->frame_tx_unwrap,proc->tti_tx);
|
||||
(long long unsigned int)timestamp,frame,proc->frame_tx_unwrap,subframe);
|
||||
VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_TRX_WRITE, 0 );
|
||||
|
||||
|
||||
@@ -1558,13 +1558,13 @@ static void* ru_thread_tx( void* param ) {
|
||||
if (oai_exit) break;
|
||||
|
||||
// do TX front-end processing if needed (precoding and/or IDFTs)
|
||||
if (ru->feptx_prec) ru->feptx_prec(ru);
|
||||
if (ru->feptx_prec) ru->feptx_prec(ru,proc->frame_tx,proc->tti_tx);
|
||||
|
||||
// do OFDM if needed
|
||||
if ((ru->fh_north_asynch_in == NULL) && (ru->feptx_ofdm)) ru->feptx_ofdm(ru);
|
||||
if ((ru->fh_north_asynch_in == NULL) && (ru->feptx_ofdm)) ru->feptx_ofdm(ru,proc->frame_tx,proc->tti_tx);
|
||||
if(!emulate_rf){
|
||||
// do outgoing fronthaul (south) if needed
|
||||
if ((ru->fh_north_asynch_in == NULL) && (ru->fh_south_out)) ru->fh_south_out(ru);
|
||||
if ((ru->fh_north_asynch_in == NULL) && (ru->fh_south_out)) ru->fh_south_out(ru,proc->frame_tx,proc->tti_tx,proc->timestamp_tx);
|
||||
|
||||
if (ru->fh_north_out) ru->fh_north_out(ru);
|
||||
}
|
||||
@@ -1764,7 +1764,7 @@ static void* ru_thread( void* param ) {
|
||||
|
||||
|
||||
// do RX front-end processing (frequency-shift, dft) if needed
|
||||
if (ru->feprx) ru->feprx(ru);
|
||||
if (ru->feprx) ru->feprx(ru,proc->tti_rx);
|
||||
|
||||
// At this point, all information for subframe has been received on FH interface
|
||||
// If this proc is to provide synchronization, do so
|
||||
@@ -1804,13 +1804,13 @@ static void* ru_thread( void* param ) {
|
||||
#ifndef PHY_TX_THREAD
|
||||
if(get_thread_parallel_conf() == PARALLEL_SINGLE_THREAD || ru->num_eNB==0){
|
||||
// do TX front-end processing if needed (precoding and/or IDFTs)
|
||||
if (ru->feptx_prec) ru->feptx_prec(ru);
|
||||
if (ru->feptx_prec) ru->feptx_prec(ru,proc->frame_tx,proc->tti_tx);
|
||||
|
||||
// do OFDM if needed
|
||||
if ((ru->fh_north_asynch_in == NULL) && (ru->feptx_ofdm)) ru->feptx_ofdm(ru);
|
||||
if ((ru->fh_north_asynch_in == NULL) && (ru->feptx_ofdm)) ru->feptx_ofdm(ru,proc->frame_tx,proc->tti_tx);
|
||||
if(!emulate_rf){
|
||||
// do outgoing fronthaul (south) if needed
|
||||
if ((ru->fh_north_asynch_in == NULL) && (ru->fh_south_out)) ru->fh_south_out(ru);
|
||||
if ((ru->fh_north_asynch_in == NULL) && (ru->fh_south_out)) ru->fh_south_out(ru,proc->frame_tx,proc->tti_tx,proc->timestamp_tx);
|
||||
|
||||
if (ru->fh_north_out) ru->fh_north_out(ru);
|
||||
}
|
||||
@@ -2074,10 +2074,10 @@ static void* rf_tx( void* param ) {
|
||||
// do TX front-end processing if needed (precoding and/or IDFTs)
|
||||
if (ru->feptx_prec) ru->feptx_prec(ru);
|
||||
// do OFDM if needed
|
||||
if ((ru->fh_north_asynch_in == NULL) && (ru->feptx_ofdm)) ru->feptx_ofdm(ru);
|
||||
if ((ru->fh_north_asynch_in == NULL) && (ru->feptx_ofdm)) ru->feptx_ofdm(ru,proc->frame_tx,proc->tti_tx);
|
||||
if(!emulate_rf){
|
||||
// do outgoing fronthaul (south) if needed
|
||||
if ((ru->fh_north_asynch_in == NULL) && (ru->fh_south_out)) ru->fh_south_out(ru);
|
||||
if ((ru->fh_north_asynch_in == NULL) && (ru->fh_south_out)) ru->fh_south_out(ru,proc->frame_tx,proc->tti_tx,proc->timestamp_tx);
|
||||
|
||||
if (ru->fh_north_out) ru->fh_north_out(ru);
|
||||
}
|
||||
@@ -2112,13 +2112,13 @@ int stop_rf(RU_t *ru)
|
||||
return 0;
|
||||
}
|
||||
|
||||
extern void fep_full(RU_t *ru);
|
||||
extern void ru_fep_full_2thread(RU_t *ru);
|
||||
extern void feptx_ofdm(RU_t *ru);
|
||||
extern void feptx_ofdm_2thread(RU_t *ru);
|
||||
extern void feptx_prec(RU_t *ru);
|
||||
extern void init_fep_thread(RU_t *ru,pthread_attr_t *attr);
|
||||
extern void init_feptx_thread(RU_t *ru,pthread_attr_t *attr);
|
||||
extern void fep_full(RU_t *ru,int subframe);
|
||||
extern void ru_fep_full_2thread(RU_t *ru,int subframe);
|
||||
extern void feptx_ofdm(RU_t *ru,int frame_tx,int tti_tx);
|
||||
extern void feptx_ofdm_2thread(RU_t *ru,int frame_tx,int tti_tx);
|
||||
extern void feptx_prec(RU_t *ru,int frame_tx,int tti_tx);
|
||||
extern void init_fep_thread(RU_t *ru);
|
||||
extern void init_feptx_thread(RU_t *ru);
|
||||
extern void kill_fep_thread(RU_t *ru);
|
||||
extern void kill_feptx_thread(RU_t *ru);
|
||||
|
||||
@@ -2256,8 +2256,8 @@ void init_RU_proc(RU_t *ru) {
|
||||
}
|
||||
|
||||
if (get_thread_worker_conf() == WORKER_ENABLE) {
|
||||
init_fep_thread(ru,NULL);
|
||||
init_feptx_thread(ru,NULL);
|
||||
init_fep_thread(ru);
|
||||
init_feptx_thread(ru);
|
||||
}
|
||||
if (opp_enabled == 1) pthread_create(&ru->ru_stats_thread,NULL,ru_stats_thread,(void*)ru);
|
||||
|
||||
|
||||
+147
-158
@@ -1,4 +1,4 @@
|
||||
/*
|
||||
/*/*
|
||||
* Licensed to the OpenAirInterface (OAI) Software Alliance under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright ownership.
|
||||
@@ -143,8 +143,8 @@ extern double cpuf;
|
||||
void init_gNB(int,int);
|
||||
void stop_gNB(int nb_inst);
|
||||
|
||||
int wakeup_txfh(gNB_L1_rxtx_proc_t *proc,PHY_VARS_gNB *gNB);
|
||||
int wakeup_tx(PHY_VARS_gNB *gNB);
|
||||
int wakeup_txfh(PHY_VARS_gNB *gNB,gNB_L1_rxtx_proc_t *proc,int frame_tx,int slot_tx,uint64_t timestamp_tx);
|
||||
int wakeup_tx(PHY_VARS_gNB *gNB,int frame_rx,int slot_rx,int frame_tx,int slot_tx,uint64_t timestamp_tx);
|
||||
extern PARALLEL_CONF_t get_thread_parallel_conf(void);
|
||||
extern WORKER_CONF_t get_thread_worker_conf(void);
|
||||
|
||||
@@ -159,7 +159,7 @@ extern void add_subframe(uint16_t *frameP, uint16_t *subframeP, int offset);
|
||||
#define TICK_TO_US(ts) (ts.trials==0?0:ts.diff/ts.trials)
|
||||
|
||||
|
||||
static inline int rxtx(PHY_VARS_gNB *gNB,gNB_L1_rxtx_proc_t *proc, char *thread_name) {
|
||||
static inline int rxtx(PHY_VARS_gNB *gNB,int frame_rx, int slot_rx, int frame_tx, int slot_tx, char *thread_name) {
|
||||
start_meas(&softmodem_stats_rxtx_sf);
|
||||
|
||||
// *******************************************************************
|
||||
@@ -167,15 +167,11 @@ static inline int rxtx(PHY_VARS_gNB *gNB,gNB_L1_rxtx_proc_t *proc, char *thread_
|
||||
if (nfapi_mode == 1) {
|
||||
|
||||
// I am a PNF and I need to let nFAPI know that we have a (sub)frame tick
|
||||
uint16_t frame = proc->frame_rx;
|
||||
uint16_t slot = proc->slot_rx;
|
||||
|
||||
//add_subframe(&frame, &subframe, 4);
|
||||
|
||||
//oai_subframe_ind(proc->frame_tx, proc->subframe_tx);
|
||||
//LOG_D(PHY, "oai_subframe_ind(frame:%u, subframe:%d) - NOT CALLED ********\n", frame, subframe);
|
||||
start_meas(&nfapi_meas);
|
||||
oai_subframe_ind(frame, slot);
|
||||
oai_subframe_ind(frame_rx, slot_rx);
|
||||
stop_meas(&nfapi_meas);
|
||||
|
||||
if (gNB->UL_INFO.rx_ind.rx_indication_body.number_of_pdus||
|
||||
@@ -184,14 +180,13 @@ static inline int rxtx(PHY_VARS_gNB *gNB,gNB_L1_rxtx_proc_t *proc, char *thread_
|
||||
gNB->UL_INFO.rach_ind.rach_indication_body.number_of_preambles ||
|
||||
gNB->UL_INFO.cqi_ind.number_of_cqis
|
||||
) {
|
||||
LOG_D(PHY, "UL_info[rx_ind:%05d:%d harqs:%05d:%d crcs:%05d:%d preambles:%05d:%d cqis:%d] RX:%04d%d TX:%04d%d \n",
|
||||
LOG_D(PHY, "UL_info[rx_ind:%05d:%d harqs:%05d:%d crcs:%05d:%d preambles:%05d:%d cqis:%d] RX:%04d%d \n",
|
||||
NFAPI_SFNSF2DEC(gNB->UL_INFO.rx_ind.sfn_sf), gNB->UL_INFO.rx_ind.rx_indication_body.number_of_pdus,
|
||||
NFAPI_SFNSF2DEC(gNB->UL_INFO.harq_ind.sfn_sf), gNB->UL_INFO.harq_ind.harq_indication_body.number_of_harqs,
|
||||
NFAPI_SFNSF2DEC(gNB->UL_INFO.crc_ind.sfn_sf), gNB->UL_INFO.crc_ind.crc_indication_body.number_of_crcs,
|
||||
NFAPI_SFNSF2DEC(gNB->UL_INFO.rach_ind.sfn_sf), gNB->UL_INFO.rach_ind.rach_indication_body.number_of_preambles,
|
||||
gNB->UL_INFO.cqi_ind.number_of_cqis,
|
||||
proc->frame_rx, proc->slot_rx,
|
||||
proc->frame_tx, proc->slot_tx);
|
||||
frame_rx, slot_rx);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -200,22 +195,22 @@ static inline int rxtx(PHY_VARS_gNB *gNB,gNB_L1_rxtx_proc_t *proc, char *thread_
|
||||
// ****************************************
|
||||
// Common RX procedures subframe n
|
||||
|
||||
T(T_GNB_PHY_DL_TICK, T_INT(gNB->Mod_id), T_INT(proc->frame_tx), T_INT(proc->slot_tx));
|
||||
T(T_GNB_PHY_DL_TICK, T_INT(gNB->Mod_id), T_INT(frame_tx), T_INT(slot_tx));
|
||||
/*
|
||||
// if this is IF5 or 3GPP_gNB
|
||||
if (gNB && gNB->RU_list && gNB->RU_list[0] && gNB->RU_list[0]->function < NGFI_RAU_IF4p5) {
|
||||
wakeup_prach_gNB(gNB,NULL,proc->frame_rx,proc->slot_rx);
|
||||
wakeup_prach_gNB(gNB,NULL,frame_rx,slot_rx);
|
||||
}
|
||||
|
||||
// UE-specific RX processing for subframe n
|
||||
if (nfapi_mode == 0 || nfapi_mode == 1) {
|
||||
phy_procedures_gNB_uespec_RX(gNB, proc, no_relay );
|
||||
phy_procedures_gNB_uespec_RX(gNB, frame_rx,slot_rx, no_relay );
|
||||
}
|
||||
*/
|
||||
pthread_mutex_lock(&gNB->UL_INFO_mutex);
|
||||
|
||||
gNB->UL_INFO.frame = proc->frame_rx;
|
||||
gNB->UL_INFO.slot = proc->slot_rx;
|
||||
gNB->UL_INFO.frame = frame_rx;
|
||||
gNB->UL_INFO.slot = slot_rx;
|
||||
gNB->UL_INFO.module_id = gNB->Mod_id;
|
||||
gNB->UL_INFO.CC_id = gNB->CC_id;
|
||||
|
||||
@@ -232,77 +227,40 @@ static inline int rxtx(PHY_VARS_gNB *gNB,gNB_L1_rxtx_proc_t *proc, char *thread_
|
||||
//if (wait_CCs(proc)<0) return(-1);
|
||||
|
||||
if (oai_exit) return(-1);
|
||||
if(get_thread_parallel_conf() == PARALLEL_SINGLE_THREAD){
|
||||
phy_procedures_gNB_TX(gNB, proc, 1);
|
||||
}
|
||||
if(get_thread_parallel_conf() != PARALLEL_RU_L1_TRX_SPLIT) phy_procedures_gNB_TX(gNB, frame_tx,slot_tx, 1);
|
||||
|
||||
stop_meas( &softmodem_stats_rxtx_sf );
|
||||
|
||||
LOG_D(PHY,"%s() Exit proc[rx:%d%d tx:%d%d]\n", __FUNCTION__, proc->frame_rx, proc->slot_rx, proc->frame_tx, proc->slot_tx);
|
||||
LOG_D(PHY,"%s() Exit proc[rx:%d%d tx:%d%d]\n", __FUNCTION__, frame_rx, slot_rx, frame_tx, slot_tx);
|
||||
|
||||
#if 0
|
||||
LOG_D(PHY, "rxtx:%lld nfapi:%lld phy:%lld tx:%lld rx:%lld prach:%lld ofdm:%lld ",
|
||||
softmodem_stats_rxtx_sf.diff_now, nfapi_meas.diff_now,
|
||||
TICK_TO_US(gNB->phy_proc),
|
||||
TICK_TO_US(gNB->phy_proc_tx),
|
||||
TICK_TO_US(gNB->phy_proc_rx),
|
||||
TICK_TO_US(gNB->rx_prach),
|
||||
TICK_TO_US(gNB->ofdm_mod_stats),
|
||||
softmodem_stats_rxtx_sf.diff_now, nfapi_meas.diff_now);
|
||||
LOG_D(PHY,
|
||||
"dlsch[enc:%lld mod:%lld scr:%lld rm:%lld t:%lld i:%lld] rx_dft:%lld ",
|
||||
TICK_TO_US(gNB->dlsch_encoding_stats),
|
||||
TICK_TO_US(gNB->dlsch_modulation_stats),
|
||||
TICK_TO_US(gNB->dlsch_scrambling_stats),
|
||||
TICK_TO_US(gNB->dlsch_rate_matching_stats),
|
||||
TICK_TO_US(gNB->dlsch_turbo_encoding_stats),
|
||||
TICK_TO_US(gNB->dlsch_interleaving_stats),
|
||||
TICK_TO_US(gNB->rx_dft_stats));
|
||||
|
||||
LOG_D(PHY," ulsch[ch:%lld freq:%lld dec:%lld demod:%lld ru:%lld ",
|
||||
TICK_TO_US(gNB->ulsch_channel_estimation_stats),
|
||||
TICK_TO_US(gNB->ulsch_freq_offset_estimation_stats),
|
||||
TICK_TO_US(gNB->ulsch_decoding_stats),
|
||||
TICK_TO_US(gNB->ulsch_demodulation_stats),
|
||||
TICK_TO_US(gNB->ulsch_rate_unmatching_stats));
|
||||
|
||||
LOG_D(PHY, "td:%lld dei:%lld dem:%lld llr:%lld tci:%lld ",
|
||||
TICK_TO_US(gNB->ulsch_turbo_decoding_stats),
|
||||
TICK_TO_US(gNB->ulsch_deinterleaving_stats),
|
||||
TICK_TO_US(gNB->ulsch_demultiplexing_stats),
|
||||
TICK_TO_US(gNB->ulsch_llr_stats),
|
||||
TICK_TO_US(gNB->ulsch_tc_init_stats));
|
||||
LOG_D(PHY, "tca:%lld tcb:%lld tcg:%lld tce:%lld l1:%lld l2:%lld]\n\n",
|
||||
TICK_TO_US(gNB->ulsch_tc_alpha_stats),
|
||||
TICK_TO_US(gNB->ulsch_tc_beta_stats),
|
||||
TICK_TO_US(gNB->ulsch_tc_gamma_stats),
|
||||
TICK_TO_US(gNB->ulsch_tc_ext_stats),
|
||||
TICK_TO_US(gNB->ulsch_tc_intl1_stats),
|
||||
TICK_TO_US(gNB->ulsch_tc_intl2_stats)
|
||||
);
|
||||
#endif
|
||||
|
||||
return(0);
|
||||
}
|
||||
|
||||
static void* gNB_L1_thread_tx(void* param) {
|
||||
|
||||
PHY_VARS_gNB *gNB = (PHY_VARS_gNB*)param;
|
||||
gNB_L1_proc_t *gNB_proc = &gNB->proc;
|
||||
gNB_L1_rxtx_proc_t *proc = &gNB_proc->L1_proc_tx;
|
||||
//PHY_VARS_gNB *gNB = RC.gNB[0][proc->CC_id];
|
||||
PHY_VARS_gNB *gNB = (PHY_VARS_gNB*)param;
|
||||
gNB_L1_rxtx_proc_t *L1_proc_tx = &gNB->proc.L1_proc_tx;
|
||||
|
||||
|
||||
char thread_name[100];
|
||||
sprintf(thread_name,"TXnp4_%d\n",&gNB->proc.L1_proc == proc ? 0 : 1);
|
||||
//thread_top_init(thread_name,1,470000,500000,500000);
|
||||
|
||||
//wait_sync("tx_thread");
|
||||
|
||||
|
||||
// This tells L1_thread (RX) that L1_thread_tx is not ready yet
|
||||
pthread_mutex_lock(&L1_proc_tx->mutex);
|
||||
L1_proc_tx->instance_cnt = -2;
|
||||
pthread_mutex_unlock(&L1_proc_tx->mutex);
|
||||
|
||||
sprintf(thread_name,"gNB_L1_thread_tx\n");
|
||||
|
||||
thread_top_init(thread_name,1,870000L,1000000L,1000000L);
|
||||
|
||||
pthread_mutex_lock(&L1_proc_tx->mutex);
|
||||
L1_proc_tx->instance_cnt++;
|
||||
pthread_mutex_unlock(&L1_proc_tx->mutex);
|
||||
|
||||
while (!oai_exit) {
|
||||
|
||||
VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_gNB_PROC_RXTX1, 0 );
|
||||
if (wait_on_condition(&proc->mutex,&proc->cond,&proc->instance_cnt,thread_name)<0) break;
|
||||
if (wait_on_condition(&L1_proc_tx->mutex,&L1_proc_tx->cond,&L1_proc_tx->instance_cnt,thread_name)<0) break;
|
||||
VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_gNB_PROC_RXTX1, 1 );
|
||||
if (oai_exit) break;
|
||||
// *****************************************
|
||||
@@ -310,23 +268,25 @@ static void* gNB_L1_thread_tx(void* param) {
|
||||
// run PHY TX procedures the one after the other for all CCs to avoid race conditions
|
||||
// (may be relaxed in the future for performance reasons)
|
||||
// *****************************************
|
||||
|
||||
VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME(VCD_SIGNAL_DUMPER_VARIABLES_SLOT_NUMBER_TX1_GNB,proc->slot_tx);
|
||||
VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME(VCD_SIGNAL_DUMPER_VARIABLES_SLOT_NUMBER_RX1_GNB,proc->slot_rx);
|
||||
VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME(VCD_SIGNAL_DUMPER_VARIABLES_FRAME_NUMBER_TX1_GNB,proc->frame_tx);
|
||||
VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME(VCD_SIGNAL_DUMPER_VARIABLES_FRAME_NUMBER_RX1_GNB,proc->frame_rx);
|
||||
int frame_tx = L1_proc_tx->frame_tx;
|
||||
int slot_tx = L1_proc_tx->slot_tx;
|
||||
uint64_t timestamp_tx = L1_proc_tx->timestamp_tx;
|
||||
|
||||
phy_procedures_gNB_TX(gNB, proc, 1);
|
||||
VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME(VCD_SIGNAL_DUMPER_VARIABLES_SLOT_NUMBER_TX1_GNB,slot_tx);
|
||||
VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME(VCD_SIGNAL_DUMPER_VARIABLES_FRAME_NUMBER_TX1_GNB,frame_tx);
|
||||
|
||||
pthread_mutex_lock( &proc->mutex );
|
||||
proc->instance_cnt = -1;
|
||||
phy_procedures_gNB_TX(gNB, frame_tx,slot_tx, 1);
|
||||
|
||||
pthread_mutex_lock( &L1_proc_tx->mutex );
|
||||
L1_proc_tx->instance_cnt = -1;
|
||||
// the thread can now be woken up
|
||||
if (pthread_cond_signal(&proc->cond) != 0) {
|
||||
LOG_E( PHY, "[gNB] ERROR pthread_cond_signal for gNB TXnp4 thread\n");
|
||||
if (pthread_cond_signal(&L1_proc_tx->cond) != 0) {
|
||||
LOG_E( PHY, "[gNB] ERROR pthread_cond_signal for L1_threa_tx\n");
|
||||
exit_fun( "ERROR pthread_cond_signal" );
|
||||
}
|
||||
pthread_mutex_unlock( &proc->mutex );
|
||||
wakeup_txfh(proc,gNB);
|
||||
pthread_mutex_unlock( &L1_proc_tx->mutex );
|
||||
wakeup_txfh(gNB,L1_proc_tx,frame_tx,slot_tx,timestamp_tx);
|
||||
VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_gNB_PROC_RXTX1, 0 );
|
||||
}
|
||||
|
||||
return 0;
|
||||
@@ -343,49 +303,58 @@ static void* gNB_L1_thread( void* param ) {
|
||||
static int gNB_thread_rxtx_status;
|
||||
PHY_VARS_gNB *gNB = (PHY_VARS_gNB*)param;
|
||||
gNB_L1_proc_t *gNB_proc = &gNB->proc;
|
||||
gNB_L1_rxtx_proc_t *proc = &gNB_proc->L1_proc;
|
||||
//PHY_VARS_gNB *gNB = RC.gNB[0][proc->CC_id];
|
||||
gNB_L1_rxtx_proc_t *L1_proc = &gNB_proc->L1_proc;
|
||||
|
||||
|
||||
char thread_name[100];
|
||||
|
||||
|
||||
// This tells ru_thread that L1_thread is not ready
|
||||
pthread_mutex_lock(&L1_proc->mutex);
|
||||
L1_proc->instance_cnt = -2;
|
||||
pthread_mutex_unlock(&L1_proc->mutex);
|
||||
|
||||
// set default return value
|
||||
gNB_thread_rxtx_status = 0;
|
||||
|
||||
|
||||
sprintf(thread_name,"RXn_TXnp4_%d",&gNB->proc.L1_proc == proc ? 0 : 1);
|
||||
//thread_top_init(thread_name,1,850000L,1000000L,2000000L);
|
||||
sprintf(thread_name,"gNB_L1_thread");
|
||||
|
||||
thread_top_init(thread_name,1,870000L,1000000L,1000000L);
|
||||
|
||||
// This tells ru_thread that L1_thread is ready
|
||||
pthread_mutex_lock(&L1_proc->mutex);
|
||||
L1_proc->instance_cnt++;
|
||||
pthread_mutex_unlock(&L1_proc->mutex);
|
||||
|
||||
while (!oai_exit) {
|
||||
|
||||
VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_gNB_PROC_RXTX0, 0 );
|
||||
if (wait_on_condition(&proc->mutex,&proc->cond,&proc->instance_cnt,thread_name)<0) break;
|
||||
if (wait_on_condition(&L1_proc->mutex,&L1_proc->cond,&L1_proc->instance_cnt,thread_name)<0) break;
|
||||
VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_gNB_PROC_RXTX0, 1 );
|
||||
|
||||
VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME(VCD_SIGNAL_DUMPER_VARIABLES_SLOT_NUMBER_TX0_GNB,proc->slot_tx);
|
||||
VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME(VCD_SIGNAL_DUMPER_VARIABLES_SLOT_NUMBER_RX0_GNB,proc->slot_rx);
|
||||
VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME(VCD_SIGNAL_DUMPER_VARIABLES_FRAME_NUMBER_TX0_GNB,proc->frame_tx);
|
||||
VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME(VCD_SIGNAL_DUMPER_VARIABLES_FRAME_NUMBER_RX0_GNB,proc->frame_rx);
|
||||
int frame_rx = L1_proc->frame_rx;
|
||||
int slot_rx = L1_proc->slot_rx;
|
||||
int frame_tx = L1_proc->frame_tx;
|
||||
int slot_tx = L1_proc->slot_tx;
|
||||
uint64_t timestamp_tx = L1_proc->timestamp_tx;
|
||||
|
||||
VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME(VCD_SIGNAL_DUMPER_VARIABLES_SLOT_NUMBER_TX0_GNB,slot_tx);
|
||||
VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME(VCD_SIGNAL_DUMPER_VARIABLES_SLOT_NUMBER_RX0_GNB,slot_rx);
|
||||
VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME(VCD_SIGNAL_DUMPER_VARIABLES_FRAME_NUMBER_TX0_GNB,frame_tx);
|
||||
VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME(VCD_SIGNAL_DUMPER_VARIABLES_FRAME_NUMBER_RX0_GNB,frame_rx);
|
||||
|
||||
if (oai_exit) break;
|
||||
|
||||
if (gNB->CC_id==0)
|
||||
{
|
||||
if (rxtx(gNB,proc,thread_name) < 0) break;
|
||||
if (rxtx(gNB,frame_rx,slot_rx,frame_tx,slot_tx,thread_name) < 0) break;
|
||||
|
||||
}
|
||||
if(get_thread_parallel_conf() == PARALLEL_RU_L1_SPLIT){
|
||||
phy_procedures_gNB_TX(gNB, proc, 1);
|
||||
}
|
||||
if (release_thread(&proc->mutex,&proc->instance_cnt,thread_name)<0) break;
|
||||
if(get_thread_parallel_conf() == PARALLEL_RU_L1_TRX_SPLIT){
|
||||
wakeup_tx(gNB);
|
||||
}
|
||||
else if(get_thread_parallel_conf() == PARALLEL_RU_L1_SPLIT){
|
||||
wakeup_txfh(proc,gNB);
|
||||
}
|
||||
if (release_thread(&L1_proc->mutex,&L1_proc->instance_cnt,thread_name)<0) break;
|
||||
|
||||
if(get_thread_parallel_conf() == PARALLEL_RU_L1_TRX_SPLIT) wakeup_tx(gNB,frame_rx,slot_rx,frame_tx,slot_tx,timestamp_tx);
|
||||
else if(get_thread_parallel_conf() == PARALLEL_RU_L1_SPLIT) wakeup_txfh(gNB,L1_proc,frame_tx,slot_tx,timestamp_tx);
|
||||
|
||||
|
||||
} // while !oai_exit
|
||||
|
||||
@@ -439,72 +408,83 @@ void gNB_top(PHY_VARS_gNB *gNB, int frame_rx, int slot_rx, char *string, struct
|
||||
L1_proc->frame_tx = (L1_proc->slot_rx > (fp->slots_per_frame-1-sl_ahead)) ? (L1_proc->frame_rx+1)&1023 : L1_proc->frame_rx;
|
||||
L1_proc->slot_tx = (L1_proc->slot_rx + sl_ahead)%fp->slots_per_frame;
|
||||
|
||||
if (rxtx(gNB,L1_proc,string) < 0) LOG_E(PHY,"gNB %d CC_id %d failed during execution\n",gNB->Mod_id,gNB->CC_id);
|
||||
if (rxtx(gNB,L1_proc->frame_rx,L1_proc->slot_rx,L1_proc->frame_tx,L1_proc->slot_tx,string) < 0) LOG_E(PHY,"gNB %d CC_id %d failed during execution\n",gNB->Mod_id,gNB->CC_id);
|
||||
ru_proc->timestamp_tx = L1_proc->timestamp_tx;
|
||||
ru_proc->tti_tx = L1_proc->slot_tx;
|
||||
ru_proc->frame_tx = L1_proc->frame_tx;
|
||||
}
|
||||
}
|
||||
|
||||
int wakeup_txfh(gNB_L1_rxtx_proc_t *proc,PHY_VARS_gNB *gNB) {
|
||||
int wakeup_txfh(PHY_VARS_gNB *gNB,gNB_L1_rxtx_proc_t *proc,int frame_tx,int slot_tx,uint64_t timestamp_tx) {
|
||||
|
||||
RU_t *ru;
|
||||
RU_proc_t *ru_proc;
|
||||
|
||||
|
||||
int waitret;
|
||||
struct timespec wait;
|
||||
wait.tv_sec=0;
|
||||
wait.tv_nsec=5000000L;
|
||||
//printf("~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~inside wakeup_txfh %d.%d IC_RU = %d\n", proc->frame_tx, proc->slot_tx, proc->instance_cnt_RUs);
|
||||
wait.tv_nsec=10000000L;
|
||||
|
||||
|
||||
if(wait_on_condition(&proc->mutex_RUs,&proc->cond_RUs,&proc->instance_cnt_RUs,"wakeup_txfh")<0) {
|
||||
LOG_E(PHY,"Frame %d, subframe %d: TX FH not ready\n", proc->frame_tx, proc->slot_tx);
|
||||
return(-1);
|
||||
}
|
||||
pthread_mutex_lock(&gNB->proc.mutex_RU_tx);
|
||||
gNB->proc.RU_mask_tx = 0;
|
||||
pthread_mutex_unlock(&gNB->proc.mutex_RU_tx);
|
||||
if (release_thread(&proc->mutex_RUs,&proc->instance_cnt_RUs,"wakeup_txfh")<0) return(-1);
|
||||
VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME(VCD_SIGNAL_DUMPER_VARIABLES_FRAME_NUMBER_RX0_UE,proc->instance_cnt_RUs);
|
||||
|
||||
// note this should depend on the numerology used by the TX L1 thread, set here for 500us slot time
|
||||
waitret=timedwait_on_condition(&proc->mutex_RUs_tx,&proc->cond_RUs,&proc->instance_cnt_RUs,"wakeup_txfh",500000);
|
||||
|
||||
if (waitret == ETIMEDOUT) {
|
||||
LOG_W(PHY,"Dropping TX slot (%d.%d) because FH is blocked more than 2 slot times (1000us)\n",frame_tx,slot_tx);
|
||||
|
||||
pthread_mutex_lock(&gNB->proc.mutex_RU_tx);
|
||||
gNB->proc.RU_mask_tx = 0;
|
||||
pthread_mutex_unlock(&gNB->proc.mutex_RU_tx);
|
||||
VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME(VCD_SIGNAL_DUMPER_VARIABLES_FRAME_NUMBER_TX0_UE,1);
|
||||
VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME(VCD_SIGNAL_DUMPER_VARIABLES_FRAME_NUMBER_TX0_UE,0);
|
||||
|
||||
return(-1);
|
||||
}
|
||||
else if (release_thread(&proc->mutex_RUs_tx,&proc->instance_cnt_RUs,"wakeup_txfh")<0) return(-1);
|
||||
|
||||
for(int i=0; i<gNB->num_RU; i++)
|
||||
{
|
||||
ru = gNB->RU_list[i];
|
||||
ru_proc = &ru->proc;
|
||||
if (ru_proc->instance_cnt_gNBs == 0) {
|
||||
LOG_E(PHY,"Frame %d, subframe %d: TX FH thread busy, dropping Frame %d, subframe %d\n", ru_proc->frame_tx, ru_proc->tti_tx, proc->frame_rx, proc->slot_rx);
|
||||
pthread_mutex_lock(&gNB->proc.mutex_RU_tx);
|
||||
gNB->proc.RU_mask_tx = 0;
|
||||
pthread_mutex_unlock(&gNB->proc.mutex_RU_tx);
|
||||
return(-1);
|
||||
}
|
||||
if (pthread_mutex_timedlock(&ru_proc->mutex_gNBs,&wait) != 0) {
|
||||
LOG_E( PHY, "[eNB] ERROR pthread_mutex_lock for eNB TX1 thread %d (IC %d)\n", ru_proc->tti_rx&1,ru_proc->instance_cnt_gNBs );
|
||||
exit_fun( "error locking mutex_gNB" );
|
||||
if ((waitret = pthread_mutex_timedlock(&ru_proc->mutex_gNBs,&wait)) == ETIMEDOUT) {
|
||||
LOG_W( PHY, "[eNB] ERROR pthread_mutex_lock timed out on mutex_gNBs L1_thread_tx (timeout)\n");
|
||||
return(-1);
|
||||
}
|
||||
else AssertFatal(waitret==0,"pthread_mutex_timedlock returned %d\n",waitret);
|
||||
|
||||
ru_proc->instance_cnt_gNBs = 0;
|
||||
ru_proc->timestamp_tx = proc->timestamp_tx;
|
||||
ru_proc->tti_tx = proc->slot_tx;
|
||||
ru_proc->frame_tx = proc->frame_tx;
|
||||
ru_proc->timestamp_tx = timestamp_tx;
|
||||
ru_proc->tti_tx = slot_tx;
|
||||
ru_proc->frame_tx = frame_tx;
|
||||
|
||||
LOG_I(PHY,"Signaling tx_thread_fh for %d.%d\n",ru_proc->frame_tx,ru_proc->tti_tx);
|
||||
VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME( VCD_SIGNAL_DUMPER_VARIABLES_FRAME_NUMBER_RX1_UE, ru_proc->instance_cnt_gNBs);
|
||||
pthread_mutex_unlock( &ru_proc->mutex_gNBs );
|
||||
|
||||
LOG_D(PHY,"Signaling tx_thread_fh for %d.%d\n",frame_tx,slot_tx);
|
||||
// the thread can now be woken up
|
||||
if (pthread_cond_signal(&ru_proc->cond_gNBs) != 0) {
|
||||
LOG_E( PHY, "[gNB] ERROR pthread_cond_signal for gNB TXnp4 thread\n");
|
||||
exit_fun( "ERROR pthread_cond_signal" );
|
||||
return(-1);
|
||||
}
|
||||
|
||||
pthread_mutex_unlock( &ru_proc->mutex_gNBs );
|
||||
}
|
||||
|
||||
return(0);
|
||||
}
|
||||
|
||||
int wakeup_tx(PHY_VARS_gNB *gNB) {
|
||||
int wakeup_tx(PHY_VARS_gNB *gNB,int frame_rx,int slot_rx,int frame_tx,int slot_tx,uint64_t timestamp_tx) {
|
||||
|
||||
gNB_L1_proc_t *proc=&gNB->proc;
|
||||
|
||||
gNB_L1_rxtx_proc_t *L1_proc_tx = &proc->L1_proc_tx;
|
||||
gNB_L1_rxtx_proc_t *L1_proc = &proc->L1_proc;
|
||||
gNB_L1_rxtx_proc_t *L1_proc_tx = &gNB->proc.L1_proc_tx;
|
||||
|
||||
|
||||
struct timespec wait;
|
||||
@@ -517,6 +497,11 @@ int wakeup_tx(PHY_VARS_gNB *gNB) {
|
||||
exit_fun("ERROR pthread_lock");
|
||||
return(-1);
|
||||
}
|
||||
if (L1_proc_tx->instance_cnt == -2) { // L1_thread_tx isn't ready yet so return
|
||||
pthread_mutex_unlock( &L1_proc_tx->mutex);
|
||||
return(0);
|
||||
}
|
||||
|
||||
while(L1_proc_tx->instance_cnt == 0){
|
||||
pthread_cond_wait(&L1_proc_tx->cond,&L1_proc_tx->mutex);
|
||||
}
|
||||
@@ -524,12 +509,17 @@ int wakeup_tx(PHY_VARS_gNB *gNB) {
|
||||
L1_proc_tx->instance_cnt = 0;
|
||||
|
||||
|
||||
L1_proc_tx->slot_rx = L1_proc->slot_rx;
|
||||
L1_proc_tx->frame_rx = L1_proc->frame_rx;
|
||||
L1_proc_tx->slot_tx = L1_proc->slot_tx;
|
||||
L1_proc_tx->frame_tx = L1_proc->frame_tx;
|
||||
L1_proc_tx->timestamp_tx = L1_proc->timestamp_tx;
|
||||
|
||||
L1_proc_tx->slot_rx = slot_rx;
|
||||
L1_proc_tx->frame_rx = frame_rx;
|
||||
L1_proc_tx->slot_tx = slot_tx;
|
||||
L1_proc_tx->frame_tx = frame_tx;
|
||||
L1_proc_tx->timestamp_tx = timestamp_tx;
|
||||
|
||||
pthread_mutex_unlock( &L1_proc_tx->mutex);
|
||||
|
||||
VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME(VCD_SIGNAL_DUMPER_VARIABLES_FRAME_NUMBER_TX1_UE,1);
|
||||
VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME(VCD_SIGNAL_DUMPER_VARIABLES_FRAME_NUMBER_TX1_UE,0);
|
||||
|
||||
// the thread can now be woken up
|
||||
if (pthread_cond_signal(&L1_proc_tx->cond) != 0) {
|
||||
LOG_E( PHY, "[eNB] ERROR pthread_cond_signal for eNB TXnp4 thread\n");
|
||||
@@ -537,7 +527,6 @@ int wakeup_tx(PHY_VARS_gNB *gNB) {
|
||||
return(-1);
|
||||
}
|
||||
|
||||
pthread_mutex_unlock( &L1_proc_tx->mutex);
|
||||
|
||||
return(0);
|
||||
}
|
||||
@@ -575,24 +564,24 @@ int wakeup_rxtx(PHY_VARS_gNB *gNB,RU_t *ru) {
|
||||
wait.tv_sec=0;
|
||||
wait.tv_nsec=5000000L;
|
||||
|
||||
/* accept some delay in processing - up to 5ms */
|
||||
for (i = 0; i < fp->slots_per_frame && L1_proc->instance_cnt == 0; i++) {
|
||||
LOG_W( PHY,"[gNB] SFN.SL %d.%d, gNB RXn-TXnp4 thread busy!! (i %d, cnt %i)\n", L1_proc->frame_tx, L1_proc->slot_tx, i,L1_proc->instance_cnt);
|
||||
usleep(100);
|
||||
}
|
||||
if (L1_proc->instance_cnt == 0) {
|
||||
exit_fun( "TX thread busy" );
|
||||
return(-1);
|
||||
}
|
||||
|
||||
// wake up TX for subframe n+sl_ahead
|
||||
// lock the TX mutex and make sure the thread is ready
|
||||
if (pthread_mutex_timedlock(&L1_proc->mutex,&wait) != 0) {
|
||||
LOG_E( PHY, "[gNB] ERROR pthread_mutex_lock for gNB RXTX thread %d (IC %d)\n", L1_proc->slot_rx&1,L1_proc->instance_cnt );
|
||||
LOG_E( PHY, "[gNB] ERROR pthread_mutex_lock for gNB L1 thread %d (IC %d)\n", L1_proc->slot_rx&1,L1_proc->instance_cnt );
|
||||
exit_fun( "error locking mutex" );
|
||||
return(-1);
|
||||
}
|
||||
|
||||
|
||||
if (L1_proc->instance_cnt==-2) { // L1_thread isn't ready yet so return
|
||||
pthread_mutex_unlock( &L1_proc->mutex );
|
||||
return(0);
|
||||
}
|
||||
|
||||
if (L1_proc->instance_cnt == 0) { // L1_thread is busy so abort the subframe
|
||||
pthread_mutex_unlock( &L1_proc->mutex );
|
||||
LOG_W(PHY,"L1_thread isn't ready in %d.%d, aborting RX processing\n",ru_proc->frame_rx,ru_proc->tti_rx);
|
||||
}
|
||||
|
||||
++L1_proc->instance_cnt;
|
||||
|
||||
// We have just received and processed the common part of a subframe, say n.
|
||||
@@ -607,7 +596,9 @@ int wakeup_rxtx(PHY_VARS_gNB *gNB,RU_t *ru) {
|
||||
L1_proc->frame_tx = (L1_proc->slot_rx > (fp->slots_per_frame-1-sl_ahead)) ? (L1_proc->frame_rx+1)&1023 : L1_proc->frame_rx;
|
||||
L1_proc->slot_tx = (L1_proc->slot_rx + sl_ahead)%fp->slots_per_frame;
|
||||
|
||||
LOG_I(PHY,"wakeupL1: passing parameter IC = %d, RX: %d.%d, TX: %d.%d to L1 sl_ahead = %d\n", L1_proc->instance_cnt, L1_proc->frame_rx, L1_proc->slot_rx, L1_proc->frame_tx, L1_proc->slot_tx, sl_ahead);
|
||||
LOG_D(PHY,"wakeupL1: passing parameter IC = %d, RX: %d.%d, TX: %d.%d to L1 sl_ahead = %d\n", L1_proc->instance_cnt, L1_proc->frame_rx, L1_proc->slot_rx, L1_proc->frame_tx, L1_proc->slot_tx, sl_ahead);
|
||||
|
||||
pthread_mutex_unlock( &L1_proc->mutex );
|
||||
|
||||
// the thread can now be woken up
|
||||
if (pthread_cond_signal(&L1_proc->cond) != 0) {
|
||||
@@ -616,8 +607,6 @@ int wakeup_rxtx(PHY_VARS_gNB *gNB,RU_t *ru) {
|
||||
return(-1);
|
||||
}
|
||||
|
||||
pthread_mutex_unlock( &L1_proc->mutex );
|
||||
|
||||
return(0);
|
||||
}
|
||||
/*
|
||||
@@ -747,8 +736,8 @@ void init_gNB_proc(int inst) {
|
||||
|
||||
L1_proc = &proc->L1_proc;
|
||||
L1_proc_tx = &proc->L1_proc_tx;
|
||||
L1_proc->instance_cnt = -1;
|
||||
L1_proc_tx->instance_cnt = -1;
|
||||
L1_proc->instance_cnt = -2;
|
||||
L1_proc_tx->instance_cnt = -2;
|
||||
L1_proc->instance_cnt_RUs = 0;
|
||||
L1_proc_tx->instance_cnt_RUs = 0;
|
||||
proc->instance_cnt_prach = -1;
|
||||
@@ -928,7 +917,7 @@ void init_eNB_afterRU(void) {
|
||||
|
||||
//LOG_I(PHY,"Overwriting gNB->prach_vars.rxsigF[0]:%p\n", gNB->prach_vars.rxsigF[0]);
|
||||
|
||||
gNB->prach_vars.rxsigF[0] = (int16_t**)malloc16(64*sizeof(int16_t*));
|
||||
//gNB->prach_vars.rxsigF[0] = (int16_t**)malloc16(64*sizeof(int16_t*));
|
||||
|
||||
LOG_I(PHY,"gNB->num_RU:%d\n", gNB->num_RU);
|
||||
|
||||
@@ -944,7 +933,7 @@ void init_eNB_afterRU(void) {
|
||||
|
||||
for (i=0;i<gNB->RU_list[ru_id]->nb_rx;aa++,i++) {
|
||||
LOG_I(PHY,"Attaching RU %d antenna %d to gNB antenna %d\n",gNB->RU_list[ru_id]->idx,i,aa);
|
||||
gNB->prach_vars.rxsigF[0][aa] = gNB->RU_list[ru_id]->prach_rxsigF[i];
|
||||
// gNB->prach_vars.rxsigF[0][aa] = gNB->RU_list[ru_id]->prach_rxsigF[i];
|
||||
gNB->common_vars.rxdataF[aa] = gNB->RU_list[ru_id]->common.rxdataF[i];
|
||||
}
|
||||
}
|
||||
|
||||
+48
-58
@@ -580,8 +580,8 @@ void fh_if4p5_north_asynch_in(RU_t *ru,int *frame,int *slot) {
|
||||
VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME( VCD_SIGNAL_DUMPER_VARIABLES_TTI_NUMBER_TX0_RU, slot_tx );
|
||||
}
|
||||
|
||||
if (ru->feptx_ofdm) ru->feptx_ofdm(ru);
|
||||
if (ru->fh_south_out) ru->fh_south_out(ru);
|
||||
if (ru->feptx_ofdm) ru->feptx_ofdm(ru,frame_tx,slot_tx);
|
||||
if (ru->fh_south_out) ru->fh_south_out(ru,frame_tx,slot_tx,proc->timestamp_tx);
|
||||
}
|
||||
|
||||
void fh_if5_north_out(RU_t *ru) {
|
||||
@@ -661,7 +661,7 @@ void rx_rf(RU_t *ru,int *frame,int *slot) {
|
||||
|
||||
old_ts = proc->timestamp_rx;
|
||||
|
||||
LOG_I(PHY,"Reading %d samples for slot %d (%p)\n",fp->samples_per_slot,*slot,rxp[0]);
|
||||
LOG_D(PHY,"Reading %d samples for slot %d (%p)\n",fp->samples_per_slot,*slot,rxp[0]);
|
||||
|
||||
if(emulate_rf){
|
||||
wait_on_condition(&proc->mutex_emulateRF,&proc->cond_emulateRF,&proc->instance_cnt_emulateRF,"emulatedRF_thread");
|
||||
@@ -691,7 +691,7 @@ void rx_rf(RU_t *ru,int *frame,int *slot) {
|
||||
}
|
||||
else {
|
||||
if (proc->timestamp_rx - old_ts != fp->samples_per_slot) {
|
||||
LOG_I(PHY,"rx_rf: rfdevice timing drift of %"PRId64" samples (ts_off %"PRId64")\n",proc->timestamp_rx - old_ts - fp->samples_per_slot,ru->ts_offset);
|
||||
LOG_D(PHY,"rx_rf: rfdevice timing drift of %"PRId64" samples (ts_off %"PRId64")\n",proc->timestamp_rx - old_ts - fp->samples_per_slot,ru->ts_offset);
|
||||
ru->ts_offset += (proc->timestamp_rx - old_ts - fp->samples_per_slot);
|
||||
proc->timestamp_rx = ts-ru->ts_offset;
|
||||
}
|
||||
@@ -701,15 +701,6 @@ void rx_rf(RU_t *ru,int *frame,int *slot) {
|
||||
proc->tti_rx = (proc->timestamp_rx / fp->samples_per_slot)%fp->slots_per_frame;
|
||||
// synchronize first reception to frame 0 subframe 0
|
||||
|
||||
proc->timestamp_tx = proc->timestamp_rx+(sl_ahead*fp->samples_per_slot);
|
||||
proc->tti_tx = (proc->tti_rx+sl_ahead)%fp->slots_per_frame;
|
||||
proc->frame_tx = (proc->tti_rx>(fp->slots_per_frame-1-sl_ahead)) ? (proc->frame_rx+1)&1023 : proc->frame_rx;
|
||||
|
||||
LOG_I(PHY,"RU %d/%d TS %llu (off %d), frame %d, slot %d.%d / %d\n",
|
||||
ru->idx,
|
||||
0,
|
||||
(unsigned long long int)proc->timestamp_rx,
|
||||
(int)ru->ts_offset,proc->frame_rx,proc->tti_rx,proc->tti_tx,fp->slots_per_frame);
|
||||
|
||||
// dump VCD output for first RU in list
|
||||
if (ru == RC.ru[0]) {
|
||||
@@ -745,7 +736,7 @@ void rx_rf(RU_t *ru,int *frame,int *slot) {
|
||||
}
|
||||
|
||||
|
||||
void tx_rf(RU_t *ru) {
|
||||
void tx_rf(RU_t *ru,int frame_tx,int tti_tx,uint64_t timestamp_tx) {
|
||||
|
||||
RU_proc_t *proc = &ru->proc;
|
||||
NR_DL_FRAME_PARMS *fp = ru->nr_frame_parms;
|
||||
@@ -754,10 +745,10 @@ void tx_rf(RU_t *ru) {
|
||||
unsigned int txs;
|
||||
int i;
|
||||
|
||||
T(T_ENB_PHY_OUTPUT_SIGNAL, T_INT(0), T_INT(0), T_INT(proc->frame_tx), T_INT(proc->tti_tx),
|
||||
T_INT(0), T_BUFFER(&ru->common.txdata[0][proc->tti_tx * fp->samples_per_slot], fp->samples_per_slot * 4));
|
||||
T(T_ENB_PHY_OUTPUT_SIGNAL, T_INT(0), T_INT(0), T_INT(frame_tx), T_INT(tti_tx),
|
||||
T_INT(0), T_BUFFER(&ru->common.txdata[0][tti_tx * fp->samples_per_slot], fp->samples_per_slot * 4));
|
||||
|
||||
nr_subframe_t SF_type = nr_slot_select(cfg,proc->tti_tx%fp->slots_per_frame);
|
||||
nr_subframe_t SF_type = nr_slot_select(cfg,tti_tx%fp->slots_per_frame);
|
||||
int sf_extension = 0;
|
||||
|
||||
if ((SF_type == SF_DL) ||
|
||||
@@ -785,29 +776,28 @@ void tx_rf(RU_t *ru) {
|
||||
flags = 4; // start of burst and end of burst (only one DL SF between two UL)
|
||||
sf_extension = ru->N_TA_offset<<1;
|
||||
} */
|
||||
VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME( VCD_SIGNAL_DUMPER_VARIABLES_FRAME_NUMBER_TX0_RU, proc->frame_tx );
|
||||
VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME( VCD_SIGNAL_DUMPER_VARIABLES_TTI_NUMBER_TX0_RU, proc->tti_tx );
|
||||
VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME( VCD_SIGNAL_DUMPER_VARIABLES_FRAME_NUMBER_TX0_RU, frame_tx );
|
||||
VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME( VCD_SIGNAL_DUMPER_VARIABLES_TTI_NUMBER_TX0_RU,tti_tx );
|
||||
|
||||
for (i=0; i<ru->nb_tx; i++)
|
||||
|
||||
txp[i] = (void*)&ru->common.txdata[i][(proc->tti_tx*fp->samples_per_slot)-sf_extension];
|
||||
txp[i] = (void*)&ru->common.txdata[i][(tti_tx*fp->samples_per_slot)-sf_extension];
|
||||
|
||||
VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME( VCD_SIGNAL_DUMPER_VARIABLES_TRX_TST, (proc->timestamp_tx-ru->openair0_cfg.tx_sample_advance)&0xffffffff );
|
||||
VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME( VCD_SIGNAL_DUMPER_VARIABLES_TRX_TST, (timestamp_tx-ru->openair0_cfg.tx_sample_advance)&0xffffffff );
|
||||
VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_TRX_WRITE, 1 );
|
||||
// prepare tx buffer pointers
|
||||
txs = ru->rfdevice.trx_write_func(&ru->rfdevice,
|
||||
proc->timestamp_tx+ru->ts_offset-ru->openair0_cfg.tx_sample_advance-sf_extension,
|
||||
timestamp_tx+ru->ts_offset-ru->openair0_cfg.tx_sample_advance-sf_extension,
|
||||
txp,
|
||||
siglen+sf_extension,
|
||||
ru->nb_tx,
|
||||
flags);
|
||||
|
||||
4);//flags);
|
||||
LOG_D(PHY,"[TXPATH] RU %d tx_rf, writing to TS %llu, frame %d, unwrapped_frame %d, subframe %d\n",ru->idx,
|
||||
(long long unsigned int)proc->timestamp_tx,proc->frame_tx,proc->frame_tx_unwrap,proc->tti_tx);
|
||||
(long long unsigned int)timestamp_tx,frame_tx,proc->frame_tx_unwrap,tti_tx);
|
||||
VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_TRX_WRITE, 0 );
|
||||
|
||||
|
||||
AssertFatal(txs == siglen+sf_extension,"TX : Timeout (sent %d/%d)\n",txs, siglen);
|
||||
AssertFatal(txs == (siglen+sf_extension),"TX : Timeout (sent %d/%d)\n",txs, siglen);
|
||||
|
||||
}
|
||||
}
|
||||
@@ -1084,7 +1074,7 @@ static inline int wakeup_prach_ru(RU_t *ru) {
|
||||
ru->gNB_list[0]->proc.frame_prach = ru->proc.frame_rx;
|
||||
ru->gNB_list[0]->proc.slot_prach = ru->proc.tti_rx;
|
||||
}
|
||||
LOG_I(PHY,"RU %d: waking up PRACH thread\n",ru->idx);
|
||||
LOG_D(PHY,"RU %d: waking up PRACH thread\n",ru->idx);
|
||||
// the thread can now be woken up
|
||||
AssertFatal(pthread_cond_signal(&ru->proc.cond_prach) == 0, "ERROR pthread_cond_signal for RU prach thread\n");
|
||||
}
|
||||
@@ -1289,47 +1279,49 @@ static void* ru_thread_tx( void* param ) {
|
||||
int print_frame = 8;
|
||||
int i = 0;
|
||||
|
||||
cpu_set_t cpuset;
|
||||
CPU_ZERO(&cpuset);
|
||||
|
||||
|
||||
thread_top_init("ru_thread_tx",1,400000,500000,500000);
|
||||
|
||||
//CPU_SET(5, &cpuset);
|
||||
//pthread_setaffinity_np(pthread_self(), sizeof(cpu_set_t), &cpuset);
|
||||
//wait_sync("ru_thread_tx");
|
||||
thread_top_init("ru_thread_tx",0,400000,500000,500000);
|
||||
|
||||
wait_on_condition(&proc->mutex_FH1,&proc->cond_FH1,&proc->instance_cnt_FH1,"ru_thread_tx");
|
||||
|
||||
|
||||
printf( "ru_thread_tx ready\n");
|
||||
while (!oai_exit) {
|
||||
|
||||
if (oai_exit) break;
|
||||
|
||||
|
||||
LOG_I(PHY,"ru_thread_tx: Waiting for TX processing\n");
|
||||
LOG_D(PHY,"ru_thread_tx: Waiting for TX processing\n");
|
||||
// wait until eNBs are finished subframe RX n and TX n+4
|
||||
|
||||
wait_on_condition(&proc->mutex_gNBs,&proc->cond_gNBs,&proc->instance_cnt_gNBs,"ru_thread_tx");
|
||||
|
||||
|
||||
pthread_mutex_lock(&proc->mutex_gNBs);
|
||||
int frame_tx=proc->frame_tx;
|
||||
int tti_tx =proc->tti_tx;
|
||||
uint64_t timestamp_tx = proc->timestamp_tx;
|
||||
|
||||
pthread_mutex_unlock(&proc->mutex_gNBs);
|
||||
|
||||
if (oai_exit) break;
|
||||
|
||||
//printf("~~~~~~~~~~~~~~~~start process for ru_thread_tx %d.%d\n", proc->frame_tx, proc->tti_tx);
|
||||
VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME( VCD_SIGNAL_DUMPER_VARIABLES_FRAME_NUMBER_TX0_RU, proc->frame_tx );
|
||||
VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME( VCD_SIGNAL_DUMPER_VARIABLES_TTI_NUMBER_TX0_RU, proc->tti_tx );
|
||||
VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME( VCD_SIGNAL_DUMPER_VARIABLES_FRAME_NUMBER_TX0_RU, frame_tx );
|
||||
VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME( VCD_SIGNAL_DUMPER_VARIABLES_TTI_NUMBER_TX0_RU, tti_tx );
|
||||
// do TX front-end processing if needed (precoding and/or IDFTs)
|
||||
if (ru->feptx_prec) ru->feptx_prec(ru);
|
||||
if (ru->feptx_prec) ru->feptx_prec(ru,frame_tx,tti_tx);
|
||||
|
||||
// do OFDM if needed
|
||||
if ((ru->fh_north_asynch_in == NULL) && (ru->feptx_ofdm)) ru->feptx_ofdm(ru);
|
||||
if ((ru->fh_north_asynch_in == NULL) && (ru->feptx_ofdm)) ru->feptx_ofdm(ru,frame_tx,tti_tx);
|
||||
if(!emulate_rf){
|
||||
// do outgoing fronthaul (south) if needed
|
||||
if ((ru->fh_north_asynch_in == NULL) && (ru->fh_south_out)) ru->fh_south_out(ru);
|
||||
|
||||
if ((ru->fh_north_asynch_in == NULL) && (ru->fh_south_out)) ru->fh_south_out(ru,frame_tx,tti_tx,timestamp_tx);
|
||||
if (ru->fh_north_out) ru->fh_north_out(ru);
|
||||
}
|
||||
else
|
||||
{
|
||||
if(proc->frame_tx == print_frame)
|
||||
if(frame_tx == print_frame)
|
||||
{
|
||||
for (i=0; i<ru->nb_tx; i++)
|
||||
{
|
||||
@@ -1356,6 +1348,8 @@ static void* ru_thread_tx( void* param ) {
|
||||
}//if(proc->frame_tx == print_frame)
|
||||
}//else emulate_rf
|
||||
release_thread(&proc->mutex_gNBs,&proc->instance_cnt_gNBs,"ru_thread_tx");
|
||||
VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME( VCD_SIGNAL_DUMPER_VARIABLES_FRAME_NUMBER_RX1_UE, proc->instance_cnt_gNBs);
|
||||
|
||||
for(i = 0; i<ru->num_gNB; i++)
|
||||
{
|
||||
gNB = ru->gNB_list[i];
|
||||
@@ -1377,14 +1371,16 @@ static void* ru_thread_tx( void* param ) {
|
||||
gNB_proc->RU_mask_tx = 0;
|
||||
pthread_mutex_unlock(&gNB_proc->mutex_RU_tx);
|
||||
|
||||
pthread_mutex_lock( &L1_proc->mutex_RUs);
|
||||
pthread_mutex_lock(&L1_proc->mutex_RUs_tx);
|
||||
L1_proc->instance_cnt_RUs = 0;
|
||||
VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME(VCD_SIGNAL_DUMPER_VARIABLES_FRAME_NUMBER_RX0_UE,L1_proc->instance_cnt_RUs);
|
||||
pthread_mutex_unlock( &L1_proc->mutex_RUs_tx );
|
||||
|
||||
// the thread can now be woken up
|
||||
if (pthread_cond_signal(&L1_proc->cond_RUs) != 0) {
|
||||
LOG_E( PHY, "[eNB] ERROR pthread_cond_signal for eNB TXnp4 thread\n");
|
||||
LOG_E( PHY, "[eNB] ERROR pthread_cond_signal for eNB L1 TX thread\n");
|
||||
exit_fun( "ERROR pthread_cond_signal" );
|
||||
}
|
||||
pthread_mutex_unlock( &L1_proc->mutex_RUs );
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1414,7 +1410,7 @@ static void* ru_thread( void* param ) {
|
||||
sprintf(threadname,"ru_thread %d",ru->idx);
|
||||
thread_top_init(threadname,0,870000,1000000,1000000);
|
||||
|
||||
LOG_I(PHY,"Starting RU %d (%s,%s),\n",ru->idx,NB_functions[ru->function],NB_timing[ru->if_timing]);
|
||||
LOG_D(PHY,"Starting RU %d (%s,%s),\n",ru->idx,NB_functions[ru->function],NB_timing[ru->if_timing]);
|
||||
|
||||
if(emulate_rf){
|
||||
fill_rf_config(ru,ru->rf_config_file);
|
||||
@@ -1505,7 +1501,7 @@ static void* ru_thread( void* param ) {
|
||||
if (ru->fh_south_in) ru->fh_south_in(ru,&frame,&slot);
|
||||
else AssertFatal(1==0, "No fronthaul interface at south port");
|
||||
|
||||
LOG_I(PHY,"AFTER fh_south_in - SFN/SL:%d%d RU->proc[RX:%d.%d TX:%d.%d] RC.gNB[0][0]:[RX:%d%d TX(SFN):%d]\n",
|
||||
LOG_D(PHY,"AFTER fh_south_in - SFN/SL:%d%d RU->proc[RX:%d.%d TX:%d.%d] RC.gNB[0][0]:[RX:%d%d TX(SFN):%d]\n",
|
||||
frame,slot,
|
||||
proc->frame_rx,proc->tti_rx,
|
||||
proc->frame_tx,proc->tti_tx,
|
||||
@@ -1534,17 +1530,17 @@ static void* ru_thread( void* param ) {
|
||||
// wakeup all gNB processes waiting for this RU
|
||||
if (ru->num_gNB>0) wakeup_gNB_L1s(ru);
|
||||
|
||||
if(get_thread_parallel_conf() == PARALLEL_SINGLE_THREAD && ru->num_eNB==0)
|
||||
if(get_thread_parallel_conf() == PARALLEL_SINGLE_THREAD && ru->num_gNB==0)
|
||||
{
|
||||
// do TX front-end processing if needed (precoding and/or IDFTs)
|
||||
if (ru->feptx_prec) ru->feptx_prec(ru);
|
||||
if (ru->feptx_prec) ru->feptx_prec(ru,proc->frame_tx,proc->tti_tx);
|
||||
|
||||
// do OFDM if needed
|
||||
if ((ru->fh_north_asynch_in == NULL) && (ru->feptx_ofdm)) ru->feptx_ofdm(ru);
|
||||
if ((ru->fh_north_asynch_in == NULL) && (ru->feptx_ofdm)) ru->feptx_ofdm(ru,proc->frame_tx,proc->tti_tx);
|
||||
if(!emulate_rf)
|
||||
{
|
||||
// do outgoing fronthaul (south) if needed
|
||||
if ((ru->fh_north_asynch_in == NULL) && (ru->fh_south_out)) ru->fh_south_out(ru);
|
||||
if ((ru->fh_north_asynch_in == NULL) && (ru->fh_south_out)) ru->fh_south_out(ru,proc->frame_tx,proc->tti_tx,proc->timestamp_tx);
|
||||
|
||||
if (ru->fh_north_out) ru->fh_north_out(ru);
|
||||
}
|
||||
@@ -1685,12 +1681,6 @@ int stop_rf(RU_t *ru)
|
||||
return 0;
|
||||
}
|
||||
|
||||
extern void fep_full(RU_t *ru);
|
||||
extern void ru_fep_full_2thread(RU_t *ru);
|
||||
extern void nr_feptx_ofdm(RU_t *ru);
|
||||
extern void nr_feptx_ofdm_2thread(RU_t *ru);
|
||||
extern void feptx_prec(RU_t *ru);
|
||||
extern void init_fep_thread(RU_t *ru,pthread_attr_t *attr);
|
||||
extern void init_nr_feptx_thread(RU_t *ru,pthread_attr_t *attr);
|
||||
|
||||
void init_RU_proc(RU_t *ru) {
|
||||
|
||||
@@ -389,7 +389,7 @@ void reset_stats(FL_OBJECT *button, long arg)
|
||||
phy_vars_gNB->UE_stats[i].dlsch_NAK[k][j]=0;
|
||||
phy_vars_gNB->UE_stats[i].dlsch_ACK[k][j]=0;
|
||||
phy_vars_gNB->UE_stats[i].dlsch_trials[k][j]=0;
|
||||
}*/
|
||||
}
|
||||
|
||||
phy_vars_gNB->UE_stats[i].dlsch_l2_errors[k]=0;
|
||||
phy_vars_gNB->UE_stats[i].ulsch_errors[k]=0;
|
||||
@@ -399,6 +399,7 @@ void reset_stats(FL_OBJECT *button, long arg)
|
||||
phy_vars_gNB->UE_stats[i].dlsch_sliding_cnt=0;
|
||||
phy_vars_gNB->UE_stats[i].dlsch_NAK_round0=0;
|
||||
phy_vars_gNB->UE_stats[i].dlsch_mcs_offset=0;
|
||||
*/
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user