--******************************************************************************
--* @short Control Logic for Simulation And Spy Logic
--*
--* This control logic is used in the SimuSpyLogic and in the
--* MIAUSimuLogic.
--*
--* Via VME Command and Status registers it generated control signals
--* for the simulation and spy logic.
--*
--* @port iPreBCRes is a BC-reset pulse used when simulationg data
--* @port iBCRes is the BC-reset pulse used in spy-mode
--*
--* @port oSimuMode is 1 in simulation mode, 0 in spy mode
--* @port oDummyIsBCReset is 1 if the dummy input should be used as a
--* bcreset at chip level (for asynchronous tests)
--*
--* @port oWE_simuspy is the WE signal for the Simu/Spy memory in spy-mode
--* @port oRW_addr is the r/w address for the Simu/Spy memory
--*
--******************************************************************************
--* @author SAKULIN Hannes <hsakulin@dsy-srv5.cern.ch>
--* @date $Date: 2005/01/19 15:35:30 $
--* @version $Revision: 1.1 $
--******************************************************************************
--/
library IEEE;
use IEEE.Std_logic_1164.all;
use IEEE.Numeric_std.all;
use work.VMEMux.all;
-- pragma translate_off
library UNISIM;
use UNISIM.VCOMPONENTS.all;
-- pragma translate_on
entity SimuSpyControlLogic is
generic (
simuspyconfig_reg_addr : integer;
spydepth_reg_addr : integer;
spyarmpulse_reg_addr : integer;
spydone_reg_addr : integer);
port (
iPreBCRes : in std_logic;
iBCRes : in std_logic;
oSimuMode : out std_logic;
oDummyIsBCReset: out std_logic;
oWE_simuspy : out std_logic;
oRW_addr : out std_logic_vector(11 downto 0); -- 4k
-- VME port
vme_addr : in std_logic_vector;
vme_data : in std_logic_vector;
vme_en : in std_logic;
vme_wr : in std_logic;
vme_data_out : out std_logic_vector(15 downto 0);
vme_en_out : out std_logic;
-- Clock, control
clk : in std_logic;
reset : in std_logic
);
end entity SimuSpyControlLogic;
architecture behavioral of SimuSpyControlLogic is
signal rw_addr : std_logic_vector(11 downto 0); -- 4k
signal we_simuspy : std_logic;
signal spy_armed : std_logic;
signal full_pulse : std_logic := '0';
signal sBCRes : std_logic;
signal sSimuSpyConfig_Reg : std_logic_vector(15 downto 0);
signal sSpyDepth : std_logic_vector(15 downto 0);
signal sSpyArmPulse : std_logic_vector(15 downto 0);
signal sSpyDone : std_logic_vector(15 downto 0);
signal vme_data_out_i : TVMEData_vec (0 to 3);
signal vme_en_out_i : TVMEEnable_vec (0 to 3);
begin -- architecture behavioral
-----------------------------------------------------------------------------
--* SIMU/SPY Config Register
-----------------------------------------------------------------------------
--
-- 0 0 0 0 | 0 0 0 0 | 0 0 0 0 | 0 0 0 0
--
-- mode 0:spy
-- 1: simulate
--
-- use dummy
-- as bcreset
--
simuspy_config_reg: entity work.VMEReg
generic map (
init_val => "0000000000000000",
my_vme_base_address => simuspyconfig_reg_addr )
port map (
data => sSimuSpyConfig_Reg,
reset => reset,
vme_addr => vme_addr, vme_data => vme_data, vme_en => vme_en, vme_wr => vme_wr,
vme_data_out => vme_data_out_i(0),
vme_en_out => vme_en_out_i(0),
vme_clk => clk);
oSimuMode <= sSimuSpyConfig_Reg(0);
oDummyIsBCReset <= sSimuSpyConfig_Reg(1);
-----------------------------------------------------------------------------
--* Spy Depth register (last address of spy in 32-bit words)
-----------------------------------------------------------------------------
spy_depth_reg: entity work.VMEReg
generic map (
init_val => "0000001111111111",
my_vme_base_address => spydepth_reg_addr )
port map (
data => sSpyDepth,
reset => reset,
vme_addr => vme_addr, vme_data => vme_data, vme_en => vme_en, vme_wr => vme_wr,
vme_data_out => vme_data_out_i(1),
vme_en_out => vme_en_out_i(1),
vme_clk => clk);
-----------------------------------------------------------------------------
--* Spy ARM register. Write to it to arm the spy.
-----------------------------------------------------------------------------
simu_arm_pulse_reg: entity work.VMEWritePulseReg
generic map (
my_vme_base_address => spyarmpulse_reg_addr )
port map (
data_pulse => sSpyArmPulse,
reset => reset,
vme_addr => vme_addr, vme_data => vme_data, vme_en => vme_en, vme_wr => vme_wr,
vme_data_out => vme_data_out_i(2),
vme_en_out => vme_en_out_i(2),
vme_clk => clk);
-----------------------------------------------------------------------------
--* Spy Arm logic
--*
--* Spy is armed with a pulse
--* write_enable is set at next bcreset
--* write enable is cleared at 2nd bcreset or counter full
-----------------------------------------------------------------------------
spy_arm_logic: process (clk, reset) is
begin -- process spy_arm_logic
if reset = '1' then
spy_armed <= '0';
we_simuspy <= '0';
sSpyDone <= "0000000000000000";
elsif clk'event and clk = '1' then
if sSimuSpyConfig_Reg(0) = '0' then -- only in spy mode
-- arm the spy with a VME write
if sSpyArmPulse(0) = '1' then
spy_armed <= '1';
sSpyDone <= "0000000000000000";
end if;
-- enable wites at the next BCreset
if spy_armed = '1' and sBCRes = '1' then
we_simuspy <= '1';
spy_armed <= '0';
end if;
-- disable writes at the following BCreset or full pulse
if we_simuspy = '1' and (sBCRes = '1' or full_pulse = '1') then
we_simuspy <= '0';
sSpyDone <= "0000000000000001";
end if;
end if;
end if;
end process spy_arm_logic;
-----------------------------------------------------------------------------
--* Spy Done Register
-----------------------------------------------------------------------------
spy_done_reg: entity work.VMEStatusReg
generic map (
my_vme_base_address => spydone_reg_addr)
port map (
data => sSpyDone,
vme_addr => vme_addr, vme_en => vme_en, vme_wr => vme_wr,
vme_data_out => vme_data_out_i(3),
vme_en_out => vme_en_out_i(3),
vme_clk => clk,
reset => reset);
-----------------------------------------------------------------------------
-- read/write counter
-----------------------------------------------------------------------------
-- in simulation mode, need to reset the counter earlier
sBCRes <= iPreBCRes when sSimuSpyConfig_Reg(0) = '1' else iBCRes;
rw_counter: process (clk, reset) is
variable counter : std_logic_vector(11 downto 0) := "000000000000";
begin -- process rw_counter (12 bit)
if reset = '1' then
counter := "000000000000";
full_pulse <= '0';
elsif clk'event and clk = '1' then
if sBCRes = '1' then
counter := "000000000000";
else
counter := std_logic_vector(TO_UNSIGNED(TO_INTEGER(UNSIGNED(counter))+1,12));
if counter = sSpyDepth(11 downto 0) then
full_pulse <= '1';
else
full_pulse <= '0';
end if;
end if;
end if;
rw_addr <= counter;
end process rw_counter;
oWE_simuspy <= we_simuspy;
oRW_addr <= rw_addr;
-- multiplex vme_data_output
mux_vme(vme_data_out_i, vme_en_out_i, vme_data_out, vme_en_out);
end architecture behavioral;