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

hdl: further update and cleanup of pulse synchronizers

parent 01731cd1
No related branches found
No related tags found
No related merge requests found
......@@ -49,51 +49,18 @@ end gc_pulse_synchronizer;
architecture rtl of gc_pulse_synchronizer is
signal ready, d_p_d0 : std_logic;
signal in_ext, out_ext : std_logic;
signal out_feedback : std_logic;
begin -- rtl
cmp_in2out_sync : gc_sync_ffs
port map (
clk_i => clk_out_i,
rst_n_i => rst_n_i,
data_i => in_ext,
synced_o => out_ext,
npulse_o => open,
ppulse_o => q_p_o);
cmp_out2in_sync : gc_sync_ffs
-- Just wrap around gc_pulse_synchronizer2
-- using the same reset on both domains
cmp_gc_pulse_sync : gc_pulse_synchronizer2
port map (
clk_i => clk_in_i,
rst_n_i => rst_n_i,
data_i => out_ext,
synced_o => out_feedback,
npulse_o => open,
ppulse_o => open);
p_input_ack : process(clk_in_i, rst_n_i)
begin
if rst_n_i = '0' then
ready <= '1';
in_ext <= '0';
d_p_d0 <= '0';
elsif rising_edge(clk_in_i) then
d_p_d0 <= d_p_i;
if ready = '1' and d_p_i = '1' and d_p_d0 = '0'then
in_ext <= '1';
ready <= '0';
elsif in_ext = '1' and out_feedback = '1' then
in_ext <= '0';
elsif in_ext = '0' and out_feedback = '0' then
ready <= '1';
end if;
end if;
end process p_input_ack;
d_ready_o <= ready;
clk_in_i => clk_in_i,
rst_in_n_i => rst_n_i,
clk_out_i => clk_out_i,
rst_out_n_i => rst_n_i,
d_ready_o => d_ready_o,
d_p_i => d_p_i,
q_p_o => q_p_o);
end rtl;
-------------------------------------------------------------------------------
-- Title : Pulse synchronizer
-- Project : General Cores Library
-------------------------------------------------------------------------------
-- File : gc_pulse_synchronizer2.vhd
-- Author : Tomasz Wlostowski, Wesley Terpstra
-- Company : CERN BE-CO-HT
-- Created : 2012-01-10
-- Last update: 2012-08-29
-- Platform : FPGA-generic
-- Standard : VHDL'93
-------------------------------------------------------------------------------
-- Description: Full feedback pulse synchronizer (works independently of the
-- input/output clock domain frequency ratio)
-------------------------------------------------------------------------------
--------------------------------------------------------------------------------
-- CERN BE-CO-HT
-- General Cores Library
-- https://www.ohwr.org/projects/general-cores
--------------------------------------------------------------------------------
--
-- Copyright (c) 2012 CERN / BE-CO-HT
-- unit name: gc_pulse_synchronizer2
--
-- description: Full feedback pulse synchronizer (works independently of the
-- input/output clock domain frequency ratio) with separate resets per domain
--
--------------------------------------------------------------------------------
-- Copyright CERN 2012-2018
--------------------------------------------------------------------------------
-- Copyright and related rights are licensed under the Solderpad Hardware
-- License, Version 0.51 (the “License”) (which enables you, at your option,
-- to treat this file as licensed under the Apache License 2.0); you may not
-- use this file except in compliance with the License. You may obtain a copy
-- of the License at http://solderpad.org/licenses/SHL-0.51.
-- License, Version 2.0 (the "License"); you may not use this file except
-- in compliance with the License. You may obtain a copy of the License at
-- http://solderpad.org/licenses/SHL-2.0.
-- Unless required by applicable law or agreed to in writing, software,
-- hardware and materials distributed under this License is distributed on an
-- AS IS BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
-- "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
-- or implied. See the License for the specific language governing permissions
-- and limitations under the License.
--
-------------------------------------------------------------------------------
-- Revisions :
-- Date Version Author Description
-- 2012-01-12 1.0 twlostow Created
-------------------------------------------------------------------------------
--------------------------------------------------------------------------------
library ieee;
use ieee.std_logic_1164.all;
......@@ -39,6 +29,7 @@ use ieee.std_logic_1164.all;
use work.gencores_pkg.all;
entity gc_pulse_synchronizer2 is
port (
-- pulse input clock
clk_in_i : in std_logic;
......@@ -46,53 +37,41 @@ entity gc_pulse_synchronizer2 is
-- pulse output clock
clk_out_i : in std_logic;
rst_out_n_i : in std_logic;
-- pulse input ready (clk_in_i domain). When HI, a pulse coming to d_p_i will be
-- correctly transferred to q_p_o.
d_ready_o : out std_logic;
-- pulse input ready (clk_in_i domain). When HI, a pulse
-- coming to d_p_i will be correctly transferred to q_p_o.
d_ready_o : out std_logic;
-- pulse input (clk_in_i domain)
d_p_i : in std_logic;
d_p_i : in std_logic;
-- pulse output (clk_out_i domain)
q_p_o : out std_logic);
q_p_o : out std_logic);
end gc_pulse_synchronizer2;
architecture rtl of gc_pulse_synchronizer2 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 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
process(clk_out_i, rst_out_n_i)
begin
if rst_out_n_i = '0' then
d_in2out <= (others => '0');
out_ext <= '0';
elsif rising_edge(clk_out_i) then
d_in2out <= d_in2out(c_sync_stages-2 downto 0) & in_ext;
out_ext <= d_in2out(c_sync_stages-1);
end if;
end process;
process(clk_in_i, rst_in_n_i)
begin
if rst_in_n_i = '0' then
d_out2in <= (others => '0');
elsif rising_edge(clk_in_i) then
d_out2in <= d_out2in(c_sync_stages-2 downto 0) & out_ext;
end if;
end process;
out_feedback <= d_out2in(c_sync_stages-1);
cmp_in2out_sync : gc_sync_ffs
port map (
clk_i => clk_out_i,
rst_n_i => rst_out_n_i,
data_i => in_ext,
synced_o => out_ext,
npulse_o => open,
ppulse_o => q_p_o);
cmp_out2in_sync : gc_sync_ffs
port map (
clk_i => clk_in_i,
rst_n_i => rst_in_n_i,
data_i => out_ext,
synced_o => out_feedback,
npulse_o => open,
ppulse_o => open);
p_input_ack : process(clk_in_i, rst_in_n_i)
begin
......@@ -103,24 +82,17 @@ begin -- rtl
elsif rising_edge(clk_in_i) then
d_p_d0 <= d_p_i;
if(ready = '1' and d_p_i = '1' and d_p_d0 = '0') then
in_ext <= not in_ext;
if ready = '1' and d_p_i = '1' and d_p_d0 = '0'then
in_ext <= '1';
ready <= '0';
elsif(in_ext = out_feedback) then
elsif in_ext = '1' and out_feedback = '1' then
in_ext <= '0';
elsif in_ext = '0' and out_feedback = '0' then
ready <= '1';
end if;
end if;
end process;
p_drive_output : process(clk_out_i, rst_out_n_i)
begin
if rst_out_n_i = '0' then
q_p_o <= '0';
elsif rising_edge(clk_out_i) then
q_p_o <= out_ext xor d_in2out(c_sync_stages-1);
end if;
end process;
end process p_input_ack;
d_ready_o <= ready;
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment