📄 dl_dch.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: C-level Test bed for downlink discrete channel routines | Author: Tommi Makelainen, Nokia/NIST | Date: February 17, 1999 | | History: | June 7, 1999 Tommi Makelainen | Initial version. | */#include <stdio.h>#include <math.h>#include "chcoding.h"#include "chdecoding.h"#include "discmod.h"#include "discdemod.h"#include "channel.h"#include "rake.h"#include "code.h"#include "blockcollect.h"#include "config_wcdma.h"#define INPUT_SIZE 10#define PROB_VECTOR_LEN 2/* ---------------- D E F I N E S ------------------------------------- *//* * Number of simultaneous primary common control physical channels * carrying logical BCCH channel. * I.e. simulation can contain maximum of MAX_CCPCH_INSTANCES base stations. */#define MAX_CCPCH_INSTANCES 4/* ---------------- D A T A T Y P E S ------------------------------- *//* * Data type for primary ccpch data. */struct dl_pri_ccpch_data_type { int channel_instance; /* handle for channel model */ int rake_instance_I; /* handle for I part of received data */ int rake_instance_Q; /* handle for Q part of received data */ int code_instance; /* handle to allocated spreading code */ int pn_code[PRI_CCPCH_SPREADING_FACTOR]; /* spreading code */ int symbuf_instances[SLOTS_IN_FRAME]; /* buffers for slots */};/* * Static data structures to manage simulation model instances. */static enum instance_state dl_pri_ccpch_alloc_list[MAX_CCPCH_INSTANCES];static int general_pri_ccpch_init_flag = FALSE;static struct dl_pri_ccpch_data_type dl_pri_ccpch_data[MAX_CCPCH_INSTANCES];static int pri_ccpch_count = 0;/* * Static vectors for I and Q part slots. * Helpful so we add pilot directly in initialization. */static int I_tmp[ ( CHIP_RATE / FRAMES_IN_SECOND ) / SLOTS_IN_FRAME ];static int Q_tmp[ ( CHIP_RATE / FRAMES_IN_SECOND ) / SLOTS_IN_FRAME ];/* * Chip pattern for a symbol period. */static int pilot_code[] = { };/* -------------------------------------------------------------------- */int dl_pri_ccpch_init( double ch_amplitudes[], /* IN: channel impulse response */ int ch_delays[], /* IN: delay taps in chips */ int nTaps, /* IN: channel imp. response length */ int nImpulse, /* IN: number of channel impulse vectors */ double impulse_prob[], /* IN: channel impulse vector probs. */ int nFrames, /* IN: total number of frames in simulation */ double esno, /* IN: received SNR for a bit */ double power, /* IN: transmission power (in dB) */ double rake_finger_threshold, /* IN: required level for a rake finger output to be added in the combiner */ int nFingers) /* IN: number of rake fingers to use */{ int i, instance; int pilot_bits[PRI_CCPCH_PILOT_BITS]; int pilot_chips[PRI_CCPCH_PILOT_BITS * PRI_CCPCH_SPREADING_FACTOR]; int pilot_len = PRI_CCPCH_PILOT_BITS; /* bits */ int sf = PRI_CCPCH_SPREADING_FACTOR; /* * If first call, initialize static data. */ if (general_pri_ccpch_init_flag == FALSE) { for (i=0; i < MAX_CCPCH_INSTANCES; i++) { dl_pri_ccpch_alloc_list[i] = FREE_INSTANCE; } /* for */ general_pri_ccpch_init_flag = TRUE; } /* if general_init_flag */ /* * Find first free instance number. */ instance = -1; for (i=0; i < MAX_CCPCH_INSTANCES; i++) { if (dl_pri_ccpch_alloc_list[i] == FREE_INSTANCE) { instance = i; break; } } if (instance == -1) return(-1); /* no free instances */ /* * Initialize channel model. */ dl_pri_ccpch_data[instance].channel_instance = wcdma_channel_init(ch_amplitudes, ch_delays, nTaps, nImpulse, impulse_prob, nFrames, esno, power, PRI_CCPCH_SPREADING_FACTOR); /* * Initialize rake receiver. */ dl_pri_ccpch_data[instance].rake_instance_I = wcdma_rake_init(pilot_len, rake_finger_threshold, nFingers); dl_pri_ccpch_data[instance].rake_instance_Q = wcdma_rake_init(pilot_len, rake_finger_threshold, nFingers); /* * Get spreading code. */ dl_pri_ccpch_data[instance].code_instance = wcdma_code_init(sf); wcdma_ovsf_code(dl_pri_ccpch_data[instance].code_instance, dl_pri_ccpch_data[instance].pn_code); /* * Set pilot chips for the slots. * On default pilot bits are all 0's. */ for (i=0; i < pilot_len; i++) pilot_bits[i] = 0; wcdma_spread(pilot_bits, pilot_len, pilot_code, sf, sf, pilot_chips); memcpy(I_tmp, pilot_chips, pilot_len * sf * sizeof(int) ); memcpy(Q_tmp, pilot_chips, pilot_len * sf * sizeof(int) ); /* * Update primary ccpch allocation list. */ dl_pri_ccpch_alloc_list[instance] = INSTANCE_IN_USE; pri_ccpch_count++; return(instance);} /* dl_pri_ccpch_init *//* -------------------------------------------------------------------- *//* * Function: dl_pri_ccpch_free * Desc.: channel clear function. * * Note: */int dl_pri_ccpch_free(int instance){ wcdma_rake_free(dl_pri_ccpch_data[instance].rake_instance_I); wcdma_rake_free(dl_pri_ccpch_data[instance].rake_instance_Q); wcdma_code_free(dl_pri_ccpch_data[instance].code_instance); wcdma_channel_free(dl_pri_ccpch_data[instance].channel_instance); dl_pri_ccpch_alloc_list[instance] = FREE_INSTANCE; pri_ccpch_count--; return(0);}/* -------------------------------------------------------------------- */int dl_pri_ccpch_xmit( int instance, /* IN: instance number */ int inData_for_slots[], /* IN: input data bits for each 16 slots given separately */ int outI_TxChips[], /* OUT: I parts of output chips */ int outQ_TxChips[]) /* OUT: Q parts of output chips */{ int i, j, k, m; int bcch_data_len = PRI_CCPCH_BITS_IN_SLOT - PRI_CCPCH_PILOT_BITS; int chips_per_slot = ( CHIP_RATE / FRAMES_IN_SECOND ) / SLOTS_IN_FRAME; /* 2560 (bcch_data_len+pilot_len)*pn_code_len/2 */ int pilot_offset = PRI_CCPCH_PILOT_BITS * PRI_CCPCH_SPREADING_FACTOR / 2; int pn_code_len = PRI_CCPCH_SPREADING_FACTOR; int *pn_code; /* * Get data for this instance. */ pn_code = dl_pri_ccpch_data[instance].pn_code; for (i=0; i < SLOTS_IN_FRAME; i++) { /* * Modulate and spread with channelization code 'pn_code'. * The start of I_tmp and Q_tmp contains preset pilot symbols. */ wcdma_dl_mod(inData_for_slots+i*PRI_CCPCH_BITS_IN_SLOT, bcch_data_len, pn_code, pn_code_len, pn_code_len, I_tmp+pilot_offset, Q_tmp+pilot_offset);#ifdef DO_DL_SCRAMBLING /* * Scramble I and Q parts separately. */ wcdma_spread(I_tmp, chips_per_slots, scrambling_code, scrambling_code_len, sf, outI_TxChips+i*sf*PRI_CCPCH_BITS_IN_SLOT); wcdma_spread(Q_tmp, chips_per_slots, scrambling_code, scrambling_code_len, sf, outQ_TxChips+i*sf*PRI_CCPCH_BITS_IN_SLOT);#endif /* DO_DL_SCRAMBLING */ /* * Pulse shaping filter root-raised cosine with roll-off 0.22. */ } /* for SLOTS_IN_FRAME */} /* dl_pri_ccpch_xmit *//* -------------------------------------------------------------------- */int dl_pri_ccpch_rcv( int instance, /* IN: instance number */ double ch_amplitudes[], /* IN: channel amplitudes */ int ch_delays[], /* IN: channel estimate delays */ int nTaps, /* IN: length of channel estimate */ double inI_RxChips[], /* IN: I parts of input chips */ double inQ_RxChips[], /* IN: Q parts of input chips */ double out_soft_bits[]) /* OUT: output data bits */{ int sf; int rake_instance_I, rake_instance_Q; int symbuf_instance; int *pn_code; int pn_code_len; int pilot_offset = PRI_CCPCH_PILOT_BITS * PRI_CCPCH_SPREADING_FACTOR / 2; int nI_mod_symbols, nQ_mod_symbols; double I_mod_symbols[PRI_CCPCH_BITS_IN_SLOT/2]; double Q_mod_symbols[PRI_CCPCH_BITS_IN_SLOT/2]; double rx_soft_bits[PRI_CCPCH_BITS_IN_SLOT * SLOTS_IN_FRAME]; int delay_I, delay_Q; int i; int j; /* * Get data for this instance. */ sf = PRI_CCPCH_SPREADING_FACTOR; pn_code_len = PRI_CCPCH_SPREADING_FACTOR; pn_code = dl_pri_ccpch_data[instance].pn_code; rake_instance_I = dl_pri_ccpch_data[instance].rake_instance_I; rake_instance_Q = dl_pri_ccpch_data[instance].rake_instance_Q; for (i=0, j=0; i < SLOTS_IN_FRAME; i++) { /* * Collect single user multipath components and despread them * separately for I and Q parts. */ wcdma_rake_receiver(rake_instance_I, inI_RxChips+i*sf*PRI_CCPCH_BITS_IN_SLOT/2+pilot_offset, sf*PRI_CCPCH_BITS_IN_SLOT/2, pn_code, pn_code_len, sf, ch_delays, ch_amplitudes, nTaps, &nI_mod_symbols, &delay_I, I_mod_symbols); wcdma_rake_receiver(rake_instance_Q, inQ_RxChips+i*sf*PRI_CCPCH_BITS_IN_SLOT/2+pilot_offset, sf*PRI_CCPCH_BITS_IN_SLOT/2, pn_code, pn_code_len, sf, ch_delays, ch_amplitudes, nTaps, &nQ_mod_symbols, &delay_Q, Q_mod_symbols); /* * Demodulate. */ for (i=0; i < (PRI_CCPCH_BITS_IN_SLOT/2); i++, j += 2) { out_soft_bits[j] = I_mod_symbols[i]; out_soft_bits[j+1] = Q_mod_symbols[i]; } } /* for SLOTS_IN_FRAME */} /* dl_pri_ccpch_rcv */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -