From f62503388c76d480086a0de9c93fe5520ed742bd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tomasz=20W=C5=82ostowski?= <tomasz.wlostowski@cern.ch> Date: Tue, 17 Jan 2012 00:09:03 +0100 Subject: [PATCH] modules/common: added clock rate independent pulse synchronizer (gc_pulse_synchronizer) --- modules/common/gc_pulse_synchronizer.vhd | 130 ++++++++++++++++++ .../{ => spartan6}/generic_async_fifo.vhd | 0 .../{ => spartan6}/generic_sync_fifo.vhd | 0 .../platform/{xilinx => spartan6}/jtag_tap.v | 0 .../{xilinx => spartan6}/lm32_multiplier.v | 0 5 files changed, 130 insertions(+) create mode 100644 modules/common/gc_pulse_synchronizer.vhd rename modules/genrams/xilinx/{ => spartan6}/generic_async_fifo.vhd (100%) rename modules/genrams/xilinx/{ => spartan6}/generic_sync_fifo.vhd (100%) rename modules/wishbone/wb_lm32/platform/{xilinx => spartan6}/jtag_tap.v (100%) rename modules/wishbone/wb_lm32/platform/{xilinx => spartan6}/lm32_multiplier.v (100%) diff --git a/modules/common/gc_pulse_synchronizer.vhd b/modules/common/gc_pulse_synchronizer.vhd new file mode 100644 index 00000000..42b154c1 --- /dev/null +++ b/modules/common/gc_pulse_synchronizer.vhd @@ -0,0 +1,130 @@ +------------------------------------------------------------------------------- +-- Title : Pulse synchronizer +-- Project : General Cores Library +------------------------------------------------------------------------------- +-- File : gc_pulse_synchronizer.vhd +-- Author : Tomasz Wlostowski +-- Company : CERN BE-CO-HT +-- Created : 2012-01-10 +-- Last update: 2012-01-10 +-- Platform : FPGA-generic +-- Standard : VHDL'93 +------------------------------------------------------------------------------- +-- Description: Full feedback pulse synchronizer (works independently of the +-- input/output clock domain frequency ratio) +------------------------------------------------------------------------------- +-- +-- Copyright (c) 2012 CERN / BE-CO-HT +-- +-- This source file is free software; you can redistribute it +-- and/or modify it under the terms of the GNU Lesser General +-- Public License as published by the Free Software Foundation; +-- either version 2.1 of the License, or (at your option) any +-- later version. +-- +-- This source is distributed in the hope that it will be +-- useful, but WITHOUT ANY WARRANTY; without even the implied +-- warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR +-- PURPOSE. See the GNU Lesser General Public License for more +-- details. +-- +-- You should have received a copy of the GNU Lesser General +-- Public License along with this source; if not, download it +-- from http://www.gnu.org/licenses/lgpl-2.1.html +-- +------------------------------------------------------------------------------- +-- Revisions : +-- Date Version Author Description +-- 2012-01-12 1.0 twlostow Created +------------------------------------------------------------------------------- + +library ieee; +use ieee.std_logic_1164.all; + +use work.gencores_pkg.all; + +entity gc_pulse_synchronizer is + + port ( + -- pulse input clock + clk_in_i : in std_logic; + -- pulse output clock + clk_out_i : in std_logic; + -- system reset (clk_in_i domain) + rst_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 (clk_in_i domain) + d_p_i : in std_logic; + -- pulse output (clk_out_i domain) + q_p_o : out std_logic); + +end gc_pulse_synchronizer; + +architecture rtl of gc_pulse_synchronizer is + + constant c_sync_stages : integer := 3; + + signal ready : 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_n_i) + begin + if rst_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_n_i) + begin + if rst_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); + + p_input_ack : process(clk_in_i, rst_n_i) + begin + if rst_n_i = '0' then + ready <= '1'; + in_ext <= '0'; + elsif rising_edge(clk_in_i) then + if(ready = '1' and d_p_i = '1') 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_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; + +end rtl; diff --git a/modules/genrams/xilinx/generic_async_fifo.vhd b/modules/genrams/xilinx/spartan6/generic_async_fifo.vhd similarity index 100% rename from modules/genrams/xilinx/generic_async_fifo.vhd rename to modules/genrams/xilinx/spartan6/generic_async_fifo.vhd diff --git a/modules/genrams/xilinx/generic_sync_fifo.vhd b/modules/genrams/xilinx/spartan6/generic_sync_fifo.vhd similarity index 100% rename from modules/genrams/xilinx/generic_sync_fifo.vhd rename to modules/genrams/xilinx/spartan6/generic_sync_fifo.vhd diff --git a/modules/wishbone/wb_lm32/platform/xilinx/jtag_tap.v b/modules/wishbone/wb_lm32/platform/spartan6/jtag_tap.v similarity index 100% rename from modules/wishbone/wb_lm32/platform/xilinx/jtag_tap.v rename to modules/wishbone/wb_lm32/platform/spartan6/jtag_tap.v diff --git a/modules/wishbone/wb_lm32/platform/xilinx/lm32_multiplier.v b/modules/wishbone/wb_lm32/platform/spartan6/lm32_multiplier.v similarity index 100% rename from modules/wishbone/wb_lm32/platform/xilinx/lm32_multiplier.v rename to modules/wishbone/wb_lm32/platform/spartan6/lm32_multiplier.v -- GitLab