-
Notifications
You must be signed in to change notification settings - Fork 12
/
Copy pathgc_sync_word_rd.vhd
105 lines (96 loc) · 3.57 KB
/
gc_sync_word_rd.vhd
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
--------------------------------------------------------------------------------
-- 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_data :
std_logic_vector (g_WIDTH - 1 downto 0) := (others => '0');
attribute keep : string;
attribute keep of gc_sync_word_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 rd_out = '1' then
gc_sync_word_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_data;
ack_out_o <= '1';
else
ack_out_o <= '0';
end if;
end if;
end process;
end arch;