diff --git a/modules/common/gc_negedge.vhd b/modules/common/gc_negedge.vhd index 24655d43c9ec8a7d15b37d42bdca11d1302950ee..46fb2d10379c93c582cf20e00c43e3c90236d901 100644 --- a/modules/common/gc_negedge.vhd +++ b/modules/common/gc_negedge.vhd @@ -27,11 +27,10 @@ use ieee.std_logic_1164.all; entity gc_negedge is port( - clk_i : in std_logic; -- clock - rst_n_i : in std_logic; -- reset - data_i : in std_logic; -- input - pulse_o : out std_logic -- positive edge dectect output - ); + clk_i : in std_logic; -- clock + rst_n_i : in std_logic; -- reset + data_i : in std_logic; -- input + pulse_o : out std_logic); -- falling edge detect output end entity gc_negedge; architecture arch of gc_negedge is diff --git a/modules/common/gc_posedge.vhd b/modules/common/gc_posedge.vhd index f6830b1151db394e27746a5e7ad067349c24f42d..70df08ddfc04125271c0bf054aa91d3fd880e82e 100644 --- a/modules/common/gc_posedge.vhd +++ b/modules/common/gc_posedge.vhd @@ -27,11 +27,10 @@ use ieee.std_logic_1164.all; entity gc_posedge is port( - clk_i : in std_logic; -- clock - rst_n_i : in std_logic; -- reset - data_i : in std_logic; -- input - pulse_o : out std_logic -- positive edge dectect output - ); + clk_i : in std_logic; -- clock + rst_n_i : in std_logic; -- reset + data_i : in std_logic; -- input + pulse_o : out std_logic); -- positive edge detect output end entity gc_posedge; architecture arch of gc_posedge is diff --git a/modules/common/gc_sync.vhd b/modules/common/gc_sync.vhd index 0b8c6e7a16e5a5353218c5f0af2d84e36da85be5..0ae143818cdac4f1b803d482e54d6eef7a9a658d 100644 --- a/modules/common/gc_sync.vhd +++ b/modules/common/gc_sync.vhd @@ -6,7 +6,7 @@ -- -- unit name: gc_sync -- --- description: Elementary synchronizer. +-- description: Elementary synchronizer chain using two flip-flops. -- -------------------------------------------------------------------------------- -- Copyright CERN 2014-2018 @@ -26,6 +26,8 @@ library ieee; use ieee.std_logic_1164.all; entity gc_sync is + generic( + g_sync_edge : string := "positive"); port ( clk_i : in std_logic; rst_n_a_i : in std_logic; @@ -36,14 +38,14 @@ end gc_sync; -- make Altera Quartus quiet regarding unknown attributes: -- altera message_off 10335 -architecture rtl of gc_sync is +architecture arch of gc_sync is -- Use an intermediate signal with a particular name and a keep attribute -- so that it can be referenced in the constraints in order to ignore -- timing (TIG) on that signal. signal gc_sync_ffs_in : std_logic; - signal sync0, sync1 : std_logic; + signal sync0, sync1 : std_logic; attribute shreg_extract : string; attribute shreg_extract of gc_sync_ffs_in : signal is "no"; @@ -55,8 +57,8 @@ architecture rtl of gc_sync is attribute keep of sync0 : signal is "true"; attribute keep of sync1 : signal is "true"; - attribute keep_hierarchy : string; - attribute keep_hierarchy of rtl : architecture is "true"; + attribute keep_hierarchy : string; + attribute keep_hierarchy of arch : architecture is "true"; attribute async_reg : string; attribute async_reg of gc_sync_ffs_in : signal is "true"; @@ -65,17 +67,36 @@ architecture rtl of gc_sync is begin - process(clk_i, rst_n_a_i) - begin - if rst_n_a_i = '0' then - sync1 <= '0'; - sync0 <= '0'; - elsif rising_edge(clk_i) then - sync0 <= gc_sync_ffs_in; - sync1 <= sync0; - end if; - end process; + assert g_sync_edge = "positive" or g_sync_edge = "negative" severity failure; gc_sync_ffs_in <= d_i; - q_o <= sync1; -end rtl; + + sync_posedge : if (g_sync_edge = "positive") generate + process(clk_i, rst_n_a_i) + begin + if rst_n_a_i = '0' then + sync1 <= '0'; + sync0 <= '0'; + elsif rising_edge(clk_i) then + sync0 <= gc_sync_ffs_in; + sync1 <= sync0; + end if; + end process; + end generate sync_posedge; + + sync_negedge : if(g_sync_edge = "negative") generate + process(clk_i, rst_n_a_i) + begin + if rst_n_a_i = '0' then + sync1 <= '0'; + sync0 <= '0'; + elsif falling_edge(clk_i) then + sync0 <= gc_sync_ffs_in; + sync1 <= sync0; + end if; + end process; + end generate sync_negedge; + + q_o <= sync1; + +end arch; diff --git a/modules/common/gc_sync_edge.vhd b/modules/common/gc_sync_edge.vhd index bd2b412713cd73a91d25c557ae33d2194f79557a..049a9d82d7da91cde3b1d255148cbb3c129d5c7b 100644 --- a/modules/common/gc_sync_edge.vhd +++ b/modules/common/gc_sync_edge.vhd @@ -31,40 +31,40 @@ entity gc_sync_edge is g_edge : string := "positive"); port( clk_i : in std_logic; -- clock from the destination clock domain - rst_n_a_i : in std_logic; -- reset + rst_n_a_i : in std_logic; -- async reset data_i : in std_logic; -- async input synced_o : out std_logic; -- synchronized output - pulse_o : out std_logic); -- edge detect output + pulse_o : out std_logic); -- edge detect output end entity gc_sync_edge; architecture arch of gc_sync_edge is signal sync : std_logic; begin - inst_sync: entity work.gc_sync + inst_sync : entity work.gc_sync port map ( - clk_i => clk_i, + clk_i => clk_i, rst_n_a_i => rst_n_a_i, - d_i => data_i, - q_o => sync); + d_i => data_i, + q_o => sync); - assert g_edge = "positive" or g_edge = "negative" severity failure; + assert g_edge = "positive" or g_edge = "negative" severity FAILURE; sync_posedge : if g_edge = "positive" generate - inst_pedge: entity work.gc_posedge + inst_pedge : entity work.gc_posedge port map ( - clk_i => clk_i, + clk_i => clk_i, rst_n_i => rst_n_a_i, - data_i => sync, + data_i => sync, pulse_o => pulse_o); end generate; - sync_negedge: if g_edge = "negative" generate - inst_pedge: entity work.gc_negedge + sync_negedge : if g_edge = "negative" generate + inst_pedge : entity work.gc_negedge port map ( - clk_i => clk_i, + clk_i => clk_i, rst_n_i => rst_n_a_i, - data_i => sync, + data_i => sync, pulse_o => pulse_o); end generate; end architecture arch; diff --git a/modules/common/gencores_pkg.vhd b/modules/common/gencores_pkg.vhd index ed654b8f41fddb2e826ee3361bd9855917974c13..e08c8e362a386244154e538cc826ce69129651fb 100644 --- a/modules/common/gencores_pkg.vhd +++ b/modules/common/gencores_pkg.vhd @@ -248,6 +248,46 @@ package gencores_pkg is ppulse_o : out std_logic); end component; + component gc_sync is + generic ( + g_sync_edge : string := "positive"); + port ( + clk_i : in std_logic; + rst_n_a_i : in std_logic; + d_i : in std_logic; + q_o : out std_logic); + end component gc_sync; + + component gc_sync_edge is + generic ( + g_edge : string := "positive"); + port ( + clk_i : in std_logic; + rst_n_a_i : in std_logic; + data_i : in std_logic; + synced_o : out std_logic; + pulse_o : out std_logic); + end component gc_sync_edge; + + ------------------------------------------------------------------------------ + -- Edge detectors + ------------------------------------------------------------------------------ + component gc_negedge is + port ( + clk_i : in std_logic; + rst_n_i : in std_logic; + data_i : in std_logic; + pulse_o : out std_logic); + end component gc_negedge; + + component gc_posedge is + port ( + clk_i : in std_logic; + rst_n_i : in std_logic; + data_i : in std_logic; + pulse_o : out std_logic); + end component gc_posedge; + ------------------------------------------------------------------------------ -- Pulse synchroniser ------------------------------------------------------------------------------