--******************************************************************************
--* @short The InChip VME Logic
--*
--* contains input and output FF's for VME signals
--* and the logic to generate a DTACK signal
--******************************************************************************
--* @author SAKULIN Hannes <hsakulin@dsy-srv3.cern.ch>
--* @date $Date: 2004/12/17 09:30:37 $
--* @version $Revision: 1.2 $
--******************************************************************************
--/
library IEEE;
use IEEE.Std_logic_1164.all;
entity InChipVMELogic is
port (
-- VME port ( these are the unregistered chip ports)
vme_addr : in std_logic_vector(19 downto 1);
vme_data : inout std_logic_vector(15 downto 0);
vme_en : in std_logic;
vme_wr : in std_logic;
vme_ndtack : out std_logic; -- low active
vme_nirq : out std_logic; -- low active
-- VME signal to chip logic
vme_addr_i : out std_logic_vector(19 downto 1);
vme_data_i : out std_logic_vector(15 downto 0);
vme_en_i : out std_logic;
vme_wr_i : out std_logic;
-- VME signals coming back form chip logic
vme_data_out : in std_logic_vector(15 downto 0);
vme_en_out : in std_logic; -- 1 if VME address was valid and
-- addresse any register/RAM in the chip
clk : in std_logic;
reset : in std_logic);
end;
architecture behavioral of InChipVMELogic is
attribute syn_useioff : boolean;
attribute syn_useioff of behavioral : architecture is true;
signal vme_en_reg : std_logic;
signal vme_wr_reg : std_logic;
signal vme_wr_d : std_logic;
signal vme_en_out_d : std_logic;
signal vme_en_out_pulse : std_logic;
begin
-----------------------------------------------------------------------------
-- Input flip-flops
-----------------------------------------------------------------------------
register_vmeinputs : process (clk, reset) is
begin
if reset = '1' then
vme_data_i <= (others => '0');
vme_addr_i <= (others => '0');
vme_en_reg <= '0';
vme_wr_reg <= '0';
elsif (clk'event and clk = '1') then
vme_data_i <= vme_data;
vme_addr_i <= vme_addr;
vme_en_reg <= vme_en;
vme_wr_reg <= vme_wr;
end if;
end process register_vmeinputs;
vme_en_i <= vme_en_reg;
vme_wr_i <= vme_wr_reg;
-- delay vme write signal
delay_vme_wr : process (clk, reset) is
begin
if reset = '1' then
vme_wr_d <= '0';
elsif (clk'event and clk = '1') then
vme_wr_d <= vme_wr_reg;
end if;
end process delay_vme_wr;
-- delay vme enable out signal
delay_enable_out: process (clk, reset) is
begin -- process generate_dtack
if reset = '1' then
vme_en_out_d <= '0';
elsif clk'event and clk = '1' then -- rising clock edge
vme_en_out_d <= vme_en_out;
end if;
end process delay_enable_out;
vme_en_out_pulse <= vme_en_out and not vme_en_out_d;
-----------------------------------------------------------------------------
-- generate DTACK
-----------------------------------------------------------------------------
generate_dtack: process (clk, reset) is
begin -- process generate_dtack
if reset = '1' then
vme_ndtack <= '1';
elsif clk'event and clk = '1' then -- rising clock edge
-- set dtack when any register in the chip is selected
if vme_en_out_pulse = '1' then
vme_ndtack <= '0';
-- clear dtack when vme_enable is clear
-- cannot use falling edge of vme enable since there is only a pulse when
-- writing
elsif vme_en_reg = '0' then
vme_ndtack <= '1';
end if;
end if;
end process generate_dtack;
-----------------------------------------------------------------------------
-- VME data output/enable FF's
-----------------------------------------------------------------------------
register_vmeoutputs : process (clk, reset) is
begin
if reset = '1' then
vme_data <= (others => 'Z');
elsif (clk'event and clk = '1') then
-- data is ready to be written when vme_en_out is '1'
-- also require vme_en_reg to be active in order to shorten the VME cycle
if (vme_en_reg = '1' and vme_en_out = '1' and vme_wr_d = '0') then
vme_data <= vme_data_out;
else
vme_data <= (others => 'Z');
end if;
end if;
end process register_vmeoutputs;
vme_nirq <= '1';
end architecture behavioral;