--******************************************************************************
--* @short Single Assignment Unit (for 1 muon) in MIAU Chip
--******************************************************************************
--* @author SAKULIN Hannes <hsakulin@dsy-srv3.cern.ch>
--* @version $Revision: 1.4 $
--* @date $Date: 2005/01/13 08:39:12 $
--******************************************************************************
--/
library IEEE;
use IEEE.Std_logic_1164.all;
use WORK.GMTTypes.all;
use work.MIAUVMEAddrMap.all;
use work.MIAUTiming.all;
entity MIAUSingleAssUnit is
generic (Neta : integer;
instance_idx : integer; -- 0 to 7
idxmuon : integer);
port (iMuon : in TSyncedMu;
iQuietBits : in TCaloRing_vector (0 to Neta-1);
oIsISO : out std_logic;
-- synthesis translate_off
oPhiSelBits : out TPhiSelBits;
oEtaSelBits : out TEtaSelBits;
-- synthesis translate_on
-- 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 and control
clk : in std_logic;
sinit : in std_logic);
end;
architecture behavioral of MIAUSingleAssUnit is
attribute syn_useioff : boolean;
attribute syn_useioff of behavioral : architecture is true;
component MIAUPhiProUnit is
port (iCh : in std_logic; -- charge
iPt : in std_logic_vector (4 downto 0); -- 5 bit pT
iEta : in std_logic_vector (5 downto 0); -- 6 bit eta
iPhi : in std_logic_vector (7 downto 0); -- 6 bit phi
oPhiSelectBits : out std_logic_vector (17 downto 0) ); -- phi select bits
end component;
signal sPhiSelectBits : std_logic_vector (17 downto 0);
signal s1PhiSelectBits : std_logic_vector (17 downto 0);
signal sEtaSelectBits : std_logic_vector (Neta-1 downto 0);
signal sEtaSelectBitsBIG : std_logic_vector (9 downto 0);
signal s1EtaSelectBits : std_logic_vector (Neta-1 downto 0);
signal s1QuietBits : TCaloRing_vector (0 to Neta-1);
signal charge_i : std_logic_vector (0 downto 0);
signal vme_data_out_i : vme_dout_vec (0 to 3);
signal vme_en_out_i : vme_enout_vec (0 to 3);
signal a1 : std_logic_vector(0 to 18*Neta-1);
signal a2 : std_logic_vector(0 to 47);
signal a3 : std_logic_vector(0 to 11);
signal a4 : std_logic_vector(0 to 2);
signal any_selected : std_logic;
-- very important attributes (otherwise synplify optimizes the AND144 for area - see below)
attribute syn_keep : boolean;
attribute syn_keep of a1:signal is true;
--attribute syn_keep of a2:signal is true;
attribute syn_keep of a3:signal is true;
--attribute syn_keep of a4:signal is true;
begin
thePhiProUnit: entity work.MIAUPhiProUnit
generic map (
instance_idx => instance_idx,
idxmuon => idxmuon)
port map (
iCh => iMuon.charge,
iPt => iMuon.pt,
iEta => iMuon.eta,
iPhi => iMuon.phi,
oPhiSelectBits => sPhiSelectBits,
vme_addr => vme_addr,
vme_data => vme_data,
vme_en => vme_en,
vme_wr => vme_wr,
vme_data_out => vme_data_out_i(0 to 2),
vme_en_out => vme_en_out_i(0 to 2),
clk => clk,
sinit => sinit);
charge_i(0) <= iMuon.charge; -- convert to 1-element vector
EtaProLUT: entity work.miauetaprolut
generic map (
instance_idx => instance_idx,
my_vme_base_address => MIAU_EtaProLUT_base(instance_idx mod 4) + idxmuon * MIAU_EtaProLUT_size)
-- 4k per muon
port map (
eta => iMuon.eta,
pt => iMuon.pt,
charge => charge_i,
eta_sel => sEtaSelectBitsBIG,
vme_addr => vme_addr,
vme_data => vme_data,
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,
clk => clk,
sinit => sinit);
sEtaSelectBits <= sEtaSelectBitsBIG (Neta-1 downto 0);
-- multiplex vme_data_output
vme_data_out <= vme_data_out_i(0) when vme_en_out_i(0) = '1' else
vme_data_out_i(1) when vme_en_out_i(1) = '1' else
vme_data_out_i(2) when vme_en_out_i(2) = '1' else
vme_data_out_i(3);
vme_en_out <= vme_en_out_i(0) or
vme_en_out_i(1) or
vme_en_out_i(2) or
vme_en_out_i(3);
s1PhiSelectBits <= sPhiSelectBits;
s1QuietBits <= iQuietBits;
s1EtaSelectBits <= sEtaSelectBits;
-- notes on implementation of AND144:
--
-- synpilfy will optimize for area independent of the vhdl coding and generate
-- at least 7 levels of logic instead of the required 5 levels. All the below
-- coding styles are optimized in the same way:
-- - loop with variables
-- - loop with variables that can be matched to 4-input luts
-- - generate of 4-input ANDs
-- - generate of 4-input ANDs inside processes
--
-- synplify will optimize for area even with strong timing constraints
-- - high frequency (100 MHz)
-- - reg_input_delay of 5 or 3 ns
--
-- only way to force syplify not to optmize for area seems to force it to keep
-- the intermediate signals with syn_keep (see above).
--
-- check if any region is selected at all (if not => empty muon)
any_selected <= '1' when s1PhiSelectBits /= "000000000000000000" else '0';
L1: for i1 in 0 to 18*Neta-1 generate
begin -- generate L1
a1(i1) <= (s1PhiSelectBits(i1 mod 18) and s1EtaSelectBits(i1 / 18) and s1QuietBits(i1 / 18)(i1 mod 18) ) or
(not (s1PhiSelectBits(i1 mod 18) and s1EtaSelectBits(i1 / 18))) ;
end generate L1;
L2: for i2 in 0 to 9*Neta/2-1 generate
begin -- generate L2
p2: process (a1(4*i2), a1(4*i2+1), a1(4*i2+2), a1(4*i2+3)) is
begin -- process p2
a2(i2) <= a1(4*i2) and a1(4*i2+1) and a1(4*i2+2) and a1(4*i2+3);
end process p2;
end generate L2;
L2A: for i2 in 9*Neta/2 to 47 generate
begin -- generate L2A
a2(i2) <= '1';
end generate L2A;
L3: for i3 in 0 to 11 generate
begin -- generate L3
p3: process (a2(4*i3), a2(4*i3+1), a2(4*i3+2), a2(4*i3+3)) is
begin
a3(i3) <= a2(4*i3) and a2(4*i3+1) and a2(4*i3+2) and a2(4*i3+3);
end process p3;
end generate L3;
L4: for i4 in 0 to 2 generate
begin -- generate L4
p4: process (a3(4*i4), a3(4*i4+1), a3(4*i4+2), a3(4*i4+3)) is
begin
a4(i4) <= a3(4*i4) and a3(4*i4+1) and a3(4*i4+2) and a3(4*i4+3);
end process p4;
end generate L4;
-- select logic
process (clk)
begin
if clk'event and clk = MIAU_EDGE_OUTPUT then
-- synthesis translate_off
oPhiSelBits <= sPhiSelectBits;
oEtaSelBits <= (others => '0');
oEtaSelBits(Neta-1 downto 0) <= sEtaSelectBits;
-- synthesis translate_on
end if;
end process;
oIsISO <= a4(0) and a4(1) and a4(2) and any_selected; -- a4(3);
--
-- alternate implementation that results in more stages of logic generated by synplify
--
-- -- select logic
-- process (clk)
-- variable tmpISO : std_logic;
-- variable selected : std_logic;
-- variable isISO : std_logic;
-- -- variable a1 : std_logic_vector(0 to 18*Neta-1);
-- -- variable a2 : std_logic_vector(0 to 63);
-- -- variable a3 : std_logic_vector(0 to 15);
-- -- variable a4 : std_logic_vector(0 to 3);
-- -- variable i : integer;
-- begin
-- if clk'event and clk = MIAU_EDGE_OUTPUT then
-- tmpISO := '1';
-- for iphi in 0 to 17 loop
-- for ieta in 0 to Neta-1 loop
-- -- if ( s1PhiSelectBits(iphi) = '1' ) and ( s1EtaSelectBits(ieta) = '1' ) then
-- selected := s1PhiSelectBits(iphi) and s1EtaSelectBits(ieta);
-- isISO := ( selected and s1QuietBits(ieta)(iphi) ) or (not selected) ;
-- tmpISO := tmpISO and isISO ;
-- -- end if;
-- end loop;
-- end loop;
-- oIsISO <= tmpISO and any_selected;
-- -- synthesis translate_off
-- oPhiSelBits <= sPhiSelectBits;
-- oEtaSelBits <= (others => '0');
-- oEtaSelBits(Neta-1 downto 0) <= sEtaSelectBits;
-- -- synthesis translate_on
-- end if;
-- end process;
end architecture behavioral;