OpenCores
URL https://opencores.org/ocsvn/neo430/neo430/trunk

Subversion Repositories neo430

Compare Revisions

  • This comparison shows the changes necessary to convert path
    /neo430
    from Rev 141 to Rev 142
    Reverse comparison

Rev 141 → Rev 142

/trunk/rtl/core/neo430_trng.vhd
1,163 → 1,162
-- #################################################################################################
-- # << NEO430 - True Random Number Generator >> #
-- # ********************************************************************************************* #
-- # True random number generator based on free running oscillators. These oscillators are built #
-- # from single inverters, where the output is directly used as input again. The feedback is de- #
-- # coupled using latches, which are transparent when the TRNG is running. The latches are auto- #
-- # matically initilized (reset) before operation. #
-- # ********************************************************************************************* #
-- # This file is part of the NEO430 Processor project: https://github.com/stnolting/neo430 #
-- # Copyright by Stephan Nolting: stnolting@gmail.com #
-- # #
-- # This source file may be used and distributed without restriction provided that this copyright #
-- # statement is not removed from the file and that any derivative work contains the original #
-- # copyright notice and the associated disclaimer. #
-- # #
-- # This source file is free software; you can redistribute it and/or modify it under the terms #
-- # of the GNU Lesser General Public License as published by the Free Software Foundation, #
-- # either version 3 of the License, or (at your option) any later version. #
-- # #
-- # This source is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; #
-- # without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. #
-- # See the GNU Lesser General Public License for more details. #
-- # #
-- # You should have received a copy of the GNU Lesser General Public License along with this #
-- # source; if not, download it from https://www.gnu.org/licenses/lgpl-3.0.en.html #
-- # ********************************************************************************************* #
-- # Stephan Nolting, Hannover, Germany 25.04.2018 #
-- #################################################################################################
 
library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
 
library neo430;
use neo430.neo430_package.all;
 
entity neo430_trng is
port (
-- host access --
clk_i : in std_ulogic; -- global clock line
rden_i : in std_ulogic; -- read enable
wren_i : in std_ulogic_vector(01 downto 0); -- write enable
addr_i : in std_ulogic_vector(15 downto 0); -- address
data_i : in std_ulogic_vector(15 downto 0); -- data in
data_o : out std_ulogic_vector(15 downto 0) -- data out
);
end neo430_trng;
 
architecture neo430_trng_rtl of neo430_trng is
 
