| write_data_field.vhd
--------------------------------------------------------------------------
-- FILENAME : write_data_field.vhd
--
-- This component monitors the external WR_SECT signal and when the user
-- requests the controller to write a sector this component then waits
-- for the read / write head to move to the correct sector. Once in
-- position the mfm_encoder is enabled which then does all the work.
--
-- AUTHOR : Craig Dunn
-- DATE STARTED : 20 January 2004
-- TAB SETTING : 4
-- RESET : Sync (when the controller is not ready)
-- CLOCK : 32MHz (not clock dependent)
-- KNOWN BUGS : None
-- VERSION : 1.0
--
-- All of the design and code in this module is my own work. No design or
-- code has been borrowed or copied from any source.
--------------------------------------------------------------------------
library IEEE;
use IEEE.STD_LOGIC_1164.all;
use IEEE.STD_LOGIC_ARITH.all;
use IEEE.STD_LOGIC_UNSIGNED.all;
entity write_data_field is
port ( MCLK : in std_logic;
EN : in std_logic;
WR_SECT : in std_logic;
ADDRESS_FIELD : in std_logic;
WRITE_PROTECT : in std_logic;
ENCODER_BSY : in std_logic;
INDEX_COUNT : in std_logic_vector(3 downto 0);
CURRENT_SECTOR : in std_logic_vector(4 downto 0);
WRITE_SECTOR : in std_logic_vector(4 downto 0);
BYTE_COUNT : in std_logic_vector(9 downto 0);
BSY : out std_logic;
SEEK_ERROR : out std_logic;
WP_ERROR : out std_logic;
ENCODER_EN : out std_logic
);
end write_data_field;
architecture write_data_field_arch of write_data_field is
type state_type is ( IDLE, SEEKING, WAIT_FOR_DFAM, WRITING );
signal state : state_type;
signal timeout_en : std_logic;
constant INDEX_TIMEOUT : std_logic_vector(3 downto 0) := "1111";
begin
main : process(MCLK)
begin
if rising_edge(MCLK) then
-- Synchronusly reset by the controller_rdy signal.
if EN = '0' then
ENCODER_EN <= '0';
BSY <= '0';
SEEK_ERROR <= '0';
WP_ERROR <= '0';
state <= IDLE;
else
case state is
-- Stay in this state until the external WR_SECT signal goes
-- high. When it does try and find the correct sector.
---------------------------------------------------------------
when IDLE =>
timeout_en <= '0';
if WR_SECT = '1' then
BSY <= '1';
state <= SEEKING;
else
BSY <= '0';
state <= IDLE;
end if;
-- Wait for the correct address field to be detected.
---------------------------------------------------------------
when SEEKING =>
if INDEX_COUNT = "0000" then
-- The index counter does not have a reset (see the
-- INDEX_COUNTER component) so wait for it to reach
-- zero before enabling the timeout option.
timeout_en <= '1';
end if;
if WRITE_PROTECT = '0' then
-- The disk is write protected so we can't do anything.
WP_ERROR <= '1';
state <= IDLE;
elsif INDEX_COUNT = INDEX_TIMEOUT and timeout_en = '1' then
-- The sector cannot be found within a set number of
-- disk revolutions.
SEEK_ERROR <= '1';
state <= IDLE;
elsif CURRENT_SECTOR = WRITE_SECTOR then
SEEK_ERROR <= '0';
WP_ERROR <= '0';
-- The correct address field has been found.
state <= WAIT_FOR_DFAM;
else
state <= SEEKING;
end if;
-- Wait until we are 26 bytes into the address field as this
-- puts us in the gap area between the address field and the
-- data field. Once in the gap start the writing process.
---------------------------------------------------------------
when WAIT_FOR_DFAM =>
if BYTE_COUNT = "0000011010" and ADDRESS_FIELD = '1' then
ENCODER_EN <= '1';
state <= WRITING;
end if;
-- Stay here until the mfm_encoder component has finished
-- writing the new data field.
---------------------------------------------------------------
when WRITING =>
if ENCODER_BSY = '0' then
ENCODER_EN <= '0';
state <= IDLE;
end if;
when others =>
null;
end case;
end if;
end if;
end process main;
end write_data_field_arch;
|