📄 interleaver.c
字号:
/* | | Copyright disclaimer: | This software was developed at the National Institute of Standards | and Technology by employees of the Federal Government in the course | of their official duties. Pursuant to title 17 Section 105 of the | United States Code this software is not subject to copyright | protection and is in the public domain. | | We would appreciate acknowledgement if the software is used. |*//* | Project: WCDMA simulation environment | Module: Interleaving routines. | Author: Tommi Makelainen | Date: January 26, 1999 | | History: | January 26, 1999 Tommi Makelainen | Initial version. */#include <stdlib.h> #include <stdio.h>#include "interleaver.h"#include "config_wcdma.h" /* ------------------------------------------------------------------- *//* * Function: wcdma_block_interleaver * Desc.: Block (B,N) interleaver, where * B = input_column_size (i.e. number of rows) and * N = output_row_size (i.e. number of columns). * * Note: * Input data is a vector, where input columns are * sequentially ordered. * I.e. input_data[] = {column1, column2, ..., columnN}. */void wcdma_block_interleaver( int input_column_size, /* size of single input column to write in */ int output_row_size, /* size of single output row to read */ int input_data[], /* vector of input data bits */ int output_data[]) /* vector of output data bits */{ int col_index, row_index, input_index, output_index; /* * Input data vector is B columns, and we read it as N rows. */ output_index = 0; for (row_index=0; row_index < input_column_size; row_index++) { for (col_index=0; col_index < output_row_size; col_index++) { input_index = row_index + col_index*input_column_size; output_data[output_index++] = input_data[input_index]; } } return;} /* wcdma_block_interleaver *//* ------------------------------------------------------------------- *//* * Function: wcdma_block_deinterleaver * Desc.: Block (N,B) deinterleaver, where * B = output_column_size (i.e. number of rows), * which is number of columns for the corresponding * interleaver and * N = input_row_size (i.e. number of columns). * * Note: * Input data is a vector, where input rows sequentially ordered. * I.e. input_data[] = {row1, row2, ..., rowN}. */void wcdma_block_deinterleaver( int input_row_size, /* size of single input row to write in */ int output_column_size, /* size of single output column to read */ int input_data[], /* vector of input data bits */ int output_data[]) /* vector of output data bits */{ int col_index, row_index, input_index, output_index; /* * Input data vector is N rows, and we read it as B columns. */ output_index = 0;#if 0 for (row_index=0; row_index < output_column_size; row_index++) { for (col_index=0; col_index < input_row_size; col_index++) { input_index = row_index + col_index*output_column_size; output_data[output_index++] = input_data[input_index]; } }#endif for (col_index=0; col_index < input_row_size; col_index++) { for (row_index=0; row_index < output_column_size; row_index++) { input_index = col_index + row_index*input_row_size; output_data[output_index++] = input_data[input_index]; } } return;} /* wcdma_block_deinterleaver *//* ------------------------------------------------------------------- *//* * Function: wcdma_conv_interleaver * Desc.: Convolutional (B,N) interleaver, where * B = no_banks and * N = shift_reg_len * no of shift register banks (no_banks). */void wcdma_conv_interleaver( int shift_reg_len, /* length of a single shift register */ int no_banks, /* number of shift register banks */ int input_data[], /* vector of input data bits */ int output_data[]) /* vector of output data bits */{ /* not implemented yet */ fprintf(stderr, "Convolutional interleaving is not available\n"); return;}/* ------------------------------------------------------------------- *//* * Function: wcdma_conv_deinterleaver * Desc.: Convolutional (B,N) deinterleaver, where * B = no_banks and * N = shift_reg_len * no of shift register banks (no_banks). */void wcdma_conv_deinterleaver( int shift_reg_len, /* length of a single shift register */ int no_banks, /* number of shift register banks */ int input_data[], /* vector of input data bits */ int output_data[]) /* vector of output data bits */{ /* not implemented yet */ fprintf(stderr, "Convolutional de-interleaving is not available\n"); return;}/* ------------------------------------------------------------------- *//* * Function: wcdma_block_float_interleaver * Desc.: Block (B,N) floating point interleaver, where * B = input_column_size and * N = output_row_size. * * Note: * Input data is a vector, where input columns are * sequentially ordered. * I.e. input_data[] = {column1, column2, ..., columnN}. */void wcdma_block_float_interleaver( int input_column_size, /* size of single input column to write in */ int output_row_size, /* size of single output row to read */ double input_data[], /* vector of input data bits */ double output_data[]) /* vector of output data bits */{ int col_index, row_index, input_index, output_index; /* * Input data vector is B columns, and we read it as N rows. */ output_index = 0; for (row_index=0; row_index < input_column_size; row_index++) { for (col_index=0; col_index < output_row_size; col_index++) { input_index = row_index + col_index*input_column_size; output_data[output_index++] = input_data[input_index]; } } return;} /* wcdma_block_float_interleaver *//* ------------------------------------------------------------------- *//* * Function: wcdma_block_float_deinterleaver * Desc.: Block (N,B) floating point deinterleaver, where * B = output_column_size and * N = input_row_size. * * Note: * Input data is a vector, where input rows sequentially ordered. * I.e. input_data[] = {row1, row2, ..., rowN}. */void wcdma_block_float_deinterleaver( int input_row_size, /* size of single input row to write in */ int output_column_size, /* size of single output column to read */ double input_data[], /* vector of input data bits */ double output_data[]) /* vector of output data bits */{ int col_index, row_index, input_index, output_index; /* * Input data vector is N rows, and we read it as B columns. */ output_index = 0;#if 0 for (row_index=0; row_index < output_column_size; row_index++) { for (col_index=0; col_index < input_row_size; col_index++) { input_index = row_index + col_index*output_column_size; output_data[output_index++] = input_data[input_index]; } }#endif for (col_index=0; col_index < input_row_size; col_index++) { for (row_index=0; row_index < output_column_size; row_index++) { input_index = col_index + row_index*input_row_size; output_data[output_index++] = input_data[input_index]; } } return;} /* wcdma_block_float_deinterleaver *//* ------------------------------------------------------------------- *//* * Function: wcdma_multistage_interleaver * Desc.: * Do multistage interleaving (MIL) for incoming data. * Start multistage by checking what is the biggest * power of 2 (e.g. 4,8,16,32) that divides the incoming * data block evenly (e.g. (nBits % 2^X) == 0 ). * If 32 is applicable, do N*32 outer block interleaving. * Otherwise perform N*16. Continue dividing * interleaver to smaller stages recursively * until all columns and rows are either 2 or 3. * On these stages use the largest powers of 2, which * produces integer division for row and column numbers. * e.g. 32[8[4[2x2]x2]x4[2x2]] * where L[NxM] means block size L, N rows and M columns. *
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -