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: Christoph Zimmermann
|
-- Author: Christoph Zimmermann
|
-- Date of creation: 8. April 2009
|
-- Date of creation: 8. April 2009
|
-- Description:
|
-- Description:
|
-- First test scenario for the GECKO3com IP core.
|
-- First test scenario for the GECKO3com IP core.
|
Line 36... |
Line 36... |
--
|
--
|
-- If you would like to change the USB TMC response, you have to change the
|
-- If you would like to change the USB TMC response, you have to change the
|
-- ROM content in this file (don't forget to adjust the the transfer size
|
-- ROM content in this file (don't forget to adjust the the transfer size
|
-- field AND the counter limit).
|
-- field AND the counter limit).
|
--
|
--
|
-- Target Devices: Xilinx Spartan3 FPGA's (usage of BlockRam in the Datapath)
|
-- Target Devices: Xilinx Spartan3 FPGA's (usage of BlockRam in the
|
|
-- Datapath)
|
-- Tool versions: 11.1
|
-- Tool versions: 11.1
|
-- Dependencies:
|
-- Dependencies:
|
--
|
--
|
----------------------------------------------------------------------------------
|
--------------------------------------------------------------------------------
|
|
|
library ieee;
|
library ieee;
|
use ieee.std_logic_1164.all;
|
use ieee.std_logic_1164.all;
|
|
use ieee.std_logic_unsigned.all;
|
|
|
library work;
|
library work;
|
use work.GECKO3COM_defines.all;
|
use work.GECKO3COM_defines.all;
|
|
|
entity gpif_com_test is
|
entity gpif_com_test 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_SYSCLK, -- FPGA System CLK
|
i_SYSCLK : in std_logic; -- FPGA System CLK
|
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
|
o_WRX, -- To write to GPIF
|
o_WRX : out std_logic; -- To write to GPIF
|
o_RDYX : out std_logic; -- IP Core is ready
|
o_RDYX : out std_logic; -- IP Core is ready
|
o_LEDrx, -- controll LED rx
|
b_gpif_bus : inout std_logic_vector(SIZE_DBUS_GPIF-1 downto 0); -- bidirect data bus
|
|
o_LEDrx : out std_logic; -- controll LED rx
|
o_LEDtx : out std_logic; -- controll LED tx
|
o_LEDtx : out std_logic; -- controll LED tx
|
o_LEDrun : out std_logic; -- controll LED running signalisation
|
o_LEDrun : out std_logic; -- controll LED running signalisation
|
b_gpif_bus : inout std_logic_vector(SIZE_DBUS_GPIF-1 downto 0)); -- bidirect data bus
|
o_dummy : out std_logic -- dummy output for RX data consumer
|
);
|
);
|
end gpif_com_test;
|
end gpif_com_test;
|
|
|
|
|
|
|
architecture loopback of gpif_com_test is
|
architecture behaviour of gpif_com_test is
|
|
|
|
|
type t_fsmLoop is (rst, idle, writeRQ, writeIn, writeEnd);
|
|
|
|
signal pr_stateLoop, nx_stateLoop : t_fsmLoop;
|
|
|
|
signal i_U2X_AM_EMPTY,
|
|
i_U2X_EMPTY,
|
|
i_X2U_AM_FULL,
|
|
i_X2U_FULL : in std_logic;
|
|
signal i_U2X_DATA : in std_logic_vector(SIZE_DBUS_FPGA-1 downto 0);
|
|
signal o_U2X_RD_EN,
|
|
o_X2U_WR_EN : out std_logic;
|
|
signal o_X2U_DATA : out std_logic_vector(SIZE_DBUS_FPGA-1 downto 0)
|
|
|
|
-----------------------------------------------------------------------------
|
-----------------------------------------------------------------------------
|
-- controll bus
|
-- controll bus
|
-----------------------------------------------------------------------------
|
-----------------------------------------------------------------------------
|
signal s_U2X_RD_EN,
|
signal s_EMPTY, s_FULL : std_logic;
|
s_X2U_WR_EN : std_logic;
|
signal s_RX_DATA : std_logic_vector(SIZE_DBUS_GPIF-1 downto 0);
|
|
signal s_RD_EN, s_WR_EN : std_logic;
|
|
signal s_TX_DATA : std_logic_vector(SIZE_DBUS_GPIF-1 downto 0);
|
|
signal s_RDYX : std_logic;
|
|
|
|
signal s_ABORT, s_ABORT_TMP : std_logic;
|
|
|
|
signal s_RX_DATA_TMP : std_logic_vector(SIZE_DBUS_GPIF-1 downto 0);
|
|
signal s_EMPTY_TMP, s_FULL_TMP : std_logic;
|
|
|
|
signal s_rom_adress : std_logic_vector(4 downto 0);
|
|
|
---------------------------------------------------------------------------------
|
|
|
-----------------------------------------------------------------------------
|
-- COMPONENTS
|
-- COMPONENTS
|
---------------------------------------------------------------------------------
|
-----------------------------------------------------------------------------
|
|
|
component gpif_com
|
component gpif_com
|
port (
|
port (
|
i_nReset,
|
i_nReset : in std_logic;
|
i_IFCLK, -- GPIF CLK (GPIF is Master and provides the clock)
|
i_SYSCLK : in std_logic;
|
i_SYSCLK, -- FPGA System CLK
|
o_ABORT : out std_logic;
|
i_WRU, -- write from GPIF
|
o_RX : out std_logic;
|
i_RDYU : in std_logic; -- GPIF is ready
|
o_TX : out std_logic;
|
o_WRX, -- To write to GPIF
|
i_RD_EN : in std_logic;
|
o_RDYX : out std_logic; -- IP Core is ready
|
o_EMPTY : out std_logic;
|
o_ABORT : out std_logic; -- Abort detected, you have to flush the data
|
o_RX_DATA : out std_logic_vector(SIZE_DBUS_GPIF-1 downto 0);
|
o_RX, -- controll LED rx
|
i_WR_EN : in std_logic;
|
o_TX : out std_logic; -- controll LED tx
|
o_FULL : out std_logic;
|
b_gpif_bus : inout std_logic_vector(SIZE_DBUS_GPIF-1 downto 0)); -- bidirect data bus
|
i_TX_DATA : in std_logic_vector(SIZE_DBUS_GPIF-1 downto 0);
|
end USB_TMC_IP;
|
i_IFCLK : in std_logic;
|
|
i_WRU : in std_logic;
|
|
i_RDYU : in std_logic;
|
|
o_WRX : out std_logic;
|
|
o_RDYX : out std_logic;
|
|
b_gpif_bus : inout std_logic_vector(SIZE_DBUS_GPIF-1 downto 0));
|
|
end component;
|
|
|
begin
|
component message_rom
|
|
port (
|
o_U2X_RD_EN <= s_U2X_RD_EN;
|
A : in std_logic_vector(4 downto 0);
|
o_X2U_WR_EN <= s_X2U_WR_EN;
|
D : out std_logic_vector(15 downto 0));
|
|
end component;
|
o_LEDrun <= '1';
|
|
|
|
|
begin -- behaviour
|
|
|
GPIF_INTERFACE : gpif_com
|
GPIF_INTERFACE : gpif_com
|
port map (
|
port map (
|
i_nReset => i_nReset,
|
i_nReset => i_nReset,
|
i_IFCLK => i_IFCLK, -- GPIF CLK (GPIF is Master and provides the clock)
|
i_SYSCLK => i_SYSCLK,
|
i_SYSCLK => i_SYSCLK, -- FPGA System CLK
|
o_ABORT => s_ABORT,
|
i_WRU => i_WRU, -- write from GPIF
|
o_RX => o_LEDrx,
|
i_RDYU => i_RDYU, -- GPIF is ready
|
o_TX => o_LEDtx,
|
o_WRX => o_WRX, -- To write to GPIF
|
i_RD_EN => s_RD_EN,
|
o_RDYX => o_RDYX, -- IP Core is ready
|
o_EMPTY => s_EMPTY,
|
o_ABORT => o_ABORT, -- Abort detected, you have to flush the data
|
o_RX_DATA => s_RX_DATA,
|
o_LEDrx => o_LEDrx, -- controll LED rx
|
i_WR_EN => s_WR_EN,
|
o_LEDtx => o_LEDtx, -- controll LED tx
|
o_FULL => s_FULL,
|
o_LEDrun => o_LEDrun, -- controll LED running signalisation
|
i_TX_DATA => s_TX_DATA,
|
b_gpif_bus => b_gpif_buf
|
--i_IFCLK => i_SYSCLK,
|
);
|
i_IFCLK => i_IFCLK,
|
|
i_WRU => i_WRU,
|
|
i_RDYU => i_RDYU,
|
|
o_WRX => o_WRX,
|
|
o_RDYX => o_RDYX,
|
|
b_gpif_bus => b_gpif_bus);
|
|
|
---------------------------------------------------------------------------
|
|
-- FPGA CLK DOMAIN -> opb site
|
|
---------------------------------------------------------------------------
|
o_LEDrun <= '1';
|
|
|
bus_loop_Dmap : process (i_SYSCLK)
|
|
|
|
begin -- process bus_access
|
|
if rising_edge(i_SYSCLK) then
|
|
o_X2U_DATA <= i_U2X_DATA;
|
|
end if;
|
|
end process bus_loop_Dmap;
|
|
|
|
|
|
-----------------------------------------------------------------------------
|
-----------------------------------------------------------------------------
|
-- FSM Loop
|
-- RX DATA CONSUMER WITH THROTLING
|
-----------------------------------------------------------------------------
|
-----------------------------------------------------------------------------
|
|
|
-- state reg
|
-- purpose: activates the read enable signal of the receive FIFO as slow as
|
actionLoop : process(i_SYSCLK, i_nReset)
|
-- you want.
|
|
-- type : sequential
|
|
-- inputs : i_SYSCLK
|
|
-- outputs: s_RX_DATA_TMP
|
|
rx_throtling: process (i_SYSCLK, i_nReset)
|
|
variable v_rx_throtle_count : std_logic_vector(6 downto 0); -- counter variable
|
begin
|
begin
|
|
|
if i_nReset = '0' then
|
if i_nReset = '0' then
|
pr_stateLoop <= rst;
|
v_rx_throtle_count := (others => '0');
|
|
s_RD_EN <= '0';
|
elsif rising_edge(i_SYSCLK) then
|
elsif i_SYSCLK = '1' and i_SYSCLK'event then
|
|
if v_rx_throtle_count >= 63 then
|
pr_stateLoop <= nx_stateLoop;
|
s_RD_EN <= '1';
|
|
v_rx_throtle_count := (others => '0');
|
end if;
|
|
end process actionLoop;
|
|
|
|
|
|
-- comb logic
|
|
loopTrans : process(pr_stateLoop, i_U2X_AM_EMPTY, i_U2X_EMPTY, i_X2U_AM_FULL )
|
|
begin -- process transaction
|
|
|
|
-- default signal sets to avoid latches
|
|
s_X2U_WR_EN <= '0';
|
|
s_U2X_RD_EN <= '0';
|
|
|
|
case pr_stateLoop is
|
|
-- controll
|
|
|
|
when rst =>
|
|
s_X2U_WR_EN <= '0';
|
|
s_U2X_RD_EN <= '0';
|
|
nx_stateLoop <= idle;
|
|
|
|
when idle =>
|
|
-- when the input fifo has data (is not empty) and the output fifo is not full:
|
|
if i_U2X_AM_EMPTY = '0' and i_X2U_AM_FULL = '0' then
|
|
nx_stateLoop <= writeRQ;
|
|
s_U2X_RD_EN <= '1';
|
|
else
|
else
|
nx_stateLoop <= idle;
|
v_rx_throtle_count := v_rx_throtle_count + 1;
|
|
s_RD_EN <= '0';
|
end if;
|
end if;
|
|
end if;
|
|
end process rx_throtling;
|
|
|
when writeRQ =>
|
-- purpose: reads the receive data from the GPIF interface
|
-- enable read from input fifo. wait one cycle untill the data is available to be written
|
-- type : sequential
|
s_U2X_RD_EN <= '1';
|
-- inputs : i_SYSCLK
|
s_X2U_WR_EN <= '0';
|
-- outputs: s_RX_DATA_TMP
|
nx_stateLoop <= writeIn;
|
rx_consumer: process (i_SYSCLK)
|
|
begin -- process rx_consumer
|
when writeIn =>
|
if i_SYSCLK = '1' and i_SYSCLK'event then
|
|
s_RX_DATA_TMP <= s_RX_DATA;
|
if i_U2X_EMPTY = '1' and i_X2U_AM_FULL = '0' then
|
s_EMPTY_TMP <= s_EMPTY;
|
-- input fifo is empty, end the transfer
|
s_FULL_TMP <= s_FULL;
|
nx_stateLoop <= writeEnd;
|
s_ABORT_TMP <= s_ABORT;
|
s_U2X_RD_EN <= '1'; -- i guess that this should be '0' here. zac1
|
|
s_X2U_WR_EN <= '1';
|
|
|
|
elsif i_U2X_EMPTY = '0' and i_X2U_AM_FULL = '1' then
|
|
-- output data is full, still data in the input fifo
|
|
nx_stateLoop <= writeEnd;
|
|
s_U2X_RD_EN <= '0';
|
|
s_X2U_WR_EN <= '1';
|
|
|
|
elsif i_U2X_EMPTY = '1' and i_X2U_AM_FULL = '1' then
|
|
-- input fifo empty and output fifo full
|
|
nx_stateLoop <= writeEnd; --idle;
|
|
s_U2X_RD_EN <= '0';
|
|
s_X2U_WR_EN <= '1'; ---s_X2U_WR_EN <= '0';
|
|
|
|
else
|
|
-- input fifo has data, output fifo has free space
|
|
nx_stateLoop <= writeIn;
|
|
s_X2U_WR_EN <= '1';
|
|
s_U2X_RD_EN <= '1';
|
|
end if;
|
end if;
|
|
end process rx_consumer;
|
|
|
|
|
when writeEnd =>
|
-- dummy logic to "use" these signals and avoid that they are removed by
|
-- copy the last data from the register to the output fifo
|
-- the optimizer
|
nx_stateLoop <= idle;
|
process(s_RX_DATA_TMP, s_EMPTY_TMP, s_FULL_TMP, s_ABORT_TMP, s_RDYX)
|
s_U2X_RD_EN <= '0';
|
variable result : std_logic := '0';
|
s_X2U_WR_EN <= '1';
|
begin
|
|
result := '0';
|
|
for i in s_RX_DATA_TMP'range loop
|
|
result := result or s_RX_DATA_TMP(i);
|
|
end loop;
|
|
o_dummy <= result or s_EMPTY_TMP or s_FULL_TMP or s_ABORT_TMP;
|
|
end process;
|
|
|
|
-----------------------------------------------------------------------------
|
|
-- RESPONSE MESSAGE GENERATOR
|
|
-----------------------------------------------------------------------------
|
|
|
-- error case
|
message_rom_1: message_rom
|
when others =>
|
port map (
|
nx_stateLoop <= idle;
|
A => s_rom_adress,
|
end case;
|
D => s_TX_DATA);
|
|
|
end process loopTrans;
|
-- purpose: counts up the rom adress lines to read out the response message
|
|
-- type : sequential
|
|
-- inputs : i_SYSCLK
|
|
-- outputs: s_RX_DATA_TMP
|
|
rom_adress_counter: process (i_SYSCLK, i_nReset)
|
|
begin
|
|
if i_nReset = '0' then
|
|
s_rom_adress <= (others => '0');
|
|
--DEBUG s_WR_EN <= '1';
|
|
s_WR_EN <= '0';
|
|
elsif i_SYSCLK = '1' and i_SYSCLK'event then
|
|
if s_rom_adress = 24 then
|
|
s_rom_adress <= s_rom_adress;
|
|
s_WR_EN <= '0';
|
|
else
|
|
s_rom_adress <= s_rom_adress + 1;
|
|
--DEBUG s_WR_EN <= '1';
|
|
s_WR_EN <= '0';
|
|
end if;
|
|
end if;
|
|
end process rom_adress_counter;
|
|
|
end loopback;
|
end behaviour;
|
|
|
No newline at end of file
|
No newline at end of file
|