@@ -496,6 +496,245 @@ void pucch_allocator_impl::slot_indication(slot_point sl_tx)
496496 pucch_common_alloc_grid[(sl_tx - 1 ).to_uint ()].clear ();
497497}
498498
499+ // //////////// Sub-class definitions //////////////
500+
501+ ofdm_symbol_range pucch_allocator_impl::pucch_grant::get_symbols () const
502+ {
503+ if (pucch_res_cfg == nullptr ) {
504+ return ofdm_symbol_range{NOF_OFDM_SYM_PER_SLOT_NORMAL_CP + 1 , NOF_OFDM_SYM_PER_SLOT_NORMAL_CP + 1 };
505+ }
506+
507+ switch (format) {
508+ case pucch_format::FORMAT_0: {
509+ const auto & f0 = std::get<pucch_format_0_cfg>(pucch_res_cfg->format_params );
510+ return ofdm_symbol_range{f0.starting_sym_idx , f0.starting_sym_idx + f0.nof_symbols };
511+ }
512+ case pucch_format::FORMAT_1: {
513+ const auto & f1 = std::get<pucch_format_1_cfg>(pucch_res_cfg->format_params );
514+ return ofdm_symbol_range{f1.starting_sym_idx , f1.starting_sym_idx + f1.nof_symbols };
515+ }
516+ case pucch_format::FORMAT_2: {
517+ const auto & f2 = std::get<pucch_format_2_3_cfg>(pucch_res_cfg->format_params );
518+ return ofdm_symbol_range{f2.starting_sym_idx , f2.starting_sym_idx + f2.nof_symbols };
519+ }
520+ default :
521+ return ofdm_symbol_range{NOF_OFDM_SYM_PER_SLOT_NORMAL_CP + 1 , NOF_OFDM_SYM_PER_SLOT_NORMAL_CP + 1 };
522+ }
523+ }
524+
525+ pucch_allocator_impl::uci_bits pucch_allocator_impl::pucch_grant_list::get_uci_bits () const
526+ {
527+ uci_bits bits;
528+ if (sr_resource.has_value ()) {
529+ bits.sr_bits = sr_resource->bits .sr_bits ;
530+ } else if (harq_resource.has_value ()) {
531+ bits.sr_bits = harq_resource->bits .sr_bits ;
532+ } else if (csi_resource.has_value ()) {
533+ bits.sr_bits = csi_resource->bits .sr_bits ;
534+ }
535+
536+ if (csi_resource.has_value ()) {
537+ bits.csi_part1_bits = csi_resource.value ().bits .csi_part1_bits ;
538+ } else if (harq_resource.has_value ()) {
539+ bits.csi_part1_bits = harq_resource.value ().bits .csi_part1_bits ;
540+ }
541+
542+ if (harq_resource.has_value ()) {
543+ bits.harq_ack_bits = harq_resource.value ().bits .harq_ack_bits ;
544+ } else if (sr_resource.has_value ()) {
545+ bits.harq_ack_bits = sr_resource.value ().bits .harq_ack_bits ;
546+ }
547+ if (csi_resource.has_value ()) {
548+ bits.harq_ack_bits = csi_resource.value ().bits .harq_ack_bits ;
549+ }
550+ return bits;
551+ }
552+
553+ // Contains the existing PUCCH grants currently allocated to a given UE.
554+ class existing_pucch_pdus_handler
555+ {
556+ public:
557+ existing_pucch_pdus_handler (rnti_t crnti, span<pucch_info> pucchs, const pucch_resource* pucch_res_cfg);
558+
559+ bool sr_id_match (const pucch_resource& pucch_res_cfg_lhs, const pucch_info& rhs) const ;
560+ bool is_empty () const { return pdus_cnt == 0 ; }
561+ pucch_info* get_next_grant ();
562+ void update_sr_pdu_bits (sr_nof_bits sr_bits, unsigned harq_ack_bits);
563+ void update_csi_pdu_bits (unsigned csi_part1_bits, sr_nof_bits sr_bits);
564+ void update_harq_pdu_bits (unsigned harq_ack_bits, sr_nof_bits sr_bits, unsigned csi_part1_bits);
565+
566+ pucch_info* sr_pdu{nullptr };
567+ pucch_info* harq_pdu{nullptr };
568+ pucch_info* csi_pdu{nullptr };
569+ unsigned pdus_cnt = 0 ;
570+ };
571+
572+ existing_pucch_pdus_handler::existing_pucch_pdus_handler (rnti_t crnti,
573+ span<pucch_info> pucchs,
574+ const pucch_resource* pucch_res_cfg)
575+ {
576+ for (auto & pucch : pucchs) {
577+ if (pucch.crnti == crnti) {
578+ if (pucch.format == srsran::pucch_format::FORMAT_0) {
579+ // With Format 0, when there are both HARQ bits and SR bits, we only use the HARQ-ACK resource; the only
580+ // case when the SR PUCCH F0 is used is when there are only SR bits.
581+ if (pucch.format_0 .sr_bits != sr_nof_bits::one and pucch.format_0 .harq_ack_nof_bits == 0U ) {
582+ sr_pdu = &pucch;
583+ ++pdus_cnt;
584+ } else if (pucch.format_0 .harq_ack_nof_bits != 0U and pucch.format_0 .harq_ack_nof_bits <= 2U ) {
585+ harq_pdu = &pucch;
586+ ++pdus_cnt;
587+ } else {
588+ srsran_assertion_failure (" Invalid HARQ/SR bits for PUCCH Format 0" );
589+ }
590+ }
591+
592+ else if (pucch.format == srsran::pucch_format::FORMAT_1) {
593+ if (pucch.format_1 .sr_bits == sr_nof_bits::one and pucch_res_cfg != nullptr and
594+ sr_id_match (*pucch_res_cfg, pucch)) {
595+ sr_pdu = &pucch;
596+ } else {
597+ harq_pdu = &pucch;
598+ }
599+ ++pdus_cnt;
600+ }
601+
602+ else if (pucch.format == srsran::pucch_format::FORMAT_2) {
603+ if (pucch.format_2 .csi_part1_bits != 0U and pucch.format_2 .harq_ack_nof_bits == 0U ) {
604+ csi_pdu = &pucch;
605+ } else {
606+ harq_pdu = &pucch;
607+ }
608+ ++pdus_cnt;
609+ }
610+ }
611+ }
612+ }
613+
614+ bool existing_pucch_pdus_handler::sr_id_match (const pucch_resource& pucch_res_cfg_lhs, const pucch_info& rhs) const
615+ {
616+ const auto & f1_cfg = std::get<pucch_format_1_cfg>(pucch_res_cfg_lhs.format_params );
617+ const bool prb_match = pucch_res_cfg_lhs.starting_prb == rhs.resources .prbs .start () and
618+ ((not pucch_res_cfg_lhs.second_hop_prb .has_value () and rhs.resources .prbs .empty ()) or
619+ (pucch_res_cfg_lhs.second_hop_prb .has_value () and pucch_res_cfg_lhs.second_hop_prb .value () and
620+ rhs.resources .second_hop_prbs .start ()));
621+ const bool symb_match =
622+ f1_cfg.starting_sym_idx == rhs.resources .symbols .start () and f1_cfg.nof_symbols == rhs.resources .symbols .length ();
623+ return prb_match && symb_match && f1_cfg.initial_cyclic_shift == rhs.format_1 .initial_cyclic_shift &&
624+ f1_cfg.time_domain_occ == rhs.format_1 .time_domain_occ ;
625+ }
626+
627+ pucch_info* existing_pucch_pdus_handler::get_next_grant ()
628+ {
629+ if (is_empty ()) {
630+ return nullptr ;
631+ }
632+ pucch_info* ret_grant = nullptr ;
633+ if (csi_pdu != nullptr ) {
634+ ret_grant = csi_pdu;
635+ --pdus_cnt;
636+ } else if (sr_pdu != nullptr ) {
637+ ret_grant = sr_pdu;
638+ --pdus_cnt;
639+ } else if (harq_pdu != nullptr ) {
640+ ret_grant = harq_pdu;
641+ --pdus_cnt;
642+ }
643+ return ret_grant;
644+ }
645+
646+ void existing_pucch_pdus_handler::update_sr_pdu_bits (sr_nof_bits sr_bits, unsigned harq_ack_bits)
647+ {
648+ if (sr_pdu == nullptr ) {
649+ return ;
650+ }
651+ if (sr_pdu->format == pucch_format::FORMAT_0) {
652+ sr_pdu->format_0 .sr_bits = sr_bits;
653+ sr_pdu->format_0 .harq_ack_nof_bits = harq_ack_bits;
654+ // Once the grant is updated, set the pointer to null, as we don't want to process this again.
655+ sr_pdu = nullptr ;
656+ --pdus_cnt;
657+ } else if (sr_pdu->format == pucch_format::FORMAT_1) {
658+ sr_pdu->format_1 .sr_bits = sr_bits;
659+ sr_pdu->format_1 .harq_ack_nof_bits = harq_ack_bits;
660+ // Once the grant is updated, set the pointer to null, as we don't want to process this again.
661+ sr_pdu = nullptr ;
662+ --pdus_cnt;
663+ } else {
664+ srsran_assertion_failure (" Only PUCCH Format 0 or 1 can be used for SR grant" );
665+ }
666+ }
667+
668+ void existing_pucch_pdus_handler::update_csi_pdu_bits (unsigned csi_part1_bits, sr_nof_bits sr_bits)
669+ {
670+ if (csi_pdu->format == pucch_format::FORMAT_2) {
671+ csi_pdu->format_2 .csi_part1_bits = csi_part1_bits;
672+ csi_pdu->format_2 .sr_bits = sr_bits;
673+ // Once the grant is updated, set the pointer to null, as we don't want to process this again.
674+ csi_pdu = nullptr ;
675+ --pdus_cnt;
676+ } else {
677+ srsran_assertion_failure (" Only PUCCH Format 2 currently supported for CSI grant" );
678+ }
679+ }
680+
681+ void existing_pucch_pdus_handler::update_harq_pdu_bits (unsigned harq_ack_bits,
682+ sr_nof_bits sr_bits,
683+ unsigned csi_part1_bits)
684+ {
685+ if (harq_pdu->format == pucch_format::FORMAT_0) {
686+ harq_pdu->format_0 .harq_ack_nof_bits = harq_ack_bits;
687+ harq_pdu->format_0 .sr_bits = sr_bits;
688+ // Once the grant is updated, set the pointer to null, as we don't want to process this again.
689+ harq_pdu = nullptr ;
690+ --pdus_cnt;
691+ } else if (harq_pdu->format == pucch_format::FORMAT_1) {
692+ harq_pdu->format_1 .harq_ack_nof_bits = harq_ack_bits;
693+ harq_pdu->format_1 .sr_bits = sr_bits;
694+ // Once the grant is updated, set the pointer to null, as we don't want to process this again.
695+ harq_pdu = nullptr ;
696+ --pdus_cnt;
697+ } else if (harq_pdu->format == pucch_format::FORMAT_2) {
698+ harq_pdu->format_2 .harq_ack_nof_bits = harq_ack_bits;
699+ harq_pdu->format_2 .sr_bits = sr_bits;
700+ harq_pdu->format_2 .csi_part1_bits = csi_part1_bits;
701+ // Once the grant is updated, set the pointer to null, as we don't want to process this again.
702+ harq_pdu = nullptr ;
703+ --pdus_cnt;
704+ } else {
705+ srsran_assertion_failure (" Only PUCCH Format 0, 1, and 2 currently supported" );
706+ }
707+ }
708+
709+ void pucch_allocator_impl::res_manager_garbage_collector::reset ()
710+ {
711+ harq_set_0 = false ;
712+ harq_set_1 = false ;
713+ csi = false ;
714+ sr = false ;
715+ }
716+
717+ void pucch_allocator_impl::res_manager_garbage_collector::release_resource (slot_point slot_tx,
718+ rnti_t crnti,
719+ const ue_cell_configuration& ue_cell_cfg)
720+ {
721+ if (harq_set_0) {
722+ res_manager.release_harq_f1_resource (
723+ slot_tx, crnti, ue_cell_cfg.cfg_dedicated ().ul_config .value ().init_ul_bwp .pucch_cfg .value ());
724+ }
725+ if (harq_set_1) {
726+ res_manager.release_harq_f2_resource (
727+ slot_tx, crnti, ue_cell_cfg.cfg_dedicated ().ul_config .value ().init_ul_bwp .pucch_cfg .value ());
728+ }
729+ if (sr) {
730+ res_manager.release_sr_resource (
731+ slot_tx, crnti, ue_cell_cfg.cfg_dedicated ().ul_config .value ().init_ul_bwp .pucch_cfg .value ());
732+ }
733+ if (csi) {
734+ res_manager.release_csi_resource (slot_tx, crnti, ue_cell_cfg);
735+ }
736+ }
737+
499738// //////////// Private functions //////////////
500739
501740// The function returns an available common PUCCH resource (i.e., not used by other UEs); it returns a null optional
@@ -1861,7 +2100,7 @@ std::optional<unsigned> pucch_allocator_impl::allocate_grants(cell_slot_resource
18612100
18622101 // Check if we can fit the new PUCCH PDUs in the output results.
18632102 // TODO: Check if this is correct, or we need to add +/-1.
1864- if (pucch_slot_alloc.result .ul .pucchs .size () + (grants_to_tx.nof_grants - existing_pdus.grants_cnt ) >=
2103+ if (pucch_slot_alloc.result .ul .pucchs .size () + (grants_to_tx.nof_grants - existing_pdus.pdus_cnt ) >=
18652104 get_max_pucch_grants (static_cast <unsigned >(pucch_slot_alloc.result .ul .puschs .size ()))) {
18662105 logger.info (
18672106 " rnti={}: PUCCH allocation for slot={} skipped. Cause: UL grants reached" , crnti, pucch_slot_alloc.slot );
0 commit comments