diff --git a/hdl/ip_cores/afc-gw b/hdl/ip_cores/afc-gw index edf19de0..51edb056 160000 --- a/hdl/ip_cores/afc-gw +++ b/hdl/ip_cores/afc-gw @@ -1 +1 @@ -Subproject commit edf19de096df7c30d7715c2ee9f00a22fd66d83d +Subproject commit 51edb05638503bf7138c00c1f25d3e1cd4795520 diff --git a/hdl/ip_cores/infra-cores b/hdl/ip_cores/infra-cores index e8c4e825..09482044 160000 --- a/hdl/ip_cores/infra-cores +++ b/hdl/ip_cores/infra-cores @@ -1 +1 @@ -Subproject commit e8c4e825910c5443ab51ebf0dea700da3140cb1d +Subproject commit 0948204484cd07b903043a6a08d1ac1a86f8d1d7 diff --git a/hdl/modules/fofb_processing/fofb_processing.vhd b/hdl/modules/fofb_processing/fofb_processing.vhd index 2149ed8d..05de4d60 100644 --- a/hdl/modules/fofb_processing/fofb_processing.vhd +++ b/hdl/modules/fofb_processing/fofb_processing.vhd @@ -228,8 +228,11 @@ begin bpm_pos_avg_sum := resize(bpm_pos_i, bpm_pos_avg_sum'length) + bpm_pos_tmp_arr(to_integer(bpm_pos_index_i)); -- Dived by 2 (take the average) bpm_pos_tmp <= bpm_pos_avg_sum(bpm_pos_avg_sum'left downto 1); - -- Store the BPM position - bpm_pos_tmp_arr(to_integer(bpm_pos_index_i)) <= bpm_pos_i; + + if bpm_pos_valid_i = '1' then + -- Store the BPM position + bpm_pos_tmp_arr(to_integer(bpm_pos_index_i)) <= bpm_pos_i; + end if; else bpm_pos_tmp <= bpm_pos_i; end if; diff --git a/hdl/syn/afcv4_ref_design/afcv4_ref_fofb_ctrl.xdc b/hdl/syn/afcv4_ref_design/afcv4_ref_fofb_ctrl.xdc index d0d6dd52..a21d56e3 100644 --- a/hdl/syn/afcv4_ref_design/afcv4_ref_fofb_ctrl.xdc +++ b/hdl/syn/afcv4_ref_design/afcv4_ref_fofb_ctrl.xdc @@ -59,69 +59,34 @@ set_property DIFF_TERM TRUE [get_ports rtmlamp set_property DIFF_TERM TRUE [get_ports rtmlamp_adc_quad_sdoc_p_i] ####################################################################### -## DELAYS ## +## PCB delays for LTC232x ADCs ## ####################################################################### -# -# From LTC2324-16 and LTC2320-16 data sheet (page 06) -# -# SDO Data Remains Valid Delay from CLKOUT falling edge: -# tHSDO_SDR 0.00ns (min) / 1.5ns (max) -# -# So, the rising edge at 0ns generates the window from 6.5ns to 15ns, -# or, equivalently, the rising edge at -10ns generates the window from -# -3.5ns to 5ns. -# -# From Xilinx constraints guide: -# -# Center-Aligned Rising Edge Source Synchronous Inputs -# -# For a center-aligned Source Synchronous interface, the clock -# transition is aligned with the center of the data valid window. -# The same clock edge is used for launching and capturing the -# data. The constraints below rely on the default timing -# analysis (setup = 1 cycle, hold = 0 cycle). -# -# input ____ __________ -# clock |_________| |_____ -# | -# dv_bre | dv_are -# <------>|<------> -# __ ________|________ __ -# data __XXXX____Rise_Data____XXXX__ -# -# -# Input Delay Constraint -# set_input_delay -clock $input_clock -max [expr $input_clock_period - $dv_bre] [get_ports $input_ports]; -# set_input_delay -clock $input_clock -min $dv_are [get_ports $input_ports]; -# -# For our case: -# -# input ____ __________ -# clock |_________| |_____ -# | -# 3.5ns | 5ns -# <------>|<------> -# __ ________|________ __ -# data __XXXX____Rise_Data____XXXX__ -# -# These will be ignored by a clock set_clock_groups -asynchronous, but we -# keep it here for reference. Also we sample SDO/SCK with IOB FF, so there is -# not much the tool can improve. -# -# set_input_delay -clock virt_rtmlamp_adc_octo_sck_ret -max 6.5 [get_ports rtmlamp_adc_octo_sdoa_p_i]; -# set_input_delay -clock virt_rtmlamp_adc_octo_sck_ret -min 5.0 [get_ports rtmlamp_adc_octo_sdoa_p_i]; -# set_input_delay -clock virt_rtmlamp_adc_octo_sck_ret -max 6.5 [get_ports rtmlamp_adc_octo_sdob_p_i]; -# set_input_delay -clock virt_rtmlamp_adc_octo_sck_ret -min 5.0 [get_ports rtmlamp_adc_octo_sdob_p_i]; -# set_input_delay -clock virt_rtmlamp_adc_octo_sck_ret -max 6.5 [get_ports rtmlamp_adc_octo_sdoc_p_i]; -# set_input_delay -clock virt_rtmlamp_adc_octo_sck_ret -min 5.0 [get_ports rtmlamp_adc_octo_sdoc_p_i]; -# set_input_delay -clock virt_rtmlamp_adc_octo_sck_ret -max 6.5 [get_ports rtmlamp_adc_octo_sdod_p_i]; -# set_input_delay -clock virt_rtmlamp_adc_octo_sck_ret -min 5.0 [get_ports rtmlamp_adc_octo_sdod_p_i]; -# -# set_input_delay -clock virt_rtmlamp_adc_quad_sck_ret -max 6.5 [get_ports rtmlamp_adc_quad_sdoa_p_i]; -# set_input_delay -clock virt_rtmlamp_adc_quad_sck_ret -min 5.0 [get_ports rtmlamp_adc_quad_sdoa_p_i]; -# set_input_delay -clock virt_rtmlamp_adc_quad_sck_ret -max 6.5 [get_ports rtmlamp_adc_quad_sdoc_p_i]; -# set_input_delay -clock virt_rtmlamp_adc_quad_sck_ret -min 5.0 [get_ports rtmlamp_adc_quad_sdoc_p_i]; +set rtmlamp_adc_octo_sdoa_delay 0.159 +set rtmlamp_adc_octo_sdob_delay 0.125 +set rtmlamp_adc_octo_sdoc_delay 0.120 +set rtmlamp_adc_octo_sdod_delay 0.107 +set rtmlamp_adc_quad_sdoa_delay -0.161 +set rtmlamp_adc_quad_sdoc_delay -0.144 + +set rtmlamp_adc_uncertainty_delay 0.020 + +set_clock_groups -asynchronous -group rtmlamp_adc_octo_sck_ret -group clk_fast_spi +set_clock_groups -asynchronous -group rtmlamp_adc_quad_sck_ret -group clk_fast_spi + +set_input_delay -clock rtmlamp_adc_octo_sck_ret -max [expr {$rtmlamp_adc_octo_sdoa_delay + $rtmlamp_adc_uncertainty_delay}] [get_ports rtmlamp_adc_octo_sdoa_p_i]; +set_input_delay -clock rtmlamp_adc_octo_sck_ret -min [expr {$rtmlamp_adc_octo_sdoa_delay - $rtmlamp_adc_uncertainty_delay}] [get_ports rtmlamp_adc_octo_sdoa_p_i]; +set_input_delay -clock rtmlamp_adc_octo_sck_ret -max [expr {$rtmlamp_adc_octo_sdob_delay + $rtmlamp_adc_uncertainty_delay}] [get_ports rtmlamp_adc_octo_sdob_p_i]; +set_input_delay -clock rtmlamp_adc_octo_sck_ret -min [expr {$rtmlamp_adc_octo_sdob_delay - $rtmlamp_adc_uncertainty_delay}] [get_ports rtmlamp_adc_octo_sdob_p_i]; +set_input_delay -clock rtmlamp_adc_octo_sck_ret -max [expr {$rtmlamp_adc_octo_sdoc_delay + $rtmlamp_adc_uncertainty_delay}] [get_ports rtmlamp_adc_octo_sdoc_p_i]; +set_input_delay -clock rtmlamp_adc_octo_sck_ret -min [expr {$rtmlamp_adc_octo_sdoc_delay - $rtmlamp_adc_uncertainty_delay}] [get_ports rtmlamp_adc_octo_sdoc_p_i]; +set_input_delay -clock rtmlamp_adc_octo_sck_ret -max [expr {$rtmlamp_adc_octo_sdod_delay + $rtmlamp_adc_uncertainty_delay}] [get_ports rtmlamp_adc_octo_sdod_p_i]; +set_input_delay -clock rtmlamp_adc_octo_sck_ret -min [expr {$rtmlamp_adc_octo_sdod_delay - $rtmlamp_adc_uncertainty_delay}] [get_ports rtmlamp_adc_octo_sdod_p_i]; + +set_input_delay -clock rtmlamp_adc_quad_sck_ret -max [expr {$rtmlamp_adc_quad_sdoa_delay + $rtmlamp_adc_uncertainty_delay}] [get_ports rtmlamp_adc_quad_sdoa_p_i]; +set_input_delay -clock rtmlamp_adc_quad_sck_ret -min [expr {$rtmlamp_adc_quad_sdoa_delay - $rtmlamp_adc_uncertainty_delay}] [get_ports rtmlamp_adc_quad_sdoa_p_i]; +set_input_delay -clock rtmlamp_adc_quad_sck_ret -max [expr {$rtmlamp_adc_quad_sdoc_delay + $rtmlamp_adc_uncertainty_delay}] [get_ports rtmlamp_adc_quad_sdoc_p_i]; +set_input_delay -clock rtmlamp_adc_quad_sck_ret -min [expr {$rtmlamp_adc_quad_sdoc_delay - $rtmlamp_adc_uncertainty_delay}] [get_ports rtmlamp_adc_quad_sdoc_p_i]; ####################################################################### ## DELAY values ## diff --git a/hdl/testbench/dot_prod/dot_prod_top.vhd b/hdl/testbench/dot_prod/dot_prod_top.vhd deleted file mode 100644 index a56e7488..00000000 --- a/hdl/testbench/dot_prod/dot_prod_top.vhd +++ /dev/null @@ -1,71 +0,0 @@ -------------------------------------------------------------------------------- --- Title : Dot Product synth test -------------------------------------------------------------------------------- --- Author : Augusto Fraga Giachero --- Company : CNPEM LNLS-GCA --- Platform : Simulation -------------------------------------------------------------------------------- --- Description: Dot Product synth test -------------------------------------------------------------------------------- --- Copyright (c) 2022 CNPEM --- Licensed under GNU Lesser General Public License (LGPL) v3.0 -------------------------------------------------------------------------------- --- Revisions : --- Date Version Author Description --- 2022-08-23 1.0 augusto.fraga Created -------------------------------------------------------------------------------- - -library ieee; -use ieee.std_logic_1164.all; -use ieee.numeric_std.all; -use ieee.fixed_pkg.all; - -library work; -use work.dot_prod_pkg.all; - -entity dot_prod_top is - generic ( - g_A_INT_WIDTH : natural := 0; - g_A_FRAC_WIDTH : natural := 31; - g_B_INT_WIDTH : natural := 31; - g_B_FRAC_WIDTH : natural := 0; - g_ACC_EXTRA_WIDTH : natural := 4 - ); - port ( - clk : in std_logic := '0'; - rst_n : in std_logic := '0'; - clear_acc : in std_logic := '0'; - valid : in std_logic := '0'; - idle : out std_logic; - a : in sfixed(g_A_INT_WIDTH downto -g_A_FRAC_WIDTH); - b : in sfixed(g_B_INT_WIDTH downto -g_B_FRAC_WIDTH); - res : out sfixed(g_ACC_EXTRA_WIDTH + g_A_INT_WIDTH + g_B_INT_WIDTH + 1 - downto - -(g_A_FRAC_WIDTH + g_B_FRAC_WIDTH)) - ); -end dot_prod_top; - -architecture rtl of dot_prod_top is -begin - cmp_dot_prod: dot_prod - generic map ( - g_A_INT_WIDTH => g_A_INT_WIDTH, - g_A_FRAC_WIDTH => g_A_FRAC_WIDTH, - g_B_INT_WIDTH => g_B_INT_WIDTH, - g_B_FRAC_WIDTH => g_B_FRAC_WIDTH, - g_ACC_EXTRA_WIDTH => 4, - g_MULT_PIPELINE_STAGES => 2, - g_ACC_PIPELINE_STAGES => 2, - g_REG_INPUTS => true - ) - port map ( - clk_i => clk, - rst_n_i => rst_n, - clear_acc_i => clear_acc, - valid_i => valid, - a_i => a, - b_i => b, - idle_o => idle, - result_o => res - ); -end architecture rtl; diff --git a/hdl/testbench/fofb_processing/fofb_processing_tb.vhd b/hdl/testbench/fofb_processing/fofb_processing_tb.vhd index fba1a6a4..6b8721ad 100644 --- a/hdl/testbench/fofb_processing/fofb_processing_tb.vhd +++ b/hdl/testbench/fofb_processing/fofb_processing_tb.vhd @@ -198,6 +198,14 @@ begin -- BPM data ended bpm_pos_valid <= '0'; + -- Simulate an invalid position to check that bpm_pos_valid is respected + bpm_pos_index <= to_unsigned(i, c_SP_COEFF_RAM_ADDR_WIDTH); + bpm_pos <= to_signed(bpm_y, c_SP_POS_RAM_DATA_WIDTH); + f_wait_cycles(clk, 1); + bpm_pos_index <= to_unsigned(i + 256, c_SP_COEFF_RAM_ADDR_WIDTH); + bpm_pos <= to_signed(bpm_x, c_SP_POS_RAM_DATA_WIDTH); + f_wait_cycles(clk, 1); + -- Compute the BPM position error if g_USE_MOVING_AVG then -- Take the average with the BPM position from the last time frame diff --git a/hdl/top/afc_ref_design_gen/afc_ref_fofb_ctrl_gen.vhd b/hdl/top/afc_ref_design_gen/afc_ref_fofb_ctrl_gen.vhd index 56d93ab7..9fda8de2 100644 --- a/hdl/top/afc_ref_design_gen/afc_ref_fofb_ctrl_gen.vhd +++ b/hdl/top/afc_ref_design_gen/afc_ref_fofb_ctrl_gen.vhd @@ -701,6 +701,12 @@ architecture top of afc_ref_fofb_ctrl_gen is -- Acquisition channels IDs constant c_ACQ_RTM_LAMP_ID : natural := 0; + -- The way the triggers were conceived, you have a single logical trigger for + -- each ACQ channel, and a single wb_trigger_mux for each ACQ core, but + -- sometimes we need triggers for things other than the ACQ. Here I'm just + -- borrowing an ACQ (core c_ACQ_CORE_RTM_LAMP_ID) trigger for channel 3 that + -- is unused and connecting it to the xwb_rtmlamp_ohwr external trigger input. + constant c_SP_TRIG_RTM_LAMP_ID : natural := 3; constant c_ACQ_DCC_ID : natural := 1; -- Number of channels per acquisition core @@ -747,9 +753,10 @@ architecture top of afc_ref_fofb_ctrl_gen is ----------------------------------------------------------------------------- -- Trigger core IDs - constant c_TRIG_MUX_CC_FMC_ID : natural := 0; - constant c_TRIG_MUX_CC_P2P_ID : natural := 1; - constant c_TRIG_MUX_RTM_LAMP_ID : natural := 2; + -- These IDs should be kept in sync with the ACQ core IDs + constant c_TRIG_MUX_RTM_LAMP_ID : natural := c_ACQ_CORE_RTM_LAMP_ID; + constant c_TRIG_MUX_CC_FMC_ID : natural := c_ACQ_CORE_CC_FMC_OR_RTM_ID; + constant c_TRIG_MUX_CC_P2P_ID : natural := c_ACQ_CORE_CC_P2P_ID; constant c_TRIG_MUX_NUM_CORES : natural := c_ACQ_NUM_CORES; @@ -895,10 +902,9 @@ begin g_AFC_SI57x_INIT_RFREQ_VALUE => c_AFC_SI57x_INIT_RFREQ_VALUE, g_AFC_SI57x_INIT_N1_VALUE => c_AFC_SI57x_INIT_N1_VALUE, g_AFC_SI57x_INIT_HS_VALUE => c_AFC_SI57x_INIT_HS_VALUE, - -- If true, instantiate a VIC/UART/DIAG/SPI. + -- If true, instantiate a VIC/UART/SPI. g_WITH_VIC => true, g_WITH_UART_MASTER => true, - g_WITH_DIAG => true, g_WITH_TRIGGER => true, g_WITH_SPI => false, g_WITH_AFC_SI57x => true, @@ -1129,10 +1135,9 @@ begin g_AFC_SI57x_INIT_RFREQ_VALUE => c_AFC_SI57x_INIT_RFREQ_VALUE, g_AFC_SI57x_INIT_N1_VALUE => c_AFC_SI57x_INIT_N1_VALUE, g_AFC_SI57x_INIT_HS_VALUE => c_AFC_SI57x_INIT_HS_VALUE, - -- If true, instantiate a VIC/UART/DIAG/SPI. + -- If true, instantiate a VIC/UART/SPI. g_WITH_VIC => true, g_WITH_UART_MASTER => true, - g_WITH_DIAG => true, g_WITH_TRIGGER => true, g_WITH_SPI => false, g_WITH_AFC_SI57x => true, @@ -1504,8 +1509,9 @@ begin --------------------------------------------------------------------------- -- clock and reset interface --------------------------------------------------------------------------- - adcclk_i => fs_clk_array(c_FOFB_CC_FMC_OR_RTM_ID), - adcreset_i => fs_rst_array(c_FOFB_CC_FMC_OR_RTM_ID), + -- This is a distributor only instance, there is no ADC data to be read + adcclk_i => '0', + adcreset_i => '1', sysclk_i => clk_sys, sysreset_n_i => fofb_sysreset_n(c_FOFB_CC_FMC_OR_RTM_ID), @@ -1668,8 +1674,9 @@ begin --------------------------------------------------------------------------- -- clock and reset interface --------------------------------------------------------------------------- - adcclk_i => fs_clk_array(c_FOFB_CC_P2P_ID), - adcreset_i => fs_rst_array(c_FOFB_CC_P2P_ID), + -- This is a distributor only instance, there is no ADC data to be read + adcclk_i => '0', + adcreset_i => '1', sysclk_i => clk_sys, sysreset_n_i => fofb_sysreset_n(c_FOFB_CC_P2P_ID), @@ -1743,7 +1750,7 @@ begin g_DOT_PROD_MUL_PIPELINE_STAGES => g_FOFB_DOT_PROD_MUL_PIPELINE_STAGES, g_DOT_PROD_ACC_PIPELINE_STAGES => g_FOFB_DOT_PROD_ACC_PIPELINE_STAGES, g_ACC_GAIN_MUL_PIPELINE_STAGES => g_FOFB_ACC_GAIN_MUL_PIPELINE_STAGES, - g_USE_MOVING_AVG => true, + g_USE_MOVING_AVG => false, g_CHANNELS => c_FOFB_CHANNELS, g_INTERFACE_MODE => PIPELINED, g_ADDRESS_GRANULARITY => BYTE, @@ -2048,7 +2055,7 @@ begin --------------------------------------------------------------------------- -- External triggers for SP and DAC. Clock domain: clk_i --------------------------------------------------------------------------- - trig_i => (others => '0'), + trig_i => (others => trig_pulse_rcv(c_TRIG_MUX_RTM_LAMP_ID, c_SP_TRIG_RTM_LAMP_ID).pulse), --------------------------------------------------------------------------- -- ADC parallel interface