From cb9d78e026a593f5a04c5d4e731a7eb1fe753772 Mon Sep 17 00:00:00 2001
From: Dimitris Lampridis <dimitris.lampridis@cern.ch>
Date: Thu, 5 Mar 2020 16:49:26 +0100
Subject: [PATCH] [hdl] add g_sync_edge generic to gc_sync module

Also perform cleanup of sync and edge modules.

Signed-off-by: Dimitris Lampridis <dimitris.lampridis@cern.ch>
---
 modules/common/gc_negedge.vhd   |  9 +++---
 modules/common/gc_posedge.vhd   |  9 +++---
 modules/common/gc_sync.vhd      | 55 +++++++++++++++++++++++----------
 modules/common/gc_sync_edge.vhd | 28 ++++++++---------
 modules/common/gencores_pkg.vhd | 40 ++++++++++++++++++++++++
 5 files changed, 100 insertions(+), 41 deletions(-)

diff --git a/modules/common/gc_negedge.vhd b/modules/common/gc_negedge.vhd
index 24655d43..46fb2d10 100644
--- a/modules/common/gc_negedge.vhd
+++ b/modules/common/gc_negedge.vhd
@@ -27,11 +27,10 @@ use ieee.std_logic_1164.all;
 
 entity gc_negedge is
   port(
-    clk_i    : in  std_logic;   -- clock
-    rst_n_i  : in  std_logic;   -- reset
-    data_i   : in  std_logic;   -- input
-    pulse_o  : out std_logic    -- positive edge dectect output
-  );
+    clk_i   : in  std_logic;   -- clock
+    rst_n_i : in  std_logic;   -- reset
+    data_i  : in  std_logic;   -- input
+    pulse_o : out std_logic);  -- falling edge detect output
 end entity gc_negedge;
 
 architecture arch of gc_negedge is
diff --git a/modules/common/gc_posedge.vhd b/modules/common/gc_posedge.vhd
index f6830b11..70df08dd 100644
--- a/modules/common/gc_posedge.vhd
+++ b/modules/common/gc_posedge.vhd
@@ -27,11 +27,10 @@ use ieee.std_logic_1164.all;
 
 entity gc_posedge is
   port(
-    clk_i    : in  std_logic;   -- clock
-    rst_n_i  : in  std_logic;   -- reset
-    data_i   : in  std_logic;   -- input
-    pulse_o  : out std_logic    -- positive edge dectect output
-  );
+    clk_i   : in  std_logic;   -- clock
+    rst_n_i : in  std_logic;   -- reset
+    data_i  : in  std_logic;   -- input
+    pulse_o : out std_logic);  -- positive edge detect output
 end entity gc_posedge;
 
 architecture arch of gc_posedge is
diff --git a/modules/common/gc_sync.vhd b/modules/common/gc_sync.vhd
index 0b8c6e7a..0ae14381 100644
--- a/modules/common/gc_sync.vhd
+++ b/modules/common/gc_sync.vhd
@@ -6,7 +6,7 @@
 --
 -- unit name:   gc_sync
 --
--- description: Elementary synchronizer.
+-- description: Elementary synchronizer chain using two flip-flops.
 --
 --------------------------------------------------------------------------------
 -- Copyright CERN 2014-2018
@@ -26,6 +26,8 @@ library ieee;
 use ieee.std_logic_1164.all;
 
 entity gc_sync is
+  generic(
+    g_sync_edge : string := "positive");
   port (
     clk_i     : in  std_logic;
     rst_n_a_i : in  std_logic;
@@ -36,14 +38,14 @@ end gc_sync;
 -- make Altera Quartus quiet regarding unknown attributes:
 -- altera message_off 10335
 
-architecture rtl of gc_sync is
+architecture arch of gc_sync is
 
   --  Use an intermediate signal with a particular name and a keep attribute
   --  so that it can be referenced in the constraints in order to ignore
   --  timing (TIG) on that signal.
   signal gc_sync_ffs_in : std_logic;
 
-  signal sync0, sync1        : std_logic;
+  signal sync0, sync1 : std_logic;
 
   attribute shreg_extract                   : string;
   attribute shreg_extract of gc_sync_ffs_in : signal is "no";
@@ -55,8 +57,8 @@ architecture rtl of gc_sync is
   attribute keep of sync0          : signal is "true";
   attribute keep of sync1          : signal is "true";
 
-  attribute keep_hierarchy        : string;
-  attribute keep_hierarchy of rtl : architecture is "true";
+  attribute keep_hierarchy         : string;
+  attribute keep_hierarchy of arch : architecture is "true";
 
   attribute async_reg                   : string;
   attribute async_reg of gc_sync_ffs_in : signal is "true";
@@ -65,17 +67,36 @@ architecture rtl of gc_sync is
 
 begin
 
-  process(clk_i, rst_n_a_i)
-  begin
-    if rst_n_a_i = '0' then
-      sync1 <= '0';
-      sync0 <= '0';
-    elsif rising_edge(clk_i) then
-      sync0 <= gc_sync_ffs_in;
-      sync1 <= sync0;
-    end if;
-  end process;
+  assert g_sync_edge = "positive" or g_sync_edge = "negative" severity failure;
 
   gc_sync_ffs_in <= d_i;
-  q_o            <= sync1;
-end rtl;
+
+  sync_posedge : if (g_sync_edge = "positive") generate
+    process(clk_i, rst_n_a_i)
+    begin
+      if rst_n_a_i = '0' then
+        sync1 <= '0';
+        sync0 <= '0';
+      elsif rising_edge(clk_i) then
+        sync0 <= gc_sync_ffs_in;
+        sync1 <= sync0;
+      end if;
+    end process;
+  end generate sync_posedge;
+
+  sync_negedge : if(g_sync_edge = "negative") generate
+    process(clk_i, rst_n_a_i)
+    begin
+      if rst_n_a_i = '0' then
+        sync1 <= '0';
+        sync0 <= '0';
+      elsif falling_edge(clk_i) then
+        sync0 <= gc_sync_ffs_in;
+        sync1 <= sync0;
+      end if;
+    end process;
+  end generate sync_negedge;
+
+  q_o <= sync1;
+
+end arch;
diff --git a/modules/common/gc_sync_edge.vhd b/modules/common/gc_sync_edge.vhd
index bd2b4127..049a9d82 100644
--- a/modules/common/gc_sync_edge.vhd
+++ b/modules/common/gc_sync_edge.vhd
@@ -31,40 +31,40 @@ entity gc_sync_edge is
     g_edge : string := "positive");
   port(
     clk_i     : in  std_logic;   -- clock from the destination clock domain
-    rst_n_a_i : in  std_logic;   -- reset
+    rst_n_a_i : in  std_logic;   -- async reset
     data_i    : in  std_logic;   -- async input
     synced_o  : out std_logic;   -- synchronized output
-    pulse_o   : out std_logic);   -- edge detect output
+    pulse_o   : out std_logic);  -- edge detect output
 end entity gc_sync_edge;
 
 architecture arch of gc_sync_edge is
   signal sync : std_logic;
 begin
 
-  inst_sync: entity work.gc_sync
+  inst_sync : entity work.gc_sync
     port map (
-      clk_i => clk_i,
+      clk_i     => clk_i,
       rst_n_a_i => rst_n_a_i,
-      d_i => data_i,
-      q_o => sync);
+      d_i       => data_i,
+      q_o       => sync);
 
-  assert g_edge = "positive" or g_edge = "negative" severity failure;
+  assert g_edge = "positive" or g_edge = "negative" severity FAILURE;
 
   sync_posedge : if g_edge = "positive" generate
-    inst_pedge: entity work.gc_posedge
+    inst_pedge : entity work.gc_posedge
       port map (
-        clk_i => clk_i,
+        clk_i   => clk_i,
         rst_n_i => rst_n_a_i,
-        data_i => sync,
+        data_i  => sync,
         pulse_o => pulse_o);
   end generate;
 
-  sync_negedge: if g_edge = "negative" generate
-    inst_pedge: entity work.gc_negedge
+  sync_negedge : if g_edge = "negative" generate
+    inst_pedge : entity work.gc_negedge
       port map (
-        clk_i => clk_i,
+        clk_i   => clk_i,
         rst_n_i => rst_n_a_i,
-        data_i => sync,
+        data_i  => sync,
         pulse_o => pulse_o);
   end generate;
 end architecture arch;
diff --git a/modules/common/gencores_pkg.vhd b/modules/common/gencores_pkg.vhd
index ed654b8f..e08c8e36 100644
--- a/modules/common/gencores_pkg.vhd
+++ b/modules/common/gencores_pkg.vhd
@@ -248,6 +248,46 @@ package gencores_pkg is
       ppulse_o : out std_logic);
   end component;
 
+  component gc_sync is
+    generic (
+      g_sync_edge : string := "positive");
+    port (
+        clk_i     : in  std_logic;
+        rst_n_a_i : in  std_logic;
+        d_i       : in  std_logic;
+        q_o       : out std_logic);
+  end component gc_sync;
+
+  component gc_sync_edge is
+    generic (
+      g_edge : string := "positive");
+    port (
+        clk_i     : in  std_logic;
+        rst_n_a_i : in  std_logic;
+        data_i    : in  std_logic;
+        synced_o  : out std_logic;
+        pulse_o   : out std_logic);
+  end component gc_sync_edge;
+
+  ------------------------------------------------------------------------------
+  -- Edge detectors
+  ------------------------------------------------------------------------------
+  component gc_negedge is
+    port (
+      clk_i   : in  std_logic;
+      rst_n_i : in  std_logic;
+      data_i  : in  std_logic;
+      pulse_o : out std_logic);
+  end component gc_negedge;
+
+  component gc_posedge is
+    port (
+      clk_i   : in  std_logic;
+      rst_n_i : in  std_logic;
+      data_i  : in  std_logic;
+      pulse_o : out std_logic);
+  end component gc_posedge;
+
   ------------------------------------------------------------------------------
   -- Pulse synchroniser
   ------------------------------------------------------------------------------
-- 
GitLab