library IEEE; use IEEE.STD_LOGIC_1164.ALL; use IEEE.STD_LOGIC_ARITH.ALL; use IEEE.STD_LOGIC_UNSIGNED.ALL; -- Uncomment the following lines to use the declarations that are -- provided for instantiating Xilinx primitive components. --library UNISIM; --use UNISIM.VComponents.all; entity dap_simple_synth is port (clk : in std_logic; res : in std_logic; siNewSample : in std_logic; siRWValue : in std_logic_vector (31 downto 0); siRRValue : out std_logic_vector (31 downto 0); siRDo : in std_logic; siRRW : in std_logic; siRReg : in std_logic_vector ( 4 downto 0); output : out std_logic_vector (31 downto 0); output_osc : out std_logic_vector (31 downto 0) ); end dap_simple_synth; architecture Behavioral of dap_simple_synth is signal siOscCounter : std_logic_vector (31 downto 0); signal siOscFreq : std_logic_vector (31 downto 0); signal siOscValue : std_logic_vector (31 downto 0); signal siOscWave : std_logic_vector (31 downto 0); signal siOscPWM : std_logic_vector (31 downto 0); signal siOscVolume : signed (31 downto 0); signal siOscOutputT : signed (31 downto 0); signal siOscOutput : signed (31 downto 0); signal siBQ1MemA1 : signed (31 downto 0); signal siBQ1MemA2 : signed (31 downto 0); signal siBQ1MemB1 : signed (31 downto 0); signal siBQ1MemB2 : signed (31 downto 0); signal siBQ1CofA1 : signed (31 downto 0); signal siBQ1CofA2 : signed (31 downto 0); signal siBQ1CofB1 : signed (31 downto 0); signal siBQ1CofB2 : signed (31 downto 0); signal siBQ1CofB3 : signed (31 downto 0); signal siBQ1CofA1S : signed (31 downto 0); signal siBQ1CofA2S : signed (31 downto 0); signal siBQ1CofB1S : signed (31 downto 0); signal siBQ1CofB2S : signed (31 downto 0); signal siBQ1CofB3S : signed (31 downto 0); signal siBQ1Output : signed (31 downto 0); signal siBQ1WrShadow : std_logic; signal siTMP_Var64 : signed (63 downto 0); type tstStates is ( stWaitSample, stOSC_01, stOSC_02, stOSC_03, stOSC_04, stOSC_05, stBQ1_01, stBQ1_02, stBQ1_03, stBQ1_04, stBQ1_05, stBQ1_06, stBQ1_07, stBQ1_08, stBQ1_09, stBQ1_10, stBQ1_11, stBQ1_12, stBQ1_13, stOutput ); signal siState : tstStates; -- 3 2 1 0 -- 10987654321098765432109876543210 constant cAUDIO_M10 : signed (31 downto 0) := "11111111000000000000000000000000"; constant cAUDIO_P10 : signed (31 downto 0) := "00000000111111111111111111111111"; constant cAUDIO_NUL : signed (31 downto 0) := "00000000000000000000000000000000"; begin process (clk, res, siState, siNewSample, siOscCounter, siOscFreq, siOscValue, siOscWave, siOscVolume, siOscPWM, siOscOutput ) begin if res = '1' then siOscCounter <= (others => '0'); siOscFreq <= X"08000000"; siOscValue <= (others => '0'); siOscWave <= X"00000002"; siOscPWM <= X"007fffff"; siOscVolume <= X"00ffffff"; siOscOutput <= (others => '0'); siTMP_Var64 <= (others => '0'); siOscOutputT <= (others => '0'); siBQ1MemA1 <= (others => '0'); siBQ1MemA2 <= (others => '0'); siBQ1MemB1 <= (others => '0'); siBQ1MemB2 <= (others => '0'); siBQ1CofA1 <= X"ff34e536"; siBQ1CofA2 <= X"00000000"; siBQ1CofB1 <= X"00308000"; siBQ1CofB2 <= X"00610000"; siBQ1CofB3 <= X"00000000"; siBQ1CofA1S <= X"ff34e536"; siBQ1CofA2S <= X"00000000"; siBQ1CofB1S <= X"00308000"; siBQ1CofB2S <= X"00610000"; siBQ1CofB3S <= X"00000000"; siBQ1Output <= (others => '0'); siBQ1WrShadow <= '0'; siState <= stWaitSample; elsif clk'event and clk = '1' then if siRDo = '1' then if siRRW = '0' then case siRReg is when "00000" => siOscFreq <= siRWValue; when "00001" => siOscWave <= siRWValue; when "00010" => siOscPWM <= siRWValue; when "00011" => siOscVolume <= signed (siRWValue); when "00100" => siBQ1CofA1S <= signed (siRWValue); when "00101" => siBQ1CofA2S <= signed (siRWValue); when "00110" => siBQ1CofB1S <= signed (siRWValue); when "00111" => siBQ1CofB2S <= signed (siRWValue); when "01000" => siBQ1CofB3S <= signed (siRWValue); when "01001" => siBQ1WrShadow <= '1'; when others => NULL; end case; else case siRReg is when "00000" => siRRValue <= siOscFreq ; when "00001" => siRRValue <= siOscWave ; when "00010" => siRRValue <= siOscPWM ; when "00011" => siRRValue <= std_logic_vector (siOscVolume ); when "00100" => siRRValue <= std_logic_vector (siBQ1CofA1S ); when "00101" => siRRValue <= std_logic_vector (siBQ1CofA2S ); when "00110" => siRRValue <= std_logic_vector (siBQ1CofB1S ); when "00111" => siRRValue <= std_logic_vector (siBQ1CofB2S ); when "01000" => siRRValue <= std_logic_vector (siBQ1CofB3S ); when others => NULL; end case; end if; end if; case siState is when stWaitSample => if siNewSample = '1' then siState <= stOSC_01; else siState <= stWaitSample; end if; when stOSC_01 => siOscCounter <= siOscCounter + siOscFreq; siState <= stOSC_02; when stOSC_02 => siOscValue <= "00000000" & siOscCounter (31 downto 8); siState <= stOSC_03; when stOSC_03 => case siOscWave (1 downto 0) is when "00" => siOscOutputT <= signed (siOscValue - X"00800000"); when "01" => if siOscValue > siOscPWM then siOscOutputT <= cAUDIO_M10; else siOscOutputT <= cAUDIO_P10; end if; when "10" => if siOscValue (23) = '1' then siOscOutputT <= cAUDIO_P10 - signed ("00000000" & (siOscValue (22 downto 0) & '0')); else siOscOutputT <= cAUDIO_M10 + signed ("00000000" & (siOscValue (22 downto 0) & '0')); end if; when others => siOscOutputT <= cAUDIO_NUL; end case; siState <= stOSC_04; when stOSC_04 => siTMP_Var64 <= siOscOutputT * siOscVolume; siState <= stOSC_05; when stOSC_05 => siOscOutput <= siTMP_Var64 (55 downto 24); -- 8bit overhead bei oscillator ignorieren (läuft nur auf 24 bit !!) siState <= stBQ1_01; when stBQ1_01 => siTMP_Var64 <= (siOscOutput * siBQ1CofB1); siState <= stBQ1_02; when stBQ1_02 => siBQ1Output <= siTMP_Var64 (55 downto 24); siState <= stBQ1_03; when stBQ1_03 => siTMP_Var64 <= siBQ1MemB1 * siBQ1CofB2; siState <= stBQ1_04; when stBQ1_04 => siBQ1Output <= siBQ1Output + siTMP_Var64 (55 downto 24); siState <= stBQ1_05; when stBQ1_05 => siTMP_Var64 <= siBQ1MemB2 * siBQ1CofB3; siState <= stBQ1_06; when stBQ1_06 => siBQ1Output <= siBQ1Output + siTMP_Var64 (55 downto 24); siState <= stBQ1_07; when stBQ1_07 => siTMP_Var64 <= siBQ1MemA1 * siBQ1CofA1; siState <= stBQ1_08; when stBQ1_08 => siBQ1Output <= siBQ1Output + siTMP_Var64 (55 downto 24); siState <= stBQ1_09; when stBQ1_09 => siTMP_Var64 <= siBQ1MemA2 * siBQ1CofA2; siState <= stBQ1_10; when stBQ1_10 => siBQ1Output <= siBQ1Output + siTMP_Var64 (55 downto 24); siState <= stBQ1_11; when stBQ1_11 => siBQ1MemA2 <= siBQ1MemA1; siBQ1MemB2 <= siBQ1MemB1; siState <= stBQ1_12; when stBQ1_12 => siBQ1MemA1 <= siBQ1Output; siBQ1MemB1 <= siOscOutput; siState <= stBQ1_13; when stBQ1_13 => if siBQ1WrShadow = '1' then siBQ1CofA1 <= siBQ1CofA1S; siBQ1CofA2 <= siBQ1CofA2S; siBQ1CofB1 <= siBQ1CofB1S; siBQ1CofB2 <= siBQ1CofB2S; siBQ1CofB3 <= siBQ1CofB3S; siBQ1WrShadow <= '0'; end if; siState <= stOutput; when stOutput => output <= std_logic_vector (siBQ1Output); output_osc <= std_logic_vector (siOscOutput); siState <= stWaitSample; when others => siState <= stWaitSample; end case; end if; end process; end Behavioral;