Nethack

This page describes the Nethack RNG hack I have planned.

I plan on using an FPGA to simulate running billions of transactions across the UNIX random() implementation to determine when is a good time to #dip or quaff from a fountain to get a wish.

Currently the PC version of this takes about 3 hours to run.

Notes on the UNIX pseudo-random number generator: http://www.mscs.dal.ca/~selinger/random/

Notes from Ben Jackson:

Ben says, "if you have a '*16807%2^n-1' engine it only runs 31 out of
 340+clocks"
Ben says, "so you should find a way to share that"
Ben says, "so yeah, your process should look like:  something that takes a
 seed and every 31 clocks produces 32 state registers"
Ben says, "the output of that should go to random number generators"
Ben says, "no, the seeding round makes the 32x 32 bit state words"
Ben says, "then to finish the 'srandom' seeding you have to generate 310
 random numbers"
Ben says, "there are ~10 rand engines per seed engine" (31 clocks x 10 = 310 random numbers)
Ben says, "now the seed engine may take longer than 31 clocks"
Ben says, "the big divide might be a killer"
Ben says, "shame it's not %2^31"

Broken Verilog:

//------------------------------------
//
// Initialize random number pool
//
//------------------------------------
module srandom(
seed, // integer seed
pool
);

// constants
parameter WIDTH = 32;
parameter LENGTH = 31;

// Ports
input [WIDTH-1:0] seed;
output [WIDTH-1:0] pool [LENGTH-1:0];

// Internal
integer i;
time tmp;

pool[0] = seed;
for (i = 1; i < 31; i = i + 1) begin
  tmp = 16807 * pool[i - 1];
  pool[i] = tmp % 2147483647;
  if (pool[i] < 0) begin
    pool[i] = pool[i] + 2147483647;
  end
end

for (i = 31; i < 34; i = i + 1) begin
  pool[i] = pool[i - 31];
end

for (i = 34; i < 344; i = i + 1) begin
  pool[i % POOL_SIZE] = pool[(i - 31) % POOL_SIZE] + pool[(i - 3) % POOL_SIZE];
end

initial begin
  $display("seed = %h", seed);
end
endmodule


//------------------------------------
//
// Actual random number output module
//
//------------------------------------
module random(
a, // i - 31
b, // i - 3
out // next random number
);

input a, b;
output out;

wire a, b;
wire out;

out <= (a + b) >> 1;

endmodule

Copyright © Kenny Root. All rights reserved.