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
 |