OpenCores
URL https://opencores.org/ocsvn/ft245r_interface/ft245r_interface/trunk

Subversion Repositories ft245r_interface

[/] [ft245r_interface/] [trunk/] [ft245rl_interface.vhd] - Diff between revs 2 and 3

Go to most recent revision | Only display areas with differences | Details | Blame | View Log

Rev 2 Rev 3
--------------------------------------------------------------------------
--------------------------------------------------------------------------
--------------------------------------------------------------------------
--------------------------------------------------------------------------
-- Title                        : FT245R interface
-- Title                        : FT245R interface
-- File                 : ft245rl_interface.vhd
-- File                 : ft245rl_interface.vhd
-- Author               : Alexey Lyashko <pradd@opencores.org>
-- Author               : Alexey Lyashko <pradd@opencores.org>
-- License              : LGPL
-- License              : LGPL
--------------------------------------------------------------------------
--------------------------------------------------------------------------
-- Description  :
-- Description  :
-- The controller simplifies the communication with FT245R chip. While 
-- The controller simplifies the communication with FT245R chip. While 
-- provided interface is very similar to that of the chip itself, 
-- provided interface is very similar to that of the chip itself, 
-- this controller takes care of all the delays and other aspects of 
-- this controller takes care of all the delays and other aspects of 
-- FT245R's protocol as well as provifes separate ports for input and 
-- FT245R's protocol as well as provifes separate ports for input and 
-- output.
-- output.
--------------------------------------------------------------------------
--------------------------------------------------------------------------
--------------------------------------------------------------------------
--------------------------------------------------------------------------
 
 
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;
 
 
 
 
entity ft245rl_interface is
entity ft245rl_interface is
        -- This value is for 400MHz clock. Change it to suit your configuration.
        -- This value is for 400MHz clock. Change it to suit your configuration.
        generic (min_delay : real := 2.5);
        generic (min_delay : real := 2.5);
        port
        port
        (
        (
                -- physical FT245RL interface 
                -- physical FT245RL interface 
                data_io                                 : inout         std_logic_vector(7 downto 0);
                data_io                                 : inout         std_logic_vector(7 downto 0);
                nrst                                            : out           std_logic := '1';
                nrst                                            : out           std_logic := '1';
                ntxe                                            : in            std_logic;
                ntxe                                            : in            std_logic;
                nrxf                                            : in            std_logic;
                nrxf                                            : in            std_logic;
                nwr                                             : out           std_logic := '0';
                nwr                                             : out           std_logic := '0';
                nrd                                             : out           std_logic := '1';
                nrd                                             : out           std_logic := '1';
 
 
                -- logical interface
                -- logical interface
                clk                                             : in            std_logic;                                                              -- System clock
                clk                                             : in            std_logic;                                                              -- System clock
                data_in                                 : in            std_logic_vector(7 downto 0);            -- Input from client entity
                data_in                                 : in            std_logic_vector(7 downto 0);            -- Input from client entity
                data_out                                        : out           std_logic_vector(7 downto 0);            -- Output to client entity
                data_out                                        : out           std_logic_vector(7 downto 0);            -- Output to client entity
                nce                                             : in            std_logic := '1';                                               -- "Chip" enable
                nce                                             : in            std_logic := '1';                                               -- "Chip" enable
                fetch_next_byte         : in            std_logic := '0';                                                -- Strobing this to '1' instructs the module to poll FT245RL for next available byte
                fetch_next_byte         : in            std_logic := '0';                                                -- Strobing this to '1' instructs the module to poll FT245RL for next available byte
                do_write                                        : in            std_logic := '0';                                                -- Strobing this to '1' instructs the module to write byte to FT245RL
                do_write                                        : in            std_logic := '0';                                                -- Strobing this to '1' instructs the module to write byte to FT245RL
                busy                                            : out           std_logic := '0';                                                -- Is '1' when the module is processing data
                busy                                            : out           std_logic := '0';                                                -- Is '1' when the module is processing data
                data_available                  : buffer        std_logic := '0';                                                -- Notifies the client of data availability
                data_available                  : buffer        std_logic := '0';                                                -- Notifies the client of data availability
                reset                                           : in            std_logic := '1'                                                -- Resets the module
                reset                                           : in            std_logic := '1'                                                -- Resets the module
        );
        );
end ft245rl_interface;
end ft245rl_interface;
 
 
 
 
architecture action of ft245rl_interface is
architecture action of ft245rl_interface is
        type state_t is (
        type state_t is (
                                                                INIT,
                                                                INIT,
                                                                IDLE,
                                                                IDLE,
                                                                READ_BYTE,
                                                                READ_BYTE,
                                                                READ_BYTE1,
                                                                READ_BYTE1,
                                                                READ_BYTE2,
                                                                READ_BYTE2,
                                                                READ_BYTE3,
                                                                READ_BYTE3,
                                                                WRITE_BYTE,
                                                                WRITE_BYTE,
                                                                WRITE_BYTE1,
                                                                WRITE_BYTE1,
                                                                WRITE_BYTE2,
                                                                WRITE_BYTE2,
                                                                WRITE_BYTE3,
                                                                WRITE_BYTE3,
                                                                DO_DELAY
                                                                DO_DELAY
                                                        );
                                                        );
        signal c_state  : state_t := INIT;      -- current state
        signal c_state  : state_t := INIT;      -- current state
        signal n_state  : state_t := INIT;      -- next state
        signal n_state  : state_t := INIT;      -- next state
 
 
        signal delay_cnt:integer := 0;                                                           -- Delay counter register
        signal delay_cnt:integer := 0;                                                           -- Delay counter register
        signal current_delay : integer := 0;                                             -- This register holds number of clock cycles 
        signal current_delay : integer := 0;                                             -- This register holds number of clock cycles 
                                                                                                                                                        -- needed by the specified delay
                                                                                                                                                        -- needed by the specified delay
        signal in_buff  : std_logic_vector(7 downto 0);                  -- holds data received from FT245RL
        signal in_buff  : std_logic_vector(7 downto 0);                  -- holds data received from FT245RL
        signal out_buff: std_logic_vector(7 downto 0);                   -- holds data to be sent to FT245RL
        signal out_buff: std_logic_vector(7 downto 0);                   -- holds data to be sent to FT245RL
        signal we               : std_logic := '0';                                                      -- enables data output to FT245RL
        signal we               : std_logic := '0';                                                      -- enables data output to FT245RL
 
 
        -- All delay specs may be found in FT245RL datasheet at
        -- All delay specs may be found in FT245RL datasheet at
        -- http://www.ftdichip.com/Support/Documents/DataSheets/ICs/DS_FT245R.pdf
        -- http://www.ftdichip.com/Support/Documents/DataSheets/ICs/DS_FT245R.pdf
        constant t1_delay               :       integer := integer(50.0 / min_delay) - 1;
        constant t1_delay               :       integer := integer(50.0 / min_delay) - 1;
        constant t2_delay               :       integer := integer((50.0 + 80.0) / min_delay) - 1;
        constant t2_delay               :       integer := integer((50.0 + 80.0) / min_delay) - 1;
        constant t3_delay               :       integer := integer(35.0 / min_delay) - 1;
        constant t3_delay               :       integer := integer(35.0 / min_delay) - 1;
        constant t4_delay               :       integer := 0;
        constant t4_delay               :       integer := 0;
        constant t5_delay               :       integer := integer(25.0 / min_delay) - 1;
        constant t5_delay               :       integer := integer(25.0 / min_delay) - 1;
        constant t6_delay               :       integer := integer(80.0 / min_delay) - 1;
        constant t6_delay               :       integer := integer(80.0 / min_delay) - 1;
        constant t7_delay               :       integer := integer(50.0 / min_delay) - 1;
        constant t7_delay               :       integer := integer(50.0 / min_delay) - 1;
        constant t8_delay               :       integer := integer(50.0 / min_delay) - 1;
        constant t8_delay               :       integer := integer(50.0 / min_delay) - 1;
        constant t9_delay               :       integer := integer(20.0 / min_delay) - 1;
        constant t9_delay               :       integer := integer(20.0 / min_delay) - 1;
        constant t10_delay      :       integer := 0;
        constant t10_delay      :       integer := 0;
        constant t11_delay      :       integer := integer(25.0 / min_delay) - 1;
        constant t11_delay      :       integer := integer(25.0 / min_delay) - 1;
        constant t12_delay      :       integer := integer(80.0 / min_delay) - 1;
        constant t12_delay      :       integer := integer(80.0 / min_delay) - 1;
