?? atacntl.vhd
字號(hào):
status_x <= "0010";
elsif(pioWr = YES) then
-- a write operation is requested
pioBusy_x <= YES; -- set busy bit
da_x <= pioAddr; -- output disk register address
ddOut_x <= pioDIn; -- output data to disk
ddOutEnbl_x <= YES; -- enable output bus
timer_x <= SETUP_CYCLES; -- set timer for address/data setup
state_x <= WR_PULSE; -- next state after address/data setup completes
status_x <= "0100";
else
-- no operation is requested
pioBusy_x <= NO; -- clear busy bit
state_x <= RW_SETUP; -- return to this state and wait for R/W request
status_x <= "0001";
end if;
-----------------------------------------------------------
-- pulse disk read control signal
-----------------------------------------------------------
when RD_PULSE =>
dior_x <= LO; -- lower disk read control line
timer_x <= PULSE_CYCLES; -- load duration of read pulse
state_x <= RD_HOLD; -- next state after pulse completes
-----------------------------------------------------------
-- get data and hold address after read pulse ends
-----------------------------------------------------------
when RD_HOLD =>
ddIn_x <= ddIn; -- load the data from the disk
dior_x <= HI; -- terminate the read pulse
timer_x <= HOLD_CYCLES; -- insert hold period after read operation
state_x <= RW_SETUP; -- look for another operation after the hold period
-----------------------------------------------------------
-- pulse disk write control signal
-----------------------------------------------------------
when WR_PULSE =>
diow_x <= LO; -- lower disk write control line
timer_x <= PULSE_CYCLES; -- load duration of write pulse
state_x <= WR_HOLD; -- next state after pulse completes
-----------------------------------------------------------
-- hold address and data after write pulse ends
-----------------------------------------------------------
when WR_HOLD =>
diow_x <= HI; -- terminate the write pulse
timer_x <= HOLD_CYCLES; -- insert hold period after write operation
state_x <= RW_SETUP; -- look for another operation after the hold period
-----------------------------------------------------------
-- unknown state
-----------------------------------------------------------
when others =>
state_x <= RW_SETUP; -- reset state if in erroneous state
status_x <= "1000";
end case;
end if;
end process combinatorial;
-----------------------------------------------------------
-- update registers on the appropriate clock edge
-----------------------------------------------------------
update : process(pioRst, clk)
begin
if pioRst = YES then
-- asynchronous reset
state_r <= RW_SETUP;
timer_r <= 0;
pioBusy_r <= NO;
pioIntrq_r <= NO;
intrq_r <= NO;
intrqCnt_r <= (others => '0');
dior_r <= HI;
diow_r <= HI;
da_r <= (others => '0');
ddOut_r <= (others => '0');
ddOutEnbl_r <= NO;
ddIn_r <= (others => '0');
status_r <= (others => '0');
elsif rising_edge(clk) then
state_r <= state_x;
timer_r <= timer_x;
pioBusy_r <= pioBusy_x;
pioIntrq_r <= pioIntrq_x;
intrq_r <= intrq_x;
intrqCnt_r <= intrqCnt_x;
dior_r <= dior_x;
diow_r <= diow_x;
da_r <= da_x;
ddOut_r <= ddOut_x;
ddOutEnbl_r <= ddOutEnbl_x;
ddIn_r <= ddIn_x;
status_r <= status_x;
end if;
end process update;
end arch;
library IEEE, UNISIM;
use IEEE.std_logic_1164.all;
use IEEE.std_logic_arith.all;
use IEEE.numeric_std.all;
use WORK.common.all;
use WORK.ata.all;
--------------------------------------------------------------------
-- Company : XESS Corp.
-- Engineer : Dave Vanden Bout
-- Creation Date : 04/14/2004
-- Copyright : 2004-2006, XESS Corp
-- Tool Versions : WebPACK 6.3.03i
--
-- Description:
-- This module reads or write a one or more 256-word sectors of the disk.
--
-- For a read operation, the host supplies the head, cylinder and beginning
-- sector to be read and pulls the read control line high. The read operation
-- begins on the next rising clock edge. A word of data from the sector can
-- be read each time the done signal goes high. Lowering the read control line
-- will temporarily halt the flow of data. The data flow will resume once the
-- read control line is raised again. The sector read operation can be terminated
-- by raising the abort control line.
--
-- For a write operation, the host supplies the head, cylinder, beginning sector,
-- and initial data word to be written and pulls the write control line high.
-- The write operation begins on the next rising clock edge. A word of data is
-- written to the sector each time the done signal goes high, after which new data
-- must be supplied. Lowering the write control line will temporarily halt the
-- flow of data. The data flow will resume once the write control line is raised
-- again. The sector write operation can be terminated by raising the abort control line.
--
-- Revision:
-- 1.0.1
--
-- Additional Comments:
-- 1.0.1:
-- Added multisector R/W.
-- Added enhanced ATA status output.
-- 1.0.0:
-- Initial release.
--
-- License:
-- This code can be freely distributed and modified as long as
-- this header is not removed.
--------------------------------------------------------------------
entity ataCntl is
generic(
FREQ : natural := 50_000; -- operating frequency in KHz
SECTORS_PER_RW : natural := 1 -- number of sectors to read/write
);
port(
-- host side
clk : in std_logic; -- master clock
rst : in std_logic; -- reset
rd : in std_logic; -- initiate read operation
wr : in std_logic; -- initiate write operation
abort : in std_logic; -- aborts read/write sector operation
head : in std_logic_vector(3 downto 0); -- disk head for data access
cylinder : in std_logic_vector(15 downto 0); -- cylinder for data access
sector : in std_logic_vector(7 downto 0); -- sector for data access
hDIn : in std_logic_vector(15 downto 0); -- data from host to disk
hDOut : out std_logic_vector(15 downto 0); -- data from disk to host
done : out std_logic; -- read or write operation is done
status : out std_logic_vector(6 downto 0); -- diagnostic status
-- disk side
dior_n : out std_logic; -- disk register read-enable
diow_n : out std_logic; -- disk register write-enable
cs0_n : out std_logic; -- disk command block register select
cs1_n : out std_logic; -- disk control block register select
da : out std_logic_vector(2 downto 0); -- register address
ddIn : in std_logic_vector(15 downto 0); -- data from disk
ddOut : out std_logic_vector(15 downto 0); -- data to disk
ddOutEnbl : out std_logic; -- enable data outputs to disk
intrq : in std_logic; -- interrupt from disk
dmack_n : out std_logic -- DMA acknowledge
);
end ataCntl;
architecture arch of ataCntl is
-- disk register addresses: (cs1,cs0,da2,da1,da0)
constant CONTROL_REG : std_logic_vector(4 downto 0) := "01110";
constant DATA_REG : std_logic_vector(4 downto 0) := "10000";
constant SECTOR_CNT_REG : std_logic_vector(4 downto 0) := "10010";
constant SECTOR_REG : std_logic_vector(4 downto 0) := "10011";
constant CYL_LOW_REG : std_logic_vector(4 downto 0) := "10100";
constant CYL_HIGH_REG : std_logic_vector(4 downto 0) := "10101";
constant DRIVE_HEAD_REG : std_logic_vector(4 downto 0) := "10110";
constant CMD_REG : std_logic_vector(4 downto 0) := "10111";
constant STATUS_REG : std_logic_vector(4 downto 0) := "10111";
-- commands for disk
constant DRIVE_RESET_CMD : std_logic_vector(7 downto 0) := x"0C";
constant DRIVE_RELEASE_CMD : std_logic_vector(7 downto 0) := x"08";
constant NOP_CMD : std_logic_vector(7 downto 0) := x"00";
constant READ_SECTOR_CMD : std_logic_vector(7 downto 0) := x"20";
constant WRITE_SECTOR_CMD : std_logic_vector(7 downto 0) := x"30";
-- disk status register bits
constant STATUS_REG_BSY : natural := 7;
constant STATUS_REG_DRQ : natural := 3;
constant STATUS_REG_ERR : natural := 0;
-- number of 16-bit words per disk sector
constant SECTOR_SIZE : natural := 256;
-- states of the ATA drive interface state machine
type cntlState is (
WAIT_FOR_NOT_BUSY,
WAIT_FOR_NOT_BUSY_1,
RESET_DRIVE,
RESET_DRIVE_1,
ABORT_1,
WAIT_FOR_CMD,
SETUP_DRIVE,
SETUP_DRIVE_1,
SETUP_DRIVE_2,
SETUP_DRIVE_3,
SETUP_DRIVE_4,
SETUP_DRIVE_5,
WRITE_WORDS,
WRITE_WORDS_1,
WRITE_WORDS_2,
WRITE_WORDS_3,
WRITE_WORDS_4,
WRITE_WORDS_5,
READ_WORDS,
READ_WORDS_1,
READ_WORDS_2,
READ_WORDS_3,
error
);
signal state_r, state_x : cntlState; -- state register and next state
signal rtnState_r, rtnState_x : cntlState; -- state register and next state
-- ATA drive interface registers
signal cmd_r, cmd_x : std_logic_vector(7 downto 0); -- ATA drive command (e.g. READ_SECTOR)
signal wordCnt_r, wordCnt_x : natural range SECTOR_SIZE-1 downto 0; -- counts words read from sector
signal status_r, status_x : std_logic_vector(status'range);
constant ERROR_FLAG : natural := 0; -- position of error flag bit in status register
-- PIO interface signals
signal pioRd : std_logic; -- initiate read operation
signal pioWr : std_logic; -- initiate write operation
signal pioBusy : std_logic; -- read or write operation in-progress
signal pioIntrq : std_logic; -- debounced interrupt from disk
signal pioAddr : std_logic_vector(4 downto 0); -- register address from host
signal pioDIn : std_logic_vector(15 downto 0); -- data from host to disk
signal pioDOut : std_logic_vector(15 downto 0); -- data from disk to host
begin
-------------------------------------------------------------------
-- instantiate the low-level interface to the disk registers
-------------------------------------------------------------------
u0 : pioIntfc
generic map(
FREQ => FREQ
)
port map(
clk => clk,
pioRst => rst,
pioRd => pioRd,
pioWr => pioWr,
pioAddr => pioAddr,
pioDIn => pioDIn,
pioDOut => pioDOut,
pioBusy => pioBusy,
pioIntrq => pioIntrq,
status => open,
dior_n => dior_n,
diow_n => diow_n,
cs0_n => cs0_n,
cs1_n => cs1_n,
da => da,
ddIn => ddIn,
ddOut => ddOut,
ddOutEnbl => ddOutEnbl,
intrq => intrq,
dmack_n => dmack_n
);
-----------------------------------------------------------
-- attach some internal signals to the host and disk ports
-----------------------------------------------------------
hdOut <= pioDOut;
status <= status_r;
-----------------------------------------------------------
?? 快捷鍵說明
復(fù)制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號(hào)
Ctrl + =
減小字號(hào)
Ctrl + -