-
Notifications
You must be signed in to change notification settings - Fork 103
/
Copy pathsync_Command.vhdl
160 lines (141 loc) · 6.08 KB
/
sync_Command.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
148
149
150
151
152
153
154
155
156
157
158
159
160
-- 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 command signal across clock-domain boundaries
--
-- Description:
-- -------------------------------------
-- This module synchronizes a vector of bits from clock-domain ``Clock1`` to
-- clock-domain ``Clock2``. The clock-domain boundary crossing is done by a
-- change comparator, a T-FF, two synchronizer D-FFs and a reconstructive
-- XOR indicating a value change on the input. This changed signal is used
-- to capture the input for the new output. A busy flag is additionally
-- calculated for the input clock-domain. The output has strobe character
-- and is reset to it's ``INIT`` value after one clock cycle.
--
-- 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.utils.all;
use PoC.sync.all;
entity sync_Command is
generic (
BITS : positive := 8; -- number of bit to be synchronized
INIT : std_logic_vector := x"00000000"; --
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
Clock2 : in std_logic; -- <Clock> output clock
Input : in std_logic_vector(BITS - 1 downto 0); -- @Clock1: input vector
Output : out std_logic_vector(BITS - 1 downto 0); -- @Clock2: output vector
Busy : out std_logic; -- @Clock1: busy bit
Changed : out std_logic -- @Clock2: changed bit
);
end entity;
architecture rtl of sync_Command is
attribute SHREG_EXTRACT : string;
constant INIT_I : std_logic_vector := descend(INIT)(BITS - 1 downto 0);
signal D0 : std_logic := '0';
signal D1 : std_logic_vector(BITS - 1 downto 0) := INIT_I;
signal T2 : std_logic := '0';
signal D3 : std_logic := '0';
signal D4 : std_logic := '0';
signal D5 : std_logic_vector(BITS - 1 downto 0) := INIT_I;
signal IsCommand_Clk1 : std_logic;
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 T2 : signal is "NO";
attribute SHREG_EXTRACT of D3 : signal is "NO";
attribute SHREG_EXTRACT of D4 : signal is "NO";
attribute SHREG_EXTRACT of D5 : signal is "NO";
signal syncClk1_In : std_logic;
signal syncClk1_Out : std_logic;
signal syncClk2_In : std_logic;
signal syncClk2_Out : std_logic;
begin
-- input D-FF @Clock1 -> changed detection
process(Clock1)
begin
if rising_edge(Clock1) then
if (Busy_i = '0') then
D0 <= IsCommand_Clk1; -- delay detected IsCommand signal for rising edge detection; gated by busy flag
D1 <= Input;
T2 <= T2 xor Changed_Clk1; -- toggle T2 if input vector has changed
end if;
end if;
end process;
-- D-FF for level change detection (both edges)
process(Clock2)
begin
if rising_edge(Clock2) then
D3 <= syncClk2_Out;
D4 <= Changed_Clk2;
if (D4 = '1') then
D5 <= INIT_I;
elsif (Changed_Clk2 = '1') then
D5 <= D1;
end if;
end if;
end process;
-- assign syncClk*_In signals
syncClk2_In <= T2;
syncClk1_In <= D3;
IsCommand_Clk1 <= to_sl(Input /= INIT_I); -- input command detection
Changed_Clk1 <= not D0 and IsCommand_Clk1; -- input rising edge detection
Changed_Clk2 <= syncClk2_Out xor D3; -- level change detection; restore strobe signal from flag
Busy_i <= T2 xor syncClk1_Out; -- calculate busy signal
-- output signals
Output <= D5;
Busy <= Busy_i;
Changed <= D4;
syncClk2 : entity PoC.sync_Bits
generic map (
BITS => 1, -- number of bit to be synchronized
SYNC_DEPTH => SYNC_DEPTH
)
port map (
Clock => Clock2, -- <Clock> output clock domain
Input(0) => syncClk2_In, -- @async: input bits
Output(0) => syncClk2_Out -- @Clock: output bits
);
syncClk1 : entity PoC.sync_Bits
generic map (
BITS => 1, -- number of bit to be synchronized
SYNC_DEPTH => SYNC_DEPTH
)
port map (
Clock => Clock1, -- <Clock> output clock domain
Input(0) => syncClk1_In, -- @async: input bits
Output(0) => syncClk1_Out -- @Clock: output bits
);
end architecture;