source: firmware/FTM/trigger/drivers/interface_sync/interface_sync_50MHz.vhd@ 10366

Last change on this file since 10366 was 10366, checked in by weitzel, 10 years ago
FTM trigger manager from MCSE added; DCM arrangement changed; changes in FTM ethernet module
File size: 10.2 KB
Line 
1--=======================================================================================
2-- TITLE : Interface synchronization on the 50MHz clock
3-- DESCRIPTION : Manage interface between 250MHz clock domain and 50MHz clock domain
4-- FILE : interface_sync_50MHz.vhd
5-- COMPANY : Micro-Cameras & Space Exploration SA
6--=======================================================================================
7-- CREATION
8-- DATE AUTHOR PROJECT REVISION
9-- 25/03/2011 JGi 110325a
10--=======================================================================================
11-- MODIFICATION HISTORY
12-- DATE AUTHOR PROJECT REVISION COMMENTS
13-- 25/03/2011 JGi 110325a Description
14--=======================================================================================
15-- Library Definition
16library ieee;
17 use ieee.std_logic_1164.all;
18 use ieee.numeric_std.all;
19
20-- Entity Definition
21entity interface_sync_50MHz is
22 port( --clock
23 clk_50MHz : in std_logic;
24 clk_250MHz : in std_logic;
25 --250MHz inputs
26 config_done : in std_logic;
27 trigger_active : in std_logic;
28 trigger_ID_done : in std_logic;
29 trigger_ID : in std_logic_vector(55 downto 0);
30 --50MHz inputs
31 trigger_ID_read : in std_logic;
32 trigger_cnt_read : in std_logic;
33 --outputs
34 sync_config_done : out std_logic;
35 sync_trigger_active : out std_logic;
36 sync_trigger_ID_ready : out std_logic;
37 sync_trigger_ID : out std_logic_vector(55 downto 0);
38 trigger_cnt_valid : out std_logic;
39 trigger_cnt_copy : out std_logic_vector(31 downto 0));
40end interface_sync_50MHz;
41
42-- Architecture Definition
43architecture RTL of interface_sync_50MHz is
44
45 type t_reg_50 is record
46 -- Ouput register declaration
47 sync_config_done : std_logic_vector(3 downto 0);
48 sync_trigger_active : std_logic_vector(3 downto 0);
49 sync_trigger_ID_ready : std_logic_vector(3 downto 0);
50 sync_trigger_ID : std_logic_vector(111 downto 0);
51 trigger_cnt_valid : std_logic;
52 trigger_cnt_copy : std_logic_vector(31 downto 0);
53 end record;
54
55 type t_reg_250 is record
56 -- Internal register declaration
57 config_done : std_logic;
58 sync_config_done : std_logic_vector(1 downto 0);
59 trigger_active : std_logic;
60 sync_trigger_active : std_logic_vector(1 downto 0);
61 trigger_ID_done : std_logic;
62 sync_trigger_ID_done : std_logic_vector(1 downto 0);
63 end record;
64
65 signal i_next_reg_250 : t_reg_250 := (config_done => '0',
66 sync_config_done => (others => '0'),
67 trigger_active => '0',
68 sync_trigger_active => (others => '0'),
69 trigger_ID_done => '0',
70 sync_trigger_ID_done => (others => '0'));
71 signal i_reg_250 : t_reg_250 := (config_done => '0',
72 sync_config_done => (others => '0'),
73 trigger_active => '0',
74 sync_trigger_active => (others => '0'),
75 trigger_ID_done => '0',
76 sync_trigger_ID_done => (others => '0'));
77 signal i_next_reg_50 : t_reg_50 := (sync_config_done => (others => '0'),
78 sync_trigger_active => (others => '0'),
79 sync_trigger_ID_ready => (others => '0'),
80 sync_trigger_ID => (others => '0'),
81 trigger_cnt_valid => '0',
82 trigger_cnt_copy => (others => '0'));
83 signal i_reg_50 : t_reg_50 := (sync_config_done => (others => '0'),
84 sync_trigger_active => (others => '0'),
85 sync_trigger_ID_ready => (others => '0'),
86 sync_trigger_ID => (others => '0'),
87 trigger_cnt_valid => '0',
88 trigger_cnt_copy => (others => '0'));
89
90begin
91
92 -- Combinatorial logic
93 -- Manage signals on the 250MHz side
94 process(config_done, trigger_active, trigger_ID_done, i_reg_50, i_reg_250)
95 variable v_reg : t_reg_250 := (config_done => '0',
96 sync_config_done => (others => '0'),
97 trigger_active => '0',
98 sync_trigger_active => (others => '0'),
99 trigger_ID_done => '0',
100 sync_trigger_ID_done => (others => '0'));
101 begin
102 v_reg := i_reg_250;
103 --===================================================================================
104
105 --===================================================================================
106 -- Generate signals until they have been received by the 50MHz interface
107 --===================================================================================
108 -- Synchronized config done from 50MHz interface
109 v_reg.sync_config_done(0) := i_reg_50.sync_config_done(1);
110 v_reg.sync_config_done(1) := i_reg_250.sync_config_done(0);
111
112 -- Set config done high when detected at input
113 if config_done = '1' then
114 v_reg.config_done := '1';
115 -- Reset config done when set high by the 50MHz part
116 elsif i_reg_250.sync_config_done(1) = '1' then
117 v_reg.config_done := '0';
118 end if;
119
120 -- Synchronized trigger active from 50MHz interface
121 v_reg.sync_trigger_active(0) := i_reg_50.sync_trigger_active(1);
122 v_reg.sync_trigger_active(1) := i_reg_250.sync_trigger_active(0);
123
124 -- Set trigger active high when detected at input
125 if trigger_active = '1' then
126 v_reg.trigger_active := '1';
127 -- Reset trigger active when set high by the 50MHz part
128 elsif i_reg_250.sync_trigger_active(1) = '1' then
129 v_reg.trigger_active := '0';
130 end if;
131
132 -- Detect rising edge on trigger ID ready from 50MHz interface
133 if i_reg_50.sync_trigger_ID_ready(1) = '1' and
134 i_reg_50.sync_trigger_ID_ready(2) = '0' then
135 v_reg.sync_trigger_ID_done(0) := '1';
136 else
137 v_reg.sync_trigger_ID_done(0) := '0';
138 end if;
139 v_reg.sync_trigger_ID_done(1) := i_reg_250.sync_trigger_ID_done(0);
140
141 -- Set trigger ID done high when detected at input
142 if trigger_ID_done = '1' then
143 v_reg.trigger_ID_done := '1';
144 -- Reset trigger ID done when set high by the 50MHz part
145 elsif i_reg_250.sync_trigger_ID_done(1) = '1' then
146 v_reg.trigger_ID_done := '0';
147 end if;
148 --===================================================================================
149
150 --===================================================================================
151 -- Drive register input
152 i_next_reg_250 <= v_reg;
153 --===================================================================================
154 end process;
155
156 -- Manage signals on the 50MHz side
157 process(trigger_ID_read, trigger_ID, trigger_cnt_read, i_reg_250, i_reg_50)
158 variable v_reg : t_reg_50 := (sync_config_done => (others => '0'),
159 sync_trigger_active => (others => '0'),
160 sync_trigger_ID_ready => (others => '0'),
161 sync_trigger_ID => (others => '0'),
162 trigger_cnt_valid => '0',
163 trigger_cnt_copy => (others => '0'));
164 begin
165 v_reg := i_reg_50;
166 --===================================================================================
167
168 --===================================================================================
169 -- Synchronize signals from the 250MHz side
170 --===================================================================================
171 -- Synchronize config done from the 250MHz interface
172 v_reg.sync_config_done(0) := i_reg_250.config_done;
173 v_reg.sync_config_done(1) := i_reg_50.sync_config_done(0);
174 v_reg.sync_config_done(2) := i_reg_50.sync_config_done(1);
175
176 -- Set config done on 50MHz when set by 250MHz interface
177 if i_reg_50.sync_config_done(1) = '1' and i_reg_50.sync_config_done(2) = '0' and
178 i_reg_50.sync_config_done(3) = '0' then
179 v_reg.sync_config_done(3) := '1';
180 else
181 v_reg.sync_config_done(3) := '0';
182 end if;
183
184 -- Synchronize trigger active from the 250MHz interface
185 v_reg.sync_trigger_active(0) := i_reg_250.trigger_active;
186 v_reg.sync_trigger_active(1) := i_reg_50.sync_trigger_active(0);
187
188 -- Synchronize trigger ID ready from the 250MHz interface
189 v_reg.sync_trigger_ID_ready(0) := i_reg_250.trigger_ID_done;
190 v_reg.sync_trigger_ID_ready(1) := i_reg_50.sync_trigger_ID_ready(0);
191 v_reg.sync_trigger_ID_ready(2) := i_reg_50.sync_trigger_ID_ready(1);
192
193 -- Set trigger ready when set on the 250MHz side and release it
194 -- when read by the 50MHz side
195 if trigger_ID_read = '1' then
196 v_reg.sync_trigger_ID_ready(3) := '0';
197 elsif i_reg_50.sync_trigger_ID_ready(1) = '1' and
198 i_reg_50.sync_trigger_ID_ready(2) = '0' then
199 v_reg.sync_trigger_ID_ready(3) := '1';
200 end if;
201
202 -- Simply synchronize trigger ID
203 v_reg.sync_trigger_ID(55 downto 0) := trigger_ID;
204 v_reg.sync_trigger_ID(111 downto 56) := i_reg_50.sync_trigger_ID(55 downto 0);
205
206 -- Counter is a simple copy of the counter of the synchronized trigger ID
207 v_reg.trigger_cnt_valid := trigger_cnt_read;
208 if trigger_cnt_read = '1' then
209 v_reg.trigger_cnt_copy := i_reg_50.sync_trigger_ID(87 downto 56);
210 end if;
211 --===================================================================================
212
213 --===================================================================================
214 -- Drive register input
215 i_next_reg_50 <= v_reg;
216
217 --===================================================================================
218 -- Output assignation
219 sync_config_done <= i_reg_50.sync_config_done(3);
220 sync_trigger_active <= i_reg_50.sync_trigger_active(1);
221 sync_trigger_ID_ready <= i_reg_50.sync_trigger_ID_ready(3);
222 sync_trigger_ID <= i_reg_50.sync_trigger_ID(111 downto 56);
223 trigger_cnt_valid <= i_reg_50.trigger_cnt_valid;
224 trigger_cnt_copy <= i_reg_50.trigger_cnt_copy;
225 --===================================================================================
226 end process;
227
228 -- Sequential logic
229 process(clk_250MHz)
230 begin
231 if rising_edge(clk_250MHz) then
232 i_reg_250 <= i_next_reg_250;
233 end if;
234 end process;
235
236 process(clk_50MHz)
237 begin
238 if rising_edge(clk_50MHz) then
239 i_reg_50 <= i_next_reg_50;
240 end if;
241 end process;
242
243end RTL;
Note: See TracBrowser for help on using the repository browser.