random.txt 6.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189
  1. IvanM - Apr 20, 2010 - 06:16 PM
  2. Post subject: Efficient pseudorandom MLS number generator 1.625 cycle/bit
  3. Two years ago I posted very fast pseudorandom number generator. It is based on MLS generator - shift register with feedback. It is faster than other implementation as it calulates 8 random bits at once.
  4. I've stored shift register in GPIOR registers as they offered faster acces, but it can be rewritten to use RAM.
  5. I have version with 15 bit feedback register (periode 32767, [15 14] polynome) and 23 bit register (periode 8,388,607 [23 14] polynome).31 bit version can be written with minor mods, but I did not need such long periode. Each length supports 8 bits and 16 bit output.
  6. Size and timing for 15 bit register (including C call):
  7. 8 bit rnd, 26 bytes 19 cycles
  8. 16 bit rnd 40 bytes 26 cycles
  9. Size and timing for 23 bit register (including C call):
  10. 8 bit rnd, 30 bytes 21 cycles
  11. 16 bit rnd, 44 bytes 28 cycles
  12. actual calculation takes 7 cycles per output byte in all 4 cases, rest is call overhead, so it can be optimized if more random bytes is needed at once.
  13. Asm routine was written following Rowley Crossworks register convention.
  14. Note1: shift registers has to be initialized with seed >1 as bit 0 is not used.
  15. Note2: to make periode practically infinite, occasionally alter shift reg. bits with bit 0 of ADC result (1 bit is enough)
  16. C usage example:
  17. unsigned int rnd16(void);
  18. unsigned int w[200];
  19. GPIOR0=2;GPIOR1=0; // initialize seed
  20. for (i=1;i<200;i=++) w[i]=rnd16();
  21. Enjoy, Ivan
  22. Code:
  23. ;RND.asm
  24. ; Pseudo Random Number Generator functions 8/16 bit 15/23 bit Maximum Lengts Sequences
  25. ; (c) Ivan Mellen, Oct 2008
  26. ; imellen at embeddedsignals dot com
  27. ; C interface
  28. ;unsigned char rnd8(void); // 8 bit rnd, 26 bytes 19 cycles [15 14] MLS
  29. ;unsigned int rnd16(void); //16 bit rnd 40 bytes 26 cycles [15 14] MLS
  30. ;unsigned char rnd8_23(void); // 8 bit rnd, 30 bytes 21 cycles [23 14] MLS
  31. ;unsigned int rnd16_23(void); //16 bit rnd, 44 bytes 28 cycles [23 14] MLS
  32. ; Crossworks C /ASM interface:
  33. ; R27 (and R26 for int) input / output from function
  34. ; asm fun can use R20-27,R0-1, R30-31
  35. #include <avr.h>
  36. ; Go to code section.
  37. code
  38. even
  39. ;-------------------------------------------------------------------
  40. ;unsigned char rnd8(void); //8 bit rnd, 26 bytes 19 cycles (7c iteration) [15 14] MLS
  41. ; periode: 32,767 (4096 unique bytes, remaining 7 iteration shifted version)
  42. public _rnd8
  43. _rnd8 proc
  44. in r27,17 ;L reg17 is L
  45. in r26,18 ;H reg 18 is H
  46. ldi r24,0 ;this will save cycles in multi byte version
  47. mov r23,r27 ;AL=L
  48. mov r22,r26 ;AH=H
  49. lsl r23
  50. rol r22 ;AH:AL <<1
  51. eor r26,r22 ;AH=AH eor H
  52. lsl r26; C<-AH.7, AH<<1 new L byte
  53. adc r27,r24 ;L.0 <-C
  54. out 17,r26 ; new L.1-7 is eor product0-6 (msb eor is in r27.0)
  55. out 18,r27 ;old L is new H also return value (top 8 bits HL)
  56. ret
  57. endproc
  58. ;-------------------------------------------------------------------
  59. ;unsigned int rnd16(void); //16 bit rnd 40 bytes 26 cycles (14c iteration) [15 14] MLS
  60. ; periode: 32767 (2048 unique words, remaining 15 iterations shifted version)
  61. public _rnd16
  62. _rnd16 proc
  63. in r27,17 ;L reg17 is L
  64. in r26,18 ;H reg 18 is H
  65. ldi r24,0 ;this will save cycles in multi byte version
  66. mov r23,r27 ;AL=L
  67. mov r22,r26 ;AH=H
  68. lsl r23
  69. rol r22 ;AH:AL <<1
  70. eor r26,r22;AH=AH eor H
  71. lsl r26; C<-AH.7, AH<<1 new L byte new L
  72. adc r27,r24 ;L.0 <-C ;first 8 bits new H 1st return value (high part)
  73. ; get 2nd byte
  74. mov r23,r26 ;AL=L
  75. mov r22,r27 ;AH=H
  76. lsl r23
  77. rol r22 ;AH:AL <<1
  78. eor r27,r22 ;AH=AH eor H
  79. lsl r27; C<-AH.7, AH<<1 new L byte
  80. adc r26,r24 ;L.0 <-C ;first 8 bits new H 2nd return value (low part)
  81. out 17,r27 ; new L.1-7 is eor product0-6 (msb eor is in r26.0)
  82. out 18,r26 ;old L is new H also return value (top 8 bits HL)
  83. ret
  84. endproc
  85. ;-------------------------------------------------------------------
  86. ;unsigned char rnd8_23(void); //8 bit rnd, 30 bytes 21 cycles (7c iteration) [23 14] MLS
  87. ; periode: 8,388,607 (1,0485,576 unique bytes, remaining 7 iteration shifted version)
  88. public _rnd8_23
  89. _rnd8_23 proc
  90. in r26,17 ;L GPIOR0 is L
  91. in r27,18 ;H GPIOR1 is M
  92. in r25,19 ;H GPIOR2 is H
  93. ldi r24,0 ;this will save cycles in multi byte version
  94. mov r20,r26 ;L2=L
  95. mov r21,r27 ;M2=M
  96. lsl r20
  97. rol r21 ;M2:L2 <<1
  98. eor r21,r25 ;M2 = M2 eor H
  99. lsl r21; C<-M2.7, M2<<1 new L byte
  100. adc r26,r24 ;L.0 <-C new M byte
  101. ; M is new H byte (also output)
  102. out 17,r21 ; new L.1-7 is eor product6-0 (msb eor is in r27.0)
  103. out 18,r26 ;old L + bit 0 from eor bit 7 is new M
  104. out 19,r27 ;old M is new H also return value (top 8 bits HML)
  105. ret
  106. endproc
  107. ;-------------------------------------------------------------------
  108. ;unsigned int rnd16_23(void); //16 bit rnd, 44 bytes 28 cycles (14c iteration) [23 14] MLS
  109. ; periode: 8,388,607 (524288 unique words, remaining 15 iteration shifted version)
  110. public _rnd16_23
  111. _rnd16_23 proc
  112. in r26,17 ;L GPIOR0 is L
  113. in r25,18 ;H GPIOR1 is M
  114. in r27,19 ;H GPIOR2 is H
  115. ldi r24,0 ;this will save cycles in multi byte version
  116. mov r20,r26 ;L2=L
  117. mov r21,r25 ;M2=M
  118. lsl r20
  119. rol r21 ;M2:L2 <<1
  120. eor r27,r21 ;H = M2 eor H
  121. lsl r27; C<-H.7, H<<1 new L byte 27
  122. adc r26,r24 ;L.0 <-C new M byte 26
  123. ; M is new H byte 25
  124. ; get 2nd byte -----------------
  125. mov r20,r27 ;L2=L
  126. mov r21,r26 ;M2=M
  127. lsl r20
  128. rol r21 ;M2:L2 <<1
  129. eor r25,r21 ;H = M2 eor H
  130. lsl r25; C<-H.7, H<<1 new L byte 25
  131. adc r27,r24 ;L.0 <-C new M byte 27(also output)
  132. ; M is new H byte 26(also output)
  133. out 17,r25 ; new L.1-7 is eor product6-0 (msb eor is in r27.0)
  134. out 18,r27 ;old L + bit 0 from eor bit 7 is new M
  135. out 19,r26 ;old M is new H
  136. ret
  137. endproc
  138. ============================================================================================