repo2/atari_chips/pokeyv2/sample/channel.vhdl @ 1476
1157 | markw | --------------------------------------------------------------------------
|
|
1154 | markw | -- (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_MISC.all;
|
|||
ENTITY sample_channel IS
|
|||
PORT
|
|||
(
|
|||
CLK : IN STD_LOGIC;
|
|||
RESET_N : IN STD_LOGIC;
|
|||
ENABLE : IN STD_LOGIC;
|
|||
1155 | markw | syncreset : in std_logic;
|
|
start_addr : IN std_logic_vector(15 downto 0);
|
|||
1172 | markw | len : IN std_logic_vector(15 downto 0);
|
|
1154 | markw | period : IN std_logic_vector(11 downto 0);
|
|
1155 | markw | twocycles : in std_logic;
|
|
addr : OUT STD_LOGIC_VECTOR(16 downto 0);
|
|||
irq : OUT STD_LOGIC;
|
|||
req : OUT STD_LOGIC
|
|||
1154 | markw | );
|
|
END sample_channel;
|
|||
ARCHITECTURE vhdl OF sample_channel IS
|
|||
1155 | markw | signal pointer_reg : unsigned(16 downto 0);
|
|
signal pointer_next : unsigned(16 downto 0);
|
|||
1172 | markw | signal remaining_reg : unsigned(15 downto 0);
|
|
signal remaining_next : unsigned(15 downto 0);
|
|||
1154 | markw | signal periodpos_reg : unsigned(11 downto 0);
|
|
signal periodpos_next : unsigned(11 downto 0);
|
|||
1157 | markw | signal req_reg : std_logic;
|
|
signal req_next : std_logic;
|
|||
signal irq_reg : std_logic;
|
|||
signal irq_next : std_logic;
|
|||
signal resetpending_reg : std_logic;
|
|||
signal resetpending_next : std_logic;
|
|||
1155 | markw | ||
1154 | markw | BEGIN
|
|
-- register
|
|||
process(clk,reset_n)
|
|||
begin
|
|||
if (reset_n='0') then
|
|||
pointer_reg <= (others=>'0');
|
|||
remaining_reg <= (others=>'0');
|
|||
periodpos_reg <= (others=>'0');
|
|||
1157 | markw | req_reg <= '0';
|
|
irq_reg <= '0';
|
|||
resetpending_reg <= '0';
|
|||
1154 | markw | elsif (clk'event and clk='1') then
|
|
pointer_reg <= pointer_next;
|
|||
remaining_reg <= remaining_next;
|
|||
periodpos_reg <= periodpos_next;
|
|||
1157 | markw | req_reg <= req_next;
|
|
irq_reg <= irq_next;
|
|||
resetpending_reg <= resetpending_next;
|
|||
1154 | markw | end if;
|
|
end process;
|
|||
process(start_addr, len, period,
|
|||
1157 | markw | pointer_reg, remaining_reg, periodpos_reg, resetpending_reg,
|
|
1155 | markw | enable,
|
|
1163 | markw | syncreset,
|
|
twocycles
|
|||
1154 | markw | )
|
|
1155 | markw | variable change : unsigned(16 downto 0);
|
|
1157 | markw | variable endperiod : std_logic;
|
|
variable endsample : std_logic;
|
|||
variable nextsample : std_logic;
|
|||
1154 | markw | begin
|
|
pointer_next <= pointer_reg;
|
|||
remaining_next <= remaining_reg;
|
|||
periodpos_next <= periodpos_reg;
|
|||
1157 | markw | resetpending_next <= resetpending_reg or syncreset;
|
|
irq_next <= '0';
|
|||
req_next <= '0';
|
|||
nextsample := '0';
|
|||
endperiod := not(or_reduce(std_logic_vector(periodpos_reg(periodpos_reg'left downto 1))));
|
|||
endsample := not(or_reduce(std_logic_vector(remaining_reg(remaining_reg'left downto 1))));
|
|||
1154 | markw | ||
if (enable='1') then
|
|||
periodpos_next <= periodpos_reg-1;
|
|||
1157 | markw | resetpending_next <='0';
|
|
if (endperiod='1') then
|
|||
1155 | markw | if (twocycles='1') then
|
|
change:=to_unsigned(1,17);
|
|||
else
|
|||
change:=to_unsigned(2,17);
|
|||
end if;
|
|||
pointer_next <= pointer_reg+change;
|
|||
remaining_next <= remaining_reg-1;
|
|||
periodpos_next <= unsigned(period);
|
|||
1157 | markw | req_next <= '1';
|
|
nextsample := endsample;
|
|||
1154 | markw | end if;
|
|
1157 | markw | ||
if (resetpending_reg='1') then
|
|||
nextsample := '1';
|
|||
end if;
|
|||
if (nextsample='1') then
|
|||
1234 | markw | irq_next <= '1';
|
|
1157 | markw | pointer_next <= unsigned(start_addr)&'0';
|
|
remaining_next <= unsigned(len);
|
|||
periodpos_next <= unsigned(period);
|
|||
req_next <= '1';
|
|||
end if;
|
|||
1154 | markw | end if;
|
|
end process;
|
|||
1160 | markw | addr <= std_logic_vector(pointer_next);
|
|
1157 | markw | ||
req <= req_reg;
|
|||
irq <= irq_reg;
|
|||
1154 | markw | ||
end vhdl;
|