Skip to content

Commit

Permalink
phy: initial PRS generator
Browse files Browse the repository at this point in the history
phy: review PRS generator related
  • Loading branch information
Xavier Arteaga committed Jan 16, 2025
1 parent d34638f commit e42c3eb
Show file tree
Hide file tree
Showing 22 changed files with 964 additions and 6 deletions.
43 changes: 43 additions & 0 deletions include/srsran/phy/upper/signal_processors/prs/factories.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
/*
*
* Copyright 2021-2025 Software Radio Systems Limited
*
* By using this file, you agree to the terms and conditions set
* forth in the LICENSE file which can be found at the top level of
* the distribution.
*
*/

#pragma once

#include "srsran/phy/generic_functions/precoding/precoding_factories.h"
#include "srsran/phy/upper/sequence_generators/sequence_generator_factories.h"
#include "srsran/phy/upper/signal_processors/prs/prs_generator.h"
#include "srsran/phy/upper/signal_processors/prs/prs_generator_validator.h"
#include <memory>

namespace srsran {

/// PRS generator factory.
class prs_generator_factory
{
public:
/// Default destructor.
virtual ~prs_generator_factory() = default;

/// Creates a PRS generator.
virtual std::unique_ptr<prs_generator> create() = 0;

/// Creates a PRS generator configuration validator.
virtual std::unique_ptr<prs_generator_validator> create_validator() = 0;
};

/// \brief Creates a generic PRS generator factory.
/// \param[in] prg_factory Pseudo-random sequence generator factory.
/// \param[in] precoder_factory Channel precoder factory.
/// \return A valid PRS generator factory if successful.
std::shared_ptr<prs_generator_factory>
create_prs_generator_generic_factory(std::shared_ptr<pseudo_random_generator_factory> prg_factory,
std::shared_ptr<channel_precoder_factory> precoder_factory);

} // namespace srsran
55 changes: 55 additions & 0 deletions include/srsran/phy/upper/signal_processors/prs/formatters.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
/*
*
* Copyright 2021-2025 Software Radio Systems Limited
*
* By using this file, you agree to the terms and conditions set
* forth in the LICENSE file which can be found at the top level of
* the distribution.
*
*/

#pragma once

#include "srsran/phy/support/precoding_formatters.h"
#include "srsran/phy/upper/signal_processors/prs/prs_generator_configuration.h"
#include "srsran/ran/precoding/precoding_weight_matrix_formatters.h"

namespace fmt {

/// \brief Custom formatter for \c pdcch_processor::coreset_description.
template <>
struct formatter<srsran::prs_generator_configuration> {
/// Helper used to parse formatting options and format fields.
srsran::delimited_formatter helper;

/// Default constructor.
formatter() = default;

template <typename ParseContext>
auto parse(ParseContext& ctx)
{
return helper.parse(ctx);
}

template <typename FormatContext>
auto format(const srsran::prs_generator_configuration& config, FormatContext& ctx) const
{
helper.format_if_verbose(ctx, "slot={}", config.slot);
helper.format_if_verbose(ctx, "cp={}", config.cp);
helper.format_always(ctx, "n_id={}", config.n_id_prs);
helper.format_always(ctx, "comb_size={}", fmt::underlying(config.comb_size));
helper.format_always(ctx, "comb_offset={}", config.comb_offset);
helper.format_always(
ctx,
"t_alloc={}",
srsran::interval<unsigned>(config.start_symbol, config.start_symbol + static_cast<unsigned>(config.duration)));
helper.format_if_verbose(ctx, "rb_start={}", config.prb_start);
helper.format_always(ctx, "f_alloc={}", config.freq_alloc);
helper.format_if_verbose(ctx, "power_offset={}", config.power_offset_dB);
helper.format_if_verbose(ctx, "precoding={}", config.precoding);

return ctx.out();
}
};

} // namespace fmt
31 changes: 31 additions & 0 deletions include/srsran/phy/upper/signal_processors/prs/prs_generator.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
/*
*
* Copyright 2021-2025 Software Radio Systems Limited
*
* By using this file, you agree to the terms and conditions set
* forth in the LICENSE file which can be found at the top level of
* the distribution.
*
*/

#pragma once

namespace srsran {

class resource_grid_writer;
struct prs_generator_configuration;

/// Positioning Reference Signals (PRS) generator interface.
class prs_generator
{
public:
/// Default destructor.
virtual ~prs_generator() = default;

/// \brief Generates Positioning Reference Signals (PRS) according to TS38.211 Section 7.4.1.7.
/// \param[out] grid Resource grid.
/// \param[in] config PRS transmission configuration.
virtual void generate(resource_grid_writer& grid, const prs_generator_configuration& config) = 0;
};

} // namespace srsran
Original file line number Diff line number Diff line change
@@ -0,0 +1,77 @@
/*
*
* Copyright 2021-2025 Software Radio Systems Limited
*
* By using this file, you agree to the terms and conditions set
* forth in the LICENSE file which can be found at the top level of
* the distribution.
*
*/

