From bdefc835b695c21798174fca29aa31d7ce30a876 Mon Sep 17 00:00:00 2001 From: Joris van Rantwijk Date: Tue, 8 Oct 2024 17:34:05 +0200 Subject: [PATCH] Capture digital input via IDDR --- fpga/constraints/red_pitaya.xdc | 7 +++---- fpga/constraints/red_pitaya_4ch.xdc | 4 +++- fpga/rtl/puzzlefw_pkg.vhd | 2 +- fpga/rtl/puzzlefw_top.vhd | 18 +++++++++++++----- fpga/rtl/puzzlefw_top_4ch.vhd | 18 +++++++++++++----- fpga/vivado/nonproject.tcl | 1 - 6 files changed, 33 insertions(+), 17 deletions(-) diff --git a/fpga/constraints/red_pitaya.xdc b/fpga/constraints/red_pitaya.xdc index 117e59b..63f5ee7 100644 --- a/fpga/constraints/red_pitaya.xdc +++ b/fpga/constraints/red_pitaya.xdc @@ -225,10 +225,9 @@ set_input_delay -clock adc_clk -min 3.0 [get_ports {adc_dat_i[*][*]}] set_input_delay -clock adc_clk -max 5.6 [get_ports {adc_dat_i[*][*]}] set_multicycle_path 2 -from [get_ports {adc_dat_i[*][*]}] -# Digital inputs are asynchronous. -# Set fairly relaxed constraints to limit delay and skew. -set_input_delay -clock adc_clk -min 0.0 [get_ports {exp_p_io[*] exp_n_io[*]}] -set_input_delay -clock adc_clk -max 3.0 [get_ports {exp_p_io[*] exp_n_io[*]}] +# Digital inputs are asynchronous and captured in IOB flipflops. +# Declare false path to avoid warning for unconstrained path. +set_false_path -from [get_ports {exp_p_io[*] exp_n_io[*]}] # Delay to LEDs does not matter; just set a long max delay. set_max_delay -to [get_ports {led_o[*]}] 20.0 diff --git a/fpga/constraints/red_pitaya_4ch.xdc b/fpga/constraints/red_pitaya_4ch.xdc index c592aef..2f19d09 100644 --- a/fpga/constraints/red_pitaya_4ch.xdc +++ b/fpga/constraints/red_pitaya_4ch.xdc @@ -215,7 +215,9 @@ set_input_delay -clock adc_clk_23 -max 0.7 [get_ports {adc_dat_i[2][*] adc_dat_ set_min_delay -from [get_clocks adc_clk_23] -to [get_clocks adc_clk_01] 1.6 set_max_delay -from [get_clocks adc_clk_23] -to [get_clocks adc_clk_01] 6.4 -# TODO -- specify input delay for digital inputs +# Digital inputs are asynchronous and captured in IOB flipflops. +# Declare false path to avoid warning for unconstrained path. +set_false_path -from [get_ports {exp_p_io[*] exp_n_io[*]}] # Delay to LEDs does not matter; just set a long max delay. set_max_delay -to [get_ports {led_o[*]}] 20.0 diff --git a/fpga/rtl/puzzlefw_pkg.vhd b/fpga/rtl/puzzlefw_pkg.vhd index 3bfcd4b..b74d242 100644 --- a/fpga/rtl/puzzlefw_pkg.vhd +++ b/fpga/rtl/puzzlefw_pkg.vhd @@ -96,7 +96,7 @@ package puzzlefw_pkg is -- Firmware info word. constant fw_api_version: natural := 1; constant fw_version_major: natural := 0; - constant fw_version_minor: natural := 12; + constant fw_version_minor: natural := 13; constant fw_info_word: std_logic_vector(31 downto 0) := x"4a" & std_logic_vector(to_unsigned(fw_api_version, 8)) diff --git a/fpga/rtl/puzzlefw_top.vhd b/fpga/rtl/puzzlefw_top.vhd index 4c0ba38..79e99bb 100644 --- a/fpga/rtl/puzzlefw_top.vhd +++ b/fpga/rtl/puzzlefw_top.vhd @@ -590,12 +590,20 @@ begin inst_dig_capture_gen: for i in 0 to 3 generate - -- Use a 2-flipflop synchronizer to avoid metastability. - inst_dig_sync: entity work.syncdff + -- Use IDDR to capture digital input. + -- The IDDR is used in pipeline mode; this inserts a secondary flip-flop + -- in the data path which helps to suppress metastability. + inst_dig_iddr: IDDR + generic map ( + DDR_CLK_EDGE => "SAME_EDGE_PIPELINED" ) port map ( - clk => clk_adc, - di => s_dig_in(i), - do => s_dig_sync(i) ); + Q1 => s_dig_sync(i), + Q2 => open, + C => clk_adc, + CE => '1', + D => s_dig_in(i), + R => '0', + S => '0' ); -- Deglitch filter. inst_dig_deglitch: entity work.deglitch diff --git a/fpga/rtl/puzzlefw_top_4ch.vhd b/fpga/rtl/puzzlefw_top_4ch.vhd index 6e0eba5..17bcfc9 100644 --- a/fpga/rtl/puzzlefw_top_4ch.vhd +++ b/fpga/rtl/puzzlefw_top_4ch.vhd @@ -628,12 +628,20 @@ begin inst_dig_capture_gen: for i in 0 to 3 generate - -- Use a 2-flipflop synchronizer to avoid metastability. - inst_dig_sync: entity work.syncdff + -- Use IDDR to capture digital input. + -- The IDDR is used in pipeline mode; this inserts a secondary flip-flop + -- in the data path which helps to suppress metastability. + inst_dig_iddr: IDDR + generic map ( + DDR_CLK_EDGE => "SAME_EDGE_PIPELINED" ) port map ( - clk => clk_adc, - di => s_dig_in(i), - do => s_dig_sync(i) ); + Q1 => s_dig_sync(i), + Q2 => open, + C => clk_adc, + CE => '1', + D => s_dig_in(i), + R => '0', + S => '0' ); -- Deglitch filter. inst_dig_deglitch: entity work.deglitch diff --git a/fpga/vivado/nonproject.tcl b/fpga/vivado/nonproject.tcl index a86dd4b..cb84af7 100644 --- a/fpga/vivado/nonproject.tcl +++ b/fpga/vivado/nonproject.tcl @@ -34,7 +34,6 @@ read_vhdl -vhdl2008 ../rtl/dma_write_channel.vhd read_vhdl -vhdl2008 ../rtl/registers.vhd read_vhdl -vhdl2008 ../rtl/sample_decimation.vhd read_vhdl -vhdl2008 ../rtl/shift_engine.vhd -read_vhdl -vhdl2008 ../rtl/syncdff.vhd read_vhdl -vhdl2008 ../rtl/simple_fifo.vhd read_vhdl -vhdl2008 ../rtl/timestamp_gen.vhd read_vhdl -vhdl2008 ../rtl/timetagger.vhd