// The following macros are used to generate pseudo random numbers.
// We implement linear feedback shift registers as described in the
// Xilinx application note XAPP 052 from July 7, 1996.
// Special thanks to Peter Alfke for the comprehensive list of shift
// register taps.
// NEC Electronics (Europe) GmbH, Michael Krämer, 2004-05-27

// The macros use datatypes that suit the number of bits, i.e.
// RND3 ~RND8  use  8-bit datatype (unsigned char)
// RND9 ~RND16 use 16-bit datatype (unsigned short)
// RND17~RND32 use 32-bit datatype (unsigned long)

// Note that the variable, which holds the pseudo random number,
// must be initialized with a value different from 0. RNDn(0) will
// always generate 0. Any other value will generate a pseudo random
// sequence of maximum length, i.e. (2^n)-1.

#define U1 ((unsigned int) 1)
#define S1 ((unsigned short) 1)
#define C1 ((unsigned char) 1)

#define RND3(arg)  (      0x07 & ((arg << 1) | (C1 & ((arg >>  1) ^ (arg >>  2)))))
#define RND4(arg)  (      0x0f & ((arg << 1) | (C1 & ((arg >>  2) ^ (arg >>  3)))))
#define RND5(arg)  (      0x1f & ((arg << 1) | (C1 & ((arg >>  2) ^ (arg >>  4)))))
#define RND6(arg)  (      0x3f & ((arg << 1) | (C1 & ((arg >>  4) ^ (arg >>  5)))))
#define RND7(arg)  (      0x7f & ((arg << 1) | (C1 & ((arg >>  5) ^ (arg >>  6)))))
#define RND8(arg)                ((arg << 1) | (C1 & ((arg >>  3) ^ (arg >>  4) ^ (arg >>  5) ^ (arg >>  7))))
#define RND9(arg)  (    0x01ff & ((arg << 1) | (S1 & ((arg >>  4) ^ (arg >>  8)))))
#define RND10(arg) (    0x03ff & ((arg << 1) | (S1 & ((arg >>  6) ^ (arg >>  9)))))
#define RND11(arg) (    0x07ff & ((arg << 1) | (S1 & ((arg >>  8) ^ (arg >> 10)))))
#define RND12(arg) (    0x0fff & ((arg << 1) | (S1 & ((arg >>  0) ^ (arg >>  3) ^ (arg >>  5) ^ (arg >> 11)))))
#define RND13(arg) (    0x1fff & ((arg << 1) | (S1 & ((arg >>  0) ^ (arg >>  2) ^ (arg >>  3) ^ (arg >> 12)))))
#define RND14(arg) (    0x3fff & ((arg << 1) | (S1 & ((arg >>  0) ^ (arg >>  2) ^ (arg >>  4) ^ (arg >> 13)))))
#define RND15(arg) (    0x7fff & ((arg << 1) | (S1 & ((arg >> 13) ^ (arg >> 14)))))
#define RND16(arg)               ((arg << 1) | (S1 & ((arg >>  3) ^ (arg >> 12) ^ (arg >> 14) ^ (arg >> 15))))
#define RND17(arg) (0x0001ffff & ((arg << 1) | (U1 & ((arg >> 13) ^ (arg >> 16)))))
#define RND18(arg) (0x0003ffff & ((arg << 1) | (U1 & ((arg >> 10) ^ (arg >> 17)))))
#define RND19(arg) (0x0007ffff & ((arg << 1) | (U1 & ((arg >>  0) ^ (arg >>  1) ^ (arg >>  5) ^ (arg >> 18)))))
#define RND20(arg) (0x000fffff & ((arg << 1) | (U1 & ((arg >> 16) ^ (arg >> 19)))))
#define RND21(arg) (0x001fffff & ((arg << 1) | (U1 & ((arg >> 18) ^ (arg >> 20)))))
#define RND22(arg) (0x003fffff & ((arg << 1) | (U1 & ((arg >> 20) ^ (arg >> 21)))))
#define RND23(arg) (0x007fffff & ((arg << 1) | (U1 & ((arg >> 17) ^ (arg >> 22)))))
#define RND24(arg) (0x00ffffff & ((arg << 1) | (U1 & ((arg >> 16) ^ (arg >> 21) ^ (arg >> 22) ^ (arg >> 23)))))
#define RND25(arg) (0x01ffffff & ((arg << 1) | (U1 & ((arg >> 21) ^ (arg >> 24)))))
#define RND26(arg) (0x03ffffff & ((arg << 1) | (U1 & ((arg >>  0) ^ (arg >>  1) ^ (arg >>  5) ^ (arg >> 25)))))
#define RND27(arg) (0x07ffffff & ((arg << 1) | (U1 & ((arg >>  0) ^ (arg >>  1) ^ (arg >>  4) ^ (arg >> 26)))))
#define RND28(arg) (0x0fffffff & ((arg << 1) | (U1 & ((arg >> 24) ^ (arg >> 27)))))
#define RND29(arg) (0x1fffffff & ((arg << 1) | (U1 & ((arg >> 26) ^ (arg >> 28)))))
#define RND30(arg) (0x3fffffff & ((arg << 1) | (U1 & ((arg >>  0) ^ (arg >>  3) ^ (arg >>  5) ^ (arg >> 29)))))
#define RND31(arg) (0x7fffffff & ((arg << 1) | (U1 & ((arg >> 27) ^ (arg >> 30)))))
#define RND32(arg)               ((arg << 1) | (U1 & ((arg >>  0) ^ (arg >>  1) ^ (arg >> 21) ^ (arg >> 31))))
