⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 ata.vhd

📁 ata hard disk init in vhdl
💻 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 + -