diff --git a/libraries/base/common/src/vhdl/common_areset.vhd b/libraries/base/common/src/vhdl/common_areset.vhd index 13c3a2454c660456b76f0b0f3bfc1d6da2f559bb..57cc27cb308c6a760b2a8dde1b7d37d4f908d468 100644 --- a/libraries/base/common/src/vhdl/common_areset.vhd +++ b/libraries/base/common/src/vhdl/common_areset.vhd @@ -23,7 +23,8 @@ -- Purpose: Immediately apply reset and synchronously release it at rising clk -- Description: -- When in_rst gets asserted, then the out_rst gets asserted immediately (= asynchronous reset apply). --- When in_rst gets de-assered, then out_rst gets de-asserted after g_delay_len cycles (= synchronous reset release). +-- When in_rst gets de-assered, then out_rst gets de-asserted after g_delay_len cycles (= synchronous +-- reset release) + g_tree_len cycles (synchronous reset tree). -- -- The in_rst assert level is set by g_in_rst_level. -- The out_rst assert level is set by c_out_rst_level = g_rst_level. @@ -40,7 +41,8 @@ entity common_areset is g_in_rst_level : std_logic := '1'; -- = in_rst level g_rst_level : std_logic := '1'; -- = out_rst level (keep original generic -- name for backward compatibility) - g_delay_len : natural := c_meta_delay_len + g_delay_len : natural := c_meta_delay_len; + g_tree_len : natural := c_tree_delay_len ); port ( in_rst : in std_logic; @@ -50,13 +52,18 @@ entity common_areset is end; architecture str of common_areset is + constant c_out_rst_value : natural := to_int(g_rst_level); constant c_out_rst_level : std_logic := g_rst_level; constant c_out_rst_level_n : std_logic := not g_rst_level; signal i_rst : std_logic; + signal o_rst : std_logic; begin i_rst <= in_rst when g_in_rst_level = '1' else not in_rst; + -- 2009 + -- Capture asynchronous reset assertion, to also support i_rst when there is + -- no clk. u_async : entity work.common_async generic map ( g_rst_level => c_out_rst_level, @@ -66,6 +73,24 @@ begin rst => i_rst, clk => clk, din => c_out_rst_level_n, - dout => out_rst + dout => o_rst + ); + + -- 2024 + -- Pass on synchronized reset with sufficient g_tree_len to ease timing + -- closure by FF duplication in out_rst tree. Keep rst = '0' to break + -- combinatorial path with in_rst to ease timing closure in the reset tree + -- network. Use g_tree_len = 0 for wire out_rst <= o_rst, so no reset tree + -- as in 2009. + u_pipe : entity work.common_pipeline_sl + generic map ( + g_pipeline => g_tree_len, + g_reset_value => c_out_rst_value + ) + port map ( + rst => '0', + clk => clk, + in_dat => o_rst, + out_dat => out_rst ); end str; diff --git a/libraries/base/common/src/vhdl/common_pkg.vhd b/libraries/base/common/src/vhdl/common_pkg.vhd index 4d42521a5ab8f728b1043fd1ee974e11d999863b..c40db3363dec211ada0560a108e162a63f6046d8 100644 --- a/libraries/base/common/src/vhdl/common_pkg.vhd +++ b/libraries/base/common/src/vhdl/common_pkg.vhd @@ -86,6 +86,7 @@ package common_pkg is constant c_eps : real := 1.0e-20; -- add small epsilon value to avoid 1/0 and log(0), 1e-20 < 1/2**64 -- FF, block RAM, FIFO + constant c_tree_delay_len : natural := 10; -- reset clock tree pipelining to facilitate FF duplication by synthesis tool constant c_meta_delay_len : natural := 3; -- default nof flipflops (FF) in meta stability recovery delay line (e.g. for clock domain crossing) constant c_meta_fifo_depth : natural := 16; -- default use 16 word deep FIFO to cross clock domain, typically > 2*c_meta_delay_len or >~ 8 is enough @@ -214,7 +215,9 @@ package common_pkg is function slv(n: in std_logic) return std_logic_vector; -- standard logic to 1 element standard logic vector function sl( n: in std_logic_vector) return std_logic; -- 1 element standard logic vector to standard logic - function to_sl( n: in boolean) return std_logic; -- if TRUE then return '1' else '0' + function to_sl( n: in boolean) return std_logic; -- if TRUE then return '1' else '0' + function to_sl( n: in integer) return std_logic; -- if 0 then return '0' else '1' + function to_int( n: in std_logic) return integer; -- if '1' or 'H' then return '1' else '0' function to_bool(n: in std_logic) return boolean; -- if '1' or 'H' then return TRUE else FALSE function to_bool(n: in integer) return boolean; -- if 0 then return FALSE else TRUE @@ -777,6 +780,24 @@ package body common_pkg is end if; end; + function to_sl(n: in integer) return std_logic is + begin + if n = 0 then + return '0'; + else + return '1'; + end if; + end; + + function to_int(n: in std_logic) return integer is + begin + if n = '1' or n = 'H' then + return 1; + else + return 0; + end if; + end; + function to_bool(n: in std_logic) return boolean is begin return n = '1' or n = 'H'; diff --git a/libraries/base/dp/tb/vhdl/tb_dp_fifo_dc_mixed_widths.vhd b/libraries/base/dp/tb/vhdl/tb_dp_fifo_dc_mixed_widths.vhd index 8e32f03f95313b0b8fce82847a51d9009710a1d4..5a553284e6af96f1ca212c1253fb16f700971e6a 100644 --- a/libraries/base/dp/tb/vhdl/tb_dp_fifo_dc_mixed_widths.vhd +++ b/libraries/base/dp/tb/vhdl/tb_dp_fifo_dc_mixed_widths.vhd @@ -140,8 +140,9 @@ begin test_fifo_afull <= '0'; verify_done <= '0'; wait until arst = '0'; - proc_common_wait_some_cycles(wide_clk, 10); - proc_common_wait_some_cycles(narrow_clk, 10); -- ensure that n2w and w2n FIFOs are out of internal reset, and align to narrow_clk + -- ensure that n2w and w2n FIFOs are out of internal reset, and align to narrow_clk + proc_common_wait_some_cycles(wide_clk, c_tree_delay_len + 10); + proc_common_wait_some_cycles(narrow_clk, c_tree_delay_len + 10); -- Frame data with incrementing data over all frames, so the data can also be used as unframed stimuli v_init := 0; v_len := 0;