/* Test viterbi decoder speeds */ #include "config.h" #include #include #include #include #include #include #include #include #ifdef HAVE_GETOPT_H #include #endif #include "viterbi224.h" #include "code.h" #include "sim.h" #if HAVE_GETOPT_LONG struct option Options[] = { {"frame-length",1,NULL,'l'}, {"frame-count",1,NULL,'n'}, {"ebn0",1,NULL,'e'}, {"gain",1,NULL,'g'}, {"verbose",0,NULL,'v'}, {NULL}, }; #endif #define RATE (0.5) #define MAXBYTES 10000 double Gain = 24.0; int Verbose = 0; static inline int popcount(int x){ return __builtin_popcount(x); } int main(int argc,char *argv[]){ int i,d,tr; int trials = 10,errcnt,framebits=1024; int tot_errs=0; unsigned char data[MAXBYTES]; unsigned char decoded_data[MAXBYTES]; unsigned char xordata[MAXBYTES]; unsigned char symbols[8*2*MAXBYTES]; void *vp; extern char *optarg; struct rusage start,finish; double extime; double noise,esn0,ebn0; time_t t; int badframes=0; time(&t); srandom(t); ebn0 = -100; #if HAVE_GETOPT_LONG while((d = getopt_long(argc,argv,"l:n:e:g:v",Options,NULL)) != EOF){ #else while((d = getopt(argc,argv,"l:n:e:g:v")) != EOF){ #endif switch(d){ case 'l': framebits = atoi(optarg); break; case 'n': trials = atoi(optarg); break; case 'e': ebn0 = atof(optarg); break; case 'g': Gain = atof(optarg); break; case 'v': Verbose++; break; } } if(framebits > 8*MAXBYTES){ fprintf(stderr,"Frame limited to %d bits\n",MAXBYTES*8); framebits = MAXBYTES*8; } if((vp = create_viterbi224(framebits)) == NULL){ printf("create_viterbi224 failed\n"); exit(1); } if(ebn0 != -100){ esn0 = ebn0 + 10*log10((double)RATE); /* Es/No in dB */ // Compute noise voltage; the sqrt(1/2) term is for BPSK noise = Gain * M_SQRT1_2 / pow(10.,0.05 * esn0); setup_channel(Gain,noise); printf("nframes = %d framesize = %d ebn0 = %.2f dB Gain = %g noise = %g\n",trials,framebits,ebn0,Gain,noise); for(tr=0;tr 1 && errcnt != 0){ printf("frame %d, %d errors: ",tr,errcnt); for(i=0;i 1) printf("nframes = %d framesize = %d ebn0 = %.2f dB Gain = %g\n",trials,framebits,ebn0,Gain); else if(Verbose == 0) printf("BER %d/%d (%.3g) FER %d/%d (%.3g)\n", tot_errs,framebits*trials,tot_errs/((double)framebits*trials), badframes,trials,(double)badframes/trials); else printf("\n"); } else { /* Do time trials */ memset(symbols,128,sizeof(symbols)); printf("Starting time trials\n"); getrusage(RUSAGE_SELF,&start); for(tr=0;tr < trials;tr++){ /* Initialize Viterbi decoder */ init_viterbi224(vp,0); /* Decode block */ update_viterbi224_blk(vp,symbols,framebits); /* Do Viterbi chainback */ chainback_viterbi224(vp,decoded_data,framebits,0); } getrusage(RUSAGE_SELF,&finish); extime = finish.ru_utime.tv_sec - start.ru_utime.tv_sec + 1e-6*(finish.ru_utime.tv_usec - start.ru_utime.tv_usec); printf("Execution time for %d %d-bit frames: %.2f sec\n",trials, framebits,extime); printf("decoder speed: %g bits/s\n",trials*framebits/extime); } delete_viterbi224(vp); exit(0); }