Commit cb09c893 authored by Adrian Byszuk's avatar Adrian Byszuk

Add configurable reset state for sync/edge_detect IP

This commit adds configurable generic to input synchronisation and edge detection IPs.
In case when the idle signal state is '1',
old IPs would generate unnecessary pulses right after reset deassertion.
parent 96630ec6
......@@ -56,41 +56,44 @@ use work.gencores_pkg.all;
entity gc_async_signals_input_stage is
generic (
-- number of input signals to be synchronised
g_signal_num : integer := 2;
g_signal_num : integer := 2;
-- number of clock cycles (N) for the extended output pulse signal
g_extended_pulse_width : integer := 0;
g_extended_pulse_width : integer := 0;
-- number of cycles that filter out glitches
g_dglitch_filter_len : integer := 2
g_dglitch_filter_len : integer := 2;
-- expected input state at reset, helpful to prevent glitches at startup
g_input_state_rst : std_logic := '0'
);
port (
clk_i : in std_logic;
rst_n_i : in std_logic;
clk_i : in std_logic;
rst_n_i : in std_logic;
-- input asynchronous signals
signals_a_i : in std_logic_vector(g_signal_num-1 downto 0);
signals_a_i : in std_logic_vector(g_signal_num-1 downto 0);
--- Configuration of each input signal
--- '0': active LOW: deglitcher works for '0s' and pulses are produced on falling edge
--- '1': active HIGH: deglitcher works for '1s' and pulses are produced on rising edge
config_active_i : in std_logic_vector(g_signal_num-1 downto 0);
config_active_i : in std_logic_vector(g_signal_num-1 downto 0);
-- synchronised and deglitched signal
signals_o : out std_logic_vector(g_signal_num-1 downto 0);
signals_o : out std_logic_vector(g_signal_num-1 downto 0);
-- single-clock pulse on rising or falling edge of the input signal (depends on the config)
signals_p1_o : out std_logic_vector(g_signal_num-1 downto 0);
signals_p1_o : out std_logic_vector(g_signal_num-1 downto 0);
-- N-cycle pulse on rising or falling edge of the input signal (depends on the config)
-- N=g_extended_pulse_width
signals_pN_o : out std_logic_vector(g_signal_num-1 downto 0)
signals_pN_o : out std_logic_vector(g_signal_num-1 downto 0)
);
end entity gc_async_signals_input_stage;
architecture behav of gc_async_signals_input_stage is
signal signals_synched : std_logic_vector(g_signal_num-1 downto 0);
signal signals_high_or_low : std_logic_vector(g_signal_num-1 downto 0);
signal signals_deglitched : std_logic_vector(g_signal_num-1 downto 0);
......@@ -106,6 +109,8 @@ begin
-- 1 stage: synchronzie with clock domain
-----------------------------------------------------------------------------------------
cmp_sync_with_clk : gc_sync_ffs
generic map (
g_INPUT_STATE_RST => g_INPUT_STATE_RST)
port map (
clk_i => clk_i,
rst_n_i => rst_n_i,
......@@ -176,5 +181,5 @@ begin
signals_o <= signals_deglitched;
signals_p1_o <= signals_pulse_p1;
signals_pN_o <= signals_pulse_pN;
end architecture behav;
......@@ -27,13 +27,15 @@ use ieee.std_logic_1164.all;
entity gc_edge_detect is
generic(
g_ASYNC_RST : boolean := FALSE;
g_ASYNC_RST : boolean := FALSE;
-- Positive/negative edge detection for pulse_o output.
-- Valid values are "positive" and "negative".
g_PULSE_EDGE : string := "positive";
g_PULSE_EDGE : string := "positive";
-- Clock edge sensitivity of edge detection flip-flop.
-- Valid values are "positive" and "negative".
g_CLOCK_EDGE : string := "positive");
g_CLOCK_EDGE : string := "positive";
-- Expected input state at reset
g_INPUT_STATE_RST : std_logic := '0');
port(
clk_i : in std_logic; -- clock
rst_n_i : in std_logic; -- reset
......@@ -64,7 +66,7 @@ begin
process (clk_i, rst_n_i)
begin
if rst_n_i = '0' then
dff <= '0';
dff <= g_INPUT_STATE_RST;
elsif rising_edge (clk_i) then
dff <= data_i;
end if;
......@@ -75,7 +77,7 @@ begin
process (clk_i, rst_n_i)
begin
if rst_n_i = '0' then
dff <= '0';
dff <= g_INPUT_STATE_RST;
elsif falling_edge (clk_i) then
dff <= data_i;
end if;
......@@ -91,7 +93,7 @@ begin
begin
if rising_edge (clk_i) then
if rst_n_i = '0' then
dff <= '0';
dff <= g_INPUT_STATE_RST;
else
dff <= data_i;
end if;
......@@ -104,7 +106,7 @@ begin
begin
if falling_edge (clk_i) then
if rst_n_i = '0' then
dff <= '0';
dff <= g_INPUT_STATE_RST;
else
dff <= data_i;
end if;
......
......@@ -30,7 +30,9 @@ entity gc_negedge is
g_ASYNC_RST : boolean := FALSE;
-- Clock edge sensitivity of edge detection flip-flop.
-- Valid values are "positive" and "negative".
g_CLOCK_EDGE : string := "positive");
g_CLOCK_EDGE : string := "positive";
-- Expected input state at reset
g_INPUT_STATE_RST : std_logic := '0');
port(
clk_i : in std_logic; -- clock
rst_n_i : in std_logic; -- reset
......@@ -44,9 +46,10 @@ begin
inst_gc_edge_detect : entity work.gc_edge_detect
generic map (
g_ASYNC_RST => g_ASYNC_RST,
g_PULSE_EDGE => "negative",
g_CLOCK_EDGE => g_CLOCK_EDGE)
g_ASYNC_RST => g_ASYNC_RST,
g_PULSE_EDGE => "negative",
g_CLOCK_EDGE => g_CLOCK_EDGE,
g_INPUT_STATE_RST => g_INPUT_STATE_RST)
port map (
clk_i => clk_i,
rst_n_i => rst_n_i,
......
......@@ -30,7 +30,9 @@ entity gc_posedge is
g_ASYNC_RST : boolean := FALSE;
-- Clock edge sensitivity of edge detection flip-flop.
-- Valid values are "positive" and "negative".
g_CLOCK_EDGE : string := "positive");
g_CLOCK_EDGE : string := "positive";
-- Expected input state at reset
g_INPUT_STATE_RST : std_logic := '0');
port(
clk_i : in std_logic; -- clock
rst_n_i : in std_logic; -- reset
......@@ -44,9 +46,10 @@ begin
inst_gc_edge_detect : entity work.gc_edge_detect
generic map (
g_ASYNC_RST => g_ASYNC_RST,
g_PULSE_EDGE => "positive",
g_CLOCK_EDGE => g_CLOCK_EDGE)
g_ASYNC_RST => g_ASYNC_RST,
g_PULSE_EDGE => "positive",
g_CLOCK_EDGE => g_CLOCK_EDGE,
g_INPUT_STATE_RST => g_INPUT_STATE_RST)
port map (
clk_i => clk_i,
rst_n_i => rst_n_i,
......
......@@ -28,7 +28,9 @@ use ieee.std_logic_1164.all;
entity gc_sync is
generic(
-- valid values are "positive" and "negative"
g_SYNC_EDGE : string := "positive");
g_SYNC_EDGE : string := "positive";
-- output state at reset
g_STATE_RST : std_logic := '0');
port (
clk_i : in std_logic;
rst_n_a_i : in std_logic;
......@@ -78,8 +80,8 @@ begin
process(clk_i, rst_n_a_i)
begin
if rst_n_a_i = '0' then
sync1 <= '0';
sync0 <= '0';
sync1 <= g_STATE_RST;
sync0 <= g_STATE_RST;
elsif rising_edge(clk_i) then
sync0 <= gc_sync_ffs_in;
sync1 <= sync0;
......@@ -91,8 +93,8 @@ begin
process(clk_i, rst_n_a_i)
begin
if rst_n_a_i = '0' then
sync1 <= '0';
sync0 <= '0';
sync1 <= g_STATE_RST;
sync0 <= g_STATE_RST;
elsif falling_edge(clk_i) then
sync0 <= gc_sync_ffs_in;
sync1 <= sync0;
......
......@@ -7,7 +7,7 @@
-- unit name: gc_sync_ffs
--
-- description: Synchronizer chain and edge detector.
-- All the registers in the chain are cleared at reset.
-- All the registers in the chain are set to configurable state at reset
--
--------------------------------------------------------------------------------
-- Copyright CERN 2010-2020
......@@ -29,7 +29,9 @@ use ieee.std_logic_1164.all;
entity gc_sync_ffs is
generic(
-- valid values are "positive" and "negative"
g_SYNC_EDGE : string := "positive");
g_SYNC_EDGE : string := "positive";
-- expected input state at reset, helpful to prevent glitches at startup
g_INPUT_STATE_RST : std_logic := '0');
port(
clk_i : in std_logic; -- clock from the destination clock domain
rst_n_i : in std_logic; -- async reset
......@@ -47,7 +49,8 @@ begin
cmp_gc_sync : entity work.gc_sync
generic map (
g_SYNC_EDGE => g_SYNC_EDGE)
g_SYNC_EDGE => g_SYNC_EDGE,
g_STATE_RST => g_INPUT_STATE_RST)
port map (
clk_i => clk_i,
rst_n_a_i => rst_n_i,
......@@ -56,9 +59,10 @@ begin
cmp_gc_posedge : entity work.gc_edge_detect
generic map (
g_ASYNC_RST => TRUE,
g_PULSE_EDGE => "positive",
g_CLOCK_EDGE => g_SYNC_EDGE)
g_ASYNC_RST => TRUE,
g_PULSE_EDGE => "positive",
g_CLOCK_EDGE => g_SYNC_EDGE,
g_INPUT_STATE_RST => g_INPUT_STATE_RST)
port map (
clk_i => clk_i,
rst_n_i => rst_n_i,
......@@ -67,9 +71,10 @@ begin
cmp_gc_negedge : entity work.gc_edge_detect
generic map (
g_ASYNC_RST => TRUE,
g_PULSE_EDGE => "negative",
g_CLOCK_EDGE => g_SYNC_EDGE)
g_ASYNC_RST => TRUE,
g_PULSE_EDGE => "negative",
g_CLOCK_EDGE => g_SYNC_EDGE,
g_INPUT_STATE_RST => g_INPUT_STATE_RST)
port map (
clk_i => clk_i,
rst_n_i => rst_n_i,
......
......@@ -238,7 +238,8 @@ package gencores_pkg is
------------------------------------------------------------------------------
component gc_sync_ffs
generic (
g_SYNC_EDGE : string := "positive");
g_SYNC_EDGE : string := "positive";
g_INPUT_STATE_RST : std_logic := '0');
port (
clk_i : in std_logic;
rst_n_i : in std_logic;
......@@ -250,7 +251,8 @@ package gencores_pkg is
component gc_sync is
generic (
g_SYNC_EDGE : string := "positive");
g_SYNC_EDGE : string := "positive";
g_STATE_RST : std_logic := '0');
port (
clk_i : in std_logic;
rst_n_a_i : in std_logic;
......@@ -263,9 +265,10 @@ package gencores_pkg is
------------------------------------------------------------------------------
component gc_edge_detect is
generic (
g_ASYNC_RST : boolean := FALSE;
g_PULSE_EDGE : string := "positive";
g_CLOCK_EDGE : string := "positive");
g_ASYNC_RST : boolean := FALSE;
g_PULSE_EDGE : string := "positive";
g_CLOCK_EDGE : string := "positive";
g_INPUT_STATE_RST : std_logic := '0');
port (
clk_i : in std_logic;
rst_n_i : in std_logic;
......@@ -275,8 +278,9 @@ package gencores_pkg is
component gc_negedge is
generic (
g_ASYNC_RST : boolean := FALSE;
g_CLOCK_EDGE : string := "positive");
g_ASYNC_RST : boolean := FALSE;
g_CLOCK_EDGE : string := "positive";
g_INPUT_STATE_RST : std_logic := '0');
port (
clk_i : in std_logic;
rst_n_i : in std_logic;
......@@ -286,8 +290,9 @@ package gencores_pkg is
component gc_posedge is
generic (
g_ASYNC_RST : boolean := FALSE;
g_CLOCK_EDGE : string := "positive");
g_ASYNC_RST : boolean := FALSE;
g_CLOCK_EDGE : string := "positive";
g_INPUT_STATE_RST : std_logic := '0');
port (
clk_i : in std_logic;
rst_n_i : in std_logic;
......@@ -670,17 +675,18 @@ package gencores_pkg is
component gc_async_signals_input_stage is
generic (
g_signal_num : integer;
g_extended_pulse_width : integer;
g_dglitch_filter_len : integer);
g_signal_num : integer;
g_extended_pulse_width : integer;
g_dglitch_filter_len : integer;
g_input_state_rst : std_logic := '0');
port (
clk_i : in std_logic;
rst_n_i : in std_logic;
signals_a_i : in std_logic_vector(g_signal_num-1 downto 0);
config_active_i : in std_logic_vector(g_signal_num-1 downto 0);
signals_o : out std_logic_vector(g_signal_num-1 downto 0);
signals_p1_o : out std_logic_vector(g_signal_num-1 downto 0);
signals_pN_o : out std_logic_vector(g_signal_num-1 downto 0));
clk_i : in std_logic;
rst_n_i : in std_logic;
signals_a_i : in std_logic_vector(g_signal_num-1 downto 0);
config_active_i : in std_logic_vector(g_signal_num-1 downto 0);
signals_o : out std_logic_vector(g_signal_num-1 downto 0);
signals_p1_o : out std_logic_vector(g_signal_num-1 downto 0);
signals_pN_o : out std_logic_vector(g_signal_num-1 downto 0));
end component;
......
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