📄 ata.vhd
字号:
-- indi16 vhdl
-- ATA Disk Interface (PIO Mode)
-- (C)2007 K Ring Technologies Semiconductor
-- designed for 64/66MHz operation
-- PIO Mode 4 ATA Interface
-- Writes do not delay so long as 8 cycles are left between writes
-- Reads do not delay also * cycles, but have a FIFO buffer
-- so reading gives the last access, and shedules the next read ready for
-- reading when the next read cycle happens.
-- This requires blank reading sometimes, so reading the status register seems
-- appropriate. Reads and writes are qued separate.
LIBRARY ieee;
USE ieee.std_logic_1164.all;
USE ieee.std_logic_unsigned.all;
ENTITY ata IS
PORT
(
-- Slave WISHBONE Classic interface (STB_I decoded)
HLT_I : IN STD_LOGIC;
RST_I : IN STD_LOGIC;
CLK_I : IN STD_LOGIC;
ADR_I : IN STD_LOGIC_VECTOR(15 DOWNTO 0);
DAT_I : IN STD_LOGIC_VECTOR(15 DOWNTO 0);
DAT_O : OUT STD_LOGIC_VECTOR(15 DOWNTO 0);
WE_I : IN STD_LOGIC;
SEL_I : IN STD_LOGIC;
STB_I : IN STD_LOGIC;
ACK_O : OUT STD_LOGIC;
CYC_I : IN STD_LOGIC;
-- ATA Interface
RESETN : OUT STD_LOGIC;
DD : INOUT STD_LOGIC_VECTOR(15 DOWNTO 0);
DMARQ : IN STD_LOGIC; --DMA Request
DIOWN : OUT STD_LOGIC;
DIORN : OUT STD_LOGIC;
IORDY : IN STD_LOGIC;
CSEL : OUT STD_LOGIC; -- Cable Select
DMACKN : OUT STD_LOGIC; -- DMA ACK
INTRQ : IN STD_LOGIC; -- Interrupt Request
DA : OUT STD_LOGIC_VECTOR(2 DOWNTO 0);
CSN : OUT STD_LOGIC_VECTOR(1 DOWNTO 0);
DASPN : IN STD_LOGIC -- device active/slave present
);
END ata;
ARCHITECTURE a OF ata IS
CONSTANT HiZ : STD_LOGIC_VECTOR(15 DOWNTO 0) := "ZZZZZZZZZZZZZZZZ";
SIGNAL Read, Write : STD_LOGIC_VECTOR(15 DOWNTO 0);
-- CS1, CS0, DA2, DA1, DA0
SIGNAL Addr : STD_LOGIC_VECTOR(4 DOWNTO 0);
SIGNAL Busy, Dir : STD_LOGIC;
SIGNAL Seq : STD_LOGIC_VECTOR(2 DOWNTO 0);
BEGIN
DMACKN <= '1'; -- no dma
ACK_O <= NOT Busy AND STB_I;
DAT_O <= Read;
-- process read and write via wishbone
PROCESS(CLK_I, HLT_I, RST_I)
BEGIN
IF RST_I = '1' THEN
Seq <= "000";
Busy <= '0';
RESETN <= '0';
DD <= HiZ;
DIOWN <= '1';
DIORN <= '0';
ELSIF rising_edge(CLK_I) THEN
RESETN <= '1';
IF Busy = '1' THEN
-- must perform ATA
CASE Seq IS
WHEN "000" =>
-- set up address
DA <= Addr(2 DOWNTO 0);
CSN <= Addr(4 DOWNTO 3);
Seq <= "001";
WHEN "001" =>
-- yes keep that address up
Seq <= "010";
WHEN "010" =>
-- assert direction
IF Dir = '1' THEN
DIOWN <= '0';
ELSE
DIORN <= '0';
END IF;
Seq <= "011";
WHEN "011" =>
-- assert data out
IF Dir = '1' THEN
DD <= Write;
END IF;
Seq <= "100";
WHEN "100" =>
-- wait
Seq <= "101";
WHEN "101" =>
-- check IORDY
IF IORDY = '1' THEN
Seq <= "110";
ELSE
Seq <= "101";
END IF;
WHEN "110" =>
-- latch in
IF Dir = '0' THEN
Read <= DD;
END IF;
Seq <= "110";
WHEN "111" =>
-- deasert direction
DD <= HiZ;
DIORN <= '1';
DIOWN <= '1';
Busy <= '0';
Seq <= "000";
END CASE;
ELSE
IF STB_I = '1' AND HLT_I = '0' THEN
Busy <= '1';
Addr <= ADR_I(4 DOWNTO 0);
Write <= DAT_I;
Dir <= WE_I;
END IF;
END IF;
END IF;
END PROCESS;
END a;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -