Line 20... |
Line 20... |
-- You should have received a copy of the GNU General Public License
|
-- You should have received a copy of the GNU General Public License
|
-- along with this program. If not, see <http://www.gnu.org/licenses/>.
|
-- along with this program. If not, see <http://www.gnu.org/licenses/>.
|
--
|
--
|
-- URL to the project description:
|
-- URL to the project description:
|
-- http://labs.ti.bfh.ch/gecko/wiki/systems/gecko3com/start
|
-- http://labs.ti.bfh.ch/gecko/wiki/systems/gecko3com/start
|
----------------------------------------------------------------------------------
|
-------------------------------------------------------------------------------
|
--
|
--
|
-- Author: Andreas Habegger, Christoph Zimmermann
|
-- Author: Andreas Habegger, Christoph Zimmermann
|
-- Date of creation: 8. April 2009
|
-- Date of creation: 8. April 2009
|
-- Description:
|
-- Description:
|
-- FSM that controls the interface between the EZ-USB (and it's internal GPIF,
|
-- FSM that controls the interface between the EZ-USB (and it's internal
|
-- General Purpose Interface) and our FPGA. The interface is synchronous, where
|
-- GPIF, General Purpose Interface) and our FPGA. The interface is
|
-- the GPIF provides the clock. This FSM is synchronous to the GPIF clock, also
|
-- synchronous, where the GPIF provides the clock. This FSM is synchronous
|
-- this side of the FIFO's.
|
-- to the GPIF clock, also this side of the FIFO's.
|
--
|
--
|
-- You can find more detailed information how the interface works in the ../Doc
|
-- You can find more detailed information how the interface works in the
|
-- folder.
|
-- ../Doc folder.
|
--
|
--
|
-- Target Devices: Xilinx Spartan3 FPGA's (usage of BlockRam in the Datapath)
|
-- Target Devices: general
|
-- Tool versions: 11.1
|
-- Tool versions: Xilinx ISE 11.1, XST
|
-- Dependencies:
|
-- Dependencies:
|
--
|
--
|
----------------------------------------------------------------------------------
|
-------------------------------------------------------------------------------
|
|
|
library ieee;
|
library ieee;
|
use ieee.std_logic_1164.all;
|
use ieee.std_logic_1164.all;
|
use ieee.std_logic_arith.all;
|
use ieee.std_logic_arith.all;
|
|
|
library work;
|
library work;
|
use work.GECKO3COM_defines.all;
|
use work.GECKO3COM_defines.all;
|
|
|
entity gpif_com_fsm is
|
entity gpif_com_fsm is
|
port (
|
port (
|
i_nReset,
|
i_nReset : in std_logic;
|
i_IFCLK, -- GPIF CLK (GPIF is Master and provides the clock)
|
i_IFCLK : in std_logic; -- GPIF CLK (GPIF is Master and provides the clock)
|
i_WRU, -- write from GPIF
|
i_WRU : in std_logic; -- write from GPIF
|
i_RDYU : in std_logic; -- GPIF is ready
|
i_RDYU : in std_logic; -- GPIF is ready
|
i_U2X_FULL,
|
i_U2X_FULL : in std_logic;
|
i_U2X_AM_FULL, -- signals for IN FIFO
|
i_U2X_AM_FULL : in std_logic; -- signals for IN FIFO
|
i_X2U_AM_EMPTY,
|
i_X2U_AM_EMPTY : in std_logic;
|
i_X2U_EMPTY : in std_logic; -- signals for OUT FIFO
|
i_X2U_EMPTY : in std_logic; -- signals for OUT FIFO
|
o_bus_trans_dir : out std_logic;
|
o_bus_trans_dir : out std_logic;
|
o_U2X_WR_EN, -- signals for IN FIFO
|
o_U2X_WR_EN : out std_logic; -- signals for IN FIFO
|
o_X2U_RD_EN, -- signals for OUT FIFO
|
o_X2U_RD_EN : out std_logic; -- signals for OUT FIFO
|
o_FIFOrst,
|
o_FIFOrst : out std_logic;
|
o_WRX, -- To write to GPIF
|
o_WRX : out std_logic; -- To write to GPIF
|
o_RDYX : out std_logic; -- Core is ready
|
o_RDYX : out std_logic; -- Core is ready
|
o_ABORT : out std_logic; -- abort condition detected. we have to flush the data
|
o_ABORT : out std_logic; -- abort condition detected. we have to flush the data
|
o_RX,
|
o_RX : out std_logic;
|
o_TX : out std_logic --
|
o_TX : out std_logic --
|
);
|
);
|
|
|
|
-- XST specific synthesize attributes
|
|
attribute safe_implementation: string;
|
|
attribute safe_recovery_state: string;
|
|
|
|
attribute safe_implementation of gpif_com_fsm : entity is "yes";
|
|
|
end gpif_com_fsm;
|
end gpif_com_fsm;
|
|
|
|
|
|
|
architecture fsm of gpif_com_fsm is
|
architecture fsm of gpif_com_fsm is
|
Line 81... |
Line 88... |
type t_busAccess is (readFromGPIF, writeToGPIF);
|
type t_busAccess is (readFromGPIF, writeToGPIF);
|
signal s_bus_trans_dir : t_busAccess;
|
signal s_bus_trans_dir : t_busAccess;
|
|
|
|
|
type t_fsmState is (rst, idle, -- controll states
|
type t_fsmState is (rst, idle, -- controll states
|
inRQ, inACK, inTrans, throt, endInTrans, -- in com states
|
inRQ, inACK, inTrans, inThrot,
|
outRQ, outTrans, endOutTrans); -- out com states
|
inThrotEnd, endInTrans, -- in com states
|
|
outRQ, outTrans, outWait, endOutTrans); -- out com states
|
|
|
|
|
|
|
signal pr_state, nx_state : t_fsmState;
|
signal pr_state, nx_state : t_fsmState;
|
|
-- XST specific synthesize attributes
|
|
attribute safe_recovery_state of pr_state : signal is "idle";
|
|
attribute safe_recovery_state of nx_state : signal is "idle";
|
|
|
|
|
-- interconection signals
|
-- interconection signals
|
|
signal s_FIFOrst, s_RDYX, s_WRX, s_ABORT : std_logic;
|
signal s_FIFOrst,
|
|
s_RDYX,
|
|
s_WRX : std_logic;
|
|
|
|
-- USB to Xilinx (U2X)
|
-- USB to Xilinx (U2X)
|
signal s_U2X_WR_EN : std_logic;
|
signal s_U2X_WR_EN : std_logic;
|
|
|
-- Xilinx to USB (X2U)
|
-- Xilinx to USB (X2U)
|
Line 108... |
Line 117... |
o_X2U_RD_EN <= s_X2U_RD_EN;
|
o_X2U_RD_EN <= s_X2U_RD_EN;
|
o_WRX <= s_WRX;
|
o_WRX <= s_WRX;
|
o_RDYX <= s_RDYX;
|
o_RDYX <= s_RDYX;
|
o_U2X_WR_EN <= s_U2X_WR_EN;
|
o_U2X_WR_EN <= s_U2X_WR_EN;
|
o_bus_trans_dir <= '1' when s_bus_trans_dir = writeToGPIF else '0';
|
o_bus_trans_dir <= '1' when s_bus_trans_dir = writeToGPIF else '0';
|
|
o_ABORT <= s_ABORT;
|
|
|
|
|
-----------------------------------------------------------------------------
|
-----------------------------------------------------------------------------
|
-- FSM GPIF
|
-- FSM GPIF
|
-----------------------------------------------------------------------------
|
-----------------------------------------------------------------------------
|
Line 121... |
Line 131... |
variable v_setup : integer range 0 to 15;
|
variable v_setup : integer range 0 to 15;
|
begin
|
begin
|
|
|
if i_nReset = '0' then
|
if i_nReset = '0' then
|
pr_state <= rst;
|
pr_state <= rst;
|
v_setup := 0;
|
|
|
|
elsif rising_edge(i_IFCLK) then
|
elsif rising_edge(i_IFCLK) then
|
if v_setup < SETUP_TIME then
|
|
v_setup := v_setup + 1;
|
|
elsif nx_state = rst then
|
|
v_setup := 0;
|
|
pr_state <= nx_state;
|
|
else
|
|
pr_state <= nx_state;
|
pr_state <= nx_state;
|
end if;
|
end if;
|
end if;
|
|
end process action;
|
end process action;
|
|
|
|
|
-- comb logic
|
-- comb logic
|
transaction : process(pr_state, i_WRU, i_RDYU, i_U2X_AM_FULL, i_X2U_EMPTY)
|
transaction : process(pr_state, i_WRU, i_RDYU, i_U2X_AM_FULL, i_X2U_EMPTY)
|
Line 148... |
Line 150... |
s_U2X_WR_EN <= '0';
|
s_U2X_WR_EN <= '0';
|
s_X2U_RD_EN <= '0';
|
s_X2U_RD_EN <= '0';
|
nx_state <= idle;
|
nx_state <= idle;
|
s_WRX <= '0';
|
s_WRX <= '0';
|
s_RDYX <= '0';
|
s_RDYX <= '0';
|
o_LEDrun <= '1';
|
s_ABORT <= '0';
|
o_LEDrx <= '0';
|
o_RX <= '0';
|
o_LEDtx <= '0';
|
o_TX <= '0';
|
|
|
case pr_state is
|
case pr_state is
|
-- controll
|
-- controll
|
|
|
when rst =>
|
when rst =>
|
Line 162... |
Line 164... |
s_FIFOrst <= '1';
|
s_FIFOrst <= '1';
|
s_WRX <= '0';
|
s_WRX <= '0';
|
s_RDYX <= '0';
|
s_RDYX <= '0';
|
s_U2X_WR_EN <= '0';
|
s_U2X_WR_EN <= '0';
|
s_X2U_RD_EN <= '0';
|
s_X2U_RD_EN <= '0';
|
|
s_ABORT <= '1';
|
|
o_RX <= '0';
|
|
o_TX <= '0';
|
|
|
s_bus_trans_dir <= readFromGPIF;
|
s_bus_trans_dir <= readFromGPIF;
|
|
|
-- state decisions
|
-- state decisions
|
|
if i_WRU = '1' and i_RDYU = '1' then
|
|
nx_state <= rst;
|
|
else
|
nx_state <= idle;
|
nx_state <= idle;
|
o_LEDrun <= '0';
|
end if;
|
|
|
|
|
when idle =>
|
when idle =>
|
-- output signal values:
|
-- output signal values:
|
s_FIFOrst <= '0';
|
s_FIFOrst <= '0';
|
s_WRX <= '0';
|
s_WRX <= '0';
|
Line 198... |
Line 205... |
s_WRX <= '0';
|
s_WRX <= '0';
|
s_RDYX <= '0';
|
s_RDYX <= '0';
|
-- state decisions
|
-- state decisions
|
if i_WRU = '1' and i_RDYU = '1' then
|
if i_WRU = '1' and i_RDYU = '1' then
|
nx_state <= rst;
|
nx_state <= rst;
|
elsif i_U2X_AM_FULL = '0' then
|
elsif i_U2X_FULL = '0' then
|
nx_state <= inACK;
|
nx_state <= inACK;
|
s_RDYX <= '1';
|
|
else
|
else
|
nx_state <= idle;
|
nx_state <= idle;
|
end if;
|
end if;
|
|
|
when inACK =>
|
when inACK =>
|
-- output signal values:
|
-- output signal values:
|
s_WRX <= '0';
|
s_WRX <= '0';
|
s_RDYX <= '0';
|
s_RDYX <= '1';
|
s_U2X_WR_EN <= '0';
|
s_U2X_WR_EN <= '1';
|
|
o_RX <= '1';
|
|
|
-- state decisions
|
-- state decisions
|
if i_WRU = '1' and i_RDYU = '1' then
|
if i_WRU = '1' and i_RDYU = '1' then
|
nx_state <= rst;
|
nx_state <= rst;
|
elsif i_WRU = '1' then
|
elsif i_WRU = '1' then
|
nx_state <= inTrans;
|
nx_state <= inTrans;
|
s_U2X_WR_EN <= '1';
|
--nx_state <= inDummy;
|
s_RDYX <= '1';
|
|
else
|
else
|
nx_state <= endInTrans;
|
nx_state <= endInTrans;
|
end if;
|
end if;
|
|
|
when inTrans =>
|
when inTrans =>
|
-- output signal values:
|
-- output signal values:
|
s_WRX <= '0';
|
s_WRX <= '0';
|
s_RDYX <= '0';
|
s_RDYX <= '1';
|
o_LEDrx <= '1';
|
s_U2X_WR_EN <= '1';
|
|
o_RX <= '1';
|
|
|
-- state decisions
|
-- state decisions
|
if i_WRU = '1' and i_RDYU = '1' then
|
if i_WRU = '1' and i_RDYU = '1' then
|
nx_state <= rst;
|
nx_state <= rst;
|
elsif i_WRU = '0' then
|
elsif i_WRU = '0' then
|
nx_state <= endInTrans;
|
nx_state <= endInTrans;
|
s_RDYX <= '1';
|
elsif i_U2X_FULL = '1' then
|
s_U2X_WR_EN <= '1';
|
nx_state <= inThrot;
|
elsif i_U2X_AM_FULL = '1' then
|
|
nx_state <= throt;
|
|
s_U2X_WR_EN <= '1';
|
|
else
|
else
|
nx_state <= inTrans;
|
nx_state <= inTrans;
|
s_RDYX <= '1';
|
|
s_U2X_WR_EN <= '1';
|
|
end if;
|
end if;
|
|
|
when throt =>
|
when inThrot =>
|
-- output signal values:
|
-- output signal values:
|
s_WRX <= '0';
|
s_WRX <= '0';
|
s_RDYX <= '0';
|
s_RDYX <= '0';
|
s_U2X_WR_EN <= '0';
|
s_U2X_WR_EN <= '0';
|
|
o_RX <= '1';
|
|
|
-- state decisions
|
-- state decisions
|
if i_WRU = '1' and i_RDYU = '1' then
|
if i_WRU = '1' and i_RDYU = '1' then
|
nx_state <= rst;
|
nx_state <= rst;
|
elsif i_U2X_AM_FULL = '0' then
|
elsif i_U2X_FULL = '0' then
|
|
--nx_state <= inThrotEnd;
|
nx_state <= inACK;
|
nx_state <= inACK;
|
s_RDYX <= '1';
|
|
s_U2X_WR_EN <= '1';
|
|
elsif i_WRU = '0' then
|
elsif i_WRU = '0' then
|
nx_state <= endInTrans;
|
nx_state <= endInTrans;
|
else
|
else
|
nx_state <= throt;
|
nx_state <= inThrot;
|
end if;
|
end if;
|
|
|
|
--when inThrotEnd =>
|
|
-- -- this is a one clock delay to help the fx2 to see the RDYX signal.
|
|
|
|
-- -- output signal values:
|
|
-- s_WRX <= '0';
|
|
-- s_RDYX <= '1';
|
|
-- s_U2X_WR_EN <= '0';
|
|
-- o_RX <= '1';
|
|
|
|
-- -- state decisions
|
|
-- nx_state <= inACK;
|
|
|
when endInTrans =>
|
when endInTrans =>
|
-- output signal values:
|
-- output signal values:
|
s_WRX <= '0';
|
s_WRX <= '0';
|
s_RDYX <= '0';
|
s_RDYX <= '0';
|
s_U2X_WR_EN <= '1';
|
s_U2X_WR_EN <= '1';
|
|
|
-- state decisions
|
-- state decisions
|
nx_state <= idle;
|
nx_state <= idle;
|
|
|
|
|
-- out trans
|
-- out trans
|
when outRQ =>
|
when outRQ =>
|
-- output signal values:
|
-- output signal values:
|
s_WRX <= '1';
|
s_WRX <= '1';
|
s_RDYX <= '0';
|
s_RDYX <= '0';
|
|
|
-- state decisions
|
-- state decisions
|
if i_WRU = '1' and i_RDYU = '1' then
|
if i_WRU = '1' and i_RDYU = '1' then
|
nx_state <= rst;
|
nx_state <= rst;
|
s_WRX <= '0';
|
|
elsif i_WRU = '1' and i_RDYU = '0' then
|
elsif i_WRU = '1' and i_RDYU = '0' then
|
nx_state <= inRQ;
|
nx_state <= inRQ;
|
elsif i_WRU = '0' and i_RDYU = '0' then -- vervollständigt, wenn ez-usb noch beschäfigt mit altem transfer
|
elsif i_WRU = '0' and i_RDYU = '0' then -- vervollständigt, wenn ez-usb noch beschäfigt mit altem transfer
|
s_X2U_RD_EN <= '1';
|
--s_X2U_RD_EN <= '1';
|
nx_state <= outTrans;
|
nx_state <= outTrans;
|
-- s_bus_trans_dir <= writeToGPIF;
|
-- s_bus_trans_dir <= writeToGPIF;
|
else
|
else
|
nx_state <= outRQ;
|
nx_state <= outRQ;
|
end if;
|
end if;
|
Line 297... |
Line 313... |
-- output signal values:
|
-- output signal values:
|
s_WRX <= '1';
|
s_WRX <= '1';
|
s_RDYX <= '0';
|
s_RDYX <= '0';
|
s_X2U_RD_EN <= '1';
|
s_X2U_RD_EN <= '1';
|
s_bus_trans_dir <= writeToGPIF;
|
s_bus_trans_dir <= writeToGPIF;
|
o_LEDtx <= '1';
|
o_TX <= '1';
|
|
|
-- state decisions
|
-- state decisions
|
if i_WRU = '1' and i_RDYU = '1' then
|
if i_WRU = '1' and i_RDYU = '1' then
|
nx_state <= rst;
|
nx_state <= rst;
|
s_WRX <= '0';
|
|
s_X2U_RD_EN <= '0';
|
|
s_bus_trans_dir <= readFromGPIF;
|
|
elsif i_X2U_EMPTY = '1' then
|
elsif i_X2U_EMPTY = '1' then
|
nx_state <= endOutTrans;
|
nx_state <= endOutTrans;
|
elsif i_WRU = '0' and i_RDYU = '1' then
|
elsif i_WRU = '0' and i_RDYU = '1' then
|
nx_state <= outTrans;
|
nx_state <= outTrans;
|
else
|
else
|
s_X2U_RD_EN <= '0'; -- to realise a wait case
|
--s_X2U_RD_EN <= '0'; -- to realise a wait case
|
|
nx_state <= outWait;
|
|
end if;
|
|
|
|
when outWait =>
|
|
-- output signal values:
|
|
s_WRX <= '1';
|
|
s_RDYX <= '0';
|
|
s_X2U_RD_EN <= '0';
|
|
o_TX <= '1';
|
|
s_bus_trans_dir <= writeToGPIF;
|
|
|
|
-- state decisions
|
|
if i_WRU = '1' and i_RDYU = '1' then
|
|
nx_state <= rst;
|
|
elsif i_WRU = '0' and i_RDYU = '1' then
|
nx_state <= outTrans;
|
nx_state <= outTrans;
|
|
else
|
|
nx_state <= outWait;
|
end if;
|
end if;
|
|
|
when endOutTrans =>
|
when endOutTrans =>
|
-- output signal values:
|
-- output signal values:
|
s_RDYX <= '0';
|
s_RDYX <= '0';
|
s_WRX <= '1'; -- nötig um letzte 16bit an ez-usb zu schreiben
|
s_WRX <= '1'; -- nötig um letzte 16bit an ez-usb zu schreiben
|
s_X2U_RD_EN <= '1'; -- nötig da empyte flag schon beim ersten fifo zugriff auftaucht, zweite 16bit müssen noch gelesen werden
|
s_X2U_RD_EN <= '1'; -- nötig da empyte flag schon beim ersten fifo zugriff auftaucht, zweite 16bit müssen noch gelesen werden
|
s_bus_trans_dir <= writeToGPIF;
|
s_bus_trans_dir <= writeToGPIF;
|
|
|
-- state decisions
|
-- state decisions
|
nx_state <= idle;
|
nx_state <= idle;
|
|
|
-- error case
|
-- error case
|
when others =>
|
when others =>
|
nx_state <= idle;
|
nx_state <= idle;
|
end case;
|
end case;
|
|
|
end process transaction;
|
end process transaction;
|
|
|
end com_core;
|
end fsm;
|
|
|
No newline at end of file
|
No newline at end of file
|