---------------------------------------------------------------------------------- -- Company: ETH Zurich, Institute for Particle Physics -- Engineer: Q. Weitzel -- -- Create Date: 02/04/2011 -- Design Name: -- Module Name: FTM_ftu_rs485_interpreter - Behavioral -- Project Name: -- Target Devices: -- Tool versions: -- Description: data interpreter of FTM RS485 module for FTU communication -- -- Dependencies: -- -- Revision: -- Revision 0.01 - File Created -- Additional Comments: -- ---------------------------------------------------------------------------------- library IEEE; use IEEE.STD_LOGIC_1164.ALL; use IEEE.STD_LOGIC_ARITH.ALL; use IEEE.STD_LOGIC_UNSIGNED.ALL; library ftm_definitions; USE ftm_definitions.ftm_array_types.all; USE ftm_definitions.ftm_constants.all; ---- Uncomment the following library declaration if instantiating ---- any Xilinx primitives in this code. --library UNISIM; --use UNISIM.VComponents.all; entity FTM_ftu_rs485_interpreter is port( clk : IN std_logic; data_block : IN std_logic_vector(FTU_RS485_BLOCK_WIDTH - 1 downto 0); -- from receiver block_valid : IN std_logic; -- from receiver crc : IN std_logic_vector(7 downto 0); -- from ucrc_par FTU_brd_add : IN std_logic_vector(5 downto 0); -- from FTM_ftu_control FSM FTU_command : IN std_logic_vector(7 downto 0); -- from FTM_ftu_control FSM reset_crc : OUT std_logic := '0'; enable_crc : OUT std_logic := '0'; FTU_answer_ok : OUT std_logic := '0'; FTU_dac_array : OUT FTU_dac_array_type := ((others => '0'), (others => '0'), (others => '0'), (others => '0'), (others => '0')); FTU_enable_array : OUT FTU_enable_array_type := ((others => '0'), (others => '0'), (others => '0'), (others => '0')); FTU_rate_array : OUT FTU_rate_array_type := ((others => '0'), (others => '0'), (others => '0'), (others => '0'), (others => '0')); FTU_overflow : OUT std_logic_vector(7 downto 0) := (others => '0'); FTU_prescaling : OUT std_logic_vector(7 downto 0) := (others => '0'); FTU_crc_error_cnt : OUT std_logic_vector(7 downto 0) := (others => '0'); FTU_dna : OUT std_logic_vector(63 downto 0) := (others => '0') ); end FTM_ftu_rs485_interpreter; architecture Behavioral of FTM_ftu_rs485_interpreter is signal block_valid_sr : std_logic_vector(3 downto 0) := (others => '0'); type FTM_ftu_rs485_interpreter_StateType is (INIT, WAIT_FOR_DATA, WAIT_CRC, CHECK_CRC, CHECK_HEADER, CHECK_CMD, DECODE); signal FTM_ftu_rs485_interpreter_State : FTM_ftu_rs485_interpreter_StateType; begin FTM_ftu_rs485_interpreter_FSM: process (clk) begin if Rising_edge(clk) then case FTM_ftu_rs485_interpreter_State is when INIT => -- reset CRC register reset_crc <= '1'; FTU_answer_ok <= '0'; FTM_ftu_rs485_interpreter_State <= WAIT_FOR_DATA; when WAIT_FOR_DATA => -- default state, waiting for valid 28-byte block block_valid_sr <= block_valid_sr(2 downto 0) & block_valid; if (block_valid_sr(3 downto 2) = "01") then -- rising edge of valid signal enable_crc <= '1'; FTM_ftu_rs485_interpreter_State <= WAIT_CRC; else enable_crc <= '0'; FTM_ftu_rs485_interpreter_State <= WAIT_FOR_DATA; end if; reset_crc <= '0'; FTU_answer_ok <= '0'; when WAIT_CRC => -- wait one cycle for CRC calculation enable_crc <= '0'; FTU_answer_ok <= '0'; FTM_ftu_rs485_interpreter_State <= CHECK_CRC; when CHECK_CRC => -- check whether CRC matches reset_crc <= '1'; FTU_answer_ok <= '0'; if ( crc = data_block((FTU_RS485_BLOCK_WIDTH - 1) downto (FTU_RS485_BLOCK_WIDTH - 8)) ) then FTM_ftu_rs485_interpreter_State <= CHECK_HEADER; else FTM_ftu_rs485_interpreter_State <= WAIT_FOR_DATA; end if; when CHECK_HEADER => -- check start delimiter and addresses if (data_block(7 downto 0) = FTU_RS485_START_DELIM) and (data_block(15 downto 8) = FTM_ADDRESS) and (data_block(23 downto 16) = ("00" & FTU_brd_add)) then FTM_ftu_rs485_interpreter_State <= CHECK_CMD; else FTM_ftu_rs485_interpreter_State <= WAIT_FOR_DATA; end if; reset_crc <= '0'; FTU_answer_ok <= '0'; when CHECK_CMD => -- check command reset_crc <= '0'; if (data_block(39 downto 32) = FTU_command) then FTM_ftu_rs485_interpreter_State <= DECODE; FTU_answer_ok <= '1'; else FTM_ftu_rs485_interpreter_State <= WAIT_FOR_DATA; FTU_answer_ok <= '0'; end if; when DECODE => -- decode instruction FTU_answer_ok <= '0'; if(data_block(39 downto 32) = "00000000") then -- set DACs FTU_dac_array <= (data_block( 55 downto 40), data_block( 71 downto 56), data_block( 87 downto 72), data_block(103 downto 88), data_block(119 downto 104) ); FTM_ftu_rs485_interpreter_State <= WAIT_FOR_DATA; elsif (data_block(39 downto 32) = "00000001") then -- read DACs FTU_dac_array <= (data_block( 55 downto 40), data_block( 71 downto 56), data_block( 87 downto 72), data_block(103 downto 88), data_block(119 downto 104) ); FTM_ftu_rs485_interpreter_State <= WAIT_FOR_DATA; elsif (data_block(39 downto 32) = "00000010") then -- read rates FTU_rate_array <= (data_block( 71 downto 40), data_block(103 downto 72), data_block(135 downto 104), data_block(167 downto 136), data_block(199 downto 168) ); FTU_overflow <= data_block(207 downto 200); FTU_crc_error_cnt <= data_block(215 downto 208); FTM_ftu_rs485_interpreter_State <= WAIT_FOR_DATA; elsif (data_block(39 downto 32) = "00000011") then -- set enables FTU_enable_array <= (data_block( 55 downto 40), data_block( 71 downto 56), data_block( 87 downto 72), data_block(103 downto 88) ); FTM_ftu_rs485_interpreter_State <= WAIT_FOR_DATA; elsif (data_block(39 downto 32) = "00000100") then -- read enables FTU_enable_array <= (data_block( 55 downto 40), data_block( 71 downto 56), data_block( 87 downto 72), data_block(103 downto 88) ); FTM_ftu_rs485_interpreter_State <= WAIT_FOR_DATA; elsif (data_block(39 downto 32) = "00000110") then -- set counter mode FTU_prescaling <= data_block(47 downto 40); FTM_ftu_rs485_interpreter_State <= WAIT_FOR_DATA; elsif (data_block(39 downto 32) = "00000111") then -- read counter mode FTU_prescaling <= data_block(47 downto 40); FTU_overflow <= data_block(55 downto 48); FTM_ftu_rs485_interpreter_State <= WAIT_FOR_DATA; elsif (data_block(39 downto 32) = "00000101") then -- ping pong FTU_dna <= data_block(103 downto 40); FTU_crc_error_cnt <= data_block(215 downto 208); FTM_ftu_rs485_interpreter_State <= WAIT_FOR_DATA; else FTM_ftu_rs485_interpreter_State <= WAIT_FOR_DATA; end if; end case; end if; end process FTM_ftu_rs485_interpreter_FSM; end Behavioral;