Skip to content
Snippets Groups Projects
wave_generator.vhd 4.46 KiB
-- TOP module of a wave generator
-- generic parameters:
-- N: number of bits of the sine value
-- f0: fundamental frequency
-- fs: sampling frequency
-- Inputs:
-- CLK, RST
-- WAVE_SEL : selects the type of waveform (sine, square, triangle, saw-tooth)
-- Outputs:
-- WAV: the wave output

library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
use ieee.math_real.all;

entity wave_generator is
    generic (
        G_N  : integer := 8;
        G_f0 : real    := 1.0;
        G_fs : real    := 100.0
        );
    port (
        I_clk      : in  std_logic;
        I_rst      : in  std_logic;
        I_wave_sel : in  std_logic_vector(1 downto 0);
        O_wav      : out std_logic_vector(G_N-1 downto 0)
        );
end wave_generator;

architecture arch of wave_generator is

    constant C_addr_half_w : integer := integer(ceil(log2(real(natural(floor(G_fs/(4.0*G_f0)))))));

    signal S_addr                 : std_logic_vector(integer(ceil(log2(real(natural(floor(G_fs/(2.0*G_f0))))))) - 1 downto 0);
    signal S_sine_out_lut         : std_logic_vector(G_N-1 downto 0);
    signal S_square               : std_logic_vector(G_N-1 downto 0);
    signal S_triangle_out_lut     : std_logic_vector(G_N-1 downto 0);
    signal S_saw_tooth_out_lut    : std_logic_vector(G_N-1 downto 0);
    signal S_opposite_wave_sample : std_logic_vector(G_N-1 downto 0);
    signal S_wave_value           : std_logic_vector(G_N-1 downto 0);
    signal S_wave_sample          : std_logic_vector(G_N-1 downto 0);
    signal S_last                 : std_logic;
    signal S_middle               : std_logic;
    signal S_u_d                  : std_logic;
    signal S_sign_sel             : std_logic;

begin
    -- Module A
    A_inst : entity work.module_A
        port map (
            I_clk      => I_clk,
            I_rst      => I_rst,
            I_wave_sel => I_wave_sel,
            I_middle   => S_middle,
            I_last     => S_last,
            O_u_d      => S_u_d,
            O_sign_sel => S_sign_sel
            );

    -- Module B
    B_inst : entity work.module_B
        generic map (
            G_MAX_VAL => natural(floor(G_fs/(2.0*G_f0)))
            )
        port map (
            I_clk    => I_clk,
            I_rst    => I_rst,
            I_u_d    => S_u_d,
            O_val    => S_addr,
            O_last   => S_last,
            O_middle => S_middle
            );

    -- Module C
    C_inst : entity work.module_C
        generic map (
            G_N  => G_N,
            G_f0 => G_f0,
            G_fs => G_fs
            )
        port map (
            I_clk  => I_clk,
            I_rst  => I_rst,
            I_addr => S_addr(C_addr_half_w-1 downto 0),
            O_sine => S_sine_out_lut
            );

    -- Module D
    D_inst : entity work.module_D
        generic map (
            G_N  => G_N,
            G_f0 => G_f0,
            G_fs => G_fs
            )
        port map (
            I_clk      => I_clk,
            I_rst      => I_rst,
            I_addr     => S_addr(C_addr_half_w-1 downto 0),
            O_triangle => S_triangle_out_lut
            );

    -- Module E
    E_inst : entity work.module_E
        generic map (
            G_N  => G_N,
            G_f0 => G_f0,
            G_fs => G_fs
            )
        port map (
            I_clk       => I_clk ,
            I_rst       => I_rst,
            I_addr      => S_addr,
            O_saw_tooth => S_saw_tooth_out_lut
            );

    S_square <= ((G_N-1) => '0', others => '1');

    -- Module F
    F_inst : entity work.module_F
        port map (
            I_sel  => I_wave_sel,
            I_din0 =>  S_sine_out_lut,
            I_din1 => S_square,
            I_din2 => S_saw_tooth_out_lut,
            I_din3 => S_triangle_out_lut,
            O_dout => S_wave_sample
            );

    -- Module G
    G_inst : entity work.module_G
        generic map(
            G_N => G_N
            )
        port map (
            I_din  => S_wave_sample,
            O_dout => S_opposite_wave_sample
            );

    -- Module H
    H_inst : entity work.module_H
        port map (
            I_sel  => S_sign_sel,
            I_din0 => S_wave_sample,
            I_din1 => S_opposite_wave_sample,
            O_dout => S_wave_value
            );

    -- Module I
    I_inst : entity work.module_I
        generic map (
            G_N => G_N
            )
        port map (
            I_clk  => I_clk,
            I_rst  => I_rst,
            I_din  => S_wave_value,
            O_dout => O_wav
            );

end arch;