mirror of https://github.com/PentHertz/srsLTE.git
Fixed a bug with type 2 distributed resource allocation
This commit is contained in:
parent
68a6169164
commit
8531fb1a0c
|
@ -41,6 +41,12 @@
|
|||
#include "liblte/cuhd/cuhd.h"
|
||||
#include "cell_search_utils.h"
|
||||
|
||||
cell_detect_cfg_t cell_detect_config = {
|
||||
500, // nof_frames_total
|
||||
50, // nof_frames_detected
|
||||
CS_FIND_THRESHOLD // threshold
|
||||
};
|
||||
|
||||
/**********************************************************************
|
||||
* Program arguments processing
|
||||
***********************************************************************/
|
||||
|
@ -157,7 +163,7 @@ int main(int argc, char **argv) {
|
|||
cuhd_rx_wait_lo_locked(uhd);
|
||||
printf("Tunning receiver to %.3f MHz\n", (double ) prog_args.uhd_freq/1000000);
|
||||
|
||||
if (cell_search(uhd, prog_args.force_N_id_2, &cell)) {
|
||||
if (detect_and_decode_cell(&cell_detect_config, uhd, prog_args.force_N_id_2, &cell)) {
|
||||
fprintf(stderr, "Cell not found\n");
|
||||
exit(-1);
|
||||
}
|
||||
|
@ -191,7 +197,7 @@ int main(int argc, char **argv) {
|
|||
}
|
||||
|
||||
int sf_re = SF_LEN_RE(cell.nof_prb, cell.cp);
|
||||
printf("%d RE allocated\n", sf_re);
|
||||
|
||||
cf_t *sf_symbols = vec_malloc(sf_re * sizeof(cf_t));
|
||||
|
||||
/* Main loop */
|
||||
|
@ -201,14 +207,17 @@ int main(int argc, char **argv) {
|
|||
if (ret < 0) {
|
||||
fprintf(stderr, "Error calling ue_sync_work()\n");
|
||||
}
|
||||
|
||||
|
||||
/* iodev_receive returns 1 if successfully read 1 aligned subframe */
|
||||
/* ue_sync_get_buffer returns 1 if successfully read 1 aligned subframe */
|
||||
if (ret == 1) {
|
||||
switch (state) {
|
||||
case DECODE_MIB:
|
||||
if (ue_sync_get_sfidx(&ue_sync) == 0) {
|
||||
pbch_decode_reset(&ue_mib.pbch);
|
||||
n = ue_mib_decode_aligned_frame(&ue_mib, &sf_buffer[ue_sync_sf_len(&ue_sync)/2], bch_payload_unpacked, NULL, &sfn_offset);
|
||||
n = ue_mib_decode_aligned_frame(&ue_mib,
|
||||
sf_buffer, bch_payload_unpacked,
|
||||
NULL, &sfn_offset);
|
||||
if (n < 0) {
|
||||
fprintf(stderr, "Error decoding UE MIB\n");
|
||||
exit(-1);
|
||||
|
@ -223,20 +232,17 @@ int main(int argc, char **argv) {
|
|||
break;
|
||||
case DECODE_SIB:
|
||||
sfn=0;
|
||||
/* If we are looking for SI Blocks, search only in appropiate places */
|
||||
if ((sfn % 2) == 0 && (ue_sync_get_sfidx(&ue_sync) == 5)) {
|
||||
/* We are looking for SI Blocks, search only in appropiate places */
|
||||
if ((ue_sync_get_sfidx(&ue_sync) == 5 && (sfn%2)==0)) {
|
||||
n = ue_dl_decode(&ue_dl, sf_buffer, data, ue_sync_get_sfidx(&ue_sync), sfn, SIRNTI);
|
||||
if (n < 0) {
|
||||
fprintf(stderr, "Error decoding UE DL\n");fflush(stdout);
|
||||
exit(-1);
|
||||
} else if (n == 0) {
|
||||
// Printf
|
||||
// if (!(sf_cnt%20)) {
|
||||
printf("CFO: %+6.4f KHz, SFO: %+6.4f Khz, ExecTime: %5.1f us, NOI: %.2f, Nof Trials: %4d, Nof Error: %4d\r",
|
||||
printf("CFO: %+6.4f KHz, SFO: %+6.4f Khz, ExecTime: %5.1f us, NOI: %.2f, PDCCH-Det: %.3f\r",
|
||||
ue_sync_get_cfo(&ue_sync)/1000, ue_sync_get_sfo(&ue_sync)/1000,
|
||||
mean_exec_time, pdsch_average_noi(&ue_dl.pdsch),
|
||||
(int) nof_trials, (int) ue_dl.pkt_errors);
|
||||
// }
|
||||
(float) ue_dl.nof_pdcch_detected/nof_trials);
|
||||
nof_trials++;
|
||||
} else {
|
||||
printf("\n\nDecoded SIB1 Message Len %d: ",n);
|
||||
|
|
|
@ -54,9 +54,8 @@
|
|||
|
||||
int band = -1;
|
||||
int earfcn_start=-1, earfcn_end = -1;
|
||||
int nof_frames_total = 50;
|
||||
int nof_frames_detected = 10;
|
||||
float threshold = CS_FIND_THRESHOLD;
|
||||
|
||||
cell_detect_cfg_t config = {50, 10, CS_FIND_THRESHOLD};
|
||||
|
||||
|
||||
float uhd_gain = 60.0;
|
||||
|
@ -70,7 +69,7 @@ void usage(char *prog) {
|
|||
printf("\t-e earfcn_end [Default All]\n");
|
||||
printf("\t-n nof_frames_total [Default 100]\n");
|
||||
printf("\t-d nof_frames_detected [Default 10]\n");
|
||||
printf("\t-t threshold [Default %.2f]\n",threshold);
|
||||
printf("\t-t threshold [Default %.2f]\n",config.threshold);
|
||||
printf("\t-v [set verbose to debug, default none]\n");
|
||||
}
|
||||
|
||||
|
@ -91,13 +90,13 @@ void parse_args(int argc, char **argv) {
|
|||
earfcn_end = atoi(argv[optind]);
|
||||
break;
|
||||
case 'n':
|
||||
nof_frames_total = atoi(argv[optind]);
|
||||
config.nof_frames_total = atoi(argv[optind]);
|
||||
break;
|
||||
case 'd':
|
||||
nof_frames_detected = atoi(argv[optind]);
|
||||
config.nof_frames_detected = atoi(argv[optind]);
|
||||
break;
|
||||
case 't':
|
||||
threshold = atof(argv[optind]);
|
||||
config.threshold = atof(argv[optind]);
|
||||
break;
|
||||
case 'g':
|
||||
uhd_gain = atof(argv[optind]);
|
||||
|
@ -119,7 +118,6 @@ void parse_args(int argc, char **argv) {
|
|||
int main(int argc, char **argv) {
|
||||
int n;
|
||||
void *uhd;
|
||||
ue_celldetect_t s;
|
||||
ue_celldetect_result_t found_cells[3];
|
||||
int nof_freqs;
|
||||
lte_earfcn_t channels[MAX_EARFCN];
|
||||
|
@ -142,21 +140,6 @@ int main(int argc, char **argv) {
|
|||
exit(-1);
|
||||
}
|
||||
|
||||
if (ue_celldetect_init(&s)) {
|
||||
fprintf(stderr, "Error initiating UE sync module\n");
|
||||
exit(-1);
|
||||
}
|
||||
if (threshold > 0) {
|
||||
ue_celldetect_set_threshold(&s, threshold);
|
||||
}
|
||||
|
||||
if (nof_frames_total > 0) {
|
||||
ue_celldetect_set_nof_frames_total(&s, nof_frames_total);
|
||||
}
|
||||
if (nof_frames_detected > 0) {
|
||||
ue_celldetect_set_nof_frames_detected(&s, nof_frames_detected);
|
||||
}
|
||||
|
||||
for (freq=0;freq<nof_freqs;freq+=10) {
|
||||
|
||||
/* set uhd_freq */
|
||||
|
@ -172,15 +155,15 @@ int main(int argc, char **argv) {
|
|||
printf("\n");
|
||||
}
|
||||
|
||||
n = find_all_cells(uhd, found_cells);
|
||||
n = detect_all_cells(&config, uhd, found_cells);
|
||||
if (n < 0) {
|
||||
fprintf(stderr, "Error searching cell\n");
|
||||
exit(-1);
|
||||
}
|
||||
if (n == CS_CELL_DETECTED) {
|
||||
for (int i=0;i<3;i++) {
|
||||
if (found_cells[i].peak > threshold/2) {
|
||||
if (decode_pbch(uhd, &found_cells[i], nof_frames_total, bch_payload, &nof_tx_ports, NULL)) {
|
||||
if (found_cells[i].peak > config.threshold/2) {
|
||||
if (decode_pbch(uhd, &found_cells[i], config.nof_frames_total, bch_payload, &nof_tx_ports, NULL)) {
|
||||
fprintf(stderr, "Error decoding PBCH\n");
|
||||
exit(-1);
|
||||
} else {
|
||||
|
@ -194,7 +177,6 @@ int main(int argc, char **argv) {
|
|||
|
||||
printf("\nBye\n");
|
||||
|
||||
ue_celldetect_free(&s);
|
||||
cuhd_close(uhd);
|
||||
exit(0);
|
||||
}
|
||||
|
|
|
@ -37,6 +37,8 @@
|
|||
|
||||
#include "liblte/phy/phy.h"
|
||||
#include "liblte/rrc/rrc.h"
|
||||
#include "cell_search_utils.h"
|
||||
|
||||
|
||||
#ifndef DISABLE_UHD
|
||||
#include "liblte/cuhd/cuhd.h"
|
||||
|
@ -82,6 +84,7 @@ int decode_pbch(void *uhd, ue_celldetect_result_t *found_cell, uint32_t nof_fram
|
|||
}
|
||||
if (n == MIB_FRAME_UNALIGNED) {
|
||||
printf("Realigning frame\n");
|
||||
// Receive some randon number of samples to try to resynchronise the frame.
|
||||
if (cuhd_recv(uhd, buffer, 1500, 1)<0) {
|
||||
fprintf(stderr, "Error receiving from USRP\n");
|
||||
goto free_and_exit;
|
||||
|
@ -110,7 +113,7 @@ free_and_exit:
|
|||
return ret;
|
||||
}
|
||||
|
||||
int find_cell(void *uhd, ue_celldetect_result_t *found_cell, uint32_t N_id_2)
|
||||
int detect_cell(cell_detect_cfg_t *config, void *uhd, ue_celldetect_result_t *found_cell, uint32_t N_id_2)
|
||||
{
|
||||
int ret = LIBLTE_ERROR;
|
||||
ue_celldetect_t cd;
|
||||
|
@ -125,6 +128,16 @@ int find_cell(void *uhd, ue_celldetect_result_t *found_cell, uint32_t N_id_2)
|
|||
fprintf(stderr, "Error initiating UE cell detect\n");
|
||||
goto free_and_exit;
|
||||
}
|
||||
|
||||
if (config->nof_frames_detected) {
|
||||
ue_celldetect_set_nof_frames_detected(&cd, config->nof_frames_detected);
|
||||
}
|
||||
if (config->nof_frames_total) {
|
||||
ue_celldetect_set_nof_frames_total(&cd, config->nof_frames_total);
|
||||
}
|
||||
if (config->threshold) {
|
||||
ue_celldetect_set_threshold(&cd, config->threshold);
|
||||
}
|
||||
|
||||
INFO("Setting sampling frequency 960 KHz for PSS search\n", 0);
|
||||
cuhd_set_rx_srate(uhd, 960000.0);
|
||||
|
@ -192,7 +205,7 @@ free_and_exit:
|
|||
}
|
||||
|
||||
|
||||
int find_all_cells(void *uhd, ue_celldetect_result_t found_cell[3])
|
||||
int detect_all_cells(cell_detect_cfg_t *config, void *uhd, ue_celldetect_result_t found_cell[3])
|
||||
{
|
||||
|
||||
uint32_t N_id_2;
|
||||
|
@ -200,7 +213,7 @@ int find_all_cells(void *uhd, ue_celldetect_result_t found_cell[3])
|
|||
int nof_detected_cells = 0;
|
||||
|
||||
for (N_id_2=0;N_id_2<3;N_id_2++) {
|
||||
ret = find_cell(uhd, &found_cell[N_id_2], N_id_2);
|
||||
ret = detect_cell(config, uhd, &found_cell[N_id_2], N_id_2);
|
||||
if (ret == 1) {
|
||||
nof_detected_cells++;
|
||||
} else if (ret == LIBLTE_ERROR) {
|
||||
|
@ -210,7 +223,7 @@ int find_all_cells(void *uhd, ue_celldetect_result_t found_cell[3])
|
|||
return nof_detected_cells;
|
||||
}
|
||||
|
||||
int cell_search(void *uhd, int force_N_id_2, lte_cell_t *cell)
|
||||
int detect_and_decode_cell(cell_detect_cfg_t *config, void *uhd, int force_N_id_2, lte_cell_t *cell)
|
||||
{
|
||||
int ret;
|
||||
uint32_t nof_tx_ports;
|
||||
|
@ -219,14 +232,10 @@ int cell_search(void *uhd, int force_N_id_2, lte_cell_t *cell)
|
|||
ue_celldetect_result_t found_cells[3];
|
||||
bzero(found_cells, 3*sizeof(ue_celldetect_result_t));
|
||||
|
||||
ue_celldetect_set_nof_frames_detected(&cd, 50);
|
||||
|
||||
ue_celldetect_set_nof_frames_total(&cd, 500);
|
||||
|
||||
if (force_N_id_2 >= 0) {
|
||||
ret = find_cell(uhd, &found_cells[force_N_id_2], force_N_id_2);
|
||||
ret = detect_cell(config, uhd, &found_cells[force_N_id_2], force_N_id_2);
|
||||
} else {
|
||||
ret = find_all_cells(uhd, found_cells);
|
||||
ret = detect_all_cells(config, uhd, found_cells);
|
||||
}
|
||||
if (ret < 0) {
|
||||
fprintf(stderr, "Error searching cell\n");
|
||||
|
|
|
@ -28,6 +28,12 @@
|
|||
|
||||
#include "liblte/phy/phy.h"
|
||||
|
||||
typedef struct LIBLTE_API {
|
||||
uint32_t nof_frames_total;
|
||||
uint32_t nof_frames_detected;
|
||||
float threshold;
|
||||
}cell_detect_cfg_t;
|
||||
|
||||
int decode_pbch(void *uhd,
|
||||
ue_celldetect_result_t *found_cell,
|
||||
uint32_t nof_frames_total,
|
||||
|
@ -35,13 +41,16 @@ int decode_pbch(void *uhd,
|
|||
uint32_t *nof_tx_ports,
|
||||
uint32_t *sfn_offset);
|
||||
|
||||
int find_all_cells(void *uhd,
|
||||
ue_celldetect_result_t found_cell[3]);
|
||||
int detect_all_cells(cell_detect_cfg_t *config,
|
||||
void *uhd,
|
||||
ue_celldetect_result_t found_cell[3]);
|
||||
|
||||
int find_cell(void *uhd,
|
||||
ue_celldetect_result_t *found_cell,
|
||||
uint32_t N_id_2);
|
||||
int detect_cell(cell_detect_cfg_t *config,
|
||||
void *uhd,
|
||||
ue_celldetect_result_t *found_cell,
|
||||
uint32_t N_id_2);
|
||||
|
||||
int cell_search(void *uhd,
|
||||
int force_N_id_2,
|
||||
lte_cell_t *cell);
|
||||
int detect_and_decode_cell(cell_detect_cfg_t *config,
|
||||
void *uhd,
|
||||
int force_N_id_2,
|
||||
lte_cell_t *cell);
|
|
@ -98,8 +98,11 @@ int iodev_init(iodev_t *q, iodev_cfg_t *config, lte_cell_t *cell) {
|
|||
cuhd_set_rx_freq(q->uhd, (double) config->uhd_freq);
|
||||
cuhd_rx_wait_lo_locked(q->uhd);
|
||||
DEBUG("Set uhd_freq to %.3f MHz\n", (double ) config->uhd_freq);
|
||||
|
||||
cell_detect_cfg_t detect_config;
|
||||
bzero(&detect_config, sizeof(cell_detect_cfg_t));
|
||||
|
||||
if (cell_search(q->uhd, config->force_N_id_2, cell)) {
|
||||
if (detect_and_decode_cell(&detect_config, q->uhd, config->force_N_id_2, cell)) {
|
||||
fprintf(stderr, "Cell not found\n");
|
||||
return LIBLTE_ERROR;
|
||||
}
|
||||
|
|
|
@ -46,7 +46,7 @@ typedef _Complex float cf_t;
|
|||
#define DCI_MAX_BITS 57
|
||||
|
||||
typedef enum {
|
||||
Format0, Format1, Format1A, Format1C
|
||||
Format0, Format1, Format1A, Format1C, FormatError
|
||||
} dci_format_t;
|
||||
|
||||
// Each type is for a different interface to packing/unpacking functions
|
||||
|
@ -89,6 +89,8 @@ LIBLTE_API int dci_msg_to_ra_ul(dci_msg_t *msg,
|
|||
uint32_t cfi,
|
||||
ra_pusch_t *ra_ul);
|
||||
*/
|
||||
LIBLTE_API dci_format_t dci_format_from_string(char *str);
|
||||
|
||||
LIBLTE_API char* dci_format_string(dci_format_t format);
|
||||
|
||||
LIBLTE_API int dci_location_set(dci_location_t *c,
|
||||
|
|
|
@ -53,7 +53,6 @@ typedef enum LIBLTE_API {
|
|||
/* PDCCH object */
|
||||
typedef struct LIBLTE_API {
|
||||
lte_cell_t cell;
|
||||
uint32_t e_bits;
|
||||
uint32_t nof_regs;
|
||||
uint32_t nof_cce;
|
||||
uint32_t max_bits;
|
||||
|
@ -99,13 +98,13 @@ LIBLTE_API int pdcch_extract_llr(pdcch_t *q,
|
|||
cf_t *sf_symbols,
|
||||
cf_t *ce[MAX_PORTS],
|
||||
float noise_estimate,
|
||||
dci_location_t location,
|
||||
uint32_t nsubframe,
|
||||
uint32_t cfi);
|
||||
|
||||
/* Decoding functions: Try to decode a DCI message after calling pdcch_extract_llr */
|
||||
LIBLTE_API int pdcch_decode_msg(pdcch_t *q,
|
||||
dci_msg_t *msg,
|
||||
dci_location_t *location,
|
||||
dci_format_t format,
|
||||
uint16_t *crc_rem);
|
||||
|
||||
|
|
|
@ -39,7 +39,7 @@
|
|||
|
||||
typedef struct LIBLTE_API {
|
||||
lte_mod_t mod;
|
||||
uint32_t tbs;
|
||||
int tbs;
|
||||
} ra_mcs_t;
|
||||
|
||||
typedef enum LIBLTE_API {
|
||||
|
@ -72,7 +72,7 @@ typedef struct LIBLTE_API {
|
|||
} ra_type2_t;
|
||||
|
||||
typedef struct LIBLTE_API {
|
||||
uint32_t prb_idx[MAX_PRB];
|
||||
bool prb_idx[MAX_PRB];
|
||||
uint32_t nof_prb;
|
||||
} ra_prb_slot_t;
|
||||
|
||||
|
@ -123,7 +123,8 @@ typedef struct LIBLTE_API {
|
|||
} ra_pusch_t;
|
||||
|
||||
LIBLTE_API void ra_prb_fprint(FILE *f,
|
||||
ra_prb_slot_t *prb);
|
||||
ra_prb_slot_t *prb,
|
||||
uint32_t nof_prb);
|
||||
|
||||
LIBLTE_API int ra_prb_get_dl(ra_prb_t *prb,
|
||||
ra_pdsch_t *ra,
|
||||
|
|
|
@ -73,6 +73,7 @@ typedef struct LIBLTE_API {
|
|||
|
||||
uint64_t pkt_errors;
|
||||
uint64_t pkts_total;
|
||||
uint64_t nof_pdcch_detected;
|
||||
|
||||
uint16_t user_rnti;
|
||||
}ue_dl_t;
|
||||
|
|
|
@ -210,10 +210,7 @@ int refsignal_cs_put_sf(lte_cell_t cell, uint32_t port_id, cf_t *pilots, cf_t *s
|
|||
fidx = ((refsignal_cs_v(port_id, l) + (cell.id % 6)) % 6);
|
||||
for (i = 0; i < 2*cell.nof_prb; i++) {
|
||||
sf_symbols[SAMPLE_IDX(cell.nof_prb, nsymbol, fidx)] = pilots[REFSIGNAL_PILOT_IDX(i,l,cell)];
|
||||
fidx += 6; // 1 reference every 6 RE
|
||||
DEBUG("Putting %d to %d (fidx: %d, lp:%d)\n",
|
||||
REFSIGNAL_PILOT_IDX(i,l,cell), SAMPLE_IDX(cell.nof_prb, nsymbol, fidx),
|
||||
fidx, nsymbol);
|
||||
fidx += 6; // 1 reference every 6 RE
|
||||
}
|
||||
}
|
||||
return LIBLTE_SUCCESS;
|
||||
|
@ -242,9 +239,6 @@ int refsignal_cs_get_sf(lte_cell_t cell, uint32_t port_id, cf_t *sf_symbols, cf_
|
|||
fidx = ((refsignal_cs_v(port_id, l) + (cell.id % 6)) % 6);
|
||||
for (i = 0; i < 2*cell.nof_prb; i++) {
|
||||
pilots[REFSIGNAL_PILOT_IDX(i,l,cell)] = sf_symbols[SAMPLE_IDX(cell.nof_prb, nsymbol, fidx)];
|
||||
DEBUG("Getting %d from %d (fidx: %d, lp:%d)\n",REFSIGNAL_PILOT_IDX(i,l,cell),
|
||||
SAMPLE_IDX(cell.nof_prb, nsymbol, fidx),
|
||||
fidx, nsymbol);
|
||||
fidx += RE_X_RB/2; // 2 references per PRB
|
||||
}
|
||||
}
|
||||
|
|
|
@ -98,7 +98,7 @@ int rm_conv_rx(float *input, uint32_t in_len, float *output, uint32_t out_len) {
|
|||
int d_i, d_j;
|
||||
|
||||
float tmp[3 * NCOLS * NROWS_MAX];
|
||||
|
||||
|
||||
nrows = (uint32_t) (out_len / 3 - 1) / NCOLS + 1;
|
||||
if (nrows > NROWS_MAX) {
|
||||
fprintf(stderr, "Output too large. Max output length is %d\n",
|
||||
|
|
|
@ -171,7 +171,7 @@ int predecoding_diversity(precoding_t *q, cf_t *y, cf_t *h[MAX_PORTS], cf_t *x[M
|
|||
// (H'H + n0)
|
||||
vec_sc_add_fff(modhh, noise_estimate, modhh, nof_symbols/2);
|
||||
}
|
||||
vec_sc_prod_fff(modhh, 1.0/sqrt(2), modhh, nof_symbols/2);
|
||||
//vec_sc_prod_fff(modhh, 1.0/sqrt(2), modhh, nof_symbols/2);
|
||||
|
||||
// x[0] = r0·h0*/(|h0|+|h1|)+r1*·h1/(|h0|+|h1|)
|
||||
vec_prod_conj_ccc(r0,h0,q->tmp1, nof_symbols/2);
|
||||
|
|
|
@ -132,7 +132,7 @@ int main(int argc, char **argv) {
|
|||
/* generate random data */
|
||||
for (i = 0; i < nof_layers; i++) {
|
||||
for (j = 0; j < nof_symbols; j++) {
|
||||
x[i][j] = (float) rand()/RAND_MAX+((float) rand()/RAND_MAX)*_Complex_I;
|
||||
x[i][j] = (2*(rand()%2)-1+(2*(rand()%2)-1)*_Complex_I)/sqrt(2);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -153,7 +153,7 @@ int main(int argc, char **argv) {
|
|||
h[i][nof_layers*j] = (float) rand()/RAND_MAX+((float) rand()/RAND_MAX)*_Complex_I;
|
||||
// assume the channel is time-invariant in nlayer consecutive symbols
|
||||
for (int k=0;k<nof_layers;k++) {
|
||||
h[i][nof_layers*j+k] = h[i][nof_layers*j];
|
||||
h[i][nof_layers*j+k] = h[i][nof_layers*j];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -170,34 +170,30 @@ int main(int argc, char **argv) {
|
|||
}
|
||||
}
|
||||
|
||||
float noise_estimate[2] = {0, 0.0000001};
|
||||
const char *algs[2] = {"ZF", "MMSE"};
|
||||
|
||||
/* predecoding / equalization */
|
||||
struct timeval t[3];
|
||||
for (int a=0;a<2;a++) {
|
||||
gettimeofday(&t[1], NULL);
|
||||
if (predecoding_type(&precoding, r[0], h, xr, nof_ports, nof_layers,
|
||||
nof_symbols * nof_layers, type, noise_estimate[a]) < 0) {
|
||||
fprintf(stderr, "Error layer mapper encoder\n");
|
||||
exit(-1);
|
||||
}
|
||||
gettimeofday(&t[2], NULL);
|
||||
get_time_interval(t);
|
||||
printf("Execution Time %s: %d us\n", algs[a], t[0].tv_usec);
|
||||
|
||||
/* check errors */
|
||||
mse = 0;
|
||||
for (i = 0; i < nof_layers; i++) {
|
||||
for (j = 0; j < nof_symbols; j++) {
|
||||
mse += cabsf(xr[i][j] - x[i][j]);
|
||||
}
|
||||
}
|
||||
printf("MSE %s: %f\n", algs[a], mse);
|
||||
if (mse / nof_layers / nof_symbols > MSE_THRESHOLD) {
|
||||
exit(-1);
|
||||
}
|
||||
gettimeofday(&t[1], NULL);
|
||||
if (predecoding_type(&precoding, r[0], h, xr, nof_ports, nof_layers,
|
||||
nof_symbols * nof_layers, type, 0) < 0) {
|
||||
fprintf(stderr, "Error layer mapper encoder\n");
|
||||
exit(-1);
|
||||
}
|
||||
gettimeofday(&t[2], NULL);
|
||||
get_time_interval(t);
|
||||
printf("Execution Time: %d us\n", t[0].tv_usec);
|
||||
|
||||
/* check errors */
|
||||
mse = 0;
|
||||
for (i = 0; i < nof_layers; i++) {
|
||||
for (j = 0; j < nof_symbols; j++) {
|
||||
printf("%f - %f\n", crealf(xr[i][j]), crealf(x[i][j]));
|
||||
mse += cabsf(xr[i][j] - x[i][j]);
|
||||
}
|
||||
}
|
||||
printf("MSE: %f\n", mse/ nof_layers / nof_symbols );
|
||||
if (mse / nof_layers / nof_symbols > MSE_THRESHOLD) {
|
||||
exit(-1);
|
||||
}
|
||||
|
||||
for (i = 0; i < nof_layers; i++) {
|
||||
free(x[i]);
|
||||
|
|
|
@ -61,7 +61,8 @@ int dci_msg_to_ra_dl(dci_msg_t *msg, uint16_t msg_rnti, uint16_t c_rnti,
|
|||
return ret;
|
||||
}
|
||||
|
||||
if (VERBOSE_ISDEBUG()) {
|
||||
if (VERBOSE_ISINFO()) {
|
||||
INFO("",0);
|
||||
dci_msg_type_fprint(stdout, type);
|
||||
}
|
||||
if (type.type == PDSCH_SCHED) {
|
||||
|
@ -72,7 +73,7 @@ int dci_msg_to_ra_dl(dci_msg_t *msg, uint16_t msg_rnti, uint16_t c_rnti,
|
|||
return ret;
|
||||
}
|
||||
|
||||
if (VERBOSE_ISDEBUG()) {
|
||||
if (VERBOSE_ISINFO()) {
|
||||
ra_pdsch_fprint(stdout, ra_dl, cell.nof_prb);
|
||||
}
|
||||
|
||||
|
@ -733,6 +734,20 @@ int dci_msg_unpack_pusch(dci_msg_t *msg, ra_pusch_t *data, uint32_t nof_prb) {
|
|||
return dci_format0_unpack(msg, data, nof_prb);
|
||||
}
|
||||
|
||||
dci_format_t dci_format_from_string(char *str) {
|
||||
if (!strcmp(str, "Format0")) {
|
||||
return Format0;
|
||||
} else if (!strcmp(str, "Format1")) {
|
||||
return Format1;
|
||||
} else if (!strcmp(str, "Format1A")) {
|
||||
return Format1A;
|
||||
} else if (!strcmp(str, "Format1C")) {
|
||||
return Format1C;
|
||||
} else {
|
||||
return FormatError;
|
||||
}
|
||||
}
|
||||
|
||||
char* dci_format_string(dci_format_t format) {
|
||||
switch (format) {
|
||||
case Format0:
|
||||
|
|
|
@ -49,14 +49,6 @@
|
|||
|
||||
#define MIN(a,b) ((a>b)?b:a)
|
||||
|
||||
|
||||
#define NOF_COMMON_FORMATS 2
|
||||
const dci_format_t common_formats[NOF_COMMON_FORMATS] = { Format1A, Format1C };
|
||||
|
||||
#define NOF_UE_FORMATS 2
|
||||
const dci_format_t ue_formats[NOF_UE_FORMATS] = { Format0, Format1 }; // 1A has the same payload as 0
|
||||
|
||||
|
||||
static void set_cfi(pdcch_t *q, uint32_t cfi) {
|
||||
if (cfi > 0 && cfi < 4) {
|
||||
q->nof_regs = (regs_pdcch_nregs(q->regs, cfi) / 9) * 9;
|
||||
|
@ -83,10 +75,11 @@ int pdcch_init(pdcch_t *q, regs_t *regs, lte_cell_t cell) {
|
|||
fprintf(stderr, "Error initializing precoding\n");
|
||||
}
|
||||
|
||||
/* Allocate memory for the largest aggregation level L=3 */
|
||||
q->max_bits = PDCCH_FORMAT_NOF_BITS(3);
|
||||
/* Allocate memory for the maximum number of PDCCH bits (CFI=3) */
|
||||
q->max_bits = (regs_pdcch_nregs(q->regs, 3) / 9) * 72;
|
||||
|
||||
INFO("Init PDCCH: %d bits, %d symbols, %d ports\n", q->max_bits, q->max_bits/2, q->cell.nof_ports);
|
||||
INFO("Init PDCCH: Max bits: %d, %d ports.\n",
|
||||
q->max_bits, q->cell.nof_ports);
|
||||
|
||||
if (modem_table_lte(&q->mod, LTE_QPSK, true)) {
|
||||
goto clean;
|
||||
|
@ -112,31 +105,33 @@ int pdcch_init(pdcch_t *q, regs_t *regs, lte_cell_t cell) {
|
|||
goto clean;
|
||||
}
|
||||
|
||||
q->pdcch_e = malloc(sizeof(uint8_t) * q->max_bits);
|
||||
q->pdcch_e = vec_malloc(sizeof(uint8_t) * q->max_bits);
|
||||
if (!q->pdcch_e) {
|
||||
goto clean;
|
||||
}
|
||||
|
||||
q->pdcch_llr = malloc(sizeof(float) * q->max_bits);
|
||||
q->pdcch_llr = vec_malloc(sizeof(float) * q->max_bits);
|
||||
if (!q->pdcch_llr) {
|
||||
goto clean;
|
||||
}
|
||||
|
||||
bzero(q->pdcch_llr, sizeof(float) * q->max_bits);
|
||||
|
||||
q->pdcch_d = malloc(sizeof(cf_t) * q->max_bits / 2);
|
||||
q->pdcch_d = vec_malloc(sizeof(cf_t) * q->max_bits / 2);
|
||||
if (!q->pdcch_d) {
|
||||
goto clean;
|
||||
}
|
||||
|
||||
for (i = 0; i < MAX_PORTS; i++) {
|
||||
q->ce[i] = malloc(sizeof(cf_t) * q->max_bits / 2);
|
||||
q->ce[i] = vec_malloc(sizeof(cf_t) * q->max_bits / 2);
|
||||
if (!q->ce[i]) {
|
||||
goto clean;
|
||||
}
|
||||
q->pdcch_x[i] = malloc(sizeof(cf_t) * q->max_bits / 2);
|
||||
q->pdcch_x[i] = vec_malloc(sizeof(cf_t) * q->max_bits / 2);
|
||||
if (!q->pdcch_x[i]) {
|
||||
goto clean;
|
||||
}
|
||||
q->pdcch_symbols[i] = malloc(sizeof(cf_t) * q->max_bits / 2);
|
||||
q->pdcch_symbols[i] = vec_malloc(sizeof(cf_t) * q->max_bits / 2);
|
||||
if (!q->pdcch_symbols[i]) {
|
||||
goto clean;
|
||||
}
|
||||
|
@ -204,7 +199,7 @@ uint32_t pdcch_ue_locations(pdcch_t *q, dci_location_t *c, uint32_t max_candidat
|
|||
|
||||
// Compute Yk for this subframe
|
||||
Yk = rnti;
|
||||
for (m = 0; m < nsubframe; m++) {
|
||||
for (m = 0; m < nsubframe+1; m++) {
|
||||
Yk = (39827 * Yk) % 65537;
|
||||
}
|
||||
|
||||
|
@ -213,7 +208,7 @@ uint32_t pdcch_ue_locations(pdcch_t *q, dci_location_t *c, uint32_t max_candidat
|
|||
for (l = 3; l >= 0; l--) {
|
||||
L = (1 << l);
|
||||
// For all possible ncce offset
|
||||
for (i = 0; i < MIN(q->nof_cce / L, 16 / S[l]); i++) {
|
||||
for (i = 0; i < MIN(q->nof_cce / L, S[l]/PDCCH_FORMAT_NOF_CCE(l)); i++) {
|
||||
ncce = L * ((Yk + i) % (q->nof_cce / L));
|
||||
if (k < max_candidates &&
|
||||
ncce + PDCCH_FORMAT_NOF_CCE(l) <= q->nof_cce)
|
||||
|
@ -221,7 +216,7 @@ uint32_t pdcch_ue_locations(pdcch_t *q, dci_location_t *c, uint32_t max_candidat
|
|||
c[k].L = l;
|
||||
c[k].ncce = ncce;
|
||||
|
||||
DEBUG("UE-specific SS Candidate %d: nCCE: %d, L: %d\n",
|
||||
INFO("UE-specific SS Candidate %d: nCCE: %d, L: %d\n",
|
||||
k, c[k].ncce, c[k].L);
|
||||
|
||||
k++;
|
||||
|
@ -256,7 +251,7 @@ uint32_t pdcch_common_locations(pdcch_t *q, dci_location_t *c, uint32_t max_cand
|
|||
if (k < max_candidates) {
|
||||
c[k].L = l;
|
||||
c[k].ncce = (L) * (i % (q->nof_cce / (L)));
|
||||
DEBUG("Common SS Candidate %d: nCCE: %d, L: %d\n",
|
||||
INFO("Common SS Candidate %d: nCCE: %d, L: %d\n",
|
||||
k, c[k].ncce, c[k].L);
|
||||
k++;
|
||||
}
|
||||
|
@ -291,6 +286,11 @@ static int dci_decode(pdcch_t *q, float *e, uint8_t *data, uint32_t E, uint32_t
|
|||
nof_bits <= DCI_MAX_BITS)
|
||||
{
|
||||
|
||||
DEBUG("Rm input: ", 0);
|
||||
if (VERBOSE_ISDEBUG()) {
|
||||
vec_fprint_f(stdout, e, E);
|
||||
}
|
||||
|
||||
/* unrate matching */
|
||||
rm_conv_rx(e, E, tmp, 3 * (nof_bits + 16));
|
||||
|
||||
|
@ -309,7 +309,7 @@ static int dci_decode(pdcch_t *q, float *e, uint8_t *data, uint32_t E, uint32_t
|
|||
x = &data[nof_bits];
|
||||
p_bits = (uint16_t) bit_unpack(&x, 16);
|
||||
crc_res = ((uint16_t) crc_checksum(&q->crc, data, nof_bits) & 0xffff);
|
||||
DEBUG("p_bits: 0x%x, crc_checksum: 0x%x, crc_rem: 0x%x\n", p_bits, crc_res,
|
||||
INFO("p_bits: 0x%x, crc_checksum: 0x%x, crc_rem: 0x%x\n", p_bits, crc_res,
|
||||
p_bits ^ crc_res);
|
||||
|
||||
if (crc) {
|
||||
|
@ -327,18 +327,30 @@ static int dci_decode(pdcch_t *q, float *e, uint8_t *data, uint32_t E, uint32_t
|
|||
* The decoded message is stored in msg and the CRC remainder in crc_rem pointer
|
||||
*
|
||||
*/
|
||||
int pdcch_decode_msg(pdcch_t *q, dci_msg_t *msg, dci_format_t format, uint16_t *crc_rem)
|
||||
int pdcch_decode_msg(pdcch_t *q, dci_msg_t *msg, dci_location_t *location, dci_format_t format, uint16_t *crc_rem)
|
||||
{
|
||||
int ret = LIBLTE_ERROR_INVALID_INPUTS;
|
||||
if (q != NULL &&
|
||||
msg != NULL &&
|
||||
if (q != NULL &&
|
||||
msg != NULL &&
|
||||
dci_location_isvalid(location) &&
|
||||
crc_rem != NULL)
|
||||
{
|
||||
uint32_t nof_bits = dci_format_sizeof(format, q->cell.nof_prb);
|
||||
if (location->ncce * 72 + PDCCH_FORMAT_NOF_BITS(location->L) >
|
||||
q->nof_cce*72) {
|
||||
fprintf(stderr, "Invalid location: nCCE: %d, L: %d, NofCCE: %d\n",
|
||||
location->ncce, location->L, q->nof_cce);
|
||||
} else {
|
||||
uint32_t nof_bits = dci_format_sizeof(format, q->cell.nof_prb);
|
||||
uint32_t e_bits = PDCCH_FORMAT_NOF_BITS(location->L);
|
||||
|
||||
ret = dci_decode(q, q->pdcch_llr, msg->data, q->e_bits, nof_bits, crc_rem);
|
||||
if (ret == LIBLTE_SUCCESS) {
|
||||
msg->nof_bits = nof_bits;
|
||||
INFO("Decoding DCI offset %d, e_bits: %d, msg_len %d (nCCE: %d, L: %d)\n",
|
||||
location->ncce * 72, e_bits, nof_bits, location->ncce, location->L);
|
||||
|
||||
ret = dci_decode(q, &q->pdcch_llr[location->ncce * 72],
|
||||
msg->data, e_bits, nof_bits, crc_rem);
|
||||
if (ret == LIBLTE_SUCCESS) {
|
||||
msg->nof_bits = nof_bits;
|
||||
}
|
||||
}
|
||||
}
|
||||
return ret;
|
||||
|
@ -350,7 +362,7 @@ int pdcch_decode_msg(pdcch_t *q, dci_msg_t *msg, dci_format_t format, uint16_t *
|
|||
* new messages from other locations can be decoded
|
||||
*/
|
||||
int pdcch_extract_llr(pdcch_t *q, cf_t *sf_symbols, cf_t *ce[MAX_PORTS], float noise_estimate,
|
||||
dci_location_t location, uint32_t nsubframe, uint32_t cfi) {
|
||||
uint32_t nsubframe, uint32_t cfi) {
|
||||
|
||||
int ret = LIBLTE_ERROR_INVALID_INPUTS;
|
||||
|
||||
|
@ -361,74 +373,66 @@ int pdcch_extract_llr(pdcch_t *q, cf_t *sf_symbols, cf_t *ce[MAX_PORTS], float n
|
|||
if (q != NULL &&
|
||||
nsubframe < 10 &&
|
||||
cfi > 0 &&
|
||||
cfi < 4 &&
|
||||
dci_location_isvalid(&location))
|
||||
cfi < 4)
|
||||
{
|
||||
set_cfi(q, cfi);
|
||||
|
||||
q->e_bits = PDCCH_FORMAT_NOF_BITS(location.L);
|
||||
nof_symbols = q->e_bits/2;
|
||||
uint32_t e_bits = 72*q->nof_cce;
|
||||
nof_symbols = e_bits/2;
|
||||
ret = LIBLTE_ERROR;
|
||||
|
||||
if (location.ncce + PDCCH_FORMAT_NOF_CCE(location.L) <= q->nof_cce) {
|
||||
|
||||
INFO("Extracting LLRs: E: %d, nCCE: %d, L: %d, SF: %d, CFI: %d\n",
|
||||
q->e_bits, location.ncce, location.L, nsubframe, cfi);
|
||||
|
||||
INFO("Extracting LLRs: E: %d, SF: %d, CFI: %d\n",
|
||||
e_bits, nsubframe, cfi);
|
||||
|
||||
/* number of layers equals number of ports */
|
||||
for (i = 0; i < q->cell.nof_ports; i++) {
|
||||
x[i] = q->pdcch_x[i];
|
||||
}
|
||||
memset(&x[q->cell.nof_ports], 0, sizeof(cf_t*) * (MAX_LAYERS - q->cell.nof_ports));
|
||||
/* number of layers equals number of ports */
|
||||
for (i = 0; i < q->cell.nof_ports; i++) {
|
||||
x[i] = q->pdcch_x[i];
|
||||
}
|
||||
memset(&x[q->cell.nof_ports], 0, sizeof(cf_t*) * (MAX_LAYERS - q->cell.nof_ports));
|
||||
|
||||
/* extract symbols */
|
||||
int n = regs_pdcch_get(q->regs, sf_symbols, q->pdcch_symbols[0]);
|
||||
if (nof_symbols != n) {
|
||||
fprintf(stderr, "Expected %d PDCCH symbols but got %d symbols\n", nof_symbols, n);
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* extract symbols */
|
||||
int n = regs_pdcch_get_offset(q->regs, sf_symbols, q->pdcch_symbols[0],
|
||||
location.ncce * 9, PDCCH_FORMAT_NOF_REGS(location.L));
|
||||
/* extract channel estimates */
|
||||
for (i = 0; i < q->cell.nof_ports; i++) {
|
||||
n = regs_pdcch_get(q->regs, ce[i], q->ce[i]);
|
||||
if (nof_symbols != n) {
|
||||
fprintf(stderr, "Expected %d PDCCH symbols but got %d symbols\n", nof_symbols, n);
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* extract channel estimates */
|
||||
for (i = 0; i < q->cell.nof_ports; i++) {
|
||||
n = regs_pdcch_get_offset(q->regs, ce[i], q->ce[i],
|
||||
location.ncce * 9, PDCCH_FORMAT_NOF_REGS(location.L));
|
||||
if (nof_symbols != n) {
|
||||
fprintf(stderr, "Expected %d PDCCH symbols but got %d symbols\n", nof_symbols, n);
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
|
||||
/* in control channels, only diversity is supported */
|
||||
if (q->cell.nof_ports == 1) {
|
||||
/* no need for layer demapping */
|
||||
predecoding_single(&q->precoding, q->pdcch_symbols[0], q->ce[0], q->pdcch_d, nof_symbols, noise_estimate);
|
||||
} else {
|
||||
predecoding_diversity(&q->precoding, q->pdcch_symbols[0], q->ce, x, q->cell.nof_ports, nof_symbols, noise_estimate);
|
||||
layerdemap_diversity(x, q->pdcch_d, q->cell.nof_ports, nof_symbols / q->cell.nof_ports);
|
||||
}
|
||||
|
||||
DEBUG("pdcch d symbols: ", 0);
|
||||
if (VERBOSE_ISDEBUG()) {
|
||||
vec_fprint_c(stdout, q->pdcch_d, nof_symbols);
|
||||
}
|
||||
|
||||
/* demodulate symbols */
|
||||
demod_soft_sigma_set(&q->demod, 1.0);
|
||||
demod_soft_demodulate(&q->demod, q->pdcch_d, q->pdcch_llr, nof_symbols);
|
||||
|
||||
DEBUG("llr: ", 0);
|
||||
if (VERBOSE_ISDEBUG()) {
|
||||
vec_fprint_f(stdout, q->pdcch_llr, q->e_bits);
|
||||
}
|
||||
|
||||
/* descramble */
|
||||
scrambling_f_offset(&q->seq_pdcch[nsubframe], q->pdcch_llr, 72 * location.ncce, q->e_bits);
|
||||
|
||||
ret = LIBLTE_SUCCESS;
|
||||
} else {
|
||||
fprintf(stderr, "Illegal DCI message nCCE: %d, L: %d, nof_cce: %d\n", location.ncce, location.L, q->nof_cce);
|
||||
}
|
||||
|
||||
/* in control channels, only diversity is supported */
|
||||
if (q->cell.nof_ports == 1) {
|
||||
/* no need for layer demapping */
|
||||
predecoding_single(&q->precoding, q->pdcch_symbols[0], q->ce[0], q->pdcch_d, nof_symbols, noise_estimate);
|
||||
} else {
|
||||
predecoding_diversity(&q->precoding, q->pdcch_symbols[0], q->ce, x, q->cell.nof_ports, nof_symbols, noise_estimate);
|
||||
layerdemap_diversity(x, q->pdcch_d, q->cell.nof_ports, nof_symbols / q->cell.nof_ports);
|
||||
}
|
||||
|
||||
DEBUG("pdcch d symbols: ", 0);
|
||||
if (VERBOSE_ISDEBUG()) {
|
||||
vec_fprint_c(stdout, q->pdcch_d, nof_symbols);
|
||||
}
|
||||
|
||||
/* demodulate symbols */
|
||||
demod_soft_sigma_set(&q->demod, 1);
|
||||
demod_soft_demodulate(&q->demod, q->pdcch_d, q->pdcch_llr, nof_symbols);
|
||||
|
||||
/* descramble */
|
||||
scrambling_f_offset(&q->seq_pdcch[nsubframe], q->pdcch_llr, 0, e_bits);
|
||||
|
||||
DEBUG("llr: ", 0);
|
||||
if (VERBOSE_ISDEBUG()) {
|
||||
vec_fprint_f(stdout, q->pdcch_llr, e_bits);
|
||||
}
|
||||
|
||||
ret = LIBLTE_SUCCESS;
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
@ -514,17 +518,17 @@ int pdcch_encode(pdcch_t *q, dci_msg_t *msg, dci_location_t location, uint16_t r
|
|||
|
||||
set_cfi(q, cfi);
|
||||
|
||||
q->e_bits = PDCCH_FORMAT_NOF_BITS(location.L);
|
||||
nof_symbols = q->e_bits/2;
|
||||
uint32_t e_bits = PDCCH_FORMAT_NOF_BITS(location.L);
|
||||
nof_symbols = e_bits/2;
|
||||
ret = LIBLTE_ERROR;
|
||||
|
||||
if (location.ncce + PDCCH_FORMAT_NOF_CCE(location.L) <= q->nof_cce &&
|
||||
msg->nof_bits < DCI_MAX_BITS)
|
||||
{
|
||||
INFO("Encoding DCI: Nbits: %d, E: %d, nCCE: %d, L: %d, RNTI: 0x%x\n",
|
||||
msg->nof_bits, q->e_bits, location.ncce, location.L, rnti);
|
||||
msg->nof_bits, e_bits, location.ncce, location.L, rnti);
|
||||
|
||||
dci_encode(q, msg->data, q->pdcch_e, msg->nof_bits, q->e_bits, rnti);
|
||||
dci_encode(q, msg->data, q->pdcch_e, msg->nof_bits, e_bits, rnti);
|
||||
|
||||
/* number of layers equals number of ports */
|
||||
for (i = 0; i < q->cell.nof_ports; i++) {
|
||||
|
@ -532,14 +536,14 @@ int pdcch_encode(pdcch_t *q, dci_msg_t *msg, dci_location_t location, uint16_t r
|
|||
}
|
||||
memset(&x[q->cell.nof_ports], 0, sizeof(cf_t*) * (MAX_LAYERS - q->cell.nof_ports));
|
||||
|
||||
scrambling_b_offset(&q->seq_pdcch[nsubframe], q->pdcch_e, 72 * location.ncce, q->e_bits);
|
||||
scrambling_b_offset(&q->seq_pdcch[nsubframe], q->pdcch_e, 72 * location.ncce, e_bits);
|
||||
|
||||
DEBUG("Scrambling output: ", 0);
|
||||
if (VERBOSE_ISDEBUG()) {
|
||||
vec_fprint_b(stdout, q->pdcch_e, q->e_bits);
|
||||
vec_fprint_b(stdout, q->pdcch_e, e_bits);
|
||||
}
|
||||
|
||||
mod_modulate(&q->mod, q->pdcch_e, q->pdcch_d, q->e_bits);
|
||||
mod_modulate(&q->mod, q->pdcch_e, q->pdcch_d, e_bits);
|
||||
|
||||
/* layer mapping & precoding */
|
||||
if (q->cell.nof_ports > 1) {
|
||||
|
|
|
@ -49,8 +49,11 @@
|
|||
const lte_mod_t modulations[4] =
|
||||
{ LTE_BPSK, LTE_QPSK, LTE_QAM16, LTE_QAM64 };
|
||||
|
||||
|
||||
//#define DEBUG_IDX
|
||||
|
||||
#ifdef DEBUG_IDX
|
||||
cf_t *offset_original=NULL;
|
||||
#endif
|
||||
|
||||
int pdsch_cp(pdsch_t *q, cf_t *input, cf_t *output, ra_prb_t *prb_alloc,
|
||||
uint32_t nsubframe, bool put) {
|
||||
|
@ -62,6 +65,10 @@ int pdsch_cp(pdsch_t *q, cf_t *input, cf_t *output, ra_prb_t *prb_alloc,
|
|||
INFO("%s %d RE from %d PRB\n", put ? "Putting" : "Getting",
|
||||
prb_alloc->re_sf[nsubframe], prb_alloc->slot[0].nof_prb);
|
||||
|
||||
#ifdef DEBUG_IDX
|
||||
offset_original = input;
|
||||
#endif
|
||||
|
||||
if (q->cell.nof_ports == 1) {
|
||||
nof_refs = 2;
|
||||
} else {
|
||||
|
@ -70,72 +77,79 @@ int pdsch_cp(pdsch_t *q, cf_t *input, cf_t *output, ra_prb_t *prb_alloc,
|
|||
|
||||
for (s = 0; s < 2; s++) {
|
||||
for (l = 0; l < CP_NSYMB(q->cell.cp); l++) {
|
||||
for (n = 0; n < prb_alloc->slot[s].nof_prb; n++) {
|
||||
if (s == 0) {
|
||||
lstart = prb_alloc->lstart;
|
||||
} else {
|
||||
lstart = 0;
|
||||
}
|
||||
lend = CP_NSYMB(q->cell.cp);
|
||||
is_pbch = is_sss = false;
|
||||
for (n = 0; n < q->cell.nof_prb; n++) {
|
||||
|
||||
// Skip PSS/SSS signals
|
||||
if (s == 0 && (nsubframe == 0 || nsubframe == 5)) {
|
||||
if (prb_alloc->slot[s].prb_idx[n] >= q->cell.nof_prb / 2 - 3
|
||||
&& prb_alloc->slot[s].prb_idx[n] <= q->cell.nof_prb / 2 + 3) {
|
||||
lend = CP_NSYMB(q->cell.cp) - 2;
|
||||
is_sss = true;
|
||||
}
|
||||
}
|
||||
// Skip PBCH
|
||||
if (s == 1 && nsubframe == 0) {
|
||||
if (prb_alloc->slot[s].prb_idx[n] >= q->cell.nof_prb / 2 - 3
|
||||
&& prb_alloc->slot[s].prb_idx[n] <= q->cell.nof_prb / 2 + 3) {
|
||||
lstart = 4;
|
||||
is_pbch = true;
|
||||
}
|
||||
}
|
||||
lp = l + s * CP_NSYMB(q->cell.cp);
|
||||
if (put) {
|
||||
out_ptr = &output[(lp * q->cell.nof_prb + prb_alloc->slot[s].prb_idx[n])
|
||||
* RE_X_RB];
|
||||
} else {
|
||||
in_ptr = &input[(lp * q->cell.nof_prb + prb_alloc->slot[s].prb_idx[n])
|
||||
* RE_X_RB];
|
||||
}
|
||||
if (l >= lstart && l < lend) {
|
||||
if (SYMBOL_HAS_REF(l, q->cell.cp, q->cell.nof_ports)) {
|
||||
if (nof_refs == 2 && l != 0) {
|
||||
offset = q->cell.id % 3 + 3;
|
||||
} else {
|
||||
offset = q->cell.id % 3;
|
||||
}
|
||||
prb_cp_ref(&in_ptr, &out_ptr, offset, nof_refs, nof_refs, put);
|
||||
// If this PRB is assigned
|
||||
if (prb_alloc->slot[s].prb_idx[n]) {
|
||||
if (s == 0) {
|
||||
lstart = prb_alloc->lstart;
|
||||
} else {
|
||||
prb_cp(&in_ptr, &out_ptr, 1);
|
||||
lstart = 0;
|
||||
}
|
||||
}
|
||||
if ((q->cell.nof_prb % 2) && ((is_pbch && l < lstart) || (is_sss && l >= lend))) {
|
||||
if (prb_alloc->slot[s].prb_idx[n] == q->cell.nof_prb / 2 - 3) {
|
||||
if (SYMBOL_HAS_REF(l, q->cell.cp, q->cell.nof_ports)) {
|
||||
prb_cp_ref(&in_ptr, &out_ptr, offset, nof_refs, nof_refs/2, put);
|
||||
} else {
|
||||
prb_cp_half(&in_ptr, &out_ptr, 1);
|
||||
lend = CP_NSYMB(q->cell.cp);
|
||||
is_pbch = is_sss = false;
|
||||
|
||||
// Skip PSS/SSS signals
|
||||
if (s == 0 && (nsubframe == 0 || nsubframe == 5)) {
|
||||
if (n >= q->cell.nof_prb / 2 - 3
|
||||
&& n < q->cell.nof_prb / 2 + 3) {
|
||||
lend = CP_NSYMB(q->cell.cp) - 2;
|
||||
is_sss = true;
|
||||
}
|
||||
} else if (prb_alloc->slot[s].prb_idx[n] == q->cell.nof_prb / 2 + 3) {
|
||||
if (put) {
|
||||
out_ptr += 6;
|
||||
} else {
|
||||
in_ptr += 6;
|
||||
}
|
||||
// Skip PBCH
|
||||
if (s == 1 && nsubframe == 0) {
|
||||
if (n >= q->cell.nof_prb / 2 - 3
|
||||
&& n < q->cell.nof_prb / 2 + 3) {
|
||||
lstart = 4;
|
||||
is_pbch = true;
|
||||
}
|
||||
}
|
||||
lp = l + s * CP_NSYMB(q->cell.cp);
|
||||
if (put) {
|
||||
out_ptr = &output[(lp * q->cell.nof_prb + n)
|
||||
* RE_X_RB];
|
||||
} else {
|
||||
in_ptr = &input[(lp * q->cell.nof_prb + n)
|
||||
* RE_X_RB];
|
||||
}
|
||||
// This is a symbol in a normal PRB with or without references
|
||||
if (l >= lstart && l < lend) {
|
||||
if (SYMBOL_HAS_REF(l, q->cell.cp, q->cell.nof_ports)) {
|
||||
prb_cp_ref(&in_ptr, &out_ptr, offset, nof_refs, nof_refs/2, put);
|
||||
if (nof_refs == 2 && l == 0) {
|
||||
offset = q->cell.id % 3 + 3;
|
||||
} else {
|
||||
offset = q->cell.id % 3;
|
||||
}
|
||||
prb_cp_ref(&in_ptr, &out_ptr, offset, nof_refs, nof_refs, put);
|
||||
} else {
|
||||
prb_cp_half(&in_ptr, &out_ptr, 1);
|
||||
prb_cp(&in_ptr, &out_ptr, 1);
|
||||
}
|
||||
}
|
||||
// This is a symbol in a PRB with PBCH or Synch signals (SS).
|
||||
// If the number or total PRB is odd, half of the the PBCH or SS will fall into the symbol
|
||||
if ((q->cell.nof_prb % 2) && ((is_pbch && l < lstart) || (is_sss && l >= lend))) {
|
||||
if (n == q->cell.nof_prb / 2 - 3) {
|
||||
if (SYMBOL_HAS_REF(l, q->cell.cp, q->cell.nof_ports)) {
|
||||
prb_cp_ref(&in_ptr, &out_ptr, offset, nof_refs, nof_refs/2, put);
|
||||
} else {
|
||||
prb_cp_half(&in_ptr, &out_ptr, 1);
|
||||
}
|
||||
} else if (n == q->cell.nof_prb / 2 + 3) {
|
||||
if (put) {
|
||||
out_ptr += 6;
|
||||
} else {
|
||||
in_ptr += 6;
|
||||
}
|
||||
if (SYMBOL_HAS_REF(l, q->cell.cp, q->cell.nof_ports)) {
|
||||
prb_cp_ref(&in_ptr, &out_ptr, offset, nof_refs, nof_refs/2, put);
|
||||
} else {
|
||||
prb_cp_half(&in_ptr, &out_ptr, 1);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -532,6 +546,8 @@ int pdsch_decode_tb(pdsch_t *q, uint8_t *data, uint32_t tbs, uint32_t nb_e,
|
|||
fprintf(stderr, "Error in rate matching\n");
|
||||
return LIBLTE_ERROR;
|
||||
}
|
||||
|
||||
vec_save_file("tdec_in.dat",q->cb_out, sizeof(float) * (3 * cb_len + 12));
|
||||
|
||||
/* Turbo Decoding with CRC-based early stopping */
|
||||
q->nof_iterations = 0;
|
||||
|
@ -542,7 +558,6 @@ int pdsch_decode_tb(pdsch_t *q, uint8_t *data, uint32_t tbs, uint32_t nb_e,
|
|||
tdec_reset(&q->decoder, cb_len);
|
||||
|
||||
do {
|
||||
|
||||
tdec_iteration(&q->decoder, (float*) q->cb_out, cb_len);
|
||||
q->nof_iterations++;
|
||||
|
||||
|
@ -651,7 +666,7 @@ int pdsch_decode(pdsch_t *q, cf_t *sf_symbols, cf_t *ce[MAX_PORTS], float noise_
|
|||
fprintf(stderr, "Error expecting %d symbols but got %d\n", nof_symbols, n);
|
||||
return LIBLTE_ERROR;
|
||||
}
|
||||
|
||||
|
||||
/* extract channel estimates */
|
||||
for (i = 0; i < q->cell.nof_ports; i++) {
|
||||
n = pdsch_get(q, ce[i], q->ce[i], &harq_process->prb_alloc, subframe);
|
||||
|
@ -660,7 +675,7 @@ int pdsch_decode(pdsch_t *q, cf_t *sf_symbols, cf_t *ce[MAX_PORTS], float noise_
|
|||
return LIBLTE_ERROR;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/* TODO: only diversity is supported */
|
||||
if (q->cell.nof_ports == 1) {
|
||||
/* no need for layer demapping */
|
||||
|
@ -672,31 +687,22 @@ int pdsch_decode(pdsch_t *q, cf_t *sf_symbols, cf_t *ce[MAX_PORTS], float noise_
|
|||
layerdemap_diversity(x, q->pdsch_d, q->cell.nof_ports,
|
||||
nof_symbols / q->cell.nof_ports);
|
||||
}
|
||||
|
||||
|
||||
vec_save_file("pdsch_after.dat",q->pdsch_d,sizeof(cf_t)*nof_symbols);
|
||||
|
||||
/* demodulate symbols
|
||||
* The MAX-log-MAP algorithm used in turbo decoding is unsensitive to SNR estimation,
|
||||
* thus we don't need tot set it in the LLRs normalization
|
||||
*/
|
||||
demod_soft_sigma_set(&q->demod, 2.0 / q->mod[harq_process->mcs.mod - 1].nbits_x_symbol);
|
||||
demod_soft_sigma_set(&q->demod, 1);//q->mod[harq_process->mcs.mod - 1].nbits_x_symbol);
|
||||
demod_soft_table_set(&q->demod, &q->mod[harq_process->mcs.mod - 1]);
|
||||
demod_soft_demodulate(&q->demod, q->pdsch_d, q->pdsch_e, nof_symbols);
|
||||
|
||||
/*
|
||||
for (int j=0;j<nof_symbols;j++) {
|
||||
if (isnan(crealf(q->pdsch_d[j])) || isnan(cimagf(q->pdsch_d[j]))) {
|
||||
printf("\nerror in d[%d]=%f+%f symbols:%f+%f ce0:%f+%f ce1:%f+%f\n",j,
|
||||
crealf(q->pdsch_d[j]), cimagf(q->pdsch_d[j]),
|
||||
crealf(q->pdsch_symbols[0][j]), cimagf(q->pdsch_symbols[0][j]),
|
||||
crealf(q->ce[0][j]), cimagf(q->ce[0][j]),
|
||||
crealf(q->ce[1][j]), cimagf(q->ce[1][j])
|
||||
);
|
||||
}
|
||||
}
|
||||
*/
|
||||
|
||||
/* descramble */
|
||||
scrambling_f_offset(&q->seq_pdsch[subframe], q->pdsch_e, 0, nof_bits_e);
|
||||
|
||||
|
||||
vec_save_file("pdsch_llr.dat",q->pdsch_e,sizeof(float)*nof_bits_e);
|
||||
|
||||
return pdsch_decode_tb(q, data, nof_bits, nof_bits_e, harq_process, rv_idx);
|
||||
} else {
|
||||
return LIBLTE_ERROR_INVALID_INPUTS;
|
||||
|
|
|
@ -32,12 +32,27 @@
|
|||
#include "prb.h"
|
||||
#include "liblte/phy/common/phy_common.h"
|
||||
|
||||
//#define DEBUG_IDX
|
||||
|
||||
#ifdef DEBUG_IDX
|
||||
extern cf_t *offset_original;
|
||||
#endif
|
||||
|
||||
void print_indexes(cf_t *offset, int len) {
|
||||
#ifdef DEBUG_IDX
|
||||
for (int i=0;i<len;i++) {
|
||||
printf("%d, ",offset-offset_original+i);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
void prb_cp_ref(cf_t **input, cf_t **output, int offset, int nof_refs,
|
||||
int nof_intervals, bool advance_output) {
|
||||
int i;
|
||||
|
||||
int ref_interval = ((RE_X_RB / nof_refs) - 1);
|
||||
memcpy(*output, *input, offset * sizeof(cf_t));
|
||||
print_indexes(*input, offset);
|
||||
*input += offset;
|
||||
*output += offset;
|
||||
for (i = 0; i < nof_intervals - 1; i++) {
|
||||
|
@ -47,6 +62,7 @@ void prb_cp_ref(cf_t **input, cf_t **output, int offset, int nof_refs,
|
|||
(*input)++;
|
||||
}
|
||||
memcpy(*output, *input, ref_interval * sizeof(cf_t));
|
||||
print_indexes(*input, ref_interval);
|
||||
*output += ref_interval;
|
||||
*input += ref_interval;
|
||||
}
|
||||
|
@ -57,6 +73,7 @@ void prb_cp_ref(cf_t **input, cf_t **output, int offset, int nof_refs,
|
|||
(*input)++;
|
||||
}
|
||||
memcpy(*output, *input, (ref_interval - offset) * sizeof(cf_t));
|
||||
print_indexes(*input, ref_interval-offset);
|
||||
*output += (ref_interval - offset);
|
||||
*input += (ref_interval - offset);
|
||||
}
|
||||
|
@ -64,6 +81,7 @@ void prb_cp_ref(cf_t **input, cf_t **output, int offset, int nof_refs,
|
|||
|
||||
void prb_cp(cf_t **input, cf_t **output, int nof_prb) {
|
||||
memcpy(*output, *input, sizeof(cf_t) * RE_X_RB * nof_prb);
|
||||
print_indexes(*input, RE_X_RB);
|
||||
*input += nof_prb * RE_X_RB;
|
||||
*output += nof_prb * RE_X_RB;
|
||||
}
|
||||
|
@ -71,6 +89,7 @@ void prb_cp(cf_t **input, cf_t **output, int nof_prb) {
|
|||
|
||||
void prb_cp_half(cf_t **input, cf_t **output, int nof_prb) {
|
||||
memcpy(*output, *input, sizeof(cf_t) * RE_X_RB * nof_prb / 2);
|
||||
print_indexes(*input, RE_X_RB/2);
|
||||
*input += nof_prb * RE_X_RB / 2;
|
||||
*output += nof_prb * RE_X_RB / 2;
|
||||
}
|
||||
|
|
|
@ -55,7 +55,7 @@ uint32_t ra_re_x_prb(uint32_t subframe, uint32_t slot, uint32_t prb_idx, uint32_
|
|||
|
||||
/* if it's the prb in the middle, there are less RE due to PBCH and PSS/SSS */
|
||||
if ((subframe == 0 || subframe == 5)
|
||||
&& (prb_idx >= nof_prb / 2 - 3 && prb_idx <= nof_prb / 2 + 3)) {
|
||||
&& (prb_idx >= nof_prb / 2 - 3 && prb_idx < nof_prb / 2 + 3)) {
|
||||
if (subframe == 0) {
|
||||
if (slot == 0) {
|
||||
re = (CP_NSYMB(cp) - nof_ctrl_symbols - 2) * RE_X_RB;
|
||||
|
@ -119,26 +119,30 @@ void ra_prb_get_re_dl(ra_prb_t *prb_dist, uint32_t nof_prb, uint32_t nof_ports,
|
|||
for (i = 0; i < NSUBFRAMES_X_FRAME; i++) {
|
||||
prb_dist->re_sf[i] = 0;
|
||||
for (s = 0; s < 2; s++) {
|
||||
for (j = 0; j < prb_dist->slot[s].nof_prb; j++) {
|
||||
prb_dist->re_sf[i] += ra_re_x_prb(i, s, prb_dist->slot[s].prb_idx[j],
|
||||
nof_prb, nof_ports, nof_ctrl_symbols, cp);
|
||||
for (j = 0; j < nof_prb; j++) {
|
||||
if (prb_dist->slot[s].prb_idx[j]) {
|
||||
prb_dist->re_sf[i] += ra_re_x_prb(i, s, j,
|
||||
nof_prb, nof_ports, nof_ctrl_symbols, cp);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void ra_prb_fprint(FILE *f, ra_prb_slot_t *prb) {
|
||||
int i, j, nrows;
|
||||
nrows = (prb->nof_prb - 1) / 25 + 1;
|
||||
for (j = 0; j < nrows; j++) {
|
||||
for (i = 0; i < min(25, prb->nof_prb - j * 25); i++) {
|
||||
fprintf(f, "%3d, ", prb->prb_idx[j * 25 + i]);
|
||||
void ra_prb_fprint(FILE *f, ra_prb_slot_t *prb, uint32_t nof_prb) {
|
||||
int i;
|
||||
if (prb->nof_prb > 0) {
|
||||
for (i=0;i<nof_prb;i++) {
|
||||
if (prb->prb_idx[i]) {
|
||||
fprintf(f, "%d, ", i);
|
||||
}
|
||||
}
|
||||
fprintf(f, "\n");
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/** Compute PRB allocation for Downlink as defined in 8.1 of 36.213 */
|
||||
/** Compute PRB allocation for Uplink as defined in 8.1 of 36.213 */
|
||||
int ra_prb_get_ul(ra_prb_slot_t *prb, ra_pusch_t *ra, uint32_t nof_prb) {
|
||||
int i;
|
||||
if (ra->type2_alloc.mode != t2_loc) {
|
||||
|
@ -168,7 +172,7 @@ int ra_prb_get_dl(ra_prb_t *prb_dist, ra_pdsch_t *ra, uint32_t nof_prb) {
|
|||
if (bitmask & (1 << (nb - i - 1))) {
|
||||
for (j = 0; j < P; j++) {
|
||||
if (i*P+j < nof_prb) {
|
||||
prb_dist->slot[0].prb_idx[prb_dist->slot[0].nof_prb] = i * P + j;
|
||||
prb_dist->slot[0].prb_idx[i * P + j] = true;
|
||||
prb_dist->slot[0].nof_prb++;
|
||||
}
|
||||
}
|
||||
|
@ -189,8 +193,8 @@ int ra_prb_get_dl(ra_prb_t *prb_dist, ra_pdsch_t *ra, uint32_t nof_prb) {
|
|||
bitmask = ra->type1_alloc.vrb_bitmask;
|
||||
for (i = 0; i < n_rb_type1; i++) {
|
||||
if (bitmask & (1 << (n_rb_type1 - i - 1))) {
|
||||
prb_dist->slot[0].prb_idx[prb_dist->slot[0].nof_prb] = ((i + shift) / P)
|
||||
* P * P + ra->type1_alloc.rbg_subset * P + (i + shift) % P;
|
||||
prb_dist->slot[0].prb_idx[((i + shift) / P)
|
||||
* P * P + ra->type1_alloc.rbg_subset * P + (i + shift) % P] = true;
|
||||
prb_dist->slot[0].nof_prb++;
|
||||
}
|
||||
}
|
||||
|
@ -199,7 +203,7 @@ int ra_prb_get_dl(ra_prb_t *prb_dist, ra_pdsch_t *ra, uint32_t nof_prb) {
|
|||
case alloc_type2:
|
||||
if (ra->type2_alloc.mode == t2_loc) {
|
||||
for (i = 0; i < ra->type2_alloc.L_crb; i++) {
|
||||
prb_dist->slot[0].prb_idx[i] = i + ra->type2_alloc.RB_start;
|
||||
prb_dist->slot[0].prb_idx[i + ra->type2_alloc.RB_start] = true;
|
||||
prb_dist->slot[0].nof_prb++;
|
||||
}
|
||||
memcpy(&prb_dist->slot[1], &prb_dist->slot[0], sizeof(ra_prb_slot_t));
|
||||
|
@ -211,10 +215,10 @@ int ra_prb_get_dl(ra_prb_t *prb_dist, ra_pdsch_t *ra, uint32_t nof_prb) {
|
|||
N_row, n_vrb;
|
||||
int n_tilde_prb_odd, n_tilde_prb_even;
|
||||
if (ra->type2_alloc.n_gap == t2_ng1) {
|
||||
N_tilde_vrb = nof_prb;
|
||||
N_tilde_vrb = ra_type2_n_vrb_dl(nof_prb, true);
|
||||
N_gap = ra_type2_ngap(nof_prb, true);
|
||||
} else {
|
||||
N_tilde_vrb = 2 * nof_prb;
|
||||
N_tilde_vrb = 2 * ra_type2_n_vrb_dl(nof_prb, true);
|
||||
N_gap = ra_type2_ngap(nof_prb, false);
|
||||
}
|
||||
N_row = (int) ceilf((float) N_tilde_vrb / (4 * P)) * P;
|
||||
|
@ -243,17 +247,17 @@ int ra_prb_get_dl(ra_prb_t *prb_dist, ra_pdsch_t *ra, uint32_t nof_prb) {
|
|||
+ N_tilde_vrb * (n_vrb / N_tilde_vrb);
|
||||
|
||||
if (n_tilde_prb_odd < N_tilde_vrb / 2) {
|
||||
prb_dist->slot[0].prb_idx[i] = n_tilde_prb_odd;
|
||||
prb_dist->slot[0].prb_idx[n_tilde_prb_odd] = true;
|
||||
} else {
|
||||
prb_dist->slot[0].prb_idx[i] = n_tilde_prb_odd + N_gap
|
||||
- N_tilde_vrb / 2;
|
||||
prb_dist->slot[0].prb_idx[n_tilde_prb_odd + N_gap
|
||||
- N_tilde_vrb / 2] = true;
|
||||
}
|
||||
prb_dist->slot[0].nof_prb++;
|
||||
if (n_tilde_prb_even < N_tilde_vrb / 2) {
|
||||
prb_dist->slot[1].prb_idx[i] = n_tilde_prb_even;
|
||||
prb_dist->slot[1].prb_idx[n_tilde_prb_even] = true;
|
||||
} else {
|
||||
prb_dist->slot[1].prb_idx[i] = n_tilde_prb_even + N_gap
|
||||
- N_tilde_vrb / 2;
|
||||
prb_dist->slot[1].prb_idx[n_tilde_prb_even + N_gap
|
||||
- N_tilde_vrb / 2] = true;
|
||||
}
|
||||
prb_dist->slot[1].nof_prb++;
|
||||
}
|
||||
|
@ -532,7 +536,7 @@ void ra_pdsch_fprint(FILE *f, ra_pdsch_t *ra, uint32_t nof_prb) {
|
|||
ra_prb_get_dl(&alloc, ra, nof_prb);
|
||||
for (int s = 0; s < 2; s++) {
|
||||
fprintf(f, " - PRB Bitmap Assignment %dst slot:\n", s);
|
||||
ra_prb_fprint(f, &alloc.slot[s]);
|
||||
ra_prb_fprint(f, &alloc.slot[s], nof_prb);
|
||||
}
|
||||
|
||||
fprintf(f, " - Number of PRBs:\t\t\t%d\n", ra_nprb_dl(ra, nof_prb));
|
||||
|
|
|
@ -67,11 +67,9 @@ void regs_pdcch_free(regs_t *h) {
|
|||
for (i=0;i<3;i++) {
|
||||
if (h->pdcch[i].regs) {
|
||||
free(h->pdcch[i].regs);
|
||||
h->pdcch[i].regs = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
bzero(h, sizeof(regs_t));
|
||||
|
||||
}
|
||||
|
||||
#define PDCCH_NCOLS 32
|
||||
|
@ -114,7 +112,7 @@ int regs_pdcch_init(regs_t *h) {
|
|||
}
|
||||
|
||||
h->pdcch[cfi].nof_regs = m;
|
||||
|
||||
|
||||
h->pdcch[cfi].regs = malloc(sizeof(regs_reg_t*) * h->pdcch[cfi].nof_regs);
|
||||
if (!h->pdcch[cfi].regs) {
|
||||
perror("malloc");
|
||||
|
@ -144,6 +142,8 @@ int regs_pdcch_init(regs_t *h) {
|
|||
}
|
||||
}
|
||||
h->pdcch[cfi].nof_regs = (h->pdcch[cfi].nof_regs/9)*9;
|
||||
INFO("Init PDCCH REG space CFI %d. %d useful REGs (%d CCEs)\n",cfi+1,
|
||||
h->pdcch[cfi].nof_regs, h->pdcch[cfi].nof_regs/9);
|
||||
free(tmp);
|
||||
tmp = NULL;
|
||||
}
|
||||
|
@ -348,13 +348,12 @@ void regs_phich_free(regs_t *h) {
|
|||
for (i=0;i<h->ngroups_phich;i++) {
|
||||
if (h->phich[i].regs) {
|
||||
free(h->phich[i].regs);
|
||||
h->phich[i].regs = NULL;
|
||||
}
|
||||
}
|
||||
free(h->phich);
|
||||
h->phich = NULL;
|
||||
}
|
||||
|
||||
bzero(h, sizeof(regs_t));
|
||||
|
||||
}
|
||||
|
||||
uint32_t regs_phich_nregs(regs_t *h) {
|
||||
|
@ -487,7 +486,7 @@ int regs_pcfich_init(regs_t *h) {
|
|||
k);
|
||||
return LIBLTE_ERROR;
|
||||
} else {
|
||||
ch->regs[i]->assigned = true;
|
||||
ch->regs[i]->assigned = true;
|
||||
INFO("Assigned PCFICH REG#%d (%d,0)\n", i, k);
|
||||
}
|
||||
}
|
||||
|
@ -497,10 +496,8 @@ int regs_pcfich_init(regs_t *h) {
|
|||
void regs_pcfich_free(regs_t *h) {
|
||||
if (h->pcfich.regs) {
|
||||
free(h->pcfich.regs);
|
||||
h->pcfich.regs = NULL;
|
||||
}
|
||||
|
||||
bzero(h, sizeof(regs_t));
|
||||
|
||||
}
|
||||
|
||||
uint32_t regs_pcfich_nregs(regs_t *h) {
|
||||
|
|
|
@ -34,8 +34,8 @@
|
|||
#include "liblte/phy/phy.h"
|
||||
|
||||
char *input_file_name = NULL;
|
||||
char *matlab_file_name = NULL;
|
||||
|
||||
#define MAX_CANDIDATES 64
|
||||
|
||||
lte_cell_t cell = {
|
||||
6, // cell.cell.cell.nof_prb
|
||||
|
@ -50,8 +50,8 @@ uint32_t cfi = 2;
|
|||
int flen;
|
||||
uint16_t rnti = SIRNTI;
|
||||
int max_frames = 10;
|
||||
FILE *fmatlab = NULL;
|
||||
|
||||
dci_format_t dci_format = Format1A;
|
||||
filesource_t fsrc;
|
||||
pdcch_t pdcch;
|
||||
cf_t *input_buffer, *fft_buffer, *ce[MAX_PORTS];
|
||||
|
@ -61,9 +61,9 @@ chest_dl_t chest;
|
|||
|
||||
void usage(char *prog) {
|
||||
printf("Usage: %s [vcfoe] -i input_file\n", prog);
|
||||
printf("\t-o output matlab file name [Default Disabled]\n");
|
||||
printf("\t-c cell.id [Default %d]\n", cell.id);
|
||||
printf("\t-f cfi [Default %d]\n", cfi);
|
||||
printf("\t-o DCI Format [Default %s]\n", dci_format_string(dci_format));
|
||||
printf("\t-r rnti [Default SI-RNTI]\n");
|
||||
printf("\t-p cell.nof_ports [Default %d]\n", cell.nof_ports);
|
||||
printf("\t-n cell.nof_prb [Default %d]\n", cell.nof_prb);
|
||||
|
@ -74,7 +74,7 @@ void usage(char *prog) {
|
|||
|
||||
void parse_args(int argc, char **argv) {
|
||||
int opt;
|
||||
while ((opt = getopt(argc, argv, "irovfcenmp")) != -1) {
|
||||
while ((opt = getopt(argc, argv, "irvofcenmp")) != -1) {
|
||||
switch(opt) {
|
||||
case 'i':
|
||||
input_file_name = argv[optind];
|
||||
|
@ -98,7 +98,11 @@ void parse_args(int argc, char **argv) {
|
|||
cell.nof_ports = atoi(argv[optind]);
|
||||
break;
|
||||
case 'o':
|
||||
matlab_file_name = argv[optind];
|
||||
dci_format = dci_format_from_string(argv[optind]);
|
||||
if (dci_format == FormatError) {
|
||||
fprintf(stderr, "Error unsupported format %s\n", argv[optind]);
|
||||
exit(-1);
|
||||
}
|
||||
break;
|
||||
case 'v':
|
||||
verbose++;
|
||||
|
@ -125,16 +129,6 @@ int base_init() {
|
|||
exit(-1);
|
||||
}
|
||||
|
||||
if (matlab_file_name) {
|
||||
fmatlab = fopen(matlab_file_name, "w");
|
||||
if (!fmatlab) {
|
||||
perror("fopen");
|
||||
return -1;
|
||||
}
|
||||
} else {
|
||||
fmatlab = NULL;
|
||||
}
|
||||
|
||||
flen = 2 * (SLOT_LEN(lte_symbol_sz(cell.nof_prb)));
|
||||
|
||||
input_buffer = malloc(flen * sizeof(cf_t));
|
||||
|
@ -189,9 +183,6 @@ void base_free() {
|
|||
int i;
|
||||
|
||||
filesource_free(&fsrc);
|
||||
if (fmatlab) {
|
||||
fclose(fmatlab);
|
||||
}
|
||||
|
||||
free(input_buffer);
|
||||
free(fft_buffer);
|
||||
|
@ -210,9 +201,9 @@ void base_free() {
|
|||
int main(int argc, char **argv) {
|
||||
ra_pdsch_t ra_dl;
|
||||
int i;
|
||||
int nof_frames;
|
||||
int frame_cnt;
|
||||
int ret;
|
||||
dci_location_t locations[10];
|
||||
dci_location_t locations[MAX_CANDIDATES];
|
||||
uint32_t nof_locations;
|
||||
dci_msg_t dci_msg;
|
||||
|
||||
|
@ -228,84 +219,72 @@ int main(int argc, char **argv) {
|
|||
exit(-1);
|
||||
}
|
||||
|
||||
if (rnti == SIRNTI) {
|
||||
INFO("Initializing common search space for SI-RNTI\n",0);
|
||||
nof_locations = pdcch_common_locations(&pdcch, locations, 10, cfi);
|
||||
} else {
|
||||
// For ue-specific, generate locations for subframe 5
|
||||
INFO("Initializing user-specific search space for RNTI: 0x%x\n", rnti);
|
||||
nof_locations = pdcch_ue_locations(&pdcch, locations, 10, 5, cfi, rnti);
|
||||
}
|
||||
ret = -1;
|
||||
nof_frames = 0;
|
||||
frame_cnt = 0;
|
||||
do {
|
||||
filesource_read(&fsrc, input_buffer, flen);
|
||||
if (nof_frames == 5) {
|
||||
INFO("Reading %d samples sub-frame %d\n", flen, nof_frames);
|
||||
|
||||
lte_fft_run_sf(&fft, input_buffer, fft_buffer);
|
||||
INFO("Reading %d samples sub-frame %d\n", flen, frame_cnt);
|
||||
|
||||
if (fmatlab) {
|
||||
fprintf(fmatlab, "infft%d=", nof_frames);
|
||||
vec_fprint_c(fmatlab, input_buffer, flen);
|
||||
fprintf(fmatlab, ";\n");
|
||||
lte_fft_run_sf(&fft, input_buffer, fft_buffer);
|
||||
|
||||
fprintf(fmatlab, "outfft%d=", nof_frames);
|
||||
vec_sc_prod_cfc(fft_buffer, 1000.0, fft_buffer, CP_NSYMB(cell.cp) * cell.nof_prb * RE_X_RB);
|
||||
vec_fprint_c(fmatlab, fft_buffer, CP_NSYMB(cell.cp) * cell.nof_prb * RE_X_RB);
|
||||
fprintf(fmatlab, ";\n");
|
||||
vec_sc_prod_cfc(fft_buffer, 0.001, fft_buffer, CP_NSYMB(cell.cp) * cell.nof_prb * RE_X_RB);
|
||||
/* Get channel estimates for each port */
|
||||
chest_dl_estimate(&chest, fft_buffer, ce, frame_cnt %10);
|
||||
|
||||
uint16_t crc_rem = 0;
|
||||
if (pdcch_extract_llr(&pdcch, fft_buffer,
|
||||
ce, chest_dl_get_noise_estimate(&chest),
|
||||
frame_cnt %10, cfi)) {
|
||||
fprintf(stderr, "Error extracting LLRs\n");
|
||||
return -1;
|
||||
}
|
||||
if (rnti == SIRNTI) {
|
||||
INFO("Initializing common search space for SI-RNTI\n",0);
|
||||
nof_locations = pdcch_common_locations(&pdcch, locations, MAX_CANDIDATES, cfi);
|
||||
} else {
|
||||
INFO("Initializing user-specific search space for RNTI: 0x%x\n", rnti);
|
||||
nof_locations = pdcch_ue_locations(&pdcch, locations, MAX_CANDIDATES, frame_cnt %10, cfi, rnti);
|
||||
}
|
||||
|
||||
for (i=0;i<nof_locations && crc_rem != rnti;i++) {
|
||||
if (pdcch_decode_msg(&pdcch, &dci_msg, &locations[i], dci_format, &crc_rem)) {
|
||||
fprintf(stderr, "Error decoding DCI msg\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* Get channel estimates for each port */
|
||||
chest_dl_estimate(&chest, fft_buffer, ce, nof_frames);
|
||||
|
||||
uint16_t crc_rem = 0;
|
||||
for (i=0;i<nof_locations && crc_rem != rnti;i++) {
|
||||
if (pdcch_extract_llr(&pdcch, fft_buffer, ce, chest_dl_get_noise_estimate(&chest), locations[i], nof_frames, cfi)) {
|
||||
fprintf(stderr, "Error extracting LLRs\n");
|
||||
return -1;
|
||||
}
|
||||
if (pdcch_decode_msg(&pdcch, &dci_msg, Format1A, &crc_rem)) {
|
||||
fprintf(stderr, "Error decoding DCI msg\n");
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
if (crc_rem == rnti) {
|
||||
dci_msg_type_t type;
|
||||
if (dci_msg_get_type(&dci_msg, &type, cell.nof_prb, rnti, 1234)) {
|
||||
fprintf(stderr, "Can't get DCI message type\n");
|
||||
exit(-1);
|
||||
}
|
||||
|
||||
if (crc_rem == rnti) {
|
||||
dci_msg_type_t type;
|
||||
if (dci_msg_get_type(&dci_msg, &type, cell.nof_prb, rnti, 1234)) {
|
||||
fprintf(stderr, "Can't get DCI message type\n");
|
||||
exit(-1);
|
||||
}
|
||||
printf("MSG %d: ",i);
|
||||
dci_msg_type_fprint(stdout, type);
|
||||
switch(type.type) {
|
||||
case PDSCH_SCHED:
|
||||
bzero(&ra_dl, sizeof(ra_pdsch_t));
|
||||
if (dci_msg_unpack_pdsch(&dci_msg, &ra_dl, cell.nof_prb, rnti != SIRNTI)) {
|
||||
fprintf(stderr, "Can't unpack PDSCH message\n");
|
||||
} else {
|
||||
ra_pdsch_fprint(stdout, &ra_dl, cell.nof_prb);
|
||||
if (ra_dl.alloc_type == alloc_type2 && ra_dl.type2_alloc.mode == t2_loc
|
||||
&& ra_dl.type2_alloc.riv == 11 && ra_dl.rv_idx == 0
|
||||
&& ra_dl.harq_process == 0 && ra_dl.mcs_idx == 2) {
|
||||
printf("This is the file signal.1.92M.amar.dat\n");
|
||||
ret = 0;
|
||||
}
|
||||
printf("MSG %d: ",i);
|
||||
dci_msg_type_fprint(stdout, type);
|
||||
switch(type.type) {
|
||||
case PDSCH_SCHED:
|
||||
bzero(&ra_dl, sizeof(ra_pdsch_t));
|
||||
if (dci_msg_unpack_pdsch(&dci_msg, &ra_dl, cell.nof_prb, rnti != SIRNTI)) {
|
||||
fprintf(stderr, "Can't unpack PDSCH message\n");
|
||||
} else {
|
||||
ra_pdsch_fprint(stdout, &ra_dl, cell.nof_prb);
|
||||
if (ra_dl.alloc_type == alloc_type2 && ra_dl.type2_alloc.mode == t2_loc
|
||||
&& ra_dl.type2_alloc.riv == 11 && ra_dl.rv_idx == 0
|
||||
&& ra_dl.harq_process == 0 && ra_dl.mcs_idx == 2) {
|
||||
printf("This is the file signal.1.92M.amar.dat\n");
|
||||
ret = 0;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
fprintf(stderr, "Unsupported message type\n");
|
||||
break;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
fprintf(stderr, "Unsupported message type\n");
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
nof_frames++;
|
||||
} while (nof_frames <= max_frames);
|
||||
frame_cnt++;
|
||||
} while (frame_cnt <= max_frames);
|
||||
|
||||
base_free();
|
||||
exit(ret);
|
||||
|
|
|
@ -182,6 +182,7 @@ int main(int argc, char **argv) {
|
|||
}
|
||||
}
|
||||
|
||||
vec_fprint_b(stdout, dci_tx[0].data, dci_tx[0].nof_bits);
|
||||
/* combine outputs */
|
||||
for (i = 1; i < cell.nof_ports; i++) {
|
||||
for (j = 0; j < nof_re; j++) {
|
||||
|
@ -190,12 +191,12 @@ int main(int argc, char **argv) {
|
|||
}
|
||||
|
||||
for (i=0;i<2;i++) {
|
||||
if (pdcch_extract_llr(&pdcch, slot_symbols[0], ce, 0, dci_locations[i], 0, cfi)) {
|
||||
if (pdcch_extract_llr(&pdcch, slot_symbols[0], ce, 0, 0, cfi)) {
|
||||
fprintf(stderr, "Error extracting LLRs\n");
|
||||
goto quit;
|
||||
}
|
||||
uint16_t crc_rem;
|
||||
if (pdcch_decode_msg(&pdcch, &dci_tmp, Format1, &crc_rem)) {
|
||||
if (pdcch_decode_msg(&pdcch, &dci_tmp, &dci_locations[i], Format1, &crc_rem)) {
|
||||
fprintf(stderr, "Error decoding DCI message\n");
|
||||
goto quit;
|
||||
}
|
||||
|
|
|
@ -33,8 +33,9 @@
|
|||
|
||||
#include "liblte/phy/phy.h"
|
||||
|
||||
#define MAX_CANDIDATES 64
|
||||
|
||||
char *input_file_name = NULL;
|
||||
char *matlab_file_name = NULL;
|
||||
|
||||
lte_cell_t cell = {
|
||||
6, // nof_prb
|
||||
|
@ -51,8 +52,9 @@ uint32_t cfi = 2;
|
|||
uint16_t rnti = SIRNTI;
|
||||
|
||||
int max_frames = 10;
|
||||
FILE *fmatlab = NULL;
|
||||
uint32_t sf_idx = 0;
|
||||
|
||||
dci_format_t dci_format = Format1A;
|
||||
filesource_t fsrc;
|
||||
pdcch_t pdcch;
|
||||
pdsch_t pdsch;
|
||||
|
@ -63,11 +65,12 @@ lte_fft_t fft;
|
|||
chest_dl_t chest;
|
||||
|
||||
void usage(char *prog) {
|
||||
printf("Usage: %s [vcfoe] -i input_file\n", prog);
|
||||
printf("\t-o output matlab file name [Default Disabled]\n");
|
||||
printf("Usage: %s [rovfcenmps] -i input_file\n", prog);
|
||||
printf("\t-o DCI format [Default %s]\n", dci_format_string(dci_format));
|
||||
printf("\t-c cell.id [Default %d]\n", cell.id);
|
||||
printf("\t-s Start subframe_idx [Default %d]\n", sf_idx);
|
||||
printf("\t-f cfi [Default %d]\n", cfi);
|
||||
printf("\t-r rnti [Default SI-RNTI]\n");
|
||||
printf("\t-r rnti [Default 0x%x]\n",rnti);
|
||||
printf("\t-p cell.nof_ports [Default %d]\n", cell.nof_ports);
|
||||
printf("\t-n cell.nof_prb [Default %d]\n", cell.nof_prb);
|
||||
printf("\t-m max_frames [Default %d]\n", max_frames);
|
||||
|
@ -77,7 +80,7 @@ void usage(char *prog) {
|
|||
|
||||
void parse_args(int argc, char **argv) {
|
||||
int opt;
|
||||
while ((opt = getopt(argc, argv, "irovfcenmp")) != -1) {
|
||||
while ((opt = getopt(argc, argv, "irovfcenmps")) != -1) {
|
||||
switch(opt) {
|
||||
case 'i':
|
||||
input_file_name = argv[optind];
|
||||
|
@ -85,6 +88,9 @@ void parse_args(int argc, char **argv) {
|
|||
case 'c':
|
||||
cell.id = atoi(argv[optind]);
|
||||
break;
|
||||
case 's':
|
||||
sf_idx = atoi(argv[optind]);
|
||||
break;
|
||||
case 'r':
|
||||
rnti = strtoul(argv[optind], NULL, 0);
|
||||
break;
|
||||
|
@ -101,7 +107,11 @@ void parse_args(int argc, char **argv) {
|
|||
cell.nof_ports = atoi(argv[optind]);
|
||||
break;
|
||||
case 'o':
|
||||
matlab_file_name = argv[optind];
|
||||
dci_format = dci_format_from_string(argv[optind]);
|
||||
if (dci_format == FormatError) {
|
||||
fprintf(stderr, "Error unsupported format %s\n", argv[optind]);
|
||||
exit(-1);
|
||||
}
|
||||
break;
|
||||
case 'v':
|
||||
verbose++;
|
||||
|
@ -128,16 +138,6 @@ int base_init() {
|
|||
exit(-1);
|
||||
}
|
||||
|
||||
if (matlab_file_name) {
|
||||
fmatlab = fopen(matlab_file_name, "w");
|
||||
if (!fmatlab) {
|
||||
perror("fopen");
|
||||
return -1;
|
||||
}
|
||||
} else {
|
||||
fmatlab = NULL;
|
||||
}
|
||||
|
||||
flen = 2 * (SLOT_LEN(lte_symbol_sz(cell.nof_prb)));
|
||||
|
||||
input_buffer = malloc(flen * sizeof(cf_t));
|
||||
|
@ -204,9 +204,6 @@ void base_free() {
|
|||
int i;
|
||||
|
||||
filesource_free(&fsrc);
|
||||
if (fmatlab) {
|
||||
fclose(fmatlab);
|
||||
}
|
||||
|
||||
free(input_buffer);
|
||||
free(fft_buffer);
|
||||
|
@ -225,16 +222,16 @@ void base_free() {
|
|||
}
|
||||
|
||||
int main(int argc, char **argv) {
|
||||
ra_pdsch_t ra_dl;
|
||||
ra_pdsch_t ra_dl;
|
||||
int i;
|
||||
int nof_frames;
|
||||
int ret;
|
||||
uint8_t *data;
|
||||
dci_location_t locations[10];
|
||||
dci_location_t locations[MAX_CANDIDATES];
|
||||
uint32_t nof_locations;
|
||||
dci_msg_t dci_msg;
|
||||
|
||||
data = malloc(10000);
|
||||
data = malloc(100000);
|
||||
|
||||
if (argc < 3) {
|
||||
usage(argv[0]);
|
||||
|
@ -250,65 +247,58 @@ int main(int argc, char **argv) {
|
|||
|
||||
if (rnti == SIRNTI) {
|
||||
INFO("Initializing common search space for SI-RNTI\n",0);
|
||||
nof_locations = pdcch_common_locations(&pdcch, locations, 10, cfi);
|
||||
} else {
|
||||
// For ue-specific, generate locations for subframe 5
|
||||
INFO("Initializing user-specific search space for RNTI: 0x%x\n", rnti);
|
||||
nof_locations = pdcch_ue_locations(&pdcch, locations, 10, 5, cfi, rnti);
|
||||
}
|
||||
nof_locations = pdcch_common_locations(&pdcch, locations, MAX_CANDIDATES, cfi);
|
||||
}
|
||||
|
||||
ret = -1;
|
||||
nof_frames = 0;
|
||||
do {
|
||||
filesource_read(&fsrc, input_buffer, flen);
|
||||
if (nof_frames == 5) {
|
||||
INFO("Reading %d samples sub-frame %d\n", flen, nof_frames);
|
||||
INFO("Reading %d samples sub-frame %d\n", flen, sf_idx);
|
||||
|
||||
lte_fft_run_sf(&fft, input_buffer, fft_buffer);
|
||||
lte_fft_run_sf(&fft, input_buffer, fft_buffer);
|
||||
|
||||
if (fmatlab) {
|
||||
fprintf(fmatlab, "infft%d=", nof_frames);
|
||||
vec_fprint_c(fmatlab, input_buffer, flen);
|
||||
fprintf(fmatlab, ";\n");
|
||||
|
||||
fprintf(fmatlab, "outfft%d=", nof_frames);
|
||||
vec_sc_prod_cfc(fft_buffer, 1000.0, fft_buffer, CP_NSYMB(cell.cp) * cell.nof_prb * RE_X_RB);
|
||||
vec_fprint_c(fmatlab, fft_buffer, CP_NSYMB(cell.cp) * cell.nof_prb * RE_X_RB);
|
||||
fprintf(fmatlab, ";\n");
|
||||
vec_sc_prod_cfc(fft_buffer, 0.001, fft_buffer, CP_NSYMB(cell.cp) * cell.nof_prb * RE_X_RB);
|
||||
/* Get channel estimates for each port */
|
||||
chest_dl_estimate(&chest, fft_buffer, ce, sf_idx);
|
||||
|
||||
if (rnti != SIRNTI) {
|
||||
INFO("Initializing user-specific search space for RNTI: 0x%x\n", rnti);
|
||||
nof_locations = pdcch_ue_locations(&pdcch, locations, MAX_CANDIDATES, sf_idx, cfi, rnti);
|
||||
}
|
||||
|
||||
uint16_t crc_rem = 0;
|
||||
if (pdcch_extract_llr(&pdcch, fft_buffer, ce, chest_dl_get_noise_estimate(&chest), sf_idx, cfi)) {
|
||||
fprintf(stderr, "Error extracting LLRs\n");
|
||||
return -1;
|
||||
}
|
||||
for (i=0;i<nof_locations && crc_rem != rnti;i++) {
|
||||
if (pdcch_decode_msg(&pdcch, &dci_msg, &locations[i], dci_format, &crc_rem)) {
|
||||
fprintf(stderr, "Error decoding DCI msg\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* Get channel estimates for each port */
|
||||
chest_dl_estimate(&chest, fft_buffer, ce, nof_frames);
|
||||
|
||||
uint16_t crc_rem = 0;
|
||||
for (i=0;i<nof_locations && crc_rem != rnti;i++) {
|
||||
if (pdcch_extract_llr(&pdcch, fft_buffer, ce, chest_dl_get_noise_estimate(&chest), locations[i], nof_frames, cfi)) {
|
||||
fprintf(stderr, "Error extracting LLRs\n");
|
||||
return -1;
|
||||
}
|
||||
if (pdcch_decode_msg(&pdcch, &dci_msg, Format1A, &crc_rem)) {
|
||||
fprintf(stderr, "Error decoding DCI msg\n");
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
if (crc_rem == rnti) {
|
||||
if (dci_msg_to_ra_dl(&dci_msg, rnti, 1234, cell, cfi, &ra_dl)) {
|
||||
fprintf(stderr, "Error unpacking PDSCH scheduling DCI message\n");
|
||||
goto goout;
|
||||
}
|
||||
|
||||
if (crc_rem == rnti) {
|
||||
if (dci_msg_to_ra_dl(&dci_msg, rnti, 1234, cell, cfi, &ra_dl)) {
|
||||
fprintf(stderr, "Error unpacking PDSCH scheduling DCI message\n");
|
||||
goto goout;
|
||||
}
|
||||
if (ra_dl.mcs.tbs > 0) {
|
||||
if (pdsch_harq_setup(&harq_process, ra_dl.mcs, &ra_dl.prb_alloc)) {
|
||||
fprintf(stderr, "Error configuring HARQ process\n");
|
||||
goto goout;
|
||||
}
|
||||
if (pdsch_decode(&pdsch, fft_buffer, ce, chest_dl_get_noise_estimate(&chest), data, nof_frames%10, &harq_process, ra_dl.rv_idx)) {
|
||||
if (pdsch_decode(&pdsch, fft_buffer, ce, chest_dl_get_noise_estimate(&chest),
|
||||
data, sf_idx, &harq_process, ra_dl.rv_idx)) {
|
||||
fprintf(stderr, "Error decoding PDSCH\n");
|
||||
goto goout;
|
||||
} else {
|
||||
printf("PDSCH Decoded OK!\n");
|
||||
}
|
||||
} else {
|
||||
printf("Received DCI with no resource allocation\n");
|
||||
}
|
||||
sf_idx = (sf_idx+1)%10;
|
||||
}
|
||||
|
||||
nof_frames++;
|
||||
|
|
|
@ -36,6 +36,7 @@
|
|||
#define CURRENT_SLOTLEN_RE SLOT_LEN_RE(q->cell.nof_prb, q->cell.cp)
|
||||
#define CURRENT_SFLEN_RE SF_LEN_RE(q->cell.nof_prb, q->cell.cp)
|
||||
|
||||
#define MAX_CANDIDATES 64
|
||||
|
||||
int ue_dl_init(ue_dl_t *q,
|
||||
lte_cell_t cell,
|
||||
|
@ -146,17 +147,24 @@ void ue_dl_free(ue_dl_t *q) {
|
|||
LIBLTE_API float mean_exec_time=0;
|
||||
int frame_cnt=0;
|
||||
|
||||
dci_format_t ue_formats[] = {Format1A,Format1}; // Format1B should go here also
|
||||
const uint32_t nof_ue_formats = 2;
|
||||
|
||||
dci_format_t common_formats[] = {Format1A,Format1C};
|
||||
const uint32_t nof_common_formats = 2;
|
||||
|
||||
int ue_dl_decode(ue_dl_t *q, cf_t *input, uint8_t *data, uint32_t sf_idx, uint32_t sfn, uint16_t rnti)
|
||||
{
|
||||
uint32_t cfi, cfi_distance, i;
|
||||
ra_pdsch_t ra_dl;
|
||||
dci_location_t locations[10];
|
||||
dci_location_t locations[MAX_CANDIDATES];
|
||||
dci_msg_t dci_msg;
|
||||
uint32_t nof_locations;
|
||||
uint16_t crc_rem;
|
||||
dci_format_t format;
|
||||
int ret = LIBLTE_ERROR;
|
||||
struct timeval t[3];
|
||||
uint32_t nof_formats;
|
||||
dci_format_t *formats = NULL;
|
||||
|
||||
/* Run FFT for all subframe data */
|
||||
lte_fft_run_sf(&q->fft, input, q->sf_symbols);
|
||||
|
@ -169,7 +177,7 @@ int ue_dl_decode(ue_dl_t *q, cf_t *input, uint8_t *data, uint32_t sf_idx, uint32
|
|||
gettimeofday(&t[2], NULL);
|
||||
get_time_interval(t);
|
||||
mean_exec_time = (float) VEC_CMA((float) t[0].tv_usec, mean_exec_time, frame_cnt);
|
||||
|
||||
|
||||
frame_cnt++;
|
||||
|
||||
|
||||
|
@ -188,28 +196,34 @@ int ue_dl_decode(ue_dl_t *q, cf_t *input, uint8_t *data, uint32_t sf_idx, uint32
|
|||
|
||||
/* Generate PDCCH candidates */
|
||||
if (rnti == SIRNTI) {
|
||||
nof_locations = pdcch_common_locations(&q->pdcch, locations, 10, cfi);
|
||||
format = Format1A;
|
||||
nof_locations = pdcch_common_locations(&q->pdcch, locations, MAX_CANDIDATES, cfi);
|
||||
formats = common_formats;
|
||||
nof_formats = nof_common_formats;
|
||||
} else {
|
||||
nof_locations = pdcch_ue_locations(&q->pdcch, locations, 10, sf_idx, cfi, q->user_rnti);
|
||||
format = Format1;
|
||||
nof_locations = pdcch_ue_locations(&q->pdcch, locations, MAX_CANDIDATES, sf_idx, cfi, q->user_rnti);
|
||||
formats = ue_formats;
|
||||
nof_formats = nof_ue_formats;
|
||||
}
|
||||
|
||||
/* Extract all PDCCH symbols and get LLRs */
|
||||
if (pdcch_extract_llr(&q->pdcch, q->sf_symbols, q->ce, chest_dl_get_noise_estimate(&q->chest), sf_idx, cfi)) {
|
||||
fprintf(stderr, "Error extracting LLRs\n");
|
||||
return LIBLTE_ERROR;
|
||||
}
|
||||
/* For all possible locations, try to decode a DCI message */
|
||||
crc_rem = 0;
|
||||
for (i=0;i<nof_locations && crc_rem != rnti;i++) {
|
||||
if (pdcch_extract_llr(&q->pdcch, q->sf_symbols, q->ce, chest_dl_get_noise_estimate(&q->chest), locations[i], sf_idx, cfi)) {
|
||||
fprintf(stderr, "Error extracting LLRs\n");
|
||||
return LIBLTE_ERROR;
|
||||
for (int f=0;f<nof_formats;f++) {
|
||||
for (i=0;i<nof_locations && crc_rem != rnti;i++) {
|
||||
if (pdcch_decode_msg(&q->pdcch, &dci_msg, &locations[i], formats[f], &crc_rem)) {
|
||||
fprintf(stderr, "Error decoding DCI msg\n");
|
||||
return LIBLTE_ERROR;
|
||||
}
|
||||
INFO("Decoded DCI message RNTI: 0x%x\n", crc_rem);
|
||||
}
|
||||
if (pdcch_decode_msg(&q->pdcch, &dci_msg, format, &crc_rem)) {
|
||||
fprintf(stderr, "Error decoding DCI msg\n");
|
||||
return LIBLTE_ERROR;
|
||||
}
|
||||
INFO("Decoded DCI message RNTI: 0x%x\n", crc_rem);
|
||||
}
|
||||
|
||||
if (crc_rem == rnti) {
|
||||
printf("Hem trobat\n");
|
||||
q->nof_pdcch_detected++;
|
||||
if (dci_msg_to_ra_dl(&dci_msg, rnti, q->user_rnti, q->cell, cfi, &ra_dl)) {
|
||||
fprintf(stderr, "Error unpacking PDSCH scheduling DCI message\n");
|
||||
return LIBLTE_ERROR;
|
||||
|
@ -249,7 +263,7 @@ int ue_dl_decode(ue_dl_t *q, cf_t *input, uint8_t *data, uint32_t sf_idx, uint32
|
|||
q->pkt_errors++;
|
||||
} else if (rnti != SIRNTI) {
|
||||
q->pkt_errors++;
|
||||
}
|
||||
}
|
||||
} else if (ret == LIBLTE_ERROR_INVALID_INPUTS) {
|
||||
fprintf(stderr, "Error calling pdsch_decode()\n");
|
||||
return LIBLTE_ERROR;
|
||||
|
|
|
@ -161,7 +161,8 @@ int ue_mib_decode_aligned_frame(ue_mib_t * q, cf_t *input,
|
|||
if (ret < 0) {
|
||||
return LIBLTE_ERROR;
|
||||
}
|
||||
|
||||
INFO("Channel estimated for %d ports, Noise: %f\n", q->chest.cell.nof_ports,
|
||||
chest_dl_get_noise_estimate(&q->chest));
|
||||
/* Reset decoder if we missed a frame */
|
||||
if ((q->last_frame_trial && (abs(q->frame_cnt - q->last_frame_trial) > 2)) ||
|
||||
q->frame_cnt > 16)
|
||||
|
@ -177,7 +178,7 @@ int ue_mib_decode_aligned_frame(ue_mib_t * q, cf_t *input,
|
|||
|
||||
/* Decode PBCH */
|
||||
ret = pbch_decode(&q->pbch, &q->sf_symbols[SLOT_LEN_RE(q->chest.cell.nof_prb, q->chest.cell.cp)],
|
||||
ce_slot1, chest_dl_get_noise_estimate(&q->chest),
|
||||
ce_slot1, chest_dl_get_noise_estimate(&q->chest),
|
||||
bch_payload, nof_tx_ports, sfn_offset);
|
||||
if (ret < 0) {
|
||||
fprintf(stderr, "Error decoding PBCH (%d)\n", ret);
|
||||
|
@ -256,9 +257,9 @@ int ue_mib_sync_and_decode(ue_mib_t * q,
|
|||
sync_get_sf_idx(&q->sfind) == 0)
|
||||
{
|
||||
INFO("Trying to decode MIB\n",0);
|
||||
printf("caution here should pass begining of frame \n");
|
||||
exit(-1);
|
||||
ret = ue_mib_decode_aligned_frame(q, &signal[nf*MIB_FRAME_SIZE_SEARCH+peak_idx-960], q->bch_payload, &q->nof_tx_ports, &q->sfn_offset);
|
||||
ret = ue_mib_decode_aligned_frame(q,
|
||||
&signal[nf*MIB_FRAME_SIZE_SEARCH+peak_idx-MIB_FRAME_SIZE_SEARCH/10],
|
||||
q->bch_payload, &q->nof_tx_ports, &q->sfn_offset);
|
||||
counter3++;
|
||||
} else if ((ret == LIBLTE_SUCCESS && peak_idx != 0) ||
|
||||
(ret == 1 && nf*MIB_FRAME_SIZE_SEARCH + peak_idx + MIB_FRAME_SIZE_SEARCH/10 > nsamples))
|
||||
|
|
|
@ -189,7 +189,7 @@ int track_peak_ok(ue_sync_t *q, uint32_t track_idx) {
|
|||
q->sf_idx, sync_get_sf_idx(&q->strack), q->strack.m0, q->strack.m0_value, q->strack.m1, q->strack.m1_value);
|
||||
/* FIXME: What should we do in this case? */
|
||||
q->sf_idx = sync_get_sf_idx(&q->strack);
|
||||
q->state = SF_TRACK;
|
||||
q->state = SF_FIND;
|
||||
} else {
|
||||
q->time_offset = ((int) track_idx - (int) CURRENT_FFTSIZE);
|
||||
|
||||
|
|
|
@ -0,0 +1,76 @@
|
|||
filename='../../debug/dist_ra.dat';
|
||||
|
||||
enb.NDLRB = 50;
|
||||
enb.CyclicPrefix = 'Normal';
|
||||
enb.PHICHDuration = 'Normal';
|
||||
enb.CFI = 2;
|
||||
enb.Ng = 'Sixth';
|
||||
enb.CellRefP = 1;
|
||||
enb.NCellID = 196;
|
||||
enb.NSubframe = 5;
|
||||
enb.NTotalSubframes=1;
|
||||
enb.DuplexMode = 'FDD';
|
||||
|
||||
dci.NDLRB = enb.NDLRB;
|
||||
dci.DCIFormat = 'Format1C';
|
||||
dci.AllocationType=1;
|
||||
%dci.Allocation.Bitmap='01111000011110000';
|
||||
%dci.Allocation.Subset=3;
|
||||
dci.Allocation.RIV = 33;
|
||||
dci.Allocation.Gap = 0;
|
||||
dci.ModCoding=6;
|
||||
dci.RV=0;
|
||||
dci.DuplexMode = enb.DuplexMode;
|
||||
dci.NTxAnts = enb.CellRefP;
|
||||
pdcch.RNTI = 65535;
|
||||
pdcch.PDCCHFormat = 3;
|
||||
|
||||
pdsch.Modulation='QPSK';
|
||||
pdsch.RNTI=pdcch.RNTI;
|
||||
if (enb.CellRefP == 1)
|
||||
pdsch.TxScheme='Port0';
|
||||
else
|
||||
pdsch.TxScheme='TxDiversity';
|
||||
end
|
||||
pdsch.NLayers=enb.CellRefP;
|
||||
pdsch.trblklen=176;
|
||||
pdsch.RV=dci.RV;
|
||||
|
||||
% Begin frame generation
|
||||
subframe = lteDLResourceGrid(enb);
|
||||
|
||||
%%% Create Reference Signals
|
||||
rsAnt = lteCellRS(enb);
|
||||
indAnt = lteCellRSIndices(enb);
|
||||
subframe(indAnt) = rsAnt;
|
||||
|
||||
%%% Create PDCCH
|
||||
[dciMessage,dciMessageBits] = lteDCI(enb,dci);
|
||||
codedDciBits = lteDCIEncode(pdcch,dciMessageBits);
|
||||
pdcchInfo = ltePDCCHInfo(enb);
|
||||
pdcchBits = -1*ones(1,pdcchInfo.MTot);
|
||||
candidates = ltePDCCHSpace(enb,pdcch,{'bits','1based'});
|
||||
pdcchBits (candidates(1,1):candidates(1,2)) = codedDciBits;
|
||||
pdcchSymbols = ltePDCCH(enb, pdcchBits);
|
||||
pdcchIndices = ltePDCCHIndices(enb,{'1based'});
|
||||
subframe(pdcchIndices) = pdcchSymbols;
|
||||
|
||||
% Create PDSCH
|
||||
pdsch.prbset = lteDCIResourceAllocation(enb,dci);
|
||||
|
||||
[pdschIndices,pdschInfo] = ltePDSCHIndices(enb,pdsch,pdsch.prbset);
|
||||
|
||||
dlschTransportBlk=randi([0 1],pdsch.trblklen,1);
|
||||
pdschcodeword = lteDLSCH(enb,pdsch,pdschInfo.G,dlschTransportBlk);
|
||||
%crced = lteCRCEncode(dlschTransportBlk, '24A');
|
||||
%encoded = lteTurboEncode(crced);
|
||||
%pdschcodeword2 = lteRateMatchTurbo(encoded,pdschInfo.G,pdsch.RV);
|
||||
pdschSymbols = ltePDSCH(enb,pdsch,pdschcodeword);
|
||||
|
||||
subframe(pdschIndices) = pdschSymbols;
|
||||
|
||||
txwaveform = lteOFDMModulate(enb,subframe);
|
||||
|
||||
write_complex(filename,sum(txwaveform,2));
|
||||
fprintf('Written signal to %s\n',filename);
|
||||
|
Loading…
Reference in New Issue