source: firmware/FTM/FTM_central_control.vhd @ 10441

Last change on this file since 10441 was 10441, checked in by weitzel, 9 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.