mirror of
https://gitlab.eurecom.fr/oai/openairinterface5g.git
synced 2026-07-13 04:30:28 +00:00
Compare commits
19 Commits
4c6747951d
...
t2-offload
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
0c7ecfaca5 | ||
|
|
6fcfbc4988 | ||
|
|
21172d2764 | ||
|
|
69e776f24d | ||
|
|
7a516e2198 | ||
|
|
1f42d8d52f | ||
|
|
5c418b58e3 | ||
|
|
56cfb8d00a | ||
|
|
5d29915d7e | ||
|
|
d3a837f116 | ||
|
|
205607d02b | ||
|
|
70f81efd66 | ||
|
|
36efab58d9 | ||
|
|
dfe5a83026 | ||
|
|
2eaecf4119 | ||
|
|
7d8075fb63 | ||
|
|
b0dcae8ae2 | ||
|
|
dffe063bc0 | ||
|
|
4c5450f7fd |
@@ -144,7 +144,6 @@ sudo ./nr-softmodem --sa -O ../../../targets/PROJECTS/GENERIC-NR-5GC/CONF/gnb.sa
|
||||
|
||||
# Limitations
|
||||
## AMD Xilinx T2 card
|
||||
- offload of the LDPC encoding implemented for MCS > 2, OAI CPU encoder is used for MCS =< 2
|
||||
- functionality of the LDPC encoding and decoding offload verified in OTA SISO setup with USRP N310 and Quectel RM500Q, blocking of the card reported for MIMO setup (2 layers)
|
||||
|
||||
*Note: AMD Xilinx T1 Telco card is not supported anymore.*
|
||||
|
||||
@@ -56,7 +56,7 @@
|
||||
// this socket is the NUMA socket, so the hardware CPU id (numa is complex)
|
||||
#define GET_SOCKET(socket_id) (((socket_id) == SOCKET_ID_ANY) ? 0 : (socket_id))
|
||||
|
||||
#define MAX_QUEUES 16
|
||||
#define MAX_QUEUES 32
|
||||
|
||||
#define OPS_CACHE_SIZE 256U
|
||||
#define OPS_POOL_SIZE_MIN 511U /* 0.5K per queue */
|
||||
@@ -181,6 +181,7 @@ optimal_mempool_size(unsigned int val)
|
||||
static int create_mempools(struct active_device *ad, int socket_id, uint16_t num_ops, int out_buff_sz, int in_max_sz)
|
||||
{
|
||||
unsigned int ops_pool_size, mbuf_pool_size, data_room_size = 0;
|
||||
num_ops = 1;
|
||||
uint8_t nb_segments = 1;
|
||||
ops_pool_size = optimal_mempool_size(RTE_MAX(
|
||||
/* Ops used plus 1 reference op */
|
||||
@@ -374,26 +375,24 @@ static int add_dev(uint8_t dev_id, struct rte_bbdev_info *info)
|
||||
|
||||
// DPDK BBDEV modified - nb_segments used, we are not using struct op_data_entries *ref_entries, but struct rte_mbuf *m_head,
|
||||
// rte_pktmbuf_reset(m_head) added? if ((op_type == DATA_INPUT) || (op_type == DATA_HARQ_INPUT)) -> no code in else?
|
||||
static int init_op_data_objs(struct rte_bbdev_op_data *bufs,
|
||||
uint8_t *input,
|
||||
uint32_t data_len,
|
||||
struct rte_mbuf *m_head,
|
||||
struct rte_mempool *mbuf_pool,
|
||||
const uint16_t n,
|
||||
enum op_data_type op_type,
|
||||
uint16_t min_alignment)
|
||||
static int init_op_data_objs_dec(struct rte_bbdev_op_data *bufs,
|
||||
uint8_t *input,
|
||||
t_nrLDPCoffload_params *offloadParams,
|
||||
struct rte_mempool *mbuf_pool,
|
||||
const uint16_t n,
|
||||
enum op_data_type op_type,
|
||||
uint16_t min_alignment)
|
||||
{
|
||||
int ret;
|
||||
unsigned int i, j;
|
||||
uint32_t data_len;
|
||||
bool large_input = false;
|
||||
uint8_t nb_segments = 1;
|
||||
for (i = 0; i < n; ++i) {
|
||||
for (int i = 0; i < n; ++i) {
|
||||
data_len = offloadParams->E_cb[i];
|
||||
char *data;
|
||||
struct rte_mbuf *m_head = rte_pktmbuf_alloc(mbuf_pool);
|
||||
TEST_ASSERT_NOT_NULL(m_head, "Not enough mbufs in %d data type mbuf pool (needed %u, available %u)",
|
||||
op_type, n, mbuf_pool->size);
|
||||
|
||||
if (data_len > RTE_BBDEV_LDPC_E_MAX_MBUF) {
|
||||
/*
|
||||
* Special case when DPDK mbuf cannot handle
|
||||
* the required input size
|
||||
*/
|
||||
printf("Warning: Larger input size than DPDK mbuf %u\n", data_len);
|
||||
large_input = true;
|
||||
}
|
||||
@@ -406,70 +405,80 @@ static int init_op_data_objs(struct rte_bbdev_op_data *bufs,
|
||||
/* Allocate a fake overused mbuf */
|
||||
data = rte_malloc(NULL, data_len, 0);
|
||||
TEST_ASSERT_NOT_NULL(data, "rte malloc failed with %u bytes", data_len);
|
||||
memcpy(data, input, data_len);
|
||||
memcpy(data, &input[i * LDPC_MAX_CB_SIZE], data_len);
|
||||
m_head->buf_addr = data;
|
||||
m_head->buf_iova = rte_malloc_virt2iova(data);
|
||||
m_head->data_off = 0;
|
||||
m_head->data_len = data_len;
|
||||
} else {
|
||||
// rte_pktmbuf_reset added
|
||||
rte_pktmbuf_reset(m_head);
|
||||
data = rte_pktmbuf_append(m_head, data_len);
|
||||
|
||||
TEST_ASSERT_NOT_NULL(data, "Couldn't append %u bytes to mbuf from %d data type mbuf pool", data_len, op_type);
|
||||
|
||||
TEST_ASSERT(data == RTE_PTR_ALIGN(data, min_alignment),
|
||||
"Data addr in mbuf (%p) is not aligned to device min alignment (%u)",
|
||||
data,
|
||||
min_alignment);
|
||||
rte_memcpy(data, input, data_len);
|
||||
rte_memcpy(data, &input[i * LDPC_MAX_CB_SIZE], data_len);
|
||||
}
|
||||
|
||||
bufs[i].length += data_len;
|
||||
|
||||
for (j = 1; j < nb_segments; ++j) {
|
||||
struct rte_mbuf *m_tail = rte_pktmbuf_alloc(mbuf_pool);
|
||||
TEST_ASSERT_NOT_NULL(m_tail,
|
||||
"Not enough mbufs in %d data type mbuf pool (needed %d, available %u)",
|
||||
op_type,
|
||||
n * nb_segments,
|
||||
mbuf_pool->size);
|
||||
|
||||
data = rte_pktmbuf_append(m_tail, data_len);
|
||||
TEST_ASSERT_NOT_NULL(data, "Couldn't append %u bytes to mbuf from %d data type mbuf pool", data_len, op_type);
|
||||
|
||||
TEST_ASSERT(data == RTE_PTR_ALIGN(data, min_alignment),
|
||||
"Data addr in mbuf (%p) is not aligned to device min alignment (%u)",
|
||||
data,
|
||||
min_alignment);
|
||||
rte_memcpy(data, input, data_len);
|
||||
bufs[i].length += data_len;
|
||||
|
||||
ret = rte_pktmbuf_chain(m_head, m_tail);
|
||||
TEST_ASSERT_SUCCESS(ret, "Couldn't chain mbufs from %d data type mbuf pool", op_type);
|
||||
}
|
||||
} else {
|
||||
/* allocate chained-mbuf for output buffer */
|
||||
/*for (j = 1; j < nb_segments; ++j) {
|
||||
struct rte_mbuf *m_tail =
|
||||
rte_pktmbuf_alloc(mbuf_pool);
|
||||
TEST_ASSERT_NOT_NULL(m_tail,
|
||||
"Not enough mbufs in %d data type mbuf pool (needed %u, available %u)",
|
||||
op_type,
|
||||
n * nb_segments,
|
||||
mbuf_pool->size);
|
||||
|
||||
ret = rte_pktmbuf_chain(m_head, m_tail);
|
||||
TEST_ASSERT_SUCCESS(ret,
|
||||
"Couldn't chain mbufs from %d data type mbuf pool",
|
||||
op_type);
|
||||
}*/
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int init_op_data_objs_enc(struct rte_bbdev_op_data *bufs,
|
||||
uint8_t **input_enc,
|
||||
t_nrLDPCoffload_params *offloadParams,
|
||||
struct rte_mbuf *m_head,
|
||||
struct rte_mempool *mbuf_pool,
|
||||
const uint16_t n,
|
||||
enum op_data_type op_type,
|
||||
uint16_t min_alignment)
|
||||
{
|
||||
uint32_t data_len;
|
||||
bool large_input = false;
|
||||
for (int i = 0; i < n; ++i) {
|
||||
data_len = offloadParams->Kr;
|
||||
char *data;
|
||||
struct rte_mbuf *m_head = rte_pktmbuf_alloc(mbuf_pool);
|
||||
TEST_ASSERT_NOT_NULL(m_head, "Not enough mbufs in %d data type mbuf pool (needed %u, available %u)",
|
||||
op_type, n, mbuf_pool->size);
|
||||
|
||||
if (data_len > RTE_BBDEV_LDPC_E_MAX_MBUF) {
|
||||
printf("Warning: Larger input size than DPDK mbuf %u\n", data_len);
|
||||
large_input = true;
|
||||
}
|
||||
bufs[i].data = m_head;
|
||||
bufs[i].offset = 0;
|
||||
bufs[i].length = 0;
|
||||
|
||||
if ((op_type == DATA_INPUT) || (op_type == DATA_HARQ_INPUT)) {
|
||||
if ((op_type == DATA_INPUT) && large_input) {
|
||||
/* Allocate a fake overused mbuf */
|
||||
data = rte_malloc(NULL, data_len, 0);
|
||||
TEST_ASSERT_NOT_NULL(data, "rte malloc failed with %u bytes", data_len);
|
||||
memcpy(data, &input_enc[0], data_len);
|
||||
m_head->buf_addr = data;
|
||||
m_head->buf_iova = rte_malloc_virt2iova(data);
|
||||
m_head->data_off = 0;
|
||||
m_head->data_len = data_len;
|
||||
} else {
|
||||
rte_pktmbuf_reset(m_head);
|
||||
data = rte_pktmbuf_append(m_head, data_len);
|
||||
TEST_ASSERT_NOT_NULL(data, "Couldn't append %u bytes to mbuf from %d data type mbuf pool", data_len, op_type);
|
||||
TEST_ASSERT(data == RTE_PTR_ALIGN(data, min_alignment),
|
||||
"Data addr in mbuf (%p) is not aligned to device min alignment (%u)",
|
||||
data,
|
||||
min_alignment);
|
||||
rte_memcpy(data, input_enc[i], data_len);
|
||||
}
|
||||
bufs[i].length += data_len;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
// DPDK BBEV copy
|
||||
static int allocate_buffers_on_socket(struct rte_bbdev_op_data **buffers, const int len, const int socket)
|
||||
{
|
||||
@@ -501,7 +510,7 @@ free_buffers(struct active_device *ad, struct test_op_params *op_params)
|
||||
rte_mempool_free(ad->harq_in_mbuf_pool);
|
||||
rte_mempool_free(ad->harq_out_mbuf_pool);
|
||||
|
||||
for (int i = 0; i < rte_lcore_count(); ++i) {
|
||||
for (int i = 2; i < rte_lcore_count(); ++i) {
|
||||
for (int j = 0; j < RTE_MAX_NUMA_NODES; ++j) {
|
||||
rte_free(op_params->q_bufs[j][i].inputs);
|
||||
rte_free(op_params->q_bufs[j][i].hard_outputs);
|
||||
@@ -525,14 +534,14 @@ set_ldpc_dec_op(struct rte_bbdev_dec_op **ops, unsigned int n,
|
||||
t_nrLDPCoffload_params *p_offloadParams)
|
||||
{
|
||||
unsigned int i;
|
||||
for (i = 0; i < n; ++i) {
|
||||
ops[i]->ldpc_dec.cb_params.e = p_offloadParams->E;
|
||||
for (i = 0; i < p_offloadParams->C; ++i) {
|
||||
ops[i]->ldpc_dec.cb_params.e = p_offloadParams->E_cb[i];
|
||||
ops[i]->ldpc_dec.basegraph = p_offloadParams->BG;
|
||||
ops[i]->ldpc_dec.z_c = p_offloadParams->Z;
|
||||
ops[i]->ldpc_dec.q_m = p_offloadParams->Qm;
|
||||
ops[i]->ldpc_dec.n_filler = p_offloadParams->F;
|
||||
ops[i]->ldpc_dec.n_cb = p_offloadParams->n_cb;
|
||||
ops[i]->ldpc_dec.iter_max = 20;
|
||||
ops[i]->ldpc_dec.iter_max = p_offloadParams->numMaxIter;
|
||||
ops[i]->ldpc_dec.rv_index = p_offloadParams->rv;
|
||||
ops[i]->ldpc_dec.op_flags = RTE_BBDEV_LDPC_ITERATION_STOP_ENABLE |
|
||||
RTE_BBDEV_LDPC_INTERNAL_HARQ_MEMORY_IN_ENABLE |
|
||||
@@ -541,10 +550,14 @@ set_ldpc_dec_op(struct rte_bbdev_dec_op **ops, unsigned int n,
|
||||
if (p_offloadParams->setCombIn) {
|
||||
ops[i]->ldpc_dec.op_flags |= RTE_BBDEV_LDPC_HQ_COMBINE_IN_ENABLE;
|
||||
}
|
||||
LOG_D(PHY,"ULSCH %02d HARQPID %02d R %02d COMBIN %d RV %d NCB %05d \n", ulsch_id, harq_pid, r, p_offloadParams->setCombIn, p_offloadParams->rv, p_offloadParams->n_cb);
|
||||
if (p_offloadParams->C > 1) {
|
||||
ops[i]->ldpc_dec.op_flags |= RTE_BBDEV_LDPC_CRC_TYPE_24B_DROP;
|
||||
ops[i]->ldpc_dec.op_flags |= RTE_BBDEV_LDPC_CRC_TYPE_24B_CHECK;
|
||||
}
|
||||
//LOG_W(PHY,"ULSCH %02d HARQPID %02d R %02d COMBIN %d RV %d NCB %05d NUM OPS %d E %05d\n", ulsch_id, harq_pid, r, p_offloadParams->setCombIn, p_offloadParams->rv, p_offloadParams->n_cb, n, p_offloadParams->E_cb[i]);
|
||||
ops[i]->ldpc_dec.code_block_mode = 1; // ldpc_dec->code_block_mode;
|
||||
ops[i]->ldpc_dec.harq_combined_input.offset = ulsch_id * 64 * LDPC_MAX_CB_SIZE + r * LDPC_MAX_CB_SIZE;
|
||||
ops[i]->ldpc_dec.harq_combined_output.offset = ulsch_id * 64 * LDPC_MAX_CB_SIZE + r * LDPC_MAX_CB_SIZE;
|
||||
ops[i]->ldpc_dec.harq_combined_input.offset = ulsch_id * LDPC_MAX_NUM_CB * LDPC_MAX_CB_SIZE + i * LDPC_MAX_CB_SIZE;
|
||||
ops[i]->ldpc_dec.harq_combined_output.offset = ulsch_id * LDPC_MAX_NUM_CB * LDPC_MAX_CB_SIZE + i * LDPC_MAX_CB_SIZE;
|
||||
if (bufs->hard_outputs != NULL)
|
||||
ops[i]->ldpc_dec.hard_output = bufs->hard_outputs[start_idx + i];
|
||||
if (bufs->inputs != NULL)
|
||||
@@ -568,14 +581,14 @@ static void set_ldpc_enc_op(struct rte_bbdev_enc_op **ops,
|
||||
{
|
||||
// struct rte_bbdev_op_ldpc_enc *ldpc_enc = &ref_op->ldpc_enc;
|
||||
for (int i = 0; i < n; ++i) {
|
||||
ops[i]->ldpc_enc.cb_params.e = 3 * p_offloadParams->E; // Fix mee: what is the correct size for "e" ???
|
||||
ops[i]->ldpc_enc.cb_params.e = p_offloadParams->E_cb[i];
|
||||
ops[i]->ldpc_enc.basegraph = p_offloadParams->BG;
|
||||
ops[i]->ldpc_enc.z_c = p_offloadParams->Z;
|
||||
ops[i]->ldpc_enc.q_m = p_offloadParams->Qm;
|
||||
ops[i]->ldpc_enc.n_filler = p_offloadParams->F;
|
||||
ops[i]->ldpc_enc.n_cb = p_offloadParams->n_cb;
|
||||
ops[i]->ldpc_enc.rv_index = p_offloadParams->rv;
|
||||
ops[i]->ldpc_enc.op_flags = RTE_BBDEV_LDPC_INTERLEAVER_BYPASS; // RTE_BBDEV_LDPC_RATE_MATCH;
|
||||
ops[i]->ldpc_enc.op_flags = RTE_BBDEV_LDPC_RATE_MATCH;
|
||||
ops[i]->ldpc_enc.code_block_mode = 1;
|
||||
ops[i]->ldpc_enc.output = outputs[start_idx + i];
|
||||
ops[i]->ldpc_enc.input = inputs[start_idx + i];
|
||||
@@ -591,33 +604,44 @@ static int retrieve_ldpc_dec_op(struct rte_bbdev_dec_op **ops,
|
||||
uint8_t *p_out)
|
||||
{
|
||||
struct rte_bbdev_op_data *hard_output;
|
||||
uint16_t data_len = 0;
|
||||
struct rte_mbuf *m;
|
||||
unsigned int i;
|
||||
char *data;
|
||||
int offset = 0;
|
||||
for (i = 0; i < n; ++i) {
|
||||
hard_output = &ops[i]->ldpc_dec.hard_output;
|
||||
m = hard_output->data;
|
||||
uint16_t data_len = rte_pktmbuf_data_len(m) - hard_output->offset;
|
||||
data_len = rte_pktmbuf_data_len(m) - hard_output->offset;
|
||||
data = m->buf_addr;
|
||||
memcpy(p_out, data + m->data_off, data_len);
|
||||
memcpy(&p_out[offset], data + m->data_off, data_len);
|
||||
offset += data_len;
|
||||
rte_pktmbuf_free(ops[i]->ldpc_dec.hard_output.data);
|
||||
rte_pktmbuf_free(ops[i]->ldpc_dec.input.data);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int retrieve_ldpc_enc_op(struct rte_bbdev_enc_op **ops, const uint16_t n, struct rte_bbdev_enc_op *ref_op, uint8_t *p_out)
|
||||
static int retrieve_ldpc_enc_op(struct rte_bbdev_enc_op **ops, const uint16_t n, struct rte_bbdev_enc_op *ref_op, uint8_t *p_out, uint32_t *E)
|
||||
{
|
||||
struct rte_bbdev_op_data *output;
|
||||
struct rte_mbuf *m;
|
||||
unsigned int i;
|
||||
char *data;
|
||||
uint8_t *out;
|
||||
int offset = 0;
|
||||
for (i = 0; i < n; ++i) {
|
||||
output = &ops[i]->ldpc_enc.output;
|
||||
m = output->data;
|
||||
uint16_t data_len = min((384 * 68) / 8, rte_pktmbuf_data_len(m)); // fix me
|
||||
uint16_t data_len = rte_pktmbuf_data_len(m) - output->offset;
|
||||
out = &p_out[offset];
|
||||
data = m->buf_addr;
|
||||
for (int byte = 0; byte < data_len; byte++)
|
||||
for (int bit = 0; bit < 8; bit++)
|
||||
p_out[byte * 8 + bit] = (data[m->data_off + byte] >> (7 - bit)) & 1;
|
||||
out[byte * 8 + bit] = (data[m->data_off + byte] >> (7 - bit)) & 1;
|
||||
offset += E[i];
|
||||
rte_pktmbuf_free(ops[i]->ldpc_enc.output.data);
|
||||
rte_pktmbuf_free(ops[i]->ldpc_enc.input.data);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
@@ -632,7 +656,7 @@ static int init_test_op_params(struct test_op_params *op_params,
|
||||
{
|
||||
int ret = 0;
|
||||
if (op_type == RTE_BBDEV_OP_LDPC_DEC) {
|
||||
ret = rte_bbdev_dec_op_alloc_bulk(ops_mp, &op_params->ref_dec_op, 1);
|
||||
ret = rte_bbdev_dec_op_alloc_bulk(ops_mp, &op_params->ref_dec_op, num_to_process);
|
||||
op_params->mp_dec = ops_mp;
|
||||
} else {
|
||||
ret = rte_bbdev_enc_op_alloc_bulk(ops_mp, &op_params->ref_enc_op, 1);
|
||||
@@ -654,8 +678,8 @@ pmd_lcore_ldpc_dec(void *arg)
|
||||
struct thread_params *tp = arg;
|
||||
uint16_t enq, deq;
|
||||
const uint16_t queue_id = tp->queue_id;
|
||||
const uint16_t burst_sz = tp->op_params->burst_sz;
|
||||
const uint16_t num_ops = tp->op_params->num_to_process;
|
||||
const uint16_t burst_sz = tp->p_offloadParams->C; //tp->op_params->burst_sz;
|
||||
const uint16_t num_ops = tp->p_offloadParams->C;
|
||||
struct rte_bbdev_dec_op *ops_enq[num_ops];
|
||||
struct rte_bbdev_dec_op *ops_deq[num_ops];
|
||||
struct rte_bbdev_dec_op *ref_op = tp->op_params->ref_dec_op;
|
||||
@@ -675,25 +699,23 @@ pmd_lcore_ldpc_dec(void *arg)
|
||||
bufs = &tp->op_params->q_bufs[GET_SOCKET(info.socket_id)][queue_id];
|
||||
while (rte_atomic16_read(&tp->op_params->sync) == SYNC_WAIT)
|
||||
rte_pause();
|
||||
|
||||
ret = rte_mempool_get_bulk(tp->op_params->mp_dec, (void **)ops_enq, num_ops);
|
||||
// looks like a bbdev internal error for the free operation, workaround here
|
||||
ops_enq[0]->mempool = tp->op_params->mp_dec;
|
||||
// ret = rte_bbdev_dec_op_alloc_bulk(tp->op_params->mp, ops_enq, num_ops);
|
||||
TEST_ASSERT_SUCCESS(ret, "Allocation failed for %d ops", num_ops);
|
||||
|
||||
set_ldpc_dec_op(ops_enq,
|
||||
num_ops,
|
||||
0,
|
||||
bufs,
|
||||
ref_op,
|
||||
r,
|
||||
harq_pid,
|
||||
ulsch_id,
|
||||
p_offloadParams);
|
||||
|
||||
/*
|
||||
for (j = 0; j < num_ops; ++j) {
|
||||
ops_enq[j]->mempool = tp->op_params->mp_dec;
|
||||
}
|
||||
*/
|
||||
set_ldpc_dec_op(ops_enq, num_ops, 0, bufs, ref_op, r, harq_pid, ulsch_id, p_offloadParams);
|
||||
/* Set counter to validate the ordering */
|
||||
/*
|
||||
for (j = 0; j < num_ops; ++j)
|
||||
ops_enq[j]->opaque_data = (void *)(uintptr_t)j;
|
||||
*/
|
||||
|
||||
for (j = 0; j < num_ops; ++j) {
|
||||
mbuf_reset(ops_enq[j]->ldpc_dec.hard_output.data);
|
||||
}
|
||||
|
||||
for (enq = 0, deq = 0; enq < num_ops;) {
|
||||
num_to_enq = burst_sz;
|
||||
@@ -711,21 +733,28 @@ pmd_lcore_ldpc_dec(void *arg)
|
||||
time_out++;
|
||||
DevAssert(time_out <= TIME_OUT_POLL);
|
||||
}
|
||||
|
||||
// This if statement is not in DPDK
|
||||
if (deq == enq) {
|
||||
tp->iter_count = 0;
|
||||
/* get the max of iter_count for all dequeued ops */
|
||||
for (i = 0; i < num_ops; ++i) {
|
||||
uint8_t *status = tp->p_offloadParams->status_cb[i];
|
||||
tp->iter_count = RTE_MAX(ops_enq[i]->ldpc_dec.iter_count, tp->iter_count);
|
||||
*status = ops_enq[i]->status;
|
||||
}
|
||||
ret = retrieve_ldpc_dec_op(ops_deq, num_ops, ref_op, tp->op_params->vector_mask, p_out);
|
||||
TEST_ASSERT_SUCCESS(ret, "Validation failed!");
|
||||
}
|
||||
/*
|
||||
for (int k = 0; k < num_ops; k++) {
|
||||
rte_mempool_put_bulk(ops_enq[k]->mempool, (void **)ops_enq, num_ops);
|
||||
}
|
||||
*/
|
||||
for (j = 0; j < num_ops; ++j) {
|
||||
mbuf_reset(ops_enq[j]->ldpc_dec.input.data);
|
||||
}
|
||||
|
||||
if (num_ops > 0)
|
||||
rte_mempool_put_bulk(ops_enq[0]->mempool, (void **)ops_enq, num_ops);
|
||||
|
||||
rte_bbdev_dec_op_free_bulk(ops_enq, num_ops);
|
||||
// Return the worst decoding number of iterations for all segments
|
||||
return tp->iter_count;
|
||||
}
|
||||
@@ -736,12 +765,14 @@ static int pmd_lcore_ldpc_enc(void *arg)
|
||||
struct thread_params *tp = arg;
|
||||
uint16_t enq, deq;
|
||||
const uint16_t queue_id = tp->queue_id;
|
||||
const uint16_t burst_sz = tp->op_params->burst_sz;
|
||||
const uint16_t burst_sz = tp->p_offloadParams->C;
|
||||
tp->op_params->num_to_process = tp->p_offloadParams->C;
|
||||
const uint16_t num_ops = tp->op_params->num_to_process;
|
||||
struct rte_bbdev_enc_op *ops_enq[num_ops];
|
||||
struct rte_bbdev_enc_op *ops_deq[num_ops];
|
||||
struct rte_bbdev_enc_op *ref_op = tp->op_params->ref_enc_op;
|
||||
int j, ret;
|
||||
struct test_buffers *bufs = NULL;
|
||||
uint16_t num_to_enq;
|
||||
uint8_t *p_out = tp->p_out;
|
||||
t_nrLDPCoffload_params *p_offloadParams = tp->p_offloadParams;
|
||||
@@ -753,14 +784,12 @@ static int pmd_lcore_ldpc_enc(void *arg)
|
||||
|
||||
TEST_ASSERT_SUCCESS((num_ops > info.drv.queue_size_lim), "NUM_OPS cannot exceed %u for this device", info.drv.queue_size_lim);
|
||||
|
||||
struct test_buffers *bufs = &tp->op_params->q_bufs[GET_SOCKET(info.socket_id)][queue_id];
|
||||
bufs = &tp->op_params->q_bufs[GET_SOCKET(info.socket_id)][queue_id];
|
||||
|
||||
while (rte_atomic16_read(&tp->op_params->sync) == SYNC_WAIT)
|
||||
rte_pause();
|
||||
|
||||
ret = rte_mempool_get_bulk(tp->op_params->mp_enc, (void **)ops_enq, num_ops);
|
||||
// ret = rte_bbdev_enc_op_alloc_bulk(tp->op_params->mp, ops_enq, num_ops);
|
||||
TEST_ASSERT_SUCCESS(ret, "Allocation failed for %d ops", num_ops);
|
||||
ops_enq[0]->mempool = tp->op_params->mp_enc;
|
||||
|
||||
set_ldpc_enc_op(ops_enq, num_ops, 0, bufs->inputs, bufs->hard_outputs, ref_op, p_offloadParams);
|
||||
@@ -788,13 +817,12 @@ static int pmd_lcore_ldpc_enc(void *arg)
|
||||
DevAssert(time_out <= TIME_OUT_POLL);
|
||||
}
|
||||
|
||||
ret = retrieve_ldpc_enc_op(ops_deq, num_ops, ref_op, p_out);
|
||||
ret = retrieve_ldpc_enc_op(ops_deq, num_ops, ref_op, p_out, tp->p_offloadParams->E_cb);
|
||||
TEST_ASSERT_SUCCESS(ret, "Validation failed!");
|
||||
// rte_bbdev_enc_op_free_bulk(ops_enq, num_ops);
|
||||
//rte_bbdev_enc_op_free_bulk(ops_enq, num_ops);
|
||||
|
||||
if (num_ops > 0)
|
||||
rte_mempool_put_bulk(ops_enq[0]->mempool, (void **)ops_enq, num_ops);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
@@ -841,7 +869,6 @@ int start_pmd_dec(struct active_device *ad,
|
||||
t_params[0].r = r;
|
||||
t_params[0].harq_pid = harq_pid;
|
||||
t_params[0].ulsch_id = ulsch_id;
|
||||
|
||||
// For now, we never enter here, we don't use the DPDK thread pool
|
||||
RTE_LCORE_FOREACH_WORKER(lcore_id) {
|
||||
if (used_cores >= num_lcores)
|
||||
@@ -867,12 +894,6 @@ int start_pmd_dec(struct active_device *ad,
|
||||
// for (used_cores = 1; used_cores < num_lcores; used_cores++)
|
||||
// ret |= rte_eal_wait_lcore(t_params[used_cores].lcore_id);
|
||||
|
||||
/* Return if test failed */
|
||||
if (ret < 0) {
|
||||
rte_free(t_params);
|
||||
return ret;
|
||||
}
|
||||
|
||||
rte_free(t_params);
|
||||
return ret;
|
||||
}
|
||||
@@ -942,9 +963,9 @@ int32_t LDPCinit()
|
||||
struct rte_bbdev_info info;
|
||||
struct active_device *ad = active_devs;
|
||||
char *dpdk_dev = "41:00.0"; //PCI address of the card
|
||||
char *argv_re[] = {"bbdev", "-a", dpdk_dev, "-l", "14-15", "--file-prefix=b6", "--"};
|
||||
char *argv_re[] = {"bbdev", "-a", dpdk_dev, "-l", "8-9", "--file-prefix=b6", "--"};
|
||||
// EAL initialization, if already initialized (init in xran lib) try to probe DPDK device
|
||||
ret = rte_eal_init(5, argv_re);
|
||||
ret = rte_eal_init(7, argv_re);
|
||||
if (ret < 0) {
|
||||
printf("EAL initialization failed, probing DPDK device %s\n", dpdk_dev);
|
||||
if (rte_dev_probe(dpdk_dev) != 0) {
|
||||
@@ -969,8 +990,8 @@ int32_t LDPCinit()
|
||||
int socket_id = GET_SOCKET(info.socket_id);
|
||||
int out_max_sz = 8448; // max code block size (for BG1), 22 * 384
|
||||
int in_max_sz = LDPC_MAX_CB_SIZE; // max number of encoded bits (for BG2 and MCS0)
|
||||
int num_ops = 1;
|
||||
int f_ret = create_mempools(ad, socket_id, num_ops, out_max_sz, in_max_sz);
|
||||
int num_queues = 1;
|
||||
int f_ret = create_mempools(ad, socket_id, num_queues, out_max_sz, in_max_sz);
|
||||
if (f_ret != TEST_SUCCESS) {
|
||||
printf("Couldn't create mempools");
|
||||
return -1;
|
||||
@@ -978,41 +999,12 @@ int32_t LDPCinit()
|
||||
// get_num_lcores() hardcoded to 1: we use one core for decode, and another for encode
|
||||
// this code from bbdev test example is not considering encode and decode test
|
||||
// get_num_ops() replaced by 1: LDPC decode and ldpc encode (7th param)
|
||||
f_ret = init_test_op_params(op_params, RTE_BBDEV_OP_LDPC_DEC, ad->bbdev_dec_op_pool, 1, 1, 1);
|
||||
f_ret |= init_test_op_params(op_params, RTE_BBDEV_OP_LDPC_ENC, ad->bbdev_enc_op_pool, 1, 1, 1);
|
||||
f_ret = init_test_op_params(op_params, RTE_BBDEV_OP_LDPC_DEC, ad->bbdev_dec_op_pool, num_queues, num_queues, 1);
|
||||
f_ret = init_test_op_params(op_params, RTE_BBDEV_OP_LDPC_ENC, ad->bbdev_enc_op_pool, num_queues, num_queues, 1);
|
||||
if (f_ret != TEST_SUCCESS) {
|
||||
printf("Couldn't init test op params");
|
||||
return -1;
|
||||
}
|
||||
|
||||
// fill_queue_buffers -> allocate_buffers_on_socket
|
||||
for (int i = 0; i < ad->nb_queues; ++i) {
|
||||
const uint16_t n = op_params->num_to_process;
|
||||
struct rte_mempool *in_mp = ad->in_mbuf_pool;
|
||||
struct rte_mempool *hard_out_mp = ad->hard_out_mbuf_pool;
|
||||
struct rte_mempool *soft_out_mp = ad->soft_out_mbuf_pool;
|
||||
struct rte_mempool *harq_in_mp = ad->harq_in_mbuf_pool;
|
||||
struct rte_mempool *harq_out_mp = ad->harq_out_mbuf_pool;
|
||||
struct rte_mempool *mbuf_pools[DATA_NUM_TYPES] = {in_mp, soft_out_mp, hard_out_mp, harq_in_mp, harq_out_mp};
|
||||
uint8_t queue_id = ad->queue_ids[i];
|
||||
struct rte_bbdev_op_data **queue_ops[DATA_NUM_TYPES] = {&op_params->q_bufs[socket_id][queue_id].inputs,
|
||||
&op_params->q_bufs[socket_id][queue_id].soft_outputs,
|
||||
&op_params->q_bufs[socket_id][queue_id].hard_outputs,
|
||||
&op_params->q_bufs[socket_id][queue_id].harq_inputs,
|
||||
&op_params->q_bufs[socket_id][queue_id].harq_outputs};
|
||||
|
||||
for (enum op_data_type type = DATA_INPUT; type < 3; type += 2) {
|
||||
int ret = allocate_buffers_on_socket(queue_ops[type], n * sizeof(struct rte_bbdev_op_data), socket_id);
|
||||
TEST_ASSERT_SUCCESS(ret, "Couldn't allocate memory for rte_bbdev_op_data structs");
|
||||
m_head[type] = rte_pktmbuf_alloc(mbuf_pools[type]);
|
||||
TEST_ASSERT_NOT_NULL(m_head[type],
|
||||
"Not enough mbufs in %d data type mbuf pool (needed %d, available %u)",
|
||||
type,
|
||||
1,
|
||||
mbuf_pools[type]->size);
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -1043,7 +1035,7 @@ int32_t LDPCdecoder(struct nrLDPC_dec_params *p_decParams,
|
||||
{
|
||||
pthread_mutex_lock(&decode_mutex);
|
||||
// hardcoded we use first device
|
||||
|
||||
LOG_D(PHY,"Offload\n");
|
||||
struct active_device *ad = active_devs;
|
||||
t_nrLDPCoffload_params offloadParams = {.E = p_decParams->E,
|
||||
.n_cb = (p_decParams->BG == 1) ? (66 * p_decParams->Z) : (50 * p_decParams->Z),
|
||||
@@ -1052,8 +1044,16 @@ int32_t LDPCdecoder(struct nrLDPC_dec_params *p_decParams,
|
||||
.rv = p_decParams->rv,
|
||||
.F = p_decParams->F,
|
||||
.Qm = p_decParams->Qm,
|
||||
.numMaxIter = p_decParams->numMaxIter,
|
||||
.C = C,
|
||||
.setCombIn = p_decParams->setCombIn};
|
||||
|
||||
for (int r = 0; r < C; r++) {
|
||||
offloadParams.E_cb[r] = p_decParams->E_cb[r];
|
||||
offloadParams.status_cb[r] = &p_decParams->status_cb[r];
|
||||
}
|
||||
struct rte_bbdev_info info;
|
||||
int ret;
|
||||
rte_bbdev_info_get(ad->dev_id, &info);
|
||||
int socket_id = GET_SOCKET(info.socket_id);
|
||||
// fill_queue_buffers -> init_op_data_objs
|
||||
@@ -1072,21 +1072,23 @@ int32_t LDPCdecoder(struct nrLDPC_dec_params *p_decParams,
|
||||
// this should be modified
|
||||
// enum rte_bbdev_op_type op_type = RTE_BBDEV_OP_LDPC_DEC;
|
||||
for (enum op_data_type type = DATA_INPUT; type < 3; type += 2) {
|
||||
int ret = init_op_data_objs(*queue_ops[type],
|
||||
ret = allocate_buffers_on_socket(queue_ops[type], C * sizeof(struct rte_bbdev_op_data), socket_id);
|
||||
TEST_ASSERT_SUCCESS(ret, "Couldn't allocate memory for rte_bbdev_op_data structs");
|
||||
//rte_pktmbuf_free(m_head[type]);
|
||||
ret = init_op_data_objs_dec(*queue_ops[type],
|
||||
(uint8_t *)p_llr,
|
||||
p_decParams->E,
|
||||
m_head[type],
|
||||
&offloadParams,
|
||||
mbuf_pools[type],
|
||||
1,
|
||||
C,
|
||||
type,
|
||||
info.drv.min_alignment);
|
||||
TEST_ASSERT_SUCCESS(ret, "Couldn't init rte_bbdev_op_data structs");
|
||||
}
|
||||
int ret = start_pmd_dec(ad, op_params, &offloadParams, C, harq_pid, ulsch_id, (uint8_t *)p_out);
|
||||
ret = start_pmd_dec(ad, op_params, &offloadParams, C, harq_pid, ulsch_id, (uint8_t *)p_out);
|
||||
if (ret < 0) {
|
||||
printf("Couldn't start pmd dec\n");
|
||||
pthread_mutex_unlock(&decode_mutex);
|
||||
return (20); // Fix me: we should propoagate max_iterations properly in the call (impp struct)
|
||||
return (p_decParams->numMaxIter); // Fix me: we should propoagate max_iterations properly in the call (impp struct)
|
||||
}
|
||||
pthread_mutex_unlock(&decode_mutex);
|
||||
return ret;
|
||||
@@ -1097,16 +1099,20 @@ int32_t LDPCencoder(unsigned char **input, unsigned char **output, encoder_imple
|
||||
pthread_mutex_lock(&encode_mutex);
|
||||
// hardcoded to use the first found board
|
||||
struct active_device *ad = active_devs;
|
||||
int Zc = impp->Zc;
|
||||
int BG = impp->BG;
|
||||
int ret;
|
||||
t_nrLDPCoffload_params offloadParams = {.E = impp->E,
|
||||
.n_cb = (BG == 1) ? (66 * Zc) : (50 * Zc),
|
||||
.BG = BG,
|
||||
.Z = Zc,
|
||||
.rv = 0, //impp->rv,
|
||||
.F = 0, //impp->F,
|
||||
.n_cb = (impp->BG == 1) ? (66 * impp->Zc) : (50 * impp->Zc),
|
||||
.BG = impp->BG,
|
||||
.Z = impp->Zc,
|
||||
.rv = impp->rv,
|
||||
.F = impp->F,
|
||||
.Qm = impp->Qm,
|
||||
.Kr = impp->Kr};
|
||||
.C = impp->n_segments,
|
||||
.Kr = (impp->K - impp->F + 7)/8};
|
||||
for (int r = 0; r < impp->n_segments; r++) {
|
||||
offloadParams.E_cb[r] = impp->E_cb[r];
|
||||
}
|
||||
|
||||
struct rte_bbdev_info info;
|
||||
rte_bbdev_info_get(ad->dev_id, &info);
|
||||
int socket_id = GET_SOCKET(info.socket_id);
|
||||
@@ -1124,17 +1130,20 @@ int32_t LDPCencoder(unsigned char **input, unsigned char **output, encoder_imple
|
||||
&op_params->q_bufs[socket_id][queue_id].harq_inputs,
|
||||
&op_params->q_bufs[socket_id][queue_id].harq_outputs};
|
||||
for (enum op_data_type type = DATA_INPUT; type < 3; type += 2) {
|
||||
int ret = init_op_data_objs(*queue_ops[type],
|
||||
*input,
|
||||
(offloadParams.Kr + 7) / 8,
|
||||
ret = allocate_buffers_on_socket(queue_ops[type], impp->n_segments * sizeof(struct rte_bbdev_op_data), socket_id);
|
||||
TEST_ASSERT_SUCCESS(ret, "Couldn't allocate memory for rte_bbdev_op_data structs");
|
||||
//m_head[type] = rte_pktmbuf_alloc(mbuf_pools[type]);
|
||||
ret = init_op_data_objs_enc(*queue_ops[type],
|
||||
input,
|
||||
&offloadParams,
|
||||
m_head[type],
|
||||
mbuf_pools[type],
|
||||
1,
|
||||
impp->n_segments,
|
||||
type,
|
||||
info.drv.min_alignment);
|
||||
TEST_ASSERT_SUCCESS(ret, "Couldn't init rte_bbdev_op_data structs");
|
||||
}
|
||||
int ret=start_pmd_enc(ad, op_params, &offloadParams, *output);
|
||||
ret = start_pmd_enc(ad, op_params, &offloadParams, *output);
|
||||
pthread_mutex_unlock(&encode_mutex);
|
||||
return ret;
|
||||
}
|
||||
|
||||
@@ -90,10 +90,13 @@ typedef struct nrLDPC_dec_params {
|
||||
uint8_t rv;
|
||||
uint8_t numMaxIter; /**< Maximum number of iterations */
|
||||
int E;
|
||||
uint32_t E_cb[64];
|
||||
e_nrLDPC_outMode outMode; /**< Output format */
|
||||
int crc_type;
|
||||
int (*check_crc)(uint8_t* decoded_bytes, uint32_t n, uint8_t crc_type);
|
||||
uint8_t setCombIn;
|
||||
uint8_t setCombIn_cb[64];
|
||||
uint8_t status_cb[64];
|
||||
} t_nrLDPC_dec_params;
|
||||
|
||||
typedef struct nrLDPCoffload_params {
|
||||
@@ -102,10 +105,15 @@ typedef struct nrLDPCoffload_params {
|
||||
uint16_t Kr;
|
||||
uint8_t rv;
|
||||
uint32_t E;
|
||||
uint32_t E_cb[64];
|
||||
uint16_t n_cb;
|
||||
uint16_t F; /**< Filler bits */
|
||||
uint8_t Qm; /**< Modulation */
|
||||
uint8_t C;
|
||||
uint8_t numMaxIter;
|
||||
uint8_t setCombIn;
|
||||
uint8_t setCombIn_cb[64];
|
||||
uint8_t *status_cb[64];
|
||||
} t_nrLDPCoffload_params;
|
||||
|
||||
/**
|
||||
|
||||
@@ -60,6 +60,8 @@ typedef struct {
|
||||
/// Modulation order
|
||||
uint8_t Qm;
|
||||
uint32_t E;
|
||||
uint32_t E_cb[64];
|
||||
uint8_t status_cb[64];
|
||||
unsigned int G;
|
||||
// Redundancy version index
|
||||
uint8_t rv;
|
||||
|
||||
@@ -23,6 +23,7 @@
|
||||
#include "openair1/PHY/CODING/nrLDPC_defs.h"
|
||||
/* LDPC maximum code block size - maximum E */
|
||||
#define LDPC_MAX_CB_SIZE 32768
|
||||
#define LDPC_MAX_NUM_CB 80
|
||||
/* ldpc coder/decoder API*/
|
||||
typedef struct ldpc_interface_s {
|
||||
LDPC_initfunc_t *LDPCinit;
|
||||
|
||||
@@ -363,40 +363,17 @@ int nr_dlsch_encoding(PHY_VARS_gNB *gNB,
|
||||
impp.tparity = tparity;
|
||||
impp.toutput = toutput;
|
||||
impp.harq = harq;
|
||||
if (gNB->ldpc_offload_flag && *rel15->mcsIndex > 2) {
|
||||
if (gNB->ldpc_offload_flag) {
|
||||
impp.Qm = rel15->qamModOrder[0];
|
||||
impp.rv = rel15->rvIndex[0];
|
||||
int nb_re_dmrs =
|
||||
(rel15->dmrsConfigType == NFAPI_NR_DMRS_TYPE1) ? (6 * rel15->numDmrsCdmGrpsNoData) : (4 * rel15->numDmrsCdmGrpsNoData);
|
||||
impp.G = nr_get_G(rel15->rbSize,
|
||||
rel15->NrOfSymbols,
|
||||
nb_re_dmrs,
|
||||
get_num_dmrs(rel15->dlDmrsSymbPos),
|
||||
harq->unav_res,
|
||||
rel15->qamModOrder[0],
|
||||
rel15->nrOfLayers);
|
||||
uint8_t tmp[68 * 384] __attribute__((aligned(32)));
|
||||
uint8_t *d = tmp;
|
||||
int r_offset = 0;
|
||||
int nb_re_dmrs = (rel15->dmrsConfigType == NFAPI_NR_DMRS_TYPE1) ?
|
||||
(6 * rel15->numDmrsCdmGrpsNoData) : (4 * rel15->numDmrsCdmGrpsNoData);
|
||||
impp.G = nr_get_G(rel15->rbSize, rel15->NrOfSymbols, nb_re_dmrs, get_num_dmrs(rel15->dlDmrsSymbPos),
|
||||
harq->unav_res, rel15->qamModOrder[0], rel15->nrOfLayers);
|
||||
for (int r = 0; r < impp.n_segments; r++) {
|
||||
impp.E = nr_get_E(impp.G, impp.n_segments, impp.Qm, rel15->nrOfLayers, r);
|
||||
impp.Kr = impp.K;
|
||||
ldpc_interface_offload.LDPCencoder(&harq->c[r], &d, &impp);
|
||||
uint8_t e[impp.E];
|
||||
bzero(e, impp.E);
|
||||
nr_rate_matching_ldpc(rel15->maintenance_parms_v3.tbSizeLbrmBytes,
|
||||
impp.BG,
|
||||
impp.Zc,
|
||||
tmp,
|
||||
e,
|
||||
impp.n_segments,
|
||||
impp.F,
|
||||
impp.K - impp.F - 2 * impp.Zc,
|
||||
impp.rv,
|
||||
impp.E);
|
||||
nr_interleaving_ldpc(impp.E, impp.Qm, e, impp.output + r_offset);
|
||||
r_offset += impp.E;
|
||||
impp.E_cb[r] = nr_get_E(impp.G, impp.n_segments, impp.Qm, rel15->nrOfLayers, r);
|
||||
}
|
||||
ldpc_interface_offload.LDPCencoder(harq->c, &impp.output, &impp);
|
||||
} else {
|
||||
notifiedFIFO_t nf;
|
||||
initNotifiedFIFO(&nf);
|
||||
|
||||
@@ -232,64 +232,58 @@ int decode_offload(PHY_VARS_gNB *phy_vars_gNB,
|
||||
{
|
||||
NR_gNB_ULSCH_t *ulsch = &phy_vars_gNB->ulsch[ULSCH_id];
|
||||
NR_UL_gNB_HARQ_t *harq_process = ulsch->harq_process;
|
||||
int16_t z_ol[LDPC_MAX_CB_SIZE] __attribute__((aligned(16)));
|
||||
int8_t l_ol[LDPC_MAX_CB_SIZE] __attribute__((aligned(16)));
|
||||
uint8_t Qm = pusch_pdu->qam_mod_order;
|
||||
uint8_t n_layers = pusch_pdu->nrOfLayers;
|
||||
int16_t z_ol[LDPC_MAX_NUM_CB * LDPC_MAX_CB_SIZE] __attribute__((aligned(16)));
|
||||
int8_t l_ol[LDPC_MAX_NUM_CB * LDPC_MAX_CB_SIZE] __attribute__((aligned(16)));
|
||||
const int kc = decParams->BG == 2 ? 52 : 68;
|
||||
uint32_t A = (harq_process->TBS) << 3;
|
||||
const int Kr = harq_process->K;
|
||||
const int Kr_bytes = Kr >> 3;
|
||||
uint32_t A = (harq_process->TBS) << 3;
|
||||
const int kc = decParams->BG == 2 ? 52 : 68;
|
||||
ulsch->max_ldpc_iterations = 20;
|
||||
int decodeIterations = 2;
|
||||
int r_offset = 0, offset = 0;
|
||||
for (int r = 0; r < harq_process->C; r++) {
|
||||
int E = nr_get_E(G, harq_process->C, Qm, n_layers, r);
|
||||
memset(harq_process->c[r], 0, Kr_bytes);
|
||||
decParams->R = nr_get_R_ldpc_decoder(pusch_pdu->pusch_data.rv_index,
|
||||
E,
|
||||
decParams->BG,
|
||||
decParams->Z,
|
||||
&harq_process->llrLen,
|
||||
harq_process->round);
|
||||
int8_t decodeIterations = 0;
|
||||
int r_offset = 0;
|
||||
int offset = 0;
|
||||
// new data received, set processedSegments to 0
|
||||
if (!decParams->setCombIn)
|
||||
harq_process->processedSegments = 0;
|
||||
|
||||
memcpy(z_ol, ulsch_llr + r_offset, E * sizeof(short));
|
||||
simde__m128i *pv_ol128 = (simde__m128i *)&z_ol;
|
||||
simde__m128i *pl_ol128 = (simde__m128i *)&l_ol;
|
||||
for (int r = 0; r < harq_process->C; r++) {
|
||||
decParams->E_cb[r] = nr_get_E(G, harq_process->C, decParams->Qm, pusch_pdu->nrOfLayers, r);
|
||||
memcpy(&z_ol[offset], ulsch_llr + r_offset, decParams->E_cb[r] * sizeof(short));
|
||||
simde__m128i *pv_ol128 = (simde__m128i *)&z_ol[offset];
|
||||
simde__m128i *pl_ol128 = (simde__m128i *)&l_ol[offset];
|
||||
for (int i = 0, j = 0; j < ((kc * harq_process->Z) >> 4) + 1; i += 2, j++) {
|
||||
pl_ol128[j] = simde_mm_packs_epi16(pv_ol128[i], pv_ol128[i + 1]);
|
||||
}
|
||||
decParams->E = E;
|
||||
decParams->rv = pusch_pdu->pusch_data.rv_index;
|
||||
decParams->F = harq_process->F;
|
||||
decParams->Qm = Qm;
|
||||
decodeIterations =
|
||||
ldpc_interface_offload
|
||||
.LDPCdecoder(decParams, harq_pid, ULSCH_id, r, (int8_t *)&pl_ol128[0], (int8_t *)harq_process->c[r], NULL, NULL);
|
||||
if (decodeIterations < 0) {
|
||||
LOG_E(PHY, "ulsch_decoding.c: Problem in LDPC decoder offload\n");
|
||||
return -1;
|
||||
}
|
||||
bool decodeSuccess = check_crc((uint8_t *)harq_process->c[r], lenWithCrc(harq_process->C, A), crcType(harq_process->C, A));
|
||||
if (decodeSuccess) {
|
||||
memcpy(harq_process->b + offset, harq_process->c[r], Kr_bytes - (harq_process->F >> 3) - ((harq_process->C > 1) ? 3 : 0));
|
||||
offset += (Kr_bytes - (harq_process->F >> 3) - ((harq_process->C > 1) ? 3 : 0));
|
||||
r_offset += decParams->E_cb[r];
|
||||
offset += LDPC_MAX_CB_SIZE;
|
||||
}
|
||||
|
||||
int8_t *p_outDec = calloc(harq_process->C * Kr_bytes, sizeof(int8_t));
|
||||
decodeIterations = ldpc_interface_offload.LDPCdecoder(decParams, harq_pid, ULSCH_id, harq_process->C, (int8_t *)l_ol, p_outDec, NULL, NULL);
|
||||
|
||||
if (decodeIterations < 0) {
|
||||
LOG_E(PHY, "ulsch_decoding.c: Problem in LDPC decoder offload\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
int offset_b = 0;
|
||||
for (int r = 0; r < harq_process->C; r++) {
|
||||
if (decParams->status_cb[r] == 0 || harq_process->C == 1) {
|
||||
memcpy(harq_process->b + offset_b, &p_outDec[offset_b], Kr_bytes - (harq_process->F >> 3) - ((harq_process->C > 1) ? 3 : 0));
|
||||
harq_process->processedSegments++;
|
||||
} else {
|
||||
LOG_D(PHY, "uplink segment error %d/%d\n", r, harq_process->C);
|
||||
LOG_D(PHY, "ULSCH %d in error\n", ULSCH_id);
|
||||
}
|
||||
r_offset += E;
|
||||
offset_b += (Kr_bytes - (harq_process->F >> 3) - ((harq_process->C > 1) ? 3 : 0));
|
||||
}
|
||||
|
||||
bool crc_valid = false;
|
||||
//CRC check made by the T2, no need to perform CRC check for a single code block twice
|
||||
if (harq_process->processedSegments == harq_process->C) {
|
||||
// When the number of code blocks is 1 (C = 1) and ulsch_harq->processedSegments = 1, we can assume a good TB because of the
|
||||
// CRC check made by the LDPC for early termination, so, no need to perform CRC check twice for a single code block
|
||||
crc_valid = true;
|
||||
if (harq_process->C > 1) {
|
||||
crc_valid = check_crc(harq_process->b, lenWithCrc(1, A), crcType(1, A));
|
||||
crc_valid = check_crc(harq_process->b, lenWithCrc(1, A), crcType(1, A));
|
||||
if (harq_process->C == 1 && !crc_valid) {
|
||||
harq_process->processedSegments--;
|
||||
}
|
||||
}
|
||||
|
||||
if (crc_valid) {
|
||||
LOG_D(PHY, "ULSCH: Setting ACK for slot %d TBS %d\n", ulsch->slot, harq_process->TBS);
|
||||
ulsch->active = false;
|
||||
@@ -313,6 +307,7 @@ int decode_offload(PHY_VARS_gNB *phy_vars_gNB,
|
||||
}
|
||||
|
||||
ulsch->last_iteration_cnt = decodeIterations;
|
||||
free(p_outDec);
|
||||
VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_gNB_ULSCH_DECODING,0);
|
||||
return 0;
|
||||
}
|
||||
@@ -350,7 +345,6 @@ int nr_ulsch_decoding(PHY_VARS_gNB *phy_vars_gNB,
|
||||
const uint8_t n_layers = pusch_pdu->nrOfLayers;
|
||||
// ------------------------------------------------------------------
|
||||
|
||||
harq_process->processedSegments = 0;
|
||||
harq_process->TBS = pusch_pdu->pusch_data.tb_size;
|
||||
|
||||
t_nrLDPC_dec_params decParams = {.check_crc = check_crc};
|
||||
@@ -419,6 +413,8 @@ int nr_ulsch_decoding(PHY_VARS_gNB *phy_vars_gNB,
|
||||
|
||||
decParams.Z = harq_process->Z;
|
||||
decParams.numMaxIter = ulsch->max_ldpc_iterations;
|
||||
decParams.Qm = Qm;
|
||||
decParams.rv = pusch_pdu->pusch_data.rv_index;
|
||||
decParams.outMode = 0;
|
||||
decParams.setCombIn = !harq_process->harq_to_be_cleared;
|
||||
if (harq_process->harq_to_be_cleared) {
|
||||
@@ -429,7 +425,7 @@ int nr_ulsch_decoding(PHY_VARS_gNB *phy_vars_gNB,
|
||||
|
||||
if (phy_vars_gNB->ldpc_offload_flag)
|
||||
return decode_offload(phy_vars_gNB, ULSCH_id, ulsch_llr, pusch_pdu, &decParams, harq_pid, G);
|
||||
|
||||
harq_process->processedSegments = 0;
|
||||
uint32_t offset = 0, r_offset = 0;
|
||||
set_abort(&harq_process->abort_decode, false);
|
||||
for (int r = 0; r < harq_process->C; r++) {
|
||||
|
||||
@@ -51,41 +51,38 @@ int nr_ulsch_encoding(PHY_VARS_NR_UE *ue,
|
||||
start_meas(&ue->ulsch_encoding_stats);
|
||||
|
||||
/////////////////////////parameters and variables initialization/////////////////////////
|
||||
///////////
|
||||
|
||||
unsigned int crc = 1;
|
||||
NR_UL_UE_HARQ_t *harq_process = &ue->ul_harq_processes[harq_pid];
|
||||
uint16_t nb_rb = ulsch->pusch_pdu.rb_size;
|
||||
uint32_t A = tb_size << 3;
|
||||
uint8_t mod_order = ulsch->pusch_pdu.qam_mod_order;
|
||||
uint16_t Kr = 0;
|
||||
uint32_t r_offset = 0;
|
||||
uint32_t F = 0;
|
||||
// target_code_rate is in 0.1 units
|
||||
float Coderate = (float) ulsch->pusch_pdu.target_code_rate / 10240.0f;
|
||||
|
||||
///////////
|
||||
encoder_implemparams_t impp = {.n_segments = harq_process->C,
|
||||
.macro_num = 0,
|
||||
.K = harq_process->K,
|
||||
.Kr = harq_process->K,
|
||||
.Zc = harq_process->Z,
|
||||
.BG = harq_process->BG,
|
||||
.F = harq_process->F,
|
||||
.rv = ulsch->pusch_pdu.pusch_data.rv_index,
|
||||
.Qm = ulsch->pusch_pdu.qam_mod_order,
|
||||
.tinput = NULL,
|
||||
.tprep = NULL,
|
||||
.tparity = NULL,
|
||||
.toutput = NULL};
|
||||
/////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_NR_UE_ULSCH_ENCODING, VCD_FUNCTION_IN);
|
||||
|
||||
LOG_D(NR_PHY, "ulsch coding nb_rb %d, Nl = %d\n", nb_rb, ulsch->pusch_pdu.nrOfLayers);
|
||||
LOG_D(NR_PHY, "ulsch coding A %d G %d mod_order %d Coderate %f\n", A, G, mod_order, Coderate);
|
||||
LOG_D(NR_PHY, "ulsch coding A %d G %d mod_order %d Coderate %f\n", A, G, impp.Qm, Coderate);
|
||||
LOG_D(NR_PHY, "harq_pid %d, pusch_data.new_data_indicator %d\n", harq_pid, ulsch->pusch_pdu.pusch_data.new_data_indicator);
|
||||
if (ulsch->pusch_pdu.pusch_data.new_data_indicator) { // this is a new packet
|
||||
#ifdef DEBUG_ULSCH_CODING
|
||||
printf("encoding thinks this is a new packet \n");
|
||||
printf("encoding thinks this is a new packet \n");
|
||||
#endif
|
||||
///////////////////////// a---->| add CRC |---->b /////////////////////////
|
||||
///////////
|
||||
/*
|
||||
int i;
|
||||
printf("ulsch (tx): \n");
|
||||
for (i=0;i<(A>>3);i++)
|
||||
printf("%02x.",harq_process->a[i]);
|
||||
printf("\n");
|
||||
*/
|
||||
|
||||
int max_payload_bytes = MAX_NUM_NR_ULSCH_SEGMENTS_PER_LAYER*ulsch->pusch_pdu.nrOfLayers*1056;
|
||||
int B;
|
||||
if (A > NR_MAX_PDSCH_TBS) {
|
||||
@@ -94,34 +91,20 @@ int nr_ulsch_encoding(PHY_VARS_NR_UE *ue,
|
||||
harq_process->a[A>>3] = ((uint8_t*)&crc)[2];
|
||||
harq_process->a[1+(A>>3)] = ((uint8_t*)&crc)[1];
|
||||
harq_process->a[2+(A>>3)] = ((uint8_t*)&crc)[0];
|
||||
//printf("CRC %x (A %d)\n",crc,A);
|
||||
//printf("a0 %d a1 %d a2 %d\n", a[A>>3], a[1+(A>>3)], a[2+(A>>3)]);
|
||||
|
||||
B = A + 24;
|
||||
|
||||
AssertFatal((A/8)+4 <= max_payload_bytes,"A %d is too big (A/8+4 = %d > %d)\n",A,(A/8)+4,max_payload_bytes);
|
||||
|
||||
memcpy(harq_process->b,harq_process->a,(A/8)+4);
|
||||
} else {
|
||||
// Add 16-bit crc (polynomial A) to payload
|
||||
crc = crc16(harq_process->a,A)>>16;
|
||||
harq_process->a[A>>3] = ((uint8_t*)&crc)[1];
|
||||
harq_process->a[1+(A>>3)] = ((uint8_t*)&crc)[0];
|
||||
//printf("CRC %x (A %d)\n",crc,A);
|
||||
//printf("a0 %d a1 %d \n", a[A>>3], a[1+(A>>3)]);
|
||||
|
||||
B = A + 16;
|
||||
|
||||
AssertFatal((A/8)+3 <= max_payload_bytes,"A %d is too big (A/8+3 = %d > %d)\n",A,(A/8)+3,max_payload_bytes);
|
||||
|
||||
memcpy(harq_process->b,harq_process->a,(A/8)+3); // using 3 bytes to mimic the case of 24 bit crc
|
||||
}
|
||||
///////////
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
|
||||
///////////////////////// b---->| block segmentation |---->c /////////////////////////
|
||||
///////////
|
||||
|
||||
if ((A <= 292) || ((A <= NR_MAX_PDSCH_TBS) && (Coderate <= 0.6667)) || Coderate <= 0.25) {
|
||||
harq_process->BG = 2;
|
||||
} else {
|
||||
@@ -130,189 +113,125 @@ int nr_ulsch_encoding(PHY_VARS_NR_UE *ue,
|
||||
|
||||
VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_NR_SEGMENTATION, VCD_FUNCTION_IN);
|
||||
start_meas(&ue->ulsch_segmentation_stats);
|
||||
uint32_t Kb = nr_segmentation(harq_process->b,
|
||||
harq_process->c,
|
||||
B,
|
||||
&harq_process->C,
|
||||
&harq_process->K,
|
||||
&harq_process->Z,
|
||||
&harq_process->F,
|
||||
harq_process->BG);
|
||||
|
||||
if (harq_process->C>MAX_NUM_NR_DLSCH_SEGMENTS_PER_LAYER*ulsch->pusch_pdu.nrOfLayers) {
|
||||
LOG_E(PHY, "nr_segmentation.c: too many segments %d, B %d\n", harq_process->C, B);
|
||||
impp.Kb = nr_segmentation(harq_process->b,
|
||||
harq_process->c,
|
||||
B,
|
||||
&harq_process->C,
|
||||
&harq_process->K,
|
||||
&harq_process->Z,
|
||||
&harq_process->F,
|
||||
harq_process->BG);
|
||||
impp.n_segments = harq_process->C;
|
||||
impp.K = harq_process->K;
|
||||
impp.Kr = impp.K;
|
||||
impp.Zc = harq_process->Z;
|
||||
impp.F = harq_process->F;
|
||||
impp.BG = harq_process->BG;
|
||||
if (impp.n_segments > MAX_NUM_NR_DLSCH_SEGMENTS_PER_LAYER*ulsch->pusch_pdu.nrOfLayers) {
|
||||
LOG_E(PHY, "nr_segmentation.c: too many segments %d, B %d\n", impp.n_segments, B);
|
||||
return(-1);
|
||||
}
|
||||
stop_meas(&ue->ulsch_segmentation_stats);
|
||||
VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_NR_SEGMENTATION, VCD_FUNCTION_OUT);
|
||||
|
||||
F = harq_process->F;
|
||||
Kr = harq_process->K;
|
||||
#ifdef DEBUG_ULSCH_CODING
|
||||
uint16_t Kr_bytes;
|
||||
Kr_bytes = Kr>>3;
|
||||
Kr_bytes = impp.Kr>>3;
|
||||
#endif
|
||||
|
||||
///////////////////////// c---->| LDCP coding |---->d /////////////////////////
|
||||
///////////
|
||||
|
||||
// printf("segment Z %d k %d Kr %d BG %d\n", harq_process->Z,harq_process->K,Kr,BG);
|
||||
|
||||
//start_meas(te_stats);
|
||||
for (int r=0; r<harq_process->C; r++) {
|
||||
//channel_input[r] = &harq_process->d[r][0];
|
||||
///////////////////////// c---->| LDCP coding |---->d ////////////////////////////////////
|
||||
for (int r = 0; r < impp.n_segments; r++) {
|
||||
#ifdef DEBUG_ULSCH_CODING
|
||||
printf("Encoder: B %d F %d \n", B, harq_process->F);
|
||||
printf("start ldpc encoder segment %d/%d\n",r,harq_process->C);
|
||||
printf("Encoder: B %d F %d \n", B, impp.F);
|
||||
printf("start ldpc encoder segment %d/%d\n", r, impp.n_segments);
|
||||
printf("input %d %d %d %d %d \n", harq_process->c[r][0], harq_process->c[r][1], harq_process->c[r][2],harq_process->c[r][3], harq_process->c[r][4]);
|
||||
for (int cnt = 0; cnt < 22 * harq_process->Z / 8; cnt++) {
|
||||
for (int cnt = 0; cnt < 22 * impp.Zc / 8; cnt++) {
|
||||
printf("%d ", harq_process->c[r][cnt]);
|
||||
}
|
||||
printf("\n");
|
||||
|
||||
#endif
|
||||
//ldpc_encoder_orig((unsigned char*)harq_process->c[r],harq_process->d[r],Kr,BG,0);
|
||||
//ldpc_encoder_optim((unsigned char*)harq_process->c[r],(unsigned char*)&harq_process->d[r][0],Kr,BG,NULL,NULL,NULL,NULL);
|
||||
}
|
||||
|
||||
//for (int i=0;i<68*384;i++)
|
||||
// printf("channel_input[%d]=%d\n",i,channel_input[i]);
|
||||
|
||||
/*printf("output %d %d %d %d %d \n", harq_process->d[0][0], harq_process->d[0][1], harq_process->d[r][2],harq_process->d[0][3],
|
||||
harq_process->d[0][4]); for (int cnt =0 ; cnt < 66*harq_process->Z; cnt ++){ printf("%d \n", harq_process->d[0][cnt]);
|
||||
}
|
||||
printf("\n");*/
|
||||
encoder_implemparams_t impp = {.n_segments = harq_process->C,
|
||||
.macro_num = 0,
|
||||
.K = harq_process->K,
|
||||
.Kb = Kb,
|
||||
.Zc = harq_process->Z,
|
||||
.BG = harq_process->BG,
|
||||
.tinput = NULL,
|
||||
.tprep = NULL,
|
||||
.tparity = NULL,
|
||||
.toutput = NULL};
|
||||
|
||||
VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_LDPC_ENCODER_OPTIM, VCD_FUNCTION_IN);
|
||||
|
||||
start_meas(&ue->ulsch_ldpc_encoding_stats);
|
||||
if (ldpc_interface_offload.LDPCencoder)
|
||||
for (int j = 0; j < harq_process->C; j++) {
|
||||
}
|
||||
start_meas(&ue->ulsch_ldpc_encoding_stats);
|
||||
if (0) {
|
||||
for (int j = 0; j < impp.n_segments; j++) {
|
||||
impp.E = nr_get_E(G, impp.n_segments, impp.Qm, ulsch->pusch_pdu.nrOfLayers, j);
|
||||
uint8_t *f = harq_process->f + r_offset;
|
||||
ldpc_interface_offload.LDPCencoder(&harq_process->c[j], &f, &impp);
|
||||
r_offset += impp.E;
|
||||
}
|
||||
} else {
|
||||
if (ulsch->pusch_pdu.pusch_data.new_data_indicator) {
|
||||
for (int j = 0; j < (impp.n_segments / 8 + 1); j++) {
|
||||
impp.macro_num = j;
|
||||
impp.E = nr_get_E(G, harq_process->C, mod_order, ulsch->pusch_pdu.nrOfLayers, j);
|
||||
impp.Kr = Kr;
|
||||
ldpc_interface_offload.LDPCencoder(&harq_process->c[j], &harq_process->d[j], &impp);
|
||||
}
|
||||
else
|
||||
for (int j = 0; j < (harq_process->C / 8 + 1); j++) {
|
||||
impp.macro_num = j;
|
||||
impp.E = nr_get_E(G, harq_process->C, mod_order, ulsch->pusch_pdu.nrOfLayers, j);
|
||||
impp.Kr = Kr;
|
||||
impp.E = nr_get_E(G, impp.n_segments, impp.Qm, ulsch->pusch_pdu.nrOfLayers, j);
|
||||
impp.Kr = impp.K;
|
||||
ldpc_interface.LDPCencoder(harq_process->c, harq_process->d, &impp);
|
||||
}
|
||||
VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_LDPC_ENCODER_OPTIM, VCD_FUNCTION_OUT);
|
||||
VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_LDPC_ENCODER_OPTIM, VCD_FUNCTION_OUT);
|
||||
|
||||
//stop_meas(te_stats);
|
||||
//printf("end ldpc encoder -- output\n");
|
||||
#ifdef DEBUG_ULSCH_CODING
|
||||
write_output("ulsch_enc_input0.m","enc_in0",&harq_process->c[0][0],Kr_bytes,1,4);
|
||||
write_output("ulsch_enc_output0.m","enc0",&harq_process->d[0][0],(3*8*Kr_bytes)+12,1,4);
|
||||
write_output("ulsch_enc_input0.m","enc_in0",&harq_process->c[0][0],Kr_bytes,1,4);
|
||||
write_output("ulsch_enc_output0.m","enc0",&harq_process->d[0][0],(3*8*Kr_bytes)+12,1,4);
|
||||
#endif
|
||||
|
||||
///////////
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
}
|
||||
F = harq_process->F;
|
||||
Kr = harq_process->K;
|
||||
|
||||
for (int r=0; r<harq_process->C; r++) { // looping over C segments
|
||||
if (harq_process->F>0) {
|
||||
for (int k = Kr - F - 2 * harq_process->Z; k < Kr - 2 * harq_process->Z; k++) {
|
||||
harq_process->d[r][k] = NR_NULL;
|
||||
//if (k<(Kr-F+8))
|
||||
//printf("r %d filler bits [%d] = %d \n", r,k, harq_process->d[r][k]);
|
||||
}
|
||||
}
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
for (int r = 0; r < impp.n_segments; r++) { // looping over C segments
|
||||
if (impp.F > 0) {
|
||||
for (int k = impp.Kr - impp.F - 2 * impp.Zc; k < impp.Kr - 2 * impp.Zc; k++) {
|
||||
harq_process->d[r][k] = NR_NULL;
|
||||
}
|
||||
}
|
||||
|
||||
LOG_D(PHY,"Rate Matching, Code segment %d (coded bits (G) %u, unpunctured/repeated bits per code segment %d, mod_order %d, nb_rb %d, rvidx %d)...\n", r, G, impp.Kr*3, impp.Qm, nb_rb, ulsch->pusch_pdu.pusch_data.rv_index);
|
||||
|
||||
LOG_D(PHY,"Rate Matching, Code segment %d (coded bits (G) %u, unpunctured/repeated bits per code segment %d, mod_order %d, nb_rb %d, rvidx %d)...\n",
|
||||
r,
|
||||
G,
|
||||
Kr*3,
|
||||
mod_order,nb_rb,
|
||||
ulsch->pusch_pdu.pusch_data.rv_index);
|
||||
|
||||
//start_meas(rm_stats);
|
||||
///////////////////////// d---->| Rate matching bit selection |---->e /////////////////////////
|
||||
///////////
|
||||
|
||||
uint32_t E = nr_get_E(G, harq_process->C, mod_order, ulsch->pusch_pdu.nrOfLayers, r);
|
||||
|
||||
VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_NR_RATE_MATCHING_LDPC, VCD_FUNCTION_IN);
|
||||
start_meas(&ue->ulsch_rate_matching_stats);
|
||||
if (nr_rate_matching_ldpc(ulsch->pusch_pdu.tbslbrm,
|
||||
harq_process->BG,
|
||||
harq_process->Z,
|
||||
harq_process->d[r],
|
||||
harq_process->e + r_offset,
|
||||
harq_process->C,
|
||||
F,
|
||||
Kr - F - 2 * harq_process->Z,
|
||||
ulsch->pusch_pdu.pusch_data.rv_index,
|
||||
E)
|
||||
== -1)
|
||||
return -1;
|
||||
|
||||
stop_meas(&ue->ulsch_rate_matching_stats);
|
||||
VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_NR_RATE_MATCHING_LDPC, VCD_FUNCTION_OUT);
|
||||
impp.E = nr_get_E(G, impp.n_segments, impp.Qm, ulsch->pusch_pdu.nrOfLayers, r);
|
||||
|
||||
VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_NR_RATE_MATCHING_LDPC, VCD_FUNCTION_IN);
|
||||
start_meas(&ue->ulsch_rate_matching_stats);
|
||||
if (nr_rate_matching_ldpc(ulsch->pusch_pdu.tbslbrm,
|
||||
impp.BG,
|
||||
impp.Zc,
|
||||
harq_process->d[r],
|
||||
harq_process->e + r_offset,
|
||||
impp.n_segments,
|
||||
impp.F,
|
||||
impp.Kr - impp.F - 2 * impp.Zc,
|
||||
impp.rv,
|
||||
impp.E) == -1)
|
||||
return -1;
|
||||
|
||||
stop_meas(&ue->ulsch_rate_matching_stats);
|
||||
VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_NR_RATE_MATCHING_LDPC, VCD_FUNCTION_OUT);
|
||||
|
||||
#ifdef DEBUG_ULSCH_CODING
|
||||
for (int i =0; i<16; i++)
|
||||
printf("output ratematching e[%d]= %d r_offset %u\n", i,harq_process->e[i+r_offset], r_offset);
|
||||
for (int i =0; i<16; i++)
|
||||
printf("output ratematching e[%d]= %d r_offset %u\n", i,harq_process->e[i + r_offset], r_offset);
|
||||
#endif
|
||||
|
||||
///////////
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
||||
///////////////////////// e---->| Rate matching bit interleaving |---->f /////////////////////////
|
||||
///////////
|
||||
|
||||
//stop_meas(rm_stats);
|
||||
|
||||
//start_meas(i_stats);
|
||||
VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_NR_INTERLEAVING_LDPC, VCD_FUNCTION_IN);
|
||||
VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_NR_INTERLEAVING_LDPC, VCD_FUNCTION_IN);
|
||||
start_meas(&ue->ulsch_interleaving_stats);
|
||||
nr_interleaving_ldpc(impp.E,
|
||||
impp.Qm,
|
||||
harq_process->e + r_offset,
|
||||
harq_process->f + r_offset);
|
||||
stop_meas(&ue->ulsch_interleaving_stats);
|
||||
|
||||
start_meas(&ue->ulsch_interleaving_stats);
|
||||
nr_interleaving_ldpc(E,
|
||||
mod_order,
|
||||
harq_process->e+r_offset,
|
||||
harq_process->f+r_offset);
|
||||
stop_meas(&ue->ulsch_interleaving_stats);
|
||||
|
||||
VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_NR_INTERLEAVING_LDPC, VCD_FUNCTION_OUT);
|
||||
//stop_meas(i_stats);
|
||||
|
||||
|
||||
VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_NR_INTERLEAVING_LDPC, VCD_FUNCTION_OUT);
|
||||
#ifdef DEBUG_ULSCH_CODING
|
||||
for (int i =0; i<16; i++)
|
||||
printf("output interleaving f[%d]= %d r_offset %u\n", i,harq_process->f[i+r_offset], r_offset);
|
||||
|
||||
if (r==harq_process->C-1)
|
||||
write_output("enc_output.m","enc",harq_process->f,G,1,4);
|
||||
for (int i = 0; i < 16; i++)
|
||||
printf("output interleaving f[%d]= %d r_offset %u\n", i, harq_process->f[i+r_offset], r_offset);
|
||||
if (r == impp.n_segments - 1)
|
||||
write_output("enc_output.m","enc", harq_process->f, G, 1, 4);
|
||||
#endif
|
||||
|
||||
r_offset += E;
|
||||
|
||||
///////////
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
r_offset += impp.E;
|
||||
}
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////
|
||||
VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_NR_UE_ULSCH_ENCODING, VCD_FUNCTION_OUT);
|
||||
|
||||
stop_meas(&ue->ulsch_encoding_stats);
|
||||
return(0);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user