Commit ca7d4208 authored by yihongzheng's avatar yihongzheng

yihz LDPC FPGA and .so can run

parent 278bfa8d
......@@ -23,6 +23,7 @@
#ifndef __NRLDPC_DEFS__H__
#define __NRLDPC_DEFS__H__
#include "openair1/PHY/CODING/nrLDPC_decoder/nrLDPC_types.h"
#include "openair1/PHY/NR_TRANSPORT/ldpc_fpga_entx.h"
/**
\brief LDPC encoder
\param 1 input
......@@ -46,6 +47,9 @@ typedef struct {
}encoder_implemparams_t;
#define INIT0_LDPCIMPLEMPARAMS {0,0,0,NULL,NULL,NULL,NULL}
typedef int(*nrLDPC_encoderfunc_t)(unsigned char **,unsigned char **,int,int,short, short, encoder_implemparams_t*);
typedef int(*LDPC_FPGA_EnTx_Test)(int , int);
typedef int(*LDPC_FPGA_HugePage_Init)(int);
typedef int(*LDPC_FPGA_EnTx)( EncodeInHeaderStruct *pHeader, unsigned char * pSrc, unsigned char * pDst );
//============================================================================================================================
// decoder interface
/**
......@@ -56,4 +60,5 @@ typedef int(*nrLDPC_encoderfunc_t)(unsigned char **,unsigned char **,int,int,sho
\param p_profiler LDPC profiler statistics
*/
typedef int32_t(*nrLDPC_decoderfunc_t)(t_nrLDPC_dec_params* , int8_t*, int8_t* , t_nrLDPC_procBuf* , t_nrLDPC_time_stats* );
// extern int (*add)(int aa, int bb);
#endif
\ No newline at end of file
......@@ -23,6 +23,9 @@
#ifdef LDPC_LOADER
nrLDPC_decoderfunc_t nrLDPC_decoder;
nrLDPC_encoderfunc_t nrLDPC_encoder;
LDPC_FPGA_EnTx_Test add;
LDPC_FPGA_HugePage_Init HugePage_Init;
LDPC_FPGA_EnTx encoder_load;
#else
/* functions to load the LDPC shared lib, implemented in openair1/PHY/CODING/nrLDPC_load.c */
extern int load_nrLDPClib(void) ;
......@@ -30,6 +33,9 @@ extern int load_nrLDPClib_ref(char *libversion, nrLDPC_encoderfunc_t * nrLDPC_en
/* ldpc coder/decoder functions, as loaded by load_nrLDPClib(). */
extern nrLDPC_decoderfunc_t nrLDPC_decoder;
extern nrLDPC_encoderfunc_t nrLDPC_encoder;
extern LDPC_FPGA_EnTx_Test add;
extern LDPC_FPGA_HugePage_Init HugePage_Init;
extern LDPC_FPGA_EnTx encoder_load;
// inline functions:
#include "openair1/PHY/CODING/nrLDPC_decoder/nrLDPC_init_mem.h"
#endif
\ No newline at end of file
......@@ -39,6 +39,17 @@
#include "PHY/CODING/nrLDPC_extern.h"
#include "common/config/config_userapi.h"
#include "common/utils/load_module_shlib.h"
#include <stdio.h>
#include <pthread.h>
#include <string.h>
#include <sys/mman.h>
#include <unistd.h>
#include <hugetlbfs.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <errno.h>
#include <sys/time.h>
#include <dlfcn.h>
/* function description array, to be used when loading the encoding/decoding shared lib */
......@@ -58,6 +69,44 @@ int load_nrLDPClib(void) {
AssertFatal( (ret >= 0),"Error loading ldpc decoder");
nrLDPC_decoder = (nrLDPC_decoderfunc_t)shlib_fdesc[0].fptr;
nrLDPC_encoder = (nrLDPC_encoderfunc_t)shlib_fdesc[1].fptr;
//手动加载指定位置的so动态库
void *handle = dlopen("/home/witcomm/work/yihz_5gran/FecDemo/cDemo2/ldpc_fpga_encode.so", RTLD_LAZY|RTLD_NODELETE|RTLD_GLOBAL);
if(!handle){
printf("open ldpc_fpga_encode error!\n");
return -1;
}
// int (*add)(int aa, int bb);
//根据动态链接库操作句柄与符号,返回符号对应的地址
add = (LDPC_FPGA_EnTx_Test) dlsym(handle, "add");
if(!add){
printf("FPGA loading add error!\n");
dlclose(handle);
return -1;
}
#if 1
HugePage_Init = (LDPC_FPGA_HugePage_Init) dlsym(handle, "HugePage_Init");
if(!HugePage_Init){
printf("FPGA loading HugePage_Init error!\n");
dlclose(handle);
return -1;
}
int HP = HugePage_Init(1);
if(HP){
printf("HugePage_Init error!\n");
}
encoder_load = (LDPC_FPGA_EnTx) dlsym(handle, "encoder_load");
if(!encoder_load){
printf("FPGA loading encoder_load error!\n");
dlclose(handle);
return -1;
}
#endif
int sum = add(7, 8);
printf("7+8 = %d\n", sum);
return 0;
}
......
//LDPC FPGA加速接口头部定义
typedef struct{
/*Word 0*/
uint32_t pktType :8; //0x12
uint32_t rsv0 :8; //空
uint32_t chkCode :16; //0xFAFA
/*Word 1*/
uint32_t pktLen :21; //Byte,pktLen=encoder header(32byte)+ tbszie (byte),并且32Byte对齐,是32的整数倍
uint32_t rsv1 :11;
/*Word 2*/
uint32_t rsv2 :28;
uint32_t sectorId :2; //=0表示单小区
uint32_t rsv3 :2;
/*Word 3*/
uint32_t sfn :10; //每次都不一样
uint32_t rsv4 :2;
uint32_t subfn :4; //=slotNum/2
uint32_t slotNum :5;
uint32_t pduIdx :9; //=0表示第一个码字,总共一个码字
uint32_t rev5 :2;
/*Word 4*/
uint32_t tbSizeB :18;
uint32_t rev6 :2;
uint32_t lastTb :1; //=1表示本slot只有一个TB
uint32_t firstTb :1; //=1表示本slot只有一个TB
uint32_t rev7 :2;
uint32_t cbNum :8;
/*Word 5*/
uint32_t qm :3; //规定是BPSK qm=0,QPSK qm=1,其他floor(调制阶数/2)
uint32_t rev8 :1;
uint32_t fillbit :14;
uint32_t rev9 :2;
uint32_t kpInByte :11;
uint32_t rev10 :1;
/*Word 6*/
uint32_t gamma :8;
uint32_t codeRate :6; //For LDPC base graph 1, a matrix of has 46 rows ,For LDPC base graph 2, a matrix of has 42 rows(看bg)
uint32_t rev11 :2;
uint32_t rvIdx :2;
uint32_t rev12 :6;
uint32_t lfSizeIx :3; //由lfSizeIx(列)和iLs(行)找到Zc
uint32_t rev13 :1;
uint32_t iLs :3;
uint32_t bg :1; //规定选择协议base grape1 bg=0; base grape2 bg=1
/*Word 7*/
uint32_t e1 :16;
uint32_t e0 :16;
}EncodeInHeaderStruct;
......@@ -102,4 +102,6 @@ void dump_pdsch_stats(PHY_VARS_gNB *gNB);
void clear_pdsch_stats(PHY_VARS_gNB *gNB);
void dl_find_iLS_lsIndex(unsigned int *LDPC_lifting_size, uint32_t *iLS_out, uint32_t *lsIndex_out);
#endif
......@@ -29,6 +29,18 @@
* \note
* \warning
*/
#include <stdio.h>
#include <stdlib.h>
#include <pthread.h>
#include <string.h>
#include <sys/mman.h>
#include <unistd.h>
#include <hugetlbfs.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <errno.h>
#include <sys/time.h>
#include "PHY/defs_gNB.h"
#include "PHY/phy_extern.h"
......@@ -44,6 +56,9 @@
#include "common/utils/LOG/vcd_signal_dumper.h"
#include "common/utils/LOG/log.h"
#include <syscall.h>
#include <dlfcn.h>
#include <dev2.0/logger_wrapper.h>
#include <dev2.0/fec_c_if.h>
//#define DEBUG_DLSCH_CODING
//#define DEBUG_DLSCH_FREE 1
......@@ -262,7 +277,23 @@ int nr_dlsch_encoding(PHY_VARS_gNB *gNB,
uint16_t R=rel15->targetCodeRate[0];
float Coderate = 0.0;
uint8_t Nl = 4;
#if 1
static uint32_t dl_encode_count = 0;
uint32_t dl_encode_count_set2 = 9;
EncodeInHeaderStruct EncodeHead;
uint8_t *pEnDataIn = NULL;
uint8_t *pEnDataOut = NULL;
static uint32_t iLS = 0;
static uint32_t lsIndex = 0;
uint32_t *iLS_out = &iLS;
uint32_t *lsIndex_out = &lsIndex;
uint32_t dl_E0 = 0, dl_E1 = 0;
uint32_t *dl_e0 = &dl_E0, *dl_e1 = &dl_E1;
pEnDataIn = a;
// int sum = add(7, 8);
// printf("7+8 = %d\n", sum);
#endif
VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_gNB_DLSCH_ENCODING, VCD_FUNCTION_IN);
A = rel15->TBSize[0]<<3;
......@@ -456,8 +487,105 @@ int nr_dlsch_encoding(PHY_VARS_gNB *gNB,
r_offset += E;
}
#if 1
if(dl_encode_count == dl_encode_count_set2){
//word 0
EncodeHead.pktType = 0x12;
EncodeHead.rsv0 = 0x00;
EncodeHead.chkCode = 0xFAFA;
//word 1
EncodeHead.pktLen = 32+((EncodeHead.tbSizeB+32-1)/32)*32;
//Byte,pktLen=encoder header(32byte)+ tbszie (byte),并且32Byte对齐,是32的整数倍
EncodeHead.rsv1 = 0x0000;
//word 2
EncodeHead.rsv2 = 0x0;
EncodeHead.sectorId = 0x0;
//=0表示单小区
EncodeHead.rsv3 = 0x0;
//word 3
EncodeHead.sfn = frame;
EncodeHead.rsv4 = 0x0;
EncodeHead.subfn = EncodeHead.slotNum/2;
EncodeHead.slotNum = slot;
EncodeHead.pduIdx = 0x0;
//=0表示第一个码字,总共一个码字
EncodeHead.rev5 = 0x0;
//word 4
EncodeHead.tbSizeB = rel15->TBSize[0];
EncodeHead.rev6 = 0x0;
EncodeHead.lastTb = 0x1;
EncodeHead.firstTb = 0x1;
//=1表示本slot只有一个TB
EncodeHead.rev7 = 0x0;
EncodeHead.cbNum = harq->C;
//word 5
EncodeHead.qm = stats->current_Qm/2;
//规定是BPSK qm=0,QPSK qm=1,其他floor(调制阶数/2);OAI的Qm为2/4/6/8
EncodeHead.rev8 = 0x0;
EncodeHead.fillbit = harq->F;
EncodeHead.rev9 = 0x0;
if( EncodeHead.cbNum == 1){
EncodeHead.kpInByte = ((harq->B)/ EncodeHead.cbNum)>>3;
}
else{
EncodeHead.kpInByte = ((harq->B+(( EncodeHead.cbNum)*24))/ EncodeHead.cbNum)>>3;
}
EncodeHead.rev10 = 0x0;
//word 6
EncodeHead.gamma = EncodeHead.cbNum - (G/(rel15->nrOfLayers*(2*EncodeHead.qm)))%EncodeHead.cbNum;
//=1表示本slot只有一个TB
EncodeHead.rev11 = 0x0;
EncodeHead.rvIdx = rel15->rvIndex[0];
EncodeHead.rev12 = 0x0;
//查找iLS和lfSizeIx
dl_find_iLS_lsIndex(Zc, iLS_out, lsIndex_out);
EncodeHead.iLs = *iLS_out;
EncodeHead.lfSizeIx = *lsIndex_out;
EncodeHead.rev13 = 0x0;
// EncodeHead.iLs = *iLS_out;
EncodeHead.bg = harq->BG-1; //规定选择协议base grape1 bg=0; base grape2 bg=1;OAI的BG大了1
if( EncodeHead.bg == 0){
EncodeHead.codeRate = 46;
}
else{
EncodeHead.codeRate = 42;
}
//word 7
//计算并获得e0和e1
nr_get_E0_E1(G, harq->C, mod_order, rel15->nrOfLayers, r, dl_e0, dl_e1);
EncodeHead.e0 = *dl_e0;
EncodeHead.e1 = *dl_e1;
printf("EncodeHead_fill_finished\n");
encoder_load( &EncodeHead, pEnDataIn, pEnDataOut );
LOG_M("pEnDataOut.m","pEnDataOut", pEnDataOut, G+32, 1, 9);
}
dl_encode_count++; //count +1 after encoding
#endif
VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_gNB_DLSCH_ENCODING, VCD_FUNCTION_OUT);
return 0;
}
void dl_find_iLS_lsIndex(unsigned int *LDPC_lifting_size, uint32_t *iLS_out, uint32_t *lsIndex_out)
{
unsigned int Set_of_LDPC_lifting_size[8][8] = {
{2,4,8,16,32,64,128,256},
{3,6,12,24,48,96,192,384},
{5,10,20,40,80,160,320},
{7,14,28,56,112,224},
{9,18,36,72,144,288},
{11,22,44,88,176,352},
{13,26,52,104,208},
{15,30,60,120,240}};
uint32_t iLS,lsIndex;
for(iLS = 0; iLS < 8; iLS++) {
for(lsIndex = 0; lsIndex < 8; lsIndex++){
if(*LDPC_lifting_size == Set_of_LDPC_lifting_size[iLS][lsIndex]){
*iLS_out = iLS;
*lsIndex_out = lsIndex;
}
}
}
}
\ No newline at end of file
......@@ -54,3 +54,26 @@ uint32_t nr_get_E(uint32_t G, uint8_t C, uint8_t Qm, uint8_t Nl, uint8_t r) {
return E;
}
void nr_get_E0_E1(uint32_t G, uint8_t C, uint8_t Qm, uint8_t Nl, uint8_t r, uint32_t *E0, uint32_t *E1) {
uint8_t Cprime = C; //assume CBGTI not present
AssertFatal(Nl>0,"Nl is 0\n");
AssertFatal(Qm>0,"Qm is 0\n");
LOG_D(PHY,"nr_get_E_ldpc_high_speed : (G %d, C %d, Qm %d, Nl %d, r %d)\n",G, C, Qm, Nl, r);
// LOG_I(PHY,"nr_get_E : (G %d, C %d, Qm %d, Nl %d, r %d)\n",G, C, Qm, Nl, r);
// printf("E0: %d, ;E1: %d\n", Nl*Qm*(G/(Nl*Qm*Cprime)), Nl*Qm*((G+(Nl*Qm*Cprime-1))/(Nl*Qm*Cprime)));
*E0 = Nl*Qm*(G/(Nl*Qm*Cprime));
*E1 = Nl*Qm*((G+(Nl*Qm*Cprime-1))/(Nl*Qm*Cprime));
// if (r <= Cprime - ((G/(Nl*Qm))%Cprime) - 1)
// {
// *E0 = Nl*Qm*(G/(Nl*Qm*Cprime));
// }
// else
// {
// *E1 = Nl*Qm*((G+(Nl*Qm*Cprime-1))/(Nl*Qm*Cprime));
// }
}
\ No newline at end of file
......@@ -60,6 +60,8 @@ uint32_t nr_get_G(uint16_t nb_rb, uint16_t nb_symb_sch, uint8_t nb_re_dmrs, uint
uint32_t nr_get_E(uint32_t G, uint8_t C, uint8_t Qm, uint8_t Nl, uint8_t r);
void nr_get_E0_E1(uint32_t G, uint8_t C, uint8_t Qm, uint8_t Nl, uint8_t r, uint32_t *E0, uint32_t *E1);
uint8_t nr_get_Qm_ul(uint8_t Imcs, uint8_t table_idx);
uint8_t nr_get_Qm_dl(uint8_t Imcs, uint8_t table_idx);
......
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