RFToolSDR/fpga/whitenoise/whitenoise-gen.vhd

74 lines
2.0 KiB
VHDL

library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.NUMERIC_STD.ALL;
--Parameterisable Gaussian White Noise Generator
--Copyright (C) 2017 David Shah
--Licensed under the MIT License
--This uses a number of LFSR pseudorandom number generators in combination with
--central limit theorem to generate gaussian noise for test purposes
entity whitenoise_gen is
generic(
int_width : natural := 32; --width of LFSRs and interal calcs
ext_width : natural := 12; --width of external value output
num_lfsrs : natural := 20; --number of parallel LFSRs
lfsr_poly : std_logic_vector := x"80000057" --LFSR polynomial
);
port(
clock : in std_logic;
enable : in std_logic;
reset : in std_logic;
data : out std_logic_vector(ext_width - 1 downto 0)
);
end whitenoise_gen;
architecture Behavioral of whitenoise_gen is
type lfsr_value_t is array(0 to num_lfsrs - 1) of std_logic_vector(int_width - 1 downto 0);
signal lfsr_q : lfsr_value_t;
signal sum_d : std_logic_vector(int_width - 1 downto 0) := (others => '0');
signal sum_q : std_logic_vector(int_width - 1 downto 0);
begin
lfsr_gen: for i in 0 to num_lfsrs - 1 generate
lfsr_i : entity work.galois_lfsr
generic map(
size => int_width,
polynomial => lfsr_poly,
init => std_logic_vector(to_unsigned( i + 1, int_width)))
port map(
clock => clock,
enable => enable,
reset => reset,
data => lfsr_q(i));
end generate;
process(lfsr_q)
variable sum : signed(int_width - 1 downto 0);
begin
sum := (others => '0');
for i in 0 to num_lfsrs - 1 loop
sum := sum + signed(lfsr_q(i));
end loop;
sum_d <= std_logic_vector(sum);
end process;
process(clock)
begin
if rising_edge(clock) then
if reset = '1' then
sum_q <= (others => '0');
elsif enable = '1' then
sum_q <= sum_d;
end if;
end if;
end process;
data <= sum_q(int_width - 1 downto (int_width - ext_width));
end Behavioral;