signal clk_200_i : std_logic; --clock for logic at 200 MHz, via Clock Manager and bypassed PLL
signal clk_125_i : std_logic; -- 125 MHz, via Clock Manager and bypassed PLL
signal clk_20_i : std_logic; -- clock for calibrating the tdc, 20 MHz, via Clock Manager and internal PLL
+ signal osc_int : std_logic; -- clock for calibrating the tdc, 20 MHz, via Clock Manager and internal PLL
signal pll_lock : std_logic; --Internal PLL locked. E.g. used to reset all internal logic.
signal clear_i : std_logic;
signal reset_i : std_logic;
CLKOK => clk_125_i,
LOCK => open);
+ OSCInst0 : OSCF -- internal oscillator with frequency of 2.5MHz
+ port map (
+ OSC => osc_int);
+
+
---------------------------------------------------------------------------
-- The TrbNet media interface (to other FPGA)
---------------------------------------------------------------------------
THE_TDC : TDC
generic map (
- CHANNEL_NUMBER => 65, -- Number of TDC channels
- CONTROL_REG_NR => 6, -- Number of control regs - higher than 8 check tdc_ctrl_addr
+ CHANNEL_NUMBER => 5, -- Number of TDC channels
+ STATUS_REG_NR => 20, -- Number of status regs
+ CONTROL_REG_NR => 6, -- Number of control regs - higher than 8 check tdc_ctrl_addr
TDC_VERSION => x"160", -- TDC version number
DEBUG => c_YES,
SIMULATION => c_NO)
RESET => reset_i,
CLK_TDC => CLK_PCLK_LEFT, -- Clock used for the time measurement
CLK_READOUT => clk_100_i, -- Clock for the readout
- REFERENCE_TIME => timing_trg_received_i, -- Reference time input
- HIT_IN => hit_in_i(64 downto 1), -- Channel start signals
- HIT_CALIBRATION => clk_20_i, -- Hits for calibrating the TDC
+ REFERENCE_TIME => timing_trg_received_i, -- Reference time input
+ HIT_IN => hit_in_i(4 downto 1), -- Channel start signals
+ HIT_CALIBRATION => osc_int, --clk_20_i, -- Hits for calibrating the TDC
TRG_WIN_PRE => tdc_ctrl_reg(42 downto 32), -- Pre-Trigger window width
TRG_WIN_POST => tdc_ctrl_reg(58 downto 48), -- Post-Trigger window width
--
-- File : Channel_200.vhd
-- Author : c.ugur@gsi.de
-- Created : 2012-08-28
--- Last update: 2014-01-21
+-- Last update: 2014-01-22
-------------------------------------------------------------------------------
-- Description:
-------------------------------------------------------------------------------
-- epoch counter
signal epoch_cntr : std_logic_vector(27 downto 0) := (others => '0');
+ signal epoch_cntr_reg : std_logic_vector(27 downto 0) := (others => '0');
signal epoch_cntr_updated : std_logic := '0';
signal epoch_capture_time : std_logic_vector(10 downto 0);
signal epoch_value : std_logic_vector(35 downto 0);
TimeStampCapture : process (CLK_200)
begin
if rising_edge(CLK_200) then
- if hit_detect_reg = '1' then -- if encoder_finished_i = '1' then
- time_stamp_i <= std_logic_vector(unsigned(coarse_cntr_reg)); -- - to_unsigned(9, 11));
+ if hit_detect_reg = '1' then
+ time_stamp_i <= coarse_cntr_reg;
end if;
end if;
end process TimeStampCapture;
- epoch_capture_time <= "00000001001";
+ epoch_capture_time <= "00000001000";
- EpochCounterCapture : process (CLK_200)
- begin
- if rising_edge(CLK_200) then
- if hit_detect_reg = '1' then -- if coarse_cntr_reg = epoch_capture_time then
- epoch_cntr_updated <= '1';
- epoch_cntr <= EPOCH_COUNTER_IN;
- elsif write_epoch_i = '1' then
- epoch_cntr_updated <= '0';
+ isChannelEpoch : if REFERENCE = c_NO generate
+ EpochCounterCapture : process (CLK_200)
+ begin
+ if rising_edge(CLK_200) then
+ if coarse_cntr_reg = epoch_capture_time then
+ epoch_cntr <= EPOCH_COUNTER_IN;
+ epoch_cntr_updated <= '1';
+ elsif write_epoch_i = '1' then
+ epoch_cntr_updated <= '0';
+ end if;
end if;
- end if;
- end process EpochCounterCapture;
+ end process EpochCounterCapture;
+ end generate isChannelEpoch;
+ isReferenceEpoch: if REFERENCE = c_YES generate
+ EpochCounterCapture : process (CLK_200)
+ begin
+ if rising_edge(CLK_200) then
+ if hit_detect_reg = '1' then
+ epoch_cntr <= EPOCH_COUNTER_IN;
+ epoch_cntr_reg <= epoch_cntr;
+ end if;
+ if hit_detect_2reg = '1' and epoch_cntr /= epoch_cntr_reg then
+ epoch_cntr_updated <= '1';
+ elsif write_epoch_i = '1' then
+ epoch_cntr_updated <= '0';
+ end if;
+ end if;
+ end process EpochCounterCapture;
+ end generate isReferenceEpoch;
+
--purpose: Encoder
Encoder : Encoder_304_Bit
port map (
-- File : Readout.vhd
-- Author : cugur@gsi.de
-- Created : 2012-10-25
--- Last update: 2014-01-20
+-- Last update: 2014-01-22
-------------------------------------------------------------------------------
-- Description:
-------------------------------------------------------------------------------
entity Readout is
generic (
CHANNEL_NUMBER : integer range 2 to 65;
+ STATUS_REG_NR : integer range 0 to 31;
TDC_VERSION : std_logic_vector(11 downto 0));
port (
RESET_100 : 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;
- STATUS_REGISTERS_BUS_OUT : out std_logic_vector_array_32(0 to 20);
+ STATUS_REGISTERS_BUS_OUT : out std_logic_vector_array_32(0 to STATUS_REG_NR-1);
READOUT_DEBUG : out std_logic_vector(31 downto 0);
REFERENCE_TIME : in std_logic;
-- ports not used after tdc_v1.5.2
signal ch_hit_time : std_logic_vector(38 downto 0);
signal ch_epoch_cntr_i : std_logic_vector(27 downto 0);
-- readout fsm
- type FSM_READ is (IDLE, WAIT_FOR_TRIG_WIND_END, RD_CH, WAIT_FOR_LVL1_TRIG_A, WAIT_FOR_LVL1_TRIG_B,
- WAIT_FOR_LVL1_TRIG_C, SEND_STATUS, SEND_TRIG_RELEASE_A, SEND_TRIG_RELEASE_B,
- WAIT_FOR_BUFFER_TRANSFER);
+ type FSM_READ is (IDLE, WAIT_FOR_TRIG_WIND_END, RD_CH, WAIT_FOR_DATA_FINISHED, WAIT_FOR_LVL1_TRIG_A,
+ WAIT_FOR_LVL1_TRIG_B, WAIT_FOR_LVL1_TRIG_C, SEND_STATUS, SEND_TRIG_RELEASE_A,
+ SEND_TRIG_RELEASE_B, WAIT_FOR_BUFFER_TRANSFER);
signal RD_CURRENT : FSM_READ := IDLE;
signal RD_NEXT : FSM_READ;
type FSM_WRITE is (IDLE, WR_CH, WAIT_A, WAIT_B, WAIT_C, WAIT_D);
signal ch_almost_full_i : std_logic;
signal rd_fsm_debug : std_logic_vector(3 downto 0);
signal wr_fsm_debug : std_logic_vector(3 downto 0);
+ signal status_registers_bus_i : std_logic_vector(31 downto 0);
begin -- behavioral
TrigWinCalculation : process (CLK_100)
begin
if rising_edge(CLK_100) then
- TW_pre <= std_logic_vector(unsigned(trig_time_i)-unsigned(trig_win_pre));
- TW_post <= std_logic_vector(unsigned(trig_time_i)+unsigned(trig_win_post));
+ TW_pre <= std_logic_vector(unsigned(trig_time_i)-trig_win_pre);
+ TW_post <= std_logic_vector(unsigned(trig_time_i)+trig_win_post);
end if;
end process TrigWinCalculation;
READ_EN_OUT <= rd_en;
RD_FSM_PROC : process (RD_CURRENT, VALID_TIMING_TRG_IN, VALID_NOTIMING_TRG_IN, TRG_DATA_VALID_IN,
- INVALID_TRG_IN, TMGTRG_TIMEOUT_IN, TRG_TYPE_IN,
+ INVALID_TRG_IN, TMGTRG_TIMEOUT_IN, TRG_TYPE_IN, finished_i,
SPURIOUS_TRG_IN, stop_status_i, DEBUG_MODE_EN_IN, fifo_nr_rd,
TRIG_WIN_END_RDO_IN, buf_delay_i, CH_EMPTY_IN, start_ch_i)
begin
case (RD_CURRENT) is
when IDLE =>
- if VALID_TIMING_TRG_IN = '1' then
- RD_NEXT <= WAIT_FOR_TRIG_WIND_END; --WR_HEADER_A;
+ if VALID_TIMING_TRG_IN = '1' then -- physical trigger
+ RD_NEXT <= WAIT_FOR_TRIG_WIND_END;
wr_header_fsm <= '1';
readout_fsm <= '1';
elsif VALID_NOTIMING_TRG_IN = '1' then
- if TRG_TYPE_IN = x"E" then
+ if TRG_TYPE_IN = x"E" then -- status trigger
wr_header_fsm <= '1';
RD_NEXT <= SEND_STATUS;
- elsif TRG_TYPE_IN = x"D" then
- RD_NEXT <= WAIT_FOR_TRIG_WIND_END; --WR_HEADER_A;
+ elsif TRG_TYPE_IN = x"D" then -- tdc calibration trigger
+ RD_NEXT <= WAIT_FOR_BUFFER_TRANSFER;
wr_header_fsm <= '1';
readout_fsm <= '1';
- else
+ else -- the other triggers
data_finished_fsm <= '1';
RD_NEXT <= SEND_TRIG_RELEASE_A;
end if;
- elsif INVALID_TRG_IN = '1' then
+ elsif INVALID_TRG_IN = '1' then -- invalid trigger
RD_NEXT <= SEND_TRIG_RELEASE_A;
data_finished_fsm <= '1';
end if;
start_ch_fsm <= 0;
idle_fsm <= '1';
rd_fsm_debug_fsm <= x"1";
-
- --when WR_HEADER_A =>
- -- RD_NEXT <= WAIT_FOR_TRIG_WIND_END;
- -- wr_header_fsm <= '1';
- -- readout_fsm <= '1';
- -- rd_fsm_debug_fsm <= x"3";
when WAIT_FOR_TRIG_WIND_END =>
if TRIG_WIN_END_RDO_IN = '1' then
- RD_NEXT <= WAIT_FOR_BUFFER_TRANSFER; --RD_CH;
+ RD_NEXT <= WAIT_FOR_BUFFER_TRANSFER;
end if;
wait_fsm <= '1';
rd_fsm_debug_fsm <= x"2";
rd_fsm_debug_fsm <= x"3";
when RD_CH =>
- if CH_EMPTY_IN(fifo_nr_rd) = '0' then
+ if CH_EMPTY_IN(fifo_nr_rd) = '0' then -- read from channel if not empty
rd_en_fsm(fifo_nr_rd) <= '1';
fifo_nr_rd_fsm <= fifo_nr_rd;
- rd_fsm_debug_fsm <= x"B";
- elsif fifo_nr_rd = CHANNEL_NUMBER-1 then
+ elsif fifo_nr_rd = CHANNEL_NUMBER-1 then -- the last channel
rd_en_fsm(fifo_nr_rd) <= '0';
- if DEBUG_MODE_EN_IN = '1' then
+ if DEBUG_MODE_EN_IN = '1' then -- send status after channel data
RD_NEXT <= SEND_STATUS;
else
- RD_NEXT <= WAIT_FOR_LVL1_TRIG_A;
+ RD_NEXT <= WAIT_FOR_DATA_FINISHED; -- WAIT_FOR_LVL1_TRIG_A;
end if;
- rd_fsm_debug_fsm <= x"C";
- else
+ else -- go to the next channel
fifo_nr_rd_fsm <= fifo_nr_rd + 1;
start_ch_fsm <= start_ch_i + 1;
- rd_fsm_debug_fsm <= x"D";
end if;
readout_fsm <= '1';
--- rd_fsm_debug_fsm <= x"4";
+ rd_fsm_debug_fsm <= x"4";
- when WAIT_FOR_LVL1_TRIG_A =>
+ when WAIT_FOR_DATA_FINISHED => -- wait until the end of the data transfer
+ if finished_i = '1' then
+ RD_NEXT <= WAIT_FOR_LVL1_TRIG_A;
+ end if;
+ wait_fsm <= '1';
+ rd_fsm_debug_fsm <= x"5";
+
+ when WAIT_FOR_LVL1_TRIG_A => -- wait for trigger data valid
if TRG_DATA_VALID_IN = '1' then
RD_NEXT <= WAIT_FOR_LVL1_TRIG_B;
elsif TMGTRG_TIMEOUT_IN = '1' then
RD_NEXT <= IDLE;
end if;
wait_fsm <= '1';
- rd_fsm_debug_fsm <= x"5";
+ rd_fsm_debug_fsm <= x"6";
when WAIT_FOR_LVL1_TRIG_B =>
RD_NEXT <= WAIT_FOR_LVL1_TRIG_C;
wait_fsm <= '1';
- rd_fsm_debug_fsm <= x"6";
+ rd_fsm_debug_fsm <= x"7";
when WAIT_FOR_LVL1_TRIG_C =>
if SPURIOUS_TRG_IN = '1' then
end if;
RD_NEXT <= SEND_TRIG_RELEASE_A;
wait_fsm <= '1';
- rd_fsm_debug_fsm <= x"7";
+ rd_fsm_debug_fsm <= x"8";
when SEND_STATUS =>
if stop_status_i = '1' then
wr_status_fsm <= '1';
end if;
readout_fsm <= '1';
- rd_fsm_debug_fsm <= x"8";
+ rd_fsm_debug_fsm <= x"9";
when SEND_TRIG_RELEASE_A =>
RD_NEXT <= SEND_TRIG_RELEASE_B;
trig_release_fsm <= '1';
fifo_nr_rd_fsm <= 0;
readout_fsm <= '1';
- rd_fsm_debug_fsm <= x"9";
+ rd_fsm_debug_fsm <= x"A";
when SEND_TRIG_RELEASE_B =>
RD_NEXT <= IDLE;
wait_fsm <= '1';
- rd_fsm_debug_fsm <= x"A";
+ rd_fsm_debug_fsm <= x"B";
when others =>
RD_NEXT <= IDLE;
end process WR_FSM_CLK;
WR_FSM : process (WR_CURRENT, wr_number, fifo_nr_wr, DATA_LIMIT_IN, start_write, CH_DATA_VALID_IN,
- start_ch_4reg)
+ start_ch_4reg, ch_data_2reg)
begin
else
wr_ch_data_fsm <= '1';
end if;
- wr_number_fsm <= wr_number + to_unsigned(1, 1);
- fifo_nr_wr_fsm <= fifo_nr_wr;
+ wr_number_fsm <= wr_number + to_unsigned(1, 8);
+ fifo_nr_wr_fsm <= fifo_nr_wr;
wr_fsm_debug_fsm <= x"4";
elsif fifo_nr_wr = CHANNEL_NUMBER-1 then
- wr_number_fsm <= (others => '0');
- wr_finished_fsm <= '1';
- WR_NEXT <= IDLE;
+ wr_number_fsm <= (others => '0');
+ wr_finished_fsm <= '1';
+ WR_NEXT <= IDLE;
wr_fsm_debug_fsm <= x"5";
elsif CH_DATA_VALID_IN(fifo_nr_wr) = '1' then
- wr_number_fsm <= wr_number;
- fifo_nr_wr_fsm <= fifo_nr_wr;
+ wr_number_fsm <= wr_number;
+ fifo_nr_wr_fsm <= fifo_nr_wr;
wr_fsm_debug_fsm <= x"6";
else
- wr_number_fsm <= (others => '0');
- fifo_nr_wr_fsm <= fifo_nr_wr + 1;
- WR_NEXT <= WAIT_A;
+ wr_number_fsm <= (others => '0');
+ fifo_nr_wr_fsm <= fifo_nr_wr + 1;
+ WR_NEXT <= WAIT_A;
wr_fsm_debug_fsm <= x"7";
end if;
-- wr_fsm_debug_fsm <= x"2";
STATUS_REGISTERS_BUS_OUT(17)(23 downto 0) <= std_logic_vector(timeout_number);
STATUS_REGISTERS_BUS_OUT(18)(23 downto 0) <= std_logic_vector(finished_number);
- STATUS_REGISTERS_BUS_OUT(19)(4 downto 0) <= CH_EMPTY_IN;
- STATUS_REGISTERS_BUS_OUT(19)(11 downto 8) <= std_logic_vector(to_unsigned(fifo_nr_rd, 4));
- STATUS_REGISTERS_BUS_OUT(20)(0) <= wr_ch_data_reg;
- STATUS_REGISTERS_BUS_OUT(20)(11 downto 8) <= std_logic_vector(to_unsigned(fifo_nr_wr, 4));
- STATUS_REGISTERS_BUS_OUT(20)(31 downto 16) <= ch_data_2reg(fifo_nr_wr)(35 downto 20);
-
+ debug0 : process (CLK_100)
+ begin
+ if rising_edge(CLK_100) then
+ if (wr_fsm_debug /= wr_fsm_debug_fsm) then
+ status_registers_bus_i(3 downto 0) <= wr_fsm_debug;
+ end if;
+ end if;
+ end process debug0;
+
+ GEN_Debug: for i in 0 to 6 generate
+ debug : process (CLK_100)
+ begin
+ if rising_edge(CLK_100) then
+ if wr_fsm_debug /= wr_fsm_debug_fsm then
+ status_registers_bus_i((i+1)*4+3 downto (i+1)*4) <= status_registers_bus_i(i*4+3 downto i*4);
+ end if;
+ end if;
+ end process debug;
+ end generate GEN_Debug;
+ STATUS_REGISTERS_BUS_OUT(19) <= status_registers_bus_i;
+
+ --STATUS_REGISTERS_BUS_OUT(19)(4 downto 0) <= CH_EMPTY_IN;
+ --STATUS_REGISTERS_BUS_OUT(19)(11 downto 8) <= std_logic_vector(to_unsigned(fifo_nr_rd, 4));
+ --STATUS_REGISTERS_BUS_OUT(20)(0) <= wr_ch_data_reg;
+ --STATUS_REGISTERS_BUS_OUT(20)(11 downto 8) <= std_logic_vector(to_unsigned(fifo_nr_wr, 4));
+ --STATUS_REGISTERS_BUS_OUT(20)(31 downto 16) <= ch_data_2reg(fifo_nr_wr)(35 downto 20);
+
FILL_BUS1 : for i in 4 to 18 generate
STATUS_REGISTERS_BUS_OUT(i)(31 downto 24) <= (others => '0');
end generate FILL_BUS1;
entity TDC is
generic (
CHANNEL_NUMBER : integer range 2 to 65;
+ STATUS_REG_NR : integer range 0 to 31;
CONTROL_REG_NR : integer range 0 to 6;
TDC_VERSION : std_logic_vector(11 downto 0);
DEBUG : integer range 0 to 1 := c_YES;
signal epoch_cntr_up_i : std_logic;
signal epoch_cntr_reset_i : std_logic;
-- Trigger Handler signals
+ signal trig_in_i : std_logic;
signal trig_rdo_i : std_logic;
signal trig_tdc_i : std_logic;
signal trig_win_en_i : std_logic;
signal ch_200_debug_i : std_logic_vector_array_32(0 to CHANNEL_NUMBER-1);
signal readout_debug_i : std_logic_vector(31 downto 0);
-- Bus signals
- signal status_registers_bus_i : std_logic_vector_array_32(0 to 21);
+ signal status_registers_bus_i : std_logic_vector_array_32(0 to STATUS_REG_NR-1);
attribute syn_keep : boolean;
attribute syn_keep of reset_tdc : signal is true;
TRIGGER_WIN_END_TDC => trig_win_end_tdc,
TRIGGER_WIN_END_RDO => trig_win_end_rdo,
EPOCH_COUNTER_IN => epoch_cntr,
- COARSE_COUNTER_IN => coarse_cntr(integer(floor(real(i)/real(16)))+1),
+ COARSE_COUNTER_IN => coarse_cntr(integer(ceil(real(i)/real(16)))),
READ_EN_IN => rd_en_i(i),
FIFO_DATA_OUT => ch_data_i(i),
FIFO_DATA_VALID_OUT => ch_data_valid_i(i),
RESET_TRG => reset_rdo,
RESET_RDO => reset_rdo,
RESET_TDC => reset_tdc,
- TRIGGER_IN(0) => REFERENCE_TIME,
+ TRIGGER_IN(0) => trig_in_i, --REFERENCE_TIME,
TRIGGER_RDO_OUT(0) => trig_rdo_i,
TRIGGER_TDC_OUT(0) => trig_tdc_i,
TRIGGER_WIN_EN_IN => trig_win_en_i,
TRIGGER_WIN_POST_IN => unsigned(TRG_WIN_POST),
TRIGGER_WIN_END_RDO_OUT => trig_win_end_rdo,
TRIGGER_WIN_END_TDC_OUT => trig_win_end_tdc);
-
+ trig_in_i <= REFERENCE_TIME or VALID_NOTIMING_TRG_IN;
+
-- Readout
TheReadout : Readout
generic map (
CHANNEL_NUMBER => CHANNEL_NUMBER,
+ STATUS_REG_NR => STATUS_REG_NR,
TDC_VERSION => TDC_VERSION)
port map (
RESET_100 => reset_rdo,
COARSE_COUNTER_IN => coarse_cntr(1),
EPOCH_COUNTER_IN => epoch_cntr,
DEBUG_MODE_EN_IN => debug_mode_en_i,
- STATUS_REGISTERS_BUS_OUT => status_registers_bus_i(0 to 20),
+ STATUS_REGISTERS_BUS_OUT => status_registers_bus_i,
READOUT_DEBUG => readout_debug_i,
REFERENCE_TIME => REFERENCE_TIME,
-- ports not used after tdc_v1.5.2
TheStatusRegistersBus : BusHandler
generic map (
- BUS_LENGTH => 21)
+ BUS_LENGTH => STATUS_REG_NR - 1)
port map (
RESET => reset_rdo,
CLK => CLK_READOUT,
DATAREADY_OUT => SRB_DATAREADY_OUT,
UNKNOWN_ADDR_OUT => SRB_UNKNOWN_ADDR_OUT);
- status_registers_bus_i(21) <= ch_200_debug_i(0);
+-- status_registers_bus_i(21) <= ch_200_debug_i(0);
--TheLostHitBus : BusHandler
-- generic map (