Revision 1525
Added by markw about 14 hours ago
| 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);
|
||
Share the multiplier in the amplitude modulator