#include #include #include #include #include #include #include #include "viterbi224.h" #include "fano.h" #include "sim.h" static inline int popcount(int x){ return __builtin_popcount(x); } struct option Options[] = { {"scale",1, NULL, 'S'}, {"delta",1, NULL, 'd'}, {"max-cycles", 1, NULL, 'm'}, {"frame-length",1,NULL,'l'}, {"frame-count",1,NULL,'n'}, {"ebn0",1,NULL,'e'}, {"gain",1,NULL,'g'}, {"verbose",0,NULL,'v'}, {NULL}, }; int Nbits = 1024; // Bits per frame, INCLUDING TAIL that must be 0's double Signal = 30; // Signal amplitude (scaled to 8 bit byte) int Scale = 8; // Fano metric scaling factor const double Rate = 0.5; // Code rate = 1/2 double Ebn0 = 2.0; // Digital signal-to-noise ratio per bit in dB unsigned long Maxcycles = 1000; // Maximum number of decoder moves per bit int Trials = 1000; // Number of frames to test int Verbose; // diag diarrhea int Zerodata; // Use all 0's data (no effect on linear codes) int main(int argc,char *argv[]){ int mettab[2][256]; unsigned char data[Nbits/8],symbols[Nbits*2],decode_data[Nbits/8]; unsigned char xordata[Nbits/8]; unsigned long cycles, metric; int delta = 4; time_t t; int trial,i,r; int errcnt; int fano_good_frames = 0; int fano_failures = 0; int fano_frame_errors = 0; int fano_bit_errors = 0; int viterbi_attempts = 0; int viterbi_good_frames = 0; int viterbi_frame_errors = 0; int viterbi_bit_errors = 0; long totcycles = 0; long histogram[256]; double noise_amp; // Actual noise amplitude, computed from Signal amplitude & Eb/N0 void *vp; while((i = getopt_long(argc,argv,"d:S:l:n:e:s:m:vz",Options,NULL)) != EOF){ switch(i){ case 'd': delta = atoi(optarg); break; case 'S': Scale = atoi(optarg); break; case 'm': Maxcycles = atoi(optarg); break; case 'l': Nbits = atoi(optarg); break; case 'n': Trials = atoi(optarg); break; case 'e': Ebn0 = atof(optarg); break; case 's': Signal = atof(optarg); break; case 'v': Verbose++; break; case 'z': Zerodata++; break; default: printf("Usage: %s [-m maxcycles/bit] [-l bits/frame] [-n numframes] [-e Eb/No] [-s signal_amplitude] [-v] [-z]\n", argv[0]); exit(1); break; } } if(Nbits < 64){ printf("bits/frame must be >= 64\n"); exit(1); } delta *= Scale; // Compute noise voltage. The factor of 2 accounts for BPSK seeing // only half the noise power, and the sqrt() converts power to voltage noise_amp = Signal / sqrt(2*Rate*pow(10.,Ebn0/10.)); gen_met(mettab,Signal,noise_amp,Rate,Scale); // Generate channel transition matrix setup_channel(Signal,noise_amp); printf("Code rate %.2f, Nbits = %d, Maxcycles/bit %ld\n",Rate,Nbits,Maxcycles); printf("Eb/N0 = %.3lf dB, Signal = %lg, Noise = %lg, BER@Eb/N0 = %lg, BER@Es/N0 = %lg\n", Ebn0,Signal,noise_amp,0.5*erfc(pow(10.,Ebn0/20.)),0.5*erfc(sqrt(Rate*pow(10.,Ebn0/10.)))); srandom(time(&t)); memset(histogram,0,sizeof(histogram)); memset(data,0,sizeof(data)); for(trial = 0; trial < Trials; trial++){ if(!Zerodata){ // Generate random data // Note last 3 bytes must be 0 to tail off the encoder for(i=0;i<(Nbits-64)/8;i++) // allow room on end for max length tail data[i] = random() & 0xff; for(;i 2){ printf("Cumulative symbol histogram:\n"); for(i=0;i<256;i++){ printf(" %6ld",histogram[i]); if((i % 16) == 15) putchar('\n'); } } memset(decode_data,0,sizeof(decode_data)); r = fano(&metric,&cycles,decode_data,symbols,Nbits,mettab,delta,Maxcycles); totcycles += cycles; if(r != 0){ ++fano_failures; if(Verbose) printf("trial %d fano: decode failure\n",trial); } else { // Fano finished, look for undetected errors errcnt = 0; for(i=0;i 1){ for(i=0;i 1) printf("trial %d fano: metric = %ld, cycles %ld; data OK\n",trial,metric,cycles); continue; // Fano OK, next frame } } // Fano failed. Try Viterbi viterbi_attempts++; if(Verbose){ printf("Trying Viterbi..."); fflush(stdout); } if((vp = create_viterbi224(Nbits)) == NULL){ printf("create_viterbi224 failed\n"); exit(1); } init_viterbi224(vp,0); // Initialize Viterbi decoder update_viterbi224_blk(vp,symbols,Nbits); // Process symbols chainback_viterbi224(vp,decode_data,Nbits,0); // Viterbi chainback delete_viterbi224(vp); // look for Viterbi errors errcnt = 0; for(i=0;i 1){ for(i=0;i