master
Xavier Arteaga 7 years ago
commit ab3a3108f1

@ -50,6 +50,8 @@
#define TTI_TX(tti) ((tti+HARQ_DELAY_MS)%10240) #define TTI_TX(tti) ((tti+HARQ_DELAY_MS)%10240)
#define TTI_RX_ACK(tti) ((tti+(2*HARQ_DELAY_MS))%10240) #define TTI_RX_ACK(tti) ((tti+(2*HARQ_DELAY_MS))%10240)
#define UL_PIDOF(tti) (tti%(2*HARQ_DELAY_MS))
#define TTIMOD_SZ (((2*HARQ_DELAY_MS) < 10)?10:20) #define TTIMOD_SZ (((2*HARQ_DELAY_MS) < 10)?10:20)
#define TTIMOD(tti) (tti%TTIMOD_SZ) #define TTIMOD(tti) (tti%TTIMOD_SZ)

@ -453,7 +453,7 @@ int srslte_ue_ul_pusch_encode_rnti_softbuffer(srslte_ue_ul_t *q,
if (srslte_pusch_encode(&q->pusch, &q->pusch_cfg, softbuffer, data, uci_data, rnti, q->sf_symbols)) { if (srslte_pusch_encode(&q->pusch, &q->pusch_cfg, softbuffer, data, uci_data, rnti, q->sf_symbols)) {
fprintf(stderr, "Error encoding TB\n"); fprintf(stderr, "Error encoding TB\n");
return ret; return SRSLTE_ERROR;
} }
if (q->signals_pregenerated) { if (q->signals_pregenerated) {

@ -95,7 +95,7 @@ private:
srslte_enb_dl_t enb_dl; srslte_enb_dl_t enb_dl;
srslte_enb_ul_t enb_ul; srslte_enb_ul_t enb_ul;
srslte_timestamp_t tx_time; srslte_timestamp_t tx_time;
// Class to store user information // Class to store user information
class ue { class ue {
@ -112,6 +112,11 @@ private:
void metrics_read(phy_metrics_t *metrics); void metrics_read(phy_metrics_t *metrics);
void metrics_dl(uint32_t mcs); void metrics_dl(uint32_t mcs);
void metrics_ul(uint32_t mcs, float rssi, float sinr, uint32_t turbo_iters); void metrics_ul(uint32_t mcs, float rssi, float sinr, uint32_t turbo_iters);
int last_dl_tbs[2*HARQ_DELAY_MS][SRSLTE_MAX_CODEWORDS];
int last_ul_tbs[2*HARQ_DELAY_MS];
srslte_mod_t last_ul_mod[2*HARQ_DELAY_MS];
private: private:
phy_metrics_t metrics; phy_metrics_t metrics;
}; };

@ -709,7 +709,7 @@ int sched::ul_sched(uint32_t tti, srsenb::sched_interface::ul_sched_res_t* sched
/* Indicate PHICH acknowledgment if needed */ /* Indicate PHICH acknowledgment if needed */
if (h->has_pending_ack()) { if (h->has_pending_ack()) {
sched_result->phich[nof_phich_elems].phich = h->get_ack()?ul_sched_phich_t::ACK:ul_sched_phich_t::NACK; sched_result->phich[nof_phich_elems].phich = h->get_ack()?ul_sched_phich_t::ACK:ul_sched_phich_t::NACK;
sched_result->phich[nof_phich_elems].rnti = rnti; sched_result->phich[nof_phich_elems].rnti = rnti;
nof_phich_elems++; nof_phich_elems++;
} }
@ -767,7 +767,7 @@ int sched::ul_sched(uint32_t tti, srsenb::sched_interface::ul_sched_res_t* sched
{ {
ul_harq_proc::ul_alloc_t alloc = h->get_alloc(); ul_harq_proc::ul_alloc_t alloc = h->get_alloc();
bool is_newtx = h->is_empty(); bool is_newtx = h->is_empty();
bool needs_pdcch = !h->is_adaptive_retx() && !is_rar; bool needs_pdcch = h->is_adaptive_retx() && !is_rar;
// Set number of retx // Set number of retx
if (is_newtx) { if (is_newtx) {

@ -198,13 +198,13 @@ ul_harq_proc::ul_alloc_t ul_harq_proc::get_alloc()
void ul_harq_proc::set_alloc(ul_harq_proc::ul_alloc_t alloc) void ul_harq_proc::set_alloc(ul_harq_proc::ul_alloc_t alloc)
{ {
is_adaptive = false; is_adaptive = true;
memcpy(&allocation, &alloc, sizeof(ul_alloc_t)); memcpy(&allocation, &alloc, sizeof(ul_alloc_t));
} }
void ul_harq_proc::same_alloc() void ul_harq_proc::same_alloc()
{ {
is_adaptive = true; is_adaptive = false;
} }
bool ul_harq_proc::is_adaptive_retx() bool ul_harq_proc::is_adaptive_retx()
@ -243,8 +243,7 @@ void ul_harq_proc::reset_pending_data()
} }
} }
uint32_t ul_harq_proc::get_pending_data()
uint32_t ul_harq_proc::get_pending_data()
{ {
return pending_data; return pending_data;
} }

@ -444,7 +444,8 @@ int sched_ue::generate_format0(ul_harq_proc *h,
int tbs = 0; int tbs = 0;
ul_harq_proc::ul_alloc_t allocation = h->get_alloc(); ul_harq_proc::ul_alloc_t allocation = h->get_alloc();
bool is_newtx = true;
if (h->get_rar_mcs(&mcs)) { if (h->get_rar_mcs(&mcs)) {
tbs = srslte_ra_tbs_from_idx(srslte_ra_tbs_idx_from_mcs(mcs), allocation.L)/8; tbs = srslte_ra_tbs_from_idx(srslte_ra_tbs_idx_from_mcs(mcs), allocation.L)/8;
h->new_tx(tti, mcs, tbs); h->new_tx(tti, mcs, tbs);
@ -463,7 +464,8 @@ int sched_ue::generate_format0(ul_harq_proc *h,
h->new_tx(tti, mcs, tbs); h->new_tx(tti, mcs, tbs);
} else { } else {
is_newtx = false;
h->new_retx(tti, &mcs, NULL); h->new_retx(tti, &mcs, NULL);
tbs = srslte_ra_tbs_from_idx(srslte_ra_tbs_idx_from_mcs(mcs), allocation.L)/8; tbs = srslte_ra_tbs_from_idx(srslte_ra_tbs_idx_from_mcs(mcs), allocation.L)/8;
} }
@ -474,9 +476,13 @@ int sched_ue::generate_format0(ul_harq_proc *h,
if (tbs > 0) { if (tbs > 0) {
dci->type2_alloc.L_crb = allocation.L; dci->type2_alloc.L_crb = allocation.L;
dci->type2_alloc.RB_start = allocation.RB_start; dci->type2_alloc.RB_start = allocation.RB_start;
dci->mcs_idx = mcs; dci->rv_idx = sched::get_rvidx(h->nof_retx());
dci->rv_idx = sched::get_rvidx(h->nof_retx()); if (!is_newtx && h->is_adaptive_retx()) {
dci->ndi = h->get_ndi(); dci->mcs_idx = 28+dci->rv_idx;
} else {
dci->mcs_idx = mcs;
}
dci->ndi = h->get_ndi();
dci->cqi_request = cqi_request; dci->cqi_request = cqi_request;
dci->freq_hop_fl = srslte_ra_ul_dci_t::SRSLTE_RA_PUSCH_HOP_DISABLED; dci->freq_hop_fl = srslte_ra_ul_dci_t::SRSLTE_RA_PUSCH_HOP_DISABLED;
dci->tpc_pusch = next_tpc_pusch; dci->tpc_pusch = next_tpc_pusch;

@ -412,6 +412,22 @@ int phch_worker::decode_pusch(srslte_enb_ul_pusch_t *grants, uint32_t nof_pusch)
srslte_ra_ul_grant_t phy_grant; srslte_ra_ul_grant_t phy_grant;
int res = -1; int res = -1;
if (!srslte_ra_ul_dci_to_grant(&grants[i].grant, enb_ul.cell.nof_prb, n_rb_ho, &phy_grant)) { if (!srslte_ra_ul_dci_to_grant(&grants[i].grant, enb_ul.cell.nof_prb, n_rb_ho, &phy_grant)) {
// Handle Format0 adaptive retx
// Use last TBS for this TB in case of mcs>28
if (phy_grant.mcs.idx > 28) {
phy_grant.mcs.tbs = ue_db[rnti].last_ul_tbs[TTI_RX(tti_rx)%(2*HARQ_DELAY_MS)];
Info("RETX: mcs=%d, old_tbs=%d pid=%d\n", phy_grant.mcs.idx, phy_grant.mcs.tbs, TTI_TX(tti_rx)%(2*HARQ_DELAY_MS));
}
ue_db[rnti].last_ul_tbs[TTI_RX(tti_rx)%(2*HARQ_DELAY_MS)] = phy_grant.mcs.tbs;
if (phy_grant.mcs.mod == SRSLTE_MOD_LAST) {
phy_grant.mcs.mod = ue_db[rnti].last_ul_mod[TTI_RX(tti_rx)%(2*HARQ_DELAY_MS)];
phy_grant.Qm = srslte_mod_bits_x_symbol(phy_grant.mcs.mod);
}
ue_db[rnti].last_ul_mod[TTI_RX(tti_rx)%(2*HARQ_DELAY_MS)] = phy_grant.mcs.mod;
if (phy_grant.mcs.mod == SRSLTE_MOD_64QAM) { if (phy_grant.mcs.mod == SRSLTE_MOD_64QAM) {
phy_grant.mcs.mod = SRSLTE_MOD_16QAM; phy_grant.mcs.mod = SRSLTE_MOD_16QAM;
} }

@ -44,39 +44,35 @@
namespace srsue { namespace srsue {
template <std::size_t N, typename Tgrant, typename Taction, typename Tphygrant> template <std::size_t N, typename Tgrant, typename Taction, typename Tphygrant>
class ul_harq_entity class ul_harq_entity {
{
public: public:
static uint32_t pidof(uint32_t tti) static uint32_t pidof(uint32_t tti) {
{ return (uint32_t) tti % N;
return (uint32_t) tti%N;
} }
ul_harq_entity() : proc(N) ul_harq_entity() : proc(N) {
{
contention_timer = NULL; contention_timer = NULL;
pcap = NULL; pcap = NULL;
mux_unit = NULL; mux_unit = NULL;
log_h = NULL; log_h = NULL;
params = NULL; params = NULL;
rntis = NULL; rntis = NULL;
average_retx = 0; average_retx = 0;
nof_pkts = 0; nof_pkts = 0;
} }
bool init(srslte::log *log_h_, bool init(srslte::log *log_h_,
mac_interface_rrc_common::ue_rnti_t *rntis_, mac_interface_rrc_common::ue_rnti_t *rntis_,
mac_interface_rrc_common::ul_harq_params_t *params_, mac_interface_rrc_common::ul_harq_params_t *params_,
srslte::timers::timer* contention_timer_, srslte::timers::timer *contention_timer_,
mux *mux_unit_) mux *mux_unit_) {
{ log_h = log_h_;
log_h = log_h_; mux_unit = mux_unit_;
mux_unit = mux_unit_; params = params_;
params = params_; rntis = rntis_;
rntis = rntis_;
contention_timer = contention_timer_; contention_timer = contention_timer_;
for (uint32_t i=0;i<N;i++) { for (uint32_t i = 0; i < N; i++) {
if (!proc[i].init(i, this)) { if (!proc[i].init(i, this)) {
return false; return false;
} }
@ -84,29 +80,29 @@ public:
return true; return true;
} }
void reset() void reset() {
{ for (uint32_t i = 0; i < N; i++) {
for (uint32_t i=0;i<N;i++) {
proc[i].reset(); proc[i].reset();
} }
ul_sps_assig.clear(); ul_sps_assig.clear();
} }
void reset_ndi() void reset_ndi() {
{ for (uint32_t i = 0; i < N; i++) {
for (uint32_t i=0;i<N;i++) {
proc[i].reset_ndi(); proc[i].reset_ndi();
} }
} }
void start_pcap(srslte::mac_pcap* pcap_) void start_pcap(srslte::mac_pcap *pcap_) {
{
pcap = pcap_; pcap = pcap_;
} }
/***************** PHY->MAC interface for UL processes **************************/ /***************** PHY->MAC interface for UL processes **************************/
void new_grant_ul(Tgrant grant, Taction *action) void new_grant_ul(Tgrant grant, Taction *action) {
new_grant_ul_ack(grant, NULL, action);
}
void new_grant_ul_ack(Tgrant grant, bool *ack, Taction *action)
{ {
if (grant.rnti_type == SRSLTE_RNTI_USER || if (grant.rnti_type == SRSLTE_RNTI_USER ||
grant.rnti_type == SRSLTE_RNTI_TEMP || grant.rnti_type == SRSLTE_RNTI_TEMP ||
@ -115,27 +111,20 @@ public:
if (grant.rnti_type == SRSLTE_RNTI_USER && proc[pidof(grant.tti)].is_sps()) { if (grant.rnti_type == SRSLTE_RNTI_USER && proc[pidof(grant.tti)].is_sps()) {
grant.ndi[0] = true; grant.ndi[0] = true;
} }
run_tti(grant.tti, &grant, action); run_tti(grant.tti, &grant, ack, action);
} else if (grant.rnti_type == SRSLTE_RNTI_SPS) { } else if (grant.rnti_type == SRSLTE_RNTI_SPS) {
if (grant.ndi[0]) { if (grant.ndi[0]) {
grant.ndi[0] = proc[pidof(grant.tti)].get_ndi(); grant.ndi[0] = proc[pidof(grant.tti)].get_ndi();
run_tti(grant.tti, &grant, action); run_tti(grant.tti, &grant, ack, action);
} else { } else {
Info("Not implemented\n"); Info("Not implemented\n");
} }
} }
} }
void new_grant_ul_ack(Tgrant grant, bool ack, Taction *action)
{
set_ack(grant.tti, ack, action);
new_grant_ul(grant, action);
}
void harq_recv(uint32_t tti, bool ack, Taction *action) void harq_recv(uint32_t tti, bool ack, Taction *action)
{ {
set_ack(tti, ack, action); run_tti(tti, NULL, &ack, action);
run_tti(tti, NULL, action);
} }
int get_current_tbs(uint32_t tti) int get_current_tbs(uint32_t tti)
@ -206,10 +195,19 @@ private:
bzero(&cur_grant, sizeof(Tgrant)); bzero(&cur_grant, sizeof(Tgrant));
} }
void reset_ndi() { ndi = false; } void reset_ndi() { cur_grant.ndi[0] = false; }
void run_tti(uint32_t tti_tx, Tgrant *grant, Taction* action) void run_tti(uint32_t tti_tx, Tgrant *grant, bool *ack, Taction* action)
{ {
if (ack) {
if (grant) {
if (grant->ndi[0] == get_ndi()) {
*ack = false;
}
}
set_harq_feedback(*ack);
}
uint32_t max_retx; uint32_t max_retx;
if (is_msg3) { if (is_msg3) {
max_retx = harq_entity->params->max_harq_msg3_tx; max_retx = harq_entity->params->max_harq_msg3_tx;
@ -219,9 +217,9 @@ private:
// Receive and route HARQ feedbacks // Receive and route HARQ feedbacks
if (grant) { if (grant) {
if ((!(grant->rnti_type == SRSLTE_RNTI_TEMP) && grant->ndi[0] != get_ndi() && grant->phy_grant.ul.mcs.idx < 29) || if ((!(grant->rnti_type == SRSLTE_RNTI_TEMP) && grant->ndi[0] != get_ndi() && ack) ||
(grant->rnti_type == SRSLTE_RNTI_USER && !has_grant()) || (grant->rnti_type == SRSLTE_RNTI_USER && !has_grant()) ||
grant->is_from_rar) grant->is_from_rar)
{ {
// New transmission // New transmission
@ -255,7 +253,7 @@ private:
generate_retx(tti_tx, grant, action); generate_retx(tti_tx, grant, action);
} }
} else { } else {
Warning("UL %d: Received mcs=%d but no previous grant available for this PID.\n", pid, grant->phy_grant.ul.mcs.idx); Warning("UL %d: Received retransmission but no previous grant available for this PID.\n", pid);
} }
} else if (has_grant()) { } else if (has_grant()) {
// Non-Adaptive Re-Tx // Non-Adaptive Re-Tx
@ -294,9 +292,8 @@ private:
} }
bool has_grant() { return is_grant_configured; } bool has_grant() { return is_grant_configured; }
bool get_ndi() { return ndi; } bool get_ndi() { return cur_grant.ndi[0]; }
bool is_sps() { return false; } bool is_sps() { return false; }
uint32_t last_tx_tti() { return tti_last_tx; }
uint32_t get_nof_retx() { return current_tx_nb; } uint32_t get_nof_retx() { return current_tx_nb; }
int get_current_tbs() { return cur_grant.n_bytes[0]*8; } int get_current_tbs() { return cur_grant.n_bytes[0]*8; }
@ -307,7 +304,6 @@ private:
uint32_t current_tx_nb; uint32_t current_tx_nb;
uint32_t current_irv; uint32_t current_irv;
bool harq_feedback; bool harq_feedback;
bool ndi;
srslte::log *log_h; srslte::log *log_h;
ul_harq_entity *harq_entity; ul_harq_entity *harq_entity;
bool is_grant_configured; bool is_grant_configured;
@ -398,24 +394,12 @@ private:
// Implements Section 5.4.2.1 // Implements Section 5.4.2.1
// Called with UL grant // Called with UL grant
void run_tti(uint32_t tti, Tgrant *grant, Taction* action) void run_tti(uint32_t tti, Tgrant *grant, bool *ack, Taction* action)
{ {
uint32_t tti_tx = (tti+action->tti_offset)%10240; uint32_t tti_tx = (tti+action->tti_offset)%10240;
proc[pidof(tti_tx)].run_tti(tti_tx, grant, action); proc[pidof(tti_tx)].run_tti(tti_tx, grant, ack, action);
} }
void set_ack(uint32_t tti, bool ack, Taction *action)
{
int tti_harq = (int) tti - action->tti_offset;
if (tti_harq < 0) {
tti_harq += 10240;
}
uint32_t pid_harq = pidof(tti_harq);
if (proc[pid_harq].has_grant() && (proc[pid_harq].last_tx_tti() <= (uint32_t)tti_harq)) {
proc[pid_harq].set_harq_feedback(ack);
}
}
ul_sps ul_sps_assig; ul_sps ul_sps_assig;
srslte::timers::timer *contention_timer; srslte::timers::timer *contention_timer;

@ -64,8 +64,16 @@ namespace srsue {
float rx_gain_offset; float rx_gain_offset;
float avg_snr_db; float avg_snr_db;
float avg_noise; float avg_noise;
float avg_rsrp; float avg_rsrp;
// Save last TBS for mcs>28 cases
int last_dl_tbs[2*HARQ_DELAY_MS][SRSLTE_MAX_CODEWORDS];
uint32_t last_dl_tti[2*HARQ_DELAY_MS];
int last_ul_tbs[2*HARQ_DELAY_MS];
uint32_t last_ul_tti[2*HARQ_DELAY_MS];
srslte_mod_t last_ul_mod[2*HARQ_DELAY_MS];
phch_common(uint32_t max_mutex = 3); phch_common(uint32_t max_mutex = 3);
void init(phy_interface_rrc::phy_cfg_t *config, void init(phy_interface_rrc::phy_cfg_t *config,
phy_args_t *args, phy_args_t *args,
@ -139,7 +147,7 @@ namespace srsue {
uint32_t n_dmrs; uint32_t n_dmrs;
} pending_ack_t; } pending_ack_t;
pending_ack_t pending_ack[TTIMOD_SZ]; pending_ack_t pending_ack[TTIMOD_SZ];
bool is_first_tx; bool is_first_tx;
uint32_t nof_workers; uint32_t nof_workers;

@ -150,11 +150,6 @@ private:
float cfo; float cfo;
bool rar_cqi_request; bool rar_cqi_request;
// Save last TBS for mcs>28 cases
int last_dl_tbs[2*HARQ_DELAY_MS][SRSLTE_MAX_CODEWORDS];
int last_ul_tbs[2*HARQ_DELAY_MS];
srslte_mod_t last_ul_mod[2*HARQ_DELAY_MS];
// Metrics // Metrics
dl_metrics_t dl_metrics; dl_metrics_t dl_metrics;
ul_metrics_t ul_metrics; ul_metrics_t ul_metrics;

@ -308,7 +308,7 @@ void mac::new_grant_ul(mac_interface_phy::mac_grant_t grant, mac_interface_phy::
void mac::new_grant_ul_ack(mac_interface_phy::mac_grant_t grant, bool ack, mac_interface_phy::tb_action_ul_t* action) void mac::new_grant_ul_ack(mac_interface_phy::mac_grant_t grant, bool ack, mac_interface_phy::tb_action_ul_t* action)
{ {
int tbs = ul_harq.get_current_tbs(tti); int tbs = ul_harq.get_current_tbs(tti);
ul_harq.new_grant_ul_ack(grant, ack, action); ul_harq.new_grant_ul_ack(grant, &ack, action);
if (!ack) { if (!ack) {
metrics.tx_errors++; metrics.tx_errors++;
} else { } else {

@ -236,8 +236,7 @@ uint8_t* mux::pdu_get(uint8_t *payload, uint32_t pdu_sz, uint32_t tx_tti, uint32
// Now allocate the SDUs from the RLC // Now allocate the SDUs from the RLC
for (uint32_t i=0;i<lch.size();i++) { for (uint32_t i=0;i<lch.size();i++) {
if (lch[i].sched_len != 0) { if (lch[i].sched_len != 0) {
log_h->info("Allocating scheduled lch=%d len=%d\n", lch[i].id, lch[i].sched_len); allocate_sdu(lch[i].id, &pdu_msg, lch[i].sched_len);
allocate_sdu(lch[i].id, &pdu_msg, lch[i].sched_len);
} }
} }
@ -285,7 +284,7 @@ bool mux::sched_sdu(lchid_t *ch, int *sdu_space, int max_sdu_sz)
sched_len = *sdu_space; sched_len = *sdu_space;
} }
log_h->info("SDU: scheduled lcid=%d, rlc_buffer=%d, allocated=%d/%d\n", log_h->debug("SDU: scheduled lcid=%d, rlc_buffer=%d, allocated=%d/%d\n",
ch->id, ch->buffer_len, sched_len, sdu_space?*sdu_space:0); ch->id, ch->buffer_len, sched_len, sdu_space?*sdu_space:0);
*sdu_space -= sched_len; *sdu_space -= sched_len;
@ -317,7 +316,7 @@ bool mux::allocate_sdu(uint32_t lcid, srslte::sch_pdu* pdu_msg, int max_sdu_sz)
sdu_len = pdu_msg->get()->set_sdu(lcid, sdu_len, rlc); sdu_len = pdu_msg->get()->set_sdu(lcid, sdu_len, rlc);
if (sdu_len > 0) { // new SDU could be added if (sdu_len > 0) { // new SDU could be added
Info("SDU: allocated lcid=%d, rlc_buffer=%d, allocated=%d/%d, max_sdu_sz=%d, remaining=%d\n", Debug("SDU: allocated lcid=%d, rlc_buffer=%d, allocated=%d/%d, max_sdu_sz=%d, remaining=%d\n",
lcid, buffer_state, sdu_len, sdu_space, max_sdu_sz, pdu_msg->rem_size()); lcid, buffer_state, sdu_len, sdu_space, max_sdu_sz, pdu_msg->rem_size());
return true; return true;
} else { } else {

@ -322,9 +322,9 @@ void phch_worker::work_imp()
ul_action.tti_offset = HARQ_DELAY_MS; ul_action.tti_offset = HARQ_DELAY_MS;
/* Send UL grant or HARQ information (from PHICH) to MAC */ /* Send UL grant or HARQ information (from PHICH) to MAC */
if (ul_grant_available && ul_ack_available && ul_mac_grant.phy_grant.ul.mcs.idx < 29) { if (ul_grant_available && ul_ack_available) {
phy->mac->new_grant_ul_ack(ul_mac_grant, ul_ack, &ul_action); phy->mac->new_grant_ul_ack(ul_mac_grant, ul_ack, &ul_action);
} else if (ul_grant_available && (!ul_ack_available || ul_mac_grant.phy_grant.ul.mcs.idx < 29)) { } else if (ul_grant_available && !ul_ack_available) {
phy->mac->new_grant_ul(ul_mac_grant, &ul_action); phy->mac->new_grant_ul(ul_mac_grant, &ul_action);
} else if (!ul_grant_available && ul_ack_available) { } else if (!ul_grant_available && ul_ack_available) {
phy->mac->harq_recv(tti, ul_ack, &ul_action); phy->mac->harq_recv(tti, ul_ack, &ul_action);
@ -477,19 +477,19 @@ bool phch_worker::decode_pdcch_dl(srsue::mac_interface_phy::mac_grant_t* grant)
return false; return false;
} }
grant->pid = ASYNC_DL_SCHED?dci_unpacked.harq_process:(tti%(2*HARQ_DELAY_MS)); grant->pid = ASYNC_DL_SCHED?dci_unpacked.harq_process:(UL_PIDOF(TTI_TX(tti)));
// Set last TBS for this TB (pid) in case of mcs>28 (7.1.7.2 of 36.213) // Set last TBS for this TB (pid) in case of mcs>28 (7.1.7.2 of 36.213)
for (int i=0;i<SRSLTE_MAX_CODEWORDS;i++) { for (int i=0;i<SRSLTE_MAX_CODEWORDS;i++) {
if (grant->phy_grant.dl.mcs[i].idx > 28) { if (grant->phy_grant.dl.mcs[i].idx > 28) {
grant->phy_grant.dl.mcs[i].tbs = last_dl_tbs[grant->pid%(2*HARQ_DELAY_MS)][i]; grant->phy_grant.dl.mcs[i].tbs = phy->last_dl_tbs[grant->pid][i];
} }
if(grant->phy_grant.dl.mcs[i].tbs < 0) { if(grant->phy_grant.dl.mcs[i].tbs < 0) {
Info("Invalid TBS size for PDSCH grant\n"); Info("Invalid TBS size for PDSCH grant\n");
grant->phy_grant.dl.mcs[i].tbs = 0; grant->phy_grant.dl.mcs[i].tbs = 0;
} }
// save it // save it
last_dl_tbs[grant->pid%(2*HARQ_DELAY_MS)][i] = grant->phy_grant.dl.mcs[i].tbs; phy->last_dl_tbs[grant->pid][i] = grant->phy_grant.dl.mcs[i].tbs;
} }
/* Fill MAC grant structure */ /* Fill MAC grant structure */
@ -743,30 +743,30 @@ bool phch_worker::decode_pdcch_ul(mac_interface_phy::mac_grant_t* grant)
} }
} }
if (ret) {
// Handle Format0 adaptive retx
if (ret) {
// Use last TBS for this TB in case of mcs>28 // Use last TBS for this TB in case of mcs>28
if (grant->phy_grant.ul.mcs.idx > 28) { if (grant->phy_grant.ul.mcs.idx > 28) {
grant->phy_grant.ul.mcs.tbs = last_ul_tbs[TTI_RX(tti)%(2*HARQ_DELAY_MS)]; // Make sure we received a grant in the previous TTI for this PID
Info("RETX: mcs=%d, old_tbs=%d pid=%d\n", grant->phy_grant.ul.mcs.idx, grant->phy_grant.ul.mcs.tbs, TTI_TX(tti)%(2*HARQ_DELAY_MS)); grant->phy_grant.ul.mcs.tbs = phy->last_ul_tbs[UL_PIDOF(TTI_TX(tti))];
} grant->phy_grant.ul.mcs.mod = phy->last_ul_mod[UL_PIDOF(TTI_TX(tti))];
last_ul_tbs[TTI_RX(tti)%(2*HARQ_DELAY_MS)] = grant->phy_grant.ul.mcs.tbs;
if (grant->phy_grant.ul.mcs.mod == SRSLTE_MOD_LAST) {
grant->phy_grant.ul.mcs.mod = last_ul_mod[TTI_RX(tti)%(2*HARQ_DELAY_MS)];
grant->phy_grant.ul.Qm = srslte_mod_bits_x_symbol(grant->phy_grant.ul.mcs.mod); grant->phy_grant.ul.Qm = srslte_mod_bits_x_symbol(grant->phy_grant.ul.mcs.mod);
} }
last_ul_mod[TTI_RX(tti)%(2*HARQ_DELAY_MS)] = grant->phy_grant.ul.mcs.mod;
} }
if (ret) {
/* Limit UL modulation if not supported by the UE or disabled by higher layers */ phy->last_ul_tbs[UL_PIDOF(TTI_TX(tti))] = grant->phy_grant.ul.mcs.tbs;
if (!phy->config->enable_64qam) { phy->last_ul_mod[UL_PIDOF(TTI_TX(tti))] = grant->phy_grant.ul.mcs.mod;
if (grant->phy_grant.ul.mcs.mod >= SRSLTE_MOD_64QAM) { phy->last_ul_tti[UL_PIDOF(TTI_TX(tti))] = TTI_RX_ACK(tti);
grant->phy_grant.ul.mcs.mod = SRSLTE_MOD_16QAM; /* Limit UL modulation if not supported by the UE or disabled by higher layers */
grant->phy_grant.ul.Qm = 4; if (!phy->config->enable_64qam) {
if (grant->phy_grant.ul.mcs.mod >= SRSLTE_MOD_64QAM) {
grant->phy_grant.ul.mcs.mod = SRSLTE_MOD_16QAM;
grant->phy_grant.ul.Qm = 4;
}
} }
} }
/* Make sure the grant is valid */ /* Make sure the grant is valid */
if (ret && !srslte_dft_precoding_valid_prb(grant->phy_grant.ul.L_prb) && grant->phy_grant.ul.L_prb <= cell.nof_prb) { if (ret && !srslte_dft_precoding_valid_prb(grant->phy_grant.ul.L_prb) && grant->phy_grant.ul.L_prb <= cell.nof_prb) {
Warning("Received invalid UL grant. L=%d\n", grant->phy_grant.ul.L_prb); Warning("Received invalid UL grant. L=%d\n", grant->phy_grant.ul.L_prb);
@ -783,11 +783,9 @@ bool phch_worker::decode_pdcch_ul(mac_interface_phy::mac_grant_t* grant)
if (SRSLTE_VERBOSE_ISINFO()) { if (SRSLTE_VERBOSE_ISINFO()) {
srslte_ra_pusch_fprint(stdout, &dci_unpacked, cell.nof_prb); srslte_ra_pusch_fprint(stdout, &dci_unpacked, cell.nof_prb);
} }
}
return true;
} else { return ret;
return false;
}
} }
void phch_worker::reset_uci() void phch_worker::reset_uci()

Loading…
Cancel
Save