Commit edf8e6ae authored by Xiwen JIANG's avatar Xiwen JIANG

TDD workaround for EXMIMO2 card

parent 57fdcd58
...@@ -1071,6 +1071,7 @@ set(PHY_SRC ...@@ -1071,6 +1071,7 @@ set(PHY_SRC
${OPENAIR1_DIR}/PHY/MODULATION/slot_fep_mbsfn.c ${OPENAIR1_DIR}/PHY/MODULATION/slot_fep_mbsfn.c
${OPENAIR1_DIR}/PHY/MODULATION/slot_fep_ul.c ${OPENAIR1_DIR}/PHY/MODULATION/slot_fep_ul.c
${OPENAIR1_DIR}/PHY/MODULATION/ul_7_5_kHz.c ${OPENAIR1_DIR}/PHY/MODULATION/ul_7_5_kHz.c
${OPENAIR1_DIR}/PHY/MODULATION/ul_1_4_fs.c
${OPENAIR1_DIR}/PHY/MODULATION/beamforming.c ${OPENAIR1_DIR}/PHY/MODULATION/beamforming.c
${OPENAIR1_DIR}/PHY/MODULATION/compute_bf_weights.c ${OPENAIR1_DIR}/PHY/MODULATION/compute_bf_weights.c
${OPENAIR1_DIR}/PHY/LTE_ESTIMATION/freq_equalization.c ${OPENAIR1_DIR}/PHY/LTE_ESTIMATION/freq_equalization.c
......
...@@ -92,6 +92,8 @@ void do_OFDM_mod(int32_t **txdataF, int32_t **txdata, uint32_t frame,uint16_t ne ...@@ -92,6 +92,8 @@ void do_OFDM_mod(int32_t **txdataF, int32_t **txdata, uint32_t frame,uint16_t ne
void do_OFDM_mod_symbol(LTE_eNB_COMMON *eNB_common_vars, int eNB_id, uint16_t next_slot, LTE_DL_FRAME_PARMS *frame_parms, int antenna); void do_OFDM_mod_symbol(LTE_eNB_COMMON *eNB_common_vars, int eNB_id, uint16_t next_slot, LTE_DL_FRAME_PARMS *frame_parms, int antenna);
void remove_1_4_fs(PHY_VARS_eNB *phy_vars_eNB,uint8_t subframe);
void remove_7_5_kHz(PHY_VARS_eNB *phy_vars_eNB,uint8_t subframe); void remove_7_5_kHz(PHY_VARS_eNB *phy_vars_eNB,uint8_t subframe);
void apply_7_5_kHz(PHY_VARS_UE *phy_vars_ue,int32_t*txdata,uint8_t subframe); void apply_7_5_kHz(PHY_VARS_UE *phy_vars_ue,int32_t*txdata,uint8_t subframe);
......
This source diff could not be displayed because it is too large. You can view the blob instead.
function [] = gen_1_4_fs()
[s6_n2, s6_e2] = gen_sig(6);
[s15_n2, s15_e2] = gen_sig(15);
[s25_n2, s25_e2] = gen_sig(25);
[s50_n2, s50_e2] = gen_sig(50);
[s75_n2, s75_e2] = gen_sig(75);
[s100_n2, s100_e2] = gen_sig(100);
fd=fopen("fs_1_4.h","w");
fprintf(fd,"int16_t s6n_fs_1_4[%d]__attribute__((aligned(16))) = {",length(s6_n2));
fprintf(fd,"%d,",s6_n2(1:(end-1)));
fprintf(fd,"%d};\n\n",s6_n2(end));
fprintf(fd,"int16_t s6e_fs_1_4[%d]__attribute__((aligned(16))) = {",length(s6_e2));
fprintf(fd,"%d,",s6_e2(1:(end-1)));
fprintf(fd,"%d};\n\n",s6_e2(end));
fprintf(fd,"int16_t s15n_fs_1_4[%d]__attribute__((aligned(16))) = {",length(s15_n2));
fprintf(fd,"%d,",s15_n2(1:(end-1)));
fprintf(fd,"%d};\n\n",s15_n2(end));
fprintf(fd,"int16_t s15e_fs_1_4[%d]__attribute__((aligned(16))) = {",length(s15_e2));
fprintf(fd,"%d,",s15_e2(1:(end-1)));
fprintf(fd,"%d};\n\n",s15_e2(end));
fprintf(fd,"int16_t s25n_fs_1_4[%d]__attribute__((aligned(16))) = {",length(s25_n2));
fprintf(fd,"%d,",s25_n2(1:(end-1)));
fprintf(fd,"%d};\n\n",s25_n2(end));
fprintf(fd,"int16_t s25e_fs_1_4[%d]__attribute__((aligned(16))) = {",length(s25_e2));
fprintf(fd,"%d,",s25_e2(1:(end-1)));
fprintf(fd,"%d};\n\n",s25_e2(end));
fprintf(fd,"int16_t s50n_fs_1_4[%d]__attribute__((aligned(16))) = {",length(s50_n2));
fprintf(fd,"%d,",s50_n2(1:(end-1)));
fprintf(fd,"%d};\n\n",s50_n2(end));
fprintf(fd,"int16_t s50e_fs_1_4[%d]__attribute__((aligned(16))) = {",length(s50_e2));
fprintf(fd,"%d,",s50_e2(1:(end-1)));
fprintf(fd,"%d};\n\n",s50_e2(end));
fprintf(fd,"int16_t s75n_fs_1_4[%d]__attribute__((aligned(16))) = {",length(s75_n2));
fprintf(fd,"%d,",s75_n2(1:(end-1)));
fprintf(fd,"%d};\n\n",s75_n2(end));
fprintf(fd,"int16_t s75e_fs_1_4[%d]__attribute__((aligned(16))) = {",length(s75_e2));
fprintf(fd,"%d,",s75_e2(1:(end-1)));
fprintf(fd,"%d};\n\n",s75_e2(end));
fprintf(fd,"int16_t s100n_fs_1_4[%d]__attribute__((aligned(16)))= {",length(s100_n2));
fprintf(fd,"%d,",s100_n2(1:(end-1)));
fprintf(fd,"%d};\n\n",s100_n2(end));
fprintf(fd,"int16_t s100e_fs_1_4[%d]__attribute__((aligned(16)))= {",length(s100_n2));
fprintf(fd,"%d,",s100_e2(1:(end-1)));
fprintf(fd,"%d};\n\n",s100_e2(end));
fclose(fd);
end
function [s_n2, s_e2] = gen_sig(RB)
% 20MHz BW
cp0 = 160;
cp = 144;
cpe = 512;
samplerate = 30.72e6;
ofdm_size = 2048;
len = 15360;
switch(RB)
case 6
ratio = 1/16;
case 15
ratio = 1/8;
case 25
ratio = 1/4;
case 50
ratio = 1/2;
case 75
ratio = 3/4;
case 100
ratio = 1;
otherwise
disp("Wrong Number of RB");
end
cp0 = cp0*ratio;
cp = cp*ratio;
cpe = cpe*ratio;
samplerate = samplerate*ratio;
ofdm_size = ofdm_size*ratio;
len = len*ratio;
s_n0 = floor(32767*exp(-sqrt(-1)*2*pi*(-cp0:ofdm_size-1)*(0.25+7.5e3/samplerate)));
s_n1 = floor(32767*exp(-sqrt(-1)*2*pi*(-cp:ofdm_size-1)*(0.25+7.5e3/samplerate)));
s_n = [s_n0 s_n1 s_n1 s_n1 s_n1 s_n1 s_n1];
s_n2 = zeros(1, 2*len);
s_n2(1:2:end) = real(s_n);
s_n2(2:2:end) = imag(s_n);
s_e = floor(32767*exp(-sqrt(-1)*2*pi*(-cpe:ofdm_size-1)*(0.25+7.5e3/samplerate)));
s_e = [s_e s_e s_e s_e s_e s_e];
s_e2 = zeros(1, 2*len);
s_e2(1:2:end) = real(s_e);
s_e2(2:2:end) = imag(s_e);
end
/*
* Licensed to the OpenAirInterface (OAI) Software Alliance under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The OpenAirInterface Software Alliance licenses this file to You under
* the OAI Public License, Version 1.0 (the "License"); you may not use this file
* except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.openairinterface.org/?page_id=698
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*-------------------------------------------------------------------------------
* For more information about the OpenAirInterface (OAI) Software Alliance:
* contact@openairinterface.org
*/
#include "PHY/defs.h"
#include "PHY/extern.h"
#include "extern.h"
#include "fs_1_4.h"
#include "prach625Hz.h"
#ifdef USER_MODE
#include <math.h>
#else
#include "rtai_math.h"
#endif
#include "PHY/sse_intrin.h"
short conjugate14[8]__attribute__((aligned(16))) = {-1,1,-1,1,-1,1,-1,1} ;
short conjugate14_2[8]__attribute__((aligned(16))) = {1,-1,1,-1,1,-1,1,-1} ;
void remove_1_4_fs(PHY_VARS_eNB *eNB,uint8_t slot)
{
int32_t **rxdata=eNB->common_vars.rxdata[0];
int32_t **rxdata_1_4fs=eNB->common_vars.rxdata_1_4fs[0];
uint16_t len;
uint32_t *fs1_4ptr;
#if defined(__x86_64__) || defined(__i386__)
__m128i *rxptr128,*rxptr128_1_4fs,*fs1_4ptr128,fs1_4_2,mmtmp_re,mmtmp_im,mmtmp_re2,mmtmp_im2;
#elif defined(__arm__)
int16x8_t *rxptr128,*fs1_4ptr128,*rxptr128_1_4fs;
int32x4_t mmtmp_re,mmtmp_im;
int32x4_t mmtmp0,mmtmp1;
#endif
uint32_t slot_offset,slot_offset2;
uint8_t aa;
uint32_t i;
LTE_DL_FRAME_PARMS *frame_parms=&eNB->frame_parms;
switch (frame_parms->N_RB_UL) {
case 6:
fs1_4ptr = (frame_parms->Ncp==0) ? (uint32_t*)s6n_fs_1_4 : (uint32_t*)s6e_fs_1_4;
break;
case 15:
fs1_4ptr = (frame_parms->Ncp==0) ? (uint32_t*)s15n_fs_1_4 : (uint32_t*)s15e_fs_1_4;
break;
case 25:
fs1_4ptr = (frame_parms->Ncp==0) ? (uint32_t*)s25n_fs_1_4 : (uint32_t*)s25e_fs_1_4;
break;
case 50:
fs1_4ptr = (frame_parms->Ncp==0) ? (uint32_t*)s50n_fs_1_4 : (uint32_t*)s50e_fs_1_4;
break;
case 75:
fs1_4ptr = (frame_parms->Ncp==0) ? (uint32_t*)s75n_fs_1_4 : (uint32_t*)s75e_fs_1_4;
break;
case 100:
fs1_4ptr = (frame_parms->Ncp==0) ? (uint32_t*)s100n_fs_1_4 : (uint32_t*)s100e_fs_1_4;
break;
default:
fs1_4ptr = (frame_parms->Ncp==0) ? (uint32_t*)s25n_fs_1_4 : (uint32_t*)s25e_fs_1_4;
break;
}
slot_offset = (uint32_t)slot * frame_parms->samples_per_tti/2-eNB->N_TA_offset;
slot_offset2 = (uint32_t)(slot&1) * frame_parms->samples_per_tti/2;
len = frame_parms->samples_per_tti/2;
for (aa=0; aa<frame_parms->nb_antennas_rx; aa++) {
#if defined(__x86_64__) || defined(__i386__)
rxptr128 = (__m128i *)&rxdata[aa][slot_offset];
rxptr128_1_4fs = (__m128i *)&rxdata_1_4fs[aa][slot_offset2];
fs1_4ptr128 = (__m128i *)fs1_4ptr;
#elif defined(__arm__)
rxptr128 = (int16x8_t *)&rxdata[aa][slot_offset];
rxptr128_1_4fs = (int16x8_t *)&rxdata_1_4fs[aa][slot_offset2];
fs1_4ptr128 = (int16x8_t *)fs1_4ptr;
#endif
// remove 7.5 kHz + 1/4*fs
// if (((slot>>1)&1) == 0) { // apply the sinusoid from the table directly
for (i=0; i<(len>>2); i++) {
#if defined(__x86_64__) || defined(__i386__)
fs1_4_2 = _mm_sign_epi16(*fs1_4ptr128,*(__m128i*)&conjugate14_2[0]);
mmtmp_re = _mm_madd_epi16(*rxptr128,fs1_4_2);
// Real part of complex multiplication (note: fs1_4 signal is conjugated for this to work)
mmtmp_im = _mm_shufflelo_epi16(fs1_4_2,_MM_SHUFFLE(2,3,0,1));
mmtmp_im = _mm_shufflehi_epi16(mmtmp_im,_MM_SHUFFLE(2,3,0,1));
mmtmp_im = _mm_sign_epi16(mmtmp_im,*(__m128i*)&conjugate14[0]);
mmtmp_im = _mm_madd_epi16(mmtmp_im,rxptr128[0]);
mmtmp_re = _mm_srai_epi32(mmtmp_re,15);
mmtmp_im = _mm_srai_epi32(mmtmp_im,15);
mmtmp_re2 = _mm_unpacklo_epi32(mmtmp_re,mmtmp_im);
mmtmp_im2 = _mm_unpackhi_epi32(mmtmp_re,mmtmp_im);
rxptr128_1_4fs[0] = _mm_packs_epi32(mmtmp_re2,mmtmp_im2);
rxptr128++;
rxptr128_1_4fs++;
fs1_4ptr128++;
#elif defined(__arm__)
fs1_4ptr128[0] = vmulq_s16(fs1_4ptr128[0],((int16x8_t*)conjugate14_2)[0]);
mmtmp0 = vmull_s16(((int16x4_t*)rxptr128)[0],((int16x4_t*)fs1_4ptr128)[0]);
//mmtmp0 = [Re(ch[0])Re(rx[0]) Im(ch[0])Im(ch[0]) Re(ch[1])Re(rx[1]) Im(ch[1])Im(ch[1])]
mmtmp1 = vmull_s16(((int16x4_t*)rxptr128)[1],((int16x4_t*)fs1_4ptr128)[1]);
//mmtmp1 = [Re(ch[2])Re(rx[2]) Im(ch[2])Im(ch[2]) Re(ch[3])Re(rx[3]) Im(ch[3])Im(ch[3])]
mmtmp_re = vcombine_s32(vpadd_s32(vget_low_s32(mmtmp0),vget_high_s32(mmtmp0)),
vpadd_s32(vget_low_s32(mmtmp1),vget_high_s32(mmtmp1)));
//mmtmp_re = [Re(ch[0])Re(rx[0])+Im(ch[0])Im(ch[0]) Re(ch[1])Re(rx[1])+Im(ch[1])Im(ch[1]) Re(ch[2])Re(rx[2])+Im(ch[2])Im(ch[2]) Re(ch[3])Re(rx[3])+Im(ch[3])Im(ch[3])]
mmtmp0 = vmull_s16(vrev32_s16(vmul_s16(((int16x4_t*)rxptr128)[0],*(int16x4_t*)conjugate14_2)), ((int16x4_t*)fs1_4ptr128)[0]);
//mmtmp0 = [-Im(ch[0])Re(rx[0]) Re(ch[0])Im(rx[0]) -Im(ch[1])Re(rx[1]) Re(ch[1])Im(rx[1])]
mmtmp1 = vmull_s16(vrev32_s16(vmul_s16(((int16x4_t*)rxptr128)[1],*(int16x4_t*)conjugate14_2)), ((int16x4_t*)fs1_4ptr128)[1]);
//mmtmp1 = [-Im(ch[2])Re(rx[2]) Re(ch[2])Im(rx[2]) -Im(ch[3])Re(rx[3]) Re(ch[3])Im(rx[3])]
mmtmp_im = vcombine_s32(vpadd_s32(vget_low_s32(mmtmp0),vget_high_s32(mmtmp0)),
vpadd_s32(vget_low_s32(mmtmp1),vget_high_s32(mmtmp1)));
//mmtmp_im = [-Im(ch[0])Re(rx[0])+Re(ch[0])Im(rx[0]) -Im(ch[1])Re(rx[1])+Re(ch[1])Im(rx[1]) -Im(ch[2])Re(rx[2])+Re(ch[2])Im(rx[2]) -Im(ch[3])Re(rx[3])+Re(ch[3])Im(rx[3])]
rxptr128_1_4fs[0] = vcombine_s16(vmovn_s32(mmtmp_re),vmovn_s32(mmtmp_im));
rxptr128_1_4fs++;
rxptr128++;
fs1_4ptr128++;
#endif
}
}
}
...@@ -640,6 +640,11 @@ typedef struct { ...@@ -640,6 +640,11 @@ typedef struct {
/// - second index: rx antenna [0..nb_antennas_rx[ /// - second index: rx antenna [0..nb_antennas_rx[
/// - third index: sample [0..] /// - third index: sample [0..]
int32_t **rxdata[3]; int32_t **rxdata[3];
/// \brief Holds the last subframe of received data in time domain after removal of 1/4fs + 7.5kHz frequency offset.
/// - first index: secotr id [0..2] (hard coded)
/// - second index: rx antenna [0..nb_antennas_rx[
/// - third index: sample [0..samples_per_tti[
int32_t **rxdata_1_4fs[3];
/// \brief Holds the last subframe of received data in time domain after removal of 7.5kHz frequency offset. /// \brief Holds the last subframe of received data in time domain after removal of 7.5kHz frequency offset.
/// - first index: secotr id [0..2] (hard coded) /// - first index: secotr id [0..2] (hard coded)
/// - second index: rx antenna [0..nb_antennas_rx[ /// - second index: rx antenna [0..nb_antennas_rx[
......
...@@ -2583,8 +2583,10 @@ void fep0(PHY_VARS_eNB *eNB,int slot) { ...@@ -2583,8 +2583,10 @@ void fep0(PHY_VARS_eNB *eNB,int slot) {
int l; int l;
// printf("fep0: slot %d\n",slot); // printf("fep0: slot %d\n",slot);
if (fp->frame_type == TDD)
remove_7_5_kHz(eNB,(slot&1)+(proc->subframe_rx<<1)); remove_1_4_fs(eNB,(slot&1)+(proc->subframe_rx<<1)); // TDD workaround for EXMIMO2 card
else
remove_7_5_kHz(eNB,(slot&1)+(proc->subframe_rx<<1));
for (l=0; l<fp->symbols_per_tti/2; l++) { for (l=0; l<fp->symbols_per_tti/2; l++) {
slot_fep_ul(fp, slot_fep_ul(fp,
&eNB->common_vars, &eNB->common_vars,
...@@ -2724,8 +2726,14 @@ void eNB_fep_full(PHY_VARS_eNB *eNB) { ...@@ -2724,8 +2726,14 @@ void eNB_fep_full(PHY_VARS_eNB *eNB) {
VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_ENB_SLOT_FEP,1); VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_ENB_SLOT_FEP,1);
start_meas(&eNB->ofdm_demod_stats); start_meas(&eNB->ofdm_demod_stats);
remove_7_5_kHz(eNB,proc->subframe_rx<<1); // TDD workaround for EXMIMO2 card
remove_7_5_kHz(eNB,1+(proc->subframe_rx<<1)); if (fp->frame_type == TDD) {
remove_1_4_fs(eNB,proc->subframe_rx<<1);
remove_1_4_fs(eNB,1+(proc->subframe_rx<<1));
} else {
remove_7_5_kHz(eNB,proc->subframe_rx<<1);
remove_7_5_kHz(eNB,1+(proc->subframe_rx<<1));
}
for (l=0; l<fp->symbols_per_tti/2; l++) { for (l=0; l<fp->symbols_per_tti/2; l++) {
slot_fep_ul(fp, slot_fep_ul(fp,
&eNB->common_vars, &eNB->common_vars,
......
...@@ -32,7 +32,7 @@ eNBs = ...@@ -32,7 +32,7 @@ eNBs =
prefix_type = "NORMAL"; prefix_type = "NORMAL";
eutra_band = 38; eutra_band = 38;
downlink_frequency = 2580000000L; downlink_frequency = 2580000000L;
uplink_frequency_offset = 0; //-120000000; uplink_frequency_offset = -1920000; //-120000000;
Nid_cell = 0; Nid_cell = 0;
N_RB_DL = 25; N_RB_DL = 25;
Nid_cell_mbsfn = 0; Nid_cell_mbsfn = 0;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment