#ifndef DF_EQUALIZER_H
#define DF_EQUALIZER_H
#include "hw_def.h"

#ifndef IS_PIPELINE
#ifndef IS_BARE

#define MAX_MDFT 75
#define MAX_LAYER 2
#define MAX_SLOT 2
#define MAX_SYM 14
#define MAX_RX_ANT 2
#define MAX_SIZE MAX_LAYER

struct hwComplex
{
    float re;
    float im;
};


hwComplex hwConj(hwComplex a);
hwComplex hwAdd(hwComplex a, hwComplex b);
hwComplex hwSub(hwComplex a, hwComplex b);
hwComplex hwMul(hwComplex a, hwComplex b);
hwComplex hwDiv(hwComplex a, hwComplex b);


void hwMatrixInv(int sz,
                 hwComplex pM[MAX_LAYER][MAX_LAYER],
                 hwComplex pInvM[MAX_LAYER][MAX_LAYER]);

void hardware_FDLSEqualization(
        hwComplex hardware_pInpData[MAX_SYM*MAX_LAYER][MAX_MDFT],
        hwComplex hardware_pEqW[MAX_MDFT][MAX_LAYER][MAX_RX_ANT],
        hwComplex hardware_pHdm[MAX_MDFT][MAX_RX_ANT][MAX_LAYER],
        hwComplex hardware_pHTranspose[MAX_LAYER][MAX_RX_ANT],
        hwComplex hardware_pOutData[MAX_SYM*MAX_LAYER][MAX_MDFT],
        int m,
        int NumLayer,
        int NumRxAntenna,
        int NumULSymbSF);

void hardware_FDLSEstimation(
        hwComplex pXt[2][MAX_LAYER],
        hwComplex pXtDagger[MAX_LAYER][2],
        hwComplex pYt[2][MAX_RX_ANT],
        hwComplex pHTranspose[MAX_LAYER][MAX_RX_ANT],
        int NumLayer,
        int NumRxAntenna);

void hardware_Equalizer(
        hwComplex hardware_pDMRS[MAX_SLOT][MAX_LAYER][MAX_MDFT],
        hwComplex hardware_pInpData[MAX_SYM*MAX_LAYER][MAX_MDFT],
        hwComplex hardware_pEqW[MAX_MDFT][MAX_LAYER][MAX_RX_ANT],
        hwComplex hardware_pHdm[MAX_MDFT][MAX_RX_ANT][MAX_LAYER],
        hwComplex hardware_pOutData[MAX_SYM*MAX_LAYER][MAX_MDFT],
        int MDFT,
        int NumLayer,
        int NumRxAntenna,
        int NumULSymbSF);


#endif
#endif


#endif // DF_EQUALIZER_H
