*

read_data_field.vhd


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

-- FILENAME : read_data_field.vhd
--
-- Reads the data field of a disk.
--
-- AUTHOR : Craig Dunn
-- DATE STARTED : 20 December 2003
-- TAB SETTING : 4
-- RESET : EN (sync)
-- CLOCK : 32MHz (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 read_data_field is
port ( MCLK : in std_logic;
EN : in std_logic;
DATA_IN : in std_logic_vector(7 downto 0);
NEW_DATA : in std_logic;
RD_SECT : in std_logic;
INDEX_COUNT : in std_logic_vector(3 downto 0);
READ_SECTOR : in std_logic_vector(4 downto 0);
CURRENT_SECTOR : in std_logic_vector(4 downto 0);
BYTE_COUNT : in std_logic_vector(9 downto 0);
DATA_FIELD : in std_logic;
BSY : out std_logic;
RAM_CLK : out std_logic;
RAM_ADDR : out std_logic_vector(8 downto 0);
CRC_ERROR : out std_logic;
SEEK_ERROR : out std_logic;
CRC_OUT : in std_logic_vector(15 downto 0);
CRC_IN : out std_logic_vector(15 downto 0);
CRC_DATA : out std_logic_vector(7 downto 0);
CRC_EN : out std_logic
);
end read_data_field;

architecture read_data_field_arch of read_data_field is

type state_type is ( IDLE, SEEKING, WAIT_FOR_BYTE, NEWBYTE, INC_RAM_ADDR, WAIT_FOR_NEXT_BIT, READ_CRC, CHECK_CRC );

signal state : state_type;
signal timeout_en : std_logic;
signal sig_ram_addr : std_logic_vector(8 downto 0);
signal crc_reg : std_logic_vector(15 downto 0);

constant INDEX_TIMEOUT : std_logic_vector(3 downto 0) := "1111";
begin

RAM_ADDR <= sig_ram_addr;

main : process(MCLK)
begin
if rising_edge(MCLK) then
if EN = '0' then
BSY <= '0';
CRC_ERROR <= '0';
SEEK_ERROR <= '0';
CRC_EN <= '0';
state <= IDLE;
else
case state is

-- Wait here until the external RD_SECT signal goes high.
---------------------------------------------------------------
when IDLE =>
RAM_CLK <= '0';
sig_ram_addr <= (others => '0');
timeout_en <= '0';
CRC_EN <= '0';

if RD_SECT = '1' then
BSY <= '1';
state <= SEEKING;
else
BSY <= '0';
state <= IDLE;
end if;


-- Wait here until the correct address field is found and
-- when it is get ready to read the following data field.
-- The correct address field must be found within 10 revolutions
-- of the disk, if it is not a seek error is reported and the
-- reading is cancelled.
---------------------------------------------------------------
when SEEKING =>

-- Enable the index_counter process count the number
-- of disk revolutions.
if INDEX_COUNT = "0000" then
timeout_en <= '1';
end if;

if INDEX_COUNT = INDEX_TIMEOUT and timeout_en = '1' then
-- Assume the sector cannot be found and give up.
SEEK_ERROR <= '1';
state <= IDLE;
elsif CURRENT_SECTOR = READ_SECTOR then
SEEK_ERROR <= '0';
CRC_EN <= '1';

-- Initialise the CRC with the address mark of the
-- data field.
crc_in <= x"CDB4";
crc_data <= x"FB";

state <= WAIT_FOR_BYTE;
end if;


-- Wait here until a new byte arrives. When we first
-- enter this state we will still be in the address field
-- so it's important to check we are still the in the data field.
---------------------------------------------------------------
when WAIT_FOR_BYTE =>
if NEW_DATA = '1' and DATA_FIELD = '1' then
state <= NEWBYTE;
end if;


-- A new byte has arrived so put it in the memory and add
-- it to the running CRC.
---------------------------------------------------------------
when NEWBYTE =>
-- Put the new byte in the CRC.
crc_in <= crc_out;
crc_data <= DATA_IN;

-- Signal to the RAM to store the byte (byte_reg holds
-- the new byte).
RAM_CLK <= '1';

if sig_ram_addr = "111111111" then
-- We've now read 512 bytes of the data field so
-- check the CRC.
state <= READ_CRC;
else -- We still have more bytes to read.
state <= INC_RAM_ADDR;
end if;


-- Increment the RAM address.
---------------------------------------------------------------
when INC_RAM_ADDR =>
RAM_CLK <= '0';
sig_ram_addr <= sig_ram_addr + '1';
state <= WAIT_FOR_NEXT_BIT;


-- The signal sig_newbyte will still indicate the arrival
-- the processed byte so wait here until it clears, otherwise
-- we will store it multiple times.
---------------------------------------------------------------
when WAIT_FOR_NEXT_BIT =>
if NEW_DATA = '0' then
state <= WAIT_FOR_BYTE;
end if;


-- We have read the entire data area so now read the
-- 16 bit CRC.
---------------------------------------------------------------
when READ_CRC =>
if NEW_DATA = '1' then
case BYTE_COUNT is

when "1000000001" =>
crc_reg(15 downto 8) <= DATA_IN;

when "1000000010" =>
crc_reg(7 downto 0) <= DATA_IN;
state <= CHECK_CRC;

when others =>
null;

end case;
end if;


-- Check the read CRC matches are generated CRC and
-- set the CRC_ERROR appropiatley.
---------------------------------------------------------------
when CHECK_CRC =>
if crc_reg = crc_out then
CRC_ERROR <= '0';
else
CRC_ERROR <= '1';
end if;

state <= IDLE;

when others =>
null;

end case;
end if;
end if;
end process main;


end read_data_field_arch;



BackHome