While trying to learn FPGA programming, I've decided to implement a massively parallel game of life. Here's my first attempt:
entity LifeCell is
Port ( neighbours : in std_logic_vector(7 downto 0);
state : inout std_logic;
clk : in std_logic);
end LifeCell;
architecture Behavioral of LifeCell is
begin
compute: process(clk)
variable temp : integer range 0 to 8;
begin
if rising_edge(clk) then
temp := 0;
for i in neighbours'range loop
if neighbours(i) = '1' then temp := temp + 1;
end if;
end loop;
if (temp = 3 or (temp = 2 and state = '1')) then
state <= '1';
else
state <= '0';
end if;
end if;
end process;
end Behavioral;
Then I realized that the Technology Diagram was using 13 LUTs. Hmmm... Maybe I can do better? Why not specify in advance the possible combinations?
function count3bits(v : std_logic_vector(7 downto 0)) return boolean is
begin
case v is
when "00000111" => return true;
when "00001011" => return true;
when "00001101" => return true;
when "00001110" => return true;
when "00010011" => return true;
when "00010101" => return true;
when "00010110" => return true;
when "00011001" => return true;
when "00011010" => return true;
when "00011100" => return true;
when "00100011" => return true;
when "00100101" => return true;
when "00100110" => return true;
when "00101001" => return true;
when "00101010" => return true;
when "00101100" => return true;
when "00110001" => return true;
when "00110010" => return true;
when "00110100" => return true;
when "00111000" => return true;
when "01000011" => return true;
when "01000101" => return true;
when "01000110" => return true;
when "01001001" => return true;
when "01001010" => return true;
when "01001100" => return true;
when "01010001" => return true;
when "01010010" => return true;
when "01010100" => return true;
when "01011000" => return true;
when "01100001" => return true;
when "01100010" => return true;
when "01100100" => return true;
when "01101000" => return true;
when "01110000" => return true;
when "10000011" => return true;
when "10000101" => return true;
when "10000110" => return true;
when "10001001" => return true;
when "10001010" => return true;
when "10001100" => return true;
when "10010001" => return true;
when "10010010" => return true;
when "10010100" => return true;
when "10011000" => return true;
when "10100001" => return true;
when "10100010" => return true;
when "10100100" => return true;
when "10101000" => return true;
when "10110000" => return true;
when "11000001" => return true;
when "11000010" => return true;
when "11000100" => return true;
when "11001000" => return true;
when "11010000" => return true;
when "11100000" => return true;
when others => return false;
end case;
end count3bits;
function count2bits(v : std_logic_vector(7 downto 0)) return boolean is
begin
case v is
when "00000011" => return true;
when "00000101" => return true;
when "00000110" => return true;
when "00001001" => return true;
when "00001010" => return true;
when "00001100" => return true;
when "00010001" => return true;
when "00010010" => return true;
when "00010100" => return true;
when "00011000" => return true;
when "00100001" => return true;
when "00100010" => return true;
when "00100100" => return true;
when "00101000" => return true;
when "00110000" => return true;
when "01000001" => return true;
when "01000010" => return true;
when "01000100" => return true;
when "01001000" => return true;
when "01010000" => return true;
when "01100000" => return true;
when "10000001" => return true;
when "10000010" => return true;
when "10000100" => return true;
when "10001000" => return true;
when "10010000" => return true;
when "10100000" => return true;
when "11000000" => return true;
when others => return false;
end case;
end count2bits;
begin
compute: process(clk)
begin
if rising_edge(clk) then
if (count3bits(neighbours) or (state = '1' and count2bits(neighbours))) then
state <= '1';
else
state <= '0';
end if;
end if;
end process;
end Behavioral;
Implementation is now down to 9 LUTs.
Now, here's the question. Is it possible to do better? (Spartan-6 only has 6-bit LUTs).