-
Notifications
You must be signed in to change notification settings - Fork 103
/
Copy pathsync_Strobe.vhdl
147 lines (129 loc) · 5.42 KB
/
sync_Strobe.vhdl
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
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
-- EMACS settings: -*- tab-width: 2; indent-tabs-mode: t -*-
-- vim: tabstop=2:shiftwidth=2:noexpandtab
-- kate: tab-width 2; replace-tabs off; indent-width 2;
-- =============================================================================
-- Authors: Patrick Lehmann
-- Steffen Koehler
--
-- Entity: Synchronizes a strobe signal across clock-domain boundaries
--
-- Description:
-- -------------------------------------
-- This module synchronizes multiple high-active bits from clock-domain
-- ``Clock1`` to clock-domain ``Clock2``. The clock-domain boundary crossing is
-- done by a T-FF, two synchronizer D-FFs and a reconstructive XOR. A busy
-- flag is additionally calculated and can be used to block new inputs. All
-- bits are independent from each other. Multiple consecutive strobes are
-- suppressed by a rising edge detection.
--
-- .. ATTENTION::
-- Use this synchronizer only for one-cycle high-active signals (strobes).
--
-- .. image:: /_static/misc/sync/sync_Strobe.*
-- :target: ../../../_static/misc/sync/sync_Strobe.svg
--
-- Constraints:
-- This module uses sub modules which need to be constrained. Please
-- attend to the notes of the instantiated sub modules.
--
-- License:
-- =============================================================================
-- Copyright 2007-2015 Technische Universitaet Dresden - Germany
-- Chair of VLSI-Design, Diagnostics and Architecture
--
-- Licensed under the Apache 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://www.apache.org/licenses/LICENSE-2.0
--
-- Unless required by applicable law or agreed to in writing, software
-- distributed under the 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 IEEE.NUMERIC_STD.all;
library PoC;
use PoC.sync.all;
entity sync_Strobe is
generic (
BITS : positive := 1; -- number of bit to be synchronized
GATED_INPUT_BY_BUSY : boolean := TRUE; -- use gated input (by busy signal)
SYNC_DEPTH : T_MISC_SYNC_DEPTH := T_MISC_SYNC_DEPTH'low -- generate SYNC_DEPTH many stages, at least 2
);
port (
Clock1 : in std_logic; -- <Clock> input clock domain
Clock2 : in std_logic; -- <Clock> output clock domain
Input : in std_logic_vector(BITS - 1 downto 0); -- @Clock1: input bits
Output : out std_logic_vector(BITS - 1 downto 0); -- @Clock2: output bits
Busy : out std_logic_vector(BITS - 1 downto 0) -- @Clock1: busy bits
);
end entity;
architecture rtl of sync_Strobe is
attribute SHREG_EXTRACT : string;
signal syncClk1_In : std_logic_vector(BITS - 1 downto 0);
signal syncClk1_Out : std_logic_vector(BITS - 1 downto 0);
signal syncClk2_In : std_logic_vector(BITS - 1 downto 0);
signal syncClk2_Out : std_logic_vector(BITS - 1 downto 0);
begin
gen : for i in 0 to BITS - 1 generate
signal D0 : std_logic := '0';
signal T1 : std_logic := '0';
signal D2 : std_logic := '0';
signal Changed_Clk1 : std_logic;
signal Changed_Clk2 : std_logic;
signal Busy_i : std_logic;
-- Prevent XST from translating two FFs into SRL plus FF
attribute SHREG_EXTRACT of D0 : signal is "NO";
attribute SHREG_EXTRACT of T1 : signal is "NO";
attribute SHREG_EXTRACT of D2 : signal is "NO";
begin
process(Clock1)
begin
if rising_edge(Clock1) then
-- input delay for rising edge detection
D0 <= Input(i);
-- T-FF to converts a strobe to a flag signal
if GATED_INPUT_BY_BUSY then
T1 <= (Changed_Clk1 and not Busy_i) xor T1;
else
T1 <= Changed_Clk1 xor T1;
end if;
end if;
end process;
-- D-FF for level change detection (both edges)
D2 <= syncClk2_Out(i) when rising_edge(Clock2);
-- assign syncClk*_In signals
syncClk2_In(i) <= T1;
syncClk1_In(i) <= syncClk2_Out(i); -- D2
Changed_Clk1 <= not D0 and Input(i); -- rising edge detection
Changed_Clk2 <= syncClk2_Out(i) xor D2; -- level change detection; restore strobe signal from flag
Busy_i <= T1 xor syncClk1_Out(i); -- calculate busy signal
-- output signals
Output(i) <= Changed_Clk2;
Busy(i) <= Busy_i;
end generate;
syncClk2 : entity PoC.sync_Bits
generic map (
BITS => BITS, -- number of bit to be synchronized
SYNC_DEPTH => SYNC_DEPTH
)
port map (
Clock => Clock2, -- <Clock> output clock domain
Input => syncClk2_In, -- @async: input bits
Output => syncClk2_Out -- @Clock: output bits
);
syncClk1 : entity PoC.sync_Bits
generic map (
BITS => BITS, -- number of bit to be synchronized
SYNC_DEPTH => SYNC_DEPTH
)
port map (
Clock => Clock1, -- <Clock> output clock domain
Input => syncClk1_In, -- @async: input bits
Output => syncClk1_Out -- @Clock: output bits
);
end architecture;