diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index 4bd83f2a135230b54945abb5b57212bc8e4eb0dd..b48da5f15f4d520c2c73157ecdfc67a396e8b431 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -8,9 +8,19 @@ stages: Lint HDL Code: stage: Code Checks - image: ubuntu + image: registry.cern.ch/docker.io/library/python + before_script: + - python3 -m pip install vsg junitparser + - mkdir reports script: - - echo "Code checks go here." + - bash run_vsg.sh + artifacts: + when: always + paths: + - report.xml + reports: + junit: report.xml + Front End Unit Tests: stage: Simulation diff --git a/dtc-be/common/firmware/hdl/GlobalFastCommand.vhd b/dtc-be/common/firmware/hdl/GlobalFastCommand.vhd index c414a875325802dc07c4a3dfc3f03ae811b48f08..d48150603b0a2a556bea6bdb68cc5687e0609ae9 100644 --- a/dtc-be/common/firmware/hdl/GlobalFastCommand.vhd +++ b/dtc-be/common/firmware/hdl/GlobalFastCommand.vhd @@ -1,259 +1,236 @@ library ieee; -use ieee.std_logic_1164.all; -use ieee.numeric_std.all; - -use work.ipbus.all; -use work.ipbus_reg_types.all; - -use work.emp_data_types.all; - -use work.module_constants.all; -use work.front_end_data_types.all; -use work.dtc_constants.all; -use work.dtc_data_types.all; - + use ieee.std_logic_1164.all; + use ieee.numeric_std.all; + +library work; + use work.ipbus.all; + use work.ipbus_reg_types.all; + use work.emp_data_types.all; + use work.module_constants.all; + use work.front_end_data_types.all; + use work.dtc_constants.all; + use work.dtc_data_types.all; entity GlobalFastCommand is -port( - --- Input Ports --- - clk_p : in std_logic; - clk40 : in std_logic; - ext_fcmd : in tFastCommand; - --- Output Ports --- - global_fcmd : out tFastCommand; - --- IPBus Ports --- - clk : in std_logic; - rst : in std_logic; - ipb_in : in ipb_wbus; - ipb_out : out ipb_rbus -); -end GlobalFastCommand; - + port ( + --- Input Ports --- + clk_p : in std_logic; + clk40 : in std_logic; + ext_fcmd : in tFastCommand; + --- Output Ports --- + global_fcmd : out tFastCommand; + --- IPBus Ports --- + clk : in std_logic; + rst : in std_logic; + ipb_in : in ipb_wbus; + ipb_out : out ipb_rbus + ); +end entity GlobalFastCommand; architecture rtl of GlobalFastCommand is + -- IPBus registers --- IPBus registers - -signal fast_cmd_status : ipb_reg_v(3 downto 0) := (others => (others => '0')); -signal fast_cmd_ctrl : ipb_reg_v(3 downto 0) := (others => (others => '0')); - -signal source_mask : std_logic_vector(3 downto 0) := (others => '0'); -signal gen_run : std_logic := '0'; -signal gen_cntr_mode : std_logic := '0'; -signal gen_repeat : integer range 0 to 1023 := 0; + signal fast_cmd_status : ipb_reg_v(3 downto 0) := (others => (others => '0')); + signal fast_cmd_ctrl : ipb_reg_v(3 downto 0) := (others => (others => '0')); -type tFastCmdBuffer is array(6 downto 0) of std_logic_vector(15 downto 0); -signal gen_buffer : tFastCmdBuffer := (others => (others => '0')); + signal source_mask : std_logic_vector(3 downto 0) := (others => '0'); + signal gen_run : std_logic := '0'; + signal gen_cntr_mode : std_logic := '0'; + signal gen_repeat : integer range 0 to 1023 := 0; + type tFastCmdBuffer is array(6 downto 0) of std_logic_vector(15 downto 0); --- Global fast command generator + signal gen_buffer : tFastCmdBuffer := (others => (others => '0')); -type tGenState is (start, countdown, stop); -signal gen_state : tGenState := start; + -- Global fast command generator -signal gen_instruction : std_logic_vector(1 downto 0) := (others => '0'); -signal gen_counter : integer range 0 to 1023 := 0; -signal gen_rpt_counter : integer range 0 to 1023 := 0; -signal cmd_gen : tFastCommand; + type tGenState is (start, countdown, stop); -signal ctr_reset_counter : integer range 0 to 255 := 0; -signal cal_pulse_counter : integer range 0 to 255 := 0; -signal l1a_trig_counter : integer range 0 to 255 := 0; -signal fast_reset_counter : integer range 0 to 255 := 0; + signal gen_state : tGenState := start; + signal gen_instruction : std_logic_vector(1 downto 0) := (others => '0'); + signal gen_counter : integer range 0 to 1023 := 0; + signal gen_rpt_counter : integer range 0 to 1023 := 0; + signal cmd_gen : tFastCommand; --- Output - -signal cmd_local : tFastCommand; -signal cmd_out : tFastCommand; + signal ctr_reset_counter : integer range 0 to 255 := 0; + signal cal_pulse_counter : integer range 0 to 255 := 0; + signal l1a_trig_counter : integer range 0 to 255 := 0; + signal fast_reset_counter : integer range 0 to 255 := 0; + -- Output + signal cmd_local : tFastCommand; + signal cmd_out : tFastCommand; begin + --==============================-- + FastCmd : entity work.ipbus_ctrlreg_v + --==============================-- + generic map ( + N_CTRL => 4, + N_STAT => 4 + ) + port map ( + clk => clk, + reset => rst, + ipbus_in => ipb_in, + ipbus_out => ipb_out, + d => fast_cmd_status, + q => fast_cmd_ctrl + ); + + --==============================-- + -- Generators + --==============================-- + + --==============================-- + pFsm : process (clk40) is + + --==============================-- + + variable buf_index : integer range 0 to 6 := 0; + + begin + + if rising_edge(clk40) then + -- latch IPBus control registers in payload clock domain + source_mask <= fast_cmd_ctrl(0)(3 downto 0); + gen_run <= fast_cmd_ctrl(0)(4); + gen_cntr_mode <= fast_cmd_ctrl(0)(5); + gen_repeat <= to_integer(unsigned(fast_cmd_ctrl(0)(15 downto 6))); + + -- 16b fast command generator commands : instruction [2b] + wait counter [10b] + fast command [4b] + -- instructions : 0 = return to first word; 1 = move to next word; 2 = stop at this word; 3 = undefined + -- fast commands: bit3 = fast_reset; bit2 = l1a_trigger; bit1 = cal_pulse; bit0 = counter_reset + gen_buffer(0) <= fast_cmd_ctrl(1)(15 downto 0); + gen_buffer(1) <= fast_cmd_ctrl(1)(31 downto 16); + gen_buffer(2) <= fast_cmd_ctrl(2)(15 downto 0); + gen_buffer(3) <= fast_cmd_ctrl(2)(31 downto 16); + gen_buffer(4) <= fast_cmd_ctrl(3)(15 downto 0); + gen_buffer(5) <= fast_cmd_ctrl(3)(31 downto 16); + gen_buffer(6) <= (others => '0'); -- null buffer + + -- only run fast command generator when gen_run enabled + if (gen_run = '1') then + + case gen_state is + + -- initial state when gen_run enabled; initialise and send fast command in first word + when start => + buf_index := 0; ---==============================-- -fast_cmd: entity work.ipbus_ctrlreg_v ---==============================-- -generic map( - N_CTRL => 4, - N_STAT => 4 -) -port map( - clk => clk, - reset => rst, - ipbus_in => ipb_in, - ipbus_out => ipb_out, - d => fast_cmd_status, - q => fast_cmd_ctrl -); - - ---==============================-- --- Generators ---==============================-- - - ---==============================-- -fsm: process(clk40) ---==============================-- - - variable buf_index: integer range 0 to 6 := 0; - -begin - - if rising_edge(clk40) then - - -- latch IPBus control registers in payload clock domain - source_mask <= fast_cmd_ctrl(0)(3 downto 0); - gen_run <= fast_cmd_ctrl(0)(4); - gen_cntr_mode <= fast_cmd_ctrl(0)(5); - gen_repeat <= to_integer(unsigned(fast_cmd_ctrl(0)(15 downto 6))); - - -- 16b fast command generator commands : instruction [2b] + wait counter [10b] + fast command [4b] - -- instructions : 0 = return to first word; 1 = move to next word; 2 = stop at this word; 3 = undefined - -- fast commands: bit3 = fast_reset; bit2 = l1a_trigger; bit1 = cal_pulse; bit0 = counter_reset - gen_buffer(0) <= fast_cmd_ctrl(1)(15 downto 0); - gen_buffer(1) <= fast_cmd_ctrl(1)(31 downto 16); - gen_buffer(2) <= fast_cmd_ctrl(2)(15 downto 0); - gen_buffer(3) <= fast_cmd_ctrl(2)(31 downto 16); - gen_buffer(4) <= fast_cmd_ctrl(3)(15 downto 0); - gen_buffer(5) <= fast_cmd_ctrl(3)(31 downto 16); - gen_buffer(6) <= (others => '0'); --null buffer - - -- only run fast command generator when gen_run enabled - if gen_run = '1' then - - case gen_state is - - -- initial state when gen_run enabled; initialise and send fast command in first word - when start => - buf_index := 0; - - gen_counter <= to_integer(unsigned(gen_buffer(buf_index)(13 downto 4))); - gen_instruction <= gen_buffer(buf_index)(15 downto 14); - - cmd_gen.fast_reset <= gen_buffer(buf_index)(3); - cmd_gen.l1a_trig <= gen_buffer(buf_index)(2); - cmd_gen.cal_pulse <= gen_buffer(buf_index)(1); - cmd_gen.counter_reset <= gen_buffer(buf_index)(0); - - gen_state <= countdown; - - -- wait for N clk cycles as defined in current word; then decide on next action - when countdown => - if gen_counter <= 0 then - if gen_instruction = "01" then - buf_index := buf_index + 1; -- move to next word - elsif gen_instruction = "00" and gen_rpt_counter > 1 then - gen_rpt_counter <= gen_rpt_counter - 1; -- decrement repeat sequence counter - buf_index := 0; -- return to word 0 - elsif gen_instruction = "00" and gen_rpt_counter = 0 then - buf_index := 0; -- return to word 0 and repeat ad infinitum - else - gen_state <= stop; - buf_index := 6; -- instruction indicates stop or is undefined - end if; - - -- set counter, instruction, and fast commands according to next word gen_counter <= to_integer(unsigned(gen_buffer(buf_index)(13 downto 4))); - gen_instruction <= gen_buffer(buf_index)(15 downto 14); + gen_instruction <= gen_buffer(buf_index)(15 downto 14); cmd_gen.fast_reset <= gen_buffer(buf_index)(3); cmd_gen.l1a_trig <= gen_buffer(buf_index)(2); cmd_gen.cal_pulse <= gen_buffer(buf_index)(1); cmd_gen.counter_reset <= gen_buffer(buf_index)(0); - else - gen_counter <= gen_counter - 1; - cmd_gen <= ('0', '0', '0', '0', '0'); - end if; - - -- final state when buffers end, instruction indicates stop, or undefined sequence - -- remain here until gen_run is reset - when others => - cmd_gen <= ('0', '0', '0', '0', '0'); - - end case; - - -- update fast counters for debugging when gen_run is enabled - if (fast_reset_counter < 255 and cmd_gen.fast_reset = '1') then - fast_reset_counter <= fast_reset_counter + 1; - end if; - - if (l1a_trig_counter < 255 and cmd_gen.l1a_trig = '1') then - l1a_trig_counter <= l1a_trig_counter + 1; - end if; - if (cal_pulse_counter < 255 and cmd_gen.cal_pulse = '1') then - cal_pulse_counter <= cal_pulse_counter + 1; - end if; + gen_state <= countdown; + + -- wait for N clk cycles as defined in current word; then decide on next action + when countdown => + if (gen_counter <= 0) then + if (gen_instruction = "01") then + buf_index := buf_index + 1; -- move to next word + elsif (gen_instruction = "00" and gen_rpt_counter > 1) then + gen_rpt_counter <= gen_rpt_counter - 1; -- decrement repeat sequence counter + buf_index := 0; -- return to word 0 + elsif (gen_instruction = "00" and gen_rpt_counter = 0) then + buf_index := 0; -- return to word 0 and repeat ad infinitum + else + gen_state <= stop; + buf_index := 6; -- instruction indicates stop or is undefined + end if; + + -- set counter, instruction, and fast commands according to next word + gen_counter <= to_integer(unsigned(gen_buffer(buf_index)(13 downto 4))); + gen_instruction <= gen_buffer(buf_index)(15 downto 14); + + cmd_gen.fast_reset <= gen_buffer(buf_index)(3); + cmd_gen.l1a_trig <= gen_buffer(buf_index)(2); + cmd_gen.cal_pulse <= gen_buffer(buf_index)(1); + cmd_gen.counter_reset <= gen_buffer(buf_index)(0); + else + gen_counter <= gen_counter - 1; + cmd_gen <= ('0', '0', '0', '0', '0'); + end if; - if (ctr_reset_counter < 255 and cmd_gen.counter_reset = '1') then - ctr_reset_counter <= ctr_reset_counter + 1; + -- final state when buffers end, instruction indicates stop, or undefined sequence + -- remain here until gen_run is reset + when others => + cmd_gen <= ('0', '0', '0', '0', '0'); + + end case; + + -- update fast counters for debugging when gen_run is enabled + if (fast_reset_counter < 255 and cmd_gen.fast_reset = '1') then + fast_reset_counter <= fast_reset_counter + 1; + end if; + + if (l1a_trig_counter < 255 and cmd_gen.l1a_trig = '1') then + l1a_trig_counter <= l1a_trig_counter + 1; + end if; + + if (cal_pulse_counter < 255 and cmd_gen.cal_pulse = '1') then + cal_pulse_counter <= cal_pulse_counter + 1; + end if; + + if (ctr_reset_counter < 255 and cmd_gen.counter_reset = '1') then + ctr_reset_counter <= ctr_reset_counter + 1; + end if; + else + -- reset fsm and counters when local_gen_run is disabled + gen_state <= start; + gen_rpt_counter <= gen_repeat; + cmd_gen <= ('0', '0', '0', '0', '0'); + fast_reset_counter <= 0; + l1a_trig_counter <= 0; + cal_pulse_counter <= 0; + ctr_reset_counter <= 0; end if; - - else - - -- reset fsm and counters when local_gen_run is disabled - gen_state <= start; - gen_rpt_counter <= gen_repeat; - cmd_gen <= ('0', '0', '0', '0', '0'); - fast_reset_counter <= 0; - l1a_trig_counter <= 0; - cal_pulse_counter <= 0; - ctr_reset_counter <= 0; - end if; - end if; - -end process fsm; - --- prepare locally generated fast commands -cmd_local.counter_mode <= gen_cntr_mode; -cmd_local.fast_reset <= cmd_gen.fast_reset; -cmd_local.l1a_trig <= cmd_gen.l1a_trig; -cmd_local.cal_pulse <= cmd_gen.cal_pulse; -cmd_local.counter_reset <= cmd_gen.counter_reset; - --- prepare IPBus status registers -fast_cmd_status(0)(7 downto 0) <= std_logic_vector(to_unsigned(ctr_reset_counter, 8)); -fast_cmd_status(0)(15 downto 8) <= std_logic_vector(to_unsigned(cal_pulse_counter, 8)); -fast_cmd_status(0)(23 downto 16) <= std_logic_vector(to_unsigned(l1a_trig_counter, 8)); -fast_cmd_status(0)(31 downto 24) <= std_logic_vector(to_unsigned(fast_reset_counter, 8)); - - - - - ---==============================-- --- Output : source select & formatting ---==============================-- - - ---==============================-- -cmd_select: process(clk40) ---==============================-- -begin - - if rising_edge(clk40) then - - -- select between tcds and local fast command sources - cmd_out.counter_mode <= cmd_local.counter_mode; - cmd_out.fast_reset <= ( ext_fcmd.fast_reset and source_mask(3) ) or cmd_local.fast_reset; - cmd_out.l1a_trig <= ( ext_fcmd.l1a_trig and source_mask(2) ) or cmd_local.l1a_trig; - cmd_out.cal_pulse <= ( ext_fcmd.cal_pulse and source_mask(1) ) or cmd_local.cal_pulse; - cmd_out.counter_reset <= ( ext_fcmd.counter_reset and source_mask(0) ) or cmd_local.counter_reset; - - end if; - -end process cmd_select; - - -global_fcmd <= cmd_out; + end process pFsm; + + -- prepare locally generated fast commands + cmd_local.counter_mode <= gen_cntr_mode; + cmd_local.fast_reset <= cmd_gen.fast_reset; + cmd_local.l1a_trig <= cmd_gen.l1a_trig; + cmd_local.cal_pulse <= cmd_gen.cal_pulse; + cmd_local.counter_reset <= cmd_gen.counter_reset; + + -- prepare IPBus status registers + fast_cmd_status(0)(7 downto 0) <= std_logic_vector(to_unsigned(ctr_reset_counter, 8)); + fast_cmd_status(0)(15 downto 8) <= std_logic_vector(to_unsigned(cal_pulse_counter, 8)); + fast_cmd_status(0)(23 downto 16) <= std_logic_vector(to_unsigned(l1a_trig_counter, 8)); + fast_cmd_status(0)(31 downto 24) <= std_logic_vector(to_unsigned(fast_reset_counter, 8)); + + --==============================-- + -- Output : source select & formatting + --==============================-- + + --==============================-- + pCmdSelect : process (clk40) is + --==============================-- + begin + + if rising_edge(clk40) then + -- select between tcds and local fast command sources + cmd_out.counter_mode <= cmd_local.counter_mode; + cmd_out.fast_reset <= (ext_fcmd.fast_reset and source_mask(3)) or cmd_local.fast_reset; + cmd_out.l1a_trig <= (ext_fcmd.l1a_trig and source_mask(2)) or cmd_local.l1a_trig; + cmd_out.cal_pulse <= (ext_fcmd.cal_pulse and source_mask(1)) or cmd_local.cal_pulse; + cmd_out.counter_reset <= (ext_fcmd.counter_reset and source_mask(0)) or cmd_local.counter_reset; + end if; + end process pCmdSelect; + global_fcmd <= cmd_out; -end rtl; +end architecture rtl; diff --git a/dtc-be/common/firmware/hdl/L1DataAggregator.vhd b/dtc-be/common/firmware/hdl/L1DataAggregator.vhd index b3bf34917a4b21b959dd2d15c95c72862e56f9bb..f7ee4042240e79590e23eb8491633eac578d2781 100644 --- a/dtc-be/common/firmware/hdl/L1DataAggregator.vhd +++ b/dtc-be/common/firmware/hdl/L1DataAggregator.vhd @@ -1,271 +1,259 @@ library ieee; - use ieee.std_logic_1164.all; - use ieee.numeric_std.all; - --- - use work.ipbus.all; - use work.ipbus_reg_types.all; - use work.ipbus_decode_dtc_data_aggregator.all; - --- - use work.emp_data_types.all; - use work.emp_daqpath_types_package.all; - use work.emp_daqpath_user_package.all; - --- - use work.dtc_link_maps.all; - use work.dtc_constants.all; - use work.dtc_data_types.all; - + use ieee.std_logic_1164.all; + use ieee.numeric_std.all; + +library work; + use work.ipbus.all; + use work.ipbus_reg_types.all; + use work.ipbus_decode_dtc_data_aggregator.all; + use work.emp_data_types.all; + use work.emp_daqpath_types_package.all; + use work.emp_daqpath_user_package.all; + use work.dtc_link_maps.all; + use work.dtc_constants.all; + use work.dtc_data_types.all; entity L1DataAggregator is - generic ( - INPUT_LINKS : integer := cNumberOfFEModules - ); - port ( - --- Input Ports --- - clk_p : in std_logic; - daq_in : in tDaqDataLinkArray(INPUT_LINKS - 1 downto 0); - empty : in tDaqFlagLinkArray(INPUT_LINKS - 1 downto 0); - --- Output Ports --- - read : out tDaqFlagLinkArray(INPUT_LINKS - 1 downto 0); - --- IPBus Ports --- - clk : in std_logic; - rst : in std_logic; - ipb_in : in ipb_wbus; - ipb_out : out ipb_rbus - ); + generic ( + input_links : integer := cNumberOfFEModules + ); + port ( + --- Input Ports --- + clk_p : in std_logic; + daq_in : in tDaqDataLinkArray(input_links - 1 downto 0); + empty : in tDaqFlagLinkArray(input_links - 1 downto 0); + --- Output Ports --- + read : out tDaqFlagLinkArray(input_links - 1 downto 0); + --- IPBus Ports --- + clk : in std_logic; + rst : in std_logic; + ipb_in : in ipb_wbus; + ipb_out : out ipb_rbus + ); end entity L1DataAggregator; - architecture rtl of L1DataAggregator is + -- IPBus fabric + + signal ipb_to_slaves : ipb_wbus_array(N_SLAVES - 1 downto 0); + signal ipb_from_slaves : ipb_rbus_array(N_SLAVES - 1 downto 0); + + -- Daqpath interface + + constant cNUM_CHANNELS : integer := input_links * cNumberOfCICs; + + signal word_fifo_rdata : generic_data_fifo_data_array(cNUM_CHANNELS - 1 downto 0); + signal id_fifo_rdata : ctrl_fifo_data_array(cNUM_CHANNELS - 1 downto 0); + signal nw_fifo_rdata : ctrl_fifo_data_array(cNUM_CHANNELS - 1 downto 0); + signal word_fifo_re : std_logic_vector(cNUM_CHANNELS - 1 downto 0); + signal id_fifo_re : std_logic_vector(cNUM_CHANNELS - 1 downto 0); + signal nw_fifo_re : std_logic_vector(cNUM_CHANNELS - 1 downto 0); + signal word_fifo_empty : std_logic_vector(cNUM_CHANNELS - 1 downto 0); + signal id_fifo_empty : std_logic_vector(cNUM_CHANNELS - 1 downto 0); + signal nw_fifo_empty : std_logic_vector(cNUM_CHANNELS - 1 downto 0); + signal daqpath_en : std_logic; + signal daqpath_rst : std_logic; + signal daqpath_ext_creg : ipb_reg_v(3 downto 0) := (others => (others => '0')); + signal daqpath_ext_sreg : ipb_reg_v(3 downto 0) := (others => (others => '0')); + + -- Daqpath core + + signal int_data_out : std_logic_vector(63 downto 0); + signal int_data_we_out : std_logic; + signal int_idnw_out : std_logic_vector(31 downto 0); + signal int_idnw_we_out : std_logic; + signal slink : lword; + + -- Output IPBus FIFO interface + + constant cNUM_LINKS : integer := 1; + signal output_data_fifo_wdata : data_fifo_data_array(0 to cNUM_LINKS - 1); + signal output_data_fifo_we : std_logic_vector(0 to cNUM_LINKS - 1); + signal output_data_fifo_empty : std_logic_vector(0 to cNUM_LINKS - 1); + signal output_data_fifo_full : std_logic_vector(0 to cNUM_LINKS - 1); + signal output_idnw_fifo_wdata : ipbus_data_array(0 to cNUM_LINKS - 1); + signal output_idnw_fifo_we : std_logic_vector(0 to cNUM_LINKS - 1); + signal output_idnw_fifo_empty : std_logic_vector(0 to cNUM_LINKS - 1); + signal output_idnw_fifo_full : std_logic_vector(0 to cNUM_LINKS - 1); - -- IPBus fabric - - signal ipb_to_slaves : ipb_wbus_array(N_SLAVES - 1 downto 0); - signal ipb_from_slaves : ipb_rbus_array(N_SLAVES - 1 downto 0); - +begin - -- Daqpath interface + --==============================-- + -- IPBus fabric + --==============================-- - constant cNUM_CHANNELS : integer := INPUT_LINKS * cNumberOfCICs; + --==============================-- + Fabric : entity work.ipbus_fabric_sel + --==============================-- + generic map ( + NSLV => N_SLAVES, + SEL_WIDTH => IPBUS_SEL_WIDTH + ) + port map ( + ipb_in => ipb_in, + ipb_out => ipb_out, + sel => ipbus_sel_dtc_data_aggregator(ipb_in.ipb_addr), + ipb_to_slaves => ipb_to_slaves, + ipb_from_slaves => ipb_from_slaves + ); - signal word_fifo_rdata : generic_data_fifo_data_array(cNUM_CHANNELS - 1 downto 0); - signal id_fifo_rdata : ctrl_fifo_data_array(cNUM_CHANNELS - 1 downto 0); - signal nw_fifo_rdata : ctrl_fifo_data_array(cNUM_CHANNELS - 1 downto 0); - signal word_fifo_re : std_logic_vector(cNUM_CHANNELS - 1 downto 0); - signal id_fifo_re : std_logic_vector(cNUM_CHANNELS - 1 downto 0); - signal nw_fifo_re : std_logic_vector(cNUM_CHANNELS - 1 downto 0); - signal word_fifo_empty : std_logic_vector(cNUM_CHANNELS - 1 downto 0); - signal id_fifo_empty : std_logic_vector(cNUM_CHANNELS - 1 downto 0); - signal nw_fifo_empty : std_logic_vector(cNUM_CHANNELS - 1 downto 0); - signal daqpath_en : std_logic; - signal daqpath_rst : std_logic; - signal daqpath_ext_creg : ipb_reg_v(3 downto 0) := (others => (others => '0')); - signal daqpath_ext_sreg : ipb_reg_v(3 downto 0) := (others => (others => '0')); + --==============================-- + DaqControl : entity work.ipbus_syncreg_v + --==============================-- + generic map ( + N_CTRL => 4, + N_STAT => 4 + ) + port map ( + clk => clk, + rst => rst, + ipb_in => ipb_to_slaves(N_SLV_DAQPATH_EXT_CTRL), + ipb_out => ipb_from_slaves(N_SLV_DAQPATH_EXT_CTRL), + slv_clk => clk_p, + d => daqpath_ext_sreg, + q => daqpath_ext_creg + ); + + -- Status register 1-3 presents input FIFO status + -- Status register 0 presents output FIFO status + -- if output FIFOs not empty -> read them out through IPBus + --==============================-- + GenStatusRegistersInput : for i in 0 to cNUM_CHANNELS - 1 generate - -- Daqpath core + daqpath_ext_sreg(1)(i) <= word_fifo_empty(i); + daqpath_ext_sreg(2)(i) <= id_fifo_empty(i); + daqpath_ext_sreg(3)(i) <= nw_fifo_empty(i); - signal int_data_out : std_logic_vector(63 downto 0); - signal int_data_we_out : std_logic; - signal int_idnw_out : std_logic_vector(31 downto 0); - signal int_idnw_we_out : std_logic; - signal slink : lword; + end generate GenStatusRegistersInput; + --==============================-- + GenStatusRegistersOutput : for i in 0 to cNUM_LINKS - 1 generate + --==============================-- - -- Output IPBus FIFO interface + daqpath_ext_sreg(0)(i * 4) <= output_data_fifo_empty(i); + daqpath_ext_sreg(0)(i * 4 + 1) <= output_idnw_fifo_empty(i); + daqpath_ext_sreg(0)(i * 4 + 2) <= output_data_fifo_full(i); + daqpath_ext_sreg(0)(i * 4 + 3) <= output_idnw_fifo_full(i); - constant cNUM_LINKS : integer := 1; - signal output_data_fifo_wdata : data_fifo_data_array(0 to cNUM_LINKS - 1); - signal output_data_fifo_we : std_logic_vector(0 to cNUM_LINKS - 1); - signal output_data_fifo_empty : std_logic_vector(0 to cNUM_LINKS - 1); - signal output_data_fifo_full : std_logic_vector(0 to cNUM_LINKS - 1); - signal output_idnw_fifo_wdata : ipbus_data_array(0 to cNUM_LINKS - 1); - signal output_idnw_fifo_we : std_logic_vector(0 to cNUM_LINKS - 1); - signal output_idnw_fifo_empty : std_logic_vector(0 to cNUM_LINKS - 1); - signal output_idnw_fifo_full : std_logic_vector(0 to cNUM_LINKS - 1); + end generate GenStatusRegistersOutput; -begin + daqpath_ext_sreg(0)(31 downto 4 * cNUM_LINKS) <= (others => '0'); - --==============================-- - -- IPBus fabric - --==============================-- - - --==============================-- - fabric : entity work.ipbus_fabric_sel - --==============================-- - generic map ( - NSLV => N_SLAVES, - SEL_WIDTH => IPBUS_SEL_WIDTH - ) - port map ( - ipb_in => ipb_in, - ipb_out => ipb_out, - sel => ipbus_sel_dtc_data_aggregator(ipb_in.ipb_addr), - ipb_to_slaves => ipb_to_slaves, - ipb_from_slaves => ipb_from_slaves - ); - - --==============================-- - daq_control : entity work.ipbus_syncreg_v - --==============================-- - generic map ( - N_CTRL => 4, - N_STAT => 4 - ) - port map ( - clk => clk, - rst => rst, - ipb_in => ipb_to_slaves(N_SLV_DAQPATH_EXT_CTRL), - ipb_out => ipb_from_slaves(N_SLV_DAQPATH_EXT_CTRL), - slv_clk => clk_p, - d => daqpath_ext_sreg, - q => daqpath_ext_creg - ); - - - -- Status register 1-3 presents input FIFO status - -- Status register 0 presents output FIFO status - -- if output FIFOs not empty -> read them out through IPBus - - --==============================-- - status_registers_i : for i in 0 to cNUM_CHANNELS - 1 generate - --==============================-- + -- Enable/reset signals for daqpath - daqpath_ext_sreg(1)(i) <= word_fifo_empty(i); - daqpath_ext_sreg(2)(i) <= id_fifo_empty(i); - daqpath_ext_sreg(3)(i) <= nw_fifo_empty(i); + -- if daqpath_en=1 -> enabled + daqpath_en <= daqpath_ext_creg(0)(0); - end generate status_registers_i; + -- if daqpath_rst=1 -> all blocks internal to daqpath in reset + daqpath_rst <= daqpath_ext_creg(0)(4); - --==============================-- - status_registers_o : for i in 0 to cNUM_LINKS - 1 generate + --==============================-- + -- DAQPATH --==============================-- - daqpath_ext_sreg(0)(i * 4) <= output_data_fifo_empty(i); - daqpath_ext_sreg(0)(i * 4 + 1) <= output_idnw_fifo_empty(i); - daqpath_ext_sreg(0)(i * 4 + 2) <= output_data_fifo_full(i); - daqpath_ext_sreg(0)(i * 4 + 3) <= output_idnw_fifo_full(i); + --==============================-- + GenMapLinks : for i in 0 to input_links - 1 generate + --==============================-- - end generate status_registers_o; + --==============================-- + GenMapChannels : for j in 0 to cNumberOfCICs - 1 generate + --==============================-- - daqpath_ext_sreg(0)(31 downto 4 * cNUM_LINKS) <= (others => '0'); + word_fifo_rdata (i * cNumberOfCICs + j) <= daq_in(i)(j).data_word; + id_fifo_rdata (i * cNumberOfCICs + j) <= daq_in(i)(j).event_id; + nw_fifo_rdata (i * cNumberOfCICs + j) <= daq_in(i)(j).n_words; + word_fifo_empty (i * cNumberOfCICs + j) <= empty(i)(j).data_word; + id_fifo_empty (i * cNumberOfCICs + j) <= empty(i)(j).event_id; + nw_fifo_empty (i * cNumberOfCICs + j) <= empty(i)(j).n_words; + read(i)(j).data_word <= word_fifo_re (i * cNumberOfCICs + j); + read(i)(j).event_id <= id_fifo_re (i * cNumberOfCICs + j); + read(i)(j).n_words <= nw_fifo_re (i * cNumberOfCICs + j); - -- Enable/reset signals for daqpath + end generate GenMapChannels; - -- if daqpath_en=1 -> enabled - daqpath_en <= daqpath_ext_creg(0)(0); + end generate GenMapLinks; - -- if daqpath_rst=1 -> all blocks internal to daqpath in reset - daqpath_rst <= daqpath_ext_creg(0)(4); + -- Daqpath core instance + -- Version 1.1 with : - input data flexibility (1,2,4,8 bytes) + -- - header insertion programmable through ipbus (hdr_en) in daqpath_regs + -- - Data formatter to have 64-bits words @clk_p at the output side + -- - channel mask + -- slink output stream also provided - not used yet + --==============================-- + DaqpathCore : entity work.emp_daqpath_module + --==============================-- + generic map ( + NUM_CHANNELS => cNUM_CHANNELS, + N_CHAN_PER_GROUP => N_CHAN_PER_GROUP + ) + port map ( + ipb_clk => clk, + ipb_rst => rst, + ipb_in => ipb_to_slaves(N_SLV_DAQPATH_CSR), + ipb_out => ipb_from_slaves(N_SLV_DAQPATH_CSR), + clk => clk_p, + rst => daqpath_rst, + en => daqpath_en, + pause => '0', + data_out => int_data_out, + data_we_out => int_data_we_out, + idnw_out => int_idnw_out, + idnw_we_out => int_idnw_we_out, + slink_data => slink.data, + slink_dv => slink.valid, + slink_start => slink.start, + slink_end => slink.strobe, + word_fifo_rdata => word_fifo_rdata, + nw_fifo_rdata => nw_fifo_rdata, + id_fifo_rdata => id_fifo_rdata, + id_fifo_re => id_fifo_re, + nw_fifo_re => nw_fifo_re, + word_fifo_re => word_fifo_re, + word_fifo_empty => word_fifo_empty, + id_fifo_empty => id_fifo_empty, + nw_fifo_empty => nw_fifo_empty + ); - --==============================-- - -- DAQPATH - --==============================-- + --==============================-- + -- IPBus Output FIFO + --==============================-- - --==============================-- - map_links : for i in 0 to INPUT_LINKS - 1 generate --==============================-- + GenMapOutput : for i in 0 to cNUM_LINKS - 1 generate + --==============================-- + + output_data_fifo_wdata(i) <= int_data_out; + output_data_fifo_we(i) <= int_data_we_out; + output_idnw_fifo_wdata(i) <= int_idnw_out; + output_idnw_fifo_we(i) <= int_idnw_we_out; + + end generate GenMapOutput; --==============================-- - map_channels : for j in 0 to cNumberOfCICs - 1 generate - --==============================-- - - word_fifo_rdata (i * cNumberOfCICs + j) <= daq_in(i)(j).data_word; - id_fifo_rdata (i * cNumberOfCICs + j) <= daq_in(i)(j).event_id; - nw_fifo_rdata (i * cNumberOfCICs + j) <= daq_in(i)(j).n_words; - word_fifo_empty (i * cNumberOfCICs + j) <= empty(i)(j).data_word; - id_fifo_empty (i * cNumberOfCICs + j) <= empty(i)(j).event_id; - nw_fifo_empty (i * cNumberOfCICs + j) <= empty(i)(j).n_words; - - read(i)(j).data_word <= word_fifo_re (i * cNumberOfCICs + j); - read(i)(j).event_id <= id_fifo_re (i * cNumberOfCICs + j); - read(i)(j).n_words <= nw_fifo_re (i * cNumberOfCICs + j); - - end generate map_channels; - - end generate map_links; - - -- Daqpath core instance - -- Version 1.1 with : - input data flexibility (1,2,4,8 bytes) - -- - header insertion programmable through ipbus (hdr_en) in daqpath_regs - -- - Data formatter to have 64-bits words @clk_p at the output side - -- - channel mask - -- slink output stream also provided - not used yet - - --==============================-- - DaqpathCore : entity work.emp_daqpath_module - --==============================-- - generic map ( - NUM_CHANNELS => cNUM_CHANNELS, - N_CHAN_PER_GROUP => N_CHAN_PER_GROUP - ) - port map ( - ipb_clk => clk, - ipb_rst => rst, - ipb_in => ipb_to_slaves(N_SLV_DAQPATH_CSR), - ipb_out => ipb_from_slaves(N_SLV_DAQPATH_CSR), - clk => clk_p, - rst => daqpath_rst, - en => daqpath_en, - pause => '0', - data_out => int_data_out, - data_we_out => int_data_we_out, - idnw_out => int_idnw_out, - idnw_we_out => int_idnw_we_out, - slink_data => slink.data, - slink_dv => slink.valid, - slink_start => slink.start, - slink_end => slink.strobe, - word_fifo_rdata => word_fifo_rdata, - nw_fifo_rdata => nw_fifo_rdata, - id_fifo_rdata => id_fifo_rdata, - id_fifo_re => id_fifo_re, - nw_fifo_re => nw_fifo_re, - word_fifo_re => word_fifo_re, - word_fifo_empty => word_fifo_empty, - id_fifo_empty => id_fifo_empty, - nw_fifo_empty => nw_fifo_empty - ); - - - --==============================-- - -- IPBus Output FIFO - --==============================-- - - --==============================-- - map_output : for i in 0 to cNUM_LINKS - 1 generate + OutputFifo : entity work.emp_daqpath_ipbus_output_FIFOs_array --==============================-- - - output_data_fifo_wdata(i) <= int_data_out; - output_data_fifo_we(i) <= int_data_we_out; - output_idnw_fifo_wdata(i) <= int_idnw_out; - output_idnw_fifo_we(i) <= int_idnw_we_out; - - end generate map_output; - - --==============================-- - OutputFifo : entity work.emp_daqpath_ipbus_output_FIFOs_array - --==============================-- - generic map ( - NUM_CHANNELS => cNUM_LINKS - ) - port map ( - dp_clk => clk_p, - ipb_clk => clk, - rst => daqpath_rst, - en => daqpath_en, - ipb_in => ipb_to_slaves(N_SLV_DAQPATH_OUT), - ipb_out => ipb_from_slaves(N_SLV_DAQPATH_OUT), - data_fifo_wdata => output_data_fifo_wdata, - data_fifo_we => output_data_fifo_we, - data_fifo_empty => output_data_fifo_empty, - data_fifo_full => output_data_fifo_full, - idnw_fifo_wdata => output_idnw_fifo_wdata, - idnw_fifo_we => output_idnw_fifo_we, - idnw_fifo_empty => output_idnw_fifo_empty, - idnw_fifo_full => output_idnw_fifo_full - ); + generic map ( + NUM_CHANNELS => cNUM_LINKS + ) + port map ( + dp_clk => clk_p, + ipb_clk => clk, + rst => daqpath_rst, + en => daqpath_en, + ipb_in => ipb_to_slaves(N_SLV_DAQPATH_OUT), + ipb_out => ipb_from_slaves(N_SLV_DAQPATH_OUT), + data_fifo_wdata => output_data_fifo_wdata, + data_fifo_we => output_data_fifo_we, + data_fifo_empty => output_data_fifo_empty, + data_fifo_full => output_data_fifo_full, + idnw_fifo_wdata => output_idnw_fifo_wdata, + idnw_fifo_we => output_idnw_fifo_we, + idnw_fifo_empty => output_idnw_fifo_empty, + idnw_fifo_full => output_idnw_fifo_full + ); end architecture rtl; diff --git a/dtc-be/common/firmware/hdl/data_types.vhd b/dtc-be/common/firmware/hdl/data_types.vhd index f93a1d9018303ce75796ce8f43d7de3c5a72706c..b8ae6b0342fd76a7ef71704f4698409f74b9a0b8 100644 --- a/dtc-be/common/firmware/hdl/data_types.vhd +++ b/dtc-be/common/firmware/hdl/data_types.vhd @@ -1,80 +1,84 @@ library ieee; - use ieee.std_logic_1164.all; - use ieee.numeric_std.all; - --- - use work.dtc_constants.all; + use ieee.std_logic_1164.all; + use ieee.numeric_std.all; +library work; + use work.dtc_constants.all; package dtc_data_types is - type tCICHeader is record - CIC_conf : std_logic; - status : std_logic_vector(8 downto 0); - bcid : std_logic_vector(11 downto 0); - stub_count : std_logic_vector(5 downto 0); - end record tCICHeader; + type tCICHeader is record + CIC_conf : std_logic; + status : std_logic_vector(8 downto 0); + bcid : std_logic_vector(11 downto 0); + stub_count : std_logic_vector(5 downto 0); + end record tCICHeader; - type tCICHeaderArray is array(integer range <>) of tCICHeader; + type tCICHeaderArray is array(integer range <>) of tCICHeader; - function cicHeaderToSLV (header: tCICHeader) return std_logic_vector; + function cicHeaderToSlv ( + header: tCICHeader + ) return std_logic_vector; + type tFastCommand is record + counter_mode : std_logic; + fast_reset : std_logic; + l1a_trig : std_logic; + cal_pulse : std_logic; + counter_reset : std_logic; + end record tFastCommand; - type tFastCommand is record - counter_mode : std_logic; - fast_reset : std_logic; - l1a_trig : std_logic; - cal_pulse : std_logic; - counter_reset : std_logic; - end record tFastCommand; + function fastCommandToSlv ( + command: tFastCommand + ) return std_logic_vector; - function fastCommandToSLV (command: tFastCommand) return std_logic_vector; + type tDaqFlag is record + data_word : std_logic; + event_id : std_logic; + n_words : std_logic; + end record tDaqFlag; + type tDaqFlagArray is array(integer range 0 to cNumberOfCICs - 1) of tDaqFlag; - type tDaqFlag is record - data_word : std_logic; - event_id : std_logic; - n_words : std_logic; - end record tDaqFlag; + type tDaqFlagLinkArray is array (integer range <>) of tDaqFlagArray; - type tDaqFlagArray is array(integer range 0 to cNumberOfCICs - 1) of tDaqFlag; + constant DaqFlag_NULL : tDaqFlag := ('0', '0', '0'); + constant DaqFlagArray_NULL : tDaqFlagArray := ((others => DaqFlag_NULL)); - type tDaqFlagLinkArray is array (integer range <>) of tDaqFlagArray; + type tDaqData is record + data_word : std_logic_vector(cL1DataFifoWidth - 1 downto 0); + event_id : std_logic_vector(cL1CtrlFifoWidth - 1 downto 0); + n_words : std_logic_vector(cL1CtrlFifoWidth - 1 downto 0); + end record tDaqData; - constant DaqFlag_NULL : tDaqFlag := ('0', '0', '0'); - constant DaqFlagArray_NULL : tDaqFlagArray := ((others => DaqFlag_NULL)); + type tDaqDataArray is array(integer range 0 to cNumberOfCICs - 1) of tDaqData; + type tDaqDataLinkArray is array (integer range <>) of tDaqDataArray; - type tDaqData is record - data_word : std_logic_vector(cL1DataFifoWidth - 1 downto 0); - event_id : std_logic_vector(cL1CtrlFifoWidth - 1 downto 0); - n_words : std_logic_vector(cL1CtrlFifoWidth - 1 downto 0); - end record tDaqData; - - type tDaqDataArray is array(integer range 0 to cNumberOfCICs - 1) of tDaqData; - - type tDaqDataLinkArray is array (integer range <>) of tDaqDataArray; - - constant DaqData_NULL : tDaqData := ((others => '0'), (others => '0'), (others => '0')); - constant DaqDataArray_NULL : tDaqDataArray := ((others => DaqData_NULL)); + constant DaqData_NULL : tDaqData := ((others => '0'), (others => '0'), (others => '0')); + constant DaqDataArray_NULL : tDaqDataArray := ((others => DaqData_NULL)); end package dtc_data_types; - package body dtc_data_types is - function cicHeaderToSLV (header: tCICHeader) return std_logic_vector is - begin + function cicHeaderToSlv ( + header: tCICHeader + ) return std_logic_vector is + begin - return header.CIC_conf & header.status & header.bcid & header.stub_count; + return header.CIC_conf & header.status & header.bcid & header.stub_count; - end cicHeaderToSLV; + end function cicHeaderToSlv; - function fastCommandToSLV (command: tFastCommand) return std_logic_vector is - begin + function fastCommandToSlv ( + command: tFastCommand + ) return std_logic_vector is + begin - return "000" & command.fast_reset & "000" & command.l1a_trig & "000" & command.cal_pulse & "000" & command.counter_reset; + return "000" & command.fast_reset & "000" & command.l1a_trig & "000" & command.cal_pulse & "000" & command.counter_reset; - end fastCommandToSLV; + end function fastCommandToSlv; end package body dtc_data_types; diff --git a/dtc-be/common/firmware/hdl/dtc_constants.vhd b/dtc-be/common/firmware/hdl/dtc_constants.vhd index 7d05d3d4de1dd50810a60cbb21de224cc8aeb3c3..e49a3c02db35ad52e589b3849abf4874fc72ab16 100644 --- a/dtc-be/common/firmware/hdl/dtc_constants.vhd +++ b/dtc-be/common/firmware/hdl/dtc_constants.vhd @@ -1,13 +1,12 @@ library ieee; - use ieee.std_logic_1164.all; - use ieee.numeric_std.all; - + use ieee.std_logic_1164.all; + use ieee.numeric_std.all; package dtc_constants is - constant cNumberOfCICs : integer := 2; + constant cNumberOfCICs : integer := 2; - constant cL1DataFifoWidth : integer := 32; - constant cL1CtrlFifoWidth : integer := 16; + constant cL1DataFifoWidth : integer := 32; + constant cL1CtrlFifoWidth : integer := 16; end package dtc_constants; diff --git a/dtc-fe/firmware/hdl/FrameAligner.vhd b/dtc-fe/firmware/hdl/FrameAligner.vhd index ec1139d423b5fe6d7176e273c8259ad44bac410a..b4d45f092e578618447650ad4401b004d1435b82 100644 --- a/dtc-fe/firmware/hdl/FrameAligner.vhd +++ b/dtc-fe/firmware/hdl/FrameAligner.vhd @@ -1,43 +1,51 @@ -library IEEE; -use IEEE.STD_LOGIC_1164.ALL; -use work.emp_data_types.all; -use work.module_constants.all; -use work.dtc_constants.all; -use work.dtc_data_types.all; +library ieee; + use ieee.std_logic_1164.all; + +library work; + use work.emp_data_types.all; + use work.module_constants.all; + use work.dtc_constants.all; + use work.dtc_data_types.all; entity FrameAligner is generic ( - index : integer; + index : integer; module_type : string ); port ( --- Input Ports --- - clk_p : in std_logic; - data_in : in lword := LWORD_NULL; + clk_p : in std_logic; + data_in : in lword := LWORD_NULL; --- Output Ports --- - data_out : out lword := LWORD_NULL + data_out : out lword := LWORD_NULL ); -end FrameAligner; +end entity FrameAligner; -architecture Behavioral of FrameAligner is +architecture behavioral of FrameAligner is type tFrameArray is array(2 * cAlignmentDepth - 1 downto 0) of std_logic_vector(cNumberOfELinks(selectIndexFromModuleType(module_type)) - 1 downto 0); + signal frame_buffer : tFrameArray := (others => (others => '0')); signal valid_buffer : std_logic_vector(cAlignmentDepth downto 0) := (others => '0'); begin - pMain : process(clk_p) + + pMain : process (clk_p) is begin + if rising_edge(clk_p) then - if data_in.strobe = '1' then + if (data_in.strobe = '1') then -- Buffer data and valid bit frame_buffer <= frame_buffer(frame_buffer'high - 1 downto 0) & data_in.data(cNumberOfELinks(selectIndexFromModuleType(module_type)) - 1 downto 0); valid_buffer <= valid_buffer(valid_buffer'high - 1 downto 0) & data_in.valid; -- Tap data from the buffers at the correct offset for j in 0 to cNumberOfELinks(selectIndexFromModuleType(module_type)) - 1 loop + data_out.data(cNumberOfELinks(selectIndexFromModuleType(module_type)) - 1 downto 0)(j) <= frame_buffer(cAlignmentDepth + link_offsets(index)(j))(j); + end loop; + data_out.valid <= valid_buffer(valid_buffer'high); -- Set strobe bit @@ -46,6 +54,7 @@ begin data_out <= LWORD_NULL; end if; end if; + end process pMain; -end Behavioral; +end architecture behavioral; diff --git a/dtc-fe/firmware/hdl/HeaderAligner.vhd b/dtc-fe/firmware/hdl/HeaderAligner.vhd index 35dfc9b358a6b83bd2a585593a5424b064210c75..e386584566b3ed1410e543ea2da7fab322be22fd 100644 --- a/dtc-fe/firmware/hdl/HeaderAligner.vhd +++ b/dtc-fe/firmware/hdl/HeaderAligner.vhd @@ -6,14 +6,13 @@ -- to extract the stubs. ---- - library ieee; -use ieee.std_logic_1164.all; -use ieee.numeric_std.all; - -use work.emp_data_types.all; -use work.module_constants.all; + use ieee.std_logic_1164.all; + use ieee.numeric_std.all; +library work; + use work.emp_data_types.all; + use work.module_constants.all; entity HeaderAligner is generic ( @@ -22,168 +21,179 @@ entity HeaderAligner is ); port ( --- Input Ports --- - clk : in std_logic; - data_in : in lword := LWORD_NULL; - reset : in std_logic := '0'; + clk : in std_logic; + data_in : in lword := LWORD_NULL; + reset : in std_logic := '0'; --- Output Ports --- - header_start : out std_logic; - state : out std_logic_vector(3 downto 0); - sync_loss : out std_logic + header_start : out std_logic; + state : out std_logic_vector(3 downto 0); + sync_loss : out std_logic ); -end HeaderAligner; +end entity HeaderAligner; + +architecture behavorial of HeaderAligner is + signal data_reg : lword := LWORD_NULL; -architecture Behavorial of HeaderAligner is + signal header_found : std_logic := '0'; + signal header_start_internal : std_logic := '0'; + signal sync_loss_internal : std_logic := '0'; + signal counter : unsigned(5 downto 0) := (others => '0'); - signal data_reg : lword := LWORD_NULL; + type tAlignerState is (unlocked, locking, locked); - signal header_found : std_logic := '0'; - signal header_start_internal : std_logic := '0'; - signal sync_loss_internal : std_logic := '0'; - signal counter : unsigned(5 downto 0) := (others => '0'); + signal aligner : tAlignerState := unlocked; - type aligner_state is (unlocked, locking, locked); - signal aligner : aligner_state := unlocked; - signal align_state : std_logic_vector(2 downto 0) := (others => '0'); signal sync_state : std_logic := '0'; signal sr_header_start : std_logic_vector(cHeaderSRDelay(selectIndexFromModuleType(module_type, bandwidth))'length - 1 downto 0) := (others => '0'); - begin - ff: process(clk) + ff : process (clk) is begin + if rising_edge(clk) then data_reg <= data_in; end if; - end process; + end process ff; header_start <= header_start_internal; - state <= sync_state & align_state; - + state <= sync_state & align_state; - align : process(clk) + align : process (clk) is begin - if rising_edge(clk) then - if data_reg.strobe = '1' then - if reset = '1' then - aligner <= unlocked; + if rising_edge(clk) then + if (data_reg.strobe = '1') then + if (reset = '1') then + aligner <= unlocked; sync_state <= '0'; end if; case aligner is - when unlocked => - align_state <= "001"; - header_start_internal <= '1'; - sync_state <= '0'; + when unlocked => + align_state <= "001"; + header_start_internal <= '1'; + sync_state <= '0'; - if header_found = '1' then - counter <= to_unsigned(cHeaderSignalDelay(selectIndexFromModuleType(module_type, bandwidth)), 6); - aligner <= locking; - end if; + if (header_found = '1') then + counter <= to_unsigned(cHeaderSignalDelay(selectIndexFromModuleType(module_type, bandwidth)), 6); + aligner <= locking; + end if; - when locking => - align_state <= "010"; - header_start_internal <= '1'; - counter <= counter - 1; - sync_state <= '0'; - - if counter = 0 then - aligner <= locked; - sync_state <= '1'; - end if; + when locking => + align_state <= "010"; + header_start_internal <= '1'; + counter <= counter - 1; + sync_state <= '0'; + + if (counter = 0) then + aligner <= locked; + sync_state <= '1'; + end if; + + when locked => + align_state <= "100"; + counter <= counter - 1; - when locked => - align_state <= "100"; - counter <= counter - 1; + if (counter = 0) then + header_start_internal <= '1'; + else + header_start_internal <= '0'; + end if; - if counter = 0 then + if (sync_loss_internal = '1') then + sync_state <= '0'; + end if; + + when others => header_start_internal <= '1'; - else - header_start_internal <= '0'; - end if; - - if sync_loss_internal = '1' then - sync_state <= '0'; - end if; - - when others => - header_start_internal <= '1'; - sync_state <= '0'; + sync_state <= '0'; end case; + else + case aligner is + when locked => header_start_internal <= '0'; - when others => + + when others => header_start_internal <= '1'; + end case; + end if; end if; - end process; + end process align; --==============================-- -- Check data for header fingerprint --==============================-- - - g2S : if module_type = "2S" generate + + Gen2s : if module_type = "2S" generate --==============================-- - FingerPrintChecker: entity work.HeaderFingerprintChecker(module2S) + FingerPrintChecker : entity work.HeaderFingerprintChecker(module2S) --==============================-- generic map ( - module_type => module_type, - bandwidth => bandwidth + MODULE_TYPE => module_type, + BANDWIDTH => bandwidth ) port map ( --- Input Ports --- - clk => clk, - data_in => data_reg, + clk => clk, + data_in => data_reg, --- Output Ports --- header_found => header_found ); - end generate; - gPS : if module_type = "PS" generate - g5G : if bandwidth = 5 generate + + end generate Gen2s; + + GenPs : if module_type = "PS" generate + + Gen5g : if bandwidth = 5 generate --==============================-- - FingerPrintChecker: entity work.HeaderFingerprintChecker(modulePS5G) + FingerPrintChecker : entity work.HeaderFingerprintChecker(modulePS5G) --==============================-- generic map ( - module_type => module_type, - bandwidth => bandwidth + MODULE_TYPE => module_type, + BANDWIDTH => bandwidth ) port map ( --- Input Ports --- - clk => clk, - data_in => data_reg, + clk => clk, + data_in => data_reg, --- Output Ports --- header_found => header_found ); - end generate; - g10G : if bandwidth = 10 generate + + end generate Gen5g; + + Gen10g : if bandwidth = 10 generate --==============================-- - FingerPrintChecker: entity work.HeaderFingerprintChecker(modulePS10G) + FingerPrintChecker : entity work.HeaderFingerprintChecker(modulePS10G) --==============================-- generic map ( - module_type => module_type, - bandwidth => bandwidth + MODULE_TYPE => module_type, + BANDWIDTH => bandwidth ) port map ( --- Input Ports --- - clk => clk, - data_in => data_reg, + clk => clk, + data_in => data_reg, --- Output Ports --- header_found => header_found ); - end generate; - end generate; + end generate Gen10g; + + end generate GenPs; --==============================-- -- Debugging @@ -191,26 +201,23 @@ begin sync_loss <= sync_loss_internal; - - pSyncCheck : process(clk) + pSyncCheck : process (clk) is begin - if rising_edge(clk) then + if rising_edge(clk) then sr_header_start <= sr_header_start(sr_header_start'high - 1 downto sr_header_start'low) & header_start_internal; - - if aligner = locked then - if sr_header_start = cHeaderSRDelay(selectIndexFromModuleType(module_type, bandwidth)) then + if (aligner = locked) then + if (sr_header_start = cHeaderSRDelay(selectIndexFromModuleType(module_type, bandwidth))) then sync_loss_internal <= not header_found; else sync_loss_internal <= '0'; end if; - else sync_loss_internal <= '0'; end if; - end if; - end process; -end architecture; + end process pSyncCheck; + +end architecture behavorial; diff --git a/dtc-fe/firmware/hdl/HeaderExtractor.vhd b/dtc-fe/firmware/hdl/HeaderExtractor.vhd index 5b90cfe3aefba3c2ac06fc21cadf46f860311efa..5e52d635f833d6a65d5f1b3717e7e0e0aaaa3f27 100644 --- a/dtc-fe/firmware/hdl/HeaderExtractor.vhd +++ b/dtc-fe/firmware/hdl/HeaderExtractor.vhd @@ -8,21 +8,21 @@ -- possible, meaning that they are not buffered until the end of the boxcar. ---- +library ieee; + use ieee.std_logic_1164.all; + use ieee.numeric_std.all; -library IEEE; -use IEEE.STD_LOGIC_1164.ALL; -use IEEE.NUMERIC_STD.ALL; - -use work.dtc_data_types.all; +library work; + use work.dtc_data_types.all; entity HeaderExtractor is port ( --- Input Ports --- - clk : in std_logic; - header_frame : in integer; - frame : in std_logic_vector(35 downto 0) := (others => '0'); + clk : in std_logic; + header_frame : in integer; + frame : in std_logic_vector(35 downto 0) := (others => '0'); --- Output Ports --- - header_out : out tCICHeader; - header_mode : out std_logic + header_out : out tCICHeader; + header_mode : out std_logic ); -end HeaderExtractor; +end entity HeaderExtractor; diff --git a/dtc-fe/firmware/hdl/HeaderExtractor_2S.vhd b/dtc-fe/firmware/hdl/HeaderExtractor_2S.vhd index 9e4a863add4313cc9eced6625213980d89daf95c..17ba7a222fbdff994e3c9ba32825768ccf16d585 100644 --- a/dtc-fe/firmware/hdl/HeaderExtractor_2S.vhd +++ b/dtc-fe/firmware/hdl/HeaderExtractor_2S.vhd @@ -8,54 +8,56 @@ -- possible, meaning that they are not buffered until the end of the boxcar. ---- +library ieee; + use ieee.std_logic_1164.all; + use ieee.numeric_std.all; -library IEEE; -use IEEE.STD_LOGIC_1164.ALL; -use IEEE.NUMERIC_STD.ALL; - -use work.module_constants.all; -use work.front_end_data_types.all; -use work.emp_data_types.all; -use work.dtc_constants.all; -use work.dtc_data_types.all; - +library work; + use work.module_constants.all; + use work.front_end_data_types.all; + use work.emp_data_types.all; + use work.dtc_constants.all; + use work.dtc_data_types.all; architecture module2S of HeaderExtractor is - signal cic_header : tCICHeader := ('0', (others => '0'), (others => '0'), (others => '0')); - signal header_mode_signal : std_logic := '0'; + + signal cic_header : tCICHeader := ('0', (others => '0'), (others => '0'), (others => '0')); + signal header_mode_signal : std_logic := '0'; begin - header_out <= cic_header; + header_out <= cic_header; header_mode <= header_mode_signal; - pMain: process(clk) + pMain : process (clk) is begin + if rising_edge(clk) then -- Header Extraction - if header_frame = 0 then - cic_header <= ('0', (others => '0'), (others => '0'), (others => '0')); - cic_header.CIC_conf <= frame(4); + if (header_frame = 0) then + cic_header <= ('0', (others => '0'), (others => '0'), (others => '0')); + cic_header.CIC_conf <= frame(4); cic_header.status(8 downto 5) <= frame(3 downto 0); - header_mode_signal <= '1'; - elsif header_frame = 1 then + header_mode_signal <= '1'; + elsif (header_frame = 1) then cic_header.status(4 downto 0) <= frame(4 downto 0); - header_mode_signal <= '1'; - elsif header_frame = 2 then + header_mode_signal <= '1'; + elsif (header_frame = 2) then cic_header.bcid(11 downto 7) <= frame(4 downto 0); - header_mode_signal <= '1'; - elsif header_frame = 3 then + header_mode_signal <= '1'; + elsif (header_frame = 3) then cic_header.bcid(6 downto 2) <= frame(4 downto 0); - header_mode_signal <= '1'; - elsif header_frame = 4 then - cic_header.bcid(1 downto 0) <= frame(4 downto 3); + header_mode_signal <= '1'; + elsif (header_frame = 4) then + cic_header.bcid(1 downto 0) <= frame(4 downto 3); cic_header.stub_count(5 downto 3) <= frame(2 downto 0); - header_mode_signal <= '0'; - elsif header_frame = 5 then + header_mode_signal <= '0'; + elsif (header_frame = 5) then cic_header.stub_count(2 downto 0) <= frame(4 downto 2); - header_mode_signal <= '0'; + header_mode_signal <= '0'; end if; end if; - end process; -end module2S; + end process pMain; + +end architecture module2S; diff --git a/dtc-fe/firmware/hdl/HeaderExtractor_PS10G.vhd b/dtc-fe/firmware/hdl/HeaderExtractor_PS10G.vhd index ad928dca82590742886b800d30892d1b23dc858c..be4208515d3e6b199b602b0c23cc405c956c0913 100644 --- a/dtc-fe/firmware/hdl/HeaderExtractor_PS10G.vhd +++ b/dtc-fe/firmware/hdl/HeaderExtractor_PS10G.vhd @@ -8,47 +8,49 @@ -- possible, meaning that they are not buffered until the end of the boxcar. ---- +library ieee; + use ieee.std_logic_1164.all; + use ieee.numeric_std.all; -library IEEE; -use IEEE.STD_LOGIC_1164.ALL; -use IEEE.NUMERIC_STD.ALL; - -use work.module_constants.all; -use work.front_end_data_types.all; -use work.emp_data_types.all; -use work.dtc_constants.all; -use work.dtc_data_types.all; - +library work; + use work.module_constants.all; + use work.front_end_data_types.all; + use work.emp_data_types.all; + use work.dtc_constants.all; + use work.dtc_data_types.all; architecture modulePS10G of HeaderExtractor is - signal cic_header : tCICHeader := ('0', (others => '0'), (others => '0'), (others => '0')); - signal header_mode_signal : std_logic := '0'; + + signal cic_header : tCICHeader := ('0', (others => '0'), (others => '0'), (others => '0')); + signal header_mode_signal : std_logic := '0'; begin - header_out <= cic_header; + header_out <= cic_header; header_mode <= header_mode_signal; - pMain: process(clk) + pMain : process (clk) is begin + if rising_edge(clk) then -- Header Extraction - if header_frame = 0 then - cic_header <= ('0', (others => '0'), (others => '0'), (others => '0')); - cic_header.CIC_conf <= frame(11); - cic_header.status <= frame(10 downto 2); + if (header_frame = 0) then + cic_header <= ('0', (others => '0'), (others => '0'), (others => '0')); + cic_header.CIC_conf <= frame(11); + cic_header.status <= frame(10 downto 2); cic_header.bcid(11 downto 10) <= frame(1 downto 0); - header_mode_signal <= '1'; - elsif header_frame = 1 then - cic_header.bcid(9 downto 0) <= frame(11 downto 2); + header_mode_signal <= '1'; + elsif (header_frame = 1) then + cic_header.bcid(9 downto 0) <= frame(11 downto 2); cic_header.stub_count(5 downto 4) <= frame(1 downto 0); - header_mode_signal <= '0'; - elsif header_frame = 2 then + header_mode_signal <= '0'; + elsif (header_frame = 2) then cic_header.stub_count(3 downto 0) <= frame(11 downto 8); - header_mode_signal <= '0'; + header_mode_signal <= '0'; end if; end if; - end process; -end modulePS10G; + end process pMain; + +end architecture modulePS10G; diff --git a/dtc-fe/firmware/hdl/HeaderExtractor_PS5G.vhd b/dtc-fe/firmware/hdl/HeaderExtractor_PS5G.vhd index f047322f8a4091d98eab69a42c11f9ea0d6489d7..713786615b4e4d29a92b96852fb20150a951808c 100644 --- a/dtc-fe/firmware/hdl/HeaderExtractor_PS5G.vhd +++ b/dtc-fe/firmware/hdl/HeaderExtractor_PS5G.vhd @@ -8,53 +8,55 @@ -- possible, meaning that they are not buffered until the end of the boxcar. ---- +library ieee; + use ieee.std_logic_1164.all; + use ieee.numeric_std.all; -library IEEE; -use IEEE.STD_LOGIC_1164.ALL; -use IEEE.NUMERIC_STD.ALL; - -use work.module_constants.all; -use work.front_end_data_types.all; -use work.emp_data_types.all; -use work.dtc_constants.all; -use work.dtc_data_types.all; - +library work; + use work.module_constants.all; + use work.front_end_data_types.all; + use work.emp_data_types.all; + use work.dtc_constants.all; + use work.dtc_data_types.all; architecture modulePS5G of HeaderExtractor is - signal cic_header : tCICHeader := ('0', (others => '0'), (others => '0'), (others => '0')); - signal header_mode_signal : std_logic := '0'; + + signal cic_header : tCICHeader := ('0', (others => '0'), (others => '0'), (others => '0')); + signal header_mode_signal : std_logic := '0'; begin - header_out <= cic_header; + header_out <= cic_header; header_mode <= header_mode_signal; - pMain: process(clk) + pMain : process (clk) is begin + if rising_edge(clk) then -- Header Extraction - if header_frame = 0 then - cic_header <= ('0', (others => '0'), (others => '0'), (others => '0')); - cic_header.CIC_conf <= frame(5); + if (header_frame = 0) then + cic_header <= ('0', (others => '0'), (others => '0'), (others => '0')); + cic_header.CIC_conf <= frame(5); cic_header.status(8 downto 4) <= frame(4 downto 0); - header_mode_signal <= '1'; - elsif header_frame = 1 then + header_mode_signal <= '1'; + elsif (header_frame = 1) then cic_header.status(3 downto 0) <= frame(5 downto 2); cic_header.bcid(11 downto 10) <= frame(1 downto 0); - header_mode_signal <= '1'; - elsif header_frame = 2 then + header_mode_signal <= '1'; + elsif (header_frame = 2) then cic_header.bcid(9 downto 4) <= frame(5 downto 0); - header_mode_signal <= '1'; - elsif header_frame = 3 then - cic_header.bcid(3 downto 0) <= frame(5 downto 2); + header_mode_signal <= '1'; + elsif (header_frame = 3) then + cic_header.bcid(3 downto 0) <= frame(5 downto 2); cic_header.stub_count(5 downto 4) <= frame(1 downto 0); - header_mode_signal <= '0'; - elsif header_frame = 4 then + header_mode_signal <= '0'; + elsif (header_frame = 4) then cic_header.stub_count(3 downto 0) <= frame(5 downto 2); - header_mode_signal <= '0'; + header_mode_signal <= '0'; end if; end if; - end process; -end modulePS5G; + end process pMain; + +end architecture modulePS5G; diff --git a/dtc-fe/firmware/hdl/HeaderFingerprintChecker.vhd b/dtc-fe/firmware/hdl/HeaderFingerprintChecker.vhd index 78aa442607195cf8eefe1bff5d8fe3626de7a2e4..8d60e09773351ca9ae4797bb8ebb447a269dd4a6 100644 --- a/dtc-fe/firmware/hdl/HeaderFingerprintChecker.vhd +++ b/dtc-fe/firmware/hdl/HeaderFingerprintChecker.vhd @@ -2,14 +2,10 @@ -- Author: David Monk -- Description file for HeaderFingerprintChecker entity - - library ieee; -use ieee.std_logic_1164.all; -use ieee.numeric_std.all; - -use work.emp_data_types.all; - + use ieee.std_logic_1164.all; + use ieee.numeric_std.all; + use work.emp_data_types.all; entity HeaderFingerprintChecker is generic ( @@ -18,9 +14,9 @@ entity HeaderFingerprintChecker is ); port ( --- Input Ports --- - clk : in std_logic; - data_in : in lword := LWORD_NULL; + clk : in std_logic; + data_in : in lword := LWORD_NULL; --- Output Ports --- - header_found : out std_logic := '0' + header_found : out std_logic := '0' ); -end HeaderFingerprintChecker; +end entity HeaderFingerprintChecker; diff --git a/dtc-fe/firmware/hdl/HeaderFingerprintChecker_2S.vhd b/dtc-fe/firmware/hdl/HeaderFingerprintChecker_2S.vhd index 464645c95ba5217fd2671d748932c6fba94a30e8..ddaccadc56509771d7a4aafeb5ab3b98a6b85124 100644 --- a/dtc-fe/firmware/hdl/HeaderFingerprintChecker_2S.vhd +++ b/dtc-fe/firmware/hdl/HeaderFingerprintChecker_2S.vhd @@ -2,59 +2,63 @@ -- Author: David Monk -- Description file for HeaderFingerprintChecker entity - - library ieee; -use ieee.std_logic_1164.all; -use ieee.numeric_std.all; - -use work.emp_data_types.all; -use work.dtc_constants.all; -use work.dtc_data_types.all; -use work.module_constants.all; + use ieee.std_logic_1164.all; + use ieee.numeric_std.all; +library work; + use work.emp_data_types.all; + use work.dtc_constants.all; + use work.dtc_data_types.all; + use work.module_constants.all; architecture module2S of HeaderFingerprintChecker is type tRollingWindow is array(70 downto 0) of std_logic_vector(cNumberOfELinks(selectIndexFromModuleType(module_type, bandwidth)) - 1 downto 0); - signal rolling_window : tRollingWindow := (others => (others => '0')); - signal match : std_logic := '0'; - constant cBCIDTapPoint : integer := 0; - constant cPaddingTapPoint : integer := 5; - constant cConfTapPoint : integer := 4; + signal rolling_window : tRollingWindow := (others => (others => '0')); + signal match : std_logic := '0'; + + constant cBCIDTapPoint : integer := 0; + constant cPaddingTapPoint : integer := 5; + constant cConfTapPoint : integer := 4; begin + header_found <= match; - pMain : process(clk) - variable previous_bcid : std_logic_vector(11 downto 0); - variable bcid : std_logic_vector(11 downto 0); - variable fingerprint_match : boolean; - variable bcid_match : boolean; - variable conf_match : boolean; + pMain : process (clk) is + + variable previous_bcid : std_logic_vector(11 downto 0); + variable bcid : std_logic_vector(11 downto 0); + variable fingerprint_match : boolean; + variable bcid_match : boolean; + variable conf_match : boolean; + begin - if rising_edge(clk) and data_in.strobe = '1' then + if (rising_edge(clk) and data_in.strobe = '1') then -- Update rolling window with new data rolling_window <= rolling_window(rolling_window'high - 1 downto 0) & data_in.data(cNumberOfELinks(selectIndexFromModuleType(module_type, bandwidth)) - 1 downto 0); - previous_bcid := rolling_window(cBCIDTapPoint + cBoxCarFrames + 2) & rolling_window(cBCIDTapPoint + cBoxCarFrames + 1) & rolling_window(cBCIDTapPoint + cBoxCarFrames)(4 downto 3); - bcid := rolling_window(cBCIDTapPoint + 2) & rolling_window(cBCIDTapPoint + 1) & rolling_window(cBCIDTapPoint)(4 downto 3); + previous_bcid := rolling_window(cBCIDTapPoint + cBoxCarFrames + 2) & rolling_window(cBCIDTapPoint + cBoxCarFrames + 1) & rolling_window(cBCIDTapPoint + cBoxCarFrames)(4 downto 3); + bcid := rolling_window(cBCIDTapPoint + 2) & rolling_window(cBCIDTapPoint + 1) & rolling_window(cBCIDTapPoint)(4 downto 3); -- Conditions for header - fingerprint_match := rolling_window(cBoxCarFrames + cPaddingTapPoint)(3 downto 0) = b"0000" and rolling_window(cPaddingTapPoint)(3 downto 0) = b"0000" ; - conf_match := rolling_window(cBoxCarFrames + cConfTapPoint)(4) = '0' and rolling_window(cConfTapPoint)(4) = '0'; - if unsigned(bcid) > 7 then - bcid_match := unsigned(bcid) - unsigned(previous_bcid) = 8; + fingerprint_match := rolling_window(cBoxCarFrames + cPaddingTapPoint)(3 downto 0) = b"0000" and rolling_window(cPaddingTapPoint)(3 downto 0) = b"0000"; + conf_match := rolling_window(cBoxCarFrames + cConfTapPoint)(4) = '0' and rolling_window(cConfTapPoint)(4) = '0'; + if (unsigned(bcid) > 7) then + bcid_match := unsigned(bcid) - unsigned(previous_bcid) = 8; else - bcid_match := unsigned(bcid) + 3564 - unsigned(previous_bcid) = 8; + bcid_match := unsigned(bcid) + 3564 - unsigned(previous_bcid) = 8; end if; - - if fingerprint_match and bcid_match and conf_match then - match <= '1'; + + if (fingerprint_match and bcid_match and conf_match) then + match <= '1'; else - match <= '0'; + match <= '0'; end if; end if; - end process; -end architecture; + + end process pMain; + +end architecture module2S; diff --git a/dtc-fe/firmware/hdl/HeaderFingerprintChecker_PS10G.vhd b/dtc-fe/firmware/hdl/HeaderFingerprintChecker_PS10G.vhd index bf6df510329a7db8f2f5bcd01a1fe172ae75a6d8..c4ffde325b53a39f22f7f13f93abb756e1fd3123 100644 --- a/dtc-fe/firmware/hdl/HeaderFingerprintChecker_PS10G.vhd +++ b/dtc-fe/firmware/hdl/HeaderFingerprintChecker_PS10G.vhd @@ -2,63 +2,65 @@ -- Author: Chithra Kurup -- Description file for HeaderFingerprintChecker entity - - library ieee; -use ieee.std_logic_1164.all; -use ieee.numeric_std.all; - -use work.emp_data_types.all; -use work.dtc_constants.all; -use work.dtc_data_types.all; -use work.module_constants.all; + use ieee.std_logic_1164.all; + use ieee.numeric_std.all; +library work; + use work.emp_data_types.all; + use work.dtc_constants.all; + use work.dtc_data_types.all; + use work.module_constants.all; architecture modulePS10G of HeaderFingerprintChecker is type tRollingWindow is array(70 downto 0) of std_logic_vector(cNumberOfELinks(selectIndexFromModuleType(module_type, bandwidth)) - 1 downto 0); - signal rolling_window : tRollingWindow := (others => (others => '0')); - signal match : std_logic := '0'; - constant cBCIDTapPoint : integer := 0; - constant cPaddingTapPoint : integer := 2; - constant cConfTapPoint : integer := 1; + signal rolling_window : tRollingWindow := (others => (others => '0')); + signal match : std_logic := '0'; + + constant cBCIDTapPoint : integer := 0; + constant cPaddingTapPoint : integer := 2; + constant cConfTapPoint : integer := 1; begin + header_found <= match; - pMain : process(clk) - variable previous_bcid : std_logic_vector(11 downto 0); - variable bcid : std_logic_vector(11 downto 0); - variable fingerprint_match : boolean; - variable bcid_match : boolean; - variable conf_match : boolean; + pMain : process (clk) is + + variable previous_bcid : std_logic_vector(11 downto 0); + variable bcid : std_logic_vector(11 downto 0); + variable fingerprint_match : boolean; + variable bcid_match : boolean; + variable conf_match : boolean; begin - if rising_edge(clk) and data_in.strobe = '1' then + if (rising_edge(clk) and data_in.strobe = '1') then -- Update rolling window with new data rolling_window <= rolling_window(rolling_window'high - 1 downto 0) & data_in.data(cNumberOfELinks(selectIndexFromModuleType(module_type, bandwidth)) - 1 downto 0); previous_bcid := rolling_window(cBCIDTapPoint + cBoxCarFrames + 1)(1 downto 0) & rolling_window(cBCIDTapPoint + cBoxCarFrames)(11 downto 2); - bcid := rolling_window(cBCIDTapPoint + 1)(1 downto 0) & rolling_window(cBCIDTapPoint)(11 downto 2); + bcid := rolling_window(cBCIDTapPoint + 1)(1 downto 0) & rolling_window(cBCIDTapPoint)(11 downto 2); -- Conditions for header fingerprint_match := rolling_window(cBoxCarFrames + cPaddingTapPoint)(4 downto 0) = b"00000" and rolling_window(cPaddingTapPoint)(4 downto 0) = b"00000"; conf_match := rolling_window(cBoxCarFrames + cConfTapPoint)(11) = '1' and rolling_window(cConfTapPoint)(11) = '1'; - if unsigned(bcid) > 7 then - bcid_match := unsigned(bcid) - unsigned(previous_bcid) = 8; + if (unsigned(bcid) > 7) then + bcid_match := unsigned(bcid) - unsigned(previous_bcid) = 8; else - bcid_match := unsigned(bcid) + 3564 - unsigned(previous_bcid) = 8; + bcid_match := unsigned(bcid) + 3564 - unsigned(previous_bcid) = 8; end if; - - if fingerprint_match and bcid_match and conf_match then - match <= '1'; + + if (fingerprint_match and bcid_match and conf_match) then + match <= '1'; else - match <= '0'; + match <= '0'; end if; - end if; - end process; -end architecture; + + end process pMain; + +end architecture modulePS10G; diff --git a/dtc-fe/firmware/hdl/HeaderFingerprintChecker_PS5G.vhd b/dtc-fe/firmware/hdl/HeaderFingerprintChecker_PS5G.vhd index 877acaddd5ace1af083492a86574e0219a69c635..b881e6e4586dcaf0bc0cc123b90386aa761edb05 100644 --- a/dtc-fe/firmware/hdl/HeaderFingerprintChecker_PS5G.vhd +++ b/dtc-fe/firmware/hdl/HeaderFingerprintChecker_PS5G.vhd @@ -2,62 +2,66 @@ -- Author: Chithra Kurup -- Description file for HeaderFingerprintChecker entity - - library ieee; -use ieee.std_logic_1164.all; -use ieee.numeric_std.all; - -use work.emp_data_types.all; -use work.dtc_constants.all; -use work.dtc_data_types.all; -use work.module_constants.all; + use ieee.std_logic_1164.all; + use ieee.numeric_std.all; +library work; + use work.emp_data_types.all; + use work.dtc_constants.all; + use work.dtc_data_types.all; + use work.module_constants.all; architecture modulePS5G of HeaderFingerprintChecker is type tRollingWindow is array(71 downto 0) of std_logic_vector(cNumberOfELinks(selectIndexFromModuleType(module_type, bandwidth)) - 1 downto 0); - signal rolling_window : tRollingWindow := (others => (others => '0')); - signal match : std_logic := '0'; - constant cBCIDTapPoint : integer := 0; - constant cPaddingTapPoint : integer := 4; - constant cConfTapPoint : integer := 3; + signal rolling_window : tRollingWindow := (others => (others => '0')); + signal match : std_logic := '0'; + + constant cBCIDTapPoint : integer := 0; + constant cPaddingTapPoint : integer := 4; + constant cConfTapPoint : integer := 3; begin + header_found <= match; - pMain : process(clk) - variable previous_bcid : std_logic_vector(11 downto 0); - variable bcid : std_logic_vector(11 downto 0); - variable fingerprint_match : boolean; - variable bcid_match : boolean; - variable conf_match : boolean; + pMain : process (clk) is + + variable previous_bcid : std_logic_vector(11 downto 0); + variable bcid : std_logic_vector(11 downto 0); + variable fingerprint_match : boolean; + variable bcid_match : boolean; + variable conf_match : boolean; + begin - if rising_edge(clk) and data_in.strobe = '1' then + if (rising_edge(clk) and data_in.strobe = '1') then -- Update rolling window with new data rolling_window <= rolling_window(rolling_window'high - 1 downto 0) & data_in.data(cNumberOfELinks(selectIndexFromModuleType(module_type, bandwidth)) - 1 downto 0); previous_bcid := rolling_window(cBCIDTapPoint + cBoxCarFrames + 2)(1 downto 0) & rolling_window(cBCIDTapPoint + cBoxCarFrames + 1) & rolling_window(cBCIDTapPoint + cBoxCarFrames)(5 downto 2); - bcid := rolling_window(cBCIDTapPoint + 2)(1 downto 0) & rolling_window(cBCIDTapPoint + 1) & rolling_window(cBCIDTapPoint)(5 downto 2); + bcid := rolling_window(cBCIDTapPoint + 2)(1 downto 0) & rolling_window(cBCIDTapPoint + 1) & rolling_window(cBCIDTapPoint)(5 downto 2); -- Conditions for header fingerprint_match := rolling_window(cBoxCarFrames + cPaddingTapPoint) = b"000000" and rolling_window(cPaddingTapPoint) = b"000000"; conf_match := rolling_window(cBoxCarFrames + cConfTapPoint)(5) = '1' and rolling_window(cConfTapPoint)(5) = '1'; - if unsigned(bcid) > 7 then - bcid_match := unsigned(bcid) - unsigned(previous_bcid) = 8; + if (unsigned(bcid) > 7) then + bcid_match := unsigned(bcid) - unsigned(previous_bcid) = 8; else - bcid_match := unsigned(bcid) + 3564 - unsigned(previous_bcid) = 8; + bcid_match := unsigned(bcid) + 3564 - unsigned(previous_bcid) = 8; end if; - - if fingerprint_match and bcid_match and conf_match then - match <= '1'; + + if (fingerprint_match and bcid_match and conf_match) then + match <= '1'; else - match <= '0'; + match <= '0'; end if; end if; - end process; -end architecture; + + end process pMain; + +end architecture modulePS5G; diff --git a/dtc-fe/firmware/hdl/HealthMonitor.vhd b/dtc-fe/firmware/hdl/HealthMonitor.vhd index c7ebaab6b9b72c3767fff02cb1111792993a34fc..896a44f5bb1c9a3d755247af67c94184ecd3aa53 100644 --- a/dtc-fe/firmware/hdl/HealthMonitor.vhd +++ b/dtc-fe/firmware/hdl/HealthMonitor.vhd @@ -5,196 +5,196 @@ ---- - -library IEEE; -use IEEE.STD_LOGIC_1164.ALL; -use IEEE.NUMERIC_STD.ALL; - -use work.module_constants.all; -use work.front_end_data_types.all; -use work.emp_data_types.all; -use work.dtc_constants.all; -use work.dtc_data_types.all; - -use work.ipbus.all; -use work.ipbus_reg_types.all; - +library ieee; + use ieee.std_logic_1164.all; + use ieee.numeric_std.all; + +library work; + use work.module_constants.all; + use work.front_end_data_types.all; + use work.emp_data_types.all; + use work.dtc_constants.all; + use work.dtc_data_types.all; + use work.ipbus.all; + use work.ipbus_reg_types.all; entity HealthMonitor is port ( --- Input Ports --- - clk_p : in std_logic; - header_start : in std_logic_vector(cNumberOfCICs - 1 downto 0); - sync_loss : in std_logic_vector(cNumberOfCICs - 1 downto 0); - header_in : in tCICHeaderArray(cNumberOfCICs - 1 downto 0); - aligner_state : in tAlignerArray(cNumberOfCICs - 1 downto 0); - counter_reset : in std_logic; - uplink_rdy_i : in std_logic; + clk_p : in std_logic; + header_start : in std_logic_vector(cNumberOfCICs - 1 downto 0); + sync_loss : in std_logic_vector(cNumberOfCICs - 1 downto 0); + header_in : in tCICHeaderArray(cNumberOfCICs - 1 downto 0); + aligner_state : in tAlignerArray(cNumberOfCICs - 1 downto 0); + counter_reset : in std_logic; + uplink_rdy_i : in std_logic; --- Output Ports --- --- IPBus Ports --- - clk : in std_logic; - rst : in std_logic; - ipb_in : in ipb_wbus; - ipb_out : out ipb_rbus + clk : in std_logic; + rst : in std_logic; + ipb_in : in ipb_wbus; + ipb_out : out ipb_rbus ); -end HealthMonitor ; +end entity HealthMonitor; architecture Behavorial of HealthMonitor is - constant N_STAT : integer := 14; - signal status_registers : ipb_reg_v(N_STAT - 1 downto 0) := (others => (others => '0')); + constant N_STAT : integer := 14; + signal status_registers : ipb_reg_v(N_STAT - 1 downto 0) := (others => (others => '0')); -- signal control_registers : ipb_reg_v(5 downto 0) := (others => (others => '0')); - signal header_reg : ipb_reg_v(cNumberOfCICs - 1 downto 0) := (others => (others => '0')); - signal sync_loss_count_reg : ipb_reg_v(cNumberOfCICs - 1 downto 0) := (others => (others => '0')); - signal stub_count_reg : ipb_reg_v(cNumberOfCICs - 1 downto 0) := (others => (others => '0')); - signal cic_sync_error_count_reg : ipb_reg_v(cNumberOfCICs - 1 downto 0) := (others => (others => '0')); - signal fe_error_flag_count_reg : ipb_reg_v(cNumberOfCICs - 1 downto 0) := (others => (others => '0')); - signal cic_overflow_count_reg : ipb_reg_v(cNumberOfCICs - 1 downto 0) := (others => (others => '0')); + signal header_reg : ipb_reg_v(cNumberOfCICs - 1 downto 0) := (others => (others => '0')); + signal sync_loss_count_reg : ipb_reg_v(cNumberOfCICs - 1 downto 0) := (others => (others => '0')); + signal stub_count_reg : ipb_reg_v(cNumberOfCICs - 1 downto 0) := (others => (others => '0')); + signal cic_sync_error_count_reg : ipb_reg_v(cNumberOfCICs - 1 downto 0) := (others => (others => '0')); + signal fe_error_flag_count_reg : ipb_reg_v(cNumberOfCICs - 1 downto 0) := (others => (others => '0')); + signal cic_overflow_count_reg : ipb_reg_v(cNumberOfCICs - 1 downto 0) := (others => (others => '0')); - signal aligner_status_reg : ipb_reg_v(0 downto 0) := (others => (others => '0')); - signal uplink_not_rdy_count : unsigned(31 downto 0) := (others => '0'); - signal uplink_rdy : std_logic := '0'; + signal aligner_status_reg : ipb_reg_v(0 downto 0) := (others => (others => '0')); + signal uplink_not_rdy_count : unsigned(31 downto 0) := (others => '0'); + signal uplink_rdy : std_logic := '0'; - - constant max_stubs : unsigned(5 downto 0) := to_unsigned(16,6); + constant max_stubs : unsigned(5 downto 0) := to_unsigned(16, 6); - --constant bin_width : integer := 32; - --signal stub_count_array : ldata(cNumberOfCICs - 1 downto 0) := (others => LWORD_NULL); - --signal trigger_window : std_logic_vector(36 - 1 downto 0) := X"100000000"; - --signal histogram_reset : std_logic := '0'; - --signal max_value0, max_value1 : std_logic_vector(bin_width - 1 downto 0) := (others => '0'); +-- constant bin_width : integer := 32; +-- signal stub_count_array : ldata(cNumberOfCICs - 1 downto 0) := (others => LWORD_NULL); +-- signal trigger_window : std_logic_vector(36 - 1 downto 0) := X"100000000"; +-- signal histogram_reset : std_logic := '0'; +-- signal max_value0, max_value1 : std_logic_vector(bin_width - 1 downto 0) := (others => '0'); begin - --==============================-- - fe_health_mon: entity work.ipbus_ctrlreg_v + FeHealthMon : entity work.ipbus_ctrlreg_v --==============================-- - generic map( - N_CTRL => 0, - N_STAT => N_STAT + generic map ( + N_CTRL => 0, + N_STAT => N_STAT ) - port map( - clk => clk, - reset => rst, - ipbus_in => ipb_in, - ipbus_out => ipb_out, - d => status_registers - -- q => control_registers + port map ( + clk => clk, + reset => rst, + ipbus_in => ipb_in, + ipbus_out => ipb_out, + d => status_registers + -- q => control_registers ); aligner_status_reg(0)(8) <= uplink_rdy; - - status_registers(0 downto 0) <= aligner_status_reg; - status_registers(2 downto 1) <= header_reg; - status_registers(4 downto 3) <= sync_loss_count_reg; - status_registers(6 downto 5) <= stub_count_reg; - status_registers(8 downto 7) <= cic_sync_error_count_reg; - status_registers(10 downto 9) <= fe_error_flag_count_reg; + + status_registers(0 downto 0) <= aligner_status_reg; + status_registers(2 downto 1) <= header_reg; + status_registers(4 downto 3) <= sync_loss_count_reg; + status_registers(6 downto 5) <= stub_count_reg; + status_registers(8 downto 7) <= cic_sync_error_count_reg; + status_registers(10 downto 9) <= fe_error_flag_count_reg; status_registers(12 downto 11) <= cic_overflow_count_reg; - status_registers(13) <= std_logic_vector(uplink_not_rdy_count); - + status_registers(13) <= std_logic_vector(uplink_not_rdy_count); --==============================-- - regInputs : process(clk_p) + regInputs : process (clk_p) is --==============================-- begin + if rising_edge(clk_p) then uplink_rdy <= uplink_rdy_i; end if; + end process regInputs; --==============================-- - genRegisters : for i in 0 to cNumberOfCICs - 1 generate - --==============================-- - signal sync_loss_count : unsigned(31 downto 0) := (others => '0'); - signal stub_count : unsigned(31 downto 0) := (others => '0'); - signal cic_sync_error_count : unsigned(31 downto 0) := (others => '0'); - signal fe_error_flag_count : unsigned(31 downto 0) := (others => '0'); - signal cic_overflow_count : unsigned(31 downto 0) := (others => '0'); + GenRegisters : for i in 0 to cNumberOfCICs - 1 generate + signal sync_loss_count : unsigned(31 downto 0) := (others => '0'); + signal stub_count : unsigned(31 downto 0) := (others => '0'); + signal cic_sync_error_count : unsigned(31 downto 0) := (others => '0'); + signal fe_error_flag_count : unsigned(31 downto 0) := (others => '0'); + signal cic_overflow_count : unsigned(31 downto 0) := (others => '0'); begin - header_reg(i)(27 downto 0) <= cicHeaderToSLV(header_in(i)); - aligner_status_reg(0)(4*i + 3 downto 4*i) <= aligner_state(i); - sync_loss_count_reg(i) <= std_logic_vector(sync_loss_count); - stub_count_reg(i) <= std_logic_vector(stub_count); - cic_sync_error_count_reg(i) <= std_logic_vector(cic_sync_error_count); - fe_error_flag_count_reg(i) <= std_logic_vector(fe_error_flag_count); - cic_overflow_count_reg(i) <= std_logic_vector(cic_overflow_count); + header_reg(i)(27 downto 0) <= cicHeaderToSLV(header_in(i)); + aligner_status_reg(0)(4 * i + 3 downto 4 * i) <= aligner_state(i); + sync_loss_count_reg(i) <= std_logic_vector(sync_loss_count); + stub_count_reg(i) <= std_logic_vector(stub_count); + cic_sync_error_count_reg(i) <= std_logic_vector(cic_sync_error_count); + fe_error_flag_count_reg(i) <= std_logic_vector(fe_error_flag_count); + cic_overflow_count_reg(i) <= std_logic_vector(cic_overflow_count); --==============================-- - pCountSyncLossEvents : process(clk_p) + pCountSyncLossEvents : process (clk_p) is --==============================-- begin + if rising_edge(clk_p) then - if counter_reset = '1' then + if (counter_reset = '1') then sync_loss_count <= (others => '0'); else - if sync_loss(i) = '1' and aligner_state(i)(2 downto 0) = "100" then + if (sync_loss(i) = '1' and aligner_state(i)(2 downto 0) = "100") then -- count occasions when aligner is in locked state, but a header is misaligned/out of sync sync_loss_count <= sync_loss_count + 1; end if; end if; end if; - end process pCountSyncLossEvents; + + end process pCountSyncLossEvents; --==============================-- - pCountStubEvents : process(clk_p) - --==============================-- - variable n_stubs : unsigned(5 downto 0); - variable cic_flag : std_logic; - variable fe_flags : std_logic_vector(7 downto 0); + pCountStubEvents : process (clk_p) is + + variable n_stubs : unsigned(5 downto 0); + variable cic_flag : std_logic; + variable fe_flags : std_logic_vector(7 downto 0); begin + if rising_edge(clk_p) then - if counter_reset = '1' then + if (counter_reset = '1') then stub_count <= (others => '0'); cic_sync_error_count <= (others => '0'); - fe_error_flag_count <= (others => '0'); - cic_overflow_count <= (others => '0'); + fe_error_flag_count <= (others => '0'); + cic_overflow_count <= (others => '0'); else - if header_start(i) = '1' and aligner_state(i) = "1100" then + if (header_start(i) = '1' and aligner_state(i) = "1100") then -- only count when aligner is in locked state, and packet decoding is in sync - n_stubs := unsigned(header_in(i).stub_count); + n_stubs := unsigned(header_in(i).stub_count); cic_flag := header_in(i).status(0); fe_flags := header_in(i).status(8 downto 1); stub_count <= stub_count + n_stubs; - if cic_flag = '1' and fe_flags /= x"00" and n_stubs /= max_stubs then - cic_sync_error_count <= cic_sync_error_count + 1; + if (cic_flag = '1' and fe_flags /= x"00" and n_stubs /= max_stubs) then + cic_sync_error_count <= cic_sync_error_count + 1; end if; - if cic_flag = '0' and fe_flags /= x"00" then - fe_error_flag_count <= fe_error_flag_count + 1; + if (cic_flag = '0' and fe_flags /= x"00") then + fe_error_flag_count <= fe_error_flag_count + 1; end if; - if cic_flag = '1' and n_stubs = max_stubs then - cic_overflow_count <= cic_overflow_count + 1; + if (cic_flag = '1' and n_stubs = max_stubs) then + cic_overflow_count <= cic_overflow_count + 1; end if; - end if; end if; end if; - end process pCountStubEvents; - - end generate genRegisters; + + end process pCountStubEvents; + + end generate GenRegisters; --==============================-- - pUplinkNotReadyCount : process(clk_p) + pUplinkNotReadyCount : process (clk_p) is --==============================-- begin + if rising_edge(clk_p) then - if counter_reset = '1' then + if (counter_reset = '1') then uplink_not_rdy_count <= (others => '0'); else - if uplink_rdy = '0' then + if (uplink_rdy = '0') then uplink_not_rdy_count <= uplink_not_rdy_count + 1; end if; end if; end if; - end process pUplinkNotReadyCount; + end process pUplinkNotReadyCount; end architecture Behavorial; diff --git a/dtc-fe/firmware/hdl/L1DataDecoder.vhd b/dtc-fe/firmware/hdl/L1DataDecoder.vhd index d2ed87d3647ee1429a8c2695da62c279388c06e0..595f7ebb894354108c4cc99641499110b4cff759 100644 --- a/dtc-fe/firmware/hdl/L1DataDecoder.vhd +++ b/dtc-fe/firmware/hdl/L1DataDecoder.vhd @@ -1,29 +1,29 @@ -library IEEE; -use IEEE.STD_LOGIC_1164.ALL; -use IEEE.NUMERIC_STD.ALL; +library ieee; + use ieee.std_logic_1164.all; + use ieee.numeric_std.all; -use work.module_constants.all; -use work.dtc_constants.all; +library work; + use work.module_constants.all; + use work.dtc_constants.all; entity L1DataDecoder is -generic ( - module_type : string; - bandwidth : integer + generic ( + module_type : string; + bandwidth : integer ); - -port ( - --- Input Ports --- - clk : in std_logic; - -- Assumed data_in(0) is the latest bit arrived, so data_in is significant from left to right - data_in : in std_logic_vector(cNumberOfL1ELinks(selectIndexFromModuleType(module_type, bandwidth)) - 1 downto 0); - reset : in std_logic; - --- Output Ports --- - event_number : out std_logic_vector(cL1CtrlFifoWidth - 1 downto 0); - data_fifo : out std_logic_vector(cL1DataFifoWidth - 1 downto 0); - event_fifo : out std_logic_vector(cL1CtrlFifoWidth - 1 downto 0); - record_fifo : out std_logic_vector(cL1CtrlFifoWidth - 1 downto 0); - data_fifo_wr : out std_logic; - event_fifo_wr : out std_logic; - record_fifo_wr : out std_logic -); -end L1DataDecoder; + port ( + --- Input Ports --- + clk : in std_logic; + -- Assumed data_in(0) is the latest bit arrived, so data_in is significant from left to right + data_in : in std_logic_vector(cNumberOfL1ELinks(selectIndexFromModuleType(module_type, bandwidth)) - 1 downto 0); + reset : in std_logic; + --- Output Ports --- + event_number : out std_logic_vector(cL1CtrlFifoWidth - 1 downto 0); + data_fifo : out std_logic_vector(cL1DataFifoWidth - 1 downto 0); + event_fifo : out std_logic_vector(cL1CtrlFifoWidth - 1 downto 0); + record_fifo : out std_logic_vector(cL1CtrlFifoWidth - 1 downto 0); + data_fifo_wr : out std_logic; + event_fifo_wr : out std_logic; + record_fifo_wr : out std_logic + ); +end entity L1DataDecoder; diff --git a/dtc-fe/firmware/hdl/L1DataDecoder_2S_CIC1.vhd b/dtc-fe/firmware/hdl/L1DataDecoder_2S_CIC1.vhd index ee62fe1e9ea5720635c6401150e5210c6acfd083..b8a13ff216394d626ecd92bb459356c5fb3105cc 100644 --- a/dtc-fe/firmware/hdl/L1DataDecoder_2S_CIC1.vhd +++ b/dtc-fe/firmware/hdl/L1DataDecoder_2S_CIC1.vhd @@ -1,187 +1,176 @@ -library IEEE; -use IEEE.STD_LOGIC_1164.ALL; -use IEEE.NUMERIC_STD.ALL; - -use work.module_constants.all; -use work.front_end_data_types.all; -use work.emp_data_types.all; -use work.dtc_constants.all; -use work.dtc_data_types.all; +library ieee; + use ieee.std_logic_1164.all; + use ieee.numeric_std.all; +library work; + use work.module_constants.all; + use work.front_end_data_types.all; + use work.emp_data_types.all; + use work.dtc_constants.all; + use work.dtc_data_types.all; architecture module2SCIC1 of L1DataDecoder is - type decoder_state is (idle, capture_armed, header_capture, payload_capture, store_event, error); - - signal decoder : decoder_state := idle; - - signal header : std_logic_vector(cL1HeaderWidth(selectIndexFromModuleType(module_type, bandwidth)) - 1 downto 0) := ( others => '0' ); - signal payload_word : std_logic_vector(cL1DataFifoWidth - 1 downto 0) := ( others => '0' ); - signal data : std_logic; - - signal start_counter : integer range 0 to 31 := cL1StartSequenceThresh; - signal header_counter : integer range 0 to 31; - signal payload_counter : integer range -1 to 4500; - signal bit_counter : integer range 0 to cL1DataFifoWidth; - - signal event_counter : unsigned(cL1CtrlFifoWidth - 1 downto 0) := to_unsigned(1, cL1CtrlFifoWidth); - - - ---- - - -- decoder state machine monitors incoming L1A data line for CIC L1A packets: - -- CIC sends a sequence of 27 '1's, followed by a '0' to indicate the start of a packet - -- a packet contains a fixed length header depending on module/packet type (2S/PS) - -- the payload length also depends on content - the cluster width field indicates length - - -- header and payload data are packed into words of width "cL1DataFifoWidth", and written to the data FIFO - -- when the packet ends, metadata is stored in two separate synchronised FWFT FIFOs: - -- event FIFO - the local event number (for synchronisation at the DTC/DAQ level), - -- record FIFO - a record of number of words written to the data FIFO for a given event - - -- (at DTC or DAQ path/SLINK level, not implemented here) - -- DAQ firmware should check the FWFT L1A event number in every event FIFO against TCDS record - -- if ready to readout, number of words to read from RAM can be determined from record FIFO - - -- also not yet implemented: - -- timeouts/error states when we are stuck in any non-idle state for too long - -- monitoring for CIC health using idle pattern? overall FE health to go in a separate block probably - -- different modes e.g. un/sparsified decoding for 2S modules, PS module decoding - -- how to handle 10G PS data (assuming two input bits, instead of one) - - ---- - - begin - - - event_number <= std_logic_vector(event_counter-1); - - - decoder_sm: process (clk) - - variable status : std_logic_vector(cL1StatusWidth - 1 downto 0); - variable l1a : std_logic_vector(cL1IdWidth - 1 downto 0); - variable nclusters : std_logic_vector(cL1NClusterWidth - 1 downto 0); - - variable word_count : unsigned(cL1CtrlFifoWidth - 1 downto 0) := ( others => '0' ); - + type tDecoderState is (idle, capture_armed, header_capture, payload_capture, store_event, error); + + signal decoder : tDecoderState := idle; + + signal header : std_logic_vector(cL1HeaderWidth(selectIndexFromModuleType(module_type, bandwidth)) - 1 downto 0) := (others => '0'); + signal payload_word : std_logic_vector(cL1DataFifoWidth - 1 downto 0) := (others => '0'); + signal data : std_logic; + + signal start_counter : integer range 0 to 31 := cL1StartSequenceThresh; + signal header_counter : integer range 0 to 31; + signal payload_counter : integer range -1 to 4500; + signal bit_counter : integer range 0 to cL1DataFifoWidth; + + signal event_counter : unsigned(cL1CtrlFifoWidth - 1 downto 0) := to_unsigned(1, cL1CtrlFifoWidth); + +---- + +-- decoder state machine monitors incoming L1A data line for CIC L1A packets: +-- CIC sends a sequence of 27 '1's, followed by a '0' to indicate the start of a packet +-- a packet contains a fixed length header depending on module/packet type (2S/PS) +-- the payload length also depends on content - the cluster width field indicates length + +-- header and payload data are packed into words of width "cL1DataFifoWidth", and written to the data FIFO +-- when the packet ends, metadata is stored in two separate synchronised FWFT FIFOs: +-- event FIFO - the local event number (for synchronisation at the DTC/DAQ level), +-- record FIFO - a record of number of words written to the data FIFO for a given event + +-- (at DTC or DAQ path/SLINK level, not implemented here) +-- DAQ firmware should check the FWFT L1A event number in every event FIFO against TCDS record +-- if ready to readout, number of words to read from RAM can be determined from record FIFO + +-- also not yet implemented: +-- timeouts/error states when we are stuck in any non-idle state for too long +-- monitoring for CIC health using idle pattern? overall FE health to go in a separate block probably +-- different modes e.g. un/sparsified decoding for 2S modules, PS module decoding +-- how to handle 10G PS data (assuming two input bits, instead of one) + +---- + +begin + + event_number <= std_logic_vector(event_counter - 1); + + pDecoderSm : process (clk) is + + variable status : std_logic_vector(cL1StatusWidth - 1 downto 0); + variable l1a : std_logic_vector(cL1IdWidth - 1 downto 0); + variable nclusters : std_logic_vector(cL1NClusterWidth - 1 downto 0); + + variable word_count : unsigned(cL1CtrlFifoWidth - 1 downto 0) := (others => '0'); + begin - if rising_edge(clk) then - - if reset = '1' then - - -- for CIC1: start sequence is shorter (subtract 8) - decoder <= idle; - start_counter <= cL1StartSequenceThresh-8; - event_counter <= to_unsigned(1, cL1CtrlFifoWidth); - - event_fifo <= ( others => '0' ); - record_fifo <= ( others => '0' ); - data_fifo <= ( others => '0' ); - - data_fifo_wr <= '0'; - event_fifo_wr <= '0'; - record_fifo_wr <= '0'; - - else - - data_fifo_wr <= '0'; - event_fifo_wr <= '0'; - record_fifo_wr <= '0'; - - data <= data_in(0); - - case decoder is - - -- wait for a start sequence of '1's indicating the start of a packet - -- for CIC1: start sequence is shorter (subtract 8) - - when idle => - -- idle pattern is a repeating 10101.. - if data = '1' then - start_counter <= start_counter - 1; - else - start_counter <= cL1StartSequenceThresh-8; - end if; - if start_counter = 0 then - -- if more than "cL1StartSequenceThresh" consecutive '1's, arm capture - decoder <= capture_armed; - start_counter <= cL1StartSequenceThresh-8; - end if; - - -- wait for a single '0' indicating the start of header - when capture_armed => - if data = '0' then - - -- for CIC1: skip header capture state and capture payload immediately - decoder <= payload_capture; - - payload_counter <= cL1UnsparsifiedLength-8; - bit_counter <= cL1DataFifoWidth; - payload_word(0) <= data; - - data_fifo <= x"55555555"; - data_fifo_wr <= '1'; - word_count := to_unsigned(1, cL1CtrlFifoWidth); - - end if; - - -- pack the payload into words until the predetermined packet length ends - when payload_capture => - -- shift in payload - payload_word(0) <= data; - payload_word(cL1DataFifoWidth - 1 downto 1) <= payload_word(cL1DataFifoWidth - 2 downto 0); - - -- wait until full length of payload has been shifted in to leave state - if payload_counter <= 0 then - decoder <= store_event; - else - payload_counter <= payload_counter - 1; - end if; - - -- check to see if we have packed enough data to write to data FIFO - if bit_counter = 0 then - - -- store the word to data FIFO, and increment word count - data_fifo <= payload_word; - - data_fifo_wr <= '1'; - word_count := word_count + 1; - bit_counter <= cL1DataFifoWidth - 1; - else - bit_counter <= bit_counter - 1; - - -- check if we have reached the end of the payload, but haven't fully packed a word - if payload_counter = 0 then - - -- pad out payload word and store it to data FIFO - data_fifo <= std_logic_vector(unsigned(payload_word) sll bit_counter); - data_fifo_wr <= '1'; - word_count := word_count + 1; - end if; - - end if; - - -- finish off packet handling by storing metadata to FIFOs, increment event counter, and reinitialise - when store_event => - event_fifo <= std_logic_vector(event_counter); - record_fifo <= std_logic_vector(word_count); - event_fifo_wr <= '1'; - record_fifo_wr <= '1'; - - decoder <= idle; - word_count := (others => '0'); - event_counter <= event_counter + 1; - - when others => - decoder <= idle; - - end case; - + + if rising_edge(clk) then + if (reset = '1') then + -- for CIC1: start sequence is shorter (subtract 8) + decoder <= idle; + start_counter <= cL1StartSequenceThresh - 8; + event_counter <= to_unsigned(1, cL1CtrlFifoWidth); + + event_fifo <= (others => '0'); + record_fifo <= (others => '0'); + data_fifo <= (others => '0'); + + data_fifo_wr <= '0'; + event_fifo_wr <= '0'; + record_fifo_wr <= '0'; + else + data_fifo_wr <= '0'; + event_fifo_wr <= '0'; + record_fifo_wr <= '0'; + + data <= data_in(0); + + case decoder is + + -- wait for a start sequence of '1's indicating the start of a packet + -- for CIC1: start sequence is shorter (subtract 8) + + when idle => + -- idle pattern is a repeating 10101.. + if (data = '1') then + start_counter <= start_counter - 1; + else + start_counter <= cL1StartSequenceThresh - 8; + end if; + if (start_counter = 0) then + -- if more than "cL1StartSequenceThresh" consecutive '1's, arm capture + decoder <= capture_armed; + start_counter <= cL1StartSequenceThresh - 8; + end if; + + -- wait for a single '0' indicating the start of header + when capture_armed => + if (data = '0') then + -- for CIC1: skip header capture state and capture payload immediately + decoder <= payload_capture; + + payload_counter <= cL1UnsparsifiedLength - 8; + bit_counter <= cL1DataFifoWidth; + payload_word(0) <= data; + + data_fifo <= x"55555555"; + data_fifo_wr <= '1'; + word_count := to_unsigned(1, cL1CtrlFifoWidth); + end if; + + -- pack the payload into words until the predetermined packet length ends + when payload_capture => + -- shift in payload + payload_word(0) <= data; + payload_word(cL1DataFifoWidth - 1 downto 1) <= payload_word(cL1DataFifoWidth - 2 downto 0); + + -- wait until full length of payload has been shifted in to leave state + if (payload_counter <= 0) then + decoder <= store_event; + else + payload_counter <= payload_counter - 1; + end if; + + -- check to see if we have packed enough data to write to data FIFO + if (bit_counter = 0) then + -- store the word to data FIFO, and increment word count + data_fifo <= payload_word; + + data_fifo_wr <= '1'; + word_count := word_count + 1; + bit_counter <= cL1DataFifoWidth - 1; + else + bit_counter <= bit_counter - 1; + + -- check if we have reached the end of the payload, but haven't fully packed a word + if (payload_counter = 0) then + -- pad out payload word and store it to data FIFO + data_fifo <= std_logic_vector(unsigned(payload_word) sll bit_counter); + data_fifo_wr <= '1'; + word_count := word_count + 1; + end if; + end if; + + -- finish off packet handling by storing metadata to FIFOs, increment event counter, and reinitialise + when store_event => + event_fifo <= std_logic_vector(event_counter); + record_fifo <= std_logic_vector(word_count); + event_fifo_wr <= '1'; + record_fifo_wr <= '1'; + + decoder <= idle; + word_count := (others => '0'); + event_counter <= event_counter + 1; + + when others => + decoder <= idle; + + end case; + + end if; end if; - end if; - end process; - - -end module2SCIC1; - + + end process pDecoderSm; + +end architecture module2SCIC1; + diff --git a/dtc-fe/firmware/hdl/L1DataDecoder_2S_CIC2.vhd b/dtc-fe/firmware/hdl/L1DataDecoder_2S_CIC2.vhd index 3e14a2750b22b450b6046247a6b0aa0d0aaecbc8..a0c271db4fb05c640f2aa6c036e1e5c00ebbfc7c 100644 --- a/dtc-fe/firmware/hdl/L1DataDecoder_2S_CIC2.vhd +++ b/dtc-fe/firmware/hdl/L1DataDecoder_2S_CIC2.vhd @@ -1,31 +1,30 @@ -library IEEE; -use IEEE.STD_LOGIC_1164.ALL; -use IEEE.NUMERIC_STD.ALL; - -use work.module_constants.all; -use work.front_end_data_types.all; -use work.emp_data_types.all; -use work.dtc_constants.all; -use work.dtc_data_types.all; +library ieee; + use ieee.std_logic_1164.all; + use ieee.numeric_std.all; +library work; + use work.module_constants.all; + use work.front_end_data_types.all; + use work.emp_data_types.all; + use work.dtc_constants.all; + use work.dtc_data_types.all; architecture module2SCIC2 of L1DataDecoder is -type decoder_state is (idle, capture_armed, header_capture, payload_capture, store_event, error); - -signal decoder : decoder_state := idle; + type tDecoderState is (idle, capture_armed, header_capture, payload_capture, store_event, error); -signal header : std_logic_vector(cL1HeaderWidth(selectIndexFromModuleType(module_type, bandwidth)) - 1 downto 0) := ( others => '0' ); -signal payload_word : std_logic_vector(cL1DataFifoWidth - 1 downto 0) := ( others => '0' ); -signal data : std_logic; + signal decoder : tDecoderState := idle; -signal start_counter : integer range 0 to 31 := cL1StartSequenceThresh; -signal header_counter : integer range 0 to 31; -signal payload_counter : integer range -1 to 4500; -signal bit_counter : integer range 0 to cL1DataFifoWidth - 1; + signal header : std_logic_vector(cL1HeaderWidth(selectIndexFromModuleType(module_type, bandwidth)) - 1 downto 0) := (others => '0'); + signal payload_word : std_logic_vector(cL1DataFifoWidth - 1 downto 0) := (others => '0'); + signal data : std_logic; -signal event_counter : unsigned(cL1CtrlFifoWidth - 1 downto 0) := to_unsigned(1, cL1CtrlFifoWidth); + signal start_counter : integer range 0 to 31 := cL1StartSequenceThresh; + signal header_counter : integer range 0 to 31; + signal payload_counter : integer range -1 to 4500; + signal bit_counter : integer range 0 to cL1DataFifoWidth - 1; + signal event_counter : unsigned(cL1CtrlFifoWidth - 1 downto 0) := to_unsigned(1, cL1CtrlFifoWidth); ---- @@ -53,158 +52,151 @@ signal event_counter : unsigned(cL1CtrlFifoWidth - 1 downto 0) := to_unsigned( begin + event_number <= std_logic_vector(event_counter - 1); - event_number <= std_logic_vector(event_counter-1); - - - decoder_sm: process (clk) - - variable status : std_logic_vector(cL1StatusWidth - 1 downto 0); - variable l1a : std_logic_vector(cL1IdWidth - 1 downto 0); - variable nclusters : std_logic_vector(cL1NClusterWidth - 1 downto 0); - - variable word_count : unsigned(cL1CtrlFifoWidth - 1 downto 0) := ( others => '0' ); - - begin - if rising_edge(clk) then - - if reset = '1' then - - decoder <= idle; - start_counter <= cL1StartSequenceThresh; - event_counter <= to_unsigned(1, cL1CtrlFifoWidth); - - event_fifo <= ( others => '0' ); - record_fifo <= ( others => '0' ); - data_fifo <= ( others => '0' ); - - data_fifo_wr <= '0'; - event_fifo_wr <= '0'; - record_fifo_wr <= '0'; - - else - - data_fifo_wr <= '0'; - event_fifo_wr <= '0'; - record_fifo_wr <= '0'; - - data <= data_in(0); - - case decoder is - - -- wait for a start sequence of '1's indicating the start of a packet - when idle => - -- idle pattern is a repeating 10101.. - if data = '1' then - start_counter <= start_counter - 1; - else - start_counter <= cL1StartSequenceThresh; - end if; - if start_counter = 0 then - -- if more than "cL1StartSequenceThresh" consecutive '1's, arm capture - decoder <= capture_armed; - start_counter <= cL1StartSequenceThresh; - end if; + pDecoderSm : process (clk) is - -- wait for a single '0' indicating the start of header - when capture_armed => - if data = '0' then - decoder <= header_capture; - header_counter <= cL1HeaderWidth(selectIndexFromModuleType(module_type, bandwidth)); - end if; + variable status : std_logic_vector(cL1StatusWidth - 1 downto 0); + variable l1a : std_logic_vector(cL1IdWidth - 1 downto 0); + variable nclusters : std_logic_vector(cL1NClusterWidth - 1 downto 0); - -- extract & store the header and calculate the payload length - when header_capture => - -- shift in header - header(0) <= data; - header(cL1HeaderWidth(selectIndexFromModuleType(module_type, bandwidth)) - 1 downto 1) <= header(cL1HeaderWidth(selectIndexFromModuleType(module_type, bandwidth)) - 2 downto 0); - - -- wait until full length of header has been shifted in - if header_counter = 0 then - -- start decoding payload on next clock cycle - decoder <= payload_capture; - - status := header(cL1StatusLow(selectIndexFromModuleType(module_type, bandwidth)) + cL1StatusWidth - 1 downto cL1StatusLow(selectIndexFromModuleType(module_type, bandwidth))); - l1a := header(cL1IdLow(selectIndexFromModuleType(module_type, bandwidth)) + cL1IdWidth - 1 downto cL1IdLow(selectIndexFromModuleType(module_type, bandwidth))); - - -- nclusters defines length of payload unless in unsparsified mode - -- initialise counters for the payload_capture state - if cSparsifiedMode then - nclusters := header(cL1NClusterLow + cL1NClusterWidth - 1 downto cL1NClusterLow); - -- this currently implements as a DSP - not clear if this is what we want - -- needs adaptation for PS data packets anyway - payload_counter <= to_integer(unsigned(nclusters))*cL1ClusterWidth - 1; - else - nclusters := (others=>'0'); - payload_counter <= cL1UnsparsifiedLength - 1; - end if; - - bit_counter <= cL1DataFifoWidth - 1; - payload_word(0) <= data; - - -- store the header to the data FIFO, and set word count to 1 - -- lowest 7 bits reserved for PS n pixel clusters - data_fifo <= l1a & status & nclusters & "0000000"; - data_fifo_wr <= '1'; - word_count := to_unsigned(1, cL1CtrlFifoWidth); - else - header_counter <= header_counter - 1; - end if; + variable word_count : unsigned(cL1CtrlFifoWidth - 1 downto 0) := (others => '0'); - -- pack the payload into words until the predetermined packet length ends - when payload_capture => - -- shift in payload - payload_word(0) <= data; - payload_word(cL1DataFifoWidth - 1 downto 1) <= payload_word(cL1DataFifoWidth - 2 downto 0); + begin - -- wait until full length of payload has been shifted in to leave state - if payload_counter <= 0 then - decoder <= store_event; - else - payload_counter <= payload_counter - 1; - end if; + if rising_edge(clk) then + if (reset = '1') then + decoder <= idle; + start_counter <= cL1StartSequenceThresh; + event_counter <= to_unsigned(1, cL1CtrlFifoWidth); - -- check to see if we have packed enough data to write to data FIFO - if bit_counter = 0 then - - -- store the word to data FIFO, and increment word count - data_fifo <= payload_word; + event_fifo <= (others => '0'); + record_fifo <= (others => '0'); + data_fifo <= (others => '0'); - data_fifo_wr <= '1'; - word_count := word_count + 1; - bit_counter <= cL1DataFifoWidth - 1; + data_fifo_wr <= '0'; + event_fifo_wr <= '0'; + record_fifo_wr <= '0'; else - bit_counter <= bit_counter - 1; - - -- check if we have reached the end of the payload, but haven't fully packed a word - if payload_counter = 0 then - - -- pad out payload word and store it to data FIFO - data_fifo <= std_logic_vector(unsigned(payload_word) sll bit_counter); - data_fifo_wr <= '1'; - word_count := word_count + 1; - end if; - + data_fifo_wr <= '0'; + event_fifo_wr <= '0'; + record_fifo_wr <= '0'; + + data <= data_in(0); + + case decoder is + + -- wait for a start sequence of '1's indicating the start of a packet + when idle => + -- idle pattern is a repeating 10101.. + if (data = '1') then + start_counter <= start_counter - 1; + else + start_counter <= cL1StartSequenceThresh; + end if; + if (start_counter = 0) then + -- if more than "cL1StartSequenceThresh" consecutive '1's, arm capture + decoder <= capture_armed; + start_counter <= cL1StartSequenceThresh; + end if; + + -- wait for a single '0' indicating the start of header + when capture_armed => + if (data = '0') then + decoder <= header_capture; + header_counter <= cL1HeaderWidth(selectIndexFromModuleType(module_type, bandwidth)); + end if; + + -- extract & store the header and calculate the payload length + when header_capture => + -- shift in header + header(0) <= data; + header(cL1HeaderWidth(selectIndexFromModuleType(module_type, bandwidth)) - 1 downto 1) <= header(cL1HeaderWidth(selectIndexFromModuleType(module_type, bandwidth)) - 2 downto 0); + + -- wait until full length of header has been shifted in + if (header_counter = 0) then + -- start decoding payload on next clock cycle + decoder <= payload_capture; + + status := header(cL1StatusLow(selectIndexFromModuleType(module_type, bandwidth)) + cL1StatusWidth - 1 downto cL1StatusLow(selectIndexFromModuleType(module_type, bandwidth))); + l1a := header(cL1IdLow(selectIndexFromModuleType(module_type, bandwidth)) + cL1IdWidth - 1 downto cL1IdLow(selectIndexFromModuleType(module_type, bandwidth))); + + -- nclusters defines length of payload unless in unsparsified mode + -- initialise counters for the payload_capture state + if (cSparsifiedMode) then + nclusters := header(cL1NClusterLow + cL1NClusterWidth - 1 downto cL1NClusterLow); + -- this currently implements as a DSP - not clear if this is what we want + -- needs adaptation for PS data packets anyway + payload_counter <= to_integer(unsigned(nclusters)) * cL1ClusterWidth - 1; + else + nclusters := (others => '0'); + payload_counter <= cL1UnsparsifiedLength - 1; + end if; + + bit_counter <= cL1DataFifoWidth - 1; + payload_word(0) <= data; + + -- store the header to the data FIFO, and set word count to 1 + -- lowest 7 bits reserved for PS n pixel clusters + data_fifo <= l1a & status & nclusters & "0000000"; + data_fifo_wr <= '1'; + word_count := to_unsigned(1, cL1CtrlFifoWidth); + else + header_counter <= header_counter - 1; + end if; + + -- pack the payload into words until the predetermined packet length ends + when payload_capture => + -- shift in payload + payload_word(0) <= data; + payload_word(cL1DataFifoWidth - 1 downto 1) <= payload_word(cL1DataFifoWidth - 2 downto 0); + + -- wait until full length of payload has been shifted in to leave state + if (payload_counter <= 0) then + decoder <= store_event; + else + payload_counter <= payload_counter - 1; + end if; + + -- check to see if we have packed enough data to write to data FIFO + if (bit_counter = 0) then + -- store the word to data FIFO, and increment word count + data_fifo <= payload_word; + + data_fifo_wr <= '1'; + word_count := word_count + 1; + bit_counter <= cL1DataFifoWidth - 1; + else + bit_counter <= bit_counter - 1; + + -- check if we have reached the end of the payload, but haven't fully packed a word + if (payload_counter = 0) then + -- pad out payload word and store it to data FIFO + data_fifo <= std_logic_vector(unsigned(payload_word) sll bit_counter); + data_fifo_wr <= '1'; + word_count := word_count + 1; + end if; + end if; + + -- finish off packet handling by storing metadata to FIFOs, increment event counter, and reinitialise + when store_event => + event_fifo <= std_logic_vector(event_counter); + record_fifo <= std_logic_vector(word_count); + event_fifo_wr <= '1'; + record_fifo_wr <= '1'; + + decoder <= idle; + word_count := (others => '0'); + event_counter <= event_counter + 1; + + when others => + decoder <= idle; + + end case; + end if; + end if; + + end process pDecoderSm; - -- finish off packet handling by storing metadata to FIFOs, increment event counter, and reinitialise - when store_event => - event_fifo <= std_logic_vector(event_counter); - record_fifo <= std_logic_vector(word_count); - event_fifo_wr <= '1'; - record_fifo_wr <= '1'; - - decoder <= idle; - word_count := (others => '0'); - event_counter <= event_counter + 1; - - when others => - decoder <= idle; - end case; - - end if; - end if; - end process; - - - end module2SCIC2; +end architecture module2SCIC2; diff --git a/dtc-fe/firmware/hdl/L1DataDecoder_PS10G.vhd b/dtc-fe/firmware/hdl/L1DataDecoder_PS10G.vhd index d2d2d7d7e9cd857b5a9c39560a56cbfaf862ade0..f6ac3e9777057dfaf21cd308ee1fc1f3a9c1d344 100644 --- a/dtc-fe/firmware/hdl/L1DataDecoder_PS10G.vhd +++ b/dtc-fe/firmware/hdl/L1DataDecoder_PS10G.vhd @@ -1,36 +1,36 @@ -library IEEE; -use IEEE.STD_LOGIC_1164.ALL; -use IEEE.NUMERIC_STD.ALL; - -use work.module_constants.all; -use work.front_end_data_types.all; -use work.emp_data_types.all; -use work.dtc_constants.all; -use work.dtc_data_types.all; +library ieee; + use ieee.std_logic_1164.all; + use ieee.numeric_std.all; +library work; + use work.module_constants.all; + use work.front_end_data_types.all; + use work.emp_data_types.all; + use work.dtc_constants.all; + use work.dtc_data_types.all; architecture modulePS10G of L1DataDecoder is -type decoder_state is (idle, capture_armed, header_capture, payload_capture, store_event, error); + type tDecoderState is (idle, capture_armed, header_capture, payload_capture, store_event, error); -signal decoder : decoder_state := idle; + signal decoder : tDecoderState := idle; -signal header : std_logic_vector(cL1HeaderWidth(selectIndexFromModuleType(module_type, bandwidth))+2 downto 0) := ( others => '0' ); -signal payload_word : std_logic_vector(cL1DataFifoWidth+2 downto 0) := ( others => '0' ); -signal last_word : std_logic_vector(cL1DataFifoWidth-1 downto 0) := ( others => '0' ); + signal header : std_logic_vector(cL1HeaderWidth(selectIndexFromModuleType(module_type, bandwidth)) + 2 downto 0) := (others => '0'); + signal payload_word : std_logic_vector(cL1DataFifoWidth + 2 downto 0) := (others => '0'); + signal last_word : std_logic_vector(cL1DataFifoWidth - 1 downto 0) := (others => '0'); -signal start_counter : integer range 0 to 31 := cL1StartSequenceThresh; -signal header_counter : integer range -1 to 35; -signal payload_counter : integer range -3 to 4500; -signal bit_counter : integer range -1 to cL1DataFifoWidth - 1; -signal extra_word : std_logic := '0'; + signal start_counter : integer range 0 to 31 := cL1StartSequenceThresh; + signal header_counter : integer range -1 to 35; + signal payload_counter : integer range -3 to 4500; + signal bit_counter : integer range -1 to cL1DataFifoWidth - 1; + signal extra_word : std_logic := '0'; -signal event_counter : unsigned(cL1CtrlFifoWidth - 1 downto 0) := to_unsigned(1, cL1CtrlFifoWidth); --- DEBUG -signal sstatus : std_logic_vector(cL1StatusWidth - 1 downto 0); -signal sl1a : std_logic_vector(cL1IdWidth - 1 downto 0); -signal snPclusters : std_logic_vector(cL1NPcluster_width - 1 downto 0); -signal snSclusters : std_logic_vector(CL1NScluster_width - 1 downto 0); + signal event_counter : unsigned(cL1CtrlFifoWidth - 1 downto 0) := to_unsigned(1, cL1CtrlFifoWidth); + -- DEBUG + signal sstatus : std_logic_vector(cL1StatusWidth - 1 downto 0); + signal sl1a : std_logic_vector(cL1IdWidth - 1 downto 0); + signal snpclusters : std_logic_vector(cL1NPcluster_width - 1 downto 0); + signal snsclusters : std_logic_vector(CL1NScluster_width - 1 downto 0); ---- @@ -58,240 +58,214 @@ signal snSclusters : std_logic_vector(CL1NScluster_width - 1 downto 0); begin + event_number <= std_logic_vector(event_counter - 1); - event_number <= std_logic_vector(event_counter-1); - - - decoder_sm: process (clk) - - variable status : std_logic_vector(cL1StatusWidth - 1 downto 0); - variable l1a : std_logic_vector(cL1IdWidth - 1 downto 0); - variable nPclusters : std_logic_vector(cL1NPcluster_width - 1 downto 0); - variable nSclusters : std_logic_vector(CL1NScluster_width - 1 downto 0); - - variable word_count : unsigned(cL1CtrlFifoWidth - 1 downto 0) := ( others => '0' ); - - begin - if rising_edge(clk) then - - if reset = '1' then - - decoder <= idle; - start_counter <= cL1StartSequenceThresh; - event_counter <= to_unsigned(1, cL1CtrlFifoWidth); - - event_fifo <= ( others => '0' ); - record_fifo <= ( others => '0' ); - data_fifo <= ( others => '0' ); - - data_fifo_wr <= '0'; - event_fifo_wr <= '0'; - record_fifo_wr <= '0'; - - else - - data_fifo_wr <= '0'; - event_fifo_wr <= '0'; - record_fifo_wr <= '0'; - - case decoder is - - -- wait for a start sequence of '1's indicating the start of a packet - when idle => - -- idle pattern is a repeating 10101.. - if data_in = "11" then - start_counter <= start_counter - 2; -- 2 bits instead of 1 in 10G - else - start_counter <= cL1StartSequenceThresh; - end if; - if start_counter = 0 then - -- if more than "cL1StartSequenceThresh" consecutive '1's, arm capture - decoder <= capture_armed; - start_counter <= cL1StartSequenceThresh; - end if; + pDecoderSm : process (clk) is - -- wait for a single '0' indicating the start of header - when capture_armed => - if data_in= "10" then -- Header word starts with next two bits - decoder <= header_capture; - header_counter <= cL1HeaderWidth(selectIndexFromModuleType(module_type, bandwidth)); - header(1 downto 0) <= data_in; - elsif data_in(1) = '0' then -- Header word already started - decoder <= header_capture; - header_counter <= cL1HeaderWidth(selectIndexFromModuleType(module_type, bandwidth))-1; - header(1 downto 0) <= data_in; - end if; + variable status : std_logic_vector(cL1StatusWidth - 1 downto 0); + variable l1a : std_logic_vector(cL1IdWidth - 1 downto 0); + variable npclusters : std_logic_vector(cL1NPcluster_width - 1 downto 0); + variable nsclusters : std_logic_vector(CL1NScluster_width - 1 downto 0); - -- extract & store the header and calculate the payload length - when header_capture => - - -- shift in header - if header_counter > 0 then - header(1 downto 0) <= data_in; - header(cL1HeaderWidth(selectIndexFromModuleType(module_type, bandwidth))+2 downto 2) <= header(cL1HeaderWidth(selectIndexFromModuleType(module_type, bandwidth)) downto 0); - header_counter <= header_counter - 2; -- 2 bits instead of 1 - - elsif header_counter = 0 then -- Aligned with the end of header, the two data in bits are for payload word - - decoder <= payload_capture; - - status := header(cL1StatusLow(selectIndexFromModuleType(module_type, bandwidth)) + cL1StatusWidth-1 downto cL1StatusLow(selectIndexFromModuleType(module_type, bandwidth))); - l1a := header(cL1IdLow(selectIndexFromModuleType(module_type, bandwidth)) + cL1IdWidth-1 downto cL1IdLow(selectIndexFromModuleType(module_type, bandwidth))); - - -- nPclusters defines length of payload Pixels' data length - nPclusters := header(cL1NPcluster_low + cL1NPcluster_width-1 downto cL1NPcluster_low); - - -- nSclusters defines length of payload strips' data length - nSclusters := header(cL1NScluster_low + cL1NScluster_width-1 downto cL1NScluster_low); - - --debug - snSclusters <= nSclusters; - snPclusters <= nPclusters; - sl1a <= l1a; - sstatus <= status; - - -- store the header to the data FIFO, and set word count to 1 - data_fifo <= l1a & status & nSclusters & nPclusters; - data_fifo_wr <= '1'; - word_count := to_unsigned(1, cL1CtrlFifoWidth); - - bit_counter <= cL1DataFifoWidth - 2; - payload_word(1 downto 0) <= data_in; - payload_counter <= to_integer(unsigned(nSclusters))*cL1SClusterWidth + to_integer(unsigned(nPclusters))*cL1PClusterWidth - 2; - - - else --header counter = -1 (the two new bits and the header(0) bit belong to payload word) - - decoder <= payload_capture; - - status := header(cL1StatusLow(selectIndexFromModuleType(module_type, bandwidth))+1 + cL1StatusWidth-1 downto cL1StatusLow(selectIndexFromModuleType(module_type, bandwidth))+1); - l1a := header(cL1IdLow(selectIndexFromModuleType(module_type, bandwidth))+1 + cL1IdWidth-1 downto cL1IdLow(selectIndexFromModuleType(module_type, bandwidth))+1); - - -- nPclusters defines length of payload Pixels' data length - nPclusters := header(cL1NPcluster_low+1 + cL1NPcluster_width-1 downto cL1NPcluster_low+1); - - -- nSclusters defines length of payload strips' data length - nSclusters := header(cL1NScluster_low+1 + cL1NScluster_width-1 downto cL1NScluster_low+1); - - --debug - snSclusters <= nSclusters; - snPclusters <= nPclusters; - sl1a <= l1a; - sstatus <= status; - - -- store the header to the data FIFO, and set word count to 1 - data_fifo <= l1a & status & nSclusters & nPclusters; - data_fifo_wr <= '1'; - word_count := to_unsigned(1, cL1CtrlFifoWidth); - - bit_counter <= cL1DataFifoWidth - 3; - payload_word(2 downto 0) <= header(0) & data_in; - payload_counter <= to_integer(unsigned(nSclusters))*cL1SClusterWidth + to_integer(unsigned(nPclusters))*cL1PClusterWidth - 3; - - end if; + variable word_count : unsigned(cL1CtrlFifoWidth - 1 downto 0) := (others => '0'); - -- pack the payload into words until the predetermined packet length ends - when payload_capture => - -- shift in payload - payload_word(1 downto 0) <= data_in; - payload_word(cL1DataFifoWidth+2 downto 2) <= payload_word(cL1DataFifoWidth downto 0); - - if payload_counter >0 then - - payload_counter <= payload_counter - 2; - - -- If buffer is full and all of the two previous bits belong to this data_fifo_word - if bit_counter = 0 then - data_fifo <= payload_word(cL1DataFifoWidth-1 downto 0); - data_fifo_wr <= '1'; - word_count := word_count + 1; - bit_counter <= cL1DataFifoWidth - 2; - - -- If buffer is full and one of the previous bits received is for the next data_fifo_word - elsif bit_counter = -1 then - data_fifo <= payload_word(cL1DataFifoWidth downto 1); - data_fifo_wr <= '1'; - word_count := word_count + 1; - bit_counter <= cL1DataFifoWidth - 3; - - else - bit_counter <= bit_counter - 2; - - end if; - - - elsif payload_counter = 0 then -- no bits remaining to store (all bits already in payload word buffer) - - decoder <= store_event; - - -- if word buffer still not full --- pad the word - if bit_counter >= 0 then - data_fifo <= std_logic_vector(unsigned(payload_word(cL1DataFifoWidth-1 downto 0)) sll bit_counter); - data_fifo_wr <= '1'; - word_count := word_count + 1; - extra_word <= '0'; - - else -- if word buffer full - data_fifo <= payload_word(cL1DataFifoWidth downto 1); - data_fifo_wr <= '1'; - word_count := word_count + 1; - extra_word <= '1'; - last_word <= payload_word(0) & b"000" & X"0000000"; - - end if; - - elsif payload_counter < -1 then -- payload_counter is -2 or -3 when Sclust = 0 and Pclust = 0 ie. no stub in the payload - - decoder <= store_event; - extra_word <= '0'; - - else --payload_counter = -1, only one bit of the last two bits added to payload word is good - - decoder <= store_event; - - if bit_counter >= 0 then - data_fifo <= std_logic_vector(unsigned(payload_word(cL1DataFifoWidth-1 downto 0)) sll bit_counter); - data_fifo_wr <= '1'; - word_count := word_count + 1; - extra_word <= '0'; - - else -- if word buffer full - data_fifo <= payload_word(cL1DataFifoWidth downto 1); - data_fifo_wr <= '1'; - word_count := word_count + 1; - extra_word <= '0'; - - end if; - - end if; + begin + + if rising_edge(clk) then + if (reset = '1') then + decoder <= idle; + start_counter <= cL1StartSequenceThresh; + event_counter <= to_unsigned(1, cL1CtrlFifoWidth); + + event_fifo <= (others => '0'); + record_fifo <= (others => '0'); + data_fifo <= (others => '0'); + + data_fifo_wr <= '0'; + event_fifo_wr <= '0'; + record_fifo_wr <= '0'; + else + data_fifo_wr <= '0'; + event_fifo_wr <= '0'; + record_fifo_wr <= '0'; + + case decoder is + + -- wait for a start sequence of '1's indicating the start of a packet + when idle => + -- idle pattern is a repeating 10101.. + if (data_in = "11") then + start_counter <= start_counter - 2; -- 2 bits instead of 1 in 10G + else + start_counter <= cL1StartSequenceThresh; + end if; + if (start_counter = 0) then + -- if more than "cL1StartSequenceThresh" consecutive '1's, arm capture + decoder <= capture_armed; + start_counter <= cL1StartSequenceThresh; + end if; + + -- wait for a single '0' indicating the start of header + when capture_armed => + if (data_in = "10") then -- Header word starts with next two bits + decoder <= header_capture; + header_counter <= cL1HeaderWidth(selectIndexFromModuleType(module_type, bandwidth)); + header(1 downto 0) <= data_in; + elsif (data_in(1) = '0') then -- Header word already started + decoder <= header_capture; + header_counter <= cL1HeaderWidth(selectIndexFromModuleType(module_type, bandwidth)) - 1; + header(1 downto 0) <= data_in; + end if; + + -- extract & store the header and calculate the payload length + when header_capture => + + -- shift in header + if (header_counter > 0) then + header(1 downto 0) <= data_in; + header(cL1HeaderWidth(selectIndexFromModuleType(module_type, bandwidth)) + 2 downto 2) <= header(cL1HeaderWidth(selectIndexFromModuleType(module_type, bandwidth)) downto 0); + header_counter <= header_counter - 2; -- 2 bits instead of 1 + elsif (header_counter = 0) then -- Aligned with the end of header, the two data in bits are for payload word + decoder <= payload_capture; + + status := header(cL1StatusLow(selectIndexFromModuleType(module_type, bandwidth)) + cL1StatusWidth - 1 downto cL1StatusLow(selectIndexFromModuleType(module_type, bandwidth))); + l1a := header(cL1IdLow(selectIndexFromModuleType(module_type, bandwidth)) + cL1IdWidth - 1 downto cL1IdLow(selectIndexFromModuleType(module_type, bandwidth))); + + -- nPclusters defines length of payload Pixels' data length + npclusters := header(cL1NPcluster_low + cL1NPcluster_width - 1 downto cL1NPcluster_low); + + -- nSclusters defines length of payload strips' data length + nsclusters := header(cL1NScluster_low + cL1NScluster_width - 1 downto cL1NScluster_low); + + -- debug + snsclusters <= nsclusters; + snpclusters <= npclusters; + sl1a <= l1a; + sstatus <= status; + + -- store the header to the data FIFO, and set word count to 1 + data_fifo <= l1a & status & nsclusters & npclusters; + data_fifo_wr <= '1'; + word_count := to_unsigned(1, cL1CtrlFifoWidth); + + bit_counter <= cL1DataFifoWidth - 2; + payload_word(1 downto 0) <= data_in; + payload_counter <= to_integer(unsigned(nsclusters)) * cL1SClusterWidth + to_integer(unsigned(npclusters)) * cL1PClusterWidth - 2; + else -- header counter = -1 (the two new bits and the header(0) bit belong to payload word) + decoder <= payload_capture; + + status := header(cL1StatusLow(selectIndexFromModuleType(module_type, bandwidth)) + 1 + cL1StatusWidth - 1 downto cL1StatusLow(selectIndexFromModuleType(module_type, bandwidth)) + 1); + l1a := header(cL1IdLow(selectIndexFromModuleType(module_type, bandwidth)) + 1 + cL1IdWidth - 1 downto cL1IdLow(selectIndexFromModuleType(module_type, bandwidth)) + 1); + + -- nPclusters defines length of payload Pixels' data length + npclusters := header(cL1NPcluster_low + 1 + cL1NPcluster_width - 1 downto cL1NPcluster_low + 1); + + -- nSclusters defines length of payload strips' data length + nsclusters := header(cL1NScluster_low + 1 + cL1NScluster_width - 1 downto cL1NScluster_low + 1); + + -- debug + snsclusters <= nsclusters; + snpclusters <= npclusters; + sl1a <= l1a; + sstatus <= status; + + -- store the header to the data FIFO, and set word count to 1 + data_fifo <= l1a & status & nsclusters & npclusters; + data_fifo_wr <= '1'; + word_count := to_unsigned(1, cL1CtrlFifoWidth); + + bit_counter <= cL1DataFifoWidth - 3; + payload_word(2 downto 0) <= header(0) & data_in; + payload_counter <= to_integer(unsigned(nsclusters)) * cL1SClusterWidth + to_integer(unsigned(npclusters)) * cL1PClusterWidth - 3; + end if; + + -- pack the payload into words until the predetermined packet length ends + when payload_capture => + -- shift in payload + payload_word(1 downto 0) <= data_in; + payload_word(cL1DataFifoWidth + 2 downto 2) <= payload_word(cL1DataFifoWidth downto 0); + + if (payload_counter > 0) then + payload_counter <= payload_counter - 2; + + -- If buffer is full and all of the two previous bits belong to this data_fifo_word + if (bit_counter = 0) then + data_fifo <= payload_word(cL1DataFifoWidth - 1 downto 0); + data_fifo_wr <= '1'; + word_count := word_count + 1; + bit_counter <= cL1DataFifoWidth - 2; + + -- If buffer is full and one of the previous bits received is for the next data_fifo_word + elsif (bit_counter = -1) then + data_fifo <= payload_word(cL1DataFifoWidth downto 1); + data_fifo_wr <= '1'; + word_count := word_count + 1; + bit_counter <= cL1DataFifoWidth - 3; + else + bit_counter <= bit_counter - 2; + end if; + elsif (payload_counter = 0) then -- no bits remaining to store (all bits already in payload word buffer) + decoder <= store_event; + + -- if word buffer still not full --- pad the word + if (bit_counter >= 0) then + data_fifo <= std_logic_vector(unsigned(payload_word(cL1DataFifoWidth - 1 downto 0)) sll bit_counter); + data_fifo_wr <= '1'; + word_count := word_count + 1; + extra_word <= '0'; + else -- if word buffer full + data_fifo <= payload_word(cL1DataFifoWidth downto 1); + data_fifo_wr <= '1'; + word_count := word_count + 1; + extra_word <= '1'; + last_word <= payload_word(0) & b"000" & x"0000000"; + end if; + elsif (payload_counter < -1) then -- payload_counter is -2 or -3 when Sclust = 0 and Pclust = 0 ie. no stub in the payload + decoder <= store_event; + extra_word <= '0'; + else -- payload_counter = -1, only one bit of the last two bits added to payload word is good + decoder <= store_event; + + if (bit_counter >= 0) then + data_fifo <= std_logic_vector(unsigned(payload_word(cL1DataFifoWidth - 1 downto 0)) sll bit_counter); + data_fifo_wr <= '1'; + word_count := word_count + 1; + extra_word <= '0'; + else -- if word buffer full + data_fifo <= payload_word(cL1DataFifoWidth downto 1); + data_fifo_wr <= '1'; + word_count := word_count + 1; + extra_word <= '0'; + end if; + end if; + + -- finish off packet handling by storing metadata to FIFOs, increment event counter, and reinitialise + when store_event => + + if (extra_word = '1') then + data_fifo <= last_word; + data_fifo_wr <= '1'; + word_count := word_count + 1; + end if; + + event_fifo <= std_logic_vector(event_counter); + record_fifo <= std_logic_vector(word_count); + event_fifo_wr <= '1'; + record_fifo_wr <= '1'; + + decoder <= idle; + word_count := (others => '0'); + event_counter <= event_counter + 1; + extra_word <= '0'; + + when others => + decoder <= idle; + + end case; - -- finish off packet handling by storing metadata to FIFOs, increment event counter, and reinitialise - when store_event => - - if (extra_word = '1') then - data_fifo <= last_word; - data_fifo_wr <= '1'; - word_count := word_count + 1; end if; - - event_fifo <= std_logic_vector(event_counter); - record_fifo <= std_logic_vector(word_count); - event_fifo_wr <= '1'; - record_fifo_wr <= '1'; - - decoder <= idle; - word_count := (others => '0'); - event_counter <= event_counter + 1; - extra_word <= '0'; - - when others => - decoder <= idle; - - end case; - - end if; - end if; - end process; - - - end modulePS10G; + end if; + + end process pDecoderSm; + +end architecture modulePS10G; diff --git a/dtc-fe/firmware/hdl/L1DataDecoder_PS5G.vhd b/dtc-fe/firmware/hdl/L1DataDecoder_PS5G.vhd index 652a3192e1b4ed3f09a35ac7853eaa475b4b62d8..291e9908d2e58f48d0ee80a12719a1de499aee21 100644 --- a/dtc-fe/firmware/hdl/L1DataDecoder_PS5G.vhd +++ b/dtc-fe/firmware/hdl/L1DataDecoder_PS5G.vhd @@ -1,31 +1,30 @@ -library IEEE; -use IEEE.STD_LOGIC_1164.ALL; -use IEEE.NUMERIC_STD.ALL; - -use work.module_constants.all; -use work.front_end_data_types.all; -use work.emp_data_types.all; -use work.dtc_constants.all; -use work.dtc_data_types.all; +library ieee; + use ieee.std_logic_1164.all; + use ieee.numeric_std.all; +library work; + use work.module_constants.all; + use work.front_end_data_types.all; + use work.emp_data_types.all; + use work.dtc_constants.all; + use work.dtc_data_types.all; architecture modulePS5G of L1DataDecoder is -type decoder_state is (idle, capture_armed, header_capture, payload_capture, store_event, error); - -signal decoder : decoder_state := idle; + type tDecoderState is (idle, capture_armed, header_capture, payload_capture, store_event, error); -signal header : std_logic_vector(cL1HeaderWidth(selectIndexFromModuleType(module_type, bandwidth)) - 1 downto 0) := ( others => '0' ); -signal payload_word : std_logic_vector(cL1DataFifoWidth - 1 downto 0) := ( others => '0' ); + signal decoder : tDecoderState := idle; -signal start_counter : integer range 0 to 31 := cL1StartSequenceThresh; -signal header_counter : integer range 0 to 35; -signal payload_counter : integer range -1 to 4500; -signal bit_counter : integer range 0 to cL1DataFifoWidth - 1; -signal data : std_logic; + signal header : std_logic_vector(cL1HeaderWidth(selectIndexFromModuleType(module_type, bandwidth)) - 1 downto 0) := (others => '0'); + signal payload_word : std_logic_vector(cL1DataFifoWidth - 1 downto 0) := (others => '0'); -signal event_counter : unsigned(cL1CtrlFifoWidth - 1 downto 0) := to_unsigned(1, cL1CtrlFifoWidth); + signal start_counter : integer range 0 to 31 := cL1StartSequenceThresh; + signal header_counter : integer range 0 to 35; + signal payload_counter : integer range -1 to 4500; + signal bit_counter : integer range 0 to cL1DataFifoWidth - 1; + signal data : std_logic; + signal event_counter : unsigned(cL1CtrlFifoWidth - 1 downto 0) := to_unsigned(1, cL1CtrlFifoWidth); ---- @@ -53,158 +52,150 @@ signal event_counter : unsigned(cL1CtrlFifoWidth - 1 downto 0) := to_unsigned( begin + event_number <= std_logic_vector(event_counter - 1); - event_number <= std_logic_vector(event_counter-1); - - - decoder_sm: process (clk) - - variable status : std_logic_vector(cL1StatusWidth - 1 downto 0); - variable l1a : std_logic_vector(cL1IdWidth - 1 downto 0); - variable nPclusters : std_logic_vector(cL1NPcluster_width - 1 downto 0); - variable nSclusters : std_logic_vector(CL1NScluster_width - 1 downto 0); - - variable word_count : unsigned(cL1CtrlFifoWidth - 1 downto 0) := ( others => '0' ); - - begin - if rising_edge(clk) then - - if reset = '1' then - - decoder <= idle; - start_counter <= cL1StartSequenceThresh; - event_counter <= to_unsigned(1, cL1CtrlFifoWidth); - - event_fifo <= ( others => '0' ); - record_fifo <= ( others => '0' ); - data_fifo <= ( others => '0' ); - - data_fifo_wr <= '0'; - event_fifo_wr <= '0'; - record_fifo_wr <= '0'; - - else - - data_fifo_wr <= '0'; - event_fifo_wr <= '0'; - record_fifo_wr <= '0'; - - data <= data_in(0); - - case decoder is - - -- wait for a start sequence of '1's indicating the start of a packet - when idle => - -- idle pattern is a repeating 10101.. - if data = '1' then - start_counter <= start_counter - 1; - else - start_counter <= cL1StartSequenceThresh; - end if; - if start_counter = 0 then - -- if more than "cL1StartSequenceThresh" consecutive '1's, arm capture - decoder <= capture_armed; - start_counter <= cL1StartSequenceThresh; - end if; + pDecoderSm : process (clk) is - -- wait for a single '0' indicating the start of header - when capture_armed => - if data = '0' then - decoder <= header_capture; - header_counter <= cL1HeaderWidth(selectIndexFromModuleType(module_type, bandwidth)); - end if; + variable status : std_logic_vector(cL1StatusWidth - 1 downto 0); + variable l1a : std_logic_vector(cL1IdWidth - 1 downto 0); + variable npclusters : std_logic_vector(cL1NPcluster_width - 1 downto 0); + variable nsclusters : std_logic_vector(CL1NScluster_width - 1 downto 0); - -- extract & store the header and calculate the payload length - when header_capture => - -- shift in header - header(0) <= data; - header(cL1HeaderWidth(selectIndexFromModuleType(module_type, bandwidth)) - 1 downto 1) <= header(cL1HeaderWidth(selectIndexFromModuleType(module_type, bandwidth)) - 2 downto 0); - - -- wait until full length of header has been shifted in - if header_counter = 0 then - -- start decoding payload on next clock cycle - decoder <= payload_capture; - -- PS sparsified mode - - status := header(cL1StatusLow(selectIndexFromModuleType(module_type, bandwidth)) + cL1StatusWidth - 1 downto cL1StatusLow(selectIndexFromModuleType(module_type, bandwidth))); - l1a := header(cL1IdLow(selectIndexFromModuleType(module_type, bandwidth)) + cL1IdWidth - 1 downto cL1IdLow(selectIndexFromModuleType(module_type, bandwidth))); - - -- nPclusters defines length of payload Pixels' data length - nPclusters := header(cL1NPcluster_low + cL1NPcluster_width - 1 downto cL1NPcluster_low); - - -- nSclusters defines length of payload strips' data length - nSclusters := header(cL1NScluster_low + cL1NScluster_width - 1 downto cL1NScluster_low); - - -- initialise counters for the payload_capture state - -- DSP calculation? maybe too hard to calculate - payload_counter <= to_integer(unsigned(nSclusters))*cL1SClusterWidth + to_integer(unsigned(nPclusters))*cL1PClusterWidth - 1; - - bit_counter <= cL1DataFifoWidth - 1; - payload_word(0) <= data; - - -- store the header to the data FIFO, and set word count to 1 - data_fifo <= l1a & status & nSclusters & nPclusters; - data_fifo_wr <= '1'; - word_count := to_unsigned(1, cL1CtrlFifoWidth); - else - header_counter <= header_counter - 1; - end if; - - -- pack the payload into words until the predetermined packet length ends - when payload_capture => - -- shift in payload - payload_word(0) <= data; - payload_word(cL1DataFifoWidth - 1 downto 1) <= payload_word(cL1DataFifoWidth - 2 downto 0); - - -- wait until full length of payload has been shifted in to leave state - if payload_counter <= 0 then - decoder <= store_event; - else - payload_counter <= payload_counter - 1; - end if; + variable word_count : unsigned(cL1CtrlFifoWidth - 1 downto 0) := (others => '0'); + + begin - -- check to see if we have packed enough data to write to data FIFO - if bit_counter = 0 then - - -- store the word to data FIFO, and increment word count - data_fifo <= payload_word; + if rising_edge(clk) then + if (reset = '1') then + decoder <= idle; + start_counter <= cL1StartSequenceThresh; + event_counter <= to_unsigned(1, cL1CtrlFifoWidth); - data_fifo_wr <= '1'; - word_count := word_count + 1; - bit_counter <= cL1DataFifoWidth - 1; + event_fifo <= (others => '0'); + record_fifo <= (others => '0'); + data_fifo <= (others => '0'); + + data_fifo_wr <= '0'; + event_fifo_wr <= '0'; + record_fifo_wr <= '0'; else - bit_counter <= bit_counter - 1; - - -- check if we have reached the end of the payload, but haven't fully packed a word - if payload_counter = 0 then - - -- pad out payload word and store it to data FIFO - data_fifo <= std_logic_vector(unsigned(payload_word) sll bit_counter); - data_fifo_wr <= '1'; - word_count := word_count + 1; - end if; - + data_fifo_wr <= '0'; + event_fifo_wr <= '0'; + record_fifo_wr <= '0'; + + data <= data_in(0); + + case decoder is + + -- wait for a start sequence of '1's indicating the start of a packet + when idle => + -- idle pattern is a repeating 10101.. + if (data = '1') then + start_counter <= start_counter - 1; + else + start_counter <= cL1StartSequenceThresh; + end if; + if (start_counter = 0) then + -- if more than "cL1StartSequenceThresh" consecutive '1's, arm capture + decoder <= capture_armed; + start_counter <= cL1StartSequenceThresh; + end if; + + -- wait for a single '0' indicating the start of header + when capture_armed => + if (data = '0') then + decoder <= header_capture; + header_counter <= cL1HeaderWidth(selectIndexFromModuleType(module_type, bandwidth)); + end if; + + -- extract & store the header and calculate the payload length + when header_capture => + -- shift in header + header(0) <= data; + header(cL1HeaderWidth(selectIndexFromModuleType(module_type, bandwidth)) - 1 downto 1) <= header(cL1HeaderWidth(selectIndexFromModuleType(module_type, bandwidth)) - 2 downto 0); + + -- wait until full length of header has been shifted in + if (header_counter = 0) then + -- start decoding payload on next clock cycle + decoder <= payload_capture; + -- PS sparsified mode + + status := header(cL1StatusLow(selectIndexFromModuleType(module_type, bandwidth)) + cL1StatusWidth - 1 downto cL1StatusLow(selectIndexFromModuleType(module_type, bandwidth))); + l1a := header(cL1IdLow(selectIndexFromModuleType(module_type, bandwidth)) + cL1IdWidth - 1 downto cL1IdLow(selectIndexFromModuleType(module_type, bandwidth))); + + -- nPclusters defines length of payload Pixels' data length + npclusters := header(cL1NPcluster_low + cL1NPcluster_width - 1 downto cL1NPcluster_low); + + -- nSclusters defines length of payload strips' data length + nsclusters := header(cL1NScluster_low + cL1NScluster_width - 1 downto cL1NScluster_low); + + -- initialise counters for the payload_capture state + -- DSP calculation? maybe too hard to calculate + payload_counter <= to_integer(unsigned(nsclusters)) * cL1SClusterWidth + to_integer(unsigned(npclusters)) * cL1PClusterWidth - 1; + + bit_counter <= cL1DataFifoWidth - 1; + payload_word(0) <= data; + + -- store the header to the data FIFO, and set word count to 1 + data_fifo <= l1a & status & nsclusters & npclusters; + data_fifo_wr <= '1'; + word_count := to_unsigned(1, cL1CtrlFifoWidth); + else + header_counter <= header_counter - 1; + end if; + + -- pack the payload into words until the predetermined packet length ends + when payload_capture => + -- shift in payload + payload_word(0) <= data; + payload_word(cL1DataFifoWidth - 1 downto 1) <= payload_word(cL1DataFifoWidth - 2 downto 0); + + -- wait until full length of payload has been shifted in to leave state + if (payload_counter <= 0) then + decoder <= store_event; + else + payload_counter <= payload_counter - 1; + end if; + + -- check to see if we have packed enough data to write to data FIFO + if (bit_counter = 0) then + -- store the word to data FIFO, and increment word count + data_fifo <= payload_word; + + data_fifo_wr <= '1'; + word_count := word_count + 1; + bit_counter <= cL1DataFifoWidth - 1; + else + bit_counter <= bit_counter - 1; + + -- check if we have reached the end of the payload, but haven't fully packed a word + if (payload_counter = 0) then + -- pad out payload word and store it to data FIFO + data_fifo <= std_logic_vector(unsigned(payload_word) sll bit_counter); + data_fifo_wr <= '1'; + word_count := word_count + 1; + end if; + end if; + + -- finish off packet handling by storing metadata to FIFOs, increment event counter, and reinitialise + when store_event => + event_fifo <= std_logic_vector(event_counter); + record_fifo <= std_logic_vector(word_count); + event_fifo_wr <= '1'; + record_fifo_wr <= '1'; + + decoder <= idle; + word_count := (others => '0'); + event_counter <= event_counter + 1; + + when others => + decoder <= idle; + + end case; + end if; + end if; + + end process pDecoderSm; - -- finish off packet handling by storing metadata to FIFOs, increment event counter, and reinitialise - when store_event => - event_fifo <= std_logic_vector(event_counter); - record_fifo <= std_logic_vector(word_count); - event_fifo_wr <= '1'; - record_fifo_wr <= '1'; - - decoder <= idle; - word_count := (others => '0'); - event_counter <= event_counter + 1; - - when others => - decoder <= idle; - - end case; - - end if; - end if; - end process; - - - end modulePS5G; +end architecture modulePS5G; diff --git a/dtc-fe/firmware/hdl/L1DataExtractor.vhd b/dtc-fe/firmware/hdl/L1DataExtractor.vhd index 8b914ffd8b68d0de8fb63ed5b88e8ef71d428f10..f6ea3c659261f46a37f0c27fb770f7db745bcd05 100644 --- a/dtc-fe/firmware/hdl/L1DataExtractor.vhd +++ b/dtc-fe/firmware/hdl/L1DataExtractor.vhd @@ -1,480 +1,483 @@ -library IEEE; -library XPM; -use IEEE.STD_LOGIC_1164.ALL; -use IEEE.NUMERIC_STD.ALL; -use XPM.VCOMPONENTS.ALL; +library ieee; + use ieee.std_logic_1164.all; + use ieee.numeric_std.all; -use work.module_constants.all; -use work.front_end_data_types.all; -use work.emp_data_types.all; -use work.dtc_constants.all; -use work.dtc_data_types.all; +library xpm; + use xpm.vcomponents.all; +library work; + use work.module_constants.all; + use work.front_end_data_types.all; + use work.emp_data_types.all; + use work.dtc_constants.all; + use work.dtc_data_types.all; entity L1DataExtractor is generic ( - module_type : string; - bandwidth : integer; - cic_type : string + module_type : string; + bandwidth : integer; + cic_type : string ); port ( - --- Input Ports --- - clk : in std_logic; - data_in : in std_logic_vector(cNumberOfL1ELinks(selectIndexFromModuleType(module_type, bandwidth))-1 downto 0); - daq_ipb_ctrl : in std_logic_vector(31 downto 0); - daq_fifo_read : in tDaqFlag; + --- Input Ports --- + clk : in std_logic; + data_in : in std_logic_vector(cNumberOfL1ELinks(selectIndexFromModuleType(module_type, bandwidth)) - 1 downto 0); + daq_ipb_ctrl : in std_logic_vector(31 downto 0); + daq_fifo_read : in tDaqFlag; --- Output Ports --- - daq_ipb_status : out std_logic_vector(31 downto 0); - daq_ipb_record : out std_logic_vector(31 downto 0); - daq_ipb_data : out std_logic_vector(31 downto 0); - daq_fifo_data : out tDaqData; - daq_fifo_empty : out tDaqFlag + daq_ipb_status : out std_logic_vector(31 downto 0); + daq_ipb_record : out std_logic_vector(31 downto 0); + daq_ipb_data : out std_logic_vector(31 downto 0); + daq_fifo_data : out tDaqData; + daq_fifo_empty : out tDaqFlag ); -end L1DataExtractor; +end entity L1DataExtractor; +architecture behavioral of L1DataExtractor is -architecture Behavioral of L1DataExtractor is + -- ---- + signal to_event_fifo : std_logic_vector(cL1CtrlFifoWidth - 1 downto 0) := (others => '0'); + signal from_event_fifo : std_logic_vector(cL1CtrlFifoWidth - 1 downto 0) := (others => '0'); + signal full_event_fifo : std_logic; + signal empty_event_fifo : std_logic; + signal write_event_fifo : std_logic; + signal read_event_fifo : std_logic; --- ---- + signal to_record_fifo : std_logic_vector(cL1CtrlFifoWidth - 1 downto 0) := (others => '0'); + signal from_record_fifo : std_logic_vector(cL1CtrlFifoWidth - 1 downto 0) := (others => '0'); + signal full_record_fifo : std_logic; + signal empty_record_fifo : std_logic; + signal write_record_fifo : std_logic; + signal read_record_fifo : std_logic; -signal to_event_fifo : std_logic_vector(cL1CtrlFifoWidth - 1 downto 0) := ( others => '0' ); -signal from_event_fifo : std_logic_vector(cL1CtrlFifoWidth - 1 downto 0) := ( others => '0' ); -signal full_event_fifo : std_logic; -signal empty_event_fifo : std_logic; -signal write_event_fifo : std_logic; -signal read_event_fifo : std_logic; + signal to_data_fifo : std_logic_vector(cL1DataFifoWidth - 1 downto 0) := (others => '0'); + signal from_data_fifo : std_logic_vector(cL1DataFifoWidth - 1 downto 0) := (others => '0'); + signal full_data_fifo : std_logic; + signal empty_data_fifo : std_logic; + signal write_data_fifo : std_logic; + signal read_data_fifo : std_logic; -signal to_record_fifo : std_logic_vector(cL1CtrlFifoWidth - 1 downto 0) := ( others => '0' ); -signal from_record_fifo : std_logic_vector(cL1CtrlFifoWidth - 1 downto 0) := ( others => '0' ); -signal full_record_fifo : std_logic; -signal empty_record_fifo : std_logic; -signal write_record_fifo : std_logic; -signal read_record_fifo : std_logic; + signal reset : std_logic; + signal event_number : std_logic_vector(cL1CtrlFifoWidth - 1 downto 0); -signal to_data_fifo : std_logic_vector(cL1DataFifoWidth - 1 downto 0) := ( others => '0' ); -signal from_data_fifo : std_logic_vector(cL1DataFifoWidth - 1 downto 0) := ( others => '0' ); -signal full_data_fifo : std_logic; -signal empty_data_fifo : std_logic; -signal write_data_fifo : std_logic; -signal read_data_fifo : std_logic; + signal ctrl_reg1 : std_logic_vector(31 downto 0); + signal ctrl_reg2 : std_logic_vector(31 downto 0); -signal reset : std_logic; -signal event_number : std_logic_vector(cL1CtrlFifoWidth - 1 downto 0); + -- daqpath module signals + signal full_daqpath_data_fifo : std_logic; + signal full_daqpath_event_fifo : std_logic; + signal full_daqpath_record_fifo : std_logic; -signal ctrl_reg1 : std_logic_vector(31 downto 0); -signal ctrl_reg2 : std_logic_vector(31 downto 0); +---- ---daqpath module signals -signal full_daqpath_data_fifo : std_logic; -signal full_daqpath_event_fifo : std_logic; -signal full_daqpath_record_fifo : std_logic; +begin ----- + --==============================-- + -- Decode stream according to module type + --==============================-- + Gen2s : if module_type = "2S" generate -begin + GenCic1 : if cic_type = "CIC1" generate + --==============================-- + L1DataDecoder : entity work.L1DataDecoder(module2SCIC1) + --==============================-- + generic map ( + MODULE_TYPE => module_type, + BANDWIDTH => bandwidth + ) + port map ( + --- Input Ports --- + clk => clk, + data_in => data_in, + reset => reset, + --- Output Ports --- + event_number => event_number, + data_fifo => to_data_fifo, + event_fifo => to_event_fifo, + record_fifo => to_record_fifo, + data_fifo_wr => write_data_fifo, + event_fifo_wr => write_event_fifo, + record_fifo_wr => write_record_fifo + ); - --==============================-- - -- Decode stream according to module type - --==============================-- - - --==============================-- - g2S : if module_type = "2S" generate - --==============================-- - gCIC1 : if cic_type = "CIC1" generate - --==============================-- - L1DataDecoder: entity work.L1DataDecoder(module2SCIC1) - --==============================-- - generic map ( - module_type => module_type, - bandwidth => bandwidth - ) - port map ( - --- Input Ports --- - clk => clk, - data_in => data_in, - reset => reset, - --- Output Ports --- - event_number => event_number, - data_fifo => to_data_fifo, - event_fifo => to_event_fifo, - record_fifo => to_record_fifo, - data_fifo_wr => write_data_fifo, - event_fifo_wr => write_event_fifo, - record_fifo_wr => write_record_fifo - ); - end generate; - gCIC2 : if cic_type = "CIC2" generate - --==============================-- - L1DataDecoder: entity work.L1DataDecoder(module2SCIC2) - --==============================-- - generic map ( - module_type => module_type, - bandwidth => bandwidth - ) - port map ( - --- Input Ports --- - clk => clk, - data_in => data_in, - reset => reset, - --- Output Ports --- - event_number => event_number, - data_fifo => to_data_fifo, - event_fifo => to_event_fifo, - record_fifo => to_record_fifo, - data_fifo_wr => write_data_fifo, - event_fifo_wr => write_event_fifo, - record_fifo_wr => write_record_fifo - ); - end generate; - end generate; - --==============================-- - gPS : if module_type = "PS" generate - --==============================-- - g5G : if bandwidth = 5 generate - --==============================-- - L1DataDecoder: entity work.L1DataDecoder(modulePS5G) - --==============================-- - generic map ( - module_type => module_type, - bandwidth => bandwidth - ) - port map ( - --- Input Ports --- - clk => clk, - data_in => data_in, - reset => reset, - --- Output Ports --- - event_number => event_number, - data_fifo => to_data_fifo, - event_fifo => to_event_fifo, - record_fifo => to_record_fifo, - data_fifo_wr => write_data_fifo, - event_fifo_wr => write_event_fifo, - record_fifo_wr => write_record_fifo - ); - end generate; - g10G : if bandwidth = 10 generate - --==============================-- - L1DataDecoder: entity work.L1DataDecoder(modulePS10G) - --==============================-- - generic map ( - module_type => module_type, - bandwidth => bandwidth - ) - port map ( - --- Input Ports --- - clk => clk, - data_in => data_in, - reset => reset, - --- Output Ports --- - event_number => event_number, - data_fifo => to_data_fifo, - event_fifo => to_event_fifo, - record_fifo => to_record_fifo, - data_fifo_wr => write_data_fifo, - event_fifo_wr => write_event_fifo, - record_fifo_wr => write_record_fifo - ); - end generate; - end generate; - - - --==============================-- - -- IPBus control logic for debug FIFOs - --==============================-- - - ipbus_ctrl_latched: process (clk) - - variable ctrl_detect : std_logic_vector(31 downto 0); - - begin - if rising_edge(clk) then - - ctrl_reg2 <= ctrl_reg1; - ctrl_reg1 <= daq_ipb_ctrl; - - -- ensure reads/resets are clocked and only rising edge of ipbus signals initiate a read - ctrl_detect := (not ctrl_reg2) and ctrl_reg1; - - reset <= '0'; - read_event_fifo <= '0'; - read_record_fifo <= '0'; - read_data_fifo <= '0'; - - if ctrl_detect(0) = '1' then - reset <= '1'; - end if; - - if ctrl_detect(1) = '1' then - read_event_fifo <= '1'; - read_record_fifo <= '1'; - end if; - - if ctrl_detect(2) = '1' then - read_data_fifo <= '1'; - end if; - - end if; - end process; - - - daq_ipb_status(3 downto 0) <= '0' & empty_data_fifo & empty_event_fifo & empty_record_fifo; - daq_ipb_status(7 downto 4) <= '0' & full_data_fifo & full_event_fifo & full_record_fifo; - daq_ipb_status(15 downto 8) <= (others => '0'); - daq_ipb_status(31 downto 16) <= event_number; - - daq_ipb_record <= from_event_fifo & from_record_fifo; - - daq_ipb_data <= from_data_fifo; - - ---================================================================================================= - --- Data FIFOs are 1k 32bit words FIFOs - implemented using xpm macros --- Ctrl FIFOs are 512 32bit words FIFOs - implemented using xpm macros - -debug_data_fifo : xpm_fifo_async + end generate GenCic1; + + GenCic2 : if cic_type = "CIC2" generate + --==============================-- + L1DataDecoder : entity work.L1DataDecoder(module2SCIC2) + --==============================-- + generic map ( + MODULE_TYPE => module_type, + BANDWIDTH => bandwidth + ) + port map ( + --- Input Ports --- + clk => clk, + data_in => data_in, + reset => reset, + --- Output Ports --- + event_number => event_number, + data_fifo => to_data_fifo, + event_fifo => to_event_fifo, + record_fifo => to_record_fifo, + data_fifo_wr => write_data_fifo, + event_fifo_wr => write_event_fifo, + record_fifo_wr => write_record_fifo + ); + + end generate GenCic2; + + end generate Gen2s; + + --==============================-- + GenPs : if module_type = "PS" generate + + --==============================-- + Gen5g : if bandwidth = 5 generate + --==============================-- + L1DataDecoder : entity work.L1DataDecoder(modulePS5G) + --==============================-- + generic map ( + MODULE_TYPE => module_type, + BANDWIDTH => bandwidth + ) + port map ( + --- Input Ports --- + clk => clk, + data_in => data_in, + reset => reset, + --- Output Ports --- + event_number => event_number, + data_fifo => to_data_fifo, + event_fifo => to_event_fifo, + record_fifo => to_record_fifo, + data_fifo_wr => write_data_fifo, + event_fifo_wr => write_event_fifo, + record_fifo_wr => write_record_fifo + ); + + end generate Gen5g; + + Gen10g : if bandwidth = 10 generate + --==============================-- + L1DataDecoder : entity work.L1DataDecoder(modulePS10G) + --==============================-- + generic map ( + MODULE_TYPE => module_type, + BANDWIDTH => bandwidth + ) + port map ( + --- Input Ports --- + clk => clk, + data_in => data_in, + reset => reset, + --- Output Ports --- + event_number => event_number, + data_fifo => to_data_fifo, + event_fifo => to_event_fifo, + record_fifo => to_record_fifo, + data_fifo_wr => write_data_fifo, + event_fifo_wr => write_event_fifo, + record_fifo_wr => write_record_fifo + ); + + end generate Gen10g; + + end generate GenPs; + + --==============================-- + -- IPBus control logic for debug FIFOs + --==============================-- + + pIpbusCtrlLatched : process (clk) is + + variable ctrl_detect : std_logic_vector(31 downto 0); + + begin + + if rising_edge(clk) then + ctrl_reg2 <= ctrl_reg1; + ctrl_reg1 <= daq_ipb_ctrl; + + -- ensure reads/resets are clocked and only rising edge of ipbus signals initiate a read + ctrl_detect := (not ctrl_reg2) and ctrl_reg1; + + reset <= '0'; + read_event_fifo <= '0'; + read_record_fifo <= '0'; + read_data_fifo <= '0'; + + if (ctrl_detect(0) = '1') then + reset <= '1'; + end if; + + if (ctrl_detect(1) = '1') then + read_event_fifo <= '1'; + read_record_fifo <= '1'; + end if; + + if (ctrl_detect(2) = '1') then + read_data_fifo <= '1'; + end if; + end if; + + end process pIpbusCtrlLatched; + + daq_ipb_status(3 downto 0) <= '0' & empty_data_fifo & empty_event_fifo & empty_record_fifo; + daq_ipb_status(7 downto 4) <= '0' & full_data_fifo & full_event_fifo & full_record_fifo; + daq_ipb_status(15 downto 8) <= (others => '0'); + daq_ipb_status(31 downto 16) <= event_number; + + daq_ipb_record <= from_event_fifo & from_record_fifo; + + daq_ipb_data <= from_data_fifo; + + --================================================================================================= + + -- Data FIFOs are 1k 32bit words FIFOs - implemented using xpm macros + -- Ctrl FIFOs are 512 32bit words FIFOs - implemented using xpm macros + + DebugDataFifo : entity xpm.xpm_fifo_async generic map ( - CDC_SYNC_STAGES => 2, -- DECIMAL - DOUT_RESET_VALUE => "0", -- String - ECC_MODE => "no_ecc", -- String - FIFO_MEMORY_TYPE => "block", -- String - FIFO_READ_LATENCY => 0, -- DECIMAL --first word fall through - FIFO_WRITE_DEPTH => 1024, -- DECIMAL - FULL_RESET_VALUE => 0, -- DECIMAL - PROG_EMPTY_THRESH => 5, -- DECIMAL - PROG_FULL_THRESH => 5, -- DECIMAL - RD_DATA_COUNT_WIDTH => 1, -- DECIMAL - READ_DATA_WIDTH => 32, -- DECIMAL - READ_MODE => "fwft", -- String - RELATED_CLOCKS => 0, -- DECIMAL - USE_ADV_FEATURES => "0000", -- String - WAKEUP_TIME => 0, -- DECIMAL - WRITE_DATA_WIDTH => 32, -- DECIMAL - WR_DATA_COUNT_WIDTH => 1 -- DECIMAL - ) - port map ( - rst => reset, - -- write port - wr_clk => clk, - din => to_data_fifo, - wr_en => write_data_fifo, - full => full_data_fifo, - -- read port - rd_clk => clk, - dout => from_data_fifo, - rd_en => read_data_fifo, - empty => empty_data_fifo, - --Others - sleep => '0', - injectdbiterr => '0', - injectsbiterr => '0', - wr_rst_busy => open, - rd_rst_busy => open - ); - -daqpath_data_fifo : xpm_fifo_async + CDC_SYNC_STAGES => 2, + DOUT_RESET_VALUE => "0", + ECC_MODE => "no_ecc", + FIFO_MEMORY_TYPE => "block", + FIFO_READ_LATENCY => 0, + FIFO_WRITE_DEPTH => 1024, + FULL_RESET_VALUE => 0, + PROG_EMPTY_THRESH => 5, + PROG_FULL_THRESH => 5, + RD_DATA_COUNT_WIDTH => 1, + READ_DATA_WIDTH => 32, + READ_MODE => "fwft", + RELATED_CLOCKS => 0, + USE_ADV_FEATURES => "0000", + WAKEUP_TIME => 0, + WRITE_DATA_WIDTH => 32, + WR_DATA_COUNT_WIDTH => 1 + ) + port map ( + rst => reset, + -- write port + wr_clk => clk, + din => to_data_fifo, + wr_en => write_data_fifo, + full => full_data_fifo, + -- read port + rd_clk => clk, + dout => from_data_fifo, + rd_en => read_data_fifo, + empty => empty_data_fifo, + -- Others + sleep => '0', + injectdbiterr => '0', + injectsbiterr => '0', + wr_rst_busy => open, + rd_rst_busy => open + ); + + DaqpathDataFifo : entity xpm.xpm_fifo_async generic map ( - CDC_SYNC_STAGES => 2, -- DECIMAL - DOUT_RESET_VALUE => "0", -- String - ECC_MODE => "no_ecc", -- String - FIFO_MEMORY_TYPE => "block", -- String - FIFO_READ_LATENCY => 0, -- DECIMAL --first word fall through - FIFO_WRITE_DEPTH => 1024, -- DECIMAL - FULL_RESET_VALUE => 0, -- DECIMAL - PROG_EMPTY_THRESH => 5, -- DECIMAL - PROG_FULL_THRESH => 5, -- DECIMAL - RD_DATA_COUNT_WIDTH => 1, -- DECIMAL - READ_DATA_WIDTH => 32, -- DECIMAL - READ_MODE => "fwft", -- String - RELATED_CLOCKS => 0, -- DECIMAL - USE_ADV_FEATURES => "0000", -- String - WAKEUP_TIME => 0, -- DECIMAL - WRITE_DATA_WIDTH => 32, -- DECIMAL - WR_DATA_COUNT_WIDTH => 1 -- DECIMAL - ) - port map ( - rst => reset, - -- write port - wr_clk => clk, - din => to_data_fifo, - wr_en => write_data_fifo, - full => full_daqpath_data_fifo, - -- read port - rd_clk => clk, - dout => daq_fifo_data.data_word, - rd_en => daq_fifo_read.data_word, - empty => daq_fifo_empty.data_word, - --Others - sleep => '0', - injectdbiterr => '0', - injectsbiterr => '0', - wr_rst_busy => open, - rd_rst_busy => open - ); - - debug_event_fifo : xpm_fifo_async + CDC_SYNC_STAGES => 2, + DOUT_RESET_VALUE => "0", + ECC_MODE => "no_ecc", + FIFO_MEMORY_TYPE => "block", + FIFO_READ_LATENCY => 0, + FIFO_WRITE_DEPTH => 1024, + FULL_RESET_VALUE => 0, + PROG_EMPTY_THRESH => 5, + PROG_FULL_THRESH => 5, + RD_DATA_COUNT_WIDTH => 1, + READ_DATA_WIDTH => 32, + READ_MODE => "fwft", + RELATED_CLOCKS => 0, + USE_ADV_FEATURES => "0000", + WAKEUP_TIME => 0, + WRITE_DATA_WIDTH => 32, + WR_DATA_COUNT_WIDTH => 1 + ) + port map ( + rst => reset, + -- write port + wr_clk => clk, + din => to_data_fifo, + wr_en => write_data_fifo, + full => full_daqpath_data_fifo, + -- read port + rd_clk => clk, + dout => daq_fifo_data.data_word, + rd_en => daq_fifo_read.data_word, + empty => daq_fifo_empty.data_word, + -- Others + sleep => '0', + injectdbiterr => '0', + injectsbiterr => '0', + wr_rst_busy => open, + rd_rst_busy => open + ); + + DebugEventFifo : entity xpm.xpm_fifo_async generic map ( - CDC_SYNC_STAGES => 2, -- DECIMAL - DOUT_RESET_VALUE => "0", -- String - ECC_MODE => "no_ecc", -- String - FIFO_MEMORY_TYPE => "block", -- String - FIFO_READ_LATENCY => 0, -- DECIMAL --first word fall through - FIFO_WRITE_DEPTH => 512, -- DECIMAL - FULL_RESET_VALUE => 0, -- DECIMAL - PROG_EMPTY_THRESH => 5, -- DECIMAL - PROG_FULL_THRESH => 5, -- DECIMAL - RD_DATA_COUNT_WIDTH => 1, -- DECIMAL - READ_DATA_WIDTH => 16, -- DECIMAL - READ_MODE => "fwft", -- String - RELATED_CLOCKS => 0, -- DECIMAL - USE_ADV_FEATURES => "0000", -- String - WAKEUP_TIME => 0, -- DECIMAL - WRITE_DATA_WIDTH => 16, -- DECIMAL - WR_DATA_COUNT_WIDTH => 1 -- DECIMAL - ) - port map ( - rst => reset, - -- write port - wr_clk => clk, - din => to_event_fifo, - wr_en => write_event_fifo, - full => full_event_fifo, - -- read port - rd_clk => clk, - dout => from_event_fifo, - rd_en => read_event_fifo, - empty => empty_event_fifo, - --Others - sleep => '0', - injectdbiterr => '0', - injectsbiterr => '0', - wr_rst_busy => open, - rd_rst_busy => open - ); - - daqpath_event_fifo : xpm_fifo_async + CDC_SYNC_STAGES => 2, + DOUT_RESET_VALUE => "0", + ECC_MODE => "no_ecc", + FIFO_MEMORY_TYPE => "block", + FIFO_READ_LATENCY => 0, + FIFO_WRITE_DEPTH => 512, + FULL_RESET_VALUE => 0, + PROG_EMPTY_THRESH => 5, + PROG_FULL_THRESH => 5, + RD_DATA_COUNT_WIDTH => 1, + READ_DATA_WIDTH => 16, + READ_MODE => "fwft", + RELATED_CLOCKS => 0, + USE_ADV_FEATURES => "0000", + WAKEUP_TIME => 0, + WRITE_DATA_WIDTH => 16, + WR_DATA_COUNT_WIDTH => 1 + ) + port map ( + rst => reset, + -- write port + wr_clk => clk, + din => to_event_fifo, + wr_en => write_event_fifo, + full => full_event_fifo, + -- read port + rd_clk => clk, + dout => from_event_fifo, + rd_en => read_event_fifo, + empty => empty_event_fifo, + -- Others + sleep => '0', + injectdbiterr => '0', + injectsbiterr => '0', + wr_rst_busy => open, + rd_rst_busy => open + ); + + DaqpathEventFifo : entity xpm.xpm_fifo_async generic map ( - CDC_SYNC_STAGES => 2, -- DECIMAL - DOUT_RESET_VALUE => "0", -- String - ECC_MODE => "no_ecc", -- String - FIFO_MEMORY_TYPE => "block", -- String - FIFO_READ_LATENCY => 0, -- DECIMAL --first word fall through - FIFO_WRITE_DEPTH => 512, -- DECIMAL - FULL_RESET_VALUE => 0, -- DECIMAL - PROG_EMPTY_THRESH => 5, -- DECIMAL - PROG_FULL_THRESH => 5, -- DECIMAL - RD_DATA_COUNT_WIDTH => 1, -- DECIMAL - READ_DATA_WIDTH => 16, -- DECIMAL - READ_MODE => "fwft", -- String - RELATED_CLOCKS => 0, -- DECIMAL - USE_ADV_FEATURES => "0000", -- String - WAKEUP_TIME => 0, -- DECIMAL - WRITE_DATA_WIDTH => 16, -- DECIMAL - WR_DATA_COUNT_WIDTH => 1 -- DECIMAL - ) - port map ( - rst => reset, - -- write port - wr_clk => clk, - din => to_event_fifo, - wr_en => write_event_fifo, - full => full_daqpath_event_fifo, - -- read port - rd_clk => clk, - dout => daq_fifo_data.event_id, - rd_en => daq_fifo_read.event_id, - empty => daq_fifo_empty.event_id, - --Others - sleep => '0', - injectdbiterr => '0', - injectsbiterr => '0', - wr_rst_busy => open, - rd_rst_busy => open - ); - - -debug_record_fifo : xpm_fifo_async + CDC_SYNC_STAGES => 2, + DOUT_RESET_VALUE => "0", + ECC_MODE => "no_ecc", + FIFO_MEMORY_TYPE => "block", + FIFO_READ_LATENCY => 0, + FIFO_WRITE_DEPTH => 512, + FULL_RESET_VALUE => 0, + PROG_EMPTY_THRESH => 5, + PROG_FULL_THRESH => 5, + RD_DATA_COUNT_WIDTH => 1, + READ_DATA_WIDTH => 16, + READ_MODE => "fwft", + RELATED_CLOCKS => 0, + USE_ADV_FEATURES => "0000", + WAKEUP_TIME => 0, + WRITE_DATA_WIDTH => 16, + WR_DATA_COUNT_WIDTH => 1 + ) + port map ( + rst => reset, + -- write port + wr_clk => clk, + din => to_event_fifo, + wr_en => write_event_fifo, + full => full_daqpath_event_fifo, + -- read port + rd_clk => clk, + dout => daq_fifo_data.event_id, + rd_en => daq_fifo_read.event_id, + empty => daq_fifo_empty.event_id, + -- Others + sleep => '0', + injectdbiterr => '0', + injectsbiterr => '0', + wr_rst_busy => open, + rd_rst_busy => open + ); + + DebugRecordFifo : entity xpm.xpm_fifo_async generic map ( - CDC_SYNC_STAGES => 2, -- DECIMAL - DOUT_RESET_VALUE => "0", -- String - ECC_MODE => "no_ecc", -- String - FIFO_MEMORY_TYPE => "block", -- String - FIFO_READ_LATENCY => 0, -- DECIMAL --first word fall through - FIFO_WRITE_DEPTH => 512, -- DECIMAL - FULL_RESET_VALUE => 0, -- DECIMAL - PROG_EMPTY_THRESH => 5, -- DECIMAL - PROG_FULL_THRESH => 5, -- DECIMAL - RD_DATA_COUNT_WIDTH => 1, -- DECIMAL - READ_DATA_WIDTH => 16, -- DECIMAL - READ_MODE => "fwft", -- String - RELATED_CLOCKS => 0, -- DECIMAL - USE_ADV_FEATURES => "0000", -- String - WAKEUP_TIME => 0, -- DECIMAL - WRITE_DATA_WIDTH => 16, -- DECIMAL - WR_DATA_COUNT_WIDTH => 1 -- DECIMAL - ) - port map ( - rst => reset, - -- write port - wr_clk => clk, - din => to_record_fifo, - wr_en => write_record_fifo, - full => full_record_fifo, - -- read port - rd_clk => clk, - dout => from_record_fifo, - rd_en => read_record_fifo, - empty => empty_record_fifo, - --Others - sleep => '0', - injectdbiterr => '0', - injectsbiterr => '0', - wr_rst_busy => open, - rd_rst_busy => open - ); - -daqpath_record_fifo : xpm_fifo_async + CDC_SYNC_STAGES => 2, + DOUT_RESET_VALUE => "0", + ECC_MODE => "no_ecc", + FIFO_MEMORY_TYPE => "block", + FIFO_READ_LATENCY => 0, + FIFO_WRITE_DEPTH => 512, + FULL_RESET_VALUE => 0, + PROG_EMPTY_THRESH => 5, + PROG_FULL_THRESH => 5, + RD_DATA_COUNT_WIDTH => 1, + READ_DATA_WIDTH => 16, + READ_MODE => "fwft", + RELATED_CLOCKS => 0, + USE_ADV_FEATURES => "0000", + WAKEUP_TIME => 0, + WRITE_DATA_WIDTH => 16, + WR_DATA_COUNT_WIDTH => 1 + ) + port map ( + rst => reset, + -- write port + wr_clk => clk, + din => to_record_fifo, + wr_en => write_record_fifo, + full => full_record_fifo, + -- read port + rd_clk => clk, + dout => from_record_fifo, + rd_en => read_record_fifo, + empty => empty_record_fifo, + -- Others + sleep => '0', + injectdbiterr => '0', + injectsbiterr => '0', + wr_rst_busy => open, + rd_rst_busy => open + ); + + DaqpathRecordFifo : entity xpm.xpm_fifo_async generic map ( - CDC_SYNC_STAGES => 2, -- DECIMAL - DOUT_RESET_VALUE => "0", -- String - ECC_MODE => "no_ecc", -- String - FIFO_MEMORY_TYPE => "block", -- String - FIFO_READ_LATENCY => 0, -- DECIMAL --first word fall through - FIFO_WRITE_DEPTH => 512, -- DECIMAL - FULL_RESET_VALUE => 0, -- DECIMAL - PROG_EMPTY_THRESH => 5, -- DECIMAL - PROG_FULL_THRESH => 5, -- DECIMAL - RD_DATA_COUNT_WIDTH => 1, -- DECIMAL - READ_DATA_WIDTH => 16, -- DECIMAL - READ_MODE => "fwft", -- String - RELATED_CLOCKS => 0, -- DECIMAL - USE_ADV_FEATURES => "0000", -- String - WAKEUP_TIME => 0, -- DECIMAL - WRITE_DATA_WIDTH => 16, -- DECIMAL - WR_DATA_COUNT_WIDTH => 1 -- DECIMAL - ) - port map ( - rst => reset, - -- write port - wr_clk => clk, - din => to_record_fifo, - wr_en => write_record_fifo, - full => full_daqpath_record_fifo, - -- read port - rd_clk => clk, - dout => daq_fifo_data.n_words, - rd_en => daq_fifo_read.n_words, - empty => daq_fifo_empty.n_words, - --Others - sleep => '0', - injectdbiterr => '0', - injectsbiterr => '0', - wr_rst_busy => open, - rd_rst_busy => open - ); - -end Behavioral; + CDC_SYNC_STAGES => 2, + DOUT_RESET_VALUE => "0", + ECC_MODE => "no_ecc", + FIFO_MEMORY_TYPE => "block", + FIFO_READ_LATENCY => 0, + FIFO_WRITE_DEPTH => 512, + FULL_RESET_VALUE => 0, + PROG_EMPTY_THRESH => 5, + PROG_FULL_THRESH => 5, + RD_DATA_COUNT_WIDTH => 1, + READ_DATA_WIDTH => 16, + READ_MODE => "fwft", + RELATED_CLOCKS => 0, + USE_ADV_FEATURES => "0000", + WAKEUP_TIME => 0, + WRITE_DATA_WIDTH => 16, + WR_DATA_COUNT_WIDTH => 1 + ) + port map ( + rst => reset, + -- write port + wr_clk => clk, + din => to_record_fifo, + wr_en => write_record_fifo, + full => full_daqpath_record_fifo, + -- read port + rd_clk => clk, + dout => daq_fifo_data.n_words, + rd_en => daq_fifo_read.n_words, + empty => daq_fifo_empty.n_words, + -- Others + sleep => '0', + injectdbiterr => '0', + injectsbiterr => '0', + wr_rst_busy => open, + rd_rst_busy => open + ); + +end architecture behavioral; diff --git a/dtc-fe/firmware/hdl/LinkInterface.vhd b/dtc-fe/firmware/hdl/LinkInterface.vhd index b9bf487538b5d4a88b43df8d72656e98b49317f0..43a1e9321cdf054ca7d20c9970da329ab37e46a3 100644 --- a/dtc-fe/firmware/hdl/LinkInterface.vhd +++ b/dtc-fe/firmware/hdl/LinkInterface.vhd @@ -1,338 +1,316 @@ library ieee; -use ieee.std_logic_1164.all; -use ieee.numeric_std.all; - -use work.ipbus.all; -use work.ipbus_reg_types.all; - -use work.emp_data_types.all; - -use work.module_constants.all; -use work.front_end_data_types.all; -use work.dtc_constants.all; -use work.dtc_data_types.all; - - -use work.ipbus_decode_dtc_link_interface.all; - + use ieee.std_logic_1164.all; + use ieee.numeric_std.all; + +library work; + use work.ipbus.all; + use work.ipbus_reg_types.all; + use work.emp_data_types.all; + use work.module_constants.all; + use work.front_end_data_types.all; + use work.dtc_constants.all; + use work.dtc_data_types.all; + use work.ipbus_decode_dtc_link_interface.all; entity LinkInterface is -generic ( - module_type : string; - bandwidth : integer; - cic_type : string; - enable_monitoring : boolean := true; - emp_channel : integer := 0 -); -port ( - --- Input Ports --- - clk_p : in std_logic; - clk40 : in std_logic; - link_in : in lword := LWORD_NULL; - daq_read : in tDaqFlagArray; - global_fcmd : in tFastCommand; - --- Output Ports --- - link_out : out lword := LWORD_NULL; - stub_out : out lword := LWORD_NULL; - header_out : out tCICHeaderArray(cNumberOfCICs - 1 downto 0) := (others => ('0', (others => '0'), (others => '0'), (others => '0'))); - daq_out : out tDaqDataArray; - daq_empty : out tDaqFlagArray; - --- IPBus Ports --- - clk : in std_logic; - rst : in std_logic; - ipb_in : in ipb_wbus; - ipb_out : out ipb_rbus; - --- Debug Ports --- - debug_header_start : out std_logic_vector(1 downto 0); - debug_header_match : out std_logic_vector(1 downto 0); - debug_aligner_state : out std_logic_vector(7 downto 0) -); -end LinkInterface; + generic ( + module_type : string; + bandwidth : integer; + cic_type : string; + enable_monitoring : boolean := true; + emp_channel : integer := 0 + ); + port ( + --- Input Ports --- + clk_p : in std_logic; + clk40 : in std_logic; + link_in : in lword := LWORD_NULL; + daq_read : in tDaqFlagArray; + global_fcmd : in tFastCommand; + --- Output Ports --- + link_out : out lword := LWORD_NULL; + stub_out : out lword := LWORD_NULL; + header_out : out tCICHeaderArray(cNumberOfCICs - 1 downto 0) := (others => ('0', (others => '0'), (others => '0'), (others => '0'))); + daq_out : out tDaqDataArray; + daq_empty : out tDaqFlagArray; + --- IPBus Ports --- + clk : in std_logic; + rst : in std_logic; + ipb_in : in ipb_wbus; + ipb_out : out ipb_rbus; + --- Debug Ports --- + debug_header_start : out std_logic_vector(1 downto 0); + debug_header_match : out std_logic_vector(1 downto 0); + debug_aligner_state : out std_logic_vector(7 downto 0) + ); +end entity LinkInterface; architecture rtl of LinkInterface is + -- IPBus fabric --- IPBus fabric - -signal ipb_to_slaves : ipb_wbus_array(N_SLAVES - 1 downto 0); -signal ipb_from_slaves : ipb_rbus_array(N_SLAVES - 1 downto 0); - -signal fe_control_registers : ipb_reg_v(0 downto 0) := (others => (others => '0')); -signal fe_status_registers : ipb_reg_v(0 downto 0) := (others => (others => '0')); - -signal daq_status_registers : ipb_reg_v(5 downto 0) := (others => (others => '0')); -signal daq_control_registers : ipb_reg_v(1 downto 0) := (others => (others => '0')); - + signal ipb_to_slaves : ipb_wbus_array(N_SLAVES - 1 downto 0); + signal ipb_from_slaves : ipb_rbus_array(N_SLAVES - 1 downto 0); --- Link decoding and module readout + signal fe_control_registers : ipb_reg_v(0 downto 0) := (others => (others => '0')); + signal fe_status_registers : ipb_reg_v(0 downto 0) := (others => (others => '0')); -signal headers : tCICHeaderArray(cNumberOfCICs - 1 downto 0) := (others => ('0', (others => '0'), (others => '0'), (others => '0'))); -signal stubs : ldata(cNumberOfCICs - 1 downto 0) := (others => LWORD_NULL); -signal stubs_interleaved : lword := LWORD_NULL; + signal daq_status_registers : ipb_reg_v(5 downto 0) := (others => (others => '0')); + signal daq_control_registers : ipb_reg_v(1 downto 0) := (others => (others => '0')); -signal aligner_state : tAlignerArray(cNumberOfCICs - 1 downto 0) := (others => (others => '0')); -signal header_start : std_logic_vector(cNumberOfCICs - 1 downto 0) := (others => '0'); -signal sync_loss : std_logic_vector(cNumberOfCICs - 1 downto 0) := (others => '0'); + -- Link decoding and module readout + signal headers : tCICHeaderArray(cNumberOfCICs - 1 downto 0) := (others => ('0', (others => '0'), (others => '0'), (others => '0'))); + signal stubs : ldata(cNumberOfCICs - 1 downto 0) := (others => LWORD_NULL); + signal stubs_interleaved : lword := LWORD_NULL; + signal aligner_state : tAlignerArray(cNumberOfCICs - 1 downto 0) := (others => (others => '0')); + signal header_start : std_logic_vector(cNumberOfCICs - 1 downto 0) := (others => '0'); + signal sync_loss : std_logic_vector(cNumberOfCICs - 1 downto 0) := (others => '0'); begin + header_out <= headers; -header_out <= headers; - -debug_header_start <= header_start; -debug_header_match <= sync_loss; -debug_aligner_state <= aligner_state(1) & aligner_state(0); -fe_status_registers(0) <= std_logic_vector(to_unsigned(emp_channel, 32)); - - ---==============================-- --- IPBus fabric ---==============================-- - ---==============================-- -fabric: entity work.ipbus_fabric_sel ---==============================-- -generic map( - NSLV => N_SLAVES, - SEL_WIDTH => IPBUS_SEL_WIDTH -) -port map( - ipb_in => ipb_in, - ipb_out => ipb_out, - sel => ipbus_sel_dtc_link_interface(ipb_in.ipb_addr), - ipb_to_slaves => ipb_to_slaves, - ipb_from_slaves => ipb_from_slaves -); - ---==============================-- -fe_control: entity work.ipbus_ctrlreg_v ---==============================-- -generic map( - N_CTRL => 1, - N_STAT => 1 -) -port map( - clk => clk, - reset => rst, - ipbus_in => ipb_to_slaves(N_SLV_FE_CTRL), - ipbus_out => ipb_from_slaves(N_SLV_FE_CTRL), - d => fe_status_registers, - q => fe_control_registers -); - - ---==============================-- -fe_daq: entity work.ipbus_ctrlreg_v ---==============================-- -generic map( - N_CTRL => 2, - N_STAT => 6 -) -port map( - clk => clk, - reset => rst, - ipbus_in => ipb_to_slaves(N_SLV_L1_DAQ), - ipbus_out => ipb_from_slaves(N_SLV_L1_DAQ), - d => daq_status_registers, - q => daq_control_registers -); - - ---==============================-- --- Link decoding and module readout ---==============================-- - - ---==============================-- -CicInterface: for i in 0 to cNumberOfCICs - 1 generate ---==============================-- - - signal stream_in : lword := LWORD_NULL; - signal stream_in_aligned : lword := LWORD_NULL; - - signal l1_data_in : std_logic_vector(cNumberOfL1ELinks(selectIndexFromModuleType(module_type, bandwidth)) -1 downto 0) := (Others=>'0'); - signal aligner_reset : std_logic := '0'; - -begin + debug_header_start <= header_start; + debug_header_match <= sync_loss; + debug_aligner_state <= aligner_state(1) & aligner_state(0); + fe_status_registers(0) <= std_logic_vector(to_unsigned(emp_channel, 32)); - stream_in.valid <= link_in.valid; - stream_in.strobe <= link_in.data(32*i + 31); - stream_in.data(cNumberOfELinks(selectIndexFromModuleType(module_type, bandwidth)) - 1 downto 0) <= link_in.data(32*i + cNumberOfELinks(selectIndexFromModuleType(module_type, bandwidth)) - 1 downto 32*i); - - l1_data_in <= link_in.data(32*i + cNumberOfELinks(selectIndexFromModuleType(module_type, bandwidth)) + cNumberOfL1ELinks(selectIndexFromModuleType(module_type, bandwidth))-1 downto 32*i + cNumberOfELinks(selectIndexFromModuleType(module_type, bandwidth))); - aligner_reset <= fe_control_registers(0)(i); - - -- --==============================-- - -- FrameAlignerInstance : entity work.FrameAligner - -- --==============================-- - -- generic map ( - -- index => i - -- ) - -- port map ( - -- --- Input Ports --- - -- clk_p => clk, - -- data_in => stream_in, - -- --- Output Ports --- - -- data_out => stream_in_aligned - -- ); + --==============================-- + -- IPBus fabric + --==============================-- --==============================-- - HeaderAligner: entity work.HeaderAligner + Fabric : entity work.ipbus_fabric_sel --==============================-- generic map ( - module_type => module_type, - bandwidth => bandwidth + NSLV => N_SLAVES, + SEL_WIDTH => IPBUS_SEL_WIDTH ) - port map( - --- Input Ports --- - clk => clk_p, - data_in => stream_in, - reset => aligner_reset, - --- Output Ports --- - header_start => header_start(i), - state => aligner_state(i), - sync_loss => sync_loss(i) + port map ( + ipb_in => ipb_in, + ipb_out => ipb_out, + sel => ipbus_sel_dtc_link_interface(ipb_in.ipb_addr), + ipb_to_slaves => ipb_to_slaves, + ipb_from_slaves => ipb_from_slaves ); --==============================-- - StubExtractor: entity work.StubExtractor + FeControl : entity work.ipbus_ctrlreg_v --==============================-- - generic map( - cic_index => i, - module_type => module_type, - bandwidth => bandwidth + generic map ( + N_CTRL => 1, + N_STAT => 1 ) - port map( - --- Input Ports --- - clk => clk_p, - data_in => stream_in, - header_start => header_start(i), - aligner_state => aligner_state(i), - --- Output Ports --- - stub_out => stubs(i), - header_out => headers(i) + port map ( + clk => clk, + reset => rst, + ipbus_in => ipb_to_slaves(N_SLV_FE_CTRL), + ipbus_out => ipb_from_slaves(N_SLV_FE_CTRL), + d => fe_status_registers, + q => fe_control_registers ); - + --==============================-- - L1DataExtractor: entity work.L1DataExtractor + FeDaq : entity work.ipbus_ctrlreg_v --==============================-- generic map ( - module_type => module_type, - bandwidth => bandwidth, - cic_type => cic_type + N_CTRL => 2, + N_STAT => 6 ) - port map( - --- Input Ports --- - clk => clk_p, - data_in => l1_data_in, - daq_ipb_ctrl => daq_control_registers(i), - daq_fifo_read => daq_read(i), - --- Output Ports --- - daq_ipb_status => daq_status_registers(3*i+0), - daq_ipb_record => daq_status_registers(3*i+1), - daq_ipb_data => daq_status_registers(3*i+2), - daq_fifo_data => daq_out(i), - daq_fifo_empty => daq_empty(i) + port map ( + clk => clk, + reset => rst, + ipbus_in => ipb_to_slaves(N_SLV_L1_DAQ), + ipbus_out => ipb_from_slaves(N_SLV_L1_DAQ), + d => daq_status_registers, + q => daq_control_registers ); -end generate CicInterface; - - ---==============================-- --- Stub interleaving ---==============================-- - ---==============================-- -StubInterleaver: entity work.StubInterleaver ---==============================-- -port map( - --- Input Ports --- - clk => clk_p, - stub_in_0 => stubs(0), - stub_in_1 => stubs(1), - --- Output Ports --- - stub_out => stubs_interleaved -); - + --==============================-- + -- Link decoding and module readout + --==============================-- ---==============================-- --- Stub conversion for input to router ---==============================-- + --==============================-- + GenCicInterface : for i in 0 to cNumberOfCICs - 1 generate + --==============================-- + + signal stream_in : lword := LWORD_NULL; + signal stream_in_aligned : lword := LWORD_NULL; + + signal l1_data_in : std_logic_vector(cNumberOfL1ELinks(selectIndexFromModuleType(module_type, bandwidth)) - 1 downto 0) := (others => '0'); + signal aligner_reset : std_logic := '0'; + + begin + + stream_in.valid <= link_in.valid; + stream_in.strobe <= link_in.data(32 * i + 31); + stream_in.data(cNumberOfELinks(selectIndexFromModuleType(module_type, bandwidth)) - 1 downto 0) <= link_in.data(32 * i + cNumberOfELinks(selectIndexFromModuleType(module_type, bandwidth)) - 1 downto 32 * i); + + l1_data_in <= link_in.data(32 * i + cNumberOfELinks(selectIndexFromModuleType(module_type, bandwidth)) + cNumberOfL1ELinks(selectIndexFromModuleType(module_type, bandwidth)) - 1 downto 32 * i + cNumberOfELinks(selectIndexFromModuleType(module_type, bandwidth))); + aligner_reset <= fe_control_registers(0)(i); + + -- --==============================-- + -- FrameAlignerInstance : entity work.FrameAligner + -- --==============================-- + -- generic map ( + -- index => i + -- ) + -- port map ( + -- --- Input Ports --- + -- clk_p => clk, + -- data_in => stream_in, + -- --- Output Ports --- + -- data_out => stream_in_aligned + -- ); + + --==============================-- + HeaderAligner : entity work.HeaderAligner + --==============================-- + generic map ( + MODULE_TYPE => module_type, + BANDWIDTH => bandwidth + ) + port map ( + --- Input Ports --- + clk => clk_p, + data_in => stream_in, + reset => aligner_reset, + --- Output Ports --- + header_start => header_start(i), + state => aligner_state(i), + sync_loss => sync_loss(i) + ); ---==============================-- -StubConverter: entity work.StubConverter ---==============================-- -generic map ( - module_type => module_type, - bandwidth => bandwidth -) -port map( - --- Input Ports --- - clk => clk_p, - stub_in => stubs_interleaved, - --- Output Ports --- - stub_out => stub_out -); + --==============================-- + StubExtractor : entity work.StubExtractor + --==============================-- + generic map ( + CIC_INDEX => i, + MODULE_TYPE => module_type, + BANDWIDTH => bandwidth + ) + port map ( + --- Input Ports --- + clk => clk_p, + data_in => stream_in, + header_start => header_start(i), + aligner_state => aligner_state(i), + --- Output Ports --- + stub_out => stubs(i), + header_out => headers(i) + ); + --==============================-- + L1DataExtractor : entity work.L1DataExtractor + --==============================-- + generic map ( + MODULE_TYPE => module_type, + BANDWIDTH => bandwidth, + CIC_TYPE => cic_type + ) + port map ( + --- Input Ports --- + clk => clk_p, + data_in => l1_data_in, + daq_ipb_ctrl => daq_control_registers(i), + daq_fifo_read => daq_read(i), + --- Output Ports --- + daq_ipb_status => daq_status_registers(3 * i + 0), + daq_ipb_record => daq_status_registers(3 * i + 1), + daq_ipb_data => daq_status_registers(3 * i + 2), + daq_fifo_data => daq_out(i), + daq_fifo_empty => daq_empty(i) + ); + end generate GenCicInterface; ---==============================-- --- Link encoding and module control ---==============================-- + --==============================-- + -- Stub interleaving + --==============================-- + --==============================-- + StubInterleaver : entity work.StubInterleaver + --==============================-- + port map ( + --- Input Ports --- + clk => clk_p, + stub_in_0 => stubs(0), + stub_in_1 => stubs(1), + --- Output Ports --- + stub_out => stubs_interleaved + ); + --==============================-- + -- Stub conversion for input to router + --==============================-- ---==============================-- -LocalFastCommand: entity work.LocalFastCommand ---==============================-- -port map( - --- Input Ports --- - clk_p => clk_p, - clk40 => clk40, - global_fcmd => global_fcmd, - --- Output Ports --- - data_out => link_out, - --- IPBus Ports --- - clk => clk, - rst => rst, - ipb_in => ipb_to_slaves(N_SLV_FAST_CMD), - ipb_out => ipb_from_slaves(N_SLV_FAST_CMD) -); + --==============================-- + StubConverter : entity work.StubConverter + --==============================-- + generic map ( + MODULE_TYPE => module_type, + BANDWIDTH => bandwidth + ) + port map ( + --- Input Ports --- + clk => clk_p, + stub_in => stubs_interleaved, + --- Output Ports --- + stub_out => stub_out + ); + --==============================-- + -- Link encoding and module control + --==============================-- + --==============================-- + LocalFastCommand : entity work.LocalFastCommand + --==============================-- + port map ( + --- Input Ports --- + clk_p => clk_p, + clk40 => clk40, + global_fcmd => global_fcmd, + --- Output Ports --- + data_out => link_out, + --- IPBus Ports --- + clk => clk, + rst => rst, + ipb_in => ipb_to_slaves(N_SLV_FAST_CMD), + ipb_out => ipb_from_slaves(N_SLV_FAST_CMD) + ); ---==============================-- --- Health Monitoring ---==============================-- + --==============================-- + -- Health Monitoring + --==============================-- -genMonitoring : if enable_monitoring = true generate + GenMonitoring : if enable_monitoring = true generate -begin + begin - --==============================-- - HealthMonitor: entity work.HealthMonitor - --==============================-- - port map( + --==============================-- + HealthMonitor : entity work.HealthMonitor + --==============================-- + port map ( --- Input Ports --- - clk_p => clk_p, - header_start => header_start, - sync_loss => sync_loss, - header_in => headers, - aligner_state => aligner_state, - counter_reset => fe_control_registers(0)(2), - uplink_rdy_i => link_in.data(62), + clk_p => clk_p, + header_start => header_start, + sync_loss => sync_loss, + header_in => headers, + aligner_state => aligner_state, + counter_reset => fe_control_registers(0)(2), + uplink_rdy_i => link_in.data(62), --- Output Ports --- --- IPBus Ports --- - clk => clk, - rst => rst, - ipb_in => ipb_to_slaves(N_SLV_HEALTH_MON), - ipb_out => ipb_from_slaves(N_SLV_HEALTH_MON) + clk => clk, + rst => rst, + ipb_in => ipb_to_slaves(N_SLV_HEALTH_MON), + ipb_out => ipb_from_slaves(N_SLV_HEALTH_MON) ); -end generate genMonitoring; - + end generate GenMonitoring; -end rtl; +end architecture rtl; diff --git a/dtc-fe/firmware/hdl/LocalFastCommand.vhd b/dtc-fe/firmware/hdl/LocalFastCommand.vhd index a2a5e7803c0bb7ca6e9ea57057a810eb00c3dcc7..04ff9c6e62355d012e29c0694e1de8dca2893e98 100644 --- a/dtc-fe/firmware/hdl/LocalFastCommand.vhd +++ b/dtc-fe/firmware/hdl/LocalFastCommand.vhd @@ -1,314 +1,289 @@ library ieee; -use ieee.std_logic_1164.all; -use ieee.numeric_std.all; - -use work.ipbus.all; -use work.ipbus_reg_types.all; - -use work.emp_data_types.all; - -use work.module_constants.all; -use work.front_end_data_types.all; -use work.dtc_constants.all; -use work.dtc_data_types.all; - + use ieee.std_logic_1164.all; + use ieee.numeric_std.all; + +library work; + use work.ipbus.all; + use work.ipbus_reg_types.all; + use work.emp_data_types.all; + use work.module_constants.all; + use work.front_end_data_types.all; + use work.dtc_constants.all; + use work.dtc_data_types.all; entity LocalFastCommand is -port( - --- Input Ports --- - clk_p : in std_logic; - clk40 : in std_logic; - global_fcmd : in tFastCommand; - --- Output Ports --- - data_out : out lword := LWORD_NULL; - --- IPBus Ports --- - clk : in std_logic; - rst : in std_logic; - ipb_in : in ipb_wbus; - ipb_out : out ipb_rbus -); -end LocalFastCommand; - + port ( + --- Input Ports --- + clk_p : in std_logic; + clk40 : in std_logic; + global_fcmd : in tFastCommand; + --- Output Ports --- + data_out : out lword := LWORD_NULL; + --- IPBus Ports --- + clk : in std_logic; + rst : in std_logic; + ipb_in : in ipb_wbus; + ipb_out : out ipb_rbus + ); +end entity LocalFastCommand; architecture rtl of LocalFastCommand is + constant PIPE_WIDTH : integer := 8; -constant PIPE_WIDTH : integer := 8; - - --- IPBus registers - -signal fast_cmd_status : ipb_reg_v(3 downto 0); -signal fast_cmd_ctrl : ipb_reg_v(3 downto 0); -signal fast_cmd_ctrl_latched : ipb_reg_v(3 downto 0); - -signal source_mask : std_logic_vector(3 downto 0) := (others => '0'); -signal gen_run : std_logic := '0'; -signal gen_cntr_mode : std_logic := '0'; -signal gen_repeat : integer range 0 to 1023 := 0; - -signal tap_select : integer range 0 to PIPE_WIDTH - 1 := 0; - -type tFastCmdBuffer is array(6 downto 0) of std_logic_vector(15 downto 0); -signal gen_buffer : tFastCmdBuffer := (others => (others => '0')); - - --- Local fast command generator + -- IPBus registers -type tGenState is (start, countdown, stop); -signal gen_state : tGenState := start; + signal fast_cmd_status : ipb_reg_v(3 downto 0); + signal fast_cmd_ctrl : ipb_reg_v(3 downto 0); + signal fast_cmd_ctrl_latched : ipb_reg_v(3 downto 0); -signal gen_instruction : std_logic_vector(1 downto 0) := (others => '0'); -signal gen_counter : integer range 0 to 1023 := 0; -signal gen_rpt_counter : integer range 0 to 1023 := 0; -signal cmd_gen : tFastCommand; + signal source_mask : std_logic_vector(3 downto 0) := (others => '0'); + signal gen_run : std_logic := '0'; + signal gen_cntr_mode : std_logic := '0'; + signal gen_repeat : integer range 0 to 1023 := 0; -signal ctr_reset_counter : integer range 0 to 255 := 0; -signal cal_pulse_counter : integer range 0 to 255 := 0; -signal l1a_trig_counter : integer range 0 to 255 := 0; -signal fast_reset_counter : integer range 0 to 255 := 0; + signal tap_select : integer range 0 to PIPE_WIDTH - 1 := 0; + type tFastCmdBuffer is array(6 downto 0) of std_logic_vector(15 downto 0); --- Output delay & formatting + signal gen_buffer : tFastCmdBuffer := (others => (others => '0')); -signal cmd_local : tFastCommand; -signal cmd_out : tFastCommand; + -- Local fast command generator -type tCmdPipe is array(PIPE_WIDTH - 1 downto 0) of tFastCommand; -signal cmd_pipe : tCmdPipe := (others => (others => '0')); + type tGenState is (start, countdown, stop); -signal cmd_delayed : tFastCommand; -signal cmd_fe : tFastCommand; -signal cmd_cic : tFastCommand; + signal gen_state : tGenState := start; -signal data_out_cache, data_out_cache2 : lword; + signal gen_instruction : std_logic_vector(1 downto 0) := (others => '0'); + signal gen_counter : integer range 0 to 1023 := 0; + signal gen_rpt_counter : integer range 0 to 1023 := 0; + signal cmd_gen : tFastCommand; + signal ctr_reset_counter : integer range 0 to 255 := 0; + signal cal_pulse_counter : integer range 0 to 255 := 0; + signal l1a_trig_counter : integer range 0 to 255 := 0; + signal fast_reset_counter : integer range 0 to 255 := 0; -begin - + -- Output delay & formatting ---==============================-- -fast_cmd: entity work.ipbus_ctrlreg_v ---==============================-- -generic map( - N_CTRL => 4, - N_STAT => 4 -) -port map( - clk => clk, - reset => rst, - ipbus_in => ipb_in, - ipbus_out => ipb_out, - d => fast_cmd_status, - q => fast_cmd_ctrl -); + signal cmd_local : tFastCommand; + signal cmd_out : tFastCommand; + type tCmdPipe is array(PIPE_WIDTH - 1 downto 0) of tFastCommand; ---==============================-- --- Local fast command generator ---==============================-- + signal cmd_pipe : tCmdPipe := (others => (others => '0')); + signal cmd_delayed : tFastCommand; + signal cmd_fe : tFastCommand; + signal cmd_cic : tFastCommand; ---==============================-- -fsm: process(clk40) ---==============================-- - - variable buf_index: integer range 0 to 6 := 0; + signal data_out_cache, data_out_cache2 : lword; begin - if rising_edge(clk40) then - - -- latch IPBus control registers in payload clock domain - source_mask <= fast_cmd_ctrl_latched(0)(3 downto 0); - gen_run <= fast_cmd_ctrl_latched(0)(4); - gen_cntr_mode <= fast_cmd_ctrl_latched(0)(5); - gen_repeat <= to_integer(unsigned(fast_cmd_ctrl_latched(0)(15 downto 6))); - - tap_select <= to_integer(unsigned(fast_cmd_ctrl_latched(0)(18 downto 16))); - - -- 16b fast command generator commands : instruction [2b] + wait counter [10b] + fast command [4b] - -- instructions : 0 = return to first word; 1 = move to next word; 2 = stop at this word; 3 = undefined - -- fast commands: bit3 = fast_reset; bit2 = l1a_trigger; bit1 = cal_pulse; bit0 = counter_reset - gen_buffer(0) <= fast_cmd_ctrl_latched(1)(15 downto 0); - gen_buffer(1) <= fast_cmd_ctrl_latched(1)(31 downto 16); - gen_buffer(2) <= fast_cmd_ctrl_latched(2)(15 downto 0); - gen_buffer(3) <= fast_cmd_ctrl_latched(2)(31 downto 16); - gen_buffer(4) <= fast_cmd_ctrl_latched(3)(15 downto 0); - gen_buffer(5) <= fast_cmd_ctrl_latched(3)(31 downto 16); - gen_buffer(6) <= (others => '0'); --null buffer - - -- only run fast command generator when gen_run enabled - if gen_run = '1' then - - case gen_state is - - -- initial state when gen_run enabled; initialise and send fast command in first word - when start => - buf_index := 0; - - gen_counter <= to_integer(unsigned(gen_buffer(buf_index)(13 downto 4))); - gen_instruction <= gen_buffer(buf_index)(15 downto 14); - - cmd_gen.fast_reset <= gen_buffer(buf_index)(3); - cmd_gen.l1a_trig <= gen_buffer(buf_index)(2); - cmd_gen.cal_pulse <= gen_buffer(buf_index)(1); - cmd_gen.counter_reset <= gen_buffer(buf_index)(0); - - gen_state <= countdown; - - -- wait for N clk cycles as defined in current word; then decide on next action - when countdown => - if gen_counter <= 0 then - if gen_instruction = "01" then - buf_index := buf_index + 1; -- move to next word - elsif gen_instruction = "00" and gen_rpt_counter > 1 then - gen_rpt_counter <= gen_rpt_counter - 1; -- decrement repeat sequence counter - buf_index := 0; -- return to word 0 - elsif gen_instruction = "00" and gen_rpt_counter = 0 then - buf_index := 0; -- return to word 0 and repeat ad infinitum - else - gen_state <= stop; - buf_index := 6; -- instruction indicates stop or is undefined - end if; + --==============================-- + FastCmd : entity work.ipbus_ctrlreg_v + --==============================-- + generic map ( + N_CTRL => 4, + N_STAT => 4 + ) + port map ( + clk => clk, + reset => rst, + ipbus_in => ipb_in, + ipbus_out => ipb_out, + d => fast_cmd_status, + q => fast_cmd_ctrl + ); + + --==============================-- + -- Local fast command generator + --==============================-- + + fsm : process (clk40) is + + variable buf_index : integer range 0 to 6 := 0; + + begin + + if rising_edge(clk40) then + -- latch IPBus control registers in payload clock domain + source_mask <= fast_cmd_ctrl_latched(0)(3 downto 0); + gen_run <= fast_cmd_ctrl_latched(0)(4); + gen_cntr_mode <= fast_cmd_ctrl_latched(0)(5); + gen_repeat <= to_integer(unsigned(fast_cmd_ctrl_latched(0)(15 downto 6))); + + tap_select <= to_integer(unsigned(fast_cmd_ctrl_latched(0)(18 downto 16))); + + -- 16b fast command generator commands : instruction [2b] + wait counter [10b] + fast command [4b] + -- instructions : 0 = return to first word; 1 = move to next word; 2 = stop at this word; 3 = undefined + -- fast commands: bit3 = fast_reset; bit2 = l1a_trigger; bit1 = cal_pulse; bit0 = counter_reset + gen_buffer(0) <= fast_cmd_ctrl_latched(1)(15 downto 0); + gen_buffer(1) <= fast_cmd_ctrl_latched(1)(31 downto 16); + gen_buffer(2) <= fast_cmd_ctrl_latched(2)(15 downto 0); + gen_buffer(3) <= fast_cmd_ctrl_latched(2)(31 downto 16); + gen_buffer(4) <= fast_cmd_ctrl_latched(3)(15 downto 0); + gen_buffer(5) <= fast_cmd_ctrl_latched(3)(31 downto 16); + gen_buffer(6) <= (others => '0'); -- null buffer + + -- only run fast command generator when gen_run enabled + if (gen_run = '1') then + + case gen_state is + + -- initial state when gen_run enabled; initialise and send fast command in first word + when start => + buf_index := 0; - -- set counter, instruction, and fast commands according to next word gen_counter <= to_integer(unsigned(gen_buffer(buf_index)(13 downto 4))); - gen_instruction <= gen_buffer(buf_index)(15 downto 14); + gen_instruction <= gen_buffer(buf_index)(15 downto 14); cmd_gen.fast_reset <= gen_buffer(buf_index)(3); cmd_gen.l1a_trig <= gen_buffer(buf_index)(2); cmd_gen.cal_pulse <= gen_buffer(buf_index)(1); cmd_gen.counter_reset <= gen_buffer(buf_index)(0); - else - gen_counter <= gen_counter - 1; - cmd_gen <= ('0', '0', '0', '0', '0'); - end if; - - -- final state when buffers end, instruction indicates stop, or undefined sequence - -- remain here until gen_run is reset - when others => - cmd_gen <= ('0', '0', '0', '0', '0'); - - end case; - -- update gen fast counters for debugging when gen_run is enabled - if (fast_reset_counter < 255 and cmd_gen.fast_reset = '1') then - fast_reset_counter <= fast_reset_counter + 1; - end if; - - if (l1a_trig_counter < 255 and cmd_gen.l1a_trig = '1') then - l1a_trig_counter <= l1a_trig_counter + 1; - end if; - - if (cal_pulse_counter < 255 and cmd_gen.cal_pulse = '1') then - cal_pulse_counter <= cal_pulse_counter + 1; - end if; + gen_state <= countdown; + + -- wait for N clk cycles as defined in current word; then decide on next action + when countdown => + if (gen_counter <= 0) then + if (gen_instruction = "01") then + buf_index := buf_index + 1; -- move to next word + elsif (gen_instruction = "00" and gen_rpt_counter > 1) then + gen_rpt_counter <= gen_rpt_counter - 1; -- decrement repeat sequence counter + buf_index := 0; -- return to word 0 + elsif (gen_instruction = "00" and gen_rpt_counter = 0) then + buf_index := 0; -- return to word 0 and repeat ad infinitum + else + gen_state <= stop; + buf_index := 6; -- instruction indicates stop or is undefined + end if; + + -- set counter, instruction, and fast commands according to next word + gen_counter <= to_integer(unsigned(gen_buffer(buf_index)(13 downto 4))); + gen_instruction <= gen_buffer(buf_index)(15 downto 14); + + cmd_gen.fast_reset <= gen_buffer(buf_index)(3); + cmd_gen.l1a_trig <= gen_buffer(buf_index)(2); + cmd_gen.cal_pulse <= gen_buffer(buf_index)(1); + cmd_gen.counter_reset <= gen_buffer(buf_index)(0); + else + gen_counter <= gen_counter - 1; + cmd_gen <= ('0', '0', '0', '0', '0'); + end if; - if (ctr_reset_counter < 255 and cmd_gen.counter_reset = '1') then - ctr_reset_counter <= ctr_reset_counter + 1; + -- final state when buffers end, instruction indicates stop, or undefined sequence + -- remain here until gen_run is reset + when others => + cmd_gen <= ('0', '0', '0', '0', '0'); + + end case; + + -- update gen fast counters for debugging when gen_run is enabled + if (fast_reset_counter < 255 and cmd_gen.fast_reset = '1') then + fast_reset_counter <= fast_reset_counter + 1; + end if; + + if (l1a_trig_counter < 255 and cmd_gen.l1a_trig = '1') then + l1a_trig_counter <= l1a_trig_counter + 1; + end if; + + if (cal_pulse_counter < 255 and cmd_gen.cal_pulse = '1') then + cal_pulse_counter <= cal_pulse_counter + 1; + end if; + + if (ctr_reset_counter < 255 and cmd_gen.counter_reset = '1') then + ctr_reset_counter <= ctr_reset_counter + 1; + end if; + else + -- reset fsm and counters when gen_run is disabled + gen_state <= start; + gen_rpt_counter <= gen_repeat; + cmd_gen <= ('0', '0', '0', '0', '0'); + fast_reset_counter <= 0; + l1a_trig_counter <= 0; + cal_pulse_counter <= 0; + ctr_reset_counter <= 0; end if; - - else - - -- reset fsm and counters when gen_run is disabled - gen_state <= start; - gen_rpt_counter <= gen_repeat; - cmd_gen <= ('0', '0', '0', '0', '0'); - fast_reset_counter <= 0; - l1a_trig_counter <= 0; - cal_pulse_counter <= 0; - ctr_reset_counter <= 0; - end if; - end if; - -end process fsm; - --- prepare locally generated fast commands -cmd_local.counter_mode <= gen_cntr_mode; -cmd_local.fast_reset <= cmd_gen.fast_reset; -cmd_local.l1a_trig <= cmd_gen.l1a_trig; -cmd_local.cal_pulse <= cmd_gen.cal_pulse; -cmd_local.counter_reset <= cmd_gen.counter_reset; - --- prepare IPBus status registers -fast_cmd_status(0)(7 downto 0) <= std_logic_vector(to_unsigned(ctr_reset_counter, 8)); -fast_cmd_status(0)(15 downto 8) <= std_logic_vector(to_unsigned(cal_pulse_counter, 8)); -fast_cmd_status(0)(23 downto 16) <= std_logic_vector(to_unsigned(l1a_trig_counter, 8)); -fast_cmd_status(0)(31 downto 24) <= std_logic_vector(to_unsigned(fast_reset_counter, 8)); - - ---==============================-- --- Output : source select, coarse delay & formatting ---==============================-- - - ---==============================-- -cmd_select: process(clk40) ---==============================-- -begin - - if rising_edge(clk40) then - - -- select between global and local fast command sources - cmd_out.counter_mode <= global_fcmd.counter_mode or cmd_local.counter_mode; - cmd_out.fast_reset <= ( global_fcmd.fast_reset and source_mask(3) ) or cmd_local.fast_reset; - cmd_out.l1a_trig <= ( global_fcmd.l1a_trig and source_mask(2) ) or cmd_local.l1a_trig; - cmd_out.cal_pulse <= ( global_fcmd.cal_pulse and source_mask(1) ) or cmd_local.cal_pulse; - cmd_out.counter_reset <= ( global_fcmd.counter_reset and source_mask(0) ) or cmd_local.counter_reset; - - end if; - -end process cmd_select; - + end process fsm; + + -- prepare locally generated fast commands + cmd_local.counter_mode <= gen_cntr_mode; + cmd_local.fast_reset <= cmd_gen.fast_reset; + cmd_local.l1a_trig <= cmd_gen.l1a_trig; + cmd_local.cal_pulse <= cmd_gen.cal_pulse; + cmd_local.counter_reset <= cmd_gen.counter_reset; + + -- prepare IPBus status registers + fast_cmd_status(0)(7 downto 0) <= std_logic_vector(to_unsigned(ctr_reset_counter, 8)); + fast_cmd_status(0)(15 downto 8) <= std_logic_vector(to_unsigned(cal_pulse_counter, 8)); + fast_cmd_status(0)(23 downto 16) <= std_logic_vector(to_unsigned(l1a_trig_counter, 8)); + fast_cmd_status(0)(31 downto 24) <= std_logic_vector(to_unsigned(fast_reset_counter, 8)); + + --==============================-- + -- Output : source select, coarse delay & formatting + --==============================-- + + --==============================-- + pCmdSelect : process (clk40) is + --==============================-- + begin + + if rising_edge(clk40) then + -- select between global and local fast command sources + cmd_out.counter_mode <= global_fcmd.counter_mode or cmd_local.counter_mode; + cmd_out.fast_reset <= (global_fcmd.fast_reset and source_mask(3)) or cmd_local.fast_reset; + cmd_out.l1a_trig <= (global_fcmd.l1a_trig and source_mask(2)) or cmd_local.l1a_trig; + cmd_out.cal_pulse <= (global_fcmd.cal_pulse and source_mask(1)) or cmd_local.cal_pulse; + cmd_out.counter_reset <= (global_fcmd.counter_reset and source_mask(0)) or cmd_local.counter_reset; + end if; ---==============================-- -cmd_delay: process(clk40) ---==============================-- -begin + end process pCmdSelect; - if rising_edge(clk40) then + --==============================-- + pCmdDelay : process (clk40) is + --==============================-- + begin - -- delay commands in 25ns increments using a shift register - cmd_pipe(0) <= cmd_out; - cmd_pipe(PIPE_WIDTH - 1 downto 1) <= cmd_pipe(PIPE_WIDTH - 2 downto 0); + if rising_edge(clk40) then + -- delay commands in 25ns increments using a shift register + cmd_pipe(0) <= cmd_out; + cmd_pipe(PIPE_WIDTH - 1 downto 1) <= cmd_pipe(PIPE_WIDTH - 2 downto 0); - cmd_delayed <= cmd_pipe(tap_select); + cmd_delayed <= cmd_pipe(tap_select); - cmd_fe <= cmd_delayed; - if cmd_delayed.counter_mode = '0' then - cmd_cic <= cmd_delayed; - else - cmd_cic <= ('0', '0', '0', '0', '0'); + cmd_fe <= cmd_delayed; + if (cmd_delayed.counter_mode = '0') then + cmd_cic <= cmd_delayed; + else + cmd_cic <= ('0', '0', '0', '0', '0'); + end if; end if; - end if; -end process cmd_delay; + end process pCmdDelay; + --==============================-- + pToClkp : process (clk_p) is + --==============================-- + begin + if rising_edge(clk_p) then + fast_cmd_ctrl_latched <= fast_cmd_ctrl; ---==============================-- -to_clkp: process(clk_p) ---==============================-- -begin - - if rising_edge(clk_p) then - - fast_cmd_ctrl_latched <= fast_cmd_ctrl; - - -- latch delayed commands into clk_p domain and hold - data_out_cache2.data(15 downto 0) <= fastCommandToSLV(cmd_fe); - data_out_cache2.data(31 downto 16) <= fastCommandToSLV(cmd_cic); - data_out_cache.data <= data_out_cache2.data; - data_out.data <= data_out_cache.data; - - end if; + -- latch delayed commands into clk_p domain and hold + data_out_cache2.data(15 downto 0) <= fastCommandToSLV(cmd_fe); + data_out_cache2.data(31 downto 16) <= fastCommandToSLV(cmd_cic); + data_out_cache.data <= data_out_cache2.data; + data_out.data <= data_out_cache.data; + end if; -end process to_clkp; + end process pToClkp; -data_out_cache.valid <= '1'; -data_out_cache.strobe <= '1'; + data_out_cache.valid <= '1'; + data_out_cache.strobe <= '1'; -end rtl; +end architecture rtl; diff --git a/dtc-fe/firmware/hdl/StubConverter.vhd b/dtc-fe/firmware/hdl/StubConverter.vhd index cc75cc159c0085683d89f59a46e497bbf2b9629f..c404de8694e6b82ccd4b9ce7b40c463e7dad4030 100644 --- a/dtc-fe/firmware/hdl/StubConverter.vhd +++ b/dtc-fe/firmware/hdl/StubConverter.vhd @@ -1,51 +1,48 @@ library ieee; -use ieee.std_logic_1164.all; -use ieee.numeric_std.all; - ---use work.config.all; -use work.emp_data_types.all; - -use work.module_constants.all; -use work.front_end_data_types.all; + use ieee.std_logic_1164.all; + use ieee.numeric_std.all; + -- use work.config.all; + use work.emp_data_types.all; + use work.module_constants.all; + use work.front_end_data_types.all; entity StubConverter is -generic ( - module_type : string; - bandwidth : integer -); -port ( - --- Input Ports --- - clk : in std_logic; - stub_in : in lword := LWORD_NULL; - --- Output Ports --- - stub_out : out lword := LWORD_NULL -); -end StubConverter; - + generic ( + module_type : string; + bandwidth : integer + ); + port ( + --- Input Ports --- + clk : in std_logic; + stub_in : in lword := LWORD_NULL; + --- Output Ports --- + stub_out : out lword := LWORD_NULL + ); +end entity StubConverter; architecture Behavorial of StubConverter is begin - stub_out.valid <= stub_in.valid; - stub_out.strobe <= stub_in.strobe; + stub_out.valid <= stub_in.valid; + stub_out.strobe <= stub_in.strobe; stub_out.data(63 downto 22) <= stub_in.data(63 downto 22); - gen2SCoversion: if module_type = "2S" generate - stub_out.data(3 downto 0) <= (others => '0'); -- Z: no Z field in 2S data format - stub_out.data(7 downto 4) <= stub_in.data(3 downto 0); -- Bend - stub_out.data(15 downto 8) <= stub_in.data(11 downto 4); -- Address + Gen2SCoversion : if module_type = "2S" generate + stub_out.data(3 downto 0) <= (others => '0'); -- Z: no Z field in 2S data format + stub_out.data(7 downto 4) <= stub_in.data(3 downto 0); -- Bend + stub_out.data(15 downto 8) <= stub_in.data(11 downto 4); -- Address stub_out.data(18 downto 16) <= stub_in.data(14 downto 12); -- CBC ID stub_out.data(21 downto 19) <= stub_in.data(17 downto 15); -- Bx offset - end generate gen2SCoversion; + end generate Gen2SCoversion; - genPSCoversion: if module_type = "PS" generate - stub_out.data(3 downto 0) <= stub_in.data(3 downto 0); -- Z - stub_out.data(7 downto 4) <= '0' & stub_in.data(6 downto 4); -- Bend: PS bend field has only 3 bits, therefore a zero is prepended - stub_out.data(15 downto 8) <= stub_in.data(14 downto 7); -- Address - stub_out.data(18 downto 16) <= stub_in.data(17 downto 15); -- CBC ID - stub_out.data(21 downto 19) <= stub_in.data(20 downto 18); -- Bx Offset - end generate genPSCoversion; + GenPSCoversion : if module_type = "PS" generate + stub_out.data(3 downto 0) <= stub_in.data(3 downto 0); -- Z + stub_out.data(7 downto 4) <= '0' & stub_in.data(6 downto 4); -- Bend: PS bend field has only 3 bits, therefore a zero is prepended + stub_out.data(15 downto 8) <= stub_in.data(14 downto 7); -- Address + stub_out.data(18 downto 16) <= stub_in.data(17 downto 15); -- CBC ID + stub_out.data(21 downto 19) <= stub_in.data(20 downto 18); -- Bx Offset + end generate GenPSCoversion; -end architecture; +end architecture Behavorial; diff --git a/dtc-fe/firmware/hdl/StubExtractor.vhd b/dtc-fe/firmware/hdl/StubExtractor.vhd index 31644ad2cea8703d335569114fb9c0d05adf8bee..f26d44937e762c37e43070e068e65f7a654f3ad4 100644 --- a/dtc-fe/firmware/hdl/StubExtractor.vhd +++ b/dtc-fe/firmware/hdl/StubExtractor.vhd @@ -8,37 +8,36 @@ -- possible, meaning that they are not buffered until the end of the boxcar. ---- +library ieee; + use ieee.std_logic_1164.all; + use ieee.numeric_std.all; -library IEEE; -use IEEE.STD_LOGIC_1164.ALL; -use IEEE.NUMERIC_STD.ALL; - -use work.module_constants.all; -use work.front_end_data_types.all; -use work.emp_data_types.all; -use work.dtc_constants.all; -use work.dtc_data_types.all; +library work; + use work.module_constants.all; + use work.front_end_data_types.all; + use work.emp_data_types.all; + use work.dtc_constants.all; + use work.dtc_data_types.all; entity StubExtractor is generic ( - cic_index : integer; + cic_index : integer; module_type : string; - bandwidth : integer + bandwidth : integer ); port ( --- Input Ports --- - clk : in std_logic; - header_start : in std_logic; - data_in : in lword := LWORD_NULL; - aligner_state : in std_logic_vector(3 downto 0) := (others => '0'); + clk : in std_logic; + header_start : in std_logic; + data_in : in lword := LWORD_NULL; + aligner_state : in std_logic_vector(3 downto 0) := (others => '0'); --- Output Ports --- - stub_out : out lword := LWORD_NULL; - header_out : out tCICHeader := ('0', (others => '0'), (others => '0'), (others => '0')) + stub_out : out lword := LWORD_NULL; + header_out : out tCICHeader := ('0', (others => '0'), (others => '0'), (others => '0')) ); -end StubExtractor; - +end entity StubExtractor; -architecture Behavorial of StubExtractor is +architecture behavorial of StubExtractor is -- The frame width, i.e. # elinks constant FRAME_WIDTH : integer := cNumberOfELinks(selectIndexFromModuleType(module_type, bandwidth)); @@ -53,41 +52,44 @@ architecture Behavorial of StubExtractor is -- Specifies the width of the shifted word. constant SHIFT_REG_WIDTH : integer := FRAME_WIDTH + STUB_WIDTH; - signal data_reg : lword := LWORD_NULL; + signal data_reg : lword := LWORD_NULL; - signal frame, frame_shifted : std_logic_vector(SHIFT_REG_WIDTH - 1 downto 0) := (others => '0'); - signal buf_offset : integer range 0 to SHIFT_REG_WIDTH - 1 := SHIFT_REG_WIDTH - FRAME_WIDTH; - signal valid, header_mode : std_logic := '0'; + signal frame, frame_shifted : std_logic_vector(SHIFT_REG_WIDTH - 1 downto 0) := (others => '0'); + signal buf_offset : integer range 0 to SHIFT_REG_WIDTH - 1 := SHIFT_REG_WIDTH - FRAME_WIDTH; + signal valid, header_mode : std_logic := '0'; signal header_start1 : std_logic; - signal header_frame : integer range 0 to cHeaderFrames(selectIndexFromModuleType(module_type, bandwidth)) + 1 := 0; - signal stub_o : lword := LWORD_NULL; - signal cic_header : tCICHeader := ('0', (others => '0'), (others => '0'), (others => '0')); - signal stub_counter : integer := 0; + signal header_frame : integer range 0 to cHeaderFrames(selectIndexFromModuleType(module_type, bandwidth)) + 1 := 0; + signal stub_o : lword := LWORD_NULL; + signal cic_header : tCICHeader := ('0', (others => '0'), (others => '0'), (others => '0')); + signal stub_counter : integer := 0; begin - ff: process(clk) + ff : process (clk) is begin + if rising_edge(clk) then data_reg <= data_in; end if; - end process; + end process ff; + + shift : process (clk) is + + variable buf : std_logic_vector(SHIFT_REG_WIDTH - 1 downto 0) := (others => '0'); - shift: process(clk) - variable buf: std_logic_vector(SHIFT_REG_WIDTH - 1 downto 0) := (others => '0'); begin - if rising_edge(clk) then - if data_reg.strobe = '1' then + if rising_edge(clk) then + if (data_reg.strobe = '1') then header_start1 <= header_start; -- Header Frame Counter - if header_start1 = '1' then + if (header_start1 = '1') then header_frame <= 0; - elsif header_frame = cHeaderFrames(selectIndexFromModuleType(module_type, bandwidth)) then + elsif (header_frame = cHeaderFrames(selectIndexFromModuleType(module_type, bandwidth))) then header_frame <= cHeaderFrames(selectIndexFromModuleType(module_type, bandwidth)); - if aligner_state = "1100" then + if (aligner_state = "1100") then header_out <= cic_header; else header_out <= ('0', (others => '0'), (others => '0'), (others => '0')); @@ -97,42 +99,41 @@ begin end if; -- Register Inputs - frame <= std_logic_vector(to_unsigned(0, STUB_WIDTH)) & data_reg.data(FRAME_WIDTH-1 downto 0); + frame <= std_logic_vector(to_unsigned(0, STUB_WIDTH)) & data_reg.data(FRAME_WIDTH - 1 downto 0); -- Stub Extraction - if header_mode = '1' then + if (header_mode = '1') then -- reset buffer and pointers during header mode frame_shifted <= (others => '0'); - buf_offset <= STUB_WIDTH + FIRST_STUB_OFFSET; - buf := (others => '0'); - valid <= '0'; - stub_counter <= 0; + buf_offset <= STUB_WIDTH + FIRST_STUB_OFFSET; + buf := (others => '0'); + valid <= '0'; + stub_counter <= 0; else -- determine if buffer word is full or not and shift offset accordingly - if buf_offset > FRAME_WIDTH then + if (buf_offset > FRAME_WIDTH) then -- buffer word not yet full buf_offset <= buf_offset - FRAME_WIDTH; - valid <= '0'; + valid <= '0'; else -- full buffer word ready, shift pointer by stub word size, flag as valid buf_offset <= buf_offset + STUB_WIDTH - FRAME_WIDTH; - valid <= '1'; + valid <= '1'; end if; -- shift frame so that it aligns with free space in buffer and merge with existing data frame_shifted <= std_logic_vector(unsigned(frame) sll buf_offset); - buf := buf or frame_shifted; + buf := buf or frame_shifted; end if; - -- Output Data stub_o <= LWORD_NULL; - if valid = '1' then - if stub_counter < to_integer(unsigned(cic_header.stub_count)) then - stub_o.data <= std_logic_vector(to_unsigned(0, 42 - (HEADER_WIDTH + 1))) & std_logic_vector(to_unsigned(cic_index, 1)) & cicHeaderToSLV(cic_header) & std_logic_vector(to_unsigned(0, 22 - STUB_WIDTH)) & buf(SHIFT_REG_WIDTH - 1 downto FRAME_WIDTH); + if (valid = '1') then + if (stub_counter < to_integer(unsigned(cic_header.stub_count))) then + stub_o.data <= std_logic_vector(to_unsigned(0, 42 - (HEADER_WIDTH + 1))) & std_logic_vector(to_unsigned(cic_index, 1)) & cicHeaderToSLV(cic_header) & std_logic_vector(to_unsigned(0, 22 - STUB_WIDTH)) & buf(SHIFT_REG_WIDTH - 1 downto FRAME_WIDTH); stub_o.valid <= '1'; - buf := buf(FRAME_WIDTH - 1 downto 0) & std_logic_vector(to_unsigned(0, STUB_WIDTH)); + buf := buf(FRAME_WIDTH - 1 downto 0) & std_logic_vector(to_unsigned(0, STUB_WIDTH)); stub_counter <= stub_counter + 1; end if; end if; @@ -140,77 +141,83 @@ begin stub_o <= LWORD_NULL; end if; end if; - end process; + end process shift; --==============================-- -- Extract the header information --==============================-- --==============================-- - g2S : if module_type = "2S" generate - --==============================-- + Gen2s : if module_type = "2S" generate signal wide_frame : std_logic_vector(35 downto 0) := (others => '0'); begin wide_frame(SHIFT_REG_WIDTH - 1 downto 0) <= frame; --==============================-- - HeaderExtractor: entity work.HeaderExtractor(module2S) + HeaderExtractor : entity work.HeaderExtractor(module2S) --==============================-- port map ( --- Input Ports --- - clk => clk, + clk => clk, header_frame => header_frame, - frame => wide_frame, + frame => wide_frame, --- Output Ports --- - header_out => cic_header, - header_mode => header_mode + header_out => cic_header, + header_mode => header_mode ); - end generate; - --==============================-- - gPS : if module_type = "PS" generate + + end generate Gen2s; + --==============================-- - g5G : if bandwidth = 5 generate + GenPs : if module_type = "PS" generate + + Gen5g : if bandwidth = 5 generate signal wide_frame : std_logic_vector(35 downto 0) := (others => '0'); begin wide_frame(SHIFT_REG_WIDTH - 1 downto 0) <= frame; --==============================-- - HeaderExtractor: entity work.HeaderExtractor(modulePS5G) + HeaderExtractor : entity work.HeaderExtractor(modulePS5G) --==============================-- port map ( --- Input Ports --- - clk => clk, + clk => clk, header_frame => header_frame, - frame => wide_frame, + frame => wide_frame, --- Output Ports --- - header_out => cic_header, - header_mode => header_mode + header_out => cic_header, + header_mode => header_mode ); - end generate; - g10G : if bandwidth = 10 generate + + end generate Gen5g; + + Gen10g : if bandwidth = 10 generate signal wide_frame : std_logic_vector(35 downto 0) := (others => '0'); begin wide_frame(SHIFT_REG_WIDTH - 1 downto 0) <= frame; --==============================-- - HeaderExtractor: entity work.HeaderExtractor(modulePS10G) + HeaderExtractor : entity work.HeaderExtractor(modulePS10G) --==============================-- port map ( --- Input Ports --- - clk => clk, + clk => clk, header_frame => header_frame, - frame => wide_frame, + frame => wide_frame, --- Output Ports --- - header_out => cic_header, - header_mode => header_mode + header_out => cic_header, + header_mode => header_mode ); - end generate; - end generate; - stub_out <= stub_o when aligner_state = "1100" else LWORD_NULL; + end generate Gen10g; + + end generate GenPs; + + stub_out <= stub_o when aligner_state = "1100" else + LWORD_NULL; -end Behavorial; +end architecture behavorial; diff --git a/dtc-fe/firmware/hdl/StubInterleaver.vhd b/dtc-fe/firmware/hdl/StubInterleaver.vhd index 3de7cf493f9b7562120f3f989bf32c14769582f6..f5b8588dc15cdd85f693463679500aa56536cac5 100644 --- a/dtc-fe/firmware/hdl/StubInterleaver.vhd +++ b/dtc-fe/firmware/hdl/StubInterleaver.vhd @@ -9,68 +9,76 @@ -- concern for the PS 10G module links. ---- +library ieee; + use ieee.std_logic_1164.all; + use ieee.numeric_std.all; -library IEEE; -use IEEE.STD_LOGIC_1164.ALL; -use IEEE.NUMERIC_STD.ALL; - -use work.emp_data_types.all; - +library work; + use work.emp_data_types.all; entity StubInterleaver is port ( --- Input Ports --- - clk : in std_logic; - stub_in_0 : in lword := LWORD_NULL; - stub_in_1 : in lword := LWORD_NULL; + clk : in std_logic; + stub_in_0 : in lword := LWORD_NULL; + stub_in_1 : in lword := LWORD_NULL; --- Output Ports --- - stub_out : out lword := LWORD_NULL + stub_out : out lword := LWORD_NULL ); -end StubInterleaver; +end entity StubInterleaver; architecture Behavioral of StubInterleaver is type tCacheArray is array(0 to 2) of lword; + signal cache : tCacheArray := (others => LWORD_NULL); begin - pMain : process(clk) + + pMain : process (clk) is begin + if rising_edge(clk) then -- Case 1: both stub 0 and stub 1 are valid - if stub_in_0.valid = '1' and stub_in_1.valid = '1' then + if (stub_in_0.valid = '1' and stub_in_1.valid = '1') then -- Output stub 0 stub_out <= stub_in_0; -- Send stub 1 to cache, place in lowest index of array that is empty - if cache(0) = LWORD_NULL then + if (cache(0) = LWORD_NULL) then cache(0) <= stub_in_1; else - if cache(1) = LWORD_NULL then + if (cache(1) = LWORD_NULL) then cache(1) <= stub_in_1; else cache(2) <= stub_in_1; end if; end if; -- Case 2: stub 0 is valid and stub 1 is not - elsif stub_in_0.valid = '1' and stub_in_1.valid = '0' then + elsif (stub_in_0.valid = '1' and stub_in_1.valid = '0') then stub_out <= stub_in_0; -- Case 3: stub 1 is valid and stub 0 is not - elsif stub_in_0.valid = '0' and stub_in_1.valid = '1' then + elsif (stub_in_0.valid = '0' and stub_in_1.valid = '1') then stub_out <= stub_in_1; -- Case 4: neither stub is valid else -- If cache is empty, output a null word - if cache(0) = LWORD_NULL then + if (cache(0) = LWORD_NULL) then stub_out <= LWORD_NULL; -- Else, output first word and shift all others down by one else stub_out <= cache(0); + for i in 1 to 2 loop - cache(i-1) <= cache(i); + + cache(i - 1) <= cache(i); + end loop; + cache(2) <= LWORD_NULL; end if; end if; end if; + end process pMain; -end Behavioral; + +end architecture Behavioral; diff --git a/dtc-fe/firmware/hdl/data_types.vhd b/dtc-fe/firmware/hdl/data_types.vhd index 91f00fca9773cf45130c86cb5478628da219ec76..3fabddbea3a201108b0566024c8cc03243bf8e8c 100644 --- a/dtc-fe/firmware/hdl/data_types.vhd +++ b/dtc-fe/firmware/hdl/data_types.vhd @@ -1,15 +1,13 @@ library ieee; -use ieee.std_logic_1164.all; -use ieee.numeric_std.all; + use ieee.std_logic_1164.all; + use ieee.numeric_std.all; package front_end_data_types is -type tAlignerArray is array(natural range <>) of std_logic_vector(3 downto 0); - + type tAlignerArray is array(natural range <>) of std_logic_vector(3 downto 0); end package front_end_data_types; - package body front_end_data_types is -end front_end_data_types; +end package body front_end_data_types; diff --git a/dtc-fe/firmware/hdl/link_maps_func.vhd b/dtc-fe/firmware/hdl/link_maps_func.vhd index 7d496e3168c71abc4a2841c2bf91bbd27c3b8cd8..fe7dd4288722752a174deed12ced1488234ef7de 100644 --- a/dtc-fe/firmware/hdl/link_maps_func.vhd +++ b/dtc-fe/firmware/hdl/link_maps_func.vhd @@ -1,6 +1,6 @@ -library IEEE; -use IEEE.STD_LOGIC_1164.ALL; -use IEEE.NUMERIC_STD.ALL; +library ieee; + use ieee.std_logic_1164.all; + use ieee.numeric_std.all; package dtc_link_maps_func is @@ -14,4 +14,5 @@ package dtc_link_maps_func is end package dtc_link_maps_func; package body dtc_link_maps_func is -end package body dtc_link_maps_func; \ No newline at end of file + +end package body dtc_link_maps_func; diff --git a/dtc-fe/firmware/hdl/lpgbt-framer/LWordBuffer.vhd b/dtc-fe/firmware/hdl/lpgbt-framer/LWordBuffer.vhd index 1a871b6fc5e718a7bf1a4852358529bc7b765b07..b6c1e5b534c2b278462833a20845d8fd8094c4eb 100644 --- a/dtc-fe/firmware/hdl/lpgbt-framer/LWordBuffer.vhd +++ b/dtc-fe/firmware/hdl/lpgbt-framer/LWordBuffer.vhd @@ -1,41 +1,41 @@ library ieee; -use ieee.std_logic_1164.all; -use ieee.numeric_std.all; - --- -use work.emp_data_types.all; + use ieee.std_logic_1164.all; + use ieee.numeric_std.all; -entity LWordBuffer is +library work; + use work.emp_data_types.all; + +entity LWordBuffer is generic ( delay : integer range 2 to 64 ); port ( --- Input Ports --- - clk : in std_logic; - d : in lword; + clk : in std_logic; + d : in lword; --- Output Ports --- - q : out lword + q : out lword ); end entity LWordBuffer; - architecture rtl of LWordBuffer is constant depth : integer := delay - 2; signal sr : ldata(depth downto 0) := (others => LWORD_NULL); - + begin - process(clk) + pMain : process (clk) is begin + if rising_edge(clk) then - - sr(depth downto 1) <= sr(depth-1 downto 0); + sr(depth downto 1) <= sr(depth - 1 downto 0); sr(0) <= d; - + q <= sr(depth); - end if; - end process; - + + end process pMain; + end architecture rtl; diff --git a/dtc-fe/firmware/hdl/lpgbt-framer/emp_rx_user_data_framer.vhd b/dtc-fe/firmware/hdl/lpgbt-framer/emp_rx_user_data_framer.vhd index 377e70d66d7f63310db6d836bce3c048aa00f64e..5b7bac68e044a59f5467dc664fbf21facf683431 100644 --- a/dtc-fe/firmware/hdl/lpgbt-framer/emp_rx_user_data_framer.vhd +++ b/dtc-fe/firmware/hdl/lpgbt-framer/emp_rx_user_data_framer.vhd @@ -1,158 +1,201 @@ -- IEEE VHDL standard library: -library ieee; -use ieee.std_logic_1164.all; -use ieee.numeric_std.all; -use work.emp_data_types.all; -use work.ipbus.all; -use work.emp_project_decl.all; -use work.emp_data_framer_decl.all; -use work.module_constants.all; -use work.dtc_constants.all; -use work.dtc_link_maps.all; +library ieee; + use ieee.std_logic_1164.all; + use ieee.numeric_std.all; + use work.emp_data_types.all; + use work.ipbus.all; + use work.emp_project_decl.all; + use work.emp_data_framer_decl.all; + use work.module_constants.all; + use work.dtc_constants.all; + use work.dtc_link_maps.all; entity emp_rx_user_data_framer is generic ( - INDEX : integer; - CHANNEL_INDEX : integer range 0 to 3; - N_EC_SPARE : integer range 0 to 16 := 0 + index : integer; + channel_index : integer range 0 to 3; + n_ec_spare : integer range 0 to 16 := 0 ); port ( --- Input Ports --- - clken_i : in std_logic; - clk_p_i : in std_logic; - clk40_i : in std_logic; - uplink_rdy_i : in std_logic; - user_data_i : in std_logic_vector(UPLINK_USERDATA_MAX_LENGTH - 1 downto 0); + clken_i : in std_logic; + clk_p_i : in std_logic; + clk40_i : in std_logic; + uplink_rdy_i : in std_logic; + user_data_i : in std_logic_vector(UPLINK_USERDATA_MAX_LENGTH - 1 downto 0); --- Ouput Ports --- - data_o : out lword; - ec_spare_data_o : out std_logic_vector(N_MAX_EC_SPARE * 2 - 1 downto 0); + data_o : out lword; + ec_spare_data_o : out std_logic_vector(N_MAX_EC_SPARE * 2 - 1 downto 0); --- IPBus Ports --- - clk_i : in std_logic; --- for ipbus (31MHz) - rst_i : in std_logic; --- for ipbus - ipb_in : in ipb_wbus; --- ipbus data in (from PC) - ipb_out : out ipb_rbus --- ipbus data out (to PC) - + clk_i : in std_logic; --- for ipbus (31MHz) + rst_i : in std_logic; --- for ipbus + ipb_in : in ipb_wbus; --- ipbus data in (from PC) + ipb_out : out ipb_rbus --- ipbus data out (to PC) ); -end emp_rx_user_data_framer; +end entity emp_rx_user_data_framer; architecture interface of emp_rx_user_data_framer is - function selectModuleTypeFromChannel(channel : in integer) return string is + function selectModuleTypeFromChannel ( + channel : in integer + ) return string is + variable module_type : string(1 to 2) := "PS"; + begin + for i in 0 to cDTCInputLinkMap'length - 1 loop - if cDTCInputLinkMap(i).index = channel then + + if (cDTCInputLinkMap(i).index = channel) then module_type := cDTCInputLinkMap(i).module_type; end if; + end loop; + return module_type; - end selectModuleTypeFromChannel; - function selectDataRateFromChannel(channel : in integer) return integer is + end function selectModuleTypeFromChannel; + + function selectDataRateFromChannel ( + channel : in integer + ) return integer is + variable bandwidth : integer := 5; + begin + for i in 0 to cDTCInputLinkMap'length - 1 loop - if cDTCInputLinkMap(i).index = channel then + + if (cDTCInputLinkMap(i).index = channel) then bandwidth := cDTCInputLinkMap(i).bandwidth; end if; + end loop; + return bandwidth; - end selectDataRateFromChannel; - constant module_type : string := selectModuleTypeFromChannel(INDEX*4 + CHANNEL_INDEX); - constant bandwidth : integer := selectDataRateFromChannel(INDEX*4 + CHANNEL_INDEX); - constant cModuleELinks : integer := cNumberOfELinks(selectIndexFromModuleType(module_type, bandwidth)); + end function selectDataRateFromChannel; + + constant module_type : string := selectModuleTypeFromChannel(index * 4 + channel_index); + constant bandwidth : integer := selectDataRateFromChannel(index * 4 + channel_index); + constant cModuleELinks : integer := cNumberOfELinks(selectIndexFromModuleType(module_type, bandwidth)); constant cModuleL1ELinks : integer := cNumberOfL1ELinks(selectIndexFromModuleType(module_type, bandwidth)); type tUnboundedLinkArray is array(integer range <>) of std_logic_vector(7 downto 0); - subtype tLinkArray is tUnboundedLinkArray(cModuleELinks - 1 downto 0); + + subtype tLinkArray is tUnboundedLinkArray(cModuleELinks - 1 downto 0); constant NullLinkArray : tLinkArray := (others => (others => '0')); type tUnboundedMultiCICLinkArray is array(integer range <>) of tLinkArray; - subtype tMultiCICLinkArray is tUnboundedMultiCICLinkArray(0 to cNumberOfCICs - 1); + + subtype tMultiCICLinkArray is tUnboundedMultiCICLinkArray(0 to cNumberOfCICs - 1); constant NullMultiCICLinkArray : tMultiCICLinkArray := (others => NullLinkArray); - signal data_s : lword := LWORD_NULL; - + signal data_s : lword := LWORD_NULL; + type tUnboundedL1ALinkArray is array(integer range <>) of std_logic_vector(7 downto 0); + subtype tL1ALinkArray is tUnboundedL1ALinkArray(cModuleL1ELinks - 1 downto 0); + type tUnboundedMultiCICL1ALinkArray is array(integer range <>) of tL1ALinkArray; + subtype tMultiCICL1ALinkArray is tUnboundedMultiCICL1ALinkArray(0 to cNumberOfCICs - 1); - signal l1a_data : tMultiCICL1ALinkArray := (others => (others => (others => '0'))); + signal l1a_data : tMultiCICL1ALinkArray := (others => (others => (others => '0'))); - signal stub_links : tMultiCICLinkArray := NullMultiCICLinkArray; + signal stub_links : tMultiCICLinkArray := NullMultiCICLinkArray; begin + pMain : process (clk_p_i) is + + variable time_index : unsigned(2 downto 0) := (others => '0'); - pMain : process(clk_p_i) - variable time_index : unsigned(2 downto 0) := (others=>'0'); begin - if rising_edge(clk_p_i) then + if rising_edge(clk_p_i) then if (clken_i = '1') then - time_index := (others=>'0'); + time_index := (others => '0'); else - time_index := time_index - 1; + time_index := time_index - 1; end if; if (time_index = 0) then for i in 0 to cNumberOfCICs - 1 loop - for j in 0 to cModuleELinks - 1 loop - for k in 7 downto 0 loop - if cWordWidth(selectIndexFromModuleType(module_type, bandwidth)) = 8 then - stub_links(i)(j)(k) <= user_data_i(link_indices(selectIndexFromModuleType(module_type, bandwidth))(i)(j) + k); - else - if j < 6 then - stub_links(i)(j)(k) <= user_data_i(link_indices(selectIndexFromModuleType(module_type, bandwidth))(i)(j) + 2*k + 1); - else - stub_links(i)(j)(k) <= user_data_i(link_indices(selectIndexFromModuleType(module_type, bandwidth))(i)(j) + 2*k); - end if; - end if; + + for j in 0 to cModuleELinks - 1 loop + + for k in 7 downto 0 loop + + if (cWordWidth(selectIndexFromModuleType(module_type, bandwidth)) = 8) then + stub_links(i)(j)(k) <= user_data_i(link_indices(selectIndexFromModuleType(module_type, bandwidth))(i)(j) + k); + else + if (j < 6) then + stub_links(i)(j)(k) <= user_data_i(link_indices(selectIndexFromModuleType(module_type, bandwidth))(i)(j) + 2 * k + 1); + else + stub_links(i)(j)(k) <= user_data_i(link_indices(selectIndexFromModuleType(module_type, bandwidth))(i)(j) + 2 * k); + end if; + end if; + + end loop; + end loop; - end loop; - for j in 0 to cModuleL1ELinks - 1 loop - --l1a_data(i)(j)(7 downto 0) <= user_data_i(l1a_indices(selectIndexFromModuleType(module_type, bandwidth))(i)(j) + 7 downto l1a_indices(selectIndexFromModuleType(module_type, bandwidth))(i)(j)); - for k in 7 downto 0 loop - if cWordWidth(selectIndexFromModuleType(module_type, bandwidth)) = 8 then - l1a_data(i)(j)(k) <= user_data_i(l1a_indices(selectIndexFromModuleType(module_type, bandwidth))(i)(j) + k); - else - l1a_data(i)(j)(k) <= user_data_i(l1a_indices(selectIndexFromModuleType(module_type, bandwidth))(i)(j) + 2*k + 1 - j); - end if; + + for j in 0 to cModuleL1ELinks - 1 loop + + -- l1a_data(i)(j)(7 downto 0) <= user_data_i(l1a_indices(selectIndexFromModuleType(module_type, bandwidth))(i)(j) + 7 downto l1a_indices(selectIndexFromModuleType(module_type, bandwidth))(i)(j)); + for k in 7 downto 0 loop + + if (cWordWidth(selectIndexFromModuleType(module_type, bandwidth)) = 8) then + l1a_data(i)(j)(k) <= user_data_i(l1a_indices(selectIndexFromModuleType(module_type, bandwidth))(i)(j) + k); + else + l1a_data(i)(j)(k) <= user_data_i(l1a_indices(selectIndexFromModuleType(module_type, bandwidth))(i)(j) + 2 * k + 1 - j); + end if; + + end loop; + end loop; - end loop; + end loop; end if; - data_s <= LWORD_NULL; - data_s.valid <= '1'; - data_s.strobe <= '1'; - data_s.start <= '1'; + data_s <= LWORD_NULL; + data_s.valid <= '1'; + data_s.strobe <= '1'; + data_s.start <= '1'; data_s.data(62) <= uplink_rdy_i; if (uplink_rdy_i = '1') then -- Iterate over 2D arrays, sending a slice per clock cycle for i in 0 to cNumberOfCICs - 1 loop - data_s.data(32*i + 31) <= '1'; + + data_s.data(32 * i + 31) <= '1'; + for j in 0 to cModuleELinks - 1 loop - data_s.data(32*i + cModuleELinks - 1 - j) <= stub_links(i)(j)(to_integer(time_index)); + + data_s.data(32 * i + cModuleELinks - 1 - j) <= stub_links(i)(j)(to_integer(time_index)); + end loop; + for j in 0 to cModuleL1ELinks - 1 loop + --- Stream L1A link --- - data_s.data(32*i + cModuleELinks + cModuleL1ELinks - 1 - j) <= l1a_data(i)(j)(to_integer(time_index)); + data_s.data(32 * i + cModuleELinks + cModuleL1ELinks - 1 - j) <= l1a_data(i)(j)(to_integer(time_index)); + end loop; + end loop; - end if; + end if; end if; + end process pMain; - ec_spare_data_o(N_EC_SPARE * 2 - 1 downto 0) <= user_data_i(N_EC_SPARE * 2 - 1 downto 0); - data_o <= data_s; + ec_spare_data_o(N_EC_SPARE * 2 - 1 downto 0) <= user_data_i(n_ec_spare * 2 - 1 downto 0); + data_o <= data_s; -end interface; +end architecture interface; diff --git a/dtc-fe/firmware/hdl/module_constants.vhd b/dtc-fe/firmware/hdl/module_constants.vhd index 55d76c17acc9a96e4fc7d27246c8cecd0a222523..94ae30ca306c47728ba5fcba0d1141d946942059 100644 --- a/dtc-fe/firmware/hdl/module_constants.vhd +++ b/dtc-fe/firmware/hdl/module_constants.vhd @@ -1,27 +1,36 @@ -library IEEE; -use IEEE.STD_LOGIC_1164.ALL; -use IEEE.NUMERIC_STD.ALL; +library ieee; + use ieee.std_logic_1164.all; + use ieee.numeric_std.all; package module_constants is type tModuleConstantIntegerArray is array (0 to 2) of integer; + type tModuleConstantBooleanArray is array (0 to 2) of boolean; + type tModuleConstantVectorArray is array (0 to 2) of std_logic_vector(6 downto 0); type tUnboundedIntegerArray is array(integer range <>) of integer; + subtype tLinkIndicesArray is tUnboundedIntegerArray(0 to 12 - 1); + subtype tL1AIndicesArray is tUnboundedIntegerArray(0 to 2 - 1); + type tUnbounded2DIntegerArray is array(integer range <>) of tLinkIndicesArray; + subtype tMultiCICLinkIndicesArray is tUnbounded2DIntegerArray(0 to 2 - 1); + type tModuleConstantLinkIndicesArray is array (0 to 2) of tMultiCICLinkIndicesArray; + type tUnboundedL1A2DIntegerArray is array(integer range <>) of tL1AIndicesArray; + subtype tMultiCICL1AIndicesArray is tUnboundedL1A2DIntegerArray(0 to 2 - 1); - type tModuleConstantL1AIndicesArray is array (0 to 2) of tMultiCICL1AIndicesArray; + type tModuleConstantL1AIndicesArray is array (0 to 2) of tMultiCICL1AIndicesArray; - constant cGBTFrameWidth : integer := 112; - constant cNumberOfELinks : tModuleConstantIntegerArray := (5, 6, 12); - constant cNumberOfL1ELinks : tModuleConstantIntegerArray := (1, 1, 2); + constant cGBTFrameWidth : integer := 112; + constant cNumberOfELinks : tModuleConstantIntegerArray := (5, 6, 12); + constant cNumberOfL1ELinks : tModuleConstantIntegerArray := (1, 1, 2); constant cWordWidth : tModuleConstantIntegerArray := (8, 8, 16); constant cStubWidth : tModuleConstantIntegerArray := (18, 21, 21); @@ -30,23 +39,18 @@ package module_constants is constant cBoxCarFrames : integer := 64; constant cHeaderFrames : tModuleConstantIntegerArray := (6, 5, 3); constant cFirstStubOffset : tModuleConstantIntegerArray := (3, 4, 4); - constant cDataPeriod : tModuleConstantIntegerArray := (8, 8, 8); - constant cModuleBendWidth : tModuleConstantIntegerArray := (4, 3, 3); constant cModuleRowWidth : tModuleConstantIntegerArray := (11, 11, 11); constant cModuleStubBxWidth : tModuleConstantIntegerArray := (3, 3, 3); constant cHeaderMultiplicityWidth : tModuleConstantIntegerArray := (6, 6, 6); constant cHeaderBxWidth : tModuleConstantIntegerArray := (12, 12, 12); - constant cAlignmentDepth : integer := 8; -- Can be reduced if no realignment is necessary, reducing both latency and resource usage for the FrameAligner - constant cL1StartSequenceThresh : integer := 20; constant cL1HeaderWidth : tModuleConstantIntegerArray := (18, 33, 33); constant cL1PClusterWidth : integer := 17; constant cL1SClusterWidth : integer := 14; constant cL1ClusterWidth : integer := 14; - constant cL1StatusWidth : integer := 9; constant cL1StatusLow : tModuleConstantIntegerArray := (9, 24, 24); constant cL1IdWidth : integer := 9; @@ -57,40 +61,47 @@ package module_constants is constant cL1NScluster_low : integer := 8; constant cL1NClusterWidth : integer := 7; constant cL1NClusterLow : integer := 1; - - constant cSparsifiedMode : boolean := false; constant cL1UnsparsifiedLength : integer := 2200; - constant cHeaderSRDelay : tModuleConstantVectorArray := ("1000000", "0100000", "0001000"); -- CHECK THIS - constant cHeaderSignalDelay : tModuleConstantIntegerArray := (55, 56, 58); -- CHECK THIS + constant cHeaderSRDelay : tModuleConstantVectorArray := ("1000000", "0100000", "0001000"); -- CHECK THIS + constant cHeaderSignalDelay : tModuleConstantIntegerArray := (55, 56, 58); -- CHECK THIS - constant link_indices : tModuleConstantLinkIndicesArray := ( + constant link_indices : tModuleConstantLinkIndicesArray := ( (( 64, 72, 80, 88, 96, -1, -1, -1, -1, -1, -1, -1), ( 8, 16, 24, 32, 40, -1, -1, -1, -1, -1, -1, -1)), (( 0, 104, 96, 88, 80, 64, -1, -1, -1, -1, -1, -1), (56, 48, 40, 32, 24, 8, -1, -1, -1, -1, -1, -1)), (( 0, 208, 192, 176, 160, 128, 0, 208, 192, 176, 160, 128), (112, 96, 80, 64, 48, 16, 112, 96, 80, 64, 48, 16)) ); - constant l1a_indices : tModuleConstantL1AIndicesArray := ( + constant l1a_indices : tModuleConstantL1AIndicesArray := ( ((0, -1), (56, -1)), ((72, -1), (16, -1)), - ((144, 144),(32, 32)) + ((144, 144), (32, 32)) ); - function selectIndexFromModuleType(module_type : in string; bandwidth : in integer) return integer; + function selectIndexFromModuleType ( + module_type : in string; + bandwidth : in integer + ) return integer; end package module_constants; package body module_constants is - function selectIndexFromModuleType(module_type : in string; bandwidth : in integer) return integer is + function selectIndexFromModuleType ( + module_type : in string; + bandwidth : in integer + ) return integer is + variable index : integer; + begin - if module_type = "2S" then + + if (module_type = "2S") then index := 0; - elsif module_type = "PS" then - if bandwidth = 5 then + elsif (module_type = "PS") then + if (bandwidth = 5) then index := 1; - elsif bandwidth = 10 then + elsif (bandwidth = 10) then index := 2; else index := -1; @@ -98,7 +109,9 @@ package body module_constants is else index := -1; end if; + return index; - end selectIndexFromModuleType; + + end function selectIndexFromModuleType; end package body module_constants; diff --git a/run_vsg.sh b/run_vsg.sh new file mode 100644 index 0000000000000000000000000000000000000000..bcdaa3132b89bb016f39ab716bcbafb40ed92b4f --- /dev/null +++ b/run_vsg.sh @@ -0,0 +1,9 @@ +for file in $(find . -not -path "./replacements/*" -not -path "./ci/*" \( -iname "*.vhd" ! -iname "*ipbus*" ! -iname "*emp*" \)); do + FILENAME=$(basename ${file%.*}) + echo $FILENAME + vsg -c style-rules.yml -f $file --junit reports/$FILENAME.xml || flag=1 +done + +python3 -m junitparser merge reports/* report.xml + +exit $flag \ No newline at end of file diff --git a/style-rules.yml b/style-rules.yml new file mode 100644 index 0000000000000000000000000000000000000000..b8a07b593fa88c38bf97ae54a054b305518e13a9 --- /dev/null +++ b/style-rules.yml @@ -0,0 +1,132 @@ +rule : + global: + indent_style: 'spaces' + indent_size: 4 + # allow vertical alignment within port map + comment_line_ends_group : False + + # Length + length_001: + disable: true + + # Comments + # comment_010: + # disable: true + + # Entity + entity_008: + case: "PascalCase" + + entity_012: + case: "PascalCase" + + # Architecture + architecture_011: + disable: true + + architecture_013: + disable: true + + architecture_014: + case: "PascalCase" + + # Case + case_200: + disable: true + + # Instantion + instantiation_008: + case: "PascalCase" + + instantiation_028: + disable: true + + instantiation_034: + method: 'entity' + + # Process + process_017: + case: "camelCase" + + process_019: + case: "camelCase" + + # Function + function_017: + case: "camelCase" + + function_506: + case: "camelCase" + + # Constant + constant_004: + disable: true + # case: "camelCase" + + constant_012: + align_left: "yes" + + # constant_015: + # disable: false + # prefixes: ["c"] + + constant_016: + first_paren_new_line: 'ignore' + last_paren_new_line: 'ignore' + open_paren_new_line: 'ignore' + close_paren_new_line: 'ignore' + new_line_after_comma: 'ignore' + + # Type + type_004: + case: "camelCase" + + type_015: + disable: false + prefixes: ["t"] + + # Subtype + subtype_501: + case: "camelCase" + + # Generate + generate_004: + # allow comments directly above generate statement + style : allow_comment + + generate_005: + case: "PascalCase" + + generate_012: + case: "PascalCase" + + generate_017: + disable: false + prefixes: ["Gen"] + + generic_map_002: + case: "upper" + + # Port + port_012 : + # allow default signal assignments in port map (remove) + disable : True + + # Signal + signal_007 : + # allow default signal assignments + disable : True + + # Variable + variable_007: + disable: True + +indent : + tokens : + component_instantiation_statement : + instantiation_label : + token : current + after : current + semicolon : + token : current + after : current diff --git a/top/dtc-full/2S-5G/firmware/hdl/vu13p_s1/link_maps.vhd b/top/dtc-full/2S-5G/firmware/hdl/vu13p_s1/link_maps.vhd index b8547f95e333851f43cc8847d9f75db5138a862f..3e7db86241660ec1ddff973ce75690b1a77f01c4 100644 --- a/top/dtc-full/2S-5G/firmware/hdl/vu13p_s1/link_maps.vhd +++ b/top/dtc-full/2S-5G/firmware/hdl/vu13p_s1/link_maps.vhd @@ -1,13 +1,17 @@ -library IEEE; -use IEEE.STD_LOGIC_1164.ALL; -use IEEE.NUMERIC_STD.ALL; -use work.dtc_link_maps_func.all; +library ieee; + use ieee.std_logic_1164.all; + use ieee.numeric_std.all; + +library work; + use work.dtc_link_maps_func.all; package dtc_link_maps is + constant cNumberOfFEModules : integer := 72; constant cNumberOfOutputLinks : integer := 36; type tDTCInputLinkMap is array(0 to cNumberOfFEModules - 1) of tDTCInputLinkConfig; + constant cDTCInputLinkMap : tDTCInputLinkMap := ( 0 => ( 4, "2S", 5, "CIC2"), 1 => ( 5, "2S", 5, "CIC2"), @@ -84,11 +88,12 @@ package dtc_link_maps is ); type tDTCOutputLinkMap is array(0 to cNumberOfOutputLinks - 1) of integer; + constant cDTCOutputLinkMap : tDTCOutputLinkMap := ( -46, 47, 48, 49, 50, 51, 52, 53, 54, -55, 56, 57, 58, 59, 60, 61, 62, 63, -64, 65, 66, 67, 68, 69, 70, 71, 72, -73, 74, 75, 76, 77, 78, 79, 80, 81 + 46, 47, 48, 49, 50, 51, 52, 53, 54, + 55, 56, 57, 58, 59, 60, 61, 62, 63, + 64, 65, 66, 67, 68, 69, 70, 71, 72, + 73, 74, 75, 76, 77, 78, 79, 80, 81 ); end package dtc_link_maps; diff --git a/top/dtc-full/PS-10G/firmware/hdl/vu13p_s1/link_maps.vhd b/top/dtc-full/PS-10G/firmware/hdl/vu13p_s1/link_maps.vhd index aaf1288eecddf2e5bb0ddd471ac4531df1dd83b3..19bab41e1329fb3be217a13f18845ea7e4674d7f 100644 --- a/top/dtc-full/PS-10G/firmware/hdl/vu13p_s1/link_maps.vhd +++ b/top/dtc-full/PS-10G/firmware/hdl/vu13p_s1/link_maps.vhd @@ -1,13 +1,17 @@ -library IEEE; -use IEEE.STD_LOGIC_1164.ALL; -use IEEE.NUMERIC_STD.ALL; -use work.dtc_link_maps_func.all; +library ieee; + use ieee.std_logic_1164.all; + use ieee.numeric_std.all; + +library work; + use work.dtc_link_maps_func.all; package dtc_link_maps is + constant cNumberOfFEModules : integer := 72; constant cNumberOfOutputLinks : integer := 36; type tDTCInputLinkMap is array(0 to cNumberOfFEModules - 1) of tDTCInputLinkConfig; + constant cDTCInputLinkMap : tDTCInputLinkMap := ( 0 => ( 4, "PS", 10, "CIC2"), 1 => ( 5, "PS", 10, "CIC2"), @@ -84,11 +88,12 @@ package dtc_link_maps is ); type tDTCOutputLinkMap is array(0 to cNumberOfOutputLinks - 1) of integer; + constant cDTCOutputLinkMap : tDTCOutputLinkMap := ( -46, 47, 48, 49, 50, 51, 52, 53, 54, -55, 56, 57, 58, 59, 60, 61, 62, 63, -64, 65, 66, 67, 68, 69, 70, 71, 72, -73, 74, 75, 76, 77, 78, 79, 80, 81 + 46, 47, 48, 49, 50, 51, 52, 53, 54, + 55, 56, 57, 58, 59, 60, 61, 62, 63, + 64, 65, 66, 67, 68, 69, 70, 71, 72, + 73, 74, 75, 76, 77, 78, 79, 80, 81 ); end package dtc_link_maps; diff --git a/top/dtc-full/PS-5G/firmware/hdl/vu13p_s1/link_maps.vhd b/top/dtc-full/PS-5G/firmware/hdl/vu13p_s1/link_maps.vhd index de8c97e3334a4c52bed2d99472452a3140f6e847..898caa32cf135a60b545f0e1a8fc53ab9a2f50b2 100644 --- a/top/dtc-full/PS-5G/firmware/hdl/vu13p_s1/link_maps.vhd +++ b/top/dtc-full/PS-5G/firmware/hdl/vu13p_s1/link_maps.vhd @@ -1,13 +1,17 @@ -library IEEE; -use IEEE.STD_LOGIC_1164.ALL; -use IEEE.NUMERIC_STD.ALL; -use work.dtc_link_maps_func.all; +library ieee; + use ieee.std_logic_1164.all; + use ieee.numeric_std.all; + +library work; + use work.dtc_link_maps_func.all; package dtc_link_maps is + constant cNumberOfFEModules : integer := 72; constant cNumberOfOutputLinks : integer := 36; type tDTCInputLinkMap is array(0 to cNumberOfFEModules - 1) of tDTCInputLinkConfig; + constant cDTCInputLinkMap : tDTCInputLinkMap := ( 0 => ( 4, "PS", 5, "CIC2"), 1 => ( 5, "PS", 5, "CIC2"), @@ -84,11 +88,12 @@ package dtc_link_maps is ); type tDTCOutputLinkMap is array(0 to cNumberOfOutputLinks - 1) of integer; + constant cDTCOutputLinkMap : tDTCOutputLinkMap := ( -46, 47, 48, 49, 50, 51, 52, 53, 54, -55, 56, 57, 58, 59, 60, 61, 62, 63, -64, 65, 66, 67, 68, 69, 70, 71, 72, -73, 74, 75, 76, 77, 78, 79, 80, 81 + 46, 47, 48, 49, 50, 51, 52, 53, 54, + 55, 56, 57, 58, 59, 60, 61, 62, 63, + 64, 65, 66, 67, 68, 69, 70, 71, 72, + 73, 74, 75, 76, 77, 78, 79, 80, 81 ); end package dtc_link_maps; diff --git a/top/dtc-mini/2S-5G/firmware/hdl/ku15p_sm1_v1/link_maps.vhd b/top/dtc-mini/2S-5G/firmware/hdl/ku15p_sm1_v1/link_maps.vhd index 51c3942573f76cea739e00ed9c2aba690a2ed0a1..00f4ba5388a17e132cddd94f3cc4281f7dbc47c2 100644 --- a/top/dtc-mini/2S-5G/firmware/hdl/ku15p_sm1_v1/link_maps.vhd +++ b/top/dtc-mini/2S-5G/firmware/hdl/ku15p_sm1_v1/link_maps.vhd @@ -1,7 +1,9 @@ -library IEEE; -use IEEE.STD_LOGIC_1164.ALL; -use IEEE.NUMERIC_STD.ALL; -use work.dtc_link_maps_func.all; +library ieee; + use ieee.std_logic_1164.all; + use ieee.numeric_std.all; + +library work; + use work.dtc_link_maps_func.all; package dtc_link_maps is @@ -9,7 +11,8 @@ package dtc_link_maps is constant cNumberOfOutputLinks : integer := 4; type tDTCInputLinkMap is array(0 to cNumberOfFEModules - 1) of tDTCInputLinkConfig; - constant cDTCInputLinkMap : tDTCInputLinkMap := ( + + constant cDTCInputLinkMap : tDTCInputLinkMap := ( 0 => (8, "2S", 5, "CIC2"), 1 => (9, "2S", 5, "CIC2"), 2 => (10, "2S", 5, "CIC2"), @@ -17,7 +20,8 @@ package dtc_link_maps is ); type tDTCOutputLinkMap is array(0 to cNumberOfOutputLinks - 1) of integer; - constant cDTCOutputLinkMap : tDTCOutputLinkMap := ( + + constant cDTCOutputLinkMap : tDTCOutputLinkMap := ( 16, 17, 18, 19 ); diff --git a/top/dtc-mini/2S-5G/firmware/hdl/vu13p_so2_v1/link_maps.vhd b/top/dtc-mini/2S-5G/firmware/hdl/vu13p_so2_v1/link_maps.vhd index 643501ccea9bf1da5738b51ffb55c814459504ec..72f25cdca936c2f110413dd4f9b700bb9da36761 100644 --- a/top/dtc-mini/2S-5G/firmware/hdl/vu13p_so2_v1/link_maps.vhd +++ b/top/dtc-mini/2S-5G/firmware/hdl/vu13p_so2_v1/link_maps.vhd @@ -1,7 +1,9 @@ -library IEEE; -use IEEE.STD_LOGIC_1164.ALL; -use IEEE.NUMERIC_STD.ALL; -use work.dtc_link_maps_func.all; +library ieee; + use ieee.std_logic_1164.all; + use ieee.numeric_std.all; + +library work; + use work.dtc_link_maps_func.all; package dtc_link_maps is @@ -9,7 +11,8 @@ package dtc_link_maps is constant cNumberOfOutputLinks : integer := 4; type tDTCInputLinkMap is array(0 to cNumberOfFEModules - 1) of tDTCInputLinkConfig; - constant cDTCInputLinkMap : tDTCInputLinkMap := ( + + constant cDTCInputLinkMap : tDTCInputLinkMap := ( 0 => (32, "2S", 5, "CIC2"), 1 => (33, "2S", 5, "CIC2"), 2 => (34, "2S", 5, "CIC2"), @@ -25,7 +28,8 @@ package dtc_link_maps is ); type tDTCOutputLinkMap is array(0 to cNumberOfOutputLinks - 1) of integer; - constant cDTCOutputLinkMap : tDTCOutputLinkMap := ( + + constant cDTCOutputLinkMap : tDTCOutputLinkMap := ( 12, 13, 14, 15 ); diff --git a/top/dtc-mini/PS-10G/firmware/hdl/ku15p_sm1_v1/link_maps.vhd b/top/dtc-mini/PS-10G/firmware/hdl/ku15p_sm1_v1/link_maps.vhd index 6f03b857e390fbeae8b8e56eaf75cb1de88582f3..b7c01338043fca02d492f4a3a626c8bca1c47541 100644 --- a/top/dtc-mini/PS-10G/firmware/hdl/ku15p_sm1_v1/link_maps.vhd +++ b/top/dtc-mini/PS-10G/firmware/hdl/ku15p_sm1_v1/link_maps.vhd @@ -1,7 +1,9 @@ -library IEEE; -use IEEE.STD_LOGIC_1164.ALL; -use IEEE.NUMERIC_STD.ALL; -use work.dtc_link_maps_func.all; +library ieee; + use ieee.std_logic_1164.all; + use ieee.numeric_std.all; + +library work; + use work.dtc_link_maps_func.all; package dtc_link_maps is @@ -9,7 +11,8 @@ package dtc_link_maps is constant cNumberOfOutputLinks : integer := 4; type tDTCInputLinkMap is array(0 to cNumberOfFEModules - 1) of tDTCInputLinkConfig; - constant cDTCInputLinkMap : tDTCInputLinkMap := ( + + constant cDTCInputLinkMap : tDTCInputLinkMap := ( 0 => (8, "PS", 5, "CIC2"), 1 => (9, "PS", 5, "CIC2"), 2 => (10, "PS", 5, "CIC2"), @@ -17,7 +20,8 @@ package dtc_link_maps is ); type tDTCOutputLinkMap is array(0 to cNumberOfOutputLinks - 1) of integer; - constant cDTCOutputLinkMap : tDTCOutputLinkMap := ( + + constant cDTCOutputLinkMap : tDTCOutputLinkMap := ( 16, 17, 18, 19 ); diff --git a/top/dtc-mini/PS-10G/firmware/hdl/vu13p_so2_v1/link_maps.vhd b/top/dtc-mini/PS-10G/firmware/hdl/vu13p_so2_v1/link_maps.vhd index ec13116f3b039b102d66186337406c8382d2e950..62743b0ddd5c903ffbc717bc2ebb8e8bc73e5a44 100644 --- a/top/dtc-mini/PS-10G/firmware/hdl/vu13p_so2_v1/link_maps.vhd +++ b/top/dtc-mini/PS-10G/firmware/hdl/vu13p_so2_v1/link_maps.vhd @@ -1,7 +1,9 @@ -library IEEE; -use IEEE.STD_LOGIC_1164.ALL; -use IEEE.NUMERIC_STD.ALL; -use work.dtc_link_maps_func.all; +library ieee; + use ieee.std_logic_1164.all; + use ieee.numeric_std.all; + +library work; + use work.dtc_link_maps_func.all; package dtc_link_maps is @@ -9,7 +11,8 @@ package dtc_link_maps is constant cNumberOfOutputLinks : integer := 4; type tDTCInputLinkMap is array(0 to cNumberOfFEModules - 1) of tDTCInputLinkConfig; - constant cDTCInputLinkMap : tDTCInputLinkMap := ( + + constant cDTCInputLinkMap : tDTCInputLinkMap := ( 0 => (32, "PS", 10, "CIC2"), 1 => (33, "PS", 10, "CIC2"), 2 => (34, "PS", 10, "CIC2"), @@ -17,7 +20,8 @@ package dtc_link_maps is ); type tDTCOutputLinkMap is array(0 to cNumberOfOutputLinks - 1) of integer; - constant cDTCOutputLinkMap : tDTCOutputLinkMap := ( + + constant cDTCOutputLinkMap : tDTCOutputLinkMap := ( 12, 13, 14, 15 ); diff --git a/top/dtc-mini/PS-5G/firmware/hdl/ku15p_sm1_v1/link_maps.vhd b/top/dtc-mini/PS-5G/firmware/hdl/ku15p_sm1_v1/link_maps.vhd index 6f03b857e390fbeae8b8e56eaf75cb1de88582f3..b7c01338043fca02d492f4a3a626c8bca1c47541 100644 --- a/top/dtc-mini/PS-5G/firmware/hdl/ku15p_sm1_v1/link_maps.vhd +++ b/top/dtc-mini/PS-5G/firmware/hdl/ku15p_sm1_v1/link_maps.vhd @@ -1,7 +1,9 @@ -library IEEE; -use IEEE.STD_LOGIC_1164.ALL; -use IEEE.NUMERIC_STD.ALL; -use work.dtc_link_maps_func.all; +library ieee; + use ieee.std_logic_1164.all; + use ieee.numeric_std.all; + +library work; + use work.dtc_link_maps_func.all; package dtc_link_maps is @@ -9,7 +11,8 @@ package dtc_link_maps is constant cNumberOfOutputLinks : integer := 4; type tDTCInputLinkMap is array(0 to cNumberOfFEModules - 1) of tDTCInputLinkConfig; - constant cDTCInputLinkMap : tDTCInputLinkMap := ( + + constant cDTCInputLinkMap : tDTCInputLinkMap := ( 0 => (8, "PS", 5, "CIC2"), 1 => (9, "PS", 5, "CIC2"), 2 => (10, "PS", 5, "CIC2"), @@ -17,7 +20,8 @@ package dtc_link_maps is ); type tDTCOutputLinkMap is array(0 to cNumberOfOutputLinks - 1) of integer; - constant cDTCOutputLinkMap : tDTCOutputLinkMap := ( + + constant cDTCOutputLinkMap : tDTCOutputLinkMap := ( 16, 17, 18, 19 ); diff --git a/top/dtc-mini/PS-5G/firmware/hdl/ku15p_sm1_v1/tb_decl.vhd b/top/dtc-mini/PS-5G/firmware/hdl/ku15p_sm1_v1/tb_decl.vhd index fb3958dc130129452027bcf59e6d3d188437948d..1f50ba6954f4b6ddf298d8bd2c3da79f074030b1 100644 --- a/top/dtc-mini/PS-5G/firmware/hdl/ku15p_sm1_v1/tb_decl.vhd +++ b/top/dtc-mini/PS-5G/firmware/hdl/ku15p_sm1_v1/tb_decl.vhd @@ -1,23 +1,22 @@ library ieee; -use ieee.std_logic_1164.all; + use ieee.std_logic_1164.all; -use work.emp_project_decl.all; +library work; + use work.emp_project_decl.all; package tb_decl is + constant SOURCE_FILE : string := "/home/csk/Documents/Projects/working_dir/src/dtc/top/dtc-mini/PS-5G/firmware/hdl/CIC2_EMP.txt"; + constant SINK_FILE : string := "/home/csk/Documents/Projects/working_dir/src/dtc/top/dtc-mini/PS-5G/firmware/hdl/out_EMP.txt"; -constant SOURCE_FILE : string := "/home/csk/Documents/Projects/working_dir/src/dtc/top/dtc-mini/PS-5G/firmware/hdl/CIC2_EMP.txt"; -constant SINK_FILE : string := "/home/csk/Documents/Projects/working_dir/src/dtc/top/dtc-mini/PS-5G/firmware/hdl/out_EMP.txt"; + constant PLAYBACK_LENGTH : integer := 100 * 108; + constant CAPTURE_LENGTH : integer := 100 * 108; + constant WAIT_CYCLES_AT_START : integer := 0; + constant PLAYBACK_OFFSET : integer := 0; + constant CAPTURE_OFFSET : integer := PAYLOAD_LATENCY + 3; -constant PLAYBACK_LENGTH : integer := 100 * 108; -constant CAPTURE_LENGTH : integer := 100 * 108; -constant WAIT_CYCLES_AT_START: integer := 0; -constant PLAYBACK_OFFSET : integer := 0; -constant CAPTURE_OFFSET : integer := PAYLOAD_LATENCY + 3; + constant PLAYBACK_LOOP : boolean := false; + constant STRIP_HEADER : boolean := false; + constant INSERT_HEADER : boolean := false; -constant PLAYBACK_LOOP : boolean := false; -constant STRIP_HEADER : boolean := false; -constant INSERT_HEADER : boolean := false; - - -end package; +end package tb_decl; diff --git a/top/dtc-mini/PS-5G/firmware/hdl/vu13p_so2_v1/link_maps.vhd b/top/dtc-mini/PS-5G/firmware/hdl/vu13p_so2_v1/link_maps.vhd index 7589a8021d78390380357f4cee2cc563c3019427..c3fc3a46155d9a6bfade8680e7b534451c926082 100644 --- a/top/dtc-mini/PS-5G/firmware/hdl/vu13p_so2_v1/link_maps.vhd +++ b/top/dtc-mini/PS-5G/firmware/hdl/vu13p_so2_v1/link_maps.vhd @@ -1,7 +1,9 @@ -library IEEE; -use IEEE.STD_LOGIC_1164.ALL; -use IEEE.NUMERIC_STD.ALL; -use work.dtc_link_maps_func.all; +library ieee; + use ieee.std_logic_1164.all; + use ieee.numeric_std.all; + +library work; + use work.dtc_link_maps_func.all; package dtc_link_maps is @@ -9,7 +11,8 @@ package dtc_link_maps is constant cNumberOfOutputLinks : integer := 4; type tDTCInputLinkMap is array(0 to cNumberOfFEModules - 1) of tDTCInputLinkConfig; - constant cDTCInputLinkMap : tDTCInputLinkMap := ( + + constant cDTCInputLinkMap : tDTCInputLinkMap := ( 0 => (32, "PS", 5, "CIC2"), 1 => (33, "PS", 5, "CIC2"), 2 => (34, "PS", 5, "CIC2"), @@ -17,7 +20,8 @@ package dtc_link_maps is ); type tDTCOutputLinkMap is array(0 to cNumberOfOutputLinks - 1) of integer; - constant cDTCOutputLinkMap : tDTCOutputLinkMap := ( + + constant cDTCOutputLinkMap : tDTCOutputLinkMap := ( 12, 13, 14, 15 ); diff --git a/top/dtc-mini/b186-vu13p/firmware/hdl/link_maps.vhd b/top/dtc-mini/b186-vu13p/firmware/hdl/link_maps.vhd index 6fd32bf1c611a199c845fe0eec057615fa7aa8a8..91ad693bf75d0974d70162756f07bd6797b2539f 100644 --- a/top/dtc-mini/b186-vu13p/firmware/hdl/link_maps.vhd +++ b/top/dtc-mini/b186-vu13p/firmware/hdl/link_maps.vhd @@ -1,7 +1,9 @@ -library IEEE; -use IEEE.STD_LOGIC_1164.ALL; -use IEEE.NUMERIC_STD.ALL; -use work.dtc_link_maps_func.all; +library ieee; + use ieee.std_logic_1164.all; + use ieee.numeric_std.all; + +library work; + use work.dtc_link_maps_func.all; package dtc_link_maps is @@ -9,7 +11,8 @@ package dtc_link_maps is constant cNumberOfOutputLinks : integer := 12; type tDTCInputLinkMap is array(0 to cNumberOfFEModules - 1) of tDTCInputLinkConfig; - constant cDTCInputLinkMap : tDTCInputLinkMap := ( + + constant cDTCInputLinkMap : tDTCInputLinkMap := ( 0 => (32, "2S", 5, "CIC2"), 1 => (33, "2S", 5, "CIC2"), 2 => (34, "2S", 5, "CIC2"), @@ -25,7 +28,8 @@ package dtc_link_maps is ); type tDTCOutputLinkMap is array(0 to cNumberOfOutputLinks - 1) of integer; - constant cDTCOutputLinkMap : tDTCOutputLinkMap := ( + + constant cDTCOutputLinkMap : tDTCOutputLinkMap := ( 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55 ); diff --git a/top/dtc-mini/b186/firmware/hdl/link_maps.vhd b/top/dtc-mini/b186/firmware/hdl/link_maps.vhd index 11dde846d7313a2e48303248a16b9df67bbbed5b..1edd9a84d1fd7b746d72ac148cbfac8a2377af3c 100644 --- a/top/dtc-mini/b186/firmware/hdl/link_maps.vhd +++ b/top/dtc-mini/b186/firmware/hdl/link_maps.vhd @@ -1,7 +1,9 @@ -library IEEE; -use IEEE.STD_LOGIC_1164.ALL; -use IEEE.NUMERIC_STD.ALL; -use work.dtc_link_maps_func.all; +library ieee; + use ieee.std_logic_1164.all; + use ieee.numeric_std.all; + +library work; + use work.dtc_link_maps_func.all; package dtc_link_maps is @@ -9,16 +11,18 @@ package dtc_link_maps is constant cNumberOfOutputLinks : integer := 5; type tDTCInputLinkMap is array(0 to cNumberOfFEModules - 1) of tDTCInputLinkConfig; - constant cDTCInputLinkMap : tDTCInputLinkMap := ( - 0 => (4, "PS", 5, "CIC1"), - 1 => (5, "PS", 10, "CIC2"), - 2 => (8, "2S", 5, "CIC2"), - 3 => (10, "2S", 5, "CIC2"), - 4 => (11, "2S", 5, "CIC1") + + constant cDTCInputLinkMap : tDTCInputLinkMap := ( + 0 => (4, "PS", 5, "CIC1"), + 1 => (5, "PS", 10, "CIC2"), + 2 => (8, "2S", 5, "CIC2"), + 3 => (10, "2S", 5, "CIC2"), + 4 => (11, "2S", 5, "CIC1") ); type tDTCOutputLinkMap is array(0 to cNumberOfOutputLinks - 1) of integer; - constant cDTCOutputLinkMap : tDTCOutputLinkMap := ( + + constant cDTCOutputLinkMap : tDTCOutputLinkMap := ( 16, 17, 18, 19, 20 ); diff --git a/top/dtc-mini/b888/firmware/hdl/link_maps.vhd b/top/dtc-mini/b888/firmware/hdl/link_maps.vhd index 8aca4366f31d2821ba7e913f6c93893224e445b2..56ba90739e042d9c0e9c5c646c863ef6cd21b521 100644 --- a/top/dtc-mini/b888/firmware/hdl/link_maps.vhd +++ b/top/dtc-mini/b888/firmware/hdl/link_maps.vhd @@ -1,7 +1,9 @@ -library IEEE; -use IEEE.STD_LOGIC_1164.ALL; -use IEEE.NUMERIC_STD.ALL; -use work.dtc_link_maps_func.all; +library ieee; + use ieee.std_logic_1164.all; + use ieee.numeric_std.all; + +library work; + use work.dtc_link_maps_func.all; package dtc_link_maps is @@ -9,7 +11,8 @@ package dtc_link_maps is constant cNumberOfOutputLinks : integer := 4; type tDTCInputLinkMap is array(0 to cNumberOfFEModules - 1) of tDTCInputLinkConfig; - constant cDTCInputLinkMap : tDTCInputLinkMap := ( + + constant cDTCInputLinkMap : tDTCInputLinkMap := ( 0 => (8, "2S", 5, "CIC2"), 1 => (9, "2S", 5, "CIC2"), 2 => (10, "PS", 5, "CIC2"), @@ -17,7 +20,8 @@ package dtc_link_maps is ); type tDTCOutputLinkMap is array(0 to cNumberOfOutputLinks - 1) of integer; - constant cDTCOutputLinkMap : tDTCOutputLinkMap := ( + + constant cDTCOutputLinkMap : tDTCOutputLinkMap := ( 16, 17, 18, 19 );