mirror of
https://github.com/MiSTer-devel/BBCMicro_MiSTer.git
synced 2026-05-17 03:03:21 +00:00
106 lines
3.3 KiB
VHDL
106 lines
3.3 KiB
VHDL
library ieee ;
|
|
use ieee.std_logic_1164.all ;
|
|
use ieee.std_logic_unsigned.all;
|
|
use ieee.numeric_std.all;
|
|
|
|
entity upd7002 is
|
|
port (
|
|
clk : in std_logic;
|
|
cpu_clken : in std_logic;
|
|
mhz1_clken : in std_logic;
|
|
reset_n : in std_logic;
|
|
cs : in std_logic;
|
|
r_nw : in std_logic;
|
|
addr : in std_logic_vector(1 downto 0);
|
|
di : in std_logic_vector(7 downto 0);
|
|
do : out std_logic_vector(7 downto 0);
|
|
eoc_n : out std_logic;
|
|
ch0 : in std_logic_vector(11 downto 0);
|
|
ch1 : in std_logic_vector(11 downto 0);
|
|
ch2 : in std_logic_vector(11 downto 0);
|
|
ch3 : in std_logic_vector(11 downto 0)
|
|
);
|
|
end entity;
|
|
|
|
architecture rtl of upd7002 is
|
|
|
|
constant convert_time_8bit : integer := 4000;
|
|
constant convert_time_12bit : integer := 10000;
|
|
|
|
signal mux : std_logic_vector(1 downto 0);
|
|
signal mode : std_logic;
|
|
signal flag : std_logic;
|
|
signal value : std_logic_vector(11 downto 0);
|
|
signal busy_n : std_logic;
|
|
signal completed_n : std_logic;
|
|
signal counter : unsigned(13 downto 0);
|
|
|
|
begin
|
|
|
|
process(clk, reset_n)
|
|
begin
|
|
if reset_n = '0' then
|
|
mux <= (others => '0');
|
|
mode <= '0';
|
|
flag <= '0';
|
|
counter <= (others => '0');
|
|
busy_n <= '1';
|
|
completed_n <= '1';
|
|
elsif rising_edge(clk) then
|
|
if cpu_clken = '1' then
|
|
-- Write
|
|
if cs = '1' and r_nw = '0' and addr = "00" then
|
|
busy_n <= '0';
|
|
completed_n <= '1';
|
|
mux <= di(1 downto 0);
|
|
flag <= di(2);
|
|
mode <= di(3);
|
|
if di(3) = '0' then
|
|
counter <= to_unsigned(convert_time_8bit, counter'length);
|
|
else
|
|
counter <= to_unsigned(convert_time_12bit, counter'length);
|
|
end if;
|
|
end if;
|
|
end if;
|
|
if mhz1_clken = '1' then
|
|
if busy_n = '0' then
|
|
counter <= counter - 1;
|
|
if counter = 0 then
|
|
busy_n <= '1';
|
|
completed_n <= '0';
|
|
end if;
|
|
end if;
|
|
end if;
|
|
end if;
|
|
end process;
|
|
|
|
process(cs, r_nw, addr, completed_n, busy_n, value, flag, mode, mux)
|
|
begin
|
|
-- Read
|
|
do <= (others => '0');
|
|
if cs = '1' and r_nw = '1' then
|
|
case addr is
|
|
when "00" =>
|
|
-- read status
|
|
do <= completed_n & busy_n & value(11 downto 10) & mode & flag & mux;
|
|
when "01" =>
|
|
-- read high byte of result
|
|
do <= value(11 downto 4);
|
|
when "10" =>
|
|
-- read low byte of result
|
|
do <= value(3 downto 0) & "0000";
|
|
when others =>
|
|
end case;
|
|
end if;
|
|
end process;
|
|
|
|
|
|
value <= ch0 when mux = "00" else
|
|
ch1 when mux = "01" else
|
|
ch2 when mux = "10" else
|
|
ch3;
|
|
|
|
eoc_n <= completed_n;
|
|
|
|
end architecture rtl;
|