source: firmware/FTM/FTM_central_control.vhd@ 10459

Last change on this file since 10459 was 10441, checked in by weitzel, 13 years ago
new FTM firmware featuring e.g. start/stop run commands and new header
File size: 13.8 KB
Line 
1----------------------------------------------------------------------------------
2-- Company: ETH Zurich, Institute for Particle Physics
3-- Engineer: Q. Weitzel
4--
5-- Create Date: 15:56:13 02/28/2011
6-- Design Name:
7-- Module Name: FTM_central_control - Behavioral
8-- Project Name:
9-- Target Devices:
10-- Tool versions:
11-- Description: Central FSM for FTM firmware
12--
13-- Dependencies:
14--
15-- Revision:
16-- Revision 0.01 - File Created
17-- Additional Comments:
18--
19----------------------------------------------------------------------------------
20library IEEE;
21use IEEE.STD_LOGIC_1164.ALL;
22use IEEE.STD_LOGIC_ARITH.ALL;
23use IEEE.STD_LOGIC_UNSIGNED.ALL;
24
25library ftm_definitions;
26USE ftm_definitions.ftm_array_types.all;
27USE ftm_definitions.ftm_constants.all;
28
29---- Uncomment the following library declaration if instantiating
30---- any Xilinx primitives in this code.
31--library UNISIM;
32--use UNISIM.VComponents.all;
33
34entity FTM_central_control is
35 port(
36 clk : IN std_logic;
37 clk_ready : in std_logic;
38 clk_scaler : IN std_logic;
39 new_config : IN std_logic;
40 config_started : OUT std_logic := '0';
41 config_started_ack : IN std_logic;
42 config_start_eth : OUT std_logic := '0';
43 config_started_eth : IN std_logic;
44 config_ready_eth : IN std_logic;
45 config_start_ftu : OUT std_logic := '0';
46 config_started_ftu : IN std_logic ;
47 config_ready_ftu : IN std_logic ;
48 ping_ftu_start : IN std_logic;
49 ping_ftu_started : OUT std_logic := '0';
50 ping_ftu_ready : OUT std_logic := '0';
51 ping_ftu_start_ftu : OUT std_logic := '0';
52 ping_ftu_started_ftu : IN std_logic;
53 ping_ftu_ready_ftu : IN std_logic;
54 rates_ftu : OUT std_logic := '0';
55 rates_started_ftu : IN std_logic;
56 rates_ready_ftu : IN std_logic;
57 prescaling_FTU01 : IN std_logic_vector(7 downto 0);
58 dd_send : OUT std_logic := '0';
59 dd_send_ack : IN std_logic;
60 dd_send_ready : IN std_logic;
61 dd_block_ready_ftu : out std_logic := '0';
62 dd_block_start_ack_ftu : in std_logic;
63 dd_block_start_ftu : out std_logic := '0';
64 config_start_cc : out std_logic := '0';
65 config_started_cc : in std_logic;
66 config_ready_cc : in std_logic;
67 config_trigger : out std_logic := '0';
68 config_trigger_done : in std_logic;
69 dna_start : out std_logic := '0';
70 dna_ready : in std_logic;
71 crate_reset : IN std_logic;
72 crate_reset_ack : OUT std_logic := '1';
73 crate_reset_param : IN std_logic_vector (15 DOWNTO 0);
74 start_run : IN std_logic;
75 start_run_ack : OUT std_logic := '0';
76 stop_run : IN std_logic;
77 stop_run_ack : OUT std_logic := '0';
78 current_cc_state : OUT std_logic_vector (15 DOWNTO 0) := X"FFFF";
79 start_run_param : IN std_logic_vector (15 DOWNTO 0);
80 start_run_num_events : IN std_logic_vector (31 DOWNTO 0);
81 trigger_start : out std_logic := '0';
82 trigger_stop : out std_logic := '1'
83 );
84end FTM_central_control;
85
86architecture Behavioral of FTM_central_control is
87
88 signal reset_scaler_sig : std_logic := '0';
89 signal reset_period_sig : std_logic := '0';
90 signal scaler_counts_sig : integer := 0;
91 signal scaler_period_sig : integer range 0 to 128 * (LOW_FREQUENCY / SCALER_FREQ_DIVIDER) := 128 * (LOW_FREQUENCY / SCALER_FREQ_DIVIDER);
92 signal period_finished_sig : std_logic := '0';
93 signal wait_cnt_sig : integer range 0 to 10 := 0;
94 signal new_period_sr_sig : std_logic_vector(1 downto 0) := (others => '0');
95 signal new_period_sig : std_logic := '0';
96 signal new_period_ack_sig : std_logic := '0';
97 signal prescaling_FTU01_sig : std_logic_vector(7 downto 0) := "00100111";
98
99 type state_central_proc_type is (CP_INIT, CP_INIT_DNA,
100 CP_RUNNING, CP_RUNNING_01, CP_RUNNING_02, CP_CONFIG_ACK,
101 CP_CONFIG_START, CP_CONFIG, CP_CONFIG_01,
102 CP_CONFIG_CC, CP_CONFIG_CC_01,
103 CP_CONFIG_FTU, CP_CONFIG_FTU_01,
104 CP_CONFIG_SCALER, CP_CONFIG_SCALER_01,
105 CP_CONFIG_TRIGGER, CP_CONFIG_TRIGGER_01,
106 CP_IDLE, CP_PING, CP_START_RATES, CP_READ_RATES, CP_READ_RATES_01,
107 CP_SEND_START, CP_SEND_END);
108 signal state_central_proc : state_central_proc_type := CP_INIT;
109
110 signal after_rates_state : state_central_proc_type := CP_IDLE;
111 signal after_ping_state : state_central_proc_type := CP_IDLE;
112
113begin
114
115 central_proc : process (clk, prescaling_FTU01)
116 begin
117 if rising_edge (clk) then
118 case state_central_proc is
119
120 when CP_INIT => -- wait for DCMs to lock
121 if (clk_ready = '1') then
122 state_central_proc <= CP_INIT_DNA;
123 end if;
124
125 when CP_INIT_DNA => -- get FPGA DNA
126 if (dna_ready = '1') then
127 state_central_proc <= CP_CONFIG;
128 dna_start <= '0';
129 else
130 dna_start <= '1';
131 state_central_proc <= CP_INIT_DNA;
132 end if;
133
134 when CP_CONFIG_START =>
135 if (config_started_ack = '1') then
136 config_started <= '0';
137 state_central_proc <= CP_CONFIG;
138 end if;
139
140 when CP_CONFIG =>
141 config_start_eth <= '1';
142 if (config_started_eth = '1') then
143 config_start_eth <= '0';
144 state_central_proc <= CP_CONFIG_01;
145 end if;
146
147 when CP_CONFIG_01 =>
148 if (config_ready_eth = '1') then
149 state_central_proc <= CP_CONFIG_CC;
150 --state_central_proc <= CP_CONFIG_SCALER;
151 --state_central_proc <= CP_IDLE;
152 end if;
153
154 when CP_CONFIG_CC =>
155 config_start_cc <= '1';
156 if (config_started_cc = '1') then
157 config_start_cc <= '0';
158 state_central_proc <= CP_CONFIG_CC_01;
159 end if;
160
161 when CP_CONFIG_CC_01 =>
162 if (config_ready_cc = '1') then
163 state_central_proc <= CP_CONFIG_FTU;
164 end if;
165
166 when CP_CONFIG_FTU =>
167 config_start_ftu <= '1';
168 if (config_started_ftu = '1') then
169 config_start_ftu <= '0';
170 state_central_proc <= CP_CONFIG_FTU_01;
171 end if;
172
173 when CP_CONFIG_FTU_01 =>
174 if (config_ready_ftu = '1') then
175 state_central_proc <= CP_CONFIG_SCALER;
176 end if;
177
178 when CP_CONFIG_SCALER =>
179 prescaling_FTU01_sig <= prescaling_FTU01;
180 --reset_period_sig <= '1';
181 state_central_proc <= CP_CONFIG_SCALER_01;
182
183 when CP_CONFIG_SCALER_01 =>
184 --reset_period_sig <= '0';
185 if wait_cnt_sig < 5 then
186 wait_cnt_sig <= wait_cnt_sig + 1;
187 reset_scaler_sig <= '1';
188 state_central_proc <= CP_CONFIG_SCALER_01;
189 else
190 wait_cnt_sig <= 0;
191 reset_scaler_sig <= '0';
192 state_central_proc <= CP_CONFIG_TRIGGER;
193 end if;
194
195 when CP_CONFIG_TRIGGER =>
196 --config trigger_manager block
197 config_trigger <= '1';
198 state_central_proc <= CP_CONFIG_TRIGGER_01;
199
200 when CP_CONFIG_TRIGGER_01 =>
201 config_trigger <= '0';
202 if (config_trigger_done = '1') then
203 state_central_proc <= CP_IDLE;
204 end if;
205
206 when CP_IDLE =>
207 current_cc_state <= FTM_STATE_IDLE;
208 stop_run_ack <= '1';
209 start_run_ack <= '0';
210 if (new_config = '1') then
211 config_started <= '1';
212 start_run_ack <= '1';
213 state_central_proc <= CP_CONFIG_START;
214 elsif (ping_ftu_start = '1') then
215 ping_ftu_start_ftu <= '1';
216 if (ping_ftu_started_ftu = '1') then
217 ping_ftu_start_ftu <= '0';
218 ping_ftu_started <= '1';
219 ping_ftu_ready <= '0';
220 after_ping_state <= CP_IDLE;
221 state_central_proc <= CP_PING;
222 end if;
223 --elsif (scaler_counts_sig = scaler_period_sig) then
224 elsif (new_period_sig = '1') then
225 new_period_ack_sig <= '1';
226 --rates_ftu <= '1';
227 --state_central_proc <= CP_READ_RATES;
228 after_rates_state <= CP_IDLE;
229 state_central_proc <= CP_START_RATES;
230 elsif (start_run = '1') then
231 start_run_ack <= '1';
232 if (start_run_param = PAR_START_RUN) then
233 state_central_proc <= CP_RUNNING;
234 end if;
235 end if;
236
237 when CP_RUNNING =>
238 current_cc_state <= FTM_STATE_RUN;
239 if (start_run = '0') then
240 start_run_ack <= '0';
241 stop_run_ack <= '0';
242 state_central_proc <= CP_RUNNING_01;
243 end if;
244
245 when CP_RUNNING_01 =>
246 current_cc_state <= FTM_STATE_RUN;
247 start_run_ack <= '1';
248 trigger_start <= '1';
249 trigger_stop <= '0';
250 if (new_config = '1') then
251 config_started <= '1';
252 state_central_proc <= CP_CONFIG_ACK;
253 elsif (ping_ftu_start = '1') then
254 ping_ftu_start_ftu <= '1';
255 if (ping_ftu_started_ftu = '1') then
256 ping_ftu_start_ftu <= '0';
257 ping_ftu_started <= '1';
258 ping_ftu_ready <= '0';
259 after_ping_state <= CP_RUNNING_01;
260 state_central_proc <= CP_PING;
261 end if;
262 elsif (new_period_sig = '1') then
263 new_period_ack_sig <= '1';
264 --rates_ftu <= '1';
265 --state_central_proc <= CP_READ_RATES;
266 after_rates_state <= CP_RUNNING_01;
267 state_central_proc <= CP_START_RATES;
268 elsif (stop_run = '1') then
269 stop_run_ack <= '1';
270 trigger_start <= '0';
271 trigger_stop <= '1';
272 state_central_proc <= CP_RUNNING_02;
273 end if;
274
275 when CP_RUNNING_02 =>
276 if (stop_run = '0') then
277 stop_run_ack <= '0';
278 state_central_proc <= CP_IDLE;
279 end if;
280
281 when CP_CONFIG_ACK =>
282 if (config_started_ack = '1') then
283 config_started <= '0';
284 state_central_proc <= CP_RUNNING_01;
285 end if;
286
287 when CP_PING =>
288 if (ping_ftu_ready_ftu = '1') then
289 if (ping_ftu_start = '0') then
290 ping_ftu_started <= '0';
291 ping_ftu_ready <= '1';
292 --state_central_proc <= CP_IDLE;
293 state_central_proc <= after_ping_state;
294 end if;
295 end if;
296
297 when CP_START_RATES =>
298 new_period_ack_sig <= '0';
299 dd_block_start_ftu <= '1';
300 dd_block_ready_ftu <= '0';
301 if (dd_block_start_ack_ftu = '1') then
302 dd_block_start_ftu <= '0';
303 rates_ftu <= '1';
304 state_central_proc <= CP_READ_RATES;
305 end if;
306
307 when CP_READ_RATES =>
308 new_period_ack_sig <= '0';
309 if (rates_started_ftu = '1') then
310 rates_ftu <= '0';
311 state_central_proc <= CP_READ_RATES_01;
312 end if;
313
314 when CP_READ_RATES_01 =>
315 if (rates_ready_ftu = '1') then
316 dd_block_ready_ftu <= '1';
317 if ( (start_run = '1') or (stop_run = '1') ) then
318 state_central_proc <= after_rates_state;
319 else
320 state_central_proc <= CP_SEND_START;
321 end if;
322 end if;
323
324 when CP_SEND_START =>
325 dd_send <= '1';
326 if (dd_send_ack = '1') then
327 dd_send <= '0';
328 state_central_proc <= CP_SEND_END;
329 end if;
330
331 when CP_SEND_END =>
332 if (dd_send_ready = '1') then
333 --state_central_proc <= CP_IDLE;
334 state_central_proc <= after_rates_state;
335 end if;
336
337 end case;
338 end if;
339 end process central_proc;
340
341 scaler_process: process(reset_scaler_sig, clk_scaler)
342 begin
343 if (reset_scaler_sig = '1') then
344 scaler_counts_sig <= 0;
345 period_finished_sig <= '0';
346 elsif rising_edge(clk_scaler) then
347 if (scaler_counts_sig < scaler_period_sig) then
348 scaler_counts_sig <= scaler_counts_sig + 1;
349 period_finished_sig <= '0';
350 else
351 period_finished_sig <= '1';
352 scaler_counts_sig <= 0;
353 end if;
354 end if;
355 end process scaler_process;
356
357-- process(reset_period_sig)
358-- begin
359-- if rising_edge(reset_period_sig) then
360-- if ((conv_integer(unsigned(prescaling_FTU01))) mod 2 = 0) then
361-- scaler_period_sig <= ((((conv_integer(unsigned(prescaling_FTU01)) / 2)) * (LOW_FREQUENCY / SCALER_FREQ_DIVIDER)) + (LOW_FREQUENCY / (2 * SCALER_FREQ_DIVIDER)));
362-- else
363-- scaler_period_sig <= (((conv_integer(unsigned(prescaling_FTU01)) - 1) / 2) + 1) * (LOW_FREQUENCY / SCALER_FREQ_DIVIDER);
364-- end if;
365-- end if;
366-- end process;
367
368 process(prescaling_FTU01_sig)
369 begin
370 if ((conv_integer(unsigned(prescaling_FTU01_sig))) mod 2 = 0) then
371 scaler_period_sig <= ((((conv_integer(unsigned(prescaling_FTU01_sig)) / 2)) * (LOW_FREQUENCY / SCALER_FREQ_DIVIDER)) + (LOW_FREQUENCY / (2 * SCALER_FREQ_DIVIDER)));
372 else
373 scaler_period_sig <= (((conv_integer(unsigned(prescaling_FTU01_sig)) - 1) / 2) + 1) * (LOW_FREQUENCY / SCALER_FREQ_DIVIDER);
374 end if;
375 end process;
376
377 detect_period_finished: process(clk)
378 begin
379 if rising_edge(clk) then
380 new_period_sr_sig <= new_period_sr_sig(new_period_sr_sig'left - 1 downto 0) & period_finished_sig;
381 if(new_period_ack_sig = '1') then
382 new_period_sig <= '0';
383 else
384 if (new_period_sr_sig(1 downto 0) = "01") then
385 new_period_sig <= '1';
386 end if;
387 end if;
388 end if;
389 end process detect_period_finished;
390
391end Behavioral;
Note: See TracBrowser for help on using the repository browser.