123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189 |
- IvanM - Apr 20, 2010 - 06:16 PM
- Post subject: Efficient pseudorandom MLS number generator 1.625 cycle/bit
- 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.
- I've stored shift register in GPIOR registers as they offered faster acces, but it can be rewritten to use RAM.
- 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.
- Size and timing for 15 bit register (including C call):
- 8 bit rnd, 26 bytes 19 cycles
- 16 bit rnd 40 bytes 26 cycles
- Size and timing for 23 bit register (including C call):
- 8 bit rnd, 30 bytes 21 cycles
- 16 bit rnd, 44 bytes 28 cycles
- 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.
- Asm routine was written following Rowley Crossworks register convention.
- Note1: shift registers has to be initialized with seed >1 as bit 0 is not used.
- Note2: to make periode practically infinite, occasionally alter shift reg. bits with bit 0 of ADC result (1 bit is enough)
- C usage example:
- unsigned int rnd16(void);
- unsigned int w[200];
- GPIOR0=2;GPIOR1=0; // initialize seed
- for (i=1;i<200;i=++) w[i]=rnd16();
- Enjoy, Ivan
- Code:
- ;RND.asm
- ; Pseudo Random Number Generator functions 8/16 bit 15/23 bit Maximum Lengts Sequences
- ; (c) Ivan Mellen, Oct 2008
- ; imellen at embeddedsignals dot com
- ; C interface
- ;unsigned char rnd8(void); // 8 bit rnd, 26 bytes 19 cycles [15 14] MLS
- ;unsigned int rnd16(void); //16 bit rnd 40 bytes 26 cycles [15 14] MLS
- ;unsigned char rnd8_23(void); // 8 bit rnd, 30 bytes 21 cycles [23 14] MLS
- ;unsigned int rnd16_23(void); //16 bit rnd, 44 bytes 28 cycles [23 14] MLS
- ; Crossworks C /ASM interface:
- ; R27 (and R26 for int) input / output from function
- ; asm fun can use R20-27,R0-1, R30-31
- #include <avr.h>
- ; Go to code section.
- code
- even
- ;-------------------------------------------------------------------
- ;unsigned char rnd8(void); //8 bit rnd, 26 bytes 19 cycles (7c iteration) [15 14] MLS
- ; periode: 32,767 (4096 unique bytes, remaining 7 iteration shifted version)
- public _rnd8
- _rnd8 proc
- in r27,17 ;L reg17 is L
- in r26,18 ;H reg 18 is H
- ldi r24,0 ;this will save cycles in multi byte version
- mov r23,r27 ;AL=L
- mov r22,r26 ;AH=H
- lsl r23
- rol r22 ;AH:AL <<1
- eor r26,r22 ;AH=AH eor H
- lsl r26; C<-AH.7, AH<<1 new L byte
- adc r27,r24 ;L.0 <-C
- out 17,r26 ; new L.1-7 is eor product0-6 (msb eor is in r27.0)
- out 18,r27 ;old L is new H also return value (top 8 bits HL)
- ret
- endproc
- ;-------------------------------------------------------------------
- ;unsigned int rnd16(void); //16 bit rnd 40 bytes 26 cycles (14c iteration) [15 14] MLS
- ; periode: 32767 (2048 unique words, remaining 15 iterations shifted version)
- public _rnd16
- _rnd16 proc
- in r27,17 ;L reg17 is L
- in r26,18 ;H reg 18 is H
- ldi r24,0 ;this will save cycles in multi byte version
- mov r23,r27 ;AL=L
- mov r22,r26 ;AH=H
- lsl r23
- rol r22 ;AH:AL <<1
- eor r26,r22;AH=AH eor H
- lsl r26; C<-AH.7, AH<<1 new L byte new L
- adc r27,r24 ;L.0 <-C ;first 8 bits new H 1st return value (high part)
- ; get 2nd byte
- mov r23,r26 ;AL=L
- mov r22,r27 ;AH=H
- lsl r23
- rol r22 ;AH:AL <<1
- eor r27,r22 ;AH=AH eor H
- lsl r27; C<-AH.7, AH<<1 new L byte
- adc r26,r24 ;L.0 <-C ;first 8 bits new H 2nd return value (low part)
- out 17,r27 ; new L.1-7 is eor product0-6 (msb eor is in r26.0)
- out 18,r26 ;old L is new H also return value (top 8 bits HL)
- ret
- endproc
- ;-------------------------------------------------------------------
- ;unsigned char rnd8_23(void); //8 bit rnd, 30 bytes 21 cycles (7c iteration) [23 14] MLS
- ; periode: 8,388,607 (1,0485,576 unique bytes, remaining 7 iteration shifted version)
- public _rnd8_23
- _rnd8_23 proc
- in r26,17 ;L GPIOR0 is L
- in r27,18 ;H GPIOR1 is M
- in r25,19 ;H GPIOR2 is H
- ldi r24,0 ;this will save cycles in multi byte version
- mov r20,r26 ;L2=L
- mov r21,r27 ;M2=M
- lsl r20
- rol r21 ;M2:L2 <<1
- eor r21,r25 ;M2 = M2 eor H
- lsl r21; C<-M2.7, M2<<1 new L byte
- adc r26,r24 ;L.0 <-C new M byte
- ; M is new H byte (also output)
- out 17,r21 ; new L.1-7 is eor product6-0 (msb eor is in r27.0)
- out 18,r26 ;old L + bit 0 from eor bit 7 is new M
- out 19,r27 ;old M is new H also return value (top 8 bits HML)
- ret
- endproc
- ;-------------------------------------------------------------------
- ;unsigned int rnd16_23(void); //16 bit rnd, 44 bytes 28 cycles (14c iteration) [23 14] MLS
- ; periode: 8,388,607 (524288 unique words, remaining 15 iteration shifted version)
- public _rnd16_23
- _rnd16_23 proc
- in r26,17 ;L GPIOR0 is L
- in r25,18 ;H GPIOR1 is M
- in r27,19 ;H GPIOR2 is H
- ldi r24,0 ;this will save cycles in multi byte version
- mov r20,r26 ;L2=L
- mov r21,r25 ;M2=M
- lsl r20
- rol r21 ;M2:L2 <<1
- eor r27,r21 ;H = M2 eor H
- lsl r27; C<-H.7, H<<1 new L byte 27
- adc r26,r24 ;L.0 <-C new M byte 26
- ; M is new H byte 25
- ; get 2nd byte -----------------
- mov r20,r27 ;L2=L
- mov r21,r26 ;M2=M
- lsl r20
- rol r21 ;M2:L2 <<1
- eor r25,r21 ;H = M2 eor H
- lsl r25; C<-H.7, H<<1 new L byte 25
- adc r27,r24 ;L.0 <-C new M byte 27(also output)
- ; M is new H byte 26(also output)
- out 17,r25 ; new L.1-7 is eor product6-0 (msb eor is in r27.0)
- out 18,r27 ;old L + bit 0 from eor bit 7 is new M
- out 19,r26 ;old M is new H
- ret
- endproc
- ============================================================================================
|