Log in

Nethack

From Kenny Root

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
Retrieved from "http://the-b.org/Nethack"
Cantonese
Kenny Root