package config is
-
------------------------------------------------------------------------------
--Begin of design configuration
------------------------------------------------------------------------------
---Include GbE logic
- constant NUM_TDC_CHANNELS : integer range 1 to 65 := 65;
- constant NUM_TDC_CHANNELS_POWER2 : integer range 0 to 6 := 6; --the nearest power of two, for convenience reasons
- constant USE_DOUBLE_EDGE : integer := c_YES;
+--TDC settings
+ constant NUM_TDC_MODULES : integer range 1 to 4 := 4; -- number of tdc modules to implement
+ constant NUM_TDC_CHANNELS : integer range 1 to 65 := 16; -- number of tdc channels per module
+ constant NUM_TDC_CHANNELS_POWER2 : integer range 0 to 6 := 6; --the nearest power of two, for convenience reasons
+ constant USE_DOUBLE_EDGE : integer := c_YES;
+ constant RING_BUFFER_SIZE : integer range 0 to 7 := 0; --ring buffer size: 0, 1, 2, 3
+ --ring buffer size: 32,64,96,128
---Include SPI on AddOn connector
+--Include SPI on AddOn connector
constant INCLUDE_SPI : integer := c_YES;
--Add logic to generate configurable trigger signal from input signals.
- constant INCLUDE_TRIGGER_LOGIC : integer := c_YES;
-
---Do histos of all inputs
- constant INCLUDE_STATISTICS : integer := c_YES;
-
---number of real inputs to the FPGA
- constant PHYSICAL_INPUTS : integer := 32;
-
---Define ringbuffer size for TDC channels: 32-64-128
- constant RING_BUFFER_SIZE : integer range 32 to 128 := 128;
-
---Run wih 125 MHz instead of 100 MHz
- constant USE_125_MHZ : integer := c_NO; --not implemented yet!
-
---Use sync mode, RX clock for all parts of the FPGA
- constant USE_RXCLOCK : integer := c_NO; --not implemented yet!
+ constant INCLUDE_TRIGGER_LOGIC : integer := c_YES;
+ constant INCLUDE_STATISTICS : integer := c_YES; --Do histos of all inputs
+ constant PHYSICAL_INPUTS : integer := 8; --number of inputs connected
+--Run wih 125 MHz instead of 100 MHz, use received clock from serdes or external clock input
+ constant USE_125_MHZ : integer := c_NO; --not implemented yet!
+ constant USE_RXCLOCK : integer := c_NO; --not implemented yet!
+ constant USE_EXTERNALCLOCK : integer := c_NO; --not implemented yet!
--Address settings
constant INIT_ADDRESS : std_logic_vector := x"F305";
------------------------------------------------------------------------------
+
------------------------------------------------------------------------------
--Select settings by configuration
------------------------------------------------------------------------------
type intlist_t is array(0 to 7) of integer;
type hw_info_t is array(0 to 7) of unsigned(31 downto 0);
constant HW_INFO_BASE : unsigned(31 downto 0) := x"91007000";
- constant HW_INFO_SPI : hw_info_t := (x"00000000", x"00000400", others => x"00000000");
- constant HW_INFO_DOUBLE_EDGE : hw_info_t := (x"00000000", x"00000800", others => x"00000000");
- constant HW_INFO_NUM_CHANS : hw_info_t := (x"00000000", x"00000010", x"00000020", x"00000030",
- x"00000040", x"00000050", x"00000060", x"00000070",
- others => x"00000000");
constant CLOCK_FREQUENCY_ARR : intlist_t := (100, 125, others => 0);
constant MEDIA_FREQUENCY_ARR : intlist_t := (200, 125, others => 0);
constant HARDWARE_INFO : std_logic_vector(31 downto 0);
constant CLOCK_FREQUENCY : integer;
constant MEDIA_FREQUENCY : integer;
+ constant INCLUDED_FEATURES : std_logic_vector(63 downto 0);
+
+function generateIncludedFeatures return std_logic_vector;
+
+
end;
package body config is
--compute correct configuration mode
- constant HARDWARE_INFO : std_logic_vector(31 downto 0) := std_logic_vector(
- HW_INFO_BASE + HW_INFO_SPI(INCLUDE_SPI) + HW_INFO_DOUBLE_EDGE(USE_DOUBLE_EDGE) +
- HW_INFO_NUM_CHANS(NUM_TDC_CHANNELS_POWER2));
+function generateIncludedFeatures return std_logic_vector is
+ variable t : std_logic_vector(63 downto 0);
+begin
+ t := (others => '0');
+ t(63 downto 56) := std_logic_vector(to_unsigned(2,8)); --table version 2
+ t(7 downto 0) := std_logic_vector(to_unsigned(1,8));
+ t(11 downto 8) := std_logic_vector(to_unsigned(USE_DOUBLE_EDGE*2,4));
+ t(14 downto 12) := std_logic_vector(to_unsigned(RING_BUFFER_SIZE,3));
+ t(15) := '1'; --TDC
+ t(17 downto 16) := std_logic_vector(to_unsigned(NUM_TDC_MODULES-1,2));
+ t(42 downto 42) := std_logic_vector(to_unsigned(INCLUDE_SPI,1));
+ t(44 downto 44) := std_logic_vector(to_unsigned(INCLUDE_STATISTICS,1));
+ t(51 downto 48) := std_logic_vector(to_unsigned(INCLUDE_TRIGGER_LOGIC,4));
+ t(52 downto 52) := std_logic_vector(to_unsigned(USE_125_MHZ,1));
+ t(53 downto 53) := std_logic_vector(to_unsigned(USE_RXCLOCK,1));
+ t(54 downto 54) := std_logic_vector(to_unsigned(USE_EXTERNALCLOCK,1));
+ return t;
+end function;
+
+ constant HARDWARE_INFO : std_logic_vector(31 downto 0) := std_logic_vector( HW_INFO_BASE );
constant CLOCK_FREQUENCY : integer := CLOCK_FREQUENCY_ARR(USE_125_MHZ);
constant MEDIA_FREQUENCY : integer := MEDIA_FREQUENCY_ARR(USE_125_MHZ);
+ constant INCLUDED_FEATURES : std_logic_vector := generateIncludedFeatures;
end package body;
use work.trb_net_std.all;
use work.trb_net_components.all;
use work.trb3_components.all;
+use work.tdc_components.all;
use work.config.all;
use work.tdc_version.all;
use work.version.all;
signal trg_spike_detected_i : std_logic;
--Data channel
- signal fee_trg_release_i : std_logic;
- signal fee_trg_statusbits_i : std_logic_vector(31 downto 0);
- signal fee_data_i : std_logic_vector(31 downto 0);
- signal fee_data_write_i : std_logic;
- signal fee_data_finished_i : std_logic;
- signal fee_almost_full_i : std_logic;
+ signal fee_trg_release_i : std_logic_vector(NUM_TDC_MODULES-1 downto 0);
+ signal fee_trg_statusbits_i : std_logic_vector_array_32(0 to NUM_TDC_MODULES-1);
+ signal fee_data_i : std_logic_vector_array_32(0 to NUM_TDC_MODULES-1);
+ signal fee_data_write_i : std_logic_vector(NUM_TDC_MODULES-1 downto 0);
+ signal fee_data_finished_i : std_logic_vector(NUM_TDC_MODULES-1 downto 0);
+ signal fee_almost_full_i : std_logic_vector(NUM_TDC_MODULES-1 downto 0);
+ signal fee_trg_statusbits : std_logic_vector(NUM_TDC_MODULES*32-1 downto 0);
+ signal fee_data : std_logic_vector(NUM_TDC_MODULES*32-1 downto 0);
--Slow Control channel
signal common_stat_reg : std_logic_vector(std_COMSTATREG*32-1 downto 0);
BROADCAST_SPECIAL_ADDR => BROADCAST_SPECIAL_ADDR,
REGIO_COMPILE_TIME => std_logic_vector(to_unsigned(VERSION_NUMBER_TIME, 32)),
REGIO_HARDWARE_VERSION => HARDWARE_INFO,
+ REGIO_INCLUDED_FEATURES => INCLUDED_FEATURES,
REGIO_INIT_ADDRESS => INIT_ADDRESS,
REGIO_USE_VAR_ENDPOINT_ID => c_YES,
CLOCK_FREQUENCY => CLOCK_FREQUENCY,
TIMING_TRIGGER_RAW => c_YES,
--Configure data handler
- DATA_INTERFACE_NUMBER => 1,
- DATA_BUFFER_DEPTH => 13, --13
+ DATA_INTERFACE_NUMBER => NUM_TDC_MODULES, --1,
+ DATA_BUFFER_DEPTH => 12, --13,
DATA_BUFFER_WIDTH => 32,
- DATA_BUFFER_FULL_THRESH => 2**13-800, --2**13-(maximal 2**12)
+ DATA_BUFFER_FULL_THRESH => 2**12-400, --2**13-800,
TRG_RELEASE_AFTER_DATA => c_YES,
HEADER_BUFFER_DEPTH => 9,
HEADER_BUFFER_FULL_THRESH => 2**9-16
TRG_SPIKE_DETECTED_OUT => trg_spike_detected_i,
--Response from FEE
- FEE_TRG_RELEASE_IN(0) => fee_trg_release_i,
- FEE_TRG_STATUSBITS_IN => fee_trg_statusbits_i,
- FEE_DATA_IN => fee_data_i,
- FEE_DATA_WRITE_IN(0) => fee_data_write_i,
- FEE_DATA_FINISHED_IN(0) => fee_data_finished_i,
- FEE_DATA_ALMOST_FULL_OUT(0) => fee_almost_full_i,
+ FEE_TRG_RELEASE_IN(NUM_TDC_MODULES-1 downto 0) => fee_trg_release_i,
+ FEE_TRG_STATUSBITS_IN => fee_trg_statusbits,
+ FEE_DATA_IN => fee_data,
+ FEE_DATA_WRITE_IN(NUM_TDC_MODULES-1 downto 0) => fee_data_write_i,
+ FEE_DATA_FINISHED_IN(NUM_TDC_MODULES-1 downto 0) => fee_data_finished_i,
+ FEE_DATA_ALMOST_FULL_OUT(NUM_TDC_MODULES-1 downto 0) => fee_almost_full_i,
+
-- Slow Control Data Port
REGIO_COMMON_STAT_REG_IN => common_stat_reg, --0x00
common_stat_reg <= (others => '0');
stat_reg <= (others => '0');
+ Allign_Bits : for i in 0 to NUM_TDC_MODULES-1 generate
+ fee_trg_statusbits((i+1)*32-1 downto i*32) <= fee_trg_statusbits_i(i)(31 downto 0);
+ fee_data((i+1)*32-1 downto i*32) <= fee_data_i(i)(31 downto 0);
+ end generate Allign_Bits;
+
---------------------------------------------------------------------------
-- AddOn
---------------------------------------------------------------------------
THE_BUS_HANDLER : trb_net16_regio_bus_handler
generic map(
PORT_NUMBER => 10,
- PORT_ADDRESSES => (0 => x"d000", 1 => x"d100", 2 => x"d400", 3 => x"c000", 4 => x"c100",
- 5 => x"c800", 6 => x"cf00", 7 => x"cf80", 8 => x"d500", 9 => x"c200", --c300 c400
+ PORT_ADDRESSES => (0 => x"d000", 1 => x"d100", 2 => x"d400", 3 => x"c000", 4 => x"c100",
+ 5 => x"c800", 6 => x"cf00", 7 => x"cf80", 8 => x"d500", 9 => x"c200", --c300 c400
others => x"0000"),
- PORT_ADDR_MASK => (0 => 1, 1 => 6, 2 => 5, 3 => 7, 4 => 5,
- 5 => 3, 6 => 6, 7 => 7, 8 => 4, 9 => 7,
+ PORT_ADDR_MASK => (0 => 1, 1 => 6, 2 => 5, 3 => 7, 4 => 5,
+ 5 => 3, 6 => 6, 7 => 7, 8 => 4, 9 => 7,
others => 0)
)
port map(
gen_TRIGGER_LOGIC : if INCLUDE_TRIGGER_LOGIC = 1 generate
THE_TRIG_LOGIC : input_to_trigger_logic
generic map(
- INPUTS => 32,
+ INPUTS => PHYSICAL_INPUTS,
OUTPUTS => 4
)
port map(
CLK => clk_100_i,
- INPUT => INP(32 downto 1),
+ INPUT => INP(PHYSICAL_INPUTS-1 downto 0),
OUTPUT => trig_out,
DATA_IN => trig_din,
THE_TDC : TDC
generic map (
- CHANNEL_NUMBER => NUM_TDC_CHANNELS, -- Number of TDC channels
+ MODULE_NUMBER => NUM_TDC_MODULES, -- Number of TDC modules
+ CHANNEL_NUMBER => NUM_TDC_CHANNELS, -- Number of channels per module
STATUS_REG_NR => 21, -- Number of status regs
CONTROL_REG_NR => 6, -- Number of control regs - higher than 8 check tdc_ctrl_addr
TDC_VERSION => TDC_VERSION, -- TDC version number
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(NUM_TDC_CHANNELS-1 downto 1), -- Channel start signals
+ HIT_IN => hit_in_i(NUM_TDC_MODULES*NUM_TDC_CHANNELS downto 1), -- Channel start signals
HIT_CALIBRATION => osc_int, -- 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
LOGIC_ANALYSER_OUT => logic_analyser_i,
CONTROL_REG_IN => tdc_ctrl_reg);
- -- For single edge measurements
+-- For single edge measurements
gen_single : if USE_DOUBLE_EDGE = 0 generate
hit_in_i <= INP;
end generate;