Skip to content
Snippets Groups Projects
Commit 01731cd1 authored by Dimitris Lampridis's avatar Dimitris Lampridis
Browse files

hdl: update synchronizers and add attributes to help with placement of timing constraints

parent 60d75393
No related merge requests found
...@@ -29,7 +29,7 @@ use ieee.std_logic_1164.all; ...@@ -29,7 +29,7 @@ use ieee.std_logic_1164.all;
use work.gencores_pkg.all; use work.gencores_pkg.all;
entity gc_pulse_synchronizer is entity gc_pulse_synchronizer is
port ( port (
-- pulse input clock -- pulse input clock
clk_in_i : in std_logic; clk_in_i : in std_logic;
...@@ -37,8 +37,8 @@ entity gc_pulse_synchronizer is ...@@ -37,8 +37,8 @@ entity gc_pulse_synchronizer is
clk_out_i : in std_logic; clk_out_i : in std_logic;
-- system reset (clk_in_i domain) -- system reset (clk_in_i domain)
rst_n_i : in std_logic; rst_n_i : in std_logic;
-- pulse input ready (clk_in_i domain). When HI, a pulse coming to d_p_i will be -- pulse input ready (clk_in_i domain). When HI, a pulse
-- correctly transferred to q_p_o. -- coming to d_p_i will be correctly transferred to q_p_o.
d_ready_o : out std_logic; d_ready_o : out std_logic;
-- pulse input (clk_in_i domain) -- pulse input (clk_in_i domain)
d_p_i : in std_logic; d_p_i : in std_logic;
...@@ -49,40 +49,29 @@ end gc_pulse_synchronizer; ...@@ -49,40 +49,29 @@ end gc_pulse_synchronizer;
architecture rtl of gc_pulse_synchronizer is architecture rtl of gc_pulse_synchronizer is
constant c_sync_stages : integer := 3; signal ready, d_p_d0 : std_logic;
signal ready, d_p_d0 : std_logic;
signal in_ext, out_ext : std_logic; signal in_ext, out_ext : std_logic;
signal out_feedback : std_logic; signal out_feedback : std_logic;
signal d_in2out : std_logic_vector(c_sync_stages-1 downto 0);
signal d_out2in : std_logic_vector(c_sync_stages-1 downto 0);
begin -- rtl begin -- rtl
process(clk_out_i, rst_n_i) cmp_in2out_sync : gc_sync_ffs
begin port map (
if rst_n_i = '0' then clk_i => clk_out_i,
d_in2out <= (others => '0'); rst_n_i => rst_n_i,
out_ext <= '0'; data_i => in_ext,
elsif rising_edge(clk_out_i) then synced_o => out_ext,
d_in2out <= d_in2out(c_sync_stages-2 downto 0) & in_ext; npulse_o => open,
out_ext <= d_in2out(c_sync_stages-1); ppulse_o => q_p_o);
end if;
end process; cmp_out2in_sync : gc_sync_ffs
port map (
clk_i => clk_in_i,
process(clk_in_i, rst_n_i) rst_n_i => rst_n_i,
begin data_i => out_ext,
if rst_n_i = '0' then synced_o => out_feedback,
d_out2in <= (others => '0'); npulse_o => open,
elsif rising_edge(clk_in_i) then ppulse_o => open);
d_out2in <= d_out2in(c_sync_stages-2 downto 0) & out_ext;
end if;
end process;
out_feedback <= d_out2in(c_sync_stages-1);
p_input_ack : process(clk_in_i, rst_n_i) p_input_ack : process(clk_in_i, rst_n_i)
begin begin
...@@ -93,26 +82,17 @@ begin -- rtl ...@@ -93,26 +82,17 @@ begin -- rtl
elsif rising_edge(clk_in_i) then elsif rising_edge(clk_in_i) then
d_p_d0 <= d_p_i; d_p_d0 <= d_p_i;
if(ready = '1' and d_p_i = '1' and d_p_d0 = '0') then if ready = '1' and d_p_i = '1' and d_p_d0 = '0'then
in_ext <= '1'; in_ext <= '1';
ready <= '0'; ready <= '0';
elsif(in_ext = '1' and out_feedback = '1') then elsif in_ext = '1' and out_feedback = '1' then
in_ext <= '0'; in_ext <= '0';
elsif(in_ext = '0' and out_feedback = '0') then elsif in_ext = '0' and out_feedback = '0' then
ready <= '1'; ready <= '1';
end if; end if;
end if; end if;
end process; end process p_input_ack;
p_drive_output : process(clk_out_i, rst_n_i)
begin
if rst_n_i = '0' then
q_p_o <= '0';
elsif rising_edge(clk_out_i) then
q_p_o <= not out_ext and d_in2out(c_sync_stages-1);
end if;
end process;
d_ready_o <= ready; d_ready_o <= ready;
......
...@@ -47,6 +47,8 @@ end gc_sync_ffs; ...@@ -47,6 +47,8 @@ end gc_sync_ffs;
architecture behavioral of gc_sync_ffs is architecture behavioral of gc_sync_ffs is
signal sync0, sync1, sync2 : std_logic; signal sync0, sync1, sync2 : std_logic;
signal gc_sync_ffs_in : std_logic;
attribute shreg_extract : string; attribute shreg_extract : string;
attribute shreg_extract of sync0 : signal is "no"; attribute shreg_extract of sync0 : signal is "no";
attribute shreg_extract of sync1 : signal is "no"; attribute shreg_extract of sync1 : signal is "no";
...@@ -56,6 +58,8 @@ architecture behavioral of gc_sync_ffs is ...@@ -56,6 +58,8 @@ architecture behavioral of gc_sync_ffs is
attribute keep of sync0 : signal is "true"; attribute keep of sync0 : signal is "true";
attribute keep of sync1 : signal is "true"; attribute keep of sync1 : signal is "true";
attribute keep of gc_sync_ffs_in : signal is "true";
-- synchronizer attribute for Vivado -- synchronizer attribute for Vivado
attribute ASYNC_REG : string; attribute ASYNC_REG : string;
attribute ASYNC_REG of sync0 : signal is "true"; attribute ASYNC_REG of sync0 : signal is "true";
...@@ -64,6 +68,9 @@ architecture behavioral of gc_sync_ffs is ...@@ -64,6 +68,9 @@ architecture behavioral of gc_sync_ffs is
begin begin
-- rename data_i to something we can use as wildcard
-- in timing constraints
gc_sync_ffs_in <= data_i;
sync_posedge : if (g_sync_edge = "positive") generate sync_posedge : if (g_sync_edge = "positive") generate
process(clk_i, rst_n_i) process(clk_i, rst_n_i)
...@@ -76,7 +83,7 @@ begin ...@@ -76,7 +83,7 @@ begin
npulse_o <= '0'; npulse_o <= '0';
ppulse_o <= '0'; ppulse_o <= '0';
elsif rising_edge(clk_i) then elsif rising_edge(clk_i) then
sync0 <= data_i; sync0 <= gc_sync_ffs_in;
sync1 <= sync0; sync1 <= sync0;
sync2 <= sync1; sync2 <= sync1;
synced_o <= sync1; synced_o <= sync1;
...@@ -97,7 +104,7 @@ begin ...@@ -97,7 +104,7 @@ begin
npulse_o <= '0'; npulse_o <= '0';
ppulse_o <= '0'; ppulse_o <= '0';
elsif falling_edge(clk_i) then elsif falling_edge(clk_i) then
sync0 <= data_i; sync0 <= gc_sync_ffs_in;
sync1 <= sync0; sync1 <= sync0;
sync2 <= sync1; sync2 <= sync1;
synced_o <= sync1; synced_o <= sync1;
...@@ -106,5 +113,5 @@ begin ...@@ -106,5 +113,5 @@ begin
end if; end if;
end process; end process;
end generate sync_negedge; end generate sync_negedge;
end behavioral; end behavioral;
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment