end component pll_in125_out20;
component OSCF -- internal oscillator with a frequency of 2MHz
- port (OSC : out
- std_logic);
+-- synthesis translate_off
+ generic (NOM_FREQ : string := "2.5");
+-- synthesis translate_on
+ port (OSC : out std_logic);
end component;
+ --component OSCF
+ -- port (OSC : out
+ -- std_logic);
+ --end component;
+
component FIFO_32x32_OutReg
port (
Data : in std_logic_vector(31 downto 0);
-- File : Readout.vhd
-- Author : cugur@gsi.de
-- Created : 2012-10-25
--- Last update: 2014-12-05
+-- Last update: 2014-12-11
-------------------------------------------------------------------------------
-- Description:
-------------------------------------------------------------------------------
RESET_COUNTERS : in std_logic;
CLK_100 : in std_logic;
CLK_200 : in std_logic;
+ HIT_IN : in std_logic_vector(CHANNEL_NUMBER-1 downto 1);
-- from the channels
CH_DATA_IN : in std_logic_vector_array_36(0 to CHANNEL_NUMBER);
CH_DATA_VALID_IN : in std_logic_vector(CHANNEL_NUMBER-1 downto 0);
TRG_TDC_IN : in std_logic;
TRG_TIME_IN : in std_logic_vector(38 downto 0);
-- miscellaneous
+ LIGHT_MODE_IN : in std_logic;
COARSE_COUNTER_IN : in std_logic_vector(10 downto 0);
EPOCH_COUNTER_IN : in std_logic_vector(27 downto 0);
DEBUG_MODE_EN_IN : in std_logic;
-- Signal Declarations
-------------------------------------------------------------------------------
- -- slow control
- signal slow_control_ch_empty : std_logic_vector(63 downto 0);
-- trigger window
signal trg_win_pre : unsigned(10 downto 0);
signal trg_win_post : unsigned(10 downto 0);
signal ch_data_r : std_logic_vector_array_36(0 to CHANNEL_NUMBER);
signal ch_data_2r : std_logic_vector_array_36(0 to CHANNEL_NUMBER);
signal ch_data_3r : std_logic_vector_array_36(0 to CHANNEL_NUMBER);
--- signal ch_data_4r : std_logic_vector_array_36(0 to CHANNEL_NUMBER);
signal ch_data_4r : std_logic_vector(31 downto 0);
- signal ch_empty_r : std_logic_vector(CHANNEL_NUMBER-1 downto 0);
- signal ch_empty_2r : std_logic_vector(CHANNEL_NUMBER-1 downto 0);
- signal ch_empty_3r : std_logic_vector(CHANNEL_NUMBER-1 downto 0);
- signal ch_empty_4r : std_logic_vector(CHANNEL_NUMBER-1 downto 0);
signal ch_hit_time : std_logic_vector(38 downto 0);
signal ch_epoch_cntr : std_logic_vector(27 downto 0);
signal buffer_transfer_done : std_logic;
signal wait_time_up : std_logic;
signal wrong_readout_up : std_logic;
signal finished : std_logic;
+ -- control
+ signal sync_q : std_logic_vector((CHANNEL_NUMBER-2)*3+2 downto 0);
+ signal isNoHit : std_logic := '0';
+ signal isNoHit_r : std_logic := '0';
+ signal hit_in_i : std_logic_vector(CHANNEL_NUMBER-1 downto 1);
-- debug
signal header_error_bits : std_logic_vector(15 downto 0);
signal trailer_error_bits : std_logic_vector(15 downto 0);
signal wr_fsm_debug_r : std_logic_vector(3 downto 0);
signal history_wr_fsm : std_logic_vector(31 downto 0) := (others => '0');
signal status_registers_bus : std_logic_vector(31 downto 0);
-
+ signal any_hit : std_logic := '0';
+
begin -- behavioral
trg_win_pre <= unsigned(TRG_WIN_PRE_IN);
case (RD_CURRENT) is
when IDLE =>
if VALID_TIMING_TRG_IN = '1' then -- physical trigger
- RD_NEXT <= WAIT_FOR_TRG_WIND_END;
- wr_header_fsm <= '1';
+ RD_NEXT <= WAIT_FOR_TRG_WIND_END;
+ if isNoHit = '0' then
+ wr_header_fsm <= '1';
+ end if;
--if isLastTriggerNoTiming = '1' then
-- wrong_readout_fsm <= '1';
--end if;
--
when WR_CH =>
if ch_data_2r(fifo_nr_wr)(35 downto 32) /= x"f" then
- if wr_number >= DATA_LIMIT_IN then
+ if wr_number >= DATA_LIMIT_IN or isNoHit_r = '1' then
wr_ch_data_fsm <= '0';
else
wr_ch_data_fsm <= '1';
wr_time <= wr_ch_data_r and ch_data_4r(31) when rising_edge(CLK_100);
wr_epoch <= wr_ch_data_r and not data_out_r(31) and data_out_r(30) and data_out_r(29) and ch_data_4r(31);
- -- and not (and_all(ch_data_4r(31 downto 29)))
-
DATA_OUT <= data_out_r;
DATA_WRITE_OUT <= wr_info or wr_time or wr_epoch; --data_wr_r;
ch_full <= or_all(CH_FULL_IN);
+-------------------------------------------------------------------------------
+-- Control bits
+-------------------------------------------------------------------------------
+ --purpose: Hit Signal Synchroniser
+ HitSignalSync : for i in 0 to CHANNEL_NUMBER-2 generate
+ sync_q(i*3) <= HIT_IN(i+1) when rising_edge(CLK_100);
+ sync_q(i*3+1) <= sync_q(i*3); -- when rising_edge(CLK_100);
+ sync_q(i*3+2) <= sync_q(i*3+1); -- when rising_edge(CLK_100);
+ hit_in_i(i+1) <= sync_q(i*3+2);
+ end generate HitSignalSync;
+ any_hit <= or_all(hit_in_i);
+ CheckHitStatus : process (CLK_100) is
+ begin
+ if rising_edge(CLK_100) then -- rising clock edge
+ if LIGHT_MODE_IN = '0' or TRG_WIN_EN_IN = '1' then
+ isNoHit <= '0';
+ isNoHit_r <= '0';
+ elsif VALID_TIMING_TRG_IN = '1' then
+ isNoHit <= '1';
+ isNoHit_r <= isNoHit;
+ elsif or_all(hit_in_i) = '1' then
+ isNoHit <= '0';
+ end if;
+ end if;
+ end process CheckHitStatus;
-------------------------------------------------------------------------------
-- Debug and statistics words
-------------------------------------------------------------------------------
-------------------------------------------------------------------------------
-- Registering
-------------------------------------------------------------------------------
- ch_data_r <= CH_DATA_IN when rising_edge(CLK_100);
- ch_data_2r <= ch_data_r when rising_edge(CLK_100);
- ch_data_3r <= ch_data_2r when rising_edge(CLK_100);
--- ch_data_4r <= ch_data_3r when rising_edge(CLK_100);
- ch_empty_r <= CH_EMPTY_IN when rising_edge(CLK_100);
- ch_empty_2r <= ch_empty_r when rising_edge(CLK_100);
- ch_empty_3r <= ch_empty_2r when rising_edge(CLK_100);
- ch_empty_4r <= ch_empty_3r when rising_edge(CLK_100);
+ ch_data_r <= CH_DATA_IN when rising_edge(CLK_100);
+ ch_data_2r <= ch_data_r when rising_edge(CLK_100);
+ ch_data_3r <= ch_data_2r when rising_edge(CLK_100);
end behavioral;
-- Slow control
signal logic_anal_control : std_logic_vector(3 downto 0);
signal debug_mode_en : std_logic;
+ signal light_mode_en : std_logic;
signal reset_counters : std_logic;
--signal run_mode : std_logic; -- 1: cc reset every trigger
-- -- 0: free running mode
signal reset_coarse_cntr_flag : std_logic := '0';
signal ch_en : std_logic_vector(64 downto 1);
signal data_limit : unsigned(7 downto 0);
- signal calibration_on : std_logic; -- turns on calibration for trig type 0xC
+ signal calibration_on : std_logic := '0'; -- turns on calibration for trig type 0xC
-- Logic analyser
signal logic_anal_data : std_logic_vector(3*32-1 downto 0);
-- Hit signals
signal hit_in_d : std_logic_vector(CHANNEL_NUMBER-1 downto 0);
+ signal hit_in_s : std_logic_vector(CHANNEL_NUMBER-1 downto 0);
signal hit_in_i : std_logic_vector(CHANNEL_NUMBER-1 downto 0);
signal hit_latch : std_logic_vector(CHANNEL_NUMBER-1 downto 1) := (others => '0');
signal hit_edge : std_logic_vector(CHANNEL_NUMBER-1 downto 1);
signal edge_falling_3r : std_logic_vector(CHANNEL_NUMBER-1 downto 1);
-- Calibration
signal hit_cal_cntr : unsigned(15 downto 0) := (others => '0');
+ signal hit_cal_i : std_logic;
signal hit_cal : std_logic;
signal calibration_freq_select : unsigned(3 downto 0) := (others => '0');
-- To the channels
-- Slow control signals
logic_anal_control <= CONTROL_REG_IN(3 downto 0) when rising_edge(CLK_READOUT);
debug_mode_en <= CONTROL_REG_IN(4);
+ light_mode_en <= CONTROL_REG_IN(5) when rising_edge(CLK_READOUT);
reset_counters <= CONTROL_REG_IN(8) or reset_tdc when rising_edge(CLK_TDC);
--run_mode <= CONTROL_REG_IN(12);
--run_mode_200 <= run_mode when rising_edge(CLK_TDC);
-------------------------------------------------------------------------------
-- Hit for calibration generation
hit_cal_cntr <= hit_cal_cntr + to_unsigned(1, 16) when rising_edge(HIT_CAL_IN);
- hit_cal <= hit_cal_cntr(to_integer(calibration_freq_select));
+ hit_cal_i <= hit_cal_cntr(to_integer(calibration_freq_select));
+
+ HitCalPulse: entity work.risingEdgeDetect
+ port map (
+ CLK => HIT_CAL_IN,
+ SIGNAL_IN => hit_cal_i,
+ PULSE_OUT => hit_cal);
+
+ GEN_HitSelect : for i in 1 to CHANNEL_NUMBER-1 generate
+ HitSelect: process (calibration_on, HIT_IN, hit_cal)is
+ begin
+ if calibration_on = '0' then
+ hit_in_s(i) <= HIT_IN(i);
+ else
+ hit_in_s(i) <= hit_cal;
+ end if;
+ end process HitSelect;
+ end generate GEN_HitSelect;
gen_double_withStretcher : if DOUBLE_EDGE_TYPE = 3 generate
The_Stretcher : entity work.Stretcher
CHANNEL => CHANNEL_NUMBER-1,
DEPTH => 4)
port map (
- PULSE_IN => HIT_IN(CHANNEL_NUMBER-1 downto 1),
+ PULSE_IN => hit_in_s(CHANNEL_NUMBER-1 downto 1),
PULSE_OUT => hit_in_d(CHANNEL_NUMBER-1 downto 1));
end generate gen_double_withStretcher;
gen_double_withoutStretcher : if DOUBLE_EDGE_TYPE = 1 generate
- hit_in_d(CHANNEL_NUMBER-1 downto 1) <= HIT_IN(CHANNEL_NUMBER-1 downto 1);
+ hit_in_d(CHANNEL_NUMBER-1 downto 1) <= hit_in_s(CHANNEL_NUMBER-1 downto 1);
end generate gen_double_withoutStretcher;
GEN_HitBlock : for i in 1 to CHANNEL_NUMBER-1 generate
gen_double : if DOUBLE_EDGE_TYPE = 1 or DOUBLE_EDGE_TYPE = 3 generate
edge_rising(i) <= '0' when edge_rising_3r(i) = '1' else
- '1' when rising_edge(HIT_IN(i));
+ '1' when rising_edge(hit_in_s(i));
edge_rising_r(i) <= edge_rising(i) when rising_edge(CLK_READOUT); -- using 100MHz clk for longer reset time
edge_rising_2r(i) <= edge_rising_r(i) when rising_edge(CLK_READOUT);
edge_rising_3r(i) <= edge_rising_r(i) and not edge_rising_2r(i) when rising_edge(CLK_READOUT);
-- for single edge and double edge in alternating channel setup
gen_single : if DOUBLE_EDGE_TYPE = 0 or DOUBLE_EDGE_TYPE = 2 generate
hit_latch(i) <= '0' when hit_3r(i) = '1' else
- '1' when rising_edge(HIT_IN(i));
+ '1' when rising_edge(hit_in_s(i));
hit_edge(i) <= '1';
hit_r <= hit_latch when rising_edge(CLK_READOUT); -- using 100MHz clk for longer reset time
hit_2r <= hit_r when rising_edge(CLK_READOUT);
hit_mux_ch : hit_mux
port map (
CH_EN_IN => ch_en(i),
- CALIBRATION_EN_IN => calibration_on,
- HIT_CALIBRATION_IN => hit_cal,
+ CALIBRATION_EN_IN => '0', --calibration_on,
+ HIT_CALIBRATION_IN => '0', --hit_cal,
HIT_PHYSICAL_IN => hit_latch(i),
HIT_OUT => hit_in_i(i));
end generate GEN_hit_mux;
RESET_COUNTERS => reset_counters,
CLK_100 => CLK_READOUT,
CLK_200 => CLK_TDC,
+ HIT_IN => hit_in_i(CHANNEL_NUMBER-1 downto 1),
-- from the channels
CH_DATA_IN => ch_data,
CH_DATA_VALID_IN => ch_data_valid,
TRG_TDC_IN => trg_tdc,
TRG_TIME_IN => trg_time,
-- miscellaneous
+ LIGHT_MODE_IN => light_mode_en,
COARSE_COUNTER_IN => coarse_cntr(0),
EPOCH_COUNTER_IN => epoch_cntr,
DEBUG_MODE_EN_IN => debug_mode_en,
-- DATAREADY_OUT => LHB_DATAREADY_OUT,
-- UNKNOWN_ADDR_OUT => LHB_UNKNOWN_ADDR_OUT);
- --GenLostHit_Inumber : for i in 1 to CHANNEL_NUMBER-1 generate
+ --GenLostHit_In_number : for i in 1 to CHANNEL_NUMBER-1 generate
-- ch_lost_hit_bus(i) <= ch_encoder_start_number(i)(15 downto 0) & ch_200_debug(i)(15 downto 0) when rising_edge(CLK_READOUT);
- --end generate GenLostHit_Inumber;
+ --end generate GenLostHit_In_number;
LHB_DATA_OUT <= (others => '0');
LHB_DATAREADY_OUT <= '0';
RESET_COUNTERS : in std_logic;
CLK_100 : in std_logic;
CLK_200 : in std_logic;
+ HIT_IN : in std_logic_vector(CHANNEL_NUMBER-1 downto 1);
CH_DATA_IN : in std_logic_vector_array_36(0 to CHANNEL_NUMBER);
CH_DATA_VALID_IN : in std_logic_vector(CHANNEL_NUMBER-1 downto 0);
CH_EMPTY_IN : in std_logic_vector(CHANNEL_NUMBER-1 downto 0);
TRG_WIN_END_RDO_IN : in std_logic;
TRG_TDC_IN : in std_logic;
TRG_TIME_IN : in std_logic_vector(38 downto 0);
+ LIGHT_MODE_IN : in std_logic;
COARSE_COUNTER_IN : in std_logic_vector(10 downto 0);
EPOCH_COUNTER_IN : in std_logic_vector(27 downto 0);
DEBUG_MODE_EN_IN : in std_logic;
package tdc_version is
- constant TDC_VERSION : std_logic_vector(11 downto 0) := x"200";
+ constant TDC_VERSION : std_logic_vector(11 downto 0) := x"201";
end;
constant REGIO_NUM_STAT_REGS : integer := 0;
constant REGIO_NUM_CTRL_REGS : integer := 0;
- attribute syn_keep : boolean;
- attribute syn_preserve : boolean;
+ attribute syn_keep : boolean;
+ attribute syn_preserve : boolean;
+ attribute NOM_FREQ : string;
+ attribute NOM_FREQ of OSCinst0 : label is "20.0";
+
--Clock / Reset
signal clk_100_i : std_logic; --clock for main logic, 100 MHz, via Clock Manager and internal PLL
);
-- internal oscillator with frequency of 2.5MHz for tdc calibration
- OSCInst0 : OSCF
+ OSCInst0: OSCF
+-- synthesis translate_off
+ generic map (
+ NOM_FREQ => "20.0")
+-- synthesis translate_on
port map (
OSC => osc_int);
-
-
-
+
---------------------------------------------------------------------------
-- The TrbNet media interface (to other FPGA)
TIMING_TRIGGER_RAW => c_YES,
--Configure data handler
DATA_INTERFACE_NUMBER => 1,
- DATA_BUFFER_DEPTH => 12,
+ DATA_BUFFER_DEPTH => EVENT_BUFFER_SIZE,
DATA_BUFFER_WIDTH => 32,
- DATA_BUFFER_FULL_THRESH => 2**12-400,
+ DATA_BUFFER_FULL_THRESH => 2**EVENT_BUFFER_SIZE-EVENT_MAX_SIZE,
TRG_RELEASE_AFTER_DATA => c_YES,
HEADER_BUFFER_DEPTH => 9,
HEADER_BUFFER_FULL_THRESH => 2**9-16
## Unimportant Data Lines ##
#############################################################################
MULTICYCLE FROM CELL "THE_TDC/reset_tdc*" TO CLKNET CLK_PCLK_LEFT_c 2x;
-
MULTICYCLE FROM CELL "THE_TDC/reset_counters*" 4x;
-# MULTICYCLE FROM CELL "PROC_TDC_CTRL_REG*tdc_ctrl_reg*" 4x;
-
-# MULTICYCLE TO CELL "THE_TDC/GEN_Channels*Channels/Channel200/SimAdderNo*FC/FF*" 4x;
-# MULTICYCLE TO CELL "THE_TDC/ReferenceChannel/Channel200/SimAdderNo*FC/FF*" 4x;
-MULTICYCLE TO CELL "THE_TDC/GEN_Channels*Channels/sync_q*" 4 x;
MULTICYCLE TO CELL "THE_TDC/ReferenceChannel/sync_q*" 4 x;
+MULTICYCLE TO CELL "THE_TDC/GEN_Channels*Channels/sync_q*" 4 x;
-MULTICYCLE FROM CELL "THE_TDC/GEN_Channels*Channels/Channel200/RingBuffer*FIFO/FF*" TO CELL "THE_TDC/GEN_Channels*Channels/Channel200/ringBuffer_almost_full_sync*" 2x;
MULTICYCLE FROM CELL "THE_TDC/ReferenceChannel/Channel200/RingBuffer*FIFO/FF*" TO CELL "THE_TDC/ReferenceChannel/Channel200/ringBuffer_almost_full_sync*" 2x;
+MULTICYCLE FROM CELL "THE_TDC/GEN_Channels*Channels/Channel200/RingBuffer*FIFO/FF*" TO CELL "THE_TDC/GEN_Channels*Channels/Channel200/ringBuffer_almost_full_sync*" 2x;
-MULTICYCLE FROM CELL "THE_TDC/TheEpochCounter/counter*" TO CELL "THE_TDC/GEN_Channels*Channels/epoch_cntr_reg*" 3 X;
MULTICYCLE FROM CELL "THE_TDC/TheEpochCounter/counter*" TO CELL "THE_TDC/ReferenceChannel/epoch_cntr_reg*" 3 X;
+MULTICYCLE FROM CELL "THE_TDC/TheEpochCounter/counter*" TO CELL "THE_TDC/GEN_Channels*Channels/epoch_cntr_reg*" 3 X;
MULTICYCLE TO CELL "THE_TDC/TheReadout/TW_pre*" 4 x;
MULTICYCLE TO CELL "THE_TDC/TheReadout/TW_post*" 4 x;
+#BLOCK PATH TO CELL "THE_TDC/edge_rising_r[*]" ;
+#BLOCK PATH TO CELL "THE_TDC/edge_falling_r[*]" ;
+BLOCK NET "THE_TDC/pulse[*]";
+BLOCK NET "THE_TDC/hit_in_s*";
+#BLOCK NET "THE_TDC/edge_rising[*]" ;
+#BLOCK NET "THE_TDC/edge_falling[*]" ;
+MAXDELAY NET "THE_TDC/hit_in_i*" 0.600000 nS; #DATAPATH_ONLY ;
-# #MAXDELAY FROM GROUP "hitBuf*" TO GROUP "FC*" 0.600000 nS;
-# #MAXDELAY FROM GROUP "hitBuf_ref*" TO GROUP "Ref_Ch" 0.600000 nS;
-MAXDELAY NET "THE_TDC/hitn*" 0.600000 nS; #DATAPATH_ONLY ;
-## Maybe effective
-
-# MULTICYCLE FROM CELL "THE_TDC/GEN_Channels*Channels/The_Buffer/*" TO CELL "THE_TDC/TheReadout/rd_en*" 2 X;
+# MULTICYCLE FROM CELL "PROC_TDC_CTRL_REG*tdc_ctrl_reg*" 4x;
+# MULTICYCLE TO CELL "THE_TDC/GEN_Channels*Channels/Channel200/SimAdderNo*FC/FF*" 4x;
+# MULTICYCLE TO CELL "THE_TDC/ReferenceChannel/Channel200/SimAdderNo*FC/FF*" 4x;
+## Maybe effective
+# MULTICYCLE FROM CELL "THE_TDC/GEN_Channels*Channels/The_Buffer/*" TO CELL "THE_TDC/TheReadout/rd_en*" 2 X;
# # BLOCK NET "THE_TDC/reset_tdc*" ;
# # BLOCK NET "THE_TDC/reset_rdo*" ;
-# # #BLOCK NET "THE_TDC/hitn_*" ;
+# # #BLOCK NET "THE_TDC/hit_in_*" ;
# # BLOCK NET "THE_TDC/hit_latch*" ;
# # BLOCK NET "THE_TDC/reset_counters*" ;