-version.vhd
XilinxProjects
.settings
.library_mapping.xml
.project
.directory
-vivado*
\ No newline at end of file
+vivado*
use ieee.numeric_std.all;
entity FrameGenerator is
- port(
- clk: in std_logic; --Taktsignal
- reset: in std_logic; --Reset
- trigger: in std_logic; --Startsignal zum Senden von Daten (wuerde sonst an MuPix gehen)
- data_out: out std_logic_vector(31 downto 0); --Datenpaket variabler Laenge, immer 32 Bit lang
- data_valid:out std_logic -- 1, wenn relevante Daten gesendet und mitgeschrieben werden sollte
- );
+ port(
+ clk : in std_logic; --Taktsignal
+ reset : in std_logic; --Reset
+ trigger : in std_logic; --Startsignal zum Senden von Daten (wuerde sonst an MuPix gehen)
+ data_out : out std_logic_vector(31 downto 0); --Datenpaket variabler Laenge, immer 32 Bit lang
+ data_valid : out std_logic; -- 1, wenn relevante Daten gesendet und mitgeschrieben werden sollte
+ data_finished : out std_logic); -- 1, wenn letztes datenwort gesendet wurde
end FrameGenerator;
-
+
architecture dataGeneration of FrameGenerator is
- component LinearFeedbackShiftRegister
- Port (
- lfsr_seed : in STD_LOGIC_VECTOR(3 downto 0);
- output_number : out STD_LOGIC_VECTOR(3 downto 0);
- clock : in std_logic;
- reset : in std_logic;
- start : in std_logic
- );
- end component;
-
- type ZUSTAENDE is (waiting, header, data, trailer);
- signal ZustandJetzt, Folge_Zustand: ZUSTAENDE;
- signal counter: integer range 0 to 2**4 - 1; -- veraenderliches Datenpaket
- signal trigger_edge : std_logic_vector(1 downto 0) := "00";
- signal lfsr_value, lfsr_value_i: std_logic_vector(3 downto 0); -- neuer Wert, der aus dem LinerFeedbackShiftRegister kommt
- signal start_signal : std_logic := '0';
-
-begin
+ component LinearFeedbackShiftRegister
+ port (
+ lfsr_seed : in std_logic_vector(3 downto 0);
+ output_number : out std_logic_vector(3 downto 0);
+ clock : in std_logic;
+ reset : in std_logic;
+ start : in std_logic
+ );
+ end component;
+
+ type ZUSTAENDE is (waiting, header, data, trailer);
+ signal ZustandJetzt : ZUSTAENDE := waiting;
+ signal counter : integer range 0 to 2**4 - 1; -- veraenderliches Datenpaket
+ signal trigger_edge : std_logic_vector(1 downto 0) := "00";
+ signal lfsr_value, lfsr_value_i : std_logic_vector(3 downto 0); -- neuer Wert, der aus dem LinerFeedbackShiftRegister kommt
+ signal start_signal : std_logic := '0';
+
+begin
+
+ lfsr1 : LinearFeedbackShiftRegister port map (clock => clk, reset => reset, output_number => lfsr_value, lfsr_seed => "0101", start => start_signal);
+
+ trigger_edge_detect : process(clk)
+ begin
+ if rising_edge(clk) then
+ if reset = '1' then
+ trigger_edge <= "00";
+ else
+ trigger_edge <= trigger_edge(0) & trigger; --dranhaengen beim vector, 01 ist der uebergang, der den Trigger darstellt
+ end if;
+ end if;
+ end process trigger_edge_detect;
+
+ Z_Aenderung : process(clk)
+ begin
+ if rising_edge(clk) then
+ case ZustandJetzt is
+ when waiting => data_valid <= '0';
+ data_finished <= '0';
+ data_out <= (others => '0');
+ if trigger_edge = "01" then
+ ZustandJetzt <= header;
+ else
+ ZustandJetzt <= waiting;
+ end if;
+
+ when header => data_valid <= '1';
+ data_out <= X"FABEABBA";
+ ZustandJetzt <= data;
+ counter <= 0;
+ lfsr_value_i <= lfsr_value;
+
+ when data => counter <= counter + 1;
+ if counter < to_integer(unsigned(lfsr_value_i)) then
+ data_valid <= '1';
+ data_out <= std_logic_vector(to_unsigned(counter, 32));
+ ZustandJetzt <= data;
+ else
+ ZustandJetzt <= trailer;
+ end if;
+
+ when trailer => data_valid <= '1';
+ data_finished <= '1';
+ data_out <= X"BEEFBEEF";
+ ZustandJetzt <= waiting;
- lfsr1: LinearFeedbackShiftRegister port map ( clock=>clk, reset=>reset,output_number =>lfsr_value, lfsr_seed => "0101", start => start_signal);
-
- trigger_edge_detect : process(clk)
- begin
- if rising_edge(clk) then
- if reset = '1' then
- trigger_edge <= "00";
- else
- trigger_edge <= trigger_edge(0) & trigger;--dranhaengen beim vector, 01 ist der uebergang, der den Trigger darstellt
- end if;
- end if;
- end process trigger_edge_detect;
+ end case;
+ end if;
+ end process Z_Aenderung;
- Z_Aenderung: process(clk)
- begin
- if rising_edge(clk) then
- case ZustandJetzt is
- when waiting => data_valid <= '0';
- data_out <= (others => '0');
- if trigger_edge = "01" then
- ZustandJetzt <= header;
- else
- ZustandJetzt <= waiting;
- end if;
-
- when header => data_valid <= '1';
- data_out <= X"FABEABBA";
- ZustandJetzt <= data;
- counter <= 0;
- lfsr_value_i <= lfsr_value;
-
- when data => counter <= counter + 1;
- if counter < to_integer(unsigned(lfsr_value_i)) then
- data_valid <= '1';
- data_out <= std_logic_vector(to_unsigned(counter, 32));
- ZustandJetzt <= data;
- else
- ZustandJetzt <= trailer;
- end if;
-
- when trailer => data_valid <= '1';
- data_out <= X"BEEFBEEF";
- ZustandJetzt <= waiting;
-
- end case;
- end if;
- end process Z_Aenderung;
-
- lfsr_val: process (clk)
- begin
- if (rising_edge(clk)) then
- if ZustandJetzt = header then
- start_signal <= '1';
- elsif ZustandJetzt = trailer then
- start_signal <= '0';
- end if;
- end if;
- end process lfsr_val;
+ lfsr_val : process (clk)
+ begin
+ if (rising_edge(clk)) then
+ if ZustandJetzt = header then
+ start_signal <= '1';
+ elsif ZustandJetzt = trailer then
+ start_signal <= '0';
+ end if;
+ end if;
+ end process lfsr_val;
end dataGeneration;
library IEEE;
-use IEEE.STD_LOGIC_1164.ALL;
-
-use IEEE.NUMERIC_STD.ALL;
+use IEEE.STD_LOGIC_1164.all;
+use IEEE.NUMERIC_STD.all;
entity LinearFeedbackShiftRegister is
- Port (
- lfsr_seed : in STD_LOGIC_VECTOR(3 downto 0);
- output_number : out STD_LOGIC_VECTOR(3 downto 0);
- clock : in std_logic;
- reset : in std_logic;
- start : in std_logic
- );
+ port (
+ lfsr_seed : in std_logic_vector(3 downto 0);
+ output_number : out std_logic_vector(3 downto 0);
+ clock : in std_logic;
+ reset : in std_logic;
+ start : in std_logic
+ );
end LinearFeedbackShiftRegister;
architecture Behavioral of LinearFeedbackShiftRegister is
-signal lfsr_speicher : std_logic_vector(3 downto 0);
-signal enable : std_logic := '0';
+ signal lfsr_speicher : std_logic_vector(3 downto 0);
+ signal enable : std_logic := '0';
begin
-output_number <= lfsr_speicher;
+ output_number <= lfsr_speicher;
-lfsr_output: process(clock, reset) begin
+ lfsr_output : process(clock, reset)
+ begin
if (reset = '1') then
- lfsr_speicher <= (others => '1');
- enable <='0';
+ lfsr_speicher <= (others => '1');
+ enable <= '0';
elsif rising_edge(clock) then
- if (start ='1' and enable = '0') then
- lfsr_speicher <= lfsr_seed;
- enable <= '1';
- elsif (start = '1' and enable = '1') then
- lfsr_speicher(3) <= lfsr_speicher(0);
- lfsr_speicher(2) <= lfsr_speicher(3) xor lfsr_speicher(0);
- lfsr_speicher(1) <= lfsr_speicher(2);
- lfsr_speicher(0) <= lfsr_speicher(1);
- end if;
+ if (start = '1' and enable = '0') then
+ lfsr_speicher <= lfsr_seed;
+ enable <= '1';
+ elsif (start = '1' and enable = '1') then
+ lfsr_speicher(3) <= lfsr_speicher(0);
+ lfsr_speicher(2) <= lfsr_speicher(3) xor lfsr_speicher(0);
+ lfsr_speicher(1) <= lfsr_speicher(2);
+ lfsr_speicher(0) <= lfsr_speicher(1);
+ end if;
end if;
-end process lfsr_output;
+ end process lfsr_output;
end Behavioral;
use ieee.numeric_std.all;
entity sodaBoard is
- port(
- clk_in : in std_logic ; --system clock
- reset_in : in std_logic ; -- system reset
- -- Slave bus
- SLV_READ_IN : in std_logic; -- data shall be read
- SLV_WRITE_IN : in std_logic; -- incoming data is meant for writing into some register
- SLV_DATA_OUT : out std_logic_vector(31 downto 0);--
- SLV_DATA_IN : in std_logic_vector(31 downto 0);--
- SLV_ADDR_IN : in std_logic_vector(15 downto 0);-- defines the address which shall be read or written
- SLV_ACK_OUT : out std_logic; -- high if data is put out
- SLV_NO_MORE_DATA_OUT : out std_logic; --
- SLV_UNKNOWN_ADDR_OUT : out std_logic --
- );
+ port(
+ clk_in : in std_logic; --system clock
+ reset_in : in std_logic; -- system reset
+ -- trigger and data logic from TRB
+ TIMING_TRG_IN : in std_logic;
+ LVL1_TRG_DATA_VALID_IN : in std_logic;
+ LVL1_VALID_TIMING_TRG_IN : in std_logic;
+ LVL1_VALID_NOTIMING_TRG_IN : in std_logic;
+ LVL1_INVALID_TRG_IN : in std_logic;
+ LVL1_TRG_TYPE_IN : in std_logic_vector(3 downto 0);
+ LVL1_TRG_NUMBER_IN : in std_logic_vector(15 downto 0);
+ LVL1_TRG_CODE_IN : in std_logic_vector(7 downto 0);
+ LVL1_TRG_INFORMATION_IN : in std_logic_vector(23 downto 0);
+ LVL1_INT_TRG_NUMBER_IN : in std_logic_vector(15 downto 0);
+
+ --TRB data connections
+ FEE_TRG_RELEASE_OUT : out std_logic;
+ FEE_TRG_STATUSBITS_OUT : out std_logic_vector(31 downto 0);
+ FEE_DATA_OUT : out std_logic_vector(31 downto 0);
+ FEE_DATA_WRITE_OUT : out std_logic;
+ FEE_DATA_FINISHED_OUT : out std_logic;
+ FEE_DATA_ALMOST_FULL_IN : in std_logic;
+ -- Slave bus
+ SLV_READ_IN : in std_logic; -- data shall be read
+ SLV_WRITE_IN : in std_logic; -- incoming data is meant for writing into some register
+ SLV_DATA_OUT : out std_logic_vector(31 downto 0); --
+ SLV_DATA_IN : in std_logic_vector(31 downto 0); --
+ SLV_ADDR_IN : in std_logic_vector(15 downto 0); -- defines the address which shall be read or written
+ SLV_ACK_OUT : out std_logic; -- high if data is put out
+ SLV_NO_MORE_DATA_OUT : out std_logic; --
+ SLV_UNKNOWN_ADDR_OUT : out std_logic --
+ );
end sodaBoard;
architecture Behavioral of sodaBoard is
- ----------------------------------
- --component of the frame generator
- component FrameGenerator is
- port(
- clk: in std_logic; -- Taktsignal
- reset: in std_logic; -- Reset
- trigger: in std_logic; -- Startsignal zum Senden von Daten (wuerde sonst an MuPix gehen)
- data_out: out std_logic_vector(31 downto 0); -- Datenpaket variabler Laenge, immer 32 Bit lang
- data_valid:out std_logic -- 1, wenn relevante Daten gesendet und mitgeschrieben werden sollte
- );
- end component FrameGenerator;
- ----------------------------------
- --signals
- signal readpointer, writepointer : integer range 0 to 17 := 0; -- pointers that tell, which one of the max 18 words shall be read or written
- signal memory : std_logic_vector (18*32 - 1 downto 0) := (others => '0'); -- vector that can contain up to 18 32-bit words
- signal single_word : std_logic_vector (31 downto 0); -- contains the actual word which is written out from the frame generator
- signal start_generation : std_logic := '0'; -- start signal for the frame generator
- signal data_valid : std_logic := '0'; -- logic that tells whether relevant data is put out from the frame generator
- signal known_word : std_logic_vector(31 downto 0) := x"abcdefab";
- begin
- -- port map for frame generator
- framegen1: FrameGenerator port map( clk => clk_in, reset => reset_in, trigger => start_generation, data_out => single_word, data_valid => data_valid);
+ ----------------------------------
+ --component of the frame generator
+ component FrameGenerator is
+ port(
+ clk : in std_logic; -- Taktsignal
+ reset : in std_logic; -- Reset
+ trigger : in std_logic; -- Startsignal zum Senden von Daten (wuerde sonst an MuPix gehen)
+ data_out : out std_logic_vector(31 downto 0); -- Datenpaket variabler Laenge, immer 32 Bit lang
+ data_valid : out std_logic; -- 1, wenn relevante Daten gesendet und mitgeschrieben werden sollte
+ data_finished : out std_logic
+ );
+ end component FrameGenerator;
+ ----------------------------------
+
+
+ ----------------------------------
+ --component of the trigger handler
+ component TriggerHandler is
+ port (
+ CLK_IN : in std_logic;
+ RESET_IN : in std_logic;
+ TIMING_TRIGGER_IN : in std_logic;
+ LVL1_TRG_DATA_VALID_IN : in std_logic;
+ LVL1_VALID_TIMING_TRG_IN : in std_logic;
+ LVL1_VALID_NOTIMING_TRG_IN : in std_logic;
+ LVL1_INVALID_TRG_IN : in std_logic;
+ LVL1_TRG_TYPE_IN : in std_logic_vector(3 downto 0);
+ LVL1_TRG_NUMBER_IN : in std_logic_vector(15 downto 0);
+ LVL1_TRG_CODE_IN : in std_logic_vector(7 downto 0);
+ FEE_DATA_OUT : out std_logic_vector(31 downto 0);
+ FEE_DATA_WRITE_OUT : out std_logic;
+ FEE_DATA_FINISHED_OUT : out std_logic;
+ FEE_TRG_RELEASE_OUT : out std_logic;
+ FEE_TRG_STATUSBITS_OUT : out std_logic_vector(31 downto 0);
+ FEE_DATA_0_IN : in std_logic_vector(31 downto 0);
+ FEE_DATA_WRITE_0_IN : in std_logic;
+ FEE_DATA_FINISHED_IN : in std_logic;
+ bypass_trigger : in std_logic;
+ reset_trigger_state : in std_logic;
+ VALID_TRIGGER_OUT : out std_logic;
+ trigger_handler_state_o : out std_logic_vector(7 downto 0);
+ trigger_rate_acc_o : out std_logic_vector(31 downto 0);
+ trigger_rate_tot_o : out std_logic_vector(31 downto 0);
+ invalid_trigger_counter_o : out std_logic_vector(31 downto 0);
+ valid_trigger_counter_o : out std_logic_vector(31 downto 0));
+ end component TriggerHandler;
+
+ ----------------------------------
+
+ --signals
+ signal readpointer, writepointer : integer range 0 to 17 := 0; -- pointers that tell, which one of the max 18 words shall be read or written
+ signal memory : std_logic_vector (18*32 - 1 downto 0) := (others => '0'); -- vector that can contain up to 18 32-bit words
+ signal single_word : std_logic_vector (31 downto 0); -- contains the actual word which is written out from the frame generator
+ signal start_generation : std_logic := '0'; -- start signal for the frame generator
+ signal start_generation_slow : std_logic := '0';
+ signal start_generation_trigger : std_logic := '0';
+ signal data_valid : std_logic := '0'; -- logic that tells whether relevant data is put out from the frame generator
+ signal data_finished : std_logic := '0';
+ signal known_word : std_logic_vector(31 downto 0) := x"abcdefab";
+ --control signals to trigger handler
+ signal bypass_trigger_i : std_logic := '1';
+ signal reset_trigger_state_i : std_logic := '0';
+ signal trigger_handler_state_i : std_logic_vector(7 downto 0);
+ signal trigger_rate_acc_i : std_logic_vector(31 downto 0);
+ signal trigger_rate_tot_i : std_logic_vector(31 downto 0);
+ signal invalid_trigger_counter_i : std_logic_vector(31 downto 0);
+ signal valid_trigger_counter_i : std_logic_vector(31 downto 0);
+
+begin
+
+ start_generation <= start_generation_trigger or start_generation_slow;
+
+ -- port map for frame generator
+ framegen1 : FrameGenerator port map(clk => clk_in,
+ reset => reset_in,
+ trigger => start_generation,
+ data_out => single_word,
+ data_valid => data_valid,
+ data_finished => data_finished);
+
+ -- port map trigger handler
+ TriggerHandler_1 : entity work.TriggerHandler
+ port map (
+ CLK_IN => CLK_IN,
+ RESET_IN => RESET_IN,
+ TIMING_TRIGGER_IN => TIMING_TRG_IN,
+ LVL1_TRG_DATA_VALID_IN => LVL1_TRG_DATA_VALID_IN,
+ LVL1_VALID_TIMING_TRG_IN => LVL1_VALID_TIMING_TRG_IN,
+ LVL1_VALID_NOTIMING_TRG_IN => LVL1_VALID_NOTIMING_TRG_IN,
+ LVL1_INVALID_TRG_IN => LVL1_INVALID_TRG_IN,
+ LVL1_TRG_TYPE_IN => LVL1_TRG_TYPE_IN,
+ LVL1_TRG_NUMBER_IN => LVL1_TRG_NUMBER_IN,
+ LVL1_TRG_CODE_IN => LVL1_TRG_CODE_IN,
+ FEE_DATA_OUT => FEE_DATA_OUT,
+ FEE_DATA_WRITE_OUT => FEE_DATA_WRITE_OUT,
+ FEE_DATA_FINISHED_OUT => FEE_DATA_FINISHED_OUT,
+ FEE_TRG_RELEASE_OUT => FEE_TRG_RELEASE_OUT,
+ FEE_TRG_STATUSBITS_OUT => FEE_TRG_STATUSBITS_OUT,
+ FEE_DATA_0_IN => single_word,
+ FEE_DATA_WRITE_0_IN => data_valid,
+ FEE_DATA_FINISHED_IN => data_finished,
+ bypass_trigger => bypass_trigger_i,
+ reset_trigger_state => reset_trigger_state_i,
+ VALID_TRIGGER_OUT => start_generation_trigger,
+ trigger_handler_state_o => trigger_handler_state_i,
+ trigger_rate_acc_o => trigger_rate_acc_i,
+ trigger_rate_tot_o => trigger_rate_tot_i,
+ invalid_trigger_counter_o => invalid_trigger_counter_i,
+ valid_trigger_counter_o => valid_trigger_counter_i);
- -----------------------------------------------------------
- --TRB SLV-BUS Handler
- ------------------------------------------------------------
- --Address Equivalents:
- --0x0001: gen trigger
- --0x0002: read word/write readpointer
- slv_bus_handler: process (clk_in) is
- begin
- if rising_edge(clk_in) then
- slv_data_out <= (others => '0');
- slv_ack_out <= '0';
- slv_no_more_data_out <= '0';
- slv_unknown_addr_out <= '0';
- if (slv_write_in = '1') then
- case slv_addr_in is
- when x"0001" => -- set trigger/start generation value
- start_generation <= slv_data_in(0);
- slv_ack_out <= '1';
- when x"0002" => -- write: readpointers value changing (word that might be read later)
- if (to_integer(unsigned(slv_data_in(4 downto 0))) < 19) then
- readpointer <= to_integer(unsigned(slv_data_in(4 downto 0)));
- slv_ack_out <= '1';
- else
- readpointer <= 0;
- slv_ack_out <= '0';
- end if;
- when x"0003" => known_word (7 downto 0) <= slv_data_in(7 downto 0);
- slv_ack_out <= '1';
- when others => -- no useful address put in
- slv_unknown_addr_out <= '1';
- end case;
- end if;
- if slv_read_in = '1' then
- case slv_addr_in is
- when x"0001" => -- read trigger value
- slv_data_out(0) <= start_generation;
- slv_ack_out <= '1';
- when x"0002" => -- read: get x-th word of the memory, value stored in the readpointer
- slv_data_out <= memory(((readpointer + 1)*32 - 1) downto readpointer*32);
- slv_ack_out <= '1';
- when x"0003" => slv_data_out <= known_word;
- slv_ack_out <= '1';
- when others => -- no useful address put in
- slv_unknown_addr_out <= '1';
- end case;
- end if;
- end if;
- end process slv_bus_handler;
+ -----------------------------------------------------------
+ --TRB SLV-BUS Handler
+ ------------------------------------------------------------
+ --Address Equivalents:
+ --0x0001: gen trigger
+ --0x0002: read word/write readpointer
+ slv_bus_handler : process (clk_in) is
+ begin
+ if rising_edge(clk_in) then
+ slv_data_out <= (others => '0');
+ slv_ack_out <= '0';
+ slv_no_more_data_out <= '0';
+ slv_unknown_addr_out <= '0';
+ reset_trigger_state_i <= '1';
+
+ if (slv_write_in = '1') then
+ case slv_addr_in is
+ when x"0001" => -- set trigger/start generation value
+ start_generation_slow <= slv_data_in(0);
+ slv_ack_out <= '1';
+ when x"0002" => -- write: readpointers value changing (word that might be read later)
+ if (to_integer(unsigned(slv_data_in(4 downto 0))) < 19) then
+ readpointer <= to_integer(unsigned(slv_data_in(4 downto 0)));
+ slv_ack_out <= '1';
+ else
+ readpointer <= 0;
+ slv_ack_out <= '0';
+ end if;
+ when x"0003" =>
+ known_word (7 downto 0) <= slv_data_in(7 downto 0);
+ slv_ack_out <= '1';
+ when x"0004" =>
+ bypass_trigger_i <= slv_data_in(0);
+ slv_ack_out <= '1';
+ when x"0005" =>
+ reset_trigger_state_i <= '1';
+ slv_ack_out <= '1';
+ when others => -- no useful address put in
+ slv_unknown_addr_out <= '1';
+ end case;
+ end if;
+
+ if slv_read_in = '1' then
+ case slv_addr_in is
+ when x"0001" => -- read trigger value
+ slv_data_out(0) <= start_generation;
+ slv_ack_out <= '1';
+ when x"0002" => -- read: get x-th word of the memory, value stored in the readpointer
+ slv_data_out <= memory(((readpointer + 1)*32 - 1) downto readpointer*32);
+ slv_ack_out <= '1';
+ when x"0003" => slv_data_out <= known_word;
+ slv_ack_out <= '1';
+ when x"0006" =>
+ slv_data_out(7 downto 0) <= trigger_handler_state_i;
+ slv_ack_out <= '1';
+ when x"0007" =>
+ slv_data_out <= trigger_rate_acc_i;
+ slv_ack_out <= '1';
+ when x"0008" =>
+ slv_data_out <= trigger_rate_tot_i;
+ slv_ack_out <= '1';
+ when x"0009" =>
+ slv_data_out <= invalid_trigger_counter_i;
+ slv_ack_out <= '1';
+ when x"000a" =>
+ slv_data_out <= valid_trigger_counter_i;
+ slv_ack_out <= '1';
+ when others => -- no useful address put in
+ slv_unknown_addr_out <= '1';
+ end case;
+ end if;
+ end if;
+ end process slv_bus_handler;
- word_generation: process (clk_in) is
- begin
- if reset_in = '1' then
- writepointer <= 0;
- memory <= (others => '0'); --reset clears memory and current value of writepointer
- elsif rising_edge(clk_in) then
- if data_valid = '1' then
- memory ( (writepointer +1)*32 -1 downto writepointer*32 ) <= single_word;
- writepointer <= writepointer + 1;
- end if;
- end if;
- end process;
+ word_generation : process (clk_in) is
+ begin
+ if reset_in = '1' then
+ writepointer <= 0;
+ memory <= (others => '0'); --reset clears memory and current value of writepointer
+ elsif rising_edge(clk_in) then
+ if data_valid = '1' then
+ memory ((writepointer +1)*32 -1 downto writepointer*32) <= single_word;
+ writepointer <= writepointer + 1;
+ end if;
+ end if;
+ end process;
end architecture;
--- /dev/null
+-----------------------------------------------------------------------------
+-- Trigger Handler for TRBnet
+-- Tobias Weber, University Mainz
+-----------------------------------------------------------------------------
+library ieee;
+use ieee.std_logic_1164.all;
+use ieee.numeric_std.all;
+
+
+entity TriggerHandler is
+ port (
+ CLK_IN : in std_logic;
+ RESET_IN : in std_logic;
+
+ --Input Triggers
+ TIMING_TRIGGER_IN : in std_logic; -- The raw timing Trigger Signal
+ LVL1_TRG_DATA_VALID_IN : in std_logic; -- Data Trigger is valid
+ LVL1_VALID_TIMING_TRG_IN : in std_logic; -- Timin Trigger is valid
+ LVL1_VALID_NOTIMING_TRG_IN : in std_logic; -- calib trigger w/o ref time
+ LVL1_INVALID_TRG_IN : in std_logic;
+
+ LVL1_TRG_TYPE_IN : in std_logic_vector(3 downto 0);
+ LVL1_TRG_NUMBER_IN : in std_logic_vector(15 downto 0);
+ LVL1_TRG_CODE_IN : in std_logic_vector(7 downto 0);
+
+ --Response from FEE
+ FEE_DATA_OUT : out std_logic_vector(31 downto 0);
+ FEE_DATA_WRITE_OUT : out std_logic;
+ FEE_DATA_FINISHED_OUT : out std_logic;
+ FEE_TRG_RELEASE_OUT : out std_logic;
+ FEE_TRG_STATUSBITS_OUT : out std_logic_vector(31 downto 0);
+
+ FEE_DATA_0_IN : in std_logic_vector(31 downto 0);
+ FEE_DATA_WRITE_0_IN : in std_logic;
+ FEE_DATA_FINISHED_IN : in std_logic;
+
+ bypass_trigger : in std_logic;
+ reset_trigger_state : in std_logic;
+
+ -- OUT
+ VALID_TRIGGER_OUT : out std_logic;
+ trigger_handler_state_o : out std_logic_vector(7 downto 0);
+ trigger_rate_acc_o : out std_logic_vector(31 downto 0);
+ trigger_rate_tot_o : out std_logic_vector(31 downto 0);
+ invalid_trigger_counter_o : out std_logic_vector(31 downto 0);
+ valid_trigger_counter_o : out std_logic_vector(31 downto 0));
+end entity TriggerHandler;
+
+
+architecture behavioral of TriggerHandler is
+
+--trigger
+ signal reset_trigger_state_edge : std_logic_vector(1 downto 0) := "00";
+ signal valid_trigger_int : std_logic := '0';
+ signal timing_trigger_edge : std_logic_vector(1 downto 0) := "00";
+ signal trigger_busy_int : std_logic := '0';
+ signal buffer_readout_end_int : std_logic_vector(1 downto 0) := "00";
+--fee
+ signal fee_data_int : std_logic_vector(31 downto 0) := (others => '0');
+ signal fee_data_write_int : std_logic := '0';
+ signal fee_data_finished_int : std_logic := '0';
+ signal fee_trg_release_int : std_logic := '0';
+ signal fee_trg_statusbit_int : std_logic_vector(31 downto 0) := (others => '0');
+--event buffer
+
+--registers
+ signal reset_trigger_counters : std_logic := '0';
+ signal reset_trigger_counters_edge : std_logic_vector(1 downto 0) := (others => '0');
+ signal trigger_rate_acc : unsigned(31 downto 0) := (others => '0');
+ signal trigger_rate_tot : unsigned(31 downto 0) := (others => '0');
+ signal trigger_rate_time_counter : unsigned(31 downto 0) := (others => '0');
+ signal invalid_trigger_counter : unsigned(31 downto 0) := (others => '0');
+ signal valid_trigger_counter : unsigned(31 downto 0) := (others => '0');
+ signal invalid_trigger_counter_t : unsigned(31 downto 0) := (others => '0');
+ signal valid_trigger_counter_t : unsigned(31 downto 0) := (others => '0');
+ signal trigger_handler_state : std_logic_vector(7 downto 0) := (others => '0');
+
+--trigger types
+ constant c_trigger_physics_type : std_logic_vector(3 downto 0) := x"1";
+ constant c_trigger_status_type : std_logic_vector(3 downto 0) := x"e";
+
+--trigger handler
+ type trigger_handler_type is (idle,
+ timing_trigger,
+ no_timing_trigger,
+ check_trigger_type,
+ status_trigger,
+ write_data_to_ipu,
+ trigger_release_a,
+ trigger_release_b,
+ trigger_release_c,
+ wait_trigger_release,
+ ignore,
+ wait_trigger_data_valid_a,
+ wait_trigger_data_valid_b);
+
+ type trigger_type_type is (t_timing,
+ t_physics,
+ t_status,
+ t_ignore,
+ t_unknown);
+
+ signal trigger_handler_fsm : trigger_handler_type := idle;
+ signal trigger_type : trigger_type_type := t_unknown;
+ signal wr_header_int : std_logic := '0';
+ signal wr_data_int : std_logic := '0';
+ signal wr_status_int : std_logic := '0';
+ signal wr_dummy_int : std_logic := '0';
+
+begin
+
+ Signal_Edge_Detect : process(CLK_IN) is
+ begin -- process Mupix_Readout_End_Detect
+ if rising_edge(CLK_IN) then
+ if reset_in = '1' then
+ buffer_readout_end_int <= (others => '0');
+ timing_trigger_edge <= (others => '0');
+ reset_trigger_state_edge <= (others => '0');
+ else
+ timing_trigger_edge <= timing_trigger_edge(0) & TIMING_TRIGGER_IN;
+ reset_trigger_state_edge <= reset_trigger_state_edge(1) & reset_trigger_state;
+ end if;
+ end if;
+ end process Signal_Edge_Detect;
+
+ ------------------------------------------------------------
+ --Handling of LVL1 triggers
+ ------------------------------------------------------------
+ trigger_handler_proc : process(clk_in) is
+ begin -- process trigger_handler_proc
+ if rising_edge(CLK_IN) then
+ trigger_busy_int <= '1';
+ fee_trg_release_int <= '0';
+ wr_header_int <= '0';
+ wr_data_int <= '0';
+ wr_status_int <= '0';
+ wr_dummy_int <= '0';
+ valid_trigger_int <= '0';
+ fee_data_finished_int <= '0';
+ fee_trg_release_int <= '0';
+ if reset_in = '1' or LVL1_INVALID_TRG_IN = '1' or reset_trigger_state_edge = "01" then
+ valid_trigger_int <= '0';
+ fee_data_finished_int <= '0';
+ fee_trg_release_int <= '0';
+ fee_trg_statusbit_int <= (others => '0');
+ trigger_busy_int <= '1';
+ fee_trg_release_int <= '0';
+ wr_header_int <= '0';
+ wr_data_int <= '0';
+ wr_status_int <= '0';
+ wr_dummy_int <= '0';
+ else
+ case trigger_handler_fsm is
+ when idle =>
+ trigger_busy_int <= '0';
+ trigger_handler_state <= x"01";
+ if LVL1_VALID_TIMING_TRG_IN = '1' then
+ wr_header_int <= '1';
+ if bypass_trigger = '1' then
+ trigger_type <= t_ignore;
+ trigger_handler_fsm <= ignore;
+ else
+ trigger_type <= t_timing;
+ trigger_handler_fsm <= timing_trigger;
+ end if;
+ elsif (LVL1_VALID_NOTIMING_TRG_IN = '1') then
+ wr_header_int <= '1';
+ if bypass_trigger = '1' then
+ trigger_type <= t_ignore;
+ trigger_handler_fsm <= ignore;
+ else
+ trigger_handler_fsm <= check_trigger_type;
+ end if;
+ end if;
+
+ when check_trigger_type =>
+ trigger_handler_state <= x"02";
+ if (LVL1_TRG_DATA_VALID_IN = '1') then
+ if (LVL1_TRG_TYPE_IN = c_trigger_status_type) then
+ trigger_type <= t_status;
+ trigger_handler_fsm <= no_timing_trigger;
+ elsif (LVL1_TRG_TYPE_IN = c_trigger_physics_type) then
+ trigger_type <= t_physics;
+ trigger_handler_fsm <= no_timing_trigger;
+ else
+ --unknown trigger
+ trigger_type <= t_unknown;
+ trigger_handler_fsm <= no_timing_trigger;
+ end if;
+ else
+ trigger_handler_fsm <= check_trigger_type;
+ end if;
+
+ when timing_trigger => --starts mupix readout fsm
+ trigger_handler_state <= x"03";
+ valid_trigger_int <= '1';
+ trigger_handler_fsm <= write_data_to_ipu;
+
+ when no_timing_trigger =>
+ trigger_handler_state <= x"04";
+ if trigger_type = t_physics then
+ trigger_handler_fsm <= timing_trigger;
+ elsif trigger_type = t_status then
+ trigger_handler_fsm <= status_trigger;
+ else
+ trigger_handler_fsm <= ignore;
+ end if;
+
+ when ignore =>
+ wr_dummy_int <= '1'; --write a dummy value to identify inactive FEE
+ trigger_handler_state <= x"05";
+ trigger_handler_fsm <= wait_trigger_data_valid_b;
+
+ when status_trigger => --dummy implementation
+ trigger_handler_state <= x"06";
+ wr_status_int <= '1';
+ trigger_handler_fsm <= wait_trigger_data_valid_b;
+
+ when write_data_to_ipu =>
+ trigger_handler_state <= x"0A";
+ wr_data_int <= '1';
+ if buffer_readout_end_int = "10" then
+ wr_data_int <= '0';
+ trigger_handler_fsm <= wait_trigger_data_valid_a;
+ else
+ trigger_handler_fsm <= write_data_to_ipu;
+ end if;
+
+ when wait_trigger_data_valid_a =>
+ trigger_handler_state <= x"0B";
+ if LVL1_TRG_DATA_VALID_IN = '1' then
+ trigger_handler_fsm <= wait_trigger_data_valid_b;
+ end if;
+
+ when wait_trigger_data_valid_b =>
+ trigger_handler_state <= x"0C";
+ trigger_handler_fsm <= trigger_release_a;
+
+ when trigger_release_a =>
+ trigger_handler_state <= x"0D";
+ trigger_handler_fsm <= trigger_release_b;
+
+ when trigger_release_b =>
+ trigger_handler_state <= x"0E";
+ fee_data_finished_int <= '1';
+ trigger_handler_fsm <= trigger_release_c;
+
+ when trigger_release_c =>
+ trigger_handler_state <= x"0F";
+ fee_trg_release_int <= '1';
+ trigger_handler_fsm <= wait_trigger_release;
+
+ when wait_trigger_release =>
+ if (LVL1_TRG_DATA_VALID_IN = '1') then
+ trigger_handler_fsm <= wait_trigger_release;
+ else
+ trigger_handler_fsm <= idle;
+ end if;
+ end case;
+ end if;
+ end if;
+ end process trigger_handler_proc;
+
+ ------------------------------------------------------------
+ --Data Output Mux
+ ------------------------------------------------------------
+ Data_Out_Mux : process(clk_in) is
+ begin -- process Data_Out_Mux
+ if rising_edge(clk_in) then
+ if Reset_in = '1' then
+ fee_data_write_int <= '0';
+ fee_data_int <= (others => '0');
+ else
+ if wr_header_int = '1' then
+ fee_data_write_int <= '1'; --header see Hades DAQ user guide
+ fee_data_int <= "001" & "0" & LVL1_TRG_TYPE_IN & LVL1_TRG_CODE_IN & LVL1_TRG_NUMBER_IN;
+ elsif wr_data_int = '1' then
+ fee_data_write_int <= FEE_DATA_WRITE_0_IN;
+ fee_data_int <= FEE_DATA_0_IN;
+ elsif wr_status_int = '1' then
+ fee_data_int <= x"deadbeef";
+ fee_data_write_int <= '1';
+ elsif wr_dummy_int = '1' then
+ fee_data_write_int <= '1';
+ fee_data_int <= x"ffeeddcc";
+ else
+ fee_data_write_int <= '0';
+ fee_data_int <= (others => '1');
+ end if;
+ end if;
+ end if;
+ end process Data_Out_Mux;
+
+
+ ------------------------------------------------------------
+ --Trigger statistics
+ ------------------------------------------------------------
+ Trigger_Statistics_Proc : process(clk_in) is
+ begin -- process Trigger_Statistics_Proc
+ if rising_edge(CLK_IN) then
+ reset_trigger_counters_edge <= reset_trigger_counters_edge(0) & reset_trigger_counters;
+ if reset_trigger_counters_edge = "01" or RESET_IN = '1' then
+ trigger_rate_acc <= (others => '0');
+ invalid_trigger_counter_t <= (others => '0');
+ valid_trigger_counter_t <= (others => '0');
+ trigger_rate_time_counter <= (others => '0');
+ else
+ if trigger_rate_time_counter < x"5f5e100" then --1s at 10ns clock period
+ --if trigger_rate_time_counter < x"000007e" then
+ trigger_rate_time_counter <= trigger_rate_time_counter + 1;
+ if valid_trigger_int = '1' then
+ valid_trigger_counter_t <= valid_trigger_counter_t + 1;
+ elsif LVL1_INVALID_TRG_IN = '1' or (trigger_busy_int = '1' and timing_trigger_edge = "01") then
+ invalid_trigger_counter_t <= invalid_trigger_counter_t + 1;
+ end if;
+ else
+ valid_trigger_counter <= valid_trigger_counter + valid_trigger_counter_t;
+ invalid_trigger_counter <= invalid_trigger_counter + invalid_trigger_counter_t;
+ trigger_rate_acc <= valid_trigger_counter_t;
+ trigger_rate_tot <= valid_trigger_counter_t + invalid_trigger_counter_t;
+ trigger_rate_time_counter <= (others => '0');
+ valid_trigger_counter_t <= (others => '0');
+ invalid_trigger_counter_t <= (others => '0');
+ end if;
+ end if;
+ end if;
+ end process Trigger_Statistics_Proc;
+
+ --map output signals
+ valid_trigger_out <= valid_trigger_int;
+ fee_data_out <= fee_data_int;
+ fee_data_write_out <= fee_data_write_int;
+ fee_data_finished_out <= fee_data_finished_int;
+ fee_trg_release_out <= fee_trg_release_int;
+ fee_trg_statusbits_out <= fee_trg_statusbit_int;
+
+ trigger_handler_state_o <= trigger_handler_state;
+ trigger_rate_acc_o <= std_logic_vector(trigger_rate_acc);
+ trigger_rate_tot_o <= std_logic_vector(trigger_rate_tot);
+ invalid_trigger_counter_o <= std_logic_vector(invalid_trigger_counter);
+ valid_trigger_counter_o <= std_logic_vector(valid_trigger_counter);
+
+end architecture behavioral;
port (
clk_in : in std_logic ; --system clock
reset_in : in std_logic ; -- system reset
+ -- trigger and data logic from TRB
+ TIMING_TRG_IN : in std_logic;
+ LVL1_TRG_DATA_VALID_IN : in std_logic;
+ LVL1_VALID_TIMING_TRG_IN : in std_logic;
+ LVL1_VALID_NOTIMING_TRG_IN : in std_logic;
+ LVL1_INVALID_TRG_IN : in std_logic;
+ LVL1_TRG_TYPE_IN : in std_logic_vector(3 downto 0);
+ LVL1_TRG_NUMBER_IN : in std_logic_vector(15 downto 0);
+ LVL1_TRG_CODE_IN : in std_logic_vector(7 downto 0);
+ LVL1_TRG_INFORMATION_IN : in std_logic_vector(23 downto 0);
+ LVL1_INT_TRG_NUMBER_IN : in std_logic_vector(15 downto 0);
+
+ --TRB data connections
+ FEE_TRG_RELEASE_OUT : out std_logic;
+ FEE_TRG_STATUSBITS_OUT : out std_logic_vector(31 downto 0);
+ FEE_DATA_OUT : out std_logic_vector(31 downto 0);
+ FEE_DATA_WRITE_OUT : out std_logic;
+ FEE_DATA_FINISHED_OUT : out std_logic;
+ FEE_DATA_ALMOST_FULL_IN : in std_logic;
-- Slave bus
SLV_READ_IN : in std_logic; -- data shall be read
- SLV_WRITE_IN : in std_logic; -- incoming data is meant for writing into some register
- SLV_DATA_OUT : out std_logic_vector(31 downto 0);--
- SLV_DATA_IN : in std_logic_vector(31 downto 0);--
- SLV_ADDR_IN : in std_logic_vector(15 downto 0);-- defines the address which shall be read or written
- SLV_ACK_OUT : out std_logic; -- high if data is put out
- SLV_NO_MORE_DATA_OUT : out std_logic; --
- SLV_UNKNOWN_ADDR_OUT : out std_logic --
+ SLV_WRITE_IN : in std_logic; -- incoming data is meant for writing into some register
+ SLV_DATA_OUT : out std_logic_vector(31 downto 0);--
+ SLV_DATA_IN : in std_logic_vector(31 downto 0);--
+ SLV_ADDR_IN : in std_logic_vector(15 downto 0);-- defines the address which shall be read or written
+ SLV_ACK_OUT : out std_logic; -- high if data is put out
+ SLV_NO_MORE_DATA_OUT : out std_logic; --
+ SLV_UNKNOWN_ADDR_OUT : out std_logic --
);
end component;
signal trg_spurious_trg_i : std_logic;
signal trg_missing_tmg_trg_i : std_logic;
signal trg_spike_detected_i : std_logic;
+
+ --Data channel
+ signal fee_trg_release_i : std_logic_vector(NumberFEECards-1 downto 0);
+ signal fee_trg_statusbits_i : std_logic_vector(NumberFEECards*32-1 downto 0);
+ signal fee_data_i : std_logic_vector(NumberFEECards*32-1 downto 0);
+ signal fee_data_write_i : std_logic_vector(NumberFEECards-1 downto 0);
+ signal fee_data_finished_i : std_logic_vector(NumberFEECards-1 downto 0);
+ signal fee_almost_full_i : std_logic_vector(NumberFEECards-1 downto 0);
--Slow Control channel
signal common_stat_reg : std_logic_vector(std_COMSTATREG*32-1 downto 0);
TRG_MISSING_TMG_TRG_OUT => trg_missing_tmg_trg_i,
TRG_SPIKE_DETECTED_OUT => trg_spike_detected_i,
- --Response from FEE, i.e. MuPix
- FEE_TRG_RELEASE_IN(0) => open,
- FEE_TRG_STATUSBITS_IN(0*32+31 downto 0*32) => open,
- FEE_DATA_IN(0*32+31 downto 0*32) => open,
- FEE_DATA_WRITE_IN(0) => open,
- FEE_DATA_FINISHED_IN(0) => open,
- FEE_DATA_ALMOST_FULL_OUT(0) => open,
+ --Response from FEE, i.e. Soda board
+ FEE_TRG_RELEASE_IN(0) => fee_trg_release_i(0),
+ FEE_TRG_STATUSBITS_IN(0*32+31 downto 0*32) => fee_trg_statusbits_i(0*32+31 downto 0*32),
+ FEE_DATA_IN(0*32+31 downto 0*32) => fee_data_i(0*32+31 downto 0*32),
+ FEE_DATA_WRITE_IN(0) => fee_data_write_i(0),
+ FEE_DATA_FINISHED_IN(0) => fee_data_finished_i(0),
+ FEE_DATA_ALMOST_FULL_OUT(0) => fee_almost_full_i(0),
-- Slow Control Data Port
REGIO_COMMON_STAT_REG_IN => common_stat_reg, --0x00
port map(
clk_in => clk_100_i, --system clock
reset_in => reset_i, -- system reset
+ --trigger logic
+ TIMING_TRG_IN => TRIGGER_RIGHT,
+ LVL1_TRG_DATA_VALID_IN => trg_data_valid_i,
+ LVL1_VALID_TIMING_TRG_IN => trg_timing_valid_i,
+ LVL1_VALID_NOTIMING_TRG_IN => trg_notiming_valid_i,
+ LVL1_INVALID_TRG_IN => trg_invalid_i,
+ LVL1_TRG_TYPE_IN => trg_type_i,
+ LVL1_TRG_NUMBER_IN => trg_number_i,
+ LVL1_TRG_CODE_IN => trg_code_i,
+ LVL1_TRG_INFORMATION_IN => trg_information_i,
+ LVL1_INT_TRG_NUMBER_IN => trg_int_number_i,
+
+ --TRB data connections
+ FEE_TRG_RELEASE_OUT => fee_trg_release_i(0),
+ FEE_TRG_STATUSBITS_OUT => fee_trg_statusbits_i(0*32+31 downto 0*32),
+ FEE_DATA_OUT => fee_data_i(0*32+31 downto 0*32),
+ FEE_DATA_WRITE_OUT => fee_data_write_i(0),
+ FEE_DATA_FINISHED_OUT => fee_data_finished_i(0),
+ FEE_DATA_ALMOST_FULL_IN => fee_almost_full_i(0),
-- Slave bus
SLV_READ_IN =>sodaboard_regio_read_enable_in_0, -- data shall be read
SLV_WRITE_IN =>sodaboard_regio_write_enable_in_0, -- incoming data is meant for writing into some register