139 lines
		
	
	
		
			3.1 KiB
		
	
	
	
		
			Plaintext
		
	
	
	
	
	
			
		
		
	
	
			139 lines
		
	
	
		
			3.1 KiB
		
	
	
	
		
			Plaintext
		
	
	
	
	
	
| program ldpcsim
 | |
| 
 | |
| use, intrinsic :: iso_c_binding
 | |
| use hashing
 | |
| use packjt
 | |
| 
 | |
| character*22 msg,msgsent,msgreceived
 | |
| character*8 arg
 | |
| integer*1, allocatable ::  codeword(:), decoded(:), message(:)
 | |
| real*8, allocatable ::  rxdata(:), rxavgd(:)
 | |
| real, allocatable :: llr(:)
 | |
| integer ihash
 | |
| integer*1 hardbits(32)
 | |
| 
 | |
| nargs=iargc()
 | |
| if(nargs.ne.4) then
 | |
|    print*,'Usage: ldpcsim  niter navg   #trials  s '
 | |
|    print*,'eg:    ldpcsim   10     1     1000    0.75'
 | |
|    return
 | |
| endif
 | |
| call getarg(1,arg)
 | |
| read(arg,*) max_iterations 
 | |
| call getarg(2,arg)
 | |
| read(arg,*) navg 
 | |
| call getarg(3,arg)
 | |
| read(arg,*) ntrials 
 | |
| call getarg(4,arg)
 | |
| read(arg,*) s
 | |
| 
 | |
| K=16
 | |
| N=32
 | |
| !rate=real(K)/real(N)
 | |
| ! don't count hash bits as data bits
 | |
| rate=4.0/real(N)
 | |
| write(*,*) "rate: ",rate
 | |
| write(*,*) "niter= ",max_iterations,"navg= ",navg," s= ",s
 | |
| 
 | |
| allocate ( codeword(N), decoded(K), message(K) )
 | |
| allocate ( rxdata(N), rxavgd(N), llr(N) )
 | |
| 
 | |
| msg="K1JT K9AN"
 | |
| call fmtmsg(msg,iz)
 | |
| call hash(msg,22,ihash)
 | |
| irpt=14
 | |
| ihash=iand(ihash,4095)                 !12-bit hash
 | |
| ig=16*ihash + irpt                     !4-bit report
 | |
| write(*,*) irpt,ihash,ig
 | |
| 
 | |
| do i=1,16
 | |
|   message(i)=iand(1,ishft(ig,1-i))
 | |
| enddo
 | |
| write(*,'(16i1)') message
 | |
| call encode_msk40(message,codeword)
 | |
| write(*,'(32i1)') codeword
 | |
| call init_random_seed()
 | |
| 
 | |
| write(*,*) "Eb/N0  SNR2500   ngood  nundetected nbadhash"
 | |
| do idb = 0, 30
 | |
|   db=idb/2.0
 | |
|   sigma=1/sqrt( 2*rate*(10**(db/10.0)) )
 | |
|   ngood=0
 | |
|   nue=0
 | |
|   nbadhash=0
 | |
| 
 | |
|   itsum=0
 | |
|   do itrial=1, ntrials
 | |
|     rxavgd=0d0
 | |
|     do iav=1,navg
 | |
|       call sgran()
 | |
| ! Create a realization of a noisy received word
 | |
|       do i=1,N
 | |
|         rxdata(i) = 2.0*codeword(i)-1.0 + sigma*gran()
 | |
|       enddo
 | |
|       rxavgd=rxavgd+rxdata
 | |
|     enddo
 | |
|     rxdata=rxavgd
 | |
| 
 | |
| ! Correct signal normalization is important for this decoder.
 | |
|     rxav=sum(rxdata)/N
 | |
|     rx2av=sum(rxdata*rxdata)/N
 | |
|     rxsig=sqrt(rx2av-rxav*rxav)
 | |
|     rxdata=rxdata/rxsig
 | |
|     if( s .le. 0 ) then
 | |
|       ss=sigma
 | |
|     else 
 | |
|       ss=s
 | |
|     endif
 | |
| 
 | |
|     llr=2.0*rxdata/(ss*ss)
 | |
| 
 | |
|     call bpdecode40(llr, max_iterations, decoded, niterations)
 | |
| ! If the decoder finds a valid codeword, niterations will be .ge. 0.
 | |
|     if( niterations .ge. 0 ) then
 | |
|       nueflag=0
 | |
|       nhashflag=0
 | |
|       imsg=0
 | |
|       do i=1,16
 | |
|         imsg=ishft(imsg,1)+iand(1,decoded(17-i))
 | |
|       enddo
 | |
|       nrxrpt=iand(imsg,15)
 | |
|       nrxhash=(imsg-nrxrpt)/16
 | |
|       if( nrxhash .ne. ihash ) then
 | |
|         nbadhash=nbadhash+1
 | |
|         nhashflag=1   
 | |
|       endif
 | |
| 
 | |
| ! Check the message plus hash against what was sent.
 | |
|       do i=1,K
 | |
|         if( message(i) .ne. decoded(i) ) then
 | |
|           nueflag=1
 | |
|         endif
 | |
|       enddo
 | |
| 
 | |
|       if( nhashflag .eq. 0 .and. nueflag .eq. 0 ) then
 | |
|         ngood=ngood+1
 | |
|         itsum=itsum+niterations
 | |
|       else if( nhashflag .eq. 0 .and. nueflag .eq. 1 ) then
 | |
|         nue=nue+1;
 | |
|       endif
 | |
|     else
 | |
|       hardbits=0
 | |
|       where(llr .gt. 0) hardbits=1
 | |
| !      write(*,'(32i1)') hardbits 
 | |
| !      write(*,'(32i1)') codeword 
 | |
|       isum=0
 | |
|       do i=1,32
 | |
|         if( hardbits(i) .ne. codeword(i) ) isum=isum+1
 | |
|       enddo
 | |
| !      write(*,*) 'number of errors ',isum
 | |
|     endif
 | |
|   enddo
 | |
|   avits=real(itsum)/real(ngood+0.1)
 | |
|   snr2500=db-10.0
 | |
|   write(*,"(f4.1,4x,f5.1,1x,i8,1x,i8,1x,i8,1x,f8.2,1x,f8.1)") db,snr2500,ngood,nue,nbadhash,ss,avits
 | |
| 
 | |
| enddo
 | |
| 
 | |
| end program ldpcsim
 | 