-- ADVANCED user configuration -------------------------------------------------------------------
constant num_trngs_c : natural := 6; -- number of random generators (= #oscillators, default = 6)
-- -----------------------------------------------------------------------------------------------
 
-- control register bits --
constant ctrl_rnd_en_c : natural := 0; -- -/w: TRNG enable
 
-- IO space: module base address --
constant hi_abb_c : natural := index_size(io_size_c)-1; -- high address boundary bit
constant lo_abb_c : natural := index_size(trng_size_c); -- low address boundary bit
 
-- access control --
signal acc_en : std_ulogic; -- module access enable
signal addr : std_ulogic_vector(15 downto 0); -- access address
signal wren : std_ulogic; -- full word write enable
signal rden : std_ulogic; -- read enable
 
-- random number generator --
signal sreg : std_ulogic_vector(7 downto 0);
signal cnt : std_ulogic_vector(2 downto 0);
signal rnd_gen : std_ulogic_vector(num_trngs_c-1 downto 0);
signal rnd_reset : std_ulogic_vector(num_trngs_c-1 downto 0);
signal rnd_enable : std_ulogic;
signal rnd_bit : std_ulogic;
signal rnd_sync0 : std_ulogic;
signal rnd_sync1 : std_ulogic;
signal rnd_data : std_ulogic_vector(7 downto 0); -- accessibe data register (read-only)
 
begin
 
-- Access Control -----------------------------------------------------------
-- -----------------------------------------------------------------------------
acc_en <= '1' when (addr_i(hi_abb_c downto lo_abb_c) = trng_base_c(hi_abb_c downto lo_abb_c)) else '0';
addr <= trng_base_c(15 downto lo_abb_c) & addr_i(lo_abb_c-1 downto 1) & '0'; -- word aligned
wren <= acc_en and wren_i(1) and wren_i(0);
rden <= acc_en and rden_i;
 
 
-- Write access -------------------------------------------------------------
-- -----------------------------------------------------------------------------
wr_access: process(clk_i)
begin
if rising_edge(clk_i) then
-- write access --
if (wren = '1') then
rnd_enable <= data_i(ctrl_rnd_en_c);
end if;
-- using individual resets for each OSC - derived from a shift register - to prevent the syntheisis tool
-- from removing all but one OSC (since they implement "logical identical functions")
rnd_reset <= rnd_reset(num_trngs_c-2 downto 0) & (not rnd_enable);
end if;
end process wr_access;
 
 
-- Random Generator ---------------------------------------------------------
-- -----------------------------------------------------------------------------
random_generator: process(rnd_reset, rnd_enable, rnd_gen)
variable rnd_v : std_ulogic;
begin
-- generators (oscillators) --
for i in 0 to num_trngs_c-1 loop
if (rnd_reset(i) = '1') then
rnd_gen(i) <= '0';
elsif (rnd_enable = '1') then -- yeah, these ARE latches ;)
rnd_gen(i) <= not rnd_gen(i); -- these are the oscillators
end if;
end loop; -- i
-- XOR all generators together --
rnd_v := rnd_gen(0);
for i in 1 to num_trngs_c-1 loop
rnd_v := rnd_v xor rnd_gen(i);
end loop; -- i
rnd_bit <= rnd_v;
end process random_generator;
 
 
-- Random Data Shift Register -----------------------------------------------
-- -----------------------------------------------------------------------------
data_sreg: process(clk_i)
begin
if rising_edge(clk_i) then
-- synchronize data --
rnd_sync0 <= rnd_bit;
rnd_sync1 <= rnd_sync0;
-- acquire data --
if (rnd_enable = '0') then
cnt <= (others => '0');
else
cnt <= std_ulogic_vector(unsigned(cnt) + 1);
sreg <= sreg(6 downto 0) & rnd_sync1;
end if;
-- sample output byte --
if (cnt = "000") and (rnd_enable = '1') then
rnd_data <= sreg;
end if;
end if;
end process data_sreg;
 
 
-- Read access --------------------------------------------------------------
-- -----------------------------------------------------------------------------
rd_access: process(clk_i)
begin
if rising_edge(clk_i) then
data_o <= (others => '0');
if (rden = '1') then
data_o(7 downto 0) <= rnd_data;
end if;
end if;
end process rd_access;
 
 
end neo430_trng_rtl;
-- #################################################################################################
-- # << NEO430 - True Random Number Generator >> #
-- # ********************************************************************************************* #
-- # True random number generator based on free running oscillators. These oscillators are built #
-- # from single inverters, where the output is directly used as input again. The feedback is de- #
-- # coupled using latches, which are transparent when the TRNG is running. The latches are auto- #
-- # matically initilized (reset) before operation. #
-- # ********************************************************************************************* #
-- # This file is part of the NEO430 Processor project: https://github.com/stnolting/neo430 #
-- # Copyright by Stephan Nolting: stnolting@gmail.com #
-- # #
-- # This source file may be used and distributed without restriction provided that this copyright #
-- # statement is not removed from the file and that any derivative work contains the original #
-- # copyright notice and the associated disclaimer. #
-- # #
-- # This source file is free software; you can redistribute it and/or modify it under the terms #
-- # of the GNU Lesser General Public License as published by the Free Software Foundation, #
-- # either version 3 of the License, or (at your option) any later version. #
-- # #
-- # This source is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; #
-- # without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. #
-- # See the GNU Lesser General Public License for more details. #
-- # #
-- # You should have received a copy of the GNU Lesser General Public License along with this #
-- # source; if not, download it from https://www.gnu.org/licenses/lgpl-3.0.en.html #
-- # ********************************************************************************************* #
-- # Stephan Nolting, Hannover, Germany 25.04.2018 #
-- #################################################################################################
 
library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
 
library neo430;
use neo430.neo430_package.all;
 
entity neo430_trng is
port (
-- host access --
clk_i : in std_ulogic; -- global clock line
rden_i : in std_ulogic; -- read enable
wren_i : in std_ulogic_vector(01 downto 0); -- write enable
addr_i : in std_ulogic_vector(15 downto 0); -- address
data_i : in std_ulogic_vector(15 downto 0); -- data in
data_o : out std_ulogic_vector(15 downto 0) -- data out
);
end neo430_trng;
 
