forked from xesscorp/VHDL_Lib
-
Notifications
You must be signed in to change notification settings - Fork 0
/
SyncToClk.vhd
119 lines (100 loc) · 3.76 KB
/
SyncToClk.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
106
107
108
109
110
111
112
113
114
115
116
117
118
119
--**********************************************************************
-- Copyright (c) 2011-2014 by XESS Corp <http://www.xess.com>.
-- All rights reserved.
--
-- This library is free software; you can redistribute it and/or
-- modify it under the terms of the GNU Lesser General Public
-- License as published by the Free Software Foundation; either
-- version 3.0 of the License, or (at your option) any later version.
--
-- This library is distributed in the hope that it will be useful,
-- but WITHOUT ANY WARRANTY; without even the implied warranty of
-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-- Lesser General Public License for more details.
--
-- You should have received a copy of the GNU Lesser General Public
-- License along with this library. If not, see
-- <http://www.gnu.org/licenses/>.
--**********************************************************************
----------------------------------------------------------------------------------
-- Modules for passing bits into a clock domain.
----------------------------------------------------------------------------------
library IEEE;
use IEEE.STD_LOGIC_1164.all;
package SyncToClockPckg is
-- Pass a bit into a clock domain.
component SyncToClock is
generic (
NUM_SYNC_STAGES_G : natural := 2
);
port (
clk_i : in std_logic; -- Clock for the domain being entered.
unsynced_i : in std_logic; -- Signal that is entering domain.
synced_o : out std_logic -- Signal sync'ed to clock domain
);
end component;
-- Pass a bus into a clock domain.
component SyncBusToClock is
generic (
NUM_SYNC_STAGES_G : natural := 2
);
port (
clk_i : in std_logic; -- Clock for the domain being entered.
unsynced_i : in std_logic_vector; -- Bus signal that is entering domain.
synced_o : out std_logic_vector -- Bus signal sync'ed to clock domain
);
end component;
end package;
library IEEE;
use IEEE.STD_LOGIC_1164.all;
entity SyncToClock is
generic (
NUM_SYNC_STAGES_G : natural := 2
);
port (
clk_i : in std_logic; -- Clock for the domain being entered.
unsynced_i : in std_logic; -- Signal that is entering domain.
synced_o : out std_logic -- Signal sync'ed to clock domain
);
end entity;
architecture arch of SyncToClock is
-- This is the sync'ing shift register. The index indicates the number of clocked flip-flops the incoming signal
-- has passed through, so sync_r(1) is one clk_i cycle stage, sync_r(2) is two cycles, etc.
signal sync_r : std_logic_vector(NUM_SYNC_STAGES_G downto 1);
begin
process(clk_i)
begin
if rising_edge(clk_i) then
-- Shift the unsync'ed signal into one end of the sync'ing register.
sync_r <= sync_r(NUM_SYNC_STAGES_G-1 downto 1) & unsynced_i;
end if;
end process;
-- Output the sync'ed signal from the other end of the shift register.
synced_o <= sync_r(NUM_SYNC_STAGES_G);
end architecture;
library IEEE, XESS;
use IEEE.STD_LOGIC_1164.all;
use XESS.SyncToClockPckg.all;
entity SyncBusToClock is
generic (
NUM_SYNC_STAGES_G : natural := 2
);
port (
clk_i : in std_logic; -- Clock for the domain being entered.
unsynced_i : in std_logic_vector; -- Bus signal that is entering domain.
synced_o : out std_logic_vector -- Bus signal sync'ed to clock domain
);
end entity;
architecture arch of SyncBusToClock is
begin
SyncLoop : for i in unsynced_i'range generate
begin
USyncBit : SyncToClock
generic map(NUM_SYNC_STAGES_G => NUM_SYNC_STAGES_G)
port map(
clk_i => clk_i,
unsynced_i => unsynced_i(i),
synced_o => synced_o(i)
);
end generate;
end architecture;