diff --git a/README.md b/README.md
index 6a18cd1365a1391803af0c399600444d0e97febc..26f052d2a8228b4a9c14a58ce6d9c1d512d29533 100644
--- a/README.md
+++ b/README.md
@@ -14,8 +14,9 @@ In [modules/common](modules/common) there are general purpose cores:
   array of std_logic, and some subprograms to handle it.
 
 * For clock-domain crossing or asynchronous signal register, use
-  [gc_sync_ffs](modules/common/gc_sync_ffs.vhd).  It also has an edge
-  detector.
+  [gc_sync](modules/common/gc_sync.vhd).  This is the basic synchronizer.
+  If you also need an edge detector, use
+  [gc_sync_ffs](modules/common/gc_sync_ffs.vhd).
   The other synchronizer [gc_sync_register](modules/common/gc_sync_register.vhd)
   is deprecated.  It can synchronize multiple signals at the same time but
   doesn't ensure coherency between these signals.
diff --git a/modules/common/Manifest.py b/modules/common/Manifest.py
index 68c45dd86391755597f719032cea60b57eed49bb..7f356aeca3c09d3af48b70f2b1586041c81655de 100644
--- a/modules/common/Manifest.py
+++ b/modules/common/Manifest.py
@@ -11,6 +11,8 @@ files = [
     "gc_serial_dac.vhd",
     "gc_sync_ffs.vhd",
     "gc_arbitrated_mux.vhd",
+    "gc_sync_register.vhd",
+    "gc_sync.vhd",
     "gc_pulse_synchronizer.vhd",
     "gc_pulse_synchronizer2.vhd",
     "gc_frequency_meter.vhd",
@@ -25,7 +27,6 @@ files = [
     "gc_big_adder.vhd",
     "gc_fsm_watchdog.vhd",
     "gc_bicolor_led_ctrl.vhd",
-    "gc_sync_register.vhd",
     "gc_single_reset_gen.vhd",
     "gc_async_signals_input_stage.vhd",
     "gc_dec_8b10b.vhd",
diff --git a/modules/common/gc_sync.vhd b/modules/common/gc_sync.vhd
new file mode 100644
index 0000000000000000000000000000000000000000..f287c9b9c3000c460deed5ddeae1bc98a990ff36
--- /dev/null
+++ b/modules/common/gc_sync.vhd
@@ -0,0 +1,79 @@
+--------------------------------------------------------------------------------
+-- CERN BE-CO-HT
+-- General Cores Library
+-- https://www.ohwr.org/projects/general-cores
+--------------------------------------------------------------------------------
+--
+-- unit name:   gc_sync
+--
+-- description: Elementary synchronizer.
+--
+--------------------------------------------------------------------------------
+-- Copyright CERN 2014-2018
+--------------------------------------------------------------------------------
+-- Copyright and related rights are licensed under the Solderpad Hardware
+-- 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
+-- or implied. See the License for the specific language governing permissions
+-- and limitations under the License.
+--------------------------------------------------------------------------------
+
+library ieee;
+use ieee.std_logic_1164.all;
+
+entity gc_sync is
+  port (
+    clk_i     : in  std_logic;
+    rst_n_a_i : in  std_logic;
+    d_i       : in  std_logic;
+    q_o       : out std_logic;
+
+end gc_sync;
+
+-- make Altera Quartus quiet regarding unknown attributes:
+-- altera message_off 10335
+
+architecture rtl 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;
+
+  attribute shreg_extract                   : string;
+  attribute shreg_extract of gc_sync_ffs_in : signal is "no";
+  attribute shreg_extract of sync0          : signal is "no";
+  attribute shreg_extract of sync1          : signal is "no";
+
+  attribute keep                   : string;
+  attribute keep of gc_sync_ffs_in : signal is "true";
+  attribute keep of sync0          : signal is "true";
+  attribute keep of sync1          : signal is "true";
+
+  attribute async_reg                   : string;
+  attribute async_reg of gc_sync_ffs_in : signal is "true";
+  attribute async_reg of sync0          : signal is "true";
+  attribute async_reg of sync1          : signal is "true";
+
+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;
+
+  gc_sync_ffs_in <= d_i;
+  q_o            <= sync1;
+end rtl;