74 lines
2.0 KiB
VHDL
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;
|