architecture neo430_trng_rtl of neo430_trng is
 
-- ADVANCED user configuration -------------------------------------------------------------------
constant num_trngs_c : natural := 6; -- number of random generators (= #oscillators, default = 6)
-- -----------------------------------------------------------------------------------------------
 
-- control register bits --
constant ctrl_rnd_en_c : natural := 0; -- -/w: TRNG enable
 
-- IO space: module base address --
constant hi_abb_c : natural := index_size(io_size_c)-1; -- high address boundary bit
constant lo_abb_c : natural := index_size(trng_size_c); -- low address boundary bit
 
-- access control --
signal acc_en : std_ulogic; -- module access enable
signal addr : std_ulogic_vector(15 downto 0); -- access address
signal wren : std_ulogic; -- full word write enable
signal rden : std_ulogic; -- read enable
 
-- random number generator --
signal sreg : std_ulogic_vector(7 downto 0);
signal cnt : std_ulogic_vector(2 downto 0);
signal rnd_gen : std_ulogic_vector(num_trngs_c-1 downto 0);
signal rnd_reset : std_ulogic_vector(num_trngs_c-1 downto 0);
signal rnd_enable : std_ulogic;
signal rnd_bit : std_ulogic;
signal rnd_sync0 : std_ulogic;
signal rnd_sync1 : std_ulogic;
signal rnd_data : std_ulogic_vector(7 downto 0); -- accessibe data register (read-only)
 
begin
 
-- Access Control -----------------------------------------------------------
-- -----------------------------------------------------------------------------
acc_en <= '1' when (addr_i(hi_abb_c downto lo_abb_c) = trng_base_c(hi_abb_c downto lo_abb_c)) else '0';
addr <= trng_base_c(15 downto lo_abb_c) & addr_i(lo_abb_c-1 downto 1) & '0'; -- word aligned
wren <= acc_en and wren_i(1) and wren_i(0);
rden <= acc_en and rden_i
 
-- Write access -------------------------------------------------------------
-- -----------------------------------------------------------------------------
wr_access: process(clk_i)
begin
if rising_edge(clk_i) then
-- write access --
if (wren = '1') then
rnd_enable <= data_i(ctrl_rnd_en_c);
end if;
-- using individual resets for each OSC - derived from a shift register - to prevent the syntheisis tool
-- from removing all but one OSC (since they implement "logical identical functions")
rnd_reset <= rnd_reset(num_trngs_c-2 downto 0) & (not rnd_enable);
end if;
end process wr_access;
 
 
-- Random Generator ---------------------------------------------------------
-- -----------------------------------------------------------------------------
random_generator: process(rnd_reset, rnd_enable, rnd_gen)
variable rnd_v : std_ulogic;
begin
-- generators (oscillators) --
for i in 0 to num_trngs_c-1 loop
if (rnd_reset(i) = '1') then
rnd_gen(i) <= '0';
elsif (rnd_enable = '1') then -- yeah, these ARE latches ;)
rnd_gen(i) <= not rnd_gen(i); -- these are the oscillators
end if;
end loop; -- i
-- XOR all generators together --
rnd_v := rnd_gen(0);
for i in 1 to num_trngs_c-1 loop
rnd_v := rnd_v xor rnd_gen(i);
end loop; -- i
rnd_bit <= rnd_v;
end process random_generator;
 
 
-- Random Data Shift Register -----------------------------------------------
-- -----------------------------------------------------------------------------
data_sreg: process(clk_i)
begin
if rising_edge(clk_i) then
-- synchronize data --
rnd_sync0 <= rnd_bit;
rnd_sync1 <= rnd_sync0;
-- acquire data --
if (rnd_enable = '0') then
cnt <= (others => '0');
else
cnt <= std_ulogic_vector(unsigned(cnt) + 1);
sreg <= sreg(6 downto 0) & rnd_sync1;
end if;
-- sample output byte --
if (cnt = "000") and (rnd_enable = '1') then
rnd_data <= sreg;
end if;
end if;
end process data_sreg;
 
 
-- Read access --------------------------------------------------------------
-- -----------------------------------------------------------------------------
rd_access: process(clk_i)
begin
if rising_edge(clk_i) then
data_o <= (others => '0');
if (rden = '1') then
data_o(7 downto 0) <= rnd_data;
end if;
end if;
end process rd_access;
 
 
end neo430_trng_rtl;

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.