repo2/atari_chips/pokey/pokey_mixer_mux.vhdl
714 | markw | ---------------------------------------------------------------------------
|
|
-- (c) 2014 mark watson
|
|||
-- I am happy for anyone to use this for non-commercial use.
|
|||
-- If my vhdl files are used commercially or otherwise sold,
|
|||
-- please contact me for explicit permission at scrameta (gmail).
|
|||
-- This applies for source and binary form and derived works.
|
|||
---------------------------------------------------------------------------
|
|||
LIBRARY ieee;
|
|||
USE ieee.std_logic_1164.all;
|
|||
use ieee.numeric_std.all;
|
|||
use IEEE.STD_LOGIC_MISC.all;
|
|||
ENTITY pokey_mixer_mux IS
|
|||
PORT
|
|||
(
|
|||
CLK : IN STD_LOGIC;
|
|||
ENABLE_179 : IN STD_LOGIC;
|
|||
CHANNEL_L_0 : IN STD_LOGIC_VECTOR(3 downto 0);
|
|||
CHANNEL_L_1 : IN STD_LOGIC_VECTOR(3 downto 0);
|
|||
CHANNEL_L_2 : IN STD_LOGIC_VECTOR(3 downto 0);
|
|||
CHANNEL_L_3 : IN STD_LOGIC_VECTOR(3 downto 0);
|
|||
CHANNEL_R_0 : IN STD_LOGIC_VECTOR(3 downto 0);
|
|||
CHANNEL_R_1 : IN STD_LOGIC_VECTOR(3 downto 0);
|
|||
CHANNEL_R_2 : IN STD_LOGIC_VECTOR(3 downto 0);
|
|||
CHANNEL_R_3 : IN STD_LOGIC_VECTOR(3 downto 0);
|
|||
734 | markw | VOLUME_OUT_M : OUT STD_LOGIC_vector(15 downto 0);
|
|
714 | markw | VOLUME_OUT_L : OUT STD_LOGIC_vector(15 downto 0);
|
|
VOLUME_OUT_R : OUT STD_LOGIC_vector(15 downto 0)
|
|||
);
|
|||
END pokey_mixer_mux;
|
|||
ARCHITECTURE vhdl OF pokey_mixer_mux IS
|
|||
734 | markw | signal CHANNEL_NEXT : STD_LOGIC_VECTOR(2 downto 0);
|
|
signal CHANNEL_REG : STD_LOGIC_VECTOR(2 downto 0) := "100";
|
|||
-- 100->left
|
|||
-- 010->right
|
|||
-- 001->both!
|
|||
714 | markw | ||
signal CHANNEL_0_SEL : STD_LOGIC_VECTOR(3 downto 0);
|
|||
signal CHANNEL_1_SEL : STD_LOGIC_VECTOR(3 downto 0);
|
|||
signal CHANNEL_2_SEL : STD_LOGIC_VECTOR(3 downto 0);
|
|||
signal CHANNEL_3_SEL : STD_LOGIC_VECTOR(3 downto 0);
|
|||
signal VOLUME_OUT_NEXT : STD_LOGIC_VECTOR(15 downto 0);
|
|||
signal VOLUME_OUT_L_NEXT : STD_LOGIC_VECTOR(15 downto 0);
|
|||
signal VOLUME_OUT_L_REG : STD_LOGIC_VECTOR(15 downto 0);
|
|||
signal VOLUME_OUT_R_NEXT : STD_LOGIC_VECTOR(15 downto 0);
|
|||
signal VOLUME_OUT_R_REG : STD_LOGIC_VECTOR(15 downto 0);
|
|||
734 | markw | signal VOLUME_OUT_M_NEXT : STD_LOGIC_VECTOR(15 downto 0);
|
|
signal VOLUME_OUT_M_REG : STD_LOGIC_VECTOR(15 downto 0);
|
|||
714 | markw | ||
signal VOLUME_POSTLOWPASS_L_REG : STD_LOGIC_VECTOR(15 downto 0);
|
|||
signal VOLUME_POSTLOWPASS_R_REG : STD_LOGIC_VECTOR(15 downto 0);
|
|||
734 | markw | signal VOLUME_POSTLOWPASS_M_REG : STD_LOGIC_VECTOR(15 downto 0);
|
|
signal channel_sum : std_logic_vector(6 downto 0);
|
|||
714 | markw | BEGIN
|
|
process(clk)
|
|||
begin
|
|||
if (clk'event and clk='1') then
|
|||
734 | markw | CHANNEL_REG <= CHANNEL_NEXT;
|
|
CHANNEL_REG <= CHANNEL_NEXT;
|
|||
714 | markw | ||
VOLUME_OUT_L_REG <= VOLUME_OUT_L_NEXT;
|
|||
VOLUME_OUT_R_REG <= VOLUME_OUT_R_NEXT;
|
|||
734 | markw | VOLUME_OUT_M_REG <= VOLUME_OUT_M_NEXT;
|
|
714 | markw | END IF;
|
|
END PROCESS;
|
|||
734 | markw | -- takes a few cycles for each channel
|
|
CHANNEL_NEXT(1 downto 0) <= CHANNEL_REG(2 downto 1);
|
|||
CHANNEL_NEXT(2) <= CHANNEL_REG(0);
|
|||
CHANNEL_NEXT(1 downto 0) <= CHANNEL_REG(2 downto 1);
|
|||
CHANNEL_NEXT(2) <= CHANNEL_REG(0);
|
|||
714 | markw | ||
-- mux input
|
|||
PROCESS(
|
|||
734 | markw | CHANNEL_L_0, CHANNEL_L_1, CHANNEL_L_2, CHANNEL_L_3,
|
|
CHANNEL_R_0, CHANNEL_R_1, CHANNEL_R_2, CHANNEL_R_3,
|
|||
channel_reg
|
|||
)
|
|||
variable left_sum : unsigned(6 downto 0);
|
|||
variable right_sum : unsigned(6 downto 0);
|
|||
variable both_sum : unsigned(6 downto 0);
|
|||
714 | markw | BEGIN
|
|
734 | markw | channel_sum <= (OTHERS=>'0');
|
|
714 | markw | ||
734 | markw | left_sum :=
|
|
(resize(unsigned(CHANNEL_L_0),7) + resize(unsigned(CHANNEL_L_1),7)) +
|
|||
(resize(unsigned(CHANNEL_L_2),7) + resize(unsigned(CHANNEL_L_3),7));
|
|||
right_sum :=
|
|||
(resize(unsigned(CHANNEL_R_0),7) + resize(unsigned(CHANNEL_R_1),7)) +
|
|||
(resize(unsigned(CHANNEL_R_2),7) + resize(unsigned(CHANNEL_R_3),7));
|
|||
both_sum := left_sum + right_sum;
|
|||
736 | markw | if (both_sum(6)='1') then
|
|
both_sum(5 downto 0) := (others=>'1');
|
|||
end if;
|
|||
714 | markw | ||
734 | markw | case channel_reg is
|
|
when "100" => -- left
|
|||
channel_sum <= std_logic_vector(left_sum);
|
|||
when "010" => -- right
|
|||
channel_sum <= std_logic_vector(right_sum);
|
|||
when others => -- both
|
|||
channel_sum <= std_logic_vector(both_sum);
|
|||
end case;
|
|||
714 | markw | ||
END PROCESS;
|
|||
-- shared mixer
|
|||
shared_pokey_mixer : entity work.pokey_mixer
|
|||
port map
|
|||
(
|
|||
734 | markw | CLK => CLK, -- takes 2 cycle...
|
|
714 | markw | ||
735 | markw | sum => channel_sum,
|
|
714 | markw | ||
VOLUME_OUT_NEXT => VOLUME_OUT_NEXT
|
|||
);
|
|||
-- mux output
|
|||
PROCESS(
|
|||
VOLUME_OUT_NEXT,
|
|||
VOLUME_OUT_L_REG,
|
|||
VOLUME_OUT_R_REG,
|
|||
734 | markw | VOLUME_OUT_M_REG,
|
|
CHANNEL_REG)
|
|||
714 | markw | BEGIN
|
|
VOLUME_OUT_L_NEXT <= VOLUME_OUT_L_REG;
|
|||
VOLUME_OUT_R_NEXT <= VOLUME_OUT_R_REG;
|
|||
734 | markw | VOLUME_OUT_M_NEXT <= VOLUME_OUT_M_REG;
|
|
714 | markw | ||
734 | markw | case channel_reg is
|
|
when "010" => -- left
|
|||
714 | markw | VOLUME_OUT_L_NEXT <= VOLUME_OUT_NEXT;
|
|
734 | markw | when "001" => -- right
|
|
714 | markw | VOLUME_OUT_R_NEXT <= VOLUME_OUT_NEXT;
|
|
734 | markw | when others => -- both
|
|
VOLUME_OUT_M_NEXT <= VOLUME_OUT_NEXT;
|
|||
end case;
|
|||
714 | markw | END PROCESS;
|
|
-- low pass filter output
|
|||
filter_left : entity work.simple_low_pass_filter
|
|||
port map
|
|||
(
|
|||
CLK => CLK,
|
|||
AUDIO_IN => VOLUME_OUT_L_REG,
|
|||
SAMPLE_IN => ENABLE_179,
|
|||
AUDIO_OUT => VOLUME_POSTLOWPASS_L_REG
|
|||
);
|
|||
filter_right : entity work.simple_low_pass_filter
|
|||
port map
|
|||
(
|
|||
CLK => CLK,
|
|||
AUDIO_IN => VOLUME_OUT_R_REG,
|
|||
SAMPLE_IN => ENABLE_179,
|
|||
AUDIO_OUT => VOLUME_POSTLOWPASS_R_REG
|
|||
);
|
|||
734 | markw | filter_both : entity work.simple_low_pass_filter
|
|
port map
|
|||
(
|
|||
CLK => CLK,
|
|||
AUDIO_IN => VOLUME_OUT_M_REG,
|
|||
SAMPLE_IN => ENABLE_179,
|
|||
AUDIO_OUT => VOLUME_POSTLOWPASS_M_REG
|
|||
);
|
|||
714 | markw | ||
-- output
|
|||
VOLUME_OUT_L <= VOLUME_POSTLOWPASS_L_REG;
|
|||
VOLUME_OUT_R <= VOLUME_POSTLOWPASS_R_REG;
|
|||
734 | markw | VOLUME_OUT_M <= VOLUME_POSTLOWPASS_M_REG;
|
|
714 | markw | ||
END vhdl;
|