source: firmware/FTM/ftu_control/FTM_ftu_control.vhd @ 10175

Last change on this file since 10175 was 10175, checked in by weitzel, 10 years ago
first version of FTM_ftu_control, not yet tested
File size: 39.3 KB
Line 
1----------------------------------------------------------------------------------
2-- Company:        ETH Zurich, Institute for Particle Physics
3-- Engineer:       Q. Weitzel
4--
5-- Create Date:    17:54:04 02/02/2011
6-- Design Name:
7-- Module Name:    FTM_ftu_control - Behavioral
8-- Project Name:
9-- Target Devices:
10-- Tool versions:
11-- Description:    Communication of FTM with the 40 FTU boards of the FACT camera
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_ftu_control is
35  port(
36    clk_50MHz : in  std_logic;  -- main clock
37   
38    -- global bus enables for FTU crates 0-3
39    rx_en : out STD_LOGIC;  -- receiver enable
40    tx_en : out STD_LOGIC;  -- transmitter enable
41   
42    -- FTU crate 0 data I/O
43    rx_d_0 : in  STD_LOGIC;
44    tx_d_0 : out STD_LOGIC;
45
46    -- FTU crate 1 data I/O
47    rx_d_1 : in  STD_LOGIC;
48    tx_d_1 : out STD_LOGIC;
49
50    -- FTU crate 2 data I/O
51    rx_d_2 : in  STD_LOGIC;
52    tx_d_2 : out STD_LOGIC;
53
54    -- FTU crate 3 data I/O
55    rx_d_3 : in  STD_LOGIC;
56    tx_d_3 : out STD_LOGIC;
57
58    -- commands from FTM main control
59    new_config : in std_logic;
60    ping_all   : in std_logic;
61    read_rates : in std_logic;
62
63    -- answers to FTM main control
64    read_rates_started : out std_logic := '0';
65    read_rates_done    : out std_logic := '0';
66    new_config_started : out std_logic := '0';
67    new_config_done    : out std_logic := '0';
68    ping_all_started   : out std_logic := '0';
69    ping_all_done      : out std_logic := '0';
70
71    -- communication with static (config) RAM
72    -- this RAM is only read by FTU_control
73    static_RAM_busy    :  in std_logic;
74    static_RAM_started :  in std_logic;
75    static_RAM_ready   :  in std_logic;
76    data_static_RAM    :  in std_logic_vector(15 downto 0) := (others => '0');
77    read_static_RAM    : out std_logic := '0';
78    addr_static_RAM    : out std_logic_vector(11 downto 0) := (others => '0');
79   
80    -- communication with dynamic RAM (e.g. rates)
81    -- this RAM is only written by FTU_control
82    dynamic_RAM_busy    :  in std_logic;
83    dynamic_RAM_started :  in std_logic;
84    dynamic_RAM_ready   :  in std_logic;
85    data_dynamic_RAM    : out std_logic_vector(15 downto 0) := (others => '0');
86    write_dynamic_RAM   : out std_logic := '0';
87    addr_dynamic_RAM    : out std_logic_vector(11 downto 0) := (others => '0');
88
89    -- communication with FTU-list RAM
90    -- this RAM is only written by FTU_control
91    FTUlist_RAM_busy    :  in std_logic;
92    FTUlist_RAM_started :  in std_logic;
93    FTUlist_RAM_ready   :  in std_logic;
94    data_FTUlist_RAM    : out std_logic_vector(15 downto 0) := (others => '0');
95    write_FTUlist_RAM   : out std_logic := '0';
96    addr_FTUlist_RAM    : out std_logic_vector(11 downto 0) := (others => '0')
97   
98  );
99end FTM_ftu_control;
100
101architecture Behavioral of FTM_ftu_control is
102
103  -- list of active FTUs, read out from static RAM before starting to contact FTUs
104  signal active_FTU_array_sig : active_FTU_array_type := ((others => '0'), (others => '0'), (others => '0'), (others => '0'));
105
106  -- signals to count the number of responding FTUs (per crate and total) in case of a ping
107  signal FTU_answer_array_sig : FTU_answer_array_type := (0,0,0,0);
108  signal no_of_FTU_answer_sig : integer range 0 to (NO_OF_CRATES * NO_OF_FTUS_PER_CRATE) := 0;
109 
110  -- FTU configuration data, read out from static RAM (board by board)
111  signal FTU_dac_array_RAM_sig    : FTU_dac_array_type := ((others => '0'), (others => '0'), (others => '0'), (others => '0'), (others => '0'));
112  signal FTU_enable_array_RAM_sig : FTU_enable_array_type := ((others => '0'), (others => '0'), (others => '0'), (others => '0'));
113  signal FTU_prescaling_RAM_sig   : std_logic_vector(15 downto 0) := (others => '0');
114 
115  -- signals for receiver of FTU communication
116  signal rec_reset_sig : std_logic := '0';  -- reset
117  signal rec_data_sig  : std_logic_vector (7 DOWNTO 0);
118  signal rec_block_sig : std_logic_vector (FTU_RS485_BLOCK_WIDTH - 1 downto 0);  -- initialized in FTM_ftu_rs485_receiver
119  signal rec_valid_sig : std_logic;  -- initialized in FTM_ftu_rs485_receiver
120 
121  -- select signal to multiplex the different crates
122  signal sel_crate_sig : STD_LOGIC_VECTOR (2 downto 0) := "111";
123
124  -- global signals after multiplexer
125  signal rx_en_sig    : std_logic;
126  signal tx_en_sig    : std_logic;
127  signal rx_valid_sig : std_logic;
128  signal tx_busy_sig  : std_logic;
129  signal tx_start_sig : std_logic;
130  signal tx_data_sig  : std_logic_vector (7 DOWNTO 0);
131 
132  -- signals for interpreter of FTU communication
133  signal FTU_brd_add_sig       : std_logic_vector (5 DOWNTO 0) := (others => '0');
134  signal FTU_command_sig       : std_logic_vector (7 DOWNTO 0) := (others => '1');
135  signal FTU_answer_ok_sig     : std_logic;  -- initialized in interpreter
136  signal FTU_dac_array_sig     : FTU_dac_array_type;  -- initialized in interpreter
137  signal FTU_enable_array_sig  : FTU_enable_array_type;  -- initialized in interpreter
138  signal FTU_rate_array_sig    : FTU_rate_array_type;  -- initialized in interpreter
139  signal FTU_prescaling_sig    : std_logic_vector(7 downto 0);  -- initialized in interpreter
140  signal FTU_crc_error_cnt_sig : std_logic_vector(7 downto 0);  -- initialized in interpreter
141  signal FTU_dna_sig           : std_logic_vector(63 downto 0);  -- initialized in interpreter
142 
143  -- rx_enable and tx_enable lines from different FTM_ftu_rs485_interface
144  -- initialized in corresponding interface
145  signal rx_en_0_sig : STD_LOGIC;
146  signal tx_en_0_sig : STD_LOGIC;
147  signal rx_en_1_sig : STD_LOGIC;
148  signal tx_en_1_sig : STD_LOGIC;
149  signal rx_en_2_sig : STD_LOGIC;
150  signal tx_en_2_sig : STD_LOGIC;
151  signal rx_en_3_sig : STD_LOGIC;
152  signal tx_en_3_sig : STD_LOGIC;
153
154  signal tx_start_0_sig : std_logic := '0';
155  signal tx_data_0_sig  : std_logic_vector (7 DOWNTO 0) := (others => '0');
156  signal tx_busy_0_sig  : std_logic;  -- initialized in FTM_ftu_rs485_interface_0
157  signal rx_valid_0_sig : std_logic;  -- initialized in FTM_ftu_rs485_interface_0
158  signal rx_data_0_sig  : std_logic_vector (7 DOWNTO 0);  -- initialized in FTM_ftu_rs485_interface_0
159 
160  signal tx_start_1_sig : std_logic := '0';
161  signal tx_data_1_sig  : std_logic_vector (7 DOWNTO 0) := (others => '0');
162  signal tx_busy_1_sig  : std_logic;  -- initialized in FTM_ftu_rs485_interface_1
163  signal rx_valid_1_sig : std_logic;  -- initialized in FTM_ftu_rs485_interface_1
164  signal rx_data_1_sig  : std_logic_vector (7 DOWNTO 0);  -- initialized in FTM_ftu_rs485_interface_1
165
166  signal tx_start_2_sig : std_logic := '0';
167  signal tx_data_2_sig  : std_logic_vector (7 DOWNTO 0) := (others => '0');
168  signal tx_busy_2_sig  : std_logic;  -- initialized in FTM_ftu_rs485_interface_2
169  signal rx_valid_2_sig : std_logic;  -- initialized in FTM_ftu_rs485_interface_2
170  signal rx_data_2_sig  : std_logic_vector (7 DOWNTO 0);  -- initialized in FTM_ftu_rs485_interface_2
171
172  signal tx_start_3_sig : std_logic := '0';
173  signal tx_data_3_sig  : std_logic_vector (7 DOWNTO 0) := (others => '0');
174  signal tx_busy_3_sig  : std_logic;  -- initialized in FTM_ftu_rs485_interface_3
175  signal rx_valid_3_sig : std_logic;  -- initialized in FTM_ftu_rs485_interface_3
176  signal rx_data_3_sig  : std_logic_vector (7 DOWNTO 0);  -- initialized in FTM_ftu_rs485_interface_3
177
178  -- signals to control and read out CRC
179  signal sel_crc_input_source_sig        : std_logic := '0';  -- 0 -> FSM, 1 -> interpreter
180  signal reset_crc_sig                   : std_logic;
181  signal enable_crc_sig                  : std_logic;
182  signal crc_data_sig                    : std_logic_vector (FTU_RS485_BLOCK_WIDTH - 9 downto 0) := (others => '0');
183  signal reset_crc_from_FSM_sig          : std_logic := '0';
184  signal reset_crc_from_interpreter_sig  : std_logic;
185  signal enable_crc_from_FSM_sig         : std_logic := '0';
186  signal enable_crc_from_interpreter_sig : std_logic;
187  signal crc_data_from_FSM_sig           : std_logic_vector (FTU_RS485_BLOCK_WIDTH - 9 downto 0) := (others => '0');
188  signal crc_sig                         : std_logic_vector(CRC_POLYNOMIAL'length - 1 downto 0);
189  signal crc_sig_inv                     : std_logic_vector(CRC_POLYNOMIAL'length - 1 downto 0);
190
191  -- various loop counters
192  signal active_FTU_list_cnt : integer range 0 to NO_OF_CRATES := 0;
193  signal crate_cnt           : integer range 0 to NO_OF_CRATES := 0;
194  signal FTU_cnt             : integer range 0 to NO_OF_FTUS_PER_CRATE := 0;
195  signal FTU_register_cnt    : integer range 0 to (NO_OF_FTU_ENABLE_REG + NO_OF_FTU_DAC_REG + 1) := 0;
196  signal FTU_command_cnt     : integer range 0 to 3 := 0;
197  signal frame_cnt           : integer range 0 to (FTU_RS485_BLOCK_WIDTH / 8) := 0;
198  signal FTU_list_reg_cnt    : integer range 0 to NO_OF_FTU_LIST_REG := 0;
199  signal FTU_list_header_cnt : integer range 0 to FTU_LIST_RAM_OFFSET := 0;
200
201  -- counter to define timeout and number of retries
202  signal timeout_cnt : integer range 0 to FTU_RS485_TIMEOUT := 0;
203  signal retry_cnt   : integer range 0 to FTU_RS485_NO_OF_RETRY := 0;
204 
205  component FTM_ftu_rs485_interface
206    port(
207      clk      : IN  std_logic;
208      -- RS485
209      rx_d     : IN  std_logic;
210      rx_en    : OUT std_logic;
211      tx_d     : OUT std_logic;
212      tx_en    : OUT std_logic;
213      -- FPGA
214      rx_data  : OUT std_logic_vector (7 DOWNTO 0);
215      --rx_busy  : OUT std_logic  := '0';
216      rx_valid : OUT std_logic  := '0';
217      tx_data  : IN  std_logic_vector (7 DOWNTO 0);
218      tx_busy  : OUT std_logic  := '0';
219      tx_start : IN  std_logic
220    );
221  end component;
222
223  component FTM_ftu_rs485_receiver
224    port(
225      rec_clk   : in  std_logic;
226      rec_reset : in  std_logic;
227      --rx_busy   : in  std_logic;
228      rec_din   : in  std_logic_vector(7 downto 0);
229      rec_den   : in  std_logic;
230      rec_dout  : out std_logic_vector(FTU_RS485_BLOCK_WIDTH - 1 downto 0) := (others => '0');
231      rec_valid : out std_logic := '0'
232    );
233  end component;
234
235  component FTM_ftu_rs485_interpreter
236    port(
237      clk               : IN  std_logic;
238      data_block        : IN  std_logic_vector(FTU_RS485_BLOCK_WIDTH - 1 downto 0);
239      block_valid       : IN  std_logic;
240      crc               : IN  std_logic_vector(7 downto 0);
241      FTU_brd_add       : IN  std_logic_vector(5 downto 0);
242      FTU_command       : IN  std_logic_vector(7 downto 0);
243      reset_crc         : OUT std_logic := '0';
244      enable_crc        : OUT std_logic := '0';
245      FTU_answer_ok     : OUT std_logic := '0';
246      FTU_dac_array     : OUT FTU_dac_array_type;
247      FTU_enable_array  : OUT FTU_enable_array_type;
248      FTU_rate_array    : OUT FTU_rate_array_type;
249      FTU_prescaling    : OUT std_logic_vector(7 downto 0);
250      FTU_crc_error_cnt : OUT std_logic_vector(7 downto 0);
251      FTU_dna           : OUT std_logic_vector(63 downto 0)
252    );
253  end component;
254 
255  component ucrc_par
256    generic(
257      POLYNOMIAL : std_logic_vector;
258      INIT_VALUE : std_logic_vector;
259      DATA_WIDTH : integer range 2 to 256;
260      SYNC_RESET : integer range 0 to 1
261    );
262    port(
263      clk_i   : in  std_logic;
264      rst_i   : in  std_logic;
265      clken_i : in  std_logic;
266      data_i  : in  std_logic_vector(DATA_WIDTH - 1 downto 0);
267      match_o : out std_logic;
268      crc_o   : out std_logic_vector(POLYNOMIAL'length - 1 downto 0)
269    );
270  end component;
271
272  type FTM_ftu_rs485_control_StateType is (INIT, IDLE, ACTIVE_LIST, READ_CONFIG, TRANSMIT_CONFIG,
273                                           PING, PING_END, FTU_LIST, RATES,
274                                           ACTIVE_LIST_1, ACTIVE_LIST_2, ACTIVE_LIST_3,
275                                           READ_CONFIG_1, READ_CONFIG_2, READ_CONFIG_3,
276                                           TRANSMIT_CONFIG_1, TRANSMIT_CONFIG_2, TRANSMIT_CONFIG_3,
277                                           PING_1, PING_2, PING_3, PING_END_1, PING_END_2, PING_END_3,
278                                           FTU_LIST_1, FTU_LIST_2, FTU_LIST_3);
279  signal FTM_ftu_rs485_control_State : FTM_ftu_rs485_control_StateType;
280
281begin
282
283  Inst_FTM_fTU_rs485_interface_0 : FTM_ftu_rs485_interface  -- crate 0
284    port map(
285      clk      => clk_50MHz,
286      -- RS485
287      rx_d     => rx_d_0,
288      rx_en    => rx_en_0_sig,
289      tx_d     => tx_d_0,
290      tx_en    => tx_en_0_sig,
291      -- FPGA
292      rx_data  => rx_data_0_sig,
293      --rx_busy  => ,
294      rx_valid => rx_valid_0_sig,
295      tx_data  => tx_data_0_sig,
296      tx_busy  => tx_busy_0_sig,
297      tx_start => tx_start_0_sig
298    );
299
300  Inst_FTM_fTU_rs485_interface_1 : FTM_ftu_rs485_interface  -- crate 1
301    port map(
302      clk      => clk_50MHz,
303      -- RS485
304      rx_d     => rx_d_1,
305      rx_en    => rx_en_1_sig,
306      tx_d     => tx_d_1,
307      tx_en    => tx_en_1_sig,
308      -- FPGA
309      rx_data  => rx_data_1_sig,
310      --rx_busy  => ,
311      rx_valid => rx_valid_1_sig,
312      tx_data  => tx_data_1_sig,
313      tx_busy  => tx_busy_1_sig,
314      tx_start => tx_start_1_sig
315    );
316
317  Inst_FTM_fTU_rs485_interface_2 : FTM_ftu_rs485_interface  -- crate 2
318    port map(
319      clk      => clk_50MHz,
320      -- RS485
321      rx_d     => rx_d_2,
322      rx_en    => rx_en_2_sig,
323      tx_d     => tx_d_2,
324      tx_en    => tx_en_2_sig,
325      -- FPGA
326      rx_data  => rx_data_2_sig,
327      --rx_busy  => ,
328      rx_valid => rx_valid_2_sig,
329      tx_data  => tx_data_2_sig,
330      tx_busy  => tx_busy_2_sig,
331      tx_start => tx_start_2_sig
332    );
333
334  Inst_FTM_fTU_rs485_interface_3 : FTM_ftu_rs485_interface  -- crate 3
335    port map(
336      clk      => clk_50MHz,
337      -- RS485
338      rx_d     => rx_d_3,
339      rx_en    => rx_en_3_sig,
340      tx_d     => tx_d_3,
341      tx_en    => tx_en_3_sig,
342      -- FPGA
343      rx_data  => rx_data_3_sig,
344      --rx_busy  => ,
345      rx_valid => rx_valid_3_sig,
346      tx_data  => tx_data_3_sig,
347      tx_busy  => tx_busy_3_sig,
348      tx_start => tx_start_3_sig
349    );
350
351  Inst_FTM_ftu_rs485_receiver : FTM_ftu_rs485_receiver
352    port map(
353      rec_clk   => clk_50MHz,
354      rec_reset => rec_reset_sig,
355      --rx_busy   =>,
356      rec_din   => rec_data_sig,
357      rec_den   => rx_valid_sig,
358      rec_dout  => rec_block_sig,
359      rec_valid => rec_valid_sig
360    );
361
362  Inst_FTM_ftu_rs485_interpreter : FTM_ftu_rs485_interpreter
363    port map(
364      clk               => clk_50MHz,
365      data_block        => rec_block_sig,
366      block_valid       => rec_valid_sig,
367      crc               => crc_sig,
368      FTU_brd_add       => FTU_brd_add_sig,
369      FTU_command       => FTU_command_sig,
370      reset_crc         => reset_crc_from_interpreter_sig,
371      enable_crc        => enable_crc_from_interpreter_sig,
372      FTU_answer_ok     => FTU_answer_ok_sig,
373      FTU_dac_array     => FTU_dac_array_sig,
374      FTU_enable_array  => FTU_enable_array_sig,
375      FTU_rate_array    => FTU_rate_array_sig,
376      FTU_prescaling    => FTU_prescaling_sig,
377      FTU_crc_error_cnt => FTU_crc_error_cnt_sig,
378      FTU_dna           => FTU_dna_sig
379    );
380 
381  Inst_ucrc_par : ucrc_par
382    generic map(
383      POLYNOMIAL => CRC_POLYNOMIAL,
384      INIT_VALUE => CRC_INIT_VALUE,
385      DATA_WIDTH => (FTU_RS485_BLOCK_WIDTH - 8),
386      SYNC_RESET => 1
387    )
388    port map(
389      clk_i   => clk_50MHz,
390      rst_i   => reset_crc_sig,
391      clken_i => enable_crc_sig,
392      data_i  => crc_data_sig,
393      match_o => open,
394      crc_o   => crc_sig_inv
395    );
396
397  -- Main finite state machine to control all 40 FTUs
398  FTM_ftu_rs485_control_FSM: process (clk_50MHz)
399  begin
400    if Rising_edge(clk_50MHz) then
401      case FTM_ftu_rs485_control_State is
402
403        when INIT =>  -- reset CRC register
404          reset_crc_from_FSM_sig <= '1';
405          FTM_ftu_rs485_control_State <= IDLE;
406
407        when IDLE =>  -- wait for command from outside
408          sel_crate_sig <= "111";
409          sel_crc_input_source_sig <= '0';
410          reset_crc_from_FSM_sig <= '0';
411          enable_crc_from_FSM_sig <= '0';
412          new_config_done <= '0';
413          ping_all_done   <= '0';
414          read_rates_done <= '0';
415          if (new_config = '1') then
416            new_config_started <= '1';
417            ping_all_started   <= '0';
418            read_rates_started <= '0';
419            FTM_ftu_rs485_control_State <= ACTIVE_LIST;
420          elsif (new_config = '0' and  ping_all = '1') then
421            new_config_started <= '0';
422            ping_all_started   <= '1';
423            read_rates_started <= '0';
424            FTM_ftu_rs485_control_State <= PING;
425          elsif (new_config = '0' and  ping_all = '0' and read_rates = '1') then
426            new_config_started <= '0';
427            ping_all_started   <= '0';
428            read_rates_started <= '1';
429            FTM_ftu_rs485_control_State <= RATES;
430          else
431            new_config_started <= '0';
432            ping_all_started   <= '0';
433            read_rates_started <= '0';
434            FTM_ftu_rs485_control_State <= IDLE;
435          end if;
436
437        when ACTIVE_LIST =>  -- loop over 4 crates to get active FTU list
438          if (active_FTU_list_cnt < NO_OF_CRATES) then
439            active_FTU_list_cnt <= active_FTU_list_cnt + 1;
440            FTM_ftu_rs485_control_State <= ACTIVE_LIST_1;
441          else
442            active_FTU_list_cnt <= 0;
443            FTM_ftu_rs485_control_State <= READ_CONFIG;
444          end if;
445
446        when ACTIVE_LIST_1 =>
447          if (static_RAM_busy = '0') then
448            read_static_RAM <= '1';
449            addr_static_RAM <= conv_std_logic_vector(STATIC_RAM_ACT_FTU_OFFSET + (active_FTU_list_cnt - 1), STATIC_RAM_ADDR_WIDTH);
450            FTM_ftu_rs485_control_State <= ACTIVE_LIST_2;
451          end if;
452           
453        when ACTIVE_LIST_2 =>
454          if (static_RAM_started = '1') then
455            FTM_ftu_rs485_control_State <= ACTIVE_LIST_3;
456          end if;
457           
458        when ACTIVE_LIST_3 =>
459          if (static_RAM_ready = '1') then
460            active_FTU_array_sig(active_FTU_list_cnt - 1) <= data_static_RAM;
461            read_static_RAM <= '0';
462            FTM_ftu_rs485_control_State <= ACTIVE_LIST;
463          end if;
464                   
465        when READ_CONFIG =>  -- read configuration of FTUs (one by one)
466          if (crate_cnt < NO_OF_CRATES) then
467            sel_crate_sig <= conv_std_logic_vector(crate_cnt, 3);
468            if (FTU_cnt < NO_OF_FTUS_PER_CRATE) then
469              if (FTU_register_cnt < (NO_OF_FTU_ENABLE_REG + NO_OF_FTU_DAC_REG + 1)) then
470                FTU_register_cnt <= FTU_register_cnt + 1;
471                FTM_ftu_rs485_control_State <= READ_CONFIG_1;
472              else
473                FTU_cnt <= FTU_cnt + 1;
474                FTU_register_cnt <= 0;
475                if (active_FTU_array_sig(crate_cnt)(FTU_cnt) = '1') then
476                  FTM_ftu_rs485_control_State <= TRANSMIT_CONFIG;
477                else
478                  FTM_ftu_rs485_control_State <= READ_CONFIG;
479                end if;
480              end if;
481            else
482              crate_cnt <= crate_cnt + 1;
483              FTU_cnt <= 0;
484              FTM_ftu_rs485_control_State <= READ_CONFIG;
485            end if;
486          else
487            crate_cnt <= 0;
488            new_config_started <= '0';
489            new_config_done <= '1';
490            sel_crate_sig <= "111";
491            FTM_ftu_rs485_control_State <= IDLE;
492          end if;
493
494        when READ_CONFIG_1 =>
495          if (static_RAM_busy = '0') then
496            read_static_RAM <= '1';
497            addr_static_RAM <= conv_std_logic_vector(STATIC_RAM_CFG_FTU_OFFSET +
498                                                     crate_cnt * NO_OF_FTUS_PER_CRATE * (NO_OF_FTU_ENABLE_REG + NO_OF_FTU_DAC_REG + 1) +
499                                                     FTU_cnt * (NO_OF_FTU_ENABLE_REG + NO_OF_FTU_DAC_REG + 1) +
500                                                     (FTU_register_cnt - 1), STATIC_RAM_ADDR_WIDTH);
501            FTM_ftu_rs485_control_State <= READ_CONFIG_2;
502          end if;
503           
504        when READ_CONFIG_2 =>
505          if (static_RAM_started = '1') then
506            FTM_ftu_rs485_control_State <= READ_CONFIG_3;
507          end if;
508           
509        when READ_CONFIG_3 =>
510          if (static_RAM_ready = '1') then
511            if ((FTU_register_cnt - 1) < NO_OF_FTU_ENABLE_REG) then
512              FTU_enable_array_RAM_sig(FTU_register_cnt - 1) <= data_static_RAM;
513            elsif ((FTU_register_cnt - 1) < (NO_OF_FTU_ENABLE_REG + NO_OF_FTU_DAC_REG)) then
514              FTU_dac_array_RAM_sig((FTU_register_cnt - 1) - NO_OF_FTU_ENABLE_REG) <= data_static_RAM;
515            elsif ((FTU_register_cnt - 1) = (NO_OF_FTU_ENABLE_REG + NO_OF_FTU_DAC_REG)) then
516              FTU_prescaling_RAM_sig <= data_static_RAM;
517            end if;
518            read_static_RAM <= '0';
519            FTM_ftu_rs485_control_State <= READ_CONFIG;
520          end if;
521         
522        when TRANSMIT_CONFIG =>  -- send configuration to FTUs (one by one)
523          rec_reset_sig <= '0';
524          if (FTU_command_cnt = 0) then  -- DACs
525            FTU_command_cnt <= FTU_command_cnt + 1;
526            enable_crc_from_FSM_sig <= '1';
527            crc_data_from_FSM_sig <= "00000000"
528                                     & "00000000" & "00000000" & "00000000" & "00000000" & "00000000"
529                                     & "00000000" & "00000000" & "00000000" & "00000000" & "00000000"
530                                     & "00000000"
531                                     & FTU_dac_array_RAM_sig(4)(15 downto 8) & FTU_dac_array_RAM_sig(4)(7 downto 0)
532                                     & FTU_dac_array_RAM_sig(3)(15 downto 8) & FTU_dac_array_RAM_sig(3)(7 downto 0)
533                                     & FTU_dac_array_RAM_sig(2)(15 downto 8) & FTU_dac_array_RAM_sig(2)(7 downto 0)
534                                     & FTU_dac_array_RAM_sig(1)(15 downto 8) & FTU_dac_array_RAM_sig(1)(7 downto 0)
535                                     & FTU_dac_array_RAM_sig(0)(15 downto 8) & FTU_dac_array_RAM_sig(0)(7 downto 0)
536                                     & "00000000" & FIRMWARE_ID & FTM_ADDRESS
537                                     & "00" & conv_std_logic_vector(FTU_cnt,4) & conv_std_logic_vector(crate_cnt,2)
538                                     & FTU_RS485_START_DELIM;
539            FTU_brd_add_sig <= conv_std_logic_vector(FTU_cnt,4) & conv_std_logic_vector(crate_cnt,2);
540            FTU_command_sig <= "00000000";
541            FTM_ftu_rs485_control_State <= TRANSMIT_CONFIG_1;
542          elsif (FTU_command_cnt = 1) then  -- enables
543            FTU_command_cnt <= FTU_command_cnt + 1;
544            enable_crc_from_FSM_sig <= '1';
545            crc_data_from_FSM_sig <= "00000000"
546                                     & "00000000" & "00000000" & "00000000" & "00000000" & "00000000"
547                                     & "00000000" & "00000000" & "00000000" & "00000000" & "00000000"
548                                     & "00000000" & "00000000" & "00000000"
549                                     & FTU_enable_array_RAM_sig(3)(15 downto 8) & FTU_enable_array_RAM_sig(3)(7 downto 0)
550                                     & FTU_enable_array_RAM_sig(2)(15 downto 8) & FTU_enable_array_RAM_sig(2)(7 downto 0)
551                                     & FTU_enable_array_RAM_sig(1)(15 downto 8) & FTU_enable_array_RAM_sig(1)(7 downto 0)
552                                     & FTU_enable_array_RAM_sig(0)(15 downto 8) & FTU_enable_array_RAM_sig(0)(7 downto 0)
553                                     & "00000011" & FIRMWARE_ID & FTM_ADDRESS
554                                     & "00" & conv_std_logic_vector(FTU_cnt,4) & conv_std_logic_vector(crate_cnt,2)
555                                     & FTU_RS485_START_DELIM;
556            FTU_brd_add_sig <= conv_std_logic_vector(FTU_cnt,4) & conv_std_logic_vector(crate_cnt,2);
557            FTU_command_sig <= "00000011";
558            FTM_ftu_rs485_control_State <= TRANSMIT_CONFIG_1;
559          elsif (FTU_command_cnt = 2) then  -- prescaling
560            FTU_command_cnt <= FTU_command_cnt + 1;
561            enable_crc_from_FSM_sig <= '1';
562            crc_data_from_FSM_sig <= "00000000"
563                                     & "00000000" & "00000000" & "00000000" & "00000000" & "00000000"
564                                     & "00000000" & "00000000" & "00000000" & "00000000" & "00000000"
565                                     & "00000000" & "00000000" & "00000000" & "00000000" & "00000000"
566                                     & "00000000" & "00000000" & "00000000" & "00000000"
567                                     & FTU_prescaling_RAM_sig(15 downto 8) & FTU_prescaling_RAM_sig(7 downto 0)
568                                     & "00000110" & FIRMWARE_ID & FTM_ADDRESS
569                                     & "00" & conv_std_logic_vector(FTU_cnt,4) & conv_std_logic_vector(crate_cnt,2)
570                                     & FTU_RS485_START_DELIM;
571            FTU_brd_add_sig <= conv_std_logic_vector(FTU_cnt,4) & conv_std_logic_vector(crate_cnt,2);
572            FTU_command_sig <= "00000110";
573            FTM_ftu_rs485_control_State <= TRANSMIT_CONFIG_1;
574          else
575            FTU_command_cnt <= 0;
576            enable_crc_from_FSM_sig <= '0';
577            FTM_ftu_rs485_control_State <= READ_CONFIG;
578          end if;
579           
580        when TRANSMIT_CONFIG_1 =>  -- wait one cycle for CRC calculation
581          enable_crc_from_FSM_sig <= '0';
582          FTM_ftu_rs485_control_State <= TRANSMIT_CONFIG_2;
583         
584        when TRANSMIT_CONFIG_2 =>  -- transmit byte by byte
585          if (tx_busy_sig = '0') then
586            if (frame_cnt < 27) then
587              frame_cnt <= frame_cnt + 1;
588              tx_data_sig <= crc_data_from_FSM_sig (7 downto 0);
589              crc_data_from_FSM_sig <= "00000000" & crc_data_from_FSM_sig ((FTU_RS485_BLOCK_WIDTH - 9) downto 8);
590              tx_start_sig <= '1';
591              FTM_ftu_rs485_control_State <= TRANSMIT_CONFIG_2;
592            elsif (frame_cnt = 27) then
593              frame_cnt <= frame_cnt + 1;
594              tx_data_sig <= crc_sig;
595              tx_start_sig <= '1';
596              FTM_ftu_rs485_control_State <= TRANSMIT_CONFIG_2;
597            else
598              frame_cnt <= 0;
599              reset_crc_from_FSM_sig <= '1';
600              FTM_ftu_rs485_control_State <= TRANSMIT_CONFIG_3;
601            end if;           
602          else
603            tx_start_sig <= '0';
604            FTM_ftu_rs485_control_State <= TRANSMIT_CONFIG_2;
605          end if;
606         
607        when TRANSMIT_CONFIG_3 =>  -- wait for FTU answer
608          reset_crc_from_FSM_sig <= '0';
609          if (FTU_answer_ok_sig = '1') then
610            timeout_cnt <= 0;
611            retry_cnt <= 0;
612            sel_crc_input_source_sig <= '0';
613            FTM_ftu_rs485_control_State <= TRANSMIT_CONFIG;
614          else
615            if (timeout_cnt < FTU_RS485_TIMEOUT) then
616              timeout_cnt <= timeout_cnt + 1;
617              sel_crc_input_source_sig <= '1';
618              FTM_ftu_rs485_control_State <= TRANSMIT_CONFIG_3;
619            else
620              timeout_cnt <= 0;
621              sel_crc_input_source_sig <= '0';
622              rec_reset_sig <= '1';
623              if (retry_cnt < FTU_RS485_NO_OF_RETRY) then
624                retry_cnt <= retry_cnt + 1;
625                FTU_command_cnt <= FTU_command_cnt - 1;  -- try this command again
626                FTM_ftu_rs485_control_State <= TRANSMIT_CONFIG;
627              else
628                retry_cnt <= 0;
629                FTU_command_cnt <= FTU_command_cnt;  -- move to next command;
630                FTM_ftu_rs485_control_State <= TRANSMIT_CONFIG;
631              end if;
632            end if;
633          end if;
634           
635        when PING =>  -- ping all FTUs
636          rec_reset_sig <= '0';
637          if (crate_cnt < NO_OF_CRATES) then
638            sel_crate_sig <= conv_std_logic_vector(crate_cnt, 3);
639            if (FTU_cnt < NO_OF_FTUS_PER_CRATE) then
640              FTU_cnt <= FTU_cnt + 1;
641              if (active_FTU_array_sig(crate_cnt)(FTU_cnt) = '1') then
642                enable_crc_from_FSM_sig <= '1';
643                crc_data_from_FSM_sig <= "00000000"
644                                         & "00000000" & "00000000" & "00000000" & "00000000" & "00000000"
645                                         & "00000000" & "00000000" & "00000000" & "00000000" & "00000000"
646                                         & "00000000" & "00000000" & "00000000" & "00000000" & "00000000"
647                                         & "00000000" & "00000000" & "00000000" & "00000000" & "00000000" & "00000000"
648                                         & "00000101" & FIRMWARE_ID & FTM_ADDRESS
649                                         & "00" & conv_std_logic_vector(FTU_cnt,4) & conv_std_logic_vector(crate_cnt,2)
650                                         & FTU_RS485_START_DELIM;
651                FTU_brd_add_sig <= conv_std_logic_vector(FTU_cnt,4) & conv_std_logic_vector(crate_cnt,2);
652                FTU_command_sig <= "00000101";
653                FTM_ftu_rs485_control_State <= PING_1;
654              else
655                FTM_ftu_rs485_control_State <= PING;
656              end if;
657            else
658              crate_cnt <= crate_cnt + 1;
659              FTU_cnt <= 0;
660              FTM_ftu_rs485_control_State <= PING;
661            end if;
662          else
663            crate_cnt <= 0;
664            FTM_ftu_rs485_control_State <= PING_END;
665          end if;
666         
667        when PING_1 =>  -- wait one cycle for CRC calculation
668          enable_crc_from_FSM_sig <= '0';
669          FTM_ftu_rs485_control_State <= PING_2;
670
671        when PING_2 =>  -- transmit byte by byte
672          if (tx_busy_sig = '0') then
673            if (frame_cnt < 27) then
674              frame_cnt <= frame_cnt + 1;
675              tx_data_sig <= crc_data_from_FSM_sig (7 downto 0);
676              crc_data_from_FSM_sig <= "00000000" & crc_data_from_FSM_sig ((FTU_RS485_BLOCK_WIDTH - 9) downto 8);
677              tx_start_sig <= '1';
678              FTM_ftu_rs485_control_State <= PING_2;
679            elsif (frame_cnt = 27) then
680              frame_cnt <= frame_cnt + 1;
681              tx_data_sig <= crc_sig;
682              tx_start_sig <= '1';
683              FTM_ftu_rs485_control_State <= PING_2;
684            else
685              frame_cnt <= 0;
686              reset_crc_from_FSM_sig <= '1';
687              FTM_ftu_rs485_control_State <= PING_3;
688            end if;           
689          else
690            tx_start_sig <= '0';
691            FTM_ftu_rs485_control_State <= PING_2;
692          end if;
693
694        when PING_3 =>  -- wait for FTU answer
695          reset_crc_from_FSM_sig <= '0';
696          if (FTU_answer_ok_sig = '1') then
697            FTU_answer_array_sig(crate_cnt) <= FTU_answer_array_sig(crate_cnt) + 1;
698            no_of_FTU_answer_sig <= no_of_FTU_answer_sig + 1;
699            timeout_cnt <= 0;
700            sel_crc_input_source_sig <= '0';
701            FTM_ftu_rs485_control_State <= FTU_LIST;
702          else
703            if (timeout_cnt < FTU_RS485_TIMEOUT) then
704              timeout_cnt <= timeout_cnt + 1;
705              sel_crc_input_source_sig <= '1';
706              FTM_ftu_rs485_control_State <= PING_3;
707            else
708              timeout_cnt <= 0;
709              sel_crc_input_source_sig <= '0';
710              rec_reset_sig <= '1';
711              if (retry_cnt < FTU_RS485_NO_OF_RETRY) then
712                retry_cnt <= retry_cnt + 1;
713                FTU_cnt <= FTU_cnt - 1;  -- repeat this FTU
714                FTM_ftu_rs485_control_State <= PING;
715              else
716                FTU_cnt <= FTU_cnt;  -- move on
717                FTM_ftu_rs485_control_State <= FTU_LIST;
718              end if;
719            end if;
720          end if;
721
722        when FTU_LIST =>  -- fill FTU-list for actual FTU
723          rec_reset_sig <= '0';
724          if (FTU_list_reg_cnt < NO_OF_FTU_LIST_REG) then
725            FTU_list_reg_cnt <= FTU_list_reg_cnt + 1;
726            FTM_ftu_rs485_control_State <= FTU_LIST_1;
727          else
728            FTU_list_reg_cnt <= 0;
729            retry_cnt <= 0;
730            FTM_ftu_rs485_control_State <= PING;
731          end if;
732         
733        when FTU_LIST_1 =>
734          if (FTUlist_RAM_busy = '0') then
735            write_FTUlist_RAM <= '1';
736            addr_FTUlist_RAM <= conv_std_logic_vector(FTU_LIST_RAM_OFFSET +
737                                                      FTU_cnt * NO_OF_FTU_LIST_REG +
738                                                      (FTU_list_reg_cnt - 1), FTU_LIST_RAM_ADDR_WIDTH);
739            if (retry_cnt < FTU_RS485_NO_OF_RETRY) then
740              if ((FTU_list_reg_cnt - 1) = 0) then
741                data_FTUlist_RAM <= "000000" & conv_std_logic_vector((retry_cnt + 1),2) & "00" & FTU_brd_add_sig;
742              elsif ((FTU_list_reg_cnt - 1) = 1) then
743                data_FTUlist_RAM <= FTU_dna_sig(63 downto 48);
744              elsif ((FTU_list_reg_cnt - 1) = 2) then
745                data_FTUlist_RAM <= FTU_dna_sig(47 downto 32);
746              elsif ((FTU_list_reg_cnt - 1) = 3) then
747                data_FTUlist_RAM <= FTU_dna_sig(31 downto 16);
748              elsif ((FTU_list_reg_cnt - 1) = 4) then
749                data_FTUlist_RAM <= FTU_dna_sig(15 downto  0);
750              elsif ((FTU_list_reg_cnt - 1) = 5) then
751                data_FTUlist_RAM <= "00000000" & FTU_crc_error_cnt_sig;
752              end if;
753            else
754              data_FTUlist_RAM <= (others => '0');
755            end if;
756            FTM_ftu_rs485_control_State <= FTU_LIST_2;
757          end if;
758
759        when FTU_LIST_2 =>
760          if (FTUlist_RAM_started = '1') then
761            write_FTUlist_RAM <= '0';
762            FTM_ftu_rs485_control_State <= FTU_LIST_3;
763          end if;
764           
765        when FTU_LIST_3 =>
766          if (FTUlist_RAM_ready = '1') then
767            FTM_ftu_rs485_control_State <= FTU_LIST;
768          end if;
769
770        when PING_END =>  -- add final ping statistics to FTU-list
771          if (FTU_list_header_cnt < FTU_LIST_RAM_OFFSET) then
772            FTU_list_header_cnt <= FTU_list_header_cnt + 1;
773            FTM_ftu_rs485_control_State <= PING_END_1;
774          else
775            FTU_list_header_cnt <= 0;
776            ping_all_started <= '0';
777            ping_all_done <= '1';
778            sel_crate_sig <= "111";
779            FTM_ftu_rs485_control_State <= IDLE;
780          end if;
781
782        when PING_END_1 =>
783          if (FTUlist_RAM_busy = '0') then
784            write_FTUlist_RAM <= '1';
785            addr_FTUlist_RAM <= conv_std_logic_vector((FTU_list_header_cnt - 1), FTU_LIST_RAM_ADDR_WIDTH);
786            if ((FTU_list_header_cnt - 1) = 0) then
787              data_FTUlist_RAM <= conv_std_logic_vector(no_of_FTU_answer_sig, 16);
788            elsif ((FTU_list_header_cnt - 1) < 5) then
789              data_FTUlist_RAM <= conv_std_logic_vector(FTU_answer_array_sig(FTU_list_header_cnt - 2), 16);
790            elsif ((FTU_list_header_cnt - 1) < 9) then
791              data_FTUlist_RAM <= active_FTU_array_sig(FTU_list_header_cnt - 6);
792            end if;
793            FTM_ftu_rs485_control_State <= PING_END_2;
794          end if;
795         
796        when PING_END_2 =>
797          if (FTUlist_RAM_started = '1') then
798            write_FTUlist_RAM <= '0';
799            FTM_ftu_rs485_control_State <= PING_END_3;
800          end if;
801       
802        when PING_END_3 =>
803          if (FTUlist_RAM_ready = '1') then
804            FTM_ftu_rs485_control_State <= PING_END;
805          end if;
806         
807        when RATES =>  -- read all FTU rates
808          FTM_ftu_rs485_control_State <= IDLE;
809
810      end case;
811    end if;
812  end process FTM_ftu_rs485_control_FSM;
813
814  -- Process to multiplex the different crate buses
815  sel_crate_process: process (sel_crate_sig,
816                              rx_en_0_sig, rx_en_1_sig, rx_en_2_sig, rx_en_3_sig,
817                              tx_en_0_sig, tx_en_1_sig, tx_en_2_sig, tx_en_3_sig,
818                              rx_valid_0_sig, rx_valid_1_sig, rx_valid_2_sig, rx_valid_3_sig,
819                              rx_data_0_sig, rx_data_1_sig, rx_data_2_sig, rx_data_3_sig,
820                              tx_busy_0_sig, tx_busy_1_sig, tx_busy_2_sig, tx_busy_3_sig,
821                              tx_start_sig, tx_data_sig)
822  begin 
823    case sel_crate_sig is 
824      when "000" =>  -- crate 0
825        rx_en_sig <= rx_en_0_sig;
826        tx_en_sig <= tx_en_0_sig;
827        rx_valid_sig <= rx_valid_0_sig;
828        rec_data_sig <= rx_data_0_sig;
829        tx_busy_sig <= tx_busy_0_sig;
830        tx_start_0_sig <= tx_start_sig;
831        tx_start_1_sig <= '0';
832        tx_start_2_sig <= '0';
833        tx_start_3_sig <= '0';
834        tx_data_0_sig <= tx_data_sig;
835        tx_data_1_sig <= (others => '0');
836        tx_data_2_sig <= (others => '0');
837        tx_data_3_sig <= (others => '0');
838      when "001" =>  -- crate 1
839        rx_en_sig <= rx_en_1_sig;
840        tx_en_sig <= tx_en_1_sig;
841        rx_valid_sig <= rx_valid_1_sig;
842        rec_data_sig <= rx_data_1_sig;
843        tx_busy_sig <= tx_busy_1_sig;
844        tx_start_0_sig <= '0';
845        tx_start_1_sig <= tx_start_sig;
846        tx_start_2_sig <= '0';
847        tx_start_3_sig <= '0';
848        tx_data_0_sig <= (others => '0');
849        tx_data_1_sig <= tx_data_sig;
850        tx_data_2_sig <= (others => '0');
851        tx_data_3_sig <= (others => '0');
852      when "010" =>  -- crate 2
853        rx_en_sig <= rx_en_2_sig;
854        tx_en_sig <= tx_en_2_sig;
855        rx_valid_sig <= rx_valid_2_sig;
856        rec_data_sig <= rx_data_2_sig;
857        tx_busy_sig <= tx_busy_2_sig;
858        tx_start_0_sig <= '0';
859        tx_start_1_sig <= '0';
860        tx_start_2_sig <= tx_start_sig;
861        tx_start_3_sig <= '0';
862        tx_data_0_sig <= (others => '0');
863        tx_data_1_sig <= (others => '0');
864        tx_data_2_sig <= tx_data_sig;
865        tx_data_3_sig <= (others => '0');
866      when "011" =>  -- crate 3
867        rx_en_sig <= rx_en_3_sig;
868        tx_en_sig <= tx_en_3_sig;
869        rx_valid_sig <= rx_valid_3_sig;
870        rec_data_sig <= rx_data_3_sig;
871        tx_busy_sig <= tx_busy_3_sig;
872        tx_start_0_sig <= '0';
873        tx_start_1_sig <= '0';
874        tx_start_2_sig <= '0';
875        tx_start_3_sig <= tx_start_sig;
876        tx_data_0_sig <= (others => '0');
877        tx_data_1_sig <= (others => '0');
878        tx_data_2_sig <= (others => '0');
879        tx_data_3_sig <= tx_data_sig;
880      when others =>  -- no crate specified
881        rx_en_sig <= '0';
882        tx_en_sig <= '0';
883        rx_valid_sig <= '0';
884        rec_data_sig <= (others => '0');
885        tx_busy_sig <= '0';
886        tx_start_0_sig <= '0';
887        tx_start_1_sig <= '0';
888        tx_start_2_sig <= '0';
889        tx_start_3_sig <= '0';
890        tx_data_0_sig <= (others => '0');
891        tx_data_1_sig <= (others => '0');
892        tx_data_2_sig <= (others => '0');
893        tx_data_3_sig <= (others => '0');
894    end case; 
895  end process; 
896
897  -- Process to select the CRC input source (FSM or interpreter)
898  sel_crc_cource_process : process (sel_crc_input_source_sig,
899                                    reset_crc_from_interpreter_sig, reset_crc_from_FSM_sig,
900                                    enable_crc_from_interpreter_sig, enable_crc_from_FSM_sig,
901                                    rec_block_sig((FTU_RS485_BLOCK_WIDTH - 9) downto 0), crc_data_from_FSM_sig)                                   
902  begin
903    case sel_crc_input_source_sig is
904      when '0' =>  -- FSM
905        reset_crc_sig <= reset_crc_from_FSM_sig;
906        enable_crc_sig <= enable_crc_from_FSM_sig;
907        crc_data_sig <= crc_data_from_FSM_sig;
908      when '1' =>  -- interpreter
909        reset_crc_sig <= reset_crc_from_interpreter_sig;
910        enable_crc_sig <= enable_crc_from_interpreter_sig;
911        crc_data_sig <= rec_block_sig((FTU_RS485_BLOCK_WIDTH - 9) downto 0);
912      when others =>  -- signal undefined
913        reset_crc_sig <= reset_crc_from_FSM_sig;
914        enable_crc_sig <= enable_crc_from_FSM_sig;
915        crc_data_sig <= crc_data_from_FSM_sig;
916    end case;
917  end process;
918 
919  rx_en <= rx_en_sig;
920  tx_en <= tx_en_sig;
921
922  crc_sig <= crc_sig_inv(0) & crc_sig_inv(1) & crc_sig_inv(2) & crc_sig_inv(3) & crc_sig_inv(4) & crc_sig_inv(5) & crc_sig_inv(6) & crc_sig_inv(7);
923 
924end Behavioral;
925
Note: See TracBrowser for help on using the repository browser.