A quick FPGA hack for you pseudo-random lovers out there

Long time ago, a friend showed me an article about cellular automata with chaotic behavior and their alleged randomness. One such CA called “Rule 30” produces pseudo random patterns using a simple compression rule. This is shown in the figure below (stolen from Wolfram Mathworld):

 

ElementaryCARule030_1000

(each cell is a CA bit, the rows represent progress over time)

 

There is really nothing special with the randomness of Rule 30, it is completely useless for cryptographic applications. What makes Rule 30 a little interesting however, is the fact that it can be implemented very efficiently in FPGA: you will need 2-3 logical elements (4LUT + DFF) for each automaton.

 

Show us the code!

I found a Verilog implementation on Kryptoblog (a Swedish blog about security and stuff), but since I suffer from a severe case of the NIH syndrome, I decided to write my own in VHDL:

-- rule30.vhd: Cellular Automata DRNG - av/tube42.se, 2010
-- Using the same structure as rule30.v by Joachim Strömbergson at Kryptblog
library IEEE;
use IEEE.std_logic_1164.all;
use IEEE.numeric_std.all;

entity rule30 is
generic ( WIDTH : integer := 32);
port (
  CLK_I : in std_logic;
  RESET_N_I : in std_logic;
  DATA_I : in unsigned(WIDTH-1 downto 0);
  LOAD_I : in std_logic;
  NEXT_I : in std_logic;
  DATA_O : out unsigned(WIDTH-1 downto 0)
);
end entity;

architecture behav of rule30 is
  signal state : unsigned(WIDTH-1 downto 0);
begin
  -- sanity checks (should be in the entity, but I cant remember the syntax)
  assert WIDTH > 2 report "WIDTH must be greater than 2" severity failure;

  -- outputs
  DATA_O <= state;

  -- main logic
  rule30_proc: process(CLK_I, RESET_N_I)
    variable tmp : unsigned(WIDTH-1 downto 0);

    -- next state function for each cell
    function comp_next(d : unsigned( 2 downto 0)) return std_logic is
    begin
      case to_integer(d) is
        -- when 1 | 2 | 3 | 4 => return '1'; -- "correct" bit order
        when 4 | 2 | 6 | 1 => return '1'; -- reverse bit order, works with tb
        when others => return '0';
      end case;
     end function;

  begin
    if RESET_N_I = '0' then
      state <= (others => '0');
    elsif rising_edge(CLK_I) then
      if LOAD_I = '1' then
        state <= DATA_I;
      elsif NEXT_I = '1' then
        tmp := state rol 1; -- we use rotating variable to simplify the code
        for i in 0 to WIDTH-1 loop
          state(i) <= comp_next(tmp(2 downto 0));
          tmp := tmp ror 1;
        end loop;
      end if;
    end if;
  end process;
end behav;

This versions is slightly shorter (the Verilog code was about 1000 lines, mine is 60), uses generics for variable bit lengths and also follows the OpenCores coding standard for better readability. It is otherwise identical to the original Verilog code and even passes the testbench supplied with it – mostly because I was too lazy to write my own testbench ;)

 

Ehh.. VHDL is all greek to us, show us the hardware!

The code above will be “synthesized” to logic gates using special software [In my case, I used Altera Quartus which is by the way free for you to experiment]. For example, the comp_next function in the code is synthesized to this:

img00

 

This is really not rocket science, but may be fun for software engineers who haven’t seen a logic gate since they graduated university :) . In any case, here are some more screen dumps from Quartus (representing an 8-bit rule30 design):

img01

img02

design as generic gates design as FPGA cells (technology mapped)

 

 

How do I know your code really works?

You must always test your code, FPGA development is no different from software development in this regard . And you will put many hours into writing unit tests or you will have to put many more hours into debugging. Actually, testing is even more important when working with FPGAs. Compared to software development, the observability is next to zero and the development cycle is very slow, so you better get it right the first time. This is even worse when designing ASIC as they are very expensive to prototype.

 

The correct way to develop with FPGA or ASIC is to simulate your code against a large set of unit tests before even thinking about synthesizers and real hardware. In this particular case, I settled with the testbench from Kryptoblog. Using the (inhumanly expensive) simulator tool Aldec Riviera, I ran the testbench against my code and the original code to prove that everything works as intended:

 

img03 

(VHDL version on top, Verilog in middle and VHDL test results at the bottom)

 

As you can see in the waveform above, this simple constructs produces chaotic data which can be used as random numbers – if your standards are really low…

 

 

That’s all folks!

About AV
I am a software developer/hardware designer working mostly with embedded systems and FPGAs on my day job. I live in the southern parts of Sweden (no I don't work for SonyEricsson). I use this site as backup & publication space for projects I play with during my (very limited) free time... Please forgive me if this site contains mostly crap and stupid rants. I have another site for my more serious work ;)

Comments

One Response to “A quick FPGA hack for you pseudo-random lovers out there”

Trackbacks

Check out what others are saying about this post...
  1. [...] have written a couple of FPGA articles on this blog. The last one was about a very simple deterministic random number generator called rule30. Since that was a very [...]



Speak Your Mind

Tell us what you're thinking...
and oh, if you want a pic to show with your comment, go get a gravatar!

  • My J2ME apps

  • Tags

    apps Bixi brainfuck Brickade ColorInvasion DSP FPGA GHDL GTKWave hacks imagelib J2ME Java Jibberish KeyInfo Linux NetMonitor OpenSource PRNG PSP rant Roses SameSame SensorApp ZPU
  • Recent Posts

  • Categories

  • Archives

  • Switch to our mobile site