File: ldpcsim40.f90

package info (click to toggle)
wsjtx 2.7.0%2Brepack-1
  • links: PTS, VCS
  • area: main
  • in suites: trixie
  • size: 70,440 kB
  • sloc: cpp: 75,379; f90: 46,460; python: 27,241; ansic: 13,367; fortran: 2,382; makefile: 197; sh: 133
file content (138 lines) | stat: -rwxr-xr-x 3,224 bytes parent folder | download | duplicates (3)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
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