-------------------------------------------------------------------------------------------------
|
-------------------------------------------------------------------------------------------------
|
-------------------------------------------------------------------------------------------------
|
-------------------------------------------------------------------------------------------------
|
-- Title : ONFI compliant NAND interface
|
-- Title : ONFI compliant NAND interface
|
-- File : io_unit.vhd
|
-- File : io_unit.vhd
|
-- Author : Alexey Lyashko <pradd@opencores.org>
|
-- Author : Alexey Lyashko <pradd@opencores.org>
|
-- License : LGPL
|
-- License : LGPL
|
-------------------------------------------------------------------------------------------------
|
-------------------------------------------------------------------------------------------------
|
-- Description:
|
-- Description:
|
-- This file implements data IO unit of the controller.
|
-- This file implements data IO unit of the controller.
|
-------------------------------------------------------------------------------------------------
|
-------------------------------------------------------------------------------------------------
|
-------------------------------------------------------------------------------------------------
|
-------------------------------------------------------------------------------------------------
|
|
|
|
|
library ieee;
|
library ieee;
|
use ieee.std_logic_1164.all;
|
use ieee.std_logic_1164.all;
|
use ieee.numeric_std.all;
|
use ieee.numeric_std.all;
|
use work.onfi.all;
|
use work.onfi.all;
|
|
|
entity io_unit is
|
entity io_unit is
|
generic (io_type : io_t);
|
generic (io_type : io_t);
|
port
|
port
|
(
|
(
|
clk : in std_logic;
|
clk : in std_logic;
|
activate : in std_logic;
|
activate : in std_logic;
|
data_in : in std_logic_vector(15 downto 0);
|
data_in : in std_logic_vector(15 downto 0);
|
|
|
io_ctrl : out std_logic := '1';
|
io_ctrl : out std_logic := '1';
|
data_out : out std_logic_vector(15 downto 0);
|
data_out : out std_logic_vector(15 downto 0);
|
busy : out std_logic
|
busy : out std_logic
|
);
|
);
|
end io_unit;
|
end io_unit;
|
|
|
|
|
|
|
architecture action of io_unit is
|
architecture action of io_unit is
|
type io_state_t is (IO_IDLE, IO_HOLD, IO_DELAY);
|
type io_state_t is (IO_IDLE, IO_HOLD, IO_DELAY);
|
signal state : io_state_t := IO_IDLE;
|
signal state : io_state_t := IO_IDLE;
|
signal n_state : io_state_t := IO_IDLE;
|
signal n_state : io_state_t := IO_IDLE;
|
signal delay : integer := 0;
|
signal delay : integer := 0;
|
signal data_reg : std_logic_vector(15 downto 0);
|
signal data_reg : std_logic_vector(15 downto 0);
|
begin
|
begin
|
|
|
busy <= '1' when state /= IO_IDLE else
|
busy <= '1' when state /= IO_IDLE else
|
'0';
|
'0';
|
|
|
data_out <= data_reg when (io_type = IO_WRITE and state /= IO_IDLE) or
|
data_out <= data_reg when (io_type = IO_WRITE and state /= IO_IDLE) or
|
io_type = IO_READ else
|
io_type = IO_READ else
|
x"0000";
|
x"0000";
|
|
|
io_ctrl <= '0' when state = IO_DELAY and n_state = IO_HOLD else
|
io_ctrl <= '0' when state = IO_DELAY and n_state = IO_HOLD else
|
'1';
|
'1';
|
|
|
IO: process(clk, activate)
|
IO: process(clk, activate)
|
begin
|
begin
|
if(rising_edge(clk))then
|
if(rising_edge(clk))then
|
case state is
|
case state is
|
when IO_IDLE =>
|
when IO_IDLE =>
|
if(io_type = IO_WRITE)then
|
if(io_type = IO_WRITE)then
|
data_reg <= data_in;
|
data_reg <= data_in;
|
end if;
|
end if;
|
if(activate = '1')then
|
if(activate = '1')then
|
if(io_type = IO_WRITE)then
|
if(io_type = IO_WRITE)then
|
delay <= t_wp;
|
delay <= t_wp;
|
else
|
else
|
delay <= t_rea;
|
delay <= t_rea;
|
end if;
|
end if;
|
n_state <= IO_HOLD;
|
n_state <= IO_HOLD;
|
state <= IO_DELAY;
|
state <= IO_DELAY;
|
end if;
|
end if;
|
|
|
when IO_HOLD =>
|
when IO_HOLD =>
|
if(io_type = IO_WRITE)then
|
if(io_type = IO_WRITE)then
|
delay <= t_wh;
|
delay <= t_wh;
|
else
|
else
|
delay <= t_reh;
|
delay <= t_reh;
|
end if;
|
end if;
|
n_state <= IO_IDLE;
|
n_state <= IO_IDLE;
|
state <= IO_DELAY;
|
state <= IO_DELAY;
|
|
|
when IO_DELAY =>
|
when IO_DELAY =>
|
if(delay > 1)then
|
if(delay > 1)then
|
delay <= delay - 1;
|
delay <= delay - 1;
|
else
|
if(delay = 2 and io_type = IO_READ)then
|
if(io_type = IO_READ and n_state = IO_IDLE)then
|
data_reg <= data_in;
|
data_reg <= data_in; -- This thing needs to be checked with read hardware. Assignment may be needed somewhat earlier.
|
|
end if;
|
end if;
|
|
else
|
|
-- if(io_type = IO_READ and n_state = IO_IDLE)then
|
|
-- data_reg <= data_in; -- This thing needs to be checked with real hardware. Assignment may be needed somewhat earlier.
|
|
-- end if;
|
state <= n_state;
|
state <= n_state;
|
end if;
|
end if;
|
|
|
when others =>
|
when others =>
|
state <= IO_IDLE;
|
state <= IO_IDLE;
|
end case;
|
end case;
|
end if;
|
end if;
|
end process;
|
end process;
|
|
|