diff --git a/simulation/ItkStrip/tb_lcb_axi_encoder.vhd b/simulation/ItkStrip/tb_lcb_axi_encoder.vhd index d07623cdfd567fd65ce23e5b1df92402857f286d..36f7da1dd309398c748ae9948bc20962a7888bf3 100644 --- a/simulation/ItkStrip/tb_lcb_axi_encoder.vhd +++ b/simulation/ItkStrip/tb_lcb_axi_encoder.vhd @@ -761,24 +761,41 @@ begin 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 - 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; + + 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; + + 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 - 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; + 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; + else + 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"); + 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; - 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; -------- verify that TTC L0A signals are ignored when disabled enable_bcr <= '1'; @@ -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,123 +1258,138 @@ begin is_HP_frame_encoded => true); - -- 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"); - + 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"); + else + log(ID_LOG_HDR, "No gating in build - skipping: Verifying that bypass frames respect gating signal"); + end if; - ----- 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"); + 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"); + else + log(ID_LOG_HDR, "No gating in build - skipping: Verifying that decoded frames respect gating signal"); + end if; - --- 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 + 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 "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"); + end if; + - ----- 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" + 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"); - 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"); + end if; + wait for 1000 ns; diff --git a/sources/CRToHost/ToHostAxiStreamController.vhd b/sources/CRToHost/ToHostAxiStreamController.vhd index 69476da9d7ffc6976d774929bf76abe58d758ff7..fcaff2a75f9c529c1b00d348c758c518a40f0926 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/ItkStrip/lcb_wrapper.vhd b/sources/ItkStrip/lcb_wrapper.vhd index 56d8322bbd7be48173627443a2bbd62b11080871..6ab02f87f20d8538984c0ed0d60830450d889d45 100644 --- a/sources/ItkStrip/lcb_wrapper.vhd +++ b/sources/ItkStrip/lcb_wrapper.vhd @@ -25,46 +25,46 @@ library ieee; entity lcb_wrapper is generic( - USE_ULTRARAM : boolean + USE_ULTRARAM : boolean ); port( - clk : in std_logic; - rst : in std_logic; + 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 + 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 + 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 + 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 + 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" + 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 + 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) @@ -74,40 +74,40 @@ 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 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 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 : 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_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; + signal trickle_trigger_gating : std_logic; -- L0A generator signals signal ttc_l0a_frame : std_logic_vector(11 downto 0); @@ -118,7 +118,7 @@ architecture RTL of lcb_wrapper is signal encoded_frame_reg : std_logic_vector(encoded_frame_o'range); -- bypass command and firmware encoded command lines - signal encoding : std_logic; + 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; @@ -132,27 +132,24 @@ architecture RTL of lcb_wrapper is 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; + 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; + 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); + 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'; @@ -164,8 +161,8 @@ begin 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 + 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, @@ -178,16 +175,16 @@ begin 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; + 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'; + 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; @@ -212,14 +209,14 @@ begin 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 + 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 @@ -251,11 +248,11 @@ begin 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, + clk => clk, + rst => rst, + wr_en => regmap_wr_en, + data_i => regmap_data, + addr_i => regmap_addr, regmap_o => regmap ); @@ -263,7 +260,7 @@ begin playback_controller : entity work.playback_controller generic map( - USE_ULTRARAM => USE_ULTRARAM + USE_ULTRARAM => USE_ULTRARAM ) port map( clk => clk, @@ -283,77 +280,115 @@ begin ready_i => trickle_ready_i ); - 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); - - 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 - ); + 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'; + trickle_allow_register_cmd <= '0'; + 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, - 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, + 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, - ttc_l0a_en => regmap(TTC_L0A_ENABLE)(0), --AP: I am not sure why this is needed - encoded_frame_o => encoded_frame_reg + 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 @@ -403,6 +438,6 @@ begin 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 8774e400d6d541da9a9b8d354a6b644cfc978d11..4376c95e20031ba16ba3f566a8fa1e337a86ea2e 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 diff --git a/sources/housekeeping/GenericConstantsToRegs.vhd b/sources/housekeeping/GenericConstantsToRegs.vhd index 8a095b8af9a6b58dc573c9bff8822cd2463ad87c..8e5eae20f100689a4d88033b7fbf548b1984f9a3 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 => (others => CFG_INCLUDE_ASIC_MASKS), + INCLUDE_BCID_GATING => (others => CFG_INCLUDE_BCID_GATING) + ); + end architecture rtl ; -- of GenericConstantsToRegs diff --git a/sources/templates/generated/dma_control.vhd b/sources/templates/generated/dma_control.vhd index 02326a28c9f32da326adc46d92bab1187d94a5af..88099cac99f71c73ba909b03d007dae0ffe0ae35 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 9c839c312a0fe81c000632453e1170f368a9d584..a4ab5445739a978fbd3c0ca6e522f8d92fb0de05 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 eda48e0018d79914c7c38f7f112d4cb4ebc9acfa..3bac7bcc892ef80f0248fbafb355bbc9f442783c 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 6651d6c70479d4f4b200f92b3ce44671e6e5c03c..63315df5c8a3b053958b268afea65d218d80fd95 160000 --- a/sources/templates/yaml/regmap +++ b/sources/templates/yaml/regmap @@ -1 +1 @@ -Subproject commit 6651d6c70479d4f4b200f92b3ce44671e6e5c03c +Subproject commit 63315df5c8a3b053958b268afea65d218d80fd95