--******************************************************************************
--* @short Mip And Iso Assignment Unit (the whole chip)
--******************************************************************************
--* @author TAUROK <taurokc@dsy-srv2.cern.ch>
--* @version $Revision: 1.0 $
--* @date $Date: 2005/12/14 14:17:18 $
--******************************************************************************
--*
--* Copied from MipIsoAU.vhd revision 1.16 from 2005/02/02
--* Contains Spy memories to monitor data from PSB board and
--* as in original version Sim memories to simulate MIP and ISO bits for all 16 muons
--* Timing on chip:
--* -------------------------------------------------------
--* | ------------------------------------ |
--* ___| | MIAUPhiProUnit| |
--* | || | -------- -------- -------- | |
--* | ||*|*|Eta |**|Phi |***|Phi | | |
--* |^|| |*|Conv | |Pro 1 | |Pro 2 | | |
--* IFF| |*|LUT | |LUT | |LUT | | |
--* | |*|-async| | | | | | |
--* | |*-------- | | | | | |
--* | |* | | | | | |
--* | |***********| | | |****** |
--* | |* | ^| | | |* |
--* | |* -------- | ^| |* /----------\ |
--* | |**********************-------- |**| | |
--* | ------------------------------------ | logic ***|**
--* | ****| | | * ___
--* | * \*---------* | * | |
--* | -------- * *** | **| |
--* ___| |Eta | * * | |^|
--* | ||************************|Pro |**** * | OFF
--* | || |LUT | * |
--* |^|| | | * |
--* IFF| | | * |
--* | | ^| * |
--* | -------- * |
--* --------------------------------------------------------
--* *
--* ___ ___ *
--* | | | | *
--* | |*****************************| |********
--* |^| |-| **|^|
--* IFF MIP | |*******
--* |^|
--* IFF ISO
--* clock:
--* ^ | ^ ^
--* | v | |
--*
--*
--* instance indices are 0 to 3 in each chip
--* 0: MIP DT/CSC
--* 1: MIP RPC
--* 2: ISO DT/CSC
--* 3: ISO RPC
--* PSB sends MIP/QUIET bits at a 80 MHz rate, therefore
--* MIP bits are taken with rising clk edge
--* QUIET bits are taken with falling clk edge
--* XC2V3000 contains 96 RAMblocks 18k
--/
library IEEE;
use IEEE.Std_logic_1164.all;
use WORK.GMTTypes.all;
use WORK.MIAUTiming.all;
use WORK.VMEMux.all;
-- use WORK.MIAUVMEAddrMap.all; --original AddressMap
use WORK.MIAUVMEAddrMap_test.all;
-- pragma translate_off
library UNISIM;
use UNISIM.VCOMPONENTS.all;
-- pragma translate_on
entity MipIsoAU is
generic (Neta : integer;
-- Neta is the number of rings of MIP and ISO bits
-- 10 in barrel chip and 10 in fwd chip
miau_idx : integer :=0); -- 0 for barrel, 1 for fwd
port (iRPCmuons : in TFourSyncedMu_flat;
iDTCSCmuons : in TFourSyncedMu_flat;
iMQbits : in std_logic_vector(0 to Neta*18-1);
oRPCisMIP,
oDTCSCisMIP,
oRPCisISO,
oDTCSCisISO : out std_logic_vector (0 to 3);
-- test outputs - for behavioral simu only
-- synthesis translate_off
oPhiSelBits : out TPhiSelBits_vec (0 to 15);
oEtaSelBits : out TEtaSelBits_vec (0 to 15);
-- synthesis translate_on
oDummy : in std_logic;
-- VME port
vme_addr : in std_logic_vector;
vme_data : inout std_logic_vector;
vme_en : in std_logic;
vme_wr : in std_logic;
vme_ndtack : out std_logic; -- low active
vme_nirq : out std_logic; -- low active
-- Clock and control
clk_input : in std_logic;
clk_test : out std_logic; -- clock1x from DCM
clk_out : out std_logic; -- clock output for feedback (use optional)
-- same as clk_test
clk_fb : in std_logic; -- clock feedback input (use optional)
dcm_locked : out std_logic; -- DCM is locked => goes to VME chip
reset_dcm : in std_logic; -- crate reset (crate reset button and after
-- power-up) => resets DCM
inactive : in std_logic; -- from front panel button (to GTS)
status : out std_logic_vector(1 downto 0);
test : out std_logic_vector(3 downto 0);
reset_input : in std_logic); -- hard reset from trigger control
--
-- register input
-- same function as level-1 reset
-- or hard reset from trigger control
--
-- generated by VME chip
-- resets only state machines, FFs,
-- counters, error flags
-- but not memories and registers
end;
architecture behavioral of MipIsoAU is
attribute syn_useioff : boolean;
attribute syn_useioff of behavioral : architecture is true;
type TIntArr is array (integer range <>) of integer;
constant chip_id_h : TIntArr(0 to 1) := (
16#0001#,
16#0001#
);
constant chip_id_l : TIntArr(0 to 1) := (
16#9152#, -- barrel
16#9151# -- forward
);
constant date_string : string := "$Date: 2005/12/07 14:18:19 $";
signal sMQbits : TCaloRing_vector (0 to Neta-1);
signal sMIPbits : TCaloRing_vector (0 to Neta-1);
signal sQuietbits : TCaloRing_vector (0 to Neta-1);
signal clk, reset : std_logic;
-- VME data and enable from various units
signal vme_data_out_i : TVMEData_vec (0 to 20);
signal vme_en_out_i : TVMEEnable_vec (0 to 20);
signal vme_data_out_muxed : std_logic_vector (15 downto 0);
signal vme_en_out_muxed : std_logic;
signal RPCmuons_reg : TSyncedMu_vector4;
signal DTCSCmuons_reg : TSyncedMu_vector4;
signal RPCisMIP_i, DTCSCisMIP_i,
RPCisISO_i, DTCSCisISO_i : std_logic_vector (0 to 3);
signal sDummy : std_logic_vector (15 downto 0);
signal vme_addr_i : std_logic_vector (vme_addr'RANGE);
signal vme_data_i : std_logic_vector (vme_data'RANGE);
signal vme_en_i : std_logic;
signal vme_wr_i : std_logic;
signal clk_fb_reg : std_logic;
signal RPCmuons_reg100, DTCSCmuons_reg100 : std_logic; -- spare bits
signal dummy_reg : std_logic;
signal dummy_reg_d : std_logic;
signal dummy_pulse : std_logic;
signal sBCReset_pre : std_logic;
signal sBCReset_main : std_logic;
signal sSimuMode : std_logic;
signal sDummyIsBCReset : std_logic;
signal sSimulatedData : std_logic_vector(15 downto 0);
signal sBXCount_unused : std_logic_vector(11 downto 0);
-- New internal signals from Toni:
signal sSelSpydata : std_logic_vector(15 downto 0); --VME register
signal spied_data : std_logic_vector(191 downto 0); -- input to spy rams
signal flat_RPCmuons_regs_i : TFourSyncedMu_flat; -- input registers in flat format
signal flat_DTCSCmuons_reg : TFourSyncedMu_flat;
signal flat_sMIPbits : std_logic_vector(0 to Neta*18-1);
signal flat_sQuietbits : std_logic_vector(0 to Neta*18-1);
begin
-------------------------------------------------------------------------------
--* register inputs
-------------------------------------------------------------------------------
-- muons
register_inputs: process (clk, reset) is
begin
if reset = '1' then
dummy_reg <= '0';
dummy_reg_d <= '0';
elsif (clk'event and clk = MIAU_EDGE_INPUT) then
RPCmuons_reg <= SyncedMu_vec_from_flat( iRPCmuons );
DTCSCmuons_reg <= SyncedMu_vec_from_flat( iDTCSCmuons );
RPCmuons_reg100 <= iRPCmuons(100);
DTCSCmuons_reg100 <= iDTCSCmuons(100);
clk_fb_reg <= clk_fb;
dummy_reg <= oDummy;
dummy_reg_d <= dummy_reg;
end if;
end process register_inputs;
dummy_pulse <= dummy_reg and (not dummy_reg_d); -- DUMMY PULSE
sMQbits <= CaloRing_vec_from_flat(iMQbits);
-----------------------------------------------------------------------------
--* The MIP and Quiet bit receiver logic
-----------------------------------------------------------------------------
the_MQReceiver : entity work.MIAUMQReceiver
generic map (
Neta => Neta)
port map (
clk => clk,
iMQbits => sMQbits,
oMIPbits => sMIPbits,
oQuietbits => sQuietbits);
-----------------------------------------------------------------------------
--* Convert registered input data back to flat format for SPY memory
-----------------------------------------------------------------------------
flat_sMIPbits <= CaloRing_vec_to_flat (sMIPbits);
flat_sQuietbits <= CaloRing_vec_to_flat (sQuietbits);
flat_RPCmuons_reg <= SyncedMu_vec_to_flat (RPCmuons_reg);
flat_DTCSCmuons_reg <= SyncedMu_vec_to_flat (DTCSCmuons_reg);
-----------------------------------------------------------------------------
--* MIAU_SelectSpydata register at ....0003a
-----------------------------------------------------------------------------
dummy_register: entity work.VMEStatusReg
generic map (
my_vme_base_address => MIAU_dummy_raddr)
port map (
data => sSelSpydata,
vme_addr => vme_addr_i,
vme_en => vme_en_i,
vme_wr => vme_wr_i,
vme_data_out => vme_data_out_i(20),
vme_en_out => vme_en_out_i(20),
vme_clk => clk,
reset => reset);
-----------------------------------------------------------------------------
--* Select which input data to spy set by VME register MIAU_SelectSpydata
-----------------------------------------------------------------------------
-- MIAU_SelectSpydata:
-- bit 1, 0 = 00 spy MIP bits
-- bit 1, 0 = 01 spy QUIET bits
-- bit 1, 0 = 10 spy RPC muons
-- bit 1, 0 = 11 spy DT/CSC muons
sel_spy_bits: process (clk)
begin
if reset = '1' then
spied_data <= (others => '0');
elsif (clk'event and clk = '1') then
if (sSelSpydata(1) = '0' and sSelSpydata(0) = '0') then
for i in 0 to 191 loop
if (i > Neta*18-1) then
spied_data(i) <= '0'; -- fill unused bits with '0'
else
spied_data(i) <= flat_sMIPbits(i);
end if;
end loop;
elsif (sSelSpydata(1) = '0' and sSelSpydata(0) = '1') then
for i in 0 to 191 loop
if (i > Neta*18-1) then
spied_data(i) <= '0'; -- fill unused bits with '0'
else
spied_data(i) <= flat_sQuietbits(i);
end if;
end loop;
elsif (sSelSpydata(1) = '1' and sSelSpydata(0) = '0') then
for i in 0 to 191 loop
if (i > 100) then spied_data <= '0'; -- fill unused bits with '0'
elsif (i = 100) then spied_data <= RPCmuons_reg100; -- insert spare bit
else
spied_data(i) <= flat_RPCmuons_reg(i);
end if;
end loop;
elsif (sSelSpydata(1) = '1' and sSelSpydata(0) = '1') then
for i in 0 to 191 loop
if (i > 100) then spied_data <= '0'; -- fill unused bits with '0'
elsif (i = 100) then spied_data <= DTCSCmuons_reg100; -- insert spare bit
else
spied_data(i) <= flat_DTCSCmuons_reg(i);
end if;
end loop;
end if;
end if;
end process sel_spy_bits;
-----------------------------------------------------------------------------
--* SPY memories
-----------------------------------------------------------------------------
-- To be done
-----------------------------------------------------------------------------
--* Generate the single assignment units
-----------------------------------------------------------------------------
G1:
for i in 0 to 3 generate -- loop over muons
DTCSCMIPUnit: entity work.MIAUSingleAssUnit
generic map (
Neta => Neta,
instance_idx => 0+(miau_idx*4), -- DT MIP
idxmuon => i)
port map (
iMuon => DTCSCmuons_reg(i),
iQuietBits => sMIPBits,
oIsISO => DTCSCisMIP_i(i),
-- synthesis translate_off
oPhiSelBits => oPhiSelBits (i),
oEtaSelBits => oEtaSelBits (i),
-- synthesis translate_on
vme_addr => vme_addr_i,
vme_data => vme_data_i,
vme_en => vme_en_i,
vme_wr => vme_wr_i,
vme_data_out => vme_data_out_i(i),
vme_en_out => vme_en_out_i(i),
clk => clk,
sinit => reset);
end generate G1;
G2:
for i in 0 to 3 generate
RPCMIPUnit: entity work.MIAUSingleAssUnit
generic map (
Neta => Neta,
instance_idx => 1+(miau_idx*4), -- RPC MIP
idxmuon => i)
port map (
iMuon => RPCmuons_reg(i),
iQuietBits => sMIPBits,
oIsISO => RPCisMIP_i(i),
-- synthesis translate_off
oPhiSelBits => oPhiSelBits (4+i),
oEtaSelBits => oEtaSelBits (4+i),
-- synthesis translate_on
vme_addr => vme_addr_i,
vme_data => vme_data_i,
vme_en => vme_en_i,
vme_wr => vme_wr_i,
vme_data_out => vme_data_out_i(i+4),
vme_en_out => vme_en_out_i(i+4),
clk => clk,
sinit => reset);
end generate G2;
G3 :
for i in 0 to 3 generate
DTCSCISOUnit: entity work.MIAUSingleAssUnit
generic map (
Neta => Neta,
instance_idx => 2+(miau_idx*4), -- DT ISO
idxmuon => i)
port map (
iMuon => DTCSCmuons_reg(i),
iQuietBits => sQuietBits,
oIsISO => DTCSCisISO_i(i),
-- synthesis translate_off
oPhiSelBits => oPhiSelBits (8+i),
oEtaSelBits => oEtaSelBits (8+i),
-- synthesis translate_on
vme_addr => vme_addr_i,
vme_data => vme_data_i,
vme_en => vme_en_i,
vme_wr => vme_wr_i,
vme_data_out => vme_data_out_i(i+8),
vme_en_out => vme_en_out_i(i+8),
clk => clk,
sinit => reset);
end generate G3;
G4 :
for i in 0 to 3 generate
RPCISOUnit: entity work.MIAUSingleAssUnit
generic map (
Neta => Neta,
instance_idx => 3+(miau_idx*4), -- RPC ISO
idxmuon => i)
port map (
iMuon => RPCmuons_reg(i),
iQuietBits => sQuietBits,
oIsISO => RPCisISO_i(i),
-- synthesis translate_off
oPhiSelBits => oPhiSelBits (12+i),
oEtaSelBits => oEtaSelBits (12+i),
-- synthesis translate_on
vme_addr => vme_addr_i,
vme_data => vme_data_i,
vme_en => vme_en_i,
vme_wr => vme_wr_i,
vme_data_out => vme_data_out_i(i+12),
vme_en_out => vme_en_out_i(i+12),
clk => clk,
sinit => reset);
end generate G4;
-----------------------------------------------------------------------------
--* Chip ID and Revision
-----------------------------------------------------------------------------
ChipID: entity work.ChipIDRegisters
generic map (
idregisters_vme_base_address => MIAU_chip_id0_raddr,
chipID_h => chip_id_h(miau_idx), chipID_l => chip_id_l(miau_idx),
chipRev_h => 16#feed#, chipRev_l => 16#deed#,
date_string => date_string)
port map (
vme_addr => vme_addr_i,
vme_en => vme_en_i,
vme_wr => vme_wr_i,
vme_data_out => vme_data_out_i(16),
vme_en_out => vme_en_out_i(16),
vme_clk => clk,
reset => reset);
-----------------------------------------------------------------------------
--* Dummy signals
-----------------------------------------------------------------------------
register_dummy: process (clk) is
begin -- process register_dummy
if clk'event and clk = '1' then
sDummy(0) <=
DTCSCmuons_reg(0).qual(0) or DTCSCmuons_reg(0).qual(1) or DTCSCmuons_reg(0).qual(2) or DTCSCmuons_reg(0).ch_valid or DTCSCmuons_reg(0).finehalo or
DTCSCmuons_reg(1).qual(0) or DTCSCmuons_reg(1).qual(1) or DTCSCmuons_reg(1).qual(2) or DTCSCmuons_reg(1).ch_valid or DTCSCmuons_reg(1).finehalo or
DTCSCmuons_reg(2).qual(0) or DTCSCmuons_reg(2).qual(1) or DTCSCmuons_reg(2).qual(2) or DTCSCmuons_reg(2).ch_valid or DTCSCmuons_reg(2).finehalo or
DTCSCmuons_reg(3).qual(0) or DTCSCmuons_reg(3).qual(1) or DTCSCmuons_reg(3).qual(2) or DTCSCmuons_reg(3).ch_valid or DTCSCmuons_reg(3).finehalo or
RPCmuons_reg(0).qual(0) or RPCmuons_reg(0).qual(1) or RPCmuons_reg(0).qual(2) or RPCmuons_reg(0).ch_valid or RPCmuons_reg(0).finehalo or
RPCmuons_reg(1).qual(0) or RPCmuons_reg(1).qual(1) or RPCmuons_reg(1).qual(2) or RPCmuons_reg(1).ch_valid or RPCmuons_reg(1).finehalo or
RPCmuons_reg(2).qual(0) or RPCmuons_reg(2).qual(1) or RPCmuons_reg(2).qual(2) or RPCmuons_reg(2).ch_valid or RPCmuons_reg(2).finehalo or
RPCmuons_reg(3).qual(0) or RPCmuons_reg(3).qual(1) or RPCmuons_reg(3).qual(2) or RPCmuons_reg(3).ch_valid or RPCmuons_reg(3).finehalo or
RPCmuons_reg100 or DTCSCmuons_reg100 or
clk_fb_reg;
end if;
end process register_dummy;
sDummy(15 downto 1) <= (others => '0');
-----------------------------------------------------------------------------
--* Dummy register
-----------------------------------------------------------------------------
dummy_register: entity work.VMEStatusReg
generic map (
my_vme_base_address => MIAU_dummy_raddr)
port map (
data => sDummy,
vme_addr => vme_addr_i,
vme_en => vme_en_i,
vme_wr => vme_wr_i,
vme_data_out => vme_data_out_i(17),
vme_en_out => vme_en_out_i(17),
vme_clk => clk,
reset => reset);
-------------------------------------------------------------------------------
-- multiplex VME outputs
-------------------------------------------------------------------------------
mux_vme(vme_data_out_i, vme_en_out_i, vme_data_out_muxed, vme_en_out_muxed);
-------------------------------------------------------------------------------
-- register outputs
-------------------------------------------------------------------------------
register_outputs: process (clk, reset) is
begin -- process register_outputs
if clk'event and clk = MIAU_EDGE_OUTPUT then -- rising clock edge
if sSimuMode = '1' then
-- the below assignments are needed to reverse the slice-direction
oDTCSCisMIP <= sSimulatedData( 0) & sSimulatedData( 1) & sSimulatedData( 2) & sSimulatedData( 3);
oRPCisMIP <= sSimulatedData( 4) & sSimulatedData( 5) & sSimulatedData( 6) & sSimulatedData( 7);
oDTCSCisISO <= sSimulatedData( 8) & sSimulatedData( 9) & sSimulatedData(10) & sSimulatedData(11);
oRPCisISO <= sSimulatedData(12) & sSimulatedData(13) & sSimulatedData(14) & sSimulatedData(15);
test(0) <= sSimulatedData( 0) ;
test(1) <= sSimulatedData( 4) ;
test(2) <= sSimulatedData( 8) ;
test(3) <= sSimulatedData(12) ;
else
oDTCSCisMIP <= DTCSCisMIP_i;
oDTCSCisISO <= DTCSCisISO_i;
oRPCisMIP <= RPCisMIP_i;
oRPCisISO <= RPCisISO_i;
test(0) <= DTCSCisMIP_i(0);
test(1) <= RPCisMIP_i(0);
test(2) <= DTCSCisISO_i(0);
test(3) <= RPCisISO_i(0);
end if;
end if;
end process register_outputs;
-----------------------------------------------------------------------------
--* BX counter (only the synchronization logic is used. the counter output is not used)
-----------------------------------------------------------------------------
bxcounter : entity work.BXCounter
generic map (
reg_addr => MIAU_ReadoutSyncReg_addr,
bcreset_delay_reg_default => "0000000000010010")
port map (
iBCReset => dummy_pulse,
oPreBCReset => sBCReset_pre,
oBCReset => sBCReset_main,
oBXCounter => sBXCount_unused,
vme_addr => vme_addr_i,
vme_data => vme_data_i,
vme_en => vme_en_i,
vme_wr => vme_wr_i,
vme_data_out => vme_data_out_i(18),
vme_en_out => vme_en_out_i(18),
clk => clk,
reset => reset);
-----------------------------------------------------------------------------
--* Simulation Logic
-----------------------------------------------------------------------------
simu_logic: entity work.MIAUSimuLogic
generic map (
simuspyconfig_reg_addr => MIAU_SimuSpyConfig_addr,
spydepth_reg_addr => MIAU_SpyDepth_addr,
spyarmpulse_reg_addr => MIAU_SpyArmPulse_waddr,
spydone_reg_addr => MIAU_SpyDone_raddr,
simuspyram_vme_base_address => MIAU_SimuRAM_base)
port map (
iPreBCRes => sBCReset_pre,
iBCRes => sBCReset_main,
oData => sSimulatedData,
oSimuMode => sSimuMode,
oDummyIsBCReset => sDummyIsBCReset,
vme_addr => vme_addr_i,
vme_data => vme_data_i,
vme_en => vme_en_i,
vme_wr => vme_wr_i,
vme_data_out => vme_data_out_i(19),
vme_en_out => vme_en_out_i(19),
clk => clk,
reset => reset);
-----------------------------------------------------------------------------
--* VME Logic
-----------------------------------------------------------------------------
vme_logic: entity work.InChipVMELogic
port map (
vme_addr => vme_addr,
vme_data => vme_data,
vme_en => vme_en,
vme_wr => vme_wr,
vme_ndtack => vme_ndtack,
vme_nirq => vme_nirq,
vme_addr_i => vme_addr_i,
vme_data_i => vme_data_i,
vme_en_i => vme_en_i,
vme_wr_i => vme_wr_i,
vme_data_out => vme_data_out_muxed,
vme_en_out => vme_en_out_muxed,
clk => clk,
reset => reset);
-------------------------------------------------------------------------------
--* Digital Clock Management & Chip Startup
-------------------------------------------------------------------------------
startup_dcm: entity work.StartupDCMVirtex2
port map (
iResetToGSR => reset_input,
iTristateToGTS => inactive,
oResetNet => reset,
iClkFromPAD => clk_input,
oClkNet => clk,
iResetDCM => reset_dcm,
oDCMLocked => dcm_locked);
-- output clock on two pins
clk_out <= clk;
clk_test <= clk;
status <= "00";
-- test <= "1111";
end architecture behavioral;