------------------------------------------------------------------------------- -- -- (C) COPYRIGHT 2010 Gideon's Logic Architectures' -- ------------------------------------------------------------------------------- -- -- Author: Gideon Zweijtzer (gideon.zweijtzer (at) gmail.com) -- -- Note that this file is copyrighted, and is not supposed to be used in other -- projects without written permission from the author. -- ------------------------------------------------------------------------------- library ieee; use ieee.std_logic_1164.all; use ieee.numeric_std.all; entity sid_regs is port ( clock : in std_logic; reset : in std_logic; addr : in unsigned(7 downto 0); wren : in std_logic; wdata : in std_logic_vector(7 downto 0); rdata : out std_logic_vector(7 downto 0); potx : in std_logic_vector(7 downto 0); poty : in std_logic_vector(7 downto 0); --- comb_wave_l : in std_logic; comb_wave_r : in std_logic; --- voice_osc : in unsigned(3 downto 0); voice_wave : in unsigned(3 downto 0); voice_adsr : in unsigned(3 downto 0); voice_mul : in unsigned(3 downto 0); -- Oscillator parameters freq : out unsigned(15 downto 0); test : out std_logic; sync : out std_logic; -- Wave map parameters comb_mode : out std_logic; ring_mod : out std_logic; wave_sel : out std_logic_vector(3 downto 0); sq_width : out unsigned(11 downto 0); -- ADSR parameters gate : out std_logic; attack : out std_logic_vector(3 downto 0); decay : out std_logic_vector(3 downto 0); sustain : out std_logic_vector(3 downto 0); release : out std_logic_vector(3 downto 0); -- mixer 1 parameters filter_en : out std_logic; -- globals volume_l : out unsigned(3 downto 0) := (others => '0'); filter_co_l : out unsigned(10 downto 0) := (others => '0'); filter_res_l : out unsigned(3 downto 0) := (others => '0'); filter_ex_l : out std_logic := '0'; filter_hp_l : out std_logic := '0'; filter_bp_l : out std_logic := '0'; filter_lp_l : out std_logic := '0'; voice3_off_l : out std_logic := '0'; volume_r : out unsigned(3 downto 0) := (others => '0'); filter_co_r : out unsigned(10 downto 0) := (others => '0'); filter_res_r : out unsigned(3 downto 0) := (others => '0'); filter_ex_r : out std_logic := '0'; filter_hp_r : out std_logic := '0'; filter_bp_r : out std_logic := '0'; filter_lp_r : out std_logic := '0'; voice3_off_r : out std_logic := '0'; -- readback osc3 : in std_logic_vector(7 downto 0); env3 : in std_logic_vector(7 downto 0) ); attribute ramstyle : string; end sid_regs; architecture gideon of sid_regs is attribute ramstyle of gideon : architecture is "logic"; type byte_array_t is array(natural range <>) of std_logic_vector(7 downto 0); type nibble_array_t is array(natural range <>) of std_logic_vector(3 downto 0); signal freq_lo : byte_array_t(0 to 15) := (others => (others => '0')); signal freq_hi : byte_array_t(0 to 15) := (others => (others => '0')); signal phase_lo : byte_array_t(0 to 15) := (others => (others => '0')); signal phase_hi : nibble_array_t(0 to 15):= (others => (others => '0')); signal control : byte_array_t(0 to 15) := (others => (others => '0')); signal att_dec : byte_array_t(0 to 15) := (others => (others => '0')); signal sust_rel : byte_array_t(0 to 15) := (others => (others => '0')); signal do_write : std_logic; signal wdata_d : std_logic_vector(7 downto 0); signal bus_value: std_logic_vector(7 downto 0); signal filt_en_i: std_logic_vector(15 downto 0) := (others => '0'); constant address_remap : byte_array_t(0 to 255) := ( X"00", X"01", X"02", X"03", X"04", X"05", X"06", -- 00 Voice 1 X"10", X"11", X"12", X"13", X"14", X"15", X"16", -- 07 Voice 2 X"20", X"21", X"22", X"23", X"24", X"25", X"26", -- 0E Voice 3 X"08", X"09", X"0A", X"0B", -- 15 X"FF", X"FF", X"FF", X"FF", X"FF", X"FF", X"FF", -- 19 X"30", X"31", X"32", X"33", X"34", X"35", X"36", -- 20 Voice 4 X"40", X"41", X"42", X"43", X"44", X"45", X"46", -- 27 Voice 5 X"50", X"51", X"52", X"53", X"54", X"55", X"56", -- 2E Voice 6 X"60", X"61", X"62", X"63", X"64", X"65", X"66", -- 35 Voice 7 X"70", X"71", X"72", X"73", X"74", X"75", X"76", -- 3C Voice 8 X"0C", X"0D", X"0E", -- 43 X"FF", X"FF", X"FF", X"FF", X"FF", X"FF", X"FF", -- 46 X"FF", X"FF", X"FF", X"FF", X"FF", X"FF", X"FF", -- 4D X"FF", X"FF", X"FF", X"FF", X"FF", X"FF", X"FF", -- 54 X"FF", X"FF", X"FF", X"FF", X"FF", X"FF", X"FF", -- 5B X"FF", X"FF", X"FF", X"FF", X"FF", X"FF", X"FF", -- 62 X"FF", X"FF", X"FF", X"FF", X"FF", X"FF", X"FF", -- 69 X"FF", X"FF", X"FF", X"FF", X"FF", X"FF", X"FF", -- 70 X"FF", X"FF", X"FF", X"FF", X"FF", X"FF", X"FF", -- 77 X"FF", X"FF", -- 7E X"80", X"81", X"82", X"83", X"84", X"85", X"86", -- 80 Voice 9 X"90", X"91", X"92", X"93", X"94", X"95", X"96", -- 87 Voice 10 X"A0", X"A1", X"A2", X"A3", X"A4", X"A5", X"A6", -- 8E Voice 11 X"88", X"89", X"8A", X"8B", -- 95 X"FF", X"FF", X"FF", X"FF", X"FF", X"FF", X"FF", -- 99 X"B0", X"B1", X"B2", X"B3", X"B4", X"B5", X"B6", -- A0 Voice 12 X"C0", X"C1", X"C2", X"C3", X"C4", X"C5", X"C6", -- A7 Voice 13 X"D0", X"D1", X"D2", X"D3", X"D4", X"D5", X"D6", -- AE Voice 14 X"E0", X"E1", X"E2", X"E3", X"E4", X"E5", X"E6", -- B5 Voice 15 X"F0", X"F1", X"F2", X"F3", X"F4", X"F5", X"F6", -- BC Voice 16 X"8C", X"8D", X"8E", -- C3 X"FF", X"FF", X"FF", X"FF", X"FF", X"FF", X"FF", -- C6 X"FF", X"FF", X"FF", X"FF", X"FF", X"FF", X"FF", -- CD X"FF", X"FF", X"FF", X"FF", X"FF", X"FF", X"FF", -- D4 X"FF", X"FF", X"FF", X"FF", X"FF", X"FF", X"FF", -- DB X"FF", X"FF", X"FF", X"FF", X"FF", X"FF", X"FF", -- E2 X"FF", X"FF", X"FF", X"FF", X"FF", X"FF", X"FF", -- E9 X"FF", X"FF", X"FF", X"FF", X"FF", X"FF", X"FF", -- F0 X"FF", X"FF", X"FF", X"FF", X"FF", X"FF", X"FF", -- F7 X"FF", X"FF" ); -- FE begin process(clock) variable address: unsigned(7 downto 0); begin if rising_edge(clock) then address := unsigned(address_remap(to_integer(addr))); do_write <= wren; wdata_d <= wdata; if do_write='0' and wren='1' then bus_value <= wdata_d; if address(3)='0' then -- Voice register case address(2 downto 0) is when "000" => freq_lo(to_integer(address(7 downto 4))) <= wdata_d; when "001" => freq_hi(to_integer(address(7 downto 4))) <= wdata_d; when "010" => phase_lo(to_integer(address(7 downto 4))) <= wdata_d; when "011" => phase_hi(to_integer(address(7 downto 4))) <= wdata_d(3 downto 0); when "100" => control(to_integer(address(7 downto 4))) <= wdata_d; when "101" => att_dec(to_integer(address(7 downto 4))) <= wdata_d; when "110" => sust_rel(to_integer(address(7 downto 4))) <= wdata_d; when others => null; end case; elsif address(7)='0' then -- Global register for left case address(2 downto 0) is when "000" => filter_co_l(2 downto 0) <= unsigned(wdata_d(2 downto 0)); when "001" => filter_co_l(10 downto 3) <= unsigned(wdata_d); when "010" => filter_res_l <= unsigned(wdata_d(7 downto 4)); filter_ex_l <= wdata_d(3); filt_en_i(2 downto 0) <= wdata_d(2 downto 0); when "011" => voice3_off_l <= wdata_d(7); filter_hp_l <= wdata_d(6); filter_bp_l <= wdata_d(5); filter_lp_l <= wdata_d(4); volume_l <= unsigned(wdata_d(3 downto 0)); when "100" => filt_en_i(7 downto 0) <= wdata_d; when others => null; end case; else -- Global register for right case address(2 downto 0) is when "000" => filter_co_r(2 downto 0) <= unsigned(wdata_d(2 downto 0)); when "001" => filter_co_r(10 downto 3) <= unsigned(wdata_d); when "010" => filter_res_r <= unsigned(wdata_d(7 downto 4)); filter_ex_r <= wdata_d(3); filt_en_i(10 downto 8) <= wdata_d(2 downto 0); when "011" => voice3_off_r <= wdata_d(7); filter_hp_r <= wdata_d(6); filter_bp_r <= wdata_d(5); filter_lp_r <= wdata_d(4); volume_r <= unsigned(wdata_d(3 downto 0)); when "100" => filt_en_i(15 downto 8) <= wdata_d; when others => null; end case; end if; end if; -- Readback (unmapped address) case addr is when "00011001" => rdata <= potx; bus_value <= potx; when "00011010" => rdata <= poty; bus_value <= poty; when "00011011" => rdata <= osc3; bus_value <= osc3; when "00011100" => rdata <= env3; bus_value <= env3; when others => rdata <= bus_value; end case; if reset='1' then freq_lo <= (others => (others => '0')); freq_hi <= (others => (others => '0')); phase_lo <= (others => (others => '0')); phase_hi <= (others => (others => '0')); control <= (others => (others => '0')); att_dec <= (others => (others => '0')); sust_rel <= (others => (others => '0')); filt_en_i <= (others => '0'); voice3_off_l <= '0'; voice3_off_r <= '0'; volume_l <= X"0"; volume_r <= X"0"; end if; end if; end process; freq <= unsigned(freq_hi(to_integer(voice_osc))) & unsigned(freq_lo(to_integer(voice_osc))); test <= control(to_integer(voice_osc))(3); sync <= control(to_integer(voice_osc))(1); -- Wave map parameters ring_mod <= control(to_integer(voice_wave))(2); wave_sel <= control(to_integer(voice_wave))(7 downto 4); sq_width <= unsigned(phase_hi(to_integer(voice_wave))) & unsigned(phase_lo(to_integer(voice_wave))); comb_mode <= (voice_wave(3) and comb_wave_r) or (not voice_wave(3) and comb_wave_l); -- ADSR parameters gate <= control(to_integer(voice_adsr))(0); attack <= att_dec(to_integer(voice_adsr))(7 downto 4); decay <= att_dec(to_integer(voice_adsr))(3 downto 0); sustain <= sust_rel(to_integer(voice_adsr))(7 downto 4); release <= sust_rel(to_integer(voice_adsr))(3 downto 0); -- Mixer 1 parameters filter_en <= filt_en_i(to_integer(voice_mul)); end gideon;