#pragma once

#include "srsran/phy/support/precoding_configuration.h"
#include "srsran/ran/cyclic_prefix.h"
#include "srsran/ran/prs/prs.h"
#include "srsran/ran/slot_point.h"

namespace srsran {

/// \brief Positioning Reference Signals (PRS) transmission parameters.
///
/// \remark Not all combinations of comb size and time domain duration are valid, see \ref
/// prs_valid_num_symbols_and_comb_size for more information.
struct prs_generator_configuration {
/// Slot and subcarrier spacing.
slot_point slot;
/// Cyclic prefix.
cyclic_prefix cp;
/// \brief Sequence identifier.
///
/// Parameter \f$n_{ID,seq}^{PRS}\f$ in TS38.211 Section 7.4.1.7.2. The range is {0, ..., 4095}. It is given by the
/// higher layer parameter \e dl-PRS-SequenceID.
///
uint16_t n_id_prs;
/// \brief Transmission comb size.
///
/// Parameter \f$K_{comb}^{PRS}\f$ in TS38.211 Section 7.4.1.7.3. It is given by the higher layer parameter \e
/// dl-PRS-CombSizeN.
prs_comb_size comb_size;
/// \brief Transmission comb offset.
///
/// Parameter \f$k_{offset}^{PRS}\f$ in TS38.211 Section 7.4.1.7.3. It is given by the higher layer parameter \e
/// dl-PRS-CombSizeN-AndReOffset
uint8_t comb_offset;
/// \brief Transmission time domain duration.
///
/// Parameter \f$L_{PRS}\f$ in TS38.211 Section 7.4.1.7.3. It is given by the higher layer parameter \e
/// dl-PRS-NumSymbols.
prs_num_symbols duration;
/// \brief First symbol index of the transmission.
///
/// Parameter \f$l_{start}^{PRS}\f$ in TS38.211 Section 7.4.1.7.3. It is given by the higher layer parameter \e
/// dl-PRS-ResourceSymbolOffset.
uint8_t start_symbol;
/// \brief Physical resource block allocation start PRB.
///
/// It is given by the higher layer parameter \e dl-PRS-StartPRB. The range is {0, ..., 2176}.
///
/// It expresses the number of PRB between the PointA given by the higher layer parameter \e dl-PRS-PointA and the
/// lowest PRB of the PRS transmission.
uint16_t prb_start;
/// \brief Physical resource block allocation expressed as a start and number of physical resource blocks.
///
/// The start position is relative to the lowest resource grid physical resource block. Set the start position equal
/// to \c prb_start, if the higher layer parameter \e dl-PRS-PointA matches with the lowest subcarrier of the resource
/// grid.
///
/// The number of PRB is derived from the higher layer parameter \e dl-PRS-ResourceBandwidth. The range is
/// {24, ..., 276} in steps of 4.
interval<uint16_t> freq_alloc;
/// Ratio of PRS data EPRE to SSS EPRE in decibels.
float power_offset_dB;
/// Precoding configuration.
precoding_configuration precoding;
};

} // namespace srsran
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
/*
*
* Copyright 2021-2025 Software Radio Systems Limited
*
* By using this file, you agree to the terms and conditions set
* forth in the LICENSE file which can be found at the top level of
* the distribution.
*
*/

#pragma once

#include "srsran/adt/expected.h"
#include <string>

namespace srsran {

struct prs_generator_configuration;

/// \brief PRS generator validator.
class prs_generator_validator
{
public:
/// Default destructor.
virtual ~prs_generator_validator() = default;

/// \brief Validates PRS generator configuration parameters.
/// \return A success if the parameters contained in \c config are supported, an error message otherwise.
virtual error_type<std::string> is_valid(const prs_generator_configuration& config) const = 0;
};

} // namespace srsran
34 changes: 34 additions & 0 deletions include/srsran/ran/prs/prs.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
/*
*
* Copyright 2021-2025 Software Radio Systems Limited
*
* By using this file, you agree to the terms and conditions set
* forth in the LICENSE file which can be found at the top level of
* the distribution.
*
*/

/// \file
/// \brief Positioning Reference Signals (PRS) parameters.

#pragma once

namespace srsran {

//// PRS transmission time domain duration.
enum class prs_num_symbols : uint8_t { two = 2, four = 4, six = 6, twelve = 12 };

/// PRS transmission comb size.
enum class prs_comb_size : uint8_t { two = 2, four = 4, six = 6, twelve = 12 };

/// \brief Determines whether the combination of time domain duration and comb size is valid.
///
/// The valid combinations are given in TS38.211 Section 7.4.1.7.3.
inline bool prs_valid_num_symbols_and_comb_size(prs_num_symbols nsymb, prs_comb_size comb_sz)
{
uint8_t nsymb_u8 = static_cast<uint8_t>(nsymb);
uint8_t comb_sz_u8 = static_cast<uint8_t>(comb_sz);
return (nsymb_u8 >= comb_sz_u8) && (nsymb_u8 % comb_sz_u8 == 0);
}

} // namespace srsran
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@

