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: ...@@ -21,7 +21,9 @@ In [modules/common](modules/common) there are general purpose cores:
doesn't ensure coherency between these signals. doesn't ensure coherency between these signals.
To pass words from one clock domain to another, you can use the module 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) [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
data.
To pass one pulse from one domain to another, use module To pass one pulse from one domain to another, use module
[gc_pulse_synchronizer](modules/common/gc_pulse_synchronizer.vhd) [gc_pulse_synchronizer](modules/common/gc_pulse_synchronizer.vhd)
......
...@@ -35,4 +35,5 @@ files = [ ...@@ -35,4 +35,5 @@ files = [
"gc_sfp_i2c_adapter.vhd", "gc_sfp_i2c_adapter.vhd",
"gc_async_counter_diff.vhd", "gc_async_counter_diff.vhd",
"gc_sync_word_wr.vhd", "gc_sync_word_wr.vhd",
"gc_sync_word_rd.vhd",
]; ];
--------------------------------------------------------------------------------
-- CERN BE-CO-HT
-- General Cores Library
-- https://www.ohwr.org/projects/general-cores
--------------------------------------------------------------------------------
--
-- 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
-- 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;
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;
begin
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)
begin
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)
begin
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';
else
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