| 
    
       ---------------------------------------------------------------------------
 
     | 
  
  
     | 
    
       -- (c) 2020 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_UNSIGNED.ALL;
 
     | 
  
  
     | 
    
       use IEEE.STD_LOGIC_MISC.all;
 
     | 
  
  
     | 
    
       use work.AudioTypes.all;
 
     | 
  
  
     | 
    
       
     | 
  
  
     | 
    
       LIBRARY work;
 
     | 
  
  
     | 
    
       
     | 
  
  
     | 
    
       ENTITY mixer IS 
 
     | 
  
  
     | 
    
       PORT
 
     | 
  
  
     | 
    
       (
 
     | 
  
  
     | 
    
       	CLK : IN STD_LOGIC;
 
     | 
  
  
     | 
    
       	RESET_N : IN STD_LOGIC;
 
     | 
  
  
     | 
    
       
     | 
  
  
     | 
    
       	ENABLE_CYCLE : IN STD_LOGIC;
 
     | 
  
  
     | 
    
       
     | 
  
  
     | 
    
       	DETECT_RIGHT : IN STD_LOGIC;
 
     | 
  
  
     | 
    
       	POST_DIVIDE : IN STD_LOGIC_VECTOR(7 downto 0);
 
     | 
  
  
     | 
    
       	FANCY_ENABLE : IN STD_LOGIC;
 
     | 
  
  
     | 
    
       	GTIA_EN : IN STD_LOGIC_VECTOR(3 downto 0);	
 
     | 
  
  
     | 
    
       	ADC_EN : IN STD_LOGIC_VECTOR(3 downto 0);	
 
     | 
  
  
     | 
    
       
     | 
  
  
     | 
    
       	CH0 : IN UNSIGNED(15 downto 0); --pokey0
 
     | 
  
  
     | 
    
       	CH1 : IN UNSIGNED(15 downto 0); --pokey1
 
     | 
  
  
     | 
    
       	CH2 : IN UNSIGNED(15 downto 0); --pokey2
 
     | 
  
  
     | 
    
       	CH3 : IN UNSIGNED(15 downto 0); --pokey3
 
     | 
  
  
     | 
    
       	CH4 : IN UNSIGNED(15 downto 0); --sample0
 
     | 
  
  
     | 
    
       	CH5 : IN UNSIGNED(15 downto 0); --sample1
 
     | 
  
  
     | 
    
       	CH6 : IN UNSIGNED(15 downto 0); --sid0
 
     | 
  
  
     | 
    
       	CH7 : IN UNSIGNED(15 downto 0); --sid1
 
     | 
  
  
     | 
    
       	CH8 : IN UNSIGNED(15 downto 0); --psg0
 
     | 
  
  
     | 
    
       	CH9 : IN UNSIGNED(15 downto 0); --psg1
 
     | 
  
  
     | 
    
       	CHA : IN UNSIGNED(15 downto 0); --gtia0	
 
     | 
  
  
     | 
    
       	CHB : IN UNSIGNED(15 downto 0); --adc	
 
     | 
  
  
     | 
    
       
     | 
  
  
     | 
    
       	AUDIO_0_UNSIGNED : out unsigned(15 downto 0);
 
     | 
  
  
     | 
    
       	AUDIO_1_UNSIGNED : out unsigned(15 downto 0);
 
     | 
  
  
     | 
    
       	AUDIO_2_UNSIGNED : out unsigned(15 downto 0);
 
     | 
  
  
     | 
    
       	AUDIO_3_UNSIGNED : out unsigned(15 downto 0)
 
     | 
  
  
     | 
    
       );
 
     | 
  
  
     | 
    
       END mixer;		
 
     | 
  
  
     | 
    
       		
 
     | 
  
  
     | 
    
       ARCHITECTURE vhdl OF mixer IS
 
     | 
  
  
     | 
    
       	-- DETECT RIGHT PLAYING
 
     | 
  
  
     | 
    
       	signal RIGHT_PLAYING_RECENTLY : std_logic;
 
     | 
  
  
     | 
    
       	signal RIGHT_NEXT : std_logic;
 
     | 
  
  
     | 
    
       	signal RIGHT_REG : std_logic;
 
     | 
  
  
     | 
    
       	signal RIGHT_PLAYING_COUNT_NEXT : unsigned(23 downto 0);
 
     | 
  
  
     | 
    
       	signal RIGHT_PLAYING_COUNT_REG : unsigned(23 downto 0);
 
     | 
  
  
     | 
    
       
     | 
  
  
     | 
    
       	-- sums
 
     | 
  
  
     | 
    
       	signal audio0_reg : unsigned(15 downto 0);
 
     | 
  
  
     | 
    
       	signal audio0_next : unsigned(15 downto 0);
 
     | 
  
  
     | 
    
       	signal audio1_reg : unsigned(15 downto 0);
 
     | 
  
  
     | 
    
       	signal audio1_next : unsigned(15 downto 0);
 
     | 
  
  
     | 
    
       	signal audio2_reg : unsigned(15 downto 0);
 
     | 
  
  
     | 
    
       	signal audio2_next : unsigned(15 downto 0);
 
     | 
  
  
     | 
    
       	signal audio3_reg : unsigned(15 downto 0);
 
     | 
  
  
     | 
    
       	signal audio3_next : unsigned(15 downto 0);
 
     | 
  
  
     | 
    
       
     | 
  
  
     | 
    
       	signal acc_reg : unsigned(19 downto 0);
 
     | 
  
  
     | 
    
       	signal acc_next : unsigned(19 downto 0);
 
     | 
  
  
     | 
    
       	
 
     | 
  
  
     | 
    
       	signal secondBatch_reg : std_logic;
 
     | 
  
  
     | 
    
       	signal secondBatch_next : std_logic;
 
     | 
  
  
     | 
    
       	
 
     | 
  
  
     | 
    
       	signal state_reg : unsigned(3 downto 0);
 
     | 
  
  
     | 
    
       	signal state_next : unsigned(3 downto 0);
 
     | 
  
  
     | 
    
       	constant state_pokeyA_L : unsigned(3 downto 0) := "0000";
 
     | 
  
  
     | 
    
       	constant state_pokeyB_L : unsigned(3 downto 0) := "0001";
 
     | 
  
  
     | 
    
       	constant state_sample_L : unsigned(3 downto 0) := "0010";
 
     | 
  
  
     | 
    
       	constant state_sid_L    : unsigned(3 downto 0) := "0011";
 
     | 
  
  
     | 
    
       	constant state_psg_L    : unsigned(3 downto 0) := "0100";
 
     | 
  
  
     | 
    
       	constant state_adc_L    : unsigned(3 downto 0) := "0101";
 
     | 
  
  
     | 
    
       	constant state_gtia_L   : unsigned(3 downto 0) := "0110";
 
     | 
  
  
     | 
    
       	constant state_clear_L  : unsigned(3 downto 0) := "0111";
 
     | 
  
  
     | 
    
       	constant state_pokeyA_R : unsigned(3 downto 0) := "1000";
 
     | 
  
  
     | 
    
       	constant state_pokeyB_R : unsigned(3 downto 0) := "1001";
 
     | 
  
  
     | 
    
       	constant state_sample_R : unsigned(3 downto 0) := "1010";
 
     | 
  
  
     | 
    
       	constant state_sid_R    : unsigned(3 downto 0) := "1011";
 
     | 
  
  
     | 
    
       	constant state_psg_R    : unsigned(3 downto 0) := "1100";
 
     | 
  
  
     | 
    
       	constant state_adc_R    : unsigned(3 downto 0) := "1101";
 
     | 
  
  
     | 
    
       	constant state_gtia_R   : unsigned(3 downto 0) := "1110";
 
     | 
  
  
     | 
    
       	constant state_clear_R  : unsigned(3 downto 0) := "1111";
 
     | 
  
  
     | 
    
       	
 
     | 
  
  
     | 
    
       	signal channelsel : std_logic_vector(3 downto 0);
 
     | 
  
  
     | 
    
       	
 
     | 
  
  
     | 
    
       	signal volume : unsigned(15 downto 0);
 
     | 
  
  
     | 
    
       	signal saturated : unsigned(15 downto 0);
 
     | 
  
  
     | 
    
       	
 
     | 
  
  
     | 
    
       	signal ready : std_logic;
 
     | 
  
  
     | 
    
       	
 
     | 
  
  
     | 
    
       	signal write_0 : std_logic;
 
     | 
  
  
     | 
    
       	signal write_1 : std_logic;
 
     | 
  
  
     | 
    
       	signal write_2 : std_logic;
 
     | 
  
  
     | 
    
       	signal write_3 : std_logic;
 
     | 
  
  
     | 
    
       BEGIN
 
     | 
  
  
     | 
    
       -- DETECT IF RIGHT CHANNEL PLAYING
 
     | 
  
  
     | 
    
       -- TODO: into another entity
 
     | 
  
  
     | 
    
       process(clk,reset_n)
 
     | 
  
  
     | 
    
       begin
 
     | 
  
  
     | 
    
       	if (reset_n='0') then
 
     | 
  
  
     | 
    
       		RIGHT_REG <= '0';
 
     | 
  
  
     | 
    
       		RIGHT_PLAYING_COUNT_REG <= (others=>'0');
 
     | 
  
  
     | 
    
       		audio0_reg <= (others=>'0');
 
     | 
  
  
     | 
    
       		audio1_reg <= (others=>'0');
 
     | 
  
  
     | 
    
       		audio2_reg <= (others=>'0');
 
     | 
  
  
     | 
    
       		audio3_reg <= (others=>'0');
 
     | 
  
  
     | 
    
       		acc_reg <= (others=>'0');
 
     | 
  
  
     | 
    
       		secondBatch_reg <= '0';
 
     | 
  
  
     | 
    
       		state_reg <= state_pokeyA_L;
 
     | 
  
  
     | 
    
       	elsif (clk'event and clk='1') then
 
     | 
  
  
     | 
    
       		RIGHT_REG <= RIGHT_NEXT;
 
     | 
  
  
     | 
    
       		RIGHT_PLAYING_COUNT_REG <= RIGHT_PLAYING_COUNT_NEXT;
 
     | 
  
  
     | 
    
       		audio0_reg <= audio0_next;
 
     | 
  
  
     | 
    
       		audio1_reg <= audio1_next;
 
     | 
  
  
     | 
    
       		audio2_reg <= audio2_next;
 
     | 
  
  
     | 
    
       		audio3_reg <= audio3_next;
 
     | 
  
  
     | 
    
       		acc_reg <= acc_next;
 
     | 
  
  
     | 
    
       		secondBatch_reg <= secondBatch_next;
 
     | 
  
  
     | 
    
       		state_reg <= state_next;
 
     | 
  
  
     | 
    
       	end if;
 
     | 
  
  
     | 
    
       end process;
 
     | 
  
  
     | 
    
       
     | 
  
  
     | 
    
       process(RIGHT_NEXT,RIGHT_REG,ENABLE_CYCLE,RIGHT_PLAYING_RECENTLY,RIGHT_PLAYING_COUNT_REG)
 
     | 
  
  
     | 
    
       begin
 
     | 
  
  
     | 
    
       	RIGHT_PLAYING_COUNT_NEXT <= RIGHT_PLAYING_COUNT_REG;
 
     | 
  
  
     | 
    
       
     | 
  
  
     | 
    
       	if (ENABLE_CYCLE='1' and RIGHT_PLAYING_RECENTLY='1') then
 
     | 
  
  
     | 
    
       		RIGHT_PLAYING_COUNT_NEXT <= RIGHT_PLAYING_COUNT_REG-1;
 
     | 
  
  
     | 
    
       	end if;
 
     | 
  
  
     | 
    
       
     | 
  
  
     | 
    
       	if (RIGHT_NEXT/=RIGHT_REG) then
 
     | 
  
  
     | 
    
       		RIGHT_PLAYING_COUNT_NEXT <= (others=>'1');
 
     | 
  
  
     | 
    
       	end if;
 
     | 
  
  
     | 
    
       end process;
 
     | 
  
  
     | 
    
       RIGHT_PLAYING_RECENTLY <= or_reduce(std_logic_vector(RIGHT_PLAYING_COUNT_REG));
 
     | 
  
  
     | 
    
       
     | 
  
  
     | 
    
       
     | 
  
  
     | 
    
       	process(state_reg,secondBatch_reg,acc_reg,volume,ready,
 
     | 
  
  
     | 
    
       	POST_DIVIDE,FANCY_ENABLE,RIGHT_PLAYING_RECENTLY,DETECT_RIGHT,RIGHT_REG,SATURATED,GTIA_EN,ADC_EN)
 
     | 
  
  
     | 
    
       		variable postdivide : std_logic_vector(1 downto 0);
 
     | 
  
  
     | 
    
       		variable presaturate : unsigned(19 downto 0);
 
     | 
  
  
     | 
    
       		variable leftOnRight : std_logic;
 
     | 
  
  
     | 
    
       		variable clearAcc : std_logic;
 
     | 
  
  
     | 
    
       		variable R : std_logic;
 
     | 
  
  
     | 
    
       		variable pdsel : std_logic_vector(1 downto 0);
 
     | 
  
  
     | 
    
       	begin
 
     | 
  
  
     | 
    
       		state_next <= state_reg;
 
     | 
  
  
     | 
    
       		secondBatch_next <= secondBatch_reg;
 
     | 
  
  
     | 
    
       		acc_next <= acc_reg;
 
     | 
  
  
     | 
    
       		RIGHT_NEXT <= RIGHT_REG;
 
     | 
  
  
     | 
    
       		
 
     | 
  
  
     | 
    
       		leftOnRight := not(FANCY_ENABLE) or (not(RIGHT_PLAYING_RECENTLY) AND DETECT_RIGHT);		
 
     | 
  
  
     | 
    
       		clearAcc := '0';
 
     | 
  
  
     | 
    
       
     | 
  
  
     | 
    
       		write_0 <= '0';
 
     | 
  
  
     | 
    
       		write_1 <= '0';
 
     | 
  
  
     | 
    
       		write_2 <= '0';
 
     | 
  
  
     | 
    
       		write_3 <= '0';
 
     | 
  
  
     | 
    
       		R := '0';
 
     | 
  
  
     | 
    
       		channelsel <= (others=>'0');
 
     | 
  
  
     | 
    
       		saturated <= (others=>'0');
 
     | 
  
  
     | 
    
       		
 
     | 
  
  
     | 
    
       		if (ready='1') then		
 
     | 
  
  
     | 
    
       			case state_reg is
 
     | 
  
  
     | 
    
       				when state_pokeyA_L =>
 
     | 
  
  
     | 
    
       					channelsel <= x"0";					
 
     | 
  
  
     | 
    
       					state_next <= state_pokeyB_L;				
 
     | 
  
  
     | 
    
       				when state_pokeyB_L =>
 
     | 
  
  
     | 
    
       					channelsel <= x"2";
 
     | 
  
  
     | 
    
       					state_next <= state_sample_L;
 
     | 
  
  
     | 
    
       				when state_sample_L =>
 
     | 
  
  
     | 
    
       					channelsel <= x"4";
 
     | 
  
  
     | 
    
       					state_next <= state_sid_L;	
 
     | 
  
  
     | 
    
       				when state_sid_L    =>
 
     | 
  
  
     | 
    
       					channelsel <= x"6";
 
     | 
  
  
     | 
    
       					state_next <= state_psg_L;
 
     | 
  
  
     | 
    
       				when state_psg_L    =>
 
     | 
  
  
     | 
    
       					channelsel <= x"8";
 
     | 
  
  
     | 
    
       					state_next <= state_adc_L;
 
     | 
  
  
     | 
    
       				when state_adc_L   =>
 
     | 
  
  
     | 
    
       					channelsel <= x"b";
 
     | 
  
  
     | 
    
       					write_0 <= not(adc_en(0));	
 
     | 
  
  
     | 
    
       					write_1 <= not(adc_en(0)) and leftOnRight;	
 
     | 
  
  
     | 
    
       					write_2 <= not(adc_en(2));	
 
     | 
  
  
     | 
    
       					write_3 <= not(adc_en(2)) and leftOnRight; 						
 
     | 
  
  
     | 
    
       					state_next <= state_gtia_L;
 
     | 
  
  
     | 
    
       				when state_gtia_L   =>
 
     | 
  
  
     | 
    
       					channelsel <= x"a";
 
     | 
  
  
     | 
    
       					write_0 <= not(gtia_en(0));	
 
     | 
  
  
     | 
    
       					write_1 <= not(gtia_en(0)) and leftOnRight;	
 
     | 
  
  
     | 
    
       					write_2 <= not(gtia_en(2));	
 
     | 
  
  
     | 
    
       					write_3 <= not(gtia_en(2)) and leftOnRight; 						
 
     | 
  
  
     | 
    
       					state_next <= state_clear_L;
 
     | 
  
  
     | 
    
       				when state_clear_L   =>
 
     | 
  
  
     | 
    
       					clearAcc := '1';
 
     | 
  
  
     | 
    
       					write_0 <= gtia_en(0);	
 
     | 
  
  
     | 
    
       					write_1 <= gtia_en(0) and leftOnRight;	
 
     | 
  
  
     | 
    
       					write_2 <= gtia_en(2);	
 
     | 
  
  
     | 
    
       					write_3 <= gtia_en(2) and leftOnRight;				
 
     | 
  
  
     | 
    
       					state_next <= state_pokeyA_R;
 
     | 
  
  
     | 
    
       				when state_pokeyA_R =>
 
     | 
  
  
     | 
    
       					channelsel <= x"1";
 
     | 
  
  
     | 
    
       					R := '1';
 
     | 
  
  
     | 
    
       					state_next <= state_pokeyB_R;
 
     | 
  
  
     | 
    
       				when state_pokeyB_R =>
 
     | 
  
  
     | 
    
       					channelsel <= x"3";
 
     | 
  
  
     | 
    
       					R := '1';
 
     | 
  
  
     | 
    
       					state_next <= state_sample_R;
 
     | 
  
  
     | 
    
       				when state_sample_R =>
 
     | 
  
  
     | 
    
       					channelsel <= x"5";
 
     | 
  
  
     | 
    
       					R := '1';
 
     | 
  
  
     | 
    
       					state_next <= state_sid_R;
 
     | 
  
  
     | 
    
       				when state_sid_R    =>
 
     | 
  
  
     | 
    
       					channelsel <= x"7";
 
     | 
  
  
     | 
    
       					R := '1';
 
     | 
  
  
     | 
    
       					state_next <= state_psg_R;
 
     | 
  
  
     | 
    
       				when state_psg_R    =>
 
     | 
  
  
     | 
    
       					channelsel <= x"9";
 
     | 
  
  
     | 
    
       					R := '1';
 
     | 
  
  
     | 
    
       					state_next <= state_adc_R;
 
     | 
  
  
     | 
    
       				when state_adc_R   =>
 
     | 
  
  
     | 
    
       					channelsel <= x"b";
 
     | 
  
  
     | 
    
       					R := '1';
 
     | 
  
  
     | 
    
       					write_1 <= not(adc_en(1)) and not(leftOnRight);
 
     | 
  
  
     | 
    
       					write_3 <= not(adc_en(3)) and not(leftOnRight);	
 
     | 
  
  
     | 
    
       					-- NEEDS DOING WITHOUT ADC GTIA mixed, since those plays on all channels!!
 
     | 
  
  
     | 
    
       					RIGHT_NEXT <= xor_reduce(std_logic_vector(saturated));						
 
     | 
  
  
     | 
    
       					state_next <= state_gtia_R;
 
     | 
  
  
     | 
    
       				when state_gtia_R   =>
 
     | 
  
  
     | 
    
       					channelsel <= x"a";
 
     | 
  
  
     | 
    
       					R := '1';
 
     | 
  
  
     | 
    
       					write_1 <= not(gtia_en(1)) and not(leftOnRight);
 
     | 
  
  
     | 
    
       					write_3 <= not(gtia_en(3)) and not(leftOnRight);	
 
     | 
  
  
     | 
    
       					state_next <= state_clear_R;
 
     | 
  
  
     | 
    
       				when state_clear_R   =>
 
     | 
  
  
     | 
    
       					clearAcc := '1';
 
     | 
  
  
     | 
    
       					R := '1';
 
     | 
  
  
     | 
    
       					write_1 <= gtia_en(1) and not(leftOnRight);
 
     | 
  
  
     | 
    
       					write_3 <= gtia_en(3) and not(leftOnRight);				
 
     | 
  
  
     | 
    
       					state_next <= state_pokeyA_L;		
 
     | 
  
  
     | 
    
       					secondBatch_next <= not(secondBatch_reg);
 
     | 
  
  
     | 
    
       				when others =>
 
     | 
  
  
     | 
    
       					state_next <= state_pokeyA_L;
 
     | 
  
  
     | 
    
       			end case;
 
     | 
  
  
     | 
    
       
     | 
  
  
     | 
    
       			pdsel(1) := secondBatch_reg;
 
     | 
  
  
     | 
    
       			pdsel(0) := R;
 
     | 
  
  
     | 
    
       			case pdsel is 
 
     | 
  
  
     | 
    
       			when "00" =>
 
     | 
  
  
     | 
    
       				postdivide:=POST_DIVIDE(1 downto 0);
 
     | 
  
  
     | 
    
       			when "01" =>
 
     | 
  
  
     | 
    
       				postdivide:=POST_DIVIDE(3 downto 2);
 
     | 
  
  
     | 
    
       			when "10" =>
 
     | 
  
  
     | 
    
       				postdivide:=POST_DIVIDE(5 downto 4);
 
     | 
  
  
     | 
    
       			when "11" =>
 
     | 
  
  
     | 
    
       				postdivide:=POST_DIVIDE(7 downto 6);
 
     | 
  
  
     | 
    
       			when others =>
 
     | 
  
  
     | 
    
       			end case;
 
     | 
  
  
     | 
    
       			
 
     | 
  
  
     | 
    
       			case postdivide is
 
     | 
  
  
     | 
    
       				when "00" =>
 
     | 
  
  
     | 
    
       					presaturate := resize(acc_reg(19 downto 0),20);
 
     | 
  
  
     | 
    
       				when "01" =>
 
     | 
  
  
     | 
    
       					presaturate := resize(acc_reg(19 downto 1),20);
 
     | 
  
  
     | 
    
       				when "10" =>
 
     | 
  
  
     | 
    
       					presaturate := resize(acc_reg(19 downto 2),20);
 
     | 
  
  
     | 
    
       				when "11" =>
 
     | 
  
  
     | 
    
       					presaturate := resize(acc_reg(19 downto 3),20);
 
     | 
  
  
     | 
    
       				when others =>
 
     | 
  
  
     | 
    
       			end case;	
 
     | 
  
  
     | 
    
       			if or_reduce(std_logic_vector(presaturate(19 downto 16)))='1' then
 
     | 
  
  
     | 
    
       				saturated <= (others=>'1');
 
     | 
  
  
     | 
    
       			else
 
     | 
  
  
     | 
    
       				saturated <= presaturate(15 downto 0);
 
     | 
  
  
     | 
    
       			end if;					
 
     | 
  
  
     | 
    
       
     | 
  
  
     | 
    
       			if (clearAcc='1') then
 
     | 
  
  
     | 
    
       				acc_next <= (others=>'0');
 
     | 
  
  
     | 
    
       			else
 
     | 
  
  
     | 
    
       				acc_next <= acc_reg + resize(volume,19);
 
     | 
  
  
     | 
    
       			end if;
 
     | 
  
  
     | 
    
       		end if;
 
     | 
  
  
     | 
    
       
     | 
  
  
     | 
    
       	end process;		
 
     | 
  
  
     | 
    
       	
 
     | 
  
  
     | 
    
       	process(state_reg,channelsel,
 
     | 
  
  
     | 
    
       		ch0,ch1,ch2,ch3,ch4,ch5,ch6,ch7,ch8,ch9,cha,chb
 
     | 
  
  
     | 
    
       		)
 
     | 
  
  
     | 
    
       	begin
 
     | 
  
  
     | 
    
       		volume <= (others=>'0');
 
     | 
  
  
     | 
    
       		ready <= '1';	
 
     | 
  
  
     | 
    
       		case channelsel is
 
     | 
  
  
     | 
    
       		when x"0" =>
 
     | 
  
  
     | 
    
       		        volume <= ch0;
 
     | 
  
  
     | 
    
       		when x"1" =>
 
     | 
  
  
     | 
    
       		        volume <= ch1;
 
     | 
  
  
     | 
    
       		when x"2" =>
 
     | 
  
  
     | 
    
       		        volume <= ch2;
 
     | 
  
  
     | 
    
       		when x"3" =>
 
     | 
  
  
     | 
    
       		        volume <= ch3;
 
     | 
  
  
     | 
    
       		when x"4" =>
 
     | 
  
  
     | 
    
       		        volume <= ch4;
 
     | 
  
  
     | 
    
       		when x"5" =>
 
     | 
  
  
     | 
    
       		        volume <= ch5;
 
     | 
  
  
     | 
    
       		when x"6" =>
 
     | 
  
  
     | 
    
       			volume <= ch6;
 
     | 
  
  
     | 
    
       		when x"7" =>
 
     | 
  
  
     | 
    
       			volume <= ch7;
 
     | 
  
  
     | 
    
       		when x"8" =>
 
     | 
  
  
     | 
    
       			volume <= ch8;
 
     | 
  
  
     | 
    
       		when x"9" =>
 
     | 
  
  
     | 
    
       			volume <= ch9;
 
     | 
  
  
     | 
    
       		when x"a" =>
 
     | 
  
  
     | 
    
       		        volume <= cha;
 
     | 
  
  
     | 
    
       		when x"b" =>
 
     | 
  
  
     | 
    
       		        volume <= chb;
 
     | 
  
  
     | 
    
       		when others =>
 
     | 
  
  
     | 
    
       		end case;
 
     | 
  
  
     | 
    
       	end process;
 
     | 
  
  
     | 
    
       	
 
     | 
  
  
     | 
    
       	process(saturated,secondBatch_reg,write_0,write_1,write_2,write_3,audio0_reg,audio1_reg,audio2_reg,audio3_reg)
 
     | 
  
  
     | 
    
       	begin
 
     | 
  
  
     | 
    
       		audio0_next <= audio0_reg;
 
     | 
  
  
     | 
    
       		audio1_next <= audio1_reg;
 
     | 
  
  
     | 
    
       		audio2_next <= audio2_reg;
 
     | 
  
  
     | 
    
       		audio3_next <= audio3_reg;
 
     | 
  
  
     | 
    
       		
 
     | 
  
  
     | 
    
       		if (write_0='1' and secondBatch_reg='0') then
 
     | 
  
  
     | 
    
       			audio0_next <= saturated;
 
     | 
  
  
     | 
    
       		end if;
 
     | 
  
  
     | 
    
       		if (write_1='1' and secondBatch_reg='0') then
 
     | 
  
  
     | 
    
       			audio1_next <= saturated;
 
     | 
  
  
     | 
    
       		end if;
 
     | 
  
  
     | 
    
       		if (write_2='1' and secondBatch_reg='1') then
 
     | 
  
  
     | 
    
       			audio2_next <= saturated;
 
     | 
  
  
     | 
    
       		end if;
 
     | 
  
  
     | 
    
       		if (write_3='1' and secondBatch_reg='1') then
 
     | 
  
  
     | 
    
       			audio3_next <= saturated;
 
     | 
  
  
     | 
    
       		end if;		
 
     | 
  
  
     | 
    
       	end process;	
 
     | 
  
  
     | 
    
       	
 
     | 
  
  
     | 
    
       -- output
 
     | 
  
  
     | 
    
       	AUDIO_0_UNSIGNED <= audio0_reg;
 
     | 
  
  
     | 
    
       	AUDIO_1_UNSIGNED <= audio1_reg;
 
     | 
  
  
     | 
    
       	AUDIO_2_UNSIGNED <= audio2_reg;
 
     | 
  
  
     | 
    
       	AUDIO_3_UNSIGNED <= audio3_reg;
 
     | 
  
  
     | 
    
       end vhdl;
 
     |