--
-- Copyright (c) 2002 Kiyoshi Ikehara, Nagoya University Amateur Raido Club.
-- All rights reserved.
--
-- Redistribution and use in source and binary forms, with or without
-- modification, are permitted provided that the following conditions
-- are met:
-- 1. Redistributions of source code must retain the above copyright
-- notice, this list of conditions and the following disclaimer.
-- 2. Redistributions in binary form must reproduce the above copyright
-- notice, this list of conditions and the following disclaimer in the
-- documentation and/or other materials provided with the distribution.
-- 3. All advertising materials mentioning features or use of this software
-- must display the following acknowledgement:
-- This product includes software developed by Nagoya University
-- Amateur Raido Club and its contributors.
-- 4. Neither the name of the Club nor the names of its contributors
-- may be used to endorse or promote products derived from this software
-- without specific prior written permission.
--
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.STD_LOGIC_ARITH.ALL;
use IEEE.STD_LOGIC_UNSIGNED.ALL;
entity DCEXT is
port(
DC_AD: inout std_logic_vector(15 downto 0);
DC_nEN: in std_logic;
DC_nDATEN: in std_logic;
DC_DIR: in std_logic;
DC_CLK: in std_logic;
DC_nINT: out std_logic;
ISA_A: out std_logic_vector(9 downto 0);
ISA_IRQ: in std_logic_vector(3 downto 0);
ISA_RST: out std_logic;
ISA_nRD: out std_logic;
ISA_nWD: out std_logic;
ISA_nG: out std_logic;
bufdir: out std_logic;
nRD: out std_logic;
nWD: out std_logic;
IDE_CS0: out std_logic;
IDE_CS1: out std_logic;
IDE_IRQ: in std_logic;
IDE_nRD: out std_logic;
IDE_nWD: out std_logic;
IDE_nG: out std_logic;
IDE_D: inout std_logic_vector(15 downto 0);
NC: out std_logic_vector(4 downto 0)
);
end DCEXT;
architecture RTL of DCEXT is
signal A: std_logic_vector(31 downto 0);
signal IRQ_CS: std_logic;
signal ACS: std_logic_vector(3 downto 0);
signal IRQSET: std_logic_vector(4 downto 0);
signal ISA_CS: std_logic;
signal IDE_CS: std_logic;
signal TEST_CS0: std_logic;
signal TEST_CS1: std_logic;
signal RD, WD: std_logic;
signal RD2, WD2: std_logic;
signal DIR: std_logic;
signal DATAEN: std_logic;
signal DCD: std_logic_vector(15 downto 0);
signal MODE: std_logic_vector(3 downto 0);
signal DRIVE: std_logic;
signal ACTIVE: std_logic;
constant ADDR_ISA: std_logic_vector(3 downto 0) := "0000";
constant ADDR_IDE: std_logic_vector(3 downto 0) := "0001";
constant ADDR_IRQ: std_logic_vector(3 downto 0) := "1100";
constant ADDR_MODE: std_logic_vector(3 downto 0) := "1111";
signal STATE: std_logic_vector(1 downto 0);
signal NEXTSTATE: std_logic_vector(1 downto 0);
signal IN_ADDRLOW: std_logic;
signal IN_ADDRHIGH: std_logic;
signal IN_DATALOW: std_logic;
signal IN_DATAHIGH: std_logic;
constant ADDRLOW: std_logic_vector(1 downto 0) := "00";
constant ADDRHIGH: std_logic_vector(1 downto 0) := "01";
constant DATALOW: std_logic_vector(1 downto 0) := "11";
constant DATAHIGH: std_logic_vector(1 downto 0) := "10";
begin
-- tri-state
ACTIVE <= '1' when A(31 downto 16) = X"1400" else '0';
DRIVE <= DIR and IN_DATALOW and ACTIVE and (not ISA_CS);
DC_AD <= DCD when DRIVE = '1' else (others => 'Z');
-- "A" latch -> ISA address
ISA_A <= A(11 downto 2);
ACS <= A(15 downto 12);
--
IN_ADDRLOW <= '1' when STATE = ADDRLOW else '0';
IN_ADDRHIGH <= '1' when STATE = ADDRHIGH else '0';
IN_DATALOW <= '1' when STATE = DATALOW else '0';
IN_DATAHIGH <= '1' when STATE = DATAHIGH else '0';
-- irqs
IRQSET <= (IDE_IRQ) & ISA_IRQ;
-- interrupt
DC_nINT <= '1' when (IRQSET = "00000") else '0';
-- read / write
RD <= DIR and (IN_ADDRHIGH or IN_DATALOW);
WD <= (not DIR) and (IN_ADDRHIGH or IN_DATALOW);
nRD <= not RD;
nWD <= not WD;
IDE_nRD <= not RD;
IDE_nWD <= not WD;
RD2 <= DIR and (IN_ADDRHIGH or IN_DATALOW);
WD2 <= (not DIR) and (IN_ADDRHIGH or IN_DATALOW);
ISA_nRD <= not (RD2 and ISA_CS); -- ISA_RD <= RD and ISA_CS
ISA_nWD <= not (WD2 and ISA_CS); -- ISA_WD <= WD and ISA_CS
-- bus EN
DATAEN <= IN_DATALOW or IN_DATAHIGH;
ISA_nG <= not (ISA_CS and DATAEN);
bufdir <= not DIR;
IDE_nG <= not (IDE_CS and IN_DATALOW); -- obsolete
-- IDE data
process(WD, ACS, DC_AD) begin
if(WD = '1' and IN_DATALOW = '1') then
case ACS is
when ADDR_IDE => IDE_D <= DC_AD;
when others => IDE_D <= (others => 'Z'); -- not selected
end case;
else
IDE_D <= (others => 'Z');
end if;
end process;
-- Clock
process(DC_CLK) begin
if(DC_CLK'event and DC_CLK='1') then
STATE <= NEXTSTATE;
end if;
end process;
-- State
process(STATE, DC_CLK, ACS, DC_nEN, ACTIVE, IDE_D, IRQSET, MODE) begin
case STATE is
when ADDRLOW =>
if((DC_CLK'event and DC_CLK='0') and DC_nEN='0') then
A(15 downto 0) <= DC_AD;
DIR <= DC_DIR;
end if;
if(DC_nEN='0') then
NEXTSTATE <= ADDRHIGH;
else
NEXTSTATE <= ADDRLOW;
end if;
when ADDRHIGH =>
if(DC_CLK'event and DC_CLK='0') then
A(31 downto 16) <= DC_AD;
end if;
NEXTSTATE <= DATALOW;
when DATALOW =>
if(ACTIVE = '1') then
case ACS is
when ADDR_IDE => DCD <= IDE_D;
when ADDR_IRQ => DCD <= X"00" & "000" & IRQSET; -- IRQ_CS
when ADDR_MODE =>
DCD <= X"000" & MODE;
if((DC_CLK'event and DC_CLK='0') and DIR='0') then
MODE <= DC_AD(3 downto 0);
end if;
when others => DCD <= X"0000"; -- not selected
end case;
end if;
NEXTSTATE <= DATAHIGH;
when DATAHIGH =>
NEXTSTATE <= ADDRLOW;
when others => NEXTSTATE <= ADDRLOW;
end case;
end process;
-- CS -> each CS
IDE_CS0 <= '0' when (ACS&A(11) = ADDR_IDE&'0') else '1';
IDE_CS1 <= '0' when (ACS&A(11) = ADDR_IDE&'1') else '1';
IDE_CS <= '1' when ACS = ADDR_IDE else '0';
ISA_CS <= '1' when ACS = ADDR_ISA else '0';
IRQ_CS <= '1' when ACS = ADDR_IRQ else '0';
ISA_RST <= MODE(0);
NC <= (others => 'Z');
end RTL;
This page is the sole property of Kiyoshi Ikehara and merely mirrored by FuzzyMuzzle.com. Please direct all questions regarding this mirror's content to Kiyoshi Ikehera himself.