Commit e2212978 authored by Matthieu Cattin's avatar Matthieu Cattin

Synchronise dma irq pulses to csr_wb clock.

parent fc0e1574
......@@ -159,6 +159,16 @@ architecture rtl of gn4124_core is
rx_bufpll_lckd : out std_logic); -- BUFPLL locked
end component serdes_1_to_n_clk_pll_s2_diff;
component pulse_synchronizer
port (
clk_in_i : in std_logic; --! Input pulse clock domain
clk_out_i : in std_logic; --! Output pulse clock domain
pulse_i : in std_logic; --! One clk_in_i tick input pulse
done_o : out std_logic; --! Input pulse is synchronized (1 clk_in_i tick)
pulse_o : out std_logic --! One clk_out_i tick output pulse
);
end component pulse_synchronizer;
------------------------------------------------------------------------------
-- Signals declaration
------------------------------------------------------------------------------
......@@ -282,6 +292,8 @@ architecture rtl of gn4124_core is
signal next_item_attrib : std_logic_vector(31 downto 0);
signal next_item_valid : std_logic;
signal dma_irq : std_logic_vector(1 downto 0);
------------------------------------------------------------------------------
-- CSR wishbone bus
------------------------------------------------------------------------------
......@@ -525,7 +537,7 @@ begin
clk_i => sys_clk,
rst_n_i => rst_n,
dma_ctrl_irq_o => dma_irq_o,
dma_ctrl_irq_o => dma_irq,
dma_ctrl_carrier_addr_o => dma_ctrl_carrier_addr,
dma_ctrl_host_addr_h_o => dma_ctrl_host_addr_h,
......@@ -566,6 +578,18 @@ begin
dma_ctrl_done <= dma_ctrl_l2p_done or dma_ctrl_p2l_done;
dma_ctrl_error <= dma_ctrl_l2p_error or dma_ctrl_p2l_error;
-- Synchronise DMA IRQ pulse to csr_clk_i clock domain
l_dma_irq_sync : for I in 0 to dma_irq'length-1 generate
cmp_dma_irq_sync : pulse_synchronizer
port map(
clk_in_i => sys_clk,
clk_out_i => csr_clk_i,
pulse_i => dma_irq(I),
done_o => open,
pulse_o => dma_irq_o(I)
);
end generate l_dma_irq_sync;
-----------------------------------------------------------------------------
-- L2P DMA master
-----------------------------------------------------------------------------
......
--=============================================================================
-- @file pulse_sync_rtl.vhd
--=============================================================================
--! Standard library
library IEEE;
--! Standard packages
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.NUMERIC_STD.ALL;
--! Specific packages
-------------------------------------------------------------------------------
-- --
-- CERN, BE-CO-HT, Synchronize a pulse between two clock domains
-- --
-------------------------------------------------------------------------------
--
-- Unit name: Pulse synchronizer (pulse_sync_rtl)
--
--! @brief Synchronize a pulse between two clock domains
--!
--
--! @author Matthieu Cattin (matthieu dot cattin at cern dot ch)
--
--! @date 17\03\2009
--
--! @version v.0.1
--
--! @details
--!
--! <b>Dependencies:</b>\n
--! None
--!
--! <b>References:</b>\n
--!
--!
--! <b>Modified by:</b>\n
--! Author:
-------------------------------------------------------------------------------
--! \n\n<b>Last changes:</b>\n
--! 19.06.2009 mcattin add an extra FF in p_pulse_sync process
--! 23.10.2009 mcattin modify it to a well known pulse synchronizer
-------------------------------------------------------------------------------
--! @todo
--
-------------------------------------------------------------------------------
--=============================================================================
--! Entity declaration for Pulse synchronizer
--=============================================================================
entity pulse_synchronizer is
port (
clk_in_i : in std_logic; --! Input pulse clock domain
clk_out_i : in std_logic; --! Output pulse clock domain
pulse_i : in std_logic; --! One clk_in_i tick input pulse
done_o : out std_logic; --! Input pulse is synchronized (1 clk_in_i tick)
pulse_o : out std_logic --! One clk_out_i tick output pulse
);
end entity pulse_synchronizer;
--=============================================================================
--! Architecture declaration Pulse synchronizer
--=============================================================================
architecture rtl of pulse_synchronizer is
signal s_input_toggle : std_logic := '0';
signal s_input_sync : std_logic_vector(2 downto 0);
signal s_gotit_toggle : std_logic := '0';
signal s_gotit_sync : std_logic_vector(2 downto 0);
signal s_output_pulse : std_logic;
--=============================================================================
--! Architecture begin
--=============================================================================
begin
--*****************************************************************************
-- Begin of p_input_pulse_to_toggle
--! Process: Toggles FF output on every input pulse
--*****************************************************************************
p_input_pulse_to_toggle : process(clk_in_i)
begin
if rising_edge(clk_in_i) then
if pulse_i = '1' then
s_input_toggle <= not(s_input_toggle);
end if;
end if;
end process p_input_pulse_to_toggle;
--*****************************************************************************
-- Begin of p_input_sync
--! Process: Synchronizes input toggle to output clock domain
--*****************************************************************************
p_input_sync: process(clk_out_i)
begin
if rising_edge(clk_out_i) then
s_input_sync(0) <= s_input_toggle;
s_input_sync(1) <= s_input_sync(0);
s_input_sync(2) <= s_input_sync(1);
end if;
end process p_input_sync;
-- generates 1 tick pulse when s_input_toggle changes
s_output_pulse <= s_input_sync(1) xor s_input_sync(2);
-- assign pulse output port
pulse_o <= s_output_pulse;
--*****************************************************************************
-- Begin of p_output_pulse_to_toggle
--! Process: Toggles FF output on every output pulse
--*****************************************************************************
p_output_pulse_to_toggle : process(clk_out_i)
begin
if rising_edge(clk_out_i) then
if s_output_pulse = '1' then
s_gotit_toggle <= not(s_gotit_toggle);
end if;
end if;
end process p_output_pulse_to_toggle;
--*****************************************************************************
-- Begin of p_gotit_sync
--! Process: Synchronizes gotit toggle to input clock domain
--*****************************************************************************
p_gotit_sync: process(clk_in_i)
begin
if rising_edge(clk_in_i) then
s_gotit_sync(0) <= s_gotit_toggle;
s_gotit_sync(1) <= s_gotit_sync(0);
s_gotit_sync(2) <= s_gotit_sync(1);
end if;
end process p_gotit_sync;
-- generates 1 tick pulse when s_gotit_toggle changes
done_o <= s_gotit_sync(1) xor s_gotit_sync(2);
end architecture rtl;
--=============================================================================
--! Architecture end
--=============================================================================
Markdown is supported
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