?? atacntl.vhd
字號:
library IEEE, UNISIM;
use IEEE.std_logic_1164.all;
use IEEE.std_logic_arith.all;
use IEEE.numeric_std.all;
use WORK.common.all;
package ata is
component pioIntfc
generic(
FREQ : natural := 50_000 -- operating frequency in KHz
);
port(
-- host side
clk : in std_logic; -- master clock
pioRst : in std_logic; -- async. reset
pioRd : in std_logic; -- initiate read operation
pioWr : in std_logic; -- initiate write operation
pioAddr : in std_logic_vector(4 downto 0); -- disk register address from host
pioDIn : in std_logic_vector(15 downto 0); -- data from host to disk
pioDOut : out std_logic_vector(15 downto 0); -- data from disk to host
pioBusy : out std_logic; -- read or write operation is in progress
pioIntrq : out std_logic; -- debounced interrupt from disk
status : out std_logic_vector(3 downto 0); -- diagnostic status for the R/W
-- 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); -- disk 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 component;
component ataCntl
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 component;
end package ata;
library IEEE, UNISIM;
use IEEE.std_logic_1164.all;
use IEEE.std_logic_arith.all;
use IEEE.numeric_std.all;
use WORK.common.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 executes a timed read/write operation to one of the disk registers.
--
-- For a read operation, the host supplies a register address and pulls the read
-- control line high. The read operation begins on the next rising clock edge
-- and the busy signal goes high. The host gets the data from the disk register
-- once the busy signal goes low again.
--
-- For a write operation, the host supplies a register address and the data to
-- be stored there and pulls the write control line high. The write operation
-- begins on the nxt rising clock edge an the busy signal goes high. The register
-- contains the new data once the busy signal goes low again.
--
-- The 5-bit register address from the host contains the 3-bit disk register address
-- along with the control and command block register select bits in the most
-- significant bit positions.
--
-- Revision:
-- 1.0.1
--
-- Additional Comments:
-- 1.0.1:
-- Added PIO Mode 2 timing parameters.
-- 1.0.0:
-- Initial release.
--
-- License:
-- This code can be freely distributed and modified as long as
-- this header is not removed.
--------------------------------------------------------------------
entity pioIntfc is
generic(
FREQ : natural := 50_000 -- operating frequency in KHz
);
port(
-- host side
clk : in std_logic; -- master clock
pioRst : in std_logic; -- async. reset
pioRd : in std_logic; -- initiate read operation
pioWr : in std_logic; -- initiate write operation
pioAddr : in std_logic_vector(4 downto 0); -- disk register address from host
pioDIn : in std_logic_vector(15 downto 0); -- data from host to disk
pioDOut : out std_logic_vector(15 downto 0); -- data from disk to host
pioBusy : out std_logic; -- read or write operation is in progress
pioIntrq : out std_logic; -- debounced interrupt from disk
status : out std_logic_vector(3 downto 0); -- diagnostic status for the R/W
-- 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); -- disk 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 pioIntfc;
architecture arch of pioIntfc is
-- PIO mode 0 timing parameters in ns
constant Top : natural := 600; -- minimum cycle time between R/W operations
constant Tsetup : natural := 70; -- address/data setup before R/W pulse
constant Tpulse : natural := 290; -- R/W pulse width
-- PIO mode 2 timing parameters in ns
-- constant Top : natural := 240; -- minimum cycle time between R/W operations
-- constant Tsetup : natural := 30; -- address/data setup before R/W pulse
-- constant Tpulse : natural := 100; -- R/W pulse width
constant Thold : natural := Top-Tsetup-Tpulse; -- address/data hold after R/W pulse
-- PIO mode timing parameters converted into clock cycles (based on FREQ)
constant NORM : natural := 1_000_000; -- normalize ns * KHz
constant OP_CYCLES : natural := 1+((Top*FREQ)/NORM);
constant SETUP_CYCLES : natural := 1+((Tsetup*FREQ)/NORM);
constant PULSE_CYCLES : natural := 1+((Tpulse*FREQ)/NORM);
constant HOLD_CYCLES : natural := 1+((Thold*FREQ)/NORM);
-- timer register that counts down times for the phases of the disk R/W operation
signal timer_r, timer_x : natural range OP_CYCLES downto 0;
-- PIO mode timing parameters converted into unsigned clock cycles for clarity
-- constant OP_CYCLES : unsigned := TO_UNSIGNED(OP_CYCLES_N, timer_r'length);
-- constant SETUP_CYCLES : unsigned := TO_UNSIGNED(SETUP_CYCLES_N, timer_r'length);
-- constant PULSE_CYCLES : unsigned := TO_UNSIGNED(PULSE_CYCLES_N, timer_r'length);
-- constant HOLD_CYCLES : unsigned := TO_UNSIGNED(HOLD_CYCLES_N, timer_r'length);
-- states of the PIO interface state machine
type cntlState is (
RW_SETUP, -- setup address/data before read pulse
RD_PULSE, -- read pulse active
RD_HOLD, -- hold address/data after read pulse
WR_PULSE, -- write pulse active
WR_HOLD -- hold address/data after write pulse
);
signal state_r, state_x : cntlState; -- state register and next state
-- PIO interface registers
signal pioBusy_r, pioBusy_x : std_logic; -- R/W in-progress register
signal dior_r, dior_x : std_logic; -- disk read signal register
signal diow_r, diow_x : std_logic; -- disk write signal register
signal da_r, da_x : std_logic_vector(pioAddr'range); -- disk register address register
signal ddOut_r, ddOut_x : std_logic_vector(ddOut'range); -- data output to disk register
signal ddOutEnbl_r, ddOutEnbl_x : std_logic; -- enable data output to disk register
signal ddIn_r, ddIn_x : std_logic_vector(ddIn'range); -- data input from disk register
-- reports the status of the PIO interface
signal status_r, status_x : std_logic_vector(3 downto 0);
-- debounce counter for the interrupt request input
signal intrqCnt_r, intrqCnt_x : unsigned(3 downto 0);
constant DEBOUNCE_CNT : natural := 10;
signal pioIntrq_r, pioIntrq_x : std_logic;
signal intrq_r, intrq_x : std_logic;
begin
-----------------------------------------------------------
-- attach some internal signals to the host and disk ports
-----------------------------------------------------------
dior_n <= dior_r;
diow_n <= diow_r;
da <= da_r(da'range);
cs0_n <= da_r(3);
cs1_n <= da_r(4);
ddOut <= ddOut_r;
ddOutEnbl <= ddOutEnbl_r;
pioDOut <= ddIn_r; -- output data to host is the input data from the disk
pioBusy <= pioBusy_r;
pioIntrq <= pioIntrq_r;
status <= status_r;
dmack_n <= HI; -- never acknowledge DMA requests from disk
-----------------------------------------------------------
-- debounce the interrupt signal from the disk
-----------------------------------------------------------
debounce : process(intrq, intrqCnt_r, intrq_r, pioIntrq_r)
begin
intrq_x <= intrq;
pioIntrq_x <= pioIntrq_r;
if(intrq = intrq_r) then
if(intrqCnt_r = DEBOUNCE_CNT) then
intrqCnt_x <= (others => '0');
pioIntrq_x <= intrq_r;
else
intrqCnt_x <= intrqCnt_r + 1;
end if;
else
intrqCnt_x <= (others => '0');
end if;
end process debounce;
-----------------------------------------------------------
-- compute the next state and outputs
-----------------------------------------------------------
combinatorial : process(pioRd, pioWr, pioAddr, pioDIn, state_r, timer_r, dior_r, pioBusy_r,
diow_r, da_r, ddOut_r, ddOutEnbl_r, ddIn_r, ddIn, status_r)
begin
-----------------------------------------------------------
-- setup default values for signals
-----------------------------------------------------------
state_x <= state_r;
dior_x <= dior_r;
diow_x <= diow_r;
da_x <= da_r;
ddOut_x <= ddOut_r;
ddOutEnbl_x <= ddOutEnbl_r;
ddIn_x <= ddIn_r;
pioBusy_x <= pioBusy_r;
status_x <= status_r;
-----------------------------------------------------------
-- update the timers
-----------------------------------------------------------
-- main timer for sequencing the phases of the R/W waveforms
if timer_r /= 0 then
-- decrement the timer and do nothing else since the previous
-- phase has not completed yet.
timer_x <= timer_r - 1;
else
-- the previous phase has completed once the timer hits zero.
-- By default, leave the timer at zero. A R/W op will set it
-- to non-zero below.
timer_x <= timer_r;
-----------------------------------------------------------
-- compute the next state and outputs
-----------------------------------------------------------
case state_r is
-----------------------------------------------------------
-- wait for a disk read or write operation
-----------------------------------------------------------
when RW_SETUP =>
dior_x <= HI; -- don't read or write the disk until requested
diow_x <= HI;
ddOutEnbl_x <= NO; -- don't drive disk data bus until requested
if(pioRd = YES) then
-- a read operation is requested
pioBusy_x <= YES; -- set busy bit
da_x <= pioAddr; -- output disk register address
timer_x <= SETUP_CYCLES; -- set timer for address setup
state_x <= RD_PULSE; -- next state after address setup completes
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -