Commit c99ecb4c authored by Tristan Gingold's avatar Tristan Gingold

Add gc_sync_word_rd core.

parent eaacde90
......@@ -21,7 +21,9 @@ In [modules/common](modules/common) there are general purpose cores:
doesn't ensure coherency between these signals.
To pass words from one clock domain to another, you can use the module
[gc_sync_word_wr](modules/common/gc_sync_word_wr.vhd) for writing data,
and [gc_sync_word_rd](modules/common/gc_sync_word_rd.vhd) for reading
To pass one pulse from one domain to another, use module
......@@ -35,4 +35,5 @@ files = [
-- General Cores Library
-- unit name: gc_sync_word_rd
-- description: Synchronizer for reading a word with an ack.
-- Used to transfer a word from the output clock domain to the input clock
-- domain. The user provided data is constantly read. When a read request
-- arrives (on the output side), the user data is frozen (not read anymore),
-- and sent to the output side. A pulse is generated on the output side
-- when the transfer is done, and the data is unfrozen. A pulse is also
-- generated on the input side.
-- Copyright CERN 2019
-- 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
-- Unless required by applicable law or agreed to in writing, software,
-- hardware and materials distributed under this License is distributed on an
-- or implied. See the License for the specific language governing permissions
-- and limitations under the License.
library ieee;
use ieee.std_logic_1164.all;
use work.gencores_pkg.all;
entity gc_sync_word_rd is
generic (
g_WIDTH : positive := 8);
port (
-- Output clock and reset (wishbone side)
clk_out_i : in std_logic;
rst_out_n_i : in std_logic;
-- Input clock and reset (user side)
clk_in_i : in std_logic;
rst_in_n_i : in std_logic;
-- Input data (user side)
data_in_i : in std_logic_vector (g_WIDTH - 1 downto 0);
-- Trigger a read (wishbone side)
rd_out_i : in std_logic := '0';
-- Pulse when the read is available (wishbone side)
ack_out_o : out std_logic;
-- Output data (wishbone side)
data_out_o : out std_logic_vector (g_WIDTH - 1 downto 0);
-- Pulse when a data is transfered (user side)
rd_in_o : out std_logic);
end entity;
architecture arch of gc_sync_word_rd is
signal gc_sync_word_rd_data :
std_logic_vector (g_WIDTH - 1 downto 0) := (others => '0');
attribute keep : string;
attribute keep of gc_sync_word_rd_data : signal is "true";
signal d_ready : std_logic;
signal wr_in : std_logic;
signal rd_out : std_logic;
cmp_pulse_sync : entity work.gc_pulse_synchronizer2
port map (
clk_in_i => clk_out_i,
rst_in_n_i => rst_out_n_i,
clk_out_i => clk_in_i,
rst_out_n_i => rst_in_n_i,
d_ready_o => d_ready,
d_ack_p_o => wr_in,
d_p_i => rd_out_i,
q_p_o => rd_out);
p_reader : process(clk_in_i)
if rising_edge(clk_in_i) then
if d_ready = '1' then
-- Constantly update the data if ready
gc_sync_word_rd_data <= data_in_i;
end if;
end if;
end process;
p_writer : process (clk_out_i)
if rising_edge(clk_out_i) then
if rst_in_n_i = '0' then
ack_out_o <= '0';
elsif wr_in = '1' then
-- Data is stable.
data_out_o <= gc_sync_word_rd_data;
ack_out_o <= '1';
ack_out_o <= '0';
end if;
end if;
end process;
end arch;
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