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

📄 atacntl.vhd

📁 xilinx fpga 下的IDE控制器原代码,贡献一起学习
💻 VHD
📖 第 1 页 / 共 3 页
字号:
            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;

  -----------------------------------------------------------

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -