#Trigger from fan-out
LOCATE COMP "TRIGGER_LEFT" SITE "V3";
#LOCATE COMP "TRIGGER_RIGHT" SITE "N24";
-#IOBUF PORT "TRIGGER_RIGHT" IO_TYPE=LVDS25 ;
+#IOBUF PORT "TRIGGER_RIGHT" IO_TYPE=LVDS25 ;
IOBUF PORT "TRIGGER_LEFT" IO_TYPE=LVDS25 ;
###########################################################
MULTICYCLE FROM CELL "THE_RESET_HANDLER/final_reset*" 50 ns;
MULTICYCLE FROM CELL "THE_RESET_HANDLER/reset" TO CELL "THE_RESET_HANDLER/final_reset[0]" 10 ns;
+MULTICYCLE FROM CELL "MupixBoard8_0/mupix_reset/stretcher/stretched" 25 ns;
+MULTICYCLE FROM CELL "MupixBoard8_0/mupix_reset/tsreset_reg" 25 ns;
--- /dev/null
+--------------------------------------------------------
+-- handle the reset signal to the mupix timestamps
+-- Tobias Weber
+-- Ruhr University Bochum
+-------------------------------------------------------
+library IEEE;
+use IEEE.std_logic_1164.all;
+use IEEE.numeric_std.all;
+
+entity MupixReset is
+ port(
+ mupixclk : in std_logic; -- mupix clock (40-125 MHz)
+ trbclk : in std_logic; -- trbnet clock (100 MHz)
+ trbreset : in std_logic; -- trb reset
+ timestamp_rst : in std_logic; -- reset timestamps signal
+ syncres : out std_logic -- sync signal to mupix timestamp generator
+ );
+end entity MupixReset;
+
+architecture rtl of MupixReset is
+
+ signal timestamp_ack : std_logic := '0'; -- timestamp reset acknowledge
+ signal tsreset_reg : std_logic := '0'; -- timestamp reset register
+ signal syncres_i : std_logic := '0';
+ signal slowrest_i : std_logic := '0';
+
+ type reset_fsm is (idle, acknowledge);
+ type hold_fsm is (idle, hold);
+ signal reseter : reset_fsm := idle;
+ signal holder : hold_fsm := idle;
+
+ component SignalStretcher is
+ generic (
+ fast_clock_speed : integer;
+ slow_clock_speed : integer);
+ port (
+ fast_clk : in std_logic;
+ reset : in std_logic;
+ pulse : in std_logic;
+ stretched : out std_logic);
+ end component SignalStretcher;
+
+ begin
+
+ stretcher: SignalStretcher
+ generic map(
+ fast_clock_speed => 10,
+ slow_clock_speed => 25
+ )
+ port map(
+ fast_clk => trbclk,
+ reset => trbreset,
+ pulse => trbreset,
+ stretched => slowrest_i
+ );
+
+ -- handshake mechanism as mupix clock is (at the moment) slower
+ -- than the TRB clock
+ hold_proc : process(trbclk)
+ begin
+ if rising_edge(trbclk) then
+ if trbreset = '1' then
+ holder <= idle;
+ tsreset_reg <= '0';
+ else
+ case holder is
+ when idle =>
+ if timestamp_rst = '1' then
+ tsreset_reg <= '1';
+ holder <= hold;
+ end if;
+ when hold =>
+ if timestamp_ack = '1' then
+ tsreset_reg <= '0';
+ holder <= idle;
+ end if;
+ end case;
+ end if;
+ end if;
+ end process;
+
+ reset_proc : process(mupixclk)
+ variable counter : integer range 0 to 3 := 0;
+ begin
+ if falling_edge(mupixclk) then
+ if slowrest_i = '1' then
+ syncres_i <= '0';
+ timestamp_ack <= '0';
+ reseter <= idle;
+ else
+ case reseter is
+ when idle =>
+ counter := 0;
+ syncres_i <= '0';
+ timestamp_ack <= '0';
+ if tsreset_reg = '1' then
+ reseter <= acknowledge;
+ end if;
+ when acknowledge =>
+ counter := counter + 1;
+ timestamp_ack <= '1';
+ syncres_i <= '1';
+ if counter = 3 then
+ reseter <= idle;
+ end if;
+ end case;
+ end if;
+ end if;
+ end process;
+
+ pipe_proc : process(mupixclk)
+ begin
+ if falling_edge(mupixclk) then
+ syncres <= syncres_i;
+ end if;
+ end process;
+
+end architecture;
dataout : out std_logic_vector(g_datawidthtrb - 1 downto 0); -- data to TRB data channel
data_valid : out std_logic; -- output data is valid
busy : out std_logic; -- readout controller is busy
+ eventcounter_reset : in std_logic; -- event counter reset from TRB broadcast
+ timestampreset : in std_logic; -- time stamp reset from TRB broadcast
-- TRB slow Control channel
SLV_READ_IN : in std_logic;
SLV_WRITE_IN : in std_logic;
counterA_in : in std_logic_vector(DWidth - 1 downto 0); -- last counter value link A
counterB_in : in std_logic_vector(DWidth - 1 downto 0); -- last counter value link B
counterC_in : in std_logic_vector(DWidth - 1 downto 0); -- last counter value link C
-
+
dataout : out std_logic_vector(DWidth - 1 downto 0); -- decoded data word
dataout_valid : out std_logic; -- valid output data
counterA_out : out std_logic_vector(DWidth - 1 downto 0); -- last counter value link A
empty : in std_logic;
almost_empty : in std_logic;
sensor_id : in std_logic_vector(g_datawidth - 1 downto 0);
+ eventcounter_rst : in std_logic;
+ timestamprst : in std_logic;
offset_en : out std_logic;
rd_en : out std_logic;
busy : out std_logic;
counterA_in => mupix_filter_counterA_i,
counterB_in => mupix_filter_counterB_i,
counterC_in => mupix_filter_counterC_i,
-
+
dataout => decoder_dataout_i,
dataout_valid => decoder_dataout_valid_i,
counterA_out => decoder_counterA_i,
empty => cycl_empty,
almost_empty => cycl_almost_empty,
sensor_id => sensor_id,
+ eventcounter_rst => eventcounter_reset,
+ timestamprst => timestampreset,
offset_en => readout_controller_offset_en,
rd_en => readout_controller_rd_en,
busy => readout_controller_busy,
empty : in std_logic; --empty flag from circular buffer
almost_empty : in std_logic; --empty flag from circular buffer
sensor_id : in std_logic_vector(g_datawidth - 1 downto 0);
+ eventcounter_rst : in std_logic; -- event counter reset from TRB broadcast
+ timestamprst : in std_logic; -- time stamp reset from TRB broadcast
offset_en : out std_logic; -- set offset between read and write pointer (offset value is set directly in circular buffer)
rd_en : out std_logic; -- read enable to circular buffer
busy : out std_logic; -- readout controller busy
signal wordcounter : unsigned(g_addresswidth - 1 downto 0) := (others => '0');
signal framecounter : unsigned(31 downto 0) := (others => '0');
+ signal framecounter_inc : std_logic := '0';
signal headercounter : integer range 0 to 3 := 0;
signal trailercounter : integer range 0 to 1 := 0;
signal triggerwaitcounter : unsigned(g_addresswidth - 1 downto 0) := (others => '0');
timestamps : process(clk)
begin
if rising_edge(clk) then
- if rst = '1' then
+ if rst = '1' or timestamprst = '1' then
timestamp_cnt <= (others => '0');
else
timestamp_cnt <= timestamp_cnt + 1;
end if;
end process timestamps;
+ framecnt_proc : process(clk)
+ begin
+ if rising_edge(clk) then
+ if rst = '1' or eventcounter_rst = '1' then
+ framecounter <= (others => '0');
+ else
+ if framecounter_inc = '1' then
+ framecounter <= framecounter + 1;
+ end if;
+ end if;
+ end if;
+ end process framecnt_proc;
+
edge_detection : process (clk) is
begin
if rising_edge(clk) then
busy <= '0';
data_valid <= '0';
data_out <= (others => '0');
- framecounter <= (others => '0');
+ framecounter_inc <= '0';
headercounter <= 0;
else
busy <= '0';
data_out <= (others => '0');
rd_en <= '0';
offset_en <= '0';
+ framecounter_inc <= '0';
case readout_fsm is
when idle =>
trailercounter <= 0;
headercounter <= 3;
when 3 =>
data_out <= std_logic_vector(framecounter);
- framecounter <= framecounter + 1;
+ framecounter_inc <= '1';
if mode = "01" then
if empty = '0' then
readout_fsm <= wait_memory;
--entities on an peripherial FPGA.
--T. Weber, University Mainz
------------------------------------------------------------
-
library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
-entity resethandler is
+entity resethandler is
port (
- CLK_IN : in std_logic; -- system clock
+ CLK_IN : in std_logic; -- system clock
RESET_IN : in std_logic; -- reset input
timestampreset_out : out std_logic; -- reset FPGA timestamps
eventcounterreset_out : out std_logic; -- reset FPGA event counters
- -- Slave bus
+ -- Slave bus
SLV_READ_IN : in std_logic;
SLV_WRITE_IN : in std_logic;
SLV_DATA_OUT : out std_logic_vector(31 downto 0);
signal eventcounterreset_i : std_logic := '0';
signal timestampreset_edge : std_logic_vector(1 downto 0) := (others => '0');
signal eventcounterreset_edge : std_logic_vector(1 downto 0) := (others => '0');
-
+
begin -- architecture behavioral
end if;
end if;
end process eventcounter_edge_detect;
-
+
------------------------------------------------------------
--TRB SLV-BUS Hanlder
end if;
end if;
end process slv_bus_handler;
-
+
end architecture behavioral;
spi_cs_adc : out std_logic; --load adc
spi_ld_thres : out std_logic; --load threshold and injection dac
hitbus : in std_logic; --hitbus signal
+ syncres : out std_logic; --syncres for timestamp reset
mupix_data : in std_logic_vector(7 downto 0); --serdes data link from mupix
channel_status_led : out std_logic_vector(3 downto 0); --status leds of serdes connection
dataout : out std_logic_vector(g_datawidthtrb - 1 downto 0);
data_valid : out std_logic;
busy : out std_logic;
+ eventcounter_reset : in std_logic;
+ timestampreset : in std_logic;
SLV_READ_IN : in std_logic;
SLV_WRITE_IN : in std_logic;
SLV_DATA_OUT : out std_logic_vector(31 downto 0);
SLV_UNKNOWN_ADDR_OUT : out std_logic);
end component MupixDataLinkWithUnpacker;
+ component MupixReset is
+ port(
+ mupixclk : in std_logic;
+ trbclk : in std_logic;
+ trbreset : in std_logic;
+ timestamp_rst : in std_logic;
+ syncres : out std_logic
+ );
+ end component;
+
constant FIFO_DEPTH : positive := 256; --size of pseudo data generator fifos
signal mux_fifo_data : std_logic_vector(c_mupixhitsize*c_links - 1 downto 0);
dataout => mupixdata_i,
data_valid => mupixdata_valid_i,
busy => mupixreadout_busy_i,
+ eventcounter_reset => eventcounterreset_in,
+ timestampreset => timestampreset_in,
SLV_READ_IN => slv_read(3),
SLV_WRITE_IN => slv_write(3),
SLV_DATA_OUT => slv_data_rd(3*32 + 31 downto 3*32),
SLV_NO_MORE_DATA_OUT => slv_no_more_data(6),
SLV_UNKNOWN_ADDR_OUT => slv_unknown_addr(6));
+ mupix_reset: entity work.MupixReset
+ port map(
+ mupixclk => data_clk,
+ trbclk => clk,
+ trbreset => reset_reg,
+ timestamp_rst => timestampreset_in,
+ syncres => syncres
+ );
+
end Behavioral;
add_file -vhdl -lib "work" "sources/Utility/GrayCounter2.vhd"
add_file -vhdl -lib "work" "sources/Utility/FIFO.vhd"
add_file -vhdl -lib "work" "sources/Utility/CRC.vhd"
+add_file -vhdl -lib "work" "sources/Utility/SignalStretcher.vhd"
add_file -vhdl -lib "work" "sources/SlowControl/ADS1018SPI.vhd"
add_file -vhdl -lib "work" "sources/SlowControl/LTC1658SPI.vhd"
add_file -vhdl -lib "work" "sources/Datapath/DataDecoder.vhd"
add_file -vhdl -lib "work" "sources/Datapath/PixelAddressDecode.vhd"
add_file -vhdl -lib "work" "sources/Datapath/Gray2Binary.vhd"
+add_file -vhdl -lib "work" "sources/Datapath/MupixReset.vhd"
add_file -vhdl -lib "work" "sources/Simulation/DatasourceSelector.vhd"
add_file -vhdl -lib "work" "sources/Simulation/FrameGeneratorMux.vhd"
spi_cs_adc : out std_logic; --load adc
spi_ld_thres : out std_logic; --load threshold and injection dac
hitbus : in std_logic; --hitbus signal
+ syncres : out std_logic;
mupix_data : in std_logic_vector(7 downto 0);
channel_status_led : out std_logic_vector(3 downto 0);
spi_cs_adc => spi_ld_adc,
spi_ld_thres => spi_ld_thres,
hitbus => hitbus,
+ syncres => syncres,
TIMING_TRG_IN => TRIGGER_RIGHT,
LVL1_TRG_DATA_VALID_IN => trg_data_valid_i,