---------------------------------------------------------------------------------- -- Company: ETH Zurich, Institute for Particle Physics -- Engineer: Q. Weitzel, P. Vogler -- -- Create Date: 08/06/2010 -- Design Name: -- Module Name: FTU_control - Behavioral -- Project Name: -- Target Devices: -- Tool versions: -- Description: Control FSM of FACT FTU board -- -- Dependencies: -- -- Revision: -- Revision 0.01 - File Created -- Revision 0.02 - change-over to 64 byte RAM, 19.10.2010, Q. Weitzel -- Additional Comments: -- ---------------------------------------------------------------------------------- library IEEE; use IEEE.STD_LOGIC_1164.ALL; use IEEE.STD_LOGIC_ARITH.ALL; use IEEE.STD_LOGIC_UNSIGNED.ALL; library ftu_definitions; USE ftu_definitions.ftu_array_types.all; USE ftu_definitions.ftu_constants.all; ---- Uncomment the following library declaration if instantiating ---- any Xilinx primitives in this code. --library UNISIM; --use UNISIM.VComponents.all; entity FTU_control is port( clk_50MHz : IN std_logic; clk_ready : IN std_logic; -- from DCM config_started : IN std_logic; -- from DAC/SPI config_ready : IN std_logic; -- from DAC/SPI ram_doa : IN STD_LOGIC_VECTOR(7 downto 0); ram_dob : IN STD_LOGIC_VECTOR(15 downto 0); rate_array : IN rate_array_type; -- from counters overflow_array : IN STD_LOGIC_VECTOR(7 downto 0); -- from counters new_rates : IN std_logic; -- from counters new_DACs : IN std_logic; -- from RS485 module new_enables : IN std_logic; -- from RS485 module new_prescaling : IN std_logic; -- from RS485 module read_rates : IN std_logic; -- from RS485 module read_DACs : IN std_logic; -- from RS485 module read_enables : IN std_logic; -- from RS485 module read_prescaling : IN std_logic; -- from RS485 module ping_pong : IN std_logic; -- from RS485 module dac_array_rs485_out : IN dac_array_type; -- from RS485 module enable_array_rs485_out : IN enable_array_type; -- from RS485 module prescaling_rs485_out : IN STD_LOGIC_VECTOR(7 downto 0); -- from RS485 module dna_ready : IN std_logic; -- from FTU_dna_gen reset : OUT std_logic; config_start : OUT std_logic; ram_ena : OUT std_logic; ram_enb : OUT std_logic; ram_wea : OUT STD_LOGIC_VECTOR(0 downto 0); ram_web : OUT STD_LOGIC_VECTOR(0 downto 0); ram_ada : OUT STD_LOGIC_VECTOR(5 downto 0); ram_adb : OUT STD_LOGIC_VECTOR(4 downto 0); ram_dia : OUT STD_LOGIC_VECTOR(7 downto 0); ram_dib : OUT STD_LOGIC_VECTOR(15 downto 0); rate_array_rs485 : OUT rate_array_type := (0,0,0,0,0); -- to RS485 module overflow_array_rs485_in : OUT STD_LOGIC_VECTOR(7 downto 0) := "00000000"; -- to RS485 module rates_ready : OUT std_logic := '0'; -- to RS485 module DACs_ready : OUT std_logic := '0'; -- to RS485 module enables_ready : OUT std_logic := '0'; -- to RS485 module prescaling_ready : OUT std_logic := '0'; -- to RS485 module ping_pong_ready : OUT std_logic := '0'; -- to RS485 module dac_array : OUT dac_array_type; enable_array : OUT enable_array_type; cntr_reset : OUT STD_LOGIC; prescaling : OUT STD_LOGIC_VECTOR(7 downto 0); dna_start : OUT std_logic := '0' -- to FTU_dna_gen ); end FTU_control; architecture Behavioral of FTU_control is signal new_rates_sr : std_logic_vector(1 downto 0) := (others => '0'); signal reset_sig : STD_LOGIC := '0'; --initialize reset to 0 at power up --DAC/SPI interface, default DACs come from RAM during INIT signal config_start_sig : STD_LOGIC := '0'; signal dac_array_sig : dac_array_type := (0,0,0,0,0,0,0,0); --enable signals for pixels in trigger, default values come from RAM during INIT signal enable_array_sig : enable_array_type := ("0000000000000000", --patch A "0000000000000000", --patch B "0000000000000000", --patch C "0000000000000000");--patch D signal rate_array_sig : rate_array_type; -- initialized in FTU_top signal cntr_reset_sig : STD_LOGIC := '0'; signal prescaling_sig : STD_LOGIC_VECTOR(7 downto 0) := "00011101"; -- 29 signal ram_ena_sig : STD_LOGIC := '0'; -- RAM enable for port A signal ram_enb_sig : STD_LOGIC := '0'; -- RAM enable for port B signal ram_wea_sig : STD_LOGIC_VECTOR(0 downto 0) := "0"; -- RAM write enable for port A signal ram_web_sig : STD_LOGIC_VECTOR(0 downto 0) := "0"; -- RAM write enable for port B signal ram_ada_sig : STD_LOGIC_VECTOR(5 downto 0) := (others => '0'); --RAM port A address signal ram_adb_sig : STD_LOGIC_VECTOR(4 downto 0) := (others => '0'); --RAM port B address signal ram_dia_sig : STD_LOGIC_VECTOR(7 downto 0) := (others => '0'); --RAM data in A signal ram_dib_sig : STD_LOGIC_VECTOR(15 downto 0) := (others => '0'); --RAM data in B --counter to loop through RAM signal ram_ada_cntr : INTEGER range 0 to 2**RAM_ADDR_WIDTH_A := 0; signal ram_dac_cntr : INTEGER range 0 to (NO_OF_DAC - NO_OF_DAC_NOT_USED + 2) := 0; signal ram_enable_cntr : INTEGER range 0 to (NO_OF_ENABLE + 1) := 0; signal ram_counter_cntr : INTEGER range 0 to (NO_OF_COUNTER*RAM_CEF + 2) := 0; --includes overflow register signal wait_cntr : INTEGER range 0 to 2**RAM_ADDR_WIDTH_A := 0; signal new_rates_sig : STD_LOGIC := '0'; signal new_rates_busy : STD_LOGIC := '1'; -- veto the writing of new rates until in RUNNING signal new_DACs_in_RAM : STD_LOGIC := '0'; signal new_enables_in_RAM : STD_LOGIC := '0'; signal new_prescaling_in_RAM : STD_LOGIC := '0'; signal ram_buffer_sig : STD_LOGIC_VECTOR(29 downto 0) := (others => '0'); type FTU_control_StateType is (IDLE, INIT_RAM, INIT_DNA, RUNNING, CONFIG_ENABLE, CONFIG_DAC, CONFIG_DAC_WAIT, CONFIG_COUNTER, WRITE_RATES, WRITE_DAC, WRITE_ENABLE, WRITE_PRESCALING, READOUT_RATES, READOUT_DAC, READOUT_ENABLE, READOUT_PRESCALING, DO_PING_PONG); signal FTU_control_State : FTU_control_StateType; begin --FTU control finite state machine FTU_control_FSM: process (clk_50MHz) begin reset_sig <= '0'; if Rising_edge(clk_50MHz) then case FTU_control_State is when IDLE => -- wait for DCMs to lock if (clk_ready = '1') then FTU_control_State <= INIT_DNA; else FTU_control_State <= IDLE; end if; when INIT_DNA => -- determine FPGA DNA if (dna_ready = '1') then FTU_control_State <= INIT_RAM; dna_start <= '0'; else dna_start <= '1'; FTU_control_State <= INIT_DNA; end if; when INIT_RAM => -- load default config data to RAM, see also ftu_definitions.vhd for more info ram_ena_sig <= '1'; ram_wea_sig <= "1"; ram_ada_cntr <= ram_ada_cntr + 1; ram_ada_sig <= conv_std_logic_vector(ram_ada_cntr, RAM_ADDR_WIDTH_A); if (ram_ada_cntr < NO_OF_ENABLE*RAM_ADDR_RATIO) then -- default enables if (ram_ada_cntr mod 2 = 0) then ram_dia_sig <= DEFAULT_ENABLE(ram_ada_cntr / 2)(7 downto 0); else ram_dia_sig <= DEFAULT_ENABLE(ram_ada_cntr / 2)(15 downto 8); end if; FTU_control_State <= INIT_RAM; elsif (ram_ada_cntr < (NO_OF_ENABLE*RAM_ADDR_RATIO + NO_OF_COUNTER*RAM_ADDR_RATIO*RAM_CEF)) then -- default counter values ram_dia_sig <= (others => '0'); FTU_control_State <= INIT_RAM; elsif (ram_ada_cntr < (NO_OF_ENABLE*RAM_ADDR_RATIO + NO_OF_COUNTER*RAM_ADDR_RATIO*RAM_CEF + (NO_OF_DAC - NO_OF_DAC_NOT_USED)*RAM_ADDR_RATIO)) then -- default DACs if (ram_ada_cntr < (NO_OF_ENABLE*RAM_ADDR_RATIO + NO_OF_COUNTER*RAM_ADDR_RATIO*RAM_CEF + (NO_OF_DAC - NO_OF_DAC_NOT_USED - 1)*RAM_ADDR_RATIO)) then if (ram_ada_cntr mod 2 = 0) then ram_dia_sig <= conv_std_logic_vector(DEFAULT_DAC((ram_ada_cntr - (NO_OF_ENABLE*RAM_ADDR_RATIO + NO_OF_COUNTER*RAM_ADDR_RATIO*RAM_CEF)) / 2),16)(7 downto 0); else ram_dia_sig <= conv_std_logic_vector(DEFAULT_DAC((ram_ada_cntr - (NO_OF_ENABLE*RAM_ADDR_RATIO + NO_OF_COUNTER*RAM_ADDR_RATIO*RAM_CEF)) / 2),16)(15 downto 8); end if; else if (ram_ada_cntr mod 2 = 0) then ram_dia_sig <= conv_std_logic_vector(DEFAULT_DAC(((ram_ada_cntr - (NO_OF_ENABLE*RAM_ADDR_RATIO + NO_OF_COUNTER*RAM_ADDR_RATIO*RAM_CEF)) / 2) + NO_OF_DAC_NOT_USED),16)(7 downto 0); else ram_dia_sig <= conv_std_logic_vector(DEFAULT_DAC(((ram_ada_cntr - (NO_OF_ENABLE*RAM_ADDR_RATIO + NO_OF_COUNTER*RAM_ADDR_RATIO*RAM_CEF)) / 2) + NO_OF_DAC_NOT_USED),16)(15 downto 8); end if; end if; FTU_control_State <= INIT_RAM; elsif (ram_ada_cntr = (NO_OF_ENABLE*RAM_ADDR_RATIO + NO_OF_COUNTER*RAM_ADDR_RATIO*RAM_CEF + (NO_OF_DAC - NO_OF_DAC_NOT_USED)*RAM_ADDR_RATIO)) then -- default prescaling ram_dia_sig <= conv_std_logic_vector(DEFAULT_PRESCALING,8); FTU_control_State <= INIT_RAM; elsif (ram_ada_cntr = (NO_OF_ENABLE*RAM_ADDR_RATIO + NO_OF_COUNTER*RAM_ADDR_RATIO*RAM_CEF + (NO_OF_DAC - NO_OF_DAC_NOT_USED)*RAM_ADDR_RATIO) + 1) then -- default overflow register ram_dia_sig <= (others => '0'); FTU_control_State <= INIT_RAM; elsif (ram_ada_cntr < 2**RAM_ADDR_WIDTH_A) then -- empty RAM cells ram_dia_sig <= (others => '0'); FTU_control_State <= INIT_RAM; else ram_dia_sig <= (others => '0'); ram_ada_cntr <= 0; ram_ada_sig <= (others => '0'); ram_ena_sig <= '0'; ram_wea_sig <= "0"; new_DACs_in_RAM <= '1'; new_enables_in_RAM <= '1'; new_prescaling_in_RAM <= '1'; cntr_reset_sig <= '1'; new_rates_busy <= '0'; FTU_control_State <= RUNNING; end if; when RUNNING => -- count triggers and react to commands from FTM cntr_reset_sig <= '0'; config_start_sig <= '0'; if (new_rates_sig = '1') then -- counters have finished a period FTU_control_State <= WRITE_RATES; else -- update FTU settings if necessary if (new_DACs_in_RAM = '1') then ram_enb_sig <= '1'; ram_adb_sig <= conv_std_logic_vector((NO_OF_ENABLE + NO_OF_COUNTER*RAM_CEF), RAM_ADDR_WIDTH_B); FTU_control_State <= CONFIG_DAC; elsif (new_DACs_in_RAM = '0' and new_enables_in_RAM = '1') then ram_enb_sig <= '1'; ram_adb_sig <= conv_std_logic_vector(0, RAM_ADDR_WIDTH_B); FTU_control_State <= CONFIG_ENABLE; elsif (new_DACs_in_RAM = '0' and new_enables_in_RAM = '0' and new_prescaling_in_RAM = '1') then ram_ena_sig <= '1'; ram_ada_sig <= conv_std_logic_vector((NO_OF_ENABLE*RAM_ADDR_RATIO + NO_OF_COUNTER*RAM_ADDR_RATIO*RAM_CEF + (NO_OF_DAC - NO_OF_DAC_NOT_USED)*RAM_ADDR_RATIO), RAM_ADDR_WIDTH_A); FTU_control_State <= CONFIG_COUNTER; else -- nothing to be updated, check new commands from RS485 if (new_DACs = '1') then FTU_control_State <= WRITE_DAC; elsif (new_DACs = '0' and new_enables = '1') then FTU_control_State <= WRITE_ENABLE; elsif (new_DACs = '0' and new_enables = '0' and new_prescaling = '1') then FTU_control_State <= WRITE_PRESCALING; elsif (new_DACs = '0' and new_enables = '0' and new_prescaling = '0' and read_rates = '1') then ram_enb_sig <= '1'; ram_adb_sig <= conv_std_logic_vector(NO_OF_ENABLE, RAM_ADDR_WIDTH_B); FTU_control_State <= READOUT_RATES; elsif (new_DACs = '0' and new_enables = '0' and new_prescaling = '0' and read_rates = '0' and read_DACs = '1') then ram_enb_sig <= '1'; ram_adb_sig <= conv_std_logic_vector(NO_OF_ENABLE + NO_OF_COUNTER*RAM_CEF, RAM_ADDR_WIDTH_B); FTU_control_State <= READOUT_DAC; elsif (new_DACs = '0' and new_enables = '0' and new_prescaling = '0' and read_rates = '0' and read_DACs = '0' and read_enables = '1') then ram_enb_sig <= '1'; ram_adb_sig <= conv_std_logic_vector(0, RAM_ADDR_WIDTH_B); FTU_control_State <= READOUT_ENABLE; elsif (new_DACs = '0' and new_enables = '0' and new_prescaling = '0' and read_rates = '0' and read_DACs = '0' and read_enables = '0' and read_prescaling = '1') then ram_ena_sig <= '1'; ram_ada_sig <= conv_std_logic_vector((NO_OF_ENABLE*RAM_ADDR_RATIO + NO_OF_COUNTER*RAM_ADDR_RATIO*RAM_CEF + (NO_OF_DAC - NO_OF_DAC_NOT_USED)*RAM_ADDR_RATIO), RAM_ADDR_WIDTH_A); FTU_control_State <= READOUT_PRESCALING; elsif (new_DACs = '0' and new_enables = '0' and new_prescaling = '0' and read_rates = '0' and read_DACs = '0' and read_enables = '0' and read_prescaling = '0' and ping_pong = '1') then FTU_control_State <= DO_PING_PONG; else FTU_control_State <= RUNNING; --no commands from RS485 -> stay running end if; end if; end if; when CONFIG_COUNTER => -- set prescaling value for counters wait_cntr <= wait_cntr + 1; new_rates_busy <= '1'; if (wait_cntr = 0) then FTU_control_State <= CONFIG_COUNTER; elsif (wait_cntr = 1) then prescaling_sig <= ram_doa; FTU_control_State <= CONFIG_COUNTER; prescaling_ready <= '1'; else cntr_reset_sig <= '1'; ram_ada_sig <= (others => '0'); wait_cntr <= 0; new_prescaling_in_RAM <= '0'; ram_ena_sig <= '0'; new_rates_busy <= '0'; prescaling_ready <= '0'; FTU_control_State <= RUNNING; end if; when CONFIG_ENABLE => -- set enable patterns for sum trigger stage ram_enable_cntr <= ram_enable_cntr + 1; new_rates_busy <= '1'; if (ram_enable_cntr = 0) then ram_adb_sig <= conv_std_logic_vector(ram_enable_cntr + 1, RAM_ADDR_WIDTH_B); FTU_control_State <= CONFIG_ENABLE; elsif (ram_enable_cntr < NO_OF_ENABLE) then ram_adb_sig <= conv_std_logic_vector(ram_enable_cntr + 1, RAM_ADDR_WIDTH_B); enable_array_sig(ram_enable_cntr - 1) <= ram_dob; FTU_control_State <= CONFIG_ENABLE; elsif (ram_enable_cntr = NO_OF_ENABLE) then ram_adb_sig <= conv_std_logic_vector(ram_enable_cntr + 1, RAM_ADDR_WIDTH_B); enable_array_sig(ram_enable_cntr - 1) <= ram_dob; enables_ready <= '1'; FTU_control_State <= CONFIG_ENABLE; else ram_adb_sig <= (others => '0'); ram_enable_cntr <= 0; new_enables_in_RAM <= '0'; ram_enb_sig <= '0'; cntr_reset_sig <= '1'; new_rates_busy <= '0'; enables_ready <= '0'; FTU_control_State <= RUNNING; end if; when CONFIG_DAC => -- start to set thresholds for sum trigger patches new_rates_busy <= '1'; ram_dac_cntr <= ram_dac_cntr + 1; if (ram_dac_cntr = 0) then ram_adb_sig <= conv_std_logic_vector((NO_OF_ENABLE + NO_OF_COUNTER*RAM_CEF + ram_dac_cntr + 1), RAM_ADDR_WIDTH_B); FTU_control_State <= CONFIG_DAC; elsif (ram_dac_cntr < (NO_OF_DAC - NO_OF_DAC_NOT_USED)) then dac_array_sig(ram_dac_cntr - 1) <= conv_integer(unsigned(ram_dob(11 downto 0))); ram_adb_sig <= conv_std_logic_vector((NO_OF_ENABLE + NO_OF_COUNTER*RAM_CEF + ram_dac_cntr + 1), RAM_ADDR_WIDTH_B); FTU_control_State <= CONFIG_DAC; elsif (ram_dac_cntr < (NO_OF_DAC - NO_OF_DAC_NOT_USED + 1)) then dac_array_sig(4) <= 0; dac_array_sig(5) <= 0; dac_array_sig(6) <= 0; dac_array_sig(ram_dac_cntr - 1 + NO_OF_DAC_NOT_USED) <= conv_integer(unsigned(ram_dob(11 downto 0))); ram_adb_sig <= (others => '0'); FTU_control_State <= CONFIG_DAC; DACs_ready <= '1'; else ram_adb_sig <= (others => '0'); ram_enb_sig <= '0'; config_start_sig <= '1'; ram_dac_cntr <= 0; DACs_ready <= '0'; FTU_control_State <= CONFIG_DAC_WAIT; end if; when CONFIG_DAC_WAIT => -- wait until setting of thresholds has finished if (config_ready = '1') then new_DACs_in_RAM <= '0'; cntr_reset_sig <= '1'; new_rates_busy <= '0'; config_start_sig <= '0'; FTU_control_State <= RUNNING; elsif (config_ready = '0' and config_started = '1') then new_rates_busy <= '1'; config_start_sig <= '0'; FTU_control_State <= CONFIG_DAC_WAIT; else new_rates_busy <= '1'; config_start_sig <= '1'; FTU_control_State <= CONFIG_DAC_WAIT; end if; when WRITE_RATES => -- write trigger/patch rates to RAM B and overflow register to RAM A new_rates_busy <= '1'; ram_counter_cntr <= ram_counter_cntr + 1; if (ram_counter_cntr < NO_OF_COUNTER*RAM_CEF) then ram_enb_sig <= '1'; ram_web_sig <= "1"; ram_adb_sig <= conv_std_logic_vector((NO_OF_ENABLE + ram_counter_cntr), RAM_ADDR_WIDTH_B); if (ram_counter_cntr mod 2 = 0) then ram_dib_sig <= conv_std_logic_vector(rate_array_sig(ram_counter_cntr / 2), 32)(15 downto 0); else ram_dib_sig <= conv_std_logic_vector(rate_array_sig(ram_counter_cntr / 2), 32)(31 downto 16); end if; FTU_control_State <= WRITE_RATES; elsif (ram_counter_cntr = NO_Of_COUNTER*RAM_CEF) then ram_dib_sig <= (others => '0'); ram_adb_sig <= (others => '0'); ram_enb_sig <= '0'; ram_web_sig <= "0"; ram_ena_sig <= '1'; ram_wea_sig <= "1"; ram_ada_sig <= conv_std_logic_vector(NO_OF_ENABLE*RAM_ADDR_RATIO + NO_OF_COUNTER*RAM_ADDR_RATIO*RAM_CEF + (NO_OF_DAC - NO_OF_DAC_NOT_USED)*RAM_ADDR_RATIO + 1, RAM_ADDR_WIDTH_A); ram_dia_sig <= overflow_array; FTU_control_State <= WRITE_RATES; else ram_ena_sig <= '0'; ram_wea_sig <= "0"; ram_counter_cntr <= 0; new_rates_busy <= '0'; FTU_control_State <= RUNNING; end if; when WRITE_DAC => -- write new DAC values from RS485 to RAM ram_dac_cntr <= ram_dac_cntr + 1; if (ram_dac_cntr < (NO_OF_DAC - NO_OF_DAC_NOT_USED - 1)) then ram_enb_sig <= '1'; ram_web_sig <= "1"; ram_adb_sig <= conv_std_logic_vector((NO_OF_ENABLE + NO_OF_COUNTER*RAM_CEF + ram_dac_cntr), RAM_ADDR_WIDTH_B); ram_dib_sig <= conv_std_logic_vector(dac_array_rs485_out(ram_dac_cntr), 16); FTU_control_State <= WRITE_DAC; elsif (ram_dac_cntr = (NO_OF_DAC - NO_OF_DAC_NOT_USED - 1)) then ram_enb_sig <= '1'; ram_web_sig <= "1"; ram_adb_sig <= conv_std_logic_vector((NO_OF_ENABLE + NO_OF_COUNTER*RAM_CEF + ram_dac_cntr), RAM_ADDR_WIDTH_B); ram_dib_sig <= conv_std_logic_vector(dac_array_rs485_out(ram_dac_cntr + NO_OF_DAC_NOT_USED), 16); FTU_control_State <= WRITE_DAC; else ram_enb_sig <= '0'; ram_web_sig <= "0"; new_DACs_in_RAM <= '1'; ram_dib_sig <= (others => '0'); ram_adb_sig <= (others => '0'); ram_dac_cntr <= 0; FTU_control_State <= RUNNING; end if; when WRITE_ENABLE => -- write new enable patterns from RS485 to RAM ram_enable_cntr <= ram_enable_cntr + 1; if (ram_enable_cntr < NO_OF_ENABLE) then ram_enb_sig <= '1'; ram_web_sig <= "1"; ram_adb_sig <= conv_std_logic_vector(ram_enable_cntr, RAM_ADDR_WIDTH_B); ram_dib_sig <= enable_array_rs485_out(ram_enable_cntr); else ram_enb_sig <= '0'; ram_web_sig <= "0"; new_enables_in_RAM <= '1'; ram_dib_sig <= (others => '0'); ram_adb_sig <= (others => '0'); ram_enable_cntr <= 0; FTU_control_State <= RUNNING; end if; when WRITE_PRESCALING => -- write new prescaling from RS485 to RAM wait_cntr <= wait_cntr + 1; if (wait_cntr = 0) then ram_ena_sig <= '1'; ram_wea_sig <= "1"; ram_ada_sig <= conv_std_logic_vector((NO_OF_ENABLE*RAM_ADDR_RATIO + NO_OF_COUNTER*RAM_ADDR_RATIO*RAM_CEF + (NO_OF_DAC - NO_OF_DAC_NOT_USED)*RAM_ADDR_RATIO), RAM_ADDR_WIDTH_A); ram_dia_sig <= prescaling_rs485_out; else ram_ena_sig <= '0'; ram_wea_sig <= "0"; new_prescaling_in_RAM <= '1'; ram_dia_sig <= (others => '0'); ram_ada_sig <= (others => '0'); wait_cntr <= 0; FTU_control_State <= RUNNING; end if; when READOUT_RATES => -- read most recent rate values from RAM and send them to RS485 module ram_counter_cntr <= ram_counter_cntr + 1; if (ram_counter_cntr = 0) then ram_enb_sig <= '1'; ram_adb_sig <= conv_std_logic_vector((NO_OF_ENABLE + ram_counter_cntr + 1), RAM_ADDR_WIDTH_B); FTU_control_State <= READOUT_RATES; elsif (ram_counter_cntr < 3) then ram_ena_sig <= '1'; ram_ada_sig <= conv_std_logic_vector(((NO_OF_ENABLE + NO_OF_COUNTER*RAM_CEF + NO_OF_DAC - NO_OF_DAC_NOT_USED)*RAM_ADDR_RATIO + 1), RAM_ADDR_WIDTH_A); ram_enb_sig <= '1'; ram_adb_sig <= conv_std_logic_vector((NO_OF_ENABLE + ram_counter_cntr + 1), RAM_ADDR_WIDTH_B); if (ram_counter_cntr = 1) then ram_buffer_sig(15 downto 0) <= ram_dob; else ram_buffer_sig(29 downto 16) <= ram_dob(13 downto 0); end if; FTU_control_State <= READOUT_RATES; elsif (ram_counter_cntr < NO_OF_COUNTER*RAM_CEF) then ram_ena_sig <= '1'; ram_ada_sig <= conv_std_logic_vector(((NO_OF_ENABLE + NO_OF_COUNTER*RAM_CEF + NO_OF_DAC - NO_OF_DAC_NOT_USED)*RAM_ADDR_RATIO + 1), RAM_ADDR_WIDTH_A); ram_enb_sig <= '1'; ram_adb_sig <= conv_std_logic_vector((NO_OF_ENABLE + ram_counter_cntr + 1), RAM_ADDR_WIDTH_B); if (ram_counter_cntr mod 2 = 1) then ram_buffer_sig(15 downto 0) <= ram_dob; rate_array_rs485((ram_counter_cntr / 2) - 1) <= conv_integer(unsigned(ram_buffer_sig)); else ram_buffer_sig(29 downto 16) <= ram_dob(13 downto 0); end if; FTU_control_State <= READOUT_RATES; elsif (ram_counter_cntr = NO_Of_COUNTER*RAM_CEF) then ram_enb_sig <= '0'; ram_adb_sig <= (others => '0'); ram_buffer_sig(29 downto 16) <= ram_dob(13 downto 0); ram_ena_sig <= '1'; ram_ada_sig <= conv_std_logic_vector(((NO_OF_ENABLE + NO_OF_COUNTER*RAM_CEF + NO_OF_DAC - NO_OF_DAC_NOT_USED)*RAM_ADDR_RATIO + 1), RAM_ADDR_WIDTH_A); FTU_control_State <= READOUT_RATES; elsif (ram_counter_cntr = NO_Of_COUNTER*RAM_CEF + 1) then rate_array_rs485((ram_counter_cntr / 2) - 1) <= conv_integer(unsigned(ram_buffer_sig)); ram_buffer_sig <= (others => '0'); ram_enb_sig <= '0'; ram_adb_sig <= (others => '0'); ram_ena_sig <= '0'; ram_ada_sig <= (others => '0'); overflow_array_rs485_in <= ram_doa; rates_ready <= '1'; FTU_control_State <= READOUT_RATES; else ram_enb_sig <= '0'; ram_adb_sig <= (others => '0'); ram_ena_sig <= '0'; ram_ada_sig <= (others => '0'); ram_counter_cntr <= 0; rates_ready <= '0'; FTU_control_State <= RUNNING; end if; when READOUT_DAC => -- read most recent DAC values from RAM and send them to RS485 module ram_dac_cntr <= ram_dac_cntr + 1; if (ram_dac_cntr = 0) then ram_enb_sig <= '1'; ram_adb_sig <= conv_std_logic_vector((NO_OF_ENABLE + NO_OF_COUNTER*RAM_CEF + ram_dac_cntr + 1), RAM_ADDR_WIDTH_B); FTU_control_State <= READOUT_DAC; elsif (ram_dac_cntr < (NO_OF_DAC - NO_OF_DAC_NOT_USED)) then ram_enb_sig <= '1'; ram_adb_sig <= conv_std_logic_vector((NO_OF_ENABLE + NO_OF_COUNTER*RAM_CEF + ram_dac_cntr + 1), RAM_ADDR_WIDTH_B); dac_array_sig(ram_dac_cntr - 1) <= conv_integer(unsigned(ram_dob(11 downto 0))); FTU_control_State <= READOUT_DAC; elsif (ram_dac_cntr = (NO_OF_DAC - NO_OF_DAC_NOT_USED)) then ram_enb_sig <= '0'; ram_adb_sig <= (others => '0'); dac_array_sig(ram_dac_cntr + NO_OF_DAC_NOT_USED - 1) <= conv_integer(unsigned(ram_dob(11 downto 0))); DACs_ready <= '1'; FTU_control_State <= READOUT_DAC; else ram_enb_sig <= '0'; ram_adb_sig <= (others => '0'); DACs_ready <= '0'; ram_dac_cntr <= 0; FTU_control_State <= RUNNING; end if; when READOUT_ENABLE => -- read most recent enable patterns from RAM and send them to RS485 module ram_enable_cntr <= ram_enable_cntr + 1; if (ram_enable_cntr = 0) then ram_enb_sig <= '1'; ram_adb_sig <= conv_std_logic_vector((ram_enable_cntr + 1), RAM_ADDR_WIDTH_B); FTU_control_State <= READOUT_ENABLE; elsif (ram_enable_cntr < NO_OF_ENABLE) then ram_enb_sig <= '1'; ram_adb_sig <= conv_std_logic_vector((ram_enable_cntr + 1), RAM_ADDR_WIDTH_B); enable_array_sig(ram_enable_cntr - 1) <= ram_dob; FTU_control_State <= READOUT_ENABLE; elsif (ram_enable_cntr = NO_OF_ENABLE) then ram_enb_sig <= '0'; ram_adb_sig <= (others => '0'); enable_array_sig(ram_enable_cntr - 1) <= ram_dob; enables_ready <= '1'; FTU_control_State <= READOUT_ENABLE; else ram_enb_sig <= '0'; ram_adb_sig <= (others => '0'); enables_ready <= '0'; ram_enable_cntr <= 0; FTU_control_State <= RUNNING; end if; when READOUT_PRESCALING => -- read most recent prescaling value from RAM and send it to RS485 module wait_cntr <= wait_cntr + 1; if (wait_cntr = 0) then ram_ena_sig <= '1'; ram_ada_sig <= conv_std_logic_vector((NO_OF_ENABLE*RAM_ADDR_RATIO + NO_OF_COUNTER*RAM_ADDR_RATIO*RAM_CEF + (NO_OF_DAC - NO_OF_DAC_NOT_USED)*RAM_ADDR_RATIO) + 1, RAM_ADDR_WIDTH_A); FTU_control_State <= READOUT_PRESCALING; elsif (wait_cntr = 1) then ram_ena_sig <= '1'; ram_ada_sig <= (others => '0'); prescaling_sig <= ram_doa; FTU_control_State <= READOUT_PRESCALING; elsif (wait_cntr = 2) then ram_ena_sig <= '0'; ram_ada_sig <= (others => '0'); overflow_array_rs485_in <= ram_doa; prescaling_ready <= '1'; FTU_control_State <= READOUT_PRESCALING; else ram_ena_sig <= '0'; ram_ada_sig <= (others => '0'); prescaling_ready <= '0'; wait_cntr <= 0; FTU_control_State <= RUNNING; end if; when DO_PING_PONG => -- answer to FTM and send DNA wait_cntr <= wait_cntr + 1; if (wait_cntr = 0) then ping_pong_ready <= '1'; FTU_control_State <= DO_PING_PONG; else ping_pong_ready <= '0'; wait_cntr <= 0; FTU_control_State <= RUNNING; end if; end case; end if; end process FTU_control_FSM; detect_new_rates: process(clk_50MHz) begin if rising_edge(clk_50MHz) then new_rates_sr <= new_rates_sr(new_rates_sr'left - 1 downto 0) & new_rates; if(new_rates_busy = '1') then new_rates_sig <= '0'; else if (new_rates_sr(1 downto 0) = "01") then new_rates_sig <= '1'; end if; end if; end if; end process detect_new_rates; reset <= reset_sig; config_start <= config_start_sig; dac_array <= dac_array_sig; enable_array <= enable_array_sig; prescaling <= prescaling_sig; rate_array_sig <= rate_array; cntr_reset <= cntr_reset_sig; ram_ena <= ram_ena_sig; ram_enb <= ram_enb_sig; ram_wea <= ram_wea_sig; ram_web <= ram_web_sig; ram_ada <= ram_ada_sig; ram_adb <= ram_adb_sig; ram_dia <= ram_dia_sig; ram_dib <= ram_dib_sig; end Behavioral;