From 8ea8457f8db7f7902080f8101e68d0051dd954f1 Mon Sep 17 00:00:00 2001 From: Matt Warren <matthew.warren@ucl.ac.uk> Date: Fri, 26 Jul 2024 16:25:25 +0100 Subject: [PATCH 1/6] Made inclusion of LCB HCC/ABC mask logic and BCID gating optional. Defaults to not included --- sources/ItkStrip/lcb_wrapper.vhd | 765 +++++++++++++++------------- sources/ItkStrip/strips_package.vhd | 20 +- 2 files changed, 415 insertions(+), 370 deletions(-) diff --git a/sources/ItkStrip/lcb_wrapper.vhd b/sources/ItkStrip/lcb_wrapper.vhd index 56d8322bb..b3df79ec6 100644 --- a/sources/ItkStrip/lcb_wrapper.vhd +++ b/sources/ItkStrip/lcb_wrapper.vhd @@ -16,393 +16,424 @@ --! limitations under the License. library ieee; - use ieee.std_logic_1164.all; - use ieee.numeric_std.all; - use work.strips_package.all; - use work.pcie_package.all; - use work.lcb_regmap_package.all; - use work.pcie_package.bitfield_global_strips_config_w_type; +use ieee.std_logic_1164.all; +use ieee.numeric_std.all; +use work.strips_package.all; +use work.pcie_package.all; +use work.lcb_regmap_package.all; +use work.pcie_package.bitfield_global_strips_config_w_type; entity lcb_wrapper is - generic( - USE_ULTRARAM : boolean + generic( + USE_ULTRARAM : boolean ); - port( - clk : in std_logic; - rst : in std_logic; - -- TTC signals - bcr_i : in std_logic; -- BCR signal --AP: This signal needs to be derived from LTI Turn singal, not BCID. - l0a_i : in std_logic; -- L0A signal - l0a_trig_i : in std_logic_vector(3 downto 0); - l0id_i : in std_logic_vector(6 downto 0); -- L0tag - sync_i : in std_logic; --AP: ITk sync pulse from the trigger tage generator - - -- link configuration data source - config_data_i : in std_logic_vector(7 downto 0); -- elink data - config_valid_i : in std_logic; -- elink data is valid this clk cycle - config_ready_o : out std_logic; -- this module is ready for the next elink data - - -- trickle configuration data source - trickle_data_i : in std_logic_vector(7 downto 0); -- elink data - trickle_valid_i : in std_logic; -- elink data is valid this clk cycle - trickle_ready_o : out std_logic; -- this module is ready for the next elink data - - -- elink command data source - command_data_i : in std_logic_vector(7 downto 0); -- elink data - command_valid_i : in std_logic; -- elink data is valid this clk cycle - command_ready_o : out std_logic; -- this module is ready for the next elink data - - -- configuration from global register map - config : in t_strips_config; -- @suppress "Port name 'config' is a keyword in Verilog and may cause problems in mixed language projects" - - -- debug / auxiliary signals - decoder_idle_o : out std_logic; -- command decoder is idle - error_count_o : out std_logic_vector(15 downto 0); -- number of errors encountered by the command decoder since last rst - frame_start_pulse_o : out std_logic; -- marks beginning of the LCB frame (new frame will be loaded next CLK cycle) - ttc_l0a_frame_o : out std_logic_vector(11 downto 0); -- pre-encoded version of L0A frame originated from TTC - ttc_l0a_frame_valid_o : out std_logic; -- is TTC l0a frame valid this clk cycle - trickle_trigger_gating_o : out std_logic; -- trigger BC gating signal - trickle_trigger_o : out std_logic; -- combined trickle trigger signal - register_guard_o : out std_logic; -- trickle register gating signal - regmap_o : out t_register_map; --output for simulation - -- data output for the device - encoded_frame_o : out std_logic_vector(15 downto 0); - edata_o : out std_logic_vector(3 downto 0) + port( + clk : in std_logic; + rst : in std_logic; + -- TTC signals + bcr_i : in std_logic; -- BCR signal --AP: This signal needs to be derived from LTI Turn singal, not BCID. + l0a_i : in std_logic; -- L0A signal + l0a_trig_i : in std_logic_vector(3 downto 0); + l0id_i : in std_logic_vector(6 downto 0); -- L0tag + sync_i : in std_logic; --AP: ITk sync pulse from the trigger tage generator + + -- link configuration data source + config_data_i : in std_logic_vector(7 downto 0); -- elink data + config_valid_i : in std_logic; -- elink data is valid this clk cycle + config_ready_o : out std_logic; -- this module is ready for the next elink data + + -- trickle configuration data source + trickle_data_i : in std_logic_vector(7 downto 0); -- elink data + trickle_valid_i : in std_logic; -- elink data is valid this clk cycle + trickle_ready_o : out std_logic; -- this module is ready for the next elink data + + -- elink command data source + command_data_i : in std_logic_vector(7 downto 0); -- elink data + command_valid_i : in std_logic; -- elink data is valid this clk cycle + command_ready_o : out std_logic; -- this module is ready for the next elink data + + -- configuration from global register map + config : in t_strips_config; -- @suppress "Port name 'config' is a keyword in Verilog and may cause problems in mixed language projects" + + -- debug / auxiliary signals + decoder_idle_o : out std_logic; -- command decoder is idle + error_count_o : out std_logic_vector(15 downto 0); -- number of errors encountered by the command decoder since last rst + frame_start_pulse_o : out std_logic; -- marks beginning of the LCB frame (new frame will be loaded next CLK cycle) + ttc_l0a_frame_o : out std_logic_vector(11 downto 0); -- pre-encoded version of L0A frame originated from TTC + ttc_l0a_frame_valid_o : out std_logic; -- is TTC l0a frame valid this clk cycle + trickle_trigger_gating_o : out std_logic; -- trigger BC gating signal + trickle_trigger_o : out std_logic; -- combined trickle trigger signal + register_guard_o : out std_logic; -- trickle register gating signal + regmap_o : out t_register_map; --output for simulation + -- data output for the device + encoded_frame_o : out std_logic_vector(15 downto 0); + edata_o : out std_logic_vector(3 downto 0) ); end entity lcb_wrapper; architecture RTL of lcb_wrapper is - -- LCB frame generator signals - signal lcb_gen_cmd : t_lcb_command; -- which command to execute - signal lcb_gen_cmd_start_pulse : std_logic; -- pulse for 1 clk cycle to start command - signal lcb_gen_fast_cmd_data : std_logic_vector(5 downto 0); -- bc & cmd - signal lcb_gen_l0a_data : std_logic_vector(11 downto 0); -- bcr & L0A mask & L0 tag - signal lcb_gen_abc_id : std_logic_vector(3 downto 0); -- ABC* address (0xF = broadcast) - signal lcb_gen_hcc_id : std_logic_vector(3 downto 0); -- HCC* address (0xF = broadcast) - signal lcb_gen_reg_addr : std_logic_vector(7 downto 0); -- register address for reg. read/write - signal lcb_gen_reg_data : std_logic_vector(31 downto 0); -- register data for reg. write - signal lcb_gen_ready : std_logic; -- indicates it's ready for a new command - signal lcb_frame : STD_LOGIC_VECTOR(12 downto 0); -- FIFO data out - signal lcb_frame_rd_en : std_logic; -- FIFO rd_en signal - signal lcb_frame_empty : std_logic; -- FIFO empty signal - signal lcb_frame_almost_empty : std_logic; -- FIFO contains one word - signal lcb_frame_fifo_almost_full : std_logic; -- FIFO is almost full - signal abc_module_mask : t_abc_mask; - signal edata_s : std_logic_vector(3 downto 0); - - signal ttc_generate_gating_enable : std_logic; - - signal regmap : t_register_map; - signal regmap_wr_en : std_logic; - signal regmap_data : std_logic_vector(t_register_data'range); - signal regmap_addr : std_logic_vector(7 downto 0); - - signal bypass_frame : STD_LOGIC_VECTOR(15 downto 0); - signal bypass_frame_ready : std_logic; - signal bypass_frame_valid : std_logic; - - signal trickle_data_o : std_logic_vector(playback_controller_data'range); - signal trickle_valid_o : std_logic; - signal trickle_ready_i : std_logic; - signal trickle_trigger_start : std_logic; - signal trickle_allow_register_cmd : std_logic; - signal trickle_trigger_gating : std_logic; - - -- L0A generator signals - signal ttc_l0a_frame : std_logic_vector(11 downto 0); - signal frame_start_pulse : std_logic; - - -- serializer registers - signal serializer_reg : std_logic_vector(encoded_frame_o'range) := (others => '0'); - signal encoded_frame_reg : std_logic_vector(encoded_frame_o'range); - - -- bypass command and firmware encoded command lines - signal encoding : std_logic; - signal encoded_cmd : std_logic_vector(7 downto 0); - signal encoded_cmd_valid : std_logic; - signal encoded_cmd_ready : std_logic; - - signal bypass_cmd : std_logic_vector(7 downto 0); - signal bypass_cmd_valid : std_logic; - signal bypass_cmd_ready : std_logic; - - -- edata_o fine delay types and registers - signal edata_delay : std_logic_vector(1 downto 0); - type t_edata_array is array (natural range <>) of std_logic_vector(3 downto 0); - signal edata_delay_reg : t_edata_array(1 to 3) := (others => (others => '0')); - - signal invert_output : boolean := False; + -- LCB frame generator signals + signal lcb_gen_cmd : t_lcb_command; -- which command to execute + signal lcb_gen_cmd_start_pulse : std_logic; -- pulse for 1 clk cycle to start command + signal lcb_gen_fast_cmd_data : std_logic_vector(5 downto 0); -- bc & cmd + signal lcb_gen_l0a_data : std_logic_vector(11 downto 0); -- bcr & L0A mask & L0 tag + signal lcb_gen_abc_id : std_logic_vector(3 downto 0); -- ABC* address (0xF = broadcast) + signal lcb_gen_hcc_id : std_logic_vector(3 downto 0); -- HCC* address (0xF = broadcast) + signal lcb_gen_reg_addr : std_logic_vector(7 downto 0); -- register address for reg. read/write + signal lcb_gen_reg_data : std_logic_vector(31 downto 0); -- register data for reg. write + signal lcb_gen_ready : std_logic; -- indicates it's ready for a new command + signal lcb_frame : std_logic_vector(12 downto 0); -- FIFO data out + signal lcb_frame_rd_en : std_logic; -- FIFO rd_en signal + signal lcb_frame_empty : std_logic; -- FIFO empty signal + signal lcb_frame_almost_empty : std_logic; -- FIFO contains one word + signal lcb_frame_fifo_almost_full : std_logic; -- FIFO is almost full + signal abc_mask : t_abc_mask; + signal edata_s : std_logic_vector(3 downto 0); + + signal ttc_generate_gating_enable : std_logic; + + signal regmap : t_register_map; + signal regmap_wr_en : std_logic; + signal regmap_data : std_logic_vector(t_register_data'range); + signal regmap_addr : std_logic_vector(7 downto 0); + + signal bypass_frame : std_logic_vector(15 downto 0); + signal bypass_frame_ready : std_logic; + signal bypass_frame_valid : std_logic; + + signal trickle_data_o : std_logic_vector(playback_controller_data'range); + signal trickle_valid_o : std_logic; + signal trickle_ready_i : std_logic; + signal trickle_trigger_start : std_logic; + signal trickle_allow_register_cmd : std_logic; + signal trickle_trigger_gating : std_logic; + + -- L0A generator signals + signal ttc_l0a_frame : std_logic_vector(11 downto 0); + signal frame_start_pulse : std_logic; + + -- serializer registers + signal serializer_reg : std_logic_vector(encoded_frame_o'range) := (others => '0'); + signal encoded_frame_reg : std_logic_vector(encoded_frame_o'range); + + -- bypass command and firmware encoded command lines + signal encoding : std_logic; + signal encoded_cmd : std_logic_vector(7 downto 0); + signal encoded_cmd_valid : std_logic; + signal encoded_cmd_ready : std_logic; + + signal bypass_cmd : std_logic_vector(7 downto 0); + signal bypass_cmd_valid : std_logic; + signal bypass_cmd_ready : std_logic; + + -- edata_o fine delay types and registers + signal edata_delay : std_logic_vector(1 downto 0); + type t_edata_array is array (natural range <>) of std_logic_vector(3 downto 0); + signal edata_delay_reg : t_edata_array(1 to 3) := (others => (others => '0')); + + signal invert_output : boolean := false; --constant zero_byte : std_logic_vector(7 downto 0) := (others => '0'); begin - encoded_frame_o <= encoded_frame_reg; - trickle_trigger_o <= trickle_trigger_start; - register_guard_o <= trickle_allow_register_cmd; - trickle_trigger_start <= regmap(TRICKLE_TRIGGER_PULSE)(0) - or config.GLOBAL_TRICKLE_TRIGGER(config.GLOBAL_TRICKLE_TRIGGER'low) - or regmap(TRICKLE_TRIGGER_RUN)(0); - - edata_delay <= regmap(L0A_FRAME_DELAY)(edata_delay'range); - - frame_start_pulse_o <= frame_start_pulse; - ttc_l0a_frame_o <= ttc_l0a_frame; - ttc_l0a_frame_valid_o <= ttc_l0a_frame(11) or ttc_l0a_frame(10) or ttc_l0a_frame(9) or ttc_l0a_frame(8) or ttc_l0a_frame(7); - trickle_trigger_gating_o <= trickle_trigger_gating; - ttc_generate_gating_enable <= (regmap(GATING_TTC_ENABLE)(0) - or config.GLOBAL_STRIPS_CONFIG.TTC_GENERATE_GATING_ENABLE(config.GLOBAL_STRIPS_CONFIG.TTC_GENERATE_GATING_ENABLE'low)) - and not config.GLOBAL_STRIPS_CONFIG.TTC_GATING_OVERRIDE(config.GLOBAL_STRIPS_CONFIG.TTC_GATING_OVERRIDE'low); - - invert_output <= config.GLOBAL_STRIPS_CONFIG.INVERT_LCB_OUT( - config.GLOBAL_STRIPS_CONFIG.INVERT_LCB_OUT'low) = '1'; - - ttc_l0a_generator : entity work.l0a_frame_generator - port map( - clk => clk, - rst => rst, - bcr_i => bcr_i, - l0a_i => l0a_i, - l0a_trig_i => l0a_trig_i, - bcr_delay_i => unsigned(regmap(TTC_BCR_DELAY)(t_bcid'range)), --AP: THis needs to be a global FELIX tegister - frame_phase_i => unsigned(regmap(L0A_FRAME_PHASE)(1 downto 0)), --AP: This needs to be done somewhere else - l0id_i => l0id_i, - frame_start_pulse_o => frame_start_pulse, - ITk_sync_i => sync_i, - l0a_frame_o => ttc_l0a_frame - ); - - encoding <= regmap(ENCODING_ENABLE)(0); - - cmd_destination_selector_mux : - process(encoding, command_data_i, command_valid_i, bypass_cmd_ready, encoded_cmd_ready) is - begin - if encoding = '0' then - encoded_cmd <= (others => '0'); - encoded_cmd_valid <= '0'; - bypass_cmd <= command_data_i; - bypass_cmd_valid <= command_valid_i; - command_ready_o <= bypass_cmd_ready; - else - encoded_cmd <= command_data_i; - encoded_cmd_valid <= command_valid_i; - bypass_cmd <= (others => '0'); - bypass_cmd_valid <= '0'; - command_ready_o <= encoded_cmd_ready; - end if; - end process; - - bypass_frame_generator : entity work.strips_bypass_frame_aggregator - generic map( - TIMEOUT => 4000 - ) - port map( - clk => clk, - rst => rst, - byte_i => bypass_cmd, - byte_valid_i => bypass_cmd_valid, - byte_ready_o => bypass_cmd_ready, - frame_o => bypass_frame, - frame_valid_o => bypass_frame_valid, - frame_ready_i => bypass_frame_ready - ); - - configuration_decoder : entity work.strips_configuration_decoder - generic map( - TIMEOUT => 4000 - ) - port map( - clk => clk, - rst => rst, - config_data_i => config_data_i, - config_valid_i => config_valid_i, - config_ready_o => config_ready_o, - regmap_wr_en_o => regmap_wr_en, - regmap_data_o => regmap_data, - regmap_addr_o => regmap_addr - ); - - command_decoder : entity work.lcb_command_decoder - generic map( - TIMEOUT => 4000 - ) - port map( - clk => clk, - rst => rst, - elink_data_i => encoded_cmd, - elink_valid_i => encoded_cmd_valid, - elink_ready_o => encoded_cmd_ready, - trickle_data_i => trickle_data_o, - trickle_valid_i => trickle_valid_o, - trickle_ready_o => trickle_ready_i, - lcb_cmd_o => lcb_gen_cmd, - lcb_cmd_start_pulse_o => lcb_gen_cmd_start_pulse, - lcb_fast_cmd_data_o => lcb_gen_fast_cmd_data, - lcb_l0a_data_o => lcb_gen_l0a_data, - lcb_abc_id_o => lcb_gen_abc_id, - lcb_hcc_id_o => lcb_gen_hcc_id, - lcb_reg_addr_o => lcb_gen_reg_addr, - lcb_reg_data_o => lcb_gen_reg_data, - lcb_ready_i => lcb_gen_ready, - lcb_frame_fifo_almost_full_i => lcb_frame_fifo_almost_full, - decoder_idle_o => decoder_idle_o, - error_count_o => error_count_o - ); - - register_map : entity work.lcb_regmap - port map ( - clk => clk, - rst => rst, - wr_en => regmap_wr_en, - data_i => regmap_data, - addr_i => regmap_addr, - regmap_o => regmap - ); - - regmap_o <= regmap; - - playback_controller : entity work.playback_controller - generic map( - USE_ULTRARAM => USE_ULTRARAM - ) - port map( - clk => clk, - rst => rst, - start_pulse_i => trickle_trigger_start, - readout_active_o => open, - playback_loops_i => regmap(PLAYBACK_LOOPS), - data_i => trickle_data_i, - valid_i => trickle_valid_i, - ready_o => trickle_ready_o, - set_write_addr_pulse_i => regmap(TRICKLE_SET_WRITE_ADDR_PULSE)(0), - write_addr_start_i => regmap(TRICKLE_WRITE_ADDR)(playback_controller_address'range), - read_addr_start_i => regmap(TRICKLE_DATA_START)(playback_controller_address'range), - read_addr_stop_i => regmap(TRICKLE_DATA_END)(playback_controller_address'range), - data_o => trickle_data_o, - valid_o => trickle_valid_o, - ready_i => trickle_ready_i + encoded_frame_o <= encoded_frame_reg; + trickle_trigger_o <= trickle_trigger_start; + register_guard_o <= trickle_allow_register_cmd; + trickle_trigger_start <= regmap(TRICKLE_TRIGGER_PULSE)(0) + or config.GLOBAL_TRICKLE_TRIGGER(config.GLOBAL_TRICKLE_TRIGGER'low) + or regmap(TRICKLE_TRIGGER_RUN)(0); + + edata_delay <= regmap(L0A_FRAME_DELAY)(edata_delay'range); + + frame_start_pulse_o <= frame_start_pulse; + ttc_l0a_frame_o <= ttc_l0a_frame; + ttc_l0a_frame_valid_o <= ttc_l0a_frame(11) or ttc_l0a_frame(10) or ttc_l0a_frame(9) or ttc_l0a_frame(8) or ttc_l0a_frame(7); + trickle_trigger_gating_o <= trickle_trigger_gating; + + invert_output <= config.GLOBAL_STRIPS_CONFIG.INVERT_LCB_OUT( + config.GLOBAL_STRIPS_CONFIG.INVERT_LCB_OUT'low) = '1'; + + ttc_l0a_generator : entity work.l0a_frame_generator + port map( + clk => clk, + rst => rst, + bcr_i => bcr_i, + l0a_i => l0a_i, + l0a_trig_i => l0a_trig_i, + bcr_delay_i => unsigned(regmap(TTC_BCR_DELAY)(t_bcid'range)), --AP: THis needs to be a global FELIX tegister + frame_phase_i => unsigned(regmap(L0A_FRAME_PHASE)(1 downto 0)), --AP: This needs to be done somewhere else + l0id_i => l0id_i, + frame_start_pulse_o => frame_start_pulse, + ITk_sync_i => sync_i, + l0a_frame_o => ttc_l0a_frame + ); + + encoding <= regmap(ENCODING_ENABLE)(0); + + cmd_destination_selector_mux : + process(encoding, command_data_i, command_valid_i, bypass_cmd_ready, encoded_cmd_ready) is + begin + if encoding = '0' then + encoded_cmd <= (others => '0'); + encoded_cmd_valid <= '0'; + bypass_cmd <= command_data_i; + bypass_cmd_valid <= command_valid_i; + command_ready_o <= bypass_cmd_ready; + else + encoded_cmd <= command_data_i; + encoded_cmd_valid <= command_valid_i; + bypass_cmd <= (others => '0'); + bypass_cmd_valid <= '0'; + command_ready_o <= encoded_cmd_ready; + end if; + end process; + + bypass_frame_generator : entity work.strips_bypass_frame_aggregator + generic map( + TIMEOUT => 4000 + ) + port map( + clk => clk, + rst => rst, + byte_i => bypass_cmd, + byte_valid_i => bypass_cmd_valid, + byte_ready_o => bypass_cmd_ready, + frame_o => bypass_frame, + frame_valid_o => bypass_frame_valid, + frame_ready_i => bypass_frame_ready + ); + + configuration_decoder : entity work.strips_configuration_decoder + generic map( + TIMEOUT => 4000 + ) + port map( + clk => clk, + rst => rst, + config_data_i => config_data_i, + config_valid_i => config_valid_i, + config_ready_o => config_ready_o, + regmap_wr_en_o => regmap_wr_en, + regmap_data_o => regmap_data, + regmap_addr_o => regmap_addr + ); + + command_decoder : entity work.lcb_command_decoder + generic map( + TIMEOUT => 4000 + ) + port map( + clk => clk, + rst => rst, + elink_data_i => encoded_cmd, + elink_valid_i => encoded_cmd_valid, + elink_ready_o => encoded_cmd_ready, + trickle_data_i => trickle_data_o, + trickle_valid_i => trickle_valid_o, + trickle_ready_o => trickle_ready_i, + lcb_cmd_o => lcb_gen_cmd, + lcb_cmd_start_pulse_o => lcb_gen_cmd_start_pulse, + lcb_fast_cmd_data_o => lcb_gen_fast_cmd_data, + lcb_l0a_data_o => lcb_gen_l0a_data, + lcb_abc_id_o => lcb_gen_abc_id, + lcb_hcc_id_o => lcb_gen_hcc_id, + lcb_reg_addr_o => lcb_gen_reg_addr, + lcb_reg_data_o => lcb_gen_reg_data, + lcb_ready_i => lcb_gen_ready, + lcb_frame_fifo_almost_full_i => lcb_frame_fifo_almost_full, + decoder_idle_o => decoder_idle_o, + error_count_o => error_count_o + ); + + register_map : entity work.lcb_regmap + port map ( + clk => clk, + rst => rst, + wr_en => regmap_wr_en, + data_i => regmap_data, + addr_i => regmap_addr, + regmap_o => regmap + ); + + regmap_o <= regmap; + + playback_controller : entity work.playback_controller + generic map( + USE_ULTRARAM => USE_ULTRARAM + ) + port map( + clk => clk, + rst => rst, + start_pulse_i => trickle_trigger_start, + readout_active_o => open, + playback_loops_i => regmap(PLAYBACK_LOOPS), + data_i => trickle_data_i, + valid_i => trickle_valid_i, + ready_o => trickle_ready_o, + set_write_addr_pulse_i => regmap(TRICKLE_SET_WRITE_ADDR_PULSE)(0), + write_addr_start_i => regmap(TRICKLE_WRITE_ADDR)(playback_controller_address'range), + read_addr_start_i => regmap(TRICKLE_DATA_START)(playback_controller_address'range), + read_addr_stop_i => regmap(TRICKLE_DATA_END)(playback_controller_address'range), + data_o => trickle_data_o, + valid_o => trickle_valid_o, + ready_i => trickle_ready_i + ); + + abc_mask(15) <= regmap(ABC_MASK_F); + abc_mask(14) <= regmap(ABC_MASK_E); + abc_mask(13) <= regmap(ABC_MASK_D); + abc_mask(12) <= regmap(ABC_MASK_C); + abc_mask(11) <= regmap(ABC_MASK_B); + abc_mask(10) <= regmap(ABC_MASK_A); + abc_mask(9) <= regmap(ABC_MASK_9); + abc_mask(8) <= regmap(ABC_MASK_8); + abc_mask(7) <= regmap(ABC_MASK_7); + abc_mask(6) <= regmap(ABC_MASK_6); + abc_mask(5) <= regmap(ABC_MASK_5); + abc_mask(4) <= regmap(ABC_MASK_4); + abc_mask(3) <= regmap(ABC_MASK_3); + abc_mask(2) <= regmap(ABC_MASK_2); + abc_mask(1) <= regmap(ABC_MASK_1); + abc_mask(0) <= regmap(ABC_MASK_0); + + g_modulemasksen : if (CFG_INCLUDE_ASIC_MASKS = '1') generate + frame_generator : entity work.lcb_frame_generator + port map( + clk => clk, + rst => rst, + cmd_i => lcb_gen_cmd, + cmd_start_pulse_i => lcb_gen_cmd_start_pulse, + fast_cmd_data_i => lcb_gen_fast_cmd_data, + hcc_mask_i => regmap(HCC_MASK), + abc_mask_i => abc_mask, + l0a_data_i => lcb_gen_l0a_data, + abc_id_i => lcb_gen_abc_id, + hcc_id_i => lcb_gen_hcc_id, + reg_addr_i => lcb_gen_reg_addr, + reg_data_i => lcb_gen_reg_data, + ready_o => lcb_gen_ready, + lcb_frame_o => lcb_frame, + lcb_frame_i_rd_en => lcb_frame_rd_en, + lcb_frame_o_empty => lcb_frame_empty, + lcb_frame_o_almost_empty => lcb_frame_almost_empty, + lcb_frame_fifo_almost_full_o => lcb_frame_fifo_almost_full ); - - abc_module_mask(15) <= regmap(ABC_MASK_F); - abc_module_mask(14) <= regmap(ABC_MASK_E); - abc_module_mask(13) <= regmap(ABC_MASK_D); - abc_module_mask(12) <= regmap(ABC_MASK_C); - abc_module_mask(11) <= regmap(ABC_MASK_B); - abc_module_mask(10) <= regmap(ABC_MASK_A); - abc_module_mask(9) <= regmap(ABC_MASK_9); - abc_module_mask(8) <= regmap(ABC_MASK_8); - abc_module_mask(7) <= regmap(ABC_MASK_7); - abc_module_mask(6) <= regmap(ABC_MASK_6); - abc_module_mask(5) <= regmap(ABC_MASK_5); - abc_module_mask(4) <= regmap(ABC_MASK_4); - abc_module_mask(3) <= regmap(ABC_MASK_3); - abc_module_mask(2) <= regmap(ABC_MASK_2); - abc_module_mask(1) <= regmap(ABC_MASK_1); - abc_module_mask(0) <= regmap(ABC_MASK_0); - + else generate --CFG_INCLUDE_ASIC_MASKS = '0' frame_generator : entity work.lcb_frame_generator - port map( - clk => clk, - rst => rst, - cmd_i => lcb_gen_cmd, - cmd_start_pulse_i => lcb_gen_cmd_start_pulse, - fast_cmd_data_i => lcb_gen_fast_cmd_data, - hcc_mask_i => regmap(HCC_MASK), - abc_mask_i => abc_module_mask, - l0a_data_i => lcb_gen_l0a_data, - abc_id_i => lcb_gen_abc_id, - hcc_id_i => lcb_gen_hcc_id, - reg_addr_i => lcb_gen_reg_addr, - reg_data_i => lcb_gen_reg_data, - ready_o => lcb_gen_ready, - lcb_frame_o => lcb_frame, - lcb_frame_i_rd_en => lcb_frame_rd_en, - lcb_frame_o_empty => lcb_frame_empty, - lcb_frame_o_almost_empty => lcb_frame_almost_empty, - lcb_frame_fifo_almost_full_o => lcb_frame_fifo_almost_full + port map( + clk => clk, + rst => rst, + cmd_i => lcb_gen_cmd, + cmd_start_pulse_i => lcb_gen_cmd_start_pulse, + fast_cmd_data_i => lcb_gen_fast_cmd_data, + hcc_mask_i => (others => '0'), + abc_mask_i => (others => (others => '0')), + l0a_data_i => lcb_gen_l0a_data, + abc_id_i => lcb_gen_abc_id, + hcc_id_i => lcb_gen_hcc_id, + reg_addr_i => lcb_gen_reg_addr, + reg_data_i => lcb_gen_reg_data, + ready_o => lcb_gen_ready, + lcb_frame_o => lcb_frame, + lcb_frame_i_rd_en => lcb_frame_rd_en, + lcb_frame_o_empty => lcb_frame_empty, + lcb_frame_o_almost_empty => lcb_frame_almost_empty, + lcb_frame_fifo_almost_full_o => lcb_frame_fifo_almost_full ); + end generate; + g_bcidgating_en : if (CFG_INCLUDE_BCID_GATING = '1') generate + ttc_generate_gating_enable <= (regmap(GATING_TTC_ENABLE)(0) + or config.GLOBAL_STRIPS_CONFIG.TTC_GENERATE_GATING_ENABLE(config.GLOBAL_STRIPS_CONFIG.TTC_GENERATE_GATING_ENABLE'low)) + and not config.GLOBAL_STRIPS_CONFIG.TTC_GATING_OVERRIDE(config.GLOBAL_STRIPS_CONFIG.TTC_GATING_OVERRIDE'low); trickle_trigger_generator : entity work.lcb_trickle_trigger - generic map (guard_window => guard_window_size) -- defined in strips_package.vhd - port map( - clk => clk, - rst => rst, - en_i => ttc_generate_gating_enable, - bcr_i => bcr_i, - bc_start_i => regmap(GATING_BC_START)(t_bcid'range), - bc_stop_i => regmap(GATING_BC_STOP)(t_bcid'range), - trickle_trigger_o => trickle_trigger_gating, - trickle_allow_register_cmd_o => trickle_allow_register_cmd - ); - - scheduler : entity work.lcb_scheduler_encoder - port map( - clk => clk, - rst => rst, - l0a_frame_i => ttc_l0a_frame, - lcb_frame_i => lcb_frame, - lcb_frame_o_rd_en => lcb_frame_rd_en, - lcb_frame_i_empty => lcb_frame_empty, - lcb_frame_i_almost_empty => lcb_frame_almost_empty, - l0a_frame_delay_i => regmap(L0A_FRAME_DELAY)(3 downto 2),--AP: I am not sure why this is needed - bypass_frame_i => bypass_frame, - bypass_frame_valid_i => bypass_frame_valid, - bypass_frame_ready_o => bypass_frame_ready, - frame_start_pulse_i => frame_start_pulse, - trickle_bc_gating_i => trickle_trigger_gating, - trickle_allow_register_cmd_i => trickle_allow_register_cmd, - trickle_bc_gating_en => ttc_generate_gating_enable, - ttc_l0a_en => regmap(TTC_L0A_ENABLE)(0), --AP: I am not sure why this is needed - encoded_frame_o => encoded_frame_reg + generic map (guard_window => guard_window_size) -- defined in strips_package.vhd + port map( + clk => clk, -- in + rst => rst, -- in + en_i => ttc_generate_gating_enable, -- in + bcr_i => bcr_i, -- in + bc_start_i => regmap(GATING_BC_START)(t_bcid'range), -- in t_bcid + bc_stop_i => regmap(GATING_BC_STOP)(t_bcid'range), -- in t_bcid + trickle_trigger_o => trickle_trigger_gating, -- out + trickle_allow_register_cmd_o => trickle_allow_register_cmd -- out ); - - -- serializes LCB frame for 4-bit elink - serializer : process(clk) is - begin - if rising_edge(clk) then - if rst = '1' then - serializer_reg <= (others => '0'); - else - if frame_start_pulse = '1' then - serializer_reg <= encoded_frame_reg; - else - serializer_reg(15 downto 4) <= serializer_reg(11 downto 0); - end if; - end if; - end if; - end process; - - -- Saves delayed elink data by up to 3 BC CLK cycles - edata_delay_proc : process(clk) is - begin - if rising_edge(clk) then - if rst = '1' then - edata_delay_reg <= (others => (others => '0')); - else - edata_delay_reg(1) <= serializer_reg(15 downto 12); - edata_delay_reg(2 to edata_delay_reg'high) <= edata_delay_reg(1 to edata_delay_reg'high - 1); - end if; + else generate -- CFG_INCLUDE_BCID_GATING = '0' + ttc_generate_gating_enable <= '0'; + trickle_trigger_gating <= '1'; + trickle_allow_register_cmd <= '1'; + end generate; + + + scheduler : entity work.lcb_scheduler_encoder + port map( + clk => clk, + rst => rst, + l0a_frame_i => ttc_l0a_frame, + lcb_frame_i => lcb_frame, + lcb_frame_o_rd_en => lcb_frame_rd_en, + lcb_frame_i_empty => lcb_frame_empty, + lcb_frame_i_almost_empty => lcb_frame_almost_empty, + l0a_frame_delay_i => regmap(L0A_FRAME_DELAY)(3 downto 2), --AP: I am not sure why this is needed + bypass_frame_i => bypass_frame, + bypass_frame_valid_i => bypass_frame_valid, + bypass_frame_ready_o => bypass_frame_ready, + frame_start_pulse_i => frame_start_pulse, + trickle_bc_gating_i => trickle_trigger_gating, + trickle_allow_register_cmd_i => trickle_allow_register_cmd, + trickle_bc_gating_en => ttc_generate_gating_enable, + ttc_l0a_en => regmap(TTC_L0A_ENABLE)(0), --AP: I am not sure why this is needed + encoded_frame_o => encoded_frame_reg + ); + + -- serializes LCB frame for 4-bit elink + serializer : process(clk) is + begin + if rising_edge(clk) then + if rst = '1' then + serializer_reg <= (others => '0'); + else + if frame_start_pulse = '1' then + serializer_reg <= encoded_frame_reg; + else + serializer_reg(15 downto 4) <= serializer_reg(11 downto 0); end if; - end process; - - -- Outputs elink data with a configurable delay - edata_output : process(clk) is - variable delay_int : integer range 0 to 3; - begin - if rising_edge(clk) then - if (rst = '1') then - edata_s <= (others => '0'); - else - delay_int := to_integer(unsigned(edata_delay)); - if delay_int = 0 then - edata_s <= serializer_reg(15 downto 12); - else - edata_s <= edata_delay_reg(delay_int); - end if; - end if; + end if; + end if; + end process; + + -- Saves delayed elink data by up to 3 BC CLK cycles + edata_delay_proc : process(clk) is + begin + if rising_edge(clk) then + if rst = '1' then + edata_delay_reg <= (others => (others => '0')); + else + edata_delay_reg(1) <= serializer_reg(15 downto 12); + edata_delay_reg(2 to edata_delay_reg'high) <= edata_delay_reg(1 to edata_delay_reg'high - 1); + end if; + end if; + end process; + + -- Outputs elink data with a configurable delay + edata_output : process(clk) is + variable delay_int : integer range 0 to 3; + begin + if rising_edge(clk) then + if (rst = '1') then + edata_s <= (others => '0'); + else + delay_int := to_integer(unsigned(edata_delay)); + if delay_int = 0 then + edata_s <= serializer_reg(15 downto 12); + else + edata_s <= edata_delay_reg(delay_int); end if; - end process; + end if; + end if; + end process; - edata_o <= not edata_s when invert_output else edata_s; + edata_o <= not edata_s when invert_output else edata_s; end architecture RTL; diff --git a/sources/ItkStrip/strips_package.vhd b/sources/ItkStrip/strips_package.vhd index 8774e400d..5e6bb3014 100644 --- a/sources/ItkStrip/strips_package.vhd +++ b/sources/ItkStrip/strips_package.vhd @@ -43,6 +43,22 @@ library IEEE; use work.pcie_package.all; package strips_package is + + -- Build settings for LCB encoders: + constant CFG_INCLUDE_BCID_GATING : std_logic := '0'; + constant CFG_INCLUDE_ASIC_MASKS : std_logic := '0'; + constant CFG_SEQRAM_ADDR_WIDTH : natural := 12; -- 4kB + --13; -- 8kB + --14; --16kB + + constant STRIPS_ENCODING_CFG_MON_REG : std_logic_vector(31 downto 0) := + x"000000" & + std_logic_vector(to_unsigned(CFG_SEQRAM_ADDR_WIDTH,4)) & + "00" & + CFG_INCLUDE_ASIC_MASKS & + CFG_INCLUDE_BCID_GATING; + + subtype t_bcid is std_logic_vector(11 downto 0); constant full_bcid : t_bcid := (others => '0'); constant frame_phase : std_logic_vector(1 downto 0) := (others => '0'); @@ -53,9 +69,7 @@ package strips_package is constant L0tag_bits : std_logic_vector(6 downto 0) := (others => '0'); -- playback controller address and data width - constant playback_controller_address : std_logic_vector(11 downto 0) := (others => '0'); --4 kB of trickle memory - --constant playback_controller_address : std_logic_vector(12 downto 0) := (others => '0'); --8 kB of trickle memory - --constant playback_controller_address : std_logic_vector(13 downto 0) := (others => '0'); --16 kB of trickle memory + constant playback_controller_address : std_logic_vector(CFG_SEQRAM_ADDR_WIDTH-1 downto 0) := (others => '0'); --4 kB of trickle memory constant playback_controller_data : std_logic_vector(7 downto 0) := (others => '0'); -- LCB encoder commands -- GitLab From c7d7c724821a974268f89df657aa64dc40699d1f Mon Sep 17 00:00:00 2001 From: Matt Warren <matthew.warren@ucl.ac.uk> Date: Tue, 30 Jul 2024 15:44:59 +0100 Subject: [PATCH 2/6] TB skips BC-gating and ASIC reg RW masking checks when not included in the build - note the existing gating-enables regs will still assert a gate --- simulation/ItkStrip/tb_lcb_axi_encoder.vhd | 149 +++++++++++++-------- sources/ItkStrip/lcb_wrapper.vhd | 58 ++++---- 2 files changed, 126 insertions(+), 81 deletions(-) diff --git a/simulation/ItkStrip/tb_lcb_axi_encoder.vhd b/simulation/ItkStrip/tb_lcb_axi_encoder.vhd index d07623cdf..32e653fce 100644 --- a/simulation/ItkStrip/tb_lcb_axi_encoder.vhd +++ b/simulation/ItkStrip/tb_lcb_axi_encoder.vhd @@ -754,31 +754,48 @@ begin procedure verify_bc_gating( expected_frame : std_logic_vector(15 downto 0) ) is - begin + begin log(ID_SEQUENCER, "Issuing BCR to start gating pulse generation"); wait until rising_edge(bcr); send_L0A( "0000", "0000000"); --'1', set_stopwatch; dequeue_next_frame; check_value(next_frame.decoded, "100000000000", ERROR, "BCR frame received"); - wait_for_next_frame(expiration_time => (bc_stop + 100) * C_CLK_PERIOD); - log(ID_SEQUENCER, "Received frames, bc_start=" & to_string(bc_start) & ", bc_stop = " & to_string(bc_stop) - & ", stopwatch shows " & to_string(stopwatch_p1)); - check_value(stopwatch_p1 >= bc_start, true, ERROR, "Low-priority frames start around the correct time"); - check_value(stopwatch_p1 <= bc_start + 20, true, ERROR, "Low-priority frames start around the correct time"); - reset_stopwatch; - for i in 0 to gating_test_frames/2 - 1 loop -- half of the frames was supposed to be scheduled + + if (CFG_INCLUDE_BCID_GATING = '1') then + wait_for_next_frame(expiration_time => (bc_stop + 100) * C_CLK_PERIOD); + log(ID_SEQUENCER, "Received frames, bc_start=" & to_string(bc_start) & ", bc_stop = " & to_string(bc_stop) + & ", stopwatch shows " & to_string(stopwatch_p1)); + check_value(stopwatch_p1 >= bc_start, true, ERROR, "Low-priority frames start around the correct time"); + check_value(stopwatch_p1 <= bc_start + 20, true, ERROR, "Low-priority frames start around the correct time"); + reset_stopwatch; + for i in 0 to gating_test_frames/2 - 1 loop -- half of the frames was supposed to be scheduled dequeue_next_frame; check_value(next_frame.encoded, expected_frame, ERROR, "Verifying low-priority frame contents"); - end loop; - wait_num_rising_edge(clk, 40); - check_value(frame_queue.is_empty(void), true, ERROR, "No frames are scheduled after gating interval is over"); - log(ID_SEQUENCER, "Disabling BC gating"); - set_register(t_register_name'pos(GATING_TTC_ENABLE), x"0000"); - for i in 0 to gating_test_frames/2 - 1 loop -- the remaining frames come out because gating is disabled + end loop; + wait_num_rising_edge(clk, 40); + check_value(frame_queue.is_empty(void), true, ERROR, "No frames are scheduled after gating interval is over"); + log(ID_SEQUENCER, "Disabling BC gating"); + set_register(t_register_name'pos(GATING_TTC_ENABLE), x"0000"); + for i in 0 to gating_test_frames/2 - 1 loop -- the remaining frames come out because gating is disabled dequeue_next_frame; check_value(next_frame.encoded, expected_frame, ERROR, "Verifying remaining low-priority frame contents"); - end loop; + end loop; + + else + for i in 0 to gating_test_frames - 1 loop + dequeue_next_frame; + check_value(next_frame.encoded, expected_frame, ERROR, "Verifying low-priority frame contents"); + end loop; + wait_num_rising_edge(clk, 40); + log(ID_SEQUENCER, "No gating in build - just checking frames"); + for i in 0 to gating_test_frames - 1 loop + dequeue_next_frame; + check_value(next_frame.encoded, expected_frame, ERROR, "Verifying low-priority frame contents"); + end loop; + + end if; + end; --- checks that register frames are always complete when coming from trickle configuration memory @@ -970,43 +987,47 @@ begin send_elink_commands_verify_response(register_elink_data); -------- verify that register read/write commands can be masked - log(ID_LOG_HDR, "Verifying that register read/write commands are maskable"); - log(ID_SEQUENCER, "Verify that HCC* register r/w commands are skipped for " - & "masked chips and not skipped for non-masked chips"); - mask_test_data := elink_parser.parse_file("../samples/hcc_mask_test_inputs.txt", - "../samples/hcc_mask_test_outputs.txt"); - for masked_hcc_id in 0 to 15 loop - set_register(t_register_name'pos(HCC_MASK), std_logic_vector(to_unsigned(2 ** masked_hcc_id, 16))); - log(ID_SEQUENCER, "Masking HCC* module " & to_string(masked_hcc_id) - & ", sending commands to every HCC* module and its ABC* submodules"); - for i in 0 to mask_test_data.inputs_count - 1 loop + if (CFG_INCLUDE_ASIC_MASKS = '1') then + log(ID_LOG_HDR, "Verifying that register read/write commands are maskable"); + log(ID_SEQUENCER, "Verify that HCC* register r/w commands are skipped for " + & "masked chips and not skipped for non-masked chips"); + mask_test_data := elink_parser.parse_file("../samples/hcc_mask_test_inputs.txt", + "../samples/hcc_mask_test_outputs.txt"); + for masked_hcc_id in 0 to 15 loop + set_register(t_register_name'pos(HCC_MASK), std_logic_vector(to_unsigned(2 ** masked_hcc_id, 16))); + log(ID_SEQUENCER, "Masking HCC* module " & to_string(masked_hcc_id) + & ", sending commands to every HCC* module and its ABC* submodules"); + for i in 0 to mask_test_data.inputs_count - 1 loop hcc_id := i / 4; send_elink_command(mask_test_data.inputs(i).data, mask_test_data.inputs(i).count); if masked_hcc_id = hcc_id then - wait for 1000 ns; - assert_idle_only; + wait for 1000 ns; + assert_idle_only; else - verify_elink_command_response(mask_test_data.outputs(i).data, mask_test_data.outputs(i).count); + verify_elink_command_response(mask_test_data.outputs(i).data, mask_test_data.outputs(i).count); end if; + end loop; end loop; - end loop; - - set_register(t_register_name'pos(HCC_MASK), x"0000"); - - log(ID_LOG_HDR, "Verify that ABC* register r/w commands are skipped for " - & "masked chips and not skipped for non-masked chips"); - set_encoding(true); - set_abc_mask(hcc_id => 3, abc_id => 5); - send_abc_reg_read(hcc_id => x"0", abc_id => x"5", addr => x"2B"); - verify_response_length(frame_count => 4); - send_abc_reg_write(hcc_id => x"3", abc_id => x"4", addr => x"2B", data => x"DEADBEEF"); - verify_response_length(frame_count => 9); - send_abc_reg_read(hcc_id => x"3", abc_id => x"5", addr => x"2B"); - assert_idle_only; - send_abc_reg_write(hcc_id => x"3", abc_id => x"5", addr => x"2B", data => x"DEADBEEF"); - assert_idle_only; - reset_lcb_configuration; - reset_abc_hcc_mask; + + set_register(t_register_name'pos(HCC_MASK), x"0000"); + log(ID_LOG_HDR, "Verify that ABC* register r/w commands are skipped for " + & "masked chips and not skipped for non-masked chips"); + set_encoding(true); + set_abc_mask(hcc_id => 3, abc_id => 5); + send_abc_reg_read(hcc_id => x"0", abc_id => x"5", addr => x"2B"); + verify_response_length(frame_count => 4); + send_abc_reg_write(hcc_id => x"3", abc_id => x"4", addr => x"2B", data => x"DEADBEEF"); + verify_response_length(frame_count => 9); + send_abc_reg_read(hcc_id => x"3", abc_id => x"5", addr => x"2B"); + assert_idle_only; + send_abc_reg_write(hcc_id => x"3", abc_id => x"5", addr => x"2B", data => x"DEADBEEF"); + assert_idle_only; + reset_lcb_configuration; + reset_abc_hcc_mask; + else + log(ID_LOG_HDR, "No ASIC reg r/w masking in build - skipping: Verifying that register read/write commands are maskable."); + end if; + -------- verify that TTC L0A signals are ignored when disabled enable_bcr <= '1'; @@ -1112,7 +1133,7 @@ begin verify_elink_command_responses(trickle_test_data_2); - ------ verify that IDLE frames can be stored in trickle configuration memory + ------ verify that IDLE frames can be stored in trickle configuration memory log(ID_LOG_HDR, "Sending a sample calibration sequence"); calibration_data := elink_parser.parse_file("../samples/trickle_calibration_inputs.txt", "../samples/trickle_calibration_outputs.txt"); @@ -1121,10 +1142,14 @@ begin std_logic_vector(to_unsigned(calibration_data.bytes_total, 16))); set_register(t_register_name'pos(TRICKLE_WRITE_ADDR), x"0000"); set_register(t_register_name'pos(TRICKLE_SET_WRITE_ADDR_PULSE), x"0001"); - log(ID_SEQUENCER, "Blocking trickle sequence with gating signal to let thel command decoder catch up"); - set_register(t_register_name'pos(GATING_BC_START), x"0000"); - set_register(t_register_name'pos(GATING_BC_STOP), x"0000"); - set_register(t_register_name'pos(GATING_TTC_ENABLE), x"0000"); + if (CFG_INCLUDE_BCID_GATING = '0') then + log(ID_SEQUENCER, "Blocking trickle sequence with gating signal to let thel command decoder catch up"); + set_register(t_register_name'pos(GATING_BC_START), x"0000"); + set_register(t_register_name'pos(GATING_BC_STOP), x"0000"); + set_register(t_register_name'pos(GATING_TTC_ENABLE), x"0000"); + else + log(ID_SEQUENCER, "No gating in build - using repurposed gating enable to directly block trickle sequence to let the command decoder catch up"); + end if; config.GLOBAL_STRIPS_CONFIG.TTC_GENERATE_GATING_ENABLE <= (others => '1'); wait_num_rising_edge(clk, 50); send_elink_commands(calibration_data, channel => trickle_channel); @@ -1142,6 +1167,7 @@ begin frame_queue.flush(void); wait until rising_edge(clk); + -- priority checks ----- TTC frames take precedence over bypass frames log(ID_LOG_HDR, "Verifying that TTC L0A frames take priority over bypass frames"); @@ -1232,6 +1258,7 @@ begin is_HP_frame_encoded => true); + if (CFG_INCLUDE_BCID_GATING = '1') then -- low-priority frame gating ----- bypass frames respect gating signals enable_bcr <= '1'; @@ -1251,9 +1278,12 @@ begin axistream_transmit(AXISTREAM_VVCT, command_channel, t_slv_array'(x"33", x"33"), "Scheduling bypass frame 0x3333");--@suppress end loop; verify_bc_gating(expected_frame => x"3333"); + else + log(ID_LOG_HDR, "No gating in build - skipping: Verifying that bypass frames respect gating signal"); + end if; - + if (CFG_INCLUDE_BCID_GATING = '1') then ----- decoded elink commands respect gating signals log(ID_LOG_HDR, "Verifying that decoded frames respect gating signal"); set_encoding(true); @@ -1270,8 +1300,12 @@ begin axistream_transmit(AXISTREAM_VVCT, command_channel, t_slv_array'(x"81", x"3A"), "Scheduling fast command");--@suppress end loop; verify_bc_gating(expected_frame => x"6A3A"); + else + log(ID_LOG_HDR, "No gating in build - skipping: Verifying that decoded frames respect gating signal"); + end if; + if (CFG_INCLUDE_BCID_GATING = '1') then --- trickle configuration commands respect gating signals log(ID_LOG_HDR, "Verifying that trickle configuration respects gating signal"); gating_test_frames := 10; @@ -1304,10 +1338,13 @@ begin frame_queue.flush(void); wait for 800 ns; wait until rising_edge(clk); - - --frame_queue.reset(VOID); + else + log(ID_LOG_HDR, "No gating in build - skipping: Verifying that trickle configuration respects gating signal"); + end if; + + if (CFG_INCLUDE_BCID_GATING = '1') then ----- gating guard interval is respected = only complete register read/write command are sent log(ID_LOG_HDR, "Register guard interval test: register read/write commands are not interrupted" & " by bypass frames and complete when read out of trickle configuration memory"); @@ -1349,6 +1386,10 @@ begin wait for 1500 ns; wait until rising_edge(clk); end loop; + else + log(ID_LOG_HDR, "No gating in build - skipping: Register guard interval test: register read/write commands are not interrupted"); + end if; + wait for 1000 ns; diff --git a/sources/ItkStrip/lcb_wrapper.vhd b/sources/ItkStrip/lcb_wrapper.vhd index b3df79ec6..8384860fb 100644 --- a/sources/ItkStrip/lcb_wrapper.vhd +++ b/sources/ItkStrip/lcb_wrapper.vhd @@ -343,48 +343,52 @@ begin ); end generate; + + + + ttc_generate_gating_enable <= + (regmap(GATING_TTC_ENABLE)(0) or config.GLOBAL_STRIPS_CONFIG.TTC_GENERATE_GATING_ENABLE(config.GLOBAL_STRIPS_CONFIG.TTC_GENERATE_GATING_ENABLE'low)) + and + not(config.GLOBAL_STRIPS_CONFIG.TTC_GATING_OVERRIDE(config.GLOBAL_STRIPS_CONFIG.TTC_GATING_OVERRIDE'low)); g_bcidgating_en : if (CFG_INCLUDE_BCID_GATING = '1') generate - ttc_generate_gating_enable <= (regmap(GATING_TTC_ENABLE)(0) - or config.GLOBAL_STRIPS_CONFIG.TTC_GENERATE_GATING_ENABLE(config.GLOBAL_STRIPS_CONFIG.TTC_GENERATE_GATING_ENABLE'low)) - and not config.GLOBAL_STRIPS_CONFIG.TTC_GATING_OVERRIDE(config.GLOBAL_STRIPS_CONFIG.TTC_GATING_OVERRIDE'low); - trickle_trigger_generator : entity work.lcb_trickle_trigger - generic map (guard_window => guard_window_size) -- defined in strips_package.vhd - port map( - clk => clk, -- in - rst => rst, -- in - en_i => ttc_generate_gating_enable, -- in - bcr_i => bcr_i, -- in - bc_start_i => regmap(GATING_BC_START)(t_bcid'range), -- in t_bcid - bc_stop_i => regmap(GATING_BC_STOP)(t_bcid'range), -- in t_bcid - trickle_trigger_o => trickle_trigger_gating, -- out - trickle_allow_register_cmd_o => trickle_allow_register_cmd -- out - ); - else generate -- CFG_INCLUDE_BCID_GATING = '0' - ttc_generate_gating_enable <= '0'; - trickle_trigger_gating <= '1'; - trickle_allow_register_cmd <= '1'; - end generate; + trickle_trigger_generator : entity work.lcb_trickle_trigger + generic map (guard_window => guard_window_size) -- defined in strips_package.vhd + port map( + clk => clk, -- in + rst => rst, -- in + en_i => ttc_generate_gating_enable, -- in + bcr_i => bcr_i, -- in + bc_start_i => regmap(GATING_BC_START)(t_bcid'range), -- in t_bcid + bc_stop_i => regmap(GATING_BC_STOP)(t_bcid'range), -- in t_bcid + trickle_trigger_o => trickle_trigger_gating, -- out + trickle_allow_register_cmd_o => trickle_allow_register_cmd -- out + ); + else generate -- CFG_INCLUDE_BCID_GATING = '0' + --ttc_generate_gating_enable <= '0'; + trickle_trigger_gating <= '0'; + trickle_allow_register_cmd <= '0'; + end generate; scheduler : entity work.lcb_scheduler_encoder port map( clk => clk, rst => rst, - l0a_frame_i => ttc_l0a_frame, - lcb_frame_i => lcb_frame, - lcb_frame_o_rd_en => lcb_frame_rd_en, + l0a_frame_i => ttc_l0a_frame, --(11:0) + lcb_frame_i => lcb_frame, --(12:0) + lcb_frame_o_rd_en => lcb_frame_rd_en, --out lcb_frame_i_empty => lcb_frame_empty, lcb_frame_i_almost_empty => lcb_frame_almost_empty, - l0a_frame_delay_i => regmap(L0A_FRAME_DELAY)(3 downto 2), --AP: I am not sure why this is needed - bypass_frame_i => bypass_frame, + l0a_frame_delay_i => regmap(L0A_FRAME_DELAY)(3 downto 2), --(1:0) --AP: I am not sure why this is needed + bypass_frame_i => bypass_frame, --(15:0) bypass_frame_valid_i => bypass_frame_valid, bypass_frame_ready_o => bypass_frame_ready, frame_start_pulse_i => frame_start_pulse, trickle_bc_gating_i => trickle_trigger_gating, trickle_allow_register_cmd_i => trickle_allow_register_cmd, - trickle_bc_gating_en => ttc_generate_gating_enable, + trickle_bc_gating_en => ttc_generate_gating_enable, -- in ttc_l0a_en => regmap(TTC_L0A_ENABLE)(0), --AP: I am not sure why this is needed - encoded_frame_o => encoded_frame_reg + encoded_frame_o => encoded_frame_reg --(15:0) ); -- serializes LCB frame for 4-bit elink -- GitLab From b9e23eeceeee3dff0e2b5b8dcaa00f5fae61651f Mon Sep 17 00:00:00 2001 From: Frans Schreuder <f.schreuder@nikhef.nl> Date: Wed, 31 Jul 2024 09:35:48 +0200 Subject: [PATCH 3/6] VSG whitespace fix --- simulation/ItkStrip/tb_lcb_axi_encoder.vhd | 314 ++++---- sources/ItkStrip/lcb_wrapper.vhd | 798 ++++++++++----------- sources/ItkStrip/strips_package.vhd | 26 +- 3 files changed, 569 insertions(+), 569 deletions(-) diff --git a/simulation/ItkStrip/tb_lcb_axi_encoder.vhd b/simulation/ItkStrip/tb_lcb_axi_encoder.vhd index 32e653fce..36f7da1dd 100644 --- a/simulation/ItkStrip/tb_lcb_axi_encoder.vhd +++ b/simulation/ItkStrip/tb_lcb_axi_encoder.vhd @@ -754,48 +754,48 @@ begin procedure verify_bc_gating( expected_frame : std_logic_vector(15 downto 0) ) is - begin + begin log(ID_SEQUENCER, "Issuing BCR to start gating pulse generation"); wait until rising_edge(bcr); send_L0A( "0000", "0000000"); --'1', set_stopwatch; dequeue_next_frame; check_value(next_frame.decoded, "100000000000", ERROR, "BCR frame received"); - - if (CFG_INCLUDE_BCID_GATING = '1') then - wait_for_next_frame(expiration_time => (bc_stop + 100) * C_CLK_PERIOD); - log(ID_SEQUENCER, "Received frames, bc_start=" & to_string(bc_start) & ", bc_stop = " & to_string(bc_stop) + + if (CFG_INCLUDE_BCID_GATING = '1') then + wait_for_next_frame(expiration_time => (bc_stop + 100) * C_CLK_PERIOD); + log(ID_SEQUENCER, "Received frames, bc_start=" & to_string(bc_start) & ", bc_stop = " & to_string(bc_stop) & ", stopwatch shows " & to_string(stopwatch_p1)); - check_value(stopwatch_p1 >= bc_start, true, ERROR, "Low-priority frames start around the correct time"); - check_value(stopwatch_p1 <= bc_start + 20, true, ERROR, "Low-priority frames start around the correct time"); - reset_stopwatch; - for i in 0 to gating_test_frames/2 - 1 loop -- half of the frames was supposed to be scheduled - dequeue_next_frame; - check_value(next_frame.encoded, expected_frame, ERROR, "Verifying low-priority frame contents"); - end loop; - wait_num_rising_edge(clk, 40); - check_value(frame_queue.is_empty(void), true, ERROR, "No frames are scheduled after gating interval is over"); - log(ID_SEQUENCER, "Disabling BC gating"); - set_register(t_register_name'pos(GATING_TTC_ENABLE), x"0000"); - for i in 0 to gating_test_frames/2 - 1 loop -- the remaining frames come out because gating is disabled - dequeue_next_frame; - check_value(next_frame.encoded, expected_frame, ERROR, "Verifying remaining low-priority frame contents"); - end loop; + check_value(stopwatch_p1 >= bc_start, true, ERROR, "Low-priority frames start around the correct time"); + check_value(stopwatch_p1 <= bc_start + 20, true, ERROR, "Low-priority frames start around the correct time"); + reset_stopwatch; + for i in 0 to gating_test_frames/2 - 1 loop -- half of the frames was supposed to be scheduled + dequeue_next_frame; + check_value(next_frame.encoded, expected_frame, ERROR, "Verifying low-priority frame contents"); + end loop; + wait_num_rising_edge(clk, 40); + check_value(frame_queue.is_empty(void), true, ERROR, "No frames are scheduled after gating interval is over"); + log(ID_SEQUENCER, "Disabling BC gating"); + set_register(t_register_name'pos(GATING_TTC_ENABLE), x"0000"); + for i in 0 to gating_test_frames/2 - 1 loop -- the remaining frames come out because gating is disabled + dequeue_next_frame; + check_value(next_frame.encoded, expected_frame, ERROR, "Verifying remaining low-priority frame contents"); + end loop; else - for i in 0 to gating_test_frames - 1 loop - dequeue_next_frame; - check_value(next_frame.encoded, expected_frame, ERROR, "Verifying low-priority frame contents"); - end loop; - wait_num_rising_edge(clk, 40); - log(ID_SEQUENCER, "No gating in build - just checking frames"); - for i in 0 to gating_test_frames - 1 loop - dequeue_next_frame; - check_value(next_frame.encoded, expected_frame, ERROR, "Verifying low-priority frame contents"); - end loop; - + for i in 0 to gating_test_frames - 1 loop + dequeue_next_frame; + check_value(next_frame.encoded, expected_frame, ERROR, "Verifying low-priority frame contents"); + end loop; + wait_num_rising_edge(clk, 40); + log(ID_SEQUENCER, "No gating in build - just checking frames"); + for i in 0 to gating_test_frames - 1 loop + dequeue_next_frame; + check_value(next_frame.encoded, expected_frame, ERROR, "Verifying low-priority frame contents"); + end loop; + end if; - + end; --- checks that register frames are always complete when coming from trickle configuration memory @@ -994,21 +994,21 @@ begin mask_test_data := elink_parser.parse_file("../samples/hcc_mask_test_inputs.txt", "../samples/hcc_mask_test_outputs.txt"); for masked_hcc_id in 0 to 15 loop - set_register(t_register_name'pos(HCC_MASK), std_logic_vector(to_unsigned(2 ** masked_hcc_id, 16))); - log(ID_SEQUENCER, "Masking HCC* module " & to_string(masked_hcc_id) + set_register(t_register_name'pos(HCC_MASK), std_logic_vector(to_unsigned(2 ** masked_hcc_id, 16))); + log(ID_SEQUENCER, "Masking HCC* module " & to_string(masked_hcc_id) & ", sending commands to every HCC* module and its ABC* submodules"); - for i in 0 to mask_test_data.inputs_count - 1 loop - hcc_id := i / 4; - send_elink_command(mask_test_data.inputs(i).data, mask_test_data.inputs(i).count); - if masked_hcc_id = hcc_id then - wait for 1000 ns; - assert_idle_only; - else - verify_elink_command_response(mask_test_data.outputs(i).data, mask_test_data.outputs(i).count); - end if; - end loop; + for i in 0 to mask_test_data.inputs_count - 1 loop + hcc_id := i / 4; + send_elink_command(mask_test_data.inputs(i).data, mask_test_data.inputs(i).count); + if masked_hcc_id = hcc_id then + wait for 1000 ns; + assert_idle_only; + else + verify_elink_command_response(mask_test_data.outputs(i).data, mask_test_data.outputs(i).count); + end if; + end loop; end loop; - + set_register(t_register_name'pos(HCC_MASK), x"0000"); log(ID_LOG_HDR, "Verify that ABC* register r/w commands are skipped for " & "masked chips and not skipped for non-masked chips"); @@ -1027,7 +1027,7 @@ begin else log(ID_LOG_HDR, "No ASIC reg r/w masking in build - skipping: Verifying that register read/write commands are maskable."); end if; - + -------- verify that TTC L0A signals are ignored when disabled enable_bcr <= '1'; @@ -1133,7 +1133,7 @@ begin verify_elink_command_responses(trickle_test_data_2); - ------ verify that IDLE frames can be stored in trickle configuration memory + ------ verify that IDLE frames can be stored in trickle configuration memory log(ID_LOG_HDR, "Sending a sample calibration sequence"); calibration_data := elink_parser.parse_file("../samples/trickle_calibration_inputs.txt", "../samples/trickle_calibration_outputs.txt"); @@ -1149,7 +1149,7 @@ begin set_register(t_register_name'pos(GATING_TTC_ENABLE), x"0000"); else log(ID_SEQUENCER, "No gating in build - using repurposed gating enable to directly block trickle sequence to let the command decoder catch up"); - end if; + end if; config.GLOBAL_STRIPS_CONFIG.TTC_GENERATE_GATING_ENABLE <= (others => '1'); wait_num_rising_edge(clk, 50); send_elink_commands(calibration_data, channel => trickle_channel); @@ -1167,7 +1167,7 @@ begin frame_queue.flush(void); wait until rising_edge(clk); - + -- priority checks ----- TTC frames take precedence over bypass frames log(ID_LOG_HDR, "Verifying that TTC L0A frames take priority over bypass frames"); @@ -1259,137 +1259,137 @@ begin if (CFG_INCLUDE_BCID_GATING = '1') then - -- low-priority frame gating - ----- bypass frames respect gating signals - enable_bcr <= '1'; - - log(ID_LOG_HDR, "Verifying that bypass frames respect gating signal"); - set_encoding(false); - gating_test_frames := 40; - bc_start := 176; - bc_stop := bc_start + (gating_test_frames / 2)*4; - shared_axistream_vvc_config(command_channel).bfm_config.max_wait_cycles := bc_stop + 20; - set_register(t_register_name'pos(TTC_L0A_ENABLE), x"0001"); - set_register(t_register_name'pos(GATING_BC_START), std_logic_vector(to_unsigned(bc_start, 16))); - set_register(t_register_name'pos(GATING_BC_STOP), std_logic_vector(to_unsigned(bc_stop, 16))); - set_register(t_register_name'pos(GATING_TTC_ENABLE), x"0001"); - wait_num_rising_edge(clk, 50); - for i in 0 to gating_test_frames - 1 loop -- schedule transmission of all bypass data - axistream_transmit(AXISTREAM_VVCT, command_channel, t_slv_array'(x"33", x"33"), "Scheduling bypass frame 0x3333");--@suppress - end loop; - verify_bc_gating(expected_frame => x"3333"); + -- low-priority frame gating + ----- bypass frames respect gating signals + enable_bcr <= '1'; + + log(ID_LOG_HDR, "Verifying that bypass frames respect gating signal"); + set_encoding(false); + gating_test_frames := 40; + bc_start := 176; + bc_stop := bc_start + (gating_test_frames / 2)*4; + shared_axistream_vvc_config(command_channel).bfm_config.max_wait_cycles := bc_stop + 20; + set_register(t_register_name'pos(TTC_L0A_ENABLE), x"0001"); + set_register(t_register_name'pos(GATING_BC_START), std_logic_vector(to_unsigned(bc_start, 16))); + set_register(t_register_name'pos(GATING_BC_STOP), std_logic_vector(to_unsigned(bc_stop, 16))); + set_register(t_register_name'pos(GATING_TTC_ENABLE), x"0001"); + wait_num_rising_edge(clk, 50); + for i in 0 to gating_test_frames - 1 loop -- schedule transmission of all bypass data + axistream_transmit(AXISTREAM_VVCT, command_channel, t_slv_array'(x"33", x"33"), "Scheduling bypass frame 0x3333");--@suppress + end loop; + verify_bc_gating(expected_frame => x"3333"); else - log(ID_LOG_HDR, "No gating in build - skipping: Verifying that bypass frames respect gating signal"); + log(ID_LOG_HDR, "No gating in build - skipping: Verifying that bypass frames respect gating signal"); end if; if (CFG_INCLUDE_BCID_GATING = '1') then - ----- decoded elink commands respect gating signals - log(ID_LOG_HDR, "Verifying that decoded frames respect gating signal"); - set_encoding(true); - gating_test_frames := 60; - bc_start := 631; - bc_stop := bc_start + (gating_test_frames / 2)*4; - shared_axistream_vvc_config(command_channel).bfm_config.max_wait_cycles := bc_stop + 20; - set_register(t_register_name'pos(TTC_L0A_ENABLE), x"0001"); - set_register(t_register_name'pos(GATING_BC_START), std_logic_vector(to_unsigned(bc_start, 16))); - set_register(t_register_name'pos(GATING_BC_STOP), std_logic_vector(to_unsigned(bc_stop, 16))); - set_register(t_register_name'pos(GATING_TTC_ENABLE), x"0001"); - wait_num_rising_edge(clk, 50); - for i in 0 to gating_test_frames - 1 loop -- schedule transmission of all bypass data - axistream_transmit(AXISTREAM_VVCT, command_channel, t_slv_array'(x"81", x"3A"), "Scheduling fast command");--@suppress - end loop; - verify_bc_gating(expected_frame => x"6A3A"); + ----- decoded elink commands respect gating signals + log(ID_LOG_HDR, "Verifying that decoded frames respect gating signal"); + set_encoding(true); + gating_test_frames := 60; + bc_start := 631; + bc_stop := bc_start + (gating_test_frames / 2)*4; + shared_axistream_vvc_config(command_channel).bfm_config.max_wait_cycles := bc_stop + 20; + set_register(t_register_name'pos(TTC_L0A_ENABLE), x"0001"); + set_register(t_register_name'pos(GATING_BC_START), std_logic_vector(to_unsigned(bc_start, 16))); + set_register(t_register_name'pos(GATING_BC_STOP), std_logic_vector(to_unsigned(bc_stop, 16))); + set_register(t_register_name'pos(GATING_TTC_ENABLE), x"0001"); + wait_num_rising_edge(clk, 50); + for i in 0 to gating_test_frames - 1 loop -- schedule transmission of all bypass data + axistream_transmit(AXISTREAM_VVCT, command_channel, t_slv_array'(x"81", x"3A"), "Scheduling fast command");--@suppress + end loop; + verify_bc_gating(expected_frame => x"6A3A"); else - log(ID_LOG_HDR, "No gating in build - skipping: Verifying that decoded frames respect gating signal"); + log(ID_LOG_HDR, "No gating in build - skipping: Verifying that decoded frames respect gating signal"); end if; if (CFG_INCLUDE_BCID_GATING = '1') then - --- trickle configuration commands respect gating signals - log(ID_LOG_HDR, "Verifying that trickle configuration respects gating signal"); - gating_test_frames := 10; - bc_start := 65; - bc_stop := bc_start + (gating_test_frames / 2)*4; - shared_axistream_vvc_config(trickle_channel).bfm_config.max_wait_cycles := bc_stop + 20; - set_register(t_register_name'pos(TTC_L0A_ENABLE), x"0001"); - set_register(t_register_name'pos(GATING_BC_START), std_logic_vector(to_unsigned(bc_start, 16))); - set_register(t_register_name'pos(GATING_BC_STOP), std_logic_vector(to_unsigned(bc_stop, 16))); - set_register(t_register_name'pos(GATING_TTC_ENABLE), x"0001"); - set_register(t_register_name'pos(TRICKLE_TRIGGER_RUN), x"0000"); - set_register(t_register_name'pos(TRICKLE_DATA_START), x"0000"); - set_register(t_register_name'pos(TRICKLE_DATA_END), std_logic_vector(to_unsigned(gating_test_frames, 16))); - set_register(t_register_name'pos(TRICKLE_WRITE_ADDR), x"0000"); - set_register(t_register_name'pos(TRICKLE_SET_WRITE_ADDR_PULSE), x"0001"); - wait_num_rising_edge(clk, 50); - for i in 0 to gating_test_frames - 1 loop -- schedule transmission of all bypass data - axistream_transmit(AXISTREAM_VVCT, trickle_channel, t_slv_array'(x"81", x"18"),--@suppress + --- trickle configuration commands respect gating signals + log(ID_LOG_HDR, "Verifying that trickle configuration respects gating signal"); + gating_test_frames := 10; + bc_start := 65; + bc_stop := bc_start + (gating_test_frames / 2)*4; + shared_axistream_vvc_config(trickle_channel).bfm_config.max_wait_cycles := bc_stop + 20; + set_register(t_register_name'pos(TTC_L0A_ENABLE), x"0001"); + set_register(t_register_name'pos(GATING_BC_START), std_logic_vector(to_unsigned(bc_start, 16))); + set_register(t_register_name'pos(GATING_BC_STOP), std_logic_vector(to_unsigned(bc_stop, 16))); + set_register(t_register_name'pos(GATING_TTC_ENABLE), x"0001"); + set_register(t_register_name'pos(TRICKLE_TRIGGER_RUN), x"0000"); + set_register(t_register_name'pos(TRICKLE_DATA_START), x"0000"); + set_register(t_register_name'pos(TRICKLE_DATA_END), std_logic_vector(to_unsigned(gating_test_frames, 16))); + set_register(t_register_name'pos(TRICKLE_WRITE_ADDR), x"0000"); + set_register(t_register_name'pos(TRICKLE_SET_WRITE_ADDR_PULSE), x"0001"); + wait_num_rising_edge(clk, 50); + for i in 0 to gating_test_frames - 1 loop -- schedule transmission of all bypass data + axistream_transmit(AXISTREAM_VVCT, trickle_channel, t_slv_array'(x"81", x"18"),--@suppress "Writing fast command to trickle configuration memory"); - end loop; - await_completion(AXISTREAM_VVCT, trickle_channel, gating_test_frames * 2 * 5 * C_CLK_PERIOD,--@suppress + end loop; + await_completion(AXISTREAM_VVCT, trickle_channel, gating_test_frames * 2 * 5 * C_CLK_PERIOD,--@suppress "Waiting for the trickle configuration memory to be written"); - set_register(t_register_name'pos(TRICKLE_TRIGGER_RUN), x"0001"); - verify_bc_gating(expected_frame => x"6AD8"); - -- clean up after using RUN - set_register(t_register_name'pos(TRICKLE_TRIGGER_RUN), x"0000"); - set_register(t_register_name'pos(GATING_TTC_ENABLE), x"0000"); - await_value(trickle_axi.tready, '1', 0 ns, gating_test_frames * 10 * C_CLK_PERIOD, "Waiting for the trickle configuration to complete (1/2)");--@suppress - await_value(frame.idle, '1', 0 ns, 5000 * C_CLK_PERIOD, "Waiting for the trickle configuration to complete (2/2)");--@suppress - frame_queue.flush(void); - wait for 800 ns; - wait until rising_edge(clk); + set_register(t_register_name'pos(TRICKLE_TRIGGER_RUN), x"0001"); + verify_bc_gating(expected_frame => x"6AD8"); + -- clean up after using RUN + set_register(t_register_name'pos(TRICKLE_TRIGGER_RUN), x"0000"); + set_register(t_register_name'pos(GATING_TTC_ENABLE), x"0000"); + await_value(trickle_axi.tready, '1', 0 ns, gating_test_frames * 10 * C_CLK_PERIOD, "Waiting for the trickle configuration to complete (1/2)");--@suppress + await_value(frame.idle, '1', 0 ns, 5000 * C_CLK_PERIOD, "Waiting for the trickle configuration to complete (2/2)");--@suppress + frame_queue.flush(void); + wait for 800 ns; + wait until rising_edge(clk); --frame_queue.reset(VOID); else - log(ID_LOG_HDR, "No gating in build - skipping: Verifying that trickle configuration respects gating signal"); + log(ID_LOG_HDR, "No gating in build - skipping: Verifying that trickle configuration respects gating signal"); end if; if (CFG_INCLUDE_BCID_GATING = '1') then - ----- gating guard interval is respected = only complete register read/write command are sent - log(ID_LOG_HDR, "Register guard interval test: register read/write commands are not interrupted" + ----- gating guard interval is respected = only complete register read/write command are sent + log(ID_LOG_HDR, "Register guard interval test: register read/write commands are not interrupted" & " by bypass frames and complete when read out of trickle configuration memory"); - register_elink_data := elink_parser.parse_file("../samples/register_command_inputs.txt", - "../samples/register_command_outputs.txt"); - shared_axistream_vvc_config(trickle_channel).bfm_config.max_wait_cycles := 1000; - set_encoding(false); - set_register(t_register_name'pos(TTC_L0A_ENABLE), x"0001"); - set_register(t_register_name'pos(TRICKLE_TRIGGER_RUN), x"0000"); - set_register(t_register_name'pos(GATING_TTC_ENABLE), x"0000"); - set_register(t_register_name'pos(TRICKLE_DATA_START), x"0000"); - set_register(t_register_name'pos(TRICKLE_DATA_END), + register_elink_data := elink_parser.parse_file("../samples/register_command_inputs.txt", + "../samples/register_command_outputs.txt"); + shared_axistream_vvc_config(trickle_channel).bfm_config.max_wait_cycles := 1000; + set_encoding(false); + set_register(t_register_name'pos(TTC_L0A_ENABLE), x"0001"); + set_register(t_register_name'pos(TRICKLE_TRIGGER_RUN), x"0000"); + set_register(t_register_name'pos(GATING_TTC_ENABLE), x"0000"); + set_register(t_register_name'pos(TRICKLE_DATA_START), x"0000"); + set_register(t_register_name'pos(TRICKLE_DATA_END), std_logic_vector(to_unsigned(register_elink_data.bytes_total, 16))); - set_register(t_register_name'pos(TRICKLE_WRITE_ADDR), x"0000"); - set_register(t_register_name'pos(TRICKLE_SET_WRITE_ADDR_PULSE), x"0001"); - wait_num_rising_edge(clk, 50); - send_elink_commands(register_elink_data, channel => trickle_channel); - await_completion(AXISTREAM_VVCT, trickle_channel, register_elink_data.bytes_total * 5 * C_CLK_PERIOD,--@suppress - "Waiting for the trickle configuration memory to be written"); - wait_num_rising_edge(clk, 150); - -- configure the trickle config + gating - for i in guard_window_size + 2 to guard_window_size + 52 loop - bc_start := random(13, 20); - bc_stop := bc_start + i*3; - log(ID_SEQUENCER, "Checking frame integrity with bc_start = " & to_string(bc_start) & ", bc_stop = " & to_string(bc_stop)); - set_register(t_register_name'pos(GATING_BC_START), std_logic_vector(to_unsigned(bc_start, 16)), timeout_clk_periods => 5000); - set_register(t_register_name'pos(GATING_BC_STOP), std_logic_vector(to_unsigned(bc_stop, 16)), timeout_clk_periods => 5000); - set_register(t_register_name'pos(GATING_TTC_ENABLE), x"0001", timeout_clk_periods => 5000); - set_register(t_register_name'pos(TRICKLE_TRIGGER_RUN), x"0001", timeout_clk_periods => 5000); + set_register(t_register_name'pos(TRICKLE_WRITE_ADDR), x"0000"); + set_register(t_register_name'pos(TRICKLE_SET_WRITE_ADDR_PULSE), x"0001"); wait_num_rising_edge(clk, 50); - verify_register_frame_completion; --needs BCR - --wait_num_rising_edge(clk, guard_window_size + 10); - set_register(t_register_name'pos(GATING_TTC_ENABLE), x"0000", timeout_clk_periods => 5000); - set_register(t_register_name'pos(TRICKLE_TRIGGER_RUN), x"0000", timeout_clk_periods => 5000); - wait_num_rising_edge(clk, 30); - await_value(frame.idle, '1', 0 ns, 5000 * C_CLK_PERIOD, "Waiting for the trickle configuration to flush out"); --@suppress - frame_queue.flush(void); - --frame_queue.reset(VOID); - wait for 1500 ns; - wait until rising_edge(clk); - end loop; + send_elink_commands(register_elink_data, channel => trickle_channel); + await_completion(AXISTREAM_VVCT, trickle_channel, register_elink_data.bytes_total * 5 * C_CLK_PERIOD,--@suppress + "Waiting for the trickle configuration memory to be written"); + wait_num_rising_edge(clk, 150); + -- configure the trickle config + gating + for i in guard_window_size + 2 to guard_window_size + 52 loop + bc_start := random(13, 20); + bc_stop := bc_start + i*3; + log(ID_SEQUENCER, "Checking frame integrity with bc_start = " & to_string(bc_start) & ", bc_stop = " & to_string(bc_stop)); + set_register(t_register_name'pos(GATING_BC_START), std_logic_vector(to_unsigned(bc_start, 16)), timeout_clk_periods => 5000); + set_register(t_register_name'pos(GATING_BC_STOP), std_logic_vector(to_unsigned(bc_stop, 16)), timeout_clk_periods => 5000); + set_register(t_register_name'pos(GATING_TTC_ENABLE), x"0001", timeout_clk_periods => 5000); + set_register(t_register_name'pos(TRICKLE_TRIGGER_RUN), x"0001", timeout_clk_periods => 5000); + wait_num_rising_edge(clk, 50); + verify_register_frame_completion; --needs BCR + --wait_num_rising_edge(clk, guard_window_size + 10); + set_register(t_register_name'pos(GATING_TTC_ENABLE), x"0000", timeout_clk_periods => 5000); + set_register(t_register_name'pos(TRICKLE_TRIGGER_RUN), x"0000", timeout_clk_periods => 5000); + wait_num_rising_edge(clk, 30); + await_value(frame.idle, '1', 0 ns, 5000 * C_CLK_PERIOD, "Waiting for the trickle configuration to flush out"); --@suppress + frame_queue.flush(void); + --frame_queue.reset(VOID); + wait for 1500 ns; + wait until rising_edge(clk); + end loop; else - log(ID_LOG_HDR, "No gating in build - skipping: Register guard interval test: register read/write commands are not interrupted"); + log(ID_LOG_HDR, "No gating in build - skipping: Register guard interval test: register read/write commands are not interrupted"); end if; - + wait for 1000 ns; diff --git a/sources/ItkStrip/lcb_wrapper.vhd b/sources/ItkStrip/lcb_wrapper.vhd index 8384860fb..6ab02f87f 100644 --- a/sources/ItkStrip/lcb_wrapper.vhd +++ b/sources/ItkStrip/lcb_wrapper.vhd @@ -16,353 +16,353 @@ --! limitations under the License. library ieee; -use ieee.std_logic_1164.all; -use ieee.numeric_std.all; -use work.strips_package.all; -use work.pcie_package.all; -use work.lcb_regmap_package.all; -use work.pcie_package.bitfield_global_strips_config_w_type; + use ieee.std_logic_1164.all; + use ieee.numeric_std.all; + use work.strips_package.all; + use work.pcie_package.all; + use work.lcb_regmap_package.all; + use work.pcie_package.bitfield_global_strips_config_w_type; entity lcb_wrapper is - generic( - USE_ULTRARAM : boolean + generic( + USE_ULTRARAM : boolean ); - port( - clk : in std_logic; - rst : in std_logic; - -- TTC signals - bcr_i : in std_logic; -- BCR signal --AP: This signal needs to be derived from LTI Turn singal, not BCID. - l0a_i : in std_logic; -- L0A signal - l0a_trig_i : in std_logic_vector(3 downto 0); - l0id_i : in std_logic_vector(6 downto 0); -- L0tag - sync_i : in std_logic; --AP: ITk sync pulse from the trigger tage generator - - -- link configuration data source - config_data_i : in std_logic_vector(7 downto 0); -- elink data - config_valid_i : in std_logic; -- elink data is valid this clk cycle - config_ready_o : out std_logic; -- this module is ready for the next elink data - - -- trickle configuration data source - trickle_data_i : in std_logic_vector(7 downto 0); -- elink data - trickle_valid_i : in std_logic; -- elink data is valid this clk cycle - trickle_ready_o : out std_logic; -- this module is ready for the next elink data - - -- elink command data source - command_data_i : in std_logic_vector(7 downto 0); -- elink data - command_valid_i : in std_logic; -- elink data is valid this clk cycle - command_ready_o : out std_logic; -- this module is ready for the next elink data - - -- configuration from global register map - config : in t_strips_config; -- @suppress "Port name 'config' is a keyword in Verilog and may cause problems in mixed language projects" - - -- debug / auxiliary signals - decoder_idle_o : out std_logic; -- command decoder is idle - error_count_o : out std_logic_vector(15 downto 0); -- number of errors encountered by the command decoder since last rst - frame_start_pulse_o : out std_logic; -- marks beginning of the LCB frame (new frame will be loaded next CLK cycle) - ttc_l0a_frame_o : out std_logic_vector(11 downto 0); -- pre-encoded version of L0A frame originated from TTC - ttc_l0a_frame_valid_o : out std_logic; -- is TTC l0a frame valid this clk cycle - trickle_trigger_gating_o : out std_logic; -- trigger BC gating signal - trickle_trigger_o : out std_logic; -- combined trickle trigger signal - register_guard_o : out std_logic; -- trickle register gating signal - regmap_o : out t_register_map; --output for simulation - -- data output for the device - encoded_frame_o : out std_logic_vector(15 downto 0); - edata_o : out std_logic_vector(3 downto 0) + port( + clk : in std_logic; + rst : in std_logic; + -- TTC signals + bcr_i : in std_logic; -- BCR signal --AP: This signal needs to be derived from LTI Turn singal, not BCID. + l0a_i : in std_logic; -- L0A signal + l0a_trig_i : in std_logic_vector(3 downto 0); + l0id_i : in std_logic_vector(6 downto 0); -- L0tag + sync_i : in std_logic; --AP: ITk sync pulse from the trigger tage generator + + -- link configuration data source + config_data_i : in std_logic_vector(7 downto 0); -- elink data + config_valid_i : in std_logic; -- elink data is valid this clk cycle + config_ready_o : out std_logic; -- this module is ready for the next elink data + + -- trickle configuration data source + trickle_data_i : in std_logic_vector(7 downto 0); -- elink data + trickle_valid_i : in std_logic; -- elink data is valid this clk cycle + trickle_ready_o : out std_logic; -- this module is ready for the next elink data + + -- elink command data source + command_data_i : in std_logic_vector(7 downto 0); -- elink data + command_valid_i : in std_logic; -- elink data is valid this clk cycle + command_ready_o : out std_logic; -- this module is ready for the next elink data + + -- configuration from global register map + config : in t_strips_config; -- @suppress "Port name 'config' is a keyword in Verilog and may cause problems in mixed language projects" + + -- debug / auxiliary signals + decoder_idle_o : out std_logic; -- command decoder is idle + error_count_o : out std_logic_vector(15 downto 0); -- number of errors encountered by the command decoder since last rst + frame_start_pulse_o : out std_logic; -- marks beginning of the LCB frame (new frame will be loaded next CLK cycle) + ttc_l0a_frame_o : out std_logic_vector(11 downto 0); -- pre-encoded version of L0A frame originated from TTC + ttc_l0a_frame_valid_o : out std_logic; -- is TTC l0a frame valid this clk cycle + trickle_trigger_gating_o : out std_logic; -- trigger BC gating signal + trickle_trigger_o : out std_logic; -- combined trickle trigger signal + register_guard_o : out std_logic; -- trickle register gating signal + regmap_o : out t_register_map; --output for simulation + -- data output for the device + encoded_frame_o : out std_logic_vector(15 downto 0); + edata_o : out std_logic_vector(3 downto 0) ); end entity lcb_wrapper; architecture RTL of lcb_wrapper is - -- LCB frame generator signals - signal lcb_gen_cmd : t_lcb_command; -- which command to execute - signal lcb_gen_cmd_start_pulse : std_logic; -- pulse for 1 clk cycle to start command - signal lcb_gen_fast_cmd_data : std_logic_vector(5 downto 0); -- bc & cmd - signal lcb_gen_l0a_data : std_logic_vector(11 downto 0); -- bcr & L0A mask & L0 tag - signal lcb_gen_abc_id : std_logic_vector(3 downto 0); -- ABC* address (0xF = broadcast) - signal lcb_gen_hcc_id : std_logic_vector(3 downto 0); -- HCC* address (0xF = broadcast) - signal lcb_gen_reg_addr : std_logic_vector(7 downto 0); -- register address for reg. read/write - signal lcb_gen_reg_data : std_logic_vector(31 downto 0); -- register data for reg. write - signal lcb_gen_ready : std_logic; -- indicates it's ready for a new command - signal lcb_frame : std_logic_vector(12 downto 0); -- FIFO data out - signal lcb_frame_rd_en : std_logic; -- FIFO rd_en signal - signal lcb_frame_empty : std_logic; -- FIFO empty signal - signal lcb_frame_almost_empty : std_logic; -- FIFO contains one word - signal lcb_frame_fifo_almost_full : std_logic; -- FIFO is almost full - signal abc_mask : t_abc_mask; - signal edata_s : std_logic_vector(3 downto 0); - - signal ttc_generate_gating_enable : std_logic; - - signal regmap : t_register_map; - signal regmap_wr_en : std_logic; - signal regmap_data : std_logic_vector(t_register_data'range); - signal regmap_addr : std_logic_vector(7 downto 0); - - signal bypass_frame : std_logic_vector(15 downto 0); - signal bypass_frame_ready : std_logic; - signal bypass_frame_valid : std_logic; - - signal trickle_data_o : std_logic_vector(playback_controller_data'range); - signal trickle_valid_o : std_logic; - signal trickle_ready_i : std_logic; - signal trickle_trigger_start : std_logic; - signal trickle_allow_register_cmd : std_logic; - signal trickle_trigger_gating : std_logic; - - -- L0A generator signals - signal ttc_l0a_frame : std_logic_vector(11 downto 0); - signal frame_start_pulse : std_logic; - - -- serializer registers - signal serializer_reg : std_logic_vector(encoded_frame_o'range) := (others => '0'); - signal encoded_frame_reg : std_logic_vector(encoded_frame_o'range); - - -- bypass command and firmware encoded command lines - signal encoding : std_logic; - signal encoded_cmd : std_logic_vector(7 downto 0); - signal encoded_cmd_valid : std_logic; - signal encoded_cmd_ready : std_logic; - - signal bypass_cmd : std_logic_vector(7 downto 0); - signal bypass_cmd_valid : std_logic; - signal bypass_cmd_ready : std_logic; - - -- edata_o fine delay types and registers - signal edata_delay : std_logic_vector(1 downto 0); - type t_edata_array is array (natural range <>) of std_logic_vector(3 downto 0); - signal edata_delay_reg : t_edata_array(1 to 3) := (others => (others => '0')); - - signal invert_output : boolean := false; + -- LCB frame generator signals + signal lcb_gen_cmd : t_lcb_command; -- which command to execute + signal lcb_gen_cmd_start_pulse : std_logic; -- pulse for 1 clk cycle to start command + signal lcb_gen_fast_cmd_data : std_logic_vector(5 downto 0); -- bc & cmd + signal lcb_gen_l0a_data : std_logic_vector(11 downto 0); -- bcr & L0A mask & L0 tag + signal lcb_gen_abc_id : std_logic_vector(3 downto 0); -- ABC* address (0xF = broadcast) + signal lcb_gen_hcc_id : std_logic_vector(3 downto 0); -- HCC* address (0xF = broadcast) + signal lcb_gen_reg_addr : std_logic_vector(7 downto 0); -- register address for reg. read/write + signal lcb_gen_reg_data : std_logic_vector(31 downto 0); -- register data for reg. write + signal lcb_gen_ready : std_logic; -- indicates it's ready for a new command + signal lcb_frame : std_logic_vector(12 downto 0); -- FIFO data out + signal lcb_frame_rd_en : std_logic; -- FIFO rd_en signal + signal lcb_frame_empty : std_logic; -- FIFO empty signal + signal lcb_frame_almost_empty : std_logic; -- FIFO contains one word + signal lcb_frame_fifo_almost_full : std_logic; -- FIFO is almost full + signal abc_mask : t_abc_mask; + signal edata_s : std_logic_vector(3 downto 0); + + signal ttc_generate_gating_enable : std_logic; + + signal regmap : t_register_map; + signal regmap_wr_en : std_logic; + signal regmap_data : std_logic_vector(t_register_data'range); + signal regmap_addr : std_logic_vector(7 downto 0); + + signal bypass_frame : std_logic_vector(15 downto 0); + signal bypass_frame_ready : std_logic; + signal bypass_frame_valid : std_logic; + + signal trickle_data_o : std_logic_vector(playback_controller_data'range); + signal trickle_valid_o : std_logic; + signal trickle_ready_i : std_logic; + signal trickle_trigger_start : std_logic; + signal trickle_allow_register_cmd : std_logic; + signal trickle_trigger_gating : std_logic; + + -- L0A generator signals + signal ttc_l0a_frame : std_logic_vector(11 downto 0); + signal frame_start_pulse : std_logic; + + -- serializer registers + signal serializer_reg : std_logic_vector(encoded_frame_o'range) := (others => '0'); + signal encoded_frame_reg : std_logic_vector(encoded_frame_o'range); + + -- bypass command and firmware encoded command lines + signal encoding : std_logic; + signal encoded_cmd : std_logic_vector(7 downto 0); + signal encoded_cmd_valid : std_logic; + signal encoded_cmd_ready : std_logic; + + signal bypass_cmd : std_logic_vector(7 downto 0); + signal bypass_cmd_valid : std_logic; + signal bypass_cmd_ready : std_logic; + + -- edata_o fine delay types and registers + signal edata_delay : std_logic_vector(1 downto 0); + type t_edata_array is array (natural range <>) of std_logic_vector(3 downto 0); + signal edata_delay_reg : t_edata_array(1 to 3) := (others => (others => '0')); + + signal invert_output : boolean := false; --constant zero_byte : std_logic_vector(7 downto 0) := (others => '0'); begin - encoded_frame_o <= encoded_frame_reg; - trickle_trigger_o <= trickle_trigger_start; - register_guard_o <= trickle_allow_register_cmd; - trickle_trigger_start <= regmap(TRICKLE_TRIGGER_PULSE)(0) - or config.GLOBAL_TRICKLE_TRIGGER(config.GLOBAL_TRICKLE_TRIGGER'low) - or regmap(TRICKLE_TRIGGER_RUN)(0); - - edata_delay <= regmap(L0A_FRAME_DELAY)(edata_delay'range); - - frame_start_pulse_o <= frame_start_pulse; - ttc_l0a_frame_o <= ttc_l0a_frame; - ttc_l0a_frame_valid_o <= ttc_l0a_frame(11) or ttc_l0a_frame(10) or ttc_l0a_frame(9) or ttc_l0a_frame(8) or ttc_l0a_frame(7); - trickle_trigger_gating_o <= trickle_trigger_gating; - - invert_output <= config.GLOBAL_STRIPS_CONFIG.INVERT_LCB_OUT( - config.GLOBAL_STRIPS_CONFIG.INVERT_LCB_OUT'low) = '1'; - - ttc_l0a_generator : entity work.l0a_frame_generator - port map( - clk => clk, - rst => rst, - bcr_i => bcr_i, - l0a_i => l0a_i, - l0a_trig_i => l0a_trig_i, - bcr_delay_i => unsigned(regmap(TTC_BCR_DELAY)(t_bcid'range)), --AP: THis needs to be a global FELIX tegister - frame_phase_i => unsigned(regmap(L0A_FRAME_PHASE)(1 downto 0)), --AP: This needs to be done somewhere else - l0id_i => l0id_i, - frame_start_pulse_o => frame_start_pulse, - ITk_sync_i => sync_i, - l0a_frame_o => ttc_l0a_frame - ); - - encoding <= regmap(ENCODING_ENABLE)(0); - - cmd_destination_selector_mux : - process(encoding, command_data_i, command_valid_i, bypass_cmd_ready, encoded_cmd_ready) is - begin - if encoding = '0' then - encoded_cmd <= (others => '0'); - encoded_cmd_valid <= '0'; - bypass_cmd <= command_data_i; - bypass_cmd_valid <= command_valid_i; - command_ready_o <= bypass_cmd_ready; - else - encoded_cmd <= command_data_i; - encoded_cmd_valid <= command_valid_i; - bypass_cmd <= (others => '0'); - bypass_cmd_valid <= '0'; - command_ready_o <= encoded_cmd_ready; - end if; - end process; - - bypass_frame_generator : entity work.strips_bypass_frame_aggregator - generic map( - TIMEOUT => 4000 - ) - port map( - clk => clk, - rst => rst, - byte_i => bypass_cmd, - byte_valid_i => bypass_cmd_valid, - byte_ready_o => bypass_cmd_ready, - frame_o => bypass_frame, - frame_valid_o => bypass_frame_valid, - frame_ready_i => bypass_frame_ready - ); - - configuration_decoder : entity work.strips_configuration_decoder - generic map( - TIMEOUT => 4000 - ) - port map( - clk => clk, - rst => rst, - config_data_i => config_data_i, - config_valid_i => config_valid_i, - config_ready_o => config_ready_o, - regmap_wr_en_o => regmap_wr_en, - regmap_data_o => regmap_data, - regmap_addr_o => regmap_addr - ); - - command_decoder : entity work.lcb_command_decoder - generic map( - TIMEOUT => 4000 - ) - port map( - clk => clk, - rst => rst, - elink_data_i => encoded_cmd, - elink_valid_i => encoded_cmd_valid, - elink_ready_o => encoded_cmd_ready, - trickle_data_i => trickle_data_o, - trickle_valid_i => trickle_valid_o, - trickle_ready_o => trickle_ready_i, - lcb_cmd_o => lcb_gen_cmd, - lcb_cmd_start_pulse_o => lcb_gen_cmd_start_pulse, - lcb_fast_cmd_data_o => lcb_gen_fast_cmd_data, - lcb_l0a_data_o => lcb_gen_l0a_data, - lcb_abc_id_o => lcb_gen_abc_id, - lcb_hcc_id_o => lcb_gen_hcc_id, - lcb_reg_addr_o => lcb_gen_reg_addr, - lcb_reg_data_o => lcb_gen_reg_data, - lcb_ready_i => lcb_gen_ready, - lcb_frame_fifo_almost_full_i => lcb_frame_fifo_almost_full, - decoder_idle_o => decoder_idle_o, - error_count_o => error_count_o - ); - - register_map : entity work.lcb_regmap - port map ( - clk => clk, - rst => rst, - wr_en => regmap_wr_en, - data_i => regmap_data, - addr_i => regmap_addr, - regmap_o => regmap - ); - - regmap_o <= regmap; - - playback_controller : entity work.playback_controller - generic map( - USE_ULTRARAM => USE_ULTRARAM - ) - port map( - clk => clk, - rst => rst, - start_pulse_i => trickle_trigger_start, - readout_active_o => open, - playback_loops_i => regmap(PLAYBACK_LOOPS), - data_i => trickle_data_i, - valid_i => trickle_valid_i, - ready_o => trickle_ready_o, - set_write_addr_pulse_i => regmap(TRICKLE_SET_WRITE_ADDR_PULSE)(0), - write_addr_start_i => regmap(TRICKLE_WRITE_ADDR)(playback_controller_address'range), - read_addr_start_i => regmap(TRICKLE_DATA_START)(playback_controller_address'range), - read_addr_stop_i => regmap(TRICKLE_DATA_END)(playback_controller_address'range), - data_o => trickle_data_o, - valid_o => trickle_valid_o, - ready_i => trickle_ready_i - ); - - abc_mask(15) <= regmap(ABC_MASK_F); - abc_mask(14) <= regmap(ABC_MASK_E); - abc_mask(13) <= regmap(ABC_MASK_D); - abc_mask(12) <= regmap(ABC_MASK_C); - abc_mask(11) <= regmap(ABC_MASK_B); - abc_mask(10) <= regmap(ABC_MASK_A); - abc_mask(9) <= regmap(ABC_MASK_9); - abc_mask(8) <= regmap(ABC_MASK_8); - abc_mask(7) <= regmap(ABC_MASK_7); - abc_mask(6) <= regmap(ABC_MASK_6); - abc_mask(5) <= regmap(ABC_MASK_5); - abc_mask(4) <= regmap(ABC_MASK_4); - abc_mask(3) <= regmap(ABC_MASK_3); - abc_mask(2) <= regmap(ABC_MASK_2); - abc_mask(1) <= regmap(ABC_MASK_1); - abc_mask(0) <= regmap(ABC_MASK_0); - - g_modulemasksen : if (CFG_INCLUDE_ASIC_MASKS = '1') generate - frame_generator : entity work.lcb_frame_generator - port map( - clk => clk, - rst => rst, - cmd_i => lcb_gen_cmd, - cmd_start_pulse_i => lcb_gen_cmd_start_pulse, - fast_cmd_data_i => lcb_gen_fast_cmd_data, - hcc_mask_i => regmap(HCC_MASK), - abc_mask_i => abc_mask, - l0a_data_i => lcb_gen_l0a_data, - abc_id_i => lcb_gen_abc_id, - hcc_id_i => lcb_gen_hcc_id, - reg_addr_i => lcb_gen_reg_addr, - reg_data_i => lcb_gen_reg_data, - ready_o => lcb_gen_ready, - lcb_frame_o => lcb_frame, - lcb_frame_i_rd_en => lcb_frame_rd_en, - lcb_frame_o_empty => lcb_frame_empty, - lcb_frame_o_almost_empty => lcb_frame_almost_empty, - lcb_frame_fifo_almost_full_o => lcb_frame_fifo_almost_full + encoded_frame_o <= encoded_frame_reg; + trickle_trigger_o <= trickle_trigger_start; + register_guard_o <= trickle_allow_register_cmd; + trickle_trigger_start <= regmap(TRICKLE_TRIGGER_PULSE)(0) + or config.GLOBAL_TRICKLE_TRIGGER(config.GLOBAL_TRICKLE_TRIGGER'low) + or regmap(TRICKLE_TRIGGER_RUN)(0); + + edata_delay <= regmap(L0A_FRAME_DELAY)(edata_delay'range); + + frame_start_pulse_o <= frame_start_pulse; + ttc_l0a_frame_o <= ttc_l0a_frame; + ttc_l0a_frame_valid_o <= ttc_l0a_frame(11) or ttc_l0a_frame(10) or ttc_l0a_frame(9) or ttc_l0a_frame(8) or ttc_l0a_frame(7); + trickle_trigger_gating_o <= trickle_trigger_gating; + + invert_output <= config.GLOBAL_STRIPS_CONFIG.INVERT_LCB_OUT( + config.GLOBAL_STRIPS_CONFIG.INVERT_LCB_OUT'low) = '1'; + + ttc_l0a_generator : entity work.l0a_frame_generator + port map( + clk => clk, + rst => rst, + bcr_i => bcr_i, + l0a_i => l0a_i, + l0a_trig_i => l0a_trig_i, + bcr_delay_i => unsigned(regmap(TTC_BCR_DELAY)(t_bcid'range)), --AP: THis needs to be a global FELIX tegister + frame_phase_i => unsigned(regmap(L0A_FRAME_PHASE)(1 downto 0)), --AP: This needs to be done somewhere else + l0id_i => l0id_i, + frame_start_pulse_o => frame_start_pulse, + ITk_sync_i => sync_i, + l0a_frame_o => ttc_l0a_frame ); - else generate --CFG_INCLUDE_ASIC_MASKS = '0' - frame_generator : entity work.lcb_frame_generator - port map( - clk => clk, - rst => rst, - cmd_i => lcb_gen_cmd, - cmd_start_pulse_i => lcb_gen_cmd_start_pulse, - fast_cmd_data_i => lcb_gen_fast_cmd_data, - hcc_mask_i => (others => '0'), - abc_mask_i => (others => (others => '0')), - l0a_data_i => lcb_gen_l0a_data, - abc_id_i => lcb_gen_abc_id, - hcc_id_i => lcb_gen_hcc_id, - reg_addr_i => lcb_gen_reg_addr, - reg_data_i => lcb_gen_reg_data, - ready_o => lcb_gen_ready, - lcb_frame_o => lcb_frame, - lcb_frame_i_rd_en => lcb_frame_rd_en, - lcb_frame_o_empty => lcb_frame_empty, - lcb_frame_o_almost_empty => lcb_frame_almost_empty, - lcb_frame_fifo_almost_full_o => lcb_frame_fifo_almost_full + + encoding <= regmap(ENCODING_ENABLE)(0); + + cmd_destination_selector_mux : + process(encoding, command_data_i, command_valid_i, bypass_cmd_ready, encoded_cmd_ready) is + begin + if encoding = '0' then + encoded_cmd <= (others => '0'); + encoded_cmd_valid <= '0'; + bypass_cmd <= command_data_i; + bypass_cmd_valid <= command_valid_i; + command_ready_o <= bypass_cmd_ready; + else + encoded_cmd <= command_data_i; + encoded_cmd_valid <= command_valid_i; + bypass_cmd <= (others => '0'); + bypass_cmd_valid <= '0'; + command_ready_o <= encoded_cmd_ready; + end if; + end process; + + bypass_frame_generator : entity work.strips_bypass_frame_aggregator + generic map( + TIMEOUT => 4000 + ) + port map( + clk => clk, + rst => rst, + byte_i => bypass_cmd, + byte_valid_i => bypass_cmd_valid, + byte_ready_o => bypass_cmd_ready, + frame_o => bypass_frame, + frame_valid_o => bypass_frame_valid, + frame_ready_i => bypass_frame_ready + ); + + configuration_decoder : entity work.strips_configuration_decoder + generic map( + TIMEOUT => 4000 + ) + port map( + clk => clk, + rst => rst, + config_data_i => config_data_i, + config_valid_i => config_valid_i, + config_ready_o => config_ready_o, + regmap_wr_en_o => regmap_wr_en, + regmap_data_o => regmap_data, + regmap_addr_o => regmap_addr + ); + + command_decoder : entity work.lcb_command_decoder + generic map( + TIMEOUT => 4000 + ) + port map( + clk => clk, + rst => rst, + elink_data_i => encoded_cmd, + elink_valid_i => encoded_cmd_valid, + elink_ready_o => encoded_cmd_ready, + trickle_data_i => trickle_data_o, + trickle_valid_i => trickle_valid_o, + trickle_ready_o => trickle_ready_i, + lcb_cmd_o => lcb_gen_cmd, + lcb_cmd_start_pulse_o => lcb_gen_cmd_start_pulse, + lcb_fast_cmd_data_o => lcb_gen_fast_cmd_data, + lcb_l0a_data_o => lcb_gen_l0a_data, + lcb_abc_id_o => lcb_gen_abc_id, + lcb_hcc_id_o => lcb_gen_hcc_id, + lcb_reg_addr_o => lcb_gen_reg_addr, + lcb_reg_data_o => lcb_gen_reg_data, + lcb_ready_i => lcb_gen_ready, + lcb_frame_fifo_almost_full_i => lcb_frame_fifo_almost_full, + decoder_idle_o => decoder_idle_o, + error_count_o => error_count_o + ); + + register_map : entity work.lcb_regmap + port map ( + clk => clk, + rst => rst, + wr_en => regmap_wr_en, + data_i => regmap_data, + addr_i => regmap_addr, + regmap_o => regmap + ); + + regmap_o <= regmap; + + playback_controller : entity work.playback_controller + generic map( + USE_ULTRARAM => USE_ULTRARAM + ) + port map( + clk => clk, + rst => rst, + start_pulse_i => trickle_trigger_start, + readout_active_o => open, + playback_loops_i => regmap(PLAYBACK_LOOPS), + data_i => trickle_data_i, + valid_i => trickle_valid_i, + ready_o => trickle_ready_o, + set_write_addr_pulse_i => regmap(TRICKLE_SET_WRITE_ADDR_PULSE)(0), + write_addr_start_i => regmap(TRICKLE_WRITE_ADDR)(playback_controller_address'range), + read_addr_start_i => regmap(TRICKLE_DATA_START)(playback_controller_address'range), + read_addr_stop_i => regmap(TRICKLE_DATA_END)(playback_controller_address'range), + data_o => trickle_data_o, + valid_o => trickle_valid_o, + ready_i => trickle_ready_i ); - end generate; - - - - - ttc_generate_gating_enable <= - (regmap(GATING_TTC_ENABLE)(0) or config.GLOBAL_STRIPS_CONFIG.TTC_GENERATE_GATING_ENABLE(config.GLOBAL_STRIPS_CONFIG.TTC_GENERATE_GATING_ENABLE'low)) - and - not(config.GLOBAL_STRIPS_CONFIG.TTC_GATING_OVERRIDE(config.GLOBAL_STRIPS_CONFIG.TTC_GATING_OVERRIDE'low)); - g_bcidgating_en : if (CFG_INCLUDE_BCID_GATING = '1') generate - trickle_trigger_generator : entity work.lcb_trickle_trigger - generic map (guard_window => guard_window_size) -- defined in strips_package.vhd - port map( - clk => clk, -- in - rst => rst, -- in - en_i => ttc_generate_gating_enable, -- in - bcr_i => bcr_i, -- in - bc_start_i => regmap(GATING_BC_START)(t_bcid'range), -- in t_bcid - bc_stop_i => regmap(GATING_BC_STOP)(t_bcid'range), -- in t_bcid - trickle_trigger_o => trickle_trigger_gating, -- out - trickle_allow_register_cmd_o => trickle_allow_register_cmd -- out - ); + + abc_mask(15) <= regmap(ABC_MASK_F); + abc_mask(14) <= regmap(ABC_MASK_E); + abc_mask(13) <= regmap(ABC_MASK_D); + abc_mask(12) <= regmap(ABC_MASK_C); + abc_mask(11) <= regmap(ABC_MASK_B); + abc_mask(10) <= regmap(ABC_MASK_A); + abc_mask(9) <= regmap(ABC_MASK_9); + abc_mask(8) <= regmap(ABC_MASK_8); + abc_mask(7) <= regmap(ABC_MASK_7); + abc_mask(6) <= regmap(ABC_MASK_6); + abc_mask(5) <= regmap(ABC_MASK_5); + abc_mask(4) <= regmap(ABC_MASK_4); + abc_mask(3) <= regmap(ABC_MASK_3); + abc_mask(2) <= regmap(ABC_MASK_2); + abc_mask(1) <= regmap(ABC_MASK_1); + abc_mask(0) <= regmap(ABC_MASK_0); + + g_modulemasksen : if (CFG_INCLUDE_ASIC_MASKS = '1') generate + frame_generator : entity work.lcb_frame_generator + port map( + clk => clk, + rst => rst, + cmd_i => lcb_gen_cmd, + cmd_start_pulse_i => lcb_gen_cmd_start_pulse, + fast_cmd_data_i => lcb_gen_fast_cmd_data, + hcc_mask_i => regmap(HCC_MASK), + abc_mask_i => abc_mask, + l0a_data_i => lcb_gen_l0a_data, + abc_id_i => lcb_gen_abc_id, + hcc_id_i => lcb_gen_hcc_id, + reg_addr_i => lcb_gen_reg_addr, + reg_data_i => lcb_gen_reg_data, + ready_o => lcb_gen_ready, + lcb_frame_o => lcb_frame, + lcb_frame_i_rd_en => lcb_frame_rd_en, + lcb_frame_o_empty => lcb_frame_empty, + lcb_frame_o_almost_empty => lcb_frame_almost_empty, + lcb_frame_fifo_almost_full_o => lcb_frame_fifo_almost_full + ); + else generate --CFG_INCLUDE_ASIC_MASKS = '0' + frame_generator : entity work.lcb_frame_generator + port map( + clk => clk, + rst => rst, + cmd_i => lcb_gen_cmd, + cmd_start_pulse_i => lcb_gen_cmd_start_pulse, + fast_cmd_data_i => lcb_gen_fast_cmd_data, + hcc_mask_i => (others => '0'), + abc_mask_i => (others => (others => '0')), + l0a_data_i => lcb_gen_l0a_data, + abc_id_i => lcb_gen_abc_id, + hcc_id_i => lcb_gen_hcc_id, + reg_addr_i => lcb_gen_reg_addr, + reg_data_i => lcb_gen_reg_data, + ready_o => lcb_gen_ready, + lcb_frame_o => lcb_frame, + lcb_frame_i_rd_en => lcb_frame_rd_en, + lcb_frame_o_empty => lcb_frame_empty, + lcb_frame_o_almost_empty => lcb_frame_almost_empty, + lcb_frame_fifo_almost_full_o => lcb_frame_fifo_almost_full + ); + end generate; + + + + + ttc_generate_gating_enable <= + (regmap(GATING_TTC_ENABLE)(0) or config.GLOBAL_STRIPS_CONFIG.TTC_GENERATE_GATING_ENABLE(config.GLOBAL_STRIPS_CONFIG.TTC_GENERATE_GATING_ENABLE'low)) + and + not(config.GLOBAL_STRIPS_CONFIG.TTC_GATING_OVERRIDE(config.GLOBAL_STRIPS_CONFIG.TTC_GATING_OVERRIDE'low)); + g_bcidgating_en : if (CFG_INCLUDE_BCID_GATING = '1') generate + trickle_trigger_generator : entity work.lcb_trickle_trigger + generic map (guard_window => guard_window_size) -- defined in strips_package.vhd + port map( + clk => clk, -- in + rst => rst, -- in + en_i => ttc_generate_gating_enable, -- in + bcr_i => bcr_i, -- in + bc_start_i => regmap(GATING_BC_START)(t_bcid'range), -- in t_bcid + bc_stop_i => regmap(GATING_BC_STOP)(t_bcid'range), -- in t_bcid + trickle_trigger_o => trickle_trigger_gating, -- out + trickle_allow_register_cmd_o => trickle_allow_register_cmd -- out + ); else generate -- CFG_INCLUDE_BCID_GATING = '0' --ttc_generate_gating_enable <= '0'; trickle_trigger_gating <= '0'; @@ -370,74 +370,74 @@ begin end generate; - scheduler : entity work.lcb_scheduler_encoder - port map( - clk => clk, - rst => rst, - l0a_frame_i => ttc_l0a_frame, --(11:0) - lcb_frame_i => lcb_frame, --(12:0) - lcb_frame_o_rd_en => lcb_frame_rd_en, --out - lcb_frame_i_empty => lcb_frame_empty, - lcb_frame_i_almost_empty => lcb_frame_almost_empty, - l0a_frame_delay_i => regmap(L0A_FRAME_DELAY)(3 downto 2), --(1:0) --AP: I am not sure why this is needed - bypass_frame_i => bypass_frame, --(15:0) - bypass_frame_valid_i => bypass_frame_valid, - bypass_frame_ready_o => bypass_frame_ready, - frame_start_pulse_i => frame_start_pulse, - trickle_bc_gating_i => trickle_trigger_gating, - trickle_allow_register_cmd_i => trickle_allow_register_cmd, - trickle_bc_gating_en => ttc_generate_gating_enable, -- in - ttc_l0a_en => regmap(TTC_L0A_ENABLE)(0), --AP: I am not sure why this is needed - encoded_frame_o => encoded_frame_reg --(15:0) - ); - - -- serializes LCB frame for 4-bit elink - serializer : process(clk) is - begin - if rising_edge(clk) then - if rst = '1' then - serializer_reg <= (others => '0'); - else - if frame_start_pulse = '1' then - serializer_reg <= encoded_frame_reg; - else - serializer_reg(15 downto 4) <= serializer_reg(11 downto 0); + scheduler : entity work.lcb_scheduler_encoder + port map( + clk => clk, + rst => rst, + l0a_frame_i => ttc_l0a_frame, --(11:0) + lcb_frame_i => lcb_frame, --(12:0) + lcb_frame_o_rd_en => lcb_frame_rd_en, --out + lcb_frame_i_empty => lcb_frame_empty, + lcb_frame_i_almost_empty => lcb_frame_almost_empty, + l0a_frame_delay_i => regmap(L0A_FRAME_DELAY)(3 downto 2), --(1:0) --AP: I am not sure why this is needed + bypass_frame_i => bypass_frame, --(15:0) + bypass_frame_valid_i => bypass_frame_valid, + bypass_frame_ready_o => bypass_frame_ready, + frame_start_pulse_i => frame_start_pulse, + trickle_bc_gating_i => trickle_trigger_gating, + trickle_allow_register_cmd_i => trickle_allow_register_cmd, + trickle_bc_gating_en => ttc_generate_gating_enable, -- in + ttc_l0a_en => regmap(TTC_L0A_ENABLE)(0), --AP: I am not sure why this is needed + encoded_frame_o => encoded_frame_reg --(15:0) + ); + + -- serializes LCB frame for 4-bit elink + serializer : process(clk) is + begin + if rising_edge(clk) then + if rst = '1' then + serializer_reg <= (others => '0'); + else + if frame_start_pulse = '1' then + serializer_reg <= encoded_frame_reg; + else + serializer_reg(15 downto 4) <= serializer_reg(11 downto 0); + end if; + end if; end if; - end if; - end if; - end process; - - -- Saves delayed elink data by up to 3 BC CLK cycles - edata_delay_proc : process(clk) is - begin - if rising_edge(clk) then - if rst = '1' then - edata_delay_reg <= (others => (others => '0')); - else - edata_delay_reg(1) <= serializer_reg(15 downto 12); - edata_delay_reg(2 to edata_delay_reg'high) <= edata_delay_reg(1 to edata_delay_reg'high - 1); - end if; - end if; - end process; - - -- Outputs elink data with a configurable delay - edata_output : process(clk) is - variable delay_int : integer range 0 to 3; - begin - if rising_edge(clk) then - if (rst = '1') then - edata_s <= (others => '0'); - else - delay_int := to_integer(unsigned(edata_delay)); - if delay_int = 0 then - edata_s <= serializer_reg(15 downto 12); - else - edata_s <= edata_delay_reg(delay_int); + end process; + + -- Saves delayed elink data by up to 3 BC CLK cycles + edata_delay_proc : process(clk) is + begin + if rising_edge(clk) then + if rst = '1' then + edata_delay_reg <= (others => (others => '0')); + else + edata_delay_reg(1) <= serializer_reg(15 downto 12); + edata_delay_reg(2 to edata_delay_reg'high) <= edata_delay_reg(1 to edata_delay_reg'high - 1); + end if; + end if; + end process; + + -- Outputs elink data with a configurable delay + edata_output : process(clk) is + variable delay_int : integer range 0 to 3; + begin + if rising_edge(clk) then + if (rst = '1') then + edata_s <= (others => '0'); + else + delay_int := to_integer(unsigned(edata_delay)); + if delay_int = 0 then + edata_s <= serializer_reg(15 downto 12); + else + edata_s <= edata_delay_reg(delay_int); + end if; + end if; end if; - end if; - end if; - end process; + end process; - edata_o <= not edata_s when invert_output else edata_s; + edata_o <= not edata_s when invert_output else edata_s; end architecture RTL; diff --git a/sources/ItkStrip/strips_package.vhd b/sources/ItkStrip/strips_package.vhd index 5e6bb3014..4376c95e2 100644 --- a/sources/ItkStrip/strips_package.vhd +++ b/sources/ItkStrip/strips_package.vhd @@ -44,19 +44,19 @@ library IEEE; package strips_package is - -- Build settings for LCB encoders: - constant CFG_INCLUDE_BCID_GATING : std_logic := '0'; - constant CFG_INCLUDE_ASIC_MASKS : std_logic := '0'; - constant CFG_SEQRAM_ADDR_WIDTH : natural := 12; -- 4kB - --13; -- 8kB - --14; --16kB - - constant STRIPS_ENCODING_CFG_MON_REG : std_logic_vector(31 downto 0) := - x"000000" & - std_logic_vector(to_unsigned(CFG_SEQRAM_ADDR_WIDTH,4)) & - "00" & - CFG_INCLUDE_ASIC_MASKS & - CFG_INCLUDE_BCID_GATING; + -- Build settings for LCB encoders: + constant CFG_INCLUDE_BCID_GATING : std_logic := '0'; + constant CFG_INCLUDE_ASIC_MASKS : std_logic := '0'; + constant CFG_SEQRAM_ADDR_WIDTH : natural := 12; -- 4kB + --13; -- 8kB + --14; --16kB + + constant STRIPS_ENCODING_CFG_MON_REG : std_logic_vector(31 downto 0) := + x"000000" & + std_logic_vector(to_unsigned(CFG_SEQRAM_ADDR_WIDTH,4)) & + "00" & + CFG_INCLUDE_ASIC_MASKS & + CFG_INCLUDE_BCID_GATING; subtype t_bcid is std_logic_vector(11 downto 0); -- GitLab From c4d67a5cd166c630bb1b485ce3fc7796dd7ad96f Mon Sep 17 00:00:00 2001 From: Frans Schreuder <f.schreuder@nikhef.nl> Date: Wed, 31 Jul 2024 10:59:10 +0200 Subject: [PATCH 4/6] Added new register for FLX-2422 --- sources/CRToHost/ToHostAxiStreamController.vhd | 2 +- sources/templates/generated/dma_control.vhd | 7 +++++++ sources/templates/generated/dma_control_5.vhd | 7 +++++++ sources/templates/generated/pcie_package.vhd | 14 +++++++++++++- sources/templates/yaml/regmap | 2 +- 5 files changed, 29 insertions(+), 3 deletions(-) diff --git a/sources/CRToHost/ToHostAxiStreamController.vhd b/sources/CRToHost/ToHostAxiStreamController.vhd index 69476da9d..fcaff2a75 100644 --- a/sources/CRToHost/ToHostAxiStreamController.vhd +++ b/sources/CRToHost/ToHostAxiStreamController.vhd @@ -76,7 +76,7 @@ architecture Behavioral of ToHostAxiStreamController is signal is_soc_all_streams : std_logic_vector(STREAMS_TOHOST downto 0); --This is the next valid word after s_axis.tlast. signal next_is_soc, update_is_soc: std_logic; --Handshake signals between processes to update is_soc signal stream_select_s: integer range 0 to STREAMS_TOHOST; - + signal stream_select_switched: std_logic; signal stream_select_and_value : axis_tready_array_type(0 to STREAMS_TOHOST-1); signal SwitchAxiStream : std_logic; diff --git a/sources/templates/generated/dma_control.vhd b/sources/templates/generated/dma_control.vhd index 02326a28c..88099cac9 100644 --- a/sources/templates/generated/dma_control.vhd +++ b/sources/templates/generated/dma_control.vhd @@ -17648,6 +17648,13 @@ end process; -- 1: Use subchunk header format -- 2: Use blockless header format + when REG_STRIPS_ENCODING_CFG => register_read_data_25_s(7 downto 4) <= register_map_monitor_s.register_map_gen_board_info.STRIPS_ENCODING_CFG.SEQRAM_ADDR_WIDTH; -- Width of the sequencer RAM + -- 12: 4kB + -- 13: 8kB + -- 14: 16kB + + register_read_data_25_s(1 downto 1) <= register_map_monitor_s.register_map_gen_board_info.STRIPS_ENCODING_CFG.INCLUDE_ASIC_MASKS; -- include hcc_mask and abc_mask in lcb_frame_generator + register_read_data_25_s(0 downto 0) <= register_map_monitor_s.register_map_gen_board_info.STRIPS_ENCODING_CFG.INCLUDE_BCID_GATING; -- include trickle trigger / BCID gating in lcb wrapper -- CRToHostControlsAndMonitors when REG_MAX_TIMEOUT => register_read_data_25_s(31 downto 0) <= register_map_monitor_s.register_map_crtohost_monitor.MAX_TIMEOUT; -- Maximum allowed timeout value diff --git a/sources/templates/generated/dma_control_5.vhd b/sources/templates/generated/dma_control_5.vhd index 9c839c312..a4ab54457 100644 --- a/sources/templates/generated/dma_control_5.vhd +++ b/sources/templates/generated/dma_control_5.vhd @@ -13571,6 +13571,13 @@ end process; -- 1: Use subchunk header format -- 2: Use blockless header format + when REG_STRIPS_ENCODING_CFG => register_read_data_25_s(7 downto 4) <= register_map_monitor_s.register_map_gen_board_info.STRIPS_ENCODING_CFG.SEQRAM_ADDR_WIDTH; -- Width of the sequencer RAM + -- 12: 4kB + -- 13: 8kB + -- 14: 16kB + + register_read_data_25_s(1 downto 1) <= register_map_monitor_s.register_map_gen_board_info.STRIPS_ENCODING_CFG.INCLUDE_ASIC_MASKS; -- include hcc_mask and abc_mask in lcb_frame_generator + register_read_data_25_s(0 downto 0) <= register_map_monitor_s.register_map_gen_board_info.STRIPS_ENCODING_CFG.INCLUDE_BCID_GATING; -- include trickle trigger / BCID gating in lcb wrapper -- CRToHostControlsAndMonitors when REG_MAX_TIMEOUT => register_read_data_25_s(31 downto 0) <= register_map_monitor_s.register_map_crtohost_monitor.MAX_TIMEOUT; -- Maximum allowed timeout value diff --git a/sources/templates/generated/pcie_package.vhd b/sources/templates/generated/pcie_package.vhd index eda48e001..3bac7bcc8 100644 --- a/sources/templates/generated/pcie_package.vhd +++ b/sources/templates/generated/pcie_package.vhd @@ -355,6 +355,7 @@ package pcie_package is constant REG_FULLMODE_HALFRATE : std_logic_vector(19 downto 0) := x"00230"; constant REG_SUPPORT_HDLC_DELAY : std_logic_vector(19 downto 0) := x"00240"; constant REG_TOHOST_DATA_FORMAT : std_logic_vector(19 downto 0) := x"00250"; + constant REG_STRIPS_ENCODING_CFG : std_logic_vector(19 downto 0) := x"00260"; --** CRToHostControlsAndMonitors constant REG_TIMEOUT_CTRL : std_logic_vector(19 downto 0) := x"00800"; @@ -7820,6 +7821,15 @@ package pcie_package is EC_INDEX : std_logic_vector(15 downto 8); -- The AXIs ID (EPath-ID) of the FromHost EC E-Link NUMBER_OF_STREAMS : std_logic_vector(7 downto 0); -- Total number of AXIs IDs (EPath-IDs) per physical link FromHost end record; + type bitfield_strips_encoding_cfg_r_type is record + SEQRAM_ADDR_WIDTH : std_logic_vector(7 downto 4); -- Width of the sequencer RAM + -- 12: 4kB + -- 13: 8kB + -- 14: 16kB + + INCLUDE_ASIC_MASKS : std_logic_vector(1 downto 1); -- include hcc_mask and abc_mask in lcb_frame_generator + INCLUDE_BCID_GATING : std_logic_vector(0 downto 0); -- include trickle trigger / BCID gating in lcb wrapper + end record; -- GenericBoardInformation type register_map_gen_board_info_type is record @@ -7889,6 +7899,7 @@ package pcie_package is -- 1: Use subchunk header format -- 2: Use blockless header format + STRIPS_ENCODING_CFG : bitfield_strips_encoding_cfg_r_type; end record; -- -- CRToHostControlsAndMonitors @@ -8508,7 +8519,8 @@ end record; FROMHOST_DATA_FORMAT => (others => '0'), FULLMODE_HALFRATE => (others => '0'), SUPPORT_HDLC_DELAY => (others => '0'), - TOHOST_DATA_FORMAT => (others => '0') + TOHOST_DATA_FORMAT => (others => '0'), + STRIPS_ENCODING_CFG => (others => (others => '0')) ); constant register_map_crtohost_monitor_c : register_map_crtohost_monitor_type := ( diff --git a/sources/templates/yaml/regmap b/sources/templates/yaml/regmap index 6651d6c70..63315df5c 160000 --- a/sources/templates/yaml/regmap +++ b/sources/templates/yaml/regmap @@ -1 +1 @@ -Subproject commit 6651d6c70479d4f4b200f92b3ce44671e6e5c03c +Subproject commit 63315df5c8a3b053958b268afea65d218d80fd95 -- GitLab From 201eab2e7960681d5507710289f53a5e08a8a3c6 Mon Sep 17 00:00:00 2001 From: Frans Schreuder <f.schreuder@nikhef.nl> Date: Wed, 31 Jul 2024 11:05:25 +0200 Subject: [PATCH 5/6] Connected register to values in strips_package --- sources/housekeeping/GenericConstantsToRegs.vhd | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/sources/housekeeping/GenericConstantsToRegs.vhd b/sources/housekeeping/GenericConstantsToRegs.vhd index 8a095b8af..63469348c 100644 --- a/sources/housekeeping/GenericConstantsToRegs.vhd +++ b/sources/housekeeping/GenericConstantsToRegs.vhd @@ -34,6 +34,7 @@ library ieee, UNISIM; use work.pcie_package.all; use work.centralRouter_package.all; use work.FELIX_package.all; + use work.strips_package.all; entity GenericConstantsToRegs is generic( @@ -154,5 +155,11 @@ begin register_map_gen_board_info.GTREFCLK_SOURCE <= "0" & CONV(USE_Si5324_RefCLK); + register_map_gen_board_info.STRIPS_ENCODING_CFG <= ( + SEQRAM_ADDR_WIDTH => std_logic_vector(to_unsigned(CFG_SEQRAM_ADDR_WIDTH,4)), + INCLUDE_ASIC_MASKS(1) => CFG_INCLUDE_ASIC_MASKS, + INCLUDE_BCID_GATING(0) => CFG_INCLUDE_BCID_GATING + ); + end architecture rtl ; -- of GenericConstantsToRegs -- GitLab From 915802e2f548a65189fa070a4062f94ecd6ccab3 Mon Sep 17 00:00:00 2001 From: Frans Schreuder <f.schreuder@nikhef.nl> Date: Wed, 31 Jul 2024 11:43:11 +0200 Subject: [PATCH 6/6] Fixed assignment in record aggregate --- sources/housekeeping/GenericConstantsToRegs.vhd | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/sources/housekeeping/GenericConstantsToRegs.vhd b/sources/housekeeping/GenericConstantsToRegs.vhd index 63469348c..8e5eae20f 100644 --- a/sources/housekeeping/GenericConstantsToRegs.vhd +++ b/sources/housekeeping/GenericConstantsToRegs.vhd @@ -157,8 +157,8 @@ begin register_map_gen_board_info.STRIPS_ENCODING_CFG <= ( SEQRAM_ADDR_WIDTH => std_logic_vector(to_unsigned(CFG_SEQRAM_ADDR_WIDTH,4)), - INCLUDE_ASIC_MASKS(1) => CFG_INCLUDE_ASIC_MASKS, - INCLUDE_BCID_GATING(0) => CFG_INCLUDE_BCID_GATING + INCLUDE_ASIC_MASKS => (others => CFG_INCLUDE_ASIC_MASKS), + INCLUDE_BCID_GATING => (others => CFG_INCLUDE_BCID_GATING) ); end architecture rtl ; -- of GenericConstantsToRegs -- GitLab