begin
begin
 
 
        -- Bidirectional bus implementation.
        -- Bidirectional bus implementation.
        data_io <=      out_buff when we = '1' else
        data_io <=      out_buff when we = '1' else
                                        "ZZZZZZZZ" when we = '0' else
                                        "ZZZZZZZZ" when we = '0' else
                                        "XXXXXXXX";
                                        "XXXXXXXX";
        in_buff <= data_io;
        in_buff <= data_io;
 
 
 
 
        process(clk, reset, nrxf, ntxe, nce)
        process(clk, reset, nrxf, ntxe, nce)
        begin
        begin
                if(reset = '0')then
                if(reset = '0')then
                        c_state         <= INIT;
                        c_state         <= INIT;
                elsif(rising_edge(clk) and nce = '0')then
                elsif(rising_edge(clk) and nce = '0')then
 
 
                        case c_state is
                        case c_state is
                                -- The module enters this state on powerup or when 'reset' is low.
                                -- The module enters this state on powerup or when 'reset' is low.
                                when INIT =>
                                when INIT =>
                                                                        delay_cnt               <= 0;
                                                                        delay_cnt               <= 0;
                                                                        current_delay   <= 0;
                                                                        current_delay   <= 0;
                                                                        c_state                 <= IDLE;
                                                                        c_state                 <= IDLE;
                                                                        nrst                            <= '0';                                                          -- Reset FT245RL on init
                                                                        nrst                            <= '0';                                                          -- Reset FT245RL on init
 
 
                                -- This is the "main loop"
                                -- This is the "main loop"
                                when IDLE =>
                                when IDLE =>
                                                                        nrst                            <= '1';
                                                                        nrst                            <= '1';
 
 
                                                                        -- If this condition is true, we may safely read another byte from FT245RL's FIFO
                                                                        -- If this condition is true, we may safely read another byte from FT245RL's FIFO
                                                                        if(nrxf = '0' and data_available = '0')then
                                                                        if(nrxf = '0' and data_available = '0')then
                                                                                c_state         <= READ_BYTE;
                                                                                c_state         <= READ_BYTE;
 
 
                                                                        -- We have to clear 'data_available' when the client module is requesting a new byte
                                                                        -- We have to clear 'data_available' when the client module is requesting a new byte
                                                                        elsif(fetch_next_byte = '1')then
                                                                        elsif(fetch_next_byte = '1')then
                                                                                data_available  <= '0';
                                                                                data_available  <= '0';
                                                                                c_state         <= IDLE;
                                                                                c_state         <= IDLE;
 
 
                                                                        -- Well, here we simply write a byte to FT245RL's data bus
                                                                        -- Well, here we simply write a byte to FT245RL's data bus
                                                                        elsif(do_write = '1')then
                                                                        elsif(do_write = '1')then
                                                                                c_state         <= WRITE_BYTE;
                                                                                c_state         <= WRITE_BYTE;
                                                                        end if;
                                                                        end if;
--                                                                      leds                            <= "1111";
 
 
 
 
 
                                -- Read one byte from the device
                                -- Read one byte from the device
                                when READ_BYTE =>
                                when READ_BYTE =>
                                                                        busy                            <= '1';
                                                                        busy                            <= '1';
                                                                        nrd                             <= '0';
                                                                        nrd                             <= '0';
                                                                        current_delay   <= t3_delay;
                                                                        current_delay   <= t3_delay;
                                                                        c_state                 <= DO_DELAY;
                                                                        c_state                 <= DO_DELAY;
                                                                        n_state                 <= READ_BYTE1;
                                                                        n_state                 <= READ_BYTE1;
--                                                                      leds                            <= "1111";
 
 
 
                                when READ_BYTE1 =>
                                when READ_BYTE1 =>
                                                                        current_delay   <= t1_delay - t3_delay;
                                                                        current_delay   <= t1_delay - t3_delay;
                                                                        c_state                 <= DO_DELAY;
                                                                        c_state                 <= DO_DELAY;
                                                                        n_state                 <= READ_BYTE2;
                                                                        n_state                 <= READ_BYTE2;
