------------------------------------------------------------------------------- -- ---------------------------------------------------------------------------- -- Jet FPGA package ------------------------------------------------------------------------------- ------------------------------------------------------------------------------- library ieee; use ieee.std_logic_1164.all; package JET_FPGA_pkg is constant number_of_registers : integer := 46; type control_register_type is array (0 to (number_of_registers-1)) of std_logic_vector(11 downto 0); constant default_register_values : control_register_type := (x"041",x"004",x"000",x"03f",x"3ff",x"3ff",x"3ff",x"3ff",x"3ff",x"3ff", x"3ff",x"3ff",x"3ff",x"3ff",x"3ff",x"3ff",x"3ff",x"3ff",x"3ff",x"3ff", x"004",x"000",x"dec",x"000",x"013",x"000",x"000",x"001",x"000",x"001", x"000",x"001",x"080",x"000",x"000",x"000",x"000",x"000",x"000",x"000", x"000",x"000",x"000",x"000",x"000",x"000"); type FCAL_mapping_array is array (0 to 2) of integer; -- (from_x, from_y, 0=preserve 1=divide 2=divide-and-preserve-sum) type FCAL_mapping_column is array (0 to 10) of FCAL_mapping_array; type FCAL_mapping_matrix is array (0 to 6) of FCAL_mapping_column; constant fcm : FCAL_mapping_matrix := (((0,0,0),(0,1,0),(0,2,0),(0,3,0),(0,4,0),(0,5,0),(0,6,0),(0,7,0),(0,8,0),(0,9,0),(0,10,0)), ((1,2,1),(1,5,2),(1,5,1),(2,5,2),(2,5,1),(2,6,2),(2,6,1),(1,6,2),(1,6,1),(2,2,2),(2,2,1)), ((1,0,0),(1,3,0),(2,3,0),(2,4,0),(1,4,0),(1,7,0),(2,7,0),(2,8,0),(1,8,0),(1,9,0),(2,9,0)), ((3,0,0),(3,3,0),(4,3,0),(4,4,0),(3,4,0),(3,7,0),(4,7,0),(4,8,0),(3,8,0),(3,9,0),(4,9,0)), ((3,2,1),(3,5,2),(3,5,1),(4,5,2),(4,5,1),(4,6,2),(4,6,1),(3,6,2),(3,6,1),(4,2,2),(4,2,1)), ((5,0,0),(5,1,0),(5,2,0),(5,3,0),(5,4,0),(5,5,0),(5,6,0),(5,7,0),(5,8,0),(5,9,0),(5,10,0)), ((6,0,0),(6,1,0),(6,2,0),(6,3,0),(6,4,0),(6,5,0),(6,6,0),(6,7,0),(6,8,0),(6,9,0),(6,10,0))); constant a_control_reg : integer := 1; constant a_input_settings : integer := 2; constant a_status_reg : integer := 3; -- Jet constant a_jet_thresholds : integer := 4; -- 16 registers. -- DAQ constant a_daq_delay : integer := 20; constant a_daq_orbit_counter_max : integer := 22; constant a_daq_orbit_counter_load : integer := 23; constant a_daq_dav_space : integer := 24; -- Spy constant a_spy_mode : integer := 25; constant a_input_spy_data : integer := 26; constant a_reset_input_spy_address : integer := 27; constant a_output_spy_data : integer := 28; constant a_reset_output_spy_address : integer := 29; constant a_roc_spy_data : integer := 30; constant a_reset_roc_spy_address : integer := 31; constant a_roc_spy_events_to_read : integer := 32; -- TTC constant a_ttc_spy_instructions : integer := 33; -- 4 registers. constant a_ttc_rec : integer := 37; -- 2 registers. -- MC constant a_mc_reg : integer := 39; -- 3 registers. -- Input mask constant a_input_mask : integer := 42; -- Access counter (Debug) constant a_access_counter : integer := 43; constant a_random_data : integer := 44; constant a_random_seed : integer := 45; end JET_FPGA_pkg; -------------------------------------------------------------------------------- -- Copyright (c) 1995-2003 Xilinx, Inc. -- All Right Reserved. -------------------------------------------------------------------------------- -- ____ ____ -- / /\/ / -- /___/ \ / Vendor: Xilinx -- \ \ \/ Version : 7.1.04i -- \ \ Application : -- / / Filename : DCM_single.vhd -- /___/ /\ Timestamp : 01/23/2006 19:46:04 -- \ \ / \ -- \___\/\___\ -- --Command: --Design Name: DCM_single -- -- Module DCM_single -- Generated by Xilinx Architecture Wizard -- Written for synthesis tool: XST library ieee; use ieee.std_logic_1164.ALL; use ieee.numeric_std.ALL; -- synopsys translate_off library UNISIM; use UNISIM.Vcomponents.ALL; -- synopsys translate_on entity DCM_single is port ( CLKIN_IN : in std_logic; CLKIN_IBUFG_OUT : out std_logic; CLK0_OUT : out std_logic; CLK90_OUT : out std_logic; CLK180_OUT : out std_logic; CLK270_OUT : out std_logic; LOCKED_OUT : out std_logic); end DCM_single; architecture BEHAVIORAL of DCM_single is signal CLKFB_IN : std_logic; signal CLKIN_IBUFG : std_logic; signal CLK0_BUF : std_logic; signal CLK90_BUF : std_logic; signal CLK180_BUF : std_logic; signal CLK270_BUF : std_logic; signal GND : std_logic; component IBUFG port ( I : in std_logic; O : out std_logic); end component; component BUFG port ( I : in std_logic; O : out std_logic); end component; component DCM generic( CLK_FEEDBACK : string := "1X"; CLKDV_DIVIDE : real := 2.000000; CLKFX_DIVIDE : integer := 1; CLKFX_MULTIPLY : integer := 4; CLKIN_DIVIDE_BY_2 : boolean := FALSE; CLKIN_PERIOD : real := 0.000000; CLKOUT_PHASE_SHIFT : string := "NONE"; DESKEW_ADJUST : string := "SYSTEM_SYNCHRONOUS"; DFS_FREQUENCY_MODE : string := "LOW"; DLL_FREQUENCY_MODE : string := "LOW"; DUTY_CYCLE_CORRECTION : boolean := TRUE; FACTORY_JF : bit_vector := x"C080"; PHASE_SHIFT : integer := 0; STARTUP_WAIT : boolean := FALSE; DSS_MODE : string := "NONE"); port ( CLKIN : in std_logic; CLKFB : in std_logic; RST : in std_logic; PSEN : in std_logic; PSINCDEC : in std_logic; PSCLK : in std_logic; DSSEN : in std_logic; CLK0 : out std_logic; CLK90 : out std_logic; CLK180 : out std_logic; CLK270 : out std_logic; CLKDV : out std_logic; CLK2X : out std_logic; CLK2X180 : out std_logic; CLKFX : out std_logic; CLKFX180 : out std_logic; STATUS : out std_logic_vector (7 downto 0); LOCKED : out std_logic; PSDONE : out std_logic); end component; begin GND <= '0'; CLKIN_IBUFG_OUT <= CLKIN_IBUFG; CLK0_OUT <= CLKFB_IN; CLKIN_IBUFG_INST : IBUFG port map (I=>CLKIN_IN, O=>CLKIN_IBUFG); CLK0_BUFG_INST : BUFG port map (I=>CLK0_BUF, O=>CLKFB_IN); CLK90_BUFG_INST : BUFG port map (I=>CLK90_BUF, O=>CLK90_OUT); CLK180_BUFG_INST : BUFG port map (I=>CLK180_BUF, O=>CLK180_OUT); CLK270_BUFG_INST : BUFG port map (I=>CLK270_BUF, O=>CLK270_OUT); DCM_INST : DCM generic map( CLK_FEEDBACK => "1X", CLKDV_DIVIDE => 2.000000, CLKFX_DIVIDE => 1, CLKFX_MULTIPLY => 4, CLKIN_DIVIDE_BY_2 => FALSE, CLKIN_PERIOD => 25.000000, CLKOUT_PHASE_SHIFT => "NONE", DESKEW_ADJUST => "SYSTEM_SYNCHRONOUS", DFS_FREQUENCY_MODE => "LOW", DLL_FREQUENCY_MODE => "LOW", DUTY_CYCLE_CORRECTION => TRUE, FACTORY_JF => x"C080", PHASE_SHIFT => 0, STARTUP_WAIT => FALSE) port map (CLKFB=>CLKFB_IN, CLKIN=>CLKIN_IBUFG, DSSEN=>GND, PSCLK=>GND, PSEN=>GND, PSINCDEC=>GND, RST=>GND, CLKDV=>open, CLKFX=>open, CLKFX180=>open, CLK0=>CLK0_BUF, CLK2X=>open, CLK2X180=>open, CLK90=>CLK90_BUF, CLK180=>CLK180_BUF, CLK270=>CLK270_BUF, LOCKED=>LOCKED_OUT, PSDONE=>open, STATUS=>open); end BEHAVIORAL; ------------------------------------------------------------------------------- -- ---------------------------------------------------------------------------- -- Clock unit ------------------------------------------------------------------------------- ------------------------------------------------------------------------------- library ieee; use ieee.std_logic_1164.all; entity clock_unit is port ( clk_des1_in, clk_des2_in : in std_logic; clk0_d1, clk180_d1 : out std_logic; clk0_d2, clk90_d2, clk180_d2, clk270_d2 : out std_logic; locked_des1, locked_des2 : out std_logic); end clock_unit; architecture clock_unit_design of clock_unit is component DCM_single port ( CLKIN_IN : in std_logic; CLKIN_IBUFG_OUT : out std_logic; CLK0_OUT : out std_logic; CLK90_OUT : out std_logic; CLK180_OUT : out std_logic; CLK270_OUT : out std_logic; LOCKED_OUT : out std_logic); end component; begin -- clock_unit_design DCM_des1: DCM_single port map(clk_des1_in,open,clk0_d1,open,clk180_d1,open,locked_des1); DCM_des2: DCM_single port map(clk_des2_in,open,clk0_d2,clk90_d2,clk180_d2,clk270_d2,locked_des2); end clock_unit_design; ------------------------------------------------------------------------------- -- ---------------------------------------------------------------------------- -- Reset unit ------------------------------------------------------------------------------- ------------------------------------------------------------------------------- library ieee; use ieee.std_logic_1164.all; entity reset_unit is port ( reset_request : in std_logic; reset : out std_logic; clk : in std_logic); end reset_unit; architecture reset_unit_design of reset_unit is signal fifo : std_logic_vector(31 downto 0) := (others => '0'); signal reset_in : std_logic := '0'; begin -- reset_unit_design RST: process (clk) begin -- process RST if clk'event and clk = '1' then -- rising clock edge fifo <= fifo((fifo'high-1) downto 0) & reset_in; if fifo(fifo'length/2-1) = '0' then reset_in <= '1'; elsif (reset_request = '1') and (fifo(fifo'high) = '1') then reset_in <= '0'; end if; reset <= fifo(fifo'length/2-1); end if; end process RST; end reset_unit_design; ------------------------------------------------------------------------------- ------------------------------------------------------------------------------- -- JET algorithm for ATLAS Level-1 Trigger. -- Written by Attila Hidvegi. ------------------------------------------------------------------------------- -- Ver: 0.5.1a -- 2003-09-25 Four clock-cycle version. -- 2003-09-23 Three clock-cycle version. -- 2003-09-12 Two clock-cycle version. -- 2003-08-22 First simple version, no FCAL. ------------------------------------------------------------------------------- ------------------------------------------------------------------------------- library ieee; use ieee.std_logic_1164.all; use ieee.std_logic_unsigned.all; use ieee.std_logic_arith.conv_std_logic_vector; entity JET is generic ( ROIx : integer := 2; -- Number of ROIs in x direction. ROIy : integer := 4; -- Number of ROIs in y direction. input_width : integer := 10; -- Width of input data. threshold_nr : integer := 8; -- Number of thresholds. threshold_width : integer := 10; -- Width of threshold. multiplicity_width : integer := 3); -- Width of a single jetmultilpicity. port ( data_in : in std_logic_vector(((ROIx*2+3)*(ROIy*2+3)*input_width-1) downto 0); thresholds : in std_logic_vector((threshold_nr*2*threshold_width-1) downto 0); sizes : in std_logic_vector((threshold_nr*2*2-1) downto 0); fcal_mode : in std_logic_vector(1 downto 0); ROIs : out std_logic_vector(((threshold_nr+4)*ROIx*ROIy-1) downto 0); jetmultiplicities : out std_logic_vector((threshold_nr*multiplicity_width) downto 0); jetmultiplicities_fcal : out std_logic_vector((threshold_nr*multiplicity_width) downto 0); clk40, reset : in std_logic); end JET; architecture JET_design of JET is type c_array is array ((ROIy*2+2) downto 0) of std_logic_vector((input_width+3) downto 0); type c_matrix is array ((ROIx*2+2) downto 0) of c_array; type cluster_type is array (7 downto 0) of c_matrix; signal clo : cluster_type; type cluster_size is array (0 to 5) of integer; type cluster_index is array (1 to 7) of cluster_size; constant ci : cluster_index := ((2,1,0,0,1,0),(3,1,1,0,2,0),(2,2,1,1,0,1),(3,2,2,2,0,1), (4,2,3,3,2,0),(3,3,4,2,0,2),(4,4,5,5,0,2)); type local_max_pos is array (0 to 1) of integer; type local_max_index is array (0 to 7) of local_max_pos; constant lmi : local_max_index := ((0,1),(1,1),(1,0),(1,-1),(0,-1),(-1,-1),(-1,0),(-1,1)); type fcal_type is array (0 to (ROIx-1)) of std_logic_vector((ROIy-1) downto 0); signal fcal : fcal_type; constant mult_width_fc : integer := multiplicity_width*2/3; type ROI_type is array ((ROIx*ROIy-1) downto 0) of std_logic_vector((threshold_nr+3) downto 0); begin -- JET_design ALG: process (clk40, reset) variable cl, st : cluster_type; variable lm : boolean; variable c3_1, c3_2, c3, mux : std_logic_vector((clo(3)(0)(0)'length-1) downto 0); variable ROI : ROI_type; variable size : std_logic_vector(1 downto 0); variable jetmult, jetmult_fcal : std_logic_vector((jetmultiplicities'length-1) downto 0); variable jetm, jetm_fcal1, jetm_fcal2 : std_logic_vector((multiplicity_width+4) downto 0); begin -- process ALG if reset = '0' then -- asynchronous reset (active low) clo <= (others => (others => (others => (others => '0')))); fcal <= (others => (others => '0')); ROIs <= (others => '0'); jetmultiplicities <= (others => '0'); jetmultiplicities_fcal <= (others => '0'); elsif clk40'event and clk40 = '1' then -- rising clock edge cl := (others => (others => (others => (others => '0')))); for x in (ROIx*2+2) downto 0 loop for y in (ROIy*2+2) downto 0 loop cl(0)(x)(y) := "0000" & data_in((((ROIy*2+3)*x+y+1)*input_width-1) downto (((ROIy*2+3)*x+y)*input_width)); end loop; -- y end loop; -- x -- Adders for c in 1 to 7 loop -- Loop over cluster sizes for x in 0 to (ROIx*2+3-ci(c)(0)) loop -- Loop over jet elements in phi direction. for y in 0 to (ROIy*2+3-ci(c)(1)) loop -- Loop over jet elements in etha direction. cl(c)(x)(y) := cl(ci(c)(2))(x)(y) + cl(ci(c)(3))(x+ci(c)(4))(y+ci(c)(5)); end loop; -- y end loop; -- x end loop; -- c -- Saturation st := (others => (others => (others => (others => '0')))); for c in 1 to 3 loop for x in 0 to (ROIx*2+2-c) loop for y in 0 to (ROIy*2+2-c) loop for i in 0 to c loop for j in 0 to c loop if conv_integer(cl(0)(x+i)(y+j)((input_width-1) downto 0)) = (2**input_width-1) then st(c)(x)(y)(0) := '1'; end if; end loop; -- j end loop; -- i end loop; -- y end loop; -- x end loop; -- c -- Local maximums & multiplexing clo <= (others => (others => (others => (others => '0')))); fcal <= (others => (others => '0')); for rx in 0 to (ROIx-1) loop for ry in 0 to (ROIy-1) loop for x in (rx*2+1) to (rx*2+2) loop for y in (ry*2+1) to (ry*2+2) loop lm := true; for i in 0 to 7 loop if i<4 then lm := lm and (cl(3)(x)(y) > cl(3)(x+lmi(i)(0))(y+lmi(i)(1))); else lm := lm and (cl(3)(x)(y) >= cl(3)(x+lmi(i)(0))(y+lmi(i)(1))); end if; end loop; -- i if lm then clo(0)(rx)(ry) <= conv_std_logic_vector(((x-1) mod 2)+2*((y-1) mod 2),clo(0)(rx)(ry)'length); clo(1)(rx)(ry) <= cl(3)(x)(y); clo(2)(rx)(ry) <= cl(6)(rx*2+1)(ry*2+1); clo(3)(rx)(ry) <= cl(6)((x/2)*2)(ry*2+1); clo(4)(rx)(ry) <= cl(6)(rx*2+1)((y/2)*2); clo(5)(rx)(ry) <= cl(6)((x/2)*2)((y/2)*2); clo(6)(rx)(ry) <= cl(7)(x-1)(y-1); clo(7)(rx)(ry)(6 downto 1) <= st(3)(x-1)(y-1)(0) & st(2)((x/2)*2)((y/2)*2)(0) & st(2)(rx*2+1)((y/2)*2)(0) & st(2)((x/2)*2)(ry*2+1)(0) & st(2)(rx*2+1)(ry*2+1)(0) & st(1)(x)(y)(0); if (x = 1 and fcal_mode(0) = '1') or (rx = (ROIx-1) and fcal_mode(1) = '1') then fcal(rx)(ry) <= '1'; end if; end if; end loop; -- y end loop; -- x end loop; -- ry end loop; -- rx -- Thresholds & ROIs ROI := (others => (others => '0')); for rx in 0 to (ROIx-1) loop for ry in 0 to (ROIy-1) loop -- if clo(2)(rx)(ry) > clo(3)(rx)(ry) then c3_1 := clo(2)(rx)(ry); else c3_1 := clo(3)(rx)(ry); end if; -- if clo(4)(rx)(ry) > clo(5)(rx)(ry) then c3_2 := clo(4)(rx)(ry); else c3_2 := clo(5)(rx)(ry); end if; -- if c3_1 > c3_2 then c3 := c3_1; else c3 := c3_2; end if; if clo(2)(rx)(ry)>=clo(3)(rx)(ry) and clo(2)(rx)(ry)>=clo(4)(rx)(ry) and clo(2)(rx)(ry)>=clo(5)(rx)(ry) then c3 := clo(2)(rx)(ry); elsif clo(3)(rx)(ry)>=clo(4)(rx)(ry) and clo(3)(rx)(ry)>=clo(5)(rx)(ry) then c3 := clo(3)(rx)(ry); elsif clo(4)(rx)(ry)>=clo(5)(rx)(ry) then c3 := clo(4)(rx)(ry); else c3 := clo(5)(rx)(ry); end if; for i in 0 to (threshold_nr-1) loop if fcal(rx)(ry) = '1' then size := sizes(((i+1+threshold_nr)*2-1) downto ((i+threshold_nr)*2)); else size := sizes(((i+1)*2-1) downto (i*2)); end if; case size is when "01" => mux := clo(1)(rx)(ry); when "11" => mux := clo(6)(rx)(ry); when "10" => mux := c3; when others => mux := (others => '0'); end case; if fcal(rx)(ry) = '1' then if mux > thresholds(((i+1+threshold_nr)*threshold_width-1) downto (threshold_width*(i+threshold_nr))) then ROI(rx*ROIy+ry)(i) := '1'; end if; else if mux > thresholds(((i+1)*threshold_width-1) downto (threshold_width*i)) then ROI(rx*ROIy+ry)(i) := '1'; end if; end if; end loop; -- i ROI(rx*ROIy+ry)(threshold_nr) := clo(7)(rx)(ry)(6); ROI(rx*ROIy+ry)((threshold_nr+2) downto (threshold_nr+1)) := clo(0)(rx)(ry)(1 downto 0); end loop; -- ry end loop; -- rx for i in 0 to (ROIx*ROIy-1) loop ROI(i)(ROI(i)'length-1) := '1'; for j in 0 to (ROI(i)'length-2) loop ROI(i)(ROI(i)'length-1) := ROI(i)(ROI(i)'length-1) xor ROI(i)(j); end loop; -- j end loop; -- i -- Jetmultiplicities jetmult := (others => '0'); jetmult_fcal := (others => '0'); for i in 0 to (threshold_nr-1) loop jetm := (others => '0'); jetm_fcal1 := (others => '0'); jetm_fcal2 := (others => '0'); for j in 0 to (ROIx*ROIy-1) loop jetm := jetm + ROI(j)(i); jetm_fcal2 := jetm_fcal2 + (ROI(j)(i) and fcal(j/ROIy)(j rem ROIy)); jetm_fcal1 := jetm_fcal1 + (ROI(j)(i) and not fcal(j/ROIy)(j rem ROIy)); end loop; -- j if conv_integer(jetm) < (2**multiplicity_width) then jetmult(((i+1)*multiplicity_width-1) downto (multiplicity_width*i)) := jetm((multiplicity_width-1) downto 0); else jetmult(((i+1)*multiplicity_width-1) downto (multiplicity_width*i)) := (others => '1'); end if; if conv_integer(jetm_fcal1) < (2**mult_width_fc) then jetmult_fcal(((i+1)*mult_width_fc-1) downto (mult_width_fc*i)) := jetm_fcal1((mult_width_fc-1) downto 0); else jetmult_fcal(((i+1)*mult_width_fc-1) downto (mult_width_fc*i)) := (others => '1'); end if; if i < (threshold_nr/2) then if conv_integer(jetm_fcal2) < (2**mult_width_fc) then jetmult_fcal(((i+1+threshold_nr)*mult_width_fc-1) downto (mult_width_fc*(i+threshold_nr))) := jetm_fcal2((mult_width_fc-1) downto 0); else jetmult_fcal(((i+1+threshold_nr)*mult_width_fc-1) downto (mult_width_fc*(i+threshold_nr))) := (others => '1'); end if; end if; end loop; -- i jetmult(jetmult'high) := '1'; jetmult_fcal(jetmult_fcal'high) := '1'; for i in 0 to (jetmult'high-1) loop jetmult(jetmult'high) := jetmult(jetmult'high) xor jetmult(i); jetmult_fcal(jetmult_fcal'high) := jetmult_fcal(jetmult_fcal'high) xor jetmult_fcal(i); end loop; -- i -- Mappings for i in 0 to (ROIx*ROIy-1) loop ROIs(((1+i)*ROI(i)'length-1) downto (ROI(i)'length*i)) <= ROI(i); end loop; -- i jetmultiplicities <= jetmult; jetmultiplicities_fcal <= jetmult_fcal; end if; end process ALG; end JET_design; ------------------------------------------------------------------------------- -- ---------------------------------------------------------------------------- -- DAQ ------------------------------------------------------------------------------- ------------------------------------------------------------------------------- library ieee; use ieee.std_logic_1164.all; use ieee.std_logic_unsigned.all; use ieee.std_logic_arith.conv_std_logic_vector; library unisim; use unisim.vcomponents.all; entity daq is generic ( data_width : integer := 16*2; FrameLength : integer := 16*1+1); port ( data_in : in std_logic_vector((data_width-1) downto 0); delay : in std_logic_vector(8 downto 0); -- frame_length : in std_logic_vector(6 downto 0); orbit_counter : in std_logic_vector(11 downto 0); counter_load : in std_logic_vector(11 downto 0); bc_reset : in std_logic; l1a : in std_logic; data_out : out std_logic_vector(4 downto 0); dav : out std_logic; dav_space : in std_logic_vector(6 downto 0); fcal_mode : in std_logic_vector(1 downto 0); full : out std_logic; clk, reset : in std_logic); end daq; architecture daq_design of daq is component RAMB16_S36_S36 port ( DIA, DIB : in std_logic_vector(31 downto 0); DIPA, DIPB : in std_logic_vector(3 downto 0); ADDRA, ADDRB : in std_logic_vector(8 downto 0); WEA, WEB : in std_logic; ENA, ENB : in std_logic; SSRA, SSRB : in std_logic; CLKA, CLKB : in std_logic; DOA, DOB : out std_logic_vector(31 downto 0); DOPA, DOPB : out std_logic_vector(3 downto 0)); end component; constant frame_length : std_logic_vector(6 downto 0) := conv_std_logic_vector(FrameLength,7); signal bc_counter : std_logic_vector(11 downto 0); constant number_of_blockrams : integer := (data_in'length+35)/36; constant high : std_logic := '1'; constant low : std_logic := '0'; signal inputs, outputs_temp, outputs : std_logic_vector((number_of_blockrams*36-1) downto 0); signal address1, address2, address_d1, address_d2 : std_logic_vector(8 downto 0); signal rreq, full_int, read_next, read_next_d, dav_down : std_logic; type shift_reg_type is array (2 downto 0) of std_logic_vector((data_in'length/2-1) downto 0); signal shift_reg : shift_reg_type; signal parity, fc_mask : std_logic_vector(data_out'high downto 0); signal fc : std_logic; signal frame_counter : std_logic_vector(frame_length'high downto 0); begin -- daq_design BC_REG: process (clk, reset) begin -- process BC_REG if reset = '0' then -- asynchronous reset (active low) bc_counter <= (others => '0'); elsif clk'event and clk = '1' then -- rising clock edge bc_counter <= bc_counter + conv_std_logic_vector(1,bc_counter'length); if bc_reset = '1' then bc_counter <= counter_load; elsif bc_counter = orbit_counter then bc_counter <= (others => '0'); end if; end if; end process BC_REG; full_int <= '1' when address_d1 = (address_d2 - conv_std_logic_vector(1,address_d2'length)) else '0'; full <= full_int; rreq <= l1a and (not full_int); ADDR: process (clk, reset) begin -- process ADDR if reset = '0' then -- asynchronous reset (active low) address1 <= (others => '0'); address_d1 <= (others => '0'); address_d2 <= (others => '0'); elsif clk'event and clk = '1' then -- rising clock edge address1 <= address1 + conv_std_logic_vector(1,address1'length); if rreq = '1' then address_d1 <= address_d1 + conv_std_logic_vector(1,address_d1'length); end if; if read_next = '1' then address_d2 <= address_d2 + conv_std_logic_vector(1,address_d2'length); end if; end if; end process ADDR; address2 <= address1 - delay; FIFO: for i in 0 to (number_of_blockrams-1) generate DELAY_RAM: RAMB16_S36_S36 port map(inputs(((i+1)*36-5) downto (i*36)),inputs(((i+1)*36-5) downto (i*36)), inputs(((i+1)*36-1) downto ((i+1)*36-4)),inputs(((i+1)*36-1) downto ((i+1)*36-4)), address1,address2,high,low,high,high,low,low,clk,clk, open,outputs_temp(((i+1)*36-5) downto (i*36)),open,outputs_temp(((i+1)*36-1) downto ((i+1)*36-4))); DERND_RAM: RAMB16_S36_S36 port map(outputs_temp(((i+1)*36-5) downto (i*36)),outputs_temp(((i+1)*36-5) downto (i*36)), outputs_temp(((i+1)*36-1) downto ((i+1)*36-4)),outputs_temp(((i+1)*36-1) downto ((i+1)*36-4)), address_d1,address_d2,rreq,low,high,high,low,low,clk,clk, open,outputs(((i+1)*36-5) downto (i*36)),open,outputs(((i+1)*36-1) downto ((i+1)*36-4))); end generate FIFO; inputs(data_in'high downto 0) <= data_in; SH_REG: process (clk, reset) begin -- process SH_REG if reset = '0' then -- asynchronous reset (active low) shift_reg <= (others => (others => '0')); parity <= (others => '1'); elsif clk'event and clk = '1' then -- rising clock edge for i in 0 to 2 loop shift_reg(i) <= '0' & shift_reg(i)((data_in'length/2-1) downto 1); end loop; -- i parity <= parity xor ((shift_reg(1)(0) & shift_reg(0)(0) & shift_reg(2)(0) & shift_reg(1)(0) & shift_reg(0)(0)) and fc_mask); if read_next_d = '1' then shift_reg(1 downto 0) <= outputs((data_in'length-1) downto (data_in'length/2)) & outputs((data_in'length/2-1) downto 0); shift_reg(2)((bc_counter'length-1) downto 0) <= bc_counter; parity <= (others => '1'); end if; end if; end process SH_REG; FC_MASK_REG: process (clk, reset) variable counter : integer; begin -- process FC_MASK_REG if reset = '0' then -- asynchronous reset (active low) counter := 0; fc <= '0'; elsif clk'event and clk = '1' then -- rising clock edge counter := counter + 1; if counter = 11 then counter := 0; end if; if counter = 0 then fc <= not shift_reg(0)(10) and fcal_mode(0); end if; if read_next_d = '1' then counter := 0; fc <= not outputs(9) and fcal_mode(0); end if; end if; end process FC_MASK_REG; fc_mask <= fcal_mode(1) & fc & '1' & not fcal_mode(1) & not fc; DOUT: process (clk, reset) begin -- process DOUT if reset = '0' then -- asynchronous reset (active low) data_out <= (others => '0'); frame_counter <= (others => '0'); read_next_d <= '0'; dav_down <= '0'; dav <= '0'; elsif clk'event and clk = '1' then -- rising clock edge data_out <= (shift_reg(1)(0) & shift_reg(0)(0) & shift_reg(2)(0) & shift_reg(1)(0) & shift_reg(0)(0)) and fc_mask; read_next_d <= read_next; dav_down <= '0'; if conv_integer(frame_counter) /= 0 then frame_counter <= frame_counter - conv_std_logic_vector(1,frame_counter'length); elsif (address_d1 /= address_d2) then frame_counter <= frame_length + dav_space; end if; if frame_counter = frame_length + dav_space - conv_std_logic_vector(1,frame_counter'length) then dav <= '1'; elsif frame_counter = dav_space then data_out <= parity; dav_down <= '1'; end if; if dav_down = '1' then dav <= '0'; end if; end if; end process DOUT; read_next <= '1' when (conv_integer(frame_counter) = 0) and (read_next_d = '0') and (address_d1 /= address_d2) else '0'; end daq_design; ------------------------------------------------------------------------------- -- ---------------------------------------------------------------------------- -- Input/Output spy ------------------------------------------------------------------------------- ------------------------------------------------------------------------------- library ieee; use ieee.std_logic_1164.all; use ieee.std_logic_signed.all; use ieee.std_logic_arith.conv_std_logic_vector; library unisim; use unisim.vcomponents.all; entity inout_spymem is generic ( data_width : integer := 10; -- Output width. input_length : integer := 213); port ( data_in : in std_logic_vector((input_length-1) downto 0); data_out : out std_logic_vector((data_width-1) downto 0); reset_address : in std_logic; next_value : in std_logic; start_recording : in std_logic; recording : in std_logic; clk : in std_logic); end inout_spymem; architecture inout_spymem_design of inout_spymem is component RAMB16_S36_S36 port ( DIA, DIB : in std_logic_vector(31 downto 0); DIPA, DIPB : in std_logic_vector(3 downto 0); ADDRA, ADDRB : in std_logic_vector(8 downto 0); WEA, WEB : in std_logic; ENA, ENB : in std_logic; SSRA, SSRB : in std_logic; CLKA, CLKB : in std_logic; DOA, DOB : out std_logic_vector(31 downto 0); DOPA, DOPB : out std_logic_vector(3 downto 0)); end component; constant blockRAM_width : integer := 72; constant number_of_blockrams : integer := (input_length+blockRAM_width-1)/blockRAM_width; signal inputs : std_logic_vector((number_of_blockrams*blockRAM_width-1) downto 0); signal outputs : std_logic_vector((number_of_blockrams*blockRAM_width+data_width-1) downto 0); signal address : std_logic_vector(7 downto 0); signal address_2, address_a, address_b : std_logic_vector(address'length downto 0); signal select_p : std_logic_vector(((input_length+data_width-1)/data_width-1) downto 0); signal wr, high, low : std_logic; signal rec_counter : std_logic_vector(6 downto 0); begin -- inout_spymem_design high <= '1'; low <= '0'; inputs(data_in'high downto 0) <= data_in; address_2 <= (address & next_value) + (conv_std_logic_vector(0,address'length) & select_p(select_p'high)); address_a <= '0' & address_2(address_2'high downto 1); address_b <= '1' & address_2(address_2'high downto 1); RAMS: for i in (number_of_blockrams-1) downto 0 generate RAM: RAMB16_S36_S36 port map(inputs(((i+1)*blockRAM_width-blockRAM_width/2-1-4) downto (i*blockRAM_width)), inputs(((i+1)*blockRAM_width-1-4) downto ((i+1)*blockRAM_width-blockRAM_width/2)), inputs(((i+1)*blockRAM_width-blockRAM_width/2-1) downto ((i+1)*blockRAM_width-blockRAM_width/2-1-3)), inputs(((i+1)*blockRAM_width-1) downto ((i+1)*blockRAM_width-1-3)), address_a,address_b,wr,wr,high,high,low,low,clk,clk, outputs(((i+1)*blockRAM_width-blockRAM_width/2-1-4) downto (i*blockRAM_width)), outputs(((i+1)*blockRAM_width-1-4) downto ((i+1)*blockRAM_width-blockRAM_width/2)), outputs(((i+1)*blockRAM_width-blockRAM_width/2-1) downto ((i+1)*blockRAM_width-blockRAM_width/2-1-3)), outputs(((i+1)*blockRAM_width-1) downto ((i+1)*blockRAM_width-1-3))); end generate RAMS; MUX: for i in select_p'high downto 0 generate data_out <= outputs(((i+1)*data_width-1) downto (i*data_width)) when select_p(i) = '1' else (others => 'Z'); end generate MUX; outputs(outputs'high downto inputs'length) <= (others => '0'); SEL1: process (clk, reset_address) begin -- process SEL1 if reset_address = '0' then -- asynchronous reset (active low) select_p <= (others => '0'); select_p(0) <= '1'; elsif clk'event and clk = '1' then -- rising clock edge if next_value = '1' then select_p <= select_p((select_p'high-1) downto 0) & select_p(select_p'high); end if; end if; end process SEL1; ADDR: process (clk, reset_address) begin -- process ADDR if reset_address = '0' then -- asynchronous reset (active low) address <= (others => '0'); elsif clk'event and clk = '1' then -- rising clock edge if (address /= (-1) and (wr = '1' or (next_value = '1' and select_p(select_p'high) = '1'))) or conv_integer(rec_counter) /= 0 then address <= address + conv_std_logic_vector(1,address'length); end if; end if; end process ADDR; REC: process (clk, start_recording, reset_address) begin -- process REC if reset_address = '0' then -- asynchronous reset (active low) wr <= '0'; rec_counter <= (others => '0'); elsif start_recording = '1' then wr <= '1'; elsif clk'event and clk = '1' then -- rising clock edge if address = (-1) then wr <= '0'; end if; if conv_integer(rec_counter) /= 0 then rec_counter <= rec_counter - conv_std_logic_vector(1,rec_counter'length); wr <= '1'; end if; if conv_integer(rec_counter) = 1 then wr <= '0'; end if; if recording = '1' then rec_counter <= (others => '1'); end if; end if; end process REC; end inout_spymem_design; ------------------------------------------------------------------------------- -- ---------------------------------------------------------------------------- -- ROC spy ------------------------------------------------------------------------------- ------------------------------------------------------------------------------- library ieee; use ieee.std_logic_1164.all; use ieee.std_logic_signed.all; use ieee.std_logic_arith.conv_std_logic_vector; library unisim; use unisim.vcomponents.all; entity ROC_spymem is generic ( data_width : integer := 10; -- Output width. input_length : integer := 17); port ( data_in : in std_logic_vector((input_length-1) downto 0); data_out : out std_logic_vector((data_width-1) downto 0); reset_address : in std_logic; next_value : in std_logic; start_recording : in std_logic; recording : in std_logic; dav : in std_logic; events_to_read : in std_logic_vector(7 downto 0); clk : in std_logic); end ROC_spymem; architecture ROC_spymem_design of ROC_spymem is component RAMB16_S2 port ( DI : in std_logic_vector(1 downto 0); ADDR : in std_logic_vector(12 downto 0); WE : in std_logic; EN : in std_logic; SSR : in std_logic; CLK : in std_logic; DO : out std_logic_vector(1 downto 0)); end component; constant blockRAM_width : integer := 2; constant number_of_blockrams : integer := (input_length+blockRAM_width-1)/blockRAM_width; signal inputs : std_logic_vector((number_of_blockrams*blockRAM_width-1) downto 0); signal outputs : std_logic_vector((number_of_blockrams*blockRAM_width+data_width-1) downto 0); signal address : std_logic_vector(12 downto 0); signal address_2 : std_logic_vector(address'length downto 0); signal select_p : std_logic_vector(((input_length+data_width-1)/data_width-1) downto 0); signal wr, high, low : std_logic; signal rec_counter : std_logic_vector(6 downto 0); signal events2read : std_logic_vector(events_to_read'high downto 0); signal wr2, dav_temp : std_logic; begin -- ROC_spymem_design high <= '1'; low <= '0'; inputs(data_in'high downto 0) <= data_in; address_2 <= (address & next_value) + (conv_std_logic_vector(0,address'length) & select_p(select_p'high)); RAMS: for i in (number_of_blockrams-1) downto 0 generate RAM: RAMB16_S2 port map(inputs(((i+1)*blockRAM_width-1) downto (i*blockRAM_width)), address_2(address_2'high downto 1),wr2,high,low,clk, outputs(((i+1)*blockRAM_width-1) downto (i*blockRAM_width))); end generate RAMS; MUX: for i in select_p'high downto 0 generate data_out <= outputs(((i+1)*data_width-1) downto (i*data_width)) when select_p(i) = '1' else (others => 'Z'); end generate MUX; outputs(outputs'high downto inputs'length) <= (others => '0'); SEL1: process (clk, reset_address) begin -- process SEL1 if reset_address = '0' then -- asynchronous reset (active low) select_p <= (others => '0'); select_p(0) <= '1'; elsif clk'event and clk = '1' then -- rising clock edge if next_value = '1' and select_p'length > 1 then select_p <= select_p((select_p'high-1) downto 0) & select_p(select_p'high); end if; end if; end process SEL1; ADDR: process (clk, reset_address) begin -- process ADDR if reset_address = '0' then -- asynchronous reset (active low) address <= (others => '0'); elsif clk'event and clk = '1' then -- rising clock edge if (address /= (-1) and (wr2 = '1' or (next_value = '1' and select_p(select_p'high) = '1'))) or wr2 = '1' then address <= address + conv_std_logic_vector(1,address'length); end if; end if; end process ADDR; REC: process (clk, start_recording, reset_address) begin -- process REC if reset_address = '0' then -- asynchronous reset (active low) wr <= '0'; rec_counter <= (others => '0'); elsif start_recording = '1' then rec_counter <= conv_std_logic_vector(2,rec_counter'length); elsif clk'event and clk = '1' then -- rising clock edge if conv_integer(rec_counter) /= 0 then rec_counter <= rec_counter - conv_std_logic_vector(1,rec_counter'length); wr <= '1'; end if; if conv_integer(rec_counter) = 1 then wr <= '0'; end if; if recording = '1' then rec_counter <= (others => '1'); end if; end if; end process REC; E2R: process (clk, reset_address) begin -- process E2R if reset_address = '0' then -- asynchronous reset (active low) events2read <= (others => '0'); dav_temp <= '0'; elsif clk'event and clk = '1' then -- rising clock edge dav_temp <= dav; if wr = '1' then events2read <= events_to_read; elsif conv_integer(events2read) /= 0 and dav_temp = '1' and dav = '0' then events2read <= events2read - conv_std_logic_vector(1,events2read'length); end if; end if; end process E2R; WR_2: process (clk, dav, events2read, reset_address) begin -- process WR_2 if reset_address = '0' then -- asynchronous reset (active low) wr2 <= '0'; elsif dav = '1' and conv_integer(events2read) /= 0 then wr2 <= '1'; elsif clk'event and clk = '1' then -- rising clock edge if dav = '0' and dav_temp = '0' then wr2 <= '0'; end if; end if; end process WR_2; end ROC_spymem_design; ------------------------------------------------------------------------------- ------------------------------------------------------------------------------- -- Elastic-Buffer ------------------------------------------------------------------------------- ------------------------------------------------------------------------------- library ieee; use ieee.std_logic_1164.all; use ieee.std_logic_unsigned.all; use ieee.std_logic_arith.conv_std_logic_vector; library unisim; use unisim.vcomponents.all; entity elastic_buffer is port ( ROC_data_in : in std_logic_vector(5 downto 0); ROC_data_out : out std_logic_vector(5 downto 0); clk_int, clk_ext, reset : in std_logic); end elastic_buffer; architecture elastic_buffer_design of elastic_buffer is component RAMB16_S9_S9 port ( DIA, DIB : in std_logic_vector(7 downto 0); DIPA, DIPB : in std_logic_vector(0 downto 0); ADDRA, ADDRB : in std_logic_vector(10 downto 0); WEA, WEB : in std_logic; ENA, ENB : in std_logic; SSRA, SSRB : in std_logic; CLKA, CLKB : in std_logic; DOA, DOB : out std_logic_vector(7 downto 0); DOPA, DOPB : out std_logic_vector(0 downto 0)); end component; signal data_out : std_logic_vector(ROC_data_out'high downto 0); signal addr_int, addr_ext : std_logic_vector(10 downto 0); signal start, temp_ext : std_logic; signal count_ext, temp_int, start_tmp : std_logic_vector(3 downto 0); signal roc_data_in_w, data_out_w : std_logic_vector(7 downto 0); constant high : std_logic := '1'; constant low : std_logic_vector(0 downto 0) := (others => '0'); begin -- elastic_buffer_design RAM1: RAMB16_S9_S9 port map(ROC_data_in_w,ROC_data_in_w,low,low,addr_int,addr_ext,high,low(0),high,high,low(0),low(0),clk_int,clk_ext,open,data_out_w,open,open); roc_data_in_w(ROC_data_in'high downto 0) <= ROC_data_in; roc_data_in_w(roc_data_in_w'high downto ROC_data_in'length) <= (others => '0'); data_out <= data_out_w(data_out'high downto 0); INT_S: process (clk_int, reset) begin -- process INT_S if reset = '0' then -- asynchronous reset (active low) addr_int <= (others => '0'); temp_int <= (others => '0'); start <= '0'; elsif clk_int'event and clk_int = '1' then -- rising clock edge temp_int <= temp_int((temp_int'high-1) downto 0) & ROC_data_in(ROC_data_in'high); if conv_integer(temp_int) /= 0 or ROC_data_in(ROC_data_in'high) = '1' then addr_int <= addr_int + conv_std_logic_vector(1,addr_int'length); end if; start <= '0'; if temp_int(1) = '1' and ROC_data_in(ROC_data_in'high) = '0' then start <= '1'; end if; end if; end process INT_S; EXT_S: process (clk_ext, reset) variable count_tmp : std_logic_vector(count_ext'high downto 0); begin -- process EXT_S if reset = '0' then -- asynchronous reset (active low) addr_ext <= (others => '0'); count_ext <= (others => '0'); temp_ext <= '0'; start_tmp <= (others => '0'); ROC_data_out <= (others => '0'); elsif clk_ext'event and clk_ext = '1' then -- rising clock edge temp_ext <= data_out(data_out'high); start_tmp <= start_tmp((start_tmp'high-1) downto 0) & start; ROC_data_out <= (others => '0'); count_tmp := count_ext; if start_tmp(0) = '1' and start_tmp(1) = '0' then count_tmp := count_tmp + conv_std_logic_vector(1,count_tmp'length); end if; if data_out(data_out'high) = '0' and temp_ext = '1' then count_tmp := count_tmp - conv_std_logic_vector(1,count_tmp'length); end if; count_ext <= count_tmp; if conv_integer(count_ext) /= 0 then ROC_data_out <= data_out; addr_ext <= addr_ext + conv_std_logic_vector(1,addr_ext'length); end if; end if; end process EXT_S; end elastic_buffer_design; ------------------------------------------------------------------------------- -- ---------------------------------------------------------------------------- -- G-Link controller ------------------------------------------------------------------------------- ------------------------------------------------------------------------------- library ieee; use ieee.std_logic_1164.all; entity g_link is port ( ROC_data : in std_logic_vector(4 downto 0); ROC_dav : in std_logic; glink : inout std_logic_vector(22 downto 0); locked : out std_logic; glink_clk : out std_logic; clk, reset : in std_logic); end g_link; architecture g_link_design of g_link is begin -- g_link_design GLINK_REG: process (clk, reset) begin -- process GLINK_REG if reset = '0' then -- asynchronous reset (active low) glink(15 downto 0) <= (others => '0'); glink(22) <= '1'; locked <= '0'; elsif clk'event and clk = '0' then -- rising clock edge glink(ROC_data'high downto 0) <= ROC_data; glink(22) <= ROC_dav; locked <= glink(16); end if; end process GLINK_REG; glink(21 downto 17) <= reset & "1001"; -- RST & M20SEL & MDFSEL & LOOPEN & DIV0 glink_clk <= clk; end g_link_design; ------------------------------------------------------------------------------- -- ---------------------------------------------------------------------------- -- Control ------------------------------------------------------------------------------- ------------------------------------------------------------------------------- library ieee; use ieee.std_logic_1164.all; use ieee.std_logic_unsigned.all; use ieee.std_logic_arith.conv_std_logic_vector; library work; use work.jet_fpga_pkg.all; entity control is port ( -- VME vme_in : in std_logic_vector(11 downto 0); vme_out : out std_logic_vector(11 downto 0); vme_address : in std_logic_vector(7 downto 0); vme_wr : in std_logic; vme_done : in std_logic; -- Debug debug_data_in : in std_logic_vector(11 downto 0); debug_data_out : out std_logic_vector(11 downto 0); debug_address : in std_logic_vector(7 downto 0); debug_write : in std_logic; debug_read : in std_logic; rnd_data : in std_logic_Vector(15 downto 0); rnd_seed : out std_logic_vector(15 downto 0); rnd_inputs : out std_logic; -- TTC l1a : in std_logic; ttc_data : in std_logic_vector(11 downto 0); ttc_bc_reset : in std_logic; -- Jet algorithm jet_thresholds : out std_logic_vector((10*8*2-1) downto 0); jet_cluster_sizes : out std_logic_vector((2*8*2-1) downto 0); fcal_mode : out std_logic_vector(1 downto 0); mask_eta : out std_logic_vector(2 downto 0); input_mask : out std_logic_vector(9 downto 0); -- DAQ daq_delay : out std_logic_vector(8 downto 0); daq_orbit_counter : out std_logic_vector(11 downto 0); daq_counter_load : out std_logic_vector(11 downto 0); daq_bc_reset : out std_logic; daq_l1a : out std_logic; daq_dav_space : out std_logic_vector(6 downto 0); -- G-Link glink_locked : in std_logic; -- Input spy input_spy_data : in std_logic_vector(9 downto 0); input_spy_reset_address : out std_logic; input_spy_next_value : out std_logic; input_spy_start_recording : out std_logic; input_spy_recording : out std_logic; -- Output spy output_spy_data : in std_logic_vector(11 downto 0); output_spy_reset_address : out std_logic; output_spy_next_value : out std_logic; output_spy_start_recording : out std_logic; output_spy_recording : out std_logic; -- ROC spy ROC_spy_data : in std_logic_vector(9 downto 0); ROC_spy_reset_address : out std_logic; ROC_spy_next_value : out std_logic; ROC_spy_start_recording : out std_logic; ROC_spy_recording : out std_logic; ROC_spy_events_to_read : out std_logic_Vector(7 downto 0); -- Clock and reset reset_request : out std_logic; locked_des1, locked_des2 : in std_logic; d1_phs_in : in std_logic_vector(1 downto 0); d1_phs_out : out std_logic_vector(1 downto 0); clk, reset : in std_logic); end control; architecture control_design of control is signal regs : control_register_type; signal ttc_data_d : std_logic_vector(ttc_data'high downto 0); signal start_spy : std_logic; signal fcal_mode_w : std_logic_vector(fcal_mode'high downto 0); signal d1_phs_out_w : std_logic_Vector(d1_phs_out'high downto 0); begin -- control_design REGISTERS: process (clk, reset) begin -- process REGISTERS if reset = '0' then -- asynchronous reset (active low) regs <= default_register_values; vme_out <= (others => 'Z'); ttc_data_d <= (others => '0'); start_spy <= '0'; elsif clk'event and clk = '1' then -- rising clock edge vme_out <= (others => '0'); ttc_data_d <= ttc_data; regs(a_control_reg) <= (others => '0'); regs(a_status_reg)(9 downto 0) <= d1_phs_out_w & fcal_mode_w & (glink_locked and regs(a_status_reg)(5)) & glink_locked & (locked_des2 and regs(a_status_reg)(3)) & locked_des2 & (locked_des1 and regs(a_status_reg)(1)) & locked_des1; if d1_phs_out_w /= d1_phs_in then regs(a_status_reg)(10) <= '1'; end if; regs(a_reset_input_spy_address) <= (others => '0'); regs(a_reset_output_spy_address) <= (others => '0'); regs(a_reset_roc_spy_address) <= (others => '0'); for i in 0 to (number_of_registers-1) loop if conv_integer(vme_address) = i then vme_out <= regs(i); if i > 0 and vme_wr = '1' then regs(i) <= vme_in; end if; end if; ----------------------------------------------------------------------- -- Debug (Begin) ----------------------------------------------------------------------- -- read_next_value for spy-memories are modified too. -- Random numbers are handled too. ----------------------------------------------------------------------- if conv_integer(debug_address) = i then debug_data_out <= regs(i); if i > 0 and debug_write = '1' then regs(i) <= debug_data_in; end if; end if; if vme_done ='1' then regs(a_access_counter) <= regs(a_access_counter) + conv_std_logic_vector(1,regs(a_access_counter)'length); end if; regs(a_random_data) <= rnd_data(regs(a_random_data)'high downto 0); ----------------------------------------------------------------------- -- Debug (End) ----------------------------------------------------------------------- end loop; -- i start_spy <= regs(a_control_reg)(1); if (l1a = '1') and (regs(a_spy_mode)(6) = '1') then start_spy <= '1'; end if; for i in 0 to 3 loop if (regs(a_ttc_spy_instructions + i) = ttc_data) and (conv_integer(ttc_data) /= 0) then start_spy <= '1'; end if; end loop; -- i if start_spy = '1' then for i in 0 to 2 loop regs(a_spy_mode)(i*2+1) <= '0'; end loop; -- i end if; regs(a_input_spy_data)(input_spy_data'high downto 0) <= input_spy_data; regs(a_output_spy_data)(output_spy_data'high downto 0) <= output_spy_data; regs(a_roc_spy_data)(roc_spy_data'high downto 0) <= roc_spy_data; if (ttc_data /= ttc_data_d) and (conv_integer(ttc_data) /= 0) then regs(a_ttc_rec to (a_ttc_rec+1)) <= ttc_data & regs(a_ttc_rec); end if; end if; end process REGISTERS; JET_REGS: for i in 0 to 15 generate jet_thresholds(((i+1)*10-1) downto (i*10)) <= regs(i+a_jet_thresholds)(9 downto 0); jet_cluster_sizes(((i+1)*2-1) downto (i*2)) <= regs(i+a_jet_thresholds)(11 downto 10) when regs(i+a_jet_thresholds)(9 downto 0) /= (-1) else (others => '0'); end generate JET_REGS; fcal_mode_w <= regs(a_input_settings)((mask_eta'length+fcal_mode'high) downto mask_eta'length); fcal_mode <= fcal_mode_w; mask_eta <= regs(a_input_settings)(mask_eta'high downto 0); input_mask <= regs(a_input_mask)(input_mask'high downto 0); rnd_inputs <= regs(a_input_settings)(mask_eta'length+fcal_mode'length+(d1_phs_out'length+1)); d1_phs_out_w <= regs(a_input_settings)(mask_eta'length+fcal_mode'length+d1_phs_out'high downto mask_eta'length+fcal_mode'length) when regs(a_input_settings)(mask_eta'length+fcal_mode'length+d1_phs_out'length) = '1' else d1_phs_in; d1_phs_out <= d1_phs_out_w; daq_delay <= regs(a_daq_delay)(daq_delay'high downto 0); daq_orbit_counter <= regs(a_daq_orbit_counter_max)(daq_orbit_counter'high downto 0); daq_counter_load <= regs(a_daq_orbit_counter_load)(daq_counter_load'high downto 0); daq_bc_reset <= ttc_bc_reset; daq_l1a <= l1a; daq_dav_space <= regs(a_daq_dav_space)(daq_dav_space'high downto 0); input_spy_reset_address <= '0' when (regs(a_control_reg)(2)='1' or conv_integer(regs(a_reset_input_spy_address))/=0) else '1'; input_spy_next_value <= '1' when ((a_input_spy_data = conv_integer(vme_address)) and (vme_done = '1')) or ((a_input_spy_data = conv_integer(debug_address)) and (debug_read = '1')) else '0'; input_spy_start_recording <= regs(a_spy_mode)(1) and not regs(a_spy_mode)(0) and start_spy; input_spy_recording <= regs(a_spy_mode)(1) and regs(a_spy_mode)(0); output_spy_reset_address <= '0' when (regs(a_control_reg)(2)='1' or conv_integer(regs(a_reset_output_spy_address))/=0) else '1'; output_spy_next_value <= '1' when ((a_output_spy_data = conv_integer(vme_address)) and (vme_done ='1')) or ((a_output_spy_data = conv_integer(debug_address)) and (debug_read = '1')) else '0'; output_spy_start_recording <= regs(a_spy_mode)(3) and not regs(a_spy_mode)(2) and start_spy; output_spy_recording <= regs(a_spy_mode)(3) and regs(a_spy_mode)(2); ROC_spy_reset_address <= '0' when (regs(a_control_reg)(2)='1' or conv_integer(regs(a_reset_roc_spy_address))/=0) else '1'; ROC_spy_next_value <= '1' when ((a_roc_spy_data = conv_integer(vme_address)) and (vme_done = '1')) or ((a_roc_spy_data = conv_integer(debug_address)) and (debug_read = '1')) else '0'; ROC_spy_start_recording <= regs(a_spy_mode)(5) and not regs(a_spy_mode)(4) and start_spy; ROC_spy_recording <= regs(a_spy_mode)(5) and regs(a_spy_mode)(4); ROC_spy_events_to_read <= regs(a_roc_spy_events_to_read)(roc_spy_events_to_read'high downto 0); reset_request <= regs(a_control_reg)(0); rnd_seed <= regs(a_random_seed)(3 downto 0) & regs(a_random_seed); end control_design; ------------------------------------------------------------------------------- -- ---------------------------------------------------------------------------- -- Clock Phase Detection ------------------------------------------------------------------------------- -- Grey-encoded output -- Indicates the phase of clk_des1 relative to clk_des2. (0-3) ------------------------------------------------------------------------------- ------------------------------------------------------------------------------- library ieee; use ieee.std_logic_1164.all; entity cpd is port ( phase : out std_logic_vector(1 downto 0); clk0_d1 : in std_logic; clk0_d2, clk90_d2 : in std_logic; clk180_d2, clk270_d2 : in std_logic); end cpd; architecture cpd_design of cpd is signal pulse : std_logic := '0'; signal phs0, phs : std_logic_vector(3 downto 0); begin -- cpd_design P1: process (clk0_d1) begin -- process P1 if clk0_d1'event and clk0_d1 = '1' then -- rising clock edge phs <= phs0; if phs = "0000" or phs = "1111" then phase <= "10"; end if; if phs = "0001" or phs = "1110" then phase <= "00"; end if; if phs = "0011" or phs = "1100" then phase <= "01"; end if; if phs = "0111" or phs = "1000" then phase <= "11"; end if; end if; end process P1; C0: process (clk0_d2) begin -- process C0 if clk0_d2'event and clk0_d2 = '1' then -- rising clock edge phs0(0) <= pulse; end if; end process C0; C90: process (clk90_d2) begin -- process C90 if clk90_d2'event and clk90_d2 = '1' then -- rising clock edge phs0(1) <= pulse; end if; end process C90; C180: process (clk180_d2) begin -- process C180 if clk180_d2'event and clk180_d2 = '1' then -- rising clock edge phs0(2) <= pulse; end if; end process C180; C270: process (clk270_d2) begin -- process C270 if clk270_d2'event and clk270_d2 = '1' then -- rising clock edge pulse <= not pulse; phs0(3) <= pulse; end if; end process C270; end cpd_design; ------------------------------------------------------------------------------- -- ---------------------------------------------------------------------------- -- Random ------------------------------------------------------------------------------- ------------------------------------------------------------------------------- library ieee; use ieee.std_logic_1164.all; entity random is port ( data_out : out std_logic_vector(15 downto 0); seed : in std_logic_vector(15 downto 0); clk, reset : in std_logic); end random; architecture random_design of random is type stream_type is array (15 downto 0) of std_logic_vector(15 downto 0); signal stream : stream_type; signal xor_ring : std_logic_vector(22 downto 0); begin -- random_design S1: process (clk, reset) variable temp : std_logic; begin -- process S1 if reset = '0' then -- asynchronous reset (active low) xor_ring <= "10110111010001100111110"; stream(15 downto 12) <= ("0010110101011001", "1001101101010100", "1101010101110110", "0011000111000111"); stream(11 downto 8) <= ("1001111111110010", "0110100000110000", "0111001110101001", "1010001000101010"); stream(7 downto 4) <= ("0010100111100000", "0100110010010111", "1100000101101100", "1101101010100110"); stream(3 downto 0) <= ("0100000100100011", "1011100101111000", "0110111100101001", "0101010100110001"); elsif clk'event and clk = '1' then -- rising clock edge xor_ring <= xor_ring(0) & xor_ring(xor_ring'high downto 1); stream(14 downto 0) <= stream(15 downto 1); for i in 0 to 15 loop temp := xor_ring(i) xor stream(0)(i) xor seed(i); for j in 1 to 4 loop temp := temp xor stream((i+5+j*3) rem 16)((i+j*3) rem 16); end loop; -- j stream(15)(i) <= temp; end loop; -- i end if; end process S1; data_out <= stream(15); end random_design; ------------------------------------------------------------------------------- -- ---------------------------------------------------------------------------- -- VME port - Written by Uli. -- Modified by Attila. (vme_done + remove testreg) -- Modified by Attila. (Separate internal and external clocks) ------------------------------------------------------------------------------- ------------------------------------------------------------------------------- LIBRARY ieee ; USE ieee.std_logic_1164.all; use IEEE.STD_LOGIC_ARITH.ALL; USE ieee.std_logic_unsigned.all; USE ieee.numeric_std.all; ENTITY vme_port IS port ( clk0_d1 : in std_logic; clk0_d2 : in std_logic; clk180_d2 : in std_logic; d1_phs : in std_logic_vector(1 downto 0); -- connect to sum/controller v_start : in std_logic; v_write : in std_logic; v_inport : in std_logic_vector (3 downto 0); v_outport : out std_logic_vector (3 downto 0); v_readstart : out std_logic; -- connect to internal registers ADDR_IN : out std_logic_vector (8 downto 0); data_write : out std_logic_vector (11 downto 0); data_read : in std_logic_vector (11 downto 0); write_en : out std_logic; vme_done : out std_logic); END vme_port ; -- hds interface_end ARCHITECTURE vme_port OF vme_port IS signal WRITEport_int : std_logic_vector(3 downto 0); signal start_int, write_int : std_logic; signal ADDR_IN_int : std_logic_vector(8 downto 0); signal data_write_int : std_logic_vector(11 downto 0); signal write_en_int, vme_done_int, write_en_tmp : std_logic; signal v_start_p, v_start_n, v_write_p, v_write_n : std_logic; signal v_inport_p, v_inport_n : std_logic_vector(v_inport'high downto 0); BEGIN process(CLK0_d1) variable wcnt,ioffset: integer range 0 to 8; variable addr_tmp: std_logic_vector(7 downto 0); variable write_tmp,read_tmp: std_logic_vector(11 downto 0); variable read_tmp1,addr_low_tmp: std_logic_vector(3 downto 0); variable vme_done_tmp,rs_tmp: std_logic; begin if rising_edge(CLK0_d1) then --IFDs WRITEport_int <= v_inport_n; start_int <= v_start_n; write_int <= v_write_n; if d1_phs = "01" or d1_phs = "11" then WRITEport_int <= v_inport_p; start_int <= v_start_p; write_int <= v_write_p; end if; -- ioffset:=3; --read latency rs_tmp:='0'; write_en_tmp<='0'; vme_done_tmp:='0'; if start_int='1' then wcnt:=0; elsif wcnt/= 8 then wcnt:=wcnt+1; end if; read_tmp:=data_read; for i in 0 to 2 loop if i+2+ioffset=wcnt then read_tmp1:=read_tmp(4*i+3 downto 4*i); if i=0 then rs_tmp:='1'; end if; end if; end loop; -- keep addr_tmp at old value while updating to allow for proper vme_done timing if wcnt=0 then addr_low_tmp :=writeport_int; end if; if wcnt=1 then addr_tmp :=writeport_int & addr_low_tmp; end if; for i in 0 to 2 loop if i+2=wcnt then write_tmp(4*i+3 downto 4*i):=writeport_int; end if; end loop; -- if wcnt=0 then vme_done_tmp:='1'; end if; if wcnt=7 then vme_done_tmp:='1'; end if; -- Attila if wcnt=4 and write_int='1' then write_en_tmp<='1'; end if; ADDR_IN_int<=addr_tmp&"0"; -- address to registers data_write_int<=write_tmp; -- data write bus to registers write_en_int<=write_en_tmp; -- write strobe active for a single tick v_outport <=read_tmp1; -- 4 bit data to control chip vme_done_int<=vme_done_tmp; -- signals end of vme cycle. Asserted before *next* VME access. Use to increment address counters etc. v_readstart<=rs_tmp; -- start bit to control chip end if; end process; CLK0_int: process (clk0_d2) begin -- process CLK0_int if clk0_d2'event and clk0_d2 = '1' then -- rising clock edge -- internal signals ADDR_IN <= ADDR_IN_int; data_write <= data_write_int; write_en <= write_en_int; vme_done <= vme_done_int; -- external signals v_start_p <= v_start; v_write_p <= v_write; v_inport_p <= v_inport; end if; end process CLK0_int; CLK180_int: process (clk180_d2) begin -- process CLK180_int if clk180_d2'event and clk180_d2 = '1' then -- rising clock edge v_start_n <= v_start; v_write_n <= v_write; v_inport_n <= v_inport; end if; end process CLK180_int; END vme_port; ------------------------------------------------------------------------------- -- ---------------------------------------------------------------------------- -- Jet FPGA ------------------------------------------------------------------------------- ------------------------------------------------------------------------------- library ieee; use ieee.std_logic_1164.all; use ieee.std_logic_unsigned.all; library work; use work.jet_fpga_pkg.all; entity jet_fpga is port ( -- VME v_start : in std_logic; v_write : in std_logic; v_inport : in std_logic_vector (3 downto 0); v_outport : out std_logic_vector (3 downto 0); v_readstart : out std_logic; -- Debug debug_data_in : in std_logic_vector(11 downto 0); debug_data_out : out std_logic_vector(11 downto 0); debug_address : in std_logic_vector(7 downto 0); debug_write : in std_logic; debug_read : in std_logic; dbg_clk_40MHz : out std_logic; dbg_rst : out std_logic; -- TTC ttc_data : in std_logic_vector(5 downto 0); ttc_bc_reset : in std_logic; l1a : in std_logic; -- JET FIO : in std_logic_vector(165 downto 1); INPUT_R_JET : in std_logic_vector(59 downto 0); INPUT_S_JET : in std_logic_vector(59 downto 0); INPUT_T_JET : in std_logic_vector(59 downto 0); INPUT_U_JET : in std_logic_vector(59 downto 20); jet_jetmultiplicities_bp : out std_logic_vector((3*8) downto 0); jet_jetmultiplicities_sm : out std_logic_vector((3*8) downto 0); -- G-Link glink : inout std_logic_vector(22 downto 0); glink_clk_in : in std_logic; -- Clocks clk_des1, clk_des2 : in std_logic); end jet_fpga; architecture jet_fpga_design of jet_fpga is -- Clocks component clock_unit port ( clk_des1_in, clk_des2_in : in std_logic; clk0_d1, clk180_d1 : out std_logic; clk0_d2, clk90_d2, clk180_d2, clk270_d2 : out std_logic; locked_des1, locked_des2 : out std_logic); end component; signal clk0_d1, clk180_d1, clk0_d2, clk90_d2, clk180_d2, clk270_d2, locked_des1, locked_des2 : std_logic; -- Reset component reset_unit port ( reset_request : in std_logic; reset : out std_logic; clk : in std_logic); end component; signal reset_request, reset : std_logic; -- JET component jet generic ( ROIx : integer := 2; -- Number of ROIs in x direction. ROIy : integer := 4; -- Number of ROIs in y direction. input_width : integer := 10; -- Width of input data. threshold_nr : integer := 8; -- Number of thresholds. threshold_width : integer := 10; -- Width of threshold. multiplicity_width : integer := 3); -- Width of a single jetmultilpicity. port ( data_in : in std_logic_vector(((ROIx*2+3)*(ROIy*2+3)*input_width-1) downto 0); thresholds : in std_logic_vector((threshold_nr*2*threshold_width-1) downto 0); sizes : in std_logic_vector((threshold_nr*2*2-1) downto 0); fcal_mode : in std_logic_vector(1 downto 0); ROIs : out std_logic_vector(((threshold_nr+4)*ROIx*ROIy-1) downto 0); jetmultiplicities : out std_logic_vector((threshold_nr*multiplicity_width) downto 0); jetmultiplicities_fcal : out std_logic_vector((threshold_nr*multiplicity_width) downto 0); clk40, reset : in std_logic); end component; signal jet_inputs : std_logic_vector((7*11*5-1) downto 0); signal jet_inputs_dff, jet_inputs_dff2 : std_logic_vector((jet_inputs'length-1) downto 0); signal jet_inputs_ddr, jet_inputs_mask, jet_inputs_rnd : std_logic_vector((jet_inputs_dff'length*2-1) downto 0); signal jet_thresholds : std_logic_vector((16*10-1) downto 0); signal jet_cluster_sizes : std_logic_vector((16*2-1) downto 0); signal jet_jetmultiplicities, jet_jetmult_p, jet_jetmult_n, jet_jetmult_cc, jet_jetmult_fc : std_logic_vector((8*3) downto 0); signal jet_rois : std_logic_vector((8*12-1) downto 0); signal jet_rois_roc : std_logic_vector((8*11-1) downto 0); -- DAQ component daq generic ( data_width : integer := 16*2; FrameLength : integer := 16*1+1); port ( data_in : in std_logic_vector((data_width-1) downto 0); delay : in std_logic_vector(8 downto 0); -- frame_length : in std_logic_vector(6 downto 0); orbit_counter : in std_logic_vector(11 downto 0); counter_load : in std_logic_vector(11 downto 0); bc_reset : in std_logic; l1a : in std_logic; data_out : out std_logic_vector(4 downto 0); dav : out std_logic; dav_space : in std_logic_vector(6 downto 0); fcal_mode : in std_logic_vector(1 downto 0); full : out std_logic; clk, reset : in std_logic); end component; signal daq_delay : std_logic_vector(8 downto 0); signal daq_orbit_counter, daq_counter_load : std_logic_vector(11 downto 0); signal daq_l1a, daq_bc_reset : std_logic; signal daq_data_out : std_logic_vector(4 downto 0); signal daq_dav : std_logic; signal daq_dav_space : std_logic_vector(6 downto 0); -- Input and output spymem component inout_spymem generic ( data_width : integer := 10; -- Output width. input_length : integer := 213); port ( data_in : in std_logic_vector((input_length-1) downto 0); data_out : out std_logic_vector((data_width-1) downto 0); reset_address : in std_logic; next_value : in std_logic; start_recording : in std_logic; recording : in std_logic; clk : in std_logic); end component; signal input_spy : std_logic_vector((jet_inputs_ddr'length+jet_thresholds'length+jet_cluster_sizes'length) downto 0); signal output_spy : std_logic_vector((jet_rois'length+jet_jetmultiplicities'length) downto 0); signal input_spy_data : std_logic_vector(9 downto 0); signal output_spy_data : std_logic_vector(11 downto 0); signal input_spy_reset_address, output_spy_reset_address, input_spy_next_value, output_spy_next_value : std_logic; signal input_spy_start_recording, output_spy_start_recording, input_spy_recording, output_spy_recording : std_logic; -- ROC spymem component roc_spymem generic ( data_width : integer := 10; -- Output width. input_length : integer := 17); port ( data_in : in std_logic_vector((input_length-1) downto 0); data_out : out std_logic_vector((data_width-1) downto 0); reset_address : in std_logic; next_value : in std_logic; start_recording : in std_logic; recording : in std_logic; dav : in std_logic; events_to_read : in std_logic_vector(7 downto 0); clk : in std_logic); end component; signal roc_spy : std_logic_vector(daq_data_out'length downto 0); signal roc_spy_data : std_logic_vector(9 downto 0); signal roc_spy_reset_address, roc_spy_next_value, roc_spy_start_recording, roc_spy_recording : std_logic; signal roc_spy_events_to_read : std_logic_vector(7 downto 0); -- Elastic-Buffer component elastic_buffer port ( ROC_data_in : in std_logic_vector(5 downto 0); ROC_data_out : out std_logic_vector(5 downto 0); clk_int, clk_ext, reset : in std_logic); end component; signal ROC_data_out : std_logic_vector(5 downto 0); -- G-Link component g_link port ( ROC_data : in std_logic_vector(4 downto 0); ROC_dav : in std_logic; glink : inout std_logic_vector(22 downto 0); locked : out std_logic; glink_clk : out std_logic; clk, reset : in std_logic); end component; signal glink_locked, glink_clk_int : std_logic; -- Control component control port ( -- VME vme_in : in std_logic_vector(11 downto 0); vme_out : out std_logic_vector(11 downto 0); vme_address : in std_logic_vector(7 downto 0); vme_wr : in std_logic; vme_done : in std_logic; -- Debug debug_data_in : in std_logic_vector(11 downto 0); debug_data_out : out std_logic_vector(11 downto 0); debug_address : in std_logic_vector(7 downto 0); debug_write : in std_logic; debug_read : in std_logic; rnd_data : in std_logic_Vector(15 downto 0); rnd_seed : out std_logic_vector(15 downto 0); rnd_inputs : out std_logic; -- TTC l1a : in std_logic; ttc_data : in std_logic_vector(11 downto 0); ttc_bc_reset : in std_logic; -- Jet algorithm jet_thresholds : out std_logic_vector((10*8*2-1) downto 0); jet_cluster_sizes : out std_logic_vector((2*8*2-1) downto 0); fcal_mode : out std_logic_vector(1 downto 0); mask_eta : out std_logic_vector(2 downto 0); input_mask : out std_logic_vector(9 downto 0); -- DAQ daq_delay : out std_logic_vector(8 downto 0); daq_orbit_counter : out std_logic_vector(11 downto 0); daq_counter_load : out std_logic_vector(11 downto 0); daq_bc_reset : out std_logic; daq_l1a : out std_logic; daq_dav_space : out std_logic_vector(6 downto 0); -- G-Link glink_locked : in std_logic; -- Input spy input_spy_data : in std_logic_vector(9 downto 0); input_spy_reset_address : out std_logic; input_spy_next_value : out std_logic; input_spy_start_recording : out std_logic; input_spy_recording : out std_logic; -- Output spy output_spy_data : in std_logic_vector(11 downto 0); output_spy_reset_address : out std_logic; output_spy_next_value : out std_logic; output_spy_start_recording : out std_logic; output_spy_recording : out std_logic; -- ROC spy ROC_spy_data : in std_logic_vector(9 downto 0); ROC_spy_reset_address : out std_logic; ROC_spy_next_value : out std_logic; ROC_spy_start_recording : out std_logic; ROC_spy_recording : out std_logic; ROC_spy_events_to_read : out std_logic_vector(7 downto 0); -- Clock and reset reset_request : out std_logic; locked_des1, locked_des2 : in std_logic; d1_phs_in : in std_logic_vector(1 downto 0); d1_phs_out : out std_logic_vector(1 downto 0); clk, reset : in std_logic); end component; signal control_vme_in, control_vme_out : std_logic_vector(11 downto 0); signal control_vme_address : std_logic_vector(7 downto 0); signal control_vme_wr, control_vme_done : std_logic; signal ttc_data_dff, ttc_data_p, ttc_data_n : std_logic_vector(11 downto 0); signal ttc_bc_reset_dff, ttc_bc_reset_p, ttc_bc_reset_n, l1a_dff, l1a_p, l1a_n : std_logic; signal fcal_mode : std_logic_vector(1 downto 0); signal mask_eta : std_logic_vector(2 downto 0); signal input_mask : std_logic_vector(9 downto 0); -- Clock Phase Detection component cpd port ( phase : out std_logic_vector(1 downto 0); clk0_d1 : in std_logic; clk0_d2, clk90_d2 : in std_logic; clk180_d2, clk270_d2 : in std_logic); end component; signal d1_phs, d1_phs_0 : std_logic_vector(1 downto 0); -- Random component random port ( data_out : out std_logic_vector(15 downto 0); seed : in std_logic_vector(15 downto 0); clk, reset : in std_logic); end component; signal rnd_data_out, rnd_seed : std_logic_vector(15 downto 0); signal rnd_inputs : std_logic; -- VME port component vme_port port ( clk0_d1 : in std_logic; clk0_d2 : in std_logic; clk180_d2 : in std_logic; d1_phs : in std_logic_vector(1 downto 0); -- connect to sum/controller v_start : in std_logic; v_write : in std_logic; v_inport : in std_logic_vector (3 downto 0); v_outport : out std_logic_vector (3 downto 0); v_readstart : out std_logic; -- connect to internal registers ADDR_IN : out std_logic_vector (8 downto 0); data_write : out std_logic_vector (11 downto 0); data_read : in std_logic_vector (11 downto 0); write_en : out std_logic; vme_done : out std_logic); end component; signal vme_address : std_logic_vector(8 downto 0); signal vme_data_write, vme_data_read : std_logic_vector(11 downto 0); signal vme_write_en, vme_vme_done : std_logic; component IBUFG port ( I : in std_logic; O : out std_logic ); end component; begin -- jet_fpga_design ----------------------------------------------------------------------------- -- Input registers ----------------------------------------------------------------------------- FIO_map: for y in 0 to 10 generate jet_inputs(((y+1)*5-1) downto (y*5)) <= FIO(((10-y)*15+5) downto ((10-y)*15+1)); jet_inputs((5*11*5+(y+1)*5-1) downto (5*11*5+y*5)) <= FIO(((10-y)*15+10) downto ((10-y)*15+6)); jet_inputs((6*11*5+(y+1)*5-1) downto (6*11*5+y*5)) <= FIO(((10-y)*15+15) downto ((10-y)*15+11)); end generate FIO_map; JET_INPUTS_map_x: for x in 0 to 3 generate JET_INPUTS_map_RST: for y in 0 to 2 generate jet_inputs(((x+1)*11*5+(y+1)*5-1) downto ((x+1)*11*5+y*5)) <= INPUT_R_JET(((2-y)*20+(3-x+1)*5-1) downto ((2-y)*20+(3-x)*5)); jet_inputs(((x+1)*11*5+(y+4)*5-1) downto ((x+1)*11*5+(y+3)*5)) <= INPUT_S_JET(((2-y)*20+(3-x+1)*5-1) downto ((2-y)*20+(3-x)*5)); jet_inputs(((x+1)*11*5+(y+7)*5-1) downto ((x+1)*11*5+(y+6)*5)) <= INPUT_T_JET(((2-y)*20+(3-x+1)*5-1) downto ((2-y)*20+(3-x)*5)); end generate JET_INPUTS_map_RST; JET_INPUTS_map_U: for y in 0 to 1 generate jet_inputs(((x+1)*11*5+(y+10)*5-1) downto ((x+1)*11*5+(y+9)*5)) <= INPUT_U_JET(((1-y+1)*20+(3-x+1)*5-1) downto ((1-y+1)*20+(3-x)*5)); end generate JET_INPUTS_map_U; end generate JET_INPUTS_map_x; DFFx: for x in 0 to 6 generate DFFy: for y in 0 to 10 generate JET_DFF: process (clk0_d2, reset) begin -- process JET_DFF if reset = '0' then -- asynchronous reset (active low) jet_inputs_dff(((x*11+y+1)*5-1) downto ((x*11+y)*5)) <= (others => '0'); elsif clk0_d2'event and clk0_d2 = '1' then -- rising clock edge jet_inputs_dff(((x*11+y+1)*5-1) downto ((x*11+y)*5)) <= jet_inputs(((x*11+y+1)*5-1) downto ((x*11+y)*5)); end if; end process JET_DFF; JET_DDR: process (clk180_d2, reset, mask_eta) begin -- process JET_DDR if reset = '0' or (x=0 and mask_eta(0)='1') or (x=5 and mask_eta(1)='1') or (x=6 and mask_eta(2)='1') then -- asynchronous reset (active low) jet_inputs_ddr(((x*11+y+1)*10-1) downto ((x*11+y)*10)) <= (others => '0'); elsif clk180_d2'event and clk180_d2 = '1' then -- rising clock edge jet_inputs_ddr(((x*11+y+1)*10-1) downto ((x*11+y)*10)) <= jet_inputs(((x*11+y+1)*5-1) downto ((x*11+y)*5)) & jet_inputs_dff(((x*11+y+1)*5-1) downto ((x*11+y)*5)); end if; end process JET_DDR; JET_MASK: process (clk0_d2, reset) constant i_high : integer := ((x*11+y+1)*10-1); constant i_low : integer := ((x*11+y)*10); variable input : std_logic_vector(9 downto 0); constant f_high : integer := ((fcm(x)(y)(0)*11+fcm(x)(y)(1)+1)*10-1); constant f_low : integer := ((fcm(x)(y)(0)*11+fcm(x)(y)(1))*10); begin -- process JET_MASK if reset = '0' then -- asynchronous reset (active low) jet_inputs_mask(i_high downto i_low) <= (others => '0'); elsif clk0_d2'event and clk0_d2 = '1' then -- rising clock edge jet_inputs_mask(i_high downto i_low) <= (others => '0'); input := jet_inputs_ddr(i_high downto i_low); if (fcal_mode(0)='1' and (x=1 or x=2)) or (fcal_mode(1)='1' and (x=3 or x=4)) then input := jet_inputs_ddr(f_high downto f_low); if fcm(x)(y)(2) >= 1 and conv_integer(input) /= (2**10-1) then input := '0' & jet_inputs_ddr(f_high downto f_low+1); if fcm(x)(y)(2) = 2 then input := input + jet_inputs_ddr(f_low); end if; end if; end if; if input >= input_mask then jet_inputs_mask(i_high downto i_low) <= input; end if; if rnd_inputs = '1' then jet_inputs_mask(i_high downto i_low) <= jet_inputs_rnd(i_high downto i_low); end if; end if; end process JET_MASK; end generate DFFy; end generate DFFx; JET_RND: process (clk0_d2, reset) begin -- process JET_RND if reset = '0' then -- asynchronous reset (active low) jet_inputs_rnd <= (others => '0'); elsif clk0_d2'event and clk0_d2 = '1' then -- rising clock edge jet_inputs_rnd <= jet_inputs_rnd(jet_inputs_rnd'high-rnd_data_out'length downto 0) & rnd_data_out; end if; end process JET_RND; IN_DFFs_0: process (clk0_d2, reset) begin -- process IN_DFFs_0 if reset = '0' then -- asynchronous reset (active low) ttc_data_p <= (others => '0'); ttc_bc_reset_p <= '0'; l1a_p <= '0'; elsif clk0_d2'event and clk0_d2 = '1' then -- rising clock edge ttc_data_p(ttc_data'high downto 0) <= ttc_data; ttc_bc_reset_p <= ttc_bc_reset; l1a_p <= l1a; end if; end process IN_DFFs_0; IN_DFFs_180: process (clk180_d2, reset) begin -- process IN_DFFs_180 if reset = '0' then -- asynchronous reset (active low) ttc_data_n <= (others => '0'); ttc_bc_reset_n <= '0'; l1a_n <= '0'; elsif clk180_d2'event and clk180_d2 = '1' then -- rising clock edge ttc_data_n(ttc_data'high downto 0) <= ttc_data; ttc_bc_reset_n <= ttc_bc_reset; l1a_n <= l1a; end if; end process IN_DFFs_180; IN_DFFs: process (clk0_d2, reset) begin -- process IN_DFFs if reset = '0' then -- asynchronous reset (active low) ttc_data_dff <= (others => '0'); ttc_bc_reset_dff <= '0'; l1a_dff <= '0'; elsif clk0_d2'event and clk0_d2 = '1' then -- rising clock edge ttc_data_dff <= ttc_data_n; ttc_bc_reset_dff <= ttc_bc_reset_n; l1a_dff <= l1a_n; if d1_phs = "01" or d1_phs = "11" then ttc_data_dff <= ttc_data_p; ttc_bc_reset_dff <= ttc_bc_reset_p; l1a_dff <= l1a_p; end if; end if; end process IN_DFFs; ----------------------------------------------------------------------------- -- Outputs ----------------------------------------------------------------------------- JET_MULT_OUT: process (clk90_d2, reset) begin -- process JET_MULT_OUT if reset = '0' then -- asynchronous reset (active low) jet_jetmultiplicities_bp <= (others => '0'); elsif clk90_d2'event and clk90_d2 = '1' then -- rising clock edge jet_jetmultiplicities_bp <= jet_jetmultiplicities; end if; end process JET_MULT_OUT; JET_MULT_0: process (clk0_d2, reset) begin -- process JET_MULT_0 if reset = '0' then -- asynchronous reset (active low) jet_jetmult_p <= (others => '0'); elsif clk0_d2'event and clk0_d2 = '1' then -- rising clock edge jet_jetmult_p <= jet_jetmultiplicities; end if; end process JET_MULT_0; JET_MULT_180: process (clk180_d2, reset) begin -- process JET_MULT_180 if reset = '0' then -- asynchronous reset (active low) jet_jetmult_n <= (others => '0'); elsif clk180_d2'event and clk180_d2 = '1' then -- rising clock edge jet_jetmult_n <= jet_jetmultiplicities; end if; end process JET_MULT_180; OUT_DFFs: process (clk0_d1, reset) begin -- process OUT_DFFs if reset = '0' then -- asynchronous reset (active low) jet_jetmultiplicities_sm <= (others => '0'); elsif clk0_d1'event and clk0_d1 = '1' then -- rising clock edge jet_jetmultiplicities_sm <= jet_jetmult_n; if d1_phs = "01" or d1_phs = "11" then jet_jetmultiplicities_sm <= jet_jetmult_p; end if; end if; end process OUT_DFFs; ----------------------------------------------------------------------------- -- Clocks and reset ----------------------------------------------------------------------------- CLK_U1: clock_unit port map(clk_des1,clk_des2,clk0_d1,clk180_d1,clk0_d2,clk90_d2,clk180_d2,clk270_d2,locked_des1,locked_des2); RST_U1: reset_unit port map(reset_request,reset,clk0_d2); CPD1: cpd port map(d1_phs_0,clk0_d1,clk0_d2,clk90_d2,clk180_d2,clk270_d2); -- Debug (Begin) dbg_clk_40MHz <= clk0_d2; dbg_rst <= reset; ----------------------------------------------------------------------------- -- Random inputs ----------------------------------------------------------------------------- RND1: random port map(rnd_data_out,rnd_seed,clk0_d2,reset); ----------------------------------------------------------------------------- -- Jet algorithm ----------------------------------------------------------------------------- JET1: jet generic map(2,4,10,8,10,3) port map(jet_inputs_mask,jet_thresholds,jet_cluster_sizes,fcal_mode,jet_rois,jet_jetmult_cc,jet_jetmult_fc,clk0_d2,reset); JET_ROIs_ROC_map: for i in 0 to 7 generate jet_rois_roc(((i+1)*11-1) downto (i*11)) <= jet_rois(((i+1)*12-2) downto (i*12)); end generate JET_ROIs_ROC_map; jet_jetmultiplicities <= jet_jetmult_cc when conv_integer(fcal_mode) = 0 else jet_jetmult_fc; ----------------------------------------------------------------------------- -- ROC ----------------------------------------------------------------------------- DAQ1: daq generic map(jet_rois_roc'length,jet_rois_roc'length/2+1) port map(jet_rois_roc,daq_delay,daq_orbit_counter,daq_counter_load,daq_bc_reset,daq_l1a,daq_data_out,daq_dav,daq_dav_space,fcal_mode,open,clk0_d2,reset); ----------------------------------------------------------------------------- -- Input spymem ----------------------------------------------------------------------------- SPY_IN: inout_spymem generic map(input_spy_data'length,input_spy'length) port map(input_spy,input_spy_data,input_spy_reset_address,input_spy_next_value,input_spy_start_recording,input_spy_recording,clk0_d2); input_spy <= (input_spy_start_recording or input_spy_recording) & jet_cluster_sizes & jet_thresholds & jet_inputs_mask; ----------------------------------------------------------------------------- -- Output spymem ----------------------------------------------------------------------------- SPY_OUT: inout_spymem generic map(output_spy_data'length,output_spy'length) port map(output_spy,output_spy_data,output_spy_reset_address,output_spy_next_value,output_spy_start_recording,output_spy_recording,clk0_d2); output_spy <= (output_spy_start_recording or output_spy_recording) & jet_jetmultiplicities & jet_rois; ----------------------------------------------------------------------------- -- ROC spymem ----------------------------------------------------------------------------- ROC_SPY1: roc_spymem generic map(roc_spy_data'length,roc_spy'length) port map(roc_spy,roc_spy_data,roc_spy_reset_address,roc_spy_next_value,roc_spy_start_recording,roc_spy_recording,daq_dav,roc_spy_events_to_read,clk0_d2); roc_spy <= daq_dav & daq_data_out; ----------------------------------------------------------------------------- -- G-Link ----------------------------------------------------------------------------- IBUFG1: IBUFG port map(glink_clk_in,glink_clk_int); EB1: elastic_buffer port map(roc_spy,ROC_data_out,clk0_d2,glink_clk_int,reset); GLINK1: g_link port map(ROC_data_out(4 downto 0),ROC_data_out(5),glink,glink_locked,open,glink_clk_int,reset); ----------------------------------------------------------------------------- -- Control ----------------------------------------------------------------------------- CONTROL1: control port map( -- VME vme_data_write,vme_data_read,vme_address(vme_address'high downto 1),vme_write_en,vme_vme_done, -- Debug debug_data_in,debug_data_out,debug_address,debug_write,debug_read,rnd_data_out,rnd_seed,rnd_inputs, -- TTC l1a_dff,ttc_data_dff,ttc_bc_reset_dff, -- Jet jet_thresholds,jet_cluster_sizes,fcal_mode,mask_eta,input_mask, -- DAQ daq_delay,daq_orbit_counter,daq_counter_load,daq_bc_reset,daq_l1a,daq_dav_space, -- G-Link glink_locked, -- Input spy input_spy_data,input_spy_reset_address,input_spy_next_value,input_spy_start_recording,input_spy_recording, -- Output spy output_spy_data,output_spy_reset_address,output_spy_next_value,output_spy_start_recording,output_spy_recording, -- ROC spy ROC_spy_data,ROC_spy_reset_address,ROC_spy_next_value,ROC_spy_start_recording,ROC_spy_recording,ROC_spy_events_to_read, -- Clock and reset reset_request,locked_des1,locked_des2,d1_phs_0,d1_phs,clk0_d2,reset); ----------------------------------------------------------------------------- -- VME port ----------------------------------------------------------------------------- VME_PORT1: vme_port port map(clk0_d1,clk0_d2,clk180_d2,d1_phs_0,v_start,v_write,v_inport,v_outport,v_readstart, vme_address,vme_data_write,vme_data_read,vme_write_en,vme_vme_done); end jet_fpga_design;