using namespace srsran;

/// \brief Looks at the output of the validator and, if unsuccessful, fills msg with the error message.
/// \brief Looks at the output of the validator and, if unsuccessful, fills \c msg with the error message.
///
/// This is used to call the validator inside the process methods only if asserts are active.
[[maybe_unused]] static bool handle_validation(std::string& msg, const error_type<std::string>& err)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@

using namespace srsran;

/// \brief Looks at the output of the validator and, if unsuccessful, fills msg with the error message.
/// \brief Looks at the output of the validator and, if unsuccessful, fills \c msg with the error message.
///
/// This is used to call the validator inside the process methods only if asserts are active.
[[maybe_unused]] static bool handle_validation(std::string& msg, const error_type<std::string>& err)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@

using namespace srsran;

/// \brief Looks at the output of the validator and, if unsuccessful, fills msg with the error message.
/// \brief Looks at the output of the validator and, if unsuccessful, fills \c msg with the error message.
///
/// This is used to call the validator inside the process methods only if asserts are active.
[[maybe_unused]] static bool handle_validation(std::string& msg, const error_type<std::string>& err)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@

using namespace srsran;

/// \brief Looks at the output of the validator and, if unsuccessful, fills msg with the error message.
/// \brief Looks at the output of the validator and, if unsuccessful, fills \c msg with the error message.
///
/// This is used to call the validator inside the process methods only if asserts are active.
[[maybe_unused]] static bool handle_validation(std::string& msg, const error_type<std::string>& err)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -123,7 +123,7 @@ void pusch_demodulator_impl::demodulate(pusch_codeword_buffer& codeword_buf
// Number of receive antenna ports.
unsigned nof_rx_ports = static_cast<unsigned>(config.rx_ports.size());

// Initialise sequence.
// Initialize sequence.
unsigned c_init = config.rnti * pow2(15) + config.n_id;
descrambler->init(c_init);

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@

using namespace srsran;

/// \brief Looks at the output of the validator and, if unsuccessful, fills msg with the error message.
/// \brief Looks at the output of the validator and, if unsuccessful, fills \c msg with the error message.
///
/// This is used to call the validator inside the process methods only if asserts are active.
[[maybe_unused]] static bool handle_validation(std::string& msg, const error_type<std::string>& err)
Expand Down
2 changes: 2 additions & 0 deletions lib/phy/upper/signal_processors/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,8 @@
#

set(SOURCES
prs/factories.cpp
prs/prs_generator_impl.cpp
ptrs/ptrs_pdsch_generator_impl.cpp
ptrs/ptrs_pdsch_generator_factory.cpp
pucch/dmrs_pucch_estimator_format1.cpp
Expand Down
55 changes: 55 additions & 0 deletions lib/phy/upper/signal_processors/prs/factories.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
/*
*
* Copyright 2021-2025 Software Radio Systems Limited
*
* By using this file, you agree to the terms and conditions set
* forth in the LICENSE file which can be found at the top level of
* the distribution.
*
*/

#include "srsran/phy/upper/signal_processors/prs/factories.h"
#include "prs_generator_impl.h"
#include "prs_generator_validator_impl.h"

using namespace srsran;

namespace {

/// Implements a generic PRS generator factory.
class prs_generator_factory_generic_impl : public prs_generator_factory
{
public:
prs_generator_factory_generic_impl(std::shared_ptr<pseudo_random_generator_factory> prg_factory_,
std::shared_ptr<channel_precoder_factory> precoder_factory_) :
prg_factory(std::move(prg_factory_)), precoder_factory(std::move(precoder_factory_))
{
srsran_assert(prg_factory, "Invalid pseudo-random sequence generator factory.");
srsran_assert(precoder_factory, "Invalid channel precoder factory.");
}

// See interface for documentation.
std::unique_ptr<prs_generator> create() override
{
return std::make_unique<prs_generator_impl>(prg_factory->create(), precoder_factory->create());
}

// See interface for documentation.
std::unique_ptr<prs_generator_validator> create_validator() override
{
return std::make_unique<prs_generator_validator_impl>();
}

private:
std::shared_ptr<pseudo_random_generator_factory> prg_factory;
std::shared_ptr<channel_precoder_factory> precoder_factory;
};

} // namespace

std::shared_ptr<prs_generator_factory>
srsran::create_prs_generator_generic_factory(std::shared_ptr<pseudo_random_generator_factory> prg_factory,
std::shared_ptr<channel_precoder_factory> precoder_factory)
{
return std::make_shared<prs_generator_factory_generic_impl>(std::move(prg_factory), std::move(precoder_factory));
}
Loading

0 comments on commit e42c3eb

Please sign in to comment.