--                                                                      leds                            <= "1110";
 
 
 
                                when READ_BYTE2 =>
                                when READ_BYTE2 =>
                                                                        data_out                        <= in_buff;
                                                                        data_out                        <= in_buff;
                                                                        nrd                             <= '1';
                                                                        nrd                             <= '1';
                                                                        current_delay   <= t5_delay;
                                                                        current_delay   <= t5_delay;
                                                                        c_state                 <= DO_DELAY;
                                                                        c_state                 <= DO_DELAY;
                                                                        n_state                 <= READ_BYTE3;
                                                                        n_state                 <= READ_BYTE3;
--                                                                      leds                            <= "1101";
 
 
 
                                when READ_BYTE3 =>
                                when READ_BYTE3 =>
                                                                        current_delay   <= t2_delay;
                                                                        current_delay   <= t2_delay;
                                                                        c_state                 <= DO_DELAY;
                                                                        c_state                 <= DO_DELAY;
                                                                        n_state                 <= IDLE;
                                                                        n_state                 <= IDLE;
                                                                        data_available  <= '1';
                                                                        data_available  <= '1';
                                                                        busy                            <= '0';
                                                                        busy                            <= '0';
--                                                                      leds                            <= "1100";
 
 
 
                                -- Write one byte to the device
                                -- Write one byte to the device
                                when WRITE_BYTE =>
                                when WRITE_BYTE =>
                                                                        busy                    <= '1';
                                                                        busy                    <= '1';
                                                                        if(ntxe = '0')then
                                                                        if(ntxe = '0')then
                                                                                nwr                     <= '1';
                                                                                nwr                     <= '1';
                                                                                we                              <= '1';
                                                                                we                              <= '1';
                                                                                current_delay<= t7_delay;
                                                                                current_delay<= t7_delay;
                                                                                c_state         <= DO_DELAY;
                                                                                c_state         <= DO_DELAY;
                                                                                n_state         <= WRITE_BYTE1;
                                                                                n_state         <= WRITE_BYTE1;
                                                                                out_buff                <= data_in;
                                                                                out_buff                <= data_in;
                                                                        else
                                                                        else
                                                                                c_state         <= WRITE_BYTE;
                                                                                c_state         <= WRITE_BYTE;
                                                                        end if;
                                                                        end if;
--                                                                      leds                            <= "1011";
 
 
 
                                when WRITE_BYTE1 =>
                                when WRITE_BYTE1 =>
                                                                        nwr                             <= '0';
                                                                        nwr                             <= '0';
                                                                        current_delay   <= t11_delay;
                                                                        current_delay   <= t11_delay;
                                                                        c_state                 <= DO_DELAY;
                                                                        c_state                 <= DO_DELAY;
                                                                        n_state                 <= WRITE_BYTE2;
                                                                        n_state                 <= WRITE_BYTE2;
--                                                                      leds                            <= "1010";
 
 
 
                                when WRITE_BYTE2 =>
                                when WRITE_BYTE2 =>
                                                                        we                                      <= '0';
                                                                        we                                      <= '0';
                                                                        current_delay   <= t12_delay;
                                                                        current_delay   <= t12_delay;
                                                                        c_state                 <=DO_DELAY;
                                                                        c_state                 <=DO_DELAY;
                                                                        n_state                 <= WRITE_BYTE3;
                                                                        n_state                 <= WRITE_BYTE3;
--                                                                      leds                            <= "1001";
 
 
 
                                when WRITE_BYTE3 =>
                                when WRITE_BYTE3 =>
                                                                        busy                            <= '0';
                                                                        busy                            <= '0';
                                                                        c_state                 <= IDLE;
                                                                        c_state                 <= IDLE;
--                                                                      leds                            <= "1000";
 
 
 
                                when DO_DELAY =>
                                when DO_DELAY =>
                                                                        if(delay_cnt < current_delay)then
                                                                        if(delay_cnt < current_delay)then
                                                                                delay_cnt       <= delay_cnt + 1;
                                                                                delay_cnt       <= delay_cnt + 1;
                                                                        else
                                                                        else
                                                                                c_state         <= n_state;
                                                                                c_state         <= n_state;
                                                                                delay_cnt       <= 0;
                                                                                delay_cnt       <= 0;
                                                                        end if;
                                                                        end if;
--                                                                      leds                            <= "0111";
 
 
 
                                when others =>
                                when others =>
                                                                        c_state         <= INIT;
                                                                        c_state         <= INIT;
                        end case;       -- c_state
                        end case;       -- c_state
                end if;
                end if;
        end process;
        end process;
 
 
 
 

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.