kahlenberg
Junior Member level 3

Hi,
I am designing a Physically Uncolonable Function using Ring Oscillator on FPGA (Spartan6). However, it does not generate uniqe ID for each chip, it generates exactly same value for different chips. Different ROs must generate different frequency due to die-imperfection. I will compare those frequencies and generate bits, which should be uniqe for each chip, since each chip has different physicall die-imperfection.
First, I generate 16 ROs, each with 51 inverter gates, all of them are connected to two multiplexers, I connected the select inputs of multiplexers with 8-bit dip-switch. Outputs of multiplexers are connected to two 16-bit counters. Outputs of counters are connected to a comparator, If first counter reachs end value (111...11) (if it is faster than second counter) comparator gives '1', if second counter is faster than first, comparator gives a '0'. This generates only one bit. I replicated this design 16-times to generate 16-bit response. The first bits of this response (3 downto 0) are connected to 4-leds. I tested the design with 3 different chips, they give exactly same respnose, which is not desired.
How can I make it in order to have different responses?
Thanks.
ring_oscillator.vhd
debounce.vhd
top.vhd
I am designing a Physically Uncolonable Function using Ring Oscillator on FPGA (Spartan6). However, it does not generate uniqe ID for each chip, it generates exactly same value for different chips. Different ROs must generate different frequency due to die-imperfection. I will compare those frequencies and generate bits, which should be uniqe for each chip, since each chip has different physicall die-imperfection.
First, I generate 16 ROs, each with 51 inverter gates, all of them are connected to two multiplexers, I connected the select inputs of multiplexers with 8-bit dip-switch. Outputs of multiplexers are connected to two 16-bit counters. Outputs of counters are connected to a comparator, If first counter reachs end value (111...11) (if it is faster than second counter) comparator gives '1', if second counter is faster than first, comparator gives a '0'. This generates only one bit. I replicated this design 16-times to generate 16-bit response. The first bits of this response (3 downto 0) are connected to 4-leds. I tested the design with 3 different chips, they give exactly same respnose, which is not desired.
How can I make it in order to have different responses?
Thanks.
ring_oscillator.vhd
Code:
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
-- Uncomment the following library declaration if using
-- arithmetic functions with Signed or Unsigned values
use IEEE.NUMERIC_STD.ALL;
-- Uncomment the following library declaration if instantiating
-- any Xilinx primitives in this code.
--library UNISIM;
--use UNISIM.VComponents.all;
entity ring_oscilator is
generic (delay: time := 200ps;
chain_len: integer := 16);
port( rst_i : in std_logic;
ro_o : out std_logic);
end ring_oscilator;
architecture Behavioral of ring_oscilator is
signal chain : std_logic_vector(chain_len downto 0);
attribute keep: boolean;
attribute keep of chain: signal is true;
begin
--assert chain_len mod 2 = 1 report "Length of ring must be an odd number!" severity failure;
gen_chain:
for i in 1 to chain_len generate
chain(i) <= not chain(i-1) after delay;
end generate;
chain(0) <= chain(chain_len) nor rst_i after delay;
ro_o <= chain(chain_len);
end Behavioral;
debounce.vhd
Code:
library ieee;
use ieee.std_logic_1164.all;
use ieee.std_logic_unsigned.all;
entity debouncer is
generic(
counter_size : INTEGER := 19); --counter size (19 bits gives 10.5ms with 50MHz clock)
port(
clk_i : in std_logic; --input clock
button_i : in std_logic; --input signal to be debounced
enable_i : in std_logic; -- for simulation
result_o : out std_logic); --debounced signal
end debouncer;
ARCHITECTURE logic of debouncer is
signal flipflops : std_logic_vector(1 downto 0); --input flip flops
signal counter_set : std_logic; --sync reset to zero
signal counter_out : std_logic_vector(counter_size downto 0) := (others => '0'); --counter output
begin
counter_set <= flipflops(0) xor flipflops(1); --determine when to start/reset counter
process(clk_i)
begin
if rising_edge(clk_i) then
flipflops(0) <= button_i;
flipflops(1) <= flipflops(0);
if enable_i = '1' then
if(counter_set = '1') then --reset counter because input is changing
counter_out <= (others => '0');
elsif(counter_out(counter_size) = '0') then --stable input time is not yet met
counter_out <= counter_out + 1;
else --stable input time is met
result_o <= flipflops(1);
end if;
else
result_o <= button_i;
end if;
end if;
end process;
end logic;
top.vhd
Code:
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.std_logic_misc.ALL;
use IEEE.std_logic_unsigned.ALL;
use ieee.numeric_std.all;
entity top is
Generic (
nr_ro : natural := 16;
puf_width : natural := 16
);
Port (
shift_i : in std_logic ; --debug
dout_o : out std_logic_vector(3 downto 0); --debug
sel_i : in std_logic_vector(7 downto 0); --debug
clk_i : in STD_LOGIC;
rst_i : in STD_LOGIC--;
-- puf_out : out STD_LOGIC_VECTOR (puf_width-1 downto 0)
);
end top;
architecture Behavioral of top is
constant c_width : natural := puf_width;
constant c_number_of_ro : natural := nr_ro;
-----------------------------DEBUG-------------------------------------
signal s_sel : std_logic_vector(7 downto 0) := (others => '0');
signal s_dout : std_logic_vector(3 downto 0) := (others => '0');
signal s_shift : std_logic := '0';
signal s_shift_pre : std_logic := '0';
signal s_pulse : std_logic := '0';
signal s_msb : integer range 0 to 16 := 4;
-----------------------------------------------------------------------
signal s_reset : std_logic := '0';
signal s_finish : std_logic_vector (c_width-1 downto 0):= (others => '0');
signal s_finished : std_logic := '0';
signal s_puf_out : std_logic_vector (c_width-1 downto 0):= (others => '0');
--------------components----------------------------
component puf_bit
generic (
nr_ro: natural := c_number_of_ro
);
port (
clk_i : in std_logic;
rst_i : in std_logic;
sel1_i : in unsigned(3 downto 0);
sel2_i : in unsigned(3 downto 0);
finish_o : out std_logic;
puf_bit_o : out std_logic
);
end component;
component debouncer
generic(counter_size : integer := 19); --counter size (19 bits gives 10.5ms with 50MHz clock)
port(
clk_i : in std_logic; --input clock
button_i : in std_logic; --input signal to be debounced
enable_i : in std_logic;
result_o : out std_logic); --debounced signal
end component;
begin
Generate_PUF:
for i in 0 to c_width-1 generate
Multiple_Puf_Bits: puf_bit
generic map (nr_ro => c_number_of_ro)
port map (
clk_i => clk_i,
rst_i => s_reset,
sel1_i => unsigned(s_sel(3 downto 0)),
sel2_i => unsigned(s_sel(7 downto 4)),
finish_o => s_finish(i),
puf_bit_o => s_puf_out(i)
);
end generate;
reset_debounce: debouncer
generic map (counter_size => 19)
port map (clk_i => clk_i, button_i => not rst_i, enable_i => '1', result_o => s_reset); --On FPGA board btn is low active
btn_debounce: debouncer
generic map (counter_size => 19)
port map (clk_i => clk_i, button_i => not shift_i, enable_i => '1', result_o => s_shift); --On FPGA board btn is low active
s_finished <= AND_REDUCE(s_finish);
------------ debug--------------------------------
s_sel <= sel_i;
dout_o <= s_puf_out(7 downto 4);
----------------------------------------------
end Behavioral;