Project

General

Profile

« Previous | Next » 

Revision 1525

Added by markw about 11 hours ago

Share the multiplier in the amplitude modulator

View differences:

atari_chips/pokeyv2/SID/amplitudeModulator.vhdl
ENTITY SID_amplitudeModulator IS
PORT
(
CLK : IN STD_LOGIC;
RESET_N : IN STD_LOGIC;
ENABLE : IN STD_LOGIC;
WAVE_A : IN STD_LOGIC_VECTOR(11 downto 0);
ENVELOPE_A : IN STD_LOGIC_VECTOR(7 downto 0);
WAVE_B : IN STD_LOGIC_VECTOR(11 downto 0);
ENVELOPE_B : IN STD_LOGIC_VECTOR(7 downto 0);
WAVE_C : IN STD_LOGIC_VECTOR(11 downto 0);
ENVELOPE_C : IN STD_LOGIC_VECTOR(7 downto 0);
CHANNEL_D : IN SIGNED(15 downto 0);
CHANNEL_MUX_SEL : IN STD_LOGIC_VECTOR(2 downto 0);
WAVE : IN STD_LOGIC_VECTOR(11 downto 0);
ENVELOPE : IN STD_LOGIC_VECTOR(7 downto 0);
MODULATED : OUT SIGNED(15 downto 0)
);
END SID_amplitudeModulator;
ARCHITECTURE vhdl OF SID_amplitudeModulator IS
signal mod_reg: signed(15 downto 0);
signal mod_next: signed(15 downto 0);
signal WAVE : STD_LOGIC_VECTOR(11 downto 0);
signal ENVELOPE : STD_LOGIC_VECTOR(7 downto 0);
signal CHANNEL_ABC : SIGNED(15 downto 0);
BEGIN
-- register
process(clk, reset_n)
process(
wave_a,envelope_a,wave_b,envelope_b,wave_c,envelope_c,
channel_d,
channel_mux_sel)
begin
if (reset_n = '0') then
mod_reg <= (others=>'0');
elsif (clk'event and clk='1') then
mod_reg <= mod_next;
end if;
MODULATED <= (others=>'0');
case channel_mux_sel is
when "001" =>
wave <= wave_a;
envelope <= envelope_a;
MODULATED <= channel_abc;
when "010" =>
wave <= wave_b;
envelope <= envelope_b;
MODULATED <= channel_abc;
when "011" =>
wave <= wave_c;
envelope <= envelope_c;
MODULATED <= channel_abc;
when "100" =>
MODULATED <= channel_d;
when others =>
end case;
end process;
-- next state
process(mod_reg,enable,wave,envelope)
process(wave,envelope)
variable multres : signed(26 downto 0);
begin
mod_next <= mod_reg;
if (enable = '1') then
multres := signed("0"&envelope)*(signed(resize(unsigned(wave),18))-2048);
mod_next <= multres(19 downto 4);
end if;
multres := signed("0"&envelope)*(signed(resize(unsigned(wave),18))-2048);
channel_abc <= multres(19 downto 4);
end process;
-- output
modulated <= mod_reg;
END vhdl;
atari_chips/pokeyv2/SID/preFilterSum.vhdl
BIAS_CHANNEL : IN STD_LOGIC;
CHANNEL_A : IN SIGNED(15 downto 0);
CHANNEL_B : IN SIGNED(15 downto 0);
CHANNEL_C : IN SIGNED(15 downto 0);
CHANNEL_MUX : IN SIGNED(15 downto 0);
CHANNEL_C_CUTDIRECT : IN STD_LOGIC;
CHANNEL_D : IN SIGNED(15 downto 0);
FILTER_EN : IN STD_LOGIC_VECTOR(3 downto 0);
CHANNEL_MUX_SEL : OUT STD_LOGIC_VECTOR(2 downto 0);
PREFILTER_OUT : OUT SIGNED(15 downto 0);
DIRECT_OUT : OUT SIGNED(15 downto 0) -- Only chdis/4 amplitude
);
......
signal phase_reg : unsigned(2 downto 0);
signal phase_next : unsigned(2 downto 0);
signal channel_mux : signed(15 downto 0);
signal channel_sel : std_logic_vector(2 downto 0);
function logic_to_unsigned(a : std_logic; b : integer) return unsigned is
......
end process;
-- next state
process(phase_reg,acc_reg,prefilter_reg,direct_reg,enable,channel_c_cutdirect,filter_en,channel_mux,bias_channel,channel_d)
process(phase_reg,acc_reg,prefilter_reg,direct_reg,enable,channel_c_cutdirect,filter_en,channel_mux,bias_channel)
variable filter_en0_ext : std_logic_vector(2 downto 0);
variable filter_en1_ext : std_logic_vector(2 downto 0);
variable filter_en2_ext : std_logic_vector(2 downto 0);
......
end case;
end process;
process(channel_sel,channel_a,channel_b,channel_c,channel_d)
begin
channel_mux <= (others=>'0');
case channel_sel is
when "001" =>
channel_mux <= channel_a;
when "010" =>
channel_mux <= channel_b;
when "011" =>
channel_mux <= channel_c;
when "100" =>
channel_mux <= channel_d;
when others =>
end case;
end process;
-- output
CHANNEL_MUX_SEL <= channel_sel;
prefilter_out <= prefilter_reg;
direct_out <= direct_reg;
atari_chips/pokeyv2/SID/top.vhdl
signal tapmatches : std_logic_vector(2 downto 0);
-- amplitude modulator
signal channel_a_modulated : signed(15 downto 0);
signal channel_b_modulated : signed(15 downto 0);
signal channel_c_modulated : signed(15 downto 0);
signal channel_mux_modulated : signed(15 downto 0);
signal channel_mux_sel : std_logic_vector(2 downto 0);
signal channel_d : signed(15 downto 0);
-- prefilter
......
);
-- volume
vol_a : entity work.SID_amplitudeModulator
vol_abc : entity work.SID_amplitudeModulator
PORT MAP
(
CLK => clk,
RESET_N => reset_n,
ENABLE => enable,
WAVE => wave_a_reg,
ENVELOPE => envelope_a_reg,
MODULATED => channel_a_modulated
);
WAVE_A => wave_a_reg,
ENVELOPE_A => envelope_a_reg,
WAVE_B => wave_b_reg,
ENVELOPE_B => envelope_b_reg,
WAVE_C => wave_c_reg,
ENVELOPE_C => envelope_c_reg,
CHANNEL_D => channel_d,
vol_b : entity work.SID_amplitudeModulator
PORT MAP
(
CLK => clk,
RESET_N => reset_n,
ENABLE => enable,
CHANNEL_MUX_SEL => channel_mux_sel,
WAVE => wave_b_reg,
ENVELOPE => envelope_b_reg,
MODULATED => channel_b_modulated
MODULATED => channel_mux_modulated
);
vol_c : entity work.SID_amplitudeModulator
PORT MAP
(
CLK => clk,
RESET_N => reset_n,
ENABLE => enable,
WAVE => wave_c_reg,
ENVELOPE => envelope_c_reg,
MODULATED => channel_c_modulated
);
prefilter: entity work.SID_preFilterSum
PORT MAP
(
......
BIAS_CHANNEL => sidtype,
CHANNEL_A => channel_a_modulated,
CHANNEL_B => channel_b_modulated,
CHANNEL_C => channel_c_modulated,
CHANNEL_MUX => channel_mux_modulated,
CHANNEL_C_CUTDIRECT => ch3silent_reg,
CHANNEL_D => channel_d,
FILTER_EN => filter_en_reg,
CHANNEL_MUX_SEL => channel_mux_sel,
PREFILTER_OUT => channel_prefilter,
DIRECT_OUT => channel_directsum
);
......
DEBUG_EV1 <= unsigned(envelope_a_reg);
DEBUG_WV1 <= unsigned(wave_a_reg);
DEBUG_AM1 <= channel_a_modulated;
DEBUG_AM1 <= channel_mux_modulated;
FILTER_BP_OUT <= filter_bp(17 downto 8);
FILTER_HP_OUT <= filter_hp(17 downto 8);

Also available in: Unified diff