/****************************************************************************** /* /* Function: slidas_random.c /* /****************************************************************************** /* Emulates the random pattern which comes out of the SLIDAS. /* ---------------------------------------------------------------------------- /* /* The function takes one argument (if "1" reset the sequence, if /* "0" continue as normal) and automatically returns the value of /* the next random number in the sequence. The seed and coding algorithm /* are hardwired in the function (like in the real SLIDAS!). /* /* Instructions: (assuming your test file is called link_test.c) /* /* (1) In link_test.c, call slidas_random() with the argument "0" /* every time you need the next random number /* /* e.g. next_random_number = slidas_random(0); /* /* (2) If you need to reset the random number sequence, call /* slidas_random() with the argument "1", e.g. /* /* first_random_number = slidas_random(1); /* /* (3) Compile link_test.c in the same directory as slidas_random.c /* with the command: /* /* $ cc -o link_test link_test.c slidas_random.c /* /* ---------------------------------------------------------------------------- /* /* The SLIDAS random pattern is generated by verilog and is a /* real-time swapping of bits in a register. On each swap; /* (1) Most bits are swapped, e.g. bit(31) gets bit(5) etc. /* (2) A new bit is formed from (31)^(29)^(18)^(5) which comes /* out on bit(16). /* (3) Old bit(29) is lost (to make way for new bit). /* /* The verilog equation is; /* /* q <= #1 {q[5], q[24], q[13], q[25], q[10], q[30], q[18], q[6], /* q[14], q[7], q[17], q[3], q[0], q[16], q[12], /* q[29]^q[31]^q[5]^q[18], /* q[31], q[26], q[21], q[27], q[15], q[23], q[2], q[11], /* q[9], q[20], q[4], q[28], q[22], q[19], q[8], q[1]}; /* /* Here, the seed is placed in reg_word and then in each call, /* reg_word is manipulated as described above to form output_word /* which is returned. Output_word becomes the next reg_word. /* /* ---------------------------------------------------------------------------- /* /* Author: Owen Boyle 23/10/97 /* /* ---------------------------------------------------------------------------- */ int slidas_random(reset) { static unsigned reg_word = 0x524948e0; /* Random number seed */ unsigned output_word; int i, j, xor_result; /* ---------------------------------------------------------------------------- /* The swap_map array is generated from the verilog equation by the /* following algorithm: /* /* "swap_map[i] is the index of q[i] in the verilog equation" /* /* so, for example; /* swap_map[0] = 19 because q[0] is bit(19) in the equation /* swap_map[1] = 0 because q[1] is bit(0) in the equation /* and so on... /* swap_map[29] = 0 because bit(29) in the register is thrown away. /* ---------------------------------------------------------------------------- */ static int swap_map[32] = { 19, 0, 9, 20, 5, 31, 24, 22, 1, 7, 27, 8, 17, 29, 23, 11, 18, 21, 25, 2, 6, 13, 3, 10, 30, 28, 14, 12, 4, 0, 26, 15}; /* Normally, the seed is initialised the first time slidas_random() is /* called. Thereafter, the random_word is incremented automatically. /* Sometimes, we may want to reset the seed. This is done by calling /* slidas_random() with a "1" as argument. */ if (reset) reg_word = 0x524948e0; /* Extract the XOR bits for testing and calculate XOR result */ xor_result = ((((reg_word & 0x80000000) && 1) ^ /* Bit 31 */ ((reg_word & 0x20000000) && 1) ^ /* Bit 29 */ ((reg_word & 0x40000) && 1) ^ /* Bit 18 */ ((reg_word & 0x20) && 1)) == 1); /* Bit 5 */ /* Rearrange bits to form output word /* ---------------------------------------------------------------------------- /* We shift throught the register word, checking each bit. If the i-th bit /* is set, we go to the swap_map array and look in the i-th entry. This /* tells us the number of bits to shift along in the output word, then we /* set that bit. If the bit in the register word is not set, we leave the /* output word alone. /* /* Note that bit(29) is not processed (it is thrown away) and that bit(16) /* gets the XOR result (hence the special treatments). /* ---------------------------------------------------------------------------- */ output_word = 0; for(j=0; j<32; j++) { /* bit(29) is thrown away */ if (j != 29) { /* bit(16) is the XOR bit */ if (j == 16) output_word ^= (xor_result << 16); /* Other bits are calculated using swap_map[] */ if (reg_word & (0x1 << j)) output_word ^= (0x1 << swap_map[j]); } } reg_word = output_word; return output_word; } /*****************************